Quick viewing(Text Mode)

Type-Based Alias Analysis Amer Diwan Stanford University

Type-Based Alias Analysis Amer Diwan Stanford University

University of Massachusetts Amherst ScholarWorks@UMass Amherst Department Faculty Publication Computer Science Series

1998 Type-Based Alias Analysis Amer Diwan

Kathryn S. McKinley University of Massachusetts - Amherst

J. Eliot B. Moss University of Massachusetts - Amherst

Follow this and additional works at: https://scholarworks.umass.edu/cs_faculty_pubs Part of the Computer Sciences Commons

Recommended Citation Diwan, Amer; McKinley, Kathryn S.; and Moss, J. Eliot B., "Type-Based Alias Analysis" (1998). Computer Science Department Faculty Publication Series. 18. Retrieved from https://scholarworks.umass.edu/cs_faculty_pubs/18

This Article is brought to you for free and open access by the Computer Science at ScholarWorks@UMass Amherst. It has been accepted for inclusion in Computer Science Department Faculty Publication Series by an authorized administrator of ScholarWorks@UMass Amherst. For more information, please contact [email protected]. Type-Based Alias Analysis Amer Diwan Kathryn S. McKinley J. Eliot B. Moss

Department of Computer Science Department of Computer Science Stanford University, Stanford, CA 94305 University of Massachusetts, Amherst, MA 01003-4610 (650) 723-4013

Abstract piler to reorder statements that do pointer accesses. This paper evaluates three alias analyses based on program- Despite its importance, few commercial or research com- ming language types. The first analysis uses type compati- pilers implement non-trivial alias analysis. Three reasons bility to determine aliases. The second extends the first by alias analysis is not implemented are: (1) Many alias anal- using additional high-level information such as field names. yses are prohibitively slow and thus impractical for produc- The third extends the second with a flow-insensitive analy- tion use. (2) The alias analyses in the literature require the sis. Although other researchers suggests using types to dis- entire program (or some representation of it), which inhibits ambiguate memory references, none evaluates its effective- separate compilation and compiling libraries. (3) Most alias ness. We perform both static and dynamic evaluations of analyses have been evaluated only statically, and thus we do type-based alias analyses for Modula-3, a statically-typed not know the effectiveness of these algorithms with respect to type-safe language. The static analysis reveals that type com- the optimizations that use them. To address these concerns, patibility alone yields a very imprecise alias analysis, but the this paper explores using fast alias analyses that rely on pro- other two analyses significantly improve alias precision. We gramming language types. While prior work [1, 6] mentions using type compatibility for alias analysis, none evaluates the use redundant load elimination (RLE) to demonstrate the ef- fectiveness of the three alias algorithms in terms of the oppor- idea or presents the details of an algorithm. tunities for optimization, the impact on simulated execution This paper describes and evaluates three fast alias analy- times, and to compute an upper bound on what a perfect alias ses based on programming language types. The first analy- analysis would yield. We show modest dynamic improve- sis (TypeDecl) uses type compatibility to determine aliases. ments for (RLE), and more surprisingly, that on average our The second (FieldTypeDecl) uses other high-level properties, alias analysis is within 2.5% of a perfect alias analysis with such as field names to improve on the first. The third (SM- respect to RLE on 8 Modula-3 programs. These results il- FieldTypeRefs) improves the second by incorporating a flow- lustrate that to explore thoroughly the effectiveness of alias insensitive pass to include the effects of variable assignments analyses, researchers need static, dynamic, and upper-bound and references. This pass is similar to Steensgaard’s algo- analysis. In addition, we show that for type-safe languages rithm [32]. like Modula-3 and Java, a fast and simple alias analysis may We statically evaluate our alias algorithms using the num- be sufficient for many applications. ber of alias pairs (the traditional method). We also evaluate TBAA based on its static and dynamic effects on an optimiza- 1 Introduction tion. In addition, we evaluate TBAA with respect to an upper bound on the same optimization. Each of the evaluation met- To exploit memory systems, multiple functional units, and rics reveals different strengths and weaknesses in our alias the multi-issue capabilities of modern uniprocessors, compil- algorithms, and we believe this range of metrics, and espe- ers must reorder instructions. For programs that use pointers, cially upper-bound analysis, is necessary to understand the the compiler’s alias analysis dramatically affects its ability to effectiveness of any alias analysis. reorder instructions, and ultimately performance. Alias anal- Our static evaluation reveals that the simplest type-based ysis disambiguates memory references, enabling the com- alias analysis is very imprecise, but that for our Modula-3

The authors can be reached electronically via Internet addresses di- benchmarks, the other two alias analyses significantly reduce g [email protected], fmckinley,moss @cs.umass.edu. This work the number of intraprocedural aliases of a reference to on av- was supported by the National Science Foundation under grants CCR- erage 3.4 references (ranging from .3 to 20.8). We find that 9211272 and CCR-9525767 and by gifts from Sun Microsystems Labora- TBAA is much less effective for interprocedural aliases. tories, Inc., Hewlett-Packard, and Digital Equipment. Kathryn S. McKinley is supported by an NSF CAREER Award CCR-9624209. Amer Diwan was We also evaluate TBAA by measuring the static and sim- also supported by the Air Force Materiel Command and ARPA award num- ulated run-time impact on an intraprocedural optimization ber: F30602-95-C-0098. that depends on alias analysis: redundant load elimination (RLE). RLE combines loop invariant code motion and com- mon subexpression elimination of memory references. TBAA In the ACM SIGPLAN Conference on Programming Language Design and RLE combine to improve simulated program performance and Implementation, June 1998, Montreal, Quebec, Canada, pp. 106– modestly, by an average of 4%, and up to 8% on a DEC Alpha 117. 3000-500 [12] for 8 Modula-3 benchmarks. We also compare TBAA to an upper bound that represents TYPE T = OBJECT f, g: T; END; the best any alias analysis algorithm could hope to do for RLE. S1 = T OBJECT ... END; This comparison shows that a perfect alias analysis could at S2 = T OBJECT ... END; most eliminate an average of 2.5% more heap loads. In addi- S3 = T OBJECT ... END; tion, we modify TBAA for incomplete programs and demon- VAR strate, using RLE, that it performs as well as it does on com- t: T; s: S1; TBAA plete programs. These results and ’s fast time complex- u: S2; ity suggest that TBAA is a practical and promising analysis for scalar optimization of type-safe programs. Figure 1: Type Hierarchy Example The remainder of this paper is organized as follows. Sec- tion 2 describes our type-based alias analysis algorithms. Section 3 presents our evaluation methodology, and uses it 2.2 TBAA Using Type Declarations to evaluate TBAA. Section 4 extends and evaluates TBAA for incomplete programs. Section 5 discusses related work in To use type declarations to disambiguate memory references, alias analysis. Section 6 concludes. we simply examine the declared type of an access path AP ,

and then assume the AP may reference any object with the 2 Type-Based Alias Analysis same declared type or subtype. We call this version of TBAA,

TypeDecl. More formally, given two AP s p and q, Type- This section describes type-based alias analyses (TBAA) in Decl(p, q) determines they may be aliases if and only if:

which the compiler has access to the entire program except

= for the standard libraries. TBAA assumes a type-safe pro- Subtypes (Type (p)) Subtypes (Type (q)) . gramming language such as Modula-3 [25] or Java [33] that Consider the example in Figure 1. Since S1 is a subtype of does not support arbitrary pointer type casting (this feature is T, objects of type T can reference objects of type S1. Thus,

supported in C and C++). We begin with our terminology,

=

and then discuss using type declarations, object field and ar- Subtypes (Type (t)) Subtypes (Type (s))

=

ray access semantics, and modifications to the set of possible Subtypes (Type (t)) Subtypes (Type (u))

= types via variable assignments to disambiguate memory ac- Subtypes (Type (s)) Subtypes (Type (u)) cesses. In other words, t and s may reference the same location, 2.1 Memory Reference Basics and t and u may reference the same location, but s and u may not reference the same location since they have different Table 1 lists the three kinds of memory references in Modula- types. Note that TypeDecl is not transitive.

3 programs, their names, and a short description. 1 AP Table 2: FieldTypeDecl (AP 1, 2) Algorithm

Table 1: Kinds of Memory References

AP AP AP Case AP 1 2 FieldTypeDecl ( 1, 2) Notation Name Description 1 p p true

p.f Qualify Access field f of object p 2 p.f q.g (f = g) FieldTypeDecl (p, q)

pˆ Dereference Dereference pointer p 3 p.f qˆ AddressTaken (p.f) p[i] Subscript Array p with subscript i TypeDecl (p.f, qˆ)

4 pˆ q[i] AddressTaken(q[i]) TypeDecl (pˆ, q[i]) We call a non-empty string of memory references, for exam- 5 p.f q[i] false

ple aˆ.b[i].c, an access path (AP ) [22]. Without loss of 6 p[i] q[j] FieldTypeDecl (p, q) generality, we assume that distinct object fields have different 7 p q TypeDecl (p, q) names. We also define: 2.3 Using Field Access Types

Type (p): Thestatictypeof AP p. We next improve the precision of TypeDecl using the type Subtypes (T): The set of subtypes of type T, declarations of fields and other high level information in the which includes T. program. We call this version of type-based alias analysis t.f

In Modula-3 and other type-safe languages, an object of type FieldTypeDecl. It distinguishes accesses such as and = t.g f g

T can legally access objects of type Subtypes (T). Each of , , that TypeDecl misses. The FieldTypeDecl al- AP gorithm appears in Table 2. Given AP 1 and 2, it returns

our alias analyses refines the type of objects to which an AP AP true if AP 1 and 2 may be aliases. It uses AddressTaken,

(memory reference) may refer. If two AP s may have the same type, then the analyses determines they may access the which returns true if the program ever takes the address of p.f same location. its argument. For example, AddressTaken ( ) is true if the program takes the address of field f of an object in the

1 These types of memory references are, of course, not unique to Modula- set TypeDecl (p). AddressTaken (q[i]) returns true if the 3. program takes the address of some element of an array of q’s 2 type. In Modula-3, programs may take the addresses of mem- (* Step 1: put each type in its own set *)

ory locations in only two ways: via the pass-by-reference for all pointer types T do gg parameter passing mechanism, and via the WITH statement, Group := Group + ffT which creates a temporary name for an expression. For sim- plicity we assume that aggregate accesses, such as assign- (* Step 2: merge sets because of assignments *) ments between two records, have been broken down into ac- for all implicit and explicit pointer assignments, a:=b, do

cesses of each component. Ta := Type (a); Tb := Type (b); =

The seven cases in Table 2 determine the following. if Ta Tb then

let Ga, Gb Group, such that Ta Ga, Tb Gb

f g f g f g 1: Identical AP s always alias each other. Group := Group - Ga - Gb + Ga Gb 2: Two qualified expressions may be aliases if they access the same field in potentially the same object. (* Step 3: Construct TypeRefsTable *) t

3-4: A pointer dereference may reference the same location for all types do g t g as a qualified or subscripted expression only if their let Group,

t g t types are compatible and the program may take the ad- TypeRefsTable ( ) = Subtypes ( ) dress of the qualified or subscripted expression. Figure 2: Selective Type Merging 5: In Modula-3, a subscripted expression cannot alias a qualified expression. 6: Two subscripted expressions are aliases if they may sub- type T (directly or indirectly), then t and s cannot possibly script the same array. FieldTypeDecl ignores the actual be aliases. Notice that if there is any such assignment, SM-

subscripts. AP TypeRefs assumes that AP s of type T may be aliased to s 7: For all other cases of AP s, including two pointer deref- of type S1. We call these assignments merges. erences, FieldTypeDecl uses TypeDecl to determine Figure 2 presents the algorithm to selectively merge

aliases. types.2 This algorithm produces a TypeRefsTable which takes a declared type T as an argument and returns all the Java programs would have similar rules. For C++ pro-

types potentially referenced by an AP declared to be of type grams, the rules must be more conservative to handle arbi-

T. Given two AP p and q, SMTypeRefs (p,q) determines trary pointer casts and pointer arithmetic. they may be aliases if and only if: 2.4 Using Assignment TypeRefsTable (Type (p))

TypeDecl is conservative in the sense that it assumes that the

= TypeRefsTable (Type (q))

program uses types in their full generality. For instance, pro-

S fT T g k grams often use list packages that support linking objects of In Figure 2, each set = 1 in Group represents

different types to link objects of only one type. We thus im- an equivalence class of types such that an AP with a declared

T S T S

prove on TypeDecl by examining the effects of explicit and type may reference any objects of type i . For

= f g AP implicit assignments to determine more accurately the types example, given the set S T1,T2 Group, s with declared type T1 may reference any object of type T1 or T2. of objects an AP may reference in a flow-insensitive manner. We call this algorithm SMTypeRefs (Selectively Merge Type Step 1 initializes Group, such that each declared type is References). Unlike TypeDecl, which always merges the de- in an independent set and an AP declared with type T is thus assumed to reference only objects of type T. Step 2 exam- clared type of an AP with all of its subtypes, SMTypeRefs

only merges a type with a subtype when a statement assigns ines all the assignment statements and merges the type sets 3 some reference of subtype S to a reference of type T. As an if the types of the left and right hand sides are different. example, consider applying TypeDecl to the following pro- Step 2 does not consider the order of the instructions and is gram given the type hierarchy in Figure 1: therefore flow insensitive. Step 3 then filters out infeasible

aliases from Group, creating asymmetry in the SMTypeRefs 4

VAR relationship. For instance, an AP with declared type T in t: T := NEW (T); Figure 1 may reference objects of type T or type S1, but an s: S1 := NEW (S1);

AP declared as S1 may not reference objects of type T. The final result of Step 3 is the TypeRefsTable. Since TypeDecl only considers declared types, it assumes Figure 3 uses the the type declarations in Figure 1 to il- that t and s may reference the same location because it is lustrate how the selective merging algorithm works. The semantically correct for objects of type T to reference objects of type S1. By inspecting the code however, it is obvious 2 A more precise but slower formulation maintains a separate group for that t and s never reference the same location since there is each type. In our experiments, the difference between the two variations was

insignificant. no explicit or implicit assignment between the two. SMType- 3 Step 2 is similar to Steensgaard’s algorithm [32].

Refs proves independence in this situation as follows: if the 4 If we took Steensgaard’s algorithm [32] and applied it to user defined program never assigns an object of type S1 to a reference of types, it would not discover this asymmetry. 3 VAR portional to the number of types in the program. The time to s1: S1 := NEW (S1); s2: S2 := NEW (S2); use the results of the TBAA may, of course, be more than lin-

s3: S3 := NEW (S3); ear time. For instance, computing all the may-alias pairs us-

2

) ( t: T; ing TBAA (or any other points-to analysis) takes O e time, BEGIN

where e is the numberof memory expressions in the program. t := s1; (* Statement 1 *) t := s2; (* Statement 2 *) END; 3 Evaluation This section evaluates type-based alias analysis using static Figure 3: Example to Illustrate SMTypeRefs and dynamic metrics, and a limit analysis. We first review the

(a) Initialized sets in Group (b) Sets after statement 1 (c) Sets after statement 2 strengths and weaknesses of static and dynamic metrics, and thus motivate our limit analysis.

T T S1 TS1 S2 Static Evaluation. The majority of previous work on alias analysis [2, 4, 6, 7, 9, 15, 20, 21, 22, 30, 32, 35] mea- sures static properties, such as the sizes of the may alias and S1 S2 S3 points-to sets. Static properties enable comparisons between the precision of two alias analyses using the size of their static S2 S3 points-to sets; the smaller the set the more precise the analy- sis. Static properties have, however, two main disadvantages. (1) Static properties cannot tell us if the analysis is effective S3 with respect to its clients. For example, even if the alias sets Figure 4: Selective Merging for Figure 3 are small, the analysis may not differentiate the pointers that will enable optimizations to improve performance or increase the effectiveness of other analyses. (2) Static properties do VAR declarations declare and initialize variables to newly al- not enable comparisons between the effectiveness of two alias located objects of their declared types. Step 1 thus initial- analyses with different strengths and weaknesses. For exam- izes each declared type in a set of its own, as shown in Fig- ple, the size of the points-to sets of two analyses may be the ure 4(a) where each oval represents a set in Group. Fig- same, but the analyses may disambiguate different pointers. ure 4(b) shows Group after Step 2 merges types T and S1, A static analysis that compares the resulting number of opti- the types for the first assignment; and Figure 4(c) shows that mization opportunities remedies some of this problem. the second assignment causes Step 2 to merge S2 with T and Dynamic Evaluation. A few researchers recently eval- S1. S3 remains in a set by itself. Step 3 of the merge algo- uated alias analyses by measuring the execution-time im- rithm then creates asymmetry for the subtype declarations in provement due to an optimization that uses alias analysis the TypeRefsTable, as shown in Table 3. Notice SMTypeRefs [19, 36, 8, 17]. Using run-time improvements complements static metrics, since run-time improvements directly measure determines AP s declared to be of type T may not reference objects of type S3, but TypeDecl must assume they may. the impact of the alias analysis on its clients (usually com- piler optimizations). However, one of their disadvantages is Table 3: TypeRefsTable for Figure 3 that the results are specific to the given program inputs. Limit Evaluation. Both static and dynamic evaluation Type TypeRefsTable (Type) have an additional significant shortcoming: these properties T T, S1, S2 do not tell us how much room for improvement there is in S1 S1 the alias analysis (except in the unusual case of an alias anal- S2 S2 ysis that disambiguates all memory references). We would S3 S3 like to know if the aliases really exist at run-time, and if any imprecision in the alias analysis causes missed opportunities for optimizations or other clients of the analysis. To detect We obtain the final version of our TBAA algorithm SMField- TypeRefs (Fields+Selectively Merge Type References) by us- imprecision and its impact, we also use a run-time limit anal- ing SMTypeRefs for TypeDecl in the FieldTypeDecl algo- ysis to determine missed optimization opportunities and their rithm in Table 2. causes for a given program input. No previous work on alias analysis uses this metric. 2.5 Complexity The remainder of this section is organized as follows. Sec- The complexity of this type-based alias analysis (TBAA) is tions 3.1 and 3.2 describe our experimental framework and dominated by step 2 of SMTypeRefs. This step makes a sin- benchmark programs. Section 3.3 presents the static alias gle linear pass through the program and at each pointer as- pairs for our analyses. Section 3.4 presents the simulated

signment unions two sets of types. The complexity of TBAA run-time improvements due to our alias analysis for redun-

(n) n is thus O bit-vector steps, where is the number of in- dant load elimination. Section 3.5 evaluates the room for im- structions in the program. Each bit-vector step takes time pro- provement in our analysis. 4 Table 4: Description of Benchmark Programs

Name Lines Instructions % Heap loads % Other loads Description format [23] 395 1,879,195 10 17 Text formatter dformat [23] 602 1,442,541 9 19 Text formatter write-pickle 654 1,614,437 13 16 Reads and writes an AST k-tree[3] 726 50,297,517 10 21 Manages sequences using trees slisp 1,645 11,462,791 27 9 Small lisp interpreter pp 2,328 45,779,402 11 19 Pretty printer for Modula-3 programs dom [24] 6,186 System for building distributed applications postcard 8,214 Graphical mail reader m2tom3 10,574 50,894,990 8 28 Converts Modula-2 code to Modula-3 m3cg 16,475 5,636,004 8 21 M3 v. 3.5.1 code generator + extensions

3.3 Static Evaluation Whole Program TBAA Optimizer Table 5 evaluates the relative importance of the three : Front end Back end TypeDecl: TBAA using only type declarations; FieldType- adapter adapter Decl: TBAA using TypeDecl and field declarations; and SM- FieldTypeRefs: TBAA using FieldTypeDecl and assignment

M3 Front End Saved IR GCC Back End Object code statements. The References column gives the total number of heap memory references in the source of the benchmark pro- grams. For each of the analyses, the table contains the num- ber of local (L Alias) and global (G Alias) alias pairs. Local Figure 5: Compilation Framework alias pairs are heap memory references within the same pro- cedure that may alias each other, and global alias pairs are heap memory references not necessarily within the same pro- cedure that may alias each other. Since each memory refer- 3.1 Environment ence trivially aliases itself, we exclude this pair. Note that Figure 5 illustrates our compilation framework. The front since SMFieldTypeRefs is strictly more powerful than Field- end reads a Modula-3 module and generates a file contain- TypeDecl, and FieldTypeDecl is strictly more powerful than ing a typed abstract syntax tree (AST) for the compiled mod- TypeDecl, we can use static metrics to compare the three. ule. The whole program optimizer (WPO) reads in the ASTs From the table, we see that TypeDecl performs a lot worse for a collection of modules, analyzes and transforms them, than FieldTypeDecl, and that flow-insensitive merging us- and then it writes out the modified AST for each module and ing SMFieldTypeRefs offers little improvement over Field- a file with the corresponding low-level stack machine code. TypeDecl. SMFieldTypeRefs improves local and global alias The stack representation is the input language for a back end pairs on postcard, and the number of global aliases for based on GCC. WPO implements all optimizations and analy- m3cg. On average, each heap reference may alias 4.7 other ses presented in this paper. intraprocedural references using TypeDecl, 3.4 references us- ing FieldTypeDecl, and 3.4 references using SMFieldType- 3.2 Benchmarks Refs. The range is from 0.3 to 20.8 references for SMField- TypeRefs. On average, each heap reference may alias 54.1 For each benchmark in our suite, Table 4 gives the num- other interprocedural references using TypeDecl, 12.7 refer- ber of non-comment, non-blank lines of code. For the non- ences using FieldTypeDecl, and 12.7 references using SM- interactive programs, Table 4 also gives the number of in- FieldTypeRefs. The range is from 2 to 27.7 references for structions executed, the percent of instructions that are mem- SMFieldTypeRefs. The number of interprocedural aliases is ory loads from the heap, and the percent of instructions that much higher than the number of intraprocedural aliases, sug- are memory loads from the stack and global area (other). gesting that TBAA is probably too imprecise for interproce- None of these programs were written to be benchmarks, dural optimizations. In the next two sections, we show that but other researchers have used several of them in previous even though our analysis does not disambiguate all intrapro- studies [16, 10]. Table 4 contains the data for the origi- cedural memory references (i.e., the local aliases are greater nal programs (i.e., without the optimizations proposed here) than zero), it may be precise enough for some applications. but with GCC’s standard optimizations turned on, which in- clude register allocation and instruction scheduling (except 3.4 Optimization Results for m2tom3). Duetoa compilerbugin GCC, we were unable This section measures the static and simulated execution-time to perform the standard optimizations on m2tom3, which ex- impact of TBAA on redundant load elimination (RLE). We plains its unusually large number of other loads. The num- first describe our implementation of RLE, and then show its bers in Table 4 do not include instructions or memory refer- impact on execution time. Section 3.5 then describes a limit ences from the standard libraries. analysis that demonstrates that with respect to RLE, there is 5 Table 5: Alias Pairs

TypeDecl FieldTypeDecl SMFieldTypeRefs Program References L Alias G Alias L Alias G Alias L Alias G Alias format 75 221 450 133 206 133 206 dformat 156 554 2665 293 1286 293 1286 write-pickle 171 383 2089 235 507 235 507 slisp 230 122 2322 74 464 74 464 pp 444 1626 10830 719 3811 719 3811 k-tree 612 2731 24344 1328 9655 1328 9655 dom 800 932 29550 589 21802 589 21802 m2tom3 904 19036 47856 18824 25048 18826 25048 postcard 1038 4208 30890 1623 5278 1615 5262 m3cg 4515 16521 1409449 6154 121476 6153 120525

is available on every path to s. RLE therefore improves per- 0 t := a.b^ formance by enabling the replacement of costly memory ref- erences with fast register references. Since RLE operates on 1 1 memory references its effectiveness depends directly on the quality of the alias information (and also on the back end). To 2 3 2 3 enable RLE across calls, RLE is preceded by a mod-ref analy- ... := a.b^[i] ... := a.b^[j] ... := t[i] ... := t[j] sis which summarizes the access paths that are referenced and

4 4 modified by each call. For example, in order to hoist a mem- ory reference out of a loop containing a call, TBAA needs to know whether the call changes the value of the memory reference. Note that even though RLE uses interprocedural Figure 6: Eliminating Loop Invariant Memory Loads mod-ref information, it does not eliminate redundant loads across procedure boundaries. 1 1 3.4.2 Impactof TBAA on RLE

2 3 2 3 Table 6 gives the number of access paths that RLE removes t := a.b^ t := a.b^ ... := a.b^[i] ... := a.b^[j] ... := t[i] ... := t[j] statically in each of our benchmark programs for each variant of TBAA: TypeDecl, FieldTypeDecl, and SMFieldTypeRefs, 4 4 ... := a.b^[j] ... := t[j] By comparing Table 6 and Table 5, we see that the differ- Figure 7: Eliminating Redundant Memory Loads ences between the number of local alias pairs is the strongest indicator of optimization opportunities for RLE. In partic- ular, the big differences between the number of alias pairs for TypeDecl and FieldTypeDecl result in an increase in the little or no room for improvement in TBAA. number of redundant loads found by RLE. In contrast, the 3.4.1 Redundant Load Elimination reductions in the number of alias pairs between FieldType- Decl and SMFieldTypeRefs does not change the number of Redundant load elimination (RLE) combines variants of loop redundant loads found by RLE. (These reductions are how- invariant code motion (similar to register promotion [8]) and ever smaller than the others.) common subexpression elimination [1], which most optimiz- ing compilers perform. RLE differs from classic loop invari- Table 6: Number of Redundant Loads Removed Statically ant code motion and common subexpression elimination in that it eliminates redundant loads instead of redundant com- Program TypeDecl FieldTypeDecl SMFieldTypeRefs putation. We expect RLE to be a profitable optimization since format 27 29 29 loads are expensive on modern machines and architects ex- dformat 10 22 22 write-pickle 46 47 47 pect they will only get more expensive [18]. k-tree 221 228 228 RLE hoists memory references out of loops if the reference m2tom3 369 396 396 is loop invariant and is executed on every iteration of the loop, slisp 36 37 37 leaving it up to the back end to place the hoisted memory ref- m3cg 524 613 613 erence in a register. For example in Figure 6, the access path a.bˆ is redundant on all paths, and loop invariant code mo- We also measured execution times using a detailed (and tion moves it into the loop header. As shown in Figure 7, validated [5]) simulator for an Alpha 21064 workstation with RLE also replaces redundant memory expressions by simple one difference: rather than simulating an 8K primary cache variable references, which the back end may place in a reg- we simulated a 32K primary cache to eliminate variations due ister. A memory expression at statement s is redundant if it to conflict misses that we observed in an 8K direct mapped 6 Base Types only Types and fields Types, fields, and merges Redundant originally Redundant after optimizations 100 100 100 100 100 100 100 0.60 99 99 99 98 98 98 98 100 98 97 97 98 98 96 97 97 0.56 95 94 94 92 92 92 90 0.50

80

0.40 70 0.34 0.32 60 0.30

50 0.22 0.21 40 0.20

Fraction of original heap references 0.16 0.14

Percent of original running time 30 0.10 0.08 0.06 20 0.05 0.05 0.05 0.04 0.03 0.01 0.02 10 0.00 format dformat slisp pp ktree m3cg m2tom3 write-pickle

0 Format Dformat Write-Pickle K-Tree M2toM3 Slisp M3CG Figure 9: Comparing TBAA to an Upper Bound

Figure 8: Impact of RLE

Encapsulated Conditional Breakup Rest

0.60 cache. Also, we only measured the execution time spent in user code since that is the only code that we were able to 0.50 analyze. Execution times are normalized with respect to the execution time of the original program without RLE, but with 0.40 all of GCC’s optimizations. (GCC eliminates redundant loads without any assignments to memory between them.) 0.30 Figure 8 illustrates the simulated execution time impact of 0.20

TBAA on RLE relative to the original execution time. The Fraction of original heap references graph has three bars for each non-interactive benchmark. 0.10 Each bar represents the execution time due to RLE and a dif- ferent alias analysis: TypeDecl (types only), FieldTypeDecl 0.00 (types and fields), and SMFieldTypeRefs (types, fields, and format dformat slisp pp ktree m3cg m2tom3 write-pickle merges). Figure 10: Source of Redundant Loads after Optimizations TBAA enables RLE to improve program performance from 1% to 8%, and on average 4%. Since RLE is just one of many optimizations that benefits from alias analysis, the full impact of alias analysis on execution time should be higher. Also, these loads using ATOM[31], a binary rewriting tool for the contrary to what the data in Table 5 and Table 6 suggest, the Alpha. We instrument every load in an executable, record- three variants of TBAA have roughly the same performance as ing its address and value. If the most recent previous load far as RLE is concerned. These results make two important of an address is redundant with the current load, we mark it points. First, a more precise alias analyses is not necessar- as redundant. (Elsewhere we describe this process in more ily better; it all depends on how the alias analysis is used. detail [13].) In Figure 9, the black bars give the fraction of Second, static metrics, such as alias pairs are insufficient by heap references that are redundant in the original program. themselves for evaluating alias analyses. The white bars give the fraction of heap references that are redundant after TBAA and RLE (this fraction is with respect 3.5 Comparing TBAA to an Upper Bound to the original number of heap references). These results are How much precision does TBAA lose in order to achieve its specific to program inputs. fast time bound? It is easy to contrive examples where TBAA Figure 9 shows that our optimizations eliminate between fails to disambiguate memory references while many other 37% and 87% of the redundant loads in these programs. alias analyses succeed. This section demonstrates, using a Moreover, for 6 of the 8 benchmark programs, only 5% limit study, that for RLE and our benchmark programs, there or fewer of the remaining loads are redundant. However, is little to be gained from an alias analysis that is more precise slisp and ktree still have many redundant loads. To un- than TBAA. derstand the source of all the remaining redundant loads, we Figure 9 compares heap loads that are redundant at run manually classified them as follows: time before and after applying RLE. A redundant load is when two consecutive loads of the same address load the 1. Encapsulation: RLE could not eliminate a redundant same value in the same procedure activation. We measure expression because it was implicit in our high-level 7 (AST) intermediate representation. For example, the The second metric, run-time improvement, indicates the subscript expression for an open array involves an im- how much an optimization or analysis really matters to the plicit memory reference to the dope vector. bottom line: performance. Our experiments find that the ma- 2. Conditional: RLE did not eliminate a redundant expres- jority of the run-time improvement comes from TypeDecl. sion because it was only partially redundant, i.e., redun- FieldTypeDecl improves performance only slightly. The re- dant along some paths but not along others. Partial re- sults also illustrate that the run-time improvement due to our dundancy elimination would catch these. analysis and optimization is relatively small: on average 4% improvement. If run-time improvement is the only metric 3. Breakup: RLE did not eliminate a redundant expression because it consisted of multiple smaller expressions and we use, then we might conclude that TBAA is a very impre- our optimizer does not do copy propagation. cise alias analysis. However, upper-bound analysis reveals that TBAA in fact performs about as well as any alias anal- 4. Alias failure: TBAA did not disambiguate two memory ysis could perform with respect to RLE and our benchmarks references. programs. 5. Rest: we don’t know the reason why RLE did not elimi- The third metric, number of opportunities exposed by nate the redundant loads since we did not determine the TBAA for RLE, reveals that FieldTypeDecl enables many reason for the entire list of redundant expressions (which more opportunities for RLE than TypeDecl. However, our is labor intensive). run-time measurements find that FieldTypeDecl is only slightly better than TypeDecl. If we had used only run-time The first category is due to a limitation of representation, improvements to evaluate our analysis we might conclude not TBAA or RLE. Categories 2 and 3 are limitations in our that TypeDecl is the algorithm of choice. However, the num- implementation of RLE, rather than TBAA. The fourth cate- ber of opportunities metric tells us that FieldTypeDecl is in- gory, alias failure, corresponds to limitations of TBAA. The deed significantly better than TypeDecl. Perhaps with differ- fifth category may be a limitation of RLE or TBAA or the rep- ent benchmark inputs FieldTypeDecl may improve perfor- resentation. Each bar in Figure 10 breaks down the Redun- mance significantly more than TypeDecl. dant after Optimizations bar from Figure 9 into the above five Finally, the upper-bound analysis for RLE using TBAA re- categories. veals that a more precise alias analysis for RLE would yield Figure 10 illustrates that Encapsulation (dope vector ac- few benefits: there is little or no room for improvement in cesses to index open arrays) is the most significant source of TBAA with respect to RLE. the remaining redundant loads. Figure 10 also shows that we To summarize, the four metrics tell us different informa- did not encounter a single situation when optimization failed tion about the different levels of TBAA. For this reason, we due to inadequacies in our alias analysis. Those redundant feel that all of these metrics should be used together in a thor- loads that could be due to failed analysis are categorized as ough evaluation of an alias analysis (or for that matter any Rest, and on average, are less than 2.5% of the remaining compiler analysis). loads. Thus, for RLE on these programs and their inputs, there is not much room for improvement in our simple and 3.7 Cumulative Results fast alias analysis. Figure 11 shows the cumulative impact of two sets of op- 3.6 Summary of Results timizations: method invocation resolution [14] plus inlin- This section evaluated TBAA using four different metrics: ing (Minv + Inlining) and RLE. Method resolution uses TBAA (and other analyses) to help resolve method invoca-

Number of static alias pairs. tions on object fields and array elements. While we expected

Run-time improvement due to an optimization that uses method resolution and inlining to expose more opportunities TBAA (RLE). for RLE, they did not. On studying the interactions of RLE with method invocations and inlining using limit analysis, we Number of opportunities exposed by TBAA for RLE. found that inlining exposes more redundant expressions but

An upper-bound for TBAA with respect to RLE. they are usually conditional (Section 3.5). Thus, while partial Each of these four metrics exposes different information redundancy elimination can eliminate these redundant loads, about TBAA. The first metric, number of static alias pairs, RLE cannot. We plan to implement and evaluate partial re- tells us two things. (1) For our benchmark programs, SM- dundancy elimination of memory expressions in future work. FieldTypeRefs offers little or no precision over FieldType- Decl. (2) FieldTypeDecl is potentially a much better alias 4 Analyzing Incomplete Programs analysis than TypeDecl. Even though FieldTypeDecl of- Most prior pointer alias analyses for the heap are whole- fers little performance improvement over TypeDecl for RLE, program analyses, i.e., the compiler assumes it is analyzing FieldTypeDecl should probably be the algorithm of choice the entire program, including libraries, making a closed world since it does gives more precise results (without much added assumption. Many situations arise when the entire program complexity) which may be important for other optimizations is not available: for instance, during separate compilation, or that use alias analysis. compiling libraries without all their potential clients, or com- 8 Base RLE Minv+Inlining RLE+Minv+Inlining108 RLE RLE Open 99 99 100 100 100 100 100 100 100 100 97 97 98 98 98 98 97 97 99 98 99 100 97 98 97 94 94 92 92 94 93 92 91 91 90 90 88

81 80 79 79 80 78 77 78 70 72 71 70 60

60 50

50 40

40 Percent of original running time 30

Percent of original running time 30 20

20 10

0 10 Format Dformat Write-Pickle K-Tree M2toM3 Slisp M3CG

0 Format Dformat Write-Pickle K-Tree M2toM3 Slisp M3CG Figure 12: Open and Closed World Assumptions Figure 11: Cumulative Impact of Optimizations

which it has access since unavailable code may assign them. piling incomplete programs. Since Modula-3 uses structural type equivalence, unavailable In unsafe languages such as C++, alias analyses must as- code can access most types because it can construct its own sume that unavailable code may affect all pointers in arbitrary copy of the types. Exceptions to this ability are Branded ways. For type-safe languages like Modula-3 and Java, the types in Modula-3. These types essentially observe name compiler can use type-safety and a type-based alias analysis equivalence and may not be “reconstructed” by unavailable to make stronger type-safety assumptions about unavailable code. code. It can assume that unavailable code will not violate Figure 12 compares the simulated run-time improvement the type system of the language. For example, consider the due to redundant load elimination using TBAA when assum- following procedure declaration using the types declared in ing that the entire program is available (closed world) and Figure 1. assuming it is not available (open world). Notice that in our experiments, the open-world assumption has an insignificant PROCEDURE f (p: S1; q: S2) = ... impact on the effectiveness of TBAA with respect to RLE. This result however reflects the results in Table 6, since SM- In an unsafe language, if some of the callers of f are not FieldTypeRefs, which is most affected by the open world as- available for analysis, the compiler must assume that p and sumption, does not enable any additional opportunities for q are aliases. For a type-safe language, a type-based analysis RLE over FieldTypeDecl. With respect to the static metrics, can safely assume that p and q are not aliases since they have we found that they were the same for the open-world and incompatible types. closed-world assumptions with one difference: M3CG had Two components of TBAA rely on properties other than the about 80 more alias pairs (interprocedurally) with the open- type system of the language: AddressTaken and type merg- world assumption than with the closed world assumption. ing. Since unavailable code may pass the address of a qual- However, the additional alias pairs did not reduce the effec- ified expression or subscript expression to available code we tiveness of RLE. revise AddressTaken as follows. AddressTaken (p) is true: 5 Related Work 1. if the program ever takes p’s address (for instance to Alias analysis must consider an unbounded number of paths pass it by reference or as part of a WITH), or through an unbounded collection of data, and is therefore harder than traditional data-flow analyses. The literature con- 2. if f is a pass-by-reference formal and p and f have the tains many algorithms for alias analysis [2, 4, 6, 7, 9, 15, 19, same type. 8, 20, 21, 22, 30, 32, 35, 36]. The key differences between Since Modula-3 requires the types of pass-by-reference the algorithms stem from where and how they approximate formals and actuals to be identical, the second clause needs the unbounded control paths and data. The approximation to check only for type equality, not type compatibility. Note determines the precision and efficiency of the algorithm, and that this new definition of AddressTaken considers instruc- these alias analyses range from precise exponential time al- tions in the program for available code (1) and considers only gorithms to less precise nearly linear time algorithms. the type system for unavailable code (2). Our work differs from previous work in two ways: (1) It Since unavailable code may cause merges of types, we is type-based instead of instruction-based. (2) We evaluate make SMFieldTypeRefs more conservative at merges. We our alias algorithm with respect to an optimization, redun- merge any two types (related by the subtype relation) to dant load elimination, and its upper bound, rather than us- 9

ing static measurements as used by most work on alias anal- Since we ignore control flow, our algorithm achieves a

( ) ysis [2, 4, 6, 7, 9, 15, 20, 21, 22, 30, 32, 35]. Our upper O Instructions Types time complexity that is asymptot- bound measurement is similar to Wall’s [34], which assumes ically as fast as the fastest existing alias analysis [32]. a “perfect alias analysis” to find an upper bound on instruc- tion level parallelism. Wall [34] does not evaluate an existing 6 Conclusions alias analysis as we do, but just gives the potential of a perfect This paper describes and evaluates three algorithms that use alias analysis for instruction level parallelism. programming language types to disambiguate memory refer- Aho, et al. [1] and Chase, et al. [6] were among the first to ences. The first analysis uses type compatibility to determine notice that using programming language types could improve aliases. The second extends the first by using additional high- alias analysis, but did not present algorithms that did so. Our level information such as field names and types. The third, alias algorithm is most similar to those of Rinard and Diniz TBAA, extends the second with a flow-insensitive analysis. [26], Steensgaard [32], and Ruf [27, 28]. We show that the algorithm that uses only type compatibility Rinard and Diniz use type equality to disambiguate mem- is very imprecise whereas the other two analyses are much ory references. The type system they use is a subset of better at disambiguating memory references in the same pro- C++ that does not have inheritance and is thus weaker than cedure. We also evaluate TBAA with respect to redundant Modula-3’s or Java’s type systems. Steensgaard uses an load elimination (RLE), one of its many potential clients. Our instruction-based alias algorithm which uses non-standard results show that TBAA and RLE improve program perfor- types, not programming language types, to obtain a fast alias mance by up to 8%, and on average 4%. We demonstrate that analysis. His type inference algorithm is similar to our selec- with respect to RLE and these benchmark programs, TBAA is tive type merging; however, he does not use programming very precise; a more precise analysis could only enable RLE language types, and in particular inheritance, to prune the to eliminate on average an additional 2.5% of redundant ref- merge sets as we do. Ruf shows how to use programming erences, and at most 6%. Because TBAA relies on type-safety, language types to partition data-flow analyses: each partition it can be conservative in the face of incomplete, type-safe pro- represents code that can be analyzed independently and thus grams without losing effectiveness. Our results show that as a different analysis can be used on each partition [28]. Ruf far as RLE is concerned, TBAA performs just as well with an uses his scheme to partition programs for alias analyses, but open-world assumption as with a closed-world assumption. does not use the programming language types in the analysis. TBAA achieves its fast time bound and accuracy because Ruf [27] compares a context sensitive alias analysis to a con- of , and our results confirm a common (but to our text insensitive alias analysis and finds, for his benchmarks, knowledge, untested) belief that type safety can be used to that they are comparable in precision. Our work supports his improve program performance. Taken together, these results in that we also find that a simple alias analysis can yield very suggest that type-based alias analysis can be effective, and precise results. that a thorough evaluation of alias analyses with respect to Cooper and Lu [8] describe and evaluate register promo- their clients is necessary to understand their strengths and tion, an optimization that moves memory references out of weaknesses. loops and into registers. They evaluate register promotion References with two alias analyses: a trivial analysis and a flow-sensitive alias analysis. They used the number of instructions executed [1] Alfred V. Aho, Ravi Sethi, and Jeffrey D. Ullman. Compilers: Principles, Techniques, and Tools. Addison-Wesley, 1986. as their performance metric and found that the more powerful alias analysis did not significantly improve performance. Our [2] John Banning. An efficient way to find side effects of results support theirs: for many applications a fast and simple procedure calls and aliases of variables. In Conference Record of the Sixth Annual ACM SIGACT/SIGPLAN alias analysis may be sufficient. Symposium on Principles of Programming Languages, pages Shapiro and Horwitz [29] evaluate the impact of three flow 29–41, San Antonio, Texas, January 1979. insensitive alias analyses on a range of optimizations. They [3] Rodney M. Bates. K-trees. Personal communication, evaluate their algorithms by counting optimization opportuni- November 1994. ties rather than any of the metrics that we use. They find that [4] Michael Burke, Paul R. Carini, Jong-Deok Choi, and Michael clients of alias analysis may run faster with a more precise Hind. Efficient flow-insensitive alias analysis in the presence alias analysis than with a less precise alias analysis. Sim- of pointers. Technical Report 19546, IBM T.J. Watson ilarly, Ghiya and Hendren [17] use pointer analysis to im- Research Center, Yorktown Heights, NY, September 1994. prove scalar optimizations, and present run-time improve- [5] Brad Calder, Dirk Grunwald, and Joel Emer. A system level ments. This work was concurrent with ours, They do not perspective on branch architecture performance. In 28th present a limit study. International Symposium on Microarchitecture, pages Debray et al. [11] describe an alias analysis for executable 199–206, November 1995. code. They evaluate their algorithm by measuring the per- [6] David R. Chase, Mark Wegman, and F. Kenneth Zadeck. centage of loads eliminated by redundant load elimination. Analysis of pointers and structures. In Proceedings of the They do not present execution time improvements or a limit ACM SIGPLAN ’90 Conference on Programming Language study for their alias analysis. Design and Implementation, pages 296–310, 1990. 10 [7] Jong-Deok Choi, Michael Burke, and Paul Carini. Efficient aliasing: a problem classification. In Conference Record of flow-sensitive interprocedural computation of pointer-induced the Eighteenth Annual ACM SIGACT/SIGPLAN Symposium aliases and side effects. In Conference Record of the on Principles of Programming Languages, pages 93–103, Twentieth Annual ACM SIGACT/SIGPLAN Symposium on Orlando, FL, January 1991. Principles of Programming Languages, pages 232–245, [21] William Landi and Barbara G. Ryder. Interprocedural side Charleston, SC, January 1993. effect analysis with pointer aliasing. In Proceedings of the [8] Keith Cooper and John Lu. Register promotion in c ACM SIGPLAN ’92 Conference on Programming Language programs. In Proceedings of the ACM SIGPLAN ’97 Design and Implementation, pages 235–248, San Francisco, Conference on Programming Language Design and CA, June 1992. Implementation, Las Vegas, Nevada, June 1997. [22] James R. Larus and Paul N. Hilfinger. Detecting conflicts [9] Keith D. Cooper and Ken Kennedy. Fast interprocedural alias between structure accesses. In Proceedings of the ACM analysis. In Conference Record of the Sixteenth Annual ACM SIGPLAN ’88 Conference on Programming Language Design SIGACT/SIGPLAN Symposium on Principles of and Implementation, pages 21–34, Atlanta, GA, June 1988. Programming Languages, pages 49–59, 1989. [23] Barbara Liskov and . Abstraction and [10] Jeffery Dean, Greg DeFouw, David Grove, Vassily Litvinov, Specification in Program Development. MIT Press, 1986. and Craig Chambers. Vortex: An optimizing compiler for [24] Farshad Nayeri, Benjamin Hurwitz, and Frank Manola. object-oriented languages. In Proceedings of the ACM Generalizing dispatching in a distributed object system. In SIGPLAN ’96 Conference on Object-Oriented Programming Proceedings of European Conference on Object-Oriented Systems, Languages, and Applications, pages 83–100, San Programming, pages 450–473, Bologna, Italy, July 1994. Jose, CA, October 1996. [25] Greg Nelson, editor. Systems Programming with Modula-3. [11] Saumya Debray, Robert Muth, and Matthew Weippert. Alias Prentice Hall, New Jersey, 1991. analysis of executable code. In Conference Record of the [26] Martin C. Rinard and Pedro C. Diniz. Commutativity Twentyfifth Annual ACM SIGPLAN/SIGACT Symposium on analysis: A new analysis framework for parallelizing Principles of Programming Languages, 1998. compilers. In Proceedings of the ACM SIGPLAN ’96 [12] Digital Equipment Corporation. DEC3000 Conference on Programming Language Design and 300/400/500/600/800 Models: System Programmer’s Implementation, Philadelphia, PA, June 1996. Manual, 1 edition, September 1993. First Printing. [27] Eric Ruf. Context-insensitive alias analysis reconsidered. In [13] Amer Diwan. Understanding and improving the performance Proceedings of the ACM SIGPLAN ’95 Conference on of modern programming languages. PhD thesis, University of Programming Language Design and Implementation, pages Massachusetts, Amherst, MA 01003, October 1996. 13–22, La Jolla, CA, June 1995. [14] Amer Diwan, Eliot Moss, and Kathryn S. McKinley. Simple [28] Erik Ruf. Partitioning dataflow analyses using types. In and effective analysis of statically typed object-oriented popl97, Paris, France, January 1997. programs. In Proceedings of the ACM SIGPLAN ’96 [29] Marc Shapiro and Susan Horwitz. The effects of the precision Conference on Object-Oriented Programming Systems, of pointer analysis. In Pascal Van Hentenryck, editor, Lecture Languages, and Applications, San Jose, CA, October 1996. Notes in Computer Science, 1302, pages 16–34. [15] Maryam Emami, Rakesh Ghiya, and Laurie J. Hendren. Springer-Verlag, 1997. Proceedings from the 4th Context-sensitive interprocedural Points-to analysis in the International Static Analysis Symposium. presence of function pointers. In Proceedings of the ACM [30] Marc Shapiro and Susan Horwitz. Fast and accurate SIGPLAN ’94 Conference on Programming Language Design flow-insensitive points-to analysis. In Conference Record of and Implementation, pages 242–256, June 1994. the Twentyfourth Annual ACM SIGPLAN/SIGACT [16] Mary F. Fernandez. Simple and effective link-time Symposium on Principles of Programming Languages, Paris, optimization of Modula-3 programs. In Proceedings of France, January 1997. Conference on Programming Language Design and [31] Amitabh Srivastava and Alan Eustace. ATOM: A system for Implementation, pages 103–115, La Jolla, CA, June 1995. building customized program analysis tools. In Proceedings SIGPLAN, ACM Press. of the ACM SIGPLAN ’94 Conference on Programming [17] Rakesh Ghiya and Laurie J. Hendren. Putting pointer analysis Language Design and Implementation, pages 196–205, to work. In Conference Record of the Twentyfifth Annual Orlando, FL, June 1994. Association of Computing ACM SIGPLAN/SIGACT Symposium on Principles of Machinery. Programming Languages, 1998. [32] Bjarne Steensgaard. Points-to analysis in almost linear time. [18] John Hennessy and David Patterson. Computer Architecture In Conference Record of the Twentythird Annual ACM A Quantitative Approach. Morgan-Kaufmann, 1995. SIGPLAN/SIGACT Symposium on Principles of [19] Joseph Hummel, Laurie J. Hendren, and Alexandru Nicolau. Programming Languages, pages 32–41. Association of A general data dependence test for dynamic, pointer-based Computing Machinery, January 1996. data structures. In Proceedings of the ACM SIGPLAN ’94 [33] Sun Microsystems Computer Corporation. The Java Conference on Programming Language Design and language specification, 1.0 beta edition, October 1995. Implementation, pages 218–229, 1994. [34] David W. Wall. Limits of instruction-level parallelism. In [20] William Landi and Barbara G. Ryder. Pointer-induced Proceedings of the Fourth International Conference on

11 Architectural Support for Programming Languages and Operating Systems, pages 176–189, Santa Clara, , 1991. [35] William E. Weihl. Interprocedural data flow analysis in the presence of pointers, procedure variables and label variables. In Conference Record of the Seventh Annual ACM SIGACT/SIGPLAN Symposium on Principles of Programming Languages, pages 83–94, Las Vegas, Nevada, January 1980. [36] Robert P. Wilson and Monica S. Lam. Efficient context-sensitive pointer analysis for C programs. In Proceedings of the ACM SIGPLAN ’95 Conference on Programming Language Design and Implementation, pages 1–12, La Jolla, CA, June 1995. Association of Computing Machinery.

12