2.4 KiB
2.4 KiB
Phase 29y: RC insertion SSOT(1箇所で決める)
Status: Ready (docs-first, post self-host)
Scope: retain/release/weak_drop の発火点を “分散実装しない” ための SSOT を固定する。
0. 目的
- RCイベント(retain/release/weak_drop)を 1箇所で挿入し、backend差と hidden root を減らす
- 「SSA last-use = 寿命」にならないよう、drop点を binding scope / explicit drop / 上書きに限定する
1. 置き場所(SSOT)
推奨: emit_frag() で CFG が確定した後、codegen直前に 1回だけ走る “RC insertion pass”
- ここなら PHI/loop/early-exit/cleanup を全部見た状態で挿入できる
- lowering 各所に retain/release を散らさない(SSOTを壊さない)
2. 入力と出力(概念)
入力:
- “CFG確定後” の IR(Frag / block graph)
- 変数スコープ境界(binding scope)の情報
出力:
- RCイベントが明示された IR(例:
rc.retain,rc.release,rc.weak_dropの effect 列)
重要:
- RCイベント列は “見える化” であり、RCの実体(カウンタ値/Alive判定)は runtime(NyRT)に委譲する
3. drop点の規則(最小)
禁止(意味論を壊しやすい):
- SSA last-use を根拠に release する(weak_to_strong で観測できて破綻し得る)
許可(意味論に沿う):
- explicit drop:
x = nullの直前に “旧値の release” - 上書き:
x = <new>の直前に “旧値の release” - スコープ終端: binding scope の終端で “そのスコープの binding が保持していた current value の release”
4. PHI / loop / early-exit の罠(最低限)
- PHI: “入力値” を間違って release すると破綻する。drop対象は binding の current value と一致する必要がある
- loop: back-edge とスコープ終端の相互作用(継続で生存する値/上書きされる値)を分類する
- early-exit(return/break/continue): exit edge により “どのスコープが閉じるか” が変わるため、cleanupと統合する必要がある
5. 実装に切る時の最小タスク(3つ以内)
- insertion pass の入口/出口を固定(どのIRを入力にし、何を出力するか)
- drop点の規則を最小実装(上書き/explicit drop/スコープ終端)
- verify(不変条件)を追加(PHI/edge数と drop点が矛盾しないこと)