Phase 10.7 — JIT CFG/PHI/ABI Hardening (Master Plan)

Intent
- Deliver a practical, observable JIT path for control flow and minimal data flow while keeping VM as the safe fallback.
- Decompose into small, shippable sub-phases with flags and examples, minimizing blast radius.

Related docs
- 10.7a details: phase_10_7a_jit_phi_cfg_and_abi_min.txt
- Current work log: docs/development/current/CURRENT_TASK.md
- Cranelift JIT backend notes: phase_10_cranelift_jit_backend.md

Flags and CLI (common across 10.7)
- Env: NYASH_JIT_EXEC, NYASH_JIT_STATS, NYASH_JIT_STATS_JSON, NYASH_JIT_DUMP, NYASH_JIT_THRESHOLD, NYASH_JIT_PHI_MIN, NYASH_JIT_HOSTCALL
- CLI: --jit-exec --jit-stats --jit-stats-json --jit-dump --jit-threshold N --jit-phi-min --jit-hostcall

Examples to validate
- examples/jit_branch_demo.hako
- examples/jit_loop_early_return.hako
- examples/jit_phi_demo.hako
- examples/jit_array_param_call.hako, jit_map_param_call.hako (when hostcall is enabled)

Sub-phases (10.7a → 10.7h)

10.7a — Minimal branch/PHI/ABI (Done or in-flight)
- Branch wiring with b1 and i64!=0 normalization
- Minimal PHI: single-value diamond via block param
- Independent ABI (JitValue) with integer-first calling
- Panic-safe dispatch (catch_unwind) and VM fallback
- Minimal hostcall bridge (Array/Map) behind NYASH_JIT_HOSTCALL
- Observability: unified JIT summary/JSON, lower summary (argc/phi_min), CFG edge dump (phi_min)

Acceptance: see 10.7a doc

10.7b — PHI generalization and block-parameterization
- Support multiple PHIs in a merge block; pass N values via block params
- LowerCore: gather PHI inputs per successor, produce explicit arg lists; handle straight merges and simple loops
- IRBuilder API formalization:
  - ensure_block_params_i64(index, count)
  - br_if_with_args(then_idx, else_idx, then_n, else_n)
  - jump_with_args(target_idx, n)
- CraneliftBuilder: append N I64 params per block, materialize current block params onto stack when requested
- Validation: multi-PHI diamonds, if-else chains, early returns; keep loops as simple as possible in 10.7b

10.7c — Independent host-handle registry (JIT↔Host decoupling)
- Introduce JitHandleRegistry: u64 ↔ Arc<dyn NyashBox>
- JIT hostcalls accept/return only handles and PODs; VMValue↔JitValue boundary converts BoxRef <-> Handle via registry
- Rooting policy: enter/pin roots for handles crossing the boundary; leave on return
- Flags: NYASH_JIT_HOSTCALL=1 (still gated); add NYASH_JIT_HANDLE_DEBUG for dumps
- Deliverables: array/map operations via handles, no direct VMValue access on JIT side

10.7d — Side-effect boundary and hostcall coverage expansion
- Keep side-effecting ops (print/IO) on VM for now; document deopt path
- Expand safe hostcalls (read-only or confined):
  - String.len / slice basics (POD returns)
  - Map.size; Map.get with integer and string keys (key boxing handled at boundary)
- Record effect categories on lowered calls for future optimizer (metadata only)

10.7e — CFG diagnostics and visualization
- Add DOT export for CLIF CFG with block params and PHI bindings
- Env: NYASH_JIT_DOT=path.dot (produces per-function graph)
- Optional: ASCII CFG summary for CI logs
- Cross-check with VM-side MIR printer for block and PHI consistency

10.7f — JitConfigBox (configuration as a Box)
- Encapsulate all JIT toggles into a runtime-managed box (JitConfigBox)
- Harmonize env/CLI with programmatic overrides for tests
- Feed config into JIT engine and lowerers (no direct env reads inside hot paths)
- Serialization: dump/load config JSON for reproducible runs

10.7g — Stability, tests, and benchmarks
- Golden tests: ensure JIT/VM outputs match on curated programs
- Fallback ratio regression guard: alert when fallback_rate spikes beyond threshold
- JSON schema stability for stats; include version field
- Microbenchmarks: branch-heavy, phi-heavy, and hostcall-heavy cases; gated perf checks

10.7h — Type widening for native ABI
- Add native F64 and Bool parameter/return paths in CLIF
- Condition handling: keep b1 where possible; map Bool to b1 cleanly
- Conversions: explicit i64<->f64 ops in lowerer where needed (no silent truncation)
- Update adapter and closure trampoline to select proper function signatures (arity×type shapes)

Out of scope for 10.7 (shift to 10.8/10.9)
- Global register allocation strategies or codegen-level optimizations
- Deoptimization machinery beyond simple VM fallback
- Advanced exception propagation across JIT/VM boundary

Risks and mitigation
- PHI N-arity correctness: introduce targeted unit tests over synthetic MIR
- Handle registry leaks: counting diagnostics, strict mode; tie roots to scope regions
- CLIF block-param misuse: deterministic block order + seal discipline + assertions in builder

Verification checklist (roll-up)
- cargo check (± --features cranelift-jit)
- Run examples with JIT flags; diff with pure VM runs
- Inspect: unified JIT summary/JSON, lower logs, CFG dumps/DOT
- Leak/roots checks when NYASH_GC_TRACE=1/2/3 and strict barrier mode is on

Suggested timeline (tentative)
- 10.7a: Minimal branch/PHI/ABI (done / in-flight)
- 10.7b: PHI generalization + builder API formalization (1–2 days)
- 10.7c: Host-handle registry PoC (1–2 days)
- 10.7d/e: Hostcall coverage + CFG DOT (2–3 days)
- 10.7f: JitConfigBox + integration (1 day)
- 10.7g/h: QA + type widening for f64/bool (2–4 days)

10.7z — Follow-ups and Open Items (post-10.7)
- b1 PHI tagging robustness
  - Problem: Provenance can be obscured by Load/Store and multi-step copies; (b1) tag may be missed in dumps.
  - Action:
    - Add a lightweight boolean-lattice analysis over MIR to classify boolean-producing values independent of path shape.
    - Extend dump to include phi_summary JSON or structured rows when NYASH_JIT_STATS_JSON is on.
  - Placement: 10.7g (stability/tests) — does not block 10.7 close.

- VM f64 arithmetic/compare parity
  - Problem: VM backend currently errors on f64 BinOp/Compare; JIT (Cranelift) supports f64 when enabled.
  - Action: Implement f64 ops in VM or add consistent auto-promotion; add golden tests.
  - Placement: 10.8 (VM parity/perf) — out-of-scope for 10.7.

- Native b1 ABI in function signatures
  - Problem: Toolchain capability for b1 return/params is currently disabled.
  - Action: Keep centralized switch; add CI probe to flip automatically when supported; wire return path fully.
  - Placement: 10.7h or later (gated by toolchain).

- Stats/diagnostics polish
  - Action: Version the unified JIT JSON schema; expose phi(b1) slot counts in JSON; enrich JitStatsBox with summary/topN (partially done).
  - Placement: 10.7g.

- Build warnings (unexpected cfg: llvm)
  - Problem: Warning noise from unused/unknown cfg.
  - Action: Declare feature flags in Cargo.toml or gate code behind existing features; optionally silence for non-supported builds.
  - Placement: 10.7g (cleanup) — non-blocking.

- Documentation sync
  - Action: Add a "JIT quick flags" section with common env/CLI combos; ensure CURRENT_TASK and examples remain aligned.
  - Placement: 10.7e (docs) — non-blocking.
