Move PointIndex to mir_dataflow.
This commit is contained in:
parent
75c68cfd2b
commit
c4b1054525
9 changed files with 127 additions and 114 deletions
|
@ -34,6 +34,7 @@ mod errors;
|
|||
mod framework;
|
||||
pub mod impls;
|
||||
pub mod move_paths;
|
||||
pub mod points;
|
||||
pub mod rustc_peek;
|
||||
pub mod storage;
|
||||
pub mod un_derefer;
|
||||
|
|
94
compiler/rustc_mir_dataflow/src/points.rs
Normal file
94
compiler/rustc_mir_dataflow/src/points.rs
Normal file
|
@ -0,0 +1,94 @@
|
|||
use rustc_index::Idx;
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::mir::{BasicBlock, Body, Location};
|
||||
|
||||
/// Maps between a `Location` and a `PointIndex` (and vice versa).
|
||||
pub struct DenseLocationMap {
|
||||
/// For each basic block, how many points are contained within?
|
||||
statements_before_block: IndexVec<BasicBlock, usize>,
|
||||
|
||||
/// Map backward from each point to the basic block that it
|
||||
/// belongs to.
|
||||
basic_blocks: IndexVec<PointIndex, BasicBlock>,
|
||||
|
||||
num_points: usize,
|
||||
}
|
||||
|
||||
impl DenseLocationMap {
|
||||
#[inline]
|
||||
pub fn new(body: &Body<'_>) -> Self {
|
||||
let mut num_points = 0;
|
||||
let statements_before_block: IndexVec<BasicBlock, usize> = body
|
||||
.basic_blocks
|
||||
.iter()
|
||||
.map(|block_data| {
|
||||
let v = num_points;
|
||||
num_points += block_data.statements.len() + 1;
|
||||
v
|
||||
})
|
||||
.collect();
|
||||
debug!("DenseLocationMap: statements_before_block={:#?}", statements_before_block);
|
||||
debug!("DenseLocationMap: num_points={:#?}", num_points);
|
||||
|
||||
let mut basic_blocks = IndexVec::with_capacity(num_points);
|
||||
for (bb, bb_data) in body.basic_blocks.iter_enumerated() {
|
||||
basic_blocks.extend((0..=bb_data.statements.len()).map(|_| bb));
|
||||
}
|
||||
|
||||
Self { statements_before_block, basic_blocks, num_points }
|
||||
}
|
||||
|
||||
/// Total number of point indices
|
||||
#[inline]
|
||||
pub fn num_points(&self) -> usize {
|
||||
self.num_points
|
||||
}
|
||||
|
||||
/// Converts a `Location` into a `PointIndex`. O(1).
|
||||
#[inline]
|
||||
pub fn point_from_location(&self, location: Location) -> PointIndex {
|
||||
let Location { block, statement_index } = location;
|
||||
let start_index = self.statements_before_block[block];
|
||||
PointIndex::new(start_index + statement_index)
|
||||
}
|
||||
|
||||
/// Converts a `Location` into a `PointIndex`. O(1).
|
||||
#[inline]
|
||||
pub fn entry_point(&self, block: BasicBlock) -> PointIndex {
|
||||
let start_index = self.statements_before_block[block];
|
||||
PointIndex::new(start_index)
|
||||
}
|
||||
|
||||
/// Return the PointIndex for the block start of this index.
|
||||
#[inline]
|
||||
pub fn to_block_start(&self, index: PointIndex) -> PointIndex {
|
||||
PointIndex::new(self.statements_before_block[self.basic_blocks[index]])
|
||||
}
|
||||
|
||||
/// Converts a `PointIndex` back to a location. O(1).
|
||||
#[inline]
|
||||
pub fn to_location(&self, index: PointIndex) -> Location {
|
||||
assert!(index.index() < self.num_points);
|
||||
let block = self.basic_blocks[index];
|
||||
let start_index = self.statements_before_block[block];
|
||||
let statement_index = index.index() - start_index;
|
||||
Location { block, statement_index }
|
||||
}
|
||||
|
||||
/// Sometimes we get point-indices back from bitsets that may be
|
||||
/// out of range (because they round up to the nearest 2^N number
|
||||
/// of bits). Use this function to filter such points out if you
|
||||
/// like.
|
||||
#[inline]
|
||||
pub fn point_in_range(&self, index: PointIndex) -> bool {
|
||||
index.index() < self.num_points
|
||||
}
|
||||
}
|
||||
|
||||
rustc_index::newtype_index! {
|
||||
/// A single integer representing a `Location` in the MIR control-flow
|
||||
/// graph. Constructed efficiently from `DenseLocationMap`.
|
||||
#[orderable]
|
||||
#[debug_format = "PointIndex({})"]
|
||||
pub struct PointIndex {}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue