Skip to content

Commit 96cf799

Browse files
committed
Introduce Bx::switch_to_block
1 parent 0edcf1e commit 96cf799

File tree

6 files changed

+95
-94
lines changed

6 files changed

+95
-94
lines changed

compiler/rustc_codegen_gcc/src/builder.rs

+15-9
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
404404
func.new_block(name)
405405
}
406406

407+
fn switch_to_block(&mut self, block: Self::BasicBlock) {
408+
*self.cx.current_block.borrow_mut() = Some(block);
409+
self.block = Some(block);
410+
}
411+
407412
fn ret_void(&mut self) {
408413
self.llbb().end_with_void_return(None)
409414
}
@@ -886,19 +891,20 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
886891

887892
self.br(header_bb);
888893

889-
let mut header_bx = Builder::build(self.cx, header_bb);
890-
let keep_going = header_bx.icmp(IntPredicate::IntNE, current_val, end);
891-
header_bx.cond_br(keep_going, body_bb, next_bb);
894+
self.switch_to_block(header_bb);
895+
let keep_going = self.icmp(IntPredicate::IntNE, current_val, end);
896+
self.cond_br(keep_going, body_bb, next_bb);
892897

893-
let mut body_bx = Builder::build(self.cx, body_bb);
898+
self.switch_to_block(body_bb);
894899
let align = dest.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size);
895-
cg_elem.val.store(&mut body_bx, PlaceRef::new_sized_aligned(current_val, cg_elem.layout, align));
900+
cg_elem.val.store(&mut self, PlaceRef::new_sized_aligned(current_val, cg_elem.layout, align));
896901

897-
let next = body_bx.inbounds_gep(self.backend_type(cg_elem.layout), current.to_rvalue(), &[self.const_usize(1)]);
898-
body_bx.llbb().add_assignment(None, current, next);
899-
body_bx.br(header_bb);
902+
let next = self.inbounds_gep(self.backend_type(cg_elem.layout), current.to_rvalue(), &[self.const_usize(1)]);
903+
self.llbb().add_assignment(None, current, next);
904+
self.br(header_bb);
900905

901-
Builder::build(self.cx, next_bb)
906+
self.switch_to_block(next_bb);
907+
self
902908
}
903909

904910
fn range_metadata(&mut self, _load: RValue<'gcc>, _range: WrappingRange) {

compiler/rustc_codegen_llvm/src/builder.rs

+4
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
166166
Self::append_block(self.cx, self.llfn(), name)
167167
}
168168

169+
fn switch_to_block(&mut self, llbb: Self::BasicBlock) {
170+
*self = Self::build(self.cx, llbb)
171+
}
172+
169173
fn ret_void(&mut self) {
170174
unsafe {
171175
llvm::LLVMBuildRetVoid(self.llbuilder);

compiler/rustc_codegen_llvm/src/intrinsic.rs

+44-50
Original file line numberDiff line numberDiff line change
@@ -522,11 +522,11 @@ fn codegen_msvc_try<'ll>(
522522
let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void());
523523
bx.invoke(try_func_ty, try_func, &[data], normal, catchswitch, None);
524524

525-
let mut normal = Builder::build(bx.cx, normal);
526-
normal.ret(bx.const_i32(0));
525+
bx.switch_to_block(normal);
526+
bx.ret(bx.const_i32(0));
527527

528-
let mut catchswitch = Builder::build(bx.cx, catchswitch);
529-
let cs = catchswitch.catch_switch(None, None, &[catchpad_rust, catchpad_foreign]);
528+
bx.switch_to_block(catchswitch);
529+
let cs = bx.catch_switch(None, None, &[catchpad_rust, catchpad_foreign]);
530530

531531
// We can't use the TypeDescriptor defined in libpanic_unwind because it
532532
// might be in another DLL and the SEH encoding only supports specifying
@@ -559,24 +559,24 @@ fn codegen_msvc_try<'ll>(
559559
// since our exception object effectively contains a Box.
560560
//
561561
// Source: MicrosoftCXXABI::getAddrOfCXXCatchHandlerType in clang
562-
let mut catchpad_rust = Builder::build(bx.cx, catchpad_rust);
562+
bx.switch_to_block(catchpad_rust);
563563
let flags = bx.const_i32(8);
564-
let funclet = catchpad_rust.catch_pad(cs, &[tydesc, flags, slot]);
565-
let ptr = catchpad_rust.load(bx.type_i8p(), slot, ptr_align);
564+
let funclet = bx.catch_pad(cs, &[tydesc, flags, slot]);
565+
let ptr = bx.load(bx.type_i8p(), slot, ptr_align);
566566
let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void());
567-
catchpad_rust.call(catch_ty, catch_func, &[data, ptr], Some(&funclet));
568-
catchpad_rust.catch_ret(&funclet, caught);
567+
bx.call(catch_ty, catch_func, &[data, ptr], Some(&funclet));
568+
bx.catch_ret(&funclet, caught);
569569

570570
// The flag value of 64 indicates a "catch-all".
571-
let mut catchpad_foreign = Builder::build(bx.cx, catchpad_foreign);
571+
bx.switch_to_block(catchpad_foreign);
572572
let flags = bx.const_i32(64);
573573
let null = bx.const_null(bx.type_i8p());
574-
let funclet = catchpad_foreign.catch_pad(cs, &[null, flags, null]);
575-
catchpad_foreign.call(catch_ty, catch_func, &[data, null], Some(&funclet));
576-
catchpad_foreign.catch_ret(&funclet, caught);
574+
let funclet = bx.catch_pad(cs, &[null, flags, null]);
575+
bx.call(catch_ty, catch_func, &[data, null], Some(&funclet));
576+
bx.catch_ret(&funclet, caught);
577577

578-
let mut caught = Builder::build(bx.cx, caught);
579-
caught.ret(bx.const_i32(1));
578+
bx.switch_to_block(caught);
579+
bx.ret(bx.const_i32(1));
580580
});
581581

582582
// Note that no invoke is used here because by definition this function
@@ -626,24 +626,24 @@ fn codegen_gnu_try<'ll>(
626626
let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void());
627627
bx.invoke(try_func_ty, try_func, &[data], then, catch, None);
628628

629-
let mut then = Builder::build(bx.cx, then);
630-
then.ret(bx.const_i32(0));
629+
bx.switch_to_block(then);
630+
bx.ret(bx.const_i32(0));
631631

632632
// Type indicator for the exception being thrown.
633633
//
634634
// The first value in this tuple is a pointer to the exception object
635635
// being thrown. The second value is a "selector" indicating which of
636636
// the landing pad clauses the exception's type had been matched to.
637637
// rust_try ignores the selector.
638-
let mut catch = Builder::build(bx.cx, catch);
638+
bx.switch_to_block(catch);
639639
let lpad_ty = bx.type_struct(&[bx.type_i8p(), bx.type_i32()], false);
640-
let vals = catch.landing_pad(lpad_ty, bx.eh_personality(), 1);
640+
let vals = bx.landing_pad(lpad_ty, bx.eh_personality(), 1);
641641
let tydesc = bx.const_null(bx.type_i8p());
642-
catch.add_clause(vals, tydesc);
643-
let ptr = catch.extract_value(vals, 0);
642+
bx.add_clause(vals, tydesc);
643+
let ptr = bx.extract_value(vals, 0);
644644
let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void());
645-
catch.call(catch_ty, catch_func, &[data, ptr], None);
646-
catch.ret(bx.const_i32(1));
645+
bx.call(catch_ty, catch_func, &[data, ptr], None);
646+
bx.ret(bx.const_i32(1));
647647
});
648648

649649
// Note that no invoke is used here because by definition this function
@@ -690,51 +690,45 @@ fn codegen_emcc_try<'ll>(
690690
let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void());
691691
bx.invoke(try_func_ty, try_func, &[data], then, catch, None);
692692

693-
let mut then = Builder::build(bx.cx, then);
694-
then.ret(bx.const_i32(0));
693+
bx.switch_to_block(then);
694+
bx.ret(bx.const_i32(0));
695695

696696
// Type indicator for the exception being thrown.
697697
//
698698
// The first value in this tuple is a pointer to the exception object
699699
// being thrown. The second value is a "selector" indicating which of
700700
// the landing pad clauses the exception's type had been matched to.
701-
let mut catch = Builder::build(bx.cx, catch);
701+
bx.switch_to_block(catch);
702702
let tydesc = bx.eh_catch_typeinfo();
703703
let lpad_ty = bx.type_struct(&[bx.type_i8p(), bx.type_i32()], false);
704-
let vals = catch.landing_pad(lpad_ty, bx.eh_personality(), 2);
705-
catch.add_clause(vals, tydesc);
706-
catch.add_clause(vals, bx.const_null(bx.type_i8p()));
707-
let ptr = catch.extract_value(vals, 0);
708-
let selector = catch.extract_value(vals, 1);
704+
let vals = bx.landing_pad(lpad_ty, bx.eh_personality(), 2);
705+
bx.add_clause(vals, tydesc);
706+
bx.add_clause(vals, bx.const_null(bx.type_i8p()));
707+
let ptr = bx.extract_value(vals, 0);
708+
let selector = bx.extract_value(vals, 1);
709709

710710
// Check if the typeid we got is the one for a Rust panic.
711-
let rust_typeid = catch.call_intrinsic("llvm.eh.typeid.for", &[tydesc]);
712-
let is_rust_panic = catch.icmp(IntPredicate::IntEQ, selector, rust_typeid);
713-
let is_rust_panic = catch.zext(is_rust_panic, bx.type_bool());
711+
let rust_typeid = bx.call_intrinsic("llvm.eh.typeid.for", &[tydesc]);
712+
let is_rust_panic = bx.icmp(IntPredicate::IntEQ, selector, rust_typeid);
713+
let is_rust_panic = bx.zext(is_rust_panic, bx.type_bool());
714714

715715
// We need to pass two values to catch_func (ptr and is_rust_panic), so
716716
// create an alloca and pass a pointer to that.
717717
let ptr_align = bx.tcx().data_layout.pointer_align.abi;
718718
let i8_align = bx.tcx().data_layout.i8_align.abi;
719719
let catch_data_type = bx.type_struct(&[bx.type_i8p(), bx.type_bool()], false);
720-
let catch_data = catch.alloca(catch_data_type, ptr_align);
721-
let catch_data_0 = catch.inbounds_gep(
722-
catch_data_type,
723-
catch_data,
724-
&[bx.const_usize(0), bx.const_usize(0)],
725-
);
726-
catch.store(ptr, catch_data_0, ptr_align);
727-
let catch_data_1 = catch.inbounds_gep(
728-
catch_data_type,
729-
catch_data,
730-
&[bx.const_usize(0), bx.const_usize(1)],
731-
);
732-
catch.store(is_rust_panic, catch_data_1, i8_align);
733-
let catch_data = catch.bitcast(catch_data, bx.type_i8p());
720+
let catch_data = bx.alloca(catch_data_type, ptr_align);
721+
let catch_data_0 =
722+
bx.inbounds_gep(catch_data_type, catch_data, &[bx.const_usize(0), bx.const_usize(0)]);
723+
bx.store(ptr, catch_data_0, ptr_align);
724+
let catch_data_1 =
725+
bx.inbounds_gep(catch_data_type, catch_data, &[bx.const_usize(0), bx.const_usize(1)]);
726+
bx.store(is_rust_panic, catch_data_1, i8_align);
727+
let catch_data = bx.bitcast(catch_data, bx.type_i8p());
734728

735729
let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void());
736-
catch.call(catch_ty, catch_func, &[data, catch_data], None);
737-
catch.ret(bx.const_i32(1));
730+
bx.call(catch_ty, catch_func, &[data, catch_data], None);
731+
bx.ret(bx.const_i32(1));
738732
});
739733

740734
// Note that no invoke is used here because by definition this function

compiler/rustc_codegen_llvm/src/va_arg.rs

+21-25
Original file line numberDiff line numberDiff line change
@@ -131,51 +131,47 @@ fn emit_aapcs_va_arg<'ll, 'tcx>(
131131
// it could be on the stack so we have to update the offset and then check
132132
// the offset again.
133133

134-
let mut maybe_reg = Builder::build(bx.cx, maybe_reg);
134+
bx.switch_to_block(maybe_reg);
135135
if gr_type && layout.align.abi.bytes() > 8 {
136-
reg_off_v = maybe_reg.add(reg_off_v, bx.const_i32(15));
137-
reg_off_v = maybe_reg.and(reg_off_v, bx.const_i32(-16));
136+
reg_off_v = bx.add(reg_off_v, bx.const_i32(15));
137+
reg_off_v = bx.and(reg_off_v, bx.const_i32(-16));
138138
}
139-
let new_reg_off_v = maybe_reg.add(reg_off_v, bx.const_i32(slot_size as i32));
139+
let new_reg_off_v = bx.add(reg_off_v, bx.const_i32(slot_size as i32));
140140

141-
maybe_reg.store(new_reg_off_v, reg_off, offset_align);
141+
bx.store(new_reg_off_v, reg_off, offset_align);
142142

143143
// Check to see if we have overflowed the registers as a result of this.
144144
// If we have then we need to use the stack for this value
145-
let use_stack = maybe_reg.icmp(IntPredicate::IntSGT, new_reg_off_v, zero);
146-
maybe_reg.cond_br(use_stack, on_stack, in_reg);
145+
let use_stack = bx.icmp(IntPredicate::IntSGT, new_reg_off_v, zero);
146+
bx.cond_br(use_stack, on_stack, in_reg);
147147

148-
let mut in_reg = Builder::build(bx.cx, in_reg);
148+
bx.switch_to_block(in_reg);
149149
let top_type = bx.type_i8p();
150-
let top = in_reg.struct_gep(va_list_ty, va_list_addr, reg_top_index);
151-
let top = in_reg.load(top_type, top, bx.tcx().data_layout.pointer_align.abi);
150+
let top = bx.struct_gep(va_list_ty, va_list_addr, reg_top_index);
151+
let top = bx.load(top_type, top, bx.tcx().data_layout.pointer_align.abi);
152152

153153
// reg_value = *(@top + reg_off_v);
154-
let mut reg_addr = in_reg.gep(bx.type_i8(), top, &[reg_off_v]);
154+
let mut reg_addr = bx.gep(bx.type_i8(), top, &[reg_off_v]);
155155
if bx.tcx().sess.target.endian == Endian::Big && layout.size.bytes() != slot_size {
156156
// On big-endian systems the value is right-aligned in its slot.
157157
let offset = bx.const_i32((slot_size - layout.size.bytes()) as i32);
158-
reg_addr = in_reg.gep(bx.type_i8(), reg_addr, &[offset]);
158+
reg_addr = bx.gep(bx.type_i8(), reg_addr, &[offset]);
159159
}
160160
let reg_type = layout.llvm_type(bx);
161-
let reg_addr = in_reg.bitcast(reg_addr, bx.cx.type_ptr_to(reg_type));
162-
let reg_value = in_reg.load(reg_type, reg_addr, layout.align.abi);
163-
in_reg.br(end);
161+
let reg_addr = bx.bitcast(reg_addr, bx.cx.type_ptr_to(reg_type));
162+
let reg_value = bx.load(reg_type, reg_addr, layout.align.abi);
163+
bx.br(end);
164164

165165
// On Stack block
166-
let mut on_stack = Builder::build(bx.cx, on_stack);
166+
bx.switch_to_block(on_stack);
167167
let stack_value =
168-
emit_ptr_va_arg(&mut on_stack, list, target_ty, false, Align::from_bytes(8).unwrap(), true);
169-
on_stack.br(end);
168+
emit_ptr_va_arg(bx, list, target_ty, false, Align::from_bytes(8).unwrap(), true);
169+
bx.br(end);
170170

171-
let mut end = Builder::build(bx.cx, end);
172-
let val = end.phi(
173-
layout.immediate_llvm_type(bx),
174-
&[reg_value, stack_value],
175-
&[in_reg.llbb(), on_stack.llbb()],
176-
);
171+
bx.switch_to_block(end);
172+
let val =
173+
bx.phi(layout.immediate_llvm_type(bx), &[reg_value, stack_value], &[in_reg, on_stack]);
177174

178-
*bx = end;
179175
val
180176
}
181177

compiler/rustc_codegen_ssa/src/mir/block.rs

+9-10
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,9 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
170170
}
171171

172172
if let Some((ret_dest, target)) = destination {
173-
let target_llbb = fx.llbb(target);
174-
let mut ret_bx = Bx::build(fx.cx, target_llbb);
175-
fx.set_debug_loc(&mut ret_bx, self.terminator.source_info);
176-
fx.store_return(&mut ret_bx, ret_dest, &fn_abi.ret, invokeret);
173+
bx.switch_to_block(fx.llbb(target));
174+
fx.set_debug_loc(bx, self.terminator.source_info);
175+
fx.store_return(bx, ret_dest, &fn_abi.ret, invokeret);
177176
}
178177
} else {
179178
let llret = bx.call(fn_ty, fn_ptr, &llargs, self.funclet(fx));
@@ -462,7 +461,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
462461
}
463462

464463
// After this point, bx is the block for the call to panic.
465-
bx = Bx::build(self.cx, panic_block);
464+
bx.switch_to_block(panic_block);
466465
self.set_debug_loc(&mut bx, terminator.source_info);
467466

468467
// Get the location information.
@@ -914,20 +913,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
914913
let bb_fail = bx.append_sibling_block("type_test.fail");
915914
bx.cond_br(cond, bb_pass, bb_fail);
916915

917-
let mut bx_pass = Bx::build(self.cx, bb_pass);
916+
bx.switch_to_block(bb_pass);
918917
helper.do_call(
919918
self,
920-
&mut bx_pass,
919+
&mut bx,
921920
fn_abi,
922921
fn_ptr,
923922
&llargs,
924923
destination.as_ref().map(|&(_, target)| (ret_dest, target)),
925924
cleanup,
926925
);
927926

928-
let mut bx_fail = Bx::build(self.cx, bb_fail);
929-
bx_fail.abort();
930-
bx_fail.unreachable();
927+
bx.switch_to_block(bb_fail);
928+
bx.abort();
929+
bx.unreachable();
931930

932931
return;
933932
}

compiler/rustc_codegen_ssa/src/traits/builder.rs

+2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ pub trait BuilderMethods<'a, 'tcx>:
5353

5454
fn append_sibling_block(&mut self, name: &str) -> Self::BasicBlock;
5555

56+
fn switch_to_block(&mut self, llbb: Self::BasicBlock);
57+
5658
fn ret_void(&mut self);
5759
fn ret(&mut self, v: Self::Value);
5860
fn br(&mut self, dest: Self::BasicBlock);

0 commit comments

Comments
 (0)