a + b

advertisement
Fall 2014-2015 Compiler Principles
Lecture 0: Local Optimizations
Roman Manevich
Ben-Gurion University
Tentative syllabus
Front
End
Intermediate
Representation
Optimizations
Code
Generation
Local
Optimizations
Register
Allocation
Top-down
Parsing (LL)
Dataflow
Analysis
Instruction
Selection
Bottom-up
Parsing (LR)
Loop
Optimizations
Scanning
mid-term
Lowering
exam
2
Previously
•
•
•
•
The need for Intermediate Representations
Three-Address Code
Lowering abstract syntax trees (AST) to IR
Sethi-Ullman algorithm for efficient lowering
3
agenda
• Introduction to optimizations
• Formalisms for program analysis
– Basic blocks
– Control flow graphs
• Local program analyses and optimizations
– Available expressions  common sub-expression
elimination + copy propagation
– Live variables  dead code elimination
4
Introduction to optimizations
5
Optimization points
source
code
User
profile program
change algorithm
Front
end
IR
Compiler
apply IR optimizations
Code
generator
target
code
Compiler
register allocation
instruction selection
peephole transformations
today
and next week
6
Overview of IR optimization
• Formalisms and Terminology
– Control-flow graphs
– Basic blocks
• Local optimizations
– Optimizing small pieces of a function
• Global optimizations
– Optimizing functions as a whole
• The dataflow framework
– Defining and implementing a wide class of
optimizations
7
Semantics-preserving optimizations
• An optimization is semantics-preserving if it does not alter
the semantics of the original program
• Examples:
– Eliminating unnecessary statements
– Computing values that are known statically at compile-time
instead of runtime
– Evaluating constant expressions outside of a loop instead of
inside
• Non-examples:
– Reordering side-effecting computations
– Replacing bubble sort with quicksort (why?)
• The optimizations we will consider in this class are all
semantics-preserving
• How can we find opportunities for optimizations?
8
Program analysis
• In order to optimize a program, the compiler
has to be able to reason about the properties
of that program
• An analysis is called sound if it never asserts
an incorrect fact about a program
• All the analyses we will discuss in this class are
sound
– (Why?)
9
Soundness
int x;
int y := get();
if (y < 5)
x := 137;
else
x := 42;
“At this point in the
program, x holds some
integer value”
Print(x);
10
Soundness
int x;
int y := get();
if (y < 5)
x := 137;
else
x := 42;
“At this point in the
program, x is either 137 or 42”
Print(x);
11
Soundness
int x;
int y := get();
if (y < 5)
x := 137;
else
x := 42;
“At this point in the
program, x is 137”
Print(x);
12
Soundness
int x;
int y := get();
if (y < 5)
x := 137;
else
x := 42;
“At this point in the
program, x is either 137, 42, or 271”
Print(x);
13
Control flow graphs
14
Visualizing IR
main:
_tmp0 := Call _ReadInteger;
a := _tmp0;
_tmp1 := Call _ReadInteger;
b := _tmp1;
_L0:
_tmp2 := 0;
_tmp3 := b == _tmp2;
_tmp4 := 0;
_tmp5 := _tmp3 == _tmp4;
IfZ _tmp5 Goto _L1;
c := a;
a := b;
_tmp6 := c % a;
b := _tmp6;
Goto _L0;
_L1:
Push a;
Call _PrintInt;
15
Visualizing IR
main:
_tmp0 := Call _ReadInteger;
a := _tmp0;
_tmp1 := Call _ReadInteger;
b := _tmp1;
_L0:
_tmp2 := 0;
_tmp3 := b == _tmp2;
_tmp4 := 0;
_tmp5 := _tmp3 == _tmp4;
IfZ _tmp5 Goto _L1;
c := a;
a := b;
_tmp6 := c % a;
b := _tmp6;
Goto _L0;
_L1:
Push a;
Call _PrintInt;
16
Visualizing IR
main:
_tmp0 := Call _ReadInteger;
a := _tmp0;
_tmp1 := Call _ReadInteger;
b := _tmp1;
_L0:
_tmp2 := 0;
_tmp3 := b == _tmp2;
_tmp4 := 0;
_tmp5 := _tmp3 == _tmp4;
IfZ _tmp5 Goto _L1;
c := a;
a := b;
_tmp6 := c % a;
b := _tmp6;
Goto _L0;
_L1:
Push a;
Call _PrintInt;
start
_tmp0 := Call _ReadInteger;
a := _tmp0;
_tmp1 := Call _ReadInteger;
b := _tmp1;
_tmp2 := 0;
_tmp3 := b == _tmp2;
_tmp4 := 0;
_tmp5 := _tmp3 == _tmp4;
IfZ _tmp5 Goto _L1;
c := a;
a := b;
_tmp6 := c % a;
b := _tmp6;
Goto _L0;
Push a;
Call _PrintInt;
end
17
Basic blocks
• A basic block is a sequence of IR instructions
where
– There is exactly one spot where control enters the
sequence, which must be at the start of the
sequence
– There is exactly one spot where control leaves the
sequence, which must be at the end of the
sequence
• Informally, a sequence of instructions that
always execute as a group
18
Control-flow graphs
• A control-flow graph (CFG) is a graph of the
basic blocks in a function
– From here on CFG stands for “control-flow graph”
and not “context free grammar”
• Each edge from one basic block to another
indicates that control can flow from the end of
the first block to the start of the second block
• Dedicated nodes for the start and end of a
function
19
Scope of optimizations
• An optimization is local if it works on just a
single basic block
• An optimization is global if it works on an
entire control-flow graph
• An optimization is interprocedural if it works
across the control-flow graphs of multiple
functions
– We won't talk about this in this course
20
Examples of control flow
graphs and optimizations
21
Basic blocks example
int main() {
int x;
int y;
int z;
START:
y := 137 + 3;
if (x == 0)
z := y;
else
x := y;
{
_t0 := 137;
y := _t0 + 3;
IfZ x Goto _L0;
_t1 := y;
z := _t1;
Goto END:
_L0:
_t2 := y;
x := _t2;
END:
Divide the code into basic blocks
22
Control-flow graph example
int main() {
int x;
int y;
int z;
START:
y := 137 + 3;
if (x == 0)
z := y;
else
x := y;
{
_t0 := 137;
y := _t0 + 3;
IfZ x Goto _L0;
_t1 := y;
z := _t1;
Goto END:
_L0:
_t2 := y;
x := _t2;
END:
Draw the control-flow graph
23
Control-flow graph example
int main() {
int x;
int y;
int z;
y := 137 + 3;
if (x == 0)
z := y;
else
x := y;
{
start
_t0 := 137;
y := _t0 + 3;
IfZ x Goto _L0;
_t1 := y;
z := _t1;
_t2 := y;
x := _t2;
end
24
Local optimizations example
int main() {
int x;
int y;
int z;
y := 137 + 3;
if (x == 0)
z := y;
else
x := y;
{
start
_t0 := 137;
y := _t0 + 3;
IfZ x Goto _L0;
_t1 := y;
z := _t1;
_t2 := y;
x := _t2;
end
25
Local optimizations example
int main() {
int x;
int y;
int z;
y := 137 + 3;
if (x == 0)
z := y;
else
x := y;
{
start
_t0 := 137;
y := _t0 + 3;
IfZ x Goto _L0;
_t1 := y;
z := _t1;
_t2 := y;
x := _t2;
end
26
Local optimizations example
int main() {
int x;
int y;
int z;
y := 137 + 3;
if (x == 0)
z := y;
else
x := y;
{
start
Copy
propagation
y := 137 + 3;
IfZ x Goto _L0;
_t1 := y;
z := _t1;
_t2 := y;
x := _t2;
end
27
Local optimizations example
int main() {
int x;
int y;
int z;
y := 137 + 3;
if (x == 0)
z := y;
else
x := y;
{
start
Constant
folding
y := 140;
IfZ x Goto _L0;
_t1 := y;
z := _t1;
_t2 := y;
x := _t2;
end
28
Local optimizations example
int main() {
int x;
int y;
int z;
start
y := 137 + 3;
if (x == 0)
z := y;
else
x := y;
{
Copy
propagation
y := 140;
IfZ x Goto _L0;
_t1 := y;
z := y;
_t2 := y;
x := _t2;
end
29
Local optimizations example
int main() {
int x;
int y;
int z;
y := 137 + 3;
if (x == 0)
z := y;
else
x := y;
{
start
y := 140;
IfZ x Goto _L0;
Dead
code
elimination
_t2 := y;
x := _t2;
z := y;
end
30
Local optimizations example
int main() {
int x;
int y;
int z;
y := 137 + 3;
if (x == 0)
z := y;
else
x := y;
{
start
y := 140;
IfZ x Goto _L0;
_t2 := y;
x := _t2;
z := y;
end
31
Local optimizations example
int main() {
int x;
int y;
int z;
start
y := 140;
IfZ x Goto _L0;
y := 137 + 3;
if (x == 0)
z := y;
else
x := y;
{
z := y;
Copy propagation
followed by
dead code
elimination
x := y;
end
32
Global optimizations example
int main() {
int x;
int y;
int z;
y := 137 + 3;
if (x == 0)
z := y;
else
x := y;
{
start
y := 140;
IfZ x Goto _L0;
z := y;
x := y;
end
33
Global optimizations example
int main() {
int x;
int y;
int z;
y := 137 + 3;
if (x == 0)
z := y;
else
x := y;
{
start
y := 140;
IfZ x Goto _L0;
z := y;
x := y;
end
34
Global optimizations example
int main() {
int x;
int y;
int z;
start
y := 137 + 3;
if (x == 0)
z := y;
else
x := y;
{
Copy
propagation
y := 140;
IfZ x Goto _L0;
z := 140;
x := 140;
end
35
Common Subexpression
elimination
36
CSE Example
b
c
d
e
:=
:=
:=
:=
a
a
b
b
*
*
+
+
a;
a;
c;
b;
37
CSE Example
b
c
d
e
:=
:=
:=
:=
a
a
b
b
*
*
+
+
a;
a;
c;
b;
38
CSE Example
b
c
d
e
:=
:=
:=
:=
a * a;
b;
b + c;
b + b;
Common sub-expression elimination
39
Common Subexpression Elimination
• If we have two variable assignments
v1 := a op b
…
v2 := a op b
• and the values of v1, a, and b have not changed
between the assignments, rewrite the code as
v1 := a op b
…
v2 := v1
• Eliminates useless recalculation
• Paves the way for later optimizations
40
copy propagation
41
CP Example
b
c
d
e
:=
:=
:=
:=
a * a;
b;
b + c;
b + b;
42
CP Example
b
c
d
e
:=
:=
:=
:=
a * a;
b;
b + b;
b + b;
Copy propagation
43
Copy Propagation
• If we have a variable assignment
v1 := v2
then as long as v1 and v2 are not reassigned,
we can rewrite expressions of the form
a := … v1 …
as
a := … v2 …
44
Local optimizations example
b
c
d
e
:=
:=
:=
:=
a * a;
b;
b + b;
b + b;
Which optimization should we apply here?
45
Local optimizations example
b
c
d
e
:=
:=
:=
:=
a * a;
b;
b + b;
d;
Which optimization should we apply here?
Common sub-expression elimination (again)
46
Optimizations and analyses
• Most optimizations are only possible given some
analysis of the program's behavior
• In order to implement an optimization, we will
talk about the corresponding program analyses
• Program analysis = algorithm that processes
program and infers facts
– Sound facts = facts that hold for all program
executions
– Sound analysis = program analysis that infers only
sound facts
47
Available expressions
48
Available expressions
• Both common subexpression elimination and copy
propagation depend on an analysis of the available
expressions in a program
• An expression a = b op c is called available at program
location L if variable a holds the value of b op c at that
location
– Similarly for a = b
• In common subexpression elimination, we replace an
available expression (b op c) by the variable holding its
value (a)
• In copy propagation, we replace the use of a variable
(a) by the available expression it holds (b)
49
Finding available expressions
• Compute for each program location L a set of
expressions AEL of the forms a = b op c and a = b
that are definitely available there
• Idea: Iterate across the basic block, beginning
with the empty set of expressions and updating
available expressions at each statement
• Whenever we execute a statement
a := b op c:
– Any expression holding a is invalidated
– The expression a = b op c becomes available
50
Available expressions step
Input Value
AEin
a := b + c
Note that this is an equation (a fact) –
not a statement
AEout = (AEin \ {e | e contains a})
{a=b+c}
Expressions of the forms
a=…
and
x=…a…
Output Value
AEout
Provided that a and b and a and c
are different pairs of variables
51
Available expressions example
{ }
a := b;
{ a = b }
c := b;
{ a = b, c
d := a + b;
{ a = b, c
e := a + b;
{ a = b, c
d := b;
{ a = b, c
f := a + b;
{ a = b, c
= b }
= b, d = a + b }
= b, d = a + b, e = a + b }
= b, d = b, e = a + b }
= b, d = b, e = a + b, f = a + b }
52
Optimizing via available expressions
• Common sub-expression elimination
– If {… t = y op z … } x := y op z
– Can transform statement into x := t
• Copy propagation
– If {… y = t … } x := y op z
– Can transform statement into x := t op z
• Note: same for x=y
53
Applying CSE + CP
{ }
a := b;
{ a = b }
c := b;
{ a = b, c
d := a + b;
{ a = b, c
e := a + b;
{ a = b, c
d := b;
{ a = b, c
f := a + b;
{ a = b, c
= b }
= b, d = a + b }
= b, d = a + b, e = a + b }
= b, d = b, e = a + b }
= b, d = b, e = a + b, f = a + b }
54
Applying CSE + CP
{ }
a := b;
{ a = b }
c := b;
{ a = b, c
d := a + b;
{ a = b, c
e := a + b;
{ a = b, c
d := b;
{ a = b, c
f := a + b;
{ a = b, c
= b }
= b, d = a + b }
= b, d = a + b, e = a + b }
= b, d = b, e = a + b }
= b, d = b, e = a + b, f = a + b }
55
Applying CSE + CP
{ }
a := b;
{ a = b }
c := a;
{ a = b, c
d := a + b;
{ a = b, c
e := d;
{ a = b, c
d := a;
{ a = b, c
f := e;
{ a = b, c
= b }
= b, d = a + b }
= b, d = a + b, e = a + b }
= b, d = b, e = a + b }
= b, d = b, e = a + b, f = a + b }
56
dead code elimination
57
Dead code elimination
a := b;
c := a;
d := a + b;
Can we remove this statement?
Can we remove this statement?
Can we remove this statement?
e := d;
Can we remove this statement?
d := a;
Can we remove this statement?
f := e;
Can we remove this statement?
Print(d);
Can we remove this statement?
58
Dead code elimination
• An assignment to a variable v is called dead if
the value of that assignment is never read
anywhere
• Dead code elimination removes dead
assignments from IR
• Determining whether an assignment is dead
depends on assignments preceding it
59
Live variables
• The analysis corresponding to dead code
elimination is called liveness analysis
• A variable is live at a point in a program if later
in the program its value will be read before it
is written to again
• Dead code elimination works by computing
liveness for each variable, then eliminating
assignments to dead variables
60
Computing live variables
• To know if a variable will be used at some point, we
iterate across the statements in a basic block in reverse
order
• Initially, some small set of values are known to be live
(which ones depends on the particular program)
– Usually arguments of a function call or a returned variable
(temporaries that are pushed on the stack)
• When we see the statement a := b op c:
– Just before the statement, a is not alive, since its value is
about to be overwritten
– Just before the statement, both b and c are alive, since
we're about to read their values
– (what if we have a := a + b?)
61
Live variables step
Input Value
LVin
a := b + c
LVin = (LVout \ {a})
{b,c}
Output Value
LVout
62
{ b }
a := b;
{ a, b }
c := a;
{ a, b }
d := a + b;
{ a, b, d }
e := d;
{ a, b, e }
d := a;
{ b, d, e }
f := e;
{ b, d }
Push b;
{ d }
Push d;
{ }
Liveness analysis
Which statements are dead?
63
Optimizing via liveness analysis
• Dead code elimination
– If x := y op z {v1,…,vk}
– And x {v1,…,vk}
– We can eliminate x := y op z
• Note: same for x:=y
64
Dead code elimination
{ b }
a := b;
{ a, b }
c := a;
Which statements are dead?
{ a, b }
d := a + b;
{ a, b, d }
e := d;
{ a, b, e }
d := a;
{ b, d, e }
f := e;
{ b, d } - given
65
Dead code elimination
{ b }
a := b;
{ a, b }
{ a, b }
d := a + b;
{ a, b, d }
e := d;
{ a, b, e }
d := a;
{ b, d, e }
{ b, d }
66
Liveness analysis II
{ b }
a := b;
{ a, b }
d := a + b;
{ a, b, d }
e := d;
{ a, b }
d := a;
{ b, d }
Which statements are dead?
67
Liveness analysis II
{ b }
a := b;
{ a, b }
d := a + b;
{ a, b, d }
e := d;
{ a, b }
d := a;
{ b, d }
Which statements are dead?
68
Dead code elimination
{ b }
a := b;
{ a, b }
d := a + b;
{ a, b, d }
e := d;
{ a, b }
d := a;
{ b, d }
Which statements are dead?
69
Dead code elimination
{ b }
a := b;
{ a, b }
d := a + b;
{ a, b, d }
{ a, b }
d := a;
{ b, d }
70
Liveness analysis III
{ b }
a := b;
{ a, b }
d := a + b;
Which statements are dead?
{ a, b }
d := a;
{ b, d }
71
Dead code elimination
{ b }
a := b;
{ a, b }
d := a + b;
Which statements are dead?
{ a, b }
d := a;
{ b, d }
72
Dead code elimination
{ b }
a := b;
{ a, b }
{ a, b }
d := a;
{ b, d }
73
Dead code elimination
a := b;
If we further apply
copy propagation
this statement can
be eliminated too
d := a;
74
A combined algorithm
• Start with initial live variables at end of block
• Traverse statements from end to beginning
• For each statement
– If assigns to dead variables – eliminate it
– Otherwise, compute live variables before
statement and continue in reverse
75
A combined algorithm
a := b;
c := a;
d := a + b;
e := d;
d := a;
f := e;
76
A combined algorithm
a := b;
c := a;
d := a + b;
e := d;
d := a;
f := e;
{ b, d }
77
A combined algorithm
a := b;
c := a;
d := a + b;
e := d;
d := a;
f := e;
{ b, d }
78
A combined algorithm
a := b;
c := a;
d := a + b;
e := d;
d := a;
{ b, d }
79
A combined algorithm
a := b;
c := a;
d := a + b;
e := d;
{ a, b }
d := a;
{ b, d }
80
A combined algorithm
a := b;
c := a;
d := a + b;
e := d;
{ a, b }
d := a;
{ b, d }
81
A combined algorithm
a := b;
c := a;
d := a + b;
{ a, b }
d := a;
{ b, d }
82
A combined algorithm
a := b;
c := a;
d := a + b;
{ a, b }
d := a;
{ b, d }
83
A combined algorithm
a := b;
c := a;
{ a, b }
d := a;
{ b, d }
84
A combined algorithm
a := b;
c := a;
{ a, b }
d := a;
{ b, d }
85
A combined algorithm
a := b;
{ a, b }
d := a;
{ b, d }
86
A combined algorithm
{ b }
a := b;
{ a, b }
d := a;
{ b, d }
87
A combined algorithm
a := b;
d := a;
88
Notes about optimizations
89
Applying local optimizations
• The different optimizations we've seen so far
all take care of just a small piece of the
optimization
– Common subexpression elimination eliminates
unnecessary statements
– Copy propagation helps identify dead code
– Dead code elimination removes statements that
are no longer needed
• To get maximum effect, we may have to apply
these optimizations numerous times
90
Optimization path
done
with IR
optimizations
IR
CFG
builder
Control-Flow
Graph
Code
Generation
(+optimizations)
IR
optimizations
Target
Code
Program
Analysis
Annotated
CFG
Optimizing
Transformation
91
Other types of local optimizations
• Arithmetic Simplification
– Replace “hard” operations with easier ones
– e.g. rewrite x := 4 * a; as x := a << 2;
• Constant Folding
– Evaluate expressions at compile-time if they have
a constant value.
– e.g. rewrite x := 4 * 5; as x := 20;
92
Next lecture:
Global Optimizations
via Dataflow Analysis
Download