Files
hakorune/docs/development/current/main/phases/phase-252/README.md
tomoaki 2d9c6ea3c6 feat(joinir): Phase 254-255 - Pattern 6 (ScanWithInit) + exit PHI DCE fix
## Phase 254: Pattern 6 (ScanWithInit) Detection & JoinIR Lowering

Pattern 6 detects index_of/find/contains-style loops:
- Loop condition: i < x.length()
- Loop body: if with method call condition + early return
- Step: i = i + 1
- Post-loop: return not-found value (-1)

Key features:
- Minimal lowering: main/loop_step/k_exit functions
- substring hoisted to init-time BoxCall
- Two k_exit jumps (found: i, not found: -1)
- Tests: phase254_p0_index_of_min.hako

## Phase 255 P0: Multi-param Loop CarrierInfo

Implemented CarrierInfo architecture for Pattern 6's 3-variable loop (s, ch, i):
- i: LoopState (header PHI + exit PHI)
- s, ch: ConditionOnly (header PHI only)
- Alphabetical ordering for determinism
- All 3 PHI nodes created correctly
- Eliminates "undefined ValueId" errors

## Phase 255 P1: Exit PHI DCE Fix

Prevents exit PHI from being deleted by DCE:
- PostLoopEarlyReturnStepBox emits post-loop guard
- if (i != -1) { return i } forces exit PHI usage
- Proven pattern from Pattern 2 (balanced_depth_scan)
- VM/LLVM backends working

## Test Results

 pattern254_p0_index_of_vm.sh: PASS (exit code 1)
 pattern254_p0_index_of_llvm_exe.sh: PASS (mock)
 Quick profile: json_lint_vm PASS (progresses past index_of)
 Pattern 1-5: No regressions

## Files Added

- src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs
- src/mir/join_ir/lowering/scan_with_init_minimal.rs
- apps/tests/phase254_p0_index_of_min.hako
- docs/development/current/main/phases/phase-254/README.md
- docs/development/current/main/phases/phase-255/README.md

🧠 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 23:32:25 +09:00

2.6 KiB
Raw Blame History

Status: Completed Scope: Phase 252 (JoinIR Pattern2 break 条件: this.methodcall(...) 対応 + policy SSOT) Related:

  • docs/development/current/main/10-Now.md
  • docs/development/current/main/phases/phase-251/README.md

Phase 252: Pattern2 break 条件の this.methodcall(...) 対応

目的

  • --profile quickjson_lint_vm で露出した JoinIR Pattern2 の回帰を潰す。
  • 具体的には if not this.is_whitespace(s.substring(i, i + 1)) { break } のような this.methodcall(...) を break 条件として lowering できるようにする。

実装P0/P1: 完了)

1) ユーザー定義メソッドの許可ポリシーSSOT

ファイル:

  • src/mir/join_ir/lowering/user_method_policy.rs

要点:

  • CoreMethodIdbuiltinとは別に、this.methodcall(...) の「許可」を一箇所に集約する。
  • by-name の if 分岐で散らさず、ポリシーテーブルとして SSOT 化する。

2) ConditionLowerer: ASTNode::MethodCall(object: Me, ...) の受理

ファイル:

  • src/mir/join_ir/lowering/condition_lowerer.rs

要点:

  • break 条件のトップレベルが MethodCall(Me, ...) の場合に lowering できる分岐を追加。
  • this の所属 box 名は current_static_box_name を経由して受け取る(固定名分岐しない)。

3) current_static_box_name の配線Pattern2 まで)

変更点:

  • ConditionContextcurrent_static_box_name を追加
  • Pattern2 lowering 入力inputsから break/header 条件 lowering まで current_static_box_name を伝搬

注:

  • ここは “構造” による情報伝達であり、特定関数名での回避分岐(ハードコード)ではない。

4) 局所リファクタDebugOutputBox 統一)

ファイル:

  • src/mir/join_ir/lowering/loop_with_if_phi_if_sum.rs

要点:

  • 無条件/散在ログを追加しない方針を維持しつつ、出力 API を DebugOutputBox に統一する。
  • デフォルトでは出力ゼロsmoke の期待出力を壊さない)。

5) テスト/fixture の追加

  • unit tests を追加(this.methodcall(...) 条件の lowering 回帰固定)
  • v2 smoke fixture を追加integration profile

検証状況Phase 252 終点)

  • cargo check が通る0 errors、warnings のみ)
  • --profile quick の最初の FAIL は次に切り出しPhase 253:
    • [joinir/mutable-acc-spec] Assignment form not accumulator pattern (required: target = target + x)

次の作業Phase 253

次の SSOT: docs/development/current/main/phases/phase-253/README.md