Files
hakorune/docs/development/current/main/phases/phase-256/README.md

442 lines
19 KiB
Markdown
Raw Normal View History

refactor(joinir): Phase 255 P2 - loop_invariants + var() unification + Phase 256 prep ## Task A: Loop Invariants Architecture (Option A - Boundary Extension) Introduced explicit loop_invariants concept for variables that are: - Used in loop body but never modified (e.g., substring needle in index_of) - Need header PHI (all iterations use same value) - Do NOT need exit PHI (not a LoopState) Implementation: - Added `loop_invariants: Vec<(String, ValueId)>` field to JoinInlineBoundary - Added `with_loop_invariants()` method to JoinInlineBoundaryBuilder - Modified Pattern 6 to use loop_invariants instead of ConditionOnly misuse * s (haystack) and ch (needle) now properly classified * exit_bindings simplified to only LoopState carriers - Extended LoopHeaderPhiBuilder to generate invariant PHIs * Entry PHI: from host * Latch PHI: self-reference (same value every iteration) - Updated instruction_rewriter to handle invariant latch incoming Files Modified: - src/mir/join_ir/lowering/inline_boundary.rs (structure + builder) - src/mir/join_ir/lowering/inline_boundary_builder.rs (builder method) - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/merge/loop_header_phi_builder.rs - src/mir/builder/control_flow/joinir/merge/mod.rs - src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs ## Task B: Code Quality - var() Helper Unification Created common module to eliminate var() duplication: - New module: src/mir/builder/control_flow/joinir/patterns/common/ - Centralized var() helper in ast_helpers.rs - Updated Pattern 6 and Pattern 2 to use common var() - Test code (5 occurrences) deferred to Phase 256+ per 80/20 rule Result: Eliminated 2 duplicate var() functions, 5 test occurrences remain Files Created: - src/mir/builder/control_flow/joinir/patterns/common/ast_helpers.rs - src/mir/builder/control_flow/joinir/patterns/common/mod.rs Files Modified: - src/mir/builder/control_flow/joinir/patterns/mod.rs - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/patterns/policies/balanced_depth_scan_policy.rs ## Task C: Documentation - PostLoopEarlyReturnPlan Usage Examples Enhanced post_loop_early_return_plan.rs with: - Architecture explanation (exit PHI usage prevents DCE) - Pattern 2 example (Less: balanced_depth_scan) - Pattern 6 example (NotEqual: index_of) - Builder defer decision: when 4+ patterns emerge, add builder Files Modified: - src/mir/builder/control_flow/joinir/patterns/policies/post_loop_early_return_plan.rs ## Task D: Phase 256 Preparation Analyzed next failure from smoke tests: - `StringUtils.split/2` with variable-step loop - Not constant step (i += len or similar) - Three implementation options identified Created Phase 256 README with: - Minimal reproduction code - Root cause analysis - Implementation options with trade-offs - Clear next steps Files Created: - docs/development/current/main/phases/phase-256/README.md ## Verification Results ✅ All tests passing: - pattern254_p0_index_of_vm.sh: PASS - No regression in Pattern 1-5 - Smoke test progresses past json_lint_vm to next failure ✅ Architecture achievements: - Semantic clarity: loop_invariants vs exit_bindings properly separated - ConditionOnly misuse eliminated - PHI generation correct for all carrier types - Code quality: var() duplication reduced - Next phase clearly defined ## Summary Phase 255 P2 achieves root-cause fix for multi-param loop support: - Boundary concept expanded (loop_invariants field) - Pattern 6 architecture corrected (no ConditionOnly misuse) - Code quality improved (var() centralized) - Next pattern (variable-step) is now the challenge ✨ Box-first principles maintained: clean separation, explicit roles, minimal coupling 🧠 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 23:48:49 +09:00
# Phase 256: StringUtils.split/2 Pattern Support
Status: Active
refactor(joinir): Phase 255 P2 - loop_invariants + var() unification + Phase 256 prep ## Task A: Loop Invariants Architecture (Option A - Boundary Extension) Introduced explicit loop_invariants concept for variables that are: - Used in loop body but never modified (e.g., substring needle in index_of) - Need header PHI (all iterations use same value) - Do NOT need exit PHI (not a LoopState) Implementation: - Added `loop_invariants: Vec<(String, ValueId)>` field to JoinInlineBoundary - Added `with_loop_invariants()` method to JoinInlineBoundaryBuilder - Modified Pattern 6 to use loop_invariants instead of ConditionOnly misuse * s (haystack) and ch (needle) now properly classified * exit_bindings simplified to only LoopState carriers - Extended LoopHeaderPhiBuilder to generate invariant PHIs * Entry PHI: from host * Latch PHI: self-reference (same value every iteration) - Updated instruction_rewriter to handle invariant latch incoming Files Modified: - src/mir/join_ir/lowering/inline_boundary.rs (structure + builder) - src/mir/join_ir/lowering/inline_boundary_builder.rs (builder method) - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/merge/loop_header_phi_builder.rs - src/mir/builder/control_flow/joinir/merge/mod.rs - src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs ## Task B: Code Quality - var() Helper Unification Created common module to eliminate var() duplication: - New module: src/mir/builder/control_flow/joinir/patterns/common/ - Centralized var() helper in ast_helpers.rs - Updated Pattern 6 and Pattern 2 to use common var() - Test code (5 occurrences) deferred to Phase 256+ per 80/20 rule Result: Eliminated 2 duplicate var() functions, 5 test occurrences remain Files Created: - src/mir/builder/control_flow/joinir/patterns/common/ast_helpers.rs - src/mir/builder/control_flow/joinir/patterns/common/mod.rs Files Modified: - src/mir/builder/control_flow/joinir/patterns/mod.rs - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/patterns/policies/balanced_depth_scan_policy.rs ## Task C: Documentation - PostLoopEarlyReturnPlan Usage Examples Enhanced post_loop_early_return_plan.rs with: - Architecture explanation (exit PHI usage prevents DCE) - Pattern 2 example (Less: balanced_depth_scan) - Pattern 6 example (NotEqual: index_of) - Builder defer decision: when 4+ patterns emerge, add builder Files Modified: - src/mir/builder/control_flow/joinir/patterns/policies/post_loop_early_return_plan.rs ## Task D: Phase 256 Preparation Analyzed next failure from smoke tests: - `StringUtils.split/2` with variable-step loop - Not constant step (i += len or similar) - Three implementation options identified Created Phase 256 README with: - Minimal reproduction code - Root cause analysis - Implementation options with trade-offs - Clear next steps Files Created: - docs/development/current/main/phases/phase-256/README.md ## Verification Results ✅ All tests passing: - pattern254_p0_index_of_vm.sh: PASS - No regression in Pattern 1-5 - Smoke test progresses past json_lint_vm to next failure ✅ Architecture achievements: - Semantic clarity: loop_invariants vs exit_bindings properly separated - ConditionOnly misuse eliminated - PHI generation correct for all carrier types - Code quality: var() duplication reduced - Next phase clearly defined ## Summary Phase 255 P2 achieves root-cause fix for multi-param loop support: - Boundary concept expanded (loop_invariants field) - Pattern 6 architecture corrected (no ConditionOnly misuse) - Code quality improved (var() centralized) - Next pattern (variable-step) is now the challenge ✨ Box-first principles maintained: clean separation, explicit roles, minimal coupling 🧠 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 23:48:49 +09:00
Scope: Loop pattern recognition for split/tokenization operations
Related:
- Phase 255 完了loop_invariants 導入、Pattern 6 完成)
- Phase 254 完了Pattern 6 index_of 実装)
## Current Status (SSOT)
- Current first FAIL: `StringUtils.split/2`MIR verification: “Value defined multiple times” + SSA undef
- Pattern6 は PASS 維持
- 直近の完了:
- P1.10: DCE が `jump_args` 参照を保持し、`instruction_spans` と同期するよう修正(回帰テスト追加)
- P1.7: SSA undef`%49/%67`根治continuation 関数名の SSOT 不一致)
- P1.6: pipeline contract checks を `run_all_pipeline_checks()` に集約
- 次の作業: P1.11merge 側の ExitLine/PHI/dominance を `--verify` で緑に戻す)
---
## Background (P0 Archive)
このセクションは初期の失敗詳細とP0設計の記録。現状の作業は上記の Current Status を参照。
### 失敗詳細
refactor(joinir): Phase 255 P2 - loop_invariants + var() unification + Phase 256 prep ## Task A: Loop Invariants Architecture (Option A - Boundary Extension) Introduced explicit loop_invariants concept for variables that are: - Used in loop body but never modified (e.g., substring needle in index_of) - Need header PHI (all iterations use same value) - Do NOT need exit PHI (not a LoopState) Implementation: - Added `loop_invariants: Vec<(String, ValueId)>` field to JoinInlineBoundary - Added `with_loop_invariants()` method to JoinInlineBoundaryBuilder - Modified Pattern 6 to use loop_invariants instead of ConditionOnly misuse * s (haystack) and ch (needle) now properly classified * exit_bindings simplified to only LoopState carriers - Extended LoopHeaderPhiBuilder to generate invariant PHIs * Entry PHI: from host * Latch PHI: self-reference (same value every iteration) - Updated instruction_rewriter to handle invariant latch incoming Files Modified: - src/mir/join_ir/lowering/inline_boundary.rs (structure + builder) - src/mir/join_ir/lowering/inline_boundary_builder.rs (builder method) - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/merge/loop_header_phi_builder.rs - src/mir/builder/control_flow/joinir/merge/mod.rs - src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs ## Task B: Code Quality - var() Helper Unification Created common module to eliminate var() duplication: - New module: src/mir/builder/control_flow/joinir/patterns/common/ - Centralized var() helper in ast_helpers.rs - Updated Pattern 6 and Pattern 2 to use common var() - Test code (5 occurrences) deferred to Phase 256+ per 80/20 rule Result: Eliminated 2 duplicate var() functions, 5 test occurrences remain Files Created: - src/mir/builder/control_flow/joinir/patterns/common/ast_helpers.rs - src/mir/builder/control_flow/joinir/patterns/common/mod.rs Files Modified: - src/mir/builder/control_flow/joinir/patterns/mod.rs - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/patterns/policies/balanced_depth_scan_policy.rs ## Task C: Documentation - PostLoopEarlyReturnPlan Usage Examples Enhanced post_loop_early_return_plan.rs with: - Architecture explanation (exit PHI usage prevents DCE) - Pattern 2 example (Less: balanced_depth_scan) - Pattern 6 example (NotEqual: index_of) - Builder defer decision: when 4+ patterns emerge, add builder Files Modified: - src/mir/builder/control_flow/joinir/patterns/policies/post_loop_early_return_plan.rs ## Task D: Phase 256 Preparation Analyzed next failure from smoke tests: - `StringUtils.split/2` with variable-step loop - Not constant step (i += len or similar) - Three implementation options identified Created Phase 256 README with: - Minimal reproduction code - Root cause analysis - Implementation options with trade-offs - Clear next steps Files Created: - docs/development/current/main/phases/phase-256/README.md ## Verification Results ✅ All tests passing: - pattern254_p0_index_of_vm.sh: PASS - No regression in Pattern 1-5 - Smoke test progresses past json_lint_vm to next failure ✅ Architecture achievements: - Semantic clarity: loop_invariants vs exit_bindings properly separated - ConditionOnly misuse eliminated - PHI generation correct for all carrier types - Code quality: var() duplication reduced - Next phase clearly defined ## Summary Phase 255 P2 achieves root-cause fix for multi-param loop support: - Boundary concept expanded (loop_invariants field) - Pattern 6 architecture corrected (no ConditionOnly misuse) - Code quality improved (var() centralized) - Next pattern (variable-step) is now the challenge ✨ Box-first principles maintained: clean separation, explicit roles, minimal coupling 🧠 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 23:48:49 +09:00
**テスト**: json_lint_vm (quick profile)
**エラー**: `[joinir/freeze] Loop lowering failed: JoinIR does not support this pattern`
**関数**: `StringUtils.split/2`
#### エラーメッセージ全体
refactor(joinir): Phase 255 P2 - loop_invariants + var() unification + Phase 256 prep ## Task A: Loop Invariants Architecture (Option A - Boundary Extension) Introduced explicit loop_invariants concept for variables that are: - Used in loop body but never modified (e.g., substring needle in index_of) - Need header PHI (all iterations use same value) - Do NOT need exit PHI (not a LoopState) Implementation: - Added `loop_invariants: Vec<(String, ValueId)>` field to JoinInlineBoundary - Added `with_loop_invariants()` method to JoinInlineBoundaryBuilder - Modified Pattern 6 to use loop_invariants instead of ConditionOnly misuse * s (haystack) and ch (needle) now properly classified * exit_bindings simplified to only LoopState carriers - Extended LoopHeaderPhiBuilder to generate invariant PHIs * Entry PHI: from host * Latch PHI: self-reference (same value every iteration) - Updated instruction_rewriter to handle invariant latch incoming Files Modified: - src/mir/join_ir/lowering/inline_boundary.rs (structure + builder) - src/mir/join_ir/lowering/inline_boundary_builder.rs (builder method) - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/merge/loop_header_phi_builder.rs - src/mir/builder/control_flow/joinir/merge/mod.rs - src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs ## Task B: Code Quality - var() Helper Unification Created common module to eliminate var() duplication: - New module: src/mir/builder/control_flow/joinir/patterns/common/ - Centralized var() helper in ast_helpers.rs - Updated Pattern 6 and Pattern 2 to use common var() - Test code (5 occurrences) deferred to Phase 256+ per 80/20 rule Result: Eliminated 2 duplicate var() functions, 5 test occurrences remain Files Created: - src/mir/builder/control_flow/joinir/patterns/common/ast_helpers.rs - src/mir/builder/control_flow/joinir/patterns/common/mod.rs Files Modified: - src/mir/builder/control_flow/joinir/patterns/mod.rs - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/patterns/policies/balanced_depth_scan_policy.rs ## Task C: Documentation - PostLoopEarlyReturnPlan Usage Examples Enhanced post_loop_early_return_plan.rs with: - Architecture explanation (exit PHI usage prevents DCE) - Pattern 2 example (Less: balanced_depth_scan) - Pattern 6 example (NotEqual: index_of) - Builder defer decision: when 4+ patterns emerge, add builder Files Modified: - src/mir/builder/control_flow/joinir/patterns/policies/post_loop_early_return_plan.rs ## Task D: Phase 256 Preparation Analyzed next failure from smoke tests: - `StringUtils.split/2` with variable-step loop - Not constant step (i += len or similar) - Three implementation options identified Created Phase 256 README with: - Minimal reproduction code - Root cause analysis - Implementation options with trade-offs - Clear next steps Files Created: - docs/development/current/main/phases/phase-256/README.md ## Verification Results ✅ All tests passing: - pattern254_p0_index_of_vm.sh: PASS - No regression in Pattern 1-5 - Smoke test progresses past json_lint_vm to next failure ✅ Architecture achievements: - Semantic clarity: loop_invariants vs exit_bindings properly separated - ConditionOnly misuse eliminated - PHI generation correct for all carrier types - Code quality: var() duplication reduced - Next phase clearly defined ## Summary Phase 255 P2 achieves root-cause fix for multi-param loop support: - Boundary concept expanded (loop_invariants field) - Pattern 6 architecture corrected (no ConditionOnly misuse) - Code quality improved (var() centralized) - Next pattern (variable-step) is now the challenge ✨ Box-first principles maintained: clean separation, explicit roles, minimal coupling 🧠 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 23:48:49 +09:00
```
[trace:dev] loop_canonicalizer: Decision: FAIL_FAST
[trace:dev] loop_canonicalizer: Missing caps: [ConstStep]
[trace:dev] loop_canonicalizer: Reason: Phase 143-P2: Loop does not match read_digits(loop(true)),
skip_whitespace, parse_number, continue, parse_string, or parse_array pattern
[ERROR] ❌ MIR compilation error: [joinir/freeze] Loop lowering failed: JoinIR does not support this pattern,
and LoopBuilder has been removed.
Function: StringUtils.split/2
Hint: This loop pattern is not supported. All loops must use JoinIR lowering.
```
### 期待される動作
refactor(joinir): Phase 255 P2 - loop_invariants + var() unification + Phase 256 prep ## Task A: Loop Invariants Architecture (Option A - Boundary Extension) Introduced explicit loop_invariants concept for variables that are: - Used in loop body but never modified (e.g., substring needle in index_of) - Need header PHI (all iterations use same value) - Do NOT need exit PHI (not a LoopState) Implementation: - Added `loop_invariants: Vec<(String, ValueId)>` field to JoinInlineBoundary - Added `with_loop_invariants()` method to JoinInlineBoundaryBuilder - Modified Pattern 6 to use loop_invariants instead of ConditionOnly misuse * s (haystack) and ch (needle) now properly classified * exit_bindings simplified to only LoopState carriers - Extended LoopHeaderPhiBuilder to generate invariant PHIs * Entry PHI: from host * Latch PHI: self-reference (same value every iteration) - Updated instruction_rewriter to handle invariant latch incoming Files Modified: - src/mir/join_ir/lowering/inline_boundary.rs (structure + builder) - src/mir/join_ir/lowering/inline_boundary_builder.rs (builder method) - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/merge/loop_header_phi_builder.rs - src/mir/builder/control_flow/joinir/merge/mod.rs - src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs ## Task B: Code Quality - var() Helper Unification Created common module to eliminate var() duplication: - New module: src/mir/builder/control_flow/joinir/patterns/common/ - Centralized var() helper in ast_helpers.rs - Updated Pattern 6 and Pattern 2 to use common var() - Test code (5 occurrences) deferred to Phase 256+ per 80/20 rule Result: Eliminated 2 duplicate var() functions, 5 test occurrences remain Files Created: - src/mir/builder/control_flow/joinir/patterns/common/ast_helpers.rs - src/mir/builder/control_flow/joinir/patterns/common/mod.rs Files Modified: - src/mir/builder/control_flow/joinir/patterns/mod.rs - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/patterns/policies/balanced_depth_scan_policy.rs ## Task C: Documentation - PostLoopEarlyReturnPlan Usage Examples Enhanced post_loop_early_return_plan.rs with: - Architecture explanation (exit PHI usage prevents DCE) - Pattern 2 example (Less: balanced_depth_scan) - Pattern 6 example (NotEqual: index_of) - Builder defer decision: when 4+ patterns emerge, add builder Files Modified: - src/mir/builder/control_flow/joinir/patterns/policies/post_loop_early_return_plan.rs ## Task D: Phase 256 Preparation Analyzed next failure from smoke tests: - `StringUtils.split/2` with variable-step loop - Not constant step (i += len or similar) - Three implementation options identified Created Phase 256 README with: - Minimal reproduction code - Root cause analysis - Implementation options with trade-offs - Clear next steps Files Created: - docs/development/current/main/phases/phase-256/README.md ## Verification Results ✅ All tests passing: - pattern254_p0_index_of_vm.sh: PASS - No regression in Pattern 1-5 - Smoke test progresses past json_lint_vm to next failure ✅ Architecture achievements: - Semantic clarity: loop_invariants vs exit_bindings properly separated - ConditionOnly misuse eliminated - PHI generation correct for all carrier types - Code quality: var() duplication reduced - Next phase clearly defined ## Summary Phase 255 P2 achieves root-cause fix for multi-param loop support: - Boundary concept expanded (loop_invariants field) - Pattern 6 architecture corrected (no ConditionOnly misuse) - Code quality improved (var() centralized) - Next pattern (variable-step) is now the challenge ✨ Box-first principles maintained: clean separation, explicit roles, minimal coupling 🧠 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 23:48:49 +09:00
`StringUtils.split(s, separator)` が正常にコンパイルされ、文字列分割が動作すること。
### 実際の動作
refactor(joinir): Phase 255 P2 - loop_invariants + var() unification + Phase 256 prep ## Task A: Loop Invariants Architecture (Option A - Boundary Extension) Introduced explicit loop_invariants concept for variables that are: - Used in loop body but never modified (e.g., substring needle in index_of) - Need header PHI (all iterations use same value) - Do NOT need exit PHI (not a LoopState) Implementation: - Added `loop_invariants: Vec<(String, ValueId)>` field to JoinInlineBoundary - Added `with_loop_invariants()` method to JoinInlineBoundaryBuilder - Modified Pattern 6 to use loop_invariants instead of ConditionOnly misuse * s (haystack) and ch (needle) now properly classified * exit_bindings simplified to only LoopState carriers - Extended LoopHeaderPhiBuilder to generate invariant PHIs * Entry PHI: from host * Latch PHI: self-reference (same value every iteration) - Updated instruction_rewriter to handle invariant latch incoming Files Modified: - src/mir/join_ir/lowering/inline_boundary.rs (structure + builder) - src/mir/join_ir/lowering/inline_boundary_builder.rs (builder method) - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/merge/loop_header_phi_builder.rs - src/mir/builder/control_flow/joinir/merge/mod.rs - src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs ## Task B: Code Quality - var() Helper Unification Created common module to eliminate var() duplication: - New module: src/mir/builder/control_flow/joinir/patterns/common/ - Centralized var() helper in ast_helpers.rs - Updated Pattern 6 and Pattern 2 to use common var() - Test code (5 occurrences) deferred to Phase 256+ per 80/20 rule Result: Eliminated 2 duplicate var() functions, 5 test occurrences remain Files Created: - src/mir/builder/control_flow/joinir/patterns/common/ast_helpers.rs - src/mir/builder/control_flow/joinir/patterns/common/mod.rs Files Modified: - src/mir/builder/control_flow/joinir/patterns/mod.rs - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/patterns/policies/balanced_depth_scan_policy.rs ## Task C: Documentation - PostLoopEarlyReturnPlan Usage Examples Enhanced post_loop_early_return_plan.rs with: - Architecture explanation (exit PHI usage prevents DCE) - Pattern 2 example (Less: balanced_depth_scan) - Pattern 6 example (NotEqual: index_of) - Builder defer decision: when 4+ patterns emerge, add builder Files Modified: - src/mir/builder/control_flow/joinir/patterns/policies/post_loop_early_return_plan.rs ## Task D: Phase 256 Preparation Analyzed next failure from smoke tests: - `StringUtils.split/2` with variable-step loop - Not constant step (i += len or similar) - Three implementation options identified Created Phase 256 README with: - Minimal reproduction code - Root cause analysis - Implementation options with trade-offs - Clear next steps Files Created: - docs/development/current/main/phases/phase-256/README.md ## Verification Results ✅ All tests passing: - pattern254_p0_index_of_vm.sh: PASS - No regression in Pattern 1-5 - Smoke test progresses past json_lint_vm to next failure ✅ Architecture achievements: - Semantic clarity: loop_invariants vs exit_bindings properly separated - ConditionOnly misuse eliminated - PHI generation correct for all carrier types - Code quality: var() duplication reduced - Next phase clearly defined ## Summary Phase 255 P2 achieves root-cause fix for multi-param loop support: - Boundary concept expanded (loop_invariants field) - Pattern 6 architecture corrected (no ConditionOnly misuse) - Code quality improved (var() centralized) - Next pattern (variable-step) is now the challenge ✨ Box-first principles maintained: clean separation, explicit roles, minimal coupling 🧠 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 23:48:49 +09:00
Loop canonicalizer が `ConstStep` を要求しているが、このループはステップが複雑で定数ではない。
### 最小再現コード
refactor(joinir): Phase 255 P2 - loop_invariants + var() unification + Phase 256 prep ## Task A: Loop Invariants Architecture (Option A - Boundary Extension) Introduced explicit loop_invariants concept for variables that are: - Used in loop body but never modified (e.g., substring needle in index_of) - Need header PHI (all iterations use same value) - Do NOT need exit PHI (not a LoopState) Implementation: - Added `loop_invariants: Vec<(String, ValueId)>` field to JoinInlineBoundary - Added `with_loop_invariants()` method to JoinInlineBoundaryBuilder - Modified Pattern 6 to use loop_invariants instead of ConditionOnly misuse * s (haystack) and ch (needle) now properly classified * exit_bindings simplified to only LoopState carriers - Extended LoopHeaderPhiBuilder to generate invariant PHIs * Entry PHI: from host * Latch PHI: self-reference (same value every iteration) - Updated instruction_rewriter to handle invariant latch incoming Files Modified: - src/mir/join_ir/lowering/inline_boundary.rs (structure + builder) - src/mir/join_ir/lowering/inline_boundary_builder.rs (builder method) - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/merge/loop_header_phi_builder.rs - src/mir/builder/control_flow/joinir/merge/mod.rs - src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs ## Task B: Code Quality - var() Helper Unification Created common module to eliminate var() duplication: - New module: src/mir/builder/control_flow/joinir/patterns/common/ - Centralized var() helper in ast_helpers.rs - Updated Pattern 6 and Pattern 2 to use common var() - Test code (5 occurrences) deferred to Phase 256+ per 80/20 rule Result: Eliminated 2 duplicate var() functions, 5 test occurrences remain Files Created: - src/mir/builder/control_flow/joinir/patterns/common/ast_helpers.rs - src/mir/builder/control_flow/joinir/patterns/common/mod.rs Files Modified: - src/mir/builder/control_flow/joinir/patterns/mod.rs - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/patterns/policies/balanced_depth_scan_policy.rs ## Task C: Documentation - PostLoopEarlyReturnPlan Usage Examples Enhanced post_loop_early_return_plan.rs with: - Architecture explanation (exit PHI usage prevents DCE) - Pattern 2 example (Less: balanced_depth_scan) - Pattern 6 example (NotEqual: index_of) - Builder defer decision: when 4+ patterns emerge, add builder Files Modified: - src/mir/builder/control_flow/joinir/patterns/policies/post_loop_early_return_plan.rs ## Task D: Phase 256 Preparation Analyzed next failure from smoke tests: - `StringUtils.split/2` with variable-step loop - Not constant step (i += len or similar) - Three implementation options identified Created Phase 256 README with: - Minimal reproduction code - Root cause analysis - Implementation options with trade-offs - Clear next steps Files Created: - docs/development/current/main/phases/phase-256/README.md ## Verification Results ✅ All tests passing: - pattern254_p0_index_of_vm.sh: PASS - No regression in Pattern 1-5 - Smoke test progresses past json_lint_vm to next failure ✅ Architecture achievements: - Semantic clarity: loop_invariants vs exit_bindings properly separated - ConditionOnly misuse eliminated - PHI generation correct for all carrier types - Code quality: var() duplication reduced - Next phase clearly defined ## Summary Phase 255 P2 achieves root-cause fix for multi-param loop support: - Boundary concept expanded (loop_invariants field) - Pattern 6 architecture corrected (no ConditionOnly misuse) - Code quality improved (var() centralized) - Next pattern (variable-step) is now the challenge ✨ Box-first principles maintained: clean separation, explicit roles, minimal coupling 🧠 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 23:48:49 +09:00
```nyash
split(s, separator) {
local result = new ArrayBox()
// Early return for empty separator
if separator.length() == 0 {
result.push(s)
return result
}
local start = 0
local i = 0
// Main scan loop
loop(i <= s.length() - separator.length()) {
if s.substring(i, i + separator.length()) == separator {
result.push(s.substring(start, i))
start = i + separator.length()
i = start // Variable step - moves by separator.length()
} else {
i = i + 1 // Constant step - moves by 1
}
}
// Push remaining segment
if start <= s.length() {
result.push(s.substring(start, s.length()))
}
return result
}
```
### 分析
refactor(joinir): Phase 255 P2 - loop_invariants + var() unification + Phase 256 prep ## Task A: Loop Invariants Architecture (Option A - Boundary Extension) Introduced explicit loop_invariants concept for variables that are: - Used in loop body but never modified (e.g., substring needle in index_of) - Need header PHI (all iterations use same value) - Do NOT need exit PHI (not a LoopState) Implementation: - Added `loop_invariants: Vec<(String, ValueId)>` field to JoinInlineBoundary - Added `with_loop_invariants()` method to JoinInlineBoundaryBuilder - Modified Pattern 6 to use loop_invariants instead of ConditionOnly misuse * s (haystack) and ch (needle) now properly classified * exit_bindings simplified to only LoopState carriers - Extended LoopHeaderPhiBuilder to generate invariant PHIs * Entry PHI: from host * Latch PHI: self-reference (same value every iteration) - Updated instruction_rewriter to handle invariant latch incoming Files Modified: - src/mir/join_ir/lowering/inline_boundary.rs (structure + builder) - src/mir/join_ir/lowering/inline_boundary_builder.rs (builder method) - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/merge/loop_header_phi_builder.rs - src/mir/builder/control_flow/joinir/merge/mod.rs - src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs ## Task B: Code Quality - var() Helper Unification Created common module to eliminate var() duplication: - New module: src/mir/builder/control_flow/joinir/patterns/common/ - Centralized var() helper in ast_helpers.rs - Updated Pattern 6 and Pattern 2 to use common var() - Test code (5 occurrences) deferred to Phase 256+ per 80/20 rule Result: Eliminated 2 duplicate var() functions, 5 test occurrences remain Files Created: - src/mir/builder/control_flow/joinir/patterns/common/ast_helpers.rs - src/mir/builder/control_flow/joinir/patterns/common/mod.rs Files Modified: - src/mir/builder/control_flow/joinir/patterns/mod.rs - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/patterns/policies/balanced_depth_scan_policy.rs ## Task C: Documentation - PostLoopEarlyReturnPlan Usage Examples Enhanced post_loop_early_return_plan.rs with: - Architecture explanation (exit PHI usage prevents DCE) - Pattern 2 example (Less: balanced_depth_scan) - Pattern 6 example (NotEqual: index_of) - Builder defer decision: when 4+ patterns emerge, add builder Files Modified: - src/mir/builder/control_flow/joinir/patterns/policies/post_loop_early_return_plan.rs ## Task D: Phase 256 Preparation Analyzed next failure from smoke tests: - `StringUtils.split/2` with variable-step loop - Not constant step (i += len or similar) - Three implementation options identified Created Phase 256 README with: - Minimal reproduction code - Root cause analysis - Implementation options with trade-offs - Clear next steps Files Created: - docs/development/current/main/phases/phase-256/README.md ## Verification Results ✅ All tests passing: - pattern254_p0_index_of_vm.sh: PASS - No regression in Pattern 1-5 - Smoke test progresses past json_lint_vm to next failure ✅ Architecture achievements: - Semantic clarity: loop_invariants vs exit_bindings properly separated - ConditionOnly misuse eliminated - PHI generation correct for all carrier types - Code quality: var() duplication reduced - Next phase clearly defined ## Summary Phase 255 P2 achieves root-cause fix for multi-param loop support: - Boundary concept expanded (loop_invariants field) - Pattern 6 architecture corrected (no ConditionOnly misuse) - Code quality improved (var() centralized) - Next pattern (variable-step) is now the challenge ✨ Box-first principles maintained: clean separation, explicit roles, minimal coupling 🧠 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 23:48:49 +09:00
#### ループ構造
refactor(joinir): Phase 255 P2 - loop_invariants + var() unification + Phase 256 prep ## Task A: Loop Invariants Architecture (Option A - Boundary Extension) Introduced explicit loop_invariants concept for variables that are: - Used in loop body but never modified (e.g., substring needle in index_of) - Need header PHI (all iterations use same value) - Do NOT need exit PHI (not a LoopState) Implementation: - Added `loop_invariants: Vec<(String, ValueId)>` field to JoinInlineBoundary - Added `with_loop_invariants()` method to JoinInlineBoundaryBuilder - Modified Pattern 6 to use loop_invariants instead of ConditionOnly misuse * s (haystack) and ch (needle) now properly classified * exit_bindings simplified to only LoopState carriers - Extended LoopHeaderPhiBuilder to generate invariant PHIs * Entry PHI: from host * Latch PHI: self-reference (same value every iteration) - Updated instruction_rewriter to handle invariant latch incoming Files Modified: - src/mir/join_ir/lowering/inline_boundary.rs (structure + builder) - src/mir/join_ir/lowering/inline_boundary_builder.rs (builder method) - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/merge/loop_header_phi_builder.rs - src/mir/builder/control_flow/joinir/merge/mod.rs - src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs ## Task B: Code Quality - var() Helper Unification Created common module to eliminate var() duplication: - New module: src/mir/builder/control_flow/joinir/patterns/common/ - Centralized var() helper in ast_helpers.rs - Updated Pattern 6 and Pattern 2 to use common var() - Test code (5 occurrences) deferred to Phase 256+ per 80/20 rule Result: Eliminated 2 duplicate var() functions, 5 test occurrences remain Files Created: - src/mir/builder/control_flow/joinir/patterns/common/ast_helpers.rs - src/mir/builder/control_flow/joinir/patterns/common/mod.rs Files Modified: - src/mir/builder/control_flow/joinir/patterns/mod.rs - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/patterns/policies/balanced_depth_scan_policy.rs ## Task C: Documentation - PostLoopEarlyReturnPlan Usage Examples Enhanced post_loop_early_return_plan.rs with: - Architecture explanation (exit PHI usage prevents DCE) - Pattern 2 example (Less: balanced_depth_scan) - Pattern 6 example (NotEqual: index_of) - Builder defer decision: when 4+ patterns emerge, add builder Files Modified: - src/mir/builder/control_flow/joinir/patterns/policies/post_loop_early_return_plan.rs ## Task D: Phase 256 Preparation Analyzed next failure from smoke tests: - `StringUtils.split/2` with variable-step loop - Not constant step (i += len or similar) - Three implementation options identified Created Phase 256 README with: - Minimal reproduction code - Root cause analysis - Implementation options with trade-offs - Clear next steps Files Created: - docs/development/current/main/phases/phase-256/README.md ## Verification Results ✅ All tests passing: - pattern254_p0_index_of_vm.sh: PASS - No regression in Pattern 1-5 - Smoke test progresses past json_lint_vm to next failure ✅ Architecture achievements: - Semantic clarity: loop_invariants vs exit_bindings properly separated - ConditionOnly misuse eliminated - PHI generation correct for all carrier types - Code quality: var() duplication reduced - Next phase clearly defined ## Summary Phase 255 P2 achieves root-cause fix for multi-param loop support: - Boundary concept expanded (loop_invariants field) - Pattern 6 architecture corrected (no ConditionOnly misuse) - Code quality improved (var() centralized) - Next pattern (variable-step) is now the challenge ✨ Box-first principles maintained: clean separation, explicit roles, minimal coupling 🧠 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 23:48:49 +09:00
1. **条件**: `i <= s.length() - separator.length()`
2. **ボディ**:
- If branch: マッチング検出時
- `result.push()` でセグメント追加
- `start = i + separator.length()` で次の開始位置更新
- `i = start` で大きくジャンプ(可変ステップ)
- Else branch: マッチなし
- `i = i + 1` で 1 進む(定数ステップ)
3. **特徴**:
- **可変ステップ**: マッチング時は `separator.length()` 分ジャンプ
- **複数キャリア**: `i`, `start`, `result` を更新
- **MethodCall**: `substring()`, `push()`, `length()` を使用
#### Canonicalizer の問題
refactor(joinir): Phase 255 P2 - loop_invariants + var() unification + Phase 256 prep ## Task A: Loop Invariants Architecture (Option A - Boundary Extension) Introduced explicit loop_invariants concept for variables that are: - Used in loop body but never modified (e.g., substring needle in index_of) - Need header PHI (all iterations use same value) - Do NOT need exit PHI (not a LoopState) Implementation: - Added `loop_invariants: Vec<(String, ValueId)>` field to JoinInlineBoundary - Added `with_loop_invariants()` method to JoinInlineBoundaryBuilder - Modified Pattern 6 to use loop_invariants instead of ConditionOnly misuse * s (haystack) and ch (needle) now properly classified * exit_bindings simplified to only LoopState carriers - Extended LoopHeaderPhiBuilder to generate invariant PHIs * Entry PHI: from host * Latch PHI: self-reference (same value every iteration) - Updated instruction_rewriter to handle invariant latch incoming Files Modified: - src/mir/join_ir/lowering/inline_boundary.rs (structure + builder) - src/mir/join_ir/lowering/inline_boundary_builder.rs (builder method) - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/merge/loop_header_phi_builder.rs - src/mir/builder/control_flow/joinir/merge/mod.rs - src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs ## Task B: Code Quality - var() Helper Unification Created common module to eliminate var() duplication: - New module: src/mir/builder/control_flow/joinir/patterns/common/ - Centralized var() helper in ast_helpers.rs - Updated Pattern 6 and Pattern 2 to use common var() - Test code (5 occurrences) deferred to Phase 256+ per 80/20 rule Result: Eliminated 2 duplicate var() functions, 5 test occurrences remain Files Created: - src/mir/builder/control_flow/joinir/patterns/common/ast_helpers.rs - src/mir/builder/control_flow/joinir/patterns/common/mod.rs Files Modified: - src/mir/builder/control_flow/joinir/patterns/mod.rs - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/patterns/policies/balanced_depth_scan_policy.rs ## Task C: Documentation - PostLoopEarlyReturnPlan Usage Examples Enhanced post_loop_early_return_plan.rs with: - Architecture explanation (exit PHI usage prevents DCE) - Pattern 2 example (Less: balanced_depth_scan) - Pattern 6 example (NotEqual: index_of) - Builder defer decision: when 4+ patterns emerge, add builder Files Modified: - src/mir/builder/control_flow/joinir/patterns/policies/post_loop_early_return_plan.rs ## Task D: Phase 256 Preparation Analyzed next failure from smoke tests: - `StringUtils.split/2` with variable-step loop - Not constant step (i += len or similar) - Three implementation options identified Created Phase 256 README with: - Minimal reproduction code - Root cause analysis - Implementation options with trade-offs - Clear next steps Files Created: - docs/development/current/main/phases/phase-256/README.md ## Verification Results ✅ All tests passing: - pattern254_p0_index_of_vm.sh: PASS - No regression in Pattern 1-5 - Smoke test progresses past json_lint_vm to next failure ✅ Architecture achievements: - Semantic clarity: loop_invariants vs exit_bindings properly separated - ConditionOnly misuse eliminated - PHI generation correct for all carrier types - Code quality: var() duplication reduced - Next phase clearly defined ## Summary Phase 255 P2 achieves root-cause fix for multi-param loop support: - Boundary concept expanded (loop_invariants field) - Pattern 6 architecture corrected (no ConditionOnly misuse) - Code quality improved (var() centralized) - Next pattern (variable-step) is now the challenge ✨ Box-first principles maintained: clean separation, explicit roles, minimal coupling 🧠 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 23:48:49 +09:00
```
Missing caps: [ConstStep]
```
- 既存の Pattern 1-6 は定数ステップを想定
- このループは条件分岐で異なるステップ幅を使う
- Pattern 2 (balanced_depth_scan) に近いが、可変ステップがネック
### 実装計画
refactor(joinir): Phase 255 P2 - loop_invariants + var() unification + Phase 256 prep ## Task A: Loop Invariants Architecture (Option A - Boundary Extension) Introduced explicit loop_invariants concept for variables that are: - Used in loop body but never modified (e.g., substring needle in index_of) - Need header PHI (all iterations use same value) - Do NOT need exit PHI (not a LoopState) Implementation: - Added `loop_invariants: Vec<(String, ValueId)>` field to JoinInlineBoundary - Added `with_loop_invariants()` method to JoinInlineBoundaryBuilder - Modified Pattern 6 to use loop_invariants instead of ConditionOnly misuse * s (haystack) and ch (needle) now properly classified * exit_bindings simplified to only LoopState carriers - Extended LoopHeaderPhiBuilder to generate invariant PHIs * Entry PHI: from host * Latch PHI: self-reference (same value every iteration) - Updated instruction_rewriter to handle invariant latch incoming Files Modified: - src/mir/join_ir/lowering/inline_boundary.rs (structure + builder) - src/mir/join_ir/lowering/inline_boundary_builder.rs (builder method) - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/merge/loop_header_phi_builder.rs - src/mir/builder/control_flow/joinir/merge/mod.rs - src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs ## Task B: Code Quality - var() Helper Unification Created common module to eliminate var() duplication: - New module: src/mir/builder/control_flow/joinir/patterns/common/ - Centralized var() helper in ast_helpers.rs - Updated Pattern 6 and Pattern 2 to use common var() - Test code (5 occurrences) deferred to Phase 256+ per 80/20 rule Result: Eliminated 2 duplicate var() functions, 5 test occurrences remain Files Created: - src/mir/builder/control_flow/joinir/patterns/common/ast_helpers.rs - src/mir/builder/control_flow/joinir/patterns/common/mod.rs Files Modified: - src/mir/builder/control_flow/joinir/patterns/mod.rs - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/patterns/policies/balanced_depth_scan_policy.rs ## Task C: Documentation - PostLoopEarlyReturnPlan Usage Examples Enhanced post_loop_early_return_plan.rs with: - Architecture explanation (exit PHI usage prevents DCE) - Pattern 2 example (Less: balanced_depth_scan) - Pattern 6 example (NotEqual: index_of) - Builder defer decision: when 4+ patterns emerge, add builder Files Modified: - src/mir/builder/control_flow/joinir/patterns/policies/post_loop_early_return_plan.rs ## Task D: Phase 256 Preparation Analyzed next failure from smoke tests: - `StringUtils.split/2` with variable-step loop - Not constant step (i += len or similar) - Three implementation options identified Created Phase 256 README with: - Minimal reproduction code - Root cause analysis - Implementation options with trade-offs - Clear next steps Files Created: - docs/development/current/main/phases/phase-256/README.md ## Verification Results ✅ All tests passing: - pattern254_p0_index_of_vm.sh: PASS - No regression in Pattern 1-5 - Smoke test progresses past json_lint_vm to next failure ✅ Architecture achievements: - Semantic clarity: loop_invariants vs exit_bindings properly separated - ConditionOnly misuse eliminated - PHI generation correct for all carrier types - Code quality: var() duplication reduced - Next phase clearly defined ## Summary Phase 255 P2 achieves root-cause fix for multi-param loop support: - Boundary concept expanded (loop_invariants field) - Pattern 6 architecture corrected (no ConditionOnly misuse) - Code quality improved (var() centralized) - Next pattern (variable-step) is now the challenge ✨ Box-first principles maintained: clean separation, explicit roles, minimal coupling 🧠 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 23:48:49 +09:00
#### Option A: Pattern 7 - Split/Tokenization Pattern
refactor(joinir): Phase 255 P2 - loop_invariants + var() unification + Phase 256 prep ## Task A: Loop Invariants Architecture (Option A - Boundary Extension) Introduced explicit loop_invariants concept for variables that are: - Used in loop body but never modified (e.g., substring needle in index_of) - Need header PHI (all iterations use same value) - Do NOT need exit PHI (not a LoopState) Implementation: - Added `loop_invariants: Vec<(String, ValueId)>` field to JoinInlineBoundary - Added `with_loop_invariants()` method to JoinInlineBoundaryBuilder - Modified Pattern 6 to use loop_invariants instead of ConditionOnly misuse * s (haystack) and ch (needle) now properly classified * exit_bindings simplified to only LoopState carriers - Extended LoopHeaderPhiBuilder to generate invariant PHIs * Entry PHI: from host * Latch PHI: self-reference (same value every iteration) - Updated instruction_rewriter to handle invariant latch incoming Files Modified: - src/mir/join_ir/lowering/inline_boundary.rs (structure + builder) - src/mir/join_ir/lowering/inline_boundary_builder.rs (builder method) - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/merge/loop_header_phi_builder.rs - src/mir/builder/control_flow/joinir/merge/mod.rs - src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs ## Task B: Code Quality - var() Helper Unification Created common module to eliminate var() duplication: - New module: src/mir/builder/control_flow/joinir/patterns/common/ - Centralized var() helper in ast_helpers.rs - Updated Pattern 6 and Pattern 2 to use common var() - Test code (5 occurrences) deferred to Phase 256+ per 80/20 rule Result: Eliminated 2 duplicate var() functions, 5 test occurrences remain Files Created: - src/mir/builder/control_flow/joinir/patterns/common/ast_helpers.rs - src/mir/builder/control_flow/joinir/patterns/common/mod.rs Files Modified: - src/mir/builder/control_flow/joinir/patterns/mod.rs - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/patterns/policies/balanced_depth_scan_policy.rs ## Task C: Documentation - PostLoopEarlyReturnPlan Usage Examples Enhanced post_loop_early_return_plan.rs with: - Architecture explanation (exit PHI usage prevents DCE) - Pattern 2 example (Less: balanced_depth_scan) - Pattern 6 example (NotEqual: index_of) - Builder defer decision: when 4+ patterns emerge, add builder Files Modified: - src/mir/builder/control_flow/joinir/patterns/policies/post_loop_early_return_plan.rs ## Task D: Phase 256 Preparation Analyzed next failure from smoke tests: - `StringUtils.split/2` with variable-step loop - Not constant step (i += len or similar) - Three implementation options identified Created Phase 256 README with: - Minimal reproduction code - Root cause analysis - Implementation options with trade-offs - Clear next steps Files Created: - docs/development/current/main/phases/phase-256/README.md ## Verification Results ✅ All tests passing: - pattern254_p0_index_of_vm.sh: PASS - No regression in Pattern 1-5 - Smoke test progresses past json_lint_vm to next failure ✅ Architecture achievements: - Semantic clarity: loop_invariants vs exit_bindings properly separated - ConditionOnly misuse eliminated - PHI generation correct for all carrier types - Code quality: var() duplication reduced - Next phase clearly defined ## Summary Phase 255 P2 achieves root-cause fix for multi-param loop support: - Boundary concept expanded (loop_invariants field) - Pattern 6 architecture corrected (no ConditionOnly misuse) - Code quality improved (var() centralized) - Next pattern (variable-step) is now the challenge ✨ Box-first principles maintained: clean separation, explicit roles, minimal coupling 🧠 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 23:48:49 +09:00
**新しいパターン追加**:
- 可変ステップサポート
- 複数キャリアi, start, accumulator
- If-else での異なるステップ幅処理
**検出条件**:
1. Loop condition: `i <= expr - len`
2. Body has if statement:
- Then: `i = something_big` (可変ジャンプ)
- Else: `i = i + 1` (定数ステップ)
3. Accumulator への追加操作 (`push` など)
#### Option B: Pattern 2 拡張
refactor(joinir): Phase 255 P2 - loop_invariants + var() unification + Phase 256 prep ## Task A: Loop Invariants Architecture (Option A - Boundary Extension) Introduced explicit loop_invariants concept for variables that are: - Used in loop body but never modified (e.g., substring needle in index_of) - Need header PHI (all iterations use same value) - Do NOT need exit PHI (not a LoopState) Implementation: - Added `loop_invariants: Vec<(String, ValueId)>` field to JoinInlineBoundary - Added `with_loop_invariants()` method to JoinInlineBoundaryBuilder - Modified Pattern 6 to use loop_invariants instead of ConditionOnly misuse * s (haystack) and ch (needle) now properly classified * exit_bindings simplified to only LoopState carriers - Extended LoopHeaderPhiBuilder to generate invariant PHIs * Entry PHI: from host * Latch PHI: self-reference (same value every iteration) - Updated instruction_rewriter to handle invariant latch incoming Files Modified: - src/mir/join_ir/lowering/inline_boundary.rs (structure + builder) - src/mir/join_ir/lowering/inline_boundary_builder.rs (builder method) - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/merge/loop_header_phi_builder.rs - src/mir/builder/control_flow/joinir/merge/mod.rs - src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs ## Task B: Code Quality - var() Helper Unification Created common module to eliminate var() duplication: - New module: src/mir/builder/control_flow/joinir/patterns/common/ - Centralized var() helper in ast_helpers.rs - Updated Pattern 6 and Pattern 2 to use common var() - Test code (5 occurrences) deferred to Phase 256+ per 80/20 rule Result: Eliminated 2 duplicate var() functions, 5 test occurrences remain Files Created: - src/mir/builder/control_flow/joinir/patterns/common/ast_helpers.rs - src/mir/builder/control_flow/joinir/patterns/common/mod.rs Files Modified: - src/mir/builder/control_flow/joinir/patterns/mod.rs - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/patterns/policies/balanced_depth_scan_policy.rs ## Task C: Documentation - PostLoopEarlyReturnPlan Usage Examples Enhanced post_loop_early_return_plan.rs with: - Architecture explanation (exit PHI usage prevents DCE) - Pattern 2 example (Less: balanced_depth_scan) - Pattern 6 example (NotEqual: index_of) - Builder defer decision: when 4+ patterns emerge, add builder Files Modified: - src/mir/builder/control_flow/joinir/patterns/policies/post_loop_early_return_plan.rs ## Task D: Phase 256 Preparation Analyzed next failure from smoke tests: - `StringUtils.split/2` with variable-step loop - Not constant step (i += len or similar) - Three implementation options identified Created Phase 256 README with: - Minimal reproduction code - Root cause analysis - Implementation options with trade-offs - Clear next steps Files Created: - docs/development/current/main/phases/phase-256/README.md ## Verification Results ✅ All tests passing: - pattern254_p0_index_of_vm.sh: PASS - No regression in Pattern 1-5 - Smoke test progresses past json_lint_vm to next failure ✅ Architecture achievements: - Semantic clarity: loop_invariants vs exit_bindings properly separated - ConditionOnly misuse eliminated - PHI generation correct for all carrier types - Code quality: var() duplication reduced - Next phase clearly defined ## Summary Phase 255 P2 achieves root-cause fix for multi-param loop support: - Boundary concept expanded (loop_invariants field) - Pattern 6 architecture corrected (no ConditionOnly misuse) - Code quality improved (var() centralized) - Next pattern (variable-step) is now the challenge ✨ Box-first principles maintained: clean separation, explicit roles, minimal coupling 🧠 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 23:48:49 +09:00
**既存 Pattern 2 を拡張**:
- ConstStep 要件を緩和
- If-else で異なるステップ幅を許可
- balanced_depth_scan_policy を拡張
#### Option C: Normalization 経路
refactor(joinir): Phase 255 P2 - loop_invariants + var() unification + Phase 256 prep ## Task A: Loop Invariants Architecture (Option A - Boundary Extension) Introduced explicit loop_invariants concept for variables that are: - Used in loop body but never modified (e.g., substring needle in index_of) - Need header PHI (all iterations use same value) - Do NOT need exit PHI (not a LoopState) Implementation: - Added `loop_invariants: Vec<(String, ValueId)>` field to JoinInlineBoundary - Added `with_loop_invariants()` method to JoinInlineBoundaryBuilder - Modified Pattern 6 to use loop_invariants instead of ConditionOnly misuse * s (haystack) and ch (needle) now properly classified * exit_bindings simplified to only LoopState carriers - Extended LoopHeaderPhiBuilder to generate invariant PHIs * Entry PHI: from host * Latch PHI: self-reference (same value every iteration) - Updated instruction_rewriter to handle invariant latch incoming Files Modified: - src/mir/join_ir/lowering/inline_boundary.rs (structure + builder) - src/mir/join_ir/lowering/inline_boundary_builder.rs (builder method) - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/merge/loop_header_phi_builder.rs - src/mir/builder/control_flow/joinir/merge/mod.rs - src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs ## Task B: Code Quality - var() Helper Unification Created common module to eliminate var() duplication: - New module: src/mir/builder/control_flow/joinir/patterns/common/ - Centralized var() helper in ast_helpers.rs - Updated Pattern 6 and Pattern 2 to use common var() - Test code (5 occurrences) deferred to Phase 256+ per 80/20 rule Result: Eliminated 2 duplicate var() functions, 5 test occurrences remain Files Created: - src/mir/builder/control_flow/joinir/patterns/common/ast_helpers.rs - src/mir/builder/control_flow/joinir/patterns/common/mod.rs Files Modified: - src/mir/builder/control_flow/joinir/patterns/mod.rs - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/patterns/policies/balanced_depth_scan_policy.rs ## Task C: Documentation - PostLoopEarlyReturnPlan Usage Examples Enhanced post_loop_early_return_plan.rs with: - Architecture explanation (exit PHI usage prevents DCE) - Pattern 2 example (Less: balanced_depth_scan) - Pattern 6 example (NotEqual: index_of) - Builder defer decision: when 4+ patterns emerge, add builder Files Modified: - src/mir/builder/control_flow/joinir/patterns/policies/post_loop_early_return_plan.rs ## Task D: Phase 256 Preparation Analyzed next failure from smoke tests: - `StringUtils.split/2` with variable-step loop - Not constant step (i += len or similar) - Three implementation options identified Created Phase 256 README with: - Minimal reproduction code - Root cause analysis - Implementation options with trade-offs - Clear next steps Files Created: - docs/development/current/main/phases/phase-256/README.md ## Verification Results ✅ All tests passing: - pattern254_p0_index_of_vm.sh: PASS - No regression in Pattern 1-5 - Smoke test progresses past json_lint_vm to next failure ✅ Architecture achievements: - Semantic clarity: loop_invariants vs exit_bindings properly separated - ConditionOnly misuse eliminated - PHI generation correct for all carrier types - Code quality: var() duplication reduced - Next phase clearly defined ## Summary Phase 255 P2 achieves root-cause fix for multi-param loop support: - Boundary concept expanded (loop_invariants field) - Pattern 6 architecture corrected (no ConditionOnly misuse) - Code quality improved (var() centralized) - Next pattern (variable-step) is now the challenge ✨ Box-first principles maintained: clean separation, explicit roles, minimal coupling 🧠 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 23:48:49 +09:00
**ループ正規化で対応**:
- 可変ステップを定数ステップに変換
- Carrier 追加で状態管理
### 次のステップP0時点の初期計画
refactor(joinir): Phase 255 P2 - loop_invariants + var() unification + Phase 256 prep ## Task A: Loop Invariants Architecture (Option A - Boundary Extension) Introduced explicit loop_invariants concept for variables that are: - Used in loop body but never modified (e.g., substring needle in index_of) - Need header PHI (all iterations use same value) - Do NOT need exit PHI (not a LoopState) Implementation: - Added `loop_invariants: Vec<(String, ValueId)>` field to JoinInlineBoundary - Added `with_loop_invariants()` method to JoinInlineBoundaryBuilder - Modified Pattern 6 to use loop_invariants instead of ConditionOnly misuse * s (haystack) and ch (needle) now properly classified * exit_bindings simplified to only LoopState carriers - Extended LoopHeaderPhiBuilder to generate invariant PHIs * Entry PHI: from host * Latch PHI: self-reference (same value every iteration) - Updated instruction_rewriter to handle invariant latch incoming Files Modified: - src/mir/join_ir/lowering/inline_boundary.rs (structure + builder) - src/mir/join_ir/lowering/inline_boundary_builder.rs (builder method) - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/merge/loop_header_phi_builder.rs - src/mir/builder/control_flow/joinir/merge/mod.rs - src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs ## Task B: Code Quality - var() Helper Unification Created common module to eliminate var() duplication: - New module: src/mir/builder/control_flow/joinir/patterns/common/ - Centralized var() helper in ast_helpers.rs - Updated Pattern 6 and Pattern 2 to use common var() - Test code (5 occurrences) deferred to Phase 256+ per 80/20 rule Result: Eliminated 2 duplicate var() functions, 5 test occurrences remain Files Created: - src/mir/builder/control_flow/joinir/patterns/common/ast_helpers.rs - src/mir/builder/control_flow/joinir/patterns/common/mod.rs Files Modified: - src/mir/builder/control_flow/joinir/patterns/mod.rs - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/patterns/policies/balanced_depth_scan_policy.rs ## Task C: Documentation - PostLoopEarlyReturnPlan Usage Examples Enhanced post_loop_early_return_plan.rs with: - Architecture explanation (exit PHI usage prevents DCE) - Pattern 2 example (Less: balanced_depth_scan) - Pattern 6 example (NotEqual: index_of) - Builder defer decision: when 4+ patterns emerge, add builder Files Modified: - src/mir/builder/control_flow/joinir/patterns/policies/post_loop_early_return_plan.rs ## Task D: Phase 256 Preparation Analyzed next failure from smoke tests: - `StringUtils.split/2` with variable-step loop - Not constant step (i += len or similar) - Three implementation options identified Created Phase 256 README with: - Minimal reproduction code - Root cause analysis - Implementation options with trade-offs - Clear next steps Files Created: - docs/development/current/main/phases/phase-256/README.md ## Verification Results ✅ All tests passing: - pattern254_p0_index_of_vm.sh: PASS - No regression in Pattern 1-5 - Smoke test progresses past json_lint_vm to next failure ✅ Architecture achievements: - Semantic clarity: loop_invariants vs exit_bindings properly separated - ConditionOnly misuse eliminated - PHI generation correct for all carrier types - Code quality: var() duplication reduced - Next phase clearly defined ## Summary Phase 255 P2 achieves root-cause fix for multi-param loop support: - Boundary concept expanded (loop_invariants field) - Pattern 6 architecture corrected (no ConditionOnly misuse) - Code quality improved (var() centralized) - Next pattern (variable-step) is now the challenge ✨ Box-first principles maintained: clean separation, explicit roles, minimal coupling 🧠 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 23:48:49 +09:00
1. **StepTree 詳細解析**: split ループの完全な AST 構造確認
2. **類似パターン調査**: 他の可変ステップループindexOf, contains など)
3. **Option 選択**: Pattern 7 新設 vs Pattern 2 拡張 vs Normalization
4. **実装戦略策定**: 選択した Option の詳細設計
---
## Phase 256 指示書P0 / 完了済み)
### 目標
- `StringUtils.split/2` の loop を JoinIR で受理し、`json_lint_vm` を PASS に戻す。
- by-name 分岐禁止(`StringUtils.split/2` だけを特別扱いしない)。
- workaround 禁止fallback は作らない)。
### 推奨方針P0
Option APattern 7 新設)を推奨。
理由:
- 可変 stepthen: `i = start` / else: `i = i + 1`)は既存の ConstStep 前提と相性が悪い。
- Pattern 2 を膨らませず、tokenization 系の “専用パターン” として箱化した方が責務が綺麗。
### P0 タスク
1) 最小 fixture + v2 smokeintegration
- `apps/tests/phase256_p0_split_min.hako`
- `tools/smokes/v2/profiles/integration/apps/phase256_p0_split_vm.sh`
- `tools/smokes/v2/profiles/integration/apps/phase256_p0_split_llvm_exe.sh`
2) DetectorBox構造のみ
- ループ条件が `i <= s.length() - sep.length()`
- body に `if substring(i, i + sep.length()) == sep { ... i = start } else { i = i + 1 }`
- `result.push(...)` を含むArrayBox accumulator
- ループ後に “残り push” がある(任意だがあると精度が上がる)
3) 抽出箱Parts
- `i` / `start` / `result` / `s` / `separator` を抽出
- then/else の更新式(可変 step と const stepを抽出
4) JoinIR lowerer専用
- loop_state: `i`, `start`
- invariants: `s`, `separator`, `result`result は更新されるので carrier 扱いが必要なら role を明確に)
- then/else で異なる `i_next``Select` もしくは branch で表現(設計 SSOT は JoinIR 側で決める)
5) 検証
- integration smokes 2本が PASS
- `./tools/smokes/v2/run.sh --profile quick` の最初の FAIL が次へ進む
### 注意P0ではやらない
- 既存 Pattern の大改造Pattern 2 の全面拡張)は避ける
- 正規化Normalization 経路)は P1 以降の検討に回す
refactor(joinir): Phase 255 P2 - loop_invariants + var() unification + Phase 256 prep ## Task A: Loop Invariants Architecture (Option A - Boundary Extension) Introduced explicit loop_invariants concept for variables that are: - Used in loop body but never modified (e.g., substring needle in index_of) - Need header PHI (all iterations use same value) - Do NOT need exit PHI (not a LoopState) Implementation: - Added `loop_invariants: Vec<(String, ValueId)>` field to JoinInlineBoundary - Added `with_loop_invariants()` method to JoinInlineBoundaryBuilder - Modified Pattern 6 to use loop_invariants instead of ConditionOnly misuse * s (haystack) and ch (needle) now properly classified * exit_bindings simplified to only LoopState carriers - Extended LoopHeaderPhiBuilder to generate invariant PHIs * Entry PHI: from host * Latch PHI: self-reference (same value every iteration) - Updated instruction_rewriter to handle invariant latch incoming Files Modified: - src/mir/join_ir/lowering/inline_boundary.rs (structure + builder) - src/mir/join_ir/lowering/inline_boundary_builder.rs (builder method) - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/merge/loop_header_phi_builder.rs - src/mir/builder/control_flow/joinir/merge/mod.rs - src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs ## Task B: Code Quality - var() Helper Unification Created common module to eliminate var() duplication: - New module: src/mir/builder/control_flow/joinir/patterns/common/ - Centralized var() helper in ast_helpers.rs - Updated Pattern 6 and Pattern 2 to use common var() - Test code (5 occurrences) deferred to Phase 256+ per 80/20 rule Result: Eliminated 2 duplicate var() functions, 5 test occurrences remain Files Created: - src/mir/builder/control_flow/joinir/patterns/common/ast_helpers.rs - src/mir/builder/control_flow/joinir/patterns/common/mod.rs Files Modified: - src/mir/builder/control_flow/joinir/patterns/mod.rs - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/builder/control_flow/joinir/patterns/policies/balanced_depth_scan_policy.rs ## Task C: Documentation - PostLoopEarlyReturnPlan Usage Examples Enhanced post_loop_early_return_plan.rs with: - Architecture explanation (exit PHI usage prevents DCE) - Pattern 2 example (Less: balanced_depth_scan) - Pattern 6 example (NotEqual: index_of) - Builder defer decision: when 4+ patterns emerge, add builder Files Modified: - src/mir/builder/control_flow/joinir/patterns/policies/post_loop_early_return_plan.rs ## Task D: Phase 256 Preparation Analyzed next failure from smoke tests: - `StringUtils.split/2` with variable-step loop - Not constant step (i += len or similar) - Three implementation options identified Created Phase 256 README with: - Minimal reproduction code - Root cause analysis - Implementation options with trade-offs - Clear next steps Files Created: - docs/development/current/main/phases/phase-256/README.md ## Verification Results ✅ All tests passing: - pattern254_p0_index_of_vm.sh: PASS - No regression in Pattern 1-5 - Smoke test progresses past json_lint_vm to next failure ✅ Architecture achievements: - Semantic clarity: loop_invariants vs exit_bindings properly separated - ConditionOnly misuse eliminated - PHI generation correct for all carrier types - Code quality: var() duplication reduced - Next phase clearly defined ## Summary Phase 255 P2 achieves root-cause fix for multi-param loop support: - Boundary concept expanded (loop_invariants field) - Pattern 6 architecture corrected (no ConditionOnly misuse) - Code quality improved (var() centralized) - Next pattern (variable-step) is now the challenge ✨ Box-first principles maintained: clean separation, explicit roles, minimal coupling 🧠 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 23:48:49 +09:00
## 備考
- Phase 255 で loop_invariants が導入されたが、このケースは invariants 以前の問題(可変ステップ)
- Phase 254-256 の流れで Pattern 6 → Pattern 7 の自然な進化が期待される
- split/tokenization は一般的なパターンなので、汎用的な解決策が望ましい
---
## 進捗P0/P1
### P0: Pattern 7 基本実装(完了)
- Fixture & smokesintegration:
- `apps/tests/phase256_p0_split_min.hako`
- `tools/smokes/v2/profiles/integration/apps/phase256_p0_split_vm.sh`
- `tools/smokes/v2/profiles/integration/apps/phase256_p0_split_llvm_exe.sh`
- Pattern 7:
- Detector / Extractor / JoinIR lowerer / MirBuilder 統合まで実装
- JoinIR lowerer は可変 step を `JoinInst::Select` で表現
### P1: Carrier/param 配線の整流(完了)
- “Carriers-first” の順序を SSOT として固定し、latch incoming 不足を解消
- exit bindings を明示的に構築(`i`, `start`
### P1.5: JoinIR→MIR 変換の根治(進行中)
背景:
- Pattern 7 は `JoinInst::Select` を使用するが、JoinIR→MIR 変換経路で Select が未対応だったため、
“dst が定義されない ValueId” が発生し得る。
対応(完了):
- boundary の伝播を bridge 経路全体へ追加
- `MirInstruction::Select` の追加、および JoinIR→MIR 変換 / remap / value collection を実装
現状(ブロッカー):
- integration VM が still FAIL:
- `use of undefined value ValueId(57)``StringUtils.split/2`
#### 追加の事実2025-12-20
- Pattern 6index_of回帰: PASSSelect 導入後もインフラは健全)
- `ValueId(57)` の正体:
- JoinIR `ValueId(1004)` の remap 先JoinIR→Host の remap は成功している)
- `sep_len = sep.length()` のローカル値loop_step 内で `BoxCall("length")` で定義される想定)
- つまり「remap の欠落」ではなく、「定義命令dst を持つ BoxCallが MIR に落ちていない/順序が壊れている」問題が濃厚
#### 次P1.5 Task 3: sep_len 定義トレースSSOT
目的: `sep_len` の「定義dst」が MIR に存在し、かつ use より前に配置されることを確認し、欠落しているなら根治する。
1) MIR ダンプで「%57 の定義があるか」を確認
- `./target/release/hakorune --backend vm --dump-mir --mir-verbose apps/tests/phase256_p0_split_min.hako > /tmp/split.mir`
- `rg -n \"\\bValueId\\(57\\)\\b|%57\" /tmp/split.mir`
- 期待: `BoxCall` かそれに相当する命令で `dst=%57` が use より前に出る
2) 定義が無い場合: JoinIR→MIR converter を疑う
- `JoinInst::Compute(MirLikeInst::BoxCall { dst: Some(sep_len), method: \"length\", .. })`
`MirInstruction::BoxCall { dst: Some(remapped), .. }` として出力されているかを点検する
- もし `dst: None` になっている命令自体が落ちているなら、converter か value-collector の取りこぼしを修正する
3) 定義があるが use より後の場合: ブロック内の命令順の生成/マージ規約を疑う
- joinir→mir の「生成順」か merge の「挿入位置」がおかしい
- 期待: “def-before-use” が各 BasicBlock 内で成立する
4) 受け入れ基準P1.5
- `tools/smokes/v2/profiles/integration/apps/phase256_p0_split_vm.sh` が PASS
- `tools/smokes/v2/profiles/integration/apps/phase256_p0_split_llvm_exe.sh` が PASS
- 既存: `tools/smokes/v2/profiles/integration/apps/phase254_p0_index_of_vm.sh` が PASS 維持
#### 診断アップデート2025-12-20
`ValueId(57)`= `sep_len`について、Step 2 の結果で「Case A」が確定した:
- JoinIR には定義が存在する:
- `JoinInst::Compute(MirLikeInst::BoxCall { dst: Some(sep_len), method: "length", args: [sep] })`
- しかし最終 MIR`--dump-mir`)には `%57 = ...` 相当の def が存在しないuse のみ)
- remap 自体は成功している:
- JoinIR `ValueId(1004)` → Host `ValueId(57)`
結論:
- 「remap が壊れている」ではなく、
**`JoinInst::Compute(MirLikeInst::BoxCall)` が JoinIR→MIR 変換/マージ経路のどこかで落ちている**。
次の実装タスクP1.5 Task 3.1:
- JoinIR→MIR の中間生成物bridge 側の MirModuleをダンプして、
- `dst: Some(1004)``MirInstruction::BoxCall` が生成されているか(生成されていないなら converter バグ)
- 生成されているのに最終 MIR から消えるなら merge/DCE バグ
を二分探索で確定する。
#### Task 3.1 結果2025-12-20
`ValueId(57)` undefined は根治できたdef-before-use 不変条件が回復)。
- 最終原因:
- `split_scan_minimal.rs` 内で `const_1``JoinValueSpace` のローカル ValueId**初期化されないまま** `i + const_1` に使用されていた。
- これが remap 後に `ValueId(57)` となり、最終 MIR で「use のみ / def が無い」になっていた。
- 修正:
- `const_1 = 1``JoinInst::Compute(MirLikeInst::Const { .. })` で use より前に挿入。
- 付随:
- bridge 生成物 MirModule を `/tmp/joinir_bridge_split.mir` へダンプできるようにした(`HAKO_JOINIR_DEBUG=1` ガード)。
⚠️ 注記:
- これにより「ValueId(57) = sep_len」仮説は撤回する。
- 以降は、各ローカル ValueId の意味は **bridge dump / join module dump を SSOT** として確定すること。
#### 次のブロッカーP1.5 Task 3.2
`ValueId(57)` は直ったが、Pattern7(split) はまだ PASS していない。新たに以下が露出:
- SSA:
- `Undefined value %49 used in block bb10`
- `Undefined value %67 used in block bb10`
- 型:
- `unsupported compare Le on BoxRef(ArrayBox) and Integer(...)`
次のタスクP1.5 Task 3.2:
- まず `--verify``--dump-mir`**%49 / %67 が何の値で、どの命令で定義されるべきか**を確定し、
- (A) joinir lowerer が def を吐いていないのか
- (B) bridge が落としているのか
- (C) merge/optimizer が落としているのか
を二分探索する。
#### 追記P1.7完了後)
- SSA undef`%49/%67`)は P1.7 で根治済み
- 現在の first FAIL は carrier PHI 配線へ移動:
- `[joinir/exit-line] jump_args length mismatch: expected 3 or 4 but got 5`
- `Phase 33-16: Carrier 'i' has no latch incoming set`
---
## 進捗P1.5-DBG
### P1.5-DBG: Boundary Entry Parameter Contract Check完了
目的:
- `boundary.join_inputs` と JoinIR entry function の `params` の対応(個数/順序/ValueIdを **VM 実行前**に fail-fast で検出する。
- これにより、Pattern6 で起きた `loop_invariants` 順序バグ(例: `[s, ch]``[ch, s]`)のような問題を「実行時の undef」ではなく「構造エラー」として落とせる。
実装SSOT:
- `src/mir/builder/control_flow/joinir/merge/contract_checks.rs`
- `verify_boundary_entry_params()`(個数/順序/ValueId の検証)
- `get_entry_function()``join_module.entry``"main"` へのフォールバック)
- unit tests を追加(正常/順序ミスマッチ/個数ミスマッチ)
- `src/mir/builder/control_flow/joinir/patterns/conversion_pipeline.rs`
- JoinIR→MIR 変換直前に検証を追加
- `is_joinir_debug()` 時にログ出力
運用:
- `HAKO_JOINIR_DEBUG=1``[joinir/boundary-contract] ...` を出す既存トグルのみ、env 追加なし)。
### P1.6: Pipeline Contract Checks の薄い集約(完了)
目的:
- `conversion_pipeline.rs` から契約チェック呼び出しと debug ログの詳細を排除し、
契約チェックの SSOT を `contract_checks.rs` に集約するdyn trait など過剰な箱化はしない)。
実装SSOT:
- `src/mir/builder/control_flow/joinir/merge/contract_checks.rs`
- `run_all_pipeline_checks()`(薄い集約エントリ)
- `debug_log_boundary_contract()` を同ファイルへ移設(`is_joinir_debug()` ガード)
- `src/mir/builder/control_flow/joinir/patterns/conversion_pipeline.rs`
- `run_all_pipeline_checks()` の 1 呼び出しに縮退
効果:
- pipeline 側の責務を「パイプラインの制御」に戻し、契約チェックは `contract_checks.rs` に閉じ込めた。
今後チェック項目を増やす場合も `run_all_pipeline_checks()` に追記するだけで済む。
---
## 進捗P1.7
### P1.7: SSA undef`%49/%67`)根治(完了)
症状:
- `Undefined value %49 used in block bb10`
- `Undefined value %67 used in block bb10`
根本原因:
- JoinIR→MIR bridge が `JoinFunction.name` をそのまま MirModule の関数名にしていた(例: `"k_exit"`, `"loop_step"`
- merge 側が `join_func_name(id)`(例: `"join_func_2"`)で関数を探索していた
- その結果、continuation 関数が見つからず inline/merge がスキップされ、SSA undef が露出した
修正方針:
- continuation 関数の識別を「関数ID→暗黙変換」に依存させず、MirModule 上の関数名Stringで SSOT 化する
結果:
- `./target/release/hakorune --backend vm --verify apps/tests/phase256_p0_split_min.hako` で SSA undef は消滅
---
## 進捗P1.8
### P1.8: ExitLine/jump_args と関数名マッピング整流(完了)
変更(要旨):
- ExitArgsCollector 側で「余剰 jump_argsinvariants」を許容し、`expected 3 or 4 but got 5` を解消
- JoinIR→MIR bridge 側で “join_func_N” 由来の名前と “JoinFunction.name” の不一致を解消するため、関数名マッピングを導入/伝播
結果:
- 旧 first FAILjump_args length mismatchは解消
### P1.9: Jump を tail call として表現(完了)
変更(要旨):
- JoinIR→MIR bridge で `JoinInst::Jump` を “continuation への tail call” として落とす
- `BasicBlock.jump_args` を tail call と同様に SSOT として保持ExitLine/collector の復元入力)
結果:
- `JoinInst::Jump` が “ret args[0]” 相当になり continuation が失われる問題は解消
### P1.10: DCE の jump_args + spans 同期(完了)
変更(要旨):
- DCE が `jump_args` で使われる値を used として扱い、純命令の除去で Copy が消えないようにする
- `instruction_spans``instructions` の同期不変条件を維持SPAN MISMATCH 根治)
- 回帰テストを追加(`test_dce_keeps_jump_args_values`, `test_dce_syncs_instruction_spans`
### リファクタリング方針P1.6候補 / 先送り推奨)
現時点split がまだ FAILでは、箱化のための箱化で複雑さが増えやすいので、以下を推奨する:
- ✅ 先にやってよい(低リスク / 価値が高い)
- `contract_checks.rs` 内で「チェックの実行順」を `run_all_*()` のような薄い関数にまとめるdyn trait は不要)
- debug ログは既存の仕組み(`is_joinir_debug()` / `DebugOutputBox`)に寄せる(新 logger box を増やさない)
- テストの JoinModule 構築は、重複が 3 箇所以上になった時点で共通化
- ⛔ 先送りsplit を PASS してから)
- `ContractCheckerBox`trait object柔軟だが、ここでは過剰になりやすい
- `JoinIRDebugLoggerBox` 新設:既存の DebugOutputBox と二重化しやすい
- MIR 命令 dst 抽出の広域統一:既存の `MirInstruction` helper との重複が出やすいので要調査の上で
### 小さな整理(今後の予定 / P1.8以降)
- JoinIR の関数名は `src/mir/join_ir/lowering/canonical_names.rs` を SSOT とする
- `"k_exit"` / `"loop_step"` / `"main"` の直書きは段階的に `canonical_names::*` へ置換
- 正規化 shadow の `"join_func_2"``canonical_names::K_EXIT_LEGACY` として隔離し、統一は Phase 256 完了後に検討
- legacy 掃除候補:
- `join_func_name(id)` の利用箇所を棚卸しし、「structured JoinIR では使用禁止 / normalized shadow だけで使用」など境界を明文化
P1.5 Task 3:
- `ValueId(57)` が「何の JoinIR 値の remap 結果か」を確定し、定義側dstが MIR に落ちているかを追う
- 例: `sep_len = sep.length()` の BoxCall dst が収集/変換/順序のどこかで欠けていないか