Phase 33-3: If/PHI MIR pattern matching + Select lowering (minimal patterns)
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>
This commit is contained in:
@ -41,3 +41,61 @@ 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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user