refactor(llvm): Phase 131-12-P2 - block_end_values SSOT 化(WIP)
## 実装内容 - get_end_values() API 追加 - _value_at_end_i64() を snapshot-only に変更 - def_blocks 即時更新 - PHI incoming を snapshot から取得 ## 発見された問題 - 同一ブロック内の def→use が predecessor snapshot を見てしまう - これは次フェーズで resolve_cur / resolve_incoming 分離で修正 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -58,39 +58,42 @@ def lower_phi(
|
||||
# Fallback: use blocks in incoming list
|
||||
actual_preds = [b for _, b in incoming]
|
||||
|
||||
# Collect incoming values
|
||||
# P1: Collect incoming values from corresponding snapshots (SSOT)
|
||||
incoming_pairs: List[Tuple[ir.Block, ir.Value]] = []
|
||||
used_default_zero = False
|
||||
|
||||
import os
|
||||
strict_mode = os.environ.get('NYASH_LLVM_STRICT') == '1'
|
||||
|
||||
for block_id in actual_preds:
|
||||
block = bb_map.get(block_id)
|
||||
vid = incoming_map.get(block_id)
|
||||
if block is None:
|
||||
continue
|
||||
# Prefer resolver-driven localization per predecessor block to satisfy dominance
|
||||
if vid is not None and resolver is not None and bb_map is not None:
|
||||
try:
|
||||
pred_block_obj = bb_map.get(block_id)
|
||||
if pred_block_obj is not None and hasattr(resolver, 'resolve_i64'):
|
||||
val = resolver.resolve_i64(vid, pred_block_obj, preds_map or {}, block_end_values or {}, vmap, bb_map)
|
||||
else:
|
||||
val = None
|
||||
except Exception:
|
||||
val = None
|
||||
if val is None:
|
||||
# Missing incoming for this predecessor → default 0
|
||||
val = ir.Constant(phi_type, 0)
|
||||
used_default_zero = True
|
||||
|
||||
# P1: Get value from pred_bid's snapshot (SSOT - no global search)
|
||||
if block_end_values is not None:
|
||||
pred_snapshot = block_end_values.get(block_id, {})
|
||||
val = pred_snapshot.get(vid) if vid is not None else None
|
||||
else:
|
||||
val = None
|
||||
|
||||
if val is None:
|
||||
# P1: STRICT mode - fail fast on snapshot miss
|
||||
if strict_mode:
|
||||
available_keys = sorted(list(pred_snapshot.keys())) if block_end_values is not None else []
|
||||
raise RuntimeError(
|
||||
f"[LLVM_PY/STRICT] PHI incoming miss:\n"
|
||||
f" Source ValueId: v{vid}\n"
|
||||
f" Predecessor Block: bb{block_id}\n"
|
||||
f" PHI destination: v{dst_vid}\n"
|
||||
f" Available in snapshot: {available_keys}\n"
|
||||
f" Hint: Value v{vid} should be in block_end_values[{block_id}]"
|
||||
)
|
||||
# Non-STRICT: fallback to 0
|
||||
val = ir.Constant(phi_type, 0)
|
||||
used_default_zero = True
|
||||
else:
|
||||
# Snapshot fallback
|
||||
if block_end_values is not None:
|
||||
snap = block_end_values.get(block_id, {})
|
||||
val = snap.get(vid) if vid is not None else None
|
||||
else:
|
||||
val = vmap.get(vid) if vid is not None else None
|
||||
if not val:
|
||||
# Missing incoming for this predecessor → default 0
|
||||
val = ir.Constant(phi_type, 0)
|
||||
used_default_zero = True
|
||||
# Coerce pointer to i64 at predecessor end
|
||||
if hasattr(val, 'type') and val.type != phi_type:
|
||||
pb = ir.IRBuilder(block)
|
||||
|
||||
Reference in New Issue
Block a user