diff --git a/src/librustc/mir/cache.rs b/src/librustc/mir/cache.rs new file mode 100644 index 00000000000..8dac356c0a2 --- /dev/null +++ b/src/librustc/mir/cache.rs @@ -0,0 +1,47 @@ +use rustc_index::vec::IndexVec; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; +use crate::ich::StableHashingContext; +use crate::mir::BasicBlock; + +#[derive(Clone, Debug)] +pub(in crate::mir) struct Cache { + pub(in crate::mir) predecessors: Option>> +} + + +impl rustc_serialize::Encodable for Cache { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + Encodable::encode(&(), s) + } +} + +impl rustc_serialize::Decodable for Cache { + fn decode(d: &mut D) -> Result { + Decodable::decode(d).map(|_v: ()| Self::new()) + } +} + +impl<'a> HashStable> for Cache { + fn hash_stable(&self, _: &mut StableHashingContext<'a>, _: &mut StableHasher) { + // Do nothing. + } +} + +impl Cache { + pub fn new() -> Self { + Cache { + predecessors: None + } + } + + #[inline] + pub fn invalidate_predecessors(&mut self) { + // FIXME: consider being more fine-grained + self.predecessors = None; + } +} + +CloneTypeFoldableAndLiftImpls! { + Cache, +} diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index ea9de2fdae8..fb5ee211de2 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -40,6 +40,7 @@ use syntax_pos::{Span, DUMMY_SP}; pub use crate::mir::interpret::AssertMessage; +mod cache; pub mod interpret; pub mod mono; pub mod tcx; @@ -154,7 +155,7 @@ pub struct Body<'tcx> { pub span: Span, /// A cache for various calculations. - predecessors_cache: Option>>, + cache: cache::Cache, } impl<'tcx> Body<'tcx> { @@ -191,7 +192,7 @@ impl<'tcx> Body<'tcx> { spread_arg: None, var_debug_info, span, - predecessors_cache: None, + cache: cache::Cache::new(), control_flow_destroyed, } } @@ -204,7 +205,7 @@ impl<'tcx> Body<'tcx> { #[inline] pub fn basic_blocks_mut(&mut self) -> &mut IndexVec> { debug!("bbm: Clearing predecessors cache for body at: {:?}", self.span.data()); - self.predecessors_cache = None; + self.cache.invalidate_predecessors(); &mut self.basic_blocks } @@ -213,23 +214,23 @@ impl<'tcx> Body<'tcx> { &mut self, ) -> (&mut IndexVec>, &mut LocalDecls<'tcx>) { debug!("bbaldm: Clearing predecessors cache for body at: {:?}", self.span.data()); - self.predecessors_cache = None; + self.cache.invalidate_predecessors(); (&mut self.basic_blocks, &mut self.local_decls) } #[inline] pub fn unwrap_predecessors(&self) -> &IndexVec> { assert!( - self.predecessors_cache.is_some(), - "Expected predecessors_cache to be `Some(...)` for block at: {:?}", + self.cache.predecessors.is_some(), + "Expected cache.predecessors to be `Some(...)` for block at: {:?}", self.span.data() ); - self.predecessors_cache.as_ref().unwrap() + self.cache.predecessors.as_ref().unwrap() } #[inline] pub fn ensure_predecessors(&mut self) { - if self.predecessors_cache.is_none() { + if self.cache.predecessors.is_none() { let mut result = IndexVec::from_elem(vec![], self.basic_blocks()); for (bb, data) in self.basic_blocks().iter_enumerated() { if let Some(ref term) = data.terminator { @@ -239,7 +240,7 @@ impl<'tcx> Body<'tcx> { } } - self.predecessors_cache = Some(result) + self.cache.predecessors = Some(result) } } @@ -247,7 +248,7 @@ impl<'tcx> Body<'tcx> { /// This will recompute the predecessors cache if it is not available pub fn predecessors(&mut self) -> &IndexVec> { self.ensure_predecessors(); - self.predecessors_cache.as_ref().unwrap() + self.cache.predecessors.as_ref().unwrap() } #[inline] @@ -1030,8 +1031,6 @@ impl BasicBlock { } } -CloneTypeFoldableAndLiftImpls!{ BasicBlock, } - /////////////////////////////////////////////////////////////////////////// // BasicBlockData and Terminator diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 820783bab6d..bbf28418f11 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -1082,7 +1082,7 @@ impl<'a, 'tcx> CrateMetadata { fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> { self.root.per_def.mir.get(self, id) - .filter(|_| !self.is_proc_macro(id)) + self.entry_unless_proc_macro(id) .unwrap_or_else(|| { bug!("get_optimized_mir: missing MIR for `{:?}`", self.local_def_id(id)) }) diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 156ef4c3b8a..e80fb936170 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -249,8 +249,9 @@ fn mir_validated( // What we need to run borrowck etc. &promote_pass, &simplify::SimplifyCfg::new("qualify-consts"), - &ensure_predecessors_cache::EnsurePredecessorsCache::new("qualify-consts"), ]); + + body.ensure_predecessors(); let promoted = promote_pass.promoted_fragments.into_inner(); (tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted)) }