1 / 59

CMPUT680 - Winter 2006

This article discusses the various techniques and algorithms used in reference analysis for compiler optimization, including flow-sensitivity, context-sensitivity, and Andersen's and Steensgaard's analysis. Examples and explanations are provided to illustrate these concepts.

sbill
Download Presentation

CMPUT680 - Winter 2006

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CMPUT680 - Winter 2006 Topic P: Reference Analysis José Nelson Amaral http://www.cs.ualberta.ca/~amaral/courses/680 CMPUT 680 - Compiler Design and Optimization

  2. References • Ryder, Barbara G., “Dimensions of Precision in Reference Analysis of Object-Oriented Programming Languages,” Compiler Construction, pp. 126-137, Warsaw, Poland, April, 2003. • Shapiro, Marc and Horwitz, Susan, “Fast and Accurate Flow-Insensitive Points-To Analysis,” Symposium on Principles of Programming Languages, pp. 1-14, Paris, France, 1997. • Emami, Maryam, Ghiya, Rakesh, and Hendren, Laurie J., “Context-Sensitive Interprocedural Points-to Analysis in the Presence of Function Pointers,” Programming Language Design & Implementation, pp. 242-256, Orlando, FL, 1994. • Steensgaard, Bjarne, “Points-to Analysis in Almost Linear Time,” Symposium on Principles of Programming Languages, pp. 32-41, 1996. • Landi, William, and Ryder, Barbara G., “A Safe Approximate Algorithm for Interprocedural Pointer Aliasing, Programming Language Design & Implementation, pp. 235-248, 1992. CMPUT 680 - Compiler Design and Optimization

  3. Motivation … [1] x=0; [2] *p = 1; [3] write(x); … Example of Optimization Problems: Draw a Data Dependence Graph for statements 1-3; Does definition [1] reaches statement [3]? Can the constant 0 be propagated to statement [3]? CMPUT 680 - Compiler Design and Optimization (Shapiro/Horwitz, PPL97)

  4. Motivation … [1] x=0; [2] *p = 1; [3] write(x); … • There are three situations to consider: • pmust point to xx=1 in [3]. • pmust not point to xx=0 in [3]. • pmay point to x the compiler does not know the value of x in [3]. CMPUT 680 - Compiler Design and Optimization (Shapiro/Horwitz, PPL97)

  5. Flow-sensitivity • Flow-sensitive analysis: takes into account the order in which statements are executed; • Flow-insensitive analysis: assumes that statements can be executed in any order; CMPUT 680 - Compiler Design and Optimization (Shapiro/Horwitz, PPL97)

  6. Context-sensitivity • Context-sensitive analysis: takes into account the fact that a function must return to the site of the most recent call; • Context-insensitive analysis:propagates information from a call site, through the called function, and back to all call sites. • A context-insensitive analysis constructs a single approximation to a procedure’s effect on all of its callers (Ruf, PLDI95). CMPUT 680 - Compiler Design and Optimization (Shapiro/Horwitz, PPL97)

  7. Andersen’s X Steensgaard’s Analysis • Both analysis are flow-insensitive and context-insensitive. • Both build an alias graph (Burke, Carini, Choi, Hind, LCPC94) or a storage shape graph (Chase, Wegman, Zadeck, PLDI90). • Andersen: each node can have an arbitrary number of out-edges  each node represents one variable. • Steensgaard: each node has at most one out-edge  each node may represent more than one variable. CMPUT 680 - Compiler Design and Optimization (Shapiro/Horwitz, PPL97)

  8. a Andersen’s X Steensgaard’s (Example) Program: Steensgaard: a = &b; S = {(a,b)} b Andersen: S = {(a,b)} b a CMPUT 680 - Compiler Design and Optimization (Shapiro/Horwitz, PPL97)

  9. a Andersen’s X Steensgaard’s (Example) Program: Steensgaard: a = &b; b = &c; S = {(a,b); (b,c)} b c Andersen: S = {(a,b); (b,c)} b c a CMPUT 680 - Compiler Design and Optimization (Shapiro/Horwitz, PPL97)

  10. a Andersen’s X Steensgaard’s (Example) Program: Steensgaard: a = &b; b = &c; a = &d; S = {(a,b); (b,c)} b c Andersen: What should happen in each analysis? S = {(a,b); (b,c)} b c a CMPUT 680 - Compiler Design and Optimization (Shapiro/Horwitz, PPL97)

  11. a Andersen’s X Steensgaard’s (Example) Program: Steensgaard: a = &b; b = &c; a = &d; S = {(a,b); (b,c); (a,d); (d,c)} (b,d) c Andersen: S = {(a,b); (b,c); (a,d)} b c a d CMPUT 680 - Compiler Design and Optimization (Shapiro/Horwitz, PPL97)

  12. a Andersen’s X Steensgaard’s (Example) Program: Steensgaard: a = &b; b = &c; a = &d; d = &e; S = {(a,b); (b,c); (a,d); (d,c)} (b,d) c Andersen: And now? S = {(a,b); (b,c); (a,d)} b c a d CMPUT 680 - Compiler Design and Optimization (Shapiro/Horwitz, PPL97)

  13. a Andersen’s X Steensgaard’s (Example) Program: Steensgaard: a = &b; b = &c; a = &d; d = &e; S = {(a,b); (b,c); (a,d); (d,c); (d,e); (b,e)} (b,d) (c,e) Andersen: S = {(a,b); (b,c); (a,d); (d,e)} b c a e d CMPUT 680 - Compiler Design and Optimization (Shapiro/Horwitz, PPL97)

  14. Steensgaard’s Algorithm • Based on non-standard type-system. The “type” of a variable describes a set of locations possibly pointed-to by the variable. • At initialization, each variable is described by a different type. • Fast union-find structures are used to provide constant-time access to the type associated with a variable name. • Process each statement exactly once, joining type variables as necessary to ensure that the program is well-typed. CMPUT 680 - Compiler Design and Optimization (Steensgaard, PPL96)

  15. Comparison of Steensgaard and Andersen • For small programs (up to 3,000 lines) both analyses are very fast. • For some large programs, Andersen’s may take a very long time (from more than 10 to more than 100 times as long as Steensgaard’s). • For 37 out of 61 programs (21 out of 25 “large” programs), Andersen’s points-to-set is less than half the size of Steengaard’s (thus Andersen’s is more precise). CMPUT 680 - Compiler Design and Optimization (Shapiro/Horwitz, PPL97)

  16. Shapiro/Horwitz Algorithm 1 • Allows each node in the alias graph to have out-degree k (k is an input to the algorithm). • Each variable is assigned to one of k categories. Only merge nodes of variables in the same category. • Partition of variables into categories is an input for the algorithm: • All variables in one category  Steensgaard • Each variable in a separate category  Andersen CMPUT 680 - Compiler Design and Optimization (Shapiro/Horwitz, PPL97)

  17. b b (b,c,d) (b,d) d c c (c,d) a a a a Shapiro/Horwitz Algorithm 1 (Example) Categories: {a, b, c, d} Program: S = {(a, b); (a,c); (a,d); (b,b); (b,c); (b,d); (c,b); (c,c); (c,d); (d,b); (d,c), (d,d)} a = &b; a = &c; a = &d c = &d Categories: {a, b} {c, d} S = {(a, b); (a,c); (a,d); (c,c); (c,d); (d,c), (d,d)} Categories: {a, c}, {b, d} S = {(a, b); (a,c); (a,d); (c,b); (c,d)} Categories: {a, b}, {c}, {d} S = {(a, b); (a,c); (a,d); (c,d)} (Shapiro/Horwitz, PPL97)

  18. Shapiro/Horwitz Algorithm 2 • Insight: Run algorithm 1 multiple times with k categories and a different category partition each time: • True points-to relationships are found by taking the intersection of the points-to sets computed by each run. • Goal: Select a set of runs such that for every pair of variables (x, y), there is at least one run in which x and y are in different categories. CMPUT 680 - Compiler Design and Optimization (Shapiro/Horwitz, PPL97)

  19. Shapiro/Horwitz Algorithm 2 • Solution: R = logk N runs, where N is the number of variables. • Assign each variable a unique number, in base k, in the range 0 to N-1 using R digits. • Use this encoding to select the variables categories. CMPUT 680 - Compiler Design and Optimization (Shapiro/Horwitz, PPL97)

  20. Categories for run 1: {a,c}, {b,d} Categories for run 2: {a,b}, {c,d} Run 1: S1 = {(a, b); (a,c); (a,d); (c,b); (c,d)} Run 2: S2 = {(a, b); (a,c); (a,d); (c,c); (c,d); (d,c), (d,d)} Shapiro/Horwitz Algorithm 2 (Example) Program: The program has four variables, for k=2: a = &b; a = &c; a = &d c = &d a 00 b 01 c 10 d 11 S1  S2 = {(a, b); (a,c); (a,d); (c,d)} CMPUT 680 - Compiler Design and Optimization (Shapiro/Horwitz, PPL97)

  21. If pdefinitely points to y at this point. Then all previous point-to relations from y are now killed. w w y p y p x z z Before the statement After the statement May X (Possible or Definite) Points-to Relations • Possible and definite points-to information can be important: p = x CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  22. May X (Possible or Definite) Points-to Relations • Possible and definite points-to information can be important: If qdefinitely points to y at this point. x = q Then the statement can be replaced by x=y. CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  23. Stack-based and Heap-based aliasing • Three varieties of aliases: • Aliases between variable references to the stack; • Aliases between references to the heap; • Aliases between two references to the same array. • Analysis of stack-based aliases and heap-based aliases should be decoupled. CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  24. Stack-based and Heap-based aliasing • Stack-base analysis: • A name exist for each location of interest; • Compute an approximation of the relationship between these locations; • Heap-base analysis: • There are no natural names for locations; • We don’t know how many locations will exist; • Solution: consider the entire heap a single location in the stack analysis. CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  25. The Reference Analysis Problem Statement • The reference analysis problem is a generalization of alias analysis: • Given two references p and q, is it possible that p and q may: • point to the same memory location? • refer to the same object? • dispatch to the same method? CMPUT 680 - Compiler Design and Optimization

  26. Alias Pairs • Sets of alias pairs (Landi & Ryder PLDI93): two variable references may be aliased if they may refer to the same memory location. q After statement p=q, the following alias pairs are created: p, q, p->next, q->next, p->next->next, q->next->next, … CMPUT 680 - Compiler Design and Optimization

  27. Points-to Abstraction • Create an abstract representation of the stack: • Each real stack location that is involved in a points-to relationship is represented by exactly one named abstract location; • Each named abstract location represents one or more real stack locations. Real Locations Abstract Locations loci x locj y lock CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  28. Abstract Stack Location • An abstract stack location corresponds to one of this: • The name of a local variable, global variable, or parameter. • A symbolic name that represents a location not in the scope of the procedure under analysis. • The symbolic name heap. CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  29. Definitely Points-to • An abstract location xdefinitely points to abstract location y, noted (x, y, D), for a given invocation context, if: • x and y each represent exactly one real location in that context; and • the real location corresponding to x contains the address of the real location y. CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  30. Possibly Points-to • An abstract location xpossibly points to abstract location y, noted (x, y, P), for a given invocation context, if: • It is possible that one of the real locations corresponding to x contains the address of one of the real locations represented by y. CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  31. Real Locations Abstract Locations loci x locj y Safe Approximation • Let S be the points-to set at point p. • Consider all pairs of real locations loci and locj. Let x be the abstract location of loci and y be the abstract location of locj. CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  32. Safe Approximation • S is a safe approximation at p if: • S contains (x,y,D) or (x,y,P) when locipoints to locj on all valid execution paths to p. • S contains (x,y,P) when loci points to locj in some, but not all, execution paths to p. • If S contains (x,y,D) then locimust point to locj in all paths to p. Real Locations Abstract Locations loci x ? locj y CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  33. Safety and Precision • An approximation is unsafe if: • A real points-to relationship is not in S; • A spurious definite points-to relation is in S; • The following approximation is safe, just not very precise: • Every abstract location possibly points-to every other abstract location. CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  34. L-locations and R-locations • Problem: Given the input points-to set Sin of an statement S, generate its output points-to set Sout. • Solution: • Compute an abstract representation of the locations represented in the left-hand side (L-locations) and in the right-hand side (R-locations) of S. • Notation: • (x,D): abstract location x is definitely in the set • (x,P): abstract location x is possibly in the set CMPUT 680 - Compiler Design and Optimization

  35. w v y q z Sinput = {(q,y,D); (y,w,P); (y,z,P); (w,v,D)} Before the statement q = w Soutput = ? L-locations and R-locations (example) L-locations(*q) = {(x,d) | (q,x,d)  S} L-locations(*q) = ? R-locations(w) = {(x,d) | (w,x,d)  S} R-locations(w) = ? CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  36. w v y q z Sinput = {(q,y,D); (y,w,P); (y,z,P); (w,v,D)} Before the statement q = w Soutput = ? Skill = {(p,x,d) | (p,D)  L-locations(*q)  (p,x,d)  Sinput} = ? The clause in green above is not in the original paper, but it is necessary. L-locations and R-locations (example) L-locations(*q) = {(x,d) | (q,x,d)  S} L-locations(*q) = {(y,D)} R-locations(w) = {(x,d) | (w,x,d)  S} R-locations(w) = {(v,D)} Schange = {(p,x,D) | (p,P)  L-locations(*q)  (p,x,D)  Sinput} = ? Sgen = {(p,x,d1  d2) | (p,d1)  L-locations(*q)  (x,d2)  R-locations(w)} = ? CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  37. w v y q z Sinput = {(q,y,D); (y,w,P); (y,z,P); (w,v,D)} Before the statement q = w Soutput = ? L-locations and R-locations (example) L-locations(*q) = {(x,d) | (q,x,d)  S} L-locations(*q) = {(y,D)} R-locations(w) = {(x,d) | (w,x,d)  S} R-locations(w) = {(v,D)} Skill = {(p,x,d) | (p,D)  L-locations(*q)  (p,x,d)  Sinput} = {(y,w,P),(y,z,P)} Schange = {(p,x,D) | (p,P)  L-locations(*q)  (p,x,D)  Sinput} = { } Sgen = {(p,x,d1  d2) | (p,d1)  L-locations(*q)  (x,d2)  R-locations(w)} = {(y,v,D)} CMPUT 680 - Compiler Design and Optimization The clause in green above is not in the original paper, but it is necessary. (Emami, Ghiya, Hendren, PLDI 94)

  38. w v y q z Sinput = {(q,y,D); (y,w,P); (y,z,P); (w,v,D)} Before the statement q = w Soutput = ? L-locations and R-locations (example) L-locations(*q) = {(y,D)} R-locations(w) = {(v,D)} Skill = {(y,w,P),(y,z,P)} Schange = { } Sgen = {(y,v,D)} Sinputchanged = (Sinput - Schange)  {(p,x,D)  Schange} = CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  39. w v y q z Sinput = {(q,y,D); (y,w,P); (y,z,P); (w,v,D)} Before the statement q = w Soutput = ? L-locations and R-locations (example) L-locations(*q) = {(y,D)} R-locations(w) = {(v,D)} Skill = {(y,w,P),(y,z,P)} Schange = { } Sgen = {(y,v,D)} Sinputchanged = (Sinput - Schange)  {(p,x,D)  Schange} = Sinput CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  40. w v y q z Sinput = {(q,y,D); (y,w,P); (y,z,P); (w,v,D)} Before the statement q = w Soutput = ? L-locations and R-locations (example) L-locations(*q) = {(y,D)} R-locations(w) = {(v,D)} Skill = {(y,w,P),(y,z,P)} Schange = { } Sgen = {(y,v,D)} Sinputchanged = (Sinput - Schange)  {(p,x,D)  Schange} = Sinput Soutput = (Sinputchanged - Skill)  Sgen = ? CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  41. w v y q z Sinput = {(q,y,D); (y,w,P); (y,z,P); (w,v,D)} Before the statement q = w Soutput = {(q,y,D); (w,v,D); (y,v,D)} L-locations and R-locations (example) L-locations(*q) = {(y,D)} R-locations(w) = {(v,D)} w v Skill = {(y,w,P),(y,z,P)} y q Schange = { } z Sgen = {(y,v,D)} Sinputchanged = Sinput After the statement Soutput = (Sinputchanged - Skill)  Sgen = ? CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  42. Invocation Graph • Programs without recursion: Invocation graph built with a depth-first traversal of the call structure, starting with main. • Programs with recursion: Invocation structure not known at compile time. Invocation graph approximates all unrollings of recursions. CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  43. main g g main f f f-R g f-A f-A Invocation Graph (examples) main() { … f(); } f() { g(); if (y) f(); } g() { if (e) f(); } main() { … g(); g(); } g() { … f(); … } f-A: An approximate node where a stored approximation for the function should be used (instead of an evaluation of the function call). f-R: A recursive node where a fixed-point computation must be performed. CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  44. Advantages of using an Invocation Graph • Separates inter-procedural analysis from calling contexts. • Creates places to deposit context-sensitive information for subsequent analysis. • Creates places to store IN/OUT pairs summarizing the effects of a function call. • Allows simple compositional fixed-point computations for recursions. CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  45. Callee Caller Map Process f() { … g(a); } g(x) { … } Function Analysis Unmap Process Inter-procedural Context-sensitivy analysis Special care in the Map process: • Formal parameters and global variables that are multi-level pointers. • Invisible variables: formals and globals that point to variables outside of the scope of the callee. CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  46. Callee Caller Map Process f() { … g(a); } g(x) { … } Function Analysis Unmap Process Inter-procedural Context-sensitivy analysis Solutions to the Map process: • Multi-level pointers: apply the mapping process recursively to all levels of pointer type. • Invisible variables: generate special symbolic names to represent each level of indirection of pointer variables (see paper for details). CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  47. Approximate and Recursive Nodes • A recursive node f-R stores an input, an output, and a list of pending inputs. • The input and output pairs approximate the effect of the call to f. • The fixed-point computation generalizes the stored input and output until it summarizes all invocations of f. CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  48. Function Pointer • When a function is called through a function pointer a set of functions may be called. • Some safe approximations for this set are: • All the functions in the program. • All functions which have had their addresses taken. • The set of functions that the pointer can point to at the program point where the call is. CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  49. A cyclic dependence • To obtain the points-to set for the function pointer, we need to perform points-to analysis. • But points-to analysis needs the invocation graph of the program because it is context sensitive and inter-procedural. • The solution is to construct the invocation graph while performing points-to analysis. CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

  50. Handling Function Pointers • Build the invocation graph, leaving it incomplete where a function pointer call is encountered. • Perform points-to analysis using the incomplete invocation graph. • When an indirect call through a function pointer is encountered, find the set P of all functions it can point to according to current information. • Update the invocation graph to indicate that the indirect call may call any function in P. • Analyze each function fP in the context of the call --- while analyzing f assume that the function pointer definitely points to f. • Merge the output points-to sets of all functions in P. CMPUT 680 - Compiler Design and Optimization (Emami, Ghiya, Hendren, PLDI 94)

More Related