dataflow-notes.txt 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. Liveness Analysis as a Dataflow Analysis
  2. ----------------------------------------
  3. References:
  4. * Principles of Program Analysis by Nielson, Nielson, and Hankin
  5. * Ch. 9 of Compilers: Principles, Techniques, & Tools
  6. by Aho, Lam, Sethi, Ullman
  7. * Ch. 17 of Modern Compiler Implemenation in ML by Appel
  8. Running example:
  9. S* =
  10. [y := 1]^1
  11. while [x>0]^2
  12. [w := y]^3
  13. [x := x - 1]^4
  14. [z := w]^5
  15. We're going to work on the control flow graph of the program,
  16. where each superscript corresponds to a node in the graph
  17. and the edges represent control flow possibilities.
  18. Recall that a variable is *live* if it might get used later.
  19. Used for register allocation and dead code elimination.
  20. A backward analysis.
  21. gen([x:=e]) = FV(e)
  22. gen([skip]) = {}
  23. gen([e]) = FV(e)
  24. kill([x:=e]) = {x}
  25. kill([skip]) = {}
  26. kill([e]) = {}
  27. Let P[l] be the statement number l in program P.
  28. LV_before(l) = (LV_after(l) - kill(P[l])) U gen(P[l]) (1)
  29. LV_after(l) = Union{ LV_before(l') | l --> l' in CFG(P) } (2)
  30. We'd like to find a solution to these equations.
  31. It's useful to combine all these equations into a single
  32. equation by putting all the LV's into two vectors:
  33. LV_before = [LV_before(1), LV_before(2), ... ]
  34. LV_after = [LV_after(1), LV_after(2), ... ]
  35. And then encode the equations (1) and (2) for all the statements
  36. into two vector-valued functions F_before and F_after.
  37. F_before(l)(LV_after) = (LV_after[l] - kill(P[l])) U gen(P[l])
  38. F_after(l)(LV_before) = Union{ LV_before[l'] | l --> l' in CFG(P) }
  39. We could even squish these two vectors (before/after) and two
  40. functions into a single vector LV and function F. Then a solution
  41. looks like:
  42. LV = F(LV)
  43. That is, we'd like to find a fixed point of F.
  44. There's a branch of mathematics that studies fixed points
  45. in the context of lattices.
  46. The sets of variables ordered by subseteq form a lattice,
  47. with {} as the bottom element and the set of all variables V
  48. as the top element.
  49. Vectors of sets ordered pointwise forms a lattice, with
  50. [{},{},{},...] as the bottom element and
  51. [V,V,V,...] as the top element.
  52. One of the classic fixpoint theorems is:
  53. Suppose F is an order-preserving function. If the set L
  54. has no infinitely ascending chains and a least element bot,
  55. then there is a fixed point of F.
  56. Proof.
  57. bot <= F(bot) because bot is the least element of L
  58. F(bot) <= F(F(bot)) because F is order preserving.
  59. and so on, so in general we have
  60. F^i(bot) <= F^i+1(bot)
  61. but this can't go on forever, so at some point
  62. F^n(bot) = F^n+1(bot)
  63. and therefore, F^n(bot) is a fixed point of F.
  64. But is our F for liveness order-preserving? (skip this)
  65. Suppose V <= V'.
  66. Let l be any statement number.
  67. If l is even: (LV_before)
  68. We have V[l] <= V'[l].
  69. then V[l] - kill(P[l]) <= V[l]' - kill(P[l])
  70. and (V[l] - kill(P[l])) U gen(P[l]) <= (V[l]' - kill(P[l])) U gen(P[l]).
  71. Therefore F_l(V) <= F_l(V').
  72. If l is odd: (LV_after)
  73. We have V[i] <= V'[i] for any i.
  74. Thus,
  75. Union{ V[l'] | l --> l' in CFG(P) }
  76. <= Union{ V'[l'] | l --> l' in CFG(P) }
  77. Therefore F_l(V) <= F_l(V')
  78. So F(V) <= F(V).
  79. Do we have a least element? Yes:
  80. [{}, {}, ...]
  81. Are there infinite ascending chains? No, because there are
  82. a finite number of variables in the program.
  83. Worklist algorithm (applied to Liveness)
  84. W is a list of control-flow edges
  85. 1. Initialization
  86. W = []
  87. for (l,l') in CFG
  88. W = [(l,l')] + W
  89. for l in CFG do
  90. Analysis[l] = {}
  91. 2. Iteration
  92. while W != []:
  93. (l,l') = W[0]
  94. W = W[1:]
  95. if F_l(Analysis[l]) not <= Analysis[l']:
  96. Analysis[l'] := Analysis[l'] |_| F_l(Analysis[l])
  97. for l'' in in_edges(CFG, l'):
  98. W = [(l'',l')] + W
  99. 3. Recording the result
  100. LV_after(l) := Analysis[l]
  101. LV_before(l) := F_l(Analysis[l])
  102. Example
  103. S* =
  104. [y := 1]^1
  105. while [x>0]^2
  106. [w := y]^3
  107. [x := x - 1]^4
  108. [z := w]^5
  109. flow^R(S*) = (2,1),(3,2),(4,3),(2,4),(5,2)
  110. F_before_1(X) = X - {y}
  111. F_before_2(X) = X U {x}
  112. F_before_3(X) = (X - {w}) U {y}
  113. F_before_4(X) = X U {x}
  114. F_before_5(X) = (X - {z}) U {w}
  115. Analysis W
  116. step 1 2 3 4 5
  117. 1 {} {} {} {} {} (2,1),(3,2),(4,3),(2,4),(5,2)
  118. 2 {x} {} {} {} {} (3,2),(4,3),(2,4),(5,2)
  119. 3 {x} {y} {} {} {} (2,1),(2,4),(4,3),(2,4),(5,2)
  120. 4 {x,y} {y} {} {} {} (2,4),(4,3),(2,4),(5,2)
  121. 5 {x,y} {y} {} {x,y} {} (4,3),(4,3),(2,4),(5,2)
  122. 6 {x,y} {y} {x,y} {x,y} {} (3,2),(4,3),(2,4),(5,2)
  123. 7 {x,y} {x,y} {x,y} {x,y} {} (2,1),(2,4),(4,3),(2,4),(5,2)
  124. 8 {x,y} {x,y} {x,y} {x,y} {} (2,4),(4,3),(2,4),(5,2)
  125. 9 {x,y} {x,y} {x,y} {x,y} {} (4,3),(2,4),(5,2)
  126. 10 {x,y} {x,y} {x,y} {x,y} {} (2,4),(5,2)
  127. 11 {x,y} {x,y} {x,y} {x,y} {} (5,2)
  128. 12 {x,y} {x,y,w} {x,y} {x,y} {} (2,1),(2,4)
  129. 13 {x,y,w} {x,y,w} {x,y} {x,y} {} (2,4)
  130. 14 {x,y,w} {x,y,w} {x,y} {x,y,w} {} (4,3)
  131. 15 {x,y,w} {x,y,w} {x,y,w} {x,y,w} {} (3,2)
  132. 16 {x,y,w} {x,y,w} {x,y,w} {x,y,w} {}
  133. Constant Propagation and Folding
  134. z = 3
  135. x = 1
  136. while x > 0:
  137. if x == 1:
  138. y = 7
  139. else:
  140. y = z + 4
  141. x = 3
  142. print y
  143. ===>
  144. z = 3
  145. x = 1
  146. while x > 0:
  147. if x == 1:
  148. y = 7
  149. else:
  150. y = 3 + 4 ***
  151. x = 3
  152. print y
  153. ===>
  154. z = 3
  155. x = 1
  156. while x > 0:
  157. if x == 1:
  158. y = 7
  159. else:
  160. y = 7 ***
  161. x = 3
  162. print y
  163. ===>
  164. z = 3
  165. x = 1
  166. while x > 0:
  167. if x == 1:
  168. y = 7
  169. else:
  170. y = 7
  171. x = 3
  172. print 7 ***
  173. Lattice for one program variable:
  174. NAC (not a constant)
  175. 1 2 3 4 ... (definitely a constant)
  176. UNDEF (don't know anything about the variable)
  177. The after/before's are mappings from variables to values
  178. in the above lattice.
  179. THE FOLLOWING NEEDS TO BE REVISED -Jeremy
  180. Constant propagation is a forward analysis
  181. kill([x:=e]^l) = {(x,c) | for any c}
  182. kill([skip]^l) = {}
  183. kill([e]^l) = {}
  184. gen([x:=e}^l) = { (x,eval(e,l)) }
  185. gen([skip]^l) = {}
  186. gen([e]^l) = {}
  187. eval(n,l) = n
  188. eval(x,l) = c if (x, c) in CP_before(l)
  189. eval(e1 + e2,l) =
  190. eval(e1,l)
  191. eval(e2,l) bot 1 2 ... uninit top
  192. bot bot bot bot bot bot
  193. 1 bot 2 3 bot top
  194. 2 bot 3 4 bot top
  195. ...
  196. uninit bot bot bot bot bot
  197. top bot top top top
  198. CP_before(l) =
  199. if l = init(S*) then
  200. {(x,uninit),(y,uninit),...}
  201. else
  202. |_| { CP_after(l') | (l',l) in flow(S*) }
  203. CP_after(l) = (CP_before(l) - kill(P[l])) |_| gen(P[l])