use std::collections::{BTreeMap, BTreeSet};
use crate::decompiler::cfg::{BlockId, Cfg};
use super::traversal::idom_parent;
pub(super) fn compute_df(
cfg: &Cfg,
idom: &BTreeMap<BlockId, Option<BlockId>>,
) -> BTreeMap<BlockId, BTreeSet<BlockId>> {
let mut df: BTreeMap<BlockId, BTreeSet<BlockId>> = BTreeMap::new();
for block in cfg.blocks() {
df.insert(block.id, BTreeSet::new());
}
for block in cfg.blocks() {
let predecessors = cfg.predecessors(block.id);
if predecessors.len() < 2 {
continue;
}
let block_idom = idom.get(&block.id).copied().flatten();
for &pred in predecessors {
let mut runner = pred;
while Some(runner) != block_idom {
df.entry(runner).or_default().insert(block.id);
match idom_parent(idom, runner) {
Some(next) => runner = next,
None => break,
}
}
}
}
df
}