Skip to content

Commit 2b66221

Browse files
Mark drop calls in landing pads cold instead of noinline
Now that deferred inlining has been disabled in LLVM, this shouldn't cause catastrophic size blowup.
1 parent 7ae5508 commit 2b66221

File tree

6 files changed

+42
-9
lines changed

6 files changed

+42
-9
lines changed

Diff for: compiler/rustc_codegen_gcc/src/builder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1404,7 +1404,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
14041404
self.cx
14051405
}
14061406

1407-
fn do_not_inline(&mut self, _llret: RValue<'gcc>) {
1407+
fn mark_callsite_cold(&mut self, _llret: RValue<'gcc>) {
14081408
unimplemented!();
14091409
}
14101410

Diff for: compiler/rustc_codegen_llvm/src/builder.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1201,8 +1201,8 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
12011201
unsafe { llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, UNNAMED) }
12021202
}
12031203

1204-
fn do_not_inline(&mut self, llret: &'ll Value) {
1205-
llvm::Attribute::NoInline.apply_callsite(llvm::AttributePlace::Function, llret);
1204+
fn mark_callsite_cold(&mut self, llret: &'ll Value) {
1205+
llvm::Attribute::Cold.apply_callsite(llvm::AttributePlace::Function, llret);
12061206
}
12071207
}
12081208

Diff for: compiler/rustc_codegen_ssa/src/mir/block.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,8 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
160160
let llret = bx.call(fn_ty, fn_ptr, &llargs, self.funclet(fx));
161161
bx.apply_attrs_callsite(&fn_abi, llret);
162162
if fx.mir[self.bb].is_cleanup {
163-
// Cleanup is always the cold path. Don't inline
164-
// drop glue. Also, when there is a deeply-nested
165-
// struct, there are "symmetry" issues that cause
166-
// exponential inlining - see issue #41696.
167-
bx.do_not_inline(llret);
163+
// Cleanup is always the cold path.
164+
bx.mark_callsite_cold(llret);
168165
}
169166

170167
if let Some((ret_dest, target)) = destination {

Diff for: compiler/rustc_codegen_ssa/src/traits/builder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -311,5 +311,5 @@ pub trait BuilderMethods<'a, 'tcx>:
311311
) -> Self::Value;
312312
fn zext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
313313

314-
fn do_not_inline(&mut self, llret: Self::Value);
314+
fn mark_callsite_cold(&mut self, llret: Self::Value);
315315
}

Diff for: src/test/codegen/unwind-landingpad-cold.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// compile-flags: -Cno-prepopulate-passes
2+
#![crate_type = "lib"]
3+
4+
// This test checks that drop calls in unwind landing pads
5+
// get the `cold` attribute.
6+
7+
// CHECK-LABEL: @check_cold
8+
// CHECK: call void {{.+}}drop_in_place{{.+}} [[ATTRIBUTES:#[0-9]+]]
9+
// CHECK: attributes [[ATTRIBUTES]] = { cold }
10+
#[no_mangle]
11+
pub fn check_cold(f: fn(), x: Box<u32>) {
12+
// this may unwind
13+
f();
14+
}

Diff for: src/test/codegen/unwind-landingpad-inline.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// no-system-llvm: needs patch for Rust alloc/dealloc functions
2+
// compile-flags: -Copt-level=3
3+
#![crate_type = "lib"]
4+
5+
// This test checks that we can inline drop_in_place in
6+
// unwind landing pads. Without this, the box pointers escape,
7+
// and LLVM will not optimize out the pointer comparison.
8+
// See https://github.com/rust-lang/rust/issues/46515
9+
10+
// Everything should be optimized out.
11+
// CHECK-LABEL: @check_no_escape_in_landingpad
12+
// CHECK: start:
13+
// CHECK-NEXT: ret void
14+
#[no_mangle]
15+
pub fn check_no_escape_in_landingpad(f: fn()) {
16+
let x = &*Box::new(0);
17+
let y = &*Box::new(0);
18+
19+
if x as *const _ == y as *const _ {
20+
f();
21+
}
22+
}

0 commit comments

Comments
 (0)