120 likes | 206 Views
Example of Constructing the DAG. *. t 1. *. t 1 := 4 * i Step (1): create node 4 and i 0 Step (2): create node Step (3): attach identifier t 1 t 2 := a[t 1 ] Step (1): create nodes labeled [], a Step (2): find previously node(t 1 ) Step (3): attach label t 3 := 4 * i
E N D
Example of Constructing the DAG * t1 * • t1:= 4 * i Step (1):create node 4 and i0 Step (2): create node Step (3): attach identifier t1 • t2:= a[t1] Step (1): create nodes labeled [], a Step (2): find previously node(t1) Step (3): attach label • t3:= 4 * i Here we determine that: node (4) was created node (i) was created node (*) was created just attach t3 to *. 4 i0 t2 [] t1,t3 a0 * 4 i0
Common Subexpression Elimination • Example: • a:= b + c • b:= a – d • c:= b + c • d:= a - d c + a:= b + c b:= a – d c:= b + c d:= b b,d - Detection: Common subexpressions can be detected by noticing, as a new node m is about to be added, whether there is an existing node n with the same children, in the same order, and with the same operator. if so, n computes the same value as m and may be used in its place. Note: The expressions b+c in (1) and (3) are not confused. a d0 + c0 b0
Transfomation: if x is dead (i.e., not live) – never subsequently used – after a point where statement x := y + z appears in a basic block. Then, this statement may be safely removed. Method: Delete from the DAG any root (node with no ancestors) that has no live variable. Weaker form: delete (when multiple) dead variable label. Repeat until we remove all nodes (labels) that correspond to dead code. Dead Code Elimination e Examples: c + + a:= b+c b:=b-d c:=c+d e:=b+c a:=b + c d:=a - d c:=d + c a b c b,d - + - + a d0 + b0 c0 d0 c0 b0 b is not used at the exit of the basic block
Renaming Temporary Variables Example: (1) t := b + c (1) u := b + c rename Normal Form: Each statement that defines a temporary, defines a new temporary. - A basic block can always be transformed into an equivalent block which is in normal form t u Change (rename) label + + b0 c0 b0 c0
Example: t1 := b + c t2 := x + y Observation: We can interchange the statements without affecting the value of the block if and only if neither x nor y is t1 and neither b nor c is t2, i.e. we have two trees. Note:Normal-form basic blocks permit all statement interchanges that are possible. Interchange of Statements t1 t2 + + b0 c0 x0 y0
Arithmetic Identities: x + 0 = 0 + x = x x – 0 = x x + 1 = 1 + x = x x / 1 = x - Replace left-hand side with simples right hand side. Associative/Commutative laws x + (y + z) = (x + y) + z x + y = y + x Reduction in strength: x ** 2 = x * x 2.0 * x = x + x x / 2 = x + 0.5 - Replace an expensive operator with a cheaper one. Constant folding 2 * 3.14 = 6.28 -Evaluate constant expression at compile time` Algebraic Transformations Methodology: Before we create a node of the DAG we check whether such a node exists modulo the above identities.
Global Data Flow Analysis To do code generation and optimization a compiler needs to collectinformation about the program as a whole and to distribute this information to each block in the flow-graph. Data flow analysis: the process by which the compiler collects data-flow information. - by setting up and solving systems of equations that relate information at various points in the program. Example (generic): out[S] = gen[S] U (in[S] – kill[S]) Information killed by the exec. of S Information flowing after the execution of S Generated by execution of S Information flowing at the beginning of S Note:Sometimes information flows backwards in[S] = … out[S] …
Points between two adjacent statements within a block before the first statement after the last statement Paths Consider all points in all the blocks. A path from p1 to pn is a sequence of points p1, …, pn such that for each i[1, n-1]: - pi is the point immediately preceding a statement and pi+1 is the point immediately following that statement in the same block, or - pi is the end of some block and pi+1 is the beginning of a successor block. Points and Paths d1 B i:= m-1 d1: i:= m-1 d2: j:= n d2 j:= n flow-graph State machine
Example of DFA Problem: Reaching Definitions Definition of variable x: is a statement that assigns or may assign a value to x. - unambiguous definitions: assignment to x or read & store a value in x from an I/O device. - ambiguous definitions: may define the value of x: • procedure call with x as a parameter or global variable. • assignment through a pointer. Definition d reaches a point p if there is a path from the point immediately following d to p such that d is not “killed” along that path. Killing a definition of a variable x happens if between two points along the path there is a definition of x.
Reaching Definition (Cont) Inaccuracies: When defining reaching definition we sometimes allow inaccuracies. Undecidability: to decide in general whether each path in a flow graph can be taken is an undecidable problem. Conservative inaccuracy: an inaccuracy is conservative if it never leads to a change in what the program computes. - it is normally conservative to assume that a definition can reach a point even if it may not. - we allow definitions to pass through ambiguous definitions.
DF Analysis of Strongly Structured Programs (a) S d: a:= b + c gen[s] = {d} kill[s] = Da – {d} out[s] = gen[s] (in[s] \ kill[s]) gen[s] = gen[s2] (gen[s1] – kill[s2]) kill[s] = kill[s2] (kill[s1] – gen[s2]) in[s1] = in[s], in[s2] = out[s1] out[s] = out[s2] gen[s] = gen[s1] gen[s2] kill[s] = kill[s1] kill[s2] in[s1] = in[s], in[s2] = in[s] out[s] = out[s1] U out[s2] S1 (b) S S2 (c) S S1 S2
Syntax directed definitions: the equations are syntax directed. - synthesized attributes: gen, kill, (out – depends on in) - inherited attributes: in ( in backward dir – out) Note: out[s] gen[s] (gen – definitions reaching end of S without following paths outside S) Loops & Fixpoints: Given gen[s], kill[s], in[s] we cannot simply use in[s] = in[s1].I = J O in[s1] = in[s] out[s1] O = G ( I – K) out[s] = out[s1] Take O0 = out[s1] = gen[s1] (in[s1] – kill[s1]) I1 = J1, O1 = G ( J – K) I2 = J G, O2 = O1 gen[s] = gen[s1] kill[s] = kill[s1] in[s1] = in[s] gen[s1] out[s] = out[s1] DFA of Strongly Structured Programs (Cont) (d) S S1