diff --git a/src/mir/loop_builder.rs b/src/mir/loop_builder.rs index bd03ea80..96e705ab 100644 --- a/src/mir/loop_builder.rs +++ b/src/mir/loop_builder.rs @@ -384,88 +384,21 @@ impl<'a> LoopBuilder<'a> { // BreakFinderBox / FuncScannerBox 等で、loop body 内で新規宣言された local 変数が // loop header に戻った時に undefined になる問題を修正 // - // Step 5-5-A: PHI pred mismatch 根本修正 - // - Preheader入力(poison)とLatch入力の両方を即座に追加 - // - 空PHI生成→後で埋める方式は不完全だった(seal_phisが処理しない) + // Step 5-5-B: EXPERIMENTAL - Body-local Header PHI generation DISABLED + // Reason: Option C design states body-local variables should NOT have header PHIs + // - BodyLocalExit: needs EXIT PHI only, NOT header PHI + // - BodyLocalInternal: needs NO PHI at all + // + // TODO Step 5-3: Integrate Option C classification (LoopVarClassBox) here + // + // TEMPORARY DISABLE to test hypothesis that header PHIs are the root cause let trace_loop_phi = std::env::var("HAKO_LOOP_PHI_TRACE").ok().as_deref() == Some("1"); - if trace_loop_phi { - eprintln!("[loop-phi/body-local] Checking for body-local variables"); - eprintln!(" current_vars.len()={}, body_end_vars.len()={}", current_vars.len(), body_end_vars.len()); - } - // Detect body-local variables (variables declared in body, not in preheader) - let body_local_vars: Vec<(String, ValueId)> = body_end_vars - .iter() - .filter(|(name, _value)| !current_vars.contains_key(name.as_str())) - .map(|(name, value)| (name.clone(), *value)) - .collect(); - - if !body_local_vars.is_empty() { - if trace_loop_phi { - eprintln!("[loop-phi/body-local] Found {} body-local variables", body_local_vars.len()); - } - - // Step 5-5-A: Add PHI nodes with BOTH inputs (preheader + latch) - for (var_name, _body_value) in &body_local_vars { - if trace_loop_phi { - eprintln!("[loop-phi/body-local] Adding PHI for body-local var: {}", var_name); - } - - let phi_id = self.new_value(); - - // Step 5-5-A: Preheader input is poison (variable doesn't exist yet) - let preheader_poison = self.new_value(); - - // Emit Const::Poison instruction in preheader block - if let Some(ref mut func) = self.parent_builder.current_function { - if let Some(preheader_block) = func.blocks.get_mut(&preheader_id) { - preheader_block.add_instruction(MirInstruction::Const { - dst: preheader_poison, - value: crate::mir::ConstValue::Null, // Poison semantics - }); - } - } - - // Step 5-5-A FIX: Get latch value from current variable map - // The variable map was updated at line 374-377 with body_end_vars, - // so looking it up now gives us the correct ValueId for the latch block. - let latch_value = self.get_current_variable_map() - .get(var_name) - .copied() - .unwrap_or(phi_id); // Fallback to phi_id if not found - - // Step 5-5-A: Insert PHI with BOTH inputs (preheader poison + latch value) - if let Some(ref mut func) = self.parent_builder.current_function { - if let Some(header_block) = func.blocks.get_mut(&header_id) { - // Find position after existing PHIs - let phi_count = header_block.phi_instructions().count(); - header_block.instructions.insert( - phi_count, - MirInstruction::Phi { - dst: phi_id, - inputs: vec![ - (preheader_id, preheader_poison), // ← Preheader input (poison) - (latch_id, latch_value), // ← Latch input (from variable map) - ], - }, - ); - } - } - - // Rebind variable to PHI - self.update_variable(var_name.clone(), phi_id); - - if trace_loop_phi { - eprintln!( - "[loop-phi/body-local] Created PHI {}: preheader={} (poison), latch={} ({})", - phi_id.0, preheader_poison.0, latch_id.0, latch_value.0 - ); - } - } - - if trace_loop_phi { - eprintln!("[loop-phi/body-local] Added {} body-local PHIs with complete inputs", body_local_vars.len()); - } + // DISABLED: Body-local header PHI generation + // This code was causing undefined value errors because it created header PHIs + // for variables that should only have exit PHIs (or no PHIs at all) + if false { // Disabled for Step 5-5-B experiment + // [Original code removed - see git history if needed] } // Pass 4: Generate continue_merge PHIs first, then seal header PHIs