Presentation is loading. Please wait.

Presentation is loading. Please wait.

CSE 231 : Advanced Compilers Building Program Analyzers.

Similar presentations


Presentation on theme: "CSE 231 : Advanced Compilers Building Program Analyzers."— Presentation transcript:

1 CSE 231 : Advanced Compilers Building Program Analyzers

2

3 dataflow analysis

4 http://blog.ezyang.com/2011/04/hoopl-dataflow-lattices/

5 http://lambda-the-ultimate.org/node/3557

6 http://blog.ezyang.com/2011/04/hoopl-dataflow-lattices/ http://lambda-the-ultimate.org/node/3557 http://research.microsoft.com/en- us/um/people/simonpj/papers/c--/dfopt.pdf

7 http://blog.ezyang.com/2011/04/hoopl-dataflow-lattices/ http://lambda-the-ultimate.org/node/3557 http://research.microsoft.com/en- us/um/people/simonpj/papers/c--/dfopt.pdf

8 Now where were we…

9 for edge e in CFG: m[e] = EMPTY for node n in CFG: q.push(n) while not q.empty(): n = q.pop() info_in = m[n.in_edges] info_out = F(n, info_in) for i from 0 to len(info_out): e = n.out_edges[i] new_info = m[e] UNION info_out[i] if m[e] != new_info: m[e] = new_info q.push(e.dest) Started with sets. Termination worries.

10 Foundations : Lattices A lattice is (S, ⊑, ⊥, ⊤, ⊔, ⊓ ) where: (S, ⊑ ) is a poset ⊥ is the smallest thing in S ⊤ is the biggest thing in S lub(a, b) and glb(a, b) always exist a ⊔ b = lub(a, b) a ⊓ b = glb(a, b)

11 Foundations : Lattices (Formally) A lattice is (S, ⊑, ⊥, ⊤, ⊔, ⊓ ) where: (S, ⊑ ) is a poset ∀ a ∈ S. ⊥ ⊑ a ∀ a ∈ S. a ⊑ ⊤ ∀ a, b ∈ S. ∃ c. c = lub(a, b) /\ a ⊔ b = c ∀ a, b ∈ S. ∃ c. c = glb(a, b) /\ a ⊓ b = c

12 Foundations : Fancy Lattice Names ⊥ is “botom” ⊤ is “top” ⊔ is “join” ⊓ is “meet”

13 for edge e in CFG: m[e] = BOTTOM for node n in CFG: q.push(n) while not q.empty(): n = q.pop() info_in = m[n.in_edges] info_out = F(n, info_in) for i from 0 to len(info_out): e = n.out_edges[i] new_info = m[e] JOIN info_out[i] if m[e] != new_info: m[e] = new_info q.push(e.dest) Port to lattices. Small patch set.

14 while not q.empty(): n = q.pop() info_in = m[n.in_edges] info_out = F(n, info_in) for i from 0 to len(info_out): e = n.out_edges[i] new_info = m[e] JOIN info_out[i] if m[e] != new_info: m[e] = new_info q.push(e.dest) Termination. Finite lattice height implies termination.

15 while not q.empty(): n = q.pop() info_in = m[n.in_edges] info_out = F(n, info_in) for i from 0 to len(info_out): e = n.out_edges[i] new_info = m[e] JOIN info_out[i] if m[e] != new_info: m[e] = new_info q.push(e.dest) Termination. But can we do better? Finite lattice height implies termination. Get rid of that JOIN right in the middle?

16 while not q.empty(): n = q.pop() info_in = m[n.in_edges] info_out = F(n, info_in) for i from 0 to len(info_out): e = n.out_edges[i] new_info = m[e] JOIN info_out[i] if m[e] != new_info: m[e] = new_info q.push(e.dest) Termination. But can we do better? Get rid of that JOIN right in the middle? Yes. The trick is in the flow functions.

17 In general, can’t remove join and have termination. So, when is it OK? Safely Getting Rid Of The Join

18 In general, can’t remove join and have termination. So, when is it OK? Port our algorithm to math to figure it out. Build in terms of fixpoints. Safely Getting Rid Of The Join

19 Fixpoint: an input equal the output. A fixpoint of F is any X such that F(X) = X. “Best” answer since repeating yields same result. Fixpoints Are Easy

20 Using Fixpoints In Analysis Goal: compute map m from CFG edges to dataflow information Strategy: define a global flow function F as follows: F takes a map m as a parameter and returns a new map m’, in which individual local flow functions have been applied

21 The Big F F mm’

22 Just Regular Flow Funcs Inside mm’ f1 f2 f3

23 Goal: Find Fixpoint of F F m F F m’ …

24 Fixpoint of F Goal: a fixed point of F, i.e. m where m = F(m) How should we do this?

25 Fixpoint of F Goal: a fixed point of F, i.e. m where m = F(m) How should we do this? Let ⊥ be ⊥ lifted to a map: ⊥ = e. ⊥ Compute F( ⊥ ), then F(F( ⊥ )), then F(F(F( ⊥ ))),... until the result doesn’t change

26 Fixpoint of F Goal: a fixed point of F, i.e. m where m = F(m) How should we do this? Let ⊥ be ⊥ lifted to a map: ⊥ = e. ⊥ Compute F( ⊥ ), then F(F( ⊥ )), then F(F(F( ⊥ ))),... until the result doesn’t change … but how long could that take ???

27 Fixpoint of F : Formal Solution Solution: ⊔ i = 0 Fi(⊥)Fi(⊥)

28 Fixpoint of F : Formal Solution Solution: We want F 1 ( ⊥ ) ⊑ F 2 ( ⊥ ) ⊑ F 3 ( ⊥ ) … ⊑ F k ( ⊥ ) Allows us to eliminate the big join. Just require F to be monotonic: ∀ a b, a ⊑ b ➞ F(a) ⊑ F(b) ⊔ i = 0 Fi(⊥)Fi(⊥)

29 Back To Termination Solution: if F is monotonic, we have it. Finite lattice height  termination w/out joins! OK. But how do we know F is monotonic? F is monotonic if flow functions monotonic.

30

31 Another benefit of monotonicity Suppose Marsians came to earth, and miraculously give you a fixed point of F, call it fp. Then:

32 Another benefit of monotonicity Suppose Marsians came to earth, and miraculously give you a fixed point of F, call it fp. Then:

33 Another benefit of monotonicity We are computing the least fixed point...

34 Recap Let’s do a recap of what we’ve seen so far Started with worklist algorithm for reaching definitions

35 Worklist algorithm for reaching defns let m: map from edge to computed value at edge let worklist: work list of nodes for each edge e in CFG do m(e) := ∅ for each node n do worklist.add(n) while (worklist.empty.not) do let n := worklist.remove_any; let info_in := m(n.incoming_edges); let info_out := F(n, info_in); for i := 0.. info_out.length do let new_info := m(n.outgoing_edges[i]) ∪ info_out[i]; if (m(n.outgoing_edges[i])  new_info]) m(n.outgoing_edges[i]) := new_info; worklist.add(n.outgoing_edges[i].dst);

36 Generalized algorithm using lattices let m: map from edge to computed value at edge let worklist: work list of nodes for each edge e in CFG do m(e) := ⊥ for each node n do worklist.add(n) while (worklist.empty.not) do let n := worklist.remove_any; let info_in := m(n.incoming_edges); let info_out := F(n, info_in); for i := 0.. info_out.length do let new_info := m(n.outgoing_edges[i]) ⊔ info_out[i]; if (m(n.outgoing_edges[i])  new_info]) m(n.outgoing_edges[i]) := new_info; worklist.add(n.outgoing_edges[i].dst);

37 Next step: removed outer join Wanted to remove the outer join, while still providing termination guarantee To do this, we re-expressed our algorithm more formally We first defined a “global” flow function F, and then expressed our algorithm as a fixed point computation

38 Guarantees If F is monotonic, don’t need outer join If F is monotonic and height of lattice is finite: iterative algorithm terminates If F is monotonic, the fixed point we find is the least fixed point. Any questions?

39 What about if we start at top? What if we start with ⊤, F( ⊤ ), F(F( ⊤ )), F(F(F( ⊤ )))

40 What about if we start at top? What if we start with ⊤, F( ⊤ ), F(F( ⊤ )), F(F(F( ⊤ ))) We get the greatest fixed point Why do we prefer the least fixed point? –More precise

41 Graphically x y 10

42 Graphically x y 10

43 Graphically x y 10

44 Another example: constant prop Set D = x := N in out F x := N (in) = x := y op z in out F x := y op z (in) =

45 Another example: constant prop Set D = 2 { x ! N | x 2 Vars Æ N 2 Z } x := N in out F x := N (in) = in – { x ! * } [ { x ! N } x := y op z in out F x := y op z (in) = in – { x ! * } [ { x ! N | ( y ! N 1 ) 2 in Æ ( z ! N 2 ) 2 in Æ N = N 1 op N 2 }

46 Another example: constant prop *x := y in out F *x := y (in) = x := *y in out F x := *y (in) =

47 Another example: constant prop *x := y in out F *x := y (in) = in – { z ! * | z 2 may-point(x) } [ { z ! N | z 2 must-point-to(x) Æ y ! N 2 in } [ { z ! N | (y ! N) 2 in Æ (z ! N) 2 in } x := *y in out F x := *y (in) = in – { x ! * } [ { x ! N | 8 z 2 may-point-to(x). (z ! N) 2 in }

48 Another example: constant prop x := f(...) in out F x := f(...) (in) = *x := *y + *z in out F *x := *y + *z (in) =

49 Another example: constant prop x := f(...) in out F x := f(...) (in) = ; *x := *y + *z in out F *x := *y + *z (in) = F a := *y;b := *z;c := a + b; *x := c (in)

50 Another example: constant prop s: if (...) in out[0]out[1] merge out in[0]in[1]

51 Another example: constant prop Set D = 2 { x ! N | x 2 Vars Æ N 2 Z } x := N in out F x := N (in) = in – { x ! * } [ { x ! N } x := y op z in out F x := y op z (in) = in – { x ! * } [ { x ! N | ( y ! N 1 ) 2 in Æ ( z ! N 2 ) 2 in Æ N = N 1 op N 2 }

52 Another example: constant prop *x := y in out F *x := y (in) = in – { z ! * | z 2 may-point(x) } [ { z ! N | z 2 must-point-to(x) Æ y ! N 2 in } [ { z ! N | (y ! N) 2 in Æ (z ! N) 2 in } x := *y in out F x := *y (in) = in – { x ! * } [ { x ! N | 8 z 2 may-point-to(x). (z ! N) 2 in }

53 Another example: constant prop x := f(...) in out F x := f(...) (in) = ; *x := *y + *z in out F *x := *y + *z (in) = F a := *y;b := *z;c := a + b; *x := c (in)

54 Another example: constant prop s: if (...) in out[0]out[1] merge out in[0]in[1]

55 Lattice (D, v, ?, >, t, u) =


Download ppt "CSE 231 : Advanced Compilers Building Program Analyzers."

Similar presentations


Ads by Google