diff options
| author | bors <bors@rust-lang.org> | 2020-02-27 04:51:34 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-02-27 04:51:34 +0000 |
| commit | d28560e660168b30af3b58167094aeb299bc2b58 (patch) | |
| tree | 1069e81fa52193fb5b0499c0d07d3f6864ff387a /src | |
| parent | 0c15adc5308b92919580e98f2fd77cdd448f24a0 (diff) | |
| parent | b9445311462549fdc22e5ca0732be60c1b2a5d32 (diff) | |
| download | rust-d28560e660168b30af3b58167094aeb299bc2b58.tar.gz rust-d28560e660168b30af3b58167094aeb299bc2b58.zip | |
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
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/ty/instance.rs | 25 | ||||
| -rw-r--r-- | src/librustc_mir/monomorphize/partitioning.rs | 13 | ||||
| -rw-r--r-- | src/test/codegen-units/partitioning/extern-drop-glue.rs | 17 | ||||
| -rw-r--r-- | src/test/codegen-units/partitioning/local-drop-glue.rs | 39 |
4 files changed, 54 insertions, 40 deletions
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 0ec30bc583c..66888cdb552 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -53,7 +53,10 @@ pub enum InstanceDef<'tcx> { call_once: DefId, }, - /// `drop_in_place::<T>; None` for empty drop glue. + /// `core::ptr::drop_in_place::<T>`. + /// The `DefId` is for `core::ptr::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. @@ -176,11 +179,25 @@ impl<'tcx> InstanceDef<'tcx> { if self.requires_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() } diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index de45808a481..9b81d69ce69 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -680,13 +680,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 `drop_in_place` + // since `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(), diff --git a/src/test/codegen-units/partitioning/extern-drop-glue.rs b/src/test/codegen-units/partitioning/extern-drop-glue.rs index f85ae0c0774..662519067d7 100644 --- a/src/test/codegen-units/partitioning/extern-drop-glue.rs +++ b/src/test/codegen-units/partitioning/extern-drop-glue.rs @@ -2,23 +2,23 @@ // We specify -Z incremental here because we want to test the partitioning for // incremental compilation +// We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing // compile-flags:-Zprint-mono-items=lazy -Zincremental=tmp/partitioning-tests/extern-drop-glue -// compile-flags:-Zinline-in-all-cgus +// compile-flags:-Zinline-in-all-cgus -Copt-level=0 #![allow(dead_code)] -#![crate_type="rlib"] +#![crate_type = "rlib"] // aux-build:cgu_extern_drop_glue.rs extern crate cgu_extern_drop_glue; -//~ 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] +//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<cgu_extern_drop_glue::Struct[0]> @@ extern_drop_glue-fallback.cgu[External] 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]::drop_in_place[0]<extern_drop_glue::LocalStruct[0]> @@ extern_drop_glue[Internal] +pub fn user() { + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::LocalStruct[0]> @@ extern_drop_glue-fallback.cgu[External] let _ = LocalStruct(cgu_extern_drop_glue::Struct(0)); } @@ -28,9 +28,8 @@ pub mod mod1 { struct LocalStruct(cgu_extern_drop_glue::Struct); //~ MONO_ITEM fn extern_drop_glue::mod1[0]::user[0] @@ extern_drop_glue-mod1[External] - pub fn user() - { - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::mod1[0]::LocalStruct[0]> @@ extern_drop_glue-mod1[Internal] + pub fn user() { + //~ MONO_ITEM fn core::ptr[0]::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)); } } diff --git a/src/test/codegen-units/partitioning/local-drop-glue.rs b/src/test/codegen-units/partitioning/local-drop-glue.rs index 366af4d4c38..14a50bf5798 100644 --- a/src/test/codegen-units/partitioning/local-drop-glue.rs +++ b/src/test/codegen-units/partitioning/local-drop-glue.rs @@ -1,54 +1,45 @@ // ignore-tidy-linelength // We specify -Z incremental here because we want to test the partitioning for // incremental compilation +// We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing // compile-flags:-Zprint-mono-items=lazy -Zincremental=tmp/partitioning-tests/local-drop-glue -// compile-flags:-Zinline-in-all-cgus +// compile-flags:-Zinline-in-all-cgus -Copt-level=0 #![allow(dead_code)] -#![crate_type="rlib"] +#![crate_type = "rlib"] -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::Struct[0]> @@ local_drop_glue[Internal] local_drop_glue-mod1[Internal] +//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::Struct[0]> @@ local_drop_glue-fallback.cgu[External] struct Struct { - _a: u32 + _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]::drop_in_place[0]<local_drop_glue::Outer[0]> @@ local_drop_glue[Internal] +//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::Outer[0]> @@ local_drop_glue-fallback.cgu[External] struct Outer { - _a: Struct + _a: Struct, } //~ MONO_ITEM fn local_drop_glue::user[0] @@ local_drop_glue[External] -pub fn user() -{ - let _ = Outer { - _a: Struct { - _a: 0 - } - }; +pub fn user() { + let _ = Outer { _a: Struct { _a: 0 } }; } -pub mod mod1 -{ +pub mod mod1 { use super::Struct; - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::mod1[0]::Struct2[0]> @@ local_drop_glue-mod1[Internal] + //~ MONO_ITEM fn core::ptr[0]::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]::drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-mod1[Internal] + //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-fallback.cgu[Internal] _b: (u32, Struct), } //~ MONO_ITEM fn local_drop_glue::mod1[0]::user[0] @@ local_drop_glue-mod1[External] - pub fn user() - { - let _ = Struct2 { - _a: Struct { _a: 0 }, - _b: (0, Struct { _a: 0 }), - }; + pub fn user() { + let _ = Struct2 { _a: Struct { _a: 0 }, _b: (0, Struct { _a: 0 }) }; } } |
