These instructions that influence the loop variable are called the common instructions. In the example it is simply the two operations that decrease the loop variable, but the case could have been less simple.
In the following, we consider our loop code (the code inside the loop) to be the only code visible to us (which is actually the case for the loop parallelizer in the current implementation).
We work with several sets here: The set C of common
instructions. The set of variables
that influence the
loop variable. The touches set
of the current
instruction. And finally the uses set
of the current
instruction.
Initially
is set to contain only the loop variable
itself. We set the current instruction to be the last
instruction in the loop code. We want to traverse the loop from the
bottom and up (since the last instruction in the loop code is the one
that has most recently had the chance to alter the loop variable, in
the second and all following iterations).
We calculate the intersection
.
This
is the set of variables that currently influence the loop, and that
the current instruction touches.
If
is non-empty, we add the current instruction to the set of
common instructions. And, we assign
.
Or, in other words, we remove the
variables the current instruction touches from the set of variables
that influence the loop variable. Secondly, we add the variables it
uses, to this same set.
The current instruction is then set to be the instruction preceding
the current ``current instruction''. Remember, we are traversing the
loop code from the bottom and up. We go back to recalculating .
This iteration is continued until we have been thru all instructions in the loop code.
The end result, is a set of common instructions that reflects exactly which instructions are needed to update the loop variable properly. Any remaining instructions are the ones that do the ``real'' work.