- contract_checks.rs (846行) を facade 化 - 6モジュールへ分割(1 module = 1 contract): - terminator_targets.rs (208行) - Branch/Jump検証 - exit_bindings.rs (35行) - exit_bindings ↔ exit_phis - carrier_inputs.rs (145行) - carrier_inputs完全性 - boundary_creation.rs (160行) - B1/C2不変条件 - entry_params.rs (317行) - Entry param一貫性 - mod.rs (30行) - Facade - Total: 846 → 895行(+49行モジュール境界オーバーヘッド) - 意味論不変: エラータグ/ヒント文すべて保存 - Fail-Fast遵守: silent fallback追加なし - 検証: Build 0 errors / Pattern6 RC=9 / quick 154/154 PASS 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
5.7 KiB
5.7 KiB
Phase 287 P0: Big Files Refactoring 指示書(意味論不変 / 推定の削減)
Date: 2025-12-27
Status: Complete ✅
Scope: Rust 側の“でかいファイル”を分割して、推定(heuristics)依存を減らす
Non-goals: 新機能、既定挙動変更、silent fallback 追加、env var 追加
目的(SSOT)
- “推定で決めている箇所” を減らし、境界・契約・入口を SSOT として明文化する。
- 意味論不変で分割し、将来の拡張(Pattern6 generalize / merge 強化)に備える。
前提(現状の到達点)
- Pattern6 の事故(undef / 無限ループ)は SSOT へ固定済み:
- latch 記録は
TailCallKind::BackEdgeのみ - entry-like は “JoinIR main の entry block のみ”
- 二重 latch は
debug_assert!で fail-fast - 入口:
docs/development/current/main/phases/phase-188.3/P2-REFACTORING-INSTRUCTIONS.md
- latch 記録は
でかいファイルの棚卸し(再現コマンド)
find src -name '*.rs' -print0 | xargs -0 wc -l | sort -nr | head -50
このセッションの観測(500行超え):
- 16 個
優先順位(今すぐやる価値)
1) merge/mod.rs(1,555行)— 最優先
現状: merge coordinator + value remap + 契約検証 + header PHI 構築が 1 ファイルに同居。
方針: “純粋寄り” から剥がして、mod.rs は orchestrator に寄せる。
実行用の詳細プラン:
docs/development/current/main/phases/phase-287/P0-MERGE_MOD_MODULARIZATION_PLAN.md
結果(実装済み):
merge/mod.rs: 1,555 → 1,053 lines- 新規モジュール:
entry_selector.rs,header_phi_prebuild.rs,value_remapper.rs,boundary_logging.rs - heuristic 排除: continuation 判定は
boundary.continuation_func_idsを SSOT に採用(文字列一致を撤去)
目標構造(案)
src/mir/builder/control_flow/joinir/merge/
├── mod.rs # orchestrator(公開APIと配線のみ)
├── entry_selector.rs # loop header / entry block 選定(SSOT)
├── header_phi_prebuild.rs # LoopHeaderPhiBuilder 呼び出し(SSOT)
├── boundary_logging.rs # verbose/debug のみ(trace統一)
└── debug_assertions.rs # merge 内の fail-fast / 契約検証(debug で固定)
注:
- Phase 287 P0 では
verification/の新設ではなく、既存の “契約検証” をdebug_assertions.rsに統合した(意味論不変)。 - 次(P2)で
contract_checks.rsを facade 化し、契約単位のモジュール分割を行う(contract_checks/を新設予定)。
SSOT(ここで削る推定)
- loop header の推定を boundary に寄せる:
JoinInlineBoundary.loop_header_func_nameを優先し、無い場合のみ legacy heuristic
- “log を常時出す” を禁止し、
trace.stderr_if(..., debug/verbose)に統一
受け入れ基準
cargo build --releaseが通る./tools/smokes/v2/run.sh --profile quickが PASS- 差分は “移動 + 入口統一” に限定(意味論不変)
2) merge/instruction_rewriter.rs(1,297行)— 今は“触らない”が正しい
現状: Scan → Plan → Apply の 3 段パイプラインが 1 ファイルで、局所的に複雑。
方針: Pattern6 の直後なので、いま大きく動かさない(回帰コストが高い)。
ただし“安全にできる”こと(意味論不変)
- policy を 1 箇所へ集約して SSOT にする(既に一部完了)
- latch 記録:
src/mir/builder/control_flow/joinir/merge/rewriter/latch_incoming_recorder.rs - tail-call 分類:
src/mir/builder/control_flow/joinir/merge/tail_call_classifier.rs
- latch 記録:
- “loop header 推定” を boundary SSOT に寄せる(既に実装済み)
将来の分割計画(今すぐはやらない)
scanner.rs/planner//applicator.rsへ物理分割RewriteContextを SSOT にして、stage 間の引数を減らす
3) patterns/ast_feature_extractor.rs(1,148行)— 低難易度で効く
現状: 複数の “検出器” が同居。純粋関数なので物理分割が安全。
方針: pattern_recognizers/ を作って“1 recognizer = 1 質問”にする。
結果(実装済み):
ast_feature_extractor.rs: 1,148 → 135 lines(facade)pattern_recognizers/: 8 modules(1 module = 1 質問)
目標構造(案)
src/mir/builder/control_flow/joinir/patterns/
├── ast_feature_extractor.rs # facade(re-export と glue)
└── pattern_recognizers/
├── mod.rs
├── continue_break.rs
├── infinite_loop.rs
├── if_else_phi.rs
├── carrier_count.rs
└── ...(既存の extracted recognizer と揃える)
受け入れ基準
- 既存の public 関数シグネチャを維持(呼び出し側の差分を最小化)
cargo build --release+ quick PASS- unit tests は “薄く” で良い(recognizer 単位で 1–2 個)
小テスト(1本だけ)で契約を固定する(推奨)
“bb番号や ValueId の固定” は不安定なので、構造テストで固定する。
- latch 二重セット検知(debug):
LoopHeaderPhiInfo::set_latch_incoming()に#[should_panic] - tail-call 分類の境界:
classify_tail_call()の “entry-like でも target!=loop_step は LoopEntry ではない”
(MIR文字列の grep 固定は、ブロック番号が揺れやすいので最終手段)
検証手順(毎回)
cargo build --release
./target/release/hakorune --backend vm apps/tests/phase1883_nested_minimal.hako # RC=9
./tools/smokes/v2/run.sh --profile quick