Skip to content

Commit 1f40573

Browse files
Skip collecting no-op DropGlue in vtables
Since 122662 this no longer gets used in vtables, so we're safe to fully drop generating these empty functions. Those are eventually cleaned up by LLVM, but it's wasteful to produce them in the first place. This also adds a missing test for fn-ptr casts, which do still need to generate no-op drop glue. It's possible a future optimization could point all of those at the same drop glue (e.g., for *mut ()) rather than for each separate type, but that would require extra work for CFI and isn't particularly easy to do anyway.
1 parent d4e1159 commit 1f40573

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

compiler/rustc_monomorphize/src/collector.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,9 @@ fn visit_instance_use<'tcx>(
949949
}
950950
ty::InstanceKind::DropGlue(_, None) => {
951951
// Don't need to emit noop drop glue if we are calling directly.
952+
//
953+
// Note that we also optimize away the call to visit_instance_use in vtable construction
954+
// (see create_mono_items_for_vtable_methods).
952955
if !is_direct_call {
953956
output.push(create_fn_mono_item(tcx, instance, source));
954957
}
@@ -1177,8 +1180,13 @@ fn create_mono_items_for_vtable_methods<'tcx>(
11771180
output.extend(methods);
11781181
}
11791182

1180-
// Also add the destructor.
1181-
visit_drop_use(tcx, impl_ty, false, source, output);
1183+
// Also add the destructor, if it's necessary.
1184+
//
1185+
// This matches the check in vtable_allocation_provider in middle/ty/vtable.rs,
1186+
// if we don't need drop we're not adding an actual pointer to the vtable.
1187+
if impl_ty.needs_drop(tcx, ty::TypingEnv::fully_monomorphized()) {
1188+
visit_drop_use(tcx, impl_ty, false, source, output);
1189+
}
11821190
}
11831191

11841192
/// Scans the CTFE alloc in order to find function pointers and statics that must be monomorphized.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//@ compile-flags:-Clink-dead-code -Zmir-opt-level=0
2+
3+
#![deny(dead_code)]
4+
#![crate_type = "lib"]
5+
6+
//~ MONO_ITEM fn start
7+
#[no_mangle]
8+
pub fn start(_: isize, _: *const *const u8) -> isize {
9+
// No item produced for this, it's a no-op drop and so is removed.
10+
unsafe {
11+
std::ptr::drop_in_place::<u32>(&mut 0);
12+
}
13+
14+
// No choice but to codegen for indirect drop as a function pointer, since we have to produce a
15+
// function with the right signature. In vtables we can avoid that (tested in
16+
// instantiation-through-vtable.rs) because we special case null pointer for drop glue since
17+
// #122662.
18+
//
19+
//~ MONO_ITEM fn std::ptr::drop_in_place::<u64> - shim(None) @@ drop_glue_noop-cgu.0[External]
20+
std::ptr::drop_in_place::<u64> as unsafe fn(*mut u64);
21+
22+
0
23+
}

0 commit comments

Comments
 (0)