about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-12-10 03:49:38 +0000
committerbors <bors@rust-lang.org>2016-12-10 03:49:38 +0000
commitd53f39e1e5bc7d960ef2af34a3124e6387fa2d27 (patch)
tree72f9a43a7ba5a6cfe6b3d9c88bcd65532bfb7af1 /src
parentebf2e7da5b7ec70c28bd5535829a13203585f854 (diff)
parentd74d15345cab54860a6e8cf19021372665ce0577 (diff)
downloadrust-d53f39e1e5bc7d960ef2af34a3124e6387fa2d27.tar.gz
rust-d53f39e1e5bc7d960ef2af34a3124e6387fa2d27.zip
Auto merge of #38217 - oli-obk:mir-for-all-and-all-for-mir, r=eddyb
add a -Z flag to guarantee that MIR is generated for all functions

r? @eddyb

cc @solson
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/cstore.rs8
-rw-r--r--src/librustc/session/config.rs2
-rw-r--r--src/librustc_metadata/cstore_impl.rs5
-rw-r--r--src/librustc_metadata/decoder.rs38
-rw-r--r--src/librustc_metadata/encoder.rs7
-rw-r--r--src/librustc_trans/collector.rs5
6 files changed, 53 insertions, 12 deletions
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 78bbb03f40d..f2be97c8323 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -355,6 +355,11 @@ pub trait CrateStore<'tcx> {
     fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Mir<'tcx>;
     fn is_item_mir_available(&self, def: DefId) -> bool;
 
+    /// Take a look if we need to inline or monomorphize this. If so, we
+    /// will emit code for this item in the local crate, and thus
+    /// create a translation item for it.
+    fn can_have_local_instance<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> bool;
+
     // This is basically a 1-based range of ints, which is a little
     // silly - I may fix that.
     fn crates(&self) -> Vec<CrateNum>;
@@ -528,6 +533,9 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
     fn is_item_mir_available(&self, def: DefId) -> bool {
         bug!("is_item_mir_available")
     }
+    fn can_have_local_instance<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> bool {
+        bug!("can_have_local_instance")
+    }
 
     // This is basically a 1-based range of ints, which is a little
     // silly - I may fix that.
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 47f0de3ce57..17b572e7f9e 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -928,6 +928,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
           "print some statistics about AST and HIR"),
     mir_stats: bool = (false, parse_bool, [UNTRACKED],
           "print some statistics about MIR"),
+    always_encode_mir: bool = (false, parse_bool, [TRACKED],
+          "encode MIR of all functions into the crate metadata"),
 }
 
 pub fn default_lib_output() -> CrateType {
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 2882efb75b0..1a1bb1432ee 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -527,6 +527,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         self.get_crate_data(def.krate).is_item_mir_available(def.index)
     }
 
+    fn can_have_local_instance<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> bool {
+        self.dep_graph.read(DepNode::MetaData(def));
+        def.is_local() || self.get_crate_data(def.krate).can_have_local_instance(tcx, def.index)
+    }
+
     fn crates(&self) -> Vec<CrateNum>
     {
         let mut result = vec![];
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 2a6063cc4bd..54c195b1881 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -504,6 +504,14 @@ impl<'tcx> EntryKind<'tcx> {
             EntryKind::Closure(_) => return None,
         })
     }
+    fn is_const_fn(&self, meta: &CrateMetadata) -> bool {
+        let constness = match *self {
+            EntryKind::Method(data) => data.decode(meta).fn_data.constness,
+            EntryKind::Fn(data) => data.decode(meta).constness,
+            _ => hir::Constness::NotConst,
+        };
+        constness == hir::Constness::Const
+    }
 }
 
 impl<'a, 'tcx> CrateMetadata {
@@ -839,6 +847,29 @@ impl<'a, 'tcx> CrateMetadata {
         self.maybe_entry(id).and_then(|item| item.decode(self).mir).is_some()
     }
 
+    pub fn can_have_local_instance(&self,
+                                   tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                   id: DefIndex) -> bool {
+        self.maybe_entry(id).map_or(false, |item| {
+            let item = item.decode(self);
+            // if we don't have a MIR, then this item was never meant to be locally instantiated
+            // or we have a bug in the metadata serialization
+            item.mir.is_some() && (
+                // items with generics always can have local instances if monomorphized
+                item.generics.map_or(false, |generics| {
+                    let generics = generics.decode((self, tcx));
+                    generics.parent_types != 0 || !generics.types.is_empty()
+                }) ||
+                match item.kind {
+                    EntryKind::Closure(_) => true,
+                    _ => false,
+                } ||
+                item.kind.is_const_fn(self) ||
+                attr::requests_inline(&self.get_attributes(&item))
+            )
+        })
+    }
+
     pub fn maybe_get_item_mir(&self,
                               tcx: TyCtxt<'a, 'tcx, 'tcx>,
                               id: DefIndex)
@@ -1051,12 +1082,7 @@ impl<'a, 'tcx> CrateMetadata {
     }
 
     pub fn is_const_fn(&self, id: DefIndex) -> bool {
-        let constness = match self.entry(id).kind {
-            EntryKind::Method(data) => data.decode(self).fn_data.constness,
-            EntryKind::Fn(data) => data.decode(self).constness,
-            _ => hir::Constness::NotConst,
-        };
-        constness == hir::Constness::Const
+        self.entry(id).kind.is_const_fn(self)
     }
 
     pub fn is_foreign_item(&self, id: DefIndex) -> bool {
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 01cb0f823e8..443f3fbaa6e 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -577,7 +577,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             let types = generics.parent_types as usize + generics.types.len();
             let needs_inline = types > 0 || attr::requests_inline(&ast_item.attrs);
             let is_const_fn = sig.constness == hir::Constness::Const;
-            (is_const_fn, needs_inline || is_const_fn)
+            let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
+            (is_const_fn, needs_inline || is_const_fn || always_encode_mir)
         } else {
             (false, false)
         };
@@ -838,11 +839,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 _ => None,
             },
             mir: match item.node {
+                hir::ItemStatic(..) |
                 hir::ItemConst(..) => self.encode_mir(def_id),
                 hir::ItemFn(_, _, constness, _, ref generics, _) => {
                     let tps_len = generics.ty_params.len();
                     let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs);
-                    if needs_inline || constness == hir::Constness::Const {
+                    let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
+                    if needs_inline || constness == hir::Constness::Const || always_encode_mir {
                         self.encode_mir(def_id)
                     } else {
                         None
diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs
index 087fe4decbf..3af3ada66b3 100644
--- a/src/librustc_trans/collector.rs
+++ b/src/librustc_trans/collector.rs
@@ -706,10 +706,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
 fn can_have_local_instance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                      def_id: DefId)
                                      -> bool {
-    // Take a look if we have the definition available. If not, we
-    // will not emit code for this item in the local crate, and thus
-    // don't create a translation item for it.
-    def_id.is_local() || tcx.sess.cstore.is_item_mir_available(def_id)
+    tcx.sess.cstore.can_have_local_instance(tcx, def_id)
 }
 
 fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,