Intermediate Representation

The MIND IR is a typed, SSA-based intermediate representation designed for tensor operations and automatic differentiation.

📐 IR canon (mindc 0.10.x, RFC 0021 steps 1–4 shipped):

  • • Canonical data shape: IRModule (the SSA structure described below).
  • • Canonical text serialisation: mic@1. RFC 0001 fixed-point form; the evidence-chain trace_hash is computed over mic@3 binary (RFC 0016 GAP-1, re-anchored 2026-05-31).
  • • Canonical binary serialisation: mic@3 (magic MIC3). Round-trip equivalent to mic@1; carries the evidence MAP epilogue via a 0x4D sentinel.
  • • Legacy dataflow lineage (back-compat only): mic@2 / mic@2.1 (with MAP). Demoted — never the current or canonical compiled-artifact IR. The rename to mind-model@2, a model-exchange artifact decoupled from the IR contract, is RFC 0021 step 5 (a byte-preserving cross-repo migration, still pending).
  • • Consumer surface: mindc verify <artifact> re-computes the trace_hash over the parsed IR body and reports it; mindc inspect <artifact> decodes a mic@3 binary and pretty-prints the canonical IR body plus a structural summary.
  • • Stability surface: /docs/stability + mind-spec ir-stability.md.

IR Structure

MIND IR uses Static Single Assignment (SSA) form with explicit types:

// Example IR for: y = relu(x @ w)
%0 = mind.const : tensor<2x2xf32> = [[1.0, 2.0], [3.0, 4.0]]
%1 = mind.randn : tensor<2x2xf32>
%2 = mind.matmul(%0, %1) : tensor<2x2xf32>
%3 = mind.relu(%2) : tensor<2x2xf32>
mind.return %3

Core Operations

CategoryOperations
Arithmeticadd, sub, mul, div, neg, pow
Linear Algebramatmul, transpose, dot
Activationsrelu, sigmoid, tanh, softmax, gelu
Reductionssum, mean, max, min, prod
Shapereshape, broadcast, squeeze, unsqueeze
Convolutionconv2d, maxpool2d, avgpool2d

Type Representation

IR types encode both dtype and shape information:

tensor<f32>           // Scalar
tensor<10xf32>        // 1D, static shape
tensor<2x3xf32>       // 2D, static shape
tensor<?x?xf32>       // 2D, dynamic shape
tensor<2x?xf32>       // Mixed static/dynamic

Canonicalization

The IR undergoes canonicalization passes to normalize operations:

  • Dead-code elimination — provably dead instructions are pruned.
  • Commutative operand orderingadd / mul operands are put in a canonical order, so two spellings of the same expression serialise identically.
  • Constant folding, exact-or-skip — a constant subtree is folded only when the result is representable. On overflow the expression is left unfolded so the runtime wraps it identically; the pass never emits a wrapped or saturated constant. A const-position expression and the identical runtime-position expression therefore always produce the same bytes.

The pass is deliberately conservative and idempotent: it keeps the existing SSA IDs, so running it repeatedly changes nothing. That conservatism is load-bearing — canonicalization output is what trace_hash anchors on.

A further mic@3 → mic@3 middle-end (SCCP-lite const-condition pruning, integer algebraic-identity elimination, region-scoped CSE/GVN) exists but is opt-in and OFF by default, and is a developer flag rather than a shipping profile. With it disabled every emitted byte is byte-identical to the un-optimized IR. Strength reduction, loop-invariant code motion, and register allocation beyond the first deterministic callee-saved slice are not shipped.

Lowering Pipeline

The normative self-host backend emits native x86-64/ELF directly from the canonical IR. The MLIR → LLVM path shown below is the downstream-interchange route for specialty targets (see MLIR Lowering):

Source (.mind)
    ↓ Parse
AST
    ↓ Type check
Typed AST
    ↓ Lower
MIND IR (High-level)
    ↓ Canonicalize
MIND IR (Canonical)
    ↓ Autodiff (if needed)
MIND IR + Gradients
    ↓ Lower to MLIR
MLIR Dialects
    ↓ Lower to LLVM
LLVM IR
    ↓ Codegen
Machine Code

Learn More

See the full IR specification at mind-spec/ir.md.