Mica compiles to native Linux x86_64 and AArch64 ELF binaries using its own backend. There is no LLVM underneath and no GCC backend. The GNU assembler and linker are the only external tools, and they take textual assembly the compiler emits.
What is in the pipeline
Parse → analyse → generate intermediate code → inline → build control flow and SSA → prove heap obligations → allocate registers and lay out frames → emit.
- Intermediate language — three-address code with roughly sixty operations, with a readable text form you can dump at any stage.
- Inlining — a pure intermediate-to-intermediate transform placed before SSA, so the existing folding, forwarding, and dead-code passes clean up each substituted body for free. Budgets are explicit constants, and every declined site records why.
- SSA optimization — pruned φ placement at the iterated dominance frontier of live variables; constant propagation; store-to-load and load-to-load forwarding; dominance-scoped global value numbering; value-range propagation with overflow-checked interval arithmetic; loop-invariant code motion; loop rotation; a UTF-8 cursor strength reduction that guarantees sequential string indexing stays linear.
- Bounds-check elimination falls out of value-range propagation: where the range of an index provably lies inside the array’s index domain, the check is removed rather than executed.
- Register allocation — graph colouring with coalescing and loop-weighted spill costs, plus a linear-scan local allocator.
- Emission — two backends behind one seam, System V AMD64 and AAPCS64 AArch64, each with its own peephole optimizer, and ELF output carrying DWARF v5 debug information with a registered language code.
Debug builds keep values where the debugger can see them
Register homes are treated as a release-mode optimization. A debug build keeps every value on its stack home, so each one has a stable location the debugger can read at any program point. Stepping through optimized-away variables is not a problem you have here, because a debug build does not create them.
Debugger behaviour is a test category, not an aspiration: gdb sessions run against expected output as part of the corpus.
Targets
| x86_64 | x86-64-v3 baseline — AVX2 and FMA3 guaranteed to the code generator |
| AArch64 | ARMv8.0-A baseline |
| Output | ELF executables, static archives, shared objects; PIE by default |
| Assembly syntax | Intel or AT&T |
Cross-compilation between the two architectures works on a single host.