|
LLZK 2.1.1
An open-source IR for Zero Knowledge (ZK) circuits
|
llzk-opt is a version of the mlir-opt tool that supports passes on LLZK IR files. You can refer to the mlir-opt documentation for a general overview of the operation of *-opt tooling, but note that many options and passes available in mlir-opt are not available in llzk-opt. llzk-opt -h will show a list of all available flags and options.
Print the LLZK module's call graph.
Print the SCCs from the LLZK module's call graph.
Print constraint dependency graph for all LLZK structs.
Print interval analysis results for all LLZK structs.
Print the predecessors of all operations.
Print symbol definition tree.
Print symbol use graph.
_Replace separate @compute and @constrain functions in a struct with a single @product function_
Replace separate @compute and @constrain functions in a struct with a single @product function
Remove redundant operations
Remove llzk and arith dialect operations that produce the same results as previously executed operations.
Pass should be run after llzk-duplicate-read-write-elim for maximum effect.
Remove redundant reads and writes
Remove read and write operations to struct members and arrays that are redundant or unnecessary.
Checks that every struct member is written exactly once
This pass currently reports an error if any struct member may not be written exactly once (i.e. overwritten or left uninitialized), and does not attempt to perform any repairs (e.g. SSA-ifying overwritten struct members, or default-initializing unwritten members). This pass overapproximates conditionals, and can result in false positives.
_Fuse matching witness/constraint loops in a @product function_
Fuse matching witness/constraint loops in a @product function
Inlines nested structs (i.e., subcomponents).
This pass inlines nested structs (i.e., subcomponents) at struct-type members and at calls to the subcomponent compute/constrain functions. Inlining decisions are guided by the call graph of "constrain" functions.
The max-merge-complexity parameter can be used to limit the complexity of the resulting structs such that a potential inlining will not take place if doing so would push the sum of constraint and multiplications in the combined struct over the limit. The default value 0 indicates no limits which means all structs will be inlined into the Main struct.
This pass should be run after llzk-flatten to ensure structs do not have template parameters because structs with template parameters cannot (currently) be inlined. Inlining is also not (currently) supported for subcomponent structs stored in an array-type member.
This pass also assumes that all subcomponents that are created by calling a struct "@compute" function are ultimately written to exactly one member within the current struct.
Lower the degree of all polynomial equations to a specified maximum
Rewrites constraint expressions into an (observationally) equivalent system where the degree of every polynomial is less than or equal to the specified maximum.
High-degree subexpressions are factored into auxiliary struct members. The pass also recurses through degree-neutral roots such as felt.add, felt.sub, and felt.neg, so composite equality operands and struct constrain call arguments satisfy their degree bounds.
This pass is best used as part of the -llzk-full-poly-lowering pipeline, which includes additional cleanup passes to ensure correctness and optimal performance.
Remove unread discardable allocations and their dead stores
Remove ops with the selected allocator operation name when they are marked with MemAlloc<DiscardableAllocationResource>, the allocation has no reads, and every direct user is a discardable allocation accessor that can be erased as a dead store.
Remove unused member and struct declarations
Remove member and struct declarations that are unused within the current compilation unit. Note that this pass may cause linking issues with external modules that depend on any unused member and struct declarations from this compilation unit.
Pass should be run after llzk-duplicate-read-write-elim and llzk-duplicate-op-elim for maximum effect.
Converts scf.while loops to equivalent scf.for loops when possible
This pass identifies scf.while loops that have an induction variable and a uniform step, and converts them to equivalent scf.for loops, which are preferred by some analyses. This pass may introduce some spurious felt/index casts which should be cleaned up by –canonicalize.
Replace arrays with scalar values
Replace known-shape arrays with the proper number of scalar values
Remove empty templates
Performs the following transformations:
Flatten structs and unroll loops
Performs the following transformations:
Detect multiple and missing writes to the same member of a component.
Detect multiple and missing writes to the same member of a component.
Note that this is overapproximate (i.e., some writes may erroneously be flagged as overwrites, and some members may erroneously be marked unwritten).
llzk-witgen executes LLZK witness-generation logic for the concrete main component declared by llzk.main. It evaluates compute() and prints JSON for either the public outputs of the main component or the full generated witness signal set.
The --inputs file must contain a top-level JSON object or JSON array.
At the main boundary, llzk-witgen only supports felt and array<... x felt> inputs, due to the restrictions posed on llzk.main components. Field element values are accepted in the same JSON form used by the witgen tests, namely JSON integers or decimal strings.
llzk-witgen writes one JSON object to stdout. The exact shape depends on --output-scope.
llzk-witgen currently supports two execution backends:
The default backend is interpreter, as the execution-engine does not currently support all LLZK features due to existing lowering limitations (e.g., in the -llzk-flattening pass).
Before execution, llzk-witgen performs the preprocessing needed to make witness generation concrete and executable:
Template parameters and affine instantiations are therefore supported only when they can be fully resolved by the preprocessing pipeline before execution.
cmake --build <build dir> --target llzk-lsp-server will produce an LLZK-specific LSP server that can be used in an IDE to provide language information for LLZK. Refer to the MLIR LSP documentation for a more detailed explanation of the MLIR LSP tools and how to set them up in your IDE.