refactor(phi): Phase 59 PhiInputCollector inline in loopform_builder
Phase 59: PhiBuilderBox / PhiInputCollector JoinIR統合(部分完了) ## 変更内容 - loopform_builder.rs: PhiInputCollector使用を完全にインライン化 - seal_pinned_phis (L455): インライン化 - seal_carrier_phis (L528): インライン化 - build_exit_phis (L746): インライン化 - PhiInputCollector import を削除 ## インライン化されたロジック 1. 入力収集: Vec<(BasicBlockId, ValueId)> 2. sanitize: BTreeMapで重複削除&ソート 3. optimize_same_value: 全同値ならPHI不要 4. finalize: Vec返却 ## 残存callsite - loop_builder.rs:524 (continue merge) - JoinIRに概念なし、現状維持 ## テスト結果 - loopform: 14 passed / 0 failed - JoinIR: 56 passed / 0 failed 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -9,7 +9,8 @@
|
||||
*/
|
||||
|
||||
use crate::mir::phi_core::loop_snapshot_merge::LoopSnapshotMergeBox;
|
||||
use crate::mir::phi_core::phi_input_collector::PhiInputCollector;
|
||||
// Phase 59: PhiInputCollector使用廃止(インライン化完了)
|
||||
// use crate::mir::phi_core::phi_input_collector::PhiInputCollector;
|
||||
use crate::mir::{BasicBlockId, ValueId};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
@ -452,32 +453,56 @@ impl LoopFormBuilder {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut collector = PhiInputCollector::new();
|
||||
collector.add_preheader(self.preheader_id, pinned.preheader_copy);
|
||||
// ========================================
|
||||
// Phase 59: PhiInputCollector インライン化
|
||||
// ========================================
|
||||
// Step 1: 入力収集
|
||||
let mut raw_inputs: Vec<(BasicBlockId, ValueId)> = Vec::new();
|
||||
raw_inputs.push((self.preheader_id, pinned.preheader_copy));
|
||||
|
||||
for (cid, snapshot) in continue_snapshots {
|
||||
if let Some(&value) = snapshot.get(&pinned.name) {
|
||||
collector.add_snapshot(&[(*cid, value)]);
|
||||
raw_inputs.push((*cid, value));
|
||||
}
|
||||
}
|
||||
|
||||
let latch_value = ops
|
||||
.get_variable_at_block(&pinned.name, latch_id)
|
||||
.unwrap_or(pinned.header_phi);
|
||||
collector.add_latch(latch_id, latch_value);
|
||||
collector.sanitize();
|
||||
raw_inputs.push((latch_id, latch_value));
|
||||
|
||||
if let Some(same_value) = collector.optimize_same_value() {
|
||||
// Step 2: sanitize (BTreeMapで重複削除&ソート)
|
||||
let mut sanitized: std::collections::BTreeMap<BasicBlockId, ValueId> =
|
||||
std::collections::BTreeMap::new();
|
||||
for (bb, val) in &raw_inputs {
|
||||
sanitized.insert(*bb, *val);
|
||||
}
|
||||
let inputs: Vec<(BasicBlockId, ValueId)> = sanitized.into_iter().collect();
|
||||
|
||||
// Step 3: optimize_same_value
|
||||
let same_value = if inputs.is_empty() {
|
||||
None
|
||||
} else if inputs.len() == 1 {
|
||||
Some(inputs[0].1)
|
||||
} else {
|
||||
let first_val = inputs[0].1;
|
||||
if inputs.iter().all(|(_, val)| *val == first_val) {
|
||||
Some(first_val)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(same_val) = same_value {
|
||||
if debug {
|
||||
eprintln!(
|
||||
"[loopform/seal_phis] OPTIMIZED pinned '{}': phi={:?} → same_value={:?} (loop-invariant)",
|
||||
pinned.name, pinned.header_phi, same_value
|
||||
pinned.name, pinned.header_phi, same_val
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
let inputs = collector.finalize();
|
||||
if debug {
|
||||
eprintln!(
|
||||
"[loopform/seal_phis] pinned '{}' phi={:?} inputs={:?}",
|
||||
@ -525,29 +550,53 @@ impl LoopFormBuilder {
|
||||
)
|
||||
})?;
|
||||
|
||||
let mut collector = PhiInputCollector::new();
|
||||
collector.add_preheader(self.preheader_id, carrier.preheader_copy);
|
||||
// ========================================
|
||||
// Phase 59: PhiInputCollector インライン化
|
||||
// ========================================
|
||||
// Step 1: 入力収集
|
||||
let mut raw_inputs: Vec<(BasicBlockId, ValueId)> = Vec::new();
|
||||
raw_inputs.push((self.preheader_id, carrier.preheader_copy));
|
||||
|
||||
for (cid, snapshot) in continue_snapshots {
|
||||
if let Some(&value) = snapshot.get(&carrier.name) {
|
||||
collector.add_snapshot(&[(*cid, value)]);
|
||||
raw_inputs.push((*cid, value));
|
||||
}
|
||||
}
|
||||
|
||||
collector.add_latch(latch_id, carrier.latch_value);
|
||||
collector.sanitize();
|
||||
raw_inputs.push((latch_id, carrier.latch_value));
|
||||
|
||||
if let Some(same_value) = collector.optimize_same_value() {
|
||||
// Step 2: sanitize (BTreeMapで重複削除&ソート)
|
||||
let mut sanitized: std::collections::BTreeMap<BasicBlockId, ValueId> =
|
||||
std::collections::BTreeMap::new();
|
||||
for (bb, val) in &raw_inputs {
|
||||
sanitized.insert(*bb, *val);
|
||||
}
|
||||
let inputs: Vec<(BasicBlockId, ValueId)> = sanitized.into_iter().collect();
|
||||
|
||||
// Step 3: optimize_same_value
|
||||
let same_value = if inputs.is_empty() {
|
||||
None
|
||||
} else if inputs.len() == 1 {
|
||||
Some(inputs[0].1)
|
||||
} else {
|
||||
let first_val = inputs[0].1;
|
||||
if inputs.iter().all(|(_, val)| *val == first_val) {
|
||||
Some(first_val)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(same_val) = same_value {
|
||||
if debug {
|
||||
eprintln!(
|
||||
"[loopform/seal_phis] OPTIMIZED carrier '{}': phi={:?} → same_value={:?} (misclassified as carrier, actually loop-invariant)",
|
||||
carrier.name, carrier.header_phi, same_value
|
||||
carrier.name, carrier.header_phi, same_val
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
let inputs = collector.finalize();
|
||||
if debug {
|
||||
eprintln!(
|
||||
"[loopform/seal_phis] carrier '{}' phi={:?} inputs={:?}",
|
||||
@ -740,23 +789,44 @@ impl LoopFormBuilder {
|
||||
inspector,
|
||||
)?;
|
||||
|
||||
// 4. PHI 生成(Phase 26-B-3: PhiInputCollectorを使用)
|
||||
// ========================================
|
||||
// Phase 59: PHI生成(PhiInputCollectorインライン化)
|
||||
// ========================================
|
||||
// 旧: PhiInputCollector::new() + add_snapshot + sanitize + optimize_same_value
|
||||
// 新: BTreeMapで直接処理(同等のロジックをインライン展開)
|
||||
for (var_name, inputs) in all_vars {
|
||||
// Phase 26-B-3: Use PhiInputCollector for unified PHI input handling
|
||||
let mut collector = PhiInputCollector::new();
|
||||
collector.add_snapshot(&inputs);
|
||||
collector.sanitize();
|
||||
// Step 1: sanitize - BTreeMapで重複削除&ソート
|
||||
let mut sanitized: std::collections::BTreeMap<BasicBlockId, ValueId> =
|
||||
std::collections::BTreeMap::new();
|
||||
for (bb, val) in &inputs {
|
||||
sanitized.insert(*bb, *val);
|
||||
}
|
||||
let final_inputs: Vec<(BasicBlockId, ValueId)> = sanitized.into_iter().collect();
|
||||
|
||||
if debug {
|
||||
eprintln!(
|
||||
"[DEBUG/exit_phi] Variable '{}': {} inputs",
|
||||
var_name,
|
||||
collector.len()
|
||||
final_inputs.len()
|
||||
);
|
||||
}
|
||||
|
||||
// Phase 25.2: optimize_same_value() で最適化判定
|
||||
if let Some(same_val) = collector.optimize_same_value() {
|
||||
// Step 2: optimize_same_value - 全て同じ値ならPHI不要
|
||||
let same_value = if final_inputs.is_empty() {
|
||||
None
|
||||
} else if final_inputs.len() == 1 {
|
||||
Some(final_inputs[0].1)
|
||||
} else {
|
||||
let first_val = final_inputs[0].1;
|
||||
if final_inputs.iter().all(|(_, val)| *val == first_val) {
|
||||
Some(first_val)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
// Step 3: PHI生成 or 直接バインド
|
||||
if let Some(same_val) = same_value {
|
||||
// 全て同じ値 or 単一入力 → PHI 不要
|
||||
if debug {
|
||||
eprintln!(
|
||||
@ -767,8 +837,6 @@ impl LoopFormBuilder {
|
||||
ops.update_var(var_name, same_val);
|
||||
} else {
|
||||
// 異なる値を持つ場合は PHI ノードを生成
|
||||
let final_inputs = collector.finalize();
|
||||
|
||||
let phi_id = ops.new_value();
|
||||
if debug {
|
||||
eprintln!(
|
||||
|
||||
Reference in New Issue
Block a user