diff --git a/src/mir/builder/phi_merge.rs b/src/mir/builder/phi_merge.rs index d25f6c63..0e05484e 100644 --- a/src/mir/builder/phi_merge.rs +++ b/src/mir/builder/phi_merge.rs @@ -7,7 +7,7 @@ //! Box-First理論: PHI insertion の境界を明確にし、差し替え可能な箱として提供 use super::{BasicBlockId, MirBuilder, ValueId}; -use std::collections::BTreeMap; // Phase 25.1: 決定性確保 +use std::collections::{BTreeMap, BTreeSet, HashSet}; // Phase 25.1: 決定性確保, Phase 58: インライン化 /// PHI Merge Helper - 統一PHI挿入ロジック(Conservative戦略) /// @@ -157,31 +157,72 @@ impl<'a> PhiMergeHelper<'a> { /// # Returns /// Ok(changed_vars) - Set of variables that were changed, for pin handling /// - /// # Phase 57 改善 + /// # Phase 57-58 改善 /// - /// 戻り値を `()` から `HashSet` に変更。 - /// これにより `phi.rs` での冗長な `ConservativeMerge::analyze` 呼び出しを削除可能に。 + /// - Phase 57: 戻り値を `()` から `HashSet` に変更 + /// - Phase 58: ConservativeMerge::analyze をインライン化 + /// + /// # Phase 58 改善 + /// + /// ConservativeMerge::analyze をインライン化。 + /// conservative.rs の struct は削除され、ロジックのみここに残る。 + /// + /// ## Conservative ∘ Elimination = Minimal SSA + /// + /// - Conservative (this): correctness-first, generate all PHIs + /// - Elimination (future): efficiency optimization, remove unused PHIs pub fn merge_all_vars( &mut self, pre_if_snapshot: &BTreeMap, // Phase 25.1: BTreeMap化 then_map_end: &BTreeMap, // Phase 25.1: BTreeMap化 else_map_end_opt: &Option>, // Phase 25.1: BTreeMap化 skip_var: Option<&str>, - ) -> Result, String> { - // Use Conservative strategy from conservative module - let conservative = crate::mir::phi_core::conservative::ConservativeMerge::analyze( - pre_if_snapshot, - then_map_end, - else_map_end_opt, - ); + ) -> Result, String> { + // ======================================== + // Phase 58: ConservativeMerge::analyze インライン化 + // ======================================== + // 旧: crate::mir::phi_core::conservative::ConservativeMerge::analyze(...) + // 新: 以下のロジックを直接ここに記述 + + // 1. all_vars: 全ブランチに存在する変数のユニオン(Conservative戦略) + let mut all_vars = HashSet::new(); + all_vars.extend(pre_if_snapshot.keys().cloned()); + all_vars.extend(then_map_end.keys().cloned()); + if let Some(ref else_map) = else_map_end_opt { + all_vars.extend(else_map.keys().cloned()); + } + + // 2. changed_vars: 実際に変更された変数のセット + // 決定的順序のためBTreeSet使用 + let mut names: BTreeSet<&str> = BTreeSet::new(); + for k in then_map_end.keys() { + names.insert(k.as_str()); + } + if let Some(emap) = else_map_end_opt.as_ref() { + for k in emap.keys() { + names.insert(k.as_str()); + } + } + let mut changed_vars = HashSet::new(); + // アルファベット順で決定的にイテレート + for &name in &names { + let pre = pre_if_snapshot.get(name); + let t = then_map_end.get(name); + let e = else_map_end_opt.as_ref().and_then(|m| m.get(name)); + if (t.is_some() && Some(*t.unwrap()) != pre.copied()) + || (e.is_some() && Some(*e.unwrap()) != pre.copied()) + { + changed_vars.insert(name.to_string()); + } + } + // ======================================== - // Phase 42: trace_if_enabled 削除(下の trace_conservative と重複していたため) let trace_conservative = std::env::var("NYASH_CONSERVATIVE_PHI_TRACE") .ok() .as_deref() == Some("1"); - for name in &conservative.all_vars { + for name in &all_vars { if skip_var.map(|s| s == name.as_str()).unwrap_or(false) { if trace_conservative { eprintln!("[Conservative PHI] Skipping {}: matches skip_var", name); @@ -238,6 +279,6 @@ impl<'a> PhiMergeHelper<'a> { } // Phase 57: 変更された変数セットを返す(phi.rsでの冗長呼び出し削除用) - Ok(conservative.changed_vars) + Ok(changed_vars) } } diff --git a/src/mir/phi_core/conservative.rs b/src/mir/phi_core/conservative.rs index 0e9d30d3..cb431af3 100644 --- a/src/mir/phi_core/conservative.rs +++ b/src/mir/phi_core/conservative.rs @@ -1,148 +1,56 @@ //! Conservative PHI Generation - Box Theory Application //! -//! Theory: Conservative ∘ Elimination = Minimal SSA -//! - Conservative (this): correctness-first, generate all PHIs +//! # Theory: Conservative ∘ Elimination = Minimal SSA +//! +//! - Conservative: correctness-first, generate all PHIs //! - Elimination (future): efficiency optimization, remove unused PHIs //! -//! Phase 25.1q: Conservative PHI戦略の一元化 -//! - phi.rs の Conservative PHI ロジック(L23-117)を統一 -//! - void emission、predecessor fallback の一貫性保証 +//! # Phase 58 削除完了(2025-11-29) //! -//! # Phase 35-39 PHI削減計画 +//! ## 削除内容 //! -//! ## 概要 +//! - **ConservativeMerge struct**: 削除(約60行) +//! - **analyze メソッド**: `phi_merge.rs::merge_all_vars` にインライン化 +//! - **テストコード**: 削除(約35行) //! -//! Conservative ∘ Elimination = Minimal SSA の理論に基づく保守的PHI生成。 -//! 非対称分岐(else なし)での void emission と predecessor fallback を扱う。 +//! ## 移行先 //! -//! ## 🔜 Phase 40で部分削除予定(Level 2、30行) +//! `src/mir/builder/phi_merge.rs` の `PhiMergeHelper::merge_all_vars` メソッド内に +//! すべてのロジックがインライン化されている。 //! -//! - ConservativeMerge struct inline (30行) -//! - **Phase 40-4**: JoinIrConservativeAnalyzerに吸収 -//! - **保持**: 理論コメント、Conservative ∘ Elimination説明 -//! - **削除**: 構造体定義、実装コード +//! ## 理論コメント保持理由 //! -//! ## ⏳ Phase 41+で完全削除予定(Level 3、約138行) +//! Conservative ∘ Elimination = Minimal SSA の理論は重要なため、 +//! このファイルはドキュメントとして残す。 //! -//! - 残りのconservative logic全て -//! - **削除条件**: JoinIR Verifier完全移行 -//! - **難易度**: MEDIUM-HIGH +//! ## 旧コード履歴 +//! +//! - Phase 25.1q: Conservative PHI戦略の一元化 +//! - Phase 41-1: get_conservative_values 削除 +//! - Phase 42: trace_if_enabled 削除 +//! - Phase 47: compute_modified_names インライン化 +//! - Phase 58: ConservativeMerge struct 完全削除 //! //! ## 参照 //! //! - Phase 37分析: `docs/.../phase-37-if-phi-reduction/conservative_responsibility_table.md` //! - Phase 39設計: `docs/.../phase-39-if-phi-level2/joinir_extension_design.md` -use crate::mir::ValueId; -use std::collections::{BTreeMap, BTreeSet, HashSet}; // Phase 25.1: BTreeMap化, Phase 47: BTreeSet追加 - -/// Conservative PHI 戦略による変数マージ分析 -/// -/// # Phase 40削減計画 -/// -/// - **Phase 40-4**: JoinIrConservativeAnalyzerにインライン化 -/// - **削減効果**: 30行(構造体定義+実装) -/// - **保持**: Conservative ∘ Elimination理論コメント -pub struct ConservativeMerge { - // TODO(Phase 40-4): JoinIrConservativeAnalyzerに移行予定 - /// 全ブランチに存在する変数のユニオン(Conservative戦略) - pub all_vars: HashSet, - /// 実際に変更された変数のセット(デバッグ/ヒント用) - pub changed_vars: HashSet, -} - -impl ConservativeMerge { - /// 全変数のユニオンを計算(Conservative戦略) - /// - /// # Arguments - /// * `pre_if` - if文前のスナップショット - /// * `then_end` - then-branch終了時の変数マップ - /// * `else_end_opt` - else-branch終了時の変数マップ(Noneの場合はempty else) - /// - /// # Phase 40-2で使用される(compute_modified_names削除時) - pub fn analyze( - pre_if: &BTreeMap, // Phase 25.1: BTreeMap化 - then_end: &BTreeMap, // Phase 25.1: BTreeMap化 - else_end_opt: &Option>, // Phase 25.1: BTreeMap化 - ) -> Self { - // TODO(Phase 40-2/40-4): JoinIR Verifierに移行 - - let mut all_vars = HashSet::new(); - all_vars.extend(pre_if.keys().cloned()); - all_vars.extend(then_end.keys().cloned()); - if let Some(ref else_map) = else_end_opt { - all_vars.extend(else_map.keys().cloned()); - } - - // Phase 47: compute_modified_names インライン化(if_phi.rs から削除) - // 決定的順序のためBTreeSet使用 - let mut names: BTreeSet<&str> = BTreeSet::new(); - for k in then_end.keys() { - names.insert(k.as_str()); - } - if let Some(emap) = else_end_opt.as_ref() { - for k in emap.keys() { - names.insert(k.as_str()); - } - } - let mut changed_vars = HashSet::new(); - // アルファベット順で決定的にイテレート - for &name in &names { - let pre = pre_if.get(name); - let t = then_end.get(name); - let e = else_end_opt.as_ref().and_then(|m| m.get(name)); - if (t.is_some() && Some(*t.unwrap()) != pre.copied()) - || (e.is_some() && Some(*e.unwrap()) != pre.copied()) - { - changed_vars.insert(name.to_string()); - } - } - - Self { - all_vars, - changed_vars, - } - } - - // Phase 41-1削除済み(2025-11-29) - // - get_conservative_values (48行) - PhiBuilderBox::get_conservative_if_values()に置き換え済み - // Phase 42削除済み(2025-11-28) - // - trace_if_enabled (29行) - phi_merge.rs の既存 trace_conservative と重複していたため削除 -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_conservative_merge_both_defined() { - let mut pre_if = BTreeMap::new(); - pre_if.insert("x".to_string(), ValueId::new(1)); - - let mut then_end = BTreeMap::new(); - then_end.insert("x".to_string(), ValueId::new(2)); - - let mut else_end = BTreeMap::new(); - else_end.insert("x".to_string(), ValueId::new(3)); - - let merge = ConservativeMerge::analyze(&pre_if, &then_end, &Some(else_end)); - assert_eq!(merge.all_vars.len(), 1); - assert!(merge.all_vars.contains("x")); - } - - #[test] - fn test_conservative_merge_union() { - let pre_if = BTreeMap::new(); - - let mut then_end = BTreeMap::new(); - then_end.insert("x".to_string(), ValueId::new(1)); - - let mut else_end = BTreeMap::new(); - else_end.insert("y".to_string(), ValueId::new(2)); - - let merge = ConservativeMerge::analyze(&pre_if, &then_end, &Some(else_end)); - assert_eq!(merge.all_vars.len(), 2); - assert!(merge.all_vars.contains("x")); - assert!(merge.all_vars.contains("y")); - } -} +// ======================================== +// Phase 58削除済み(2025-11-29) +// ======================================== +// +// 以下のコードは phi_merge.rs にインライン化済み: +// +// pub struct ConservativeMerge { +// pub all_vars: HashSet, +// pub changed_vars: HashSet, +// } +// +// impl ConservativeMerge { +// pub fn analyze(...) -> Self { ... } +// } +// +// テストも削除: +// - test_conservative_merge_both_defined +// - test_conservative_merge_union