HOT

Lecture 2 数据流

1 .CSC D70: Compiler Optimization Dataflow Analysis Prof. Gennady Pekhimenko University of Toronto Winter 2018 The content of this lecture is adapted from the lectures of Todd Mowry and Phillip Gibbons

2 .Refreshing from Last Lecture Basic Block Formation Value Numbering 2

3 .Partitioning into Basic Blocks Identify the leader of each basic block First instruction Any target of a jump Any instruction immediately following a jump Basic block starts at leader &amp; ends at instruction immediately before a leader (or the last instruction) 3

4 .4 ALSU pp. 529-531

5 .Value Numbering (VN) More explicit with respect to VALUES, and TIME each value has its own “number” common subexpression means same value number var2value: current map of variable to value used to determine the value number of current expression r1 + r2 =&gt; var2value(r1)+var2value(r2) 5

6 .Algorithm Data structure: VALUES = Table of expression //[OP, valnum1, valnum2} var //name of variable currently holding expression For each instruction ( dst = src1 OP src2) in execution order valnum1 = var2value(src1); valnum2 = var2value(src2); IF [OP, valnum1, valnum2] is in VALUES v = the index of expression Replace instruction with CPY dst = VALUES[v]. var ELSE Add expression = [OP, valnum1, valnum2] var = dst to VALUES v = index of new entry; tv is new temporary for v Replace instruction with: tv = VALUES[valnum1]. var OP VALUES[valnum2]. var dst = tv; set_var2value ( dst , v) 6

7 .VN Example Assign: a-&gt;r1,b-&gt;r2,c-&gt;r3,d-&gt;r4 a = b+c; ADD t1 = r2,r3 CPY r1 = t1 b = a-d; SUB t2 = r1,r4 CPY r2 = t2 c = b+c; ADD t3 = r2,r3 CPY r3 = t3 d = a-d; SUB t4 = r1,r4 CPY r4 = t4 7

8 .Questions about Assignment #1 Tutorial #1 Tutorial #2 next week More in-depth LLVM coverage 8

9 .Outline 9 Structure of data flow analysis Example 1: Reaching definition analysis Example 2: Liveness analysis Generalization

10 .What is Data Flow Analysis? Local analysis (e.g. value numbering) analyze effect of each instruction compose effects of instructions to derive information from beginning of basic block to each instruction Data flow analysis analyze effect of each basic block compose effects of basic blocks to derive information at basic block boundaries from basic block boundaries, apply local technique to generate information on instructions 10

11 .What is Data Flow Analysis? (2) Data flow analysis: Flow-sensitive: sensitive to the control flow in a function intraprocedural analysis Examples of optimizations: Constant propagation Common subexpression elimination Dead code elimination 11

12 .What is Data Flow Analysis? (3) 12 For each variable x determine: Value of x? Which “definition” defines x? Is the definition still meaningful (live)? e = b + c a = 243 e = d+3 g = a a = b + c d = 7

13 .Static Program vs. Dynamic Execution Statically : Finite program Dynamically : Can have infinitely many possible execution paths Data flow analysis abstraction: For each point in the program: combines information of all the instances of the same program point. Example of a data flow question: Which definition defines the value used in statement “b = a”? 13

14 .Effects of a Basic Block Effect of a statement: a = b+c Use s variables (b, c) Kill s an old definition (old definition of a) new definition (a) Compose effects of statements -&gt; Effect of a basic block A locally exposed use in a b.b . is a use of a data item which is not preceded in the b.b . by a definition of the data item any definition of a data item in the basic block kills all definitions of the same data item reaching the basic block. A locally available definition = last definition of data item in b.b . 14

15 .Effects of a Basic Block A locally available definition = last definition of data item in b.b . 15 t1 = r1+r2 r2 = t1 t2 = r2+r1 r1 = t2 t3 = r1*r1 r2 = t3 if r2&gt;100 goto L1

16 .Reaching Definitions Every assignment is a definition A definition d reaches a point p if there exists path from the point immediately following d to p such that d is not killed (overwritten) along that path. Problem statement For each point in the program, determine if each definition in the program reaches the point A bit vector per program point, vector-length = # defs 16 d3: x = 1 d4: y = 2 d5: z = x d6: x = 4 d0: y = 3 d1: x = 10 d2: y = 11 if e B0 B1 B2 d1 reaches this point?

17 .Reaching Definitions (2) Every assignment is a definition A definition d reaches a point p if there exists path from the point immediately following d to p such that d is not killed (overwritten) along that path. Problem statement For each point in the program, determine if each definition in the program reaches the point A bit vector per program point, vector-length = # defs 17 d3: x = 1 d4: y = 2 d5: z = x d6: x = 4 d0: y = 3 d1: x = 10 d2: y = 11 if e B0 B1 B2 d2 reaches this point?

18 .Reaching Definitions (3) 18 L1: if input() GOTO L2 d0: a = x L2: … d1: b = a d2: a = y GOTO L1 d2 reaches this point? yes

19 .Data Flow Analysis Schema Build a flow graph (nodes = basic blocks, edges = control flow) Set up a set of equations between in[b] and out[b] for all basic blocks b Effect of code in basic block : Transfer function f b relates in[b] and out[b] , for same b Effect of flow of control : relates out[b 1 ], in[b 2 ] if b 1 and b 2 are adjacent Find a solution to the equations 19 f 2 f 1 out[entry] entry exit f 3 in out in out in out in[exit]

20 .Effects of a Statement f s : A transfer function of a statement abstracts the execution with respect to the problem of interest For a statement s ( d: x = y + z ) out[s] = f s (in[s]) = Gen[s] U (in[s]-Kill[s]) Gen[s] : definitions generated : Gen[s] = {d} Propagated definitions: in[s] - Kill[s] , where Kill[s] =set of all other defs to x in the rest of program 20 d1: x = 10 d0: y = 3 in[B0] d2: y = 11 out[B0] f d0 f d1 f d2

21 .Effects of a Basic Block Transfer function of a statement s: out[s] = f s (in[s]) = Gen[s] U (in[s]-Kill[s]) Transfer function of a basic block B : Composition of transfer functions of statements in B out[B] = f B (in[B]) = f d2 f d1 f d0 (in[B]) = Gen[d 2 ] U (Gen[d 1 ] U (Gen[d 0 ] U (in[B]-Kill[d 0 ]))-Kill[d 1 ])) -Kill[d 2 ] = Gen[d 2 ] U (Gen[d 1 ] U (Gen[d 0 ] - Kill[d 1 ]) - Kill[d 2 ]) U in[B] - (Kill[d 0 ] U Kill[d 1 ] U Kill[d 2 ]) = Gen[B] U (in[B] - Kill[B]) Gen[B] : locally exposed definitions (available at end of bb) Kill[B] : set of definitions killed by B 21 d1: x = 10 d0: y = 3 in[B0] d2: y = 11 out[B0] f d0 f d1 f d2 f B = f d2  f d1  f d1

22 .Example a transfer function f b of a basic block b: OUT[b] = f b (IN[b]) incoming reaching definitions -&gt; outgoing reaching definitions A basic block b generates definitions: Gen[b], set of locally available definitions in b kills definitions: in[b] - Kill[b], where Kill[b]=set of defs (in rest of program) killed by defs in b out[b] = Gen[b] U (in(b)-Kill[b]) 22 d3: x = 1 d4: y = 2 d5: z = x d6: x = 4 d0: y = 3 d1: x = 10 d2: y = 11 if e B0 B1 B2

23 .Effects of the Edges (acyclic) out[b] = f b (in[b]) Join node: a node with multiple predecessors meet operator: in[b] = out[p 1 ] U out[p 2 ] U ... U out[ p n ], where p 1 , ..., p n are all predecessors of b 23 f Gen Kill 1 {1,2} {3,4,6} 2 {3,4} {1,2,6} 3 {5,6} {1,3} f 2 f 1 out[entry] entry exit f 3 in out in out in out in[exit]

24 .Cyclic Graphs Equations still hold out[b] = f b (in[b]) in[b] = out[p 1 ] U out[p 2 ] U ... U out[ p n ], p 1 , ..., p n pred. Find: fixed point solution 24

25 .Reaching Definitions: Iterative Algorithm input: control flow graph CFG = (N, E, Entry, Exit) // Boundary condition out[Entry] =  // Initialization for iterative algorithm For each basic block B other than Entry out[B] =  // iterate While (Changes to any out[] occur) { For each basic block B other than Entry { in[B] =  (out[p]), for all predecessors p of B out[B] = f B (in[B]) // out[B]=gen[B]  (in[B]-kill[B]) } 25

26 .Reaching Definitions: Worklist Algorithm input: control flow graph CFG = (N, E, Entry, Exit) // Initialize out[Entry] =  // can set out[Entry] to special def // if reaching then undefined use For all nodes i out[ i ] =  // can optimize by out[ i ]=gen[ i ] ChangedNodes = N // iterate While ChangedNodes ≠  { Remove i from ChangedNodes in[ i ] = U (out[p]), for all predecessors p of i oldout = out[ i ] out[i] = f i (in[i]) // out[i]=gen[i]U(in[i]-kill[i]) if ( oldout ≠ out[ i ]) { for all successors s of i add s to ChangedNodes } } 26

27 .Example 27

28 .Live Variable Analysis Definition A variable v is live at point p if the value of v is used along some path in the flow graph starting at p . Otherwise, the variable is dead . Motivation e.g. register allocation for i = 0 to n … i … … for i = 0 to n … i … Problem statement For each basic block determine if each variable is live in each basic block Size of bit vector: one bit for each variable 28 v live at this point?

29 .Transfer Function Insight: Trace uses backwards to the definitions A basic block b can generate live variables: Use[b] set of locally exposed uses in b propagate incoming live variables: OUT [b] - Def[b] , where Def[b] = set of variables defined in b.b . transfer function for block b: in[b] = Use[b] U (out(b)-Def[b]) 29

3 点赞
2 收藏
1下载