Getting Started

Prerequisites

Clone and build the project

git clone git@github.com:google/heir.git && cd heir
bazel build @heir//tools:heir-opt

Some passes in this repository require Yosys as a dependency (--yosys-optimizer). If you would like to skip Yosys and ABC compilation to speed up builds, use the following build setting:

bazel build --define=HEIR_NO_YOSYS=1 @heir//tools:heir-opt

Optional: Run the tests

bazel test @heir//...

Like above, run the following to skip tests that depend on Yosys:

bazel test --define=HEIR_NO_YOSYS=1 --test_tag_filters=-yosys @heir//...

Optional: Run heir-opt on an mlir file

HEIR comes with two central binaries, heir-opt for running optimization passes and dialect conversions, and heir-translate for backend code generation. To see the list of available passes in each one, run the binary with --help:

bazel run //tools:heir-opt -- --help
bazel run //tools:heir-translate -- --help

Once you’ve chosen a pass or --pass-pipeline to run, execute it on the desired file. For example, you can run a test file through heir-opt to see its output. Note that when the binary is run via bazel, you must pass absolute paths to input files. You can also access the underlying binary at bazel-bin/tools/heir-opt, provided it has already been built.

bazel run //tools:heir-opt -- \
  --comb-to-cggi -cse \
  $PWD/tests/comb_to_cggi/add_one.mlir

Developing in HEIR

We use pre-commit to manage a series of git pre-commit hooks for the project; for example, each time you commit code, the hooks will make sure that your C++ is formatted properly. If your code isn’t, the hook will format it, so when you try to commit the second time you’ll get past the hook.

All hooks are defined in .pre-commit-config.yaml. To install these hooks, run

pip install -r requirements-dev.txt

Then install the hooks to run automatically on git commit:

pre-commit install

To run them manually, run

pre-commit run --all-files

Creating a New Pass

The templates folder contains Python scripts to create boilerplate for new conversion or (dialect-specific) transform passes.

Conversion Pass

To create a new conversion pass, run a command similar to the following:

python templates/templates.py new_conversion_pass \
--source_dialect_name=CGGI \
--source_dialect_namespace=cggi \
--source_dialect_mnemonic=cggi \
--target_dialect_name=TfheRust \
--target_dialect_namespace=tfhe_rust \
--target_dialect_mnemonic=tfhe_rust

In order to build the resulting code, you must fix the labeled FIXMEs in the type converter and the op conversion patterns.

Transform Passes

To create a transform or rewrite pass that operates on a dialect, run a command similar to the following:

python templates/templates.py new_dialect_transform \
--pass_name=ForgetSecrets \
--pass_flag=forget-secrets \
--dialect_name=Secret \
--dialect_namespace=secret \
--force=false

If the transform does not operate from and to a specific dialect, use

python templates/templates.py new_transform \
--pass_name=ForgetSecrets \
--pass_flag=forget-secrets \
--force=false