Skip to content

Commit e54c177

Browse files
committed
Remove Analysis::into_engine.
This is a standard pattern: ``` MyAnalysis.into_engine(tcx, body).iterate_to_fixpoint() ``` `into_engine` and `iterate_to_fixpoint` are always called in pairs, but sometimes with a builder-style `pass_name` call between them. But a builder-style interface is overkill here. This has been bugging me a for a while. This commit: - Merges `Engine::new` and `Engine::iterate_to_fixpoint`. This removes the need for `Engine` to have fields, leaving it as a trivial type that the next commit will remove. - Renames `Analysis::into_engine` as `Analysis::iterate_to_fixpoint`, gives it an extra argument for the optional pass name, and makes it call `Engine::iterate_to_fixpoint` instead of `Engine::new`. This turns the pattern from above into this: ``` MyAnalysis.iterate_to_fixpoint(tcx, body, None) ``` which is shorter at every call site, and there's less plumbing required to support it.
1 parent 31e102c commit e54c177

File tree

14 files changed

+72
-116
lines changed

14 files changed

+72
-116
lines changed

Diff for: compiler/rustc_borrowck/src/lib.rs

+16-15
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,7 @@ fn do_mir_borrowck<'tcx>(
193193
.map(|(idx, body)| (idx, MoveData::gather_moves(body, tcx, |_| true)));
194194

195195
let mut flow_inits = MaybeInitializedPlaces::new(tcx, body, &move_data)
196-
.into_engine(tcx, body)
197-
.pass_name("borrowck")
198-
.iterate_to_fixpoint()
196+
.iterate_to_fixpoint(tcx, body, Some("borrowck"))
199197
.into_results_cursor(body);
200198

201199
let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(def).is_fn_or_closure();
@@ -243,18 +241,21 @@ fn do_mir_borrowck<'tcx>(
243241
// usage significantly on some benchmarks.
244242
drop(flow_inits);
245243

246-
let flow_borrows = Borrows::new(tcx, body, &regioncx, &borrow_set)
247-
.into_engine(tcx, body)
248-
.pass_name("borrowck")
249-
.iterate_to_fixpoint();
250-
let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &move_data)
251-
.into_engine(tcx, body)
252-
.pass_name("borrowck")
253-
.iterate_to_fixpoint();
254-
let flow_ever_inits = EverInitializedPlaces::new(body, &move_data)
255-
.into_engine(tcx, body)
256-
.pass_name("borrowck")
257-
.iterate_to_fixpoint();
244+
let flow_borrows = Borrows::new(tcx, body, &regioncx, &borrow_set).iterate_to_fixpoint(
245+
tcx,
246+
body,
247+
Some("borrowck"),
248+
);
249+
let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &move_data).iterate_to_fixpoint(
250+
tcx,
251+
body,
252+
Some("borrowck"),
253+
);
254+
let flow_ever_inits = EverInitializedPlaces::new(body, &move_data).iterate_to_fixpoint(
255+
tcx,
256+
body,
257+
Some("borrowck"),
258+
);
258259

259260
let movable_coroutine =
260261
// The first argument is the coroutine type passed by value

Diff for: compiler/rustc_const_eval/src/check_consts/check.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,7 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
6363
let ConstCx { tcx, body, .. } = *ccx;
6464

6565
FlowSensitiveAnalysis::new(NeedsDrop, ccx)
66-
.into_engine(tcx, body)
67-
.iterate_to_fixpoint()
66+
.iterate_to_fixpoint(tcx, body, None)
6867
.into_results_cursor(body)
6968
});
7069

@@ -93,8 +92,7 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
9392
let ConstCx { tcx, body, .. } = *ccx;
9493

9594
FlowSensitiveAnalysis::new(NeedsNonConstDrop, ccx)
96-
.into_engine(tcx, body)
97-
.iterate_to_fixpoint()
95+
.iterate_to_fixpoint(tcx, body, None)
9896
.into_results_cursor(body)
9997
});
10098

@@ -123,8 +121,7 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
123121
let ConstCx { tcx, body, .. } = *ccx;
124122

125123
FlowSensitiveAnalysis::new(HasMutInterior, ccx)
126-
.into_engine(tcx, body)
127-
.iterate_to_fixpoint()
124+
.iterate_to_fixpoint(tcx, body, None)
128125
.into_results_cursor(body)
129126
});
130127

@@ -239,8 +236,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
239236
let always_live_locals = &always_storage_live_locals(&ccx.body);
240237
let mut maybe_storage_live =
241238
MaybeStorageLive::new(Cow::Borrowed(always_live_locals))
242-
.into_engine(ccx.tcx, &ccx.body)
243-
.iterate_to_fixpoint()
239+
.iterate_to_fixpoint(ccx.tcx, &ccx.body, None)
244240
.into_results_cursor(&ccx.body);
245241

246242
// And then check all `Return` in the MIR, and if a local is "maybe live" at a

Diff for: compiler/rustc_mir_dataflow/src/framework/engine.rs

+12-35
Original file line numberDiff line numberDiff line change
@@ -71,25 +71,21 @@ where
7171
}
7272

7373
/// A solver for dataflow problems.
74-
pub struct Engine<'mir, 'tcx, A>
75-
where
76-
A: Analysis<'tcx>,
77-
{
78-
tcx: TyCtxt<'tcx>,
79-
body: &'mir mir::Body<'tcx>,
80-
entry_sets: IndexVec<BasicBlock, A::Domain>,
81-
pass_name: Option<&'static str>,
82-
analysis: A,
83-
}
74+
pub struct Engine;
8475

85-
impl<'mir, 'tcx, A, D> Engine<'mir, 'tcx, A>
86-
where
87-
A: Analysis<'tcx, Domain = D>,
88-
D: Clone + JoinSemiLattice,
89-
{
76+
impl Engine {
9077
/// Creates a new `Engine` to solve a dataflow problem with an arbitrary transfer
9178
/// function.
92-
pub(crate) fn new(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>, analysis: A) -> Self {
79+
pub(crate) fn iterate_to_fixpoint<'mir, 'tcx, A>(
80+
tcx: TyCtxt<'tcx>,
81+
body: &'mir mir::Body<'tcx>,
82+
mut analysis: A,
83+
pass_name: Option<&'static str>,
84+
) -> Results<'tcx, A>
85+
where
86+
A: Analysis<'tcx>,
87+
A::Domain: DebugWithContext<A> + Clone + JoinSemiLattice,
88+
{
9389
let mut entry_sets =
9490
IndexVec::from_fn_n(|_| analysis.bottom_value(body), body.basic_blocks.len());
9591
analysis.initialize_start_block(body, &mut entry_sets[mir::START_BLOCK]);
@@ -99,25 +95,6 @@ where
9995
bug!("`initialize_start_block` is not yet supported for backward dataflow analyses");
10096
}
10197

102-
Engine { analysis, tcx, body, pass_name: None, entry_sets }
103-
}
104-
105-
/// Adds an identifier to the graphviz output for this particular run of a dataflow analysis.
106-
///
107-
/// Some analyses are run multiple times in the compilation pipeline. Give them a `pass_name`
108-
/// to differentiate them. Otherwise, only the results for the latest run will be saved.
109-
pub fn pass_name(mut self, name: &'static str) -> Self {
110-
self.pass_name = Some(name);
111-
self
112-
}
113-
114-
/// Computes the fixpoint for this dataflow problem and returns it.
115-
pub fn iterate_to_fixpoint(self) -> Results<'tcx, A>
116-
where
117-
A::Domain: DebugWithContext<A>,
118-
{
119-
let Engine { mut analysis, body, mut entry_sets, tcx, pass_name } = self;
120-
12198
let mut dirty_queue: WorkQueue<BasicBlock> = WorkQueue::with_none(body.basic_blocks.len());
12299

123100
if A::Direction::IS_FORWARD {

Diff for: compiler/rustc_mir_dataflow/src/framework/mod.rs

+19-14
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,17 @@
77
//!
88
//! The `impls` module contains several examples of dataflow analyses.
99
//!
10-
//! Create an `Engine` for your analysis using the `into_engine` method on the `Analysis` trait,
11-
//! then call `iterate_to_fixpoint`. From there, you can use a `ResultsCursor` to inspect the
12-
//! fixpoint solution to your dataflow problem, or implement the `ResultsVisitor` interface and use
13-
//! `visit_results`. The following example uses the `ResultsCursor` approach.
10+
//! Then call `iterate_to_fixpoint` on your type that impls `Analysis` to get a `Results`. From
11+
//! there, you can use a `ResultsCursor` to inspect the fixpoint solution to your dataflow problem,
12+
//! or implement the `ResultsVisitor` interface and use `visit_results`. The following example uses
13+
//! the `ResultsCursor` approach.
1414
//!
1515
//! ```ignore (cross-crate-imports)
16-
//! use rustc_const_eval::dataflow::Analysis; // Makes `into_engine` available.
16+
//! use rustc_const_eval::dataflow::Analysis; // Makes `iterate_to_fixpoint` available.
1717
//!
1818
//! fn do_my_analysis(tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>) {
1919
//! let analysis = MyAnalysis::new()
20-
//! .into_engine(tcx, body)
21-
//! .iterate_to_fixpoint()
20+
//! .iterate_to_fixpoint(tcx, body, None)
2221
//! .into_results_cursor(body);
2322
//!
2423
//! // Print the dataflow state *after* each statement in the start block.
@@ -39,6 +38,8 @@ use rustc_index::bit_set::{BitSet, ChunkedBitSet, HybridBitSet};
3938
use rustc_middle::mir::{self, BasicBlock, CallReturnPlaces, Location, TerminatorEdges};
4039
use rustc_middle::ty::TyCtxt;
4140

41+
use super::fmt::DebugWithContext;
42+
4243
mod cursor;
4344
mod direction;
4445
mod engine;
@@ -223,26 +224,30 @@ pub trait Analysis<'tcx> {
223224

224225
/* Extension methods */
225226

226-
/// Creates an `Engine` to find the fixpoint for this dataflow problem.
227+
/// Finds the fixpoint for this dataflow problem.
227228
///
228229
/// You shouldn't need to override this. Its purpose is to enable method chaining like so:
229230
///
230231
/// ```ignore (cross-crate-imports)
231232
/// let results = MyAnalysis::new(tcx, body)
232-
/// .into_engine(tcx, body, def_id)
233-
/// .iterate_to_fixpoint()
233+
/// .iterate_to_fixpoint(tcx, body, None)
234234
/// .into_results_cursor(body);
235235
/// ```
236-
#[inline]
237-
fn into_engine<'mir>(
236+
/// You can optionally add a `pass_name` to the graphviz output for this particular run of a
237+
/// dataflow analysis. Some analyses are run multiple times in the compilation pipeline.
238+
/// Without a `pass_name` to differentiates them, only the results for the latest run will be
239+
/// saved.
240+
fn iterate_to_fixpoint<'mir>(
238241
self,
239242
tcx: TyCtxt<'tcx>,
240243
body: &'mir mir::Body<'tcx>,
241-
) -> Engine<'mir, 'tcx, Self>
244+
pass_name: Option<&'static str>,
245+
) -> Results<'tcx, Self>
242246
where
243247
Self: Sized,
248+
Self::Domain: DebugWithContext<Self>,
244249
{
245-
Engine::new(tcx, body, self)
250+
Engine::iterate_to_fixpoint(tcx, body, self, pass_name)
246251
}
247252
}
248253

Diff for: compiler/rustc_mir_dataflow/src/rustc_peek.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -43,31 +43,28 @@ pub fn sanity_check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
4343
let move_data = MoveData::gather_moves(body, tcx, |_| true);
4444

4545
if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_init).is_some() {
46-
let flow_inits = MaybeInitializedPlaces::new(tcx, body, &move_data)
47-
.into_engine(tcx, body)
48-
.iterate_to_fixpoint();
46+
let flow_inits =
47+
MaybeInitializedPlaces::new(tcx, body, &move_data).iterate_to_fixpoint(tcx, body, None);
4948

5049
sanity_check_via_rustc_peek(tcx, flow_inits.into_results_cursor(body));
5150
}
5251

5352
if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_uninit).is_some() {
5453
let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &move_data)
55-
.into_engine(tcx, body)
56-
.iterate_to_fixpoint();
54+
.iterate_to_fixpoint(tcx, body, None);
5755

5856
sanity_check_via_rustc_peek(tcx, flow_uninits.into_results_cursor(body));
5957
}
6058

6159
if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_definite_init).is_some() {
62-
let flow_def_inits = DefinitelyInitializedPlaces::new(body, &move_data)
63-
.into_engine(tcx, body)
64-
.iterate_to_fixpoint();
60+
let flow_def_inits =
61+
DefinitelyInitializedPlaces::new(body, &move_data).iterate_to_fixpoint(tcx, body, None);
6562

6663
sanity_check_via_rustc_peek(tcx, flow_def_inits.into_results_cursor(body));
6764
}
6865

6966
if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_liveness).is_some() {
70-
let flow_liveness = MaybeLiveLocals.into_engine(tcx, body).iterate_to_fixpoint();
67+
let flow_liveness = MaybeLiveLocals.iterate_to_fixpoint(tcx, body, None);
7168

7269
sanity_check_via_rustc_peek(tcx, flow_liveness.into_results_cursor(body));
7370
}

Diff for: compiler/rustc_mir_transform/src/coroutine.rs

+5-10
Original file line numberDiff line numberDiff line change
@@ -666,31 +666,26 @@ fn locals_live_across_suspend_points<'tcx>(
666666
// Calculate when MIR locals have live storage. This gives us an upper bound of their
667667
// lifetimes.
668668
let mut storage_live = MaybeStorageLive::new(std::borrow::Cow::Borrowed(always_live_locals))
669-
.into_engine(tcx, body)
670-
.iterate_to_fixpoint()
669+
.iterate_to_fixpoint(tcx, body, None)
671670
.into_results_cursor(body);
672671

673672
// Calculate the MIR locals which have been previously
674673
// borrowed (even if they are still active).
675674
let borrowed_locals_results =
676-
MaybeBorrowedLocals.into_engine(tcx, body).pass_name("coroutine").iterate_to_fixpoint();
675+
MaybeBorrowedLocals.iterate_to_fixpoint(tcx, body, Some("coroutine"));
677676

678677
let mut borrowed_locals_cursor = borrowed_locals_results.clone().into_results_cursor(body);
679678

680679
// Calculate the MIR locals that we actually need to keep storage around
681680
// for.
682681
let mut requires_storage_cursor =
683682
MaybeRequiresStorage::new(borrowed_locals_results.into_results_cursor(body))
684-
.into_engine(tcx, body)
685-
.iterate_to_fixpoint()
683+
.iterate_to_fixpoint(tcx, body, None)
686684
.into_results_cursor(body);
687685

688686
// Calculate the liveness of MIR locals ignoring borrows.
689-
let mut liveness = MaybeLiveLocals
690-
.into_engine(tcx, body)
691-
.pass_name("coroutine")
692-
.iterate_to_fixpoint()
693-
.into_results_cursor(body);
687+
let mut liveness =
688+
MaybeLiveLocals.iterate_to_fixpoint(tcx, body, Some("coroutine")).into_results_cursor(body);
694689

695690
let mut storage_liveness_map = IndexVec::from_elem(None, &body.basic_blocks);
696691
let mut live_locals_at_suspension_points = Vec::new();

Diff for: compiler/rustc_mir_transform/src/dataflow_const_prop.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ impl<'tcx> crate::MirPass<'tcx> for DataflowConstProp {
5959
// Perform the actual dataflow analysis.
6060
let analysis = ConstAnalysis::new(tcx, body, map);
6161
let mut results = debug_span!("analyze")
62-
.in_scope(|| analysis.wrap().into_engine(tcx, body).iterate_to_fixpoint());
62+
.in_scope(|| analysis.wrap().iterate_to_fixpoint(tcx, body, None));
6363

6464
// Collect results and patch the body afterwards.
6565
let mut visitor = Collector::new(tcx, &body.local_decls);

Diff for: compiler/rustc_mir_transform/src/dead_store_elimination.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
3737
always_live.union(&borrowed_locals);
3838

3939
let mut live = MaybeTransitiveLiveLocals::new(&always_live)
40-
.into_engine(tcx, body)
41-
.iterate_to_fixpoint()
40+
.iterate_to_fixpoint(tcx, body, None)
4241
.into_results_cursor(body);
4342

4443
// For blocks with a call terminator, if an argument copy can be turned into a move,

Diff for: compiler/rustc_mir_transform/src/dest_prop.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,7 @@ impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
169169

170170
let borrowed = rustc_mir_dataflow::impls::borrowed_locals(body);
171171

172-
let live = MaybeLiveLocals
173-
.into_engine(tcx, body)
174-
.pass_name("MaybeLiveLocals-DestinationPropagation")
175-
.iterate_to_fixpoint();
172+
let live = MaybeLiveLocals.iterate_to_fixpoint(tcx, body, Some("MaybeLiveLocals-DestProp"));
176173
let points = DenseLocationMap::new(body);
177174
let mut live = save_as_intervals(&points, body, live);
178175

Diff for: compiler/rustc_mir_transform/src/elaborate_drops.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,14 @@ impl<'tcx> crate::MirPass<'tcx> for ElaborateDrops {
6464

6565
let mut inits = MaybeInitializedPlaces::new(tcx, body, &env.move_data)
6666
.skipping_unreachable_unwind()
67-
.into_engine(tcx, body)
68-
.pass_name("elaborate_drops")
69-
.iterate_to_fixpoint()
67+
.iterate_to_fixpoint(tcx, body, Some("elaborate_drops"))
7068
.into_results_cursor(body);
7169
let dead_unwinds = compute_dead_unwinds(body, &mut inits);
7270

7371
let uninits = MaybeUninitializedPlaces::new(tcx, body, &env.move_data)
7472
.mark_inactive_variants_as_uninit()
7573
.skipping_unreachable_unwind(dead_unwinds)
76-
.into_engine(tcx, body)
77-
.pass_name("elaborate_drops")
78-
.iterate_to_fixpoint()
74+
.iterate_to_fixpoint(tcx, body, Some("elaborate_drops"))
7975
.into_results_cursor(body);
8076

8177
let drop_flags = IndexVec::from_elem(None, &env.move_data.move_paths);

Diff for: compiler/rustc_mir_transform/src/lint.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,11 @@ pub(super) fn lint_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, when: String
1717
let always_live_locals = &always_storage_live_locals(body);
1818

1919
let maybe_storage_live = MaybeStorageLive::new(Cow::Borrowed(always_live_locals))
20-
.into_engine(tcx, body)
21-
.iterate_to_fixpoint()
20+
.iterate_to_fixpoint(tcx, body, None)
2221
.into_results_cursor(body);
2322

2423
let maybe_storage_dead = MaybeStorageDead::new(Cow::Borrowed(always_live_locals))
25-
.into_engine(tcx, body)
26-
.iterate_to_fixpoint()
24+
.iterate_to_fixpoint(tcx, body, None)
2725
.into_results_cursor(body);
2826

2927
let mut lint = Lint {

Diff for: compiler/rustc_mir_transform/src/ref_prop.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,7 @@ fn compute_replacement<'tcx>(
126126
// Compute `MaybeStorageDead` dataflow to check that we only replace when the pointee is
127127
// definitely live.
128128
let mut maybe_dead = MaybeStorageDead::new(Cow::Owned(always_live_locals))
129-
.into_engine(tcx, body)
130-
.iterate_to_fixpoint()
129+
.iterate_to_fixpoint(tcx, body, None)
131130
.into_results_cursor(body);
132131

133132
// Map for each local to the pointee.

Diff for: compiler/rustc_mir_transform/src/remove_uninit_drops.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveUninitDrops {
2222
let move_data = MoveData::gather_moves(body, tcx, |ty| ty.needs_drop(tcx, param_env));
2323

2424
let mut maybe_inits = MaybeInitializedPlaces::new(tcx, body, &move_data)
25-
.into_engine(tcx, body)
26-
.pass_name("remove_uninit_drops")
27-
.iterate_to_fixpoint()
25+
.iterate_to_fixpoint(tcx, body, Some("remove_uninit_drops"))
2826
.into_results_cursor(body);
2927

3028
let mut to_remove = vec![];

Diff for: src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,7 @@ impl<'b, 'tcx> PossibleBorrowerMap<'b, 'tcx> {
185185
vis.into_map(cx)
186186
};
187187
let maybe_storage_live_result = MaybeStorageLive::new(Cow::Owned(BitSet::new_empty(mir.local_decls.len())))
188-
.into_engine(cx.tcx, mir)
189-
.pass_name("redundant_clone")
190-
.iterate_to_fixpoint()
188+
.iterate_to_fixpoint(cx.tcx, mir, Some("redundant_clone"))
191189
.into_results_cursor(mir);
192190
let mut vis = PossibleBorrowerVisitor::new(cx, mir, possible_origin);
193191
vis.visit_body(mir);

0 commit comments

Comments
 (0)