GCC 7 - The importance of a cutting-edge compiler

GCC 7* was released last May 2nd and the Clear Linux* Project already uses it as the default C compiler. This latest GCC* compiler version came with new features and performance optimizations including various improvements in the diagnostics, location ranges, suggestions for misspellings, and even hints for code fixes. The following examples showcase some cool features included in GCC 7.

Loop splitting optimization

The GCC 7 release notes [1] provide the following example: Take the following loop containing an always true condition on one side of the iteration space and an always false condition on the other:

for (i = 0; i < 100; i++) {
if (i < 50)
A;
Else
B;
}

In GCC 7, the option “fsplit-loops” splits this code into two loops. The -O3 optimization level or higher includes this feature by default. Each of the two new loops iterates on just one side of the iteration space and the condition does not need to be checked inside of the loop:

for (i = 0; i < 50; i++) {
A;
}
for (; i < 100; i++) {
B;
}

The author of this change on GCC provides example codes to validate the feature [2]. The first experiments show a minimal but relevant performance improvement [3] thanks to this change.

Code hoisting optimization

This feature was merged last year [4]. It helps with the partial redundancy elimination or PRE. PRE is a compiler optimization which eliminates unnecessary and redundant expressions on some paths through of the code. It primarily reduces the code size. However, it improves the speed of the generated code as well. This feature is enabled with the “-fcode-hoisting” flag, at the -O2 optimization level or higher, and on -Os. Good examples of this feature are described on its test suite[4]. Take this example from [5]:

Detect buffer overflow and invalid memory accesses

When compiled with the new flag -Walloca-larger-than=1024, GCC 7 shows this warning:

warning: argument to 'alloca may be too large due to conversion from 'int' to 'long unsigned int' [-Walloca-larger-than=]

At first sight, it is not clear why the compiler warns if alloca was called to allocate memory which is automatically freed. It was called for sizes of 1kb and less, which is the limit implicit in “-Walloca-larger-than”. However, since n is signed, a negative value would result in a call to the function well in excess of the limit. Thus, the warning is triggered.

Smarter fix-it hints

Two new options have been added for printing fix-it hints. Take, for example, the following hello world code:

A simple compilation with the -fdiagnostics-parseable-fixits flag results in:

$ gcc hello.c -o hello -fdiagnostics-parseable-fixits
hello.c: In function ‘main’:
hello.c:6:17: error: ‘colour’ undeclared (first use in this function); did you mean ‘color’?
printf("%d",colour);
^~~~~~
color
fix-it:"hello.c":{6:17-6:23}:"color"
hello.c:6:17: note: each undeclared identifier is reported only once for each function it appears in

The -fdiagnostics-parseable-fixits flag shows the fix-it hints in a machine-readable form, suitable for consumption by IDEs. On the other hand, the -fdiagnostics-generate-patch flag prints a patch in the "unified" format after any diagnostics are shown:

Conclusion

With the early adoption of GCC 7, the Clear Linux Project stays on the leading edge of adoption of new features and performance optimizations. This allows us to showcase the best of Intel® architecture technology and performance, from low-level kernel features to complex applications which span the entire operating system.