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

11 KiB
Raw Blame 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想定

%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
}

%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 ループ

%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化の雛形

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 vBreak(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: 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 で時間を進める/止める。