Skip to content

Commit

Permalink
Auto merge of #67332 - matthewjasper:drop-in-place-cgus, r=<try>
Browse files Browse the repository at this point in the history
[PERF] Don't instantiate so many copies of real_drop_in_place

Split out from #66703.

r? @ghost
  • Loading branch information
bors committed Dec 21, 2019
2 parents c64eecf + b231749 commit 877fa2e
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 17 deletions.
28 changes: 24 additions & 4 deletions src/librustc/ty/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ pub enum InstanceDef<'tcx> {
/// `<[mut closure] as FnOnce>::call_once`
ClosureOnceShim { call_once: DefId },

/// `drop_in_place::<T>; None` for empty drop glue.
/// `real_drop_in_place::<T>`.
/// The `DefId` is for `real_drop_in_place`.
/// The `Option<Ty<'tcx>>` is either `Some(T)`, or `None` for empty drop
/// glue.
DropGlue(DefId, Option<Ty<'tcx>>),

///`<T as Clone>::clone` shim.
Expand Down Expand Up @@ -108,11 +111,28 @@ impl<'tcx> InstanceDef<'tcx> {
if self.is_inline(tcx) {
return true
}
if let ty::InstanceDef::DropGlue(..) = *self {
// Drop glue wants to be instantiated at every codegen
if let ty::InstanceDef::DropGlue(.., Some(ty)) = *self {
// Drop glue generally wants to be instantiated at every codegen
// unit, but without an #[inline] hint. We should make this
// available to normal end-users.
return true
if tcx.sess.opts.incremental.is_none() {
return true;
}
// When compiling with incremental, we can generate a *lot* of
// codegen units. Including drop glue into all of them has a
// considerable compile time cost.
//
// We include enums without destructors to allow, say, optimizing
// drops of `Option::None` before LTO. We also respect the intent of
// `#[inline]` on `Drop::drop` implementations.
return ty.ty_adt_def()
.map_or(true, |adt_def| {
adt_def.destructor(tcx)
.map_or(
adt_def.is_enum(),
|dtor| tcx.codegen_fn_attrs(dtor.did).requests_inline(),
)
})
}
tcx.codegen_fn_attrs(self.def_id()).requests_inline()
}
Expand Down
22 changes: 20 additions & 2 deletions src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1122,8 +1122,26 @@ fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>

// Can refer to a type which may drop.
// FIXME(eddyb) check this against a ParamEnv.
ty::Dynamic(..) | ty::Projection(..) | ty::Param(_) | ty::Bound(..) |
ty::Placeholder(..) | ty::Opaque(..) | ty::Infer(_) | ty::Error => true,
ty::Dynamic(..) |
ty::Param(_) |
ty::Bound(..) |
ty::Placeholder(..) |
ty::Opaque(..) |
ty::Infer(_) |
ty::Error => true,

ty::Projection(..) => {
if let traits::Reveal::All = param_env.reveal {
let normalized = tcx.normalize_erasing_regions(param_env, ty);
if let ty::Projection(..) = normalized.kind {
true
} else {
needs_drop(normalized)
}
} else {
true
}
}

ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),

Expand Down
13 changes: 10 additions & 3 deletions src/librustc_mir/monomorphize/partitioning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -690,13 +690,20 @@ fn characteristic_def_id_of_mono_item<'tcx>(

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

if let Some(impl_def_id) = tcx.impl_of_method(def_id) {
// This is a method within an inherent impl, find out what the
// self-type is:
if tcx.sess.opts.incremental.is_some()
&& tcx.trait_id_of_impl(impl_def_id) == tcx.lang_items().drop_trait()
{
// Put `Drop::drop` into the same cgu as `real_drop_in_place`
// since `real_drop_in_place` is the only thing that can
// call it.
return None;
}
// This is a method within an impl, find out what the self-type is:
let impl_self_ty = tcx.subst_and_normalize_erasing_regions(
instance.substs,
ty::ParamEnv::reveal_all(),
Expand Down
6 changes: 3 additions & 3 deletions src/test/codegen-units/partitioning/extern-drop-glue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
// aux-build:cgu_extern_drop_glue.rs
extern crate cgu_extern_drop_glue;

//~ 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]
//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<cgu_extern_drop_glue::Struct[0]> @@ extern_drop_glue-fallback.cgu[Internal]

struct LocalStruct(cgu_extern_drop_glue::Struct);

//~ MONO_ITEM fn extern_drop_glue::user[0] @@ extern_drop_glue[External]
pub fn user()
{
//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<extern_drop_glue::LocalStruct[0]> @@ extern_drop_glue[Internal]
//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<extern_drop_glue::LocalStruct[0]> @@ extern_drop_glue-fallback.cgu[External]
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
}

Expand All @@ -30,7 +30,7 @@ pub mod mod1 {
//~ MONO_ITEM fn extern_drop_glue::mod1[0]::user[0] @@ extern_drop_glue-mod1[External]
pub fn user()
{
//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<extern_drop_glue::mod1[0]::LocalStruct[0]> @@ extern_drop_glue-mod1[Internal]
//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<extern_drop_glue::mod1[0]::LocalStruct[0]> @@ extern_drop_glue-fallback.cgu[External]
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
}
}
10 changes: 5 additions & 5 deletions src/test/codegen-units/partitioning/local-drop-glue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@
#![allow(dead_code)]
#![crate_type="rlib"]

//~ 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]
//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<local_drop_glue::Struct[0]> @@ local_drop_glue-fallback.cgu[Internal]
struct Struct {
_a: u32
}

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

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

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

Expand Down

0 comments on commit 877fa2e

Please sign in to comment.