Cs6241Hw3.doc: uploaded 27 May 2004 at 6:15 pm

advertisement
Cs6241 Hw3
Tony Hannan
14 Oct 2003
In order for an invariant definition to be moved before the loop, it must dominate all its
uses in the loop, ie. be the only definition for all uses in the loop. However, an invariant
definition that shares a loop use with one or more definitions outside of the loop, does
dominate the use once it is executed the first time, because the other definitions are
outside the loop and will never get re-executed. So, we can move these kind of invariant
definitions outside the loop by splitting the loop in two. The first loop executes a copy of
the loop until the invariant is executed. That block then continues in the second loop
which is a copy of the loop without the invariant. These two loops are equivalent to the
original because once the invariant is executed it always holds and therefore does not
have to be in the second loop. Again this only holds for non-dominating invariants
whose other definitions are outside the loop. Below is an example:
Original loop
Equivalent loops with invariant (x := 2) removed
x := 1
x := 1
x := 2
:= x
x := 2
:= x
:= x
Notice, in both loops, that once the invariant, x := 2, is executed, x will always equal 2
for the rest of the loop, because it is the only definition of x inside the loop.
Below is the algorithm for transforming a single loop with a single non-dominating
invariant definition into an equivalent two-part loop with the invariant removed (like
above). The gist of it is to copy the loop, remove the invariant from the second loop, and
have the outgoing edges of the invariant block in the first loop point to the corresponding
destination blocks in the second loop.
procedure TransformLoopWithoutInvariant (LoopHeader, Invariant)
LoopHeader: in Node
Invariant: in Statement
|| assumes Invariant is sole definition of variable in Loop. Make copy of loop and
|| attach to existing loop by having outpointers of Invariant block point to corresponding
|| blocks in new loop. Also remove Invariant from new loop.
begin
NewLoop, InvariantBlock, NewInvariantBlock: Node
NewLoop := CopyLoop (LoopHeader)
|| NewLoop will have no entry but the same exits
InvariantBlock := BlockOf (Invariant)
NewInvariantBlock := CopyOfIn (InvariantBlock, NewLoop)
|| CopyOfIn will return the corresonding block in NewLoop
RemoveStatementIn (Invariant, NewInvariantBlock)
for each e in SuccessorEdges (InvariantBlock)
with each f in SuccessorEdges (NewInvariantBlock) do
|| iterate over each old edge with corresponding new edge
ChangeHeadOfToHeadOf (e, f)
|| change head of old edge to point to the head of new edge
od
end
This algorithm will produce an equivalent program with the invariant removed from the
loop as long as the invariant definition is the only definition of its variable in the loop.
By “only definition” we allow the same invariant definition to appear multiple times in
the loop. In other words “x := 2” can appear multiple times in the loop above, since once
one of them is executed, x will equal 2 for the remainder of the loop. To handle these
cases I would extend the above algorithm as follows:
procedure TransformLoopWithoutInvariants (LoopHeader, Invariants)
|| assume all Invariants have the same definition
LoopHeader: in Node
Invariant: in set of Statement
begin
NewLoop, InvariantBlock, NewInvariantBlock: Node
NewLoop := CopyLoop (LoopHeader)
for each Invariant in Invariants do
InvariantBlock := BlockOf (Invariant)
NewInvariantBlock := CopyOfIn (InvariantBlock, NewLoop)
RemoveStatementIn (Invariant, NewInvariantBlock)
for each e in SuccessorEdges (InvariantBlock)
with each f in SuccessorEdges (NewInvariantBlock) do
ChangeHeadOfToHeadOf (e, f)
od
od
end
The above algorithms will work for both dominating invariants and non-dominating
invariants, and for single uses or multiple uses in the loop. Other definitions can reach
from outside the loop, but only the same definition can be inside the loop.
If multiple different definitions for the same variable exist inside the loop, the loop can
not be transformed to move any definition outside the loop. This is because any iteration
could change the variable by going through one or the other definition.
Download