Flame
Flame is a set of C# libraries and tools for reading, analyzing, optimizing, and writing managed code.
It is built around an SSA-based intermediate representation and includes:
- an IR designed for compiler analysis and transformation
- optimization passes such as inlining, scalar replacement, value numbering, control-flow simplification, and tail-recursion elimination
- analysis passes for dominators, liveness, value uses, predecessors, nullability, and more
- a CIL frontend and backend for translating between .NET IL and Flame IR
- command-line tools and examples built on top of the core libraries
Documentation:
Repository layout
The main projects live under src/:
Flame: core abstractions and type systemFlame.Compiler: IR, analyses, and optimization passesFlame.Clr: CIL import/export and CLR-specific supportFlame.Ir: IR serialization supportFlame.Llvm: LLVM backend piecesILOpt: CIL optimizer built on FlameIL2LLVM: IL-to-LLVM compilation toolExamples/Brainfuck: Brainfuck-to-CIL compiler exampleUnitTests: unit tests and tool tests
Tool-oriented test inputs live under tool-tests/.
Requirements
- .NET SDK 10.x
Build
From the repository root:
$ dotnet restore src/Flame.sln
$ dotnet build src/Flame.sln -c Debug
There is also a small make wrapper in src/Makefile:
$ make -C src debug
Test
The main test entrypoint is the portable suite, which excludes LLVM-dependent tests:
$ dotnet test src/UnitTests/UnitTests.csproj -c Debug --filter "TestCategory!=LLVM"
The make wrapper runs the same suite:
$ make -C src test
The LLVM-specific tests are separate and require LLVM/Clang to be installed:
$ make -C src test-llvm
To run the LLVM tests manually, specify the runtime identifier for your platform and set CLANG_PATH to the Clang executable:
$ CLANG_PATH=clang dotnet test src/UnitTests/UnitTests.csproj -c Debug -r osx-arm64 --filter "TestCategory=LLVM"
Common runtime identifiers are linux-x64, linux-arm64, osx-arm64, win-x64, and win-arm64.
The current tool-tests/IL2LLVM samples use Linux libc.so.6 imports. On non-Linux hosts, the LLVM tool tests skip those samples instead of failing; CI still exercises them on Linux.
Tools
ilopt
ilopt reads a managed assembly, optimizes it, and writes the optimized result back to disk.
Build it with the solution or directly:
$ dotnet build src/ILOpt/ILOpt.csproj -c Debug
Run it with:
$ dotnet src/ILOpt/bin/Debug/net10.0/ilopt.dll input.dll -o output.dll
The supported single-file samples used by the test suite live in tool-tests/ILOpt.
il2llvm
il2llvm compiles managed assemblies to LLVM IR.
$ dotnet publish src/IL2LLVM/IL2LLVM.csproj -c Debug -r osx-arm64 --self-contained false
$ dotnet src/IL2LLVM/bin/Debug/net10.0/osx-arm64/publish/il2llvm.dll input.dll -o output.ll
Continuous integration
GitHub Actions is configured in .github/workflows/ci.yml.
The CI workflow:
- restores
src/Flame.sln - builds the solution in
Debug - runs the portable test suite via
dotnet test --filter "TestCategory!=LLVM" - runs the LLVM backend test suite via
dotnet test -r linux-x64 --filter "TestCategory=LLVM"withCLANG_PATHset toclang-20