15-745 Optimizing Compilers: What Is A Compiler?
15-745 Optimizing Compilers: What Is A Compiler?
15-745 Optimizing Compilers: What Is A Compiler?
What is a compiler?
A compiler translates source programs into target programs Source programs are usually in a highlevel, human-readable form that species both static (compile-time) and dynamic (run-time) computations Target programs are usually machine executable and specify only run-time computations
static computations
target program machine
This course is about optimizing compilers methods for automatically improving the quality of the target programs, usually for faster execution usually based on a semantics-based analysis of the program
dynamic computations
results
Id rather have a search engine or a compiler on a deserted island than a game. - John Carmack, Co-founder, id Soft ware
Compiler structure
string of characters lexical analyzer sequence of tokens parser symbol table abstract syntax tree semantic analyzer intermediate code code generator relocatable object code
MIPS
OCaml
PPC
C#
ARM
n!m compilers!
More realistically...
Abstract syntax Reductions lex parse parsing actions semantic analysis Translate Machine code Flow Graph Tokens
Translate
IR
canonicalize
Assembly code
OCaml
IR
IR
MIPS
translate
instruction selection
C#
ARM
code emission
Relocatable code
Register assignment
Assem
assembler
linker
vs n+m compilers
This course
Theory and practice of modern optimizing compilers major focus: analysis and optimizing transformations of the intermediate representation some on target code transformations some on run-time systems no lexing, parsing, typechecking
Optimization
The most important function of a compiler is static code checking/analysis But almost as important is optimization Optimization was the driving force behind the modern RISC microprocessors... ...and today the language+compiler is the driving force behind architecture developments such as multi-core processors
What is optimization?
Informally: Transform a program into an equivalent but better form
[Note: Red denotes dangerous hand-waving!]
Optimize is a bit of a misnomer the results are almost never optimal the Full Employment Theorem anyway, what is meant by better?
cache
virtual memory
CPU
regs
8B
cache memory
32B
main memory
60ns
8KB
disk
3ns
6ns
Most optimizations performed on an intermediate form larger, slower, cheaper Eases retargeting to multiple source and target languages 8ms
Most optimizations we can imagine or desire are not susceptible to this recipe
SumFrom1toN (int max) { sum = 0; for (i=1; i<max; i++) sum += i; return sum; }
optimizer
Local optimizations
Some optimizations are local, meaning that the legality and desirability for a statement or expression can be determined in isolation from the rest of the program
Algebraic simplications
a*1 + a/1 + a*0 + a+0 + a-0 +
a = b+1 c = a-1
a a 0 a a + c=b
Global optimizations
The most important optimizations are global They typically require a semantics-based analysis of the entire procedure (or program) dataow analysis abstract interpretation
Dead-code elimination
debug = false; ... if (debug) { ... } ...
If code will never be executed or its result and effect will never be used, eliminate it
Constant propagation
a = 5; b = 3; ... n = a + b; for (i=0; i<n; ++i) .. a = 5; b = 3; ... n = 5 + 3; for (i=0; i<n; ++i) ..
Constant folding
a = 5; b = 3; ... n = 5 + 3; for (i=0; i<n; ++i) .. ... n = 8; for (i=0; i<n; ++i) ..
Local and global optimizations can trigger additional local and global optimization opportunities
Redundant computations
The detection and elimination of (fully or partially) redundant computations is perhaps the major goal of an optimizer
Oops!
Semantics-based analyses
We will spend considerable time on the theory and practice of dataow analysis This is the major semantics-based analysis used by most optimizing compilers Some particularly difcult problems, such as predicting aliasing or heap pointer structure, seem less susceptible to dataow analysis and often use other methods
Code-level optimizations
Some optimizations are code-level, i.e., performed on the target code (or some machine-dependent intermediate form)
Jump optimizations
cmp d0,d1 beq L1 br L2 L1: ... ... L2: ... ... cmp d0,d1 bne L2 L1: ... ... L2: ... ...
Strength reduction
b*2 + -1 * b + b+b + -b lsh(b)
On some processors, some operations are signicantly less expensive than others
Cache optimizations
for (j=0; j<n; ++j) for (i=0; i<n; ++i) x += a[i][j]; for (i=0; i<n; ++i) for (j=0; j<n; ++j) x += a[i][j];
i Loop permutation can sometimes improve the spatial locality of memory accesses
Course staff
Peter Lee
Prerequisites
undergraduate architecture course e.g., 15-213 undergraduate compiler design course e.g., 15-411 prociency in SML, OCaml, or Java programming basic understanding of architecture, especially x86
Tasks
We will assign tasks to implement specic optimizations in a compiler this guarantees that you will denitely understand and gain experience with some basics We will give you a basic compiler a toy compiler, but the optimization tasks will be realistic You will evaluate your own compiler, submit the results, and this is your grade
Readings
Textbook: Steven Muchnick, Advanced Compiler Design and Implementation, Morgan Kaufmann, 1997 Reading list assignments: In-class presentations, as time allows Reading list is forthcoming
Course schedule
Web site forthcoming will contain schedule of lectures, tasks, etc also lots of support material and writeups, including task information
Communication
Please send email to Mike (mderosa@cs) to get put onto the class mailing list