Implementation:
- Implement MIR pattern matching in if_select.rs (simple/local patterns)
- Add try_lower_if_to_joinir() entry point in lowering/mod.rs
- Create comprehensive integration tests (4/4 passing)
Pattern Support:
- Simple pattern: if cond { return 1 } else { return 2 }
- Both blocks must have Return only (no instructions)
- Local pattern: if cond { x = a } else { x = b }; return x
- Each branch has exactly 1 Copy instruction
- Both branches jump to same merge block
- Merge block Returns the assigned variable
Safety Mechanisms:
- Dev toggle: NYASH_JOINIR_IF_SELECT=1 required
- Function name filter: Only IfSelectTest.* functions
- Fallback: Returns None on pattern mismatch
- Zero breaking changes: Existing if_phi path untouched
Tests (4/4 PASS):
- test_if_select_simple_pattern
- test_if_select_local_pattern
- test_if_select_disabled_by_default
- test_if_select_wrong_function_name
Files:
- Modified: src/mir/join_ir/lowering/if_select.rs (pattern matching)
- Modified: src/mir/join_ir/lowering/mod.rs (entry point)
- New: src/tests/mir_joinir_if_select.rs (integration tests)
- Modified: src/tests/mod.rs (module registration)
Phase 33-3.2/3.3 (legacy removal) pending
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
102 lines
3.5 KiB
Rust
102 lines
3.5 KiB
Rust
//! JoinIR Lowering Functions
|
||
//!
|
||
//! Phase 27.9: Modular separation of MIR → JoinIR lowering implementations.
|
||
//!
|
||
//! このモジュールは各種 MIR 関数を JoinIR に変換する lowering 関数を提供します。
|
||
//!
|
||
//! ## 構成:
|
||
//! - `common.rs`: CFG sanity checks と lowering 共通ユーティリティ(Phase 27.10)
|
||
//! - `value_id_ranges.rs`: ValueId 範囲管理(Phase 27.13+)
|
||
//! - `min_loop.rs`: JoinIrMin.main/0 専用の最小ループ lowering
|
||
//! - `skip_ws.rs`: Main.skip/1 の空白スキップ lowering(手書き版+MIR自動解析版)
|
||
//! - `funcscanner_trim.rs`: FuncScannerBox.trim/1 の trim lowering
|
||
//! - `stage1_using_resolver.rs`: Stage1UsingResolverBox.resolve_for_source entries loop lowering(Phase 27.12)
|
||
//! - `funcscanner_append_defs.rs`: FuncScannerBox._append_defs/2 の配列結合 lowering(Phase 27.14)
|
||
//! - `if_select.rs`: Phase 33 If/Else → Select lowering
|
||
|
||
pub mod common;
|
||
pub mod exit_args_resolver;
|
||
pub mod funcscanner_append_defs;
|
||
pub mod funcscanner_trim;
|
||
pub mod generic_case_a;
|
||
pub mod if_select; // Phase 33
|
||
pub mod loop_form_intake;
|
||
pub mod loop_scope_shape;
|
||
pub mod loop_to_join;
|
||
pub mod min_loop;
|
||
pub mod skip_ws;
|
||
pub mod stage1_using_resolver;
|
||
pub mod stageb_body;
|
||
pub mod stageb_funcscanner;
|
||
pub mod value_id_ranges;
|
||
|
||
// Re-export public lowering functions
|
||
pub use funcscanner_append_defs::lower_funcscanner_append_defs_to_joinir;
|
||
pub use funcscanner_trim::lower_funcscanner_trim_to_joinir;
|
||
// Phase 31: LoopToJoinLowerer 統一箱
|
||
pub use loop_to_join::LoopToJoinLowerer;
|
||
// Phase 30 F-3: 旧 lower_case_a_loop_to_joinir_for_minimal_skip_ws は _with_scope に置き換え済みのため削除
|
||
pub use min_loop::lower_min_loop_to_joinir;
|
||
pub use skip_ws::lower_skip_ws_to_joinir;
|
||
pub use stage1_using_resolver::lower_stage1_usingresolver_to_joinir;
|
||
pub use stageb_body::lower_stageb_body_to_joinir;
|
||
pub use stageb_funcscanner::lower_stageb_funcscanner_to_joinir;
|
||
|
||
// Phase 33: If/Else → Select lowering entry point
|
||
use crate::mir::join_ir::JoinInst;
|
||
use crate::mir::{BasicBlockId, MirFunction};
|
||
|
||
/// Phase 33-3: Try to lower if/else to JoinIR Select instruction
|
||
///
|
||
/// Scope:
|
||
/// - Only applies to functions matching "IfSelectTest.*"
|
||
/// - Requires NYASH_JOINIR_IF_SELECT=1 environment variable
|
||
/// - Falls back to traditional if_phi on pattern mismatch
|
||
///
|
||
/// Returns Some(JoinInst::Select) if pattern matched, None otherwise.
|
||
pub fn try_lower_if_to_joinir(
|
||
func: &MirFunction,
|
||
block_id: BasicBlockId,
|
||
debug: bool,
|
||
) -> Option<JoinInst> {
|
||
// dev トグルチェック
|
||
if !crate::config::env::joinir_if_select_enabled() {
|
||
return None;
|
||
}
|
||
|
||
// 関数名で制限(IfSelectTest.* のみ)
|
||
if !func.signature.name.starts_with("IfSelectTest.") {
|
||
if debug {
|
||
eprintln!(
|
||
"[try_lower_if_to_joinir] skipping non-test function: {}",
|
||
func.signature.name
|
||
);
|
||
}
|
||
return None;
|
||
}
|
||
|
||
// if_select lowering を試行
|
||
let lowerer = if_select::IfSelectLowerer::new(debug);
|
||
|
||
if !lowerer.can_lower_to_select(func, block_id) {
|
||
if debug {
|
||
eprintln!(
|
||
"[try_lower_if_to_joinir] pattern not matched for {}",
|
||
func.signature.name
|
||
);
|
||
}
|
||
return None;
|
||
}
|
||
|
||
let result = lowerer.lower_if_to_select(func, block_id);
|
||
|
||
if result.is_some() && debug {
|
||
eprintln!(
|
||
"[try_lower_if_to_joinir] if_select lowering used for {}",
|
||
func.signature.name
|
||
);
|
||
}
|
||
|
||
result
|
||
}
|