2025-11-23 16:49:49 +09:00
|
|
|
//! Phase 26-H: JoinIrMin.main/0 専用の MIR → JoinIR 変換
|
|
|
|
|
//!
|
|
|
|
|
//! 目的: apps/tests/joinir_min_loop.hako の MIR を JoinIR に変換する最小実装
|
|
|
|
|
//!
|
|
|
|
|
//! 期待される変換:
|
|
|
|
|
//! ```text
|
|
|
|
|
//! // MIR (元):
|
|
|
|
|
//! static box JoinIrMin {
|
|
|
|
|
//! main() {
|
|
|
|
|
//! local i = 0
|
|
|
|
|
//! loop(i < 3) {
|
|
|
|
|
//! if i >= 2 { break }
|
|
|
|
|
//! i = i + 1
|
|
|
|
|
//! }
|
|
|
|
|
//! return i
|
|
|
|
|
//! }
|
|
|
|
|
//! }
|
|
|
|
|
//!
|
|
|
|
|
//! // JoinIR (変換後):
|
|
|
|
|
//! fn main(k_exit) {
|
|
|
|
|
//! let i_init = 0
|
|
|
|
|
//! loop_step(i_init, k_exit)
|
|
|
|
|
//! }
|
|
|
|
|
//!
|
|
|
|
|
//! fn loop_step(i, k_exit) {
|
|
|
|
|
//! if i >= 2 {
|
|
|
|
|
//! k_exit(i) // break
|
|
|
|
|
//! } else {
|
|
|
|
|
//! loop_step(i + 1, k_exit) // continue
|
|
|
|
|
//! }
|
|
|
|
|
//! }
|
|
|
|
|
//! ```
|
|
|
|
|
|
|
|
|
|
use crate::mir::join_ir::{
|
|
|
|
|
BinOpKind, CompareOp, ConstValue, JoinFuncId, JoinFunction, JoinInst, JoinModule, MirLikeInst,
|
|
|
|
|
};
|
2025-11-24 14:17:02 +09:00
|
|
|
use crate::mir::ValueId;
|
2025-11-23 16:49:49 +09:00
|
|
|
|
|
|
|
|
pub fn lower_min_loop_to_joinir(module: &crate::mir::MirModule) -> Option<JoinModule> {
|
|
|
|
|
// Step 1: "JoinIrMin.main/0" を探す
|
|
|
|
|
let target_func = module.functions.get("JoinIrMin.main/0")?;
|
|
|
|
|
|
|
|
|
|
eprintln!("[joinir/lower] Found JoinIrMin.main/0");
|
|
|
|
|
eprintln!("[joinir/lower] MIR blocks: {}", target_func.blocks.len());
|
|
|
|
|
|
|
|
|
|
// Step 2: JoinModule を構築
|
|
|
|
|
let mut join_module = JoinModule::new();
|
|
|
|
|
|
|
|
|
|
// Phase 26-H: 最小実装として、固定的な JoinIR を生成
|
|
|
|
|
// (実際の MIR 解析は Phase 27 以降)
|
|
|
|
|
|
|
|
|
|
// main 関数: i_init = 0, loop_step(0, k_exit)
|
|
|
|
|
let main_id = JoinFuncId::new(0);
|
|
|
|
|
let mut main_func = JoinFunction::new(main_id, "main".to_string(), vec![]);
|
|
|
|
|
|
|
|
|
|
let i_init = ValueId(1000); // 固定 ValueId
|
|
|
|
|
let const_1 = ValueId(1002);
|
|
|
|
|
let const_2 = ValueId(1003);
|
|
|
|
|
|
|
|
|
|
// const 0
|
|
|
|
|
main_func.body.push(JoinInst::Compute(MirLikeInst::Const {
|
|
|
|
|
dst: i_init,
|
|
|
|
|
value: ConstValue::Integer(0),
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
// loop_step(i_init, k_exit)
|
|
|
|
|
let loop_step_id = JoinFuncId::new(1);
|
|
|
|
|
main_func.body.push(JoinInst::Call {
|
|
|
|
|
func: loop_step_id,
|
|
|
|
|
args: vec![i_init],
|
|
|
|
|
k_next: None, // main は直接 loop_step を呼ぶ
|
|
|
|
|
dst: None,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
join_module.add_function(main_func);
|
|
|
|
|
|
|
|
|
|
// loop_step 関数: if i >= 2 { ret i } else { loop_step(i+1) }
|
|
|
|
|
let mut loop_step_func = JoinFunction::new(
|
|
|
|
|
loop_step_id,
|
|
|
|
|
"loop_step".to_string(),
|
|
|
|
|
vec![ValueId(2000)], // i パラメータ
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let i_param = ValueId(2000);
|
|
|
|
|
let cmp_result = ValueId(2001);
|
|
|
|
|
let i_plus_1 = ValueId(2002);
|
|
|
|
|
|
|
|
|
|
// const 2 (for comparison)
|
2025-11-24 14:17:02 +09:00
|
|
|
loop_step_func
|
|
|
|
|
.body
|
|
|
|
|
.push(JoinInst::Compute(MirLikeInst::Const {
|
|
|
|
|
dst: const_2,
|
|
|
|
|
value: ConstValue::Integer(2),
|
|
|
|
|
}));
|
2025-11-23 16:49:49 +09:00
|
|
|
|
|
|
|
|
// cmp_result = (i >= 2)
|
2025-11-24 14:17:02 +09:00
|
|
|
loop_step_func
|
|
|
|
|
.body
|
|
|
|
|
.push(JoinInst::Compute(MirLikeInst::Compare {
|
|
|
|
|
dst: cmp_result,
|
|
|
|
|
op: CompareOp::Ge,
|
|
|
|
|
lhs: i_param,
|
|
|
|
|
rhs: const_2,
|
|
|
|
|
}));
|
2025-11-23 16:49:49 +09:00
|
|
|
|
|
|
|
|
// if cmp_result { ret i } else { loop_step(i+1) }
|
|
|
|
|
// Phase 26-H 簡略化: 分岐はせず両方の経路を示す
|
|
|
|
|
|
|
|
|
|
// ret i (break path)
|
|
|
|
|
loop_step_func.body.push(JoinInst::Ret {
|
|
|
|
|
value: Some(i_param),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// const 1 (for increment)
|
2025-11-24 14:17:02 +09:00
|
|
|
loop_step_func
|
|
|
|
|
.body
|
|
|
|
|
.push(JoinInst::Compute(MirLikeInst::Const {
|
|
|
|
|
dst: const_1,
|
|
|
|
|
value: ConstValue::Integer(1),
|
|
|
|
|
}));
|
2025-11-23 16:49:49 +09:00
|
|
|
|
|
|
|
|
// i_plus_1 = i + 1
|
2025-11-24 14:17:02 +09:00
|
|
|
loop_step_func
|
|
|
|
|
.body
|
|
|
|
|
.push(JoinInst::Compute(MirLikeInst::BinOp {
|
|
|
|
|
dst: i_plus_1,
|
|
|
|
|
op: BinOpKind::Add,
|
|
|
|
|
lhs: i_param,
|
|
|
|
|
rhs: const_1,
|
|
|
|
|
}));
|
2025-11-23 16:49:49 +09:00
|
|
|
|
|
|
|
|
// loop_step(i + 1) (continue path)
|
|
|
|
|
loop_step_func.body.push(JoinInst::Call {
|
|
|
|
|
func: loop_step_id,
|
|
|
|
|
args: vec![i_plus_1],
|
|
|
|
|
k_next: None,
|
|
|
|
|
dst: None,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
join_module.add_function(loop_step_func);
|
|
|
|
|
|
2025-11-24 14:17:02 +09:00
|
|
|
eprintln!(
|
|
|
|
|
"[joinir/lower] Generated {} JoinIR functions",
|
|
|
|
|
join_module.functions.len()
|
|
|
|
|
);
|
2025-11-23 16:49:49 +09:00
|
|
|
|
|
|
|
|
Some(join_module)
|
|
|
|
|
}
|