Skip to content

Commit 063b998

Browse files
committed
add pre-statement-effect to dataflow
1 parent 5165ee9 commit 063b998

File tree

4 files changed

+77
-5
lines changed

4 files changed

+77
-5
lines changed

Diff for: src/librustc_mir/dataflow/at_location.rs

+24
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,18 @@ impl<BD> FlowsAtLocation for FlowAtLocation<BD>
149149
fn reconstruct_statement_effect(&mut self, loc: Location) {
150150
self.stmt_gen.reset_to_empty();
151151
self.stmt_kill.reset_to_empty();
152+
{
153+
let mut sets = BlockSets {
154+
on_entry: &mut self.curr_state,
155+
gen_set: &mut self.stmt_gen,
156+
kill_set: &mut self.stmt_kill,
157+
};
158+
self.base_results
159+
.operator()
160+
.before_statement_effect(&mut sets, loc);
161+
}
162+
self.apply_local_effect(loc);
163+
152164
let mut sets = BlockSets {
153165
on_entry: &mut self.curr_state,
154166
gen_set: &mut self.stmt_gen,
@@ -162,6 +174,18 @@ impl<BD> FlowsAtLocation for FlowAtLocation<BD>
162174
fn reconstruct_terminator_effect(&mut self, loc: Location) {
163175
self.stmt_gen.reset_to_empty();
164176
self.stmt_kill.reset_to_empty();
177+
{
178+
let mut sets = BlockSets {
179+
on_entry: &mut self.curr_state,
180+
gen_set: &mut self.stmt_gen,
181+
kill_set: &mut self.stmt_kill,
182+
};
183+
self.base_results
184+
.operator()
185+
.before_terminator_effect(&mut sets, loc);
186+
}
187+
self.apply_local_effect(loc);
188+
165189
let mut sets = BlockSets {
166190
on_entry: &mut self.curr_state,
167191
gen_set: &mut self.stmt_gen,

Diff for: src/librustc_mir/dataflow/mod.rs

+44-3
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ impl<'a, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation
214214
}
215215
for j_stmt in 0..statements.len() {
216216
let location = Location { block: bb, statement_index: j_stmt };
217+
self.flow_state.operator.before_statement_effect(sets, location);
217218
self.flow_state.operator.statement_effect(sets, location);
218219
if track_intrablock {
219220
sets.apply_local_effect();
@@ -222,6 +223,7 @@ impl<'a, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation
222223

223224
if terminator.is_some() {
224225
let location = Location { block: bb, statement_index: statements.len() };
226+
self.flow_state.operator.before_terminator_effect(sets, location);
225227
self.flow_state.operator.terminator_effect(sets, location);
226228
if track_intrablock {
227229
sets.apply_local_effect();
@@ -365,9 +367,10 @@ pub(crate) trait DataflowResultsConsumer<'a, 'tcx: 'a> {
365367
fn mir(&self) -> &'a Mir<'tcx>;
366368
}
367369

368-
pub fn state_for_location<T: BitDenotation>(loc: Location,
369-
analysis: &T,
370-
result: &DataflowResults<T>)
370+
pub fn state_for_location<'tcx, T: BitDenotation>(loc: Location,
371+
analysis: &T,
372+
result: &DataflowResults<T>,
373+
mir: &Mir<'tcx>)
371374
-> IdxSetBuf<T::Idx> {
372375
let mut entry = result.sets().on_entry_set_for(loc.block.index()).to_owned();
373376

@@ -381,8 +384,16 @@ pub fn state_for_location<T: BitDenotation>(loc: Location,
381384
for stmt in 0..loc.statement_index {
382385
let mut stmt_loc = loc;
383386
stmt_loc.statement_index = stmt;
387+
analysis.before_statement_effect(&mut sets, stmt_loc);
384388
analysis.statement_effect(&mut sets, stmt_loc);
385389
}
390+
391+
// Apply the pre-statement effect of the statement we're evaluating.
392+
if loc.statement_index == mir[loc.block].statements.len() {
393+
analysis.before_terminator_effect(&mut sets, loc);
394+
} else {
395+
analysis.before_statement_effect(&mut sets, loc);
396+
}
386397
}
387398

388399
entry
@@ -637,6 +648,21 @@ pub trait BitDenotation: BitwiseOperator {
637648
/// (For example, establishing the call arguments.)
638649
fn start_block_effect(&self, entry_set: &mut IdxSet<Self::Idx>);
639650

651+
/// Similar to `statement_effect`, except it applies
652+
/// *just before* the statement rather than *just after* it.
653+
///
654+
/// This matters for "dataflow at location" APIs, because the
655+
/// before-statement effect is visible while visiting the
656+
/// statement, while the after-statement effect only becomes
657+
/// visible at the next statement.
658+
///
659+
/// Both the before-statement and after-statement effects are
660+
/// applied, in that order, before moving for the next
661+
/// statement.
662+
fn before_statement_effect(&self,
663+
_sets: &mut BlockSets<Self::Idx>,
664+
_location: Location) {}
665+
640666
/// Mutates the block-sets (the flow sets for the given
641667
/// basic block) according to the effects of evaluating statement.
642668
///
@@ -651,6 +677,21 @@ pub trait BitDenotation: BitwiseOperator {
651677
sets: &mut BlockSets<Self::Idx>,
652678
location: Location);
653679

680+
/// Similar to `terminator_effect`, except it applies
681+
/// *just before* the terminator rather than *just after* it.
682+
///
683+
/// This matters for "dataflow at location" APIs, because the
684+
/// before-terminator effect is visible while visiting the
685+
/// terminator, while the after-terminator effect only becomes
686+
/// visible at the terminator's successors.
687+
///
688+
/// Both the before-terminator and after-terminator effects are
689+
/// applied, in that order, before moving for the next
690+
/// terminator.
691+
fn before_terminator_effect(&self,
692+
_sets: &mut BlockSets<Self::Idx>,
693+
_location: Location) {}
694+
654695
/// Mutates the block-sets (the flow sets for the given
655696
/// basic block) according to the effects of evaluating
656697
/// the terminator.

Diff for: src/librustc_mir/transform/generator.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ fn locals_live_across_suspend_points<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
363363
statement_index: data.statements.len(),
364364
};
365365

366-
let storage_liveness = state_for_location(loc, &analysis, &storage_live);
366+
let storage_liveness = state_for_location(loc, &analysis, &storage_live, mir);
367367

368368
storage_liveness_map.insert(block, storage_liveness.clone());
369369

Diff for: src/librustc_mir/transform/rustc_peek.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,18 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
203203
// reset GEN and KILL sets before emulating their effect.
204204
for e in sets.gen_set.words_mut() { *e = 0; }
205205
for e in sets.kill_set.words_mut() { *e = 0; }
206-
results.0.operator.statement_effect(&mut sets, Location { block: bb, statement_index: j });
206+
results.0.operator.before_statement_effect(
207+
&mut sets, Location { block: bb, statement_index: j });
208+
results.0.operator.statement_effect(
209+
&mut sets, Location { block: bb, statement_index: j });
207210
sets.on_entry.union(sets.gen_set);
208211
sets.on_entry.subtract(sets.kill_set);
209212
}
210213

214+
results.0.operator.before_terminator_effect(
215+
&mut sets,
216+
Location { block: bb, statement_index: statements.len() });
217+
211218
tcx.sess.span_err(span, &format!("rustc_peek: MIR did not match \
212219
anticipated pattern; note that \
213220
rustc_peek expects input of \

0 commit comments

Comments
 (0)