Category
Optimization and tuning
Purpose
Indicates to the compiler that the code strictly follows the type-based
aliasing rule in the ISO C and C++ standards, and can therefore be
compiled with higher performance optimization of the generated code.
When ANSIALIAS is in effect, you are making a promise to the compiler
that your source code obeys the constraints in the ISO standard. On
the basis of using this compiler option, the compiler front end passes
aliasing information to the optimizer, which performs optimization
accordingly.
When NOANSIALIAS is in effect, the optimizer assumes that a given
pointer of a given type can point to an external object or any object
whose address is taken, regardless of type. This assumption creates
a larger aliasing set at the expense of performance optimization.
Syntax
.-ANS---.
>>-+-NOANS-+---------------------------------------------------><
Defaults
ANSIALIAS
The cc compiler invocation command for a
regular compile in the z/OS® UNIX System Services environment
uses NOANSIALIAS as the default option.
Usage
When type-based aliasing is used during optimization, the optimizer
assumes that pointers can only be used to access objects of the same
type.
Type-based aliasing improves optimization in the following ways.
- It provides precise knowledge of what pointers can and cannot
point at.
- It allows more loads to memory to be moved up and stores to memory
moved down past each other, which allows the delays that normally
occur in the original written sequence of statements to be overlapped
with other tasks. These re-arrangements in the sequence of execution
increase parallelism, which is desirable for optimization.
- It allows the removal of some loads and stores that otherwise
might be needed in case those values were accessed by unknown pointers.
- It allows more identical calculations to be recognized ("commoning").
- It allows more calculations that do not depend on values modified
in a loop to be moved out of the loop ("code motion").
- It allows better optimization of parameter usage in inlined functions.
Simplified, the rule is that you cannot safely dereference a
pointer that has been cast to a type that is not closely related to
the type of what it points at. The ISO C and C++ standards define
the closely related types.
The following are not subject to type-based aliasing:
- Types that differ only in reference to whether they are signed
or unsigned. For example, a pointer to a signed int can point to an unsigned
int.
- Character pointer types (char, unsigned char,
and in C but not C++ signed char).
- Types that differ only in their const or volatile qualification.
For example, a pointer to a const int can point to an int.
- C++ types where one is a class derived from the other.
z/OS XL C/C++ compilers often expose type-based aliasing violations
that other compilers do not. The C++ compiler corrects most but not
all suspicious and incorrect casts without warnings or informational
messages. For examples of aliasing violations that are detected and
quietly fixed by the compiler, see the discussion of the
reinterpret_cast operator
in the
z/OS XL C/C++ Language Reference.
In addition to the specific optimizations to the lines of source
code that can be obtained by compiling with the ANSIALIAS compiler
option, other benefits and advantages, which are at the program level,
are described below:
- It reduces the time and memory needed for the compiler to optimize
programs.
- It allows a program with a few coding errors to compile with optimization,
so that a relatively small percentage of incorrect code does not prevent
the optimized compilation of an entire program.
- It positively affects the long-term maintainability of a program
by supporting ISO-compliant code.
It is important to remember that even though a program compiles,
its source code may not be completely correct. When you weigh tradeoffs
in a project, the short-term expedience of getting a successful compilation
by forgoing performance optimization should be considered with awareness
that you may be nurturing an incorrect program. The performance penalties
that exist today could worsen as the compilers that base their optimization
on strict adherence to ISO rules evolve in their ability to handle
increased parallelism.
The ANSIALIAS compiler option only takes effect if the OPTIMIZE
option is in effect.
If you specify LANGLVL(COMMONC), the ANSIALIAS option is automatically
turned off. If you want ANSIALIAS turned on, you must explicitly
specify it. Using LANGLVL(COMMONC) and ANSIALIAS together may have
undesirable effects on your code at a high optimization level. See LANGLVL for more information on LANGLVL(COMMONC).
A comment that indicates the ANSIALIAS option setting is generated
in your object module to aid you in diagnosing a problem with your
program.
Although type-based aliasing does not apply to the volatile and const qualifiers,
these qualifiers are still subject to other semantic restrictions.
For example, casting away a const qualifier might lead
to an error at run time.
IPA effects
If the ANSIALIAS option is specified, then the IPA link step phase
will take advantage of the knowledge that the program will adhere
to the standard C/C++ aliasing rules in order to improve its variable
aliasing calculations.
Examples
The following example executes as expected when compiled unoptimized
or with the NOANSIALIAS option; it successfully compiles optimized
with ANSIALIAS, but does not necessarily execute as expected. On non-IBM
compilers, the following code may execute properly, even though it
is incorrect.
1 extern int y = 7.;
2
3 void main() {
4 float x;
5 int i;
6 x = y;
7 i = *(int *) &x;
8 printf("i=%d. x=%f.\n", i, x);
9 }
In this example, the value in object x of type float has
its stored value accessed via the expression * (int *) &x.
The access to the stored value is done by the * operator,
operating on the expression (int *) &x. The type of
that expression is (int *), which is not covered by the
list of valid ways to access the value in the ISO standard, so the
program violates the standard.
When ANSIALIAS (the default) is in effect, the compiler front
end passes aliasing information to the optimizer that, in this case,
an object of type float could not possibly be pointed to
by an (int *) pointer (that is, that they could not be
aliases for the same storage). The optimizer performs optimization
accordingly. When it compares the instruction that stores into
x and
the instruction that loads out of
*(int *), it believes
it is safe to put them in either order. Doing the load before the
store will make the program run faster, so it interchanges them. The
program becomes equivalent to:
1 extern int y = 7.;
2
3 void main() {
4 float x;
5 int i;
6 int temp;
7 temp = *(int *) &x; /* uninitialized */
8 x = y;
9 i = temp;
10 printf("i=%d. x=%f.\n", i, x);
9 }
The value stored into variable
i is the old value
of
x, before it was initialized, instead of the new value
that was intended. IBM® compilers
apply some optimizations more aggressively than some other compilers
so correctness is more important.
Related information
For C, the CHECKOUT(CAST) compiler option can help you locate some
but not all suspicious casts and ANSIALIAS violations. See CHECKOUT | NOCHECKOUT (C only) to see how to obtain more diagnostic information.