refactor(phi): Phase 58 ConservativeMerge inline into merge_all_vars
Phase 58: ConservativeMerge 本体削除 ## 変更内容 - ConservativeMerge::analyze を phi_merge.rs の merge_all_vars 内にインライン化 - conservative.rs から struct と impl を削除(約95行削減) - conservative.rs はドキュメントコメントのみ残す ## 技術的詳細 - all_vars: 全ブランチの変数ユニオン(Conservative戦略) - changed_vars: 実際に変更された変数(決定的順序のためBTreeSet使用) - Conservative ∘ Elimination = Minimal SSA 理論コメント保持 ## 削減効果 - conservative.rs: 149行 → 57行(92行削減、62%削減) - ConservativeMerge struct 完全削除 - テストコード 35行削除 ## テスト結果 - JoinIR: 56 passed / 0 failed - PHI関連テスト: 全PASS 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -7,7 +7,7 @@
|
|||||||
//! Box-First理論: PHI insertion の境界を明確にし、差し替え可能な箱として提供
|
//! Box-First理論: PHI insertion の境界を明確にし、差し替え可能な箱として提供
|
||||||
|
|
||||||
use super::{BasicBlockId, MirBuilder, ValueId};
|
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戦略)
|
/// PHI Merge Helper - 統一PHI挿入ロジック(Conservative戦略)
|
||||||
///
|
///
|
||||||
@ -157,31 +157,72 @@ impl<'a> PhiMergeHelper<'a> {
|
|||||||
/// # Returns
|
/// # Returns
|
||||||
/// Ok(changed_vars) - Set of variables that were changed, for pin handling
|
/// Ok(changed_vars) - Set of variables that were changed, for pin handling
|
||||||
///
|
///
|
||||||
/// # Phase 57 改善
|
/// # Phase 57-58 改善
|
||||||
///
|
///
|
||||||
/// 戻り値を `()` から `HashSet<String>` に変更。
|
/// - Phase 57: 戻り値を `()` から `HashSet<String>` に変更
|
||||||
/// これにより `phi.rs` での冗長な `ConservativeMerge::analyze` 呼び出しを削除可能に。
|
/// - 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(
|
pub fn merge_all_vars(
|
||||||
&mut self,
|
&mut self,
|
||||||
pre_if_snapshot: &BTreeMap<String, ValueId>, // Phase 25.1: BTreeMap化
|
pre_if_snapshot: &BTreeMap<String, ValueId>, // Phase 25.1: BTreeMap化
|
||||||
then_map_end: &BTreeMap<String, ValueId>, // Phase 25.1: BTreeMap化
|
then_map_end: &BTreeMap<String, ValueId>, // Phase 25.1: BTreeMap化
|
||||||
else_map_end_opt: &Option<BTreeMap<String, ValueId>>, // Phase 25.1: BTreeMap化
|
else_map_end_opt: &Option<BTreeMap<String, ValueId>>, // Phase 25.1: BTreeMap化
|
||||||
skip_var: Option<&str>,
|
skip_var: Option<&str>,
|
||||||
) -> Result<std::collections::HashSet<String>, String> {
|
) -> Result<HashSet<String>, String> {
|
||||||
// Use Conservative strategy from conservative module
|
// ========================================
|
||||||
let conservative = crate::mir::phi_core::conservative::ConservativeMerge::analyze(
|
// Phase 58: ConservativeMerge::analyze インライン化
|
||||||
pre_if_snapshot,
|
// ========================================
|
||||||
then_map_end,
|
// 旧: crate::mir::phi_core::conservative::ConservativeMerge::analyze(...)
|
||||||
else_map_end_opt,
|
// 新: 以下のロジックを直接ここに記述
|
||||||
);
|
|
||||||
|
// 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")
|
let trace_conservative = std::env::var("NYASH_CONSERVATIVE_PHI_TRACE")
|
||||||
.ok()
|
.ok()
|
||||||
.as_deref()
|
.as_deref()
|
||||||
== Some("1");
|
== 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 skip_var.map(|s| s == name.as_str()).unwrap_or(false) {
|
||||||
if trace_conservative {
|
if trace_conservative {
|
||||||
eprintln!("[Conservative PHI] Skipping {}: matches skip_var", name);
|
eprintln!("[Conservative PHI] Skipping {}: matches skip_var", name);
|
||||||
@ -238,6 +279,6 @@ impl<'a> PhiMergeHelper<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Phase 57: 変更された変数セットを返す(phi.rsでの冗長呼び出し削除用)
|
// Phase 57: 変更された変数セットを返す(phi.rsでの冗長呼び出し削除用)
|
||||||
Ok(conservative.changed_vars)
|
Ok(changed_vars)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,148 +1,56 @@
|
|||||||
//! Conservative PHI Generation - Box Theory Application
|
//! Conservative PHI Generation - Box Theory Application
|
||||||
//!
|
//!
|
||||||
//! Theory: Conservative ∘ Elimination = Minimal SSA
|
//! # Theory: Conservative ∘ Elimination = Minimal SSA
|
||||||
//! - Conservative (this): correctness-first, generate all PHIs
|
//!
|
||||||
|
//! - Conservative: correctness-first, generate all PHIs
|
||||||
//! - Elimination (future): efficiency optimization, remove unused PHIs
|
//! - Elimination (future): efficiency optimization, remove unused PHIs
|
||||||
//!
|
//!
|
||||||
//! Phase 25.1q: Conservative PHI戦略の一元化
|
//! # Phase 58 削除完了(2025-11-29)
|
||||||
//! - phi.rs の Conservative PHI ロジック(L23-117)を統一
|
|
||||||
//! - void emission、predecessor fallback の一貫性保証
|
|
||||||
//!
|
//!
|
||||||
//! # 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 37分析: `docs/.../phase-37-if-phi-reduction/conservative_responsibility_table.md`
|
||||||
//! - Phase 39設計: `docs/.../phase-39-if-phi-level2/joinir_extension_design.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追加
|
// Phase 58削除済み(2025-11-29)
|
||||||
|
// ========================================
|
||||||
/// Conservative PHI 戦略による変数マージ分析
|
//
|
||||||
///
|
// 以下のコードは phi_merge.rs にインライン化済み:
|
||||||
/// # Phase 40削減計画
|
//
|
||||||
///
|
// pub struct ConservativeMerge {
|
||||||
/// - **Phase 40-4**: JoinIrConservativeAnalyzerにインライン化
|
// pub all_vars: HashSet<String>,
|
||||||
/// - **削減効果**: 30行(構造体定義+実装)
|
// pub changed_vars: HashSet<String>,
|
||||||
/// - **保持**: Conservative ∘ Elimination理論コメント
|
// }
|
||||||
pub struct ConservativeMerge {
|
//
|
||||||
// TODO(Phase 40-4): JoinIrConservativeAnalyzerに移行予定
|
// impl ConservativeMerge {
|
||||||
/// 全ブランチに存在する変数のユニオン(Conservative戦略)
|
// pub fn analyze(...) -> Self { ... }
|
||||||
pub all_vars: HashSet<String>,
|
// }
|
||||||
/// 実際に変更された変数のセット(デバッグ/ヒント用)
|
//
|
||||||
pub changed_vars: HashSet<String>,
|
// テストも削除:
|
||||||
}
|
// - test_conservative_merge_both_defined
|
||||||
|
// - test_conservative_merge_union
|
||||||
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<String, ValueId>, // Phase 25.1: BTreeMap化
|
|
||||||
then_end: &BTreeMap<String, ValueId>, // Phase 25.1: BTreeMap化
|
|
||||||
else_end_opt: &Option<BTreeMap<String, ValueId>>, // 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"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user