Interprocedural pointer analysis for C We’ll look at Wilson & Lam PLDI 95, and focus on two problems solved by this paper: –how to represent pointer information.

Slides:



Advertisements
Similar presentations
P3 / 2004 Register Allocation. Kostis Sagonas 2 Spring 2004 Outline What is register allocation Webs Interference Graphs Graph coloring Spilling Live-Range.
Advertisements

Advanced Compiler Techniques LIU Xianhua School of EECS, Peking University Pointer Analysis.
Context-Sensitive Interprocedural Points-to Analysis in the Presence of Function Pointers Presentation by Patrick Kaleem Justin.
Pointer Analysis – Part I Mayur Naik Intel Research, Berkeley CS294 Lecture March 17, 2009.
CSI 3120, Implementing subprograms, page 1 Implementing subprograms The environment in block-structured languages The structure of the activation stack.
CS412/413 Introduction to Compilers Radu Rugina Lecture 37: DU Chains and SSA Form 29 Apr 02.
Demand-driven Alias Analysis Implementation Based on Open64 Xiaomi An
Flow insensitive pointer analysis: fixed S1: l := new Cons p := l S2: t := new Cons *p := t p := t l p S1 l p tS2 l p S1 t S2 l t S1 p S2 l t S1 p S2 l.
School of EECS, Peking University “Advanced Compiler Techniques” (Fall 2011) Pointer Analysis.
Worst case complexity of Andersen *x = y x abc y def x abc y def Worst case: N 2 per statement, so at least N 3 for the whole program. Andersen is in fact.
Optimizing Compilers for Modern Architectures More Interprocedural Analysis Chapter 11, Sections to end.
Parameterized Object Sensitivity for Points-to Analysis for Java Presented By: - Anand Bahety Dan Bucatanschi.
The Ant and The Grasshopper Fast and Accurate Pointer Analysis for Millions of Lines of Code Ben Hardekopf and Calvin Lin PLDI 2007 (Best Paper & Best.
Semi-Sparse Flow-Sensitive Pointer Analysis Ben Hardekopf Calvin Lin The University of Texas at Austin POPL ’09 Simplified by Eric Villasenor.
Interprocedural analysis © Marcelo d’Amorim 2010.
6/9/2015© Hal Perkins & UW CSEU-1 CSE P 501 – Compilers SSA Hal Perkins Winter 2008.
Recap from last time We were trying to do Common Subexpression Elimination Compute expressions that are available at each program point.
Aliases in a bug finding tool Benjamin Chelf Seth Hallem June 5 th, 2002.
Next Section: Pointer Analysis Outline: –What is pointer analysis –Intraprocedural pointer analysis –Interprocedural pointer analysis (Wilson & Lam) –Unification.
U NIVERSITY OF M ASSACHUSETTS, A MHERST Department of Computer Science Emery Berger University of Massachusetts, Amherst Advanced Compilers CMPSCI 710.
Context-Sensitive Flow Analysis Using Instantiation Constraints CS 343, Spring 01/02 John Whaley Based on a presentation by Chris Unkel.
Speeding Up Dataflow Analysis Using Flow- Insensitive Pointer Analysis Stephen Adams, Tom Ball, Manuvir Das Sorin Lerner, Mark Seigle Westley Weimer Microsoft.
Chapter 2: Algorithm Discovery and Design
Approach #1 to context-sensitivity Keep information for different call sites separate In this case: context is the call site from which the procedure is.
From last time: reaching definitions For each use of a variable, determine what assignments could have set the value being read from the variable Information.
KQS More exercises/practice What about research frontier? Reading material Meetings for project Post notes more promptly.
Flow insensitivity and imprecision If you ignore flow, then you lose precision. main() { x := &y;... x := &z; } Flow insensitive analysis tells us that.
Previous finals up on the web page use them as practice problems look at them early.
Range Analysis. Intraprocedural Points-to Analysis Want to compute may-points-to information Lattice:
Run time vs. Compile time
1 Refinement-Based Context-Sensitive Points-To Analysis for Java Manu Sridharan, Rastislav Bodík UC Berkeley PLDI 2006.
Intraprocedural Points-to Analysis Flow functions:
From last time S1: l := new Cons p := l S2: t := new Cons *p := t p := t l p S1 l p tS2 l p S1 t S2 l t S1 p S2 l t S1 p S2 l t S1 p L2 l t S1 p S2 l t.
U NIVERSITY OF M ASSACHUSETTS, A MHERST Department of Computer Science Emery Berger University of Massachusetts, Amherst Advanced Compilers CMPSCI 710.
Recap from last time g() { lock; } h() { unlock; } f() { h(); if (...) { main(); } } main() { g(); f(); lock; unlock; } mainfgh ;;;;;;; u u ” ”””” ” ”
Approach #1 to context-sensitivity Keep information for different call sites separate In this case: context is the call site from which the procedure is.
Comparison Caller precisionCallee precisionCode bloat Inlining context-insensitive interproc Context sensitive interproc Specialization.
Pointer and Shape Analysis Seminar Mooly Sagiv Schriber 317 Office Hours Thursday
Reps Horwitz and Sagiv 95 (RHS) Another approach to context-sensitive interprocedural analysis Express the problem as a graph reachability query Works.
From last time: reaching definitions For each use of a variable, determine what assignments could have set the value being read from the variable Information.
Schedule Midterm out tomorrow, due by next Monday Final during finals week Project updates next week.
An Efficient Inclusion-Based Points-To Analysis for Strictly-Typed Languages John Whaley Monica S. Lam Computer Systems Laboratory Stanford University.
Transfer functions Our pairs of summaries look like functions from input information to output information We call these transfer functions Complete transfer.
Pointer analysis. Flow insensitive loss of precision S1: l := new Cons p := l S2: t := new Cons *p := t p := t l t S1 p S2 l t S1 p S2 l t S1 p S2 l t.
Pointer analysis. Pointer Analysis Outline: –What is pointer analysis –Intraprocedural pointer analysis –Interprocedural pointer analysis Andersen and.
Symbolic Path Simulation in Path-Sensitive Dataflow Analysis Hari Hampapuram Jason Yue Yang Manuvir Das Center for Software Excellence (CSE) Microsoft.
PRESTO: Program Analyses and Software Tools Research Group, Ohio State University STATIC ANALYSES FOR JAVA IN THE PRESENCE OF DISTRIBUTED COMPONENTS AND.
Recursion Textbook chapter Recursive Function Call a recursive call is a function call in which the called function is the same as the one making.
Fast Points-to Analysis for Languages with Structured Types Michael Jung and Sorin A. Huss Integrated Circuits and Systems Lab. Department of Computer.
Pointer Analysis Lecture 2 G. Ramalingam Microsoft Research, India.
Static Program Analysis of Embedded Software Ramakrishnan Venkitaraman Graduate Student, Computer Science Advisor: Dr. Gopal Gupta.
CSC 211 Data Structures Lecture 13
Jeffrey D. Ullman Stanford University. 2 boolean x = true; while (x) {... // no change to x }  Doesn’t terminate.  Proof: only assignment to x is at.
ESEC/FSE-99 1 Data-Flow Analysis of Program Fragments Atanas Rountev 1 Barbara G. Ryder 1 William Landi 2 1 Department of Computer Science, Rutgers University.
Pointer Analysis Survey. Rupesh Nasre. Aug 24, 2007.
Pointer Analysis Lecture 2 G. Ramalingam Microsoft Research, India & K. V. Raghavan.
Pointer Analysis for Multithreaded Programs Radu Rugina and Martin Rinard M I T Laboratory for Computer Science.
Pointer Analysis – Part I CS Pointer Analysis Answers which pointers can point to which memory locations at run-time Central to many program optimization.
CHAPTER 51 LINKED LISTS. Introduction link list is a linear array collection of data elements called nodes, where the linear order is given by means of.
Pointer Analysis CS Alias Analysis  Aliases: two expressions that denote the same memory location.  Aliases are introduced by:  pointers  call-by-reference.
Chapter 2 : Graph Coverage (part 2)
Inter-procedural analysis
Pointer Analysis Lecture 2
Circular Buffers, Linked Lists
Dataflow analysis.
Pointer Analysis Lecture 2
Pointer analysis.
Pointer Analysis Jeff Da Silva Sept 20, 2004 CARG.
CSE P 501 – Compilers SSA Hal Perkins Autumn /31/2019
Pointer analysis John Rollinson & Kaiyuan Li
Presentation transcript:

Interprocedural pointer analysis for C We’ll look at Wilson & Lam PLDI 95, and focus on two problems solved by this paper: –how to represent pointer information in the presence of casts, pointer arithmetic, unions, and all the rest of C. –how to perform context-sensitive pointer analysis interprocedurally in a way that provides good precision at reasonable costs.

Representing pointer information for C Problem: –C types can be subverted by type casts: an int can in fact be a pointer. –Pointer arithmetic can lead to subobject boundaries being crossed. So, ignore the type system and subobject boundaries. Instead use a representation that decides what’s a pointer based on how it is used. Treat memory as composed of blocks of bits: –each local, global variable is a block –each malloc returns a block. Assume that casts and pointer arithmetic do not cross object boundaries.

Location sets Location set is a triple (block,offset,stride), which represents the set of locations: –{ offset + i £ stride | i 2 Ints} ExpressionLocation Set scalar(scalar,0,0) struct.F(struct,offs(F),0) array[i](array,0,elmtSize) array[i].F(array,offs(F),elmtSize) *(&p + X)(p,0,1) This representation distinguishes between different fields within a structure, but not the different elements of an array. FFF strideoffsetstride

Points-to graphs with locations sets Points-to graph at L3: struct Complex { real* r; real* i; } void f(int u,int v, Complex a[]) { L1: a[u].r := new real; L2: a[u].i := new real; p := a[v].r; L3:... }

Points-to graphs with locations sets Points-to graph at L3: (p,0,0) (a,offs(r), sizeof(Complex)) struct Complex { real* r; real* i; } void f(int u,int v, Complex a[]) { L1: a[u].r := new real; L2: a[u].i := new real; p := a[v].r; L3:... } (S1,0,0) (a,offs(i), sizeof(Complex)) (S2,0,0)

Interprocedural pointer analysis Context-insensitive –Smears effects of callers together. We can do better than that! Context-sensitive: total transfer function (bottom up approach) –Must summarize the effect of a procedure on all possible incoming alias patterns! –It can be difficult to actually generate all the possible alias patterns. –It can also be expensive to compute such summaries.

Wilson & Lam approach: PTFs Compute partial transfer functions (PTFs), instead of total transfer functions. A PTF for a procedure stores pairs (in,out) for those inputs in that have been seen during analysis.

f(p,q,r) { *p = *q; *q = *r; } PTF for f inout …… p*p**p q*q**q r*r**r p*p**p q*q**q r*r**r p *p**p q*q**q r p *p**p q*q**q r Examples of (in,out) pairs

f(p,q,r) { *p = *q; *q = *r; } PTF for f inout …… p*p**p q*q**q r*r**r p*p**p q*q**q r*r**r p *p**p q*q**q r p *p**p q*q**q r Examples of (in,out) pairs

Wilson & Lam algorithm The analysis is done top-down: –start from main() –when a function call to f is hit, see if the current context matches any of the (in,out) pairs in f’s summary. –If so, the info after the call is the out part of the pair (after appropriate renaming) –Otherwise, analyze f in the current context curr to get the result res after the call. Also, update the summary for f with the pair (curr, res)

Example f(p,q,r) { *p = *q; *q = *r; } main() { x := &a; y:= &b; z := &b; xp := &x; yp := &y; zp = &z; if (...) L1: f(&xp,&yp,&zp); else L2: f(&zp,&xp,&yp); }

callermapcallee in at L1 out at L1 PTF for f inout Call site L1

callermapcallee in at L1 out at L1 PTF for f inout Call site L2

p $ &xp q $ &yp r $ &zp *p $ xp **p $ x *q $ yp **p $ y *r $ zp **r $ z p*p**p q*q**q r*r**r xpx&xp ypy&yp zpz&zp p*p**p q*q**q r*r**r xpx&xp ypy&yp zpz&zp b a b a callermapcallee in at L1 out at L1 PTF for f inout p*p**p q*q**q r*r**r p*p**p q*q**q r*r**r Call site L1 Add to summary

callermapcallee in at L2 out at L2 PTF for f inout p*p**p q*q**q r*r**r p*p**p q*q**q r*r**r Call site L2 p $ &zp q $ &xp r $ &yp *p $ zp **p $ z … xpx&xp ypy&yp zpz&zp xpx&xp ypy&yp zpz&zp b a b a Use summary

Additional issues Want the (in,out) pair to be as reusable as possible: –compute the input context in on demand as the procedure is being analyzed How does one determine that the input context matches one of the (in,out) pairs of the PTF? How does one translate the information from the callee to the caller?

Comparison of PTF and total transfer fns Total transfer functions: –bottom up. –summaries are complete. –can discard a procedure once its summary has been computed. –Keep one strongly connected component in memory at a time, or use a worklist of functions. Partial transfer functions: –top down, demand driven. –may be less expensive, because summaries are computed only for those contexts that arise during analysis. –Keep the whole program in memory, or use a worklist of functions.

Wilson & Lam experimental results On benchmarks < 5,000 LOC: –at most 16 secs to run the analysis “These times do not include the overhead for reading the procedures from the input files, building flow graphs, and computing dominance frontiers. Neither do they include the time required to write the results to the SUIF output files” –average number of pairs in each PTF: 1.4 Used the pointer information to parallelize two benchmarks –speedups vary from 1.42 to 3.5 depending on the benchmark and the number of processors (2 or 4) How will analysis time scale with the number of fns? How useful is the pointer info for other opts?

Steensgaard: almost linear time points-to analysis Wilson & Lam algorithm doesn’t scale to millions of lines of code.

Cost: –space: store one fact at each prog point –time: iteration S1: l := new Cons p := l S2: t := new Cons *p := t p := t l p S1 l p tS2 l p S1 t S2 l t S1 p S2 l t S1 p S2 l t S1 p L2 l t S1 p S2 l t S1 p S2 l t S1 p S2 l t L1 p L2 l t S1 p S2 l t S1 p S2 Iter 1Iter 2Iter 3 Example revisited

New idea: store one dataflow fact Store one dataflow fact for the whole program Each statement updates this one dataflow fact –use the previous flow functions, but now they take the whole program dataflow fact, and return an updated version of it. Process each statement once, ignoring the order of the statements This is called a flow-insensitive analysis.

Flow insensitive pointer analysis S1: l := new Cons p := l S2: t := new Cons *p := t p := t

Flow insensitive pointer analysis S1: l := new Cons p := l S2: t := new Cons *p := t p := t l p S1 l p tS2 l p S1 t S2 l t S1 p S2

What went wrong?

What happened to the link between p and S1? –Can’t do strong updates anymore! –Need to remove all the kill sets from the flow functions. What happened to the self loop on S2? –We still have to iterate!

Flow insensitive pointer analysis: fixed S1: l := new Cons p := l S2: t := new Cons *p := t p := t l p S1 l p tS2 l p S1 t S2 l t S1 p S2 l t S1 p S2 l t S1 p L2 l t S1 p S2 l t S1 p S2 l t S1 p S2 l t L1 p L2 l t S1 p S2 Iter 1Iter 2Iter 3 l t S1 p S2 Final result This is Andersen’s algorithm ’94

Flow insensitive loss of precision Flow insensitive analysis leads to loss of precision! main() { x := &y;... x := &z; } Flow insensitive analysis tells us that x may point to z here! However: –uses less memory (memory can be a big bottleneck to running on large programs) –runs faster

Worst case complexity of Andersen *x = y x abc y def x abc y def Worst case: N 2 per statement, so at least N 3 for the whole program. Andersen is in fact O(N 3 )

New idea: one successor per node Make each node have only one successor. This is an invariant that we want to maintain. x a,b,c y d,e,f *x = y x a,b,c y d,e,f

x *x = y y More general case for *x = y

x *x = y yxyxy More general case for *x = y

x x = *y y Handling: x = *y

x x = *y yxyxy Handling: x = *y

x x = y y x = &y xy Handling: x = y (what about y = x?) Handling: x = &y

x x = y yxyxy x = &y xyx y,… xy Handling: x = y (what about y = x?) Handling: x = &y get the same for y = x

Our favorite example, once more! S1: l := new Cons p := l S2: t := new Cons *p := t p := t

Our favorite example, once more! S1: l := new Cons p := l S2: t := new Cons *p := t p := t l S1 t S2 p l S1 l p l t S2 p l S1,S2 tp l S1 t S2 p 4 5

bar() { i := &a; j := &b; foo(&i); foo(&j); // i pnts to what? *i :=...; } void foo(int* p) { printf(“%d”,*p); } Another example

bar() { i := &a; j := &b; foo(&i); foo(&j); // i pnts to what? *i :=...; } void foo(int* p) { printf(“%d”,*p); } i a j b p i a i a j b i a j b p i,j a,b p Another example 4 3

Steensgaard & beyond A well engineered implementation of Steensgaard ran on Word97 (2.1 MLOC) in 1 minute. One Level Flow (Das PLDI 00) is an extension to Steensgaard that gets more precision and runs in 2 minutes on Word97. CLA (Heintze and Tardieu PLDI 01) shows how to run Andersen in 1 second on 1 million lines of C code.