about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2020-01-20 16:38:42 +0100
committerMichael Woerister <michaelwoerister@posteo>2020-01-23 13:15:15 +0100
commit2ceb92bc53a849e36341c3fd619cb49470e224e2 (patch)
tree34b98766b88b3740251bb9d9991aa22b2321b337
parent190f0c0b0babaef16c97aea87189f89fa0481fba (diff)
downloadrust-2ceb92bc53a849e36341c3fd619cb49470e224e2.tar.gz
rust-2ceb92bc53a849e36341c3fd619cb49470e224e2.zip
Make drop-glue take advantage of -Zshare-generics.
-rw-r--r--src/librustc_codegen_ssa/back/symbol_export.rs28
-rw-r--r--src/librustc_mir/monomorphize/collector.rs10
-rw-r--r--src/librustc_mir/monomorphize/partitioning.rs2
-rw-r--r--src/test/codegen-units/partitioning/auxiliary/shared_generics_aux.rs16
-rw-r--r--src/test/codegen-units/partitioning/shared-generics.rs12
5 files changed, 52 insertions, 16 deletions
diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs
index 12b82633245..7e888a271e3 100644
--- a/src/librustc_codegen_ssa/back/symbol_export.rs
+++ b/src/librustc_codegen_ssa/back/symbol_export.rs
@@ -5,7 +5,7 @@ use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc::middle::exported_symbols::{metadata_symbol_name, ExportedSymbol, SymbolExportLevel};
 use rustc::session::config::{self, Sanitizer};
 use rustc::ty::query::Providers;
-use rustc::ty::subst::SubstsRef;
+use rustc::ty::subst::{GenericArgKind, SubstsRef};
 use rustc::ty::Instance;
 use rustc::ty::{SymbolName, TyCtxt};
 use rustc_codegen_utils::symbol_names;
@@ -248,19 +248,31 @@ fn exported_symbols_provider_local(
                 continue;
             }
 
-            if let &MonoItem::Fn(Instance { def: InstanceDef::Item(def_id), substs }) = mono_item {
-                if substs.non_erasable_generics().next().is_some() {
-                    symbols
-                        .push((ExportedSymbol::Generic(def_id, substs), SymbolExportLevel::Rust));
+            match *mono_item {
+                MonoItem::Fn(Instance { def: InstanceDef::Item(def_id), substs }) => {
+                    if substs.non_erasable_generics().next().is_some() {
+                        let symbol = ExportedSymbol::Generic(def_id, substs);
+                        symbols.push((symbol, SymbolExportLevel::Rust));
+                    }
+                }
+                MonoItem::Fn(Instance { def: InstanceDef::DropGlue(def_id, Some(ty)), substs }) => {
+                    // A little sanity-check
+                    debug_assert_eq!(
+                        substs.non_erasable_generics().next(),
+                        Some(GenericArgKind::Type(ty))
+                    );
+                    let symbol = ExportedSymbol::Generic(def_id, substs);
+                    symbols.push((symbol, SymbolExportLevel::Rust));
+                }
+                _ => {
+                    // Any other symbols don't qualify for sharing
                 }
             }
         }
     }
 
     // Sort so we get a stable incr. comp. hash.
-    symbols.sort_unstable_by(|&(ref symbol1, ..), &(ref symbol2, ..)| {
-        symbol1.compare_stable(tcx, symbol2)
-    });
+    symbols.sort_by_cached_key(|s| s.0.symbol_name_for_local_instance(tcx));
 
     Arc::new(symbols)
 }
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index f4611c32e0a..91e685babbc 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -713,7 +713,8 @@ fn visit_instance_use<'tcx>(
 // need a mono item.
 fn should_monomorphize_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> bool {
     let def_id = match instance.def {
-        ty::InstanceDef::Item(def_id) => def_id,
+        ty::InstanceDef::Item(def_id) | ty::InstanceDef::DropGlue(def_id, Some(_)) => def_id,
+
         ty::InstanceDef::VtableShim(..)
         | ty::InstanceDef::ReifyShim(..)
         | ty::InstanceDef::ClosureOnceShim { .. }
@@ -725,12 +726,14 @@ fn should_monomorphize_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx
     };
 
     if tcx.is_foreign_item(def_id) {
-        // We can always link to foreign items.
+        // Foreign items are always linked against, there's no way of
+        // instantiating them.
         return false;
     }
 
     if def_id.is_local() {
-        // Local items cannot be referred to locally without monomorphizing them locally.
+        // Local items cannot be referred to locally without
+        // monomorphizing them locally.
         return true;
     }
 
@@ -745,6 +748,7 @@ fn should_monomorphize_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx
     if !tcx.is_mir_available(def_id) {
         bug!("cannot create local mono-item for {:?}", def_id)
     }
+
     return true;
 
     fn is_available_upstream_generic<'tcx>(
diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs
index 0def51a6a33..8bcf420e2aa 100644
--- a/src/librustc_mir/monomorphize/partitioning.rs
+++ b/src/librustc_mir/monomorphize/partitioning.rs
@@ -324,7 +324,7 @@ fn mono_item_visibility(
     };
 
     let def_id = match instance.def {
-        InstanceDef::Item(def_id) => def_id,
+        InstanceDef::Item(def_id) | InstanceDef::DropGlue(def_id, Some(_)) => def_id,
 
         // These are all compiler glue and such, never exported, always hidden.
         InstanceDef::VtableShim(..)
diff --git a/src/test/codegen-units/partitioning/auxiliary/shared_generics_aux.rs b/src/test/codegen-units/partitioning/auxiliary/shared_generics_aux.rs
index 9050e8f1671..ffbd0dc5484 100644
--- a/src/test/codegen-units/partitioning/auxiliary/shared_generics_aux.rs
+++ b/src/test/codegen-units/partitioning/auxiliary/shared_generics_aux.rs
@@ -1,4 +1,6 @@
-// compile-flags:-Zshare-generics=yes
+// NOTE: We always compile this test with -Copt-level=0 because higher opt-levels
+//       prevent drop-glue from participating in share-generics.
+// compile-flags:-Zshare-generics=yes -Copt-level=0
 // no-prefer-dynamic
 
 #![crate_type="rlib"]
@@ -8,5 +10,17 @@ pub fn generic_fn<T>(x: T, y: T) -> (T, T) {
 }
 
 pub fn use_generic_fn_f32() -> (f32, f32) {
+    // This line causes drop glue for Foo to be instantiated. We want to make
+    // sure that this crate exports an instance to be re-used by share-generics.
+    let _ = Foo(0);
+
     generic_fn(0.0f32, 1.0f32)
 }
+
+pub struct Foo(pub u32);
+
+impl Drop for Foo {
+    fn drop(&mut self) {
+        println!("foo");
+    }
+}
diff --git a/src/test/codegen-units/partitioning/shared-generics.rs b/src/test/codegen-units/partitioning/shared-generics.rs
index 58e485be003..47ff94437ff 100644
--- a/src/test/codegen-units/partitioning/shared-generics.rs
+++ b/src/test/codegen-units/partitioning/shared-generics.rs
@@ -1,6 +1,8 @@
 // ignore-tidy-linelength
 // no-prefer-dynamic
-// compile-flags:-Zprint-mono-items=eager -Zshare-generics=yes -Zincremental=tmp/partitioning-tests/shared-generics-exe
+// NOTE: We always compile this test with -Copt-level=0 because higher opt-levels
+//       prevent drop-glue from participating in share-generics.
+// compile-flags:-Zprint-mono-items=eager -Zshare-generics=yes -Zincremental=tmp/partitioning-tests/shared-generics-exe -Copt-level=0
 
 #![crate_type="rlib"]
 
@@ -16,6 +18,10 @@ pub fn foo() {
     // This should not generate a monomorphization because it's already
     // available in `shared_generics_aux`.
     let _ = shared_generics_aux::generic_fn(0.0f32, 3.0f32);
-}
 
-// MONO_ITEM drop-glue i8
+    // The following line will drop an instance of `Foo`, generating a call to
+    // Foo's drop-glue function. However, share-generics should take care of
+    // reusing the drop-glue from the upstream crate, so we do not expect a
+    // mono item for the drop-glue
+    let _ = shared_generics_aux::Foo(1);
+}