Inline cache impl into Body, rename predecessor fns, change output of predecessors_for to slice
This commit is contained in:
parent
c16ef6b21d
commit
b5240596d2
4 changed files with 38 additions and 91 deletions
|
@ -1,75 +0,0 @@
|
|||
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::{Body, BasicBlock};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Cache {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
pub fn invalidate(&mut self) {
|
||||
// FIXME: consider being more fine-grained
|
||||
self.predecessors = None;
|
||||
}
|
||||
|
||||
pub fn predecessors_ref(&self) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
|
||||
assert!(self.predecessors.is_some());
|
||||
self.predecessors.as_ref().unwrap()
|
||||
}
|
||||
|
||||
pub fn predecessors_mut(
|
||||
&mut self,
|
||||
body: &Body<'_>
|
||||
) -> &mut IndexVec<BasicBlock, Vec<BasicBlock>> {
|
||||
if self.predecessors.is_none() {
|
||||
self.predecessors = Some(calculate_predecessors(body));
|
||||
}
|
||||
|
||||
self.predecessors.as_mut().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn calculate_predecessors(body: &Body<'_>) -> IndexVec<BasicBlock, Vec<BasicBlock>> {
|
||||
let mut result = IndexVec::from_elem(vec![], body.basic_blocks());
|
||||
for (bb, data) in body.basic_blocks().iter_enumerated() {
|
||||
if let Some(ref term) = data.terminator {
|
||||
for &tgt in term.successors() {
|
||||
result[tgt].push(bb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
CloneTypeFoldableAndLiftImpls! {
|
||||
Cache,
|
||||
}
|
|
@ -40,7 +40,6 @@ use syntax_pos::{Span, DUMMY_SP};
|
|||
|
||||
pub use crate::mir::interpret::AssertMessage;
|
||||
|
||||
mod cache;
|
||||
pub mod interpret;
|
||||
pub mod mono;
|
||||
pub mod tcx;
|
||||
|
@ -155,7 +154,7 @@ pub struct Body<'tcx> {
|
|||
pub span: Span,
|
||||
|
||||
/// A cache for various calculations.
|
||||
cache: cache::Cache,
|
||||
predecessors_cache: Option<IndexVec<BasicBlock, Vec<BasicBlock>>>,
|
||||
}
|
||||
|
||||
impl<'tcx> Body<'tcx> {
|
||||
|
@ -192,7 +191,7 @@ impl<'tcx> Body<'tcx> {
|
|||
spread_arg: None,
|
||||
var_debug_info,
|
||||
span,
|
||||
cache: cache::Cache::new(),
|
||||
predecessors_cache: None,
|
||||
control_flow_destroyed,
|
||||
}
|
||||
}
|
||||
|
@ -204,7 +203,8 @@ impl<'tcx> Body<'tcx> {
|
|||
|
||||
#[inline]
|
||||
pub fn basic_blocks_mut(&mut self) -> &mut IndexVec<BasicBlock, BasicBlockData<'tcx>> {
|
||||
self.cache.invalidate();
|
||||
self.predecessors_cache = None;
|
||||
// self.cache.invalidate();
|
||||
&mut self.basic_blocks
|
||||
}
|
||||
|
||||
|
@ -212,24 +212,44 @@ impl<'tcx> Body<'tcx> {
|
|||
pub fn basic_blocks_and_local_decls_mut(
|
||||
&mut self,
|
||||
) -> (&mut IndexVec<BasicBlock, BasicBlockData<'tcx>>, &mut LocalDecls<'tcx>) {
|
||||
self.cache.invalidate();
|
||||
self.predecessors_cache = None;
|
||||
// self.cache.invalidate();
|
||||
(&mut self.basic_blocks, &mut self.local_decls)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn predecessors_ref(&self) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
|
||||
self.cache.predecessors_ref()
|
||||
pub fn unwrap_predecessors(&self) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
|
||||
assert!(self.predecessors_cache.is_some());
|
||||
self.predecessors_cache.as_ref().unwrap()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn predecessors_mut(&mut self) -> &mut IndexVec<BasicBlock, Vec<BasicBlock>> {
|
||||
pub fn predecessors(&mut self) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
|
||||
// TODO(nashenas88) figure out a way to get rid of this clone
|
||||
self.cache.predecessors_mut(&self.clone())
|
||||
if self.predecessors_cache.is_none() {
|
||||
self.predecessors_cache = Some(self.calculate_predecessors())
|
||||
}
|
||||
|
||||
self.predecessors_cache.as_ref().unwrap()
|
||||
}
|
||||
|
||||
fn calculate_predecessors(&self) -> IndexVec<BasicBlock, Vec<BasicBlock>> {
|
||||
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 {
|
||||
for &tgt in term.successors() {
|
||||
result[tgt].push(bb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn predecessors_for(&self, bb: BasicBlock) -> &Vec<BasicBlock> {
|
||||
&self.predecessors_ref()[bb]
|
||||
pub fn predecessors_for(&self, bb: BasicBlock) -> &[BasicBlock] {
|
||||
// TODO(nashenas88) could this be predecessors sometimes too?
|
||||
&self.unwrap_predecessors()[bb]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -1007,6 +1027,8 @@ impl BasicBlock {
|
|||
}
|
||||
}
|
||||
|
||||
CloneTypeFoldableAndLiftImpls!{ BasicBlock, }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// BasicBlockData and Terminator
|
||||
|
||||
|
@ -2628,7 +2650,7 @@ impl<'tcx> graph::WithPredecessors for Body<'tcx> {
|
|||
&self,
|
||||
node: Self::Node,
|
||||
) -> <Self as GraphPredecessors<'_>>::Iter {
|
||||
self.predecessors_for(node).clone().into_iter()
|
||||
self.predecessors_for(node).to_vec().into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2688,13 +2710,13 @@ impl Location {
|
|||
}
|
||||
|
||||
// If we're in another block, then we want to check that block is a predecessor of `other`.
|
||||
let mut queue: Vec<BasicBlock> = body.predecessors_for(other.block).clone();
|
||||
let mut queue: Vec<BasicBlock> = body.predecessors_for(other.block).to_vec();
|
||||
let mut visited = FxHashSet::default();
|
||||
|
||||
while let Some(block) = queue.pop() {
|
||||
// If we haven't visited this block before, then make sure we visit it's predecessors.
|
||||
if visited.insert(block) {
|
||||
queue.append(&mut body.predecessors_for(block).clone());
|
||||
queue.extend(body.predecessors_for(block).iter().cloned());
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ impl<'tcx> MirPass<'tcx> for AddCallGuards {
|
|||
impl AddCallGuards {
|
||||
pub fn add_call_guards(&self, body: &mut Body<'_>) {
|
||||
let pred_count: IndexVec<_, _> =
|
||||
body.predecessors_mut().iter().map(|ps| ps.len()).collect();
|
||||
body.predecessors().iter().map(|ps| ps.len()).collect();
|
||||
|
||||
// We need a place to store the new blocks generated
|
||||
let mut new_blocks = Vec::new();
|
||||
|
|
|
@ -94,7 +94,7 @@ pub fn liveness_of_locals(
|
|||
dirty_queue.insert(bb);
|
||||
}
|
||||
|
||||
let predecessors = body.predecessors_ref();
|
||||
let predecessors = body.unwrap_predecessors();
|
||||
|
||||
while let Some(bb) = dirty_queue.pop() {
|
||||
// bits = use ∪ (bits - def)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue