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.
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/.