rustc_mir_dataflow/
points.rs1use rustc_index::{Idx, IndexVec};
2use rustc_middle::mir::{BasicBlock, Body, Location};
3
4pub struct DenseLocationMap {
6 statements_before_block: IndexVec<BasicBlock, usize>,
8
9 basic_blocks: IndexVec<PointIndex, BasicBlock>,
12
13 num_points: usize,
14}
15
16impl DenseLocationMap {
17 #[inline]
18 pub fn new(body: &Body<'_>) -> Self {
19 let mut num_points = 0;
20 let statements_before_block: IndexVec<BasicBlock, usize> = body
21 .basic_blocks
22 .iter()
23 .map(|block_data| {
24 let v = num_points;
25 num_points += block_data.statements.len() + 1;
26 v
27 })
28 .collect();
29
30 let mut basic_blocks = IndexVec::with_capacity(num_points);
31 for (bb, bb_data) in body.basic_blocks.iter_enumerated() {
32 basic_blocks.extend((0..=bb_data.statements.len()).map(|_| bb));
33 }
34
35 Self { statements_before_block, basic_blocks, num_points }
36 }
37
38 #[inline]
40 pub fn num_points(&self) -> usize {
41 self.num_points
42 }
43
44 #[inline]
46 pub fn point_from_location(&self, location: Location) -> PointIndex {
47 let Location { block, statement_index } = location;
48 let start_index = self.statements_before_block[block];
49 PointIndex::new(start_index + statement_index)
50 }
51
52 #[inline]
54 pub fn entry_point(&self, block: BasicBlock) -> PointIndex {
55 let start_index = self.statements_before_block[block];
56 PointIndex::new(start_index)
57 }
58
59 #[inline]
61 pub fn to_block_start(&self, index: PointIndex) -> PointIndex {
62 PointIndex::new(self.statements_before_block[self.basic_blocks[index]])
63 }
64
65 #[inline]
67 pub fn to_location(&self, index: PointIndex) -> Location {
68 assert!(index.index() < self.num_points);
69 let block = self.basic_blocks[index];
70 let start_index = self.statements_before_block[block];
71 let statement_index = index.index() - start_index;
72 Location { block, statement_index }
73 }
74
75 #[inline]
80 pub fn point_in_range(&self, index: PointIndex) -> bool {
81 index.index() < self.num_points
82 }
83}
84
85rustc_index::newtype_index! {
86 #[orderable]
89 #[debug_format = "PointIndex({})"]
90 pub struct PointIndex {}
91}