bloqade.lanes.rewrite.stackify
stackify¶
bloqade.lanes.rewrite.stackify
Stackification for single-block stack_move ir.Method.
stackify(method) is the primary entry point. It normalises a
stack_move ir.Method in place so that BytecodeEncoder can walk
the entry block in statement order and emit correct bytecode.
Restriction: the method must contain exactly one block with no branches or back-edges. This is enforced at runtime. All IR produced by the current compiler pipeline (Move → StackMove → Bytecode) satisfies this invariant.
Three sub-passes run in sequence:
Pass 1 — CloneConstants (RewriteRule via Walk)
For each consuming statement, clones every ConstantLike (Const*)
argument and inserts the clone immediately before the consumer in
stack-depth order: deepest arg first (highest stmt.args index),
top-of-stack arg last (index 0). The arg reference on the consumer
is updated to the clone in-place; the original becomes dead and is
removed by Pass 2.
Pass 2 — DCE Removes the now-dead original constant definitions left behind by Pass 1.
Pass 3 — Dup/Swap insertion
For each non-Pure SSA value consumed by more than one statement
(e.g. an AwaitMeasure result used by N GetItem statements),
inserts Dup/Swap instructions so the value remains available
for later consumers without violating the stack discipline.
For consumers c_0, …, c_{N-1} in block order the pattern emitted
before each non-last consumer c_k is:
Dup(live_copy) ← save a copy below c_k’s const args <const args of c_k> ← already placed by Pass 1 c_k(dup_result, …) ← consumes the dup Swap(c_k.result, live) ← out_top = live copy (for c_{k+1})
The last consumer uses out_top from the preceding Swap directly.