feat(mir): Phase 30 F-3.0.7 LoopScopeShape Case-A minimal routing
Add func_name-based routing in LoopScopeShape::from_existing_boxes() to prepare for MIR-based independent analysis: - Add is_case_a_minimal_target() helper for 4 Case-A targets - Add analyze_case_a() method (delegates to legacy, future MIR-based) - Add from_existing_boxes_legacy() for backward compatibility - Update from_existing_boxes() with func_name: Option<&str> parameter - Update 4 production call sites with specific func_name - Update 6 test cases with None for legacy path - Update module documentation with routing logic diagram Tests: 10/10 LoopScopeShape tests PASS, 6/7 JoinIR VM bridge tests PASS 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -346,7 +346,12 @@ fn lower_from_mir(module: &crate::mir::MirModule) -> Option<JoinModule> {
|
||||
eprintln!("[joinir/funcscanner_append_defs/mir] CFG sanity checks passed ✅");
|
||||
eprintln!("[joinir/funcscanner_append_defs/mir] Found: length(), get(), push(), i+1");
|
||||
|
||||
// Phase 30 F-3: LoopScopeShape 経由の新API を使用
|
||||
if crate::mir::join_ir::env_flag_is_1("NYASH_JOINIR_LOWER_GENERIC") {
|
||||
use crate::mir::join_ir::lowering::generic_case_a::lower_case_a_append_defs_with_scope;
|
||||
use crate::mir::join_ir::lowering::loop_form_intake::intake_loop_form;
|
||||
use crate::mir::join_ir::lowering::loop_scope_shape::LoopScopeShape;
|
||||
|
||||
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);
|
||||
@ -366,20 +371,27 @@ fn lower_from_mir(module: &crate::mir::MirModule) -> Option<JoinModule> {
|
||||
);
|
||||
let var_classes = crate::mir::phi_core::loop_var_classifier::LoopVarClassBox::new();
|
||||
let exit_live = crate::mir::phi_core::loop_exit_liveness::LoopExitLivenessBox::new();
|
||||
if let Some(jm) = crate::mir::join_ir::lowering::generic_case_a::lower_case_a_loop_to_joinir_for_append_defs_minimal(
|
||||
&loop_form,
|
||||
&var_classes,
|
||||
&exit_live,
|
||||
&query,
|
||||
target_func,
|
||||
) {
|
||||
eprintln!(
|
||||
"[joinir/funcscanner_append_defs/generic-hook] generic_case_a produced JoinIR, returning early"
|
||||
);
|
||||
return Some(jm);
|
||||
|
||||
// Phase 30 F-3: LoopFormIntake + LoopScopeShape 経由で呼び出し
|
||||
if let Some(intake) = intake_loop_form(&loop_form, &var_classes, &query, target_func) {
|
||||
if let Some(scope) = LoopScopeShape::from_existing_boxes(
|
||||
&loop_form,
|
||||
&intake,
|
||||
&var_classes,
|
||||
&exit_live,
|
||||
&query,
|
||||
Some("FuncScannerBox.append_defs/2"), // Phase 30 F-3.1: Case-A minimal target
|
||||
) {
|
||||
if let Some(jm) = lower_case_a_append_defs_with_scope(scope) {
|
||||
eprintln!(
|
||||
"[joinir/funcscanner_append_defs/generic-hook] generic_case_a produced JoinIR via _with_scope, returning early"
|
||||
);
|
||||
return Some(jm);
|
||||
}
|
||||
}
|
||||
}
|
||||
eprintln!(
|
||||
"[joinir/funcscanner_append_defs/generic-hook] generic_case_a returned None, falling back to handwritten/MIR path"
|
||||
"[joinir/funcscanner_append_defs/generic-hook] generic_case_a via _with_scope returned None, falling back to handwritten/MIR path"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -619,7 +619,12 @@ fn lower_trim_from_mir(module: &crate::mir::MirModule) -> Option<JoinModule> {
|
||||
|
||||
eprintln!("[joinir/trim/mir] CFG sanity checks passed ✅");
|
||||
|
||||
// Phase 30 F-3: LoopScopeShape 経由の新API を使用
|
||||
if crate::mir::join_ir::env_flag_is_1("NYASH_JOINIR_LOWER_GENERIC") {
|
||||
use crate::mir::join_ir::lowering::generic_case_a::lower_case_a_trim_with_scope;
|
||||
use crate::mir::join_ir::lowering::loop_form_intake::intake_loop_form;
|
||||
use crate::mir::join_ir::lowering::loop_scope_shape::LoopScopeShape;
|
||||
|
||||
let header = query.succs(entry_id).get(0).copied().unwrap_or(entry_id);
|
||||
let succs_header = query.succs(header);
|
||||
let body = succs_header.get(0).copied().unwrap_or(header);
|
||||
@ -639,12 +644,25 @@ fn lower_trim_from_mir(module: &crate::mir::MirModule) -> Option<JoinModule> {
|
||||
);
|
||||
let var_classes = crate::mir::phi_core::loop_var_classifier::LoopVarClassBox::new();
|
||||
let exit_live = crate::mir::phi_core::loop_exit_liveness::LoopExitLivenessBox::new();
|
||||
if let Some(jm) = crate::mir::join_ir::lowering::generic_case_a::lower_case_a_loop_to_joinir_for_trim_minimal(&loop_form, &var_classes, &exit_live, &query, target_func) {
|
||||
eprintln!("[joinir/trim/generic-hook] generic_case_a produced JoinIR, returning early");
|
||||
return Some(jm);
|
||||
|
||||
// Phase 30 F-3: LoopFormIntake + LoopScopeShape 経由で呼び出し
|
||||
if let Some(intake) = intake_loop_form(&loop_form, &var_classes, &query, target_func) {
|
||||
if let Some(scope) = LoopScopeShape::from_existing_boxes(
|
||||
&loop_form,
|
||||
&intake,
|
||||
&var_classes,
|
||||
&exit_live,
|
||||
&query,
|
||||
Some("FuncScannerBox.trim/1"), // Phase 30 F-3.1: Case-A minimal target
|
||||
) {
|
||||
if let Some(jm) = lower_case_a_trim_with_scope(scope) {
|
||||
eprintln!("[joinir/trim/generic-hook] generic_case_a produced JoinIR via _with_scope, returning early");
|
||||
return Some(jm);
|
||||
}
|
||||
}
|
||||
}
|
||||
eprintln!(
|
||||
"[joinir/trim/generic-hook] generic_case_a placeholder returned None, falling back to handwritten"
|
||||
"[joinir/trim/generic-hook] generic_case_a via _with_scope returned None, falling back to handwritten"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,19 +12,34 @@
|
||||
//! - LoopScopeShape: 変数の「役割」(pinned/carrier/body_local/exit_live)
|
||||
//! - JoinIR: 関数と継続で表現された制御構造
|
||||
//!
|
||||
//! # Phase 29 Strategy
|
||||
//! # Phase 30 F-3.1 Strategy: Case-A Minimal Routing
|
||||
//!
|
||||
//! 現在は「既存箱を呼ぶだけの薄いラッパー」として実装。
|
||||
//! 将来は既存箱を吸収して LoopScopeShape を唯一のソースにする(Phase 30)。
|
||||
//! `from_existing_boxes` メソッドは、関数名に基づいてCase-A minimalターゲット
|
||||
//! (skip_ws, trim, append_defs, stage1_using_resolver)を新しいパスに
|
||||
//! ルーティングする。現在は同じ結果を返すが、将来的に `analyze_case_a` は
|
||||
//! MIRベースの独立解析を行う基盤となる。
|
||||
//!
|
||||
//! ## Routing Logic
|
||||
//!
|
||||
//! ```ignore
|
||||
//! from_existing_boxes(func_name: Option<&str>)
|
||||
//! ├── Some("Main.skip/1") → analyze_case_a()
|
||||
//! ├── Some("FuncScannerBox.trim/1") → analyze_case_a()
|
||||
//! ├── Some("FuncScannerBox.append_defs/2") → analyze_case_a()
|
||||
//! ├── Some("Stage1UsingResolverBox.resolve_for_source/5") → analyze_case_a()
|
||||
//! └── None or other → from_existing_boxes_legacy()
|
||||
//! ```
|
||||
//!
|
||||
//! # Usage
|
||||
//!
|
||||
//! ```ignore
|
||||
//! let scope = LoopScopeShape::from_existing_boxes(
|
||||
//! &loop_form_intake,
|
||||
//! &loop_form,
|
||||
//! &intake,
|
||||
//! &var_classes,
|
||||
//! &exit_live,
|
||||
//! query,
|
||||
//! Some("Main.skip/1"), // Case-A minimal target
|
||||
//! )?;
|
||||
//!
|
||||
//! // JoinIR lowering では scope のフィールドを参照
|
||||
@ -42,6 +57,36 @@ use crate::mir::phi_core::loop_exit_liveness::LoopExitLivenessBox;
|
||||
use crate::mir::phi_core::loop_var_classifier::{LoopVarClass, LoopVarClassBox};
|
||||
use crate::mir::{BasicBlockId, MirQuery, ValueId};
|
||||
|
||||
// ============================================================================
|
||||
// Phase 30 F-3.1: Case-A Minimal Target Detection
|
||||
// ============================================================================
|
||||
|
||||
/// Phase 30 F-3.1: Case-A minimal ターゲット判定
|
||||
///
|
||||
/// 現在 JoinIR lowering でサポートしている Case-A minimal ループのみ true を返す。
|
||||
/// これらは LoopScopeShape の新しい analyze_case_a パスを通る。
|
||||
///
|
||||
/// # Supported Targets
|
||||
///
|
||||
/// - `Main.skip/1`: minimal_ssa_skip_ws.hako
|
||||
/// - `FuncScannerBox.trim/1`: funcscanner_trim_min.hako
|
||||
/// - `FuncScannerBox.append_defs/2`: funcscanner_append_defs_min.hako
|
||||
/// - `Stage1UsingResolverBox.resolve_for_source/5`: stage1_using_resolver minimal
|
||||
///
|
||||
/// # Future
|
||||
///
|
||||
/// この関数は将来的に LoopForm/LoopScopeShape ベースの汎用判定に置き換わる予定。
|
||||
/// その時点でこのハードコードリストは削除される。
|
||||
pub(crate) fn is_case_a_minimal_target(func_name: &str) -> bool {
|
||||
matches!(
|
||||
func_name,
|
||||
"Main.skip/1"
|
||||
| "FuncScannerBox.trim/1"
|
||||
| "FuncScannerBox.append_defs/2"
|
||||
| "Stage1UsingResolverBox.resolve_for_source/5"
|
||||
)
|
||||
}
|
||||
|
||||
/// ループ変数スコープの統合ビュー
|
||||
///
|
||||
/// # Phase 30: 変数分類の唯一の仕様ソース (SSOT)
|
||||
@ -160,7 +205,7 @@ pub(crate) struct LoopScopeShape {
|
||||
}
|
||||
|
||||
impl LoopScopeShape {
|
||||
/// Create LoopScopeShape from existing boxes (Phase 30: unified interface)
|
||||
/// Create LoopScopeShape from existing boxes (Phase 30 F-3.1: unified interface)
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
@ -169,28 +214,146 @@ impl LoopScopeShape {
|
||||
/// - `var_classes`: LoopVarClassBox for classification
|
||||
/// - `exit_live_box`: LoopExitLivenessBox for exit liveness
|
||||
/// - `query`: MirQuery for liveness computation
|
||||
/// - `func_name`: Optional function name for Case-A minimal routing
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Some(LoopScopeShape) if successful, None if critical data is missing.
|
||||
///
|
||||
/// # Phase 30 Design
|
||||
/// # Phase 30 F-3.1 Design
|
||||
///
|
||||
/// This is the primary entry point for creating LoopScopeShape.
|
||||
/// Block IDs come from loop_form, variable classification from existing boxes.
|
||||
/// Future phases will internalize the box logic entirely.
|
||||
/// - Case-A minimal targets route through `analyze_case_a` (new path)
|
||||
/// - Other loops use `from_existing_boxes_legacy` (existing path)
|
||||
///
|
||||
/// Both paths currently produce the same result, but analyze_case_a
|
||||
/// is the foundation for future MIR-based independent analysis.
|
||||
pub(crate) fn from_existing_boxes(
|
||||
loop_form: &LoopForm,
|
||||
intake: &LoopFormIntake,
|
||||
var_classes: &LoopVarClassBox,
|
||||
exit_live_box: &LoopExitLivenessBox,
|
||||
query: &impl MirQuery,
|
||||
func_name: Option<&str>,
|
||||
) -> Option<Self> {
|
||||
// Phase 30 F-3.1: Route Case-A minimal targets through new path
|
||||
if let Some(name) = func_name {
|
||||
if is_case_a_minimal_target(name) {
|
||||
return Self::analyze_case_a(
|
||||
loop_form, intake, var_classes, exit_live_box, query, name,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Default: use legacy path
|
||||
Self::from_existing_boxes_legacy(loop_form, intake, var_classes, exit_live_box, query)
|
||||
}
|
||||
|
||||
/// Check if a variable needs header PHI
|
||||
#[allow(dead_code)] // Phase 30: will be used in F-3 generic lowering
|
||||
pub fn needs_header_phi(&self, var_name: &str) -> bool {
|
||||
self.pinned.contains(var_name) || self.carriers.contains(var_name)
|
||||
}
|
||||
|
||||
/// Check if a variable needs exit PHI
|
||||
pub fn needs_exit_phi(&self, var_name: &str) -> bool {
|
||||
self.exit_live.contains(var_name)
|
||||
}
|
||||
|
||||
/// Get ordered pinned variables (for JoinIR parameter generation)
|
||||
pub fn pinned_ordered(&self) -> Vec<String> {
|
||||
self.pinned.iter().cloned().collect()
|
||||
}
|
||||
|
||||
/// Get ordered carrier variables (for JoinIR parameter generation)
|
||||
pub fn carriers_ordered(&self) -> Vec<String> {
|
||||
self.carriers.iter().cloned().collect()
|
||||
}
|
||||
|
||||
/// Get all variables that need header PHI (pinned + carriers)
|
||||
#[allow(dead_code)] // Phase 30: will be used in F-3 generic lowering
|
||||
pub fn header_phi_vars(&self) -> Vec<String> {
|
||||
let mut result: Vec<String> = self.pinned.iter().cloned().collect();
|
||||
result.extend(self.carriers.iter().cloned());
|
||||
result
|
||||
}
|
||||
|
||||
/// Get all variables that need exit PHI
|
||||
#[allow(dead_code)] // Phase 30: will be used in F-3 generic lowering
|
||||
pub fn exit_phi_vars(&self) -> Vec<String> {
|
||||
self.exit_live.iter().cloned().collect()
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Phase 30 F-3.1: Case-A Minimal Analysis Path
|
||||
// =========================================================================
|
||||
|
||||
/// Phase 30 F-3.1: Case-A minimal 用の解析パス
|
||||
///
|
||||
/// 現在は `from_existing_boxes_legacy` と同じ実装だが、
|
||||
/// debug_assert で結果を検証し、将来的に MIR ベースの独立実装に移行する。
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `loop_form`: LoopForm containing block structure
|
||||
/// - `intake`: LoopFormIntake containing classified variable info
|
||||
/// - `var_classes`: LoopVarClassBox for classification
|
||||
/// - `exit_live_box`: LoopExitLivenessBox for exit liveness
|
||||
/// - `query`: MirQuery for liveness computation
|
||||
/// - `func_name`: 関数名(ログ用)
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Some(LoopScopeShape) if successful, None if critical data is missing.
|
||||
fn analyze_case_a(
|
||||
loop_form: &LoopForm,
|
||||
intake: &LoopFormIntake,
|
||||
var_classes: &LoopVarClassBox,
|
||||
exit_live_box: &LoopExitLivenessBox,
|
||||
query: &impl MirQuery,
|
||||
func_name: &str,
|
||||
) -> Option<Self> {
|
||||
// Phase 30 F-3.1: 現在は legacy と同じ実装
|
||||
// 将来は MIR から独立して pinned/carriers/body_locals/exit_live を計算
|
||||
let result = Self::from_existing_boxes_legacy(
|
||||
loop_form, intake, var_classes, exit_live_box, query,
|
||||
)?;
|
||||
|
||||
// Debug: Case-A minimal path が使われていることをログ
|
||||
if std::env::var("NYASH_LOOPSCOPE_DEBUG").is_ok() {
|
||||
eprintln!(
|
||||
"[loopscope/case_a] {} via analyze_case_a path (pinned={}, carriers={}, exit_live={})",
|
||||
func_name,
|
||||
result.pinned.len(),
|
||||
result.carriers.len(),
|
||||
result.exit_live.len(),
|
||||
);
|
||||
}
|
||||
|
||||
// TODO (F-3.1+): MIR ベースの独立計算を実装し、ここで debug_assert_eq! する
|
||||
// let mir_based_result = Self::compute_from_mir(...);
|
||||
// debug_assert_eq!(result.pinned, mir_based_result.pinned);
|
||||
// debug_assert_eq!(result.carriers, mir_based_result.carriers);
|
||||
|
||||
Some(result)
|
||||
}
|
||||
|
||||
/// Phase 30 F-3.1: 従来の既存箱ベース実装(legacy path)
|
||||
///
|
||||
/// analyze_case_a と分離することで、Case-A minimal だけ新パスを通せる。
|
||||
fn from_existing_boxes_legacy(
|
||||
loop_form: &LoopForm,
|
||||
intake: &LoopFormIntake,
|
||||
var_classes: &LoopVarClassBox,
|
||||
exit_live_box: &LoopExitLivenessBox,
|
||||
query: &impl MirQuery,
|
||||
) -> Option<Self> {
|
||||
// Extract block IDs from LoopForm
|
||||
let header = loop_form.header;
|
||||
let body = loop_form.body;
|
||||
let latch = loop_form.latch;
|
||||
let exit = loop_form.exit;
|
||||
|
||||
// Extract pinned and carriers from intake (already classified)
|
||||
let pinned: BTreeSet<String> = intake.pinned_ordered.iter().cloned().collect();
|
||||
let carriers: BTreeSet<String> = intake.carrier_ordered.iter().cloned().collect();
|
||||
@ -266,41 +429,6 @@ impl LoopScopeShape {
|
||||
})
|
||||
}
|
||||
|
||||
/// Check if a variable needs header PHI
|
||||
#[allow(dead_code)] // Phase 30: will be used in F-3 generic lowering
|
||||
pub fn needs_header_phi(&self, var_name: &str) -> bool {
|
||||
self.pinned.contains(var_name) || self.carriers.contains(var_name)
|
||||
}
|
||||
|
||||
/// Check if a variable needs exit PHI
|
||||
pub fn needs_exit_phi(&self, var_name: &str) -> bool {
|
||||
self.exit_live.contains(var_name)
|
||||
}
|
||||
|
||||
/// Get ordered pinned variables (for JoinIR parameter generation)
|
||||
pub fn pinned_ordered(&self) -> Vec<String> {
|
||||
self.pinned.iter().cloned().collect()
|
||||
}
|
||||
|
||||
/// Get ordered carrier variables (for JoinIR parameter generation)
|
||||
pub fn carriers_ordered(&self) -> Vec<String> {
|
||||
self.carriers.iter().cloned().collect()
|
||||
}
|
||||
|
||||
/// Get all variables that need header PHI (pinned + carriers)
|
||||
#[allow(dead_code)] // Phase 30: will be used in F-3 generic lowering
|
||||
pub fn header_phi_vars(&self) -> Vec<String> {
|
||||
let mut result: Vec<String> = self.pinned.iter().cloned().collect();
|
||||
result.extend(self.carriers.iter().cloned());
|
||||
result
|
||||
}
|
||||
|
||||
/// Get all variables that need exit PHI
|
||||
#[allow(dead_code)] // Phase 30: will be used in F-3 generic lowering
|
||||
pub fn exit_phi_vars(&self) -> Vec<String> {
|
||||
self.exit_live.iter().cloned().collect()
|
||||
}
|
||||
|
||||
/// Phase 30 F-1.1: 変数を4分類に分類する
|
||||
///
|
||||
/// LoopVarClassBox.classify() と同じロジックを LoopScopeShape の内部状態から導出。
|
||||
@ -548,6 +676,7 @@ mod tests {
|
||||
&var_classes,
|
||||
&exit_live_box,
|
||||
&query,
|
||||
None, // generic test - use legacy path
|
||||
);
|
||||
|
||||
assert!(scope.is_some());
|
||||
@ -586,6 +715,7 @@ mod tests {
|
||||
&var_classes,
|
||||
&exit_live_box,
|
||||
&query,
|
||||
None, // generic test - use legacy path
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@ -609,6 +739,7 @@ mod tests {
|
||||
&var_classes,
|
||||
&exit_live_box,
|
||||
&query,
|
||||
None, // generic test - use legacy path
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@ -632,6 +763,7 @@ mod tests {
|
||||
&var_classes,
|
||||
&exit_live_box,
|
||||
&query,
|
||||
None, // generic test - use legacy path
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@ -694,6 +826,7 @@ mod tests {
|
||||
&var_classes,
|
||||
&exit_live_box,
|
||||
&query,
|
||||
None, // generic test - use legacy path
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@ -741,6 +874,7 @@ mod tests {
|
||||
&var_classes,
|
||||
&exit_live_box,
|
||||
&query,
|
||||
None, // generic test - use legacy path
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
||||
@ -352,8 +352,12 @@ fn lower_skip_ws_handwritten_or_mir(module: &crate::mir::MirModule) -> Option<Jo
|
||||
}
|
||||
|
||||
/// トグル ON 時にだけ試す generic Case A ロワー(minimal_ssa_skip_ws 限定)
|
||||
///
|
||||
/// Phase 30 F-3: LoopScopeShape 経由の新API を使用
|
||||
fn try_lower_skip_ws_generic_case_a(module: &crate::mir::MirModule) -> Option<JoinModule> {
|
||||
use crate::mir::join_ir::lowering::generic_case_a::lower_case_a_loop_to_joinir_for_minimal_skip_ws;
|
||||
use crate::mir::join_ir::lowering::generic_case_a::lower_case_a_skip_ws_with_scope;
|
||||
use crate::mir::join_ir::lowering::loop_form_intake::intake_loop_form;
|
||||
use crate::mir::join_ir::lowering::loop_scope_shape::LoopScopeShape;
|
||||
use crate::mir::loop_form::LoopForm;
|
||||
use crate::mir::phi_core::loop_exit_liveness::LoopExitLivenessBox;
|
||||
use crate::mir::phi_core::loop_var_classifier::LoopVarClassBox;
|
||||
@ -380,14 +384,23 @@ fn try_lower_skip_ws_generic_case_a(module: &crate::mir::MirModule) -> Option<Jo
|
||||
break_targets: vec![exit],
|
||||
};
|
||||
|
||||
// Phase 30 F-3: 実データ Box を使用(空箱から実箱へ)
|
||||
let var_classes = LoopVarClassBox::new();
|
||||
let exit_live = LoopExitLivenessBox::new();
|
||||
|
||||
lower_case_a_loop_to_joinir_for_minimal_skip_ws(
|
||||
// LoopFormIntake 構築
|
||||
let intake = intake_loop_form(&loop_form, &var_classes, &query, target_func)?;
|
||||
|
||||
// LoopScopeShape 構築
|
||||
let scope = LoopScopeShape::from_existing_boxes(
|
||||
&loop_form,
|
||||
&intake,
|
||||
&var_classes,
|
||||
&exit_live,
|
||||
&query,
|
||||
target_func,
|
||||
)
|
||||
Some("Main.skip/1"), // Phase 30 F-3.1: Case-A minimal target
|
||||
)?;
|
||||
|
||||
// 新API経由で JoinModule 生成
|
||||
lower_case_a_skip_ws_with_scope(scope)
|
||||
}
|
||||
|
||||
@ -343,7 +343,12 @@ fn lower_from_mir(module: &crate::mir::MirModule) -> Option<JoinModule> {
|
||||
|
||||
eprintln!("[joinir/stage1_using_resolver/mir] CFG sanity checks passed ✅");
|
||||
|
||||
// Phase 30 F-3: LoopScopeShape 経由の新API を使用
|
||||
if crate::mir::join_ir::env_flag_is_1("NYASH_JOINIR_LOWER_GENERIC") {
|
||||
use crate::mir::join_ir::lowering::generic_case_a::lower_case_a_stage1_usingresolver_with_scope;
|
||||
use crate::mir::join_ir::lowering::loop_form_intake::intake_loop_form;
|
||||
use crate::mir::join_ir::lowering::loop_scope_shape::LoopScopeShape;
|
||||
|
||||
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);
|
||||
@ -365,21 +370,27 @@ fn lower_from_mir(module: &crate::mir::MirModule) -> Option<JoinModule> {
|
||||
let exit_live = crate::mir::phi_core::loop_exit_liveness::LoopExitLivenessBox::new();
|
||||
let params_len = target_func.params.len();
|
||||
if params_len == 5 {
|
||||
if let Some(jm) = crate::mir::join_ir::lowering::generic_case_a::lower_case_a_loop_to_joinir_for_stage1_usingresolver_minimal(
|
||||
&loop_form,
|
||||
&var_classes,
|
||||
&exit_live,
|
||||
&query,
|
||||
target_func,
|
||||
) {
|
||||
eprintln!(
|
||||
"[joinir/stage1_using_resolver/generic-hook] generic_case_a produced JoinIR, returning early"
|
||||
);
|
||||
return Some(jm);
|
||||
// Phase 30 F-3: LoopFormIntake + LoopScopeShape 経由で呼び出し
|
||||
if let Some(intake) = intake_loop_form(&loop_form, &var_classes, &query, target_func) {
|
||||
if let Some(scope) = LoopScopeShape::from_existing_boxes(
|
||||
&loop_form,
|
||||
&intake,
|
||||
&var_classes,
|
||||
&exit_live,
|
||||
&query,
|
||||
Some("Stage1UsingResolverBox.resolve_for_source/5"), // Phase 30 F-3.1: Case-A minimal target
|
||||
) {
|
||||
if let Some(jm) = lower_case_a_stage1_usingresolver_with_scope(scope) {
|
||||
eprintln!(
|
||||
"[joinir/stage1_using_resolver/generic-hook] generic_case_a produced JoinIR via _with_scope, returning early"
|
||||
);
|
||||
return Some(jm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
eprintln!(
|
||||
"[joinir/stage1_using_resolver/generic-hook] generic_case_a returned None or params mismatch, falling back to handwritten/MIR path"
|
||||
"[joinir/stage1_using_resolver/generic-hook] generic_case_a via _with_scope returned None or params mismatch, falling back to handwritten/MIR path"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user