Skip to content

Commit 293615e

Browse files
committed
Auto merge of #67332 - matthewjasper:drop-in-place-cgus, r=<try>
[PERF] Don't instantiate so many copies of real_drop_in_place Split out from #66703. r? @ghost
2 parents f0d4b57 + e95280d commit 293615e

File tree

4 files changed

+42
-15
lines changed

4 files changed

+42
-15
lines changed

src/librustc/ty/instance.rs

+24-4
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@ pub enum InstanceDef<'tcx> {
5252
/// `<[mut closure] as FnOnce>::call_once`
5353
ClosureOnceShim { call_once: DefId },
5454

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

5861
///`<T as Clone>::clone` shim.
@@ -108,11 +111,28 @@ impl<'tcx> InstanceDef<'tcx> {
108111
if self.is_inline(tcx) {
109112
return true
110113
}
111-
if let ty::InstanceDef::DropGlue(..) = *self {
112-
// Drop glue wants to be instantiated at every codegen
114+
if let ty::InstanceDef::DropGlue(.., Some(ty)) = *self {
115+
// Drop glue generally wants to be instantiated at every codegen
113116
// unit, but without an #[inline] hint. We should make this
114117
// available to normal end-users.
115-
return true
118+
if tcx.sess.opts.incremental.is_none() {
119+
return true;
120+
}
121+
// When compiling with incremental, we can generate a *lot* of
122+
// codegen units. Including drop glue into all of them has a
123+
// considerable compile time cost.
124+
//
125+
// We include enums without destructors to allow, say, optimizing
126+
// drops of `Option::None` before LTO. We also respect the intent of
127+
// `#[inline]` on `Drop::drop` implementations.
128+
return ty.ty_adt_def()
129+
.map_or(true, |adt_def| {
130+
adt_def.destructor(tcx)
131+
.map_or(
132+
adt_def.is_enum(),
133+
|dtor| tcx.codegen_fn_attrs(dtor.did).requests_inline(),
134+
)
135+
})
116136
}
117137
tcx.codegen_fn_attrs(self.def_id()).requests_inline()
118138
}

src/librustc_mir/monomorphize/partitioning.rs

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

691691
if tcx.trait_of_item(def_id).is_some() {
692692
let self_ty = instance.substs.type_at(0);
693-
// This is an implementation of a trait method.
693+
// This is a default implementation of a trait method.
694694
return characteristic_def_id_of_type(self_ty).or(Some(def_id));
695695
}
696696

697697
if let Some(impl_def_id) = tcx.impl_of_method(def_id) {
698-
// This is a method within an inherent impl, find out what the
699-
// self-type is:
698+
if tcx.sess.opts.incremental.is_some()
699+
&& tcx.trait_id_of_impl(impl_def_id) == tcx.lang_items().drop_trait()
700+
{
701+
// Put `Drop::drop` into the same cgu as `real_drop_in_place`
702+
// since `real_drop_in_place` is the only thing that can
703+
// call it.
704+
return None;
705+
}
706+
// This is a method within an impl, find out what the self-type is:
700707
let impl_self_ty = tcx.subst_and_normalize_erasing_regions(
701708
instance.substs,
702709
ty::ParamEnv::reveal_all(),

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
1111
// aux-build:cgu_extern_drop_glue.rs
1212
extern crate cgu_extern_drop_glue;
1313

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

1616
struct LocalStruct(cgu_extern_drop_glue::Struct);
1717

1818
//~ MONO_ITEM fn extern_drop_glue::user[0] @@ extern_drop_glue[External]
1919
pub fn user()
2020
{
21-
//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<extern_drop_glue::LocalStruct[0]> @@ extern_drop_glue[Internal]
21+
//~ MONO_ITEM fn core::ptr[0]::real_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

@@ -30,7 +30,7 @@ pub mod mod1 {
3030
//~ MONO_ITEM fn extern_drop_glue::mod1[0]::user[0] @@ extern_drop_glue-mod1[External]
3131
pub fn user()
3232
{
33-
//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<extern_drop_glue::mod1[0]::LocalStruct[0]> @@ extern_drop_glue-mod1[Internal]
33+
//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<extern_drop_glue::mod1[0]::LocalStruct[0]> @@ extern_drop_glue-fallback.cgu[External]
3434
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
3535
}
3636
}

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

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,17 @@
77
#![allow(dead_code)]
88
#![crate_type="rlib"]
99

10-
//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<local_drop_glue::Struct[0]> @@ local_drop_glue[Internal] local_drop_glue-mod1[Internal]
10+
//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<local_drop_glue::Struct[0]> @@ local_drop_glue-fallback.cgu[Internal]
1111
struct Struct {
1212
_a: u32
1313
}
1414

1515
impl Drop for Struct {
16-
//~ MONO_ITEM fn local_drop_glue::{{impl}}[0]::drop[0] @@ local_drop_glue[External]
16+
//~ MONO_ITEM fn local_drop_glue::{{impl}}[0]::drop[0] @@ local_drop_glue-fallback.cgu[External]
1717
fn drop(&mut self) {}
1818
}
1919

20-
//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<local_drop_glue::Outer[0]> @@ local_drop_glue[Internal]
20+
//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<local_drop_glue::Outer[0]> @@ local_drop_glue-fallback.cgu[External]
2121
struct Outer {
2222
_a: Struct
2323
}
@@ -36,10 +36,10 @@ pub mod mod1
3636
{
3737
use super::Struct;
3838

39-
//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<local_drop_glue::mod1[0]::Struct2[0]> @@ local_drop_glue-mod1[Internal]
39+
//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<local_drop_glue::mod1[0]::Struct2[0]> @@ local_drop_glue-fallback.cgu[External]
4040
struct Struct2 {
4141
_a: Struct,
42-
//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-mod1[Internal]
42+
//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-fallback.cgu[Internal]
4343
_b: (u32, Struct),
4444
}
4545

0 commit comments

Comments
 (0)