diff --git a/src/ir/display.rs b/src/ir/display.rs index fe7edc5..73f9701 100644 --- a/src/ir/display.rs +++ b/src/ir/display.rs @@ -29,6 +29,20 @@ impl<'a> Display for FunctionBodyDisplay<'a> { ret_tys.join(", ") )?; + for (value, value_def) in self.0.values.entries() { + match value_def { + ValueDef::Operator(..) | ValueDef::BlockParam(..) => {} + ValueDef::Alias(_alias_target) => {} + ValueDef::PickOutput(val, idx, ty) => { + writeln!(f, "{} {} = {}.{} # {}", self.1, value, val, idx, ty)? + } + ValueDef::Placeholder(ty) => { + writeln!(f, "{} {} = placeholder # {}", self.1, value, ty)? + } + ValueDef::None => panic!(), + } + } + for (block_id, block) in self.0.blocks.entries() { let block_params = block .params @@ -76,9 +90,6 @@ impl<'a> Display for FunctionBodyDisplay<'a> { ValueDef::PickOutput(val, idx, ty) => { writeln!(f, "{} {} = {}.{} # {}", self.1, inst, val, idx, ty)?; } - ValueDef::Alias(v) => { - writeln!(f, "{} {} <- {}", self.1, inst, v)?; - } _ => unreachable!(), } } diff --git a/src/ir/module.rs b/src/ir/module.rs index 40846fa..a05dd92 100644 --- a/src/ir/module.rs +++ b/src/ir/module.rs @@ -98,7 +98,8 @@ impl<'a> Module<'a> { let mut module = frontend::wasm_to_ir(bytes)?; for func_decl in module.funcs.values_mut() { if let Some(body) = func_decl.body_mut() { - crate::passes::rpo::reorder_into_rpo(body); + crate::passes::rpo::run(body); + crate::passes::resolve_aliases::run(body); } } Ok(module) diff --git a/src/ir/value.rs b/src/ir/value.rs index 64565d9..8a6df73 100644 --- a/src/ir/value.rs +++ b/src/ir/value.rs @@ -1,13 +1,15 @@ -use super::{Block, Value, Type}; +use super::{Block, Type, Value}; use crate::Operator; -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] pub enum ValueDef { BlockParam(Block, usize, Type), Operator(Operator, Vec, Vec), PickOutput(Value, usize, Type), Alias(Value), Placeholder(Type), + #[default] + None, } impl ValueDef { @@ -22,6 +24,7 @@ impl ValueDef { &ValueDef::PickOutput(from, ..) => f(from), &ValueDef::Alias(value) => f(value), &ValueDef::Placeholder(_) => {} + &ValueDef::None => panic!(), } } @@ -36,6 +39,7 @@ impl ValueDef { &mut ValueDef::PickOutput(ref mut from, ..) => f(from), &mut ValueDef::Alias(ref mut value) => f(value), &mut ValueDef::Placeholder(_) => {} + &mut ValueDef::None => panic!(), } } } diff --git a/src/lib.rs b/src/lib.rs index 43f7c2e..d1b1464 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,8 +12,7 @@ mod frontend; mod ir; mod op_traits; mod ops; -mod passes; -pub use passes::rpo::reorder_into_rpo; +pub mod passes; pub use ir::*; pub use ops::Operator; diff --git a/src/passes.rs b/src/passes.rs index 20ce41e..ed419f5 100644 --- a/src/passes.rs +++ b/src/passes.rs @@ -1,3 +1,4 @@ //! Passes. pub mod rpo; +pub mod resolve_aliases; diff --git a/src/passes/resolve_aliases.rs b/src/passes/resolve_aliases.rs new file mode 100644 index 0000000..8d254b2 --- /dev/null +++ b/src/passes/resolve_aliases.rs @@ -0,0 +1,33 @@ +//! Resolve all aliases. + +use crate::{FunctionBody, ValueDef}; + +pub fn run(body: &mut FunctionBody) { + for value in body.values.iter() { + let mut value_def = std::mem::take(&mut body.values[value]); + match &mut value_def { + ValueDef::Operator(_op, args, _tys) => { + for arg in args { + *arg = body.resolve_alias(*arg); + } + } + ValueDef::PickOutput(val, _idx, _ty) => { + *val = body.resolve_alias(*val); + } + ValueDef::Alias(val) => { + *val = body.resolve_alias(*val); + } + _ => {} + } + body.values[value] = value_def; + } + let mut blocks = std::mem::take(&mut body.blocks); + for block in blocks.values_mut() { + block.terminator.update_targets(|target| { + for arg in &mut target.args { + *arg = body.resolve_alias(*arg); + } + }); + } + body.blocks = blocks; +} diff --git a/src/passes/rpo.rs b/src/passes/rpo.rs index 9533174..faa66bd 100644 --- a/src/passes/rpo.rs +++ b/src/passes/rpo.rs @@ -136,7 +136,7 @@ impl RPO { } } -pub fn reorder_into_rpo(body: &mut FunctionBody) { +pub fn run(body: &mut FunctionBody) { let rpo = RPO::compute(body); // Remap entry block. body.entry = rpo.map_block(body.entry);