IR and SSA Form TODO
Concept
An IR (intermediate representation) sits between the source language and the target machine so that optimization and code-generation logic scales as (languages + targets) instead of (languages x targets). SSA (static single assignment) is an IR form in which every variable is assigned exactly once; at points where control flow merges, a phi function picks a value depending on which predecessor block execution came from. Because every use points to a unique definition, def-use relationships are explicit in the representation itself, which makes optimizations like constant propagation, dead-code elimination, and common-subexpression elimination simpler without a separate dataflow analysis. Where to place phi functions is computed from the dominance frontier, derived from the dominance relation; just before register allocation, an out-of-SSA pass lowers phi nodes into copy instructions.
Modern optimization in LLVM, the Go compiler, most JITs, and even Solidity's Yul-based IR pipeline all run on top of SSA, so reading why some code gets optimized and some doesn't requires thinking in SSA.
Code & Formula
# IR과 SSA 형식 — 분기가 있는 프로그램을 SSA로 변환하고 phi 노드로 값을 합류시킨다.
# 원본: x=1; if cond: x=2; y = x+1 → SSA: x1=1; (분기) x2=2; x3=phi(x1,x2); y=x3+1
def original(cond):
x = 1
if cond:
x = 2
y = x + 1
return y
def ssa_form(cond):
x1 = 1 # entry 블록에서의 정의
x2 = None
if cond:
x2 = 2 # then 블록에서의 새 정의 (재대입이 아니라 새 이름)
pred = "then"
else:
pred = "entry"
# 합류 지점의 phi: 어느 선행 블록에서 왔는지에 따라 값을 고른다
x3 = x2 if pred == "then" else x1
y = x3 + 1
return y
for cond in (True, False):
o, s = original(cond), ssa_form(cond)
print(f"cond={cond}: original={o}, ssa={s}, 일치={o == s}")
assert o == s
docs/code/algorithms/algorithms-20.py
Exercise
Hand-convert a short function containing a branch and a loop into SSA form, placing the phi nodes yourself, then compare it side by side with an actual compiler's SSA dump (e.g., Go's GOSSAFUNC output).
Practical Connection
When judging why a particular construct in solc's optimizer settings or Go runtime code ends up using more instructions and more gas, looking at what folds away and what survives at the IR level — not the source level — is the most reliable evidence.
Where it lands in Jayverse
- CI: add a gas-snapshot check that diffs IR-level (Yul) output, not just gas totals, for Verex, Token and Bridge contracts. A regression becomes traceable to what stopped folding rather than just a number moving.
- Token: when tuning the mini-AMM or bridge contracts for gas, read the Yul/SSA dump before hand-optimizing Solidity. This follows this page's own method for judging what survives at the IR level.
- gitboard: surface a per-contract gas-cost trend on the dashboard. An IR-level regression shows up before it reaches real gas costs.
Key expressions
| Expression | 뜻 · 쓰이는 자리 |
|---|---|
| scale as | (증가율이) ~형태로 커지다 · 작업량이 곱셈이 아니라 덧셈으로 늘어나는 구조적 이점을 말할 때. "scales as (languages + targets)" |
| merge (control flow) | 합류하다, 흐름이 하나로 합쳐지다 · 여러 실행 경로가 한 지점에서 만날 때. "at points where control flow merges" |
| explicit | 명시적인, 드러나 있는 · 굳이 따로 분석하지 않아도 표현 자체에 정보가 드러날 때. "def-use relationships are explicit in the representation itself" |
| derive from | ~에서 도출되다, 유도되다 · 어떤 개념이 다른 개념을 바탕으로 계산되어 나올 때. "derived from the dominance relation" |
| lower (into) | (더 낮은 단계로) 변환하다 · 상위 표현을 하위 명령어 형태로 바꿔 내릴 때. "an out-of-SSA pass lowers phi nodes into copy instructions" |
| fold away | 접혀서 사라지다, 소거되다 · 최적화 과정에서 불필요한 코드가 없어질 때. "what folds away and what survives at the IR level" |
| optimizer settings | 최적화 설정 · 컴파일러가 코드를 얼마나·어떻게 최적화할지 정하는 옵션. "a change in compiler optimization settings" |
| IR | 중간표현(Intermediate Representation) · 소스 언어와 타깃 머신 사이에 두어 최적화·코드생성 로직이 (언어+타깃) 규모로만 커지게 하는 계층. "An IR (intermediate representation) sits between the source language" |
| SSA | 정적 단일 대입 형식(Static Single Assignment) · 모든 변수가 딱 한 번만 대입되는 IR 형태, 최적화를 단순하게 만드는 핵심 전제. "SSA (static single assignment) is an IR form" |
| LLVM | LLVM · 여러 언어·타깃이 공유하는 대표적인 컴파일러 인프라 프로젝트, SSA 기반 최적화를 쓰는 대표 사례로 언급. "Modern optimization in LLVM, the Go compiler, most JITs" |
| GOSSAFUNC | GOSSAFUNC · Go 컴파일러가 특정 함수의 SSA 변환 과정을 단계별로 덤프해 보여주는 환경변수/도구. "Go's GOSSAFUNC output" |
| phi function | 파이 함수(phi function) · 여러 실행 경로가 합류하는 지점에서 어느 분기에서 왔는지에 따라 값을 선택하는 SSA 전용 구성 요소. "a phi function picks a value depending" |
| dominance frontier | 지배 프론티어(dominance frontier) · phi 함수를 어디에 배치해야 하는지 계산해주는 그래프 이론 개념, dominance relation에서 유도됨. "computed from the dominance frontier" |
If you study this on a given day, add a note link and a ✅ to this line in the source curriculum (docs/knowledge/dev-100-curriculum.md) and this spot will lead straight to the note body. You can also write directly on this page — but regenerating overwrites it, so it's safer to keep anything you want to save as markdown under docs/algorithms/.