From 52b56efb47f5c84b22f1810bd58cc6f0319f2b5f Mon Sep 17 00:00:00 2001 From: nyash-codex Date: Sun, 23 Nov 2025 11:26:42 +0900 Subject: [PATCH] =?UTF-8?q?feat(phi):=20Phase=2027.6-2=20-=20ExitPhiBuilde?= =?UTF-8?q?r=20=E3=83=90=E3=82=A4=E3=83=91=E3=82=B9=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ExitPhiBuilder にトグル付きバイパスを追加: - ヘルパー関数追加 (exit_phi_builder.rs:397-419) - joinir_exit_bypass_enabled(): トグルチェック - is_joinir_exit_bypass_target(): 対象関数判定 - 環境変数: NYASH_JOINIR_EXPERIMENT=1 + NYASH_JOINIR_EXIT_EXP=1 - バイパス実装 (loop_builder.rs:657-692) - Exit φ 生成前にバイパス判定 - 対象関数: Main.skip/1, FuncScannerBox.trim/1 - ログ: [loopform/exit-bypass] func=... exit=... header=... - Header φ バイパス(27.4-C)と対称的な実装 - 両方のトグルで Header/Exit φ の完全スキップが可能 - JoinIR 実験経路専用(本線影響ゼロ) - 動作確認 - トグル OFF: 372 passed; 9 failed(既存と一致)✅ - コンパイル: エラーゼロ ✅ 本線影響ゼロ。次は Phase 27.6-3 で A/B テスト。 --- src/mir/loop_builder.rs | 47 +++++++++++++++++++++------- src/mir/phi_core/exit_phi_builder.rs | 24 ++++++++++++++ 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/mir/loop_builder.rs b/src/mir/loop_builder.rs index ab223291..bba016a1 100644 --- a/src/mir/loop_builder.rs +++ b/src/mir/loop_builder.rs @@ -654,17 +654,42 @@ impl<'a> LoopBuilder<'a> { // Region 情報(entry/exit/slots)をログに出すよ。 crate::mir::region::observer::observe_control_form(self.parent_builder, &form); - // [LoopForm] exit PHI for Case A/B (uses exit_snapshots + exit_preds) - // - Case A: header+break → exit PHI includes both paths - // - Case B: break-only → exit PHI excludes header (not a predecessor) - let exit_snaps = self.exit_snapshots.clone(); - crate::mir::phi_core::loopform_builder::build_exit_phis_for_control( - &loopform, - self, - &form, - &exit_snaps, - branch_source_block, - )?; + // Phase 27.6-2: JoinIR Exit φ バイパスチェック + let fn_name = self + .parent_builder + .current_function + .as_ref() + .map(|f| f.signature.name.as_str()) + .unwrap_or(""); + + let exit_bypass = crate::mir::phi_core::exit_phi_builder::joinir_exit_bypass_enabled() + && crate::mir::phi_core::exit_phi_builder::is_joinir_exit_bypass_target(fn_name); + + if exit_bypass { + // Phase 27.6-2: JoinIR 実験経路では Exit φ を生成しない。 + // ループ内で定義された値だけで exit 後を構成する(JoinIR の k_exit 引数として表現)。 + // + // ⚠️ 重要: このモードでは MIR は不完全(Exit φ 抜け)であり、VM で実行できない。 + // JoinIR runner 専用モードであることに注意。 + if std::env::var("NYASH_LOOPFORM_DEBUG").is_ok() { + eprintln!( + "[loopform/exit-bypass] func={} exit={:?} header={:?} (JoinIR experiment only)", + fn_name, exit_id, header_id + ); + } + } else { + // [LoopForm] exit PHI for Case A/B (uses exit_snapshots + exit_preds) + // - Case A: header+break → exit PHI includes both paths + // - Case B: break-only → exit PHI excludes header (not a predecessor) + let exit_snaps = self.exit_snapshots.clone(); + crate::mir::phi_core::loopform_builder::build_exit_phis_for_control( + &loopform, + self, + &form, + &exit_snaps, + branch_source_block, + )?; + } // Pop loop context crate::mir::builder::loops::pop_loop_context(self.parent_builder); diff --git a/src/mir/phi_core/exit_phi_builder.rs b/src/mir/phi_core/exit_phi_builder.rs index 35d1e6c5..c2116c71 100644 --- a/src/mir/phi_core/exit_phi_builder.rs +++ b/src/mir/phi_core/exit_phi_builder.rs @@ -394,6 +394,30 @@ impl LoopFormOps for T { } } +// ============================================================================ +// Phase 27.6-2: JoinIR Exit φ バイパス用ヘルパー関数 +// ============================================================================ + +/// JoinIR Exit φ 縮退実験トグル +/// +/// - NYASH_JOINIR_EXPERIMENT=1 +/// - NYASH_JOINIR_EXIT_EXP=1 +/// +/// の両方が立っているときだけ true。 +pub(crate) fn joinir_exit_bypass_enabled() -> bool { + crate::mir::join_ir::env_flag_is_1("NYASH_JOINIR_EXPERIMENT") + && crate::mir::join_ir::env_flag_is_1("NYASH_JOINIR_EXIT_EXP") +} + +/// Exit φ バイパス対象の関数かどうか +/// +/// 当面は minimal/trim の 2 本だけ: +/// - Main.skip/1 +/// - FuncScannerBox.trim/1 +pub(crate) fn is_joinir_exit_bypass_target(func_name: &str) -> bool { + matches!(func_name, "Main.skip/1" | "FuncScannerBox.trim/1") +} + // ============================================================================ // Unit Tests // ============================================================================