40 lines
1.5 KiB
Rust
40 lines
1.5 KiB
Rust
use crate::mir::function::MirFunction;
|
|
use crate::mir::verification::utils;
|
|
use crate::mir::verification_types::VerificationError;
|
|
|
|
/// Verify dominance: def must dominate use across blocks (Phi inputs excluded)
|
|
pub fn check_dominance(function: &MirFunction) -> Result<(), Vec<VerificationError>> {
|
|
if crate::config::env::verify_allow_no_phi() {
|
|
return Ok(());
|
|
}
|
|
let mut errors = Vec::new();
|
|
let def_block = utils::compute_def_blocks(function);
|
|
let dominators = utils::compute_dominators(function);
|
|
for (use_block_id, block) in &function.blocks {
|
|
for sp in block.all_spanned_instructions() {
|
|
if let crate::mir::MirInstruction::Phi { .. } = sp.inst {
|
|
continue;
|
|
}
|
|
for used_value in sp.inst.used_values() {
|
|
if let Some(&def_bb) = def_block.get(&used_value) {
|
|
if def_bb != *use_block_id {
|
|
let doms = dominators.get(use_block_id).unwrap();
|
|
if !doms.contains(&def_bb) {
|
|
errors.push(VerificationError::DominatorViolation {
|
|
value: used_value,
|
|
use_block: *use_block_id,
|
|
def_block: def_bb,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if errors.is_empty() {
|
|
Ok(())
|
|
} else {
|
|
Err(errors)
|
|
}
|
|
}
|