Skip to content

Tiered, Adaptive JIT#6

Merged
techomancer merged 5 commits intotechomancer:mainfrom
unxmaal:cranelift
Apr 6, 2026
Merged

Tiered, Adaptive JIT#6
techomancer merged 5 commits intotechomancer:mainfrom
unxmaal:cranelift

Conversation

@unxmaal
Copy link
Copy Markdown
Contributor

@unxmaal unxmaal commented Apr 6, 2026

Summary

Adds an optional Cranelift-based JIT compiler that translates hot MIPS R4400 basic blocks to native x86_64 code at runtime. Feature-gated behind --features jit and controlled by IRIS_JIT=1 at runtime.

Architecture

  • Interpreter-first dispatch: The interpreter runs in short bursts with periodic cache probes. JIT blocks execute one at a time between interpreter bursts — no block chaining.
  • Three-tier compilation: Blocks start at ALU tier (registers + branches only), promote to Loads (+ memory reads), then Full (+ stores) based on stable execution history. Blocks demote on repeated exceptions.
  • Speculative execution with rollback: ALU and Loads tier blocks use CPU snapshots for safe rollback on exceptions. Full-tier blocks are non-speculative since memory writes can't be undone.
  • Adaptive probe controller: Probe interval adjusts dynamically using asymmetric EWMA hit rate tracking, sqrt-based cache size pressure, and LFSR jitter.
  • Profile cache: Hot block addresses and tiers persist across sessions for warm-start recompilation.

Compiled instructions

  • ALU: ADDU, SUBU, AND, OR, XOR, NOR, SLT, SLTU, DADDU, DSUBU, shifts (SLL/SRL/SRA/DSLL/DSRL/DSRA + variable and 32-bit variants), MULT/MULTU/DIV/DIVU/DMULT/DMULTU/DDIV/DDIVU, MFHI/MTHI/MFLO/MTLO, MOVZ/MOVN, ADDIU/DADDIU/SLTI/SLTIU/ANDI/ORI/XORI/LUI, SYNC
  • Loads: LB/LBU/LH/LHU/LW/LWU/LD
  • Stores: SB/SH/SW/SD
  • Branches: BEQ/BNE/BLEZ/BGTZ/J/JAL/JR
  • Delay slots compiled inline when possible, interpreter fallback otherwise

Key design decisions

  • extern "C" fn(*mut JitContext) block signature with #[repr(C)] bridge struct
  • Memory helpers use black_box pointer casts to defeat LLVM noalias optimization through LTO
  • sync_to_executor only writes back GPRs/PC/hi/lo — CP0, nanotlb, and FPR are managed directly on the executor by helpers
  • Post-block cp0_count bulk advancement and interrupt checking to maintain kernel timer expectations
  • Full-tier blocks terminate at first store instruction to avoid Cranelift regalloc2 issues with complex CFG from many helper call sites

Runtime configuration

Variable Default Description
IRIS_JIT 0 Enable JIT (1) or interpreter-only (0)
IRIS_JIT_MAX_TIER 2 Cap tier: 0=ALU, 1=Loads, 2=Full
IRIS_JIT_VERIFY 0 Run each block through interpreter and compare
IRIS_JIT_PROBE 200 Base probe interval
IRIS_JIT_PROBE_MIN 100 Minimum probe interval
IRIS_JIT_PROBE_MAX 2000 Maximum probe interval
IRIS_JIT_STABLE 50 Hits before block leaves speculative mode
IRIS_JIT_PROMOTE 200 Stable hits before tier promotion
IRIS_JIT_DEMOTE 3 Exceptions before tier demotion

New files

  • src/jit/mod.rs — module root
  • src/jit/compiler.rs — Cranelift block compiler
  • src/jit/dispatch.rs — adaptive dispatch loop
  • src/jit/context.rs — JitContext bridge struct and sync
  • src/jit/helpers.rs — extern "C" memory access helpers
  • src/jit/cache.rs — code cache with tier metadata
  • src/jit/snapshot.rs — CPU rollback snapshots
  • src/jit/profile.rs — profile save/load

Test plan

  • IRIS_JIT=1 IRIS_JIT_MAX_TIER=0 — ALU+branches only, boots to login
  • IRIS_JIT=1 IRIS_JIT_MAX_TIER=1 — loads enabled, boots to login
  • IRIS_JIT=1 — full tier with stores, boots to login
  • IRIS_JIT=0 — interpreter-only, no regression

@techomancer techomancer merged commit 57c30b9 into techomancer:main Apr 6, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants