qat.experimental.dialect.q1_scf.transforms.lower_to_cf module
Lower structured q1_scf regions to a q1_cf block CFG.
q1_scf expresses control flow with structured containers: an if conditional
and while/for loops whose bodies are regions terminated by condition and
yield. q1_cf is the layer below, an unstructured CFG of basic blocks wired by
branch terminators. This pass expands each container into blocks and selects the
matching q1_cf terminator, carrying the source predicate across unchanged.
Each construct is lowered by splitting its parent block into the ops preceding it and a continuation holding the ops that follow. The container regions inline between the two, and the branch terminators thread live values as successor block arguments:
q1_scf.ifbecomes a conditional branch intothen/elseblocks, both rejoining the continuation. Regionyieldoperands become the continuation’s block arguments, which stand in for the conditional’s results.q1_scf.whilebecomes a header block that tests the condition and branches to the body or the exit, with the body’syieldforming the back-edge to the header.q1_scf.forbecomes a self-looping body whose terminator isq1_cf.loop_branch, the native decrement-and-branch. The induction counter, its back-edge argument, and the loop-branch counter operand are one value, decremented in place each iteration.
The lowering is register-neutral. It introduces no new register values: every value a
branch forwards already exists as an SSA value at the q1_scf level. Conditions carry
a predicate over q1.reg operands rather than a boolean, so predicate selection is a
direct match with no value to materialise. Whether a pre-allocation body still needs
relocation is left to register allocation.
A q1_cf conditional branch falls through to its else successor, which its
verifier requires to be the branch block’s layout neighbour. The lowering honours this
by placing the else block, or a forwarding stub for edges that leave through the
continuation, immediately after the branch.
Reference: https://docs.qblox.com/en/main/products/qblox_instruments/q1/index.html
- class ForLowering
Bases:
RewritePatternLower
q1_scf.forto a self-looping body terminated byloop_branch.The counted loop maps onto the native decrement-and-branch. The body runs at least once, so a well-formed
q1_scf.forhas a positive iteration count; a zero-trip loop is not expressible on the hardware and is expected to be removed upstream.- match_and_rewrite(op: Operation, rewriter: PatternRewriter) None
Match an operation, and optionally perform a rewrite using the rewriter.
- Return type:
None
- class IfLowering
Bases:
RewritePatternLower
q1_scf.ifto a conditional branch overthen/elseblocks.- match_and_rewrite(op: Operation, rewriter: PatternRewriter) None
Match an operation, and optionally perform a rewrite using the rewriter.
- Return type:
None
- class LowerQ1ScfToQ1CfPass
Bases:
ModulePassLower every
q1_scfcontainer in the module to aq1_cfblock CFG.- apply(ctx, op)
Run lowering in a fixed inside-out order across structured forms.
Rewrites run as
if -> while -> forin one greedy walk so nested containers dissolve from the smallest structured region toward enclosing loop forms.- Return type:
None
- name: ClassVar[str] = 'lower-q1-scf-to-q1-cf'