## Summary Implemented fail-fast validation for PHI ordering and value resolution in strict mode. ## Changes ### P1-1: Strict mode for "PHI after terminator" - File: `src/llvm_py/phi_wiring/wiring.py::ensure_phi` - Behavior: `NYASH_LLVM_PHI_STRICT=1` → RuntimeError if PHI created after terminator - Default: Warning only (no regression) ### P1-2: Strict mode for "fallback 0" - File: `src/llvm_py/phi_wiring/wiring.py::wire_incomings` - Behavior: Strict mode forbids silent fallback to 0 (2 locations) - Location 1: Unresolvable incoming value - Location 2: Type coercion failure - Error messages point to next debug file: `llvm_builder.py::_value_at_end_i64` ### P1-3: Connect verify_phi_ordering() to execution path - File: `src/llvm_py/builders/function_lower.py` - Behavior: Verify PHI ordering after all instructions emitted - Debug mode: Shows "✅ All N blocks have correct PHI ordering" - Strict mode: Raises RuntimeError with block list if violations found ## Testing ✅ Test 1: strict=OFF - passes without errors ✅ Test 2: strict=ON - passes without errors (no violations in test fixtures) ✅ Test 3: debug mode - verify_phi_ordering() connected and running ## Scope - LLVM harness (Python) changes only - No new environment variables (uses existing 3 from Phase 277 P2) - No JoinIR/Rust changes (root fix is Phase 279) - Default behavior unchanged (strict mode opt-in) ## Next Steps - Phase 278: Remove deprecated env var support - Phase 279: Root fix - unify "2本のコンパイラ" pipelines 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
4.0 KiB
4.0 KiB
Phase 277 P1: PHI順序検証強化(validation)
Status: planned / validation
Goal: PHI placement/order を fail-fast で検出しやすくし、LLVM harness の “後段で壊れる” ではなく “原因箇所で止まる” を実現する。
Scope:
- 検証とエラーメッセージの改善(実装は最小・局所)
- “順序違反” と “型不整合” の可観測性を上げる
Non-goals:
- 新しい env var 追加
- 大規模なパイプライン統一(Phase 279)
1) 何を検証するか(契約SSOT)
最低限、この契約を SSOT として明文化する:
-
Block内順序:
- PHI 群
- non-PHI 命令群
- terminator(Branch/Jump/Return)
- この順序以外は “バグ” として扱う
-
PHI 入力の完全性:
- incoming が欠ける場合は fail-fast(既定で silent fallback をしない)
- strict mode(
NYASH_LLVM_PHI_STRICT=1)では必ず Err
-
型整合:
dst_typeと実際に生成する LLVM type が一致していること- mismatch を “CRITICAL” として可視化する(Phase 276 P0 の方針を踏襲)
2) 実装ポイント(現状コードに合わせた最小)
現状の構造(要点):
- llvmlite は “命令の並べ替え” が基本できないため、PHI-first は 生成時に守る必要がある
src/llvm_py/phi_placement.pyは “reorder” ではなく “verify/report” が主
- PHI 配線は
finalize_phisで行われる(PHI placeholder 作成→incoming 配線)- 実際のSSOT呼び出しは
src/llvm_py/builders/function_lower.pyの_finalize_phis(builder, context)経路 NyashLLVMBuilder.finalize_phis()は別実装が残っており、P1では どちらをSSOTにするかを明示する
- 実際のSSOT呼び出しは
実装点(推奨):
- “PHIを遅く作ってしまった” を strict で即死
- 対象:
src/llvm_py/phi_wiring/wiring.py::ensure_phi- すでに
bb.terminatorを検知して warning を出している - P1では
NYASH_LLVM_PHI_STRICT=1のとき、ここを fail-fast(例:raise/unreachable相当)にする
- すでに
- 期待効果: “順序違反の原因” で止まる
- fallback 0 の採用を strict で禁止
- 対象: PHI incoming を解決できず
0を選ぶ箇所src/llvm_py/llvm_builder.pyおよびsrc/llvm_py/phi_wiring/wiring.py::wire_incomingsに存在
- P1では strict のとき:
- “missing snapshot / unresolved” を明示エラーにする
- エラー文に
block_id / dst_vid / pred_bidを含める
- PHI ordering verifier を “実行経路に接続”
- 現状
src/llvm_py/phi_placement.py::verify_phi_ordering(builder)が未使用 - P1では呼び出し点を 1 箇所に固定する:
- 候補:
src/llvm_py/builders/function_lower.pyのlower_terminators(...)後 - strict のときは ordering NG を Err にする
- debug のときは詳細を stderr に出す(
NYASH_LLVM_DEBUG_PHI=1)
- 候補:
補足:
- ここで reorder はできないので、verifier は “最後に怒る” ではなく “生成時の契約が破られていないことを確認する” 目的で使う
3) エラーメッセージ(迷子防止)
エラー文は必ず以下を含める:
- block id
- dst ValueId(PHIの対象)
- expected vs actual(型/順序)
- 次に見るファイル(1つ、固定)
推奨:
- ordering なら
src/llvm_py/phi_wiring/wiring.py(PHI生成の入口) - missing incoming なら
src/llvm_py/llvm_builder.py(snapshot/value解決の入口)
4) 最小テスト
P1 の目的は “検証が働くこと” なので、最小の再現でよい:
- 既存の PHI を含む fixture を 1 つ選ぶ(Phase 275 のものなど)
- strict mode で実行して、違反があれば落ちることを確認する
No new CI jobs.
5) 完了条件
- PHI順序違反が “原因箇所で” fail-fast する
- strict mode が意味を持つ(silent fallback が残っていない)
- 既存の正常ケース(代表スモーク)が退行しない