ANSIALIAS | NOANSIALIAS

Category

Optimization and tuning

Pragma equivalent

#pragma options (ansialias) (C only), #pragma options (noansialias) (C only)

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

Read syntax diagramSkip visual syntax diagram
   .-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.

Predefined macros

None.

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.