mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-16 13:05:18 +03:00
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:
@@ -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,
|
||||
}
|
||||
+11
-12
@@ -40,6 +40,7 @@
|
||||
|
||||
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 @@ pub fn new(
|
||||
spread_arg: None,
|
||||
var_debug_info,
|
||||
span,
|
||||
predecessors_cache: None,
|
||||
cache: cache::Cache::new(),
|
||||
control_flow_destroyed,
|
||||
}
|
||||
}
|
||||
@@ -204,7 +205,7 @@ pub fn basic_blocks(&self) -> &IndexVec<BasicBlock, BasicBlockData<'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 @@ pub fn basic_blocks_and_local_decls_mut(
|
||||
&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 @@ pub fn ensure_predecessors(&mut self) {
|
||||
}
|
||||
}
|
||||
|
||||
self.predecessors_cache = Some(result)
|
||||
self.cache.predecessors = Some(result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,7 +248,7 @@ pub fn ensure_predecessors(&mut self) {
|
||||
/// 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 @@ pub fn start_location(self) -> Location {
|
||||
}
|
||||
}
|
||||
|
||||
CloneTypeFoldableAndLiftImpls!{ BasicBlock, }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// BasicBlockData and Terminator
|
||||
|
||||
|
||||
@@ -1082,7 +1082,7 @@ fn is_item_mir_available(&self, id: DefIndex) -> bool {
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user