Compile circom code to LLVM IR.
NOTICE Use Ninja
as the build tool default, so you need to install one before building LLVM.
If you don't have, please follow the offcial guide from LLVM at: https://github.com/llvm/llvm-project/tree/release/13.x .
NOTICE The building command used by us is different from the standard one.
NOTICE The path/to/llvm-project should be an abstract path, such as /User/You/app/llvm-project.
NOTICE DLLVM_TARGETS_TO_BUILD depends on your architecture.
git clone --depth 1 --branch release/13.x [email protected]:llvm/llvm-project.git
cd ./llvm-project
cmake -S llvm -B build -G Ninja \
-DLLVM_TARGETS_TO_BUILD="{X86||ARM||RISCV}" \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_PARALLEL_LINK_JOBS=1 \
-DLLVM_OPTIMIZED_TABLEGEN=ON \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake --build build/
export LLVM_PATH=path/to/llvm-project/build
export PATH=$PATH:$LLVM_PATH/bin
export LLVM_SYS_130_PREFIX=$LLVM_PATH
This repo works on rustc & cargo 1.64.0
, and all of the crates dependencies will be installed automatically.
- One circom file will => one LLVM
.ll
file, with a module namedmain
. - All functions and templates are concluded into the
.ll
file. - If the main component isn't provided:
One circom template => two LLVM functions:
Name the parameters of the circom template as
p
Build(p)
=> Returns an LLVM struct represents the template, named ass
.Init(p, s)
=> Executes the logic inside the template.
- Else, all possible instantiations will be collected, and for every instantiation, two functions mentioned before will be generated under that instantiation.
- One circom Function => one LLVM function.
- Collect and resolve dependencies.
- Infer types and collect all possible instantiations (if provided).
- Unroll all of the
while
loop andif-else
statements if the instantiation is provided. - Generate LLVM functions and instructions of circom functions.
- Generate LLVM functions of circom templates.
- Generate LLVM instructions of circom templates.
git clone https://github.com/Veridise/circom2llvm path/to/circom2llvm
cd path/to/circom2llvm
cargo build --bin=circom2llvm --package=circom2llvm
./target/debug/circom2llvm --input path/to/circomfile_or_dir --output path/to/output
- Critical variables and functions are named in
ir_generator/src/namer.rs
. - The IR is Load-Store format, you could transfer it to SSA format by mem2reg pass.
- The size of every dimension of the array is limited to a constant, the default is 256 and could be provided by the command line.
- Don't define a component variable without initializing it.
- Support the function interpretation during the instantiation.