Skip to content

WasmIR

The primitive SSA representation between canonical MIR and WebAssembly encoding.

Updated View as Markdown

WasmIR is the small canonical SSA representation between canonical MIR and wasm-encoder. It is WebAssembly-oriented but is not WebAssembly text, a module format, or a second semantic IR.

Its governing rule is:

The encoder emits an instruction from the instruction’s fields, the read-only frame layout, and read-only module indices. It does not make a language, layout, continuation, or calling-convention decision.

Function

A WasmIRFn contains:

  • a function kind and explicit WebAssembly parameter/result types;
  • dense virtual-register type, definition, and origin tables;
  • basic blocks, block parameters, and an entry block;
  • a shared reference to the finalized MIR frame layout;
  • optional human-readable debug names;
  • instruction-to-MIR provenance;
  • a flag selecting the relocation-safe arena-base discipline.

Every virtual register has one natural WasmTy and exactly one definition. Every block ends in one Term. The entry block is reachable and has no block parameters.

Function kinds

FnKind fixes the encoded signature:

Kind Parameters Purpose
Continuation five i32 values: arena base, frame offset, handle, tag, value Entry, resume, or loop-step runtime target
BlockFn arena base, frame offset, then typed live-ins Hoisted CFG region
Direct natural typed parameters and results Non-suspending value-ABI function

The kind is descriptive at this layer, not permission for the encoder to recreate a prologue policy. MIR canonicalization and WasmIR lowering have already materialized required frame writes, value conversions, scheduler operations, and branches.

Three invariants

Self-contained instructions

An instruction’s fields determine its emitted byte behavior. Frame loads/stores name a frame slot; flex accesses name a base, offset, and width; calls name their selected index, arguments, results, and call kind.

Natural values

Every VReg has one of I32, I64, F32, F64, or V128. There are no virtual i8, i16, aggregate, optional, string, or semantic enum values. Those values have already been mapped to natural carriers.

Explicit boundaries

Width conversions are explicit Convert instructions except at typed storage boundaries, where width and signedness select the exact load/store behavior. This exception exists because WebAssembly has no first-class i8, i16, or i128 value type.

Pipeline

canonical primitive MIR
    ↓ mechanical lowering
WasmIR
    ↓ forwarding, folding, DCE, peepholes, branch simplification, CSE
optimized WasmIR
    ↓ liveness, register allocation, stack residency, control structuring
encodable WasmIR
    ↓ encoding
WebAssembly function body

Every optimization consumes the effect classification rather than maintaining its own incomplete opcode list. Verifiers run after construction and, in debug builds, after transformations.

Exclusions

WasmIR deliberately excludes:

  • unresolved Atoll types or type registry queries;
  • trait, method, or overload selection;
  • generic specialization;
  • continuation-kind dispatch policy;
  • enum layout discovery or aggregate field placement;
  • implicit calling-convention selection;
  • unit discovery, section merging, and final module linking.

Module assembly is documented in WebAssembly and Linking. This section defines only function-level IR and its direct encoding obligations.

Read Values for representation, Control for CFG shape, and Effects for optimization and verification.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close