Commit Graph

21 Commits

Author SHA1 Message Date
a2c5fd90fe feat(joinir): Phase 188.3 - Pattern6 (NestedLoopMinimal) 選択ロジック実装
## Phase 188.3 進捗: Phase 2 完了 (6/13 tasks)

### 実装完了 

**Phase 1: Fixture作成**
- apps/tests/phase1883_nested_minimal.hako 追加
  - Add/Compare のみ(乗算なし)
  - 期待 exit code: 9 (3×3 nested loops)
- 既存 lowering で fallback 動作確認

**Phase 2: 選択ロジック (SSOT)**
- LoopPatternContext に step_tree_max_loop_depth フィールド追加
- choose_pattern_kind() に Pattern6 選択ロジック実装:
  1. Cheap check (has_inner_loop)
  2. StepTree 構築 (max_loop_depth 取得)
  3. AST validation (is_pattern6_lowerable)
- pattern6_nested_minimal.rs モジュール作成 (stub)
- LOOP_PATTERNS に Pattern6 entry 追加
- **検証**: Pattern6 が正しく選択される 

### 設計原則 (確認済み)

1. **Fail-Fast**: Pattern6 選択後は Ok(None) で逃げない
2. **outer 変数 write-back 検出 → validation false** (Phase 188.4+)
3. **最小実装**: inner local だけ、Pattern1 モデル二重化
4. **cfg! 依存なし**: production で動作

### 検証結果

```
[choose_pattern_kind] has_inner_loop=true
[choose_pattern_kind] max_loop_depth=2
[choose_pattern_kind] is_pattern6_lowerable=true
 Pattern6 SELECTED!
```

Stub からの期待エラー:
```
[ERROR]  [Pattern6] Nested loop lowering not yet implemented
```

### 次: Phase 3 (Lowering 実装 - 推定4時間)

残りタスク:
- Phase 3-1: AST 抽出ヘルパー
- Phase 3-2: Validation ヘルパー
- Phase 3-3: Continuation 生成 (outer_step, inner_step, k_inner_exit)
- Phase 3-4: fixture が exit=9 を返すことを検証

### 変更ファイル

**新規**:
- apps/tests/phase1883_nested_minimal.hako
- src/mir/builder/control_flow/joinir/patterns/pattern6_nested_minimal.rs
- docs/development/current/main/phases/phase-188.{1,2,3}/README.md

**変更**:
- src/mir/builder/control_flow/joinir/routing.rs (Pattern6 選択)
- src/mir/builder/control_flow/joinir/patterns/router.rs (Context 拡張)
- src/mir/builder/control_flow/joinir/patterns/mod.rs (module 宣言)

🎯 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-27 05:45:12 +09:00
348b19f42d docs(phase-29y): self-contained consult packet + entry 2025-12-27 01:03:24 +09:00
ba1fc21375 docs(phase-29y): tighten lifecycle vocab consult packet 2025-12-27 00:38:21 +09:00
f74ff6116c refactor(lifecycle): Phase 285 P2.1 hygiene - lifecycle.rs 箱化完了
責務分離により KeepAlive 処理を handlers/lifecycle.rs に隔離:
- handlers/lifecycle.rs 新規作成(47行)
  - handle_keepalive() で drop_after 判定
  - release_strong_refs() で Arc 同一性探索を集約
  - HashSet による O(1) 検索最適化
- handlers/mod.rs を dispatch 専用化(49行削除→1行呼び出し)
- README.md に P2.1 完了状態を記載(SKIP→PASS)
- phase-29y 将来設計相談パケット追加(NyRT ABI/RC insertion pass)

Test: 154/154 PASS 

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 13:36:17 +09:00
65304ec0c4 docs(joinir): Phase 286 Pattern2調査・設計相談パケット追加
- phase286_pattern2_frag_poc.hako: Pattern2 PoC fixture
- phase286_pattern2_frag_poc.sh: integration smoke
- phase-286-plan-normalization-consult.md: Plan正規化の設計相談
- 10-Now.md, 30-Backlog.md: 進捗更新
- pattern2-deferred.md: 更新

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 04:58:38 +09:00
ab76e39036 feat(parser): Phase 285A1.4 & A1.5 - Weak field sugar + Parser hang fix
A1.4: Add sugar syntax `public weak parent` ≡ `public { weak parent }`
A1.5: Fix parser hang on unsupported `param: Type` syntax

Key changes:
- A1.4: Extend visibility parser to handle weak modifier (fields.rs)
- A1.5: Shared helper `parse_param_name_list()` with progress-zero detection
- A1.5: Fix 6 vulnerable parameter parsing loops (methods, constructors, functions)
- Tests: Sugar syntax (OK/NG), parser hang (timeout-based)
- Docs: lifecycle.md, EBNF.md, phase-285a1-boxification.md

Additional changes:
- weak() builtin implementation (handlers/weak.rs)
- Leak tracking improvements (leak_tracker.rs)
- Documentation updates (lifecycle, types, memory-finalization, etc.)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 07:44:50 +09:00
757193891f feat(llvm/phi): Phase 277 P1 - fail-fast validation for PHI strict mode
## Summary
Implemented fail-fast validation for PHI ordering and value resolution in strict mode.

## Changes

### P1-1: Strict mode for "PHI after terminator"
- File: `src/llvm_py/phi_wiring/wiring.py::ensure_phi`
- Behavior: `NYASH_LLVM_PHI_STRICT=1` → RuntimeError if PHI created after terminator
- Default: Warning only (no regression)

### P1-2: Strict mode for "fallback 0"
- File: `src/llvm_py/phi_wiring/wiring.py::wire_incomings`
- Behavior: Strict mode forbids silent fallback to 0 (2 locations)
  - Location 1: Unresolvable incoming value
  - Location 2: Type coercion failure
- Error messages point to next debug file: `llvm_builder.py::_value_at_end_i64`

### P1-3: Connect verify_phi_ordering() to execution path
- File: `src/llvm_py/builders/function_lower.py`
- Behavior: Verify PHI ordering after all instructions emitted
- Debug mode: Shows " All N blocks have correct PHI ordering"
- Strict mode: Raises RuntimeError with block list if violations found

## Testing
 Test 1: strict=OFF - passes without errors
 Test 2: strict=ON - passes without errors (no violations in test fixtures)
 Test 3: debug mode - verify_phi_ordering() connected and running

## Scope
- LLVM harness (Python) changes only
- No new environment variables (uses existing 3 from Phase 277 P2)
- No JoinIR/Rust changes (root fix is Phase 279)
- Default behavior unchanged (strict mode opt-in)

## Next Steps
- Phase 278: Remove deprecated env var support
- Phase 279: Root fix - unify "2本のコンパイラ" pipelines

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 14:48:37 +09:00
4dfe3349bf refactor(mir): phase260 p0 edge-args plumbing (strangler) + ssot api + docs 2025-12-21 04:34:22 +09:00
73ddc5f58d feat(joinir): Phase 257 P1.1/P1.2/P1.3 - Pattern6 SSOT + LoopHeaderPhi CFG fix
P1.1: Pattern6 false positive fix (SSOT approach)
- can_lower() now calls extract_scan_with_init_parts() for SSOT
- index_of_string/2 no longer triggers false positive
- Graceful fall-through with Ok(None)

P1.2: LoopHeaderPhi CFG-based correction
- Step 0: Manual successor update from terminators
- CFG-based entry predecessor computation (header_preds - latch)
- Multi-entry-pred support (bb0 host + bb10 JoinIR main)
- Explicit host_entry_block addition (emit_jump runs after finalize)

P1.3: Smoke script validation
- phase254_p0_index_of_vm.sh: --verify + VM error detection
- phase257 smokes updated

Acceptance criteria (all PASS):
 phase254_p0_index_of_min.hako verify
 phase257_p0_last_index_of_min.hako verify
 ./tools/smokes/v2/run.sh --profile quick (no Pattern6 false positive)

Technical discovery:
- Host entry block (bb0) Jump set in Phase 6 (after finalize)
- instruction_rewriter bypasses set_terminator(), skips successor update

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 23:30:27 +09:00
edc7355937 refactor(joinir): unify boundary join_inputs SSOT (pattern4/6/7)
Apply Phase 256.8 SSOT fix to Pattern4/6/7:
- Use join_module.entry.params.clone() instead of hardcoded ValueIds
- Add fail-fast validation for params count mismatch
- Remove ValueId(0), ValueId(PARAM_MIN + k) patterns
- Clean up unused PARAM_MIN imports

This prevents entry_param_mismatch errors structurally and maintains
consistency with Pattern2/3.

Changes:
- pattern4_with_continue.rs: Lines 442-476 (SSOT extraction + validation)
- pattern6_scan_with_init.rs: Lines 447-471 (SSOT extraction + validation)
- pattern7_split_scan.rs: Lines 495-526 (SSOT extraction + validation)

All patterns now use the same SSOT principle:
1. Extract entry function (priority: join_module.entry → fallback "main")
2. Use params as SSOT: join_inputs = entry_func.params.clone()
3. Build host_inputs in expected order (pattern-specific)
4. Fail-fast validation: join_inputs.len() == host_inputs.len()

Verification:
- cargo build --release:  PASS (no PARAM_MIN warnings)
- Quick profile:  First FAIL still json_lint_vm (baseline maintained)
- Pattern6 smoke:  PASS (index_of test)
- Pattern7 smoke: Pre-existing phi pred mismatch (not introduced by SSOT)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 20:05:11 +09:00
4439d64da3 refactor(joinir): make jump_args layout explicit (Phase 256) 2025-12-20 13:04:24 +09:00
1028bd419c fix(joinir): stabilize Phase 256 merge (jump_args, DCE, func names) 2025-12-20 11:01:48 +09:00
077657b7a1 feat(joinir): Phase 256 P1.5-P1.7 contracts and naming SSOT 2025-12-20 06:38:21 +09:00
4082abb30c feat(normalization): Phase 142 P0 - Loop statement-level normalization
Phase 142-loopstmt P0: Statement-level normalization

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 05:28:49 +09:00
771bf6b0d1 feat(joinir): Phase 132-P3 - Exit PHI collision early detection
Added verify_exit_phi_no_collision() to contract_checks.rs for early detection
of ValueId collisions between exit PHIs and other instructions.

Problem detected:
- If exit_phi_builder uses builder.value_gen.next() (module-level) instead of
  func.next_value_id() (function-level), ValueIds can collide:

  Example:
  - bb0: %1 = const 0   (counter init)
  - bb3: %1 = phi ...   (exit PHI - collision!)

Previous behavior:
- Error only detected at LLVM backend runtime
- Cryptic error: "Cannot overwrite PHI dst=1"

New behavior:
- Panic at Rust compile time (debug build)
- Clear error message with fix suggestion:
  "Exit PHI dst %1 collides with instruction in block 0
   Fix: Use func.next_value_id() in exit_phi_builder.rs"

Benefits:
- 🔥 Fail-Fast: Catch errors during Rust compilation, not LLVM execution
- 📋 Clear messages: Exact collision point + fix suggestion
- 🧪 Testable: verify_exit_phi_no_collision() can be unit tested

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 06:00:48 +09:00
3f58f34592 feat(llvm): Phase 132-P0 - block_end_values tuple-key fix for cross-function isolation
## Problem
`block_end_values` used block ID only as key, causing collisions when
multiple functions share the same block IDs (e.g., bb0 in both
condition_fn and main).

## Root Cause
- condition_fn's bb0 → block_end_values[0]
- main's bb0 → block_end_values[0] (OVERWRITES!)
- PHI resolution gets wrong snapshot → dominance error

## Solution (Box-First principle)
Change key from `int` to `Tuple[str, int]` (func_name, block_id):

```python
# Before
block_end_values: Dict[int, Dict[int, ir.Value]]

# After
block_end_values: Dict[Tuple[str, int], Dict[int, ir.Value]]
```

## Files Modified (Python - 6 files)

1. `llvm_builder.py` - Type annotation update
2. `function_lower.py` - Pass func_name to lower_blocks
3. `block_lower.py` - Use tuple keys for snapshot save/load
4. `resolver.py` - Add func_name parameter to resolve_incoming
5. `wiring.py` - Thread func_name through PHI wiring
6. `phi_manager.py` - Debug traces

## Files Modified (Rust - cleanup)

- Removed deprecated `loop_to_join.rs` (297 lines deleted)
- Updated pattern lowerers for cleaner exit handling
- Added lifecycle management improvements

## Verification

-  Pattern 1: VM RC: 3, LLVM Result: 3 (no regression)
- ⚠️ Case C: Still has dominance error (separate root cause)
  - Needs additional scope fixes (phi_manager, resolver caches)

## Design Principles

- **Box-First**: Each function is an isolated Box with scoped state
- **SSOT**: (func_name, block_id) uniquely identifies block snapshots
- **Fail-Fast**: No cross-function state contamination

## Known Issues (Phase 132-P1)

Other function-local state needs same treatment:
- phi_manager.predeclared
- resolver caches (i64_cache, ptr_cache, etc.)
- builder._jump_only_blocks

## Documentation

- docs/development/current/main/investigations/phase132-p0-case-c-root-cause.md
- docs/development/current/main/investigations/phase132-p0-tuple-key-implementation.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 05:36:50 +09:00
447d4ea246 feat(llvm): Phase 132 - Pattern 1 exit value parity fix + Box-First refactoring
## Phase 132: Exit PHI Value Parity Fix

### Problem
Pattern 1 (Simple While) returned 0 instead of final loop variable value (3)
- VM: RC: 3  (correct)
- LLVM: Result: 0  (wrong)

### Root Cause (Two Layers)
1. **JoinIR/Boundary**: Missing exit_bindings → ExitLineReconnector not firing
2. **LLVM Python**: block_end_values snapshot dropping PHI values

### Fix
**JoinIR** (simple_while_minimal.rs):
- Jump(k_exit, [i_param]) passes exit value

**Boundary** (pattern1_minimal.rs):
- Added LoopExitBinding with carrier_name="i", role=LoopState
- Enables ExitLineReconnector to update variable_map

**LLVM** (block_lower.py):
- Use predeclared_ret_phis for reliable PHI filtering
- Protect builder.vmap PHIs from overwrites (SSOT principle)

### Result
-  VM: RC: 3
-  LLVM: Result: 3
-  VM/LLVM parity achieved

## Phase 132-Post: Box-First Refactoring

### Rust Side
**JoinModule::require_function()** (mod.rs):
- Encapsulate function search logic
- 10 lines → 1 line (90% reduction)
- Reusable for Pattern 2-5

### Python Side
**PhiManager Box** (phi_manager.py - new):
- Centralized PHI lifecycle management
- 47 lines → 8 lines (83% reduction)
- SSOT: builder.vmap owns PHIs
- Fail-Fast: No silent overwrites

**Integration**:
- LLVMBuilder: Added phi_manager
- block_lower.py: Delegated to PhiManager
- tagging.py: Register PHIs with manager

### Documentation
**New Files**:
- docs/development/architecture/exit-phi-design.md
- docs/development/current/main/investigations/phase132-llvm-exit-phi-wrong-result.md
- docs/development/current/main/phases/phase-132/

**Updated**:
- docs/development/current/main/10-Now.md
- docs/development/current/main/phase131-3-llvm-lowering-inventory.md

### Design Principles
- Box-First: Logic encapsulated in classes/methods
- SSOT: Single Source of Truth (builder.vmap for PHIs)
- Fail-Fast: Early explicit failures, no fallbacks
- Separation of Concerns: 3-layer architecture

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-15 03:17:31 +09:00
a955dd6b18 feat(llvm): Phase 131-15 - print/concat segfault 根治修正
## P1-1/P1-2: TypeFacts 優先化
- binop.py: operand facts が dst_type ヒントより優先
- mir_json_emit.rs: Unknown 時に dst_type を出さない
- function_lower.py: value_types を metadata から読み込み

## P2: handle concat 統一(根治)
- print シグネチャ修正: i64(i64) → void(i8*)
- Mixed concat を handle ベースに統一:
  - concat_si/concat_is → concat_hh
  - box.from_i64 で integer を handle 化
  - Everything is Box 哲学に統一
- legacy 関数は互換性のために保持

## 結果
-  print("Result: " + 3) → Result: 3
-  segfault 解消
-  Everything is Box 統一

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-15 01:36:34 +09:00
7f57a1bb05 feat(llvm): Phase 131-13/14 - MIR JSON順序修正 & 2パスsnapshot解決
## Phase 131-13: MIR JSON 命令順序修正
- copy 遅延ロジック削除(~80行)
- MIR の def→use 順序をそのまま出力(SSOT)
- PHI 先頭集約のみ維持

## Phase 131-14: jump-only block 2パス snapshot 解決
- Pass A: jump-only block はメタ記録のみ
- Pass B: resolve_jump_only_snapshots() で CFG ベース解決
- path compression で連鎖を効率的に解決
- サイクル検出で Fail-Fast

## 結果
-  STRICT モードでエラーなし
-  bb7 が bb5 の snapshot を正しく継承
-  ループが正しく動作(1, 2 出力確認)
- ⚠️ print/concat で segfault(別問題、次Phase)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 00:39:43 +09:00
7dfd6ff1d9 feat(llvm): Phase 131-11-H/12 - ループキャリアPHI型修正 & vmap snapshot SSOT
## Phase 131-11-H: ループキャリアPHI型修正
- PHI生成時に初期値(entry block)の型のみ使用
- backedge の値を型推論に使わない(循環依存回避)
- NYASH_CARRIER_PHI_DEBUG=1 でトレース

## Phase 131-12-P0: def_blocks 登録 & STRICT エラー化
- safe_vmap_write() で PHI 上書き保護
- resolver miss を STRICT でエラー化(フォールバック 0 禁止)
- def_blocks 自動登録

## Phase 131-12-P1: vmap_cur スナップショット実装
- DeferredTerminator 構造体(block, term_ops, vmap_snapshot)
- Pass A で vmap_cur をスナップショット
- Pass C でスナップショット復元(try-finally)
- STRICT モード assert

## 結果
-  MIR PHI型: Integer(正しい)
-  VM: Result: 3
-  vmap snapshot 機構: 動作確認
- ⚠️ LLVM: Result: 0(別のバグ、次Phase で調査)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 21:28:41 +09:00
4b87b6cc88 docs: ドキュメント配置ルール(SSOT)確立
## 追加内容
- CLAUDE.md にドキュメント配置ルール(SSOT)セクション追加
- DOCS_LAYOUT.md (SSOT): 置き場所ルール定義
- phases/README.md: Phase ドキュメント説明
- design/README.md: 設計図ドキュメント説明
- investigations/README.md: 調査ログ説明

## ルール概要
1. **Phase 文書** → phases/phase-<N>/
2. **設計図** → design/
3. **調査ログ** → investigations/ (結論を 10-Now/20-Decisions に反映)

## 導線
- CLAUDE.md で概要説明
- DOCS_LAYOUT.md で詳細定義(SSOT)
- 各フォルダ README で参照方法

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-14 18:27:24 +09:00