AST/ProgramJSON から OwnershipPlan を生成する解析箱を実装。 Key changes: - New analyzer.rs (632 lines): - OwnershipAnalyzer: Main analysis engine - ScopeKind: Function/Loop/Block/If scope types - ScopeInfo: Internal scope representation with reads/writes tracking Algorithm: 1. Build scope tree (Function/Loop/Block/If hierarchy) 2. Collect reads/writes/condition_reads per scope 3. Apply body-local ownership rule (if/block locals → enclosing Loop/Function) 4. Generate OwnershipPlan: owned_vars, relay_writes, captures, condition_captures Core invariants enforced: - Ownership Uniqueness: Each variable has exactly one owner - Carrier Locality: carriers = writes ∩ owned - Relay Propagation: writes to ancestor-owned → relay up - Capture Read-Only: captures have no PHI at this scope Tests: 7 ownership unit tests + 946 existing (0 regressions) - test_simple_loop_ownership: relay writes to function - test_loop_local_carrier: owned AND written = carrier - test_capture_read_only: read-only captures - test_nested_loop_relay: relay chains through nested loops Design: "読むのは自由、管理は直下だけ" Phase 57 is dev-only - not yet connected to lowering. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
6.3 KiB
6.3 KiB
Phase 57: OWNERSHIP-ANALYZER-DEV - Summary
Status: ✅ COMPLETED
Date: 2025-12-12 Duration: Single session implementation Test Results: All 946 tests passing (56 ignored)
What Was Implemented
1. Naming SSOT Fix
- Unified naming:
owned_vars(code) vsowned_carriers(docs) - Decision: Keep
owned_varsin code (more general - includes read-only owned) - Updated all documentation to use
owned_varsconsistently
2. Core Analyzer Implementation
Created /home/tomoaki/git/hakorune-selfhost/src/mir/join_ir/ownership/analyzer.rs:
- OwnershipAnalyzer: Main analysis engine (420+ lines)
- ScopeKind: Function/Loop/Block/If scope types
- ScopeInfo: Internal scope representation with defined/reads/writes/condition_reads
3. Analysis Algorithm
Scope Tree Construction
- Function/Loop/Block/If each get unique ScopeId
- Parent-child relationships tracked via scope hierarchy
- Body-local ownership rule:
localin if/block → enclosing Loop/Function owns it
Variable Collection (per scope)
defined: Variables declared withlocalin this scopereads: All variable reads (including nested scopes)writes: All variable writes (including nested scopes)condition_reads: Variables read in loop/if conditions
Ownership Assignment
owned_vars= variables defined in Loop/Function scopes- Carriers =
owned_vars.filter(is_written == true) - Read-only owned variables are NOT carriers
Plan Generation
relay_writes= writes - owned (find owner in ancestors)captures= reads - owned - writes (read-only captures)condition_captures= captures ∩ condition_reads
4. Key Implementation Decisions
Smart Propagation
Fixed issue where parent scopes were trying to relay variables owned by child Loop/Function scopes:
// Only propagate writes that are NOT locally owned by Loop/Function children
if child_kind == ScopeKind::Loop || child_kind == ScopeKind::Function {
// Don't propagate writes for variables defined in this Loop/Function
for write in writes {
if !child_defined.contains(&write) {
parent.writes.insert(write);
}
}
} else {
// For If/Block, propagate all writes
parent.writes.extend(writes);
}
Relay Path Construction
- Walk up ancestor chain to find owner
- Collect only Loop scopes in relay_path (skip If/Block)
- Inner loop → Outer loop → Function (relay chain)
Invariant Verification (debug builds only)
- No variable appears in multiple categories (owned/relay/capture)
- All relay_writes have valid owners
- condition_captures ⊆ captures
5. Comprehensive Test Suite
Implemented 4 test cases covering all major scenarios:
- test_simple_loop_ownership: Basic loop with relay writes to function
- test_loop_local_carrier: Loop-local variable (owned AND written)
- test_capture_read_only: Read-only capture in loop condition
- test_nested_loop_relay: Nested loops with relay chain
All tests pass ✅
6. Documentation Updates
- Updated
phase56-ownership-relay-design.mdwith Phase 57 algorithm section - Updated
mod.rsto reflect Phase 57 completion status - Clear separation: analyzer = dev-only, not connected to lowering yet
Architecture Highlights
Responsibility Boundary
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
Core Invariants Enforced
- Ownership Uniqueness: Each variable has exactly one owner scope
- Carrier Locality: carriers = writes ∩ owned
- Relay Propagation: writes to ancestor-owned → relay up
- Capture Read-Only: captures have no PHI at this scope
Files Changed
New Files
/home/tomoaki/git/hakorune-selfhost/src/mir/join_ir/ownership/analyzer.rs(420+ lines)
Modified Files
/home/tomoaki/git/hakorune-selfhost/src/mir/join_ir/ownership/mod.rs(export analyzer)/home/tomoaki/git/hakorune-selfhost/docs/development/current/main/phase56-ownership-relay-design.md(algorithm section)
Test Results
running 7 tests
test mir::join_ir::ownership::analyzer::tests::test_capture_read_only ... ok
test mir::join_ir::ownership::types::tests::test_carriers_filter ... ok
test mir::join_ir::ownership::analyzer::tests::test_nested_loop_relay ... ok
test mir::join_ir::ownership::types::tests::test_invariant_verification ... ok
test mir::join_ir::ownership::analyzer::tests::test_loop_local_carrier ... ok
test mir::join_ir::ownership::analyzer::tests::test_simple_loop_ownership ... ok
test mir::join_ir::ownership::types::tests::test_empty_plan ... ok
test result: ok. 7 passed; 0 failed; 0 ignored
Full test suite: 946 tests passed, 0 failed, 56 ignored ✅
Next Steps (Phase 58+)
Phase 58: P2 Plumbing (dev-only)
- Connect analyzer to Pattern 2 lowering
- Generate PHI instructions based on OwnershipPlan
- Test with P2 loops
Phase 59: P3 Plumbing (dev-only)
- Connect analyzer to Pattern 3 lowering
- Handle relay chains in nested loops
- Test with P3 loops
Phase 60: Cleanup Dev Heuristics
- Remove old carrier detection logic
- Switch to OwnershipPlan throughout
Phase 61: Canonical Promotion Decision
- Finalize promotion strategy
- Production rollout
Design Philosophy
"読むのは自由、管理は直下だけ" (Read Freely, Manage Directly)
- Variables can be READ from anywhere (capture)
- Variables can only be WRITTEN by their owner or via relay
- Ownership is determined by definition scope (body-local rule)
- No shadowing complexity - clear ownership hierarchy
Dev-First Approach
- Implemented as pure analysis module first
- Not yet connected to lowering (no behavioral changes)
- Can be tested independently with JSON input
- Safe to merge without affecting existing code paths
References
- Phase 56 Design: phase56-ownership-relay-design.md
- JoinIR Architecture: joinir-architecture-overview.md
- Phase 43/245B: Normalized JoinIR completion
- ChatGPT Discussion: 「読むのは自由、管理は直下だけ」設計
Implementation Status: ✅ Phase 57 Complete - Ready for Phase 58 plumbing