Skip to content

Commit f010e2d

Browse files
Rollup merge of #133155 - nnethercote:yet-more-rustc_mir_dataflow-cleanups, r=cjgillot
Yet more `rustc_mir_dataflow` cleanups A few more cleanups. r? `@cjgillot`
2 parents 6e5bac1 + be7c6a3 commit f010e2d

File tree

9 files changed

+242
-213
lines changed

9 files changed

+242
-213
lines changed

compiler/rustc_mir_dataflow/src/framework/cursor.rs

+53-12
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,71 @@
11
//! Random access inspection of the results of a dataflow analysis.
22
33
use std::cmp::Ordering;
4+
use std::ops::{Deref, DerefMut};
45

56
#[cfg(debug_assertions)]
67
use rustc_index::bit_set::BitSet;
78
use rustc_middle::mir::{self, BasicBlock, Location};
89

910
use super::{Analysis, Direction, Effect, EffectIndex, Results};
1011

11-
/// Allows random access inspection of the results of a dataflow analysis.
12+
/// Some `ResultsCursor`s want to own a `Results`, and some want to borrow a `Results`, either
13+
/// mutable or immutably. This type allows all of the above. It's similar to `Cow`.
14+
pub enum ResultsHandle<'a, 'tcx, A>
15+
where
16+
A: Analysis<'tcx>,
17+
{
18+
Borrowed(&'a Results<'tcx, A>),
19+
BorrowedMut(&'a mut Results<'tcx, A>),
20+
Owned(Results<'tcx, A>),
21+
}
22+
23+
impl<'tcx, A> Deref for ResultsHandle<'_, 'tcx, A>
24+
where
25+
A: Analysis<'tcx>,
26+
{
27+
type Target = Results<'tcx, A>;
28+
29+
fn deref(&self) -> &Results<'tcx, A> {
30+
match self {
31+
ResultsHandle::Borrowed(borrowed) => borrowed,
32+
ResultsHandle::BorrowedMut(borrowed) => borrowed,
33+
ResultsHandle::Owned(owned) => owned,
34+
}
35+
}
36+
}
37+
38+
impl<'tcx, A> DerefMut for ResultsHandle<'_, 'tcx, A>
39+
where
40+
A: Analysis<'tcx>,
41+
{
42+
fn deref_mut(&mut self) -> &mut Results<'tcx, A> {
43+
match self {
44+
ResultsHandle::Borrowed(_borrowed) => {
45+
panic!("tried to deref_mut a `ResultsHandle::Borrowed")
46+
}
47+
ResultsHandle::BorrowedMut(borrowed) => borrowed,
48+
ResultsHandle::Owned(owned) => owned,
49+
}
50+
}
51+
}
52+
53+
/// Allows random access inspection of the results of a dataflow analysis. Use this when you want
54+
/// to inspect domain values only in certain locations; use `ResultsVisitor` if you want to inspect
55+
/// domain values in many or all locations.
1256
///
13-
/// This cursor only has linear performance within a basic block when its statements are visited in
14-
/// the same order as the `DIRECTION` of the analysis. In the worst case—when statements are
15-
/// visited in *reverse* order—performance will be quadratic in the number of statements in the
16-
/// block. The order in which basic blocks are inspected has no impact on performance.
57+
/// Because `Results` only has domain values for the entry of each basic block, these inspections
58+
/// involve some amount of domain value recomputations. This cursor only has linear performance
59+
/// within a basic block when its statements are visited in the same order as the `DIRECTION` of
60+
/// the analysis. In the worst case—when statements are visited in *reverse* order—performance will
61+
/// be quadratic in the number of statements in the block. The order in which basic blocks are
62+
/// inspected has no impact on performance.
1763
pub struct ResultsCursor<'mir, 'tcx, A>
1864
where
1965
A: Analysis<'tcx>,
2066
{
2167
body: &'mir mir::Body<'tcx>,
22-
results: Results<'tcx, A>,
68+
results: ResultsHandle<'mir, 'tcx, A>,
2369
state: A::Domain,
2470

2571
pos: CursorPosition,
@@ -47,13 +93,8 @@ where
4793
self.body
4894
}
4995

50-
/// Unwraps this cursor, returning the underlying `Results`.
51-
pub fn into_results(self) -> Results<'tcx, A> {
52-
self.results
53-
}
54-
5596
/// Returns a new cursor that can inspect `results`.
56-
pub fn new(body: &'mir mir::Body<'tcx>, results: Results<'tcx, A>) -> Self {
97+
pub fn new(body: &'mir mir::Body<'tcx>, results: ResultsHandle<'mir, 'tcx, A>) -> Self {
5798
let bottom_value = results.analysis.bottom_value(body);
5899
ResultsCursor {
59100
body,

0 commit comments

Comments
 (0)