Skip to content

Use struct types during codegen in less places #105252

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions compiler/rustc_codegen_gcc/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1119,18 +1119,18 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
// TODO(antoyo)
}

fn cleanup_landing_pad(&mut self, _ty: Type<'gcc>, _pers_fn: RValue<'gcc>) -> RValue<'gcc> {
let field1 = self.context.new_field(None, self.u8_type.make_pointer(), "landing_pad_field_1");
let field2 = self.context.new_field(None, self.i32_type, "landing_pad_field_1");
let struct_type = self.context.new_struct_type(None, "landing_pad", &[field1, field2]);
self.current_func().new_local(None, struct_type.as_type(), "landing_pad")
.to_rvalue()
fn cleanup_landing_pad(&mut self, _pers_fn: RValue<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) {
(
self.current_func().new_local(None, self.u8_type.make_pointer(), "landing_pad0")
.to_rvalue(),
self.current_func().new_local(None, self.i32_type, "landing_pad1").to_rvalue(),
)
// TODO(antoyo): Properly implement unwinding.
// the above is just to make the compilation work as it seems
// rustc_codegen_ssa now calls the unwinding builder methods even on panic=abort.
}

fn resume(&mut self, _exn: RValue<'gcc>) {
fn resume(&mut self, _exn0: RValue<'gcc>, _exn1: RValue<'gcc>) {
// TODO(bjorn3): Properly implement unwinding.
self.unreachable();
}
Expand Down
11 changes: 8 additions & 3 deletions compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -961,15 +961,20 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
}
}

fn cleanup_landing_pad(&mut self, ty: &'ll Type, pers_fn: &'ll Value) -> &'ll Value {
fn cleanup_landing_pad(&mut self, pers_fn: &'ll Value) -> (&'ll Value, &'ll Value) {
let ty = self.type_struct(&[self.type_i8p(), self.type_i32()], false);
let landing_pad = self.landing_pad(ty, pers_fn, 1 /* FIXME should this be 0? */);
unsafe {
llvm::LLVMSetCleanup(landing_pad, llvm::True);
}
landing_pad
(self.extract_value(landing_pad, 0), self.extract_value(landing_pad, 1))
}

fn resume(&mut self, exn: &'ll Value) {
fn resume(&mut self, exn0: &'ll Value, exn1: &'ll Value) {
let ty = self.type_struct(&[self.type_i8p(), self.type_i32()], false);
let mut exn = self.const_undef(ty);
exn = self.insert_value(exn, exn0, 0);
exn = self.insert_value(exn, exn1, 1);
unsafe {
llvm::LLVMBuildResume(self.llbuilder, exn);
}
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,9 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
typeid: &'ll Value,
) -> Self::Value {
let vtable_byte_offset = self.const_i32(vtable_byte_offset as i32);
self.call_intrinsic("llvm.type.checked.load", &[llvtable, vtable_byte_offset, typeid])
let type_checked_load =
self.call_intrinsic("llvm.type.checked.load", &[llvtable, vtable_byte_offset, typeid]);
self.extract_value(type_checked_load, 0)
}

fn va_start(&mut self, va_list: &'ll Value) -> &'ll Value {
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_codegen_ssa/src/meth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ impl<'a, 'tcx> VirtualIndex {
let typeid =
bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), expect_dyn_trait_in_self(ty)));
let vtable_byte_offset = self.0 * bx.data_layout().pointer_size.bytes();
let type_checked_load = bx.type_checked_load(llvtable, vtable_byte_offset, typeid);
let func = bx.extract_value(type_checked_load, 0);
let func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid);
bx.pointercast(func, llty)
} else {
let ptr_align = bx.tcx().data_layout.pointer_align.abi;
Expand Down
27 changes: 8 additions & 19 deletions compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,16 +289,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx.cleanup_ret(funclet, None);
} else {
let slot = self.get_personality_slot(bx);
let lp0 = slot.project_field(bx, 0);
let lp0 = bx.load_operand(lp0).immediate();
let lp1 = slot.project_field(bx, 1);
let lp1 = bx.load_operand(lp1).immediate();
let exn0 = slot.project_field(bx, 0);
let exn0 = bx.load_operand(exn0).immediate();
let exn1 = slot.project_field(bx, 1);
let exn1 = bx.load_operand(exn1).immediate();
slot.storage_dead(bx);

let mut lp = bx.const_undef(self.landing_pad_type());
lp = bx.insert_value(lp, lp0, 0);
lp = bx.insert_value(lp, lp1, 1);
bx.resume(lp);
bx.resume(exn0, exn1);
}
}

Expand Down Expand Up @@ -1635,24 +1632,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let mut cleanup_bx = Bx::build(self.cx, cleanup_llbb);

let llpersonality = self.cx.eh_personality();
let llretty = self.landing_pad_type();
let lp = cleanup_bx.cleanup_landing_pad(llretty, llpersonality);
let (exn0, exn1) = cleanup_bx.cleanup_landing_pad(llpersonality);

let slot = self.get_personality_slot(&mut cleanup_bx);
slot.storage_live(&mut cleanup_bx);
Pair(cleanup_bx.extract_value(lp, 0), cleanup_bx.extract_value(lp, 1))
.store(&mut cleanup_bx, slot);
Pair(exn0, exn1).store(&mut cleanup_bx, slot);

cleanup_bx.br(llbb);
cleanup_llbb
}
}

fn landing_pad_type(&self) -> Bx::Type {
let cx = self.cx;
cx.type_struct(&[cx.type_i8p(), cx.type_i32()], false)
}

fn unreachable_block(&mut self) -> Bx::BasicBlock {
self.unreachable_block.unwrap_or_else(|| {
let llbb = Bx::append_block(self.cx, self.llfn, "unreachable");
Expand All @@ -1672,8 +1662,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.set_debug_loc(&mut bx, mir::SourceInfo::outermost(self.mir.span));

let llpersonality = self.cx.eh_personality();
let llretty = self.landing_pad_type();
bx.cleanup_landing_pad(llretty, llpersonality);
bx.cleanup_landing_pad(llpersonality);

let (fn_abi, fn_ptr) = common::build_langcall(&bx, None, LangItem::PanicNoUnwind);
let fn_ty = bx.fn_decl_backend_type(&fn_abi);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
assert!(bx.cx().tcx().is_static(def_id));
let static_ = bx.get_static(def_id);
let layout = bx.layout_of(bx.cx().tcx().static_ptr_ty(def_id));
OperandRef::from_immediate_or_packed_pair(bx, static_, layout)
OperandRef { val: OperandValue::Immediate(static_), layout }
}
mir::Rvalue::Use(ref operand) => self.codegen_operand(bx, operand),
mir::Rvalue::Repeat(..) | mir::Rvalue::Aggregate(..) => {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_ssa/src/traits/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,8 @@ pub trait BuilderMethods<'a, 'tcx>:
fn set_personality_fn(&mut self, personality: Self::Value);

// These are used by everyone except msvc
fn cleanup_landing_pad(&mut self, ty: Self::Type, pers_fn: Self::Value) -> Self::Value;
fn resume(&mut self, exn: Self::Value);
fn cleanup_landing_pad(&mut self, pers_fn: Self::Value) -> (Self::Value, Self::Value);
fn resume(&mut self, exn0: Self::Value, exn1: Self::Value);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a more descriptive name we could give for these fields? Ultimately these values are produced by the personality function and have specific meaning, don’t they?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They have a specific meaning (the exception object as first value and 0 as second value). But as far as the codegen backend is concerned they are just opaque values to pass back to resume. I'm not sure why the second value even exists at all. It could have been an LLVM limitation or because we used to reuse GCC's C++ personality function which uses both.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, so we could call it something like exception_obj and dummy, but doesn’t matter much either way.


// These are used only by msvc
fn cleanup_pad(&mut self, parent: Option<Self::Value>, args: &[Self::Value]) -> Self::Funclet;
Expand Down