open_vaf/analysis/data_flow/framework/
engine.rs1use std::mem::swap;
10
11use crate::analysis::data_flow::framework::{Analysis, DataFlowGraph, Direction};
12use crate::data_structures::BitSet;
13use crate::ir::cfg::ControlFlowGraph;
14use log::*;
15
16pub struct Engine<'lt, A: Analysis<'lt>> {
17 pub analysis: &'lt mut A,
18 pub dfg: DataFlowGraph<A::SetType>,
19 pub cfg: &'lt ControlFlowGraph,
20}
21
22impl<'lt, A: Analysis<'lt>> Engine<'lt, A> {
23 pub fn new(cfg: &'lt ControlFlowGraph, analysis: &'lt mut A) -> Self {
24 Self {
25 dfg: DataFlowGraph::new(analysis.max_idx(), cfg),
26 analysis,
27 cfg,
28 }
29 }
30
31 pub fn iterate_to_fixpoint(mut self) -> DataFlowGraph<A::SetType> {
32 let mut worklist =
33 <<A as Analysis<'lt>>::Direction as Direction<'lt>>::inital_work_queue(self.cfg);
34 let mut temporary_set = BitSet::new_empty(self.analysis.max_idx());
35 trace!("Data Flow Engine: Starting with worklist: {:?}", worklist);
36 while let Some(bb) = worklist.pop() {
37 trace!("Data Flow Engine: Processing {:?}", bb);
38 self.analysis.transfer_function(
39 &self.dfg.in_sets[bb],
40 &mut temporary_set,
41 bb,
42 self.cfg,
43 );
44 if temporary_set != self.dfg.out_sets[bb] {
45 swap(&mut temporary_set, &mut self.dfg.out_sets[bb]);
46
47 A::Direction::propagate_result(bb, self.cfg, |dst| {
48 worklist.insert(dst);
49 self.analysis
50 .join(&mut self.dfg.in_sets[dst], &self.dfg.out_sets[bb])
51 });
52 }
53 }
54 self.dfg
55 }
56}