refactor(llvm): Phase 132-P1 follow-up - bind block_end_values and clear predeclared PHIs
This commit is contained in:
@ -27,6 +27,16 @@
|
|||||||
- Investigation: [phase132-llvm-exit-phi-wrong-result.md](investigations/phase132-llvm-exit-phi-wrong-result.md)
|
- Investigation: [phase132-llvm-exit-phi-wrong-result.md](investigations/phase132-llvm-exit-phi-wrong-result.md)
|
||||||
- Phase summary: [phases/phase-132/README.md](phases/phase-132/README.md)
|
- Phase summary: [phases/phase-132/README.md](phases/phase-132/README.md)
|
||||||
|
|
||||||
|
## Phase 132-P1 Update (2025-12-15)
|
||||||
|
|
||||||
|
✅ **STRUCTURAL FIX**: Function-local state isolation in LLVM Python backend
|
||||||
|
|
||||||
|
- **Issue**: block id / value id が “関数をまたいで” 衝突し得る(snapshot / cache / PHI state の漏洩)
|
||||||
|
- **Fix**: `FunctionLowerContext` Box で function-scoped state を隔離し、tuple-key workaround を不要化
|
||||||
|
- **Code**:
|
||||||
|
- `src/llvm_py/context/function_lower_context.py`
|
||||||
|
- `src/llvm_py/builders/function_lower.py`
|
||||||
|
|
||||||
## Root Causes Identified
|
## Root Causes Identified
|
||||||
|
|
||||||
### 1. TAG-EMIT: Loop PHI → Invalid LLVM IR (Case B) ✅ FIXED (Phase 131-10)
|
### 1. TAG-EMIT: Loop PHI → Invalid LLVM IR (Case B) ✅ FIXED (Phase 131-10)
|
||||||
|
|||||||
@ -110,3 +110,24 @@ JoinIR merge の契約検証(debug build)で **早期に Fail-Fast** する
|
|||||||
期待される振る舞い:
|
期待される振る舞い:
|
||||||
- debug build では compile/run 中に panic で即停止(原因と修正案が出る)
|
- debug build では compile/run 中に panic で即停止(原因と修正案が出る)
|
||||||
- release build の既定挙動は変えない(検証は `debug_assertions` のみ)
|
- release build の既定挙動は変えない(検証は `debug_assertions` のみ)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 追加: Phase 132-P1(LLVM Python)FunctionLowerContext Box
|
||||||
|
|
||||||
|
Phase 131–132 で顕在化した「関数間の状態漏洩(block id / value id の衝突)」を、
|
||||||
|
tuple-key の小手先ではなく **構造で根治**するために、関数ローカル状態を 1 箱に隔離した。
|
||||||
|
|
||||||
|
- 実装: `src/llvm_py/context/function_lower_context.py`
|
||||||
|
- 統合: `src/llvm_py/builders/function_lower.py`
|
||||||
|
|
||||||
|
箱の責務(SSOT):
|
||||||
|
- `block_end_values`(snapshot)
|
||||||
|
- `def_blocks`
|
||||||
|
- `jump_only_blocks`
|
||||||
|
- `phi_manager`
|
||||||
|
- resolver caches(i64/ptr/f64/end_i64 など)
|
||||||
|
|
||||||
|
狙い:
|
||||||
|
- 関数単位で state を自動破棄し、cross-function collision を “起こせない構造” にする
|
||||||
|
- 追加の手動クリアや tuple-key を不要にする
|
||||||
|
|||||||
@ -51,6 +51,14 @@ def lower_function(builder, func_data: Dict[str, Any]):
|
|||||||
builder.bb_map.clear()
|
builder.bb_map.clear()
|
||||||
except Exception:
|
except Exception:
|
||||||
builder.bb_map = {}
|
builder.bb_map = {}
|
||||||
|
# Phase 132-P1: Clear per-function predeclared PHI placeholders (avoid cross-function leakage)
|
||||||
|
try:
|
||||||
|
builder.predeclared_ret_phis.clear()
|
||||||
|
except Exception:
|
||||||
|
try:
|
||||||
|
builder.predeclared_ret_phis = {}
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
# Phase 132-P1: Create function-local context Box
|
# Phase 132-P1: Create function-local context Box
|
||||||
# This automatically isolates all function-scoped state
|
# This automatically isolates all function-scoped state
|
||||||
@ -63,6 +71,7 @@ def lower_function(builder, func_data: Dict[str, Any]):
|
|||||||
builder.phi_manager = context.phi_manager
|
builder.phi_manager = context.phi_manager
|
||||||
builder.block_phi_incomings = context.block_phi_incomings
|
builder.block_phi_incomings = context.block_phi_incomings
|
||||||
builder.def_blocks = context.def_blocks
|
builder.def_blocks = context.def_blocks
|
||||||
|
builder.block_end_values = context.block_end_values
|
||||||
|
|
||||||
# Bind resolver to context (redirects caches to context storage)
|
# Bind resolver to context (redirects caches to context storage)
|
||||||
builder.resolver.bind_context(context)
|
builder.resolver.bind_context(context)
|
||||||
@ -311,7 +320,7 @@ def lower_function(builder, func_data: Dict[str, Any]):
|
|||||||
vmap=builder.vmap,
|
vmap=builder.vmap,
|
||||||
bb_map=builder.bb_map,
|
bb_map=builder.bb_map,
|
||||||
preds=builder.preds,
|
preds=builder.preds,
|
||||||
block_end_values=builder.block_end_values,
|
block_end_values=context.block_end_values,
|
||||||
resolver=builder.resolver,
|
resolver=builder.resolver,
|
||||||
trace_phi=os.environ.get('NYASH_LLVM_TRACE_PHI') == '1',
|
trace_phi=os.environ.get('NYASH_LLVM_TRACE_PHI') == '1',
|
||||||
verbose=os.environ.get('NYASH_CLI_VERBOSE') == '1',
|
verbose=os.environ.get('NYASH_CLI_VERBOSE') == '1',
|
||||||
|
|||||||
Reference in New Issue
Block a user