diff --git a/CLAUDE.md b/CLAUDE.md index 051e7d8d..f0636144 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -276,6 +276,16 @@ NYASH_DISABLE_PLUGINS=1 ./target/release/nyash program.nyash NYASH_LLVM_USE_HARNESS=1 ./target/release/nyash program.nyash ``` +## 📝 Update (2025-09-22) ⚡ フェーズM実装大幅進展!PHI一本化によるコード大削減達成 +- ✅ **MirBuilder no_phi_mode完全撤廃!** phi.rs、exprs_peek.rs全分岐をPHI命令一本化 +- ✅ **LoopBuilder no_phi_mode完全撤廃!** 3箇所のedge copy分岐をPHI命令一本化 +- ✅ **edge_copy関連コード削除!** insert_edge_copy()メソッド含む数十行削減 +- 🔧 **ビルド成功維持!** フェーズS+フェーズM修正でもエラーなしを確認 +- ⏳ **JSON v0 Bridge保留中**: Phase 15重要コンポーネントのため慎重対応予定 +- 🎯 **次の一歩**: collect_prints動作確認→JSON v0 Bridge対応→フェーズM完了 +- 📊 **戦略文書更新**: break-control-flow-strategy.mdの段階的根治計画に沿って実行 +- 🚀 **効果**: 数百行削減によりPhase 15の80k→20k圧縮目標に大きく貢献 + ## 📝 Update (2025-09-22) 🎯 Phase 15 JITアーカイブ完了&デバッグ大進展! - ✅ **JIT/Craneliftアーカイブ完了!** Phase 15集中開発のため全JIT機能を安全にアーカイブ - 🔧 **コンパイルエラー全解決!** JITスタブ作成でビルド成功、開発環境復活 @@ -317,17 +327,13 @@ NYASH_LLVM_USE_HARNESS=1 ./target/release/nyash program.nyash - 🗃️ **アーカイブ整理**: 古いphaseファイル群をarchiveに移動、導線クリーンアップ完了 - 📋 詳細: [Property System仕様](docs/proposals/unified-members.md) | [Python統合計画](docs/development/roadmap/phases/phase-10.7/) -## 📝 Update (2025-09-23) 🔧 break制御フロー問題の段階的根治戦略確定! -- 🎯 **AI協働分析完了!** task+Gemini+codex+ChatGPT Pro最強モードで根本原因完全特定 -- 🔍 **根本問題**: break文が値を返す設計歪み → collect_printsメソッドでnull値返却 -- 🚀 **3段階根治戦略決定**: - - **フェーズS(即効止血)**: PHI incoming修正+終端ガード徹底 - - **フェーズM(PHI一本化)**: no_phi_mode撤廃で数百行削減 - - **フェーズL(根本解決)**: BuildOutcome導入で完全治癒 -- 📊 **期待効果**: 80k→20k圧縮に大きく貢献+設計歪み根絶 -- 💾 **codex解決策保存**: archive/codex-solutions/に高度な型推論実装を保管 -- 📚 **戦略文書化**: [break-control-flow-strategy.md](docs/development/strategies/break-control-flow-strategy.md)完成 -- 🎯 **次のアクション**: フェーズSから段階的実行開始 +## 📝 Update (2025-09-23) ✅ フェーズS実装完了!break制御フロー根治開始 +- ✅ **フェーズS完了!** PHI incoming修正+終端ガード徹底→重複処理4箇所統一 +- 🔧 **新ユーティリティ**: `src/mir/utils/control_flow.rs`で制御フロー処理統一化 +- 📊 **AI協働成果**: task+Gemini+codex+ChatGPT Pro最強分析→段階的実装戦略確立 +- 🎯 **次段階**: フェーズM(PHI一本化)→数百行削減でPhase 15目標達成へ +- 📚 **戦略**: [break-control-flow-strategy.md](docs/development/strategies/break-control-flow-strategy.md) +- 💾 **アーカイブ**: codex高度解決策を`archive/codex-solutions/`に保存 ## 📝 Update (2025-09-14) 🎉 セルフホスティング大前進! - ✅ Python LLVM実装が実用レベル到達!(esc_dirname_smoke, min_str_cat_loop, dep_tree_min_string全てPASS) diff --git a/src/mir/builder.rs b/src/mir/builder.rs index 16b03c7a..f8a6be08 100644 --- a/src/mir/builder.rs +++ b/src/mir/builder.rs @@ -106,8 +106,7 @@ pub struct MirBuilder { /// when lowering nested conditionals and to simplify jump generation. pub(super) if_merge_stack: Vec, - /// Whether PHI emission is disabled (edge-copy mode) - pub(super) no_phi_mode: bool, + // フェーズM: no_phi_modeフィールド削除(常にPHI使用) // ---- Try/Catch/Cleanup lowering context ---- /// When true, `return` statements are deferred: they assign to `return_defer_slot` @@ -133,7 +132,7 @@ impl MirBuilder { /// Create a new MIR builder pub fn new() -> Self { let plugin_method_sigs = plugin_sigs::load_plugin_method_sigs(); - let no_phi_mode = crate::config::env::mir_no_phi(); + // フェーズM: no_phi_mode初期化削除 Self { current_module: None, current_function: None, @@ -155,7 +154,7 @@ impl MirBuilder { loop_header_stack: Vec::new(), loop_exit_stack: Vec::new(), if_merge_stack: Vec::new(), - no_phi_mode, + // フェーズM: no_phi_modeフィールド削除 return_defer_active: false, return_defer_slot: None, return_defer_target: None, @@ -339,48 +338,9 @@ impl MirBuilder { } } - pub(super) fn is_no_phi_mode(&self) -> bool { - self.no_phi_mode - } + // フェーズM: is_no_phi_mode()メソッド削除 - /// Insert a Copy instruction into `block_id`, defining `dst` from `src`. - /// Skips blocks that terminate via return/throw, and avoids duplicate copies. - pub(super) fn insert_edge_copy( - &mut self, - block_id: BasicBlockId, - dst: ValueId, - src: ValueId, - ) -> Result<(), String> { - // No-op self copy guard to avoid useless instructions and accidental reordering issues - if dst == src { - return Ok(()); - } - if let Some(ref mut function) = self.current_function { - let block = function - .get_block_mut(block_id) - .ok_or_else(|| format!("Basic block {} does not exist", block_id))?; - if let Some(term) = &block.terminator { - if matches!( - term, - MirInstruction::Return { .. } | MirInstruction::Throw { .. } - ) { - return Ok(()); - } - } - let already_present = block.instructions.iter().any(|inst| { - matches!(inst, MirInstruction::Copy { dst: existing_dst, .. } if *existing_dst == dst) - }); - if !already_present { - block.add_instruction(MirInstruction::Copy { dst, src }); - } - if let Some(ty) = self.value_types.get(&src).cloned() { - self.value_types.insert(dst, ty); - } - Ok(()) - } else { - Err("No current function".to_string()) - } - } + // フェーズM: insert_edge_copy()メソッド削除(no_phi_mode撤廃により不要) // moved to builder/utils.rs: ensure_block_exists diff --git a/src/mir/builder/exprs_peek.rs b/src/mir/builder/exprs_peek.rs index a7ab4598..32bf3be1 100644 --- a/src/mir/builder/exprs_peek.rs +++ b/src/mir/builder/exprs_peek.rs @@ -50,16 +50,11 @@ impl super::MirBuilder { target: merge_block, })?; self.start_new_block(merge_block)?; - if self.is_no_phi_mode() { - for (pred, val) in phi_inputs { - self.insert_edge_copy(pred, result_val, val)?; - } - } else { - self.emit_instruction(super::MirInstruction::Phi { - dst: result_val, - inputs: phi_inputs, - })?; - } + // フェーズM: 常にPHI命令を使用(no_phi_mode撤廃) + self.emit_instruction(super::MirInstruction::Phi { + dst: result_val, + inputs: phi_inputs, + })?; return Ok(result_val); } @@ -122,16 +117,11 @@ impl super::MirBuilder { // Merge and yield result self.start_new_block(merge_block)?; - if self.is_no_phi_mode() { - for (pred, val) in phi_inputs { - self.insert_edge_copy(pred, result_val, val)?; - } - } else { - self.emit_instruction(super::MirInstruction::Phi { - dst: result_val, - inputs: phi_inputs, - })?; - } + // フェーズM: 常にPHI命令を使用(no_phi_mode撤廃) + self.emit_instruction(super::MirInstruction::Phi { + dst: result_val, + inputs: phi_inputs, + })?; Ok(result_val) } } diff --git a/src/mir/builder/phi.rs b/src/mir/builder/phi.rs index a9e1d873..8c6c2d0f 100644 --- a/src/mir/builder/phi.rs +++ b/src/mir/builder/phi.rs @@ -113,27 +113,15 @@ impl MirBuilder { .as_ref() .and_then(|m| m.get(name).copied()) .unwrap_or(pre); - if self.is_no_phi_mode() { - let merged = self.value_gen.next(); - // Insert edge copies from then/else exits into merge - self.insert_edge_copy(then_exit_block, merged, then_v)?; - if let Some(else_exit_block) = else_exit_block_opt { - self.insert_edge_copy(else_exit_block, merged, else_v)?; - } else { - // Fallback: if else missing, copy pre value from then as both inputs already cover - self.insert_edge_copy(then_exit_block, merged, then_v)?; + // フェーズM: 常にPHI命令を使用(no_phi_mode撤廃) + let merged = self.value_gen.next(); + self.emit_instruction( + MirInstruction::Phi { + dst: merged, + inputs: vec![(then_block, then_v), (else_block, else_v)], } - self.variable_map.insert(name.to_string(), merged); - } else { - let merged = self.value_gen.next(); - self.emit_instruction( - MirInstruction::Phi { - dst: merged, - inputs: vec![(then_block, then_v), (else_block, else_v)], - } - )?; - self.variable_map.insert(name.to_string(), merged); - } + )?; + self.variable_map.insert(name.to_string(), merged); } Ok(()) } @@ -162,71 +150,7 @@ impl MirBuilder { .and_then(|a| extract_assigned_var(a)); let result_val = self.value_gen.next(); - if self.is_no_phi_mode() { - // In PHI-off mode, emit per-predecessor copies into the actual predecessors - // of the current (merge) block instead of the entry blocks. This correctly - // handles nested conditionals where the then-branch fans out and merges later. - let merge_block = self - .current_block - .ok_or_else(|| "normalize_if_else_phi: no current (merge) block".to_string())?; - let preds: Vec = if let Some(ref fun_ro) = self.current_function { - if let Some(bb) = fun_ro.get_block(merge_block) { - bb.predecessors.iter().copied().collect() - } else { - Vec::new() - } - } else { - Vec::new() - }; - // Prefer explicit exit blocks if provided; fall back to predecessor scan - let then_exits: Vec = if let Some(b) = then_exit_block_opt { - vec![b] - } else { - preds.iter().copied().filter(|p| *p != else_block).collect() - }; - let else_exits: Vec = if let Some(b) = else_exit_block_opt { - vec![b] - } else { - preds.iter().copied().filter(|p| *p == else_block).collect() - }; - - if let Some(var_name) = assigned_var_then.clone() { - let else_assigns_same = assigned_var_else - .as_ref() - .map(|s| s == &var_name) - .unwrap_or(false); - let then_value_for_var = then_var_map_end - .get(&var_name) - .copied() - .unwrap_or(then_value_raw); - let else_value_for_var = if else_assigns_same { - else_var_map_end_opt - .as_ref() - .and_then(|m| m.get(&var_name).copied()) - .unwrap_or(else_value_raw) - } else { - pre_then_var_value.unwrap_or(else_value_raw) - }; - // Map predecessors: else_block retains else value; others take then value - for p in then_exits.iter().copied() { - self.insert_edge_copy(p, result_val, then_value_for_var)?; - } - for p in else_exits.iter().copied() { - self.insert_edge_copy(p, result_val, else_value_for_var)?; - } - self.variable_map = pre_if_var_map.clone(); - self.variable_map.insert(var_name, result_val); - } else { - for p in then_exits.iter().copied() { - self.insert_edge_copy(p, result_val, then_value_raw)?; - } - for p in else_exits.iter().copied() { - self.insert_edge_copy(p, result_val, else_value_raw)?; - } - self.variable_map = pre_if_var_map.clone(); - } - return Ok(result_val); - } + // フェーズM: no_phi_mode分岐削除(常にPHI命令を使用) if let Some(var_name) = assigned_var_then.clone() { let else_assigns_same = assigned_var_else diff --git a/src/mir/loop_builder.rs b/src/mir/loop_builder.rs index bd5981c5..2c847100 100644 --- a/src/mir/loop_builder.rs +++ b/src/mir/loop_builder.rs @@ -45,8 +45,7 @@ pub struct LoopBuilder<'a> { /// continue文からの変数スナップショット continue_snapshots: Vec<(BasicBlockId, HashMap)>, - /// PHI を生成しないモードかどうか - no_phi_mode: bool, + // フェーズM: no_phi_modeフィールド削除(常にPHI使用) } // (removed) extract_assigned_var_local was a local helper used during @@ -103,14 +102,14 @@ impl<'a> LoopBuilder<'a> { // ============================================================= /// 新しいループビルダーを作成 pub fn new(parent: &'a mut super::builder::MirBuilder) -> Self { - let no_phi_mode = parent.is_no_phi_mode(); + // フェーズM: no_phi_mode初期化削除 Self { parent_builder: parent, incomplete_phis: HashMap::new(), block_var_maps: HashMap::new(), loop_header: None, continue_snapshots: Vec::new(), - no_phi_mode, + // フェーズM: no_phi_modeフィールド削除 } } @@ -278,10 +277,7 @@ impl<'a> LoopBuilder<'a> { incomplete_phis.push(incomplete_phi); - if self.no_phi_mode { - self.parent_builder - .insert_edge_copy(preheader_id, phi_id, value_before)?; - } + // フェーズM: no_phi_mode分岐削除(常にPHI使用) // 変数マップを更新(Phi nodeの結果を使用) self.update_variable(var_name.clone(), phi_id); @@ -310,17 +306,8 @@ impl<'a> LoopBuilder<'a> { phi.known_inputs.push((latch_id, value_after)); - if self.no_phi_mode { - let mut seen: HashSet = HashSet::new(); - for &(pred, val) in &phi.known_inputs { - if seen.insert(pred) { - self.parent_builder - .insert_edge_copy(pred, phi.phi_id, val)?; - } - } - } else { - self.emit_phi_at_block_start(block_id, phi.phi_id, phi.known_inputs)?; - } + // フェーズM: 常にPHI命令を使用(no_phi_mode分岐削除) + self.emit_phi_at_block_start(block_id, phi.phi_id, phi.known_inputs)?; self.update_variable(phi.var_name.clone(), phi.phi_id); } } @@ -601,13 +588,8 @@ impl<'a> LoopBuilder<'a> { } _ => { let phi_id = self.new_value(); - if self.no_phi_mode { - for (pred, v) in incomings.iter().copied() { - self.parent_builder.insert_edge_copy(pred, phi_id, v)?; - } - } else { - self.emit_phi_at_block_start(merge_bb, phi_id, incomings)?; - } + // フェーズM: 常にPHI命令を使用(no_phi_mode分岐削除) + self.emit_phi_at_block_start(merge_bb, phi_id, incomings)?; self.parent_builder.variable_map.insert(var_name, phi_id); } }