x[i+1] = y;
while ( i < max ) {
x [ i+1 ] = x[ i+1 ] + z;
i = i+1;
}
In this example, we would assign the same value number to all four instances of i+1, but
the assignment statement at the end of the loop means that the instance of i+1 outside
the loop will not have the same value as those inside in all cases.
w = 2*x + 1;
if ( x > 0 )
{ z = 2*x }
y = z + 1;
In this example, 2*x + 1 and z + 1 might be common subexpressions, but we can't be sure
unless we know whether or not x will be positive.
for all basic blocks do
initialize various data structures
for each instruction in the block do
scan the instruction and
optimize (if possible).
void optimizeLogicalExpr( node * expr) {
optimizeExpr( expr->internal.child[0] );
startNewBlock();
optimizeExpr( expr->internal.child[1] );
startNewBlock();
}
void optimizeIf( node * stmt ) {
optimizeExpr( stmt->internal.child[0] );
startNewBlock();
optimizeStmtList( stmt->internal.child[1] );
startNewBlock();
optimizeStmtList( stmt->internal.child[2]);
startNewBlock();
}
void optimizeStmt( node * stmt ) {
switch (stmt->internal.type ) {
case Nif:
optimizeIf( stmt );
break;
case Nwhile:
optimizeWhile( stmt );
break;
...
}
void optimizeStmtList( node * slist ) {
visitlist( slist, optimizeStmt, 0);
}
void optimizeLogicalExpr( node * expr) {
optimizeExpr( expr->internal.child[0] );
optimizeExpr( expr->internal.child[1] );
startNewBlock();
}
void optimizeIf( node * stmt ) {
optimizeExpr( stmt->internal.child[0] );
optimizeStmtList( stmt->internal.child[1] );
startNewBlock();
optimizeStmtList( stmt->internal.child[2]);
startNewBlock();
}