「読むのは自由、管理は直下 owned だけ」アーキテクチャの設計文書と型定義。 Key changes: - Design doc: phase56-ownership-relay-design.md - Core definitions: owned/carriers/captures/relay - Invariants: Ownership Uniqueness, Carrier Locality, Relay Propagation - Shadowing rules, multi-writer merge semantics - JoinIR mapping from current system to new system - Implementation phases roadmap (56-61) - New module: src/mir/join_ir/ownership/ - types.rs: ScopeId, ScopeOwnedVar, RelayVar, CapturedVar, OwnershipPlan - mod.rs: Module documentation with responsibility boundaries - README.md: Usage guide and examples - API methods: - OwnershipPlan::carriers() - owned AND written variables - OwnershipPlan::condition_only_carriers() - condition-only carriers - OwnershipPlan::verify_invariants() - invariant checking Tests: 942/942 PASS (+3 unit tests) Zero behavioral change - analysis module skeleton only. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
225 lines
5.6 KiB
Markdown
225 lines
5.6 KiB
Markdown
# Phase 56: Ownership-Relay Design
|
||
|
||
## Overview
|
||
「読むのは自由、管理は直下 owned だけ」アーキテクチャの設計文書。
|
||
|
||
Phase 56 は **インターフェース設計のみ**。実装は Phase 57 以降。
|
||
|
||
## Core Definitions
|
||
|
||
### owned (所有)
|
||
- 変数を定義したスコープが唯一の owner
|
||
- Loop直下の `local x` → そのループが owned
|
||
- body-local(if/block内の local)→ 最も内側の enclosing loop が owned
|
||
|
||
**例**:
|
||
```rust
|
||
fn outer() {
|
||
local a = 0 // owned by outer
|
||
loop {
|
||
local b = 0 // owned by this loop
|
||
if cond {
|
||
local c = 0 // owned by enclosing loop (not if!)
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### carriers (管理対象)
|
||
- `carriers = writes ∩ owned`
|
||
- そのスコープが定義 AND 更新する変数のみ
|
||
- loop_step の引数として管理
|
||
|
||
**重要**: Carrier は「所有 AND 更新」のみ。読み取り専用の owned 変数は carrier ではない。
|
||
|
||
### captures (読み取り参照)
|
||
- `captures = reads \ owned` (かつ carriers ではない)
|
||
- 祖先スコープの変数への read-only アクセス
|
||
- CapturedEnv / ConditionEnv 経由
|
||
|
||
**例**:
|
||
```rust
|
||
local limit = 100
|
||
loop {
|
||
local sum = 0
|
||
if sum < limit { // limit は capture (read-only)
|
||
sum++ // sum は carrier (owned + written)
|
||
}
|
||
}
|
||
```
|
||
|
||
### relay (中継)
|
||
- 内側スコープが祖先 owned を更新する場合
|
||
- 更新責務を owner へ昇格(relay up)
|
||
- 中間ループは引数として素通し
|
||
|
||
**例**:
|
||
```rust
|
||
loop outer {
|
||
local total = 0 // owned by outer
|
||
loop inner {
|
||
total++ // relay to outer (inner doesn't own total)
|
||
}
|
||
}
|
||
// outer の exit PHI で total を merge
|
||
```
|
||
|
||
## Invariants (不変条件)
|
||
|
||
1. **Ownership Uniqueness**: 各変数は唯一の owner を持つ
|
||
2. **Carrier Locality**: carriers = writes ∩ owned (借用なし)
|
||
3. **Relay Propagation**: writes \ owned → owner に昇格
|
||
4. **Capture Read-Only**: captures は read-only (PHI 不要)
|
||
|
||
## Shadowing Rules
|
||
|
||
```nyash
|
||
local x = 0 // outer owned
|
||
loop {
|
||
local x = 1 // inner owned (shadows outer)
|
||
// 外の x は capture 可能だが、inner の x が優先
|
||
print(x) // inner の x (1)
|
||
}
|
||
print(x) // outer の x (0)
|
||
```
|
||
|
||
- Shadowing = 新しい ownership 発生
|
||
- 名前解決は最内スコープ優先
|
||
- 外の x は capture として参照可能だが、内の x が存在する限り内が優先
|
||
|
||
## Multi-Writer Merge
|
||
|
||
```nyash
|
||
loop outer {
|
||
local total = 0
|
||
if a { loop inner1 { total++ } } // relay to outer
|
||
if b { loop inner2 { total-- } } // relay to outer
|
||
}
|
||
// outer の exit PHI で merge
|
||
```
|
||
|
||
- Relay は「更新意図の伝達」
|
||
- 実際の PHI merge は owner 側で実行
|
||
- 複数の内側ループが同じ変数を relay → owner の exit PHI で統合
|
||
|
||
## JoinIR Mapping
|
||
|
||
### Current System → New System
|
||
|
||
| Current | New |
|
||
|---------|-----|
|
||
| CarrierInfo.carriers | OwnershipPlan.owned_carriers |
|
||
| promoted_loopbodylocals | (absorbed into owned analysis) |
|
||
| CapturedEnv | OwnershipPlan.captures |
|
||
| ConditionEnv | OwnershipPlan.condition_captures |
|
||
| (implicit) | OwnershipPlan.relay_writes |
|
||
|
||
### OwnershipPlan Structure
|
||
|
||
```rust
|
||
pub struct OwnershipPlan {
|
||
pub scope_id: ScopeId,
|
||
pub owned_carriers: Vec<ScopeOwnedVar>,
|
||
pub relay_writes: Vec<RelayVar>,
|
||
pub captures: Vec<CapturedVar>,
|
||
pub condition_captures: Vec<CapturedVar>,
|
||
}
|
||
```
|
||
|
||
**設計意図**:
|
||
- `owned_carriers`: このスコープが所有 AND 更新する変数
|
||
- `relay_writes`: 祖先の変数への書き込み(owner へ昇格)
|
||
- `captures`: 祖先の変数への読み取り専用参照
|
||
- `condition_captures`: captures のうち、条件式で使われるもの
|
||
|
||
## Implementation Phases
|
||
|
||
- **Phase 56**: Design + interface skeleton (this phase) ✅
|
||
- **Phase 57**: OwnershipAnalyzer implementation (dev-only)
|
||
- **Phase 58**: P2 plumbing (dev-only)
|
||
- **Phase 59**: P3 plumbing (dev-only)
|
||
- **Phase 60**: Cleanup dev heuristics
|
||
- **Phase 61**: Canonical promotion decision
|
||
|
||
## Module Boundary
|
||
|
||
`src/mir/join_ir/ownership/` - 責務は「解析のみ」
|
||
|
||
**This module does**:
|
||
- ✅ Collect reads/writes from AST/ProgramJSON
|
||
- ✅ Determine variable ownership (owned/relay/capture)
|
||
- ✅ Produce OwnershipPlan for downstream lowering
|
||
|
||
**This module does NOT**:
|
||
- ❌ Generate MIR instructions
|
||
- ❌ Modify JoinIR structures
|
||
- ❌ Perform lowering transformations
|
||
|
||
Lowering/MIR生成は既存モジュールが担当。
|
||
|
||
## Example Ownership Plans
|
||
|
||
### Example 1: Simple Loop
|
||
|
||
```nyash
|
||
local sum = 0
|
||
loop {
|
||
sum++
|
||
}
|
||
```
|
||
|
||
**OwnershipPlan (loop scope)**:
|
||
- `owned_carriers`: [`sum` (written)]
|
||
- `relay_writes`: []
|
||
- `captures`: []
|
||
|
||
### Example 2: Nested Loop with Relay
|
||
|
||
```nyash
|
||
local total = 0
|
||
loop outer {
|
||
loop inner {
|
||
total++
|
||
}
|
||
}
|
||
```
|
||
|
||
**OwnershipPlan (inner loop)**:
|
||
- `owned_carriers`: []
|
||
- `relay_writes`: [`total` → relay to outer]
|
||
- `captures`: []
|
||
|
||
**OwnershipPlan (outer loop)**:
|
||
- `owned_carriers`: [`total` (written via relay)]
|
||
- `relay_writes`: []
|
||
- `captures`: []
|
||
|
||
### Example 3: Capture + Carrier
|
||
|
||
```nyash
|
||
local limit = 100
|
||
loop {
|
||
local sum = 0
|
||
if sum < limit {
|
||
sum++
|
||
}
|
||
}
|
||
```
|
||
|
||
**OwnershipPlan (loop scope)**:
|
||
- `owned_carriers`: [`sum` (written)]
|
||
- `relay_writes`: []
|
||
- `captures`: [`limit` (read-only)]
|
||
- `condition_captures`: [`limit`]
|
||
|
||
## References
|
||
- **Phase 53-54**: Structural axis expansion
|
||
- **Phase 43/245B**: Normalized JoinIR completion
|
||
- **ChatGPT discussion**: 「読むのは自由、管理は直下だけ」設計
|
||
- **JoinIR Architecture**: [joinir-architecture-overview.md](joinir-architecture-overview.md)
|
||
|
||
## Status
|
||
|
||
- ✅ Phase 56 (this): Design + interface skeleton completed
|
||
- ⏳ Phase 57+: Implementation pending
|