ben livshits based in part of stanford class slides from ullman/dragon/w06/w06.html

72
Introduction to Compilers Ben Livshits Based in part of Stanford class slides from http://infolab.stanford.edu/~ullman/

Upload: rose-stone

Post on 17-Dec-2015

213 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

Introduction to Compilers

Ben Livshits

Based in part of Stanford class slides from http://infolab.stanford.edu/~ullman/dragon/

w06/w06.html

Page 2: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

Organization• Really basic stuff• Flow Graphs• Constant Folding• Global Common Subexpressions• Induction Variables/Reduction in Strength

• Data-flow analysis• Proving Little Theorems• Data-Flow Equations• Major Examples

• Pointer analysis

Page 3: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

Compiler Organization

Page 4: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

6

Really Basic Stuff

• Flow Graphs• Constant Folding• Global Common Subexpressions• Induction Variables/Reduction in Strength

Page 5: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

7

Dawn of Code Optimization

A never-published Stanford technical report by Fran Allen in 1968

Flow graphs of intermediate code

Key things worth doing

Page 6: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

8

Intermediate Code

for (i=0; i<n; i++) A[i] = 1; Intermediate code exposes

optimizable constructs we cannot see at source-code level.

Make flow explicit by breaking into basic blocks = sequences of steps with entry at beginning, exit at end.

Page 7: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

9

Basic Blocks

i = 0

if i>=n goto …

t1 = 8*i A[t1] = 1i = i+1

for (i=0; i<n; i++) A[i] = 1;

Page 8: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

10

Induction Variables

x is an induction variable in a loop if it takes on a linear sequence of values each time through the loop.

Common case: loop index like i and computed array index like t1.

Eliminate “superfluous” induction variables.

Replace multiplication by addition (reduction in strength ).

Page 9: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

11

Example

i = 0

if i>=n goto …

t1 = 8*i A[t1] = 1i = i+1

t1 = 0 n1 = 8*n

if t1>=n1 goto …

A[t1] = 1 t1 = t1+8

Page 10: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

12

Loop-Invariant Code Motion

Sometimes, a computation is done each time around a loop.

Move it before the loop to save n-1 computations. Be careful: could n=0? I.e., the loop

is typically executed 0 times.

Page 11: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

13

Example

i = 0

if i>=n goto …

t1 = y+z x = x+t1 i = i+1

i = 0 t1 = y+z

if i>=n goto …

x = x+t1i = i+1

Page 12: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

14

Constant Folding

Sometimes a variable has a known constant value at a point.

If so, replacing the variable by the constant simplifies and speeds-up the code.

Easy within a basic block; harder across blocks.

Page 13: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

15

Example

i = 0 n = 100

if i>=n goto …

t1 = 8*i A[t1] = 1i = i+1

t1 = 0

if t1>=800 goto …

A[t1] = 1 t1 = t1+8

Page 14: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

16

Global Common Subexpressions

Suppose block B has a computation of x+y.

Suppose we are sure that when we reach this computation, we are sure to have:

1. Computed x+y, and2. Not subsequently reassigned x or y.

Then we can hold the value of x+y and use it in B.

Page 15: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

17

Example

a = x+y

b = x+y

c = x+y

t = x+ya = t

t = x+yb = t

c = t

Page 16: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

18

Example --- Even Better

t = x+ya = t

b = t

c = t

t = x+ya = t

t = x+yb = t

c = t

t = x+yb = t

Page 17: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

19

Data-Flow Analysis

• Proving Little Theorems• Data-Flow Equations• Major Examples

Page 18: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

20

An Obvious Theorem

boolean x = true;while (x) { . . . // no change to x} Doesn’t terminate. Proof: only assignment to x is at

top, so x is always true.

Page 19: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

21

As a Flow Graph

x = true

if x == true

“body”

Page 20: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

22

Formulation: Reaching Definitions

Each place some variable x is assigned is a definition.

Ask: for this use of x, where could x last have been defined.

In our example: only at x=true.

Page 21: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

23

Example: Reaching Definitions

d1: x = true

if x == true

d2: a = 10

d2

d1

d1d2

d1

Page 22: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

24

Clincher

Since at x == true, d1 is the only definition of x that reaches, it must be that x is true at that point.

The conditional is not really a conditional and can be replaced by a branch.

Page 23: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

25

Not Always That Easy

int i = 2; int j = 3;while (i != j) { if (i < j) i += 2; else j += 2;} We’ll develop techniques for this

problem, but later …

Page 24: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

26

The Flow Graphd1: i = 2d2: j = 3

if i != j

if i < j

d4: j = j+2d3: i = i+2

d1, d2, d3, d4

d1

d3 d4

d2

d2, d3, d4

d1, d3, d4d1, d2, d3, d4

d1, d2, d3, d4

Page 25: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

27

DFA Is Sometimes Insufficient

In this example, i can be defined in two places, and j in two places.

No obvious way to discover that i!=j is always true.

But OK, because reaching definitions is sufficient to catch most opportunities for constant folding (replacement of a variable by its only possible value).

Page 26: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

28

Be Conservative!

(Code optimization only) It’s OK to discover a subset of the

opportunities to make some code-improving transformation.

It’s not OK to think you have an opportunity that you don’t really have.

Page 27: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

29

Example: Be Conservative

boolean x = true;while (x) { . . . *p = false; . . .} Is it possible that p points to x?

Page 28: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

30

As a Flow Graph

d1: x = true

if x == true

d2: *p = false

d1

d2

Anotherdef of x

Page 29: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

31

Possible Resolution

Just as data-flow analysis of “reaching definitions” can tell what definitions of x might reach a point, another DFA can eliminate cases where p definitely does not point to x.

Example: the only definition of p is p = &y and there is no possibility that y is an alias of x.

Page 30: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

32

Reaching Definitions Formalized

A definition d of a variable x is said to reach a point p in a flow graph if:

1. Every path from the entry of the flow graph to p has d on the path, and

2. After the last occurrence of d there is no possibility that x is redefined.

Page 31: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

33

Data-Flow Equations --- (1)

A basic block can generate a definition.

A basic block can either1. Kill a definition of x if it surely

redefines x.2. Transmit a definition if it may not

redefine the same variable(s) as that definition.

Page 32: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

34

Data-Flow Equations --- (2)

Variables:1. IN(B) = set of definitions reaching

the beginning of block B.2. OUT(B) = set of definitions reaching

the end of B.

Page 33: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

35

Data-Flow Equations --- (3)

Two kinds of equations:1. Confluence equations : IN(B) in

terms of outs of predecessors of B.2. Transfer equations : OUT(B) in terms

of of IN(B) and what goes on in block B.

Page 34: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

36

Confluence Equations

IN(B) = ∪predecessors P of B OUT(P)

P2

B

P1

{d1, d2, d3}

{d2, d3}{d1, d2}

Page 35: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

37

Transfer Equations

Generate a definition in the block if its variable is not definitely rewritten later in the basic block.

Kill a definition if its variable is definitely rewritten in the block.

An internal definition may be both killed and generated.

Page 36: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

38

Example: Gen and Kill

d1: y = 3 d2: x = y+zd3: *p = 10d4: y = 5

IN = {d2(x), d3(y), d3(z), d5(y), d6(y), d7(z)}

Kill includes {d1(x), d2(x),d3(y), d5(y), d6(y),…}

Gen = {d2(x), d3(x), d3(z),…, d4(y)}

OUT = {d2(x), d3(x), d3(z),…, d4(y), d7(z)}

Page 37: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

39

Transfer Function for a Block

For any block B:

OUT(B) = (IN(B) – Kill(B)) ∪ Gen(B)

Page 38: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

40

Iterative Solution to Equations

For an n-block flow graph, there are 2n equations in 2n unknowns.

Alas, the solution is not unique. Use iterative solution to get the

least fixed-point. Identifies any def that might reach a

point.

Page 39: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

41

Iterative Solution --- (2)

IN(entry) = ∅;for each block B do OUT(B)= ∅;while (changes occur) do for each block B do { IN(B) = ∪predecessors P of B OUT(P);

OUT(B) = (IN(B) – Kill(B)) ∪ Gen(B);

}

Page 40: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

42

Example: Reaching Definitions

d1: x = 5

if x == 10

d2: x = 15

B1

B3

B2

IN(B1) = {}

OUT(B1) = {

OUT(B2) = {

OUT(B3) = {

d1}

IN(B2) = { d1,

d1,

IN(B3) = { d1,

d2}

d2}

d2}

d2}

Page 41: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

43

Aside: Notice the Conservatism

Not only the most conservative assumption about when a def is killed or gen’d.

Also the conservative assumption that any path in the flow graph can actually be taken.

Page 42: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

44

Everything Else About Data Flow Analysis

• Flow- and Context-Sensitivity Logical Representation

• Pointer Analysis• Interprocedural Analysis

Page 43: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

45

Three Levels of Sensitivity

In DFA so far, we have cared about where in the program we are. Called flow-sensitivity.

But we didn’t care how we got there. Called context-sensitivity.

We could even care about neither. Example: where could x ever be

defined in this program?

Page 44: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

46

Flow/Context Insensitivity

Not so bad when program units are small (few assignments to any variable).

Example: Java code often consists of many small methods. Remember: you can distinguish

variables by their full name, e.g., class.method.block.identifier.

Page 45: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

47

Context Sensitivity

Can distinguish paths to a given point.

Example: If we remembered paths, we would not have the problem in the constant-propagation framework where x+y = 5 but neither x nor y is constant over all paths.

Page 46: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

48

The Example Again

x = 3y = 2

x = 2y = 3

z = x+y

Page 47: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

49

An Interprocedural Example

int id(int x) {return x;}void p() {a=2; b=id(a);…}void q() {c=3; d=id(c);…} If we distinguish p calling id from q

calling id, then we can discover b=2 and d=3.

Otherwise, we think b, d = {2, 3}.

Page 48: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

50

Context-Sensitivity --- (2)

Loops and recursive calls lead to an infinite number of contexts.

Generally used only for interprocedural analysis, so forget about loops.

Need to collapse strong components of the calling graph to a single group.

“Context” becomes the sequence of groups on the calling stack.

Page 49: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

51

Example: Calling Graph

main

p

sr

q

t Contexts:

GreenGreen, pinkGreen, yellowGreen, pink, yellow

Page 50: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

52

Comparative Complexity

Insensitive: proportional to size of program (number of variables).

Flow-Sensitive: size of program, squared (points times variables).

Context-Sensitive: worst-case exponential in program size (acyclic paths through the code).

Page 51: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

53

Logical Representation

We have used a set-theoretic formulation of DFA. IN = set of definitions, e.g.

There has been recent success with a logical formulation, involving predicates.

Example: Reach(d,x,i) = “definition d of variable x can reach point i.”

Page 52: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

54

Comparison: Sets Vs. Logic

Both have an efficiency enhancement. Sets: bit vectors and boolean ops. Logic: BDD’s, incremental evaluation.

Logic allows integration of different aspects of a flow problem. Think of PRE as an example. We

needed 6 stages to compute what we wanted.

Page 53: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

55

Datalog --- (1)

Atom = Reach(d,x,i)

Literal = Atom or NOT Atom

Rule = Atom :- Literal & … & Literal

Predicate

Arguments:variables or constants

The body :For each assignment of valuesto variables that makes all thesetrue …

Make thisatom true(the head ).

Page 54: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

56

Example: Datalog Rules

Reach(d,x,j) :- Reach(d,x,i) &StatementAt(i,s) &NOT Assign(s,x) &Follows(i,j)

Reach(s,x,j) :- StatementAt(i,s) &Assign(s,x) &Follows(i,j)

Page 55: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

57

Datalog --- (2)

Intuition: subgoals in the body are combined by “and” (strictly speaking: “join”).

Intuition: Multiple rules for a predicate (head) are combined by “or.”

Page 56: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

58

Datalog --- (3)

Predicates can be implemented by relations (as in a database).

Each tuple, or assignment of values to the arguments, also represents a propositional (boolean) variable.

Page 57: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

59

Iterative Algorithm for Datalog

Start with the EDB predicates = “whatever the code dictates,” and with all IDB predicates empty.

Repeatedly examine the bodies of the rules, and see what new IDB facts can be discovered from the EDB and existing IDB facts.

Page 58: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

60

Example: Seminaive

Path(x,y) :- Arc(x,y)Path(x,y) :- Path(x,z) & Path(z,y)NewPath(x,y) = Arc(x,y); Path(x,y) = ∅;while (NewPath != ∅) do {NewPath(x,y) = {(x,y) | NewPath(x,z)

&& Path(z,y) || Path(x,z) &&NewPath(z,y)} – Path(x,y);

Path(x,y) = Path(x,y) ∪ NewPath(x,y);}

Page 59: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

Pointer analysis

61

Page 60: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

62

New Topic: Pointer Analysis

We shall consider Andersen’s formulation of Java object references.

Flow/context insensitive analysis. Cast of characters:

1. Local variables, which point to:2. Heap objects, which may have fields

that are references to other heap objects.

Page 61: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

63

Representing Heap Objects

A heap object is named by the statement in which it is created.

Note many run-time objects may have the same name.

Example: h: T v = new T; says variable v can point to (one of) the heap object(s) created by statement h.

v h

Page 62: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

64

Other Relevant Statements

v.f = w makes the f field of the heap object h pointed to by v point to what variable w points to.

v

h g

w

if f

Page 63: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

65

Other Statements --- (2)

v = w.f makes v point to what the f field of the heap object h pointed to by w points to.

v

hg

wi

f

Page 64: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

66

Other Statements --- (3)

v = w makes v point to whatever w points to. Interprocedural Analysis : Also models

copying an actual parameter to the corresponding formal or return value to a variable.

v

h

w

Page 65: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

67

Datalog Rules

1. Pts(V,H) :- “H: V = new T”2. Pts(V,H) :- “V=W” & Pts(W,H)3. Pts(V,H) :- “V=W.F” & Pts(W,G) &

Hpts(G,F,H)4. Hpts(H,F,G) :- “V.F=W” & Pts(V,H)

& Pts(W,G)

Page 66: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

68

ExampleT p(T x) {h: T a = new T;

a.f = x;return a;

}void main() {g: T b = new T;

b = p(b);b = b.f;

}

Page 67: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

69

Apply Rules Recursively --- Round 1

T p(T x) {h: T a = new T;a.f = x; return a;}

void main() {g: T b = new T;b = p(b); b = b.f;}

Pts(a,h)

Pts(b,g)

Page 68: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

70

Apply Rules Recursively --- Round 2

T p(T x) {h: T a = new T;a.f = x; return a;}

void main() {g: T b = new T;b = p(b); b = b.f;}

Pts(a,h)

Pts(b,g)

Pts(b,h)

Pts(x,g)

Page 69: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

71

Apply Rules Recursively --- Round 3

T p(T x) {h: T a = new T;a.f = x; return a;}

void main() {g: T b = new T;b = p(b); b = b.f;}

Pts(a,h)

Pts(b,g)

Pts(x,g)

Pts(b,h)

Hpts(h,f,g)Pts(x,h)

Page 70: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

72

Apply Rules Recursively --- Round 4

T p(T x) {h: T a = new T;a.f = x; return a;}

void main() {g: T b = new T;b = p(b); b = b.f;}

Pts(a,h)

Pts(b,g)

Pts(x,g)

Pts(b,h)

Pts(x,h) Hpts(h,f,g)

Hpts(h,f,h)

Page 71: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

73

Adding Context Sensitivity

Include a component C = context. C doesn’t change within a function. Call and return can extend the

context if the called function is not mutually recursive with the caller.

Page 72: Ben Livshits Based in part of Stanford class slides from ullman/dragon/w06/w06.html

74

Example of Rules: Context Sensitive

Pts(V,H,B,I+1,C) :- “B,I: V=W” & Pts(W,H,B,I,C)

Pts(X,H,B0,0,D) :- Pts(V,H,B,I,C) & “B,I: call P(…,V,…)” & “X is the corresponding actual to V in P” & “B0 is the entry of P” & “context D is C extended by P”