Add SSA validator to end of optimization pipeline.
This commit is contained in:
parent
958269be23
commit
63f5eca6a9
|
@ -135,6 +135,7 @@ impl FunctionBody {
|
||||||
let cfg = crate::cfg::CFGInfo::new(self);
|
let cfg = crate::cfg::CFGInfo::new(self);
|
||||||
crate::passes::basic_opt::gvn(self, &cfg);
|
crate::passes::basic_opt::gvn(self, &cfg);
|
||||||
crate::passes::resolve_aliases::run(self);
|
crate::passes::resolve_aliases::run(self);
|
||||||
|
crate::passes::ssa::run(self, &cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn convert_to_max_ssa(&mut self) {
|
pub fn convert_to_max_ssa(&mut self) {
|
||||||
|
|
|
@ -6,3 +6,4 @@ pub mod empty_blocks;
|
||||||
pub mod maxssa;
|
pub mod maxssa;
|
||||||
pub mod resolve_aliases;
|
pub mod resolve_aliases;
|
||||||
pub mod trace;
|
pub mod trace;
|
||||||
|
pub mod ssa;
|
||||||
|
|
56
src/passes/ssa.rs
Normal file
56
src/passes/ssa.rs
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
//! SSA validation.
|
||||||
|
|
||||||
|
use crate::cfg::CFGInfo;
|
||||||
|
use crate::entity::*;
|
||||||
|
use crate::ir::*;
|
||||||
|
|
||||||
|
struct DefBlocks {
|
||||||
|
def_block: PerEntity<Value, Block>,
|
||||||
|
}
|
||||||
|
impl DefBlocks {
|
||||||
|
fn compute(body: &FunctionBody) -> Self {
|
||||||
|
let mut def_block = PerEntity::default();
|
||||||
|
for (block, data) in body.blocks.entries() {
|
||||||
|
for &(_, param) in &data.params {
|
||||||
|
def_block[param] = block;
|
||||||
|
}
|
||||||
|
for &inst in &data.insts {
|
||||||
|
def_block[inst] = block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DefBlocks { def_block }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(body: &FunctionBody, cfg: &CFGInfo) {
|
||||||
|
let def_blocks = DefBlocks::compute(body);
|
||||||
|
|
||||||
|
for (block, data) in body.blocks.entries() {
|
||||||
|
let validate = |value| {
|
||||||
|
let value = body.resolve_alias(value);
|
||||||
|
let def_block = def_blocks.def_block[value];
|
||||||
|
assert!(cfg.dominates(def_block, block));
|
||||||
|
};
|
||||||
|
|
||||||
|
for &inst in &data.insts {
|
||||||
|
match &body.values[inst] {
|
||||||
|
&ValueDef::Operator(_, ref args, _) => {
|
||||||
|
for &arg in args {
|
||||||
|
validate(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&ValueDef::PickOutput(val, _, _) => {
|
||||||
|
validate(val);
|
||||||
|
}
|
||||||
|
&ValueDef::Trace(_, ref args) => {
|
||||||
|
for &arg in args {
|
||||||
|
validate(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&ValueDef::Alias(..) => {}
|
||||||
|
&ValueDef::None | &ValueDef::Placeholder(_) | &ValueDef::BlockParam(..) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.terminator.visit_uses(|u| validate(u));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue