Files
hakorune/docs/private/papers/paper-e-loop-signal-ir/main-paper-jp.md

210 lines
11 KiB
Markdown
Raw Normal View History

# LifeBox Model と LoopForm IR: Box指向実行系における制御の値化と統一
> 統一直観(融合案): 「Everything is Box空間×「Everything is Loop時間
>
> すべての箱は“ループ1回Loop1の箱”として捉えられ、制御は LoopSignalNext/Break/Yield[/Return])という値で運ばれる。
## 概要
本稿は、Nyashの「Everything is Box」を拡張する概念 LifeBox ModelLBM: Box=Loop1と、その思想をIR上で実現する LoopForm IR別名: LoopSignal IRを提案する。分岐・関数・スコープ・反復・ジェネレータ・async を「Loop=反復の箱」に正規化し、制御結果を値Signalとして扱う。IRレベルでは `loop.begin / loop.iter / loop.branch / loop.end` による標準ディスパッチ形を導入する。これにより、Front-endのLoweringが一様化し、CFGの合流点が定型化dispatchブロックへ集約され、PHIの整理・最適化DCE/LICM/インラインが素直になる。Loop1 は完全インライン化によりオーバーヘッドを排除可能である。
なお、LoopFormは中間正規形であり、最終的にはCore13 IR固定13命令に再Loweringできることを前提とする後方互換を常時確保
本稿はコンセプト草稿であり、論文AMIR13/IR設計の後、短論文/ワークショップ稿として展開する。
### Executive Summary1ページ要約
- 目的: if/while/for/scope/function/generator/async を LoopBox+LoopSignal に正規化し、Lowering/最適化/拡張を単純化する。
- 中核: SignalNext/Break/Yield[/Return])をタグ付き値で表し、`loop.begin/iter/branch/end` の4命令で統一ディスパッチ。
- 融合: 「普通の箱」も Loop1 として扱いinit/step/fini、スコープ=Loop1 を基本単位にする。
- 実利: 合流点の定型化により PHI/支配木が単純化。Loop1はインライン畳み込みでオーバーヘッドゼロ。generator/asyncは Signal 拡張のみで実装可能。
## 1. 背景と動機
- 現行MIR13は、BoxCall統一によりデータ操作を簡素化した。一方で制御構造if/loop/call/return/scopeは表現が分散し、Loweringと最適化で個別処理が残る。
- 制御を「値化Signal」し、Loopの反復単位で標準ディスパッチすることで、表現・Lowering・最適化・拡張generator/async/effectのすべてを一様化できる。
## 2. 提案: LoopSignal IR の最小仕様
- Signal 型: `LoopSignal<T> = Next(T) | Break(T) | Yield(T) [| Return(T)]`
- 擬似命令IR注釈:
- `loop.begin %id`
- `loop.iter %sig, %loop, %state` // 反復1回実行LoopBoxの一回分
- `loop.branch %sig { onNext: L1, onBreak: L2, onYield: L3 }`
- `loop.end %id`
- LoopBox: 反復1回の本体。入力 `state` を受け `LoopSignal<...>` を返す小さな「箱」。
### 2.1 型の実体化LLVM想定
```llvm
%LoopSignal_T = type { i8 /*tag:0=Next,1=Break,2=Yield,3=Return*/, T /*payload*/ }
; switch %tag で L_next/L_break/L_yield/L_return へ分岐
```
### 2.2 Box=Loop1 の取り決め
- どの Box も `init -> step -> fini` を持つとみなせる。
- 「通常の箱」は `step()` が 1 回で `Break(result)` を返す(= Loop1
- RAII/using/defer は `init/fini` に収容され、`loop.begin/end` に対応付ける。
## 3. 正規化Lowering規則
### 3.0 記法: 二層構造(表記と内部)
表記従来構文と内部LoopFormを併存させ、内部では常にLoopFormへ正規化する。
```
// 従来: 複雑な分岐
if (x) { a() } else { b() }
while (y) { c() }
func() { d() }
// ループ統一: シンプル(内部正規形のイメージ)
loop { x ? break(a()) : next }
loop { y ? next : break }
loop { break(d()) }
// 「複雑に見えるのは慣れの問題」→ 表記は従来も提供、内部はLoopで統一
```
### 3.1 スコープ `{ ... }` → Loop1
```
{
x = 1
y = 2
}
```
```mir
%lp = loop.begin
%s0 = Const(void)
%sg = loop.iter %lp, %s0
loop.branch %sg { onBreak: Lb, onNext: Ln }
Ln: jump Ld
Lb: loop.end %lp; jump Ld
Ld: ; 続き
```
解釈: Blockを「1回だけ回る Loop」と見なし、`iter` は即時 `Break` を返す。
### 3.2 while ループ
```mir
%lp = loop.begin
%s = Const(init)
Lh:
%sg = loop.iter %lp, %s
loop.branch %sg { onNext: Lh, onBreak: Lb }
Lb:
loop.end %lp
```
### 3.3 for-inLoopBox化の雛形
```mir
func LoopBox_for(state: ForState, env: Env) -> LoopSignal<ForState> {
%x, %st' = iter_next(state)
br_if %x==None -> return Break(state)
call body(%x, env)
return Next(%st')
}
%lp = loop.begin
%sig = loop.iter %lp, %init
Ldisp:
loop.branch %sig { onNext: Lnext, onBreak: Lbr }
Lnext:
%st = extract_next(%sig)
%sig = loop.iter %lp, %st
jmp Ldisp
Lbr:
%fin = extract_break(%sig)
loop.end %lp
ret finalize(%fin)
```
### 3.4 関数呼び出し/return → Loop1
`return v``Break(Return v)` として統一可能実装ではReturnをSignalに含めるか分離を選択
### 3.5 generator/async
`Yield` をSignalに含め、`onYield` 分岐でハンドリング。状態は `state` に保持。
## 4. 実装方針(安全な導入順序)
1) LoopSignal 型と `loop.*` ードをMIRに追加オプトイン
2) while/for/スコープのみ LoopForm にLoweringif/関数は従来)
3) LoopForm → 従来MIRへの逆Loweringパス実装常時オフに戻せる
4) 最適化: Loop1 の完全インライン化、Yieldなしの状態保存省略、支配関連の簡略解析
5) 拡張: generator/async → effect必要なら
6) フォールバック: 互換性のため LoopForm→従来MIR への逆Loweringを維持フラグで切替
## 4.1 コア要件(不変条件 / Core Invariants
- ループ正規形: すべての制御は `loop.begin → loop.iter → loop.branch → loop.end` の列で現れ、dispatchブロックで合流PHIはdispatch直後のみ
- Signal整合性: `LoopSignal<T> = Next/Break/Yield/Return` は i8タグ1ペイロードSSA値。4タグは相互排他。
- 単一継続点: 各Loopは1つの出口break/return合流点を持つ。Loop1は必ず畳み込み可能inlineでゼロコスト
- 可逆性: LoopForm → Core13現行MIRへの逆Loweringが常に可能フラグでON/OFF安全導入
## 5. 評価計画
- 表現の簡潔さ: ブロック数・分岐数・PHI数の変化
- コンパイラ時間: Lowering/最適化の時間(±)
- 実行性能: VM/JIT/AOTで従来MIRとの差同等〜微差で良い。主眼は実装簡易性。
- 拡張容易性: generator/asyncの実装コード量・変更影響の定量化
### 5.1 最初のPoC課題段階的
1. `while(true){break}` を Loop1 に変換 → 命令数/PHI/実行時間を計測
2. `for-in` をステートマシン化 → Next/Break 型で VM/AOT の一致を検証
3. `yield` 付き最小ジェネレータ → 状態保持と再開の健全性(再現テスト)
### 5.2 受入基準Acceptance
- MIR構造: dispatch合流点のみでPHIPrinterで自明にわかる
- 差分実行: 5スモークconst/return, add, branch+phi, while, nested-branchが現行MIRとVM結果一致
- 観測: covered/unsupported と decisions(allow,fallback) をLoopForm/逆Lowering双方で採取
## 6. 関連研究と差分
- CPS/継続: 制御を関数化するが、LoopSignalは「値としての制御」をMIRで直接扱う点が異なるCPS変換を前提にしない
- 代数的効果/ハンドラ: 近いが、最小Signal集合loop.*に限定し実用性を優先。
- コルーチン/ジェネレータ: 専用機構に閉じず、関数/スコープまでLoop1として統一。
- Smalltalk/Lispの統一思想: 本稿は制御フローの大統一をMIRで具体化。
補足: MLIR/Swift SIL/Rust MIR 等のSSA系IRと比較すると、本稿は「制御時間側の正規化」をMinimal命令で達成し、最適化・実装コストの低減を主眼に置く。
## 7. 限界と今後
- 説明コスト: 初学者負荷。導入は while/for のみから段階的に。
- オーバーヘッド: Loop1は必ず即時畳み込みインライン化で無害化。
- デバッグ: loop.begin にソース範囲・ID埋め込み、iterで行情報維持。
---
付録:名前候補(査読者向け)
- Signal Loop IRSLIR/ LoopSignal FormLSF/ Boxed Loop SemanticsBLS/ LoopBox IR
## 8. 外部レビュー統合と確定方針Claude/Gemini 要点)
本案に対する外部AIレビューclaude_output.md / gemini_output.mdの要点を統合し、当面の確定方針を示す。
- 型表現LoopSignal<T>: Next/Break/Yield/Return を採用Geminiの Continue 提案は命名差。既存説明と整合する Next を採用)。タグは i8 固定、ペイロードはSSA値。
- 返却の扱い: Return を Signal に含める「統一モデル」を採用Claude/Gemini一致。IR直交性と最適化容易性を優先。
- MIR命令の厳密化: loop.begin / loop.iter / loop.branch / loop.end の4命令でLoopFormを定義。PHI配置点は loop.begin合流標準形に確定。
- LLVM/ABI: まずは { i8 tag, payload } の素直なstruct表現で実装し、ホットパスNextを既存最適化に委ねる。必要なら将来特殊化を導入。
- 逆Lowering互換性: LoopForm→従来MIRへの逆変換パスをフラグでON/OFF可能に--no-loop-signal-ir。段階的導入で安全性を担保。
- 最適化パス: 1) Loop1完全インライン化 2) Yieldなし状態省略 3) 分岐合流点正規化dispatch集中を優先実装。既存DCE/LICM/Inlineとの整合を確認。
- 適用範囲の段階化: while/for/scope から導入(関数/ifは後追い。例外・effects代数的効果/ハンドラ)は将来拡張として外出し。
- ドキュメント方針: LoopFormは「中間正規形」であり、最終的にCore-13に再Loweringできることを明記実装も常時オン/オフ可能)。
実装ロードマップ(最小到達順)
1) LoopSignal型・loop.*命令IRード追加ビルドフラグでオプトイン
2) while/for/scope のLoweringをLoopFormへ移行if/関数は現状)
3) 逆LoweringLoopForm→従来MIRを完成、デフォルトONで安全運用可に
4) 最適化: Loop1 inline / Yieldなし省略 / dispatch統合の3本
5) 評価: 表現簡潔さPHI/ブロック数)、コンパイラ時間、実行性能(同等〜微差で良い)
6) 適用拡大: 関数/if、generator/asyncReturn/YieldのSignal化
付録:用語の二元性(覚え方)
- Box空間= データ/資源の単位。Instance化で1反復を生む。
- Loop時間= 制御/継続の単位。Next/Break/Yield で時間を進める/止める。