Skip to content

Commit ee7413b

Browse files
committed
Implement apply_switch_int_edge_effects for backward analyses
1 parent 9c7f6d6 commit ee7413b

File tree

3 files changed

+56
-8
lines changed

3 files changed

+56
-8
lines changed

compiler/rustc_mir_dataflow/src/framework/direction.rs

+55-5
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ impl Direction for Backward {
248248
);
249249
propagate(pred, &tmp);
250250
}
251+
251252
mir::TerminatorKind::InlineAsm {
252253
destination: Some(dest), ref operands, ..
253254
} if dest == bb => {
@@ -266,6 +267,25 @@ impl Direction for Backward {
266267
propagate(pred, &tmp);
267268
}
268269

270+
mir::TerminatorKind::SwitchInt { ref targets, ref discr, switch_ty: _ } => {
271+
let mut applier = BackwardSwitchIntEdgeEffectsApplier {
272+
pred,
273+
exit_state,
274+
targets,
275+
bb,
276+
propagate: &mut propagate,
277+
effects_applied: false,
278+
};
279+
280+
analysis.apply_switch_int_edge_effects(pred, discr, &mut applier);
281+
282+
let BackwardSwitchIntEdgeEffectsApplier { effects_applied, .. } = applier;
283+
284+
if !effects_applied {
285+
propagate(pred, exit_state)
286+
}
287+
}
288+
269289
// Ignore dead unwinds.
270290
mir::TerminatorKind::Call { cleanup: Some(unwind), .. }
271291
| mir::TerminatorKind::Assert { cleanup: Some(unwind), .. }
@@ -286,6 +306,33 @@ impl Direction for Backward {
286306
}
287307
}
288308

309+
struct BackwardSwitchIntEdgeEffectsApplier<'a, D, F> {
310+
pred: BasicBlock,
311+
exit_state: &'a mut D,
312+
targets: &'a SwitchTargets,
313+
bb: BasicBlock,
314+
propagate: &'a mut F,
315+
316+
effects_applied: bool,
317+
}
318+
319+
impl<D, F> super::SwitchIntEdgeEffects<D> for BackwardSwitchIntEdgeEffectsApplier<'_, D, F>
320+
where
321+
D: Clone,
322+
F: FnMut(BasicBlock, &D),
323+
{
324+
fn apply(&mut self, mut apply_edge_effect: impl FnMut(&mut D, SwitchIntTarget)) {
325+
assert!(!self.effects_applied);
326+
327+
let value =
328+
self.targets.iter().find_map(|(value, target)| (target == self.bb).then_some(value));
329+
apply_edge_effect(self.exit_state, SwitchIntTarget { value, target: self.bb });
330+
(self.propagate)(self.pred, self.exit_state);
331+
332+
self.effects_applied = true;
333+
}
334+
}
335+
289336
/// Dataflow that runs from the entry of a block (the first statement), to its exit (terminator).
290337
pub struct Forward;
291338

@@ -528,7 +575,7 @@ impl Direction for Forward {
528575
}
529576

530577
SwitchInt { ref targets, ref discr, switch_ty: _ } => {
531-
let mut applier = SwitchIntEdgeEffectApplier {
578+
let mut applier = ForwardSwitchIntEdgeEffectsApplier {
532579
exit_state,
533580
targets,
534581
propagate,
@@ -537,8 +584,11 @@ impl Direction for Forward {
537584

538585
analysis.apply_switch_int_edge_effects(bb, discr, &mut applier);
539586

540-
let SwitchIntEdgeEffectApplier {
541-
exit_state, mut propagate, effects_applied, ..
587+
let ForwardSwitchIntEdgeEffectsApplier {
588+
exit_state,
589+
mut propagate,
590+
effects_applied,
591+
..
542592
} = applier;
543593

544594
if !effects_applied {
@@ -551,15 +601,15 @@ impl Direction for Forward {
551601
}
552602
}
553603

554-
struct SwitchIntEdgeEffectApplier<'a, D, F> {
604+
struct ForwardSwitchIntEdgeEffectsApplier<'a, D, F> {
555605
exit_state: &'a mut D,
556606
targets: &'a SwitchTargets,
557607
propagate: F,
558608

559609
effects_applied: bool,
560610
}
561611

562-
impl<D, F> super::SwitchIntEdgeEffects<D> for SwitchIntEdgeEffectApplier<'_, D, F>
612+
impl<D, F> super::SwitchIntEdgeEffects<D> for ForwardSwitchIntEdgeEffectsApplier<'_, D, F>
563613
where
564614
D: Clone,
565615
F: FnMut(BasicBlock, &D),

compiler/rustc_mir_dataflow/src/framework/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,6 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> {
234234
/// about a given `SwitchInt` terminator for each one of its edges—and more efficient—the
235235
/// engine doesn't need to clone the exit state for a block unless
236236
/// `SwitchIntEdgeEffects::apply` is actually called.
237-
///
238-
/// FIXME: This class of effects is not supported for backward dataflow analyses.
239237
fn apply_switch_int_edge_effects(
240238
&self,
241239
_block: BasicBlock,

compiler/rustc_mir_dataflow/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub use self::drop_flag_effects::{
2828
pub use self::framework::{
2929
fmt, graphviz, lattice, visit_results, Analysis, AnalysisDomain, Backward, CallReturnPlaces,
3030
Direction, Engine, Forward, GenKill, GenKillAnalysis, JoinSemiLattice, Results, ResultsCursor,
31-
ResultsRefCursor, ResultsVisitable, ResultsVisitor,
31+
ResultsRefCursor, ResultsVisitable, ResultsVisitor, SwitchIntEdgeEffects,
3232
};
3333

3434
use self::move_paths::MoveData;

0 commit comments

Comments
 (0)