560 likes | 781 Views
Region-Based Data Flow Analysis. Loops. Loops in programs deserve special treatment Because programs spend most of their time executing loops, improving the performance of loops can have a significant impact
E N D
Loops • Loops in programs deserve special treatment • Because programs spend most of their time executing loops, improving the performance of loops can have a significant impact • If a program does not contain any loops, we can obtain the answers to data-flow problems by making just one pass through the program
Dominators • A node n1dominates a node n2 , written n1domn2, if every path from the ENTRY node of the flow graph to n2 goes through n1 • Every node dominates itself
1 2 3 4 5 6 7 8 9 10 An Example 10 dom {10} 9 dom {9} 8 dom {8,9,10} 7 dom {7,8,9,10} 6 dom {6} 5 dom {5} 4 dom {4,5,6,7,8,9,10} 3 dom {3,4,5,6,7,8,9,10} 2 dom {2} 1 dom {1,2,3,4,5,6,7,8,9,10}
Dominator Trees • The dom relation between the nodes of a flow graph can be represented as a tree, called the dominator tree • The ENTRY node of the graph is the root of the tree, and each node n dominates only its descendants in the tree • Each node n has a unique immediate dominatorm that is the last dominator of n on any path from the ENTRY node to n
1 1 2 2 3 3 4 4 5 6 5 6 7 7 8 8 9 10 9 10 An Example
Finding Dominators • If p1, p2, …, pk are all the predecessors of n, and n d, then ddomn iff ddompi for each i
Finding Dominators Direction Forwards Transfer fB(x) = x { B } function Boundary OUT[ENTRY] = { ENTRY } Meet() Equations OUT[B] = fB(IN[B]) IN[B] = P, pred(B) OUT[P] Initialization OUT[B] = N (set of nodes)
An Example 1 D(1) = {1} D(2) = {1,2} D(3) = {1,3} D(4) = {1,3,4} D(5) = {1,3,4,5} D(6) = {1,3,4,6} D(7) = {1,3,4,7} D(8) = {1,3,4,7,8} D(9) = {1,3,4,7,8,9} D(10) = {1,3,4,7,8,10} 2 3 4 5 6 7 8 9 10
Depth-First Ordering • A depth-first traversal of a graph starts at the ENTRY node and visits nodes as far away from the ENTRY node as quickly as possible • The route of a depth-first traversal forms a tree called a depth-first spanning tree (DEST) of the graph • A depth-first ordering of the nodes in a graph is the reverse of the postorder traversal
1 2 3 4 5 6 7 8 9 10 An Example 1 3 2 4 6 5 7 8 10 9 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
Depth-First Traversal Algorithm void search(n) { mark n “visited”; for (each successor s of n) if (s is “unvisited”) { add edge n s to T; search(s); } dfn[n] = c; c= c– 1; } main( ) { T = ; for (each node n of G) mark n “unvisited”; c= number of nodes of G; search(n0); }
Edges in a Depth-First Spanning Tree • An advancing edge goes from a node m to a descendant of m in the tree • A retreating edge goes from a node m to an ancestor of m in the tree • A cross edge is an edge m n such that neither m nor n is an ancestor of the other in the tree
1 2 1 3 3 2 4 4 5 6 7 6 5 7 8 9 10 8 10 9 An Example
Back Edges • A back edge is an edge a bwhose head bdominates its tail a • For any flow graph, every back edge is retreating, but not every retreating edge is a back edge
1 2 1 3 3 2 4 4 5 6 7 6 5 7 8 9 10 8 10 9 An Example
Reducibility • A flow graph is said to be reducible if all its retreating edges in any DFST are also back edges • If a flow graph is nonreducible, all the back edges are retreating edges in any DFST, but each DFST may have additional retreating edges that are not back edges. • A flow graph is reducible if after removing all the back edges, the remaining graph is acyclic
1 2 3 4 5 6 7 8 9 10 A Reducible Example 1 3 2 4 6 5 7 8 10 9
1 2 3 A Nonreducible Example
Depth of a Flow Graph • Given a DFST for a flow graph, the depth of the flow is the largest number of retreating edges on any cycle-free path
1 3 2 4 6 5 7 8 10 9 An Example 10 7 4 3 depth is 3
Natural Loops • A natural loop is defined by two properties: • It must have a single-entry node, called the header. This entry node dominates all nodes in the loop • There must be a back edge that enters the loop header • Given a back edge n d, we define the natural loop of the edge to be d plus the set of nodes that can reach n without going through d. Node d is the header of the loop.
Constructing Natural Loops voidinsert(m) { if (m is not in loop) { loop = loop {m}; push m onto S; } } main(n d) { S = empty; loop = {d}; insert(n); while (S is not empty) { pop m off S; for (each predecessor p of m) insert(p); } }
An Example 1 2 3 107:{7,8,10} 74 :{4,5,6,7,8,10} 43 :{3,4,5,6,7,8,10} 83 :{3,4,5,6,7,8,10} 91 :{1,2,3,4,5,6,7,8,9,10} 4 5 6 7 8 9 10
Innermost Loops • Unless two loops have the same header, they are either disjoint or one is nested within the other • When two loops have the same header, but neither is nested within the other, they are combined and treated as a single loop • An innermost loop is one that contains no other loops
B0 B1 B2 B3 An Example
Speed of Convergence of Iterative Data-Flow Algorithms • The maximum number of iterations the algorithm may take is the product of the height of the lattice and the number of nodes in the flow graph • It is possible to order the evaluation such that the algorithm converges in a much smaller number of iterations
Speed of Convergence of Iterative Data-Flow Algorithms • If all useful information propagates along acyclic paths, we have an opportunity to tailor the order in which we visit nodes in iterative data-flow algorithms, so that after relatively few passes through the nodes we can be sure information has passed along all the acyclic paths
Information Propagation • In reaching definitions, if a definition d is in IN[B], then there is some acyclic path from the block containing d to B such that d is in the IN’s and OUT’s all along that path • In constant propagation, information may propagate through cyclic paths L: a = b b = c c = 1 goto L
Using Depth-First Order • Process the basic blocks in the flow graph in depth-first order • The number of iterations needed is no more than two greater than the depth 35193516234541017
Region-Based Analysis • In the iterative analysis, we create transfer functions for basic blocks, then find the fixedpoint solution of data-flow values by repeated passes over the blocks • A region-based analysis finds transfer functions that summarize the execution of progressively larger regions of the program • Ultimately, transfer functions for entire procedures are constructed and then applied to get the desired data-flow values directly
Regions • A region of a flow graph is a collection of nodes N and edges E such that • There is a headerh in N that dominates all the nodes in N • If some node m can reach a node n in N without going through h, then m is also in N • E is the set of all the control flow edges between nodes n1 and n2 in N, except (possibly) for some that enter h
An Example B1 N: {B1, B2}, E: {B1B2}. N: {B1, B2, B3}, E: {B1B2,B2B3,B1B3}. N: {B2, B3}, E: {B2B3}. B2 B3 B4
Region Hierarchies • First, every block is a region by itself. These regions are called leaf regions • Then we order the natural loops from the inside out. We replace each loop by a node in two steps: • The body of the loop is replaced by a node. This node is called a body region • The body region and the loop back edge are replaced by a node. This node is called a loop region
d1: i = m - 1 d2: j = n d3: a = u1 B1 d4: i = i + 1 B2 d5: a = u2 B3 B4 d6: j = u3 B5 An Example
R1 R1 R6 R7 R5 R5 An Example R1 R2 R8 R3 R4 R5
Overview of Region-Based Analysis • This is a two-pass analysis. The first pass computes transfer functions bottom-up. The second pass computes data-flow values top-down • We first consider the bottom-up pass • For each region R, and for each subregion R’ within R, we compute a transfer function fR,IN[R’] that summarizes the effect of executing all possible paths leading from the entry of R to the entry of R’, while staying within R
Overview of Region-Based Analysis • We say that a block B within R is an exit block of region R if it has an outgoing edge to some block outside R • We also compute a transfer function for each exit block B of R, denoted fR,OUT[B], that summarizes the effect of executing all possible paths within R, leading from the entry of R to the exit of B
Overview of Region-Based Analysis • We begin with regions that are single blocks, where fB,IN[B] is just the identity function I and fB,OUT[B] is the transfer function fB for the block B itself • We then proceed up the region hierarchy, computing transfer functions for progressively larger regions • Eventually, we reach the top of the hierarchy and compute the transfer functions for the top region Rn that is the entire flow graph
Overview of Region-Based Analysis • If R is a body region, then the edges belonging to R form an acyclic graph on the subregions of R. for (each subregion S immediately contained in R, in topological order) {fR,IN[S]= Bpred(S)fR,OUT[B];for (each exit block B in S)fR,OUT[B]=fS,OUT[B]。fR,IN[S]; }
Overview of Region-Based Analysis • If R is a loop region, then we only need to account for the effect of the back edges to the header of R.letS be the body region immediately contained in R;fR,IN[S]= (Bpred(S)fS,OUT[B])*;for (each exit block B in R)fR,OUT[B]=fS,OUT[B]。fR,IN[S];
Overview of Region-Based Analysis • We now consider the top-down pass • For each region, we compute the data-flow values at the entry • For region Rn, IN[Rn] = IN[ENTRY] • For each subregion R in Rn, IN[R] = fRn,IN[R](IN[Rn]) • We repeat until we reach the basic block at the leaves of the region hierarchy
Necessary Assumptions about Transfer Functions • For region-based analysis to work, we need three primitive operations on transfer functions: composition, meet, and closure • Let f1 and f2 be transfer functions of nodes n1 and n2. The effect of executing n1 followed by n2 is represented by f2。f1f2。f1(x) = gen2 ((gen1 (x – kill1)) – kill2) = (gen2 (gen1 – kill2)) (x – (kill1 kill2))
Necessary Assumptions about Transfer Functions • The meet of two transfer functions f1 and f2, f1 ff2 , is defined by (f1 ff2)(x) = f1(x) f2(x) (f1 ff2)(x) = f1(x) f2(x) = (gen1 (x – kill1)) (gen2 (x – kill2)) = (gen1 gen2) (x – (kill1 kill2))
Necessary Assumptions about Transfer Functions • If f represents the transfer function of a cycle. Assume that the cycle may be executed 0 or more times. The closure of f is defined byf* = n0f norf* = I (n>0f n) f 2(x) = f (f (x)) = gen ((gen (x – kill)) – kill) = gen (x – kill) = f 1(x)f*(x) = If 1(x)f 2(x) …= x (gen (x – kill)) = gen x
d1: i = m - 1 d2: j = n d3: a = u1 B1 d4: i = i + 1 B2 d5: a = u2 B3 B4 d6: j = u3 B5 An Example genB, killB: B1:{d1,d2,d3}, {d4,d5,d6}. B2:{d4}, {d1}. B3:{d5}, {d3}. B4:{d6}, {d2}. B5: , .
An Example R1 For Ri, 1 i 5, fRi,IN[Bi](x) = I, fRi,OUT[Bi](x) = genBi (x – killBi) R2 R3 R4 R5
R1 R6 R2 R3 R4 R5 An Example Transfer Function gen kill fR6,IN[R2] = I fR6,OUT[B2] = fR2,OUT[B2]。fR6,IN[R2]{d4} {d1} fR6,IN[R3] = fR6,OUT[B2] {d4} {d1} fR6,OUT[B3] = fR3,OUT[B3]。fR6,IN[R3]{d4,d5} {d1,d3} fR6,IN[R4] = fR6,OUT[B2] fR6,OUT[B3]{d4,d5} {d1} fR6,OUT[B4] = fR4,OUT[B4]。fR6,IN[R4]{d4,d5,d6} {d1,d2}
R1 R6 R5 An Example Transfer Function gen kill fR7,IN[R6] = f*R6,OUT[B4] {d4,d5,d6} fR7,OUT[B3] = fR6,OUT[B3]。fR7,IN[R6]{d4,d5,d6} {d1,d3} fR7,OUT[B4] = fR6,OUT[B4]。fR7,IN[R6]{d4,d5,d6} {d1,d2} R7
R1 R7 R5 An Example Transfer Function gen kill fR8,IN[R1] = I fR8,OUT[B1] = fR1,OUT[B1]{d1,d2,d3} {d4,d5,d6} fR8,IN[R7] = fR8,OUT[B1] {d1,d2,d3} {d4,d5,d6} fR8,OUT[B3] = fR7,OUT[B3]。fR8,IN[R7]{d2,d4,d5,d6} {d1,d3} fR8,OUT[B4] = fR7,OUT[B4]。fR8,IN[R7]{d3,d4,d5,d6} {d1,d2} fR8,IN[R5] = fR8,OUT[B3] fR8,OUT[B4]{d2,d3,d4,d5,d6} {d1} fR8,OUT[B5] = fR5,OUT[B5]。fR8,IN[R5]{d2,d3,d4,d5,d6} {d1} R8