From 9d769e9217d605fe6f37d61aad076cac8364af5c Mon Sep 17 00:00:00 2001 From: nyash-codex Date: Wed, 26 Nov 2025 10:47:35 +0900 Subject: [PATCH] refactor(joinir): L-2.2 Step-1 - Unify Stage-B lowering via LoopToJoinLowerer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stage-B minimal JoinIR lowering統一化: 1. Add Case-A helpers to loop_to_join.rs: - lower_case_a_for_stageb_body (StageBBodyExtractorBox.build_body_src/2) - lower_case_a_for_stageb_funcscanner (StageBFuncScannerBox.scan_all_boxes/1) 2. Update stageb_body.rs and stageb_funcscanner.rs: - Replace manual LoopForm construction with construct_simple_while_loopform - Route through LoopToJoinLowerer like other Case-A functions - Remove unused imports (LoopForm, MirQuery) Now all 6 JoinIR lowering modules use the same unified pattern: - skip_ws, trim, append_defs, stage1_resolver, stageb_body, stageb_funcscanner All route through LoopToJoinLowerer for consistency. Test results: JSON snapshot 6/6 PASS 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/mir/join_ir/lowering/loop_to_join.rs | 20 ++++++++++ src/mir/join_ir/lowering/stageb_body.rs | 37 +++++++++++-------- .../join_ir/lowering/stageb_funcscanner.rs | 37 +++++++++++-------- 3 files changed, 64 insertions(+), 30 deletions(-) diff --git a/src/mir/join_ir/lowering/loop_to_join.rs b/src/mir/join_ir/lowering/loop_to_join.rs index f7a14fd0..2a568abe 100644 --- a/src/mir/join_ir/lowering/loop_to_join.rs +++ b/src/mir/join_ir/lowering/loop_to_join.rs @@ -339,6 +339,26 @@ impl LoopToJoinLowerer { ) -> Option { self.lower(func, loop_form, Some("Stage1UsingResolverBox.resolve_for_source/5")) } + + /// Case-A 汎用 lowerer の「StageBBodyExtractorBox.build_body_src/2 用」薄いラッパー。 + /// 実際のロジックは `lower` に集約されている。 + pub fn lower_case_a_for_stageb_body( + &self, + func: &MirFunction, + loop_form: &LoopForm, + ) -> Option { + self.lower(func, loop_form, Some("StageBBodyExtractorBox.build_body_src/2")) + } + + /// Case-A 汎用 lowerer の「StageBFuncScannerBox.scan_all_boxes/1 用」薄いラッパー。 + /// 実際のロジックは `lower` に集約されている。 + pub fn lower_case_a_for_stageb_funcscanner( + &self, + func: &MirFunction, + loop_form: &LoopForm, + ) -> Option { + self.lower(func, loop_form, Some("StageBFuncScannerBox.scan_all_boxes/1")) + } } #[cfg(test)] diff --git a/src/mir/join_ir/lowering/stageb_body.rs b/src/mir/join_ir/lowering/stageb_body.rs index adb1db2d..fa9bd69e 100644 --- a/src/mir/join_ir/lowering/stageb_body.rs +++ b/src/mir/join_ir/lowering/stageb_body.rs @@ -11,8 +11,7 @@ use crate::mir::join_ir::lowering::common::{ }; use crate::mir::join_ir::lowering::value_id_ranges::stageb_body_extract as vid; use crate::mir::join_ir::JoinModule; -use crate::mir::loop_form::LoopForm; -use crate::mir::query::{MirQuery, MirQueryBox}; +use crate::mir::query::MirQueryBox; /// Public dispatcher (MIR-based vs handwritten) pub fn lower_stageb_body_to_joinir(module: &crate::mir::MirModule) -> Option { @@ -173,22 +172,30 @@ fn lower_from_mir(module: &crate::mir::MirModule) -> Option { return lower_handwritten(module); } + // Phase 32: LoopToJoinLowerer 統一箱経由に移行 + // construct_simple_while_loopform 共通ヘルパーを使用 if crate::mir::join_ir::env_flag_is_1("NYASH_JOINIR_LOWER_GENERIC") { - let header = query.succs(entry).get(0).copied().unwrap_or(entry); - let succs_header = query.succs(header); - let body = succs_header.get(0).copied().unwrap_or(header); - let exit = succs_header.get(1).copied().unwrap_or(header); - let loop_form = LoopForm { - preheader: entry, - header, - body, - latch: body, - exit, - continue_targets: vec![body], - break_targets: vec![exit], + use crate::mir::join_ir::lowering::common::construct_simple_while_loopform; + use crate::mir::join_ir::lowering::loop_to_join::LoopToJoinLowerer; + + // stageb_body: entry_is_preheader=true, has_break=true + let Some(loop_form) = construct_simple_while_loopform(entry, &query, true, true) else { + eprintln!("[joinir/stageb_body/generic-hook] failed to construct LoopForm from CFG"); + return build_stageb_body_joinir(module); }; + if crate::mir::join_ir::lowering::common::case_a::is_simple_case_a_loop(&loop_form) { - eprintln!("[joinir/stageb_body/generic-hook] simple Case A loop detected (generic_case_a hook placeholder)"); + eprintln!( + "[joinir/stageb_body/generic-hook] simple Case A loop detected (LoopToJoinLowerer)" + ); + let lowerer = LoopToJoinLowerer::new(); + if let Some(jm) = lowerer.lower_case_a_for_stageb_body(target_func, &loop_form) { + eprintln!("[joinir/stageb_body/generic-hook] LoopToJoinLowerer produced JoinIR, returning early"); + return Some(jm); + } + eprintln!( + "[joinir/stageb_body/generic-hook] LoopToJoinLowerer returned None, falling back to handwritten" + ); } } diff --git a/src/mir/join_ir/lowering/stageb_funcscanner.rs b/src/mir/join_ir/lowering/stageb_funcscanner.rs index 5382af65..950acb1d 100644 --- a/src/mir/join_ir/lowering/stageb_funcscanner.rs +++ b/src/mir/join_ir/lowering/stageb_funcscanner.rs @@ -11,8 +11,7 @@ use crate::mir::join_ir::lowering::common::{ }; use crate::mir::join_ir::lowering::value_id_ranges::stageb_funcscanner as vid; use crate::mir::join_ir::JoinModule; -use crate::mir::loop_form::LoopForm; -use crate::mir::query::{MirQuery, MirQueryBox}; +use crate::mir::query::MirQueryBox; /// Public dispatcher (MIR-based vs handwritten) pub fn lower_stageb_funcscanner_to_joinir(module: &crate::mir::MirModule) -> Option { @@ -163,22 +162,30 @@ fn lower_from_mir(module: &crate::mir::MirModule) -> Option { return lower_handwritten(module); } + // Phase 32: LoopToJoinLowerer 統一箱経由に移行 + // construct_simple_while_loopform 共通ヘルパーを使用 if crate::mir::join_ir::env_flag_is_1("NYASH_JOINIR_LOWER_GENERIC") { - let header = query.succs(entry).get(0).copied().unwrap_or(entry); - let succs_header = query.succs(header); - let body = succs_header.get(0).copied().unwrap_or(header); - let exit = succs_header.get(1).copied().unwrap_or(header); - let loop_form = LoopForm { - preheader: entry, - header, - body, - latch: body, - exit, - continue_targets: vec![body], - break_targets: vec![exit], + use crate::mir::join_ir::lowering::common::construct_simple_while_loopform; + use crate::mir::join_ir::lowering::loop_to_join::LoopToJoinLowerer; + + // stageb_funcscanner: entry_is_preheader=true, has_break=true + let Some(loop_form) = construct_simple_while_loopform(entry, &query, true, true) else { + eprintln!("[joinir/stageb_funcscanner/generic-hook] failed to construct LoopForm from CFG"); + return build_stageb_funcscanner_joinir(module); }; + if crate::mir::join_ir::lowering::common::case_a::is_simple_case_a_loop(&loop_form) { - eprintln!("[joinir/stageb_funcscanner/generic-hook] simple Case A loop detected (generic_case_a hook placeholder)"); + eprintln!( + "[joinir/stageb_funcscanner/generic-hook] simple Case A loop detected (LoopToJoinLowerer)" + ); + let lowerer = LoopToJoinLowerer::new(); + if let Some(jm) = lowerer.lower_case_a_for_stageb_funcscanner(target_func, &loop_form) { + eprintln!("[joinir/stageb_funcscanner/generic-hook] LoopToJoinLowerer produced JoinIR, returning early"); + return Some(jm); + } + eprintln!( + "[joinir/stageb_funcscanner/generic-hook] LoopToJoinLowerer returned None, falling back to handwritten" + ); } }