Rollup merge of #97832 - tmiasko:const-direction, r=cjgillot
Change `Direction::{is_forward,is_backward}` functions into constants Make it explicit that the analysis direction is constant. This also makes the value immediately available for optimizations. Previously those functions were neither inline nor generic and so their definition was unavailable when using data flow framework from other crates.
This commit is contained in:
commit
796c466cea
@ -109,7 +109,7 @@ pub(super) fn seek_to_block_entry(&mut self, block: BasicBlock) {
|
|||||||
/// For backward analyses, this is the state that will be propagated to its
|
/// For backward analyses, this is the state that will be propagated to its
|
||||||
/// predecessors (ignoring edge-specific effects).
|
/// predecessors (ignoring edge-specific effects).
|
||||||
pub fn seek_to_block_start(&mut self, block: BasicBlock) {
|
pub fn seek_to_block_start(&mut self, block: BasicBlock) {
|
||||||
if A::Direction::is_forward() {
|
if A::Direction::IS_FORWARD {
|
||||||
self.seek_to_block_entry(block)
|
self.seek_to_block_entry(block)
|
||||||
} else {
|
} else {
|
||||||
self.seek_after(Location { block, statement_index: 0 }, Effect::Primary)
|
self.seek_after(Location { block, statement_index: 0 }, Effect::Primary)
|
||||||
@ -123,7 +123,7 @@ pub fn seek_to_block_start(&mut self, block: BasicBlock) {
|
|||||||
/// For forward analyses, this is the state that will be propagated to its
|
/// For forward analyses, this is the state that will be propagated to its
|
||||||
/// successors (ignoring edge-specific effects).
|
/// successors (ignoring edge-specific effects).
|
||||||
pub fn seek_to_block_end(&mut self, block: BasicBlock) {
|
pub fn seek_to_block_end(&mut self, block: BasicBlock) {
|
||||||
if A::Direction::is_backward() {
|
if A::Direction::IS_BACKWARD {
|
||||||
self.seek_to_block_entry(block)
|
self.seek_to_block_entry(block)
|
||||||
} else {
|
} else {
|
||||||
self.seek_after(self.body.terminator_loc(block), Effect::Primary)
|
self.seek_after(self.body.terminator_loc(block), Effect::Primary)
|
||||||
@ -157,7 +157,7 @@ fn seek_after(&mut self, target: Location, effect: Effect) {
|
|||||||
self.seek_to_block_entry(target.block);
|
self.seek_to_block_entry(target.block);
|
||||||
} else if let Some(curr_effect) = self.pos.curr_effect_index {
|
} else if let Some(curr_effect) = self.pos.curr_effect_index {
|
||||||
let mut ord = curr_effect.statement_index.cmp(&target.statement_index);
|
let mut ord = curr_effect.statement_index.cmp(&target.statement_index);
|
||||||
if A::Direction::is_backward() {
|
if A::Direction::IS_BACKWARD {
|
||||||
ord = ord.reverse()
|
ord = ord.reverse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ fn seek_after(&mut self, target: Location, effect: Effect) {
|
|||||||
debug_assert_eq!(target.block, self.pos.block);
|
debug_assert_eq!(target.block, self.pos.block);
|
||||||
|
|
||||||
let block_data = &self.body[target.block];
|
let block_data = &self.body[target.block];
|
||||||
let next_effect = if A::Direction::is_forward() {
|
let next_effect = if A::Direction::IS_FORWARD {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
self.pos.curr_effect_index.map_or_else(
|
self.pos.curr_effect_index.map_or_else(
|
||||||
|| Effect::Before.at_index(0),
|
|| Effect::Before.at_index(0),
|
||||||
|
@ -9,11 +9,9 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub trait Direction {
|
pub trait Direction {
|
||||||
fn is_forward() -> bool;
|
const IS_FORWARD: bool;
|
||||||
|
|
||||||
fn is_backward() -> bool {
|
const IS_BACKWARD: bool = !Self::IS_FORWARD;
|
||||||
!Self::is_forward()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Applies all effects between the given `EffectIndex`s.
|
/// Applies all effects between the given `EffectIndex`s.
|
||||||
///
|
///
|
||||||
@ -68,9 +66,7 @@ fn join_state_into_successors_of<'tcx, A>(
|
|||||||
pub struct Backward;
|
pub struct Backward;
|
||||||
|
|
||||||
impl Direction for Backward {
|
impl Direction for Backward {
|
||||||
fn is_forward() -> bool {
|
const IS_FORWARD: bool = false;
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn apply_effects_in_block<'tcx, A>(
|
fn apply_effects_in_block<'tcx, A>(
|
||||||
analysis: &A,
|
analysis: &A,
|
||||||
@ -338,9 +334,7 @@ fn apply(&mut self, mut apply_edge_effect: impl FnMut(&mut D, SwitchIntTarget))
|
|||||||
pub struct Forward;
|
pub struct Forward;
|
||||||
|
|
||||||
impl Direction for Forward {
|
impl Direction for Forward {
|
||||||
fn is_forward() -> bool {
|
const IS_FORWARD: bool = true;
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn apply_effects_in_block<'tcx, A>(
|
fn apply_effects_in_block<'tcx, A>(
|
||||||
analysis: &A,
|
analysis: &A,
|
||||||
|
@ -147,7 +147,7 @@ fn new(
|
|||||||
let mut entry_sets = IndexVec::from_elem(bottom_value.clone(), body.basic_blocks());
|
let mut entry_sets = IndexVec::from_elem(bottom_value.clone(), body.basic_blocks());
|
||||||
analysis.initialize_start_block(body, &mut entry_sets[mir::START_BLOCK]);
|
analysis.initialize_start_block(body, &mut entry_sets[mir::START_BLOCK]);
|
||||||
|
|
||||||
if A::Direction::is_backward() && entry_sets[mir::START_BLOCK] != bottom_value {
|
if A::Direction::IS_BACKWARD && entry_sets[mir::START_BLOCK] != bottom_value {
|
||||||
bug!("`initialize_start_block` is not yet supported for backward dataflow analyses");
|
bug!("`initialize_start_block` is not yet supported for backward dataflow analyses");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,7 +200,7 @@ pub fn iterate_to_fixpoint(self) -> Results<'tcx, A>
|
|||||||
let mut dirty_queue: WorkQueue<BasicBlock> =
|
let mut dirty_queue: WorkQueue<BasicBlock> =
|
||||||
WorkQueue::with_none(body.basic_blocks().len());
|
WorkQueue::with_none(body.basic_blocks().len());
|
||||||
|
|
||||||
if A::Direction::is_forward() {
|
if A::Direction::IS_FORWARD {
|
||||||
for (bb, _) in traversal::reverse_postorder(body) {
|
for (bb, _) in traversal::reverse_postorder(body) {
|
||||||
dirty_queue.insert(bb);
|
dirty_queue.insert(bb);
|
||||||
}
|
}
|
||||||
|
@ -216,7 +216,7 @@ fn write_node_label(
|
|||||||
// Write the full dataflow state immediately after the terminator if it differs from the
|
// Write the full dataflow state immediately after the terminator if it differs from the
|
||||||
// state at block entry.
|
// state at block entry.
|
||||||
self.results.seek_to_block_end(block);
|
self.results.seek_to_block_end(block);
|
||||||
if self.results.get() != &block_start_state || A::Direction::is_backward() {
|
if self.results.get() != &block_start_state || A::Direction::IS_BACKWARD {
|
||||||
let after_terminator_name = match terminator.kind {
|
let after_terminator_name = match terminator.kind {
|
||||||
mir::TerminatorKind::Call { target: Some(_), .. } => "(on unwind)",
|
mir::TerminatorKind::Call { target: Some(_), .. } => "(on unwind)",
|
||||||
_ => "(on end)",
|
_ => "(on end)",
|
||||||
@ -390,7 +390,7 @@ fn write_statements_and_terminator(
|
|||||||
let mut afters = diffs.after.into_iter();
|
let mut afters = diffs.after.into_iter();
|
||||||
|
|
||||||
let next_in_dataflow_order = |it: &mut std::vec::IntoIter<_>| {
|
let next_in_dataflow_order = |it: &mut std::vec::IntoIter<_>| {
|
||||||
if A::Direction::is_forward() { it.next().unwrap() } else { it.next_back().unwrap() }
|
if A::Direction::IS_FORWARD { it.next().unwrap() } else { it.next_back().unwrap() }
|
||||||
};
|
};
|
||||||
|
|
||||||
for (i, statement) in body[block].statements.iter().enumerate() {
|
for (i, statement) in body[block].statements.iter().enumerate() {
|
||||||
@ -527,7 +527,7 @@ fn visit_block_start(
|
|||||||
_block_data: &mir::BasicBlockData<'tcx>,
|
_block_data: &mir::BasicBlockData<'tcx>,
|
||||||
_block: BasicBlock,
|
_block: BasicBlock,
|
||||||
) {
|
) {
|
||||||
if A::Direction::is_forward() {
|
if A::Direction::IS_FORWARD {
|
||||||
self.prev_state.clone_from(state);
|
self.prev_state.clone_from(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -538,7 +538,7 @@ fn visit_block_end(
|
|||||||
_block_data: &mir::BasicBlockData<'tcx>,
|
_block_data: &mir::BasicBlockData<'tcx>,
|
||||||
_block: BasicBlock,
|
_block: BasicBlock,
|
||||||
) {
|
) {
|
||||||
if A::Direction::is_backward() {
|
if A::Direction::IS_BACKWARD {
|
||||||
self.prev_state.clone_from(state);
|
self.prev_state.clone_from(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ fn expected_state_at_target(&self, target: SeekTarget) -> BitSet<usize> {
|
|||||||
SeekTarget::After(loc) => Effect::Primary.at_index(loc.statement_index),
|
SeekTarget::After(loc) => Effect::Primary.at_index(loc.statement_index),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut pos = if D::is_forward() {
|
let mut pos = if D::IS_FORWARD {
|
||||||
Effect::Before.at_index(0)
|
Effect::Before.at_index(0)
|
||||||
} else {
|
} else {
|
||||||
Effect::Before.at_index(self.body[block].statements.len())
|
Effect::Before.at_index(self.body[block].statements.len())
|
||||||
@ -153,7 +153,7 @@ fn expected_state_at_target(&self, target: SeekTarget) -> BitSet<usize> {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if D::is_forward() {
|
if D::IS_FORWARD {
|
||||||
pos = pos.next_in_forward_order();
|
pos = pos.next_in_forward_order();
|
||||||
} else {
|
} else {
|
||||||
pos = pos.next_in_backward_order();
|
pos = pos.next_in_backward_order();
|
||||||
|
Loading…
Reference in New Issue
Block a user