mir: extract CSE into passes::cse and wire it in optimizer. Behavior preserved (count-only, no SSA rewrites). Build + PyVM Stage-2 smokes PASS.
This commit is contained in:
@ -68,8 +68,11 @@ impl MirOptimizer {
|
|||||||
stats.dead_code_eliminated += eliminated;
|
stats.dead_code_eliminated += eliminated;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass 2: Pure instruction CSE (Common Subexpression Elimination)
|
// Pass 2: Pure instruction CSE (modularized)
|
||||||
stats.merge(self.common_subexpression_elimination(module));
|
{
|
||||||
|
let eliminated = crate::mir::passes::cse::eliminate_common_subexpressions(module);
|
||||||
|
stats.cse_eliminated += eliminated;
|
||||||
|
}
|
||||||
|
|
||||||
// Pass 3: Pure instruction reordering for better locality
|
// Pass 3: Pure instruction reordering for better locality
|
||||||
stats.merge(self.reorder_pure_instructions(module));
|
stats.merge(self.reorder_pure_instructions(module));
|
||||||
|
|||||||
56
src/mir/passes/cse.rs
Normal file
56
src/mir/passes/cse.rs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
//! Common Subexpression Elimination (CSE) for pure MIR instructions.
|
||||||
|
//!
|
||||||
|
//! Note: Current implementation mirrors the prior monolithic behavior and
|
||||||
|
//! counts eliminations without rewriting uses (SSA update is TODO). This keeps
|
||||||
|
//! behavior identical while modularizing the pass for future enhancement.
|
||||||
|
|
||||||
|
use crate::mir::{MirInstruction, MirModule, MirFunction, ValueId};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
/// Run CSE across the module. Returns the number of eliminated expressions.
|
||||||
|
pub fn eliminate_common_subexpressions(module: &mut MirModule) -> usize {
|
||||||
|
let mut eliminated = 0usize;
|
||||||
|
for (_name, func) in module.functions.iter_mut() {
|
||||||
|
eliminated += cse_in_function(func);
|
||||||
|
}
|
||||||
|
eliminated
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cse_in_function(function: &mut MirFunction) -> usize {
|
||||||
|
let mut expression_map: HashMap<String, ValueId> = HashMap::new();
|
||||||
|
let mut eliminated = 0usize;
|
||||||
|
|
||||||
|
for (_bid, block) in &mut function.blocks {
|
||||||
|
for inst in &mut block.instructions {
|
||||||
|
if inst.effects().is_pure() {
|
||||||
|
let key = instruction_key(inst);
|
||||||
|
if let Some(&existing) = expression_map.get(&key) {
|
||||||
|
if let Some(dst) = inst.dst_value() {
|
||||||
|
// Count as eliminated; rewriting uses is a future improvement.
|
||||||
|
let _ = (existing, dst); // keep variables referenced
|
||||||
|
eliminated += 1;
|
||||||
|
}
|
||||||
|
} else if let Some(dst) = inst.dst_value() {
|
||||||
|
expression_map.insert(key, dst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eliminated
|
||||||
|
}
|
||||||
|
|
||||||
|
fn instruction_key(i: &MirInstruction) -> String {
|
||||||
|
match i {
|
||||||
|
MirInstruction::Const { value, .. } => format!("const_{:?}", value),
|
||||||
|
MirInstruction::BinOp { op, lhs, rhs, .. } =>
|
||||||
|
format!("binop_{:?}_{}_{}", op, lhs.as_u32(), rhs.as_u32()),
|
||||||
|
MirInstruction::Compare { op, lhs, rhs, .. } =>
|
||||||
|
format!("cmp_{:?}_{}_{}", op, lhs.as_u32(), rhs.as_u32()),
|
||||||
|
MirInstruction::Call { func, args, .. } => {
|
||||||
|
let args_str = args.iter().map(|v| v.as_u32().to_string()).collect::<Vec<_>>().join(",");
|
||||||
|
format!("call_{}_{}", func.as_u32(), args_str)
|
||||||
|
}
|
||||||
|
other => format!("other_{:?}", other),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -5,6 +5,7 @@ pub mod type_hints;
|
|||||||
pub mod escape;
|
pub mod escape;
|
||||||
pub mod method_id_inject;
|
pub mod method_id_inject;
|
||||||
pub mod dce;
|
pub mod dce;
|
||||||
|
pub mod cse;
|
||||||
|
|
||||||
/// Minimal pass trait for future expansion. Currently unused by the main
|
/// Minimal pass trait for future expansion. Currently unused by the main
|
||||||
/// optimizer pipeline but provided to guide modularization.
|
/// optimizer pipeline but provided to guide modularization.
|
||||||
|
|||||||
Reference in New Issue
Block a user