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);
|
propagate(pred, &tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
mir::TerminatorKind::InlineAsm {
|
mir::TerminatorKind::InlineAsm {
|
||||||
destination: Some(dest), ref operands, ..
|
destination: Some(dest), ref operands, ..
|
||||||
} if dest == bb => {
|
} if dest == bb => {
|
||||||
@ -266,6 +267,25 @@ impl Direction for Backward {
|
|||||||
propagate(pred, &tmp);
|
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.
|
// Ignore dead unwinds.
|
||||||
mir::TerminatorKind::Call { cleanup: Some(unwind), .. }
|
mir::TerminatorKind::Call { cleanup: Some(unwind), .. }
|
||||||
| mir::TerminatorKind::Assert { 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).
|
/// Dataflow that runs from the entry of a block (the first statement), to its exit (terminator).
|
||||||
pub struct Forward;
|
pub struct Forward;
|
||||||
|
|
||||||
@ -528,7 +575,7 @@ impl Direction for Forward {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SwitchInt { ref targets, ref discr, switch_ty: _ } => {
|
SwitchInt { ref targets, ref discr, switch_ty: _ } => {
|
||||||
let mut applier = SwitchIntEdgeEffectApplier {
|
let mut applier = ForwardSwitchIntEdgeEffectsApplier {
|
||||||
exit_state,
|
exit_state,
|
||||||
targets,
|
targets,
|
||||||
propagate,
|
propagate,
|
||||||
@ -537,8 +584,11 @@ impl Direction for Forward {
|
|||||||
|
|
||||||
analysis.apply_switch_int_edge_effects(bb, discr, &mut applier);
|
analysis.apply_switch_int_edge_effects(bb, discr, &mut applier);
|
||||||
|
|
||||||
let SwitchIntEdgeEffectApplier {
|
let ForwardSwitchIntEdgeEffectsApplier {
|
||||||
exit_state, mut propagate, effects_applied, ..
|
exit_state,
|
||||||
|
mut propagate,
|
||||||
|
effects_applied,
|
||||||
|
..
|
||||||
} = applier;
|
} = applier;
|
||||||
|
|
||||||
if !effects_applied {
|
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,
|
exit_state: &'a mut D,
|
||||||
targets: &'a SwitchTargets,
|
targets: &'a SwitchTargets,
|
||||||
propagate: F,
|
propagate: F,
|
||||||
@ -559,7 +609,7 @@ struct SwitchIntEdgeEffectApplier<'a, D, F> {
|
|||||||
effects_applied: bool,
|
effects_applied: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D, F> super::SwitchIntEdgeEffects<D> for SwitchIntEdgeEffectApplier<'_, D, F>
|
impl<D, F> super::SwitchIntEdgeEffects<D> for ForwardSwitchIntEdgeEffectsApplier<'_, D, F>
|
||||||
where
|
where
|
||||||
D: Clone,
|
D: Clone,
|
||||||
F: FnMut(BasicBlock, &D),
|
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
|
/// 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
|
/// engine doesn't need to clone the exit state for a block unless
|
||||||
/// `SwitchIntEdgeEffects::apply` is actually called.
|
/// `SwitchIntEdgeEffects::apply` is actually called.
|
||||||
///
|
|
||||||
/// FIXME: This class of effects is not supported for backward dataflow analyses.
|
|
||||||
fn apply_switch_int_edge_effects(
|
fn apply_switch_int_edge_effects(
|
||||||
&self,
|
&self,
|
||||||
_block: BasicBlock,
|
_block: BasicBlock,
|
||||||
|
@ -28,7 +28,7 @@ pub use self::drop_flag_effects::{
|
|||||||
pub use self::framework::{
|
pub use self::framework::{
|
||||||
fmt, graphviz, lattice, visit_results, Analysis, AnalysisDomain, Backward, CallReturnPlaces,
|
fmt, graphviz, lattice, visit_results, Analysis, AnalysisDomain, Backward, CallReturnPlaces,
|
||||||
Direction, Engine, Forward, GenKill, GenKillAnalysis, JoinSemiLattice, Results, ResultsCursor,
|
Direction, Engine, Forward, GenKill, GenKillAnalysis, JoinSemiLattice, Results, ResultsCursor,
|
||||||
ResultsRefCursor, ResultsVisitable, ResultsVisitor,
|
ResultsRefCursor, ResultsVisitable, ResultsVisitor, SwitchIntEdgeEffects,
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::move_paths::MoveData;
|
use self::move_paths::MoveData;
|
||||||
|
Loading…
Reference in New Issue
Block a user