Optimization phase that performs global value numbering and loop invariant code motion on a
StructuredGraph. It only considers
FixedNode nodes, floating nodes are handled
automatically via their representation in the IR as
FloatingNode.
Note on loop invariant code motion: This phase only performs loop invariant code motion for
instructions unconditionally executed inside a loop. A standard example is a loop iterating until
an array length
for (int i = 0; i < arr.length; i++) {
// body
}
In a more IR focused notation this code looks like
*
int i = 0;
while (true) {
int len = arr.length;
if (i < len) {
// body
i++;
}
break;
}
The length of the array is read in every iteration of the loop. However, it is loop invariant and
the array length
LocationIdentity is immutable. Thus, the read can be moved out of the
loop as it is loop-invariant.
The algorithm is based on a dominator tree traversal of the
ControlFlowGraph where
dominated blocks are visited before post dominated blocks. This means if a
Block starts
with a
MergeNode all its predecessor blocks have already been visited. This is important
to properly track
MemoryKill nodes.
The algorithm uses
MemoryKill and
MemoryAccess to reason about memory effects.
The algorithm does not create
ProxyNode. Thus, if a node is defined inside a loop and
another value equal node is outside of this loop, value numbering will not happen (for the sake
of simplicity of the algorithm).