Course Overview
COP-5621, Spring 2024
Table of Contents
What do you want to get out of this course?
- Intros
- Why are you taking this course?
- What do you hope to learn?
- about me, research, positions
- favorite course
- program analysis and transformation, tool engineers
- use course project to gauge interest
What I hope you will get out of this course
- Deeper understanding of compiler techniques
- See compiler techniques are used in research
Symbols vs. meaning
1 + 2 * 3
6 / 2(1 + 2)
一加二乘三
What gives symbols meaning?
- Moon vs. finger pointing at the moon
- "The map is not the territory"
- the compiler itself defines meaning
- defines input language in terms of output language
- (why does output language have meaning?)
ASCII vs. machine code
od
gcc -S
- ASCII table
What is a compiler?
- What do you think?
Classic phases of a compiler
Dragon book
Front-end
- Language-processing
- Remember regexes, grammar from discrete? (If you took it)
- Type checking
- Did I assign an array to a float?
Back-end
- Code generation
- Equivalent machine code for any valid input program
- Optimization
- Choose equivalent machine code that's faster, smaller, etc.
"Middle-end"
- Intermediate code
- Like machine code
- Without machine specifics
- Lots of different designs
Why an intermediate representation?
Multiple front-ends and back-ends
What makes compiler-writing hard?
Compilers take an entire program as input
Interpreters vs. Compilers
Compilers translate
They do not provide you the output
(Diagram)
- Input: program
- Output: (equivalent) program
Interpreters execute
They do give you the output
(Diagram)
- Input: program
- Output: value
Single execution vs. all executions
Example program
x = input() a = 5 b = a - 3 if x == "yes": b = b * b - 2 print(b)
Example execution
(Diagram)
- input: yes
- output: 4
- one input represents one execution trace (in deterministic programs)
- trace: one sequence of state changes, steps through the program
- are traces always unique?
- is a trace always finite?
All executions
(Diagram)
- set of all traces
- can we compute them all?
- is the set of all traces always finite?
Example: translate to machine code
x = input() a = 5 b = a - 3 if x == "yes": b = b * b - 2 print(b)
(Diagram)
- pick any machine-code-like language (finite registers, single arithmetic operations, branches, etc.)