bx
}
- fn build_sibling_block(&mut self, name: &str) -> Self {
- let block = self.append_sibling_block(name);
- Self::build(self.cx, block)
- }
-
fn llbb(&self) -> Block<'gcc> {
self.block.expect("block")
}
let start = dest.project_index(&mut self, zero).llval;
let end = dest.project_index(&mut self, count).llval;
- let mut header_bx = self.build_sibling_block("repeat_loop_header");
- let mut body_bx = self.build_sibling_block("repeat_loop_body");
- let next_bx = self.build_sibling_block("repeat_loop_next");
+ let header_bb = self.append_sibling_block("repeat_loop_header");
+ let body_bb = self.append_sibling_block("repeat_loop_body");
+ let next_bb = self.append_sibling_block("repeat_loop_next");
let ptr_type = start.get_type();
let current = self.llbb().get_function().new_local(None, ptr_type, "loop_var");
let current_val = current.to_rvalue();
self.assign(current, start);
- self.br(header_bx.llbb());
+ self.br(header_bb);
+ let mut header_bx = Builder::build(self.cx, header_bb);
let keep_going = header_bx.icmp(IntPredicate::IntNE, current_val, end);
- header_bx.cond_br(keep_going, body_bx.llbb(), next_bx.llbb());
+ header_bx.cond_br(keep_going, body_bb, next_bb);
+ let mut body_bx = Builder::build(self.cx, body_bb);
let align = dest.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size);
cg_elem.val.store(&mut body_bx, PlaceRef::new_sized_aligned(current_val, cg_elem.layout, align));
let next = body_bx.inbounds_gep(self.backend_type(cg_elem.layout), current.to_rvalue(), &[self.const_usize(1)]);
body_bx.llbb().add_assignment(None, current, next);
- body_bx.br(header_bx.llbb());
+ body_bx.br(header_bb);
- next_bx
+ Builder::build(self.cx, next_bb)
}
fn range_metadata(&mut self, _load: RValue<'gcc>, _range: WrappingRange) {
Self::append_block(self.cx, self.llfn(), name)
}
- fn build_sibling_block(&mut self, name: &str) -> Self {
- let llbb = self.append_sibling_block(name);
- Self::build(self.cx, llbb)
- }
-
fn ret_void(&mut self) {
unsafe {
llvm::LLVMBuildRetVoid(self.llbuilder);
let start = dest.project_index(&mut self, zero).llval;
let end = dest.project_index(&mut self, count).llval;
- let mut header_bx = self.build_sibling_block("repeat_loop_header");
- let mut body_bx = self.build_sibling_block("repeat_loop_body");
- let next_bx = self.build_sibling_block("repeat_loop_next");
+ let header_bb = self.append_sibling_block("repeat_loop_header");
+ let body_bb = self.append_sibling_block("repeat_loop_body");
+ let next_bb = self.append_sibling_block("repeat_loop_next");
+
+ self.br(header_bb);
- self.br(header_bx.llbb());
+ let mut header_bx = Self::build(self.cx, header_bb);
let current = header_bx.phi(self.val_ty(start), &[start], &[self.llbb()]);
let keep_going = header_bx.icmp(IntPredicate::IntNE, current, end);
- header_bx.cond_br(keep_going, body_bx.llbb(), next_bx.llbb());
+ header_bx.cond_br(keep_going, body_bb, next_bb);
+ let mut body_bx = Self::build(self.cx, body_bb);
let align = dest.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size);
cg_elem
.val
current,
&[self.const_usize(1)],
);
- body_bx.br(header_bx.llbb());
- header_bx.add_incoming_to_phi(current, next, body_bx.llbb());
+ body_bx.br(header_bb);
+ header_bx.add_incoming_to_phi(current, next, body_bb);
- next_bx
+ Self::build(self.cx, next_bb)
}
fn range_metadata(&mut self, load: &'ll Value, range: WrappingRange) {
let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| {
bx.set_personality_fn(bx.eh_personality());
- let mut normal = bx.build_sibling_block("normal");
- let mut catchswitch = bx.build_sibling_block("catchswitch");
- let mut catchpad_rust = bx.build_sibling_block("catchpad_rust");
- let mut catchpad_foreign = bx.build_sibling_block("catchpad_foreign");
- let mut caught = bx.build_sibling_block("caught");
+ let normal = bx.append_sibling_block("normal");
+ let catchswitch = bx.append_sibling_block("catchswitch");
+ let catchpad_rust = bx.append_sibling_block("catchpad_rust");
+ let catchpad_foreign = bx.append_sibling_block("catchpad_foreign");
+ let caught = bx.append_sibling_block("caught");
let try_func = llvm::get_param(bx.llfn(), 0);
let data = llvm::get_param(bx.llfn(), 1);
let ptr_align = bx.tcx().data_layout.pointer_align.abi;
let slot = bx.alloca(bx.type_i8p(), ptr_align);
let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void());
- bx.invoke(try_func_ty, try_func, &[data], normal.llbb(), catchswitch.llbb(), None);
+ bx.invoke(try_func_ty, try_func, &[data], normal, catchswitch, None);
+ let mut normal = Builder::build(bx.cx, normal);
normal.ret(bx.const_i32(0));
- let cs =
- catchswitch.catch_switch(None, None, &[catchpad_rust.llbb(), catchpad_foreign.llbb()]);
+ let mut catchswitch = Builder::build(bx.cx, catchswitch);
+ let cs = catchswitch.catch_switch(None, None, &[catchpad_rust, catchpad_foreign]);
// We can't use the TypeDescriptor defined in libpanic_unwind because it
// might be in another DLL and the SEH encoding only supports specifying
// since our exception object effectively contains a Box.
//
// Source: MicrosoftCXXABI::getAddrOfCXXCatchHandlerType in clang
+ let mut catchpad_rust = Builder::build(bx.cx, catchpad_rust);
let flags = bx.const_i32(8);
let funclet = catchpad_rust.catch_pad(cs, &[tydesc, flags, slot]);
let ptr = catchpad_rust.load(bx.type_i8p(), slot, ptr_align);
let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void());
catchpad_rust.call(catch_ty, catch_func, &[data, ptr], Some(&funclet));
- catchpad_rust.catch_ret(&funclet, caught.llbb());
+ catchpad_rust.catch_ret(&funclet, caught);
// The flag value of 64 indicates a "catch-all".
+ let mut catchpad_foreign = Builder::build(bx.cx, catchpad_foreign);
let flags = bx.const_i32(64);
let null = bx.const_null(bx.type_i8p());
let funclet = catchpad_foreign.catch_pad(cs, &[null, flags, null]);
catchpad_foreign.call(catch_ty, catch_func, &[data, null], Some(&funclet));
- catchpad_foreign.catch_ret(&funclet, caught.llbb());
+ catchpad_foreign.catch_ret(&funclet, caught);
+ let mut caught = Builder::build(bx.cx, caught);
caught.ret(bx.const_i32(1));
});
// (%ptr, _) = landingpad
// call %catch_func(%data, %ptr)
// ret 1
- let mut then = bx.build_sibling_block("then");
- let mut catch = bx.build_sibling_block("catch");
+ let then = bx.append_sibling_block("then");
+ let catch = bx.append_sibling_block("catch");
let try_func = llvm::get_param(bx.llfn(), 0);
let data = llvm::get_param(bx.llfn(), 1);
let catch_func = llvm::get_param(bx.llfn(), 2);
let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void());
- bx.invoke(try_func_ty, try_func, &[data], then.llbb(), catch.llbb(), None);
+ bx.invoke(try_func_ty, try_func, &[data], then, catch, None);
+
+ let mut then = Builder::build(bx.cx, then);
then.ret(bx.const_i32(0));
// Type indicator for the exception being thrown.
// being thrown. The second value is a "selector" indicating which of
// the landing pad clauses the exception's type had been matched to.
// rust_try ignores the selector.
+ let mut catch = Builder::build(bx.cx, catch);
let lpad_ty = bx.type_struct(&[bx.type_i8p(), bx.type_i32()], false);
let vals = catch.landing_pad(lpad_ty, bx.eh_personality(), 1);
let tydesc = bx.const_null(bx.type_i8p());
// %catch_data[1] = %is_rust_panic
// call %catch_func(%data, %catch_data)
// ret 1
- let mut then = bx.build_sibling_block("then");
- let mut catch = bx.build_sibling_block("catch");
+ let then = bx.append_sibling_block("then");
+ let catch = bx.append_sibling_block("catch");
let try_func = llvm::get_param(bx.llfn(), 0);
let data = llvm::get_param(bx.llfn(), 1);
let catch_func = llvm::get_param(bx.llfn(), 2);
let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void());
- bx.invoke(try_func_ty, try_func, &[data], then.llbb(), catch.llbb(), None);
+ bx.invoke(try_func_ty, try_func, &[data], then, catch, None);
+
+ let mut then = Builder::build(bx.cx, then);
then.ret(bx.const_i32(0));
// Type indicator for the exception being thrown.
// The first value in this tuple is a pointer to the exception object
// being thrown. The second value is a "selector" indicating which of
// the landing pad clauses the exception's type had been matched to.
+ let mut catch = Builder::build(bx.cx, catch);
let tydesc = bx.eh_catch_typeinfo();
let lpad_ty = bx.type_struct(&[bx.type_i8p(), bx.type_i32()], false);
let vals = catch.landing_pad(lpad_ty, bx.eh_personality(), 2);
let va_list_ty = va_list_layout.llvm_type(bx);
let layout = bx.cx.layout_of(target_ty);
- let mut maybe_reg = bx.build_sibling_block("va_arg.maybe_reg");
- let mut in_reg = bx.build_sibling_block("va_arg.in_reg");
- let mut on_stack = bx.build_sibling_block("va_arg.on_stack");
- let mut end = bx.build_sibling_block("va_arg.end");
+ let maybe_reg = bx.append_sibling_block("va_arg.maybe_reg");
+ let in_reg = bx.append_sibling_block("va_arg.in_reg");
+ let on_stack = bx.append_sibling_block("va_arg.on_stack");
+ let end = bx.append_sibling_block("va_arg.end");
let zero = bx.const_i32(0);
let offset_align = Align::from_bytes(4).unwrap();
// if the offset >= 0 then the value will be on the stack
let mut reg_off_v = bx.load(bx.type_i32(), reg_off, offset_align);
let use_stack = bx.icmp(IntPredicate::IntSGE, reg_off_v, zero);
- bx.cond_br(use_stack, on_stack.llbb(), maybe_reg.llbb());
+ bx.cond_br(use_stack, on_stack, maybe_reg);
// The value at this point might be in a register, but there is a chance that
// it could be on the stack so we have to update the offset and then check
// the offset again.
+ let mut maybe_reg = Builder::build(bx.cx, maybe_reg);
if gr_type && layout.align.abi.bytes() > 8 {
reg_off_v = maybe_reg.add(reg_off_v, bx.const_i32(15));
reg_off_v = maybe_reg.and(reg_off_v, bx.const_i32(-16));
// Check to see if we have overflowed the registers as a result of this.
// If we have then we need to use the stack for this value
let use_stack = maybe_reg.icmp(IntPredicate::IntSGT, new_reg_off_v, zero);
- maybe_reg.cond_br(use_stack, on_stack.llbb(), in_reg.llbb());
+ maybe_reg.cond_br(use_stack, on_stack, in_reg);
+ let mut in_reg = Builder::build(bx.cx, in_reg);
let top_type = bx.type_i8p();
let top = in_reg.struct_gep(va_list_ty, va_list_addr, reg_top_index);
let top = in_reg.load(top_type, top, bx.tcx().data_layout.pointer_align.abi);
let reg_type = layout.llvm_type(bx);
let reg_addr = in_reg.bitcast(reg_addr, bx.cx.type_ptr_to(reg_type));
let reg_value = in_reg.load(reg_type, reg_addr, layout.align.abi);
- in_reg.br(end.llbb());
+ in_reg.br(end);
// On Stack block
+ let mut on_stack = Builder::build(bx.cx, on_stack);
let stack_value =
emit_ptr_va_arg(&mut on_stack, list, target_ty, false, Align::from_bytes(8).unwrap(), true);
- on_stack.br(end.llbb());
+ on_stack.br(end);
+ let mut end = Builder::build(bx.cx, end);
let val = end.phi(
layout.immediate_llvm_type(bx),
&[reg_value, stack_value],
// Create the failure block and the conditional branch to it.
let lltarget = helper.llblock(self, target);
- let panic_block = bx.build_sibling_block("panic");
+ let panic_block = bx.append_sibling_block("panic");
if expected {
- bx.cond_br(cond, lltarget, panic_block.llbb());
+ bx.cond_br(cond, lltarget, panic_block);
} else {
- bx.cond_br(cond, panic_block.llbb(), lltarget);
+ bx.cond_br(cond, panic_block, lltarget);
}
// After this point, bx is the block for the call to panic.
- bx = panic_block;
+ bx = Bx::build(self.cx, panic_block);
self.set_debug_loc(&mut bx, terminator.source_info);
// Get the location information.
// Test whether the function pointer is associated with the type identifier.
let cond = bx.type_test(fn_ptr, typeid_metadata);
- let mut bx_pass = bx.build_sibling_block("type_test.pass");
- let mut bx_fail = bx.build_sibling_block("type_test.fail");
- bx.cond_br(cond, bx_pass.llbb(), bx_fail.llbb());
+ let bb_pass = bx.append_sibling_block("type_test.pass");
+ let bb_fail = bx.append_sibling_block("type_test.fail");
+ bx.cond_br(cond, bb_pass, bb_fail);
+ let mut bx_pass = Bx::build(self.cx, bb_pass);
helper.do_call(
self,
&mut bx_pass,
cleanup,
);
+ let mut bx_fail = Bx::build(self.cx, bb_fail);
bx_fail.abort();
bx_fail.unreachable();
})
}
- // FIXME(eddyb) replace with `build_sibling_block`/`append_sibling_block`
+ // FIXME(eddyb) replace with `append_sibling_block`
// (which requires having a `Bx` already, and not all callers do).
fn new_block(&self, name: &str) -> Bx {
let llbb = Bx::append_block(self.cx, self.llfn, name);
fn append_sibling_block(&mut self, name: &str) -> Self::BasicBlock;
- // FIXME(eddyb) replace with callers using `append_sibling_block`.
- fn build_sibling_block(&mut self, name: &str) -> Self;
-
fn ret_void(&mut self);
fn ret(&mut self, v: Self::Value);
fn br(&mut self, dest: Self::BasicBlock);