feat(joinir): Phase 61-3 IfInLoopPhiEmitter箱実装

If-in-loop PHI生成を箱化モジュール化:

## 新規ファイル
- if_in_loop_phi_emitter.rs: IfInLoopPhiEmitter 箱(~250行)
  - emit_header_phis(): VarLookup方式でPHI生成
  - ユニットテスト2件: basic / same_value

## 変更ファイル
- mod.rs: IfInLoopPhiEmitter モジュール追加・pub use
- if_lowering.rs: Phase 61-3本番経路統合
  - HAKO_JOINIR_IF_IN_LOOP_ENABLE=1 で IfInLoopPhiEmitter 使用
  - JoinIRパターンマッチ成功時のみ動作
- if_phi_context.rs: unused imports削除

## 箱理論
- IfInLoopPhiEmitter: PHI命令発行に専念(Thin Box)
- VarLookup方式: snapshot lookup + pre_val fallback
- CFG非依存: incoming値はsnapshotから直接取得

🤖 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 14:39:51 +09:00
parent f4fb798ec8
commit 9037467ac7
4 changed files with 349 additions and 12 deletions

View File

@ -228,6 +228,12 @@ impl<'a> LoopBuilder<'a> {
join_inst
);
// Phase 61-2.3: JoinInstからPhiSpecを計算
let joinir_spec = crate::mir::join_ir::lowering::if_phi_spec::compute_phi_spec_from_joinir(
&if_phi_context,
&join_inst,
);
// Phase 61-2: dry-runモードでPHI仕様を検証
if crate::config::env::joinir_if_in_loop_dryrun_enabled() {
eprintln!("[Phase 61-2] 🔍 dry-run mode enabled");
@ -240,23 +246,18 @@ impl<'a> LoopBuilder<'a> {
_ => "Other",
}
);
// Phase 61-2.3: JoinInstからPhiSpecを計算
let joinir_spec = crate::mir::join_ir::lowering::if_phi_spec::compute_phi_spec_from_joinir(
&if_phi_context,
&join_inst,
);
eprintln!(
"[Phase 61-2] JoinIR PhiSpec: header={}, exit={}",
joinir_spec.header_count(),
joinir_spec.exit_count()
);
// A/B比較用に保存
joinir_phi_spec_opt = Some(joinir_spec);
}
false // Phase 61-2では検証のみ、本番切り替えはPhase 61-3
// A/B比較用に保存
joinir_phi_spec_opt = Some(joinir_spec);
// Phase 61-3: 本番経路有効かどうかを返す
crate::config::env::joinir_if_in_loop_enable()
}
None => {
if crate::config::env::joinir_if_in_loop_dryrun_enabled() {
@ -278,6 +279,30 @@ impl<'a> LoopBuilder<'a> {
// Phase 35-5: if_body_local_merge.rs削除、PhiBuilderBoxに吸収
// 理由: 箱理論による責務分離(ループスコープ分析 vs if-merge専用処理
// Phase 61-3: JoinIR本番経路IfInLoopPhiEmitter
if joinir_success {
if let Some(ref joinir_spec) = joinir_phi_spec_opt {
// IfInLoopPhiEmitter を使用してPHI生成
let else_snap_opt = else_var_map_end_opt.as_ref();
let phi_count = super::IfInLoopPhiEmitter::emit_header_phis(
joinir_spec,
&pre_if_var_map,
&then_var_map_end,
else_snap_opt,
&carrier_names,
&mut ops,
&if_shape,
)?;
if crate::config::env::joinir_if_in_loop_dryrun_enabled() {
eprintln!(
"[Phase 61-3] ✅ IfInLoopPhiEmitter generated {} PHIs",
phi_count
);
}
}
}
// フォールバック: PhiBuilderBox経路既存
if !joinir_success {
// Phase 26-E: PhiBuilderBox SSOT統合If PHI生成