Upload
bernard-hayden
View
222
Download
0
Embed Size (px)
Citation preview
Solving Shape-Analysis Problems with Languages with Destructive updating
By M. Sagiv et al.
Presentation by
Justin Bronn
Travis Pinney
Josh Bauman
Introduction
Addresses problems with pointer, alias, sharing, and storage analysis, and type-checking problems.
Storage analysis is emphasized.
Shape Analysis
Give a conservative, finite characterization of the possible “shapes” that a programs heap-allocated data structures can have at each program point
New Algorithm
Verifies shape-preservation properties of lists, trees, and certain programs that update circular lists.
Differences from Previous methods: Deliberately drops information about concrete locations. Run-time locations that are not pointed by variables are clustered in a single
summary node. Removes edges on the tail of lists. Sharing through variables: When two variables point to the same cons cell –
it is represented directly by shape-graph edges.
The is# (is shared) variable
Each SG# (Static-Shaped Graph) has a boolean value associated with it {false, true}. When true, it indicates the cons-cells represented
by n may be the target of pointers emanating from two or more distinct cons-cell fields.
is# Exercise
What is the is# value of this graph?
is# Exercise
What is the is# value of this graph?
is# Exercise
What is the is# value of this graph?
Example
Uses a program that performs a list reversal via destructive updating.
Invariant is something that does not change. In the program reverse(x,y) these always hold true
1. Variable x points to an unshared, acyclic, singly linked list.
2. Variable y points to an unshared, acyclic, singly linked list, and t may point to the second element of the y-list (if such an element exists).
3. The lists pointed to by x and y are disjoint
Iteration 1
Iteration 1 (Continued)
Iteration 2
Iteration 2 (Continued)
Iteration 3
Iteration 3 (Continued)
Iteration 4
Iteration 4 (Continued)
Tracking and Aliasing Functions
“t:=y” Tracking the aliasing of configurations using “names” attached to shape-nodes. Liquidization and Renaming Liquidizing, when a variable t no longer points to a cons-cell, we remove the t from the
name of n{t} This is done because the “name” of the shape-node goes into phi (falls into the primordial
soup) Renaming occurs when a statement is processed that can increase the amount of sharing in
a concrete store. Ex: “y := x” | n{t,y} -> n{t} | n{x} -> n{y,x} The use of sets of variables to name the nodes in SSGs can result in an exponential number
of shape-nodes. Techniques to sidestep this problem is discussed in the Optimization section (Section 2.2)
Node Materialization
When x := x.cdr occurs, the affect has been to “materialize” a new non-summary from n-phi. This materialization conservatively covers all possible configurations of the storage.
Cutting the List
“y.cdr := t” cuts the y list at the head, (produces the fifth SSG from the fourth SSG} The cdr edge of shape-node n{y} is first removed. This cuts the y list at the head,
seperating the first element n{y}, from the tail, which x points to. A cdr edge from n{y} to n{t} is then added, which concatenates shape-node n{y} at the
head of the list that t points to.
Normalization
Only one constructor or selector is applied per assignment statement A selector is something like x.car or x.cdr
An expression cons(x,y) is executed in three steps 1. An unitialized cons cell is allocated, and its address is assigned into a new temp variable 2. The car component of the temp is initialized with the value of x 3. The cdr component of temp is initialized with a value of y
All allocation statements must be in the form x := new, you can’t use x.sel := new !!! Each assignment statement, the same variable cannot occur on the left and right hand
side Each assignment of the form lhs:=rhs in which rhs ==/ nil is An assignment statement of the form temp := nil is placed at the end of the program for
each temporary variable introduced in the normalization.
Shape Graphs – Basic Terminology
Ev is defined as the graph’s set of variable edges: From the start to the first node. It is denoted [x,n] where x is a pointer variable (PVar) and n is a shape node.
Es is defined as the graph’s set of selector edges: Between nodes. It is denoted <s, sel, t> where s and t are the shape-nodes and sel is of the set {car, cdr}
When Ev(x) is overloaded, it represents
When Es(s, sel) is overloaded, it represents
In concrete semantics, the result of an execution sequence is a shape-graph that represents the state of heap-allocated storage in memory.
Concrete Semantic Operations
1. Variable Edge Null
2. Selector Edge Null
3. Variable Edge New
4. Variable Edge Variable Edge
5. Selector Edge Variable Edge
6. Variable Edge Selector Edge
Deterministic (DSG) vs. Nondeterministic Shape Graphs (SSG)
Deterministic Shape Graphs (DSG):
Deterministic (DSG) vs. Nondeterministic Shape Graphs (SSG)
Nondeterministic Shape Graph (SSG):
Concrete Semantics
Nonstandard in the following ways
1. The only parts of the store that the concrete semantics keeps track of are the pointer variables and the cons-cells of heap-allocated storage.
2. Rather than causing an “abnormal termination” of the program, dereferences of nil pointers and uninitialized pointers are treated as no-ops.
3. The concrete semantics does not interpret predicates, read statements, and assignment statements that do not perform manipulation
A small amount of abstraction is built in which may associate a control-flow-graph vertex with more concrete stores.
Abstract Semantics – Static Shape-Graphs(Definition 5.1.1)
A static shape-graph is a pair <SG#, is#> where: SG# = A Shape Graph is# = a function of type shape_nodes(SG#) {false, true} The class of static shape-graphs is denoted by
Join Operation ( ) (Definition 5.1.2)
(Just two Static Shape-Graphs)
Then, the Join Operation would be:
Abstract Semantics – The Abstraction Function (Definition 5.2.1)
Let SG# = <Ev, Es>, be a shape graph in DSG, and let l, l1, and l2, be shape-nodes.
Then:
π[Ev](l) is also written as π(l)
Yikes! (What this means is that π(l) list of all variables belonging to L)
Abstract Semantics – The Abstraction Function(Definition 5.2.1)
Beta Functions (Author Overloads β 6 times!)
Abstract Semantics – The Abstraction Function(Definition 5.2.1)
Beta Functions (continued)
Abstract Semantics – The Abstraction Function(Definition 5.2.1)
Finally, we get to the abstraction function:
What’s going on? He is pruning down the DSG SSG, and building up a naming scheme (via β functions). The abstraction function merges multiple DSG’s into one SSG
iis function (induced is-shared)
Checks whether a cons-cell l is the target of pointers emanating from two or more distinct cons-cell fields
Concretization
This function goes from an SSG to a set of DSGs (think of it as the ‘reverse’ of the abstraction function)
Examples (Abstract Semantics)
Abstract Interpretation
Figure 8
Concrete Predicates
Strong Nullification
When the algorithm processes a statement like x.sel := nil, it always removes the sel edges emanating from the shape nodes.
If-Then-Else
Merging of Two Lists
program mergesort(x, y)
// sort the lists x and y into foo
foo := nil
while x.cdr != nil and y.cdr != nil do
if x.car > y.car then
t := x
x := x.cdr
else
t := y
y := y.cdr
fi
t.cdr := foo
foo := t
od
Merging of Two Lists - normalized
program mergesort(x, y)
// sort the lists x and y into foo
foo := nil
while x.cdr != nil and y.cdr != nil do
t := nil
if x.car > y.car then
t := x
x := nil
x := t.cdr
else
t := x
x := nil
x := t.cdr
fi
t.cdr := nil
t.cdr := foo
foo := nil
foo := t
od
Inconsistencies
Does not give running times are program length Relevance to Current Times Published in January 1998 Seems to slow to be run on a whole program 2^2^|Pvar| for the number of shape nodes in
the worst case scenario. Believe that running a single SSG per vertex would be more practical. It is still very slow
Programs must be normalized to be analyzed
Extensions
Inaccuracy caused by by n-phi representing unrelated cons-cells, which is particulary a problem when is#(n-phi) = true.
Possible ways of dealing with this
1. Using two separate summary nodes: is#(n-phi) = false and is#(n-phi) = true
2. Using allocation-sites to identify shape-nodes: shape nodes have names like n_s,x, where s is an allocation site, and X is a set of program variables.
3. Using type information: having a unique n-phi for every declared data type
These extensions do not work in all cases though. One example when it will cause problems is…
Reducing the Number of Shape-Nodes
The number of shape-nodes is an SSG is bounded by 2^|PVar|. Reaches this limit is unlikely in practice, because of the main reason being that the number of possible aliasing configurations is normally small. (It his difficult to determine whether this is true, because the author never goes shows any results from running the analysis on programs. )
Widening can be used to eliminate the possibility of exponential blow-up.
Widening
The basic idea of widening is to use discard an arbitrary amount of
For various points in loops, we can widen an SSG into a less precise, but ussually more compact, SSG by merging shape-nodes
Ex. n_z_1 and n_z_2 into n_z_1 union n_z_2 combining all the variable and selector edges.
A weaker property that would enable widening would be
Narrowing
SSG can be narrowed to be more “precise” x.sel := nil
Refining Concrete Semantics
In Scheme, when a cons cell is no longer reachable, the interpreter incorporates garbage-collection to efficiently free the memory of the cons cell. The shape-analyis can benefit from this same idea when shape-nodes are no longer reachable by variables.
May Alias-Problem
The may-alias problem is a fundamental problem in optimizing compilers generating code for scalar, superscalar, and parallel architectures
Possible Enhancements
Current code works for a small lisp-like language, which conservatively approximates the possible shapes that the program can have.
Could not be used for a language such as C++ or C Becomes more complex when the SSG is non-deterministic, which will occur on any type
of control structure. eg. if-then-else May be able to used for Java because of its stronger typing, but the analysis would have to
be greatly extended Code can be run on different sections on a program, such as broken up into classes, or
subprograms. A linking mechanism would have to be created to be able to see how all the analyses for
each subpart can be used.
Insertion into a List
Listness and Circular Listness are preserved. In other words, when a list or a circular list goes through the shape-analysis algorithm, a list or circular list is still there at the end of the program.
The End
Happy Thanksgiving!!