Files
hakorune/CURRENT_TASK.md
nyash-codex fd83903f87 feat(joinir): Phase P1 If Handler boxification - 40% code reduction
## Summary
Refactored loop-internal If statement handling into a boxified module
structure, achieving 154-line reduction (40%) from stmt_handlers.rs
with zero regression.

## Implementation
- Created if_in_loop/ module (9 files, ~480 lines)
  - pattern.rs: IfInLoopPattern enum (5 variants)
  - lowering/{empty,single_var_then,single_var_both,conditional_effect,unsupported}.rs
- Replaced lower_if_stmt_in_loop() (154 lines) with lower_if_stmt_in_loop_boxified()
- Made StatementEffect pub(crate) for module visibility

## Pattern Classification
1. Empty: condition-only check (no side effects)
2. SingleVarThen: if { x = a } → x = cond ? a : x
3. SingleVarBoth: if { x = a } else { x = b } → x = cond ? a : b
4. ConditionalEffect: if pred(v) { acc.push(v) } (filter pattern)
5. Unsupported: complex cases (Phase 54+)

## Test Results
 56 JoinIR tests PASSED (0 failed, 0 regression)
 Build successful (1m 02s)
 Improved maintainability (easier to add new patterns)

## Files Changed
- src/mir/join_ir/frontend/ast_lowerer/
  - if_in_loop/ (9 new files)
  - mod.rs (+2 lines: module + pub use)
  - stmt_handlers.rs (-154 lines: 40% reduction)
- CURRENT_TASK.md (+5 lines: Phase P1 記録)
- docs/development/refactoring/p1-if-handler-boxification-plan.md (new)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 07:20:56 +09:00

188 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Current Task — JoinIR / PHI 削減スナップショット2025-11-29 時点)
> このファイルは「今どこまで終わっていて、次に何をやるか」を 1000 行以内でざっくり把握するためのスナップショットだよ。
> 過去の詳細ログは `docs/private/roadmap2/CURRENT_TASK_2025-11-29_full.md` や各 Phase の README/TASKS を見てね。
---
## 0. 現在地ざっくり
- **JoinIR ライン**
- Phase 2731: Loop→JoinIR loweringskip_ws / trim / append_defs / Stage1 minimalで、ループの制御構造を関数継続だけで表現できることを実証済み。
- Phase 3334: IfSelect / IfMerge / JoinIR FrontendIf/Loop/Break/Continue実装。AST→JoinIR→MIR→VM まで tiny ケースが通る。
- **PHI 削減ライン**
- Phase 3536: HIGH/MEDIUM 安全度の PHI 箱if_body_local_merge / phi_invariants / LoopSnapshotMergeBoxの削除・縮退で 537 行削減。
- Phase 3740: If 側 PHIif_phi.rs / conservative.rsの Level 1/2 相当まで設計一部削減。array_ext.filter については JoinIR Frontend + JoinFuncMeta に移行し、collect_assigned_vars を削除済み。
- **これから**
- Phase 41: If 側 PHI Level 3本体ロジックの代表ケースを JoinIR 経路に載せる設計と最初の実装。
- 以降: If 側 PHI 本体削減 → Classifier Trio → AST→JoinIR Frontend 本線化 → LLVM / ny-llvmc の JoinIR 統合。
---
## 1. 最近の主戦場Phase 3341
### 1-00a. Phase 33 — IfSelect / IfMerge + PHI 設計原則
- IfSelect / IfMerge lowering 実装simple/local, 23 変数パターン)。
- VM ラインへの If lowering ドライランを `IfLoweringDryRunner` に箱化し、VM パイプラインと解析ロジックを分離。
- 「JoinIR は PHI 生成器SSOT、既存 PHI の変換器にはしない」原則をコードdocs で固定。
- docs: `docs/private/roadmap2/phases/phase-33-joinir-if-phi-cleanup/if_joinir_design.md`
### 1-00b. Phase 34 — JoinIR FrontendAST→JoinIR
- 目的: ASTProgram JSON v0→ JoinIR Frontend を設計・実装し、「PHI 意味論の SSOT を JoinIR 側に寄せる」。
- 実績:
- If: simple/local/json_shape パターンを Select に正規化(同じ JoinIR 出力)。
- Loop: tiny while / break / continue を 3 関数構造entry/loop_step/k_exit Jump/Call/Select で表現。
- MethodCall: substring などを JoinInst::MethodCall として構造化し、JoinIR→MIR Bridge で BoxCall に変換。
- docs: `docs/private/roadmap2/phases/phase-34-joinir-frontend/README.md`
### 1-00c. Phase 3536 — PHI 箱削減HIGH/MEDIUM
- Phase 35HIGH:
- `if_body_local_merge.rs` / `phi_invariants.rs` 削除(合計 430 行)。
- PHI_BOX_INVENTORY.md で PHI 箱の一覧と削除順を整理。
- Phase 36MEDIUM:
- LoopSnapshotMergeBox を「Exit PHI マージ専用の純粋静的ユーティリティ」に縮退470→363 行)。
- PhiBuilderBox に Loop/If/Common/Stub の責務マーカー追加(実装本体削減は Phase 38+)。
- docs:
- `docs/private/roadmap2/phases/phi-reduction-series/INDEX.md`
- `docs/private/roadmap2/phases/phase-36-phi-midrange/README.md`
### 1-00d. Phase 3739 — If 側 PHI Level 1/2 設計と準備
- Phase 37: If 側 PHI 全体設計docs-only
- if_phi.rs / conservative.rs の責務表、12 callsite の難易度分類。
- 削除基準Level 1/2/3の定義。
- Phase 38: if_phi.rs Level 1 削除90 行)。
- `merge_modified_with_control`dead code`extract_assigned_var`JoinIR AST lowering で代替)を削除。
- Phase 39: Level 2 準備array_ext.filter 選定と JoinIR 拡張設計)。
- array_ext.filter を代表 if-in-loop パターンに選定。
- JoinIR Frontend / JoinFuncMeta / Bridge 拡張と削除条件を設計。
- docs:
- `docs/private/roadmap2/phases/phase-37-if-phi-reduction/README.md`
- `docs/private/roadmap2/phases/phase-38-if-phi-level1/README.md`
- `docs/private/roadmap2/phases/phase-39-if-phi-level2/README.md`
### 1-00e. Phase 40 — If 側 PHI Level 2 実装array_ext.filter
- 目的: array_ext.filter の ifinloop PHI を JoinIR Frontend + JoinFuncMeta + Bridge 経由に移し、collect_assigned_vars を削除する。
- 実績:
- JoinFuncMeta / JoinFuncMetaMap / convert_join_module_to_mir_with_meta 実装。
- AST→JoinIR Frontend で ifinloop の modified 変数集合を解析し、JoinIR→MIR Bridge で PHI 生成。
- loop_builder.rs に HAKO_JOINIR_ARRAY_FILTER 経路を追加し、Route BJoinIR 経路)をデフォルト化。
- `collect_assigned_vars` を削除し、JSON ベースの `collect_assigned_vars_via_joinir` に置き換えPhase 40-4.1)。
- デッドな env フラグ等をクリーンアップ40-4.1.1)。
- 削減実績Phase 40 時点):
- 35 行collect_assigned_vars16 行(デッドコード)= 51 行純減。
- docs:
- `docs/private/roadmap2/phases/phase-40-if-phi-level2/README.md`
- `docs/private/roadmap2/phases/phi-reduction-series/INDEX.md`
### 1-00f. Phase 41 — If-Side PHI Level 3 Reduction ✅ 完了2025-11-28
- 目的:
- if_phi.rs / conservative.rs に残る「Level 3 本体ロジック」を JoinIR 経路に移すための設計と代表ケース実装。
- 実績:
- Level 3 関数の再インベントリとデッドコード 147 行削除。
- 代表 If 関数として `ParserControlBox.parse_loop()` を選定。
- NestedIfMerge JoinInst 設計実装mod.rs, json.rs
- AST→JoinIR Frontend に `lower_nested_if_pattern()` 追加dev flag: `HAKO_JOINIR_NESTED_IF=1`)。
- JoinIR→MIR Bridge に NestedIfMerge 展開ロジック追加(多段 Branch + Copy
- Route BNestedIfMerge 経由)の A/B テスト 7 ケース全 PASSparse_loop 代表ケース)。
- 実削除if_phi.rs / conservative.rs 本体の縮退・削除)は Phase 42 に繰り越し。
- docs:
- `docs/private/roadmap2/phases/phase-41-if-phi-level3/README.md`
- `docs/private/roadmap2/phases/phase-41-if-phi-level3/TASKS.md`
### 1-00g. Phase 45 — read_quoted_from JoinIR 実装 ✅ 完了2025-11-28
- 目的:
- `MiniJsonCur.read_quoted_from(s, pos)` を JoinIR Frontend/Bridge で実装し、Guard if + Loop with break + accumulator パターンの PHI 削減を実証。
- 実績:
- **45-1**: フィクスチャ `apps/tests/phase45_read_quoted_fixture.hako` 作成T1-T4 Route A で PASS
- **45-2**: AST→JoinIR Frontend `lower_read_quoted_pattern()` 実装(`ast_lowerer.rs`)。
- **45-3**: JoinIR→MIR Bridge 確認(既存 bridge で変更不要)。
- **45-4**: Route B E2E テスト `test_read_quoted_from_route_b_e2e()` 追加、T1-T4 全 PASS。
- **45-5**: PHI_BOX_INVENTORY.md / CURRENT_TASK.md 更新。
- 既知の制限:
- **T5エスケープ処理**: 変数再代入 inside if-block が PHI を生成しない問題 → **Phase 46 で解決済み**
- Dev Flag: `HAKO_JOINIR_READ_QUOTED=1`
- JoinIR 構造: entry → k_guard_fail / loop_step → k_exit4 関数構造)
- docs:
- `docs/private/roadmap2/phases/phase-30-final-joinir-world/PHI_BOX_INVENTORY.md` (Phase 45 セクション)
### 1-00h. Phase 46 — IfMerge 拡張(ループ内 if での変数再代入 PHI 問題)✅ 完了2025-11-28
- 目的:
- ループ内の `if (cond) { x = expr; }` パターンで、if-body での変数再代入が merge ブロックで PHI に反映されない問題を修正。
- 実績:
- **46-1**: 現状 MIR の問題点を CFG 図で固定T5 専用)。
- **46-2**: JoinIR レベルでの「正しい形」を IfMerge で設計Option A 採用)。
- **46-3**: `lower_read_quoted_pattern()` に IfMerge 拡張を設計・実装。
- **46-4**: Route B E2E テスト T1-T5 全 PASS。
- テスト結果:
- T1-T4: ✅ PASSPhase 45 と同じ)
- **T5エスケープ処理**: ✅ PASS`"a\"b"``a"b`
- Dev Flag: `HAKO_JOINIR_READ_QUOTED_IFMERGE=1`Phase 46 IfMerge 拡張有効化)
- 修正ファイル:
- `src/mir/join_ir/frontend/ast_lowerer.rs`: IfMerge による escape 処理追加
- `src/mir/join_ir_vm_bridge.rs`: T5 テストケース追加
- docs:
- `docs/private/roadmap2/phases/phase-46-ifmerge-loop-reassign/README.md`
### 1-00i. Phase 4956 — JoinIR Frontend 本線統合print_tokens / filter✅ 進行中
- Phase 4952: `cf_loop` に JoinIR Frontend ルートを追加しdev フラグ付き)、`LoopFrontendBinding` / JSON v0 / expr タイプField/NewBoxを整備。
- `HAKO_JOINIR_PRINT_TOKENS_MAIN` / `HAKO_JOINIR_ARRAY_FILTER_MAIN` で対象ループだけを Frontend 経由にルーティング。
- `merge_joinir_mir_blocks` で JoinIR→MIR のブロック/値 ID リマップと制御フロー接続を実装。
- Phase 5355: statement loweringLocal/Assignment/Print/Method/Ifと AST→JSON の `"type"`/`"expr"` 整備により、`JsonTokenizer.print_tokens/1` が JoinIR Frontend→Bridge→VM 経由で最後まで実行可能にRoute A/B 等価、dev フラグ ON 限定)。
- Phase 56: `ArrayExtBox.filter/2` 向けに `LoopFrontendBinding::for_array_filter` を MethodCall ベース(`arr.size()`)に修正し、外部参照 `arr/pred` を Binding 経由で渡す構造に統一。
- JoinIR に `ConditionalMethodCall` / Unary / Call を追加し、filter の「pred が true のときだけ push する」パターンを 4 ブロック構造で表現。
- `HAKO_JOINIR_ARRAY_FILTER_MAIN=1` で Route BJoinIR Frontend 経路)がフォールバックなし完走(テスト済み、既定は従来ルート)。
- Phase P1: **If Handler 箱化モジュール化** ✅ 完了2025-11-29
- ループ内 If 処理の 5 パターンEmpty/SingleVarThen/SingleVarBoth/ConditionalEffect/Unsupported`IfInLoopPattern` enum で分類。
- `if_in_loop/` モジュール9 ファイル、~480 行)を新設し、`stmt_handlers.rs` から 154 行削減40% 削減達成)。
- 全 56 JoinIR tests PASS回帰なし、保守性・拡張性向上新パターン追加が容易に
- docs: `docs/development/refactoring/p1-if-handler-boxification-plan.md`
---
## 2. 中期 TODOざっくり
- **Phase 42: PHI Workaround 条件付きスキップ** ✅ 完了2025-11-28
- ✅ 42-1: PHI workaround 内容の文書化完了README.md に記録)
- ✅ 42-2: `parser_control_box.hako:85-139` に条件付きスキップ実装
- Route Adefault: workaround 使用(後方互換性維持)
- Route B`HAKO_JOINIR_NESTED_IF=1`: workaround スキップ
- Route B テスト 3/3 PASS、Route A テスト 13/13 PASS
- ✅ 42-3: callsite 再分析・Phase 43 候補リスト作成完了
- if_phi.rs: 4残存関数全て parse_loop 以外からも呼ばれる)
- conservative.rs: ConservativeMerge::analyze が phi_merge.rs/phi.rs から使用中
- Phase 43 推奨: NestedIfMerge 適用範囲拡大 → phi_merge.rs JoinIR 移行
- docs: `docs/private/roadmap2/phases/phase-42-if-phi-level3-removal/README.md`
- **Phase 43+: If 側 PHI 本体削除**
- if_phi.rs / conservative.rs の残存関数は全て parse_loop 以外からも呼ばれている
- 他の関数print_tokens 等)も JoinIR 経路に乗せてから本体削除
- **Classifier Trio**
- LoopVarClassBox / LoopExitLivenessBox / LocalScopeInspectorBox を LoopScopeShape に吸収し、JoinIR lowering / LoopForm 側から直接 LoopScopeShape を見る構造に整理。
---
## 3. 旧フェーズ(過去ログへのポインタ)
古いフェーズの詳細な経緯やログは、以下のドキュメントと
`docs/private/roadmap2/CURRENT_TASK_2025-11-29_full.md` を見てね。
- Phase 21.7 — Static Box Methodization
- StaticMethodId / NamingBox で BoxName.method/arity 名前解決の SSOT 化。
- docs: `docs/development/current/main/phase-21.7-naming-ssot-checklist.md` など。
- Phase 25.x / 26.x — LoopForm v2 / LoopSSA v2 / Exit PHI / ExitLiveness
- LoopForm v2 / LoopSSA v2 の整備と Exit PHI / ExitLiveness まわりの 4 箱構成。
- Phase 2732 — JoinIR 初期実験〜汎用化
- LoopToJoinLowerer / LoopScopeShape / JoinIR VM Bridge を minimal ケースから Stage1 / StageB へ広げていくライン。
- docs: `docs/private/roadmap2/phases/phase-27-joinir*`, `phase-31-looptojoin-lowerer`, `phase-32-joinir-complete-migration` など。
CURRENT_TASK.md 自体は「いまどこを触っているか」と「次に何をやるか」を
1 画面で把握できる軽さを維持する方針だよ。***