

Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
An introduction to static pointer analysis, focusing on points-to analysis and the categorization of pointers. The document also discusses the concepts of flow sensitivity and context sensitivity, which impact the accuracy and speed of pointer analysis. From a university of illinois at urbana-champaign ece 497mf lecture, delivered by ian steiner on february 23, 2004.
Typology: Study notes
1 / 3
This page cannot be seen from the preview
Don't miss anything!


February 23rd, 2004 University of Illinois at Urbana-Champaign
This lecture will cover mostly static pointer analysis. First we will provide a general overview of how static (done in the compiler) pointer analysis is performed. Then we will take a look at flow and context sensitivity. Finally, we will take a short look at how all of this information is generally maintained inside of the compiler.
The general goal of pointer analysis is as follows:
We perform pointer analysis by doing Points-To Analysis. In order to perform this analysis, we first need to understand how we will be categorizing the different types of pointers. There are three differ- ent ways that we can categorize a pointer:
Lets make sure that everyone is on the same page by giving a short evample snip of code that has each of these types. In this example, g var is obviously a global variable type, m 1 and m 2 are malloc points, and s 1 and s 2 are static points.
int g_var;
typedef struct foo { int a; int b; float c; char[] d; } foo;
int bar () { foo *m_1 = malloc (sizeof foo); foo *m_2 = malloc (sizeof foo + 10); }
int baz (int s_1) { float s_2; goo (&s_2); }
When performing pointer analysis, there are a few decisions that need to be made that have tradeoffs between speed (algorithm runtime) and accuracy. Flow Sensitivity and Context Sensitivity are two examples of this. Today, we will just give examples and motivate what it means to be Flow and/or Context Sensitive. In the next lecture, we will cover adding these two the analysis.
In Flow Sensitive analysis, we consider of the control flow of proceedures when determining the possible points-to sets. The following snip of code should help to make this clear:
int *foo (int *p, int *q) { int *u; if (p == q) u = p; else u = q; return u; } In this example, if we can determine that p != q ahead of time, then we know that u b {q} and perform our analysis accordingly. However, in the flow insensitive case, we have to assume u b {p, q}.
With Context Sensitivity, we concern our- selves with how different functions are called, and perform pointer analysis ac- cordingly. Again, an example should help to motivate this idea. Assume we have the function from above for this example.
void bar() { int *a, *b, *c, *d; c = foo(a, b); d = foo(a, a); }
In the first call to foo in this example, we do not know whether a or b are equal, and a flow sensitive analysis of foo would result in c b {p, q}. However, in the second call, if we have context sensitivity (and flow sensitivity), we will know that d b {q}.
This section will cover how we go about performing pointer analysis that is both flow and context insensitive. This is not a very difficult algorithm, and can abstractly be interpretter as running the program, but the memory statements manipulate the abstract values (in this case the allocation points). With further ado... For each variable set points-to set to empty set
Travserse through program ‘‘generate’’ -- create new sets for all initial definitions Copy Statements -- merge sets w/ Union when copy statements are encountered Repeat until no change
It is relatively straightforward to store the pointer information in the compiler. Essentially, each generation point (see Points-to Analysis Section) is assigned a number. Then, as we proceed through the program, encountering copy statements, we update the sets associated with each variable. There are a couple of ways to go about doing this, each with different storage and runtime requirements. The first method, which is inaccurate but fast, always merges sets together. For example, if we have two different pointers, A and B, that each have different sets associated with one another, and A is then assigned to B, we merge the sets and say that both A and B can point to the union of the original two sets. This method is θ(n) in both size and space where n is the number of statements in the program. On the other side of the spectrum is an algorithm that only maintains sets a single direction. So, using the above example, only B’s set grows and A remains the same. This algorithm, although much more accurate,