Skip to content

Commit d28560e

Browse files
committed
Auto merge of #67332 - matthewjasper:drop-in-place-cgus, r=michaelwoerister
Don't instantiate so many copies of drop_in_place Split out from #66703. r? @ghost
2 parents 0c15adc + b944531 commit d28560e

File tree

4 files changed

+54
-40
lines changed

4 files changed

+54
-40
lines changed

src/librustc/ty/instance.rs

+21-4
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ pub enum InstanceDef<'tcx> {
5353
call_once: DefId,
5454
},
5555

56-
/// `drop_in_place::<T>; None` for empty drop glue.
56+
/// `core::ptr::drop_in_place::<T>`.
57+
/// The `DefId` is for `core::ptr::drop_in_place`.
58+
/// The `Option<Ty<'tcx>>` is either `Some(T)`, or `None` for empty drop
59+
/// glue.
5760
DropGlue(DefId, Option<Ty<'tcx>>),
5861

5962
///`<T as Clone>::clone` shim.
@@ -176,11 +179,25 @@ impl<'tcx> InstanceDef<'tcx> {
176179
if self.requires_inline(tcx) {
177180
return true;
178181
}
179-
if let ty::InstanceDef::DropGlue(..) = *self {
180-
// Drop glue wants to be instantiated at every codegen
182+
if let ty::InstanceDef::DropGlue(.., Some(ty)) = *self {
183+
// Drop glue generally wants to be instantiated at every codegen
181184
// unit, but without an #[inline] hint. We should make this
182185
// available to normal end-users.
183-
return true;
186+
if tcx.sess.opts.incremental.is_none() {
187+
return true;
188+
}
189+
// When compiling with incremental, we can generate a *lot* of
190+
// codegen units. Including drop glue into all of them has a
191+
// considerable compile time cost.
192+
//
193+
// We include enums without destructors to allow, say, optimizing
194+
// drops of `Option::None` before LTO. We also respect the intent of
195+
// `#[inline]` on `Drop::drop` implementations.
196+
return ty.ty_adt_def().map_or(true, |adt_def| {
197+
adt_def.destructor(tcx).map_or(adt_def.is_enum(), |dtor| {
198+
tcx.codegen_fn_attrs(dtor.did).requests_inline()
199+
})
200+
});
184201
}
185202
tcx.codegen_fn_attrs(self.def_id()).requests_inline()
186203
}

src/librustc_mir/monomorphize/partitioning.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -680,13 +680,20 @@ fn characteristic_def_id_of_mono_item<'tcx>(
680680

681681
if tcx.trait_of_item(def_id).is_some() {
682682
let self_ty = instance.substs.type_at(0);
683-
// This is an implementation of a trait method.
683+
// This is a default implementation of a trait method.
684684
return characteristic_def_id_of_type(self_ty).or(Some(def_id));
685685
}
686686

687687
if let Some(impl_def_id) = tcx.impl_of_method(def_id) {
688-
// This is a method within an inherent impl, find out what the
689-
// self-type is:
688+
if tcx.sess.opts.incremental.is_some()
689+
&& tcx.trait_id_of_impl(impl_def_id) == tcx.lang_items().drop_trait()
690+
{
691+
// Put `Drop::drop` into the same cgu as `drop_in_place`
692+
// since `drop_in_place` is the only thing that can
693+
// call it.
694+
return None;
695+
}
696+
// This is a method within an impl, find out what the self-type is:
690697
let impl_self_ty = tcx.subst_and_normalize_erasing_regions(
691698
instance.substs,
692699
ty::ParamEnv::reveal_all(),

src/test/codegen-units/partitioning/extern-drop-glue.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,23 @@
22

33
// We specify -Z incremental here because we want to test the partitioning for
44
// incremental compilation
5+
// We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing
56
// compile-flags:-Zprint-mono-items=lazy -Zincremental=tmp/partitioning-tests/extern-drop-glue
6-
// compile-flags:-Zinline-in-all-cgus
7+
// compile-flags:-Zinline-in-all-cgus -Copt-level=0
78

89
#![allow(dead_code)]
9-
#![crate_type="rlib"]
10+
#![crate_type = "rlib"]
1011

1112
// aux-build:cgu_extern_drop_glue.rs
1213
extern crate cgu_extern_drop_glue;
1314

14-
//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<cgu_extern_drop_glue::Struct[0]> @@ extern_drop_glue[Internal] extern_drop_glue-mod1[Internal]
15+
//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<cgu_extern_drop_glue::Struct[0]> @@ extern_drop_glue-fallback.cgu[External]
1516

1617
struct LocalStruct(cgu_extern_drop_glue::Struct);
1718

1819
//~ MONO_ITEM fn extern_drop_glue::user[0] @@ extern_drop_glue[External]
19-
pub fn user()
20-
{
21-
//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::LocalStruct[0]> @@ extern_drop_glue[Internal]
20+
pub fn user() {
21+
//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::LocalStruct[0]> @@ extern_drop_glue-fallback.cgu[External]
2222
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
2323
}
2424

@@ -28,9 +28,8 @@ pub mod mod1 {
2828
struct LocalStruct(cgu_extern_drop_glue::Struct);
2929

3030
//~ MONO_ITEM fn extern_drop_glue::mod1[0]::user[0] @@ extern_drop_glue-mod1[External]
31-
pub fn user()
32-
{
33-
//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::mod1[0]::LocalStruct[0]> @@ extern_drop_glue-mod1[Internal]
31+
pub fn user() {
32+
//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::mod1[0]::LocalStruct[0]> @@ extern_drop_glue-fallback.cgu[External]
3433
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
3534
}
3635
}
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,45 @@
11
// ignore-tidy-linelength
22
// We specify -Z incremental here because we want to test the partitioning for
33
// incremental compilation
4+
// We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing
45
// compile-flags:-Zprint-mono-items=lazy -Zincremental=tmp/partitioning-tests/local-drop-glue
5-
// compile-flags:-Zinline-in-all-cgus
6+
// compile-flags:-Zinline-in-all-cgus -Copt-level=0
67

78
#![allow(dead_code)]
8-
#![crate_type="rlib"]
9+
#![crate_type = "rlib"]
910

10-
//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::Struct[0]> @@ local_drop_glue[Internal] local_drop_glue-mod1[Internal]
11+
//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::Struct[0]> @@ local_drop_glue-fallback.cgu[External]
1112
struct Struct {
12-
_a: u32
13+
_a: u32,
1314
}
1415

1516
impl Drop for Struct {
16-
//~ MONO_ITEM fn local_drop_glue::{{impl}}[0]::drop[0] @@ local_drop_glue[External]
17+
//~ MONO_ITEM fn local_drop_glue::{{impl}}[0]::drop[0] @@ local_drop_glue-fallback.cgu[External]
1718
fn drop(&mut self) {}
1819
}
1920

20-
//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::Outer[0]> @@ local_drop_glue[Internal]
21+
//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::Outer[0]> @@ local_drop_glue-fallback.cgu[External]
2122
struct Outer {
22-
_a: Struct
23+
_a: Struct,
2324
}
2425

2526
//~ MONO_ITEM fn local_drop_glue::user[0] @@ local_drop_glue[External]
26-
pub fn user()
27-
{
28-
let _ = Outer {
29-
_a: Struct {
30-
_a: 0
31-
}
32-
};
27+
pub fn user() {
28+
let _ = Outer { _a: Struct { _a: 0 } };
3329
}
3430

35-
pub mod mod1
36-
{
31+
pub mod mod1 {
3732
use super::Struct;
3833

39-
//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::mod1[0]::Struct2[0]> @@ local_drop_glue-mod1[Internal]
34+
//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::mod1[0]::Struct2[0]> @@ local_drop_glue-fallback.cgu[External]
4035
struct Struct2 {
4136
_a: Struct,
42-
//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-mod1[Internal]
37+
//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-fallback.cgu[Internal]
4338
_b: (u32, Struct),
4439
}
4540

4641
//~ MONO_ITEM fn local_drop_glue::mod1[0]::user[0] @@ local_drop_glue-mod1[External]
47-
pub fn user()
48-
{
49-
let _ = Struct2 {
50-
_a: Struct { _a: 0 },
51-
_b: (0, Struct { _a: 0 }),
52-
};
42+
pub fn user() {
43+
let _ = Struct2 { _a: Struct { _a: 0 }, _b: (0, Struct { _a: 0 }) };
5344
}
5445
}

0 commit comments

Comments
 (0)