feat(mir/llvm): Phase 273 P0-P1 DomainPlan→CorePlan + LLVM arg fix
Phase 273 P0-P1: Two-layer plan architecture - DomainPlan: Pattern-specific knowledge (ScanWithInit) - CorePlan: Fixed vocabulary (Seq, Loop, If, Effect, Exit) - ValueId references only (String expressions forbidden) - Pipeline: Extractor→Normalizer→Verifier→Lowerer New plan/ module: - mod.rs: Type definitions, SSOT spec - normalizer.rs: DomainPlan→CorePlan + ID allocation - verifier.rs: V1-V6 invariant checks (fail-fast) - lowerer.rs: CorePlan→MIR (pattern-agnostic) LLVM fix (ChatGPT): - function_lower.py: Fix argument reference bug - Phase 258 index_of_string now PASS on LLVM backend 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
119
docs/development/current/main/phases/phase-273/README.md
Normal file
119
docs/development/current/main/phases/phase-273/README.md
Normal file
@ -0,0 +1,119 @@
|
||||
# Phase 273: Plan Extractor (Pure) + PlanLowerer SSOT
|
||||
|
||||
Status: ✅ P0/P1 completed (2025-12-22)
|
||||
|
||||
Goal:
|
||||
- pattern 列挙の裾広がりを止める。
|
||||
- pattern は "検出して Plan を返すだけ" に降格し、CFG/PHI/block/value の生成責務を 1 箇所に閉じ込める。
|
||||
- P1: DomainPlan → CorePlan の 2層構造で "収束" を強める
|
||||
|
||||
---
|
||||
|
||||
## P1 完了 (2025-12-22)
|
||||
|
||||
### アーキテクチャ
|
||||
|
||||
```
|
||||
DomainPlan (Pattern固有)
|
||||
↓ PlanNormalizer (SSOT)
|
||||
CorePlan (固定語彙 - 構造ノードのみ)
|
||||
↓ PlanVerifier (fail-fast)
|
||||
↓ PlanLowerer
|
||||
MIR (block/value/phi)
|
||||
```
|
||||
|
||||
### SSOT Entry Point
|
||||
|
||||
**Files**:
|
||||
- `src/mir/builder/control_flow/plan/mod.rs` - DomainPlan/CorePlan 型定義
|
||||
- `src/mir/builder/control_flow/plan/normalizer.rs` - PlanNormalizer(DomainPlan → CorePlan)
|
||||
- `src/mir/builder/control_flow/plan/verifier.rs` - PlanVerifier(fail-fast 検証)
|
||||
- `src/mir/builder/control_flow/plan/lowerer.rs` - PlanLowerer(CorePlan → MIR)
|
||||
|
||||
### 原則
|
||||
|
||||
- Extractor は **pure**(builder 触り厳禁、DomainPlan を返すのみ)
|
||||
- Normalizer は **SSOT**(pattern 固有知識はここに集約)
|
||||
- CorePlan の式は **ValueId 参照のみ**(String 禁止 → 第2の言語処理系を作らない)
|
||||
- Lowerer は **pattern-agnostic**(CorePlan のみを処理)
|
||||
- terminator SSOT: Frag → emit_frag()
|
||||
|
||||
---
|
||||
|
||||
## CorePlan 固定語彙
|
||||
|
||||
```rust
|
||||
pub enum CorePlan {
|
||||
Seq(Vec<CorePlan>),
|
||||
Loop(CoreLoopPlan),
|
||||
If(CoreIfPlan),
|
||||
Effect(CoreEffectPlan),
|
||||
Exit(CoreExitPlan),
|
||||
}
|
||||
|
||||
pub enum CoreEffectPlan {
|
||||
MethodCall { dst, object, method, args },
|
||||
BinOp { dst, lhs, op, rhs },
|
||||
Compare { dst, lhs, op, rhs },
|
||||
Const { dst, value },
|
||||
}
|
||||
```
|
||||
|
||||
**増殖禁止ルール**:
|
||||
- ノード種別(variant)の追加は禁止
|
||||
- `EffectPlan::ScanInit` のような scan専用 variant は禁止
|
||||
- データ(フィールド、パラメータ)の追加は許容
|
||||
|
||||
---
|
||||
|
||||
## P1 Implementation Summary
|
||||
|
||||
**Files changed** (7 total):
|
||||
- Modified: `src/mir/builder/control_flow/plan/mod.rs` - DomainPlan/CorePlan 型定義 (~220 lines)
|
||||
- New: `src/mir/builder/control_flow/plan/normalizer.rs` - PlanNormalizer (~290 lines)
|
||||
- New: `src/mir/builder/control_flow/plan/verifier.rs` - PlanVerifier (~180 lines)
|
||||
- Modified: `src/mir/builder/control_flow/plan/lowerer.rs` - CorePlan 対応 (~250 lines)
|
||||
- Modified: `src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs` - DomainPlan 返却
|
||||
- Modified: `src/mir/builder/control_flow/joinir/patterns/router.rs` - Normalizer + Verifier 経由
|
||||
|
||||
**Regression test**:
|
||||
- ✅ phase254_p0_index_of_vm.sh (fixed needle, forward scan)
|
||||
- ✅ phase258_p0_index_of_string_vm.sh (dynamic needle)
|
||||
|
||||
---
|
||||
|
||||
## LLVM harness の落とし穴(Phase 258 で露出)
|
||||
|
||||
Phase 258 の `index_of_string`(dynamic needle)で、VM では正しいのに LLVM で `Result: 0` になるケースが露出した。
|
||||
原因は Phase 273 P1 の本線(DomainPlan→CorePlan→emit_frag)ではなく、LLVM harness / AOT ランタイム側の “契約” だった。
|
||||
|
||||
### 1) `params` を使わないと引数が silently に潰れる
|
||||
|
||||
MIR JSON の `params`(ValueId の引数順)を使わず、heuristic で「未定義の use」を拾うと、
|
||||
`box` フィールド等を見落とした場合に **v1 が arg0 に誤マップ**され、needle が haystack と同一扱いになる。
|
||||
|
||||
- Fix: `src/llvm_py/builders/function_lower.py` で `func_data["params"]` を SSOT として優先する
|
||||
|
||||
### 2) “raw integer vs handle” 衝突で `Result` が 0 になる
|
||||
|
||||
AOT ランタイム(nyrt)は `ny_main()` の返り値が **raw i64** か **handle(i64)** かを区別できない。
|
||||
正しい raw 返り値(例: `6`)が、たまたま生成済みの handle id と衝突すると、IntegerBox ではないため `Result: 0` になりうる。
|
||||
|
||||
- Fix: `crates/nyash_kernel/src/lib.rs` の exit_code 抽出で、handle が IntegerBox 以外なら raw i64 として扱う
|
||||
|
||||
## References
|
||||
|
||||
- JoinIR SSOT overview: `docs/development/current/main/joinir-architecture-overview.md`
|
||||
- Frag SSOT: `docs/development/current/main/design/edgecfg-fragments.md`
|
||||
- Phase 272(Pattern6/7, Frag適用): `docs/development/current/main/phases/phase-272/README.md`
|
||||
|
||||
## Instructions
|
||||
|
||||
- P0 Claude Code: `docs/development/current/main/phases/phase-273/P0-CLAUDE.md`
|
||||
- P1 Claude Code: `docs/development/current/main/phases/phase-273/P1-CLAUDE.md`
|
||||
|
||||
## Future Work (P2+)
|
||||
|
||||
1. **Pattern7/8/9 DomainPlan 追加**: Split, BoolPredicate 等を DomainPlan に追加
|
||||
2. **Normalizer 拡張**: 各 DomainPlan → CorePlan 変換
|
||||
3. **全 Pattern の Plan 化**: Pattern1-5 を段階的に Plan 化
|
||||
Reference in New Issue
Block a user