LLVM Compiler Infrastructure Reuse Optimization Source: “ LLVM: A Compilation Framework for Lifelong Program Analysis & Transformation” by Lattner and Adve Idea − Eliminate redundant operations in the dynamic execution of instructions How do redundancies arise? Goals − Loop invariant code ( e.g., index calculation for arrays) - lifelong analysis and optimization − Sequence of similar operations ( e.g., method lookup) - modular compiler components − Same value be generated in multiple places in the code IR is low level, control-flow graph and SSA - language-independent types: 8-26 bit ints, float, double, pointers, arrays, structures, functions Types of reuse optimization Status − Value numbering -Apple is paying main developer (Chris Lattner) to continue development − Common subexpression elimination -built OpenGL JIT compiler with it in two weeks − Partial redundancy elimination CS553 Lecture Value Numbering 1 CS553 Lecture Value Numbering 2 Local Value Numbering Local Value Numbering (cont) Idea Temporaries may be necessary − Each variable, expression, and constant is assigned a unique number b → #1 a := b + c − When we encounter a variable, expression or constant, see if it’s already c → #2 a := b been assigned a number b + c is #1 + # 2 → #3 #1 d := a + c a → # 3 − If so, use the value for that number a + c is #1 + # 2 → #3 − If not, assign a new number d → #3 − Same number ⇒ same value #3 b → #1 b → #1 Example t := b + c c → #2 c → #2 a := b + c a := b b + c is #1 + # 2 → #3 b + c is #1 + # 2 → #3 d := b d := b + c t t → # 3 a → # 3 b := a a → # 1 d → #1 e := d + c a a + c is #1 + # 2 → #3 d + c is #1 + # 2 → #3 d → #3 e → #3 CS553 Lecture Value Numbering 3 CS553 Lecture Value Numbering 4 1
Global Value Numbering Global Value Numbering (cont) How do we handle control flow? Idea [Alpern, Wegman, and Zadeck 1988] − Partition program variables into congruence classes − All variables in a particular congruence class have the same value w = 5 w = 8 − SSA form is helpful x = 5 x = 8 w → #1 w → #2 Approaches to computing congruence classes y = w+1 x → #1 x → #2 − Pessimistic z = x+1 . . . . . . − Assume no variables are congruent (start with n classes) − Iteratively coalesce classes that are determined to be congruent − Optimistic − Assume all variables are congruent (start with one class) − Iteratively partition variables that contradict assumption − Slower but better results CS553 Lecture Value Numbering 5 CS553 Lecture Value Numbering 6 Role of SSA Form Basis SSA form is helpful Idea − Allows us to avoid data-flow analysis − If x and y are congruent then f(x) and f(y) are congruent − Variables correspond to values ta = a tb = b a = b x and y are a 1 = b x = f(a,b) congruent . . . . . . y = f(ta,tb) a = c a 2 = c a not congruent to Congruence classes: . . . . . . { a 1 , b }, { a 2 , c }, { a 3 , d } anything − Use this fact to combine (pessimistic) or split (optimistic) classes a = d a 3 = d Problem − This is not true for φ -functions a 1 & b 1 congruent? a 1 = x 1 a 2 = y 1 b 1 = x 1 b 2 = y 1 a 2 & b 2 congruent? n m a 3 = φ (a 1 ,a 2 ) b 3 = φ (b 1 ,b 2 ) n m a 3 & b 3 congruent? Solution: Label φ -functions with join point CS553 Lecture Value Numbering 7 CS553 Lecture Value Numbering 8 2
Pessimistic Global Value Numbering Algorithm Idea for each assignment of the form: “ x = f(a,b) ” − Initially each variable is in its own congruence class ValNum[x] ← UniqueValue() // same for a and b − Consider each assignment statement s (reverse postorder in CFG) for each assignment of the form: “ x = f(a,b) ” (in reverse postorder) − Update LHS value number with hash of RHS ValNum[x] ← Hash(f ⊕ ValNum[a] ⊕ ValNum[b]) − Identical value number ⇒ congruence #1 i 1 = 1 a 1 #2 b 1 Why reverse postorder? i 1 #3 w 1 = b 1 w 2 = a 1 w 1 #4 #2 − Ensures that when we consider an assignment statement, we have already x 1 = b 1 x 2 = a 1 x 1 #5 #2 considered definitions that reach the RHS operands w 2 #6 #1 a x 2 #7 #1 w 3 = φ n (w 1 , w 2 ) φ n (#2,#1) → #12 w 3 #8 x 3 = φ n (x 1 , x 2 ) b φ n (#2,#1) → #12 Postorder: d, c, e, b, f, a x 3 #9 y 1 = w 3 +i 1 c e f +(#12,#3) → #13 y 1 #10 z 1 = x 3 +i 1 +(#12,#3) → #13 z 1 #11 d CS553 Lecture Value Numbering 9 CS553 Lecture Value Numbering 10 Snag! Optimistic Global Value Numbering Problem Idea − Our algorithm assumes that we consider operands before variables that − Initially all variables in one congruence class depend upon it − Split congruence classes when evidence of non-congruence arises − Can’t deal with code containing loops! − Variables that are computed using different functions − Variables that are computed using functions with non-congruent Solution operands − Ignore back edges − Make conservative (worst case) assumption for previously unseen variable ( i.e., assume its in it’s own congruence class) CS553 Lecture Value Numbering 11 CS553 Lecture Value Numbering 12 3
Splitting Splitting (cont) Initially Definitions − Variables computed using the same function are placed in the same class − Suppose P and Q are sets representing congruence classes − Q splits P for each i into two sets P P’ x 1 = f(a 1 ,b 1 ) − P \ i Q contains variables in P whose i th operand is in Q . . . x 1 y 1 z 1 − P / i Q contains variables in P whose i th operand is not in Q y 1 = f(c 1 ,d 1 ) . . . − Q properly splits P if neither resulting set is empty z 1 = f(e 1 ,f 1 ) Iteratively P Q x 1 = f(a 1 ,b 1 ) Q − Split classes when corresponding . . . operands are in different classes x 1 y 1 z 1 a 1 c 1 a 1 c 1 y 1 = f(c 1 ,d 1 ) − Example: assume a 1 and c 1 are congruent, . . . but e 1 is congruent to neither z 1 = f(e 1 ,f 1 ) P \ 1 Q P / 1 Q CS553 Lecture Value Numbering 13 CS553 Lecture Value Numbering 14 Algorithm Example worklist ← ∅ SSA code Congruence classes for each function f S 0 { x 0 } x 0 = 1 C f ← ∅ S 1 { y 0 } y 0 = 2 for each assignment of the form “x = f(a,b)” S 2 { x 1 , y 1 , z 1 } x 1 = x 0 +1 C f ← C f ∪ { x } S 3 { x 1 ,z 1 } y 1 = y 0 +1 worklist ← worklist ∪ {C f } S 4 { y 1 } z 1 = x 0 +1 CC ← CC ∪ {C f } while worklist ≠ ∅ Delete some D from worklist Worklist: S 0 ={ x 0 }, S 1 ={ y 0 }, S 2 ={ x 1 , y 1 ,z 1 } , S 3 ={ x 1 ,z 1 }, S 4 ={ y 1 } for each class C properly split by D (at operand i) CC ← CC – C S 0 psplit S 0 ? no S 0 psplit S 1 ? no S 0 psplit S 2 ? yes! worklist ← worklist – C Create new congruence classes C j ← {C \ i D} and C k ← {C / i D} S 2 \ 1 S 0 = { x 1 , z 1 } = S 3 CC ← CC ∪ C j ∪ C k S 2 / 1 S 0 = { y 1 } = S 4 worklist ← worklist ∪ C j ∪ C k Note: see paper for optimization CS553 Lecture Value Numbering 15 CS553 Lecture Value Numbering 16 4
Comparing Optimistic and Pessimistic Role of SSA Differences Single global result − Handling of loops − Single def reaches each use − Pessimistic makes worst-case assumptions on back edges − No data (flow value) at each point − Optimistic requires actual contradiction to split classes No data flow analysis w 0 = 5 − Optimistic: Iterate over congruence classes, not CFG nodes x 0 = 5 − Pessimistic: Visit each assignment once φ -functions w 1 = φ (w 0 ,w 2 ) − Make data-flow merging explicit x 1 = φ (x 0 ,x 2 ) w 2 = w 1 +1 − Treat like normal functions after subscripting them for each merge point x 2 = x 1 +1 CS553 Lecture Value Numbering 17 CS553 Lecture Value Numbering 18 Next Time Lecture − Parallelism and Data Locality, start reading chapter 11 in dragon book Suggested Exercise − Use any programming language to write the class declarations for the equivalence class and variable structures described at the bottom of page 6 in the value numbering chapter. − Instantiate the data structures for the small example programs in Figures 7.2 and 7.6 and perform optimistic value numbering. Remember to convert to SSA first. − After performing value numbering, how will the program be transformed? − Now perform pessimistic value numbering on the two examples. Transform the code as well. CS553 Lecture Value Numbering 19 5
Recommend
More recommend