feat(joinir): Phase 80 JoinIR Mainline Unification

Phase 80: JoinIR 本線化(Core ON 対応)

## 変更内容

### Phase 80-1: SSOT 関数群の追加 (mod.rs)
- `is_loop_mainline_target()`: Loop本線化対象判定
- `is_if_mainline_target()`: If本線化対象判定
- `should_try_joinir_mainline()`: Core ON時の本線試行判定
- `should_panic_on_joinir_failure()`: Strict時のパニック判定

### Phase 80-2: If本線化 (if_form.rs)
- Core ON (`joinir_core_enabled()`) 時に代表関数でJoinIRを本線として試行
- Strict mode (`joinir_strict_enabled()`) でパターン不一致時にパニック

### Phase 80-3: Loop本線化 (vm_bridge_dispatch/mod.rs)
- Core ON 時に本線対象関数でJoinIR VMブリッジを優先試行
- Strict mode で失敗時にパニック

## 対象関数
- Loop: Main.skip/1, FuncScannerBox.trim/1, etc. (6本)
- If: IfSelectTest.*, IfMergeTest.*, JsonShapeToMap.* etc.

## 環境変数
- NYASH_JOINIR_CORE=1: Core ON(本線化有効)
- NYASH_JOINIR_STRICT=1: Strict ON(フォールバック禁止)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-02 13:45:47 +09:00
parent 804ccff23f
commit c61f4bc742
3 changed files with 71 additions and 3 deletions

View File

@ -228,7 +228,16 @@ impl MirBuilder {
.unwrap_or("");
let is_target = crate::mir::join_ir::lowering::is_joinir_if_toplevel_target(func_name);
if joinir_enabled && is_target && (joinir_toplevel || joinir_dryrun) {
// Phase 80: Core ON 時は代表関数で JoinIR を本線として試行
let core_mainline =
crate::mir::join_ir::lowering::should_try_joinir_mainline(func_name, false);
let strict_mode =
crate::mir::join_ir::lowering::should_panic_on_joinir_failure(func_name, false);
// Core ON + 本線対象の場合は環境変数に関わらず試行
let should_try_joinir = core_mainline || (joinir_enabled && is_target && (joinir_toplevel || joinir_dryrun));
if should_try_joinir {
if let Some(ref func) = self.current_function {
let context =
crate::mir::join_ir::lowering::if_phi_context::IfPhiContext::pure_if();
@ -298,6 +307,13 @@ impl MirBuilder {
func_name
);
}
// Phase 80/81: Strict mode では本線対象関数の失敗でパニック
if strict_mode {
panic!(
"[joinir/if] strict mode: pattern not matched for {} (if_form.rs)",
func_name
);
}
}
}
}

View File

@ -82,6 +82,50 @@ pub(crate) fn is_loop_lowered_function(name: &str) -> bool {
LOOP_LOWERED_FUNCTIONS.contains(&name)
}
// ============================================================================
// Phase 80: JoinIR Mainline Unification - Core ON 時の本線化判定
// ============================================================================
/// Phase 80: JoinIR 本線化対象Loopの判定
///
/// `joinir_core_enabled()=true` の時、これらの関数のループは
/// 必ず JoinIR → MIR 経路を本線として試行します。
pub fn is_loop_mainline_target(name: &str) -> bool {
is_loop_lowered_function(name)
}
/// Phase 80: JoinIR 本線化対象Ifの判定
///
/// `joinir_core_enabled()=true` の時、これらの関数の if/else は
/// 必ず JoinIR → MIR 経路を本線として試行します。
pub fn is_if_mainline_target(name: &str) -> bool {
is_joinir_if_toplevel_target(name)
}
/// Phase 80: Core ON 時に JoinIR を本線として試行すべきか判定
///
/// Returns true if:
/// - `joinir_core_enabled()=true` AND
/// - 関数が本線化対象 (Loop or If)
pub fn should_try_joinir_mainline(func_name: &str, is_loop: bool) -> bool {
if !crate::config::env::joinir_core_enabled() {
return false;
}
if is_loop {
is_loop_mainline_target(func_name)
} else {
is_if_mainline_target(func_name)
}
}
/// Phase 80/81: Strict モードで JoinIR lowering 失敗時にパニックすべきか判定
pub fn should_panic_on_joinir_failure(func_name: &str, is_loop: bool) -> bool {
if !crate::config::env::joinir_strict_enabled() {
return false;
}
should_try_joinir_mainline(func_name, is_loop)
}
/// Phase 61-4: ループ外 If の JoinIR 対象関数判定
///
/// HAKO_JOINIR_IF_TOPLEVEL=1 有効時に、ループ外 if の JoinIR 経路を試行する関数。

View File

@ -47,10 +47,15 @@ pub fn try_run_joinir_vm_bridge(module: &MirModule, quiet_pipe: bool) -> bool {
return false;
};
// Phase 80: Core ON 時は本線化対象として判定
let core_mainline =
crate::mir::join_ir::lowering::should_try_joinir_mainline(target.func_name, true);
// Phase 32 L-4: 有効化条件チェック
// - Phase 80: Core ON + 本線対象 OR
// - env フラグが有効 OR
// - default_enabled=true の対象関数
let is_enabled = flags.is_bridge_enabled() || target.default_enabled;
let is_enabled = core_mainline || flags.is_bridge_enabled() || target.default_enabled;
if !is_enabled {
return false;
}
@ -67,7 +72,10 @@ pub fn try_run_joinir_vm_bridge(module: &MirModule, quiet_pipe: bool) -> bool {
};
if !handled {
if strict {
// Phase 80/81: Strict mode では本線対象関数の失敗でパニック
let should_panic =
crate::mir::join_ir::lowering::should_panic_on_joinir_failure(target.func_name, true);
if strict || should_panic {
eprintln!(
"[joinir/bridge] ERROR: target={} lowering/exec failed (strict, no fallback)",
target.func_name