Loop-invariant code motion

This is an old revision of this page, as edited by SimonTrew (talk | contribs) at 22:07, 9 March 2009 (Really bad example this loop is entirely unnecessary.). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

In computer programming, loop-invariant code consists of statements (in an imperative programming language) which can be moved outside the body of a loop without affecting the semantics of the program.

Loop-invariant code motion (also called hoisting or scalar promotion) is a compiler optimization which performs this movement automatically.

Loop-invariant code which has been hoisted out of a loop is executed less often, providing a speedup. Another effect of this transformation is allowing constants to be stored in registers and not having to calculate the address and access the memory (or cache line) at each iteration.

However, if too many variables are created, there will be high register pressure, especially on processors with few registers, like the 32-bit x86. If the compiler runs out of registers, some variables will be spilled. To counteract this, the “opposite” optimization can be performed, rematerialization.

Worked example

If we consider the following code sample, two optimization possibilities can be applied.

while (j < maximum - 1)
{
    j = j + (4+array[k])*pi+5; 
}

The calculation of maximum - 1 and (4+array[k])*pi+5 can be moved outside the loop, and precalculated, resulting in something similar to:

int maxval = maximum - 1;
int calcval = (4+array[k])*pi+5;
while (j < maxval)
{
    j += calcval; 
}

It might then occur to us that the since the loop exit value of j must fall between maxval - calcval and maxval + calcval, or if not it was already beyond that range, then there is no need for the loop at all.