diff --git a/CURRENT_TASK.md b/CURRENT_TASK.md index 6c89f197..39ccaf22 100644 --- a/CURRENT_TASK.md +++ b/CURRENT_TASK.md @@ -7,6 +7,11 @@ ## 0. 現在地ざっくり +- **最終ゴール** + - 制御構造と PHI の意味論は **JoinIR(+LoopScopeShape/IfPhiContext 等の薄い箱)** に一本化する。 + - 実行の SSOT は VM / LLVM ラインとし、JoinIR→MIR→VM/LLVM は「構造 SSOT → 実行 SSOT」への変換として扱う。 + - 既存の PHI 箱(if_phi.rs / PhiBuilderBox / conservative.rs / Trio 等)は、JoinIR 側のカバレッジが十分になったところから順に削っていく。 + - **JoinIR ライン** - Phase 27–31: Loop→JoinIR lowering(skip_ws / trim / append_defs / Stage‑1 minimal)で、ループの制御構造を関数+継続だけで表現できることを実証済み。 - Phase 33–34: IfSelect / IfMerge / JoinIR Frontend(If/Loop/Break/Continue)実装。AST→JoinIR→MIR→VM まで tiny ケースが通る。 diff --git a/src/mir/loop_builder/if_lowering.rs b/src/mir/loop_builder/if_lowering.rs index 8e67422b..dba0179e 100644 --- a/src/mir/loop_builder/if_lowering.rs +++ b/src/mir/loop_builder/if_lowering.rs @@ -200,77 +200,29 @@ impl<'a> LoopBuilder<'a> { .cloned() .collect(); - // Phase 61-2: JoinIR dry-run検証モード - // dry-run用: JoinInstとPhiSpecを保存(A/B比較用) - let mut joinir_phi_spec_opt: Option = - None; - - let joinir_success = if crate::config::env::joinir_if_select_enabled() { - // IfPhiContext作成 - let if_phi_context = - crate::mir::join_ir::lowering::if_phi_context::IfPhiContext::for_loop_body( - carrier_names.clone(), - ); - - // JoinIR経路を試行 + // Phase 62-B: JoinIRIfPhiSelector箱化(-60行の簡潔化) + let joinir_result = if crate::config::env::joinir_if_select_enabled() { if let Some(ref func) = self.parent_builder.current_function { - match crate::mir::join_ir::lowering::try_lower_if_to_joinir( - func, - pre_branch_bb, - false, // debug - Some(&if_phi_context), - ) { - Some(join_inst) => { - eprintln!( - "[Phase 61-2] ✅ If-in-loop lowered via JoinIR: {:?}", - 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"); - eprintln!("[Phase 61-2] Carrier variables: {:?}", carrier_names); - eprintln!( - "[Phase 61-2] JoinInst type: {}", - match &join_inst { - crate::mir::join_ir::JoinInst::Select { .. } => "Select", - crate::mir::join_ir::JoinInst::IfMerge { .. } => "IfMerge", - _ => "Other", - } - ); - 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); - - // Phase 61-3: 本番経路有効かどうかを返す - crate::config::env::joinir_if_in_loop_enable() - } - None => { - if crate::config::env::joinir_if_in_loop_dryrun_enabled() { - eprintln!("[Phase 61-2] ⏭️ JoinIR pattern not matched, using fallback"); - } - false - } - } + let selector = super::JoinIRIfPhiSelector::new(func, pre_branch_bb, carrier_names.clone()); + selector.try_lower() } else { - false + super::JoinIRResult { + success: false, + phi_spec: None, + join_inst: None, + } } } else { - false + super::JoinIRResult { + success: false, + phi_spec: None, + join_inst: None, + } }; + let joinir_success = joinir_result.success; + let joinir_phi_spec_opt = joinir_result.phi_spec; + let mut ops = Ops(self); // Phase 61-3: JoinIR本番経路(IfInLoopPhiEmitter) diff --git a/src/mir/loop_builder/joinir_if_phi_selector.rs b/src/mir/loop_builder/joinir_if_phi_selector.rs new file mode 100644 index 00000000..529451b3 --- /dev/null +++ b/src/mir/loop_builder/joinir_if_phi_selector.rs @@ -0,0 +1,162 @@ +//! Phase 62-B: JoinIR If-PHI Selector +//! +//! If-in-loop の JoinIR lowering 試行と PhiSpec 生成を担当する箱。 +//! +//! ## 箱理論における位置づけ +//! +//! ```text +//! ┌─────────────────────────────────────────────────────────────┐ +//! │ if_lowering.rs(オーケストレーター) │ +//! │ ↓ │ +//! │ ┌─────────────────────┐ ┌─────────────────────────────┐ │ +//! │ │ JoinIRIfPhiSelector │→ │ IfInLoopPhiEmitter │ │ +//! │ │ (試行・PhiSpec生成) │ │ (PHI命令発行) │ │ +//! │ └─────────────────────┘ └─────────────────────────────┘ │ +//! └─────────────────────────────────────────────────────────────┘ +//! ``` +//! +//! ## 責務 +//! +//! - JoinIR lowering の試行(try_lower_if_to_joinir 呼び出し) +//! - PhiSpec の計算(compute_phi_spec_from_joinir 呼び出し) +//! - dry-run モード時のログ出力 +//! - 本番/dry-run 切り替え判定 +//! +//! ## 設計原則 +//! +//! - **Thin Box**: JoinIR/PhiSpec計算は既存関数に委譲 +//! - **状態保持**: 試行結果とPhiSpecを返却 +//! - **ログ制御**: dry-runフラグに応じた詳細ログ + +use crate::mir::join_ir::lowering::if_phi_context::IfPhiContext; +use crate::mir::join_ir::lowering::if_phi_spec::{compute_phi_spec_from_joinir, PhiSpec}; +use crate::mir::join_ir::lowering::try_lower_if_to_joinir; +use crate::mir::join_ir::JoinInst; +use crate::mir::{BasicBlockId, MirFunction}; +use std::collections::BTreeSet; + +/// JoinIR If-PHI Selector の試行結果 +#[derive(Debug)] +pub struct JoinIRResult { + /// JoinIR lowering 成功フラグ + pub success: bool, + + /// 計算された PhiSpec(成功時のみ) + pub phi_spec: Option, + + /// lowering された JoinInst(デバッグ用) + pub join_inst: Option, +} + +/// JoinIR If-PHI Selector +/// +/// If-in-loop の JoinIR 経路を試行し、PhiSpec を生成する。 +pub struct JoinIRIfPhiSelector<'a> { + /// If-PHI コンテキスト + context: IfPhiContext, + + /// 現在の MIR 関数 + func: &'a MirFunction, + + /// 分岐前ブロック + pre_branch_bb: BasicBlockId, + + /// dry-run モード + dryrun: bool, +} + +impl<'a> JoinIRIfPhiSelector<'a> { + /// JoinIR If-PHI Selector を作成 + /// + /// # Arguments + /// + /// * `func` - 現在の MIR 関数 + /// * `pre_branch_bb` - 分岐前ブロック + /// * `carrier_names` - ループキャリア変数名 + pub fn new( + func: &'a MirFunction, + pre_branch_bb: BasicBlockId, + carrier_names: BTreeSet, + ) -> Self { + let context = IfPhiContext::for_loop_body(carrier_names); + let dryrun = crate::config::env::joinir_if_in_loop_dryrun_enabled(); + + Self { + context, + func, + pre_branch_bb, + dryrun, + } + } + + /// JoinIR lowering を試行 + /// + /// # Returns + /// + /// JoinIR 試行結果(success, phi_spec, join_inst) + pub fn try_lower(&self) -> JoinIRResult { + // JoinIR lowering 試行 + match try_lower_if_to_joinir(self.func, self.pre_branch_bb, false, Some(&self.context)) { + Some(join_inst) => { + if self.dryrun { + eprintln!( + "[Phase 61-2] ✅ If-in-loop lowered via JoinIR: {:?}", + join_inst + ); + } + + // PhiSpec 計算 + let phi_spec = compute_phi_spec_from_joinir(&self.context, &join_inst); + + // dry-run ログ + if self.dryrun { + self.log_dryrun(&join_inst, &phi_spec); + } + + // 本番経路有効判定 + let success = crate::config::env::joinir_if_in_loop_enable(); + + JoinIRResult { + success, + phi_spec: Some(phi_spec), + join_inst: Some(join_inst), + } + } + None => { + if self.dryrun { + eprintln!("[Phase 61-2] ⏭️ JoinIR pattern not matched, using fallback"); + } + + JoinIRResult { + success: false, + phi_spec: None, + join_inst: None, + } + } + } + } + + /// dry-run モード時の詳細ログ出力 + fn log_dryrun(&self, join_inst: &JoinInst, phi_spec: &PhiSpec) { + eprintln!("[Phase 61-2] 🔍 dry-run mode enabled"); + eprintln!( + "[Phase 61-2] Carrier variables: {:?}", + self.context.carrier_names + ); + eprintln!( + "[Phase 61-2] JoinInst type: {}", + match join_inst { + JoinInst::Select { .. } => "Select", + JoinInst::IfMerge { .. } => "IfMerge", + _ => "Other", + } + ); + eprintln!( + "[Phase 61-2] JoinIR PhiSpec: header={}, exit={}", + phi_spec.header_count(), + phi_spec.exit_count() + ); + } +} + +// テストは if_lowering.rs の統合テストで検証 diff --git a/src/mir/loop_builder/mod.rs b/src/mir/loop_builder/mod.rs index d97f7119..b313add5 100644 --- a/src/mir/loop_builder/mod.rs +++ b/src/mir/loop_builder/mod.rs @@ -30,11 +30,13 @@ mod control; mod if_in_loop_phi_emitter; mod if_lowering; +mod joinir_if_phi_selector; mod loop_form; mod phi_ops; mod statements; pub use if_in_loop_phi_emitter::IfInLoopPhiEmitter; +pub use joinir_if_phi_selector::{JoinIRIfPhiSelector, JoinIRResult}; use super::{BasicBlockId, ConstValue, MirInstruction, ValueId}; use std::collections::BTreeMap; // Phase 25.1: 決定性確保