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:
nyash-codex
2025-11-29 09:14:24 +09:00
parent 50bb58f2a1
commit c10ffa4c2b
2 changed files with 94 additions and 145 deletions

View File

@ -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<String>` に変更
/// これにより `phi.rs` での冗長な `ConservativeMerge::analyze` 呼び出しを削除可能に。
/// - Phase 57: 戻り値を `()` から `HashSet<String>` に変更
/// - 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<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化
skip_var: Option<&str>,
) -> Result<std::collections::HashSet<String>, 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<HashSet<String>, 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)
}
}