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:
Paul Daniel Faria 2019-10-07 16:08:57 -04:00
parent 22bc8a01c1
commit 9b335ce1a6
4 changed files with 61 additions and 14 deletions

47
src/librustc/mir/cache.rs Normal file
View 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,
}

View File

@ -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

View File

@ -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))
})

View File

@ -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))
}