 |
» |
|
|
 |
Before ex
ploring
the various optimizations that are performed, it is important to
review the coding guidelines used to assist the optimizer. This
section is broken down into the following subsections: General guidelines |  |
The coding guidelines presented in this section help the optimizer
to optimize your program, regardless of the language in which the
program is written. Use local variables to help the optimizer
promote variables to registers. Do not use local variables before they are initialized.
When you request +O2, +O3,
or +O4 optimizations, the compiler
tries to detect and indicate violations of this rule. See “+O[no]initcheck” for
related information. Use constants instead of variables in arithmetic
expressions such as shift, multiplication, division, or remainder
operations. Position the loop inside the procedure or use a
directive to call the loop in parallel, when a loop contains a procedure
call. Construct loops so the induction variable increases
or decreases toward zero where possible. The code generated for
a loop termination test is more efficient with a test against zero
than with a test against some other value. Do not reference outside the bounds of an array.
Fortran provides the -C
option to check whether your program references outside array bounds. Do not pass an incorrect number of arguments to
a function.
The coding guid
elines presented in this section help the optimizer to optimize
your C and C++ programs. Use do
loops and for loops in place of
while loops. do
loops and for loops are more efficient
because opportunities for removing loop-invariant code are greater. Use register variables
where possible. Use unsigned variables rather than signed, when
using short or char
variables or bit-fields. This is more efficient because a signed
variable causes an extra instruction to be generated. Pass and return pointers to large structs instead
of passing and returning large structs by value, where possible. Use type-checking tools like lint
to help eliminate semantic errors. Use local variables for the upper bounds (stop values)
of loops. Using local variables may enable the compiler to optimize
the loop.
During optimization, the compiler gathers information about
the use of variables and passes this information to the optimizer.
The optimizer uses this information to ensure that every code transformation
maintains the correctness of the program, at least to the extent
that the original unoptimized program is correct. When gathering this information, the compiler assumes that
while inside a function, the only variables that are accessed indirectly
through a pointer or by another function call are: Global variables (all variables with
file scope) Local variables that have had their addresses taken
either explicitly by the &
operator, or implicitly by the automatic conversion of array references
to pointers.
In general, the preceding assumption should not pose a problem.
Standard-compliant C and C++ programs do not violate
this assumption. However, if you have code that does violate this
assumption, the optimizer can change the behavior of the program
in an undesirable way. In particular, you should follow the coding
practices to ensure correct program execution for optimized code: Avoid using variables that are accessed
by external processes. Unless a variable is declared with the volatile
attribute, the compiler assumes that a program's data is
accessed only by that program. Using the volatile
attribute may significantly slow down a program. Avoid accessing an array other than the one being
subscripted. For example, the construct a[b-a],
where a and b
are the same type of array, actually references the array b,
because it is equivalent to *(a+(b-a)),
which is equivalent to *b. Using
this construct might yield unexpected optimization results. Avoid referencing outside the bounds of the objects
a pointer is pointing to. All references of the form *(p+i)
are assumed to remain within the bounds of the variable or variables
that p was assigned to point to. Do not rely on the memory layout scheme when manipulating
pointers, as incorrect optimizations may result. For example, if
p is pointing to the first member
of a structure, do not assume that p+1
points to the second member of the structure. Additionally, if p
is pointing to the first in a list of declared variables, p+1
is not necessarily pointing to the second variable in the list.
For more information regarding coding guidelines, see “General guidelines”. The coding guidelines presented in this section help the optimizer
to optimize Fortran programs. As part of the optimization process, the compiler gathers
information about the use of variables and passes this information
to the optimizer. The optimizer uses this information to ensure
that every code transformation maintains the correctness of the
program, at least to the extent that the original unoptimized program
is correct. When gathering this information, the compiler assumes that
inside a routine (either a function or a subroutine) the only variables
that are accessed (directly or indirectly) are: COMMON
variables declared in the routine Parameters to this routine
Local variables include all static and nonstatic variables. In general, you do not need to be concerned about the preceding
assumption. However, if you have code that violates it, the optimizer
can adversely affect the behavior of the program. Avoid using variables that are accessed by a process other
than the program. The compiler assumes that the program is the only
process accessing its data. The only exception is the shared COMMON
variable in Fortran 90. Also avoid using extensive equivalencing and memory-mapping
schemes, where possible. See the section “General guidelines”
for additional guidelines.
|