Files
hakorune/docs/development/architecture/phi-entry-in-hako.md

2.7 KiB
Raw Blame History

Phi Entry in Hako — Design Notes (SSA/CFG Parity)

Purpose

  • Specify how to implement SSA φ (phi) on the Hakorune side cleanly, mirroring Rust/Core invariants while keeping the code small and testable.

Rust/Core invariants to adopt (parity)

  • Placement: φ nodes are considered at the head of a block (grouped), applied once at block entry.
  • Selection: choose one incoming (value, pred) where pred == prev_bb (the block we arrived from).
  • Coverage: incoming pairs cover all reachable predecessors. Missing entries are a hard error in strict mode.
  • Execution: after φ application, the resulting dst registers are defined before any instruction in the block reads them.

Hako design (Reader → IR → Runner)

  • Reader (JsonV1ReaderBox, extended):
    • Parse MIR JSON v1 into a minimal per-function IR: blocks (id, insts[]), and extract φ entries into a phi_table (block_id → [(dst, [(pred,val)])]).
    • Keep scanning light by using JsonFragBox helpers (read_int_from/after, seek_array_end, scan_string_end).
  • PhiTable (V1PhiTableBox):
    • API: apply_at_entry(regs, phi_table, prev_bb, block_id, policy) → writes dst from the matched incoming.
    • policy.strict (default ON): fail-fast when incoming is missing or source is undefined; policy.tolerate_void (dev) treats missing/undefined as Void/0.
  • Runner (NyVmDispatcherV1Box):
    • On block entry: apply φ via PhiTable; then run instructions (φ removed from the runtime loop).
    • Branch/jump update prev_bb and bb; compare/branch read the compare.dst as the condition value.

Flags

  • HAKO_V1_PHI_STRICT=1 (default), HAKO_V1_PHI_TOLERATE_VOID=0 (dev-only safety).
  • HAKO_V1_DISPATCHER_FLOW=1 to run the IR-based flow; keep fallback to Mini-VM and Core for stability during bring-up.

Testing plan

  • Canary 1: simple if (then/else with single incoming) → ret of φ.dst equals the selected value.
  • Canary 2: multi-incoming with (pred,val) pairs for both paths; ensure prev_bb select works for both branches.
  • Canary 3: nested branch (entry φ in deeper block).
  • Negative: missing incoming for reachable pred → strict fail; tolerate_void → rc stable with Void/0.

Why this works in Hako

  • Although Hako doesnt have first-class structs, the minimal IR and phi_table can be represented as arrays of tuples or MiniMap-backed strings with helper boxes.
  • JsonFragBox provides escape-aware scanning; Reader avoids brittle substring logic.
  • Runner remains small and composable: “read/apply/run” with φ isolated at entry.

Migration plan

  • Phase 20.37: introduce Reader+PhiTable+entry-apply (flagged), keep fallback to Mini-VM/Core.
  • Phase 20.38+: expand coverage (binop/compare edges), flip v1 verify default to Hako when parity canaries are green.