diff --git a/src/frontend.rs b/src/frontend.rs index 356db26..a4cc719 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -385,6 +385,7 @@ impl LocalTracker { } let placeholder = body.add_placeholder(ty); + body.mark_value_as_local(placeholder, local); self.block_end .entry(at_block) .or_insert_with(|| FxHashMap::default()) @@ -393,7 +394,15 @@ impl LocalTracker { self.compute_blockparam(body, at_block, local, placeholder); placeholder } else { + if let Some(end_mapping) = self.block_end.get(&at_block) { + if let Some(&value) = end_mapping.get(&local) { + log::trace!(" -> from end_mapping: {:?}", value); + return value; + } + } + let placeholder = body.add_placeholder(ty); + body.mark_value_as_local(placeholder, local); self.block_end .entry(at_block) .or_insert_with(|| FxHashMap::default()) diff --git a/src/ir/display.rs b/src/ir/display.rs index c7da2f9..39f6ff7 100644 --- a/src/ir/display.rs +++ b/src/ir/display.rs @@ -101,7 +101,15 @@ impl<'a> Display for FunctionBodyDisplay<'a> { .collect::>() .join(", ") )?; + for (_, param) in &block.params { + if let Some(local) = self.0.value_locals[*param] { + writeln!(f, "{} # {}: {}", self.1, param, local)?; + } + } for &inst in &block.insts { + if let Some(local) = self.0.value_locals[inst] { + writeln!(f, "{} # {}: {}", self.1, inst, local)?; + } match &self.0.values[inst] { ValueDef::Operator(op, args, tys) => { let args = args.iter().map(|&v| format!("{}", v)).collect::>(); diff --git a/src/ir/func.rs b/src/ir/func.rs index e88bee6..359a0dd 100644 --- a/src/ir/func.rs +++ b/src/ir/func.rs @@ -47,6 +47,8 @@ pub struct FunctionBody { pub values: EntityVec, /// Blocks in which values are computed. Each may be `Block::invalid()` if not placed. pub value_blocks: PerEntity, + /// Wasm locals that values correspond to, if any. + pub value_locals: PerEntity>, } impl FunctionBody { @@ -71,6 +73,7 @@ impl FunctionBody { blocks, values, value_blocks, + value_locals: PerEntity::default(), } } @@ -142,6 +145,10 @@ impl FunctionBody { self.values[value] = ValueDef::BlockParam(block, index, ty); } + pub fn mark_value_as_local(&mut self, value: Value, local: Local) { + self.value_locals[value] = Some(local); + } + pub fn resolve_and_update_alias(&mut self, value: Value) -> Value { let to = self.resolve_alias(value); // Short-circuit the chain, union-find-style.