Repository navigation
Architecture
How a program gets from Lamina IR text to a running executable, and which crate owns each step.
program.lamina IR text
│
▼ parser
Lamina IR typed, block-based, target independent
│
▼ lowering
LUMIR machine IR: registers, machine types, still target independent
│
▼ transform pipeline (--opt-level 0 .. 3)
LUMIR optimized
│
▼ mir_codegen, per target
program.s native assembly
│
▼ ras (or the system as)
program.o relocatable object: ELF, Mach-O, COFF/PE
│
▼ weld (or ld, lld, mold)
program executable
There is a second exit. With the encoder feature the JIT skips assembly text and
encodes LUMIR straight to bytes in executable memory, which is what --jit and the
lamina! macro use.
| Crate | Owns |
|---|---|
lamina |
The driver and CLI, the parser, the transform pipeline, the per-target instruction emitters in src/mir_codegen/, and the JIT runtime |
lamina-ir |
The IR itself: types, instructions, modules, IRBuilder, and the owned builder the C bindings use |
lamina-mir |
LUMIR type definitions: modules, functions, instructions, registers, machine types |
lamina-codegen |
Shared codegen machinery: ABI, stack frames, register allocation, and the target-support tables |
lamina-platform |
Target vocabulary and host detection, including the architecture table every per-architecture property comes from. Split out to avoid a dependency cycle with ras
|
lamina-c |
The C API. Opaque handles, explicit ownership. Reports its own version through lia_version()
|
ras |
Assembler. Assembly text to object file, and the encoder the JIT uses |
weld |
Linker. Objects to executable |
Code generation lives in two places, and the split is not obvious from the names.
lamina-codegen holds the shared pieces: ABI rules, frame layout, register
allocation, and the table saying which architecture and OS pairs are supported.
Everything an architecture states about itself — widths, byte order, alignments,
interpreters, environments — is one step further out, in lamina-platform. The
actual per-instruction emitters live in the root crate under src/mir_codegen/. If you
are adding an architecture you will touch both, which is exactly the problem the codegen
trait in 0.2 is meant to solve.
The IR's meaning is stated separately from its syntax. IR semantics is the normative page: numbered clauses saying what each operation computes, what traps, and which targets refuse it. Where this page or another one describes a behaviour in passing, that page is the one that decides.
Lamina IR is what a frontend targets. It is typed and block-based, and knows nothing about registers or calling conventions. Keeping it target independent means a frontend author never has to think about machine details.
LUMIR is what the optimizer and the backends work on. It is assembly-shaped: virtual registers, machine types, explicit memory operands. Most optimization passes are easier to write here because the representation is closer to what will actually run.
The split costs a lowering step. It buys a frontend-facing layer that stays stable while backends change underneath it, which is the whole proposition of using Lamina as a backend at all.
Lamina IR — the typed intermediate representation a frontend produces, in text
form or through IRBuilder.
LUMIR — Lamina Unified Machine Intermediate Representation, the machine-level IR
produced from Lamina IR. The lamina-mir crate defines it. Usually just called MIR in
conversation and in the source.
Transform — one optimization pass over LUMIR. The set that runs depends on the
--opt-level the driver was given.
Backend — the per-architecture emitter that turns LUMIR into assembly text.
Target name — <architecture>_<operating-system>[_<environment>], written
x86_64_linux or x86_64_linux_musl. A sub-architecture may stand in place of the bare
architecture: rv64gc, armv7a-neon, aarch64v8.2, ppc64le-power9. The parser
recognizes more names than the driver accepts, and the driver accepts more than any one
backend finishes. See the target table.
Environment — the fourth axis of a target: gnu, musl, lamina, eabi,
eabihf or none. It decides the C library, the ELF interpreter, the C runtime startup
objects and the compiler runtime. Left out of a target name, each architecture and
operating system pair declares its own; none is freestanding and is what an operating
system that supplies its own runtime takes. lamina names Lamina's own C library. It
parses on x86_64 and aarch64 and nothing implements it, so the link refuses by name
rather than borrowing another libc's loader and startup objects.
Compiler runtime — the routines code generation calls that the user did not write,
such as __divti3. Lamina's own are in builtins/, written in Lamina IR and compiled
per program for the target. They cover the 128-bit division, remainder and float
conversion routines and the 64-bit forms of the same, so an architecture whose integer
registers hold 32 bits gets its __divdi3 family from the same place. No host libgcc
is required on any target. Where the host happens to have one, the GNU link path still
names it after the compiled routines.
Host detection — working out the target of the machine the compiler is running on. It fails with a message naming the architecture or operating system when there is no backend for it, rather than guessing one. There is no unknown-architecture fallback.
AOT — ahead of time. The normal compile-to-executable path.
JIT — compiling into executable memory and calling it in the same process. --jit
runs in a default build; the C bindings' JIT extension is the part behind nightly.
See Releases.
ABI — the calling convention plus layout rules for a target. Which registers carry arguments, who saves what, how a struct is passed.
Relocation — a note in an object file saying "patch this address once you know where the symbol landed". The linker resolves them.
Red zone — a region below the stack pointer that leaf functions may use without
adjusting rsp. Unusable in anything that takes interrupts.
- IR semantics for what each operation means, clause by clause
- Roadmap for what is being worked on and in what order
-
Releases for versioning and what
nightlymeans - Ecosystem for projects built on Lamina
- IR language reference for the syntax itself
lamina · ras · weld · lamina-web