Implement optimization pipeline: peephole, constant folding, strength reduction, DCE, tail calls

IR optimizer with 6 composable passes:
- Peephole: PushI32+Drop, Dup+Drop, Swap+Swap, Swap+Drop→Nip, identity ops
- Constant folding: binary (Add/Sub/Mul/And/Or/Xor/shifts/comparisons) + unary (Negate/Abs/Invert/ZeroEq/ZeroLt)
- Strength reduction: power-of-2 multiply→shift, PushI32(0)+Eq→ZeroEq
- Dead code elimination: truncate after Exit, constant-conditional If
- Tail call detection: last Call→TailCall when return stack balanced
- Compound ops: Over+Over→TwoDup, Drop+Drop→TwoDrop with optimized codegen

Dictionary hash index for O(1) word lookup during compilation.
wasmtime config: disable NaN canonicalization, enable module caching.
319 unit tests + 11 compliance, all passing.
This commit is contained in:
2026-04-01 21:50:08 +02:00
parent 8c38487390
commit 180982576e
5 changed files with 718 additions and 11 deletions
+27
View File
@@ -260,6 +260,33 @@ fn emit_op(f: &mut Function, op: &IrOp) {
push_via_local(f, 2);
}
IrOp::TwoDup => {
// ( a b -- a b a b ) : read top two cells, push copies
// Read b (at dsp) into local 0
f.instruction(&Instruction::GlobalGet(DSP))
.instruction(&Instruction::I32Load(MEM4))
.instruction(&Instruction::LocalSet(0));
// Read a (at dsp + 4) into local 1
f.instruction(&Instruction::GlobalGet(DSP))
.instruction(&Instruction::I32Const(CELL_SIZE as i32))
.instruction(&Instruction::I32Add)
.instruction(&Instruction::I32Load(MEM4))
.instruction(&Instruction::LocalSet(1));
// Push a then b
f.instruction(&Instruction::LocalGet(1));
push_via_local(f, 2);
f.instruction(&Instruction::LocalGet(0));
push_via_local(f, 2);
}
IrOp::TwoDrop => {
// ( a b -- ) : increment dsp by 2 cells
f.instruction(&Instruction::GlobalGet(DSP))
.instruction(&Instruction::I32Const(CELL_SIZE as i32 * 2))
.instruction(&Instruction::I32Add)
.instruction(&Instruction::GlobalSet(DSP));
}
// -- Arithmetic -----------------------------------------------------
IrOp::Add => emit_binary_commutative(f, &Instruction::I32Add),
IrOp::Mul => emit_binary_commutative(f, &Instruction::I32Mul),