GAP Message - remark #30534: (LOOP) Add -Qansi-alias option ...

Message

Add -Qansi-alias option for better type-based disambiguation analysis by the compiler if appropriate (the option will apply for the entire compilation). This will improve optimizations for the loop at line 28. [VERIFY] Make sure that the semantics of this option is obeyed for the entire compilation.

Description

Use option -ansi-alias (Linux* OS and Mac OS* X) or /Qansi-alias (Windows* OS) for the specified file. This option will help the compiler to optimize the loop at the specified line. You must verify that the ANSI rules are followed for the entire file. gcc assumes this property by default in default setting O2; the Intel compiler does not. This option is particularly useful for C++ programs since it enables type-based disambiguation between pointers and other elemental datatypes (that in turn enables optimizations such as vectorization and parallelization). Option -ansi-alias (Linux* OS and Mac OS* X) and /Qansi-alias (Windows* OS) enable or disable use of ANSI aliasing rules optimizations, and assert that the program adheres to these rules.

ANSI-aliasing rules are described in the Standards documentation:

a) C: ISO/IEC 9899, chapter 6.5 paragraph 7

b) C++: ISO/IEC 14882, chapter 3.10, paragraph 15

Summary of ANSI aliasing rules:

a) Stored value of object can be accessed by an lvalue of types that is: - compatible with effective type of object OR - Qualified (const, volatile, ...) + signed/unsigned version of compatible type OR - Aggregate or union type that includes aforementioned types as members
b) Pointers of different types (say int* and float*) can't point to the same object.
c) Access to a field of a structure can't alias with access to another field of the same structure
d) There are exceptions: char*

An example describing the rules:

typedef struct { short field1; } S1; 
typedef struct { double field1; double field2; } S2; 
void foo( int *p1, float *p2, S1 *p3, S1 *p4, S2 *p5)
{
	*p1 = 10;
	*p2 = 20.0;
	p3->field1 = 30;
	p4->field1 = 40;
	p5->field1 = 50.0;
	p5->field2 = 60.0;
}

In the above example, p3->field1 and p4->field1 may alias; the others can't (based on ANSI-aliasing rules).
How the rules can be violated:
"Type punning" - violation of the aliasing rules based on assumption that two different data types have the same representation:
- Pointer type and an integral type
- Floating point types and integral type (very often in math libraries)
An example that demonstrates a violation (from the SPEC* CPU2006 benchmark 403.gcc, varasm.c:3723):

	 int *strp;
	 struct rtx_const value;
	 ...
	 strp = (int *) &value;
	 while (--len >= 0)
	   if (*p++ != *strp++)	
            ...

How to fix violations?
If you really have to access a particular data object using different types, then:
- use unions OR
- use char*
One possible change, using unions, for previous example from 403.gcc:

	 union { int strp[]; struct rtx_const value; } foo;
	 int* pv = foo.strp;              
	 ...
	 while (--len >= 0)
	   if (*p++ != *pv++) 
             ...

Example

#include <stddef.h>

template<typename T>
class blocked_range {
    T my_begin;
    T my_end;
public:
    blocked_range();
    T begin() const {return my_begin;}
    T end() const {return my_end;}
};

class ApplyMatAdd {
    double *const A, *const B, *const C;
    const size_t size;
public:
    ApplyMatAdd(double *A_, double *B_, double *C_, size_t size_) : A(A_), B(B_), C(C_), size(size_) {}
    void operator()( const blocked_range<size_t>& range ) const;
};

void ApplyMatAdd::operator()( const blocked_range<size_t>& range ) const {
    for (size_t i=range.begin(); i<range.end(); ++i) {
        for (size_t j=0; j<size; ++j) {
            C[i*size + j] = A[i*size + j] + B[i*size + j];
        }
    }
}

For this example, the compiler is unable to vectorize the innermost loop at -O2. Adding the -Qguide option produces the following message:

test1.cpp(28): remark #30534: (LOOP) Add -Qansi-alias option for better type-based disambiguation analysis by the compiler if appropriate (option will apply for entire compilation). This will improve optimizations for the loop at line 28 [VERIFY] Make sure that the semantics of this option is obeyed for entire compilation.

Compiling this example with -Qansi-alias option added (if the user decides it is safe to do so) enables vectorization of the innermost loop.

Optimization Notice in English

Einzelheiten zur Compiler-Optimierung finden Sie in unserem Optimierungshinweis.
Tags: