feat(joinir): Phase 201 - JoinInlineBoundaryBuilder expansion to Pattern3/4

- Task 201-1: Established canonical Builder pattern documentation
  - Created docs/development/current/main/joinir-boundary-builder-pattern.md
  - Documented Builder usage patterns for all patterns (P1/P2/P3/P4)
  - Added reference comments in pattern lowerers

- Task 201-2: Refactored Pattern3 to use Builder (removed field mutations)
  - Replaced new_with_exit_bindings + field mutation with Builder chain
  - Pattern3: 2 carriers (i + sum), exit_bindings, loop_var_name
  - Proper LoopExitBinding struct usage

- Task 201-3: Refactored Pattern4 to use Builder (continue/Trim support)
  - Replaced new_with_exit_bindings + field mutation with Builder chain
  - Pattern4: Dynamic carrier count, proper boundary construction

- Task 201-4: Added unit tests for Pattern3/4 style boundaries
  - test_builder_pattern3_style: Two carriers, exit_bindings validation
  - test_builder_pattern4_style: Dynamic carrier count validation
  - Verified no field mutations remain (exit_binding.rs uses deprecated fields only)

- Task 201-5: Updated architecture docs and CURRENT_TASK
  - joinir-architecture-overview.md: Builder now applied to all patterns
  - CURRENT_TASK.md: Phase 201 completion entry

All patterns now use consistent boundary construction via Builder.
Tests: All patterns pass (挙動不変).
This commit is contained in:
nyash-codex
2025-12-08 06:14:03 +09:00
parent 891c39c67f
commit cbeab6abd7
8 changed files with 191 additions and 26 deletions

View File

@ -92,13 +92,16 @@ impl MirBuilder {
};
// Phase 33-22: Create boundary for JoinIR conversion
let mut boundary = crate::mir::join_ir::lowering::inline_boundary::JoinInlineBoundary::new_inputs_only(
vec![ValueId(0)], // JoinIR's main() parameter (loop variable)
vec![loop_var_id], // Host's loop variable
);
// Phase 33-16: Set loop_var_name to enable header PHI generation
// This is required for the merge pipeline to generate header PHIs for SSA correctness
boundary.loop_var_name = Some(loop_var_name.clone());
// Phase 201: Use JoinInlineBoundaryBuilder for clean construction
// Canonical Builder pattern - see docs/development/current/main/joinir-boundary-builder-pattern.md
use crate::mir::join_ir::lowering::JoinInlineBoundaryBuilder;
let boundary = JoinInlineBoundaryBuilder::new()
.with_inputs(
vec![ValueId(0)], // JoinIR's main() parameter (loop variable)
vec![loop_var_id], // Host's loop variable
)
.with_loop_var_name(Some(loop_var_name.clone())) // Phase 33-16: Enable header PHI generation for SSA correctness
.build();
// Phase 33-22: Use JoinIRConversionPipeline for unified conversion flow
use super::conversion_pipeline::JoinIRConversionPipeline;

View File

@ -329,6 +329,7 @@ impl MirBuilder {
let exit_bindings = ExitMetaCollector::collect(self, &exit_meta, debug);
// Phase 200-2: Use JoinInlineBoundaryBuilder for clean construction
// Canonical Builder pattern - see docs/development/current/main/joinir-boundary-builder-pattern.md
use crate::mir::join_ir::lowering::JoinInlineBoundaryBuilder;
let boundary = JoinInlineBoundaryBuilder::new()
.with_inputs(

View File

@ -100,24 +100,28 @@ impl MirBuilder {
};
// Phase 33-22: Create boundary for JoinIR conversion
// Phase 201: Use JoinInlineBoundaryBuilder for clean construction
// Canonical Builder pattern - see docs/development/current/main/joinir-boundary-builder-pattern.md
// Pattern 3 has TWO carriers: i and sum
self.trace_varmap("pattern3_before_merge");
let mut boundary = crate::mir::join_ir::lowering::inline_boundary::JoinInlineBoundary::new_with_exit_bindings(
vec![ValueId(0), ValueId(1)], // JoinIR's main() parameters (i, sum init)
vec![loop_var_id, sum_var_id], // Host's loop variables
vec![
use crate::mir::join_ir::lowering::JoinInlineBoundaryBuilder;
use crate::mir::join_ir::lowering::inline_boundary::LoopExitBinding;
let boundary = JoinInlineBoundaryBuilder::new()
.with_inputs(
vec![ValueId(0), ValueId(1)], // JoinIR's main() parameters (i, sum init)
vec![loop_var_id, sum_var_id], // Host's loop variables
)
.with_exit_bindings(vec![
// Phase 33-16: Only include non-loop-variable carriers in exit_bindings
// The loop variable is handled separately via boundary.loop_var_name
crate::mir::join_ir::lowering::inline_boundary::LoopExitBinding {
LoopExitBinding {
carrier_name: "sum".to_string(),
join_exit_value: ValueId(18), // k_exit's parameter (sum_final)
host_slot: sum_var_id, // variable_map["sum"]
}
],
);
// Phase 33-16: Set loop_var_name to enable header PHI generation
// This is required for the merge pipeline to generate header PHIs for SSA correctness
boundary.loop_var_name = Some(loop_var_name.clone());
])
.with_loop_var_name(Some(loop_var_name.clone())) // Phase 33-16: Enable header PHI generation for SSA correctness
.build();
// Phase 33-22: Use JoinIRConversionPipeline for unified conversion flow
use super::conversion_pipeline::JoinIRConversionPipeline;

View File

@ -358,13 +358,14 @@ impl MirBuilder {
&format!("join_inputs: {:?}", join_inputs.iter().map(|v| v.0).collect::<Vec<_>>())
);
let mut boundary = crate::mir::join_ir::lowering::inline_boundary::JoinInlineBoundary::new_with_exit_bindings(
join_inputs, // JoinIR's main() parameters (dynamic)
host_inputs, // Host's loop variables (dynamic)
exit_bindings,
);
// Phase 33-19: Set loop_var_name for proper exit PHI collection
boundary.loop_var_name = Some(loop_var_name.clone());
// Phase 201: Use JoinInlineBoundaryBuilder for clean construction
// Canonical Builder pattern - see docs/development/current/main/joinir-boundary-builder-pattern.md
use crate::mir::join_ir::lowering::JoinInlineBoundaryBuilder;
let boundary = JoinInlineBoundaryBuilder::new()
.with_inputs(join_inputs, host_inputs) // Dynamic carrier count
.with_exit_bindings(exit_bindings)
.with_loop_var_name(Some(loop_var_name.clone())) // Phase 33-19: Enable exit PHI collection
.build();
// Phase 33-22: Use JoinIRConversionPipeline for unified conversion flow
use super::conversion_pipeline::JoinIRConversionPipeline;