🛡️ Add terminator safety guard for LLVM blocks

Added extra safety check after block lowering:
- Check if LLVM basic block still lacks terminator
- Insert conservative jump to next block (or entry if last)
- This prevents 'Basic Block does not have terminator' errors

Also updated CURRENT_TASK.md with:
- Reproduction steps for esc_json/1 PHI issue
- Sealed ON/OFF comparison commands
- Root cause hypothesis: vmap snapshot timing issue
- Next steps for block_end_values implementation

Current blocker analysis:
- Sealed OFF: PHI incoming count mismatch
- Sealed ON: 'phi incoming (seal) value missing'
- Likely cause: seal_block using work vmap instead of
  end-of-block snapshot

Progress: Main.esc_json/1 terminator issue resolved,
now focusing on PHI value availability.
This commit is contained in:
Selfhosting Dev
2025-09-12 12:38:06 +09:00
parent a28fcac368
commit fc18a925fd
2 changed files with 26 additions and 0 deletions

View File

@ -28,6 +28,22 @@ Hot Update — 2025-09-12 (quick)
- 現在のブロッカー: esc_json/1 で「phi incoming value missing」
- 対応: emit_jump/emit_branch の incoming 配線をログ付きで点検し、値未定義箇所byname/fastpath戻りを補完
Hot Repro — esc_json/1 PHI 配線20250912
- 対象: apps/selfhost/tools/dep_tree_min_string.nyash
- 実行LLVM:
- Sealed OFF: `NYASH_CLI_VERBOSE=1 NYASH_LLVM_TRACE_PHI=1 NYASH_DISABLE_PLUGINS=1 ./target/release/nyash --backend llvm apps/selfhost/tools/dep_tree_min_string.nyash`
- Sealed ON: `NYASH_LLVM_PHI_SEALED=1 NYASH_CLI_VERBOSE=1 NYASH_LLVM_TRACE_PHI=1 NYASH_DISABLE_PLUGINS=1 ./target/release/nyash --backend llvm apps/selfhost/tools/dep_tree_min_string.nyash`
- 観測:
- Sealed OFF: Main.esc_json/1 で PHI incoming 不足(`PHINode should have one entry for each predecessor`)。
- Sealed ON: `phi incoming (seal) value missing`pred側終端値の取得ができていない。別途 Terminator 欠落も検知→終端フォールバックを実装して解消済み。
- 原因仮説: Sealed ON で `seal_block` が pred終端時点の値value_at_end_of_blockではなく関数作業用 vmap を参照しているため、未定義扱いになっている。
Next StepsSealed SSA 段階導入)
1) block_end_values を導入し、各BB降下完了時に vmap スナップショットを保存。`seal_block` は pred のスナップショットから in_vid を取得。
2) Sealed=ON で apps/selfhost/tools/dep_tree_min_string.nyash を再確認PHIログ=ON。OFF/ON の一致を比較し、incoming が pred数で揃うことを検証。
3) 足りない型整合String/Box/Array→i8*)があれば `coerce_to_type` を拡張。
4) グリーン後、Sealed をデフォルトONにする前にスモーク一式で回帰確認。
Plan — PHI/SSA Hardening (Sealed SSA)
- Sealed SSA 入れ替え(安全に段階導入)
- Blockごとに `sealed: bool``incomplete_phis: Map<Var, Phi>` を保持

View File

@ -344,6 +344,16 @@ impl LLVMCompiler {
let entry_first = func.entry_block;
instructions::emit_jump(&codegen, *bid, &entry_first, &bb_map, &phis_by_block, &vmap)?;
}
}
// Extra guard: if the current LLVM basic block still lacks a terminator for any reason,
// insert a conservative branch to the next block (or entry if last) to satisfy verifier.
if unsafe { bb.get_terminator() }.is_none() {
if let Some(next_bid) = block_ids.get(bi + 1) {
instructions::emit_jump(&codegen, *bid, next_bid, &bb_map, &phis_by_block, &vmap)?;
} else {
let entry_first = func.entry_block;
instructions::emit_jump(&codegen, *bid, &entry_first, &bb_map, &phis_by_block, &vmap)?;
}
}
if sealed_mode {
instructions::flow::seal_block(&codegen, *bid, &succs, &bb_map, &phis_by_block, &vmap)?;