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::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 crate::mir::{BasicBlockId, ValueId};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
@ -452,32 +453,56 @@ impl LoopFormBuilder {
|
|||||||
continue;
|
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 {
|
for (cid, snapshot) in continue_snapshots {
|
||||||
if let Some(&value) = snapshot.get(&pinned.name) {
|
if let Some(&value) = snapshot.get(&pinned.name) {
|
||||||
collector.add_snapshot(&[(*cid, value)]);
|
raw_inputs.push((*cid, value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let latch_value = ops
|
let latch_value = ops
|
||||||
.get_variable_at_block(&pinned.name, latch_id)
|
.get_variable_at_block(&pinned.name, latch_id)
|
||||||
.unwrap_or(pinned.header_phi);
|
.unwrap_or(pinned.header_phi);
|
||||||
collector.add_latch(latch_id, latch_value);
|
raw_inputs.push((latch_id, latch_value));
|
||||||
collector.sanitize();
|
|
||||||
|
|
||||||
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 {
|
if debug {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"[loopform/seal_phis] OPTIMIZED pinned '{}': phi={:?} → same_value={:?} (loop-invariant)",
|
"[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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let inputs = collector.finalize();
|
|
||||||
if debug {
|
if debug {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"[loopform/seal_phis] pinned '{}' phi={:?} inputs={:?}",
|
"[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 {
|
for (cid, snapshot) in continue_snapshots {
|
||||||
if let Some(&value) = snapshot.get(&carrier.name) {
|
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);
|
raw_inputs.push((latch_id, carrier.latch_value));
|
||||||
collector.sanitize();
|
|
||||||
|
|
||||||
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 {
|
if debug {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"[loopform/seal_phis] OPTIMIZED carrier '{}': phi={:?} → same_value={:?} (misclassified as carrier, actually loop-invariant)",
|
"[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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let inputs = collector.finalize();
|
|
||||||
if debug {
|
if debug {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"[loopform/seal_phis] carrier '{}' phi={:?} inputs={:?}",
|
"[loopform/seal_phis] carrier '{}' phi={:?} inputs={:?}",
|
||||||
@ -740,23 +789,44 @@ impl LoopFormBuilder {
|
|||||||
inspector,
|
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 {
|
for (var_name, inputs) in all_vars {
|
||||||
// Phase 26-B-3: Use PhiInputCollector for unified PHI input handling
|
// Step 1: sanitize - BTreeMapで重複削除&ソート
|
||||||
let mut collector = PhiInputCollector::new();
|
let mut sanitized: std::collections::BTreeMap<BasicBlockId, ValueId> =
|
||||||
collector.add_snapshot(&inputs);
|
std::collections::BTreeMap::new();
|
||||||
collector.sanitize();
|
for (bb, val) in &inputs {
|
||||||
|
sanitized.insert(*bb, *val);
|
||||||
|
}
|
||||||
|
let final_inputs: Vec<(BasicBlockId, ValueId)> = sanitized.into_iter().collect();
|
||||||
|
|
||||||
if debug {
|
if debug {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"[DEBUG/exit_phi] Variable '{}': {} inputs",
|
"[DEBUG/exit_phi] Variable '{}': {} inputs",
|
||||||
var_name,
|
var_name,
|
||||||
collector.len()
|
final_inputs.len()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Phase 25.2: optimize_same_value() で最適化判定
|
// Step 2: optimize_same_value - 全て同じ値ならPHI不要
|
||||||
if let Some(same_val) = collector.optimize_same_value() {
|
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 不要
|
// 全て同じ値 or 単一入力 → PHI 不要
|
||||||
if debug {
|
if debug {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
@ -767,8 +837,6 @@ impl LoopFormBuilder {
|
|||||||
ops.update_var(var_name, same_val);
|
ops.update_var(var_name, same_val);
|
||||||
} else {
|
} else {
|
||||||
// 異なる値を持つ場合は PHI ノードを生成
|
// 異なる値を持つ場合は PHI ノードを生成
|
||||||
let final_inputs = collector.finalize();
|
|
||||||
|
|
||||||
let phi_id = ops.new_value();
|
let phi_id = ops.new_value();
|
||||||
if debug {
|
if debug {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
|
|||||||
Reference in New Issue
Block a user