Compilers

In the loop above, which computation is a candidate for loop-invariant code motion (hoisting out of the loop)? (Assume x and y are not modified in the loop.)

for (i = 0; i < n; i++)
    a[i] = b[i] * (x * y);
  1. AThe whole of b[i] * (x * y)
  2. Bx * y
  3. CThe assignment to a[i]
Show answer and explanation

Answer: B. x * y

Loop-invariant code motion moves computations that yield the same value on every iteration in front of the loop so they are computed once. x and y do not change inside the loop, so x * y is the same every time; t = x * y can be computed before the loop and the body becomes a[i] = b[i] * t. b[i] differs for each i, so the whole of b[i] * (x * y) cannot be moved. The assignment to a[i] writes a different element each iteration and stays in the loop.

  • A. b[i] changes each iteration, so the whole expression cannot move.
  • B. Correct. x * y has the same value on every iteration.
  • C. The assignment is needed for each element and stays in the loop.
Practice this topic Back to topic

More Compilers questions

  1. In the loop above, which transformation applies strength reduction to the index computation i * 4?
  2. Why is the loop above hard to vectorize with SIMD instructions?
  3. In the function above, why can the compiler not simply hoist the load of *b out of the loop?
  4. In register allocation by coloring an interference graph, what do the nodes and edges represent?
  5. What happens to generated code when register allocation causes a "spill"?