Skip to content

Theory test — Chapter 16

51 questions; you pass at 80 %. This page shows the questions only: take the test in the terminal, where every answer is graded and explained.

./course quiz 16                                   # interactive
./course quiz template 16 -o answers/ch16.yaml  # or fill in a file ...
./course quiz grade 16                             # ... and grade it
Question 1 flavor-counts · mapping · 1 pt · 01-ssa-properties-and-flavors

The running example (labs/ch16-ssa-construct/inputs/running.tac), blocks A–I:

A: i = 0 ; x = 1
B: y = add x, i ; ifz i goto E
C: x = add y, 2 ; t = lt x, 20 ; ifz t goto H
D: y = mul y, 2
E: t = gt y, 0 ; ifz t goto H
F: x = add x, y ; y = sub y, 7 ; goto G
G: t = rem x, 3 ; if t goto E
H: i = add i, 1 ; t = lt i, 4 ; if t goto B
I: return x

How many phis does Cytron's construction place in each flavor?

Keys: minimal, semi-pruned, pruned
Answer format: one value per key
Question 2 minimal-dead-phi · number · 1 pt · 01-ssa-properties-and-flavors

In minimal SSA of the running example (previous question), how many of the 10 phis are
dead, i.e. never reach a non-phi use through phi chains?

Answer format: a number
Question 3 phi-parallel · mapping · 1 pt · 01-ssa-properties-and-flavors

Block H begins with a2 = phi [1, entry], [b2, H] and b2 = phi [2, entry], [a2, H].
Control arrives from H on the back edge with a2 = 3 and b2 = 7. Give the values of a2 and
b2 after H's phis execute, with the semantics of LLVM (and of block arguments).

Keys: a2, b2
Answer format: one value per key
Question 4 semi-pruned-global · set · 1 pt · 01-ssa-properties-and-flavors

Which variables of the running example (see flavor-counts) are global in Briggs et
al.'s sense (upward-exposed in some block)?

Answer format: items separated by commas or spaces, e.g. {a, b}
Question 5 pruned-theorem · single · 1 pt · 01-ssa-properties-and-flavors

Which statement about pruned SSA is a theorem of Lesson 16.1?

  1. Pruned SSA has the fewest phis of any correct SSA form of the program.
  2. Pruned SSA's phis are exactly minimal SSA's phis minus the dead ones.
  3. Pruned SSA and semi-pruned SSA always place the same phis for global names.
  4. Pruned SSA can place a phi outside DF⁺(defs(v)).
Answer format: one letter
Question 6 llvm-where-livein · single · 1 pt · 01-ssa-properties-and-flavors

In PromoteMem2Reg::ComputeLiveInBlocks (PromoteMemoryToRegister.cpp), a block both
loads from and stores to the alloca. How does LLVM decide whether the block is live-in?

  1. It is always live-in, because it contains a load.
  2. It scans the block from the top: if the first reference to the alloca is a store, the block is not live-in; if it is a load, it is.
  3. It asks the IDFCalculator.
  4. It is never live-in, because it defines the alloca.
Answer format: one letter
Question 7 cytron-rename-trace · mapping · 1 pt · 02-frontier-based-construction

Pruned SSA of the running example (flavor-counts), with the oracle's naming: versions are
numbered per variable in dominator-tree preorder with children in RPO (A, B, C, D, E, F,
G, H, I), phis first; x.0 is A's x = 1, the phi for x at B is x.1, C defines x.2, the phi
at E is x.3, F defines x.4 and the phi at H is x.5. Which name of x does each block read?
(F: in x = add x, y; G: in t = rem x, 3; I: in return x.)

Keys: F, G, I
Answer format: one value per key
Question 8 cytron-phi-operands · mapping · 1 pt · 02-frontier-based-construction

Same program and naming as cytron-rename-trace. The phi x.5 at H has one operand per
predecessor C, E and G. Give each operand.

Keys: C, E, G
Answer format: one value per key
Question 9 cytron-invariant · single · 1 pt · 02-frontier-based-construction

What is the invariant of Cytron's renaming walk (Lemma 16.2.5)?

  1. Every stack holds exactly one name per block visited so far.
  2. When the walk is at a point p, the top of v's stack is the name of the definition of v that reaches p (the most recent one on every path).
  3. The stacks are empty whenever the walk enters a join block.
  4. The top of v's stack is always the phi of the nearest DF⁺ block.
Answer format: one letter
Question 10 sg-live-in · set · 1 pt · 02-frontier-based-construction

Algorithm 16.2.4 (Sreedhar–Gao with a live-in filter) runs for y in the running example
with S = defs(y) = {A, B, D, F} and live-in filter L = {C, D, E, F, G}. Which blocks does it
return?

Answer format: items separated by commas or spaces, e.g. {a, b}
Question 11 llvm-where-phiblocks-sort · text · 1 pt · 02-frontier-based-construction

In PromoteMem2Reg::run, after IDF.calculate(PHIBlocks) the phi blocks are sorted.
Which BasicBlock member function supplies the sort key?

Answer format: a short answer
Question 12 braun-trivial · single · 1 pt · 03-construction-without-frontiers

When is a phi trivial in Braun et al.'s sense (Definition 16.3.1)?

  1. When it has exactly one predecessor block.
  2. When all its operands, ignoring references to the phi itself, are the same single value.
  3. When its result is not used.
  4. When all its operands are constants.
Answer format: one letter
Question 13 braun-scc · mapping · 1 pt · 03-construction-without-frontiers

The corpus listing irreducible-two-entry (c is never assigned, so it is 0):

  x = 5
  if c goto R
L:
  y = add y, 1
  t = lt y, 3
  ifz t goto X
R:
  goto L
X:
  return x

How many phis does Braun et al.'s construction leave with trivial-phi removal only, and
with the redundant-SCC pass (Algorithm 16.3.4) as well?

Keys: trivial-only, with-scc
Answer format: one value per key
Question 14 braun-seal · single · 1 pt · 03-construction-without-frontiers

When may Braun et al.'s algorithm seal a block?

  1. As soon as the block itself has been filled.
  2. As soon as all its predecessors have been filled, because no new predecessor edge can appear.
  3. Only after the whole function has been processed.
  4. When the dominator tree says the block has no back edges.
Answer format: one letter
Question 15 ah-count · number · 1 pt · 03-construction-without-frontiers

Aycock–Horspool on the running example (flavor-counts): a phi for each of the 4 variables
at each of the 3 join blocks, renaming with copy folding, then the two removal rules until
nothing changes. How many phis are left?

Answer format: a number
Question 16 llvm-where-phi-simplify · text · 1 pt · 03-construction-without-frontiers

After renaming, PromoteMem2Reg::run loops over the new phis and folds the redundant ones,
which is Aycock and Horspool's cleanup. Which LLVM function does it call on each phi?

Answer format: a short answer
Question 17 mem2reg-table · mapping · 1 pt · 04-llvm-mem2reg-sroa-ssaupdater

clang -O0 compiles the fib loop of Lesson 16.4 (int a = 0, b = 1; for (int i = 0; i < n; i++) { int t = a; a = b; b = t + b; } return a;) with the allocas n.addr, a, b, i
and t. How many phis does mem2reg create for each?

Keys: n.addr, a, b, i, t
Answer format: one value per key
Question 18 llvm-where-single-store · text · 1 pt · 04-llvm-mem2reg-sroa-ssaupdater

PromoteMem2Reg::run tries two special cases before computing any frontier. What is the
name of the function that handles an alloca with exactly one store?

Answer format: a short answer
Question 19 sroa-partitions · number · 1 pt · 04-llvm-mem2reg-sroa-ssaupdater

In struct pair { int a, b; } code (Lesson 16.4), the alloca %p (8 bytes) has the slices
memcpy [0, 8), load p.a [0, 4), load p.b [4, 8) and memcpy [0, 8). Into how many partitions
does SROA split it?

Answer format: a number
Question 20 sroa-why · single · 1 pt · 04-llvm-mem2reg-sroa-ssaupdater

Why does mem2reg alone leave a struct local of struct pair in memory?

  1. Structs cannot be held in SSA registers in LLVM.
  2. The alloca is accessed through memcpy, GEPs and loads of different types, so it is not promotable (Definition 16.4.1); SROA first splits it into scalar allocas with only whole loads and stores.
  3. mem2reg only promotes allocas that have exactly one store.
  4. The struct escapes to a call.
Answer format: one letter
Question 21 ssaupdater-phi · single · 1 pt · 04-llvm-mem2reg-sroa-ssaupdater

Loop rotation clones the header, so %sq has two definitions: 0 in the new preheader and
%sq at the bottom of the loop. The use at the top of the body asks
GetValueInMiddleOfBlock(body). What does SSAUpdater produce?

  1. The value 0, because the preheader dominates the body.
  2. A new phi in the body: [0, preheader], [%sq, latch].
  3. A phi in every block of DF⁺ of both definitions, computed with frontiers.
  4. An error: SSAUpdater requires one definition per value.
Answer format: one letter
Question 22 ssaupdater-vs-bulk · single · 1 pt · 04-llvm-mem2reg-sroa-ssaupdater

How does SSAUpdaterBulk differ from SSAUpdater?

  1. It handles many variables at once with live-in blocks and IDFCalculator, and needs a dominator tree; SSAUpdater answers one value at a time by walking predecessors.
  2. It works only on reducible CFGs.
  3. It produces minimal instead of pruned SSA.
  4. It removes phis instead of creating them.
Answer format: one letter
Question 23 llvm-where-phi-verify · text · 1 pt · 05-phi-block-arguments-upsilon

In llvm/lib/IR/Verifier.cpp, which Verifier member function checks "PHINode should have
one entry for each predecessor of its parent basic block!"?

Answer format: a short answer
Question 24 blockargs-edge-edit · single · 1 pt · 05-phi-block-arguments-upsilon

A pass deletes one edge P → B of a CFG. What must it update in each representation?

  1. Phi nodes: remove P's entry from every phi of B. Block arguments: drop P's branch operands for B; nothing in B changes.
  2. Nothing in either representation.
  3. Phi nodes: nothing. Block arguments: remove a parameter of B.
  4. Both: renumber every value of B.
Answer format: one letter
Question 25 upsilon-semantics · mapping · 1 pt · 05-phi-block-arguments-upsilon

The swap loop in upsilon/phi form (Lesson 16.5): entry does Upsilon(1, ^a); Upsilon(2, ^b); Upsilon(0, ^i); the loop does a = Phi(); b = Phi(); i = Phi(); i1 = Add(i, 1); ...; Upsilon(b, ^a); Upsilon(a, ^b); Upsilon(i1, ^i). What are a, b and i after the loop's Phis
execute for the second time?

Keys: a, b, i
Answer format: one value per key
Question 26 upsilon-destruction · single · 1 pt · 05-phi-block-arguments-upsilon

Why does leaving upsilon/phi form need no parallel copies and no edge splitting?

  1. Because B3 forbids critical edges.
  2. Each shadow variable becomes an ordinary variable: an Upsilon is a copy into it and a Phi a copy out of it. Upsilons write shadows, never the Phi results that other code reads, so no lost copy or swap can occur.
  3. Because Phis execute sequentially.
  4. Because the register allocator inserts the copies later.
Answer format: one letter
Question 27 naive-lost-copy-value · number · 1 pt · 06-ssa-destruction

Briggs et al.'s lost-copy program in block-argument SSA returns 4:

entry: br H(1)
H(x2): x3 = add x2, 1 ; t = lt x3, 5 ; cbr t, H(x3), X()
X:     ret x2

What does Cytron's naive translation return (copy x2 = x3 at the end of H, before the
branch)?

Answer format: a number
Question 28 naive-cssa-correct · single · 1 pt · 06-ssa-destruction

On which inputs is naive destruction guaranteed correct (Theorem 16.6.6)?

  1. On every strict SSA program.
  2. On programs with no lost-copy and no swap edge, in particular conventional SSA whose phi operands are all names.
  3. Only on programs without loops.
  4. On any program after copy propagation.
Answer format: one letter
Question 29 briggs-which-problem · mapping · 1 pt · 06-ssa-destruction

For each problem, which fix does Briggs et al.'s analysis prescribe: split (split the
critical edge) or order (order the copies, with a temporary for cycles)?

Keys: lost-copy, swap
Answer format: one value per key
Question 30 llvm-where-split-all · text · 1 pt · 06-ssa-destruction

In llvm/lib/CodeGen/PHIElimination.cpp, what is the command-line option that forces
splitting of every critical edge during phi elimination?

Answer format: a short answer
Question 31 sreedhar-method1-count · number · 1 pt · 06-ssa-destruction

Sreedhar's Method I on the lost-copy program (naive-lost-copy-value): one copy per phi
operand on each incoming edge plus one at the block entry, before any coalescing. How many
copies does the result contain?

Answer format: a number
Question 32 sreedhar-method3-case · single · 1 pt · 06-ssa-destruction

Method III on the lost-copy phi x2 = φ(1, x3): the classes of x2 and x3 interfere; x2's
class is live out of H (into X); x3's class is not live on entry to H. Which copy does it
insert, and how many copies does the result have?

  1. Copy the operand x3 only; 3 copies.
  2. Copy the result x2 only (x2 := x2' at H's start); 2 copies in total.
  3. Copy both; 4 copies.
  4. No copy is needed; 1 copy.
Answer format: one letter
Question 33 boissinot-value-interference · single · 1 pt · 07-parallel-copies-and-coalescing

In strict SSA, b = a (a copy), and afterwards both a and b are used. Do a and b interfere
in Boissinot et al.'s value-based sense?

  1. Yes: their live ranges intersect.
  2. No: they intersect but hold the same value, V(b) = V(a).
  3. Only if the copy is in a loop.
  4. Yes, unless b is a phi.
Answer format: one letter
Question 34 coalesce-lost-copy · number · 1 pt · 07-parallel-copies-and-coalescing

Lab L2's coalesce method on the lost-copy program: how many copy instructions does the
output contain?

Answer format: a number
Question 35 pcopy-moves · number · 1 pt · 07-parallel-copies-and-coalescing

With one spare location t, what is the minimum number of moves for the parallel copy
(a, b, c, d) ← (b, a, d, 5)?

Answer format: a number
Question 36 pcopy-sequence · sequence · 1 pt · 07-parallel-copies-and-coalescing

Run Algorithm 16.7.5 on (a, b, c) ← (b, c, a) with spare t (pending destinations in the order
a, b, c). Give the moves in order, each written dst=src.

Answer format: items in order, e.g. A B C
Question 37 pcopy-fanout · number · 1 pt · 07-parallel-copies-and-coalescing

Minimum number of moves (spare t available) for (a, b, c) ← (b, a, a)?

Answer format: a number
Question 38 llvm-where-joinvals · text · 1 pt · 07-parallel-copies-and-coalescing

In llvm/lib/CodeGen/RegisterCoalescer.cpp, which member function of JoinVals decides,
for one value number, between CR_Keep, CR_Erase, CR_Replace and CR_Impossible?

Answer format: a short answer
Question 39 ssa-regalloc-preview · single · 1 pt · 07-parallel-copies-and-coalescing

What property makes register allocation before leaving SSA attractive (Hack's thesis)?

  1. SSA programs never need spills.
  2. Interference graphs of strict SSA programs are chordal, so they can be colored optimally in polynomial time.
  3. Coalescing becomes polynomial.
  4. Phis disappear during coloring.
Answer format: one letter
Question 40 essa-pi-count · number · 1 pt · 08-ssa-extensions

How many π-assignments does Algorithm 16.8.3 (and LLVM's PredicateInfo) insert here?

entry: c1 = lt x, n ; if c1 goto A ; goto R
A:     c2 = gt x, 0 ; if c2 goto B ; goto R2
B:     y = add x, n ; return y
R:     return n
R2:    return x
Answer format: a number
Question 41 essa-renamed-uses · mapping · 1 pt · 08-ssa-extensions

Same program as essa-pi-count, with π names x1 = π(x) and n1 = π(n) on entry → A,
n2 = π(n) on entry → R, x2 = π(x1) on A → B and x3 = π(x1) on A → R2. Which name does each
use read? Keys: B.x and B.n (in y = add x, n), R.n, R2.x.

Keys: B.x, B.n, R.n, R2.x
Answer format: one value per key
Question 42 llvm-where-predicateinfo · text · 1 pt · 08-ssa-extensions

In llvm/lib/Transforms/Utils/PredicateInfo.cpp, CreateSSACopy creates the π-copies.
Which LLVM instruction (opcode name) is the copy?

Answer format: a short answer
Question 43 gsa-gamma-tree · single · 1 pt · 08-ssa-extensions

D branches on p to T and F; T branches on q to T1 and T2; T1 and F jump to M with x1 and x3;
T2 returns. What does Algorithm 16.8.6 give for the φ at M?

  1. γ(p, γ(q, x1, ⊥), x3), kept as written.
  2. γ(p, x1, x3)
  3. γ(q, x1, x3)
  4. γ(p, x3, x1)
Answer format: one letter
Question 44 gsa-eta-value · number · 1 pt · 08-ssa-extensions

In gated SSA, s1 = μ(s0, s2) with s0 = 0 and s2 = s1 + i1, i1 = μ(0, i1 + 1), loop test
c = i1 < n, and at the exit s3 = η(¬c, s1). What is s3 for n = 4?

Answer format: a number
Question 45 mssa-phi-blocks · set · 1 pt · 08-ssa-extensions

CFG: entry → A, B; A → C; B → C; C → D, E; D → E. MemoryDefs are in entry (a store), B (a
call) and D (a store); A, C and E only load. At which blocks does Memory SSA (Algorithm
16.8.8, like LLVM: no live-in filter) place MemoryPhis?

Answer format: items separated by commas or spaces, e.g. {a, b}
Question 46 mssa-def-chain · sequence · 1 pt · 08-ssa-extensions

In the print<memoryssa> output of Lesson 16.8 (1 = MemoryDef(liveOnEntry),
2 = MemoryDef(1), 3 = MemoryDef(2), 4 = MemoryPhi({%2,1},{%4,3})), follow the
defining accesses from access 3 to the entry. Write the accesses in order, with
liveOnEntry for M0.

Answer format: items in order, e.g. A B C
Question 47 llvm-where-mssa-phis · text · 1 pt · 08-ssa-extensions

MemorySSA::placePHINodes (llvm/lib/Analysis/MemorySSA.cpp) computes the MemoryPhi blocks
with which class?

Answer format: a short answer
Question 48 array-ssa-load · single · 1 pt · 08-ssa-extensions

Array SSA: A[i] := 1, then conditionally A[j] := 2, then at the join x := A[i]. When
can the load be replaced by the constant 1?

  1. Always: the store A[i] := 1 dominates the load.
  2. Exactly when i ≠ j is known, because the dφ after A[j] := 2 takes element i from the new store only if j = i.
  3. Never.
  4. Only if the branch is not taken.
Answer format: one letter
Question 49 array-ssa-heap · single · 1 pt · 08-ssa-extensions

In Fink, Knobe and Sarkar's heap Array SSA (Jikes RVM), what is p.f = v?

  1. A store H_f[p] := v into the heap array of field f, indexed by the object reference: it uses and defines H_f.
  2. A definition of a scalar variable p.f.
  3. A MemoryDef of the whole memory.
  4. A μ on every field.
Answer format: one letter
Question 50 hssa-chi-count · number · 1 pt · 08-ssa-extensions

A function has 4 stores through pointers, each of which may point to any of 3 address-taken
variables. How many χ-assignments for real variables does HSSA's step 2 insert (before zero
versioning)?

Answer format: a number
Question 51 hssa-zero-version · single · 1 pt · 08-ssa-extensions

Which versions does HSSA make zero versions?

  1. Versions with no real occurrence whose value comes from at least one χ, possibly through φs.
  2. Versions defined in the entry block.
  3. Every version defined by a φ.
  4. Versions with exactly one use.
Answer format: one letter