feat(joinir): Phase 188.3-P3.3 - Pattern6 continuation generation + Call callee fix
Phase 3-3 完了: 4関数モデル JoinIR 生成 - nested_loop_minimal.rs (337行, 新規): 4関数モデル実装 - main(): エントリーポイント - loop_step(i, sum): outer loop header - inner_step(j, i_outer, sum): inner loop (tail recursion) - k_inner_exit(i, sum): outer continuation after inner loop - k_exit(sum): 最終 exit - pattern6_nested_minimal.rs: lowering pipeline 実装 - boundary 構築 (continuation_func_ids 設定) - JoinIRConversionPipeline 呼び出し - instruction_rewriter.rs: latch incoming 拡張 - continuation→header 呼び出し対応 Call callee 修正: - call_generator.rs: callee フィールドを Callee::Global に設定 - joinir_block_converter.rs: emit_call_pair 使用に統一 smoke test 追加: - phase1883_nested_minimal_vm.sh (integration) 既知の問題 (次タスク): - ValueId(104) undefined: PHI/merge 問題 - JoinIR 関数パラメータの MIR マッピングが不完全 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -100,18 +100,112 @@ pub(crate) fn can_lower(_builder: &MirBuilder, ctx: &LoopPatternContext) -> bool
|
||||
|
||||
/// Lower Pattern6 (NestedLoopMinimal) to MIR
|
||||
///
|
||||
/// Phase 188.3: Full implementation with continuation generation
|
||||
/// Phase 188.3 P1: Full implementation with JoinIR pipeline
|
||||
pub(crate) fn lower(
|
||||
_builder: &mut MirBuilder,
|
||||
builder: &mut MirBuilder,
|
||||
ctx: &LoopPatternContext,
|
||||
) -> Result<Option<ValueId>, String> {
|
||||
use super::super::trace;
|
||||
|
||||
// Phase 3-1: Extract inner loop AST (validate exactly 1 inner loop)
|
||||
let inner_ast = extract_inner_loop_ast(ctx)?;
|
||||
let _inner_ast = extract_inner_loop_ast(ctx)?;
|
||||
|
||||
// Phase 3-2: Validate strict mode constraints (Fail-Fast)
|
||||
validate_strict_mode(inner_ast, ctx)?;
|
||||
validate_strict_mode(_inner_ast, ctx)?;
|
||||
|
||||
// Phase 3-3 stub - full implementation next
|
||||
// TODO: Implement continuation generation (outer_step, inner_step, k_inner_exit)
|
||||
Err("[Pattern6] Nested loop lowering not yet implemented (Phase 3-3 pending)".to_string())
|
||||
// Phase 3-3: Full implementation with JoinIR pipeline
|
||||
trace::trace().debug("pattern6", "Calling Pattern 6 nested loop minimal lowerer");
|
||||
|
||||
// Build preprocessing context - Pattern6 shares Pattern1's infrastructure
|
||||
use super::pattern_pipeline::{build_pattern_context, PatternVariant};
|
||||
let pattern_ctx = build_pattern_context(builder, ctx.condition, ctx.body, PatternVariant::Pattern1)?;
|
||||
|
||||
trace::trace().varmap("pattern6_start", &builder.variable_ctx.variable_map);
|
||||
|
||||
// Create JoinValueSpace for unified ValueId allocation
|
||||
use crate::mir::join_ir::lowering::join_value_space::JoinValueSpace;
|
||||
let mut join_value_space = JoinValueSpace::new();
|
||||
|
||||
// Call Pattern 6 lowerer with preprocessed scope
|
||||
use crate::mir::join_ir::lowering::nested_loop_minimal::lower_nested_loop_minimal;
|
||||
let join_module = match lower_nested_loop_minimal(pattern_ctx.loop_scope, &mut join_value_space) {
|
||||
Some(module) => module,
|
||||
None => {
|
||||
trace::trace().debug("pattern6", "Pattern 6 lowerer returned None");
|
||||
return Ok(None);
|
||||
}
|
||||
};
|
||||
|
||||
// Create boundary from context
|
||||
// Phase 188.3: Critical - must include continuation_func_ids to prevent merge misdetection
|
||||
use crate::mir::join_ir::lowering::carrier_info::CarrierRole;
|
||||
use crate::mir::join_ir::lowering::inline_boundary::LoopExitBinding;
|
||||
use crate::mir::join_ir::lowering::join_value_space::PARAM_MIN;
|
||||
use crate::mir::join_ir::lowering::JoinInlineBoundaryBuilder;
|
||||
use crate::mir::join_ir::lowering::nested_loop_minimal::{INNER_STEP, K_INNER_EXIT};
|
||||
|
||||
// Extract k_exit's parameter ValueId from join_module
|
||||
let k_exit_func = join_module.require_function("k_exit", "Pattern 6");
|
||||
let sum_exit_value = k_exit_func
|
||||
.params
|
||||
.first()
|
||||
.copied()
|
||||
.expect("k_exit must have parameter for exit value (sum)");
|
||||
|
||||
// Phase 188.3: Extract variables from variable_map
|
||||
let sum_var_id = builder
|
||||
.variable_ctx
|
||||
.variable_map
|
||||
.get("sum")
|
||||
.copied()
|
||||
.ok_or_else(|| "[Pattern6] sum variable not found in variable_map".to_string())?;
|
||||
|
||||
let i_var_id = pattern_ctx.loop_var_id;
|
||||
|
||||
// Create exit binding for sum (the final return value)
|
||||
let sum_exit_binding = LoopExitBinding {
|
||||
carrier_name: "sum".to_string(),
|
||||
join_exit_value: sum_exit_value,
|
||||
host_slot: sum_var_id,
|
||||
role: CarrierRole::LoopState,
|
||||
};
|
||||
|
||||
// Phase 188.3 CRITICAL: Include continuation_func_ids to prevent merge from
|
||||
// selecting inner_step as loop header
|
||||
use std::collections::BTreeSet;
|
||||
let continuation_funcs = BTreeSet::from([
|
||||
"k_exit".to_string(),
|
||||
K_INNER_EXIT.to_string(),
|
||||
INNER_STEP.to_string(),
|
||||
]);
|
||||
|
||||
let boundary = JoinInlineBoundaryBuilder::new()
|
||||
.with_inputs(
|
||||
vec![ValueId(PARAM_MIN), ValueId(PARAM_MIN + 1)], // main(i0, sum0)
|
||||
vec![i_var_id, sum_var_id], // host variables
|
||||
)
|
||||
.with_exit_bindings(vec![sum_exit_binding])
|
||||
.with_loop_var_name(Some(pattern_ctx.loop_var_name.clone())) // Phase 188.3: Enables header PHI for 'i'
|
||||
.with_continuation_funcs(continuation_funcs)
|
||||
.build();
|
||||
|
||||
// Use JoinIRConversionPipeline for unified conversion flow
|
||||
use super::conversion_pipeline::JoinIRConversionPipeline;
|
||||
let _ = JoinIRConversionPipeline::execute(
|
||||
builder,
|
||||
join_module,
|
||||
Some(&boundary),
|
||||
"pattern6",
|
||||
ctx.debug,
|
||||
)?;
|
||||
|
||||
// Return Void (loops don't produce values)
|
||||
let void_val = crate::mir::builder::emission::constant::emit_void(builder);
|
||||
|
||||
trace::trace().debug(
|
||||
"pattern6",
|
||||
&format!("Nested loop complete, returning Void {:?}", void_val),
|
||||
);
|
||||
|
||||
Ok(Some(void_val))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user