Skip to content

Commit 5baaafd

Browse files
Rework introduction to SSA-IR in dev docs (#49796)
Primary authorship credits for this go to Oscar Smith. This reworks the introduction to the SSA-IR section of the manual to give a brief introduction to SSA to prepare the reader with a short example. We also rework the Background and IR Node types sections. Co-authored-by: Oscar Smith <[email protected]>
1 parent 5a33c70 commit 5baaafd

File tree

1 file changed

+50
-4
lines changed

1 file changed

+50
-4
lines changed

doc/src/devdocs/ssair.md

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,53 @@
11
# Julia SSA-form IR
22

3+
Julia uses a static single assignment intermediate representation ([SSA IR](https://en.wikipedia.org/wiki/Static_single-assignment_form)) to perform optimization.
4+
This IR is different from LLVM IR, and unique to Julia.
5+
It allows for Julia specific optimizations.
6+
7+
1. Basic blocks (regions with no control flow) are explicitly annotated.
8+
2. if/else and loops are turned into `goto` statements.
9+
3. lines with multiple operations are split into multiple lines by introducing variables.
10+
11+
For example the following Julia code:
12+
```julia
13+
function foo(x)
14+
y = sin(x)
15+
if x > 5.0
16+
y = y + cos(x)
17+
end
18+
return exp(2) + y
19+
end
20+
```
21+
when called with a `Float64` argument is translated into:
22+
23+
```julia
24+
using InteractiveUtils
25+
@code_typed foo(1.0)
26+
```
27+
28+
```llvm
29+
CodeInfo(
30+
1 ─ %1 = invoke Main.sin(x::Float64)::Float64
31+
│ %2 = Base.lt_float(x, 5.0)::Bool
32+
└── goto #3 if not %2
33+
2 ─ %4 = invoke Main.cos(x::Float64)::Float64
34+
└── %5 = Base.add_float(%1, %4)::Float64
35+
3 ┄ %6 = φ (#2 => %5, #1 => %1)::Float64
36+
│ %7 = Base.add_float(7.38905609893065, %6)::Float64
37+
└── return %7
38+
) => Float64
39+
```
40+
41+
In this example, we can see all of these changes.
42+
1. The first basic block is everything in
43+
```llvm
44+
1 ─ %1 = invoke Main.sin(x::Float64)::Float64
45+
│ %2 = Base.lt_float(x, 5.0)::Bool
46+
└── goto #3 if not %2
47+
```
48+
2. The `if` statement is translated into `goto #3 if not %2` which goes to the 3rd basic block if `x>5` isn't met and otherwise goes to the second basic block.
49+
3. `%2` is an SSA value introduced to represent `x > 5`.
50+
351
## Background
452

553
Beginning in Julia 0.7, parts of the compiler use a new [SSA-form](https://en.wikipedia.org/wiki/Static_single_assignment_form)
@@ -11,11 +59,9 @@ linearized (i.e. turned into a form where function arguments could only be SSA v
1159
conditional control flow). This negated much of the usefulness of SSA form representation when performing
1260
middle end optimizations. Some heroic effort was put into making these optimizations work without a complete SSA
1361
form representation, but the lack of such a representation ultimately proved prohibitive.
62+
## Categories of IR nodes
1463

15-
## New IR nodes
16-
17-
With the new IR representation, the compiler learned to handle four new IR nodes, Phi nodes, Pi
18-
nodes as well as PhiC nodes and Upsilon nodes (the latter two are only used for exception handling).
64+
The SSA IR representation has four categories of IR nodes: Phi, Pi, PhiC, and Upsilon nodes (the latter two are only used for exception handling).
1965

2066
### Phi nodes and Pi nodes
2167

0 commit comments

Comments
 (0)