use synth_cfg::CfgBuilder;
use synth_opt::{
AlgebraicSimplification, CommonSubexpressionElimination, ConstantFolding, DeadCodeElimination,
Instruction, Opcode, PassManager, PeepholeOptimization, Reg,
};
fn main() {
println!("=== Synth Optimization Pipeline Example ===\n");
let mut builder = CfgBuilder::new();
for _ in 0..15 {
builder.add_instruction();
}
let mut cfg = builder.build();
let mut instructions = vec![
Instruction {
id: 0,
opcode: Opcode::Const {
dest: Reg(0),
value: 100,
},
block_id: 0,
is_dead: false,
},
Instruction {
id: 1,
opcode: Opcode::Const {
dest: Reg(0),
value: 5,
},
block_id: 0,
is_dead: false,
},
Instruction {
id: 2,
opcode: Opcode::Const {
dest: Reg(1),
value: 10,
},
block_id: 0,
is_dead: false,
},
Instruction {
id: 3,
opcode: Opcode::Const {
dest: Reg(2),
value: 20,
},
block_id: 0,
is_dead: false,
},
Instruction {
id: 4,
opcode: Opcode::Add {
dest: Reg(3),
src1: Reg(1),
src2: Reg(2),
},
block_id: 0,
is_dead: false,
},
Instruction {
id: 5,
opcode: Opcode::Const {
dest: Reg(4),
value: 0,
},
block_id: 0,
is_dead: false,
},
Instruction {
id: 6,
opcode: Opcode::Add {
dest: Reg(5),
src1: Reg(3),
src2: Reg(4),
},
block_id: 0,
is_dead: false,
},
Instruction {
id: 7,
opcode: Opcode::Mul {
dest: Reg(6),
src1: Reg(0),
src2: Reg(4),
},
block_id: 0,
is_dead: false,
},
Instruction {
id: 8,
opcode: Opcode::Add {
dest: Reg(7),
src1: Reg(1),
src2: Reg(2),
},
block_id: 0,
is_dead: false,
},
Instruction {
id: 9,
opcode: Opcode::Sub {
dest: Reg(8),
src1: Reg(3),
src2: Reg(3),
},
block_id: 0,
is_dead: false,
},
];
println!("Original program:");
print_program(&instructions);
let mut manager = PassManager::new()
.add_pass(PeepholeOptimization::new())
.add_pass(ConstantFolding::new())
.add_pass(AlgebraicSimplification::new())
.add_pass(CommonSubexpressionElimination::new())
.add_pass(DeadCodeElimination::new())
.with_max_iterations(10);
println!("\n=== Running Optimization Pipeline ===");
let result = manager.run(&mut cfg, &mut instructions);
println!("\nOptimization Results:");
println!(" Changed: {}", result.changed);
println!(" Removed: {} instructions", result.removed_count);
println!(" Modified: {} instructions", result.modified_count);
println!(" Added: {} instructions", result.added_count);
println!("\nOptimized program:");
print_program(&instructions);
println!("\n=== Optimizations Applied ===");
println!("1. Peephole: Eliminated redundant const to r0");
println!("2. Constant Folding: 10 + 20 = 30");
println!("3. Algebraic: r3 + 0 simplified");
println!("4. Algebraic: r0 * 0 = 0");
println!("5. CSE: Duplicate add eliminated");
println!("6. Algebraic: r3 - r3 = 0");
println!("\n=== Benefits ===");
let original_count = instructions.len();
let optimized_count = instructions.iter().filter(|i| !i.is_dead).count();
let reduction = ((original_count - optimized_count) as f64 / original_count as f64) * 100.0;
println!(
"Code size: {} → {} instructions ({:.1}% reduction)",
original_count, optimized_count, reduction
);
}
fn print_program(instructions: &[Instruction]) {
for (i, inst) in instructions.iter().enumerate() {
if inst.is_dead {
println!(" {:2}: {:?} [DEAD]", i, inst.opcode);
} else {
println!(" {:2}: {:?}", i, inst.opcode);
}
}
}