Aggressive optimizations with OPTIMIZE(3)

The compiler optimizes more aggressively with OPTIMIZE(3) than with OPTIMIZE(2). Code may be moved, and computations may be scheduled, even if this could potentially raise an exception.

OPTIMIZE(3) may place instructions onto execution paths where they will be executed when they may not have been according to the actual semantics of the program. For example, a loop-invariant floating-point computation that is found on some, but not all, paths through a loop will not be moved using OPTIMIZE(2) because the computation may cause an exception. For OPTIMIZE(3), the compiler will move the computation because it is not certain to cause an exception.

The same is true for moving loads. Although a load through a pointer is never moved, loads off the static or stack base register are considered movable using OPTIMIZE(3). Loads in general are not considered to be absolutely safe using OPTIMIZE(2) because a program can contain a declaration of a static array a of 10 elements and load a[60000000003], which could cause a segmentation violation.

The same concepts apply to scheduling. In Figure 1, using OPTIMIZE(2), the computation of b+c is not moved out of the loop for two reasons:
  • It is considered dangerous because it is a floating-point operation
  • It does not occur on every path through the loop
Figure 1. Example of using OPTIMIZE(2)
⋮
int i;
float a[100], b, c;
for (i=0; i < 100; i++)
 {
 if (a[i] < a[i+11])
  a[i] = b + c;
 }
⋮

At OPTIMIZE(3), the computation b + c is moved out of the loop.