IR & Optimization
The IR (intermediate representation) is the bridge between the parser’s AST and the constraint backends. It uses Static Single Assignment form — every variable is defined exactly once.
SSA Variables
Section titled “SSA Variables”struct SsaVar(pub u32);Each SsaVar is a unique, immutable variable identified by an integer. The IrProgram allocates them sequentially via fresh_var().
Instructions
Section titled “Instructions”The IR has 19 instruction variants. Each defines exactly one result variable:
| Instruction | Fields | Description |
|---|---|---|
Const | value: FieldElement | Compile-time constant |
Input | name, visibility | Circuit input (public or witness) |
Arithmetic
Section titled “Arithmetic”| Instruction | Description | R1CS Cost |
|---|---|---|
Add(lhs, rhs) | Field addition | 0 (LC arithmetic) |
Sub(lhs, rhs) | Field subtraction | 0 |
Mul(lhs, rhs) | Field multiplication | 1 constraint |
Div(lhs, rhs) | Field division | 2 constraints |
Neg(operand) | Field negation | 0 |
Control Flow
Section titled “Control Flow”| Instruction | Description | R1CS Cost |
|---|---|---|
Mux(cond, if_true, if_false) | Boolean selector | 2 constraints |
Assertions
Section titled “Assertions”| Instruction | Description | R1CS Cost |
|---|---|---|
AssertEq(lhs, rhs) | Enforce equality | 1 constraint |
Assert(operand) | Enforce operand == 1 | 2 constraints |
RangeCheck(operand, bits) | Enforce 0 ≤ operand < 2^bits | bits+1 constraints |
Boolean Logic
Section titled “Boolean Logic”| Instruction | Description | R1CS Cost |
|---|---|---|
Not(operand) | 1 − operand | 1 constraint |
And(lhs, rhs) | lhs × rhs | 3 constraints |
Or(lhs, rhs) | lhs + rhs − lhs×rhs | 3 constraints |
Comparisons
Section titled “Comparisons”| Instruction | Description | R1CS Cost |
|---|---|---|
IsEq(lhs, rhs) | 1 if equal, 0 otherwise | 2 constraints |
IsNeq(lhs, rhs) | 1 if not equal, 0 otherwise | 2 constraints |
IsLt(lhs, rhs) | 1 if lhs < rhs | ~760 constraints |
IsLe(lhs, rhs) | 1 if lhs ≤ rhs | ~760 constraints |
Cryptographic
Section titled “Cryptographic”| Instruction | Description | R1CS Cost |
|---|---|---|
PoseidonHash(left, right) | Poseidon 2-to-1 hash | 361 constraints |
IrProgram
Section titled “IrProgram”struct IrProgram { instructions: Vec<Instruction>, next_var: u32, var_names: HashMap<SsaVar, String>, // source names for errors var_types: HashMap<SsaVar, IrType>, // Field or Bool}The program is a flat list of instructions — no phi-nodes needed because circuits have no dynamic branching. Type metadata (IrType::Field or IrType::Bool) is set by type annotations and used by backends to skip redundant boolean enforcement.
IR Lowering
Section titled “IR Lowering”IrLowering converts the AST into an IrProgram:
// With explicit declarationsIrLowering::lower_circuit(source, public_vars, witness_vars) -> IrProgram
// With in-source declarationsIrLowering::lower_self_contained(source) -> (pub_names, wit_names, IrProgram)Key Lowering Rules
Section titled “Key Lowering Rules”letbindings are aliases — no instruction emitted, the name maps to an existingSsaVarif/elsecompiles toMux(cond, then_val, else_val)forloops are statically unrolled (max 10,000 iterations)- Function calls are inlined at each call site with recursion detection via
call_stack - Arrays are
EnvValue::Array(Vec<SsaVar>)— indexing must be compile-time constant len(arr)is resolved at compile time to a constant
Environment
Section titled “Environment”Variables are tracked via HashMap<String, EnvValue>:
enum EnvValue { Scalar(SsaVar), Array(Vec<SsaVar>),}Optimization Passes
Section titled “Optimization Passes”The optimizer runs three passes sequentially via passes::optimize(&mut program):
1. Constant Folding (const_fold)
Section titled “1. Constant Folding (const_fold)”A forward O(n) pass that evaluates operations on known constants:
- Arithmetic:
Const(3) + Const(5)→Const(8) - Identity:
x * 1→x,x + 0→x - Annihilation:
x * 0→Const(0) - Self-operations:
x - x→Const(0),x / x→Const(1)(when x is a non-zero constant) - Boolean logic: folds
Not,And,Oron constant operands - Comparisons: folds
IsEq,IsNeq,IsLt,IsLeon constant operands (canonical limb comparison) - Range checks: verifies
RangeCheckon constants, replaces with pass-through
2. Dead Code Elimination (dce)
Section titled “2. Dead Code Elimination (dce)”A backward pass that removes instructions whose results are never used.
Eliminable (pure): Const, Add, Sub, Neg
Conservative (may have side effects or be expensive): Mul, Div, Mux, PoseidonHash, RangeCheck, Not, And, Or, IsEq, IsNeq, IsLt, IsLe, Assert
Never eliminated: AssertEq, Input, RangeCheck, Assert (side-effecting)
3. Boolean Propagation (bool_prop)
Section titled “3. Boolean Propagation (bool_prop)”A forward O(n) pass that computes the set of SSA variables proven to be boolean (0 or 1). The backends use this set to skip redundant boolean enforcement constraints.
Seeds (known boolean):
Const(0)andConst(1)- Comparison results:
IsEq,IsNeq,IsLt,IsLe RangeCheck(x, 1)targetsAssertoperands and results- Variables with
IrType::Boolannotation
Propagation:
Not(x)→ result is boolean ifxis booleanAnd(a, b)→ result is boolean if both are booleanOr(a, b)→ result is boolean if both are booleanMux(c, t, f)→ result is boolean if bothtandfare boolean
Taint Analysis (taint)
Section titled “Taint Analysis (taint)”An additional analysis pass (not part of optimize()) that runs as a diagnostic:
- Forward taint propagation: marks all SSA variables derived from inputs
- Backward constraint reachability: marks variables used by assertions/constraints
Warnings:
UnderConstrained: an input influences no constraint — potential soundness issueUnusedInput: an input is declared but never used
IR Evaluator
Section titled “IR Evaluator”ir::eval::evaluate(program, inputs) provides concrete forward evaluation of an IrProgram:
evaluate(program: &IrProgram, inputs: &HashMap<String, FieldElement>) -> Result<HashMap<SsaVar, FieldElement>, EvalError>Used by compile_ir_with_witness() for early validation before constraint generation. Error variants: MissingInput, DivisionByZero, AssertionFailed, AssertEqFailed, RangeCheckFailed, UndefinedVar.
Source Files
Section titled “Source Files”| Component | File |
|---|---|
| Types | ir/src/types.rs |
| Lowering | ir/src/lower.rs |
| Evaluator | ir/src/eval.rs |
| Constant Folding | ir/src/passes/const_fold.rs |
| Dead Code Elimination | ir/src/passes/dce.rs |
| Boolean Propagation | ir/src/passes/bool_prop.rs |
| Taint Analysis | ir/src/passes/taint.rs |