Incrementalized Pointer and Escape Analysis Martin Rinard MIT LCS.

Slides:



Advertisements
Similar presentations
Chapter 22 Implementing lists: linked implementations.
Advertisements

Garbage collection David Walker CS 320. Where are we? Last time: A survey of common garbage collection techniques –Manual memory management –Reference.
P3 / 2004 Register Allocation. Kostis Sagonas 2 Spring 2004 Outline What is register allocation Webs Interference Graphs Graph coloring Spilling Live-Range.
Introduction to Memory Management. 2 General Structure of Run-Time Memory.
1 Write Barrier Elision for Concurrent Garbage Collectors Martin T. Vechev Cambridge University David F. Bacon IBM T.J.Watson Research Center.
Context-Sensitive Interprocedural Points-to Analysis in the Presence of Function Pointers Presentation by Patrick Kaleem Justin.
Compilation 2011 Static Analysis Johnni Winther Michael I. Schwartzbach Aarhus University.
Pointer Analysis – Part I Mayur Naik Intel Research, Berkeley CS294 Lecture March 17, 2009.
Building a Better Backtrace: Techniques for Postmortem Program Analysis Ben Liblit & Alex Aiken.
Lecture 10: Heap Management CS 540 GMU Spring 2009.
Garbage Collection What is garbage and how can we deal with it?
Commutativity Analysis: A New Analysis Technique for Parallelizing Compilers Martin C. Rinard Pedro C. Diniz April 7 th, 2010 Youngjoon Jo.
CS 326 Programming Languages, Concepts and Implementation Instructor: Mircea Nicolescu Lecture 18.
Free-Me: A Static Analysis for Individual Object Reclamation Samuel Z. Guyer Tufts University Kathryn S. McKinley University of Texas at Austin Daniel.
Parameterized Object Sensitivity for Points-to Analysis for Java Presented By: - Anand Bahety Dan Bucatanschi.
Recap from last time We were trying to do Common Subexpression Elimination Compute expressions that are available at each program point.
Vertically Integrated Analysis and Transformation for Embedded Software John Regehr University of Utah.
Next Section: Pointer Analysis Outline: –What is pointer analysis –Intraprocedural pointer analysis –Interprocedural pointer analysis (Wilson & Lam) –Unification.
Interprocedural analyses and optimizations. Costs of procedure calls Up until now, we treated calls conservatively: –make the flow function for call nodes.
Previous finals up on the web page use them as practice problems look at them early.
Compositional Pointer and Escape Analysis for Java Programs Martin Rinard Laboratory for Computer Science MIT John Whaley IBM Tokyo Research Laboratory.
Run time vs. Compile time
1 Refinement-Based Context-Sensitive Points-To Analysis for Java Manu Sridharan, Rastislav Bodík UC Berkeley PLDI 2006.
An Adaptive, Region-based Allocator for Java Feng Qian & Laurie Hendren 2002.
Compile-Time Deallocation of Individual Objects Sigmund Cherem and Radu Rugina International Symposium on Memory Management June, 2006.
The environment of the computation Declarations introduce names that denote entities. At execution-time, entities are bound to values or to locations:
From last time: Inlining pros and cons Pros –eliminate overhead of call/return sequence –eliminate overhead of passing args & returning results –can optimize.
1 Run time vs. Compile time The compiler must generate code to handle issues that arise at run time Representation of various data types Procedure linkage.
Reps Horwitz and Sagiv 95 (RHS) Another approach to context-sensitive interprocedural analysis Express the problem as a graph reachability query Works.
Pointer analysis. Pointer Analysis Outline: –What is pointer analysis –Intraprocedural pointer analysis –Interprocedural pointer analysis Andersen and.
Memory Management for Real-Time Java Wes Beebee and Martin Rinard Laboratory for Computer Science Massachusetts Institute of Technology Supported by: DARPA.
Procedure Optimizations and Interprocedural Analysis Chapter 15, 19 Mooly Sagiv.
P ARALLEL P ROCESSING I NSTITUTE · F UDAN U NIVERSITY 1.
Analyses and Optimizations for Multithreaded Programs Martin Rinard, Alex Salcianu, Brian Demsky MIT Laboratory for Computer Science John Whaley IBM Tokyo.
PRESTO: Program Analyses and Software Tools Research Group, Ohio State University STATIC ANALYSES FOR JAVA IN THE PRESENCE OF DISTRIBUTED COMPONENTS AND.
PRESTO Research Group, Ohio State University Interprocedural Dataflow Analysis in the Presence of Large Libraries Atanas (Nasko) Rountev Scott Kagan Ohio.
An Adaptive, Region-based Allocator for Java Feng Qian, Laurie Hendren {fqian, Sable Research Group School of Computer Science McGill.
Lecture 10 : Introduction to Java Virtual Machine
Bug Localization with Machine Learning Techniques Wujie Zheng
Chapter 5: Programming Languages and Constructs by Ravi Sethi Activation Records Dolores Zage.
PRESTO: Program Analyses and Software Tools Research Group, Ohio State University Merging Equivalent Contexts for Scalable Heap-cloning-based Points-to.
Free-Me: A Static Analysis for Automatic Individual Object Reclamation Samuel Z. Guyer, Kathryn McKinley, Daniel Frampton Presented by: Dimitris Prountzos.
Synchronization Transformations for Parallel Computing Pedro Diniz and Martin Rinard Department of Computer Science University of California, Santa Barbara.
Runtime Environments. Support of Execution  Activation Tree  Control Stack  Scope  Binding of Names –Data object (values in storage) –Environment.
Component Composition for Embedded Systems Using Semantic Aspect-Oriented Programming Martin Rinard Laboratory for Computer Science Massachusetts Institute.
Finding Your Cronies: Static Analysis for Dynamic Object Colocation Samuel Z. Guyer Kathryn S. McKinley T H E U N I V E R S I T Y O F T E X A S A T A U.
OOPLs /FEN March 2004 Object-Oriented Languages1 Object-Oriented Languages - Design and Implementation Java: Behind the Scenes Finn E. Nordbjerg,
U NIVERSITY OF D ELAWARE C OMPUTER & I NFORMATION S CIENCES D EPARTMENT Optimizing Compilers CISC 673 Spring 2009 Overview of Compilers and JikesRVM John.
Incrementalized Pointer and Escape Analysis Frédéric Vivien ICPS/LSIIT Université Louis Pasteur Strasbourg, France Martin Rinard Laboratory for Computer.
PRESTO: Program Analyses and Software Tools Research Group, Ohio State University Merging Equivalent Contexts for Scalable Heap-cloning-based Points-to.
Pointer Analysis for Multithreaded Programs Radu Rugina and Martin Rinard M I T Laboratory for Computer Science.
Escape Analysis for Java Will von Rosenberg Noah Wallace.
Spring, 2011 –– Computational Thinking – Dennis Kafura – CS 2984 Data Structures Mapping complex structures to linear memory.
Design-Directed Programming Martin Rinard Daniel Jackson MIT Laboratory for Computer Science.
Pointer and Escape Analysis for (Multithreaded) Programs Martin Rinard MIT Laboratory for Computer Science.
Pointer and Escape Analysis for Multithreaded Programs Alexandru Salcianu Martin Rinard Laboratory for Computer Science Massachusetts Institute of Technology.
Pointer Analysis – Part I CS Pointer Analysis Answers which pointers can point to which memory locations at run-time Central to many program optimization.
D A C U C P Speculative Alias Analysis for Executable Code Manel Fernández and Roger Espasa Computer Architecture Department Universitat Politècnica de.
3/2/2016© Hal Perkins & UW CSES-1 CSE P 501 – Compilers Optimizing Transformations Hal Perkins Autumn 2009.
GC Assertions: Using the Garbage Collector To Check Heap Properties Samuel Z. Guyer Tufts University Edward Aftandilian Tufts University.
Runtime Environments Chapter 7. Support of Execution  Activation Tree  Control Stack  Scope  Binding of Names –Data object (values in storage) –Environment.
1 Compiler Construction (CS-636) Muhammad Bilal Bashir UIIT, Rawalpindi.
Abstract Interpretation and Future Program Analysis Problems Martin Rinard Alexandru Salcianu Laboratory for Computer Science Massachusetts Institute of.
Compositional Pointer and Escape Analysis for Java programs
Compositional Pointer and Escape Analysis for Java Programs
Martin Rinard Laboratory for Computer Science
Incrementalized Pointer and Escape Analysis
Radu Rugina and Martin Rinard Laboratory for Computer Science
Demand-Driven Context-Sensitive Alias Analysis for Java
자바 언어를 위한 정적 분석 (Static Analyses for Java) ‘99 한국정보과학회 가을학술발표회 튜토리얼
Presentation transcript:

Incrementalized Pointer and Escape Analysis Martin Rinard MIT LCS

Context Unsafe languages (C, C++, …) Safe languages (Java, ML, Scheme, …) Big difference: garbage collection Goal: analyze program to safely allocate objects on the call stack instead of in garbage- collected heap Advantages No dangling references No memory leaks Disadvantages Collection overhead Collection pauses

void compute(d,e) ———— void multiplyAdd(a,b,c) ————————— void multiply(m) ———— void add(u,v) —————— void main(i,j) ——————— void evaluate(i,j) —————— void abs(r) ———— void scale(n,m) —————— Program With Allocation Sites

void compute(d,e) ———— void multiplyAdd(a,b,c) ————————— void multiply(m) ———— void add(u,v) —————— void main(i,j) ——————— void evaluate(i,j) —————— void abs(r) ———— void scale(n,m) —————— Program With Allocation Sites When program runs

void compute(d,e) ———— void multiplyAdd(a,b,c) ————————— void multiply(m) ———— void add(u,v) —————— void main(i,j) ——————— void evaluate(i,j) —————— void abs(r) ———— void scale(n,m) —————— Program With Allocation Sites When program runs

void compute(d,e) ———— void multiplyAdd(a,b,c) ————————— void multiply(m) ———— void add(u,v) —————— void main(i,j) ——————— void evaluate(i,j) —————— void abs(r) ———— void scale(n,m) —————— Program With Allocation Sites When program runs It allocates objects in heap

void compute(d,e) ———— void multiplyAdd(a,b,c) ————————— void multiply(m) ———— void add(u,v) —————— void main(i,j) ——————— void evaluate(i,j) —————— void abs(r) ———— void scale(n,m) —————— Program With Allocation Sites When program runs It allocates objects in heap

void compute(d,e) ———— void multiplyAdd(a,b,c) ————————— void multiply(m) ———— void add(u,v) —————— void main(i,j) ——————— void evaluate(i,j) —————— void abs(r) ———— void scale(n,m) —————— Program With Allocation Sites When program runs It allocates objects in heap

void compute(d,e) ———— void multiplyAdd(a,b,c) ————————— void multiply(m) ———— void add(u,v) —————— void main(i,j) ——————— void evaluate(i,j) —————— void abs(r) ———— void scale(n,m) —————— Program With Allocation Sites When program runs It allocates objects in heap

void compute(d,e) ———— void multiplyAdd(a,b,c) ————————— void multiply(m) ———— void add(u,v) —————— void main(i,j) ——————— void evaluate(i,j) —————— void abs(r) ———— void scale(n,m) —————— Program With Allocation Sites When objects become unreachable

void compute(d,e) ———— void multiplyAdd(a,b,c) ————————— void multiply(m) ———— void add(u,v) —————— void main(i,j) ——————— void evaluate(i,j) —————— void abs(r) ———— void scale(n,m) —————— Program With Allocation Sites When objects become unreachable Garbage collector (eventually) reclaims memory

void compute(d,e) ———— void multiplyAdd(a,b,c) ————————— void multiply(m) ———— void add(u,v) —————— void main(i,j) ——————— void evaluate(i,j) —————— void abs(r) ———— void scale(n,m) —————— Stack Allocation Correlate lifetimes of objects with lifetimes of procedures

void compute(d,e) ———— void multiplyAdd(a,b,c) ————————— void multiply(m) ———— void add(u,v) —————— void main(i,j) ——————— void evaluate(i,j) —————— void abs(r) ———— void scale(n,m) —————— Stack Allocation Allocate object on activation record of procedure

void compute(d,e) ———— void multiplyAdd(a,b,c) ————————— void multiply(m) ———— void add(u,v) —————— void main(i,j) ——————— void evaluate(i,j) —————— void abs(r) ———— void scale(n,m) —————— Stack Allocation When procedure returns

void compute(d,e) ———— void multiplyAdd(a,b,c) ————————— void multiply(m) ———— void add(u,v) —————— void main(i,j) ——————— void evaluate(i,j) —————— void abs(r) ———— void scale(n,m) —————— Stack Allocation When procedure returns Object automatically deallocated

Problem How does compiler determine if it is safe to allocate objects on stack? Classic problem in program analysis Standard approach Analyze whole program Use information to find “captured” objects Allocate captured objects on stack

Stack Allocation Percentage of Memory Allocated on Stack barneswaterjlexdbraytracecompress Whole-Program Analysis

Normalized Execution Times barneswaterjlexdbraytracecompress Whole-Program Analysis Reference: execution time without optimization

Analysis Times barneswaterjlexdbraytracecompress Analysis Time (seconds) Whole-Program Analysis

void compute(d,e) ———— void multiplyAdd(a,b,c) ————————— void multiply(m) ———— void add(u,v) —————— void main(i,j) ——————— void evaluate(i,j) —————— void abs(r) ———— void scale(n,m) —————— Key Observation Number One: Most optimizations require only the analysis of a small part of program surrounding the object allocation site

void compute(d,e) ———— void multiplyAdd(a,b,c) ————————— void multiply(m) ———— void add(u,v) —————— void main(i,j) ——————— void evaluate(i,j) —————— void abs(r) ———— void scale(n,m) —————— Key Observation Number Two: Most of the optimization benefit comes from a small percentage of the allocation sites 99% of objects allocated at these two sites

Intuition for Better Analysis Locate important allocation sites Use demand-driven approach to analyze region surrounding site Somehow avoid sinking analysis resources into unprofitable sites void compute(d,e) ———— void multiplyAdd(a,b,c) ————————— void multiply(m) ———— void add(u,v) —————— void main(i,j) ——————— void evaluate(i,j) —————— void abs(r) ———— void scale(n,m) —————— 99% of objects allocated at these two sites

How we do it Develop an incremental, demand-driven analysis Use profiling to identify important allocation sites Monitor analysis results to estimate Chance of optimizing site Analysis cost of realizing optimization Use estimates to direct analysis to profitable sites Result Usually get almost all of the benefit of whole-program analysis But at a fraction of the analysis cost

What This Talk is About How we turned this intuition into an algorithm that usually 1)obtains almost all the benefit of the whole program analysis 2) analyzes a small fraction of program 3) consumes a small fraction of whole program analysis time

Basic Idea Incremental, demand-driven analysis Profiling identifies important allocation sites Monitor analysis results to estimate Chance of optimizing site Analysis cost of realizing optimization Estimates direct analysis to profitable sites

Structure of Talk Motivating Example Base whole program analysis (Whaley and Rinard, OOPSLA 99) Incrementalized analysis Analysis policy Experimental results

Example

Employee Database Example Traverse database, extract max salary Name Salary John Doe $45,000 Ben Bit $30,000 Jane Roe $55,000 Vector max salary = $55,000 highest paid = Jane Roe

Coding Max Computation (in Java) class EmployeeDatabase { Vector database = new Vector(); Employee highestPaid; void computeMax() { int max = 0; Enumeration enum = database.elements(); while (enum.hasMoreElements()) { Employee e = enum.nextElement(); if (max < e.salary()) { max = e.salary(); highestPaid = e; }

Coding Max Computation (in Java) class EmployeeDatabase { Vector database = new Vector(); Employee highestPaid; void computeMax() { int max = 0; Enumeration enum = database.elements(); while (enum.hasMoreElements()) { Employee e = enum.nextElement(); if (max < e.salary()) { max = e.salary(); highestPaid = e; } Would like to allocate enum object on stack, not on the heap

Whole Program Analysis

void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() —————— Bottom Up and Compositional Currently analyzed procedure Currently analyzed part of the program

void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() —————— Bottom Up and Compositional Currently analyzed procedure Currently analyzed part of the program

Base Analysis Basic Abstraction: Points-to Escape Graph Intraprocedural Analysis Flow sensitive abstract interpretation Produces points-to escape graph at each program point Interprocedural Analysis Bottom up and compositional Analyzes each procedure once to obtain a single parameterized analysis result Result is specialized for use at each call site

Points-to Graph in Example void computeMax() { int max = 0; Enumeration enum = database.elements(); while (enum.hasMoreElements()) { Employee e = enum.nextElement(); if (max < e.salary()) { max = e.salary(); highestPaid = e; } } vectorelementData [ ] this enum e database highestPaid

Edge Types Inside Edges: Represent references created in currently analyzed part of program Outside Edges: Represent references created outside currently analyzed part of program vectorelementData [ ] this enum e database highestPaid dashed = outside solid = inside

Node Types Inside Nodes: Represent objects created in currently analyzed part of program Outside Nodes: Parameter nodes – represent parameters Load nodes - represent objects accessed via pointers created outside analyzed part vectorelementData [ ] this enum e database highestPaid dashed = outside solid = inside

Escape Information Escaped nodes parameter nodes returned nodes nodes reachable from other escaped nodes Captured is the opposite of escaped vectorelementData [ ] this enum e database highestPaid green = escaped white = captured

Stack Allocation Optimization Examine graph from end of procedure If a node is captured in this graph Allocate corresponding objects on stack (may need to inline procedures to apply optimization) vectorelementData [ ] this enum e database highestPaid green = escaped white = captured Can allocate enum object on stack

Interprocedural Analysis void printStatistics(BufferedReader r) { EmployeeDatabase e = new EmployeeDatabase(r); e.computeMax(); System.out.println(“max salary = “ + e.highestPaid); }

Start with graph before call site void printStatistics(BufferedReader r) { EmployeeDatabase e = new EmployeeDatabase(r); e.computeMax(); System.out.println(“max salary = “ + e.highestPaid); } e graph before call site elementData [ ] database

Retrieve graph from end of callee void printStatistics(BufferedReader r) { EmployeeDatabase e = new EmployeeDatabase(r); e.computeMax(); System.out.println(“max salary = “ + e.highestPaid); } e graph before call site elementData [ ] database elementData [ ] this database highestPaid Enum object is not present because it was captured in the callee

Map formals to actuals void printStatistics(BufferedReader r) { EmployeeDatabase e = new EmployeeDatabase(r); e.computeMax(); System.out.println(“max salary = “ + e.highestPaid); } e graph before call site elementData [ ] database elementData [ ] this database highestPaid

Match corresponding inside and outside edges to complete mapping void printStatistics(BufferedReader r) { EmployeeDatabase e = new EmployeeDatabase(r); e.computeMax(); System.out.println(“max salary = “ + e.highestPaid); } e graph before call site elementData [ ] database elementData [ ] this database highestPaid

Match corresponding inside and outside edges to complete mapping void printStatistics(BufferedReader r) { EmployeeDatabase e = new EmployeeDatabase(r); e.computeMax(); System.out.println(“max salary = “ + e.highestPaid); } e graph before call site elementData [ ] database elementData [ ] this database highestPaid

Match corresponding inside and outside edges to complete mapping void printStatistics(BufferedReader r) { EmployeeDatabase e = new EmployeeDatabase(r); e.computeMax(); System.out.println(“max salary = “ + e.highestPaid); } e graph before call site elementData [ ] database elementData [ ] this database highestPaid

Match corresponding inside and outside edges to complete mapping void printStatistics(BufferedReader r) { EmployeeDatabase e = new EmployeeDatabase(r); e.computeMax(); System.out.println(“max salary = “ + e.highestPaid); } e graph before call site elementData [ ] database elementData [ ] this database highestPaid

Combine graphs to obtain new graph after call site void printStatistics(BufferedReader r) { EmployeeDatabase e = new EmployeeDatabase(r); e.computeMax(); System.out.println(“max salary = “ + e.highestPaid); } e graph before call site elementData [ ] database elementData [ ] this database highestPaid graph after call site e elementData [ ] highestPaid

Continue analysis after call site void printStatistics(BufferedReader r) { EmployeeDatabase e = new EmployeeDatabase(r); e.computeMax(); System.out.println(“max salary = “ + e.highestPaid); } e graph before call site elementData [ ] database graph after call site e elementData [ ] highestPaid

Whole Program Analysis void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() ——————

Whole Program Analysis void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() ——————

Whole Program Analysis void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() ——————

Whole Program Analysis void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() ——————

Whole Program Analysis void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() ——————

Whole Program Analysis void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() ——————

Whole Program Analysis void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() ——————

Whole Program Analysis void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() ——————

Incrementalized Analysis

Incrementalized Analysis Requirements Must be able to Analyze procedure independently of callers Whole-program analysis is compositional Already does this Skip analysis of invoked procedures But later incrementally integrate analysis results if desirable to do so

First Extension to Whole-Program Analysis Skip the analysis of invoked procedures Parameters are marked as escaping into skipped call site Assume analysis skips enum.nextElement() vector 1 this enum e database highestPaid Node 1 escapes into enum.nextElement()

First Extension Almost Works Can skip analysis of invoked procedures If allocation site is captured, great! If not, escape information tells you what procedures you should have analyzed… Should have analyzed enum.nextElement() vector 1 this enum e database highestPaid Node 1 escapes into enum.nextElement()

Second Extension to Base Algorithm Record enough information to undo skip and incorporate analysis into existing result Parameter mapping at call site Ordering information for call sites

void compute() { —————— foo(x,y); ——————— } Graph before call site Graph after call site Graph at end of procedure Graphs from Whole-Program Analysis Generated during analysis Used to apply stack allocation optimization

void compute() { —————— foo(x,y); ——————— } Graph before call site Graph after skipped call site Graph at end of procedure Graphs from Incrementalized Analysis Generated during analysis Used to apply stack allocation optimization

Incorporating Result from Skipped Call Site Naive approach: use mapping algorithm directly on graph from end of caller procedure Before incorporating result from skipped call site After incorporating result from skipped call site

Incorporating Result from Skipped Call Site Naive approach: use mapping algorithm directly on graph from end of caller procedure Graph from whole program analysis After incorporating result from skipped call site

Basic Problem and Solution Problem: additional edges in graph from end of method make result less precise Solution: augment abstraction For each call skipped call site, record Edges which were present in the graph before the call site Edges which were present after call site Use this information when incorporating results from skipped call sites

After Augmenting Abstraction Graph from whole program analysis After incorporating result from skipped call site

void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() —————— Incrementalized Analysis

void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() —————— Incrementalized Analysis Attempt to stack allocate Enumeration object from elements

void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() —————— Incrementalized Analysis Analyze elements (intraprocedurally)

void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() —————— Incrementalized Analysis Analyze elements (intraprocedurally)

void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() —————— Incrementalized Analysis Analyze elements (intraprocedurally) Escapes only into the caller

void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() —————— Incrementalized Analysis Analyze computeMax (intraprocedurally)

void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() —————— Incrementalized Analysis Analyze computeMax (intraprocedurally)

void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() —————— Incrementalized Analysis Analyze computeMax (intraprocedurally) Escapes to hasMoreElements nextElement

void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() —————— Incrementalized Analysis Analyze hasMoreElements and nextElement (intraprocedurally)

void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() —————— Incrementalized Analysis Incorporate Results

void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() —————— Incrementalized Analysis Enumeration object Captured in computeMax

void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() —————— Incrementalized Analysis Enumeration object Captured in computeMax Inline elements Stack allocate enumeration object

void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() —————— Incrementalized Analysis We skipped the analysis of some procedures

void computeMax() ———— Enumeration elements() ——— Vector elementData() ———— boolean hasMoreElements() —————— void printStatistics() ——————— Employee nextElement() —————— int salary() —————— Incrementalized Analysis We skipped the analysis of some procedures We ignored some other procedures

Result We can incrementally analyze Only what is needed For whatever allocation site we want And even temporarily suspend analysis part of the way through!

New Issue We can incrementally analyze Only what is needed For whatever allocation site we want And even temporarily suspend analysis part of the way through! But… Lots of analysis opportunities Not all opportunities are profitable Where to invest analysis resources? How much resources to invest?

Analysis Policy Formulate policy as solution to an investment problem Goal Maximize optimization payoff from invested analysis resources

Analysis Policy Implementation For each allocation site, estimate marginal return on invested analysis resources Loop Invest a unit of analysis resources (time) in site that offers best return Expand analyzed region surrounding site When unit expires, recompute marginal returns (best site may change)

Marginal Return Estimate N · P(d) C · T N = Number of objects allocated at the site P(d) = Probability of capturing the site, knowing we explored a region of call depth d C = Number of skipped call sites the allocation site escapes through T = Average time needed to analyze a call site

Marginal Return Estimate N · P(d) C · T As invest analysis resources explore larger regions around allocation sites get more information about sites marginal return estimates improve analysis makes better investment decisions!

Usage Scenarios Ahead of time compiler Give algorithm an analysis budget Algorithm spends budget Takes whatever optimizations it uncovered Dynamic compiler Algorithm acquires analysis budget as a percentage of run time Periodically spends budget, delivers additional optimizations Longer program runs, more optimizations

Experimental Results

Methodology Implemented analysis in MIT Flex System Obtained several benchmarks Scientific computations: barnes, water Our lexical analyzer: jlex Spec benchmarks: db, raytrace, compress

Analysis Times jdk 1.2

Allocation Sites Analyzed

Distribution of Allocated Objects

Analysis Time Payoff Stack allocated by incrementalized analysis Decided Stack allocated by whole-program analysis % of Objects Analysis Time (seconds) compressraytracedb Analysis Time (seconds) barneswaterjlex

Stack Allocation

Normalized Execution Times Reference: execution time without optimization

Experimental Summary Key Application Properties Most objects allocated at very few allocation sites Can capture objects with an incremental analysis of region surrounding allocation sites Consequence Most of the benefits of whole-program analysis Fraction of the cost of whole-program analysis

Other Analyses and Uses Whole-program pointer and escape analysis (OOPSLA 1999) Stack allocation Synchronization elimination Pointer and escape analysis for multithreaded programs (PLDI 1999, PPoPP 2001) Correct use of region-based allocation Elimination of dynamic region checks Synchronization elimination Memory bank disambiguation (RAW, DeepC) Foundation for other analyses Bitwidth analysis (MIT and CMU) Symbolic accessed region analysis

Other Analyses and Uses Symbolic analysis of accessed regions of memory blocks (PPoPP 1999, PLDI 2000) Automatic parallelization of sequential divide and conquer programs Data race freedom for parallel divide and conquer programs Absence of array bounds violations for both Bitwidth analysis

Future Directions Information from designers and developers Type systems for program properties Automatic parallelization and data race freedom for divide and conquer programs (CC 2001) Data race freedom for OO programs (OOPSLA 2001) Application-specific design properties Shapes of recursive data structures Object role transitions and constraints Distributed systems, component-based systems Interaction patterns Failure propagation properties Global view of system

Related Work Demand-driven Analyses Horwitz, Reps, Sagiv (FSE 1995) Duesterwald, Soffa, Gupta (TOPLAS 1997) Heintze, Tardieu (PLDI 2001) Key differences Integration of escape information enables incrementalized algorithms to suspend partially completed analyses Maintain accurate marginal payoff estimates Avoid overly costly analyses

Related Work Previous Escape Analyses Blanchet (OOPSLA 1999) Bogda, Hoelzle (OOPSLA 1999) Choi, Gupta, Serrano, Sreedhar, Midkiff (OOPSLA 1999) Whaley, Rinard (OOPSLA 1999) Ruf (PLDI 2000) Key Differences Previous algorithms analyze whole program But could incrementalize other analyses Get a range of algorithms with varying analysis time/precision tradeoffs

Conclusion Whole-Program Analysis Incrementalized Analysis Properties Uses escape information to incrementally analyze relevant regions of program Analysis policy driven by estimates of optimization benefits and costs Results Most of benefits of whole program analysis Fraction of the cost