feat(llvm): Phase 131-4 P1 完了 - PHI ordering 修正(multi-pass architecture)

Phase 131-4 P1: PHI After Terminator Bug 修正

問題:
- LLVM IR で PHI が terminator の後に出現(LLVM invariant 違反)
- Case B (loop_min_while.hako) が TAG-EMIT で失敗

修正:
- Multi-pass block lowering architecture 実装:
  - Pass A: non-terminator instructions のみ emit
  - Pass B: PHI finalization(block head に確実に配置)
  - Pass C: deferred terminators を最後に emit

変更ファイル:
- src/llvm_py/builders/block_lower.py (~40行):
  - lower_blocks() で terminator を defer
  - lower_terminators() 新設(Pass C)
  - _deferred_terminators dict で管理
- src/llvm_py/builders/function_lower.py (3行):
  - Pass 順序更新: A→B→C
- src/llvm_py/instructions/ret.py (5行):
  - _disable_phi_synthesis flag で Pass C 中の PHI 生成を抑制

テスト結果:
- Case B EMIT:  (修正成功)
- Case B LINK:  (新 TAG-LINK: undefined nyash_console_log)
- Case A/B2:  (退行なし)

箱化モジュール化:
-  Multi-pass で責務分離
-  Flag mechanism で構造的制御
-  ハードコード禁止原則遵守

Next: Phase 131-5 (TAG-LINK 修正)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-14 06:12:31 +09:00
parent 5709026812
commit 73613dcef0
4 changed files with 138 additions and 30 deletions

View File

@ -275,6 +275,7 @@ def lower_function(builder, func_data: Dict[str, Any]):
except Exception:
loop_plan = None
# Phase 131-4 Pass A: Lower non-terminator instructions (terminators deferred)
from builders.block_lower import lower_blocks as _lower_blocks
_lower_blocks(builder, func, block_by_id, order, loop_plan)
@ -299,9 +300,13 @@ def lower_function(builder, func_data: Dict[str, Any]):
except Exception:
pass
# Finalize PHIs for this function
# Phase 131-4 Pass B: Finalize PHIs (wires incoming edges)
_finalize_phis(builder)
# Phase 131-4 Pass C: Lower deferred terminators (after PHIs are placed)
from builders.block_lower import lower_terminators as _lower_terminators
_lower_terminators(builder, func)
# Safety pass: ensure every basic block ends with a terminator.
# This avoids llvmlite IR parse errors like "expected instruction opcode" on empty blocks.
try: