Next: Strength Reduction
Up: Optimization Strategies for HPJava
Previous: Optimization Strategies for HPJava
Contents
Partial Redundancy Elimination
Partial Redundancy Elimination (PRE) is a global, powerful
optimization technique first developed by Morel and Renvoise
[34] and discussed in [27,6]. PRE generally results in removing partially
redundant expressions, and hoisting loopinvariant expressions. Unlike
many other optimization algorithms, PRE doesn't need to distinguish
between global and local optimizations. The same algorithm can handle
both global and local versions of an optimization
simultaneously. Moreover, PRE never lengthens an execution path.
Here, we need to review PRE a bit more deeply in order to know what
features of PRE are suitable to our optimization plans.
PRE eliminates redundant computations of expressions that do not
necessarily occur on all control flow paths leading to a given
redundant computation. It combines two other techniques: common
subexpression elimination and loopinvariant code motion. We
need a couple of definitions before discussing these two.
Definition 3
An expression, e is redundant at some point p
if and only if it is computed along every path leading to p
and none of its constituent subexpressions has been redefined.
Definition 4
An expression, e is loopinvariant if it is computed
inside a loop and its value is identical in all the iterations of the
loop.
Common subexpression elimination says that if an expression e is
redundant at p, then the evaluation of e at p can be
replaced with a reference. Loopinvariant code motion says that if an
expression e is loopinvariant in a loop, then it can be
computed before the loop and referenced, rather than evaluated inside
the loop.
Figure 5.1:
Partial Redundancy Elimination

Figure 5.2:
Simple example of Partial Redundancy of loopinvariant

Definition 5
An expression e is partially redundant at a point p
if it is redundant along some, but not all, paths that reach p.
PRE is a complicated algorithm to understand and to implement,
compared with other wellknown optimization alogithms. However, the
basic idea of PRE is simple. Basically, PRE converts partially
redundant expressions into redundant expressions. The key steps of PRE
are:

Step 1:
 Discover where expressions are partially redundant using
dataflow analysis.

Step 2:
 Solve a dataflow problem that shows where inserting copies of a
computation would convert a partial redundancy into a full
redundancy.

Step 3:
 Insert the appropriate code and delete the redundant copy of the
expression.
The PRE we plan to apply to the HPJava System is originally described
in [27]. It is a PRE using
Static Single Assignment (SSA) form [15], called SSAPRE.
In Figure 5.1, the expression is redundant along
the lefthand control flow path, but not the right. PRE inserts a
computation of along the righthand path. Thus, the
computation of at the merge point is fully redundant and can
be replaced with a temporary variable.
Moreover, loopinvariant expressions are partially redundant as seen
in Figure 5.2. On the left, is partially redundant
since it is available from one predecessor (along the backedge of the
loop), but not the other. Inserting an evaluation of before
the loop allows it to be eliminated from the loop body.
We have reviewed the key features of PRE and its algorithm
briefly. Since PRE is a global and powerful optimization algorithm to
eliminate partial redundancy, (especially to get rid of
loopinvariants generated by the current HPJava translator), we expect
the optimized code to be very competitive and faster than the naively
translated one. We will see experimental studies, applying PRE to
some HPJava applications in section 5.5.
Next: Strength Reduction
Up: Optimization Strategies for HPJava
Previous: Optimization Strategies for HPJava
Contents
Bryan Carpenter
20040609