Software and Optimizing Compilers

Computer Architecture and Systems

Constructing efficient software for different applications (video game vs. a web browser) running on different hardware platforms (desktop vs. mobile phone) is extremely challenging. This is partly because software development is a challenging task and partly because our expectations of software steadily grow. With each new generation of desktop or mobile phone, for example, we expect higher performance, lower power/longer battery life, increased reliability, and greater security. One way to help meet these expectations is the development of automatic tools that can analyze source code, optimize it for a particular platform, and catch errors and other programming flaws. These analyses and optimizations can be implemented as part of a compiler.

A compiler performs three distinct and inter-related tasks: it translates from a high level language to a target hardware-interpretive language, it optimizes the code to both improve the quality of the translation and improve on the programmer's work, and it creates a schedule to efficiently use hardware's resources when the program is ultimately run. These tasks typically involve multiple steps:

  • Compiler analysis - This is the process to gather program information from the intermediate representation of the input source files. Typical analysis are variable define-use and use-define chain, data dependence analysis, alias analysis etc. Accurate analysis is the base for any compiler optimizations. The call graph and control flow graph are usually also built during the analysis phase.
  • Optimization/Transformation - the intermediate language representation is transformed into functionally equivalent but faster (or smaller) forms. Popular optimizations are inline expansion, dead code elimination, constant propagation, loop transformation, register allocation or even automatic parallelization. Innovative transformations that improve reliability/security by testing for programming errors, like double-free errors or NULL-pointer dereferences, are also possible.
  • Code generation - the transformed intermediate language is translated into the output language, usually the native machine language of the system. This involves resource and storage decisions, such as deciding which variables to fit into registers and memory and the selection and scheduling of appropriate machine instructions along with their associated addressing modes. Analysis of memory requirements and execution time is also suitable in this phase.

Students can learn more about Software and Compiler Optimizations in a sequence of courses spanning the undergraduate and graduate curriculum. At the 500 level and lower, students learn about techniques for software design (ECE 517) and generating efficient code for modern architectures (ECE 466/566). In the 700 level courses, students can explore advanced analyses and optimizations for parallelization and reliability (ECE 743, ECE 785). This coursework prepares students for jobs in industry and for Masters and Ph.D. level research in this area.


code generation, optimization, compiler analysis, data dependence analysis, alias analysis, automatic parallelization, speculative parallelization, loop transformation, register allocation, instruction selection, instruction scheduling, resource scheduling, reliability

Associated Courses