2025-12-27 10:10:59 +09:00
|
|
|
|
# Phase 287 P0: Big Files Refactoring 指示書(意味論不変 / 推定の削減)
|
|
|
|
|
|
|
|
|
|
|
|
**Date**: 2025-12-27
|
2025-12-27 11:05:40 +09:00
|
|
|
|
**Status**: Complete ✅
|
2025-12-27 10:10:59 +09:00
|
|
|
|
**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`
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## でかいファイルの棚卸し(再現コマンド)
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
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`
|
|
|
|
|
|
|
2025-12-27 11:05:40 +09:00
|
|
|
|
結果(実装済み):
|
|
|
|
|
|
- `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 に採用(文字列一致を撤去)
|
|
|
|
|
|
|
2025-12-27 10:10:59 +09:00
|
|
|
|
#### 目標構造(案)
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
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統一)
|
2025-12-27 11:05:40 +09:00
|
|
|
|
└── debug_assertions.rs # merge 内の fail-fast / 契約検証(debug で固定)
|
2025-12-27 10:10:59 +09:00
|
|
|
|
```
|
|
|
|
|
|
|
2025-12-27 11:05:40 +09:00
|
|
|
|
注:
|
|
|
|
|
|
- Phase 287 P0 では `verification/` の新設ではなく、既存の “契約検証” を `debug_assertions.rs` に統合した(意味論不変)。
|
|
|
|
|
|
- 次(P2)で `contract_checks.rs` を facade 化し、契約単位のモジュール分割を行う(`contract_checks/` を新設予定)。
|
|
|
|
|
|
|
2025-12-27 10:10:59 +09:00
|
|
|
|
#### 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`
|
|
|
|
|
|
- “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 質問”にする。
|
|
|
|
|
|
|
2025-12-27 11:05:40 +09:00
|
|
|
|
結果(実装済み):
|
|
|
|
|
|
- `ast_feature_extractor.rs`: 1,148 → 135 lines(facade)
|
|
|
|
|
|
- `pattern_recognizers/`: 8 modules(1 module = 1 質問)
|
|
|
|
|
|
|
2025-12-27 10:10:59 +09:00
|
|
|
|
#### 目標構造(案)
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
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 固定は、ブロック番号が揺れやすいので最終手段)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 検証手順(毎回)
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cargo build --release
|
|
|
|
|
|
./target/release/hakorune --backend vm apps/tests/phase1883_nested_minimal.hako # RC=9
|
|
|
|
|
|
./tools/smokes/v2/run.sh --profile quick
|
|
|
|
|
|
```
|