Skip to content

Commit 8793239

Browse files
committed
Put Analysis back into Results.
`Results` used to contain an `Analysis`, but it was removed in #140234. That change made sense because the analysis was mutable but the entry states were immutable and it was good to separate them so the mutability of the different pieces was clear. Now that analyses are immutable there is no need for the separation, lots of analysis+results pairs can be combined, and the names are going back to what they were before: - `Results` -> `EntryStates` - `AnalysisAndResults` -> `Results`
1 parent a97cd3b commit 8793239

File tree

11 files changed

+77
-107
lines changed

11 files changed

+77
-107
lines changed

compiler/rustc_borrowck/src/lib.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ use rustc_mir_dataflow::move_paths::{
4949
InitIndex, InitLocation, LookupResult, MoveData, MovePathIndex,
5050
};
5151
use rustc_mir_dataflow::points::DenseLocationMap;
52-
use rustc_mir_dataflow::{Analysis, Results, ResultsVisitor, visit_results};
52+
use rustc_mir_dataflow::{Analysis, EntryStates, Results, ResultsVisitor, visit_results};
5353
use rustc_session::lint::builtin::{TAIL_EXPR_DROP_ORDER, UNUSED_MUT};
5454
use rustc_span::{ErrorGuaranteed, Span, Symbol};
5555
use smallvec::SmallVec;
@@ -537,12 +537,10 @@ fn borrowck_check_region_constraints<'tcx>(
537537
mbcx.report_region_errors(nll_errors);
538538
}
539539

540-
let (flow_analysis, flow_results) =
541-
get_flow_results(tcx, body, &move_data, &borrow_set, &regioncx);
540+
let flow_results = get_flow_results(tcx, body, &move_data, &borrow_set, &regioncx);
542541
visit_results(
543542
body,
544543
traversal::reverse_postorder(body).map(|(bb, _)| bb),
545-
&flow_analysis,
546544
&flow_results,
547545
&mut mbcx,
548546
);
@@ -604,7 +602,7 @@ fn get_flow_results<'a, 'tcx>(
604602
move_data: &'a MoveData<'tcx>,
605603
borrow_set: &'a BorrowSet<'tcx>,
606604
regioncx: &RegionInferenceContext<'tcx>,
607-
) -> (Borrowck<'a, 'tcx>, Results<BorrowckDomain>) {
605+
) -> Results<'tcx, Borrowck<'a, 'tcx>> {
608606
// We compute these three analyses individually, but them combine them into
609607
// a single results so that `mbcx` can visit them all together.
610608
let borrows = Borrows::new(tcx, body, regioncx, borrow_set).iterate_to_fixpoint(
@@ -629,14 +627,14 @@ fn get_flow_results<'a, 'tcx>(
629627
ever_inits: ever_inits.analysis,
630628
};
631629

632-
assert_eq!(borrows.results.len(), uninits.results.len());
633-
assert_eq!(borrows.results.len(), ever_inits.results.len());
634-
let results: Results<_> =
635-
itertools::izip!(borrows.results, uninits.results, ever_inits.results)
630+
assert_eq!(borrows.entry_states.len(), uninits.entry_states.len());
631+
assert_eq!(borrows.entry_states.len(), ever_inits.entry_states.len());
632+
let entry_states: EntryStates<_> =
633+
itertools::izip!(borrows.entry_states, uninits.entry_states, ever_inits.entry_states)
636634
.map(|(borrows, uninits, ever_inits)| BorrowckDomain { borrows, uninits, ever_inits })
637635
.collect();
638636

639-
(analysis, results)
637+
Results { analysis, entry_states }
640638
}
641639

642640
pub(crate) struct BorrowckInferCtxt<'tcx> {

compiler/rustc_mir_dataflow/src/framework/cursor.rs

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ where
4242
A: Analysis<'tcx>,
4343
{
4444
body: &'mir mir::Body<'tcx>,
45-
analysis: SimpleCow<'mir, A>,
46-
results: SimpleCow<'mir, Results<A::Domain>>,
45+
results: SimpleCow<'mir, Results<'tcx, A>>,
4746
state: A::Domain,
4847

4948
pos: CursorPosition,
@@ -71,15 +70,10 @@ where
7170
self.body
7271
}
7372

74-
fn new(
75-
body: &'mir mir::Body<'tcx>,
76-
analysis: SimpleCow<'mir, A>,
77-
results: SimpleCow<'mir, Results<A::Domain>>,
78-
) -> Self {
79-
let bottom_value = analysis.bottom_value(body);
73+
fn new(body: &'mir mir::Body<'tcx>, results: SimpleCow<'mir, Results<'tcx, A>>) -> Self {
74+
let bottom_value = results.analysis.bottom_value(body);
8075
ResultsCursor {
8176
body,
82-
analysis,
8377
results,
8478

8579
// Initialize to the `bottom_value` and set `state_needs_reset` to tell the cursor that
@@ -95,21 +89,13 @@ where
9589
}
9690

9791
/// Returns a new cursor that takes ownership of and inspects analysis results.
98-
pub fn new_owning(
99-
body: &'mir mir::Body<'tcx>,
100-
analysis: A,
101-
results: Results<A::Domain>,
102-
) -> Self {
103-
Self::new(body, SimpleCow::Owned(analysis), SimpleCow::Owned(results))
92+
pub fn new_owning(body: &'mir mir::Body<'tcx>, results: Results<'tcx, A>) -> Self {
93+
Self::new(body, SimpleCow::Owned(results))
10494
}
10595

10696
/// Returns a new cursor that borrows and inspects analysis results.
107-
pub fn new_borrowing(
108-
body: &'mir mir::Body<'tcx>,
109-
analysis: &'mir A,
110-
results: &'mir Results<A::Domain>,
111-
) -> Self {
112-
Self::new(body, SimpleCow::Borrowed(analysis), SimpleCow::Borrowed(results))
97+
pub fn new_borrowing(body: &'mir mir::Body<'tcx>, results: &'mir Results<'tcx, A>) -> Self {
98+
Self::new(body, SimpleCow::Borrowed(results))
11399
}
114100

115101
/// Allows inspection of unreachable basic blocks even with `debug_assertions` enabled.
@@ -121,7 +107,7 @@ where
121107

122108
/// Returns the `Analysis` used to generate the underlying `Results`.
123109
pub fn analysis(&self) -> &A {
124-
&self.analysis
110+
&self.results.analysis
125111
}
126112

127113
/// Resets the cursor to hold the entry set for the given basic block.
@@ -133,7 +119,7 @@ where
133119
#[cfg(debug_assertions)]
134120
assert!(self.reachable_blocks.contains(block));
135121

136-
self.state.clone_from(&self.results[block]);
122+
self.state.clone_from(&self.results.entry_states[block]);
137123
self.pos = CursorPosition::block_entry(block);
138124
self.state_needs_reset = false;
139125
}
@@ -225,7 +211,7 @@ where
225211
let target_effect_index = effect.at_index(target.statement_index);
226212

227213
A::Direction::apply_effects_in_range(
228-
&*self.analysis,
214+
&self.results.analysis,
229215
&mut self.state,
230216
target.block,
231217
block_data,
@@ -241,7 +227,7 @@ where
241227
/// This can be used, e.g., to apply the call return effect directly to the cursor without
242228
/// creating an extra copy of the dataflow state.
243229
pub fn apply_custom_effect(&mut self, f: impl FnOnce(&A, &mut A::Domain)) {
244-
f(&self.analysis, &mut self.state);
230+
f(&self.results.analysis, &mut self.state);
245231
self.state_needs_reset = true;
246232
}
247233
}

compiler/rustc_mir_dataflow/src/framework/graphviz.rs

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ use crate::errors::{
3232
pub(super) fn write_graphviz_results<'tcx, A>(
3333
tcx: TyCtxt<'tcx>,
3434
body: &Body<'tcx>,
35-
analysis: &A,
36-
results: &Results<A::Domain>,
35+
results: &Results<'tcx, A>,
3736
pass_name: Option<&'static str>,
3837
) -> std::io::Result<()>
3938
where
@@ -80,7 +79,7 @@ where
8079

8180
let mut buf = Vec::new();
8281

83-
let graphviz = Formatter::new(body, analysis, results, style);
82+
let graphviz = Formatter::new(body, results, style);
8483
let mut render_opts =
8584
vec![dot::RenderOption::Fontname(tcx.sess.opts.unstable_opts.graphviz_font.clone())];
8685
if tcx.sess.opts.unstable_opts.graphviz_dark_mode {
@@ -205,8 +204,7 @@ where
205204
A: Analysis<'tcx>,
206205
{
207206
body: &'mir Body<'tcx>,
208-
analysis: &'mir A,
209-
results: &'mir Results<A::Domain>,
207+
results: &'mir Results<'tcx, A>,
210208
style: OutputStyle,
211209
reachable: DenseBitSet<BasicBlock>,
212210
}
@@ -215,14 +213,9 @@ impl<'mir, 'tcx, A> Formatter<'mir, 'tcx, A>
215213
where
216214
A: Analysis<'tcx>,
217215
{
218-
fn new(
219-
body: &'mir Body<'tcx>,
220-
analysis: &'mir A,
221-
results: &'mir Results<A::Domain>,
222-
style: OutputStyle,
223-
) -> Self {
216+
fn new(body: &'mir Body<'tcx>, results: &'mir Results<'tcx, A>, style: OutputStyle) -> Self {
224217
let reachable = traversal::reachable_as_bitset(body);
225-
Formatter { body, analysis, results, style, reachable }
218+
Formatter { body, results, style, reachable }
226219
}
227220
}
228221

@@ -260,11 +253,10 @@ where
260253
}
261254

262255
fn node_label(&self, block: &Self::Node) -> dot::LabelText<'_> {
263-
let diffs =
264-
StateDiffCollector::run(self.body, *block, self.analysis, self.results, self.style);
256+
let diffs = StateDiffCollector::run(self.body, *block, self.results, self.style);
265257

266258
let mut fmt = BlockFormatter {
267-
cursor: ResultsCursor::new_borrowing(self.body, self.analysis, self.results),
259+
cursor: ResultsCursor::new_borrowing(self.body, self.results),
268260
style: self.style,
269261
bg: Background::Light,
270262
};
@@ -692,21 +684,20 @@ impl<D> StateDiffCollector<D> {
692684
fn run<'tcx, A>(
693685
body: &Body<'tcx>,
694686
block: BasicBlock,
695-
analysis: &A,
696-
results: &Results<A::Domain>,
687+
results: &Results<'tcx, A>,
697688
style: OutputStyle,
698689
) -> Self
699690
where
700691
A: Analysis<'tcx, Domain = D>,
701692
D: DebugWithContext<A>,
702693
{
703694
let mut collector = StateDiffCollector {
704-
prev_state: analysis.bottom_value(body),
695+
prev_state: results.analysis.bottom_value(body),
705696
after: vec![],
706697
before: (style == OutputStyle::BeforeAndAfter).then_some(vec![]),
707698
};
708699

709-
visit_results(body, std::iter::once(block), analysis, results, &mut collector);
700+
visit_results(body, std::iter::once(block), results, &mut collector);
710701
collector
711702
}
712703
}

compiler/rustc_mir_dataflow/src/framework/mod.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ mod visitor;
5858
pub use self::cursor::ResultsCursor;
5959
pub use self::direction::{Backward, Direction, Forward};
6060
pub use self::lattice::{JoinSemiLattice, MaybeReachable};
61-
pub(crate) use self::results::AnalysisAndResults;
62-
pub use self::results::Results;
61+
pub use self::results::{EntryStates, Results};
6362
pub use self::visitor::{ResultsVisitor, visit_reachable_results, visit_results};
6463

6564
/// Analysis domains are all bitsets of various kinds. This trait holds
@@ -249,15 +248,17 @@ pub trait Analysis<'tcx> {
249248
tcx: TyCtxt<'tcx>,
250249
body: &'mir mir::Body<'tcx>,
251250
pass_name: Option<&'static str>,
252-
) -> AnalysisAndResults<'tcx, Self>
251+
) -> Results<'tcx, Self>
253252
where
254253
Self: Sized,
255254
Self::Domain: DebugWithContext<Self>,
256255
{
257-
let mut results = IndexVec::from_fn_n(|_| self.bottom_value(body), body.basic_blocks.len());
258-
self.initialize_start_block(body, &mut results[mir::START_BLOCK]);
256+
let mut entry_states =
257+
IndexVec::from_fn_n(|_| self.bottom_value(body), body.basic_blocks.len());
258+
self.initialize_start_block(body, &mut entry_states[mir::START_BLOCK]);
259259

260-
if Self::Direction::IS_BACKWARD && results[mir::START_BLOCK] != self.bottom_value(body) {
260+
if Self::Direction::IS_BACKWARD && entry_states[mir::START_BLOCK] != self.bottom_value(body)
261+
{
261262
bug!("`initialize_start_block` is not yet supported for backward dataflow analyses");
262263
}
263264

@@ -281,8 +282,8 @@ pub trait Analysis<'tcx> {
281282
let mut state = self.bottom_value(body);
282283
while let Some(bb) = dirty_queue.pop() {
283284
// Set the state to the entry state of the block. This is equivalent to `state =
284-
// results[bb].clone()`, but it saves an allocation, thus improving compile times.
285-
state.clone_from(&results[bb]);
285+
// entry_states[bb].clone()`, but it saves an allocation, thus improving compile times.
286+
state.clone_from(&entry_states[bb]);
286287

287288
Self::Direction::apply_effects_in_block(
288289
&self,
@@ -291,22 +292,24 @@ pub trait Analysis<'tcx> {
291292
bb,
292293
&body[bb],
293294
|target: BasicBlock, state: &Self::Domain| {
294-
let set_changed = results[target].join(state);
295+
let set_changed = entry_states[target].join(state);
295296
if set_changed {
296297
dirty_queue.insert(target);
297298
}
298299
},
299300
);
300301
}
301302

303+
let results = Results { analysis: self, entry_states };
304+
302305
if tcx.sess.opts.unstable_opts.dump_mir_dataflow {
303-
let res = write_graphviz_results(tcx, body, &self, &results, pass_name);
306+
let res = write_graphviz_results(tcx, body, &results, pass_name);
304307
if let Err(e) = res {
305308
error!("Failed to write graphviz dataflow results: {}", e);
306309
}
307310
}
308311

309-
AnalysisAndResults { analysis: self, results }
312+
results
310313
}
311314
}
312315

compiler/rustc_mir_dataflow/src/framework/results.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,26 @@ use rustc_middle::mir::{BasicBlock, Body};
55

66
use super::{Analysis, ResultsCursor};
77

8-
/// The results of a dataflow analysis that has converged to fixpoint. It only holds the domain
9-
/// values at the entry of each basic block. Domain values in other parts of the block are
10-
/// recomputed on the fly by visitors (i.e. `ResultsCursor`, or `ResultsVisitor` impls).
11-
pub type Results<D> = IndexVec<BasicBlock, D>;
8+
pub type EntryStates<D> = IndexVec<BasicBlock, D>;
129

13-
/// Utility type used in a few places where it's convenient to bundle an analysis with its results.
14-
pub struct AnalysisAndResults<'tcx, A>
10+
/// The results of a dataflow analysis that has converged to fixpoint. It holds the domain values
11+
/// (states) at the entry of each basic block. Domain values in other parts of the block are
12+
/// recomputed on the fly by visitors (i.e. `ResultsCursor`, or `ResultsVisitor` impls). The
13+
/// analysis is also present because it's often needed alongside the entry states.
14+
pub struct Results<'tcx, A>
1515
where
1616
A: Analysis<'tcx>,
1717
{
1818
pub analysis: A,
19-
pub results: Results<A::Domain>,
19+
pub entry_states: EntryStates<A::Domain>,
2020
}
2121

22-
impl<'tcx, A> AnalysisAndResults<'tcx, A>
22+
impl<'tcx, A> Results<'tcx, A>
2323
where
2424
A: Analysis<'tcx>,
2525
{
2626
/// Creates a `ResultsCursor` that takes ownership of `self`.
2727
pub fn into_results_cursor<'mir>(self, body: &'mir Body<'tcx>) -> ResultsCursor<'mir, 'tcx, A> {
28-
ResultsCursor::new_owning(body, self.analysis, self.results)
28+
ResultsCursor::new_owning(body, self)
2929
}
3030
}

compiler/rustc_mir_dataflow/src/framework/tests.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,15 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> {
7171
///
7272
/// | Location | Before | After |
7373
/// |------------------------|-------------------|--------|
74-
/// | (on_entry) | {102} ||
74+
/// | (on_entry) | {102} | |
7575
/// | statement 0 | +0 | +1 |
7676
/// | statement 1 | +2 | +3 |
7777
/// | `Call` terminator | +4 | +5 |
78-
/// | (on unwind) | {102,0,1,2,3,4,5} ||
78+
/// | (on unwind) | {102,0,1,2,3,4,5} | |
7979
///
8080
/// The `102` in the block's entry set is derived from the basic block index and ensures that the
8181
/// expected state is unique across all basic blocks. Remember, it is generated by
82-
/// `mock_results`, not from actually running `MockAnalysis` to fixpoint.
82+
/// `mock_entry_states`, not from actually running `MockAnalysis` to fixpoint.
8383
struct MockAnalysis<'tcx, D> {
8484
body: &'tcx mir::Body<'tcx>,
8585
dir: PhantomData<D>,
@@ -96,7 +96,7 @@ impl<D: Direction> MockAnalysis<'_, D> {
9696
ret
9797
}
9898

99-
fn mock_results(&self) -> IndexVec<BasicBlock, DenseBitSet<usize>> {
99+
fn mock_entry_states(&self) -> IndexVec<BasicBlock, DenseBitSet<usize>> {
100100
let empty = self.bottom_value(self.body);
101101
let mut ret = IndexVec::from_elem(empty, &self.body.basic_blocks);
102102

@@ -255,7 +255,7 @@ fn test_cursor<D: Direction>(analysis: MockAnalysis<'_, D>) {
255255
let body = analysis.body;
256256

257257
let mut cursor =
258-
AnalysisAndResults { results: analysis.mock_results(), analysis }.into_results_cursor(body);
258+
Results { entry_states: analysis.mock_entry_states(), analysis }.into_results_cursor(body);
259259

260260
cursor.allow_unreachable();
261261

0 commit comments

Comments
 (0)