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;
|
pub use crate::mir::interpret::AssertMessage;
|
||||||
|
|
||||||
mod cache;
|
|
||||||
pub mod interpret;
|
pub mod interpret;
|
||||||
pub mod mono;
|
pub mod mono;
|
||||||
pub mod tcx;
|
pub mod tcx;
|
||||||
|
@ -155,7 +154,7 @@ pub struct Body<'tcx> {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
|
||||||
/// A cache for various calculations.
|
/// A cache for various calculations.
|
||||||
cache: cache::Cache,
|
predecessors_cache: Option<IndexVec<BasicBlock, Vec<BasicBlock>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Body<'tcx> {
|
impl<'tcx> Body<'tcx> {
|
||||||
|
@ -192,7 +191,7 @@ impl<'tcx> Body<'tcx> {
|
||||||
spread_arg: None,
|
spread_arg: None,
|
||||||
var_debug_info,
|
var_debug_info,
|
||||||
span,
|
span,
|
||||||
cache: cache::Cache::new(),
|
predecessors_cache: None,
|
||||||
control_flow_destroyed,
|
control_flow_destroyed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,7 +203,8 @@ impl<'tcx> Body<'tcx> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn basic_blocks_mut(&mut self) -> &mut IndexVec<BasicBlock, BasicBlockData<'tcx>> {
|
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
|
&mut self.basic_blocks
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,24 +212,44 @@ impl<'tcx> Body<'tcx> {
|
||||||
pub fn basic_blocks_and_local_decls_mut(
|
pub fn basic_blocks_and_local_decls_mut(
|
||||||
&mut self,
|
&mut self,
|
||||||
) -> (&mut IndexVec<BasicBlock, BasicBlockData<'tcx>>, &mut LocalDecls<'tcx>) {
|
) -> (&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)
|
(&mut self.basic_blocks, &mut self.local_decls)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn predecessors_ref(&self) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
|
pub fn unwrap_predecessors(&self) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
|
||||||
self.cache.predecessors_ref()
|
assert!(self.predecessors_cache.is_some());
|
||||||
|
self.predecessors_cache.as_ref().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[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
|
// 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]
|
#[inline]
|
||||||
pub fn predecessors_for(&self, bb: BasicBlock) -> &Vec<BasicBlock> {
|
pub fn predecessors_for(&self, bb: BasicBlock) -> &[BasicBlock] {
|
||||||
&self.predecessors_ref()[bb]
|
// TODO(nashenas88) could this be predecessors sometimes too?
|
||||||
|
&self.unwrap_predecessors()[bb]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1007,6 +1027,8 @@ impl BasicBlock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CloneTypeFoldableAndLiftImpls!{ BasicBlock, }
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// BasicBlockData and Terminator
|
// BasicBlockData and Terminator
|
||||||
|
|
||||||
|
@ -2628,7 +2650,7 @@ impl<'tcx> graph::WithPredecessors for Body<'tcx> {
|
||||||
&self,
|
&self,
|
||||||
node: Self::Node,
|
node: Self::Node,
|
||||||
) -> <Self as GraphPredecessors<'_>>::Iter {
|
) -> <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`.
|
// 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();
|
let mut visited = FxHashSet::default();
|
||||||
|
|
||||||
while let Some(block) = queue.pop() {
|
while let Some(block) = queue.pop() {
|
||||||
// If we haven't visited this block before, then make sure we visit it's predecessors.
|
// If we haven't visited this block before, then make sure we visit it's predecessors.
|
||||||
if visited.insert(block) {
|
if visited.insert(block) {
|
||||||
queue.append(&mut body.predecessors_for(block).clone());
|
queue.extend(body.predecessors_for(block).iter().cloned());
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ impl<'tcx> MirPass<'tcx> for AddCallGuards {
|
||||||
impl AddCallGuards {
|
impl AddCallGuards {
|
||||||
pub fn add_call_guards(&self, body: &mut Body<'_>) {
|
pub fn add_call_guards(&self, body: &mut Body<'_>) {
|
||||||
let pred_count: IndexVec<_, _> =
|
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
|
// We need a place to store the new blocks generated
|
||||||
let mut new_blocks = Vec::new();
|
let mut new_blocks = Vec::new();
|
||||||
|
|
|
@ -94,7 +94,7 @@ pub fn liveness_of_locals(
|
||||||
dirty_queue.insert(bb);
|
dirty_queue.insert(bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
let predecessors = body.predecessors_ref();
|
let predecessors = body.unwrap_predecessors();
|
||||||
|
|
||||||
while let Some(bb) = dirty_queue.pop() {
|
while let Some(bb) = dirty_queue.pop() {
|
||||||
// bits = use ∪ (bits - def)
|
// bits = use ∪ (bits - def)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue