🔧 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:
@ -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:
|
||||
// - Stage‑1 Program(JSON v0) に対して、loop + break パターンを検出し、
|
||||
// exit block に PHI 相当の命令を注入する「SSA 補強フェーズ」の入口だよ。
|
||||
// - 自身はオーケストレータ箱として振る舞い、実際の解析/変換は
|
||||
// BreakFinderBox / PhiInjectorBox に委譲するよ。
|
||||
// Policy:
|
||||
// - 入力: Stage‑1 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 point(0/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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user