Source layout¶
The project follows the layout MLIR and IREE use: public headers and TableGen
under include/, implementations mirrored under compiler/, tools separate.
include/hexir/
Dialect/Hexir/IR/ dialect header, HexirOps.td
Dialect/Hexir/Transforms/ passes that stay inside one dialect
Dialect/HexTIR/IR/
Dialect/LS/{IR,Transforms}/
Conversion/Passes.h passes that cross dialects
Pipelines/Pipelines.h pass ordering, and the Stage enum
Serialization/ the .hxb writer
Target/, Support/
compiler/
Dialect/<Name>/{IR,Transforms}/
Conversion/<A>To<B>/ one directory per conversion
Pipelines/ Serialization/ Target/ Support/
test/ compiler tests (need only `hexir`)
runtime/ the standalone C runtime
include/ src/ tools/
test/ artifact tests (run `hexir-run`)
tools/hexir/ the compiler driver
cmake/HexirLibrary.cmake the hexir_library() helper
lit.common.cfg.py shared test configuration
Transforms or Conversion?¶
This is the split that matters.
Transforms — the pass rewrites a dialect into itself. Shape inference and
partitioning stay in Dialect/Hexir/Transforms/.
Conversion — the pass turns one dialect into another. It lives in
Conversion/<A>To<B>/, named for the pair: HexirToLinalg, HexirToTIR,
HexirToLLVM, LSToLinalg, CudaToGpu.
Adding things¶
There is no glob. Each directory has a CMakeLists.txt calling
hexir_library(...), which builds a static library, wires its TableGen
dependencies, and registers itself in a global property that tools/hexir
links.
So:
a new file needs a line in its directory’s
CMakeLists.txta new directory needs an
add_subdirectoryin its parenta new
.tdfile needs an entry in the matchinginclude/.../IR/CMakeLists.txt
That is deliberate. Which module a file belongs to should be a decision, not a side effect of where it was saved.
Tests live with what they test¶
The compiler and the runtime each own a suite.
compiler/test/Needs only the
hexirbinary. Pipeline stages, dialects, placement.runtime/test/Runs
hexir-run. These are the artifact tests — they invokehexiras well, but what they assert is the runtime’s behaviour, and a test belongs with the binary whose behaviour it asserts.
make check-hexir # both
make check-hexir-compiler # one
make check-hexir-runtime # the other
Both suites load lit.common.cfg.py from the repo root, so build-directory and
tool discovery is written once and the two cannot drift apart.
The runtime is separate¶
runtime/ has its own CMakeLists.txt, builds standalone, and has no
include path into include/ and no MLIR or LLVM dependency. It is added from
the root build before the LLVM include directories so it cannot inherit them
by accident.
If the runtime ever needs to link an MLIR library, the layering is wrong.