42 lines
2.7 KiB
Markdown
42 lines
2.7 KiB
Markdown
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 doesn’t 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.
|
||
|