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
This commit is contained in:
commit
d28560e660
4 changed files with 54 additions and 40 deletions
|
@ -53,7 +53,10 @@ pub enum InstanceDef<'tcx> {
|
||||||
call_once: DefId,
|
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>>),
|
DropGlue(DefId, Option<Ty<'tcx>>),
|
||||||
|
|
||||||
///`<T as Clone>::clone` shim.
|
///`<T as Clone>::clone` shim.
|
||||||
|
@ -176,11 +179,25 @@ impl<'tcx> InstanceDef<'tcx> {
|
||||||
if self.requires_inline(tcx) {
|
if self.requires_inline(tcx) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if let ty::InstanceDef::DropGlue(..) = *self {
|
if let ty::InstanceDef::DropGlue(.., Some(ty)) = *self {
|
||||||
// Drop glue wants to be instantiated at every codegen
|
// Drop glue generally wants to be instantiated at every codegen
|
||||||
// unit, but without an #[inline] hint. We should make this
|
// unit, but without an #[inline] hint. We should make this
|
||||||
// available to normal end-users.
|
// 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()
|
tcx.codegen_fn_attrs(self.def_id()).requests_inline()
|
||||||
}
|
}
|
||||||
|
|
|
@ -680,13 +680,20 @@ fn characteristic_def_id_of_mono_item<'tcx>(
|
||||||
|
|
||||||
if tcx.trait_of_item(def_id).is_some() {
|
if tcx.trait_of_item(def_id).is_some() {
|
||||||
let self_ty = instance.substs.type_at(0);
|
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));
|
return characteristic_def_id_of_type(self_ty).or(Some(def_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(impl_def_id) = tcx.impl_of_method(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
|
if tcx.sess.opts.incremental.is_some()
|
||||||
// self-type is:
|
&& 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(
|
let impl_self_ty = tcx.subst_and_normalize_erasing_regions(
|
||||||
instance.substs,
|
instance.substs,
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
|
|
|
@ -2,23 +2,23 @@
|
||||||
|
|
||||||
// We specify -Z incremental here because we want to test the partitioning for
|
// We specify -Z incremental here because we want to test the partitioning for
|
||||||
// incremental compilation
|
// 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:-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)]
|
#![allow(dead_code)]
|
||||||
#![crate_type="rlib"]
|
#![crate_type = "rlib"]
|
||||||
|
|
||||||
// aux-build:cgu_extern_drop_glue.rs
|
// aux-build:cgu_extern_drop_glue.rs
|
||||||
extern crate cgu_extern_drop_glue;
|
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);
|
struct LocalStruct(cgu_extern_drop_glue::Struct);
|
||||||
|
|
||||||
//~ MONO_ITEM fn extern_drop_glue::user[0] @@ extern_drop_glue[External]
|
//~ MONO_ITEM fn extern_drop_glue::user[0] @@ extern_drop_glue[External]
|
||||||
pub fn user()
|
pub fn user() {
|
||||||
{
|
//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::LocalStruct[0]> @@ extern_drop_glue-fallback.cgu[External]
|
||||||
//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::LocalStruct[0]> @@ extern_drop_glue[Internal]
|
|
||||||
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
|
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,9 +28,8 @@ pub mod mod1 {
|
||||||
struct LocalStruct(cgu_extern_drop_glue::Struct);
|
struct LocalStruct(cgu_extern_drop_glue::Struct);
|
||||||
|
|
||||||
//~ MONO_ITEM fn extern_drop_glue::mod1[0]::user[0] @@ extern_drop_glue-mod1[External]
|
//~ MONO_ITEM fn extern_drop_glue::mod1[0]::user[0] @@ extern_drop_glue-mod1[External]
|
||||||
pub fn user()
|
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]
|
||||||
//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::mod1[0]::LocalStruct[0]> @@ extern_drop_glue-mod1[Internal]
|
|
||||||
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
|
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,54 +1,45 @@
|
||||||
// ignore-tidy-linelength
|
// ignore-tidy-linelength
|
||||||
// We specify -Z incremental here because we want to test the partitioning for
|
// We specify -Z incremental here because we want to test the partitioning for
|
||||||
// incremental compilation
|
// 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:-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)]
|
#![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 {
|
struct Struct {
|
||||||
_a: u32
|
_a: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Struct {
|
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) {}
|
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 {
|
struct Outer {
|
||||||
_a: Struct
|
_a: Struct,
|
||||||
}
|
}
|
||||||
|
|
||||||
//~ MONO_ITEM fn local_drop_glue::user[0] @@ local_drop_glue[External]
|
//~ MONO_ITEM fn local_drop_glue::user[0] @@ local_drop_glue[External]
|
||||||
pub fn user()
|
pub fn user() {
|
||||||
{
|
let _ = Outer { _a: Struct { _a: 0 } };
|
||||||
let _ = Outer {
|
|
||||||
_a: Struct {
|
|
||||||
_a: 0
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod mod1
|
pub mod mod1 {
|
||||||
{
|
|
||||||
use super::Struct;
|
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 {
|
struct Struct2 {
|
||||||
_a: Struct,
|
_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),
|
_b: (u32, Struct),
|
||||||
}
|
}
|
||||||
|
|
||||||
//~ MONO_ITEM fn local_drop_glue::mod1[0]::user[0] @@ local_drop_glue-mod1[External]
|
//~ MONO_ITEM fn local_drop_glue::mod1[0]::user[0] @@ local_drop_glue-mod1[External]
|
||||||
pub fn user()
|
pub fn user() {
|
||||||
{
|
let _ = Struct2 { _a: Struct { _a: 0 }, _b: (0, Struct { _a: 0 }) };
|
||||||
let _ = Struct2 {
|
|
||||||
_a: Struct { _a: 0 },
|
|
||||||
_b: (0, Struct { _a: 0 }),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue