Files
hakorune/docs/development/current/main/phases/phase-260
tomoaki 89c5fc2654 docs: Phase 260 P0.3 完了記録 + 既知FAIL SSOT更新
**10-Now.md 更新**:
- Phase 260 P0.2/P0.3 完了記録追加(15モジュール、約3941行、53単体テスト)
- Current First FAIL を "P0.3完了後" に更新
- 既知FAILに "Phase 260 scope外" を明記
- 期待/実際の詳細追加
- 次アクション: 機能側Phase(Pattern2 LoopBodyLocal promotion)へ

**phase-260/README.md 更新**:
- Status: P0.3 完了 
- P0.2/P0.3 進捗セクション追加(commit履歴、成果)
- モジュール分割の責務一覧(Utilities 7 + Handlers 8)
- SSOT維持確認項目(jump_args直参照ゼロ、out_edges()/edge_args_to() SSOT維持、PHI preservation、Phase metadata保持)

Phase 260 完全達成: CFG基盤整備完了、今後は機能側Phaseへ

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 08:18:29 +09:00
..

Phase 260: Block-Parameterized CFGedge-args段階導入

Status: P0.3 完了 Last updated: 2025-12-21

進捗(セーブポイント)

  • P0併存導入の芯: 完了(読む側 SSOT を out_edges()/edge_args_to() に寄せた)
    • Commit: 4dfe3349b
  • P0.1hardening: 完了legacy layout 無し禁止 + DCE/verify の参照点整理)
    • Commit: 1fe5be347
  • P0.2instruction_rewriter モジュール化): 完了
    • Commits: cbed040a7, aa3fdf3c1, c2e8099ff, 84cd653ae, 875bfee1b, 666de9d3e
    • 抽出モジュール: exit_collection, block_allocator, merge_variable_handler, call_generator, handlers/8ファイル
  • P0.3joinir_block_converter モジュール化): 完了
    • Commits: e7f9adcfe, 2c01a7335
    • Phase 1: terminator_builder, block_finalizer
    • Phase 2: handlers/call, jump, conditional_method_call, if_merge, nested_if_merge
    • 合計抽出: 15モジュール、約3941行、53単体テスト全てpass
    • 統合テスト: 45/46 pass既知のPattern2 LoopBodyLocal問題1件のみ

P0.2/P0.3 モジュール分割の責務一覧

Utilities7モジュール

  • block_allocator.rs: ブロックID割り当て統一allocate_one/two/three/n
  • merge_variable_handler.rs: マージコピー生成emit_merge_copies, MergeBranch
  • call_generator.rs: Call命令生成統一emit_call_pair, emit_call_pair_with_spans
  • terminator_builder.rs: Terminator生成統一create_branch/jump/return_terminator, emit_branch_and_finalize
  • block_finalizer.rs: PHI保持ブロック確定finalize_block, finalize_remaining_instructions
  • exit_collection.rs: Exit値収集collect_exit_values, ExitCollectionResult
  • convert.rs: MirLikeInst変換convert_mir_like_inst

Handlers8モジュール

  • handlers/ret.rs: Return処理
  • handlers/method_call.rs: MethodCall → BoxCall変換
  • handlers/field_access.rs: FieldAccess → BoxCallgetter pattern
  • handlers/new_box.rs: NewBox命令処理
  • handlers/select.rs: Select命令直接、展開なし
  • handlers/call.rs: Call + tail call処理Phase 131 P2: 安定ValueId、legacy jump_args
  • handlers/jump.rs: Jump → tail call変換Phase 256 P1.9: continuation、Phase 246-EX: legacy jump_args
  • handlers/conditional_method_call.rs: ConditionalMethodCall → if/phi展開単一変数
  • handlers/if_merge.rs: IfMerge → if/phi複数変数
  • handlers/nested_if_merge.rs: NestedIfMerge → 多段分岐N+3ブロック、最複雑

SSOT維持の確認項目Phase 260の契約

jump_args直参照ゼロ維持: 全モジュールでBasicBlock.jump_argsへの直接参照なし(out_edges()/edge_args_to()経由のみ) out_edges()/edge_args_to() SSOT維持: 読む側APIが単一参照点に統一Branchを含む複数edge前提 terminator operand優先: 新規コードはterminator operandを優先的に使用legacy jump_argsは併存のみ PHI preservation: block_finalizer.rsでPhase 189 FIXPHI命令をブロック先頭保持を維持 Phase metadata保持: Phase 131 P2安定ValueId、Phase 246-EXlegacy jump_args、Phase 256 P1.9continuation名前解決の契約を全て保持

目的P0

JoinIR→MIR の暗黙 ABIjump_args / carriers / expr_result slot / successorsを減らし、将来的な block-parameterized CFGedge-args を第一級に持つCFGへ収束するための「大工事パート」を開始する。

このフェーズは “一括置換” ではなく、**併存導入Strangler**で可逆に進める。

背景Phase 256-259 で露出した型)

  • jump_args が IR 外メタとして存在すると、DCE/verify/CFG 更新が「忘れると壊れる」になる
  • spans が並行 Vec だと、最適化や変換で同期漏れが起きやすい
  • continuation / entry / exit の識別と args 順序が散在すると、推測・補正が増殖する

North Star: docs/development/current/main/design/join-explicit-cfg-construction.md

方針2段正規化

  • Semantic Normalization意味SSOT: terminator 語彙の固定(例: cond付きJumpを正規形から禁止しBranchへ
  • Plumbing Normalization配線SSOT: edge-args / CFG successor / spans を IR 構造に閉じ込め、写像に縮退

スコープPhase 260

In scope

  • MIR に「edge-args を持つ terminator 表現」を 併存導入する(旧 BasicBlock.jump_args は残す)
  • “読む側” を単一APIに寄せるBranch を含むので “複数 edge” 前提で一本化する)
    • 例: block.out_edges() / block.edge_args_to(target)
  • 互換期間は 一致検証を Fail-Fast(両方ある場合は矛盾で即死)

Out of scopeP0ではやらない

  • BasicBlock.jump_args の削除(削除は Phase 261+
  • spans の内部表現を Vec<Spanned<_>> に一気に切替Phase 261+ で段階導入)
  • JoinIR を削除するbuilder DSL 降格は長期)

実装タスクP0

  1. MirTerminator(または既存 terminator に edge-args を持てる variantを追加併存導入
    • Jump だけでなく Branch を含むため、API は “複数 edge” を前提にする
  2. bridge が Jump/Branch の edge-args を terminator operand としてもセット旧jump_argsも併記してよい
  3. merge/ExitLine/DCE/verify/printer が参照する入口を一本化(読む側の Strangler
    • 推奨: block.out_edges() / block.edge_args_to(target) のような APIedge_args() 単発は Branch で曖昧)
  4. Fail-Fast 契約チェック(--verify 時に必須)
    • “両方ある場合は一致” を verify で保証
    • 追加: “terminator から計算した successors” と “block.successors キャッシュ” の一致も verify で保証(同期漏れを即死)

受け入れ基準P0

  • cargo build --release が通る
  • ./tools/smokes/v2/run.sh --profile quick が少なくとも悪化しないsame first FAIL 以上)
  • --verify の既存テストが壊れないPHI/CFG検証が健全
  • legacy 依存の “推測” が増えていない(新規の env var 追加なし)
  • rg "jump_args" を走らせて、移行コードと API 以外に参照が増えていない(読む側の寄せ漏れを検出)
  • DCE 回帰が 1 本以上あり、「edge-args だけで使われる値」が消されないことを固定できている

ロードマップP0→P3

P0併存導入の芯

  • 単一参照APIを作るBranch を含むので “複数 edge” 前提)
    • 例: BasicBlock::out_edges() / BasicBlock::edge_args_to(target)
  • MIR terminator に edge-args を持てる表現を追加(旧 jump_args併存
    • 推奨: EdgeArgs { layout: JumpArgsLayout, values: Vec<ValueId> } のように “意味layout” も同梱する
  • bridge が edge-args を terminator operand に必ず埋める旧jump_argsも同内容でセットしてよい
  • merge/ExitLine/DCE/verify/printer は参照点を out_edges()/edge_args_to(...) に寄せる
  • 両方ある場合の 一致検証を Fail-Fast--verify で必須)

P1切替

  • jump_args を読む経路を段階的に減らす(参照点は out_edges()/edge_args_to(...) のみ)
  • terminator 更新の API一本化successors/preds の同期漏れを構造で潰す)
    • 読む側だけでなく、書く側terminator 設定/edge-args 設定)も API 経由に寄せる
  • DCE/verify が terminator operand から自然に use/pred を追えることを固定する

P2削除

  • BasicBlock.jump_args を削除(併存チェックも撤去)
  • jump_args 特例の DCE/verify コードを削除terminator operand が SSOT

P3spans 収束)

  • instructions + instruction_spans の並行 Vec を段階導入で廃止
    • 先に編集APIを一本化 → 最終的に Vec<Spanned<MirInstruction>>

メモ設計SSOT

  • 相談パケット: docs/development/current/main/investigations/phase-259-block-parameterized-cfg-consult.md
  • decisions: docs/development/current/main/20-Decisions.md