101 lines
3.5 KiB
Rust
101 lines
3.5 KiB
Rust
use il::Instructions;
|
|
|
|
// Optimization pass modules
|
|
mod helpers;
|
|
mod leaf_function;
|
|
|
|
mod algebraic_simplification;
|
|
mod constant_propagation;
|
|
mod dead_code;
|
|
mod dead_store_elimination;
|
|
mod function_call_optimization;
|
|
mod label_resolution;
|
|
mod leaf_function_optimization;
|
|
mod peephole_optimization;
|
|
mod register_forwarding;
|
|
mod strength_reduction;
|
|
|
|
use algebraic_simplification::algebraic_simplification;
|
|
use constant_propagation::constant_propagation;
|
|
use dead_code::{remove_redundant_jumps, remove_redundant_moves, remove_unreachable_code};
|
|
use dead_store_elimination::dead_store_elimination;
|
|
use function_call_optimization::optimize_function_calls;
|
|
use label_resolution::resolve_labels;
|
|
use leaf_function_optimization::optimize_leaf_functions;
|
|
use peephole_optimization::peephole_optimization;
|
|
use register_forwarding::register_forwarding;
|
|
use strength_reduction::strength_reduction;
|
|
|
|
/// Entry point for the optimizer.
|
|
pub fn optimize<'a>(instructions: Instructions<'a>) -> Instructions<'a> {
|
|
let mut instructions = instructions.into_inner();
|
|
let mut changed = true;
|
|
let mut pass_count = 0;
|
|
const MAX_PASSES: usize = 10;
|
|
|
|
// Iterative passes for code simplification
|
|
while changed && pass_count < MAX_PASSES {
|
|
changed = false;
|
|
pass_count += 1;
|
|
|
|
// Pass 1: Constant Propagation
|
|
let (new_inst, c1) = constant_propagation(instructions);
|
|
instructions = new_inst;
|
|
changed |= c1;
|
|
|
|
// Pass 2: Register Forwarding (Intermediate Move Elimination)
|
|
let (new_inst, c2) = register_forwarding(instructions);
|
|
instructions = new_inst;
|
|
changed |= c2;
|
|
|
|
// Pass 3: Function Call Optimization (Remove unused push/pop around calls)
|
|
let (new_inst, c3) = optimize_function_calls(instructions);
|
|
instructions = new_inst;
|
|
changed |= c3;
|
|
|
|
// Pass 4: Leaf Function Optimization (Remove RA save/restore for leaf functions)
|
|
// This is separate from pass 3 as it deals with the function *definition*, not the call site.
|
|
let (new_inst, c4) = optimize_leaf_functions(instructions);
|
|
instructions = new_inst;
|
|
changed |= c4;
|
|
|
|
// Pass 5: Algebraic Simplification (Identity operations)
|
|
let (new_inst, c5) = algebraic_simplification(instructions);
|
|
instructions = new_inst;
|
|
changed |= c5;
|
|
|
|
// Pass 6: Strength Reduction (Replace expensive ops with cheaper ones)
|
|
let (new_inst, c6) = strength_reduction(instructions);
|
|
instructions = new_inst;
|
|
changed |= c6;
|
|
|
|
// Pass 7: Peephole Optimizations (Common patterns)
|
|
let (new_inst, c7) = peephole_optimization(instructions);
|
|
instructions = new_inst;
|
|
changed |= c7;
|
|
|
|
// Pass 8: Dead Store Elimination
|
|
let (new_inst, c8) = dead_store_elimination(instructions);
|
|
instructions = new_inst;
|
|
changed |= c8;
|
|
|
|
// Pass 9: Redundant Move Elimination
|
|
let (new_inst, c9) = remove_redundant_moves(instructions);
|
|
instructions = new_inst;
|
|
changed |= c9;
|
|
|
|
// Pass 10: Dead Code Elimination
|
|
let (new_inst, c10) = remove_unreachable_code(instructions);
|
|
instructions = new_inst;
|
|
changed |= c10;
|
|
}
|
|
|
|
// Final Pass: Resolve Labels to Line Numbers
|
|
let instructions = resolve_labels(instructions);
|
|
|
|
// Post-resolution Pass: Remove redundant jumps (must run after label resolution)
|
|
let (instructions, _) = remove_redundant_jumps(instructions);
|
|
|
|
Instructions::new(instructions)
|
|
}
|