mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Implement apply_switch_int_edge_effects
for backward analyses
This commit is contained in:
parent
9c7f6d60b1
commit
ee7413b94c
@ -248,6 +248,7 @@ impl Direction for Backward {
|
||||
);
|
||||
propagate(pred, &tmp);
|
||||
}
|
||||
|
||||
mir::TerminatorKind::InlineAsm {
|
||||
destination: Some(dest), ref operands, ..
|
||||
} if dest == bb => {
|
||||
@ -266,6 +267,25 @@ impl Direction for Backward {
|
||||
propagate(pred, &tmp);
|
||||
}
|
||||
|
||||
mir::TerminatorKind::SwitchInt { ref targets, ref discr, switch_ty: _ } => {
|
||||
let mut applier = BackwardSwitchIntEdgeEffectsApplier {
|
||||
pred,
|
||||
exit_state,
|
||||
targets,
|
||||
bb,
|
||||
propagate: &mut propagate,
|
||||
effects_applied: false,
|
||||
};
|
||||
|
||||
analysis.apply_switch_int_edge_effects(pred, discr, &mut applier);
|
||||
|
||||
let BackwardSwitchIntEdgeEffectsApplier { effects_applied, .. } = applier;
|
||||
|
||||
if !effects_applied {
|
||||
propagate(pred, exit_state)
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore dead unwinds.
|
||||
mir::TerminatorKind::Call { cleanup: Some(unwind), .. }
|
||||
| mir::TerminatorKind::Assert { cleanup: Some(unwind), .. }
|
||||
@ -286,6 +306,33 @@ impl Direction for Backward {
|
||||
}
|
||||
}
|
||||
|
||||
struct BackwardSwitchIntEdgeEffectsApplier<'a, D, F> {
|
||||
pred: BasicBlock,
|
||||
exit_state: &'a mut D,
|
||||
targets: &'a SwitchTargets,
|
||||
bb: BasicBlock,
|
||||
propagate: &'a mut F,
|
||||
|
||||
effects_applied: bool,
|
||||
}
|
||||
|
||||
impl<D, F> super::SwitchIntEdgeEffects<D> for BackwardSwitchIntEdgeEffectsApplier<'_, D, F>
|
||||
where
|
||||
D: Clone,
|
||||
F: FnMut(BasicBlock, &D),
|
||||
{
|
||||
fn apply(&mut self, mut apply_edge_effect: impl FnMut(&mut D, SwitchIntTarget)) {
|
||||
assert!(!self.effects_applied);
|
||||
|
||||
let value =
|
||||
self.targets.iter().find_map(|(value, target)| (target == self.bb).then_some(value));
|
||||
apply_edge_effect(self.exit_state, SwitchIntTarget { value, target: self.bb });
|
||||
(self.propagate)(self.pred, self.exit_state);
|
||||
|
||||
self.effects_applied = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// Dataflow that runs from the entry of a block (the first statement), to its exit (terminator).
|
||||
pub struct Forward;
|
||||
|
||||
@ -528,7 +575,7 @@ impl Direction for Forward {
|
||||
}
|
||||
|
||||
SwitchInt { ref targets, ref discr, switch_ty: _ } => {
|
||||
let mut applier = SwitchIntEdgeEffectApplier {
|
||||
let mut applier = ForwardSwitchIntEdgeEffectsApplier {
|
||||
exit_state,
|
||||
targets,
|
||||
propagate,
|
||||
@ -537,8 +584,11 @@ impl Direction for Forward {
|
||||
|
||||
analysis.apply_switch_int_edge_effects(bb, discr, &mut applier);
|
||||
|
||||
let SwitchIntEdgeEffectApplier {
|
||||
exit_state, mut propagate, effects_applied, ..
|
||||
let ForwardSwitchIntEdgeEffectsApplier {
|
||||
exit_state,
|
||||
mut propagate,
|
||||
effects_applied,
|
||||
..
|
||||
} = applier;
|
||||
|
||||
if !effects_applied {
|
||||
@ -551,7 +601,7 @@ impl Direction for Forward {
|
||||
}
|
||||
}
|
||||
|
||||
struct SwitchIntEdgeEffectApplier<'a, D, F> {
|
||||
struct ForwardSwitchIntEdgeEffectsApplier<'a, D, F> {
|
||||
exit_state: &'a mut D,
|
||||
targets: &'a SwitchTargets,
|
||||
propagate: F,
|
||||
@ -559,7 +609,7 @@ struct SwitchIntEdgeEffectApplier<'a, D, F> {
|
||||
effects_applied: bool,
|
||||
}
|
||||
|
||||
impl<D, F> super::SwitchIntEdgeEffects<D> for SwitchIntEdgeEffectApplier<'_, D, F>
|
||||
impl<D, F> super::SwitchIntEdgeEffects<D> for ForwardSwitchIntEdgeEffectsApplier<'_, D, F>
|
||||
where
|
||||
D: Clone,
|
||||
F: FnMut(BasicBlock, &D),
|
||||
|
@ -234,8 +234,6 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> {
|
||||
/// about a given `SwitchInt` terminator for each one of its edges—and more efficient—the
|
||||
/// engine doesn't need to clone the exit state for a block unless
|
||||
/// `SwitchIntEdgeEffects::apply` is actually called.
|
||||
///
|
||||
/// FIXME: This class of effects is not supported for backward dataflow analyses.
|
||||
fn apply_switch_int_edge_effects(
|
||||
&self,
|
||||
_block: BasicBlock,
|
||||
|
@ -28,7 +28,7 @@ pub use self::drop_flag_effects::{
|
||||
pub use self::framework::{
|
||||
fmt, graphviz, lattice, visit_results, Analysis, AnalysisDomain, Backward, CallReturnPlaces,
|
||||
Direction, Engine, Forward, GenKill, GenKillAnalysis, JoinSemiLattice, Results, ResultsCursor,
|
||||
ResultsRefCursor, ResultsVisitable, ResultsVisitor,
|
||||
ResultsRefCursor, ResultsVisitable, ResultsVisitor, SwitchIntEdgeEffects,
|
||||
};
|
||||
|
||||
use self::move_paths::MoveData;
|
||||
|
Loading…
Reference in New Issue
Block a user