languages and compilers (sprog og oversættere) lecture 15 (1) compiler optimizations

37
1 Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations Bent Thomsen Department of Computer Science Aalborg University wledgement to Norm Hutchinson and Mooly Sagiv whose slides this lecture is b

Upload: shanta

Post on 05-Jan-2016

51 views

Category:

Documents


2 download

DESCRIPTION

Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations. Bent Thomsen Department of Computer Science Aalborg University. With acknowledgement to Norm Hutchinson and Mooly Sagiv whose slides this lecture is based on. Compiler Optimizations. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

1

Languages and Compilers(SProg og Oversættere)

Lecture 15 (1)

Compiler Optimizations

Bent Thomsen

Department of Computer Science

Aalborg University

With acknowledgement to Norm Hutchinson and Mooly Sagiv whose slides this lecture is based on.

Page 2: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

2

Compiler Optimizations

The code generated by the Mini Triangle compiler is not efficient:• We did some optimizations by special code templates, but

– It still computes some values at runtime that could be known at compile time– It still computes values more times than necessary– It produces code that will never be executed

We can do better! We can do code transformations• Code transformations are performed for a variety of reasons among which are:

– To reduce the size of the code – To reduce the running time of the program – To take advantage of machine idioms

• Code optimizations include:– Constant folding– Common sub-expression elimination– Code motion– Dead code elimination

• Mathematically, the generation of optimal code is undecidable.

Page 3: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

3

Criteria for code-improving transformations

• Preserve meaning of programs (safety) – Potentially unsafe transformations

• Associative reorder of operands

• Movement of expressions and code sequences

• Loop unrolling

• Must be worth the effort (profitability) and – on average, speed up programs

• 90/10 Rule: Programs spend 90% of their execution time in 10% of the code. Identify and improve "hot spots" rather than trying to improve everything.  

Page 4: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

4

Constant folding

• Consider:

• The compiler could compute 4 / 3 * pi as 4.1888 before the program runs. This saves how many instructions?

• What is wrong with the programmer writing

4.1888 * r * r * r?

static double pi = 3.1416;double volume = 4/3 * pi * r * r * r;

Page 5: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

5

Constant folding II

• Consider:

• If the address of holidays is x, what is the address of holidays[2].m?

• Could the programmer evaluate this at compile time? Safely?

struct { int y, m, d; } holidays[6];holidays[2].m = 12;holidays[2].d = 25;

Page 6: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

6

Common sub-expression elimination

• Consider:

• Computing x – y takes three instructions, could we save some of them?

int t = (x – y) * (x – y + z);

Page 7: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

7

Common sub-expression elimination II

int t = (x – y) * (x – y + z);

Naïve code:

iload xiload yisubiload xiload yisubiload ziaddImultistore t

Better code:

iload xiload yisubdupiload ziaddImultistore t

Page 8: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

8

Common sub-expression elimination III

• Consider:

• The address of holidays[i] is a common subexpression.

struct { int y, m, d; } holidays[6];holidays[i].m = 12;holidays[i].d = 25;

Page 9: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

9

• But, be careful!

• Is x – y++ still a common sub-expression?

Common sub-expression elimination IV

int t = (x – y++) * (x – y++ + z);

Page 10: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

10

Code motion

• Consider:

• Computing the address of name[i][j] is address[name] + (i * 10) + j

• Most of that computation is constant throughout the inner loop

char name[3][10];for (int i = 0; i < 3; i++) {

for (int j = 0; j < 10; j++) {name[i][j] = ‘a’;

address[name] + (i * 10)

Page 11: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

11

Code motion II

• You can think of this as rewriting the original code:

as

char name[3][10];for (int i = 0; i < 3; i++) {

for (int j = 0; j < 10; j++) {name[i][j] = ‘a’;

char name[3][10];for (int i = 0; i < 3; i++) {

char *x = &(name[i][0]);for (int j = 0; j < 10; j++) {

x[j] = ‘a’;

Page 12: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

12

Dead code elimination

• Consider:

• Computing t takes many instructions, but the value of t is never used.

• We call the value of t “dead” (or the variable t dead) because it can never affect the final value of the computation. Computing dead values and assigning to dead variables is wasteful.

int f(int x, int y, int z){

int t = (x – y) * (x – y + z);return 6;

}

Page 13: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

13

Dead code elimination II

• But consider:

• Now t is only dead for part of its existence. Hmm…

int f(int x, int y, int z){

int t = x * y;int r = t * z;t = (x – y) * (x – y + z);return r;

}

Page 14: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

14

Optimization implementation

• What do we need to know in order to apply an optimization?

–Constant folding

–Common sub-expression elimination

–Code motion

–Dead code elimination

• Is the optimization correct or safe?• Is the optimization an improvement?• What sort of analyses do we need to perform to get the

required information?

Page 15: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

15

Basic blocks

• A basic block is a sequence of instructions entered only at the beginning and left only at the end.

• A flow graph is a collection of basic blocks connected by edges indicating the flow of control.

Page 16: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

16

Finding basic blocks

iconst_1

istore 2

iconst_2

istore 3

Label_1:

iload 3

iload 1

if_icmplt Label_4

iconst_0

goto Label_5

Label_4:

iconst_1

Label_5:

ifeq Label_2

iload 2iload 3imuldupistore 2pop

Label_3:iload 3dupiconst_1iaddistore 3popgoto Label_1

Label_2:iload 2ireturn

Page 17: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

17

Finding basic blocks II

Label_2:iload 2ireturn

Label_3:iload 3dupiconst_1iaddistore 3popgoto Label_1

iload 2iload 3imuldupistore 2pop

Label_5:

ifeq Label_2

Label_4:

iconst_1

iconst_0

goto Label_5

Label_1:

iload 3

iload 1

if_icmplt Label_4

iconst_1

istore 2

iconst_2

istore 3

Page 18: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

18

Flow graphs

7: iload 2ireturn

6: iload 3dupiconst_1iaddistore 3popgoto 1

5: iload 2iload 3imuldupistore 2pop

4: ifeq 7

3: iconst_1

2: iconst_0

goto 4

1: iload 3

iload 1

if_icmplt 3

0: iconst_1

istore 2

iconst_2

istore 3

Page 19: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

19

Optimizations within a BB

• Everything you need to know is easy to determine• For example: live variable analysis

–Start at the end of the block and work backwards

–Assume everything is live at the end of the BB

–Copy live/dead info for the instruction

–If you see an assignment to x, then mark x “dead”

–If you see a reference to y, then mark y “live”

5: iload 2iload 3imuldupistore 2pop

live: 1, 2, 3

live: 1, 3

live: 1, 2, 3

live: 1, 3live: 1, 3live: 1, 2, 3

live: 1, 3

Page 20: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

20

Global optimizations

• Global means “between basic blocks”• We must know what happens across block boundaries• For example: live variable analysis

– The liveness of a value depends on its later uses perhaps in other blocks

– What values does this block define and use?

5: iload 2iload 3imuldupistore 2pop

Define: 2Use: 2, 3

Page 21: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

21

Global live variable analysis

• We define four sets for each BB– def == variables with defined values

– use == variables used before they are defined

– in == variables live at the beginning of a BB

– out == variables live at the end of a BB

• These sets are related by the following equations:– in[B] = use[B] (out[B] – def[B])

– out[B] = S in[S] where S is a successor of B

Page 22: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

22

Solving data flow equations

• We want a fixpoint of these equations• Start with a conservative estimate of in and out and

refine it as long as it changes– The best conservative definition is {}

Page 23: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

23

Dead code elimination

• Armed with global live variable information we redo the local live variable analysis with correct liveness information at the end of the block out[B]

• Whenever we see an assignment to a variable that is marked dead, we eliminate it.

Page 24: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

24

Static Analysis

• Automatic derivation of static properties which hold on every execution leading to a program location

Page 25: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

25

Example Static Analysis Problems

• Live variables

• Reaching definitions

• Expressions that are “available”

• Dead code

• Pointer variables that never point into the same location

• Points in the program in which it is safe to free an object

• An invocation of a virtual method whose address is unique

• Statements that can be executed in parallel

• An access to a variable which must be in cache

• Integer intervals

• Security properties

• …

Page 26: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

26

Foundation of Static Analysis

• Static analysis can be viewed as interpreting the program over an “abstract domain”

• Execute the program over a larger set of execution paths• Guarantee sound results

– Every identified constant is indeed a constant

– But not every constant is identified as such

Page 27: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

27

Abstract (Conservative) interpretation

abstract representation

Set of states

concretization

Abstractsemantics

statement s abstract representation

abstraction

Operational semantics

statement sSet of states

Page 28: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

28

Example rule of signs

• Safely identify the sign of variables at every program location

• Abstract representation {P, N, ?}• Abstract (conservative) semantics of *

Page 29: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

29

Abstract (conservative) interpretation

<N, N>

{…,<-88, -2>,…}

concretization

Abstractsemantics

x := x*#y<P, N>

abstraction

Operational semantics

x := x*y {…, <176, -2>…}

Page 30: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

30

Example rule of signs (cont)• Safely identify the sign of variables at every

program location• Abstract representation {P, N, ?} (C) = if all elements in C are positive

then return P else if all elements in C are negative then return N else return ?

(a) = if (a==P) then return{0, 1, 2, … } else if (a==N)

return {-1, -2, -3, …, } else return Z

Page 31: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

31

Undecidability Issues

• It is undecidable if a program point is reachablein some execution

• Some static analysis problems are undecidable even if the program conditions are ignored

Page 32: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

32

Coping with undecidabilty

• Loop free programs• Simple static properties• Interactive solutions• Conservative estimations

– Every enabled transformation cannot change the meaning of the code but some transformations are no enabled

– Non optimal code

– Every potential error is caught but some “false alarms” may be issued

Page 33: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

33

Abstract interpretation cannot always be homomorphic (rules of signs)

<N, P>

<-8, 7>

abstraction

<N, P>

abstraction

Operational semantics

x := x+y <-1, 7>

Abstractsemantics

x := x+#y<? P>

Page 34: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

34

Optimality Criteria

• Precise (with respect to a subset of the programs)• Precise under the assumption that all paths are

executable (statically exact)• Relatively optimal with respect to the chosen abstract

domain• Good enough

Page 35: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

35

A somewhat more complex compiler

Page 36: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

36

Complementary Approaches

• Unsound Approaches– Compute under approximation

• Type checking

• Just in time and dynamic compilation

• Profiling

• Runtime tests

• Program Verification

• Better programming language design

Page 37: Languages and Compilers (SProg og Oversættere) Lecture 15 (1) Compiler Optimizations

37

Learning More about Optimizations

• Read chapter 9-12 in the new Dragon Book– Compilers: Principles, Techniques, and Tools (2nd Edition) by Alfred V. Aho, Monica S. Lam, Ravi Sethi, and Jeffrey D.

Ullman, Addison-Wesley, ISBN 0-321-21091-3

• Read the ultimate reference on program analysis– Principles of Program Analysis Flemming Nielson, Hanne Riis Nielson, Chris Hankin: Principles of Program Analysis.

Springer (Corrected 2nd printing, 452 pages, ISBN 3-540-65410-0), 2005.

• Use one of the emerging frameworks:– Soot: a Java Optimization Framework

• http://www.sable.mcgill.ca/soot

– Phoenix Compiler Backend

• https://connect.microsoft.com/Phoenix