next up previous contents
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 loop-invariant 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 loop-invariant 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 loop-invariant 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. Loop-invariant code motion says that if an expression e is loop-invariant 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 loop-invariant
\includegraphics[height=2.7in]{Figures/simplePRE}

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 well-known 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 data-flow analysis.
Step 2:
Solve a data-flow 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 left-hand control flow path, but not the right. PRE inserts a computation of along the right-hand path. Thus, the computation of at the merge point is fully redundant and can be replaced with a temporary variable. Moreover, loop-invariant 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 loop-invariants 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 up previous contents
Next: Strength Reduction Up: Optimization Strategies for HPJava Previous: Optimization Strategies for HPJava   Contents
Bryan Carpenter 2004-06-09