Move predecessors cache back to its own type
This ensures that the cache can be properly ignored during encoding and decoding. Fix panics that arose due to lack of encoding
This commit is contained in:
parent
22bc8a01c1
commit
9b335ce1a6
47
src/librustc/mir/cache.rs
Normal file
47
src/librustc/mir/cache.rs
Normal file
@ -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<IndexVec<BasicBlock, Vec<BasicBlock>>>
|
||||
}
|
||||
|
||||
|
||||
impl rustc_serialize::Encodable for Cache {
|
||||
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
Encodable::encode(&(), s)
|
||||
}
|
||||
}
|
||||
|
||||
impl rustc_serialize::Decodable for Cache {
|
||||
fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
|
||||
Decodable::decode(d).map(|_v: ()| Self::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> HashStable<StableHashingContext<'a>> 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,
|
||||
}
|
@ -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<IndexVec<BasicBlock, Vec<BasicBlock>>>,
|
||||
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<BasicBlock, BasicBlockData<'tcx>> {
|
||||
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<BasicBlock, BasicBlockData<'tcx>>, &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<BasicBlock, Vec<BasicBlock>> {
|
||||
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<BasicBlock, Vec<BasicBlock>> {
|
||||
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
|
||||
|
||||
|
@ -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))
|
||||
})
|
||||
|
@ -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))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user