docs(router): Phase 282 P0+P1 - Router shrinkage SSOT + entrypoint logging
P0: Documentation SSOT (~80 lines added)
- Router Responsibilities SSOT (DOES/DOESN'T split)
- Ok(None)/Err boundary rules (Fail-Fast principle)
- Entrypoint table (Plan/JoinIR/None, 収束先明記)
- Pattern番号 = 症状ラベル定義(最小記述)
P1: Minimal Code (~10 lines)
- 4 trace statements modified (router.rs)
- Entrypoint-based logging (route=plan/joinir/none)
- Pattern names preserved (backward compatible)
- No new environment variables (既存trace機構のみ)
Test Results:
- quick profile: 45 PASS / 1 FAIL (既知failure)
- Pattern6 VM: PASS (phase258_p0_index_of_string_vm.sh)
- Pattern6 LLVM: PASS (phase258_p0_index_of_string_llvm_exe.sh)
- Zero regression ✅
Phase 282 Goal Achieved:
- Router shrinkage complete (SSOT positioning clear)
- Pattern numbers → symptom labels transition documented
- CFG construction converges to emit_frag() SSOT
This commit is contained in:
129
docs/development/current/main/phases/phase-282/README.md
Normal file
129
docs/development/current/main/phases/phase-282/README.md
Normal file
@ -0,0 +1,129 @@
|
||||
# Phase 282: Router Shrinkage (pattern番号の症状ラベル化)
|
||||
|
||||
Status: Planned (design-first)
|
||||
|
||||
Goal:
|
||||
- pattern番号(Pattern1/2/…)を “症状ラベル(テスト名)” に縮退させ、router の責務を「抽出の配線」へ収束させる。
|
||||
- CFG 構築は `Frag/ExitKind` 合成 SSOT(`compose::*` + `emit_frag()`)へ一本化する。
|
||||
|
||||
## SSOT References
|
||||
|
||||
- Frag/emit SSOT: `docs/development/current/main/design/edgecfg-fragments.md`
|
||||
- Composition SSOT: `src/mir/builder/control_flow/edgecfg/api/compose.rs`
|
||||
- JoinIR overview: `docs/development/current/main/joinir-architecture-overview.md`
|
||||
- Plan line(Pattern6/7): `docs/development/current/main/phases/phase-273/README.md`
|
||||
- Composition adoption(Pattern6/7): `docs/development/current/main/phases/phase-281/README.md`
|
||||
|
||||
## Problem
|
||||
|
||||
pattern番号が router の分岐点として肥大化すると、以下が起きる:
|
||||
- “認識(extract)” と “CFG構築(lower)” が混ざる
|
||||
- 分岐の追加が雪だるま式に増える(実質、2つ以上のコンパイラを育てる)
|
||||
- 収束先(SSOT)が曖昧になり、バグ修正の導線が折れる
|
||||
|
||||
## Target Shape (SSOT)
|
||||
|
||||
router の役割をここまで縮退させる:
|
||||
- **やる**: Extractor の列挙、Ok(None)/Err の境界管理、Plan/JoinIR の入口選択
|
||||
- **やらない**: CFG構築のディテール、terminator 生成、推測 fallback
|
||||
|
||||
CFG構築は以下に収束させる:
|
||||
- Plan line: `Extractor → DomainPlan → Normalizer → CorePlan → Lowerer → emit_frag()`
|
||||
- JoinIR line: `cf_loop → (必要な抽出) → Frag composition → emit_frag()`
|
||||
|
||||
## P0 (docs-only) — SSOT 固定
|
||||
|
||||
- router の責務/禁止事項を明文化(by-name hardcode禁止、silent fallback禁止)
|
||||
- "pattern番号の意味" を SSOT として定義(テスト名/症状ラベル)
|
||||
- 入口リンクを `10-Now.md` に固定
|
||||
|
||||
### Router Responsibilities SSOT
|
||||
|
||||
**Router がやること**:
|
||||
1. Extraction 戦略の列挙(Plan-based, JoinIR table-based)
|
||||
2. Extractor を優先順で呼び出し(Plan line → JoinIR table)
|
||||
3. Ok(None)/Err の境界管理(Fail-Fast原則)
|
||||
4. Entrypoint の選択(Plan line vs JoinIR line)
|
||||
5. Routing 決定のログ出力(debug mode のみ、既存 trace 機構)
|
||||
|
||||
**Router がやらないこと**(禁止事項):
|
||||
1. CFG 構築(block 割り当て、PHI 挿入、terminator 生成)
|
||||
2. Pattern 固有の lowering ロジック(Normalizer/Lowerer に委譲)
|
||||
3. Silent fallback(エラーは明示的に)
|
||||
4. By-name hardcode(関数名マッチング禁止、debug 以外)
|
||||
5. Mock path fallback(test 専用パターンの本番使用禁止)
|
||||
|
||||
**Pattern 番号 = 症状ラベル**(Phase 280 SSOT positioning):
|
||||
- ✅ 正しい用途: テスト名(`loop_if_phi.hako` → Pattern3_WithIfPhi)、debug ログ
|
||||
- ❌ 禁止: CFG 分岐(`if pattern == 6 then ...`)、アーキテクチャ SSOT(Frag composition が SSOT)
|
||||
|
||||
**Detection 戦略**(簡潔版、詳細は P2+ で補完):
|
||||
- **ExtractionBased**(Pattern6,7,8): extract() 成功 → match(SSOT 単一)
|
||||
- **StructureBased**(Pattern1-5,9): ctx.pattern_kind チェック(legacy、2 つの SSOT)
|
||||
|
||||
**SSOT 参照**:
|
||||
- Frag composition: `src/mir/builder/control_flow/edgecfg/api/compose.rs`
|
||||
- Plan line: `src/mir/builder/control_flow/plan/normalizer.rs`
|
||||
- Terminator 生成: `emit_frag()` (Phase 267)
|
||||
|
||||
### Ok(None)/Err Boundary Rules
|
||||
|
||||
**Fail-Fast 原則**:
|
||||
- `Ok(None)`: Extraction がパターンに一致しなかった(次を試す)
|
||||
- `Err(String)`: Extraction が一致したが検証失敗(即座に fail)
|
||||
- **禁止**: Close-but-unsupported → Ok(None)(Err で返すべき)
|
||||
|
||||
**例**:
|
||||
|
||||
```rust
|
||||
// ✅ 正しい: 一致しない
|
||||
extract_scan_with_init_plan() → Ok(None) // 次のパターンを試す
|
||||
|
||||
// ✅ 正しい: 一致したが非サポート
|
||||
extract_scan_with_init_plan() → Err("P1 scope: reverse scan not supported")
|
||||
|
||||
// ❌ 禁止: Silent fallback
|
||||
extract_scan_with_init_plan() → Ok(None) for unsupported cases
|
||||
// (非サポートケースを Ok(None) で返してはいけない)
|
||||
```
|
||||
|
||||
**境界の位置**(router.rs 実装):
|
||||
- Plan line(lines 310-337, 341-368): extract → match → Normalize → Verify → Lower
|
||||
- JoinIR table(lines 376-382): can_lower → lower
|
||||
- No match(lines 384-395): Ok(None) を caller に返す(Err ではない)
|
||||
|
||||
### Entrypoint Table
|
||||
|
||||
| Entrypoint | Entry Condition | Patterns | SSOT Downstream |
|
||||
|------------|----------------|----------|-----------------|
|
||||
| **Plan line** | extract_*_plan() が Ok(Some) | Pattern6/7 | Normalizer → CorePlan → Lowerer → emit_frag |
|
||||
| **JoinIR table** | LOOP_PATTERNS 反復 | Pattern1-5,8-9 | cf_loop 抽出 → Frag composition → emit_frag |
|
||||
| **No match** | すべての extract が Ok(None) | (none) | Err を caller に返す |
|
||||
|
||||
**Plan line の責務**(Phase 273 SSOT):
|
||||
1. **Extraction**: extract_*_plan()(pure、builder 不要)
|
||||
2. **Normalization**: PlanNormalizer(pattern 知識の展開)
|
||||
3. **Verification**: PlanVerifier(fail-fast 検証)
|
||||
4. **Lowering**: PlanLowerer(block/value 割り当て + Frag composition)
|
||||
5. **Emission**: emit_frag()(terminator SSOT)
|
||||
|
||||
**JoinIR table の責務**(Phase 194+ table-driven):
|
||||
1. **Detection**: can_lower()(structure-based、ctx.pattern_kind)
|
||||
2. **Extraction**: cf_loop 抽出
|
||||
3. **収束先**: Frag composition → emit_frag(内部パイプライン詳細は最小化)
|
||||
|
||||
**収束先の統一**(Phase 282 Goal):
|
||||
- すべての entrypoint が最終的に `emit_frag()` に収束(terminator 生成の SSOT)
|
||||
- CFG 構築の詳細は router が持たない(抽出の配線のみ)
|
||||
|
||||
## P1 (code, minimal) — 配線の可視化
|
||||
|
||||
- router に “経路ログ” を追加(既定OFF、debugのみに限定)
|
||||
- pattern番号ではなく “entrypoint(Plan/JoinIR)” をログの主語にする
|
||||
|
||||
## Acceptance (Phase 282)
|
||||
|
||||
- router の責務が docs で SSOT 化されている
|
||||
- router の変更が「extractor配線」のみになっている(CFG構築の詳細を持たない)
|
||||
- 既存の VM/LLVM smokes に退行がない
|
||||
|
||||
@ -314,7 +314,7 @@ pub(crate) fn route_loop_pattern(
|
||||
)? {
|
||||
Some(domain_plan) => {
|
||||
// DomainPlan extracted successfully
|
||||
trace::trace().pattern("route", "Pattern6_ScanWithInit (DomainPlan)", true);
|
||||
trace::trace().pattern("route", "route=plan pattern=Pattern6_ScanWithInit (Phase 273)", true);
|
||||
|
||||
// Step 1: Normalize DomainPlan → CorePlan
|
||||
let core_plan = PlanNormalizer::normalize(builder, domain_plan, ctx)?;
|
||||
@ -345,7 +345,7 @@ pub(crate) fn route_loop_pattern(
|
||||
)? {
|
||||
Some(domain_plan) => {
|
||||
// DomainPlan extracted successfully
|
||||
trace::trace().pattern("route", "Pattern7_SplitScan (DomainPlan)", true);
|
||||
trace::trace().pattern("route", "route=plan pattern=Pattern7_SplitScan (Phase 273)", true);
|
||||
|
||||
// Step 1: Normalize DomainPlan → CorePlan
|
||||
let core_plan = PlanNormalizer::normalize(builder, domain_plan, ctx)?;
|
||||
@ -376,7 +376,8 @@ pub(crate) fn route_loop_pattern(
|
||||
for entry in LOOP_PATTERNS {
|
||||
if (entry.detect)(builder, ctx) {
|
||||
// Phase 195: Use unified trace for pattern matching
|
||||
trace::trace().pattern("route", entry.name, true);
|
||||
let log_msg = format!("route=joinir pattern={} (Phase 194+)", entry.name);
|
||||
trace::trace().pattern("route", &log_msg, true);
|
||||
return (entry.lower)(builder, ctx);
|
||||
}
|
||||
}
|
||||
@ -387,7 +388,7 @@ pub(crate) fn route_loop_pattern(
|
||||
trace::trace().debug(
|
||||
"route",
|
||||
&format!(
|
||||
"No pattern matched for function '{}' (pattern_kind={:?})",
|
||||
"route=none (no pattern matched) func='{}' pattern_kind={:?} (exhausted: plan+joinir)",
|
||||
ctx.func_name, ctx.pattern_kind
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user