Checker analysis: change order of block processing for better efficiency. (#29)
After going through the checker with @fitzgen, we discussed the dataflow analysis and @fitzgen noted that it would likely be more efficient to, for example, process an inner cycle of blocks in a loop nest and converge before returning to the outer loop. I had written a BFS-style workqueue loop to converge the dataflow analysis without much thought, with a FIFO workqueue. Any workqueue ordering will work and will converge to the same fixpoint (as long as we are operating on a lattice), but indeed some orderings will be more efficient, and a DFS-style (LIFO stack) workqueue will give us this property of converging inner loops first. In measurements, there doesn't seem to be much of a difference for small fuzz testcases, but this will likely matter more if/when we try to run the checker to validate register allocation on large functions.
This commit is contained in:
@@ -102,7 +102,6 @@ use crate::{
|
||||
};
|
||||
use fxhash::{FxHashMap, FxHashSet};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::collections::VecDeque;
|
||||
use std::default::Default;
|
||||
use std::hash::Hash;
|
||||
use std::result::Result;
|
||||
@@ -726,16 +725,14 @@ impl<'a, F: Function> Checker<'a, F> {
|
||||
|
||||
/// Perform the dataflow analysis to compute checker state at each BB entry.
|
||||
fn analyze(&mut self) {
|
||||
let mut queue = VecDeque::new();
|
||||
let mut queue = Vec::new();
|
||||
let mut queue_set = FxHashSet::default();
|
||||
for block in 0..self.f.num_blocks() {
|
||||
let block = Block::new(block);
|
||||
queue.push_back(block);
|
||||
queue_set.insert(block);
|
||||
}
|
||||
|
||||
queue.push(self.f.entry_block());
|
||||
queue_set.insert(self.f.entry_block());
|
||||
|
||||
while !queue.is_empty() {
|
||||
let block = queue.pop_front().unwrap();
|
||||
let block = queue.pop().unwrap();
|
||||
queue_set.remove(&block);
|
||||
let mut state = self.bb_in.get(&block).cloned().unwrap();
|
||||
trace!("analyze: block {} has state {:?}", block.index(), state);
|
||||
@@ -777,7 +774,7 @@ impl<'a, F: Function> Checker<'a, F> {
|
||||
);
|
||||
self.bb_in.insert(succ, new_state);
|
||||
if !queue_set.contains(&succ) {
|
||||
queue.push_back(succ);
|
||||
queue.push(succ);
|
||||
queue_set.insert(succ);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user