loopform: add exit PHI fallthrough for body-local vars

This commit is contained in:
nyash-codex
2025-11-19 23:53:41 +09:00
parent 525e59bc8d
commit 7c3f1eafde

View File

@ -412,6 +412,41 @@ impl LoopFormBuilder {
.push((branch_source_block, carrier.header_phi));
}
// Phase 25.1c/k: Add header fallthrough for body-local variables
// Body-local variables (declared inside loop body) are not in pinned/carriers,
// but they need exit PHI with header fallthrough when accessed after loop.
// Collect all variables from exit_snapshots and add header values for body-locals.
let mut body_local_names: std::collections::HashSet<String> = std::collections::HashSet::new();
for (_block_id, snapshot) in exit_snapshots {
for var_name in snapshot.keys() {
// Check if this variable is NOT in pinned/carriers (= body-local)
let is_pinned = self.pinned.iter().any(|p| &p.name == var_name);
let is_carrier = self.carriers.iter().any(|c| &c.name == var_name);
if !is_pinned && !is_carrier {
body_local_names.insert(var_name.clone());
}
}
}
if debug && !body_local_names.is_empty() {
eprintln!("[DEBUG/exit_phi] Found {} body-local variables in exit_snapshots", body_local_names.len());
}
// Get header variable map and add fallthrough for body-locals
for var_name in &body_local_names {
if let Some(header_value) = ops.get_variable_at_block(var_name, self.header_id) {
all_vars
.entry(var_name.clone())
.or_default()
.push((branch_source_block, header_value));
if debug {
eprintln!("[DEBUG/exit_phi] Added header fallthrough for body-local '{}': {:?}", var_name, header_value);
}
} else if debug {
eprintln!("[DEBUG/exit_phi] ⚠️ Body-local '{}' not found at header block", var_name);
}
}
// 📦 Hotfix 6: Get actual CFG predecessors for exit block
let exit_preds = ops.get_block_predecessors(exit_id);
if debug {