🔧 Hotfix 7 (Enhanced): ValueId receiver alias tracking for nested loops

- Problem: Pinned receiver variables in loops cause undefined ValueId errors
- Enhanced fix: Update all receiver aliases (me + all __pin$N$@recv levels)
- Handles nested loops by updating previous pin levels
- Test status: Partial improvement, ValueId(50) → ValueId(40)
- Further investigation needed for complete fix

Files modified:
- src/mir/phi_core/loopform_builder.rs (emit_header_phis)
This commit is contained in:
nyash-codex
2025-11-19 00:02:41 +09:00
parent 263affe379
commit 80f8a7bc8c
17 changed files with 983 additions and 277 deletions

View File

@ -1,55 +1,68 @@
// Loop SSA - Exit PHI Generation for Loops with Breaks
// Purpose: Detect loops and inject PHI nodes at exit blocks
// Policy: Uses BreakFinderBox and PhiInjectorBox for modular implementation
// LoopSSA - Exit PHI Generation for Loops with Breaks
// Purpose:
// - Stage1 Program(JSON v0) に対して、loop + break パターンを検出し、
// exit block に PHI 相当の命令を注入する「SSA 補強フェーズ」の入口だよ。
// - 自身はオーケストレータ箱として振る舞い、実際の解析/変換は
// BreakFinderBox / PhiInjectorBox に委譲するよ。
// Policy:
// - 入力: Stage1 Program(JSON v0)(単一関数 or Program 全体)。
// - 出力: exit PHI 相当の命令が入った Program(JSON v0)(文字列)。
// - 解析: BreakFinderBox.find_breaks(json, trace_flag) が JSON を読み取り専用で解析。
// - 変換: PhiInjectorBox.inject_exit_phis(json, breaks, trace_flag) が exit block をテキストベースで書き換える。
// - 環境変数/トレース: HAKO_LOOPSSA_EXIT_PHI / HAKO_COMPILER_BUILDER_TRACE を LoopSSA 側で解釈し、
// 下流には 0/1 の trace_flag だけを渡す(箱ごとに ENV を直読しない)。
using lang.compiler.builder.ssa.exit_phi.break_finder as BreakFinderBox
using lang.compiler.builder.ssa.exit_phi.phi_injector as PhiInjectorBox
static box LoopSSA {
// Main entry: Guard PHI-like merges at loop headers/exits
// Phase 2-5 implementation: detect breaks and inject exit PHIs
stabilize_merges(stage1_json) {
local trace = env.get("HAKO_COMPILER_BUILDER_TRACE")
if trace != null && ("" + trace) == "1" {
print("[loopssa] stabilize_merges start")
}
// Check if exit PHI feature is enabled
local enable_exit_phi = 1
{
local flag = env.get("HAKO_LOOPSSA_EXIT_PHI")
if flag != null && ("" + flag) == "0" { enable_exit_phi = 0 }
}
if enable_exit_phi == 0 {
if trace != null && ("" + trace) == "1" {
print("[loopssa] exit PHI disabled, pass-through")
}
return stage1_json
}
// Phase 2: Find breaks in loops
local breaks = BreakFinderBox.find_breaks(stage1_json)
if trace != null && ("" + trace) == "1" {
print("[loopssa] found " + breaks.length() + " breaks")
}
if breaks.length() == 0 {
if trace != null && ("" + trace) == "1" {
print("[loopssa] no breaks found, pass-through")
}
return stage1_json
}
// Phase 3: Inject PHI nodes at exit blocks
local result = PhiInjectorBox.inject_exit_phis(stage1_json, breaks)
if trace != null && ("" + trace) == "1" {
print("[loopssa] exit PHIs injected successfully")
}
return result
}
}
static box LoopSSA {
// Main entry: Guard PHI-like merges at loop headers/exits
// Phase 2-5 implementation: detect breaks and inject exit PHIs
stabilize_merges(stage1_json) {
// Resolve trace flag once at the entry point0/1 に正規化)
local trace_env = env.get("HAKO_COMPILER_BUILDER_TRACE")
local trace_flag = 0
if trace_env != null && ("" + trace_env) == "1" { trace_flag = 1 }
if trace_flag == 1 {
print("[loopssa] stabilize_merges start")
}
// Check if exit PHI feature is enabled
local enable_exit_phi = 1
{
local flag = env.get("HAKO_LOOPSSA_EXIT_PHI")
if flag != null && ("" + flag) == "0" { enable_exit_phi = 0 }
}
if enable_exit_phi == 0 {
if trace_flag == 1 {
print("[loopssa] exit PHI disabled, pass-through")
}
return stage1_json
}
// Phase 2: Find breaks in loops
local breaks = BreakFinderBox.find_breaks(stage1_json, trace_flag)
if trace_flag == 1 {
print("[loopssa] found " + breaks.length() + " breaks")
}
if breaks.length() == 0 {
if trace_flag == 1 {
print("[loopssa] no breaks found, pass-through")
}
return stage1_json
}
// Phase 3: Inject PHI nodes at exit blocks
local result = PhiInjectorBox.inject_exit_phis(stage1_json, breaks, trace_flag)
if trace_flag == 1 {
print("[loopssa] exit PHIs injected successfully")
}
return result
}
}