Skip to content

Commit 8593023

Browse files
committed
Don't instantiate so many copies of drop_in_place
1 parent a1912f2 commit 8593023

File tree

2 files changed

+31
-7
lines changed

2 files changed

+31
-7
lines changed

src/librustc/ty/instance.rs

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

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

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

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(),

0 commit comments

Comments
 (0)