GCC—An Architectural Overview, Current Status, and Future Directions
Total Page:16
File Type:pdf, Size:1020Kb
GCC—An Architectural Overview, Current Status, and Future Directions Diego Novillo Red Hat Canada [email protected] Abstract GCC one of the most popular compilers in use today. It serves as the system compiler for every Linux distribution and it is also fairly The GNU Compiler Collection (GCC) is one popular in academic circles, where it is used of the most popular compilers available and it for compiler research. Despite this popular- is the de facto system compiler for Linux sys- ity, GCC has traditionally proven difficult to tems. Despite its popularity, the internal work- maintain and enhance, to the extreme that some ings of GCC are relatively unknown outside of features were almost impossible to implement. the immediate developer community. And as a result GCC was starting to lag behind This paper provides a high-level architectural the competition. overview of GCC, its internal modules, and Part of the problem is the size of its code base. how it manages to support a wide variety of While GCC is not huge by industry standards, hardware architectures and languages. Special it still is a fairly large project, with a core emphasis is placed on high-level descriptions of about 1.3 MLOC. Including the runtime li- of the different modules to provide a roadmap braries needed for all the language support, to GCC. GCC comes to about 2.2 MLOC.1 Finally, the paper also describes recent techno- logical improvements that have been added to Size is not the only hurdle presented by GCC. GCC and discusses some of the major features Compilers are inherently complex and very de- that the developer community is thinking for manding in terms of the theoretical knowl- future versions of the compiler. edge required, particularly in the area of opti- mization and analysis. Additionally, compilers are dull, dreary and rarely provide immediate gratification, as interesting features often take 1 Introduction weeks or months to implement. Over the last few releases, GCC’s internal in- The GNU Compiler Collection (GCC) has frastructure has been overhauled to address evolved from a relatively modest C compiler these problems. This has facilitated the im- to a multi-language compiler that can generate code for more than 30 architectures. This di- 1Data generated using David A. Wheeler’s ’SLOC- versity of languages and architectures has made Count’. 186 • GCC—An Architectural Overview, Current Status, and Future Directions plementation of a new SSA based global opti- lows all directory names are assumed to be rel- mizer, sophisticated data dependency analyses, ative to the root directory where GCC sources a multi-platform vectoriser, a memory bounds live. checker (mudflap) and several other new fea- tures. 2.1 Core This paper describes the major components in GCC and their internal organization. Note that The gcc directory contains the C front end, this is not intended to be a replacement for middle end, target-independent back end com- GCC’s internal documentation. Many modules ponents, and a host of other modules needed are overlooked or described only briefly. The by various parts of the compiler. This includes intent of this document is to serve as introduc- diagnostic and error machinery, the driver pro- tory material for anyone interested in extending gram, option handling, and data structures such or maintaining GCC. as bitmaps, sets, etc. The other front ends are contained in their own subdirectories: gcc/ada, gcc/cp (C++), 2 Overview of GCC gcc/fortran (Fortran 95), gcc/java, gcc/objc (Objective-C), gcc/objcp (Ob- GCC is essentially a big pipeline that converts jective C++), and gcc/treelang, which is a one program representation into another. There small toy language used as an example of how are three main components: front end (FE), to implement front ends. middle end (ME)2 and back end (BE). Source gcc/config code enters the front end and flows through the Directories inside contain all pipeline, being converted at each stage into suc- the target-dependent back end components. cessively lower-level representation forms until This includes the machine description (MD) final code generation in the form of assembly files that describe code generation patterns code that is then fed into the assembler. and support functions used by the target- independent back end functions. Figure 1 shows a bird’s eye view of the com- piler. Notice that the different phases are se- 2.2 Runtime quenced by the Call Graph and Pass managers. The call graph manager builds a call graph for the compilation unit and decides in which or- Most languages and some GCC features require der to process each function. It also drives a runtime component, which can be found at the inter-procedural optimizations (IPO) such the top of the directory tree: as inlining. The pass manager is responsible for sequencing the individual transformations The Java runtime is in boehm-gc (garbage and handling pre and post cleanup actions as collection), libffi (foreign function in- needed by each pass. terface), libjava and zlib. The source code is organized in three major The Ada, C++, Fortran 95 and groups: core, runtime and support. In what fol- Objective-C runtime are in libada, 2Consistency in naming conventions led to this unfor- libstdc++-v3, libgfortran and tunate term. libobjc respectively. 2006 Linux Symposium, Volume Two • 187 C C++ Java Fortran parser parser parser parser Pass Manager Front End (FE) GENERIC Inlining Constant Propagation (IPCP) Static variable analysis Points-to alias analysis Middle End (ME) GIMPLE Flow sensitive and flow insensitive alias analysis Constant Propagation (CCP) Interprocedural Full Redundancy Elimination (FRE) Optimizer Dead Code Elimination (DCE) Forward Propagation Jump Threading Copy Propagation (COPY-PROP) Call Graph SSA Value Range Propagation (VRP) Manager Optimizer Scalar Replacement of Aggregates (SRA) Dead Store Elimination (DSE) Tail Call discovery Partial Redundancy Elimination (PRE) Loop Optimizations Loop Invariant Motion (LIM) Back End (BE) RTL Loop Unswitching Loop Interchange Induction Variable Optimizations If conversion Vectorization RTL Loop Prefetching Optimizer Loop Unrolling Empty Loop Elimination Assembly Sibling/tail call optimization Life and Data Flow Analysis Common Subexpression Elimination (CSE) Branch prediction Instruction Combination Mode Switching Instruction Scheduling Register Allocation Register Renaming Peephole Optimizations Branch Shortening Machine Specific Reorganizations Figure 1: An Overview of GCC 188 • GCC—An Architectural Overview, Current Status, and Future Directions The preprocessor is implemented as a separate 2 is the stabilization phase, only minor fea- library in libcpp. tures are allowed and bug fixes that maintain- ers consider safe to include. Stage 3 marks A decimal arithmetic library is included in the preparation for release. During this phase libdecnumber. only bug and documentation fixes are allowed. In particular, these bug fixes are usually re- The OpenMP [14] runtime is in libgomp. quired to have a corresponding entry in GCC’s Mudflap [6], the pointer and memory check bug tracking database (http://gcc.gnu. facility, has its runtime component in org/bugzilla). libmudflap. At the end of stage 3, the release manager will The library functions for SSP (Stack Smash cut a release branch. Stabilization work con- Protection) are in libssp. tinues on the release branch and a release crite- ria is agreed by consensus between the release manager and the maintainers. Release block- 2.3 Support ing bugs are identified in the bugzilla database and the release is done once all the critical bugs have been fixed.3 Once the release branch is Various utility functions and generic data struc- created, Stage 1 for the next release begins. tures, such as bitmaps, sets, queues, etc. are im- plemented in libiberty. The configuration and build machinery live in build and vari- Using this system, GCC is averaging about a ous scripts useful for developers are stored in couple of releases a year. Once version X.Y is contrib. released, subsequent releases in the X.Y series continues. In this case, another release manager takes over the X.Y series, which accepts no new 2.4 Development Model features, just bug fixes. Major development that spans multiple releases All the major decisions in GCC are taken by is done in branches. Anyone with write access the GCC Steering Committee. This usually to the GCC repository may create a develop- includes determining maintainership rights for ment branch and develop the new feature on contributors, interfacing with the FSF, approv- the branch. When that feature is ready, they ing the inclusion of major features and other can propose including it at the next Stage 1. administrative and political decisions regard- Vendors usually create their own branches from ing the project. All these decisions are guided FSF release branches. by GCC’s mission statement (http://gcc. gnu.org/gccmission.html). All contributors must sign an FSF copyright re- lease to be able to contribute to GCC. If the GCC goes through three distinct development work is done as part of their employment, their stages, which are coordinated by GCC’s re- employer must also sign a copyright release lease manager and its maintainers. Each stage form to the FSF. usually lasts between 3 and 5 months. Dur- ing Stage 1, big and disruptive changes are 3It may also happen that some of these bugs are sim- allowed. This is where all the major fea- ply moved over to the next release, if they are not deemed tures are incorporated into the compiler. Stage to be as critical as initially thought. 2006 Linux Symposium, Volume Two • 189 3 GENERIC Representation f(int a, int b, int c) { if (g (a + b, c)) Every language front end is responsible for all c = b++ / a the syntactic and semantic processing for the return c corresponding input language.