use crate::functions::dom_children::dom_children;
use crate::functions::successors::successors;
use crate::macros::codegen_assert::CODEGEN_ASSERT;
use crate::records::cfg_info::CfgInfo;
use crate::records::idf_context::IdfContext;
use crate::records::ir_function::IrFunction;
pub fn compute_iterated_dominance_frontier_for_defs(
ctx: &mut IdfContext,
function: &IrFunction,
def_blocks: &Vec<u32>,
live_in_blocks: &Vec<u32>,
) {
CODEGEN_ASSERT!(!function.cfg.dom_ordering.is_empty());
CODEGEN_ASSERT!(ctx.queue.is_empty());
CODEGEN_ASSERT!(ctx.worklist.is_empty());
ctx.idf.clear();
ctx.visits.clear();
ctx.visits
.resize(function.blocks.len() as usize, Default::default());
for &def_block in def_blocks.iter() {
let ordering = function.cfg.dom_ordering[def_block as usize];
ctx.queue
.push(crate::records::block_and_ordering::BlockAndOrdering {
block_idx: def_block,
ordering,
});
}
while !ctx.queue.is_empty() {
let root = ctx.queue.pop().unwrap();
CODEGEN_ASSERT!(ctx.worklist.is_empty());
ctx.worklist.push(root.block_idx);
ctx.visits[root.block_idx as usize].seen_in_worklist = true;
while !ctx.worklist.is_empty() {
let block_idx = ctx.worklist.pop().unwrap();
for succ_idx in successors(&function.cfg, block_idx) {
let succ_ordering = function.cfg.dom_ordering[succ_idx as usize];
if succ_ordering.depth > root.ordering.depth {
continue;
}
if ctx.visits[succ_idx as usize].seen_in_queue {
continue;
}
ctx.visits[succ_idx as usize].seen_in_queue = true;
if !live_in_blocks.contains(&succ_idx) {
continue;
}
ctx.idf.push(succ_idx);
if !def_blocks.contains(&succ_idx) {
ctx.queue
.push(crate::records::block_and_ordering::BlockAndOrdering {
block_idx: succ_idx,
ordering: succ_ordering,
});
}
}
for dom_child_idx in dom_children(&function.cfg, block_idx) {
if ctx.visits[dom_child_idx as usize].seen_in_worklist {
continue;
}
ctx.visits[dom_child_idx as usize].seen_in_worklist = true;
ctx.worklist.push(dom_child_idx);
}
}
}
}