rustc_mir_dataflow/framework/
results.rs

1//! Dataflow analysis results.
2
3use rustc_index::IndexVec;
4use rustc_middle::mir::{BasicBlock, Body, traversal};
5
6use super::{Analysis, ResultsCursor, ResultsVisitor, visit_results};
7use crate::framework::cursor::ResultsHandle;
8
9pub type EntryStates<'tcx, A> = IndexVec<BasicBlock, <A as Analysis<'tcx>>::Domain>;
10
11/// A dataflow analysis that has converged to fixpoint. It only holds the domain values at the
12/// entry of each basic block. Domain values in other parts of the block are recomputed on the fly
13/// by visitors (i.e. `ResultsCursor`, or `ResultsVisitor` impls).
14#[derive(Clone)]
15pub struct Results<'tcx, A>
16where
17    A: Analysis<'tcx>,
18{
19    pub analysis: A,
20    pub entry_states: EntryStates<'tcx, A>,
21}
22
23impl<'tcx, A> Results<'tcx, A>
24where
25    A: Analysis<'tcx>,
26{
27    /// Creates a `ResultsCursor` that mutably borrows the `Results`, which is appropriate when the
28    /// `Results` is also used outside the cursor.
29    pub fn as_results_cursor<'mir>(
30        &'mir mut self,
31        body: &'mir Body<'tcx>,
32    ) -> ResultsCursor<'mir, 'tcx, A> {
33        ResultsCursor::new(body, ResultsHandle::BorrowedMut(self))
34    }
35
36    /// Creates a `ResultsCursor` that takes ownership of the `Results`.
37    pub fn into_results_cursor<'mir>(self, body: &'mir Body<'tcx>) -> ResultsCursor<'mir, 'tcx, A> {
38        ResultsCursor::new(body, ResultsHandle::Owned(self))
39    }
40
41    /// Gets the dataflow state for the given block.
42    pub fn entry_set_for_block(&self, block: BasicBlock) -> &A::Domain {
43        &self.entry_states[block]
44    }
45
46    pub fn visit_with<'mir>(
47        &mut self,
48        body: &'mir Body<'tcx>,
49        blocks: impl IntoIterator<Item = BasicBlock>,
50        vis: &mut impl ResultsVisitor<'mir, 'tcx, A>,
51    ) {
52        visit_results(body, blocks, self, vis)
53    }
54
55    pub fn visit_reachable_with<'mir>(
56        &mut self,
57        body: &'mir Body<'tcx>,
58        vis: &mut impl ResultsVisitor<'mir, 'tcx, A>,
59    ) {
60        let blocks = traversal::reachable(body);
61        visit_results(body, blocks.map(|(bb, _)| bb), self, vis)
62    }
63}