GCC 4.1 - Features and Benchmarks

Test Flight


The new version of the GNU Compiler (GCC) has a fresh crop of optimizations and support for Objective C. The Recursive Descent Parser introduced in version 4.0 is now used for the C and Objective C derivatives.

By René Rebe

GCC 4.1 has seen the light of the world with a delay of just one week [1]. Release Manager Mark Mitchell was forced to postpone the scheduled released data slightly to accommodate 128-bit floating point support for the PowerPC, as this feature is important for the future Glibc 2.4.

Manual Parser

One of the major changes is that GCC now uses the parser introduced with the latest version of C++ for C and Objective C. This manually written recursive descent parser (that is, it was not written with a traditional parser generator such as Bison or Yacc) is quicker, and is expected to be easier to maintain in the long run.

Apple added the ability to mix Objective C with C++ code to the GCC on MacOS X quite awhile back. Objective C is an alternative to C++ that offers object-orientation with a syntax that resembles that of Smalltalk, along with dynamic typing and introspection. On the downside, it lacks modern C++ constructs such as templates or namespaces. Objective C++ now gives you the ability to mix C++ features with Objective C, or simply to use C++ libraries with Objective C code.

The GCC developers have now integrated the Stack Smashing Protector (SSP) which was developed by IBM and has been available as an add-on patch for quite awhile now [2]. Programs built with SSP support change the order of variables on the stack to prevent inadvertent or malicious pointer manipulation. SSP lets programmers design functions to detect buffer overflows.

The GCC programmers have also considerably extended the Java library that implements major aspects of the Java API, including the AWT graphic toolkit and Swing. The Java applications alone take up more than a third of the ChangeLog [3]. GCJ and GNU Classpath support the compilation of the Eclipse developer environment, which was written in Java, without modifying the code.

The new optimizations, which are based on the Tree SSA infrastructure introduced in version 4.0 now work across function borders. This provides a more reliable scheme for detecting unused sections of code, candidates for inlining, and variables completely removed by optimizations. The developers have also improved automatic vectorization, which maps loops to vector units such as SSE (Intel/AMD) and Altivec (PowerPC) .

Legacy

Just as in previous versions of GCC, GNU extensions have been removed from standardized languages to ensure improved portability of the applications across different platforms and compilers. In this latest version of the GNU compiler, it appears that friend declarations in classes have somehow fallen foul of the cleanup:

struct a {
  friend void f() {
    ...
  }
};

In GCC 4.1, C++ programmers have to define a standards-compliant friend function outside of the class:

struct a {
  friend void f();
}

void f() {
  ...
}

Overspecified namespaces, as used in many C++ programs, are another victim, as an analysis by Debian programmer Martin Michlmayr demonstrates [4].

class b {
  void b::f ();
};

The GNU Compiler now returns an error: error: extra qualification `b::` on member `f'. In this example, you need to remove the b:: in front of the class methods.

Speed

As in my previous articles on the GNU Compiler, I again used Openbench to discover how the current compiler compares to its predecessors (see the "Benchmarks" box).

In response to a request by several readers, I measured the -O0 time, although this makes the diagrams more dynamic. The new GCC versions compile far more quickly if optimization is disabled. -O0 is particularly useful in the edit-compile cycle during development. The Athlon system I used previously has now been replaced by an AMD64 Turion64.

The most obvious effect is visible in the Botan and Tramp3d C++ tests: 25 percent quicker for O2, and over 40 percent for O3 in the case of Botan. The legacy C benchmark results are a mixed bunch (see Figure 1).

Figure 1: Runtimes for various compiler scenarios.

If you take a look at the build times (Figure 2), you will see how much more work the compiler puts in if a user enables optimization. And the optimization effort is not always reflected as a positive influence on the benchmark runtimes. One thing that makes me optimistic is that at least the demanding Tramp3d C++ benchmark is compiled more quickly by version 4.1 than by the predecessor.

Figure 2: Build times for various compiler scenarios.
Benchmarks

For the benchmarks, I again used the Openbench benchmark collection referred to in previous articles for this magazine. Openbench has now officially made the benchmark list on the GCC homepage [8].

I had to change a few things; I updated Botan again to the more recent version 1.4.12, and replaced the libmad test, which shows very similar results for different compilers, with the Lame open source MP3 encoder.

As many other open source developers are interested in a free benchmark with similar properties to SPEC, I anticipate that an initial reference version of Openbench will be frozen this year for future comparisons. Your comments and assistance are welcome.

SSP

As mentioned earlier, the IBM Stack Smashing Protector lets programmers detect buffer underflows or overflows. To do so, it places a random value from /dev/urandom, or if this is not available, a terminating string \0\xFF\n somewhere near the return address on the stack. If this value is changed when the program exits the function, you can assume that the return address has also been overwritten. This is a technique commonly used by hackers and malware. In this case, the program outputs a warning and quits. If you compile and run the program in Listing 1, you will see an error message similar to the following: * stack smashing detected  *: ./ssp-test terminated

The canary makes it difficult for attackers to inject malevolent code in the form of scripts. The GCC command line parameter, -fstack-protector, enables this protection.

Listing 1: ssp-text.c
01 int f () {
02   char a [200];
03   char* b = a;
04   int i;
05   for (i = 0;
06        i < 201; ++i)
07     a[i] = i;
08 }
09
10 int main () {
11   f ();
12 }

Mudflap

A technique introduced in GCC 4.0 takes this protection one step farther than SSP, enabling validation of pointer references in C and C++. During the build, this mechanism, known as Mudflap [5], instruments memory access to reflect the access type and the conditions the compiler detects at this time. For example, constant propagation could render some checks unnecessary. At runtime, the functions provided by the Libmudflap library validate this access, terminating the program in critical cases. Libmudflap also validates many standard C functions capable of overwriting memory, including mem*, str*, *put*, *get*, and many more. To use Mudflap, all files must be compiled with the -fmudflap flag and linked with -lmudflap. The small C test program in Listing 2 just accesses a memory position one byte beyond the boundary of the a array. In our test, Mudflap correctly pointed out the variable name that overstepped the boundary.

As Mudflap validates memory access in many cases, it can affect performance considerably in comparison to SSP, which is hardly noticeable. In this light, Mudflap is mainly useful for developers who are interested in a quick method of detecting potentially critical errors at an early stage of development.

Listing 2: mudflap-test.c
01 int main () {
02   char a [200];
03   char* b = a;
04   printf ("%c\n", b[200]);
05 }

Future

Version 4.1 of the GNU compiler comes with new optimizations and other important advances. GNU programmers, however, are already looking ahead to the next release. The features scheduled for integration with GCC 4.2 [6] include support for OpenMP [7] and extensions of the C, C++, and Fortran languages to support explicit parallelization. These projects will close the gaps that recently opened up between the free compiler collection and commercial compilers.

INFO
[1] GCC homepage: http://gcc.gnu.org/
[2] Stack Smashing Protector SSP: http://www.trl.ibm,com/projects/security/ssp/
[3] Changes to GCC 4.1: http://gcc.gnu.org/gcc-4.1/changes.html.
[4] Compiling Debian with GCC 4.1 - report on experiences: http://gcc.gnu.org/ml/gcc/2006-03/msg00740.html
[5] Mudflap http://gcc.fyxm.net/summit/2003/mudflap.pdf
[6] GCC 4.2 http://gcc.gnu.org/wiki/GCC%204.2%20Projects
[7] OpenMP http://www.openmp.org/drupal/mp-documents/spec25.pdf
[8] Openbench http://www.exactcode.de/oss/openbench