]> git.lizzy.rs Git - rust.git/commitdiff
trans: Enable falling back to on-demand instantiation for drop-glue and monomorphizat...
authorMichael Woerister <michaelwoerister@posteo.net>
Wed, 8 Jun 2016 01:14:51 +0000 (21:14 -0400)
committerMichael Woerister <michaelwoerister@posteo.net>
Fri, 8 Jul 2016 14:42:48 +0000 (10:42 -0400)
See issue #34151 for more information.

src/librustc_trans/base.rs
src/librustc_trans/context.rs
src/librustc_trans/glue.rs
src/librustc_trans/monomorphize.rs
src/librustc_trans/partitioning.rs
src/librustc_trans/trans_item.rs

index 071d9d68dbb40e3e89b6e33901b6c7b1f29c22b9..bcca008c5e9e074bc76d5880a2a04a87e9082d7b 100644 (file)
@@ -2684,6 +2684,8 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         println!("n_null_glues: {}", stats.n_null_glues.get());
         println!("n_real_glues: {}", stats.n_real_glues.get());
 
+        println!("n_fallback_instantiations: {}", stats.n_fallback_instantiations.get());
+
         println!("n_fns: {}", stats.n_fns.get());
         println!("n_monos: {}", stats.n_monos.get());
         println!("n_inlines: {}", stats.n_inlines.get());
@@ -2875,6 +2877,14 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
     assert!(scx.tcx().sess.opts.cg.codegen_units == codegen_units.len() ||
             scx.tcx().sess.opts.debugging_opts.incremental.is_some());
 
+    {
+        let mut ccx_map = scx.translation_items().borrow_mut();
+
+        for trans_item in items.iter().cloned() {
+            ccx_map.insert(trans_item, TransItemState::PredictedButNotGenerated);
+        }
+    }
+
     if scx.sess().opts.debugging_opts.print_trans_items.is_some() {
         let mut item_to_cgus = HashMap::new();
 
@@ -2926,12 +2936,6 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
         for item in item_keys {
             println!("TRANS_ITEM {}", item);
         }
-
-        let mut ccx_map = scx.translation_items().borrow_mut();
-
-        for cgi in items {
-            ccx_map.insert(cgi, TransItemState::PredictedButNotGenerated);
-        }
     }
 
     (codegen_units, symbol_map)
index 64e0351610f24441a12c7aa45b9899ad6c0ca49f..8f700e2fe389b281c09b03a8285c08d9dda746cc 100644 (file)
@@ -53,6 +53,7 @@ pub struct Stats {
     pub n_glues_created: Cell<usize>,
     pub n_null_glues: Cell<usize>,
     pub n_real_glues: Cell<usize>,
+    pub n_fallback_instantiations: Cell<usize>,
     pub n_fns: Cell<usize>,
     pub n_monos: Cell<usize>,
     pub n_inlines: Cell<usize>,
@@ -406,6 +407,7 @@ pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>,
                 n_glues_created: Cell::new(0),
                 n_null_glues: Cell::new(0),
                 n_real_glues: Cell::new(0),
+                n_fallback_instantiations: Cell::new(0),
                 n_fns: Cell::new(0),
                 n_monos: Cell::new(0),
                 n_inlines: Cell::new(0),
index 3b4a9499a11bae7d6730f9d2f023f3fb3ed74845..468192d7f1144a85fca2f5d0c14d380d3f0b6fbf 100644 (file)
@@ -234,13 +234,34 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                 g: DropGlueKind<'tcx>) -> ValueRef {
     let g = g.map_ty(|t| get_drop_glue_type(ccx.tcx(), t));
     match ccx.drop_glues().borrow().get(&g) {
-        Some(&(glue, _)) => glue,
-        None => { bug!("Could not find drop glue for {:?} -- {} -- {}. \
-                        It should have be instantiated during the pre-definition phase",
-                       g,
-                       TransItem::DropGlue(g).to_raw_string(),
-                       ccx.codegen_unit().name) }
+        Some(&(glue, _)) => return glue,
+        None => {
+            debug!("Could not find drop glue for {:?} -- {} -- {}. \
+                    Falling back to on-demand instantiation.",
+                    g,
+                    TransItem::DropGlue(g).to_raw_string(),
+                    ccx.codegen_unit().name);
+
+            ccx.stats().n_fallback_instantiations.set(ccx.stats()
+                                                         .n_fallback_instantiations
+                                                         .get() + 1);
+        }
     }
+
+    // FIXME: #34151
+    // Normally, getting here would indicate a bug in trans::collector,
+    // since it seems to have missed a translation item. When we are
+    // translating with non-MIR-based trans, however, the results of the
+    // collector are not entirely reliable since it bases its analysis
+    // on MIR. Thus, we'll instantiate the missing function on demand in
+    // this codegen unit, so that things keep working.
+
+    TransItem::DropGlue(g).predefine(ccx, llvm::LinkOnceODRLinkage);
+    TransItem::DropGlue(g).define(ccx);
+
+    // Now that we made sure that the glue function is in ccx.drop_glues,
+    // give it another try
+    get_drop_glue_core(ccx, g)
 }
 
 pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
index f12eb1cd8e1fbdc7d3db26406cb9adfa4db40778..71aacfdfe58acc90a91872e37a732572cec0884c 100644 (file)
@@ -121,8 +121,25 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
             ref attrs, node: hir::MethodTraitItem(
                 hir::MethodSig { .. }, Some(_)), ..
         }) => {
-            attributes::from_fn_attrs(ccx, attrs, lldecl);
-            llvm::SetLinkage(lldecl, llvm::ExternalLinkage);
+            let trans_item = TransItem::Fn(instance);
+
+            if ccx.shared().translation_items().borrow().contains_key(&trans_item) {
+                attributes::from_fn_attrs(ccx, attrs, lldecl);
+                llvm::SetLinkage(lldecl, llvm::ExternalLinkage);
+            } else {
+                // FIXME: #34151
+                // Normally, getting here would indicate a bug in trans::collector,
+                // since it seems to have missed a translation item. When we are
+                // translating with non-MIR based trans, however, the results of
+                // the collector are not entirely reliable since it bases its
+                // analysis on MIR. Thus, we'll instantiate the missing function
+                // privately in this codegen unit, so that things keep working.
+                ccx.stats().n_fallback_instantiations.set(ccx.stats()
+                                                             .n_fallback_instantiations
+                                                             .get() + 1);
+                trans_item.predefine(ccx, llvm::PrivateLinkage);
+                trans_item.define(ccx);
+            }
         }
 
         hir_map::NodeVariant(_) | hir_map::NodeStructCtor(_) => {
index 785c193c855707451ccb499e1231f156255e95aa..edf5db81b1843bfc695ee89ed03db750f3e5b17f 100644 (file)
@@ -517,11 +517,11 @@ fn single_codegen_unit<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     if reachable.contains(&node_id) {
                         llvm::ExternalLinkage
                     } else {
-                        llvm::InternalLinkage
+                        llvm::PrivateLinkage
                     }
                 }
                 TransItem::DropGlue(_) => {
-                    llvm::InternalLinkage
+                    llvm::PrivateLinkage
                 }
                 TransItem::Fn(instance) => {
                     if trans_item.is_generic_fn() ||
index b4f8a116662ea9755bbcbfcd386c7d8a80a1bb3f..2fc90b821feaebe53e14e06e582470441a179fcc 100644 (file)
@@ -108,19 +108,19 @@ pub fn predefine(&self,
                ccx.codegen_unit().name);
 
         let symbol_name = ccx.symbol_map()
-                             .get(*self)
-                             .expect("Name not present in SymbolMap?");
-        debug!("symbol {}", symbol_name);
+                             .get_or_compute(ccx.shared(), *self);
+
+        debug!("symbol {}", &symbol_name);
 
         match *self {
             TransItem::Static(node_id) => {
-                TransItem::predefine_static(ccx, node_id, linkage, symbol_name);
+                TransItem::predefine_static(ccx, node_id, linkage, &symbol_name);
             }
             TransItem::Fn(instance) => {
-                TransItem::predefine_fn(ccx, instance, linkage, symbol_name);
+                TransItem::predefine_fn(ccx, instance, linkage, &symbol_name);
             }
             TransItem::DropGlue(dg) => {
-                TransItem::predefine_drop_glue(ccx, dg, linkage, symbol_name);
+                TransItem::predefine_drop_glue(ccx, dg, linkage, &symbol_name);
             }
         }