Luce / engineering
Learn Luce LuciaOS

MIR optimization

Luce removes unreachable declarations and unread pure instructions. LLVM then performs machine-oriented work: inlining clamp_double, turning * 2 into a shift, and replacing a small branch with csel.

Two optimizers, two jobs. Luce knows which language operations have effects and which declarations are unreachable. LLVM knows instruction costs, registers, and the target processor. The boundary keeps each decision with the system that has the facts to make it.

Three passes

Reachability pruneStarting from the selected entry, follow direct calls, function values, interface witnesses, class deinitializers, and closure edges; remove everything unreachable.
Dead instructionsRemove unread pure results and the ownership temporaries that became redundant, while respecting runtime effects and destruction order.
Register compactionRenumber surviving registers into a dense space and update every use so serialization and downstream lowering stay small.

Reachability is more than a call graph

Edges followed by reachabilityStored and lifetime behavior can keep a function reachable
Direct code

Calls and selected entry points.

Stored behavior

Function values, bound methods, closure bodies, and interface witness slots.

Lifetime behavior

Class deinit functions and layouts referenced by live values.

An imported standard module arrives as source, so the initial program may contain many declarations outside the entry’s reachable graph. Pruning removes those declarations and their hosted Builtin effects from the artifact.

Effects keep unread results alive

A result register may be unread while its instruction still matters. A host call can print. A container mutation can change a shared object. A release can run deinit, close a file, or join a task. The effects table classifies what can disappear and what must stay.

Optimization preserves destruction order, resource behavior, traps, and host effects. A retain/release pair can be removed when those observations stay the same.

Work delegated to LLVM

Constant folding, inlining, loop transforms, vectorization, instruction selection, register allocation, and target scheduling are LLVM's work. Reimplementing them over MIR would create a second optimizer to maintain and a second place for target-sensitive bugs.

Luce MIR handles

Language reachability, explicit runtime effects, cleanup semantics, and compact protocol.

LLVM handles

General scalar and loop optimization, target instructions, physical registers, and object emission.

Verify, transform, verify

The input first passes the MIR verifier. After passes delete blocks and renumber registers, the whole result passes again. An invalid transformation therefore surfaces during the build before native lowering begins.