X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc%2Fmir%2Fmod.rs;h=cc25ad0e22529e3a57d5afa7f97c5b4198c8e7d4;hb=c6354e9839cefbaf80d3a26304bc3e4adacfabb0;hp=300b0363e2d3b20ee2f03d032643e5358716c826;hpb=427e3690f5b2aac03f0bff21d630ccf2028a6371;p=rust.git diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 300b0363e2d..cc25ad0e225 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -21,27 +21,27 @@ use polonius_engine::Atom; use rustc_index::bit_set::BitMatrix; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::graph::dominators::{dominators, Dominators}; -use rustc_data_structures::graph::{self, GraphPredecessors, GraphSuccessors}; +use rustc_data_structures::graph::dominators::Dominators; +use rustc_data_structures::graph::{self, GraphSuccessors}; use rustc_index::vec::{Idx, IndexVec}; use rustc_data_structures::sync::Lrc; -use rustc_data_structures::sync::MappedReadGuard; use rustc_macros::HashStable; use rustc_serialize::{Encodable, Decodable}; use smallvec::SmallVec; use std::borrow::Cow; use std::fmt::{self, Debug, Display, Formatter, Write}; -use std::ops::{Index, IndexMut}; +use std::ops::Index; use std::slice; -use std::vec::IntoIter; use std::{iter, mem, option, u32}; use syntax::ast::Name; use syntax::symbol::Symbol; use syntax_pos::{Span, DUMMY_SP}; pub use crate::mir::interpret::AssertMessage; +pub use crate::mir::cache::{BodyCache, ReadOnlyBodyCache}; +pub use crate::read_only; -mod cache; +pub mod cache; pub mod interpret; pub mod mono; pub mod tcx; @@ -108,7 +108,7 @@ pub struct Body<'tcx> { pub yield_ty: Option>, /// Generator drop glue. - pub generator_drop: Option>>, + pub generator_drop: Option>>, /// The layout of a generator. Produced by the state transformation. pub generator_layout: Option>, @@ -154,9 +154,6 @@ pub struct Body<'tcx> { /// A span representing this MIR, for error reporting. pub span: Span, - - /// A cache for various calculations. - cache: cache::Cache, } impl<'tcx> Body<'tcx> { @@ -193,7 +190,6 @@ pub fn new( spread_arg: None, var_debug_info, span, - cache: cache::Cache::new(), control_flow_destroyed, } } @@ -203,58 +199,6 @@ pub fn basic_blocks(&self) -> &IndexVec> { &self.basic_blocks } - #[inline] - pub fn basic_blocks_mut(&mut self) -> &mut IndexVec> { - self.cache.invalidate(); - &mut self.basic_blocks - } - - #[inline] - pub fn basic_blocks_and_local_decls_mut( - &mut self, - ) -> (&mut IndexVec>, &mut LocalDecls<'tcx>) { - self.cache.invalidate(); - (&mut self.basic_blocks, &mut self.local_decls) - } - - #[inline] - pub fn predecessors(&self) -> MappedReadGuard<'_, IndexVec>> { - self.cache.predecessors(self) - } - - #[inline] - pub fn predecessors_for(&self, bb: BasicBlock) -> MappedReadGuard<'_, Vec> { - MappedReadGuard::map(self.predecessors(), |p| &p[bb]) - } - - #[inline] - pub fn predecessor_locations(&self, loc: Location) -> impl Iterator + '_ { - let if_zero_locations = if loc.statement_index == 0 { - let predecessor_blocks = self.predecessors_for(loc.block); - let num_predecessor_blocks = predecessor_blocks.len(); - Some( - (0..num_predecessor_blocks) - .map(move |i| predecessor_blocks[i]) - .map(move |bb| self.terminator_loc(bb)), - ) - } else { - None - }; - - let if_not_zero_locations = if loc.statement_index == 0 { - None - } else { - Some(Location { block: loc.block, statement_index: loc.statement_index - 1 }) - }; - - if_zero_locations.into_iter().flatten().chain(if_not_zero_locations) - } - - #[inline] - pub fn dominators(&self) -> Dominators { - dominators(self) - } - /// Returns `true` if a cycle exists in the control-flow graph that is reachable from the /// `START_BLOCK`. pub fn is_cfg_cyclic(&self) -> bool { @@ -355,7 +299,7 @@ pub fn vars_and_temps_iter(&self) -> impl Iterator { /// Changes a statement to a nop. This is both faster than deleting instructions and avoids /// invalidating statement indices in `Location`s. pub fn make_statement_nop(&mut self, location: Location) { - let block = &mut self[location.block]; + let block = &mut self.basic_blocks[location.block]; debug_assert!(location.statement_index < block.statements.len()); block.statements[location.statement_index].make_nop() } @@ -415,13 +359,6 @@ fn index(&self, index: BasicBlock) -> &BasicBlockData<'tcx> { } } -impl<'tcx> IndexMut for Body<'tcx> { - #[inline] - fn index_mut(&mut self, index: BasicBlock) -> &mut BasicBlockData<'tcx> { - &mut self.basic_blocks_mut()[index] - } -} - #[derive(Copy, Clone, Debug, HashStable, TypeFoldable)] pub enum ClearCrossCrate { Clear, @@ -2618,15 +2555,6 @@ fn start_node(&self) -> Self::Node { } } -impl<'tcx> graph::WithPredecessors for Body<'tcx> { - fn predecessors( - &self, - node: Self::Node, - ) -> >::Iter { - self.predecessors_for(node).clone().into_iter() - } -} - impl<'tcx> graph::WithSuccessors for Body<'tcx> { fn successors( &self, @@ -2636,11 +2564,6 @@ fn successors( } } -impl<'a, 'b> graph::GraphPredecessors<'b> for Body<'a> { - type Item = BasicBlock; - type Iter = IntoIter; -} - impl<'a, 'b> graph::GraphSuccessors<'b> for Body<'a> { type Item = BasicBlock; type Iter = iter::Cloned>; @@ -2675,7 +2598,11 @@ pub fn successor_within_block(&self) -> Location { } /// Returns `true` if `other` is earlier in the control flow graph than `self`. - pub fn is_predecessor_of<'tcx>(&self, other: Location, body: &Body<'tcx>) -> bool { + pub fn is_predecessor_of<'tcx>( + &self, + other: Location, + body: ReadOnlyBodyCache<'_, 'tcx> + ) -> bool { // If we are in the same block as the other location and are an earlier statement // then we are a predecessor of `other`. if self.block == other.block && self.statement_index < other.statement_index { @@ -2683,13 +2610,13 @@ pub fn is_predecessor_of<'tcx>(&self, other: Location, body: &Body<'tcx>) -> boo } // If we're in another block, then we want to check that block is a predecessor of `other`. - let mut queue: Vec = body.predecessors_for(other.block).clone(); + let mut queue: Vec = 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; }