]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_trans/partitioning.rs
trans: Treat generics like regular functions, not like #[inline] functions during...
[rust.git] / src / librustc_trans / partitioning.rs
index d93bbec7efa41153958ad5bd959ac8ef4fff16b3..c91b25ef360cdd2bf24be7991c28e6101885622c 100644 (file)
 use symbol_map::SymbolMap;
 use syntax::ast::NodeId;
 use syntax::symbol::{Symbol, InternedString};
-use trans_item::TransItem;
+use trans_item::{TransItem, InstantiationMode};
 use util::nodemap::{FxHashMap, FxHashSet};
 
 pub enum PartitioningStrategy {
@@ -326,13 +326,15 @@ fn place_root_translation_items<'a, 'tcx, I>(scx: &SharedCrateContext<'a, 'tcx>,
     let tcx = scx.tcx();
     let mut roots = FxHashSet();
     let mut codegen_units = FxHashMap();
+    let is_incremental_build = tcx.sess.opts.incremental.is_some();
 
     for trans_item in trans_items {
-        let is_root = !trans_item.is_instantiated_only_on_demand(tcx);
+        let is_root = trans_item.instantiation_mode(tcx) == InstantiationMode::GloballyShared;
 
         if is_root {
             let characteristic_def_id = characteristic_def_id_of_trans_item(scx, trans_item);
-            let is_volatile = trans_item.is_generic_fn();
+            let is_volatile = is_incremental_build &&
+                              trans_item.is_generic_fn();
 
             let codegen_unit_name = match characteristic_def_id {
                 Some(def_id) => compute_codegen_unit_name(tcx, def_id, is_volatile),
@@ -350,25 +352,9 @@ fn place_root_translation_items<'a, 'tcx, I>(scx: &SharedCrateContext<'a, 'tcx>,
                 Some(explicit_linkage) => explicit_linkage,
                 None => {
                     match trans_item {
+                        TransItem::Fn(..) |
                         TransItem::Static(..) => llvm::ExternalLinkage,
                         TransItem::DropGlue(..) => unreachable!(),
-                        // Is there any benefit to using ExternalLinkage?:
-                        TransItem::Fn(ref instance) => {
-                            if instance.substs.types().next().is_none() {
-                                // This is a non-generic functions, we always
-                                // make it visible externally on the chance that
-                                // it might be used in another codegen unit.
-                                // Later on base::internalize_symbols() will
-                                // assign "internal" linkage to those symbols
-                                // that are not referenced from other codegen
-                                // units (and are not publicly visible).
-                                llvm::ExternalLinkage
-                            } else {
-                                // In the current setup, generic functions cannot
-                                // be roots.
-                                unreachable!()
-                            }
-                        }
                     }
                 }
             };
@@ -448,29 +434,14 @@ fn place_inlined_translation_items<'tcx>(initial_partitioning: PreInliningPartit
             if let Some(linkage) = codegen_unit.items.get(&trans_item) {
                 // This is a root, just copy it over
                 new_codegen_unit.items.insert(trans_item, *linkage);
-            } else if initial_partitioning.roots.contains(&trans_item) {
-                // This item will be instantiated in some other codegen unit,
-                // so we just add it here with AvailableExternallyLinkage
-                // FIXME(mw): I have not seen it happening yet but having
-                //            available_externally here could potentially lead
-                //            to the same problem with exception handling tables
-                //            as in the case below.
-                new_codegen_unit.items.insert(trans_item,
-                                              llvm::AvailableExternallyLinkage);
-            } else if trans_item.is_from_extern_crate() && !trans_item.is_generic_fn() {
-                // FIXME(mw): It would be nice if we could mark these as
-                // `AvailableExternallyLinkage`, since they should have
-                // been instantiated in the extern crate. But this
-                // sometimes leads to crashes on Windows because LLVM
-                // does not handle exception handling table instantiation
-                // reliably in that case.
-                new_codegen_unit.items.insert(trans_item, llvm::InternalLinkage);
             } else {
-                // We can't be sure if this will also be instantiated
-                // somewhere else, so we add an instance here with
-                // InternalLinkage so we don't get any conflicts.
-                new_codegen_unit.items.insert(trans_item,
-                                              llvm::InternalLinkage);
+                if initial_partitioning.roots.contains(&trans_item) {
+                    bug!("GloballyShared trans-item inlined into other CGU: \
+                          {:?}", trans_item);
+                }
+
+                // This is a cgu-private copy
+                new_codegen_unit.items.insert(trans_item, llvm::InternalLinkage);
             }
         }