Purdue University Purdue e-Pubs

Department of Computer Science Technical Reports Department of Computer Science

1998

Partial Redundancy Elimination for Access Path Expressions

Antony L. Hosking Purdue University, [email protected]

National Nystrom

David Whitlock

Quintin Cutts

Amer Diwan Report Number: 98-044

Hosking, Antony L.; Nystrom, National; Whitlock, David; Cutts, Quintin; and Diwan, Amer, "Partial Redundancy Elimination for Access Path Expressions" (1998). Department of Computer Science Technical Reports. Paper 1431. https://docs.lib.purdue.edu/cstech/1431

This document has been made available through Purdue e-Pubs, a service of the Purdue University Libraries. Please contact [email protected] for additional information. PARTIAL REDUNDANCY ELIMINATION FOR ACCESS PATH EXPRESSIONS

Antony Hosking Nathaniel Nystrom David Whitlock Quitin Culls AmerDiwan

CSD TR #98-044 December 1998 lmemurionul Workshop 011 Aliasing ill Ohjecl-Oriemed Systems, Lisbon, Ponugal, June 1999

Partial Redundancy Elimination for Access Path Expressions

Antony L. Hosking Nathaniel Nystrom David Whitlock Department ofComputer Sciences Purdue UniversiLY West Lafayette, IN 47907- [398, USA Quintin Cutts Amer Diwan Department ofComputing Science Department ofComputer Science University ofGlasgow Stanford University Glasgow Gl2 8QQ, Scotland Stanford, CA 94305-9030, USA

Abstract which are often the source of large performance pcnal­ ties incurred in the memory subsystem. Pointer traversals pose significant overhead to the ex­ In this paper we evaluate an approach to elimina­ ecution of object-oriented programs, since every ac­ tion of common access expressions that combines par­ cess Lo an object's state requires a pointer dereference. tial redundancy elimination (PRE) [Morel and Rcnvoise Eliminating redundant pointer traversals reduces both instructions executed as well as redundant memory ac­ 1979] with type-based (TBAA) lDhvan cesses to relieve pressure on the memory subsystem. We et al. 1998]. To explore the potential of this approach describe an approach to elimination of redundant access we have built an optimization framework for Java elass expressions that combines partial redundancy elimina­ files incorporating TBAA-based PRE for access expres­ tion (PRE) with type-based alias analysis (TBAA). To sions, and measured its impact on the performance of explore the potential of this approach we have imple­ several benchmark programs. An interesting aspect of mented an optimization framework for Java class files the optimizaLion framework is that it operates entirely as incorporating TBAA-ba~ed PRE overpointer acces~' ex­ a bytecode-to-bytccode translator, sourcing and target­ pressions. The framework is implemented as a classfile­ ing Java class files. Our experiments compare the ex­ Lo-classfile transformer; opLimized classes can then be ecution of optimized and unoptimized classes for sev­ run in any standard Java execution environment. Our eral SPARC-based execution environments: the inter­ experiments demonstrate improvements in the execu­ preted JOK reference virtual machinc, the Solaris 2.6 tion ofoptimized code for several Java benchmarks run­ ning in diverse execution environments: the standard virtual machine with ''just-in-time'' (ill) compilation, interpreted JOK virLual machine, a virtual machine us­ and native binaries compiled off-line ("way-ahead-of­ ing "just-in-time" compilation, and native binaries com­ time") to C and thence to native code using the Solaris piled off-line ("way-ahead-of-time"). We isolate the im­ C compiler. pact of access path PRE using TBAA, and demonstrate We have measured boLh the static and dynamic im­ that Java's requirement ofprecise exceptions can notice­ pact of bytecodc-Ievel PRE optimizat"lon for a seL of ably impact code-motion optimizations like PRE. Java benchmark applications, including static code size, bytecode execution counts, native-instruction execution counts, and elapsed time. The results demonstrate gen­ 1 Introduction eral improvement on all measures tor all execution en­ vironmenL~, although some benchmarks have degraded Pointer traversals pose significant overhead to the exe­ performance in certain environments. cution of object-oriented programs, since every access The remainder of thc paper is organized tls follows. to an object's state requires a pointer dereference. Ob­ Section 2 introduces the approach to elimination of jects can refer to other objects, fomling graph structures, redundant access path expressions ba~ed on partial­ and they can be modified, with such modifications vis­ redundancy elimination and type-based alias analysis. ible in future accesses. Just as common subexpressions Section 3 describes our implementation of the analysis often appear in numerical code, common access expres­ and optimization framework that supports transforma­ sions are likewise often encountered in object-oriented tion of Java cla~s files using TBAA-based PRE. Sec­ code. Where two such expressions redundantly com­ tion 4 describes ourexper"lmental methodology for eval­ pute the same value it is desirable to avoid repeated uation ofTBAA-based PRE for several Java benchmark computation of that value by caching the result of the applications. The experimental results are reponed and first computation in a temporary variable, and reusing interpreted in Section 5. We conclude with a discussion it from the temporary at the later occurrence of the ex­ of related work and speculate on directions for future pression. Eliminating redundant computations in this work. way certainly eliminates redundant CPU overhead. Per­ haps just as important for modern machinc architec­ tures, eliminating redundant access expressions also has the effect of eliminating redundant memory references, o 0 o a Table 1: Access expressions b b b b a+b H-a+b t<-a+b I Notation I Name I Variable accesscd I p.f Field access Field f of class in" ~/ ~/ stance [0 which p refers ~ ~ pi;] Array access Component with sub- o+b scripL ; of array Lo (a) Before PRE (b) After PRE which prefers Figure 1: PRE for arithmctie expressions

2 PRE for Access Expressions ble with array lype T[) if type S is a.~signable to type T. Interface types also yield rules on assignability: an Our analysis and optimization framework revolves interface type S is assignable to an interface type T only around PRE over object access expressions. We adopt if T is the same interface as S or a superinterfaee of S; slandanl terminology and notations uscd in the specifi­ a class type S is assignable to an interface type T if S cation of the Java programming language to frame the implements T. Finally, array types, interface types and analysis and optimization problem. class types are all assignablc to class type object. For our purposes we say that a type S is a subt)'pe of 2.1 Thrminology and notation a type T ifS is assignable to T. 1 We write SlIbtype~'(T) to denote all subtypes of type T, including T. Thus, The following definitions paraphrase the Java specifica­ an access path p can legally access variables of type Lion [Gosling et al. 1996J. An object in Java is eithcr a SlIbrypes(Type(p)). class i/lstance or an array. Reference values in Java are poillter~' to these objects, as well as the null reference. Both objects and arrays are created by expressions thaI 2.2 Partial redundancy elimination allocate and initializc storage for them. The operators Our approach to optimization of access expressions ·IS on references to objecLs arc field access, method invoca­ based on application of partiaf redullda/lC)' elimil/arioll tion, casts, type comparison (instanceof), equality (PRE) [Morel and Renvoise 1979]. To our knowledge operators and the conditional operator. There may be this is the first time PRE has been applied to access many references to the same object. Objects have muta­ paths. PRE is a powerful global optimization technique ble state, stored in the variablc fields of class instances Lhat subsumes the more standard common suhexpres­ or the variable elements of arrays. Two variables may sion elimination (CSE). PRE eliminates computations refer to the same object: the state of the object can be that are only partially redundant; that is, redundant only modified through the referencc stored in one variable on some, but not all, paths to somelaterrc-compulation. and then the altered state observed through the other. By inserting evaluations on those paths where the com­ Access expressiolls refer to the variables that comprise putation docs not occur, the later re-evaluation can be an objccl's state. Afield access expression refers to a eliminated and replaced instead with a use of the pre­ field of some elass instancc, while an array access ex­ computed value. This is illustrated in Figure 1. In Fig­ pressioll refers to a component ofan array. Table I sum­ ure l(a), both a and b are available along each palh marizes the Lwo kinds ofaccess expressions in Java. We to the merge point, where expression a + b is evalu" adopt the term access parh lLarus and Hilfinger 1988; ated. However, Lhis evaluation is partially redundant Diwan et al. 1998J to mean a non-empty sequence of since a+h is available on one path to the merge but not accesses. For example, the Java expression a.b[i].c is both. By hoisting the second evaluation of a + b into an access path. Without loss of generality, our nOLation the path where it was not originally available, as in Fig­ assumes that distinct fields within an object have differ­ ure I(b), a + b need only bc evaluated once along any ent names (Le., fields that override inherited fields of the path through the program, ralher Ihan twice as before. same name from superclasses are trivially renamed). Consider the Java access expression a.b[i].c, which A variable is a storage location and has an associated translates to Java bytecode of the form: type, someLimes called its compife-rime type. Given an access path p, then the compile-time lype of p, written aload a load local variable a T)'pe(p) , is simply the compile-time type of the variable getfield b load field b of a it accesses. A variable always contains a valuc that is as­ iload i load local variable i sigillI/em compatibfe with its typc. A value of compile­ aaload index array b time class Lype S is assignment compatible with class getfield c load field c of b[i]

type T if Sand T arc the same class or S is a subclass IThe lerm "sublypc" is not used al all in Ihe official Java language of T. A similar rule holds for array variables: a value spccilkatloll [Gosling el a1. 19961. prc.,umably 10 avoid cunrusing lhe of compile-time array type S[] is assignment compati- type hier.rrchy induced by Ihe subtype relation wilh class and imerface hierarchies. a a a a i i i i Table 2: FiefdTypeDecl(APl ,AP2) a.b[iJ.c 1(- a.b[iJ.c t r a.b[i]'c ~ ~/ ~/ - FieldTypeDecl(AP l ,AP.,)- I I P P 'rue 2 p.f q.g (f = g) A TypeDecl(p,q) ~ ~ 3 p.f q[n false a.b[i].c 4 p[i] qU] I)'peDee!(p,q) (a) Before PRE (b) After PRE 5 p q TypeDecl(p,q)

Figure 2: PRE for access expressions A more precise alias analysis wm distinguish accesses Traversing the access path requires successively loading 10 fields thal are the same type yet distinct. This more (he pointer at each memory location along the path and precise relation, FieldI)'PeDecl(p,q), is defincd by in­ traversing it to the next location in the sequence. Be­ duction on the structure of p and q in Table 2. Again, fore applying PRE to access path expressions, one must two access paths p and q may be aliases only if the re­ first disambiguate memory references sufficiently to be lalion FiefdTypeDecl(p,q) holds. It distinguishes ac­ able safely to assume that no memory location along the cesses such as t.f ami t.g that I)'peDee! misses. The access path can be aliased (and so modified) by some cases in Table 2 determine that: lexically distinct access path in the program. Consider 1. Identical access paths arc always aliases the example in Figure 2. The expression a.b[iJ.c will be redundant at some subsequent reevaluation so long as 2. Two field accesses may be aliases if they access the same field ofpolentially the same object no store occurs to anyone of {/, a.b, i, a.b[i] or a.b[iJ.c on the code path between the first evaluation of the ex­ 3. Array accesses cannot alias field accesses and vice pression and the second. In other words, if there are versa explicit stores to a or i (local variables cannot be alia.~ed 4. Two array accesses may be aliases if they may ac­ in Java) or potcntial aliases to anyone of a.b, a.b[iJ or cess the same array (the subscript is ignored) a.b[iJ.c through which those locations may be modified 5. All other pairs of access expressions (when none between the first and second evaluation of thc expres­ of the above apply) are possible aliases ifthey have sion, then that second evaluation cannot be treatcd as common subtypes redundant.

2.3.1 Analysing Incomplete Programs 2.3 lYPe~based alias analysis Java dynamically links classes on demand as they arc Alias analysis refincs the set of possible variables to needed during execution. Moreover, Java pemlits dy­ which an access path may refer. Two distinct access namic loading of arbitrary named classes that are stat­ paths arc said to be possiblc aliases if they may refer to ically unknown. Also, code for native methods cannot the same variable. Without alias analysis the optimizer easily be analysed. To maintain class compatibility, no must conservatively assume that all access paths are class can make static assumptions about the code that possible aliases of each other. In general, alias analy­ implements another cla.~s. Thus, alias analysis must sis in the presence ofreferences is slow and requires the make conservative assumptions about the effects ofstal­ code for the entire program to work. Type-based alias icany unavailable code. Fortunately, both TypeDec1 and analysis (TBAA) [Diwan et al. 19981 offers one possi­ FieldTypeDec/ require only the compile-time types of bility for overcoming these limitations. TBAA assumes access expressions to determine which of them may be a type-safe programming language such as Java, since aliases. Thus, they are applicable to compiled classes it uses type declarations to disambiguate references. It in isolation and optimizations that use the static alias works in linear time and does not require that the en­ information they derive will not violate dynamic class tire program be available. Rather, TBAA uses the type compatibility. system to disambiguate memory references by refining Diwan et al. [19981 further refine TBAA for dosed the type of variables to which an access path may refer, world situations: those in which all the code that might since only type-compatible access paths can alias the execute in an application is available for analysis. The same variable in a type-safe language such as Java. The refinement enumerates all the assignments in a program compile-time type of an access path provides a simple to determine Illore accurately the types of variables to way to do this: two access paths p and q may be aliases which a given access path may refer. An access path only if the relation TypeDed(p,q) holds, as defined by of type T may yield a reference to an object of a given subtype S only if there exist assignments of references I TypeDed(AP"AP2) I o[typeS to variables of type T. Unlike TypeDecl, which SII!Jrypes(I)'Pe(APJ) nSubfypes{I)'pe{AP2» I =I- 0 , always merges lhe compile-time type of an access path with all of its subtypes, Diwan's closed world refine­ sl

4 Experiments all four variants (base, pre, tbaa and loose) of the To evaluate PRE for access path expressions we took classes for each benchmark. 'Where Java source code several Java programs as benchmarks, optimized them for n benchmark wns available, it was compiled using with BLOAT and compared the results of the optimiza­ the standard JDK [.1.6 javac compiler (withoutlhc-O tion with their unopLimized counterparts, using several optimization flag since in many cases this generates er­ sLatic and dynamic performance metrics. To isolate the roneous code; our observations indicate that this flag has effeeLs ofaccess path PRE we considered 3 successively little impact on the performance ofour benchmarks). more powerful levels of optimization: PRE over scalar ex.pressions, TBAA-based PRE over both scalar and ac­ 4.3.1 JDK cess expressions, and TBAA-baseu PRE that docs not respect Java's precisc exception requirements. Each op­ JDK is the standard 1.1.6 Java virtual machine. It uses timization leve[ subsumes all optimizations that are per­ a portable threads package rathcr than the native So­ fonned by lower level optimizations. In the following laris threads and thc bytecode interpreter loop is im­ we will refer to results for the unoptimized code as plemented in assembler. We optimized the class files base, anu 10 the successive levels of PRE-based opti­ of each benchmark against the JDK version 1.1.6 core mization as pre, tbaa and loose, respectively. Java classes [Gosling et a1. 1996] at cach optimization level, to fonn the closure ofoptimized classes necessary 4.1 Platform to execute the benchmark in JDK. Similarly the unop­ timized benchmark classes were run against the unopLi­ Our experiments were run under SolariI'. 2.5. I on a mized core classes. Sun Ultra 2 Model 2200, wiLh 256Mb RAM, and two 200MHz UltraSPARC-I processors, each with IMb ex­ 4.3.2 JIT ternal cache in addition to their on-chip instruction and data caches. The UltraSPARC-I data cache is TIT refers to the Solaris 2.6 SPARC JOK with TIT ver­ a 16Kb write-through, non-allocating, direct-mapped sion 1.1.3. This VM translates a method's bytecodes cache with twO 16-byte sub-blocks per line. It is virtu­ to native SPARC instruction on first execution of the ally indexed and physically tagged. The 16Kb instruc­ method, along with thc following optimizations: tion cache is 2-way set-nssociative, physically indexed I. elimination ofsome array bounds checking and tagged, and organized into 512 32-byte Jines. 2. elimination of common subexpressions within blocks 3. elimination ofempty methods 4.2 Benchmarks 4. some regisLer allocation for locals The benchmarks we use arc summarized in Table 3. 5. no flow analysis 6. limited inlining 4.3 Execution environments Interestingly, programmers are encouraged to perform the following optimizations by hand [SunSoft 1997]: We took measurements for three different Java execu­ tion environments: the slandard Java Development Kit I. move loop invariants outside (he loop (JDK) version 1.1.6, the Solaris 2.6 SPARC JDK with 2. make loop tests as simple as possible JIT version 1.1.3 (JIT) and Toba version I. [ (Toba) 3. perfonn loops backwards 4. use only local variables inside loops [Proebsting et al. 1997]. In each environment we ran 5. move consLant conditionals outside loops 6. combine similar loops - instruction buffer stalls due to instruction 7. nest the busiest loop, if loops are interchangeable cache misses 8. unroll loops, as a last resort - data cache reads 9. avoid conditional branches - data cache read misses 10. cache values that arc expensive to fetch or compute using software) that allows user-level access to the [I. pre-compute values known at compile timc UltraSPARC hardware execmlon counters These suggestions likely reveal deficiencies in the cur­ For the dynamic measurements each run consists of two rem JIT compiler which our optimizations may address iterations of the benchmark within a given execution prior to TIT execution. environment. The first iteration is to prime the envi­ We used the same sets of class files as for JDK for ronment: loading class files, JIT-compiling them and execution in the TIT environment. wanning the caches, The second iteration is the one measured. 4.3.3 Toba The physically addressed instruction cache on the Toba compiles Java class files to C, and thence to na­ illLraSPARC means that programs can exhibit widely tive code using the host system's C compiler. The Toba varying execution times from one invocation to the next, run-time system supports native Solaris threads, and since each invocation may have quite different map­ garbage collection using the Boehm-Demers-Weiser pings from virtual 10 physical addresses that result in conservative garbage collector [Boehm and Weiser randomized instruction cache placement. Thus, the 1988J. We started with the same sets of classes as for elapsed time and cache-related mctrics were obtained JDK for execution in Toba. These class files were lhen for 10 separale runs and the results averaged. We ran compiled to nmive code using the SunPro C compiler each benchmark with sufficient heap space to eliminate ver.;ion 4.0, with the -02 compiler optimizmion flag. C the need for garbage collection, and verified that no col­ optimization level 2 performs ba.~ic local and global op­ lections occurred during benchmarking. timization, including induction variable elimination, al­ gebraic simpl ification, copy propagation, constant prop­ 5 Results agation, loop-invariant optimization, , basic block merging, tail recursion elimination, dead Our presentation normalizes all optimization results code elimination, tail call elimination and complex ex­ with respect to the base metrics. Rcporting the results pression expansion. We use this level since it does not in this way exposes the relative effects of the succes­ "oplimize references", nor "trace the effect of pointer sive levels of optimization. Error bars in our graphs assignments", and (herefore will best reveal the impact represent 90% confidence intervals; these display the ofour pointer optimizations. variation in performance due to factors beyond our con­ trol, such a~ the varying virtual-to-physical page map­ 4.4 Metrics pings. Grouped by benchmark, thc adjacent columns in the grolphs represent the transition to higher optimiza­ For each benchmark we took measurements for both (he tion levels from base, through pre and lbaa to loose, optimized and unoptimi7.ed classes. We use both static In the following discussion we consider each execu­ and dynamic metrics to expose the effects of optimiza­ tion environmenlin turn: JDK, then nT, ancllastly Tob

• counts ofsignificant performance-related events: JSee hllp:/"vww.c.~.Il1<;u,ctlul-cnbotlyl - processor cycles to measure elapsed time (al Bytecodes executed (a) load vs. load" s:: ~§~§ 8~~- 8~-~ , §~ '" " §'$;i" .., . ,, , 0 · , 1 ," , " , 0 · , ·, 0 · 0 , 0 0 , · i liIiII · 1,"1I · ,· . 0 · · · , 0 1 III · ; i - ,- ,. ,~. ~ - -

(b) TIme (cycles) (b) store vs. storen 83~3 , 8E!~~' §~:>~ .' . §~~~ -~~~ ~~;<'i §~§~ §~~'$ .. , .' . :' · ! · · , 0 · i · · ! ·, . · I · ·, ! · 0 · , , · 1 ,, 0 , · , • ., · · ~ , ~ : : , , 0 i 1 · , . ~ j ! •, :i: , . · i ! · , , ,I . ~ , • l · 1 , · , i ·,! , , · , · 0 , , .· lliI "" ""Jf.... ,- •• j,"I"" ~ ,,~ c~"" - - c~ .,~ "'.".. (e) Data reads <»1" hulfnw> 1&. jl" j1b lin~,",k I,w "",,,,1 ","" §~-- §§s§ §~;-; §~~~ §§~~ §;li~2 §;l>o: g •.. 8~~~ o no", n o~" .. 0 , 0 , 0 0 .; = •, 0 0 · , , ! 0 ,· , ~il I ·, J Figure 4: Replacing load/slore wilh shorL forms ! 0 , ,J , , , ; 0 ! · 0 · J ~ E ,"' 0 0 0 0 · · , · . ! 00 · 0 , ! · i · could be removed. It is remarkable how many of these , , , · . J · · 0 j 0 0 , are removed by our purely intra-procedural analysis. , 0 i · , ·, ,, 00 . ,, 00 , 0 o. II,... • · · J All benchmarks see a decrc~~e, oflen significant, in the huIT",,' '.o,... .~ ,"" ." J" .. frequency of getfield bytecodes (Figure 5(a)) due to <:II~ - -". -~ TBAA-based PRE over redundant access expressions "'"... ..- (Ibaa). The dramatic reduct"lon for Neural represents a reducLion of redundant getfield operations from 9% Figure 3: JDK merries of total bytecodes executed Lo 5% of total byLecodes. Linpack's reductions are similar, but getfields represem Figure 4 highlighLS these conversions. The effect is just 0.02% of total byLecodcs cxecuted so thc impact is most notable wilh LZW where the frequency of the load minimal. Relaxing Java's precisc exception requirement byteeodes decreases from II% La I% of the total byLc­ (loose) yields lillie benefit for getfield. codes executed and the frequency of loadll increases The array inLensive benchmarks (Huffman. Linpack, from 20% to 28%. These effcCl~ result in less overhead and Neural) obtain noticeable reductions in arrayload in [he interpreter's byrecode dispatch loop. The impact frequency (Figure S(b». Interestingly, relaxing Java's on data cache rcads (remember, bytecodes are daLa) is precise exceptions gives significant improvement for both Linpack and Neural, bccause freedom from con­ revealed in Figure 3(c). The large increase in stores for Unpack is due to PRE's elimination ofsignificant num­ cern over precise delivery of array out of bounds excep­ bers of redundant arithmetic expressions. tions, provides more opportunity for PRE-based code mOlion. The Huffman, Linpack, and Neural bench­ The most dramatic effects of PRE over access paths are directly revealed in the results for the access byte­ marks, which have heavy array usc (4%, 9%, and 11 %, respectively), see an elimination of4-7% of the array­ codes given in Figure 5. Here, we show the tola! number load bytecodes for TBAA-bused PRE with precise ex­ of access bytecodes performed, broken down into glob­ ally redundant versus non-redundamaccesses. The non­ ceplions (tbaa). Relaxing exception delivery (loose) redundam accesses are those that must always be per­ sees reductions in arrayloads increase to a peak of22% for Neural. FurLher improvement would accrue if array formed. The globally redundant accesses represenL op­ portunity for optimization; with perfect inler-procedural subscripts could be disambigumed via range analysis on control flow and aliasing information all such accesses lhe subscript expressions for use during array alias anal­ ysis. Few arrayload bylccodcs are eliminated in any of (a) getfield bytecodes (a) Time (cycles)

~ ! ~, IU i

IU,-,-,,,,,,L

(b) arrayload bytecodcs (b) Data reads

; =

. .1 . ' , . 11:11 .~

(c) getstatic bytecodes Figure 6: JIT metrics

variables to registers, do the exira load and store byte­ 1 codes matter much since they are converted to register accesses. The only exception to this is Linpack, which o! we saw earlier suffers from the introduction of large 1 0.' ,; numbcrs of temporaries and corresponding stores. Un­ b fortunately, the corresponding increase in contention for -~ register assignment of these temporaries causes most n.n l..lLLCU,,",WW.u-CU.llWW.u-CU.llLLW.u-CU=rn of lhem to remain in memory, with the loads turning 0)1' hulfm'"..... jb Jtb IInr.d J",. fl

Gf1I'r'A. R. AND HENDREN, L. 1. 1996.15 il alree, a DAG, ora PLOT 1998.Procccdi"g.. (ifille IICM Cmifert'l1cc Oil Pmgrt"'lllli'lg cyclic graph'! a shape ~nalysi5 for heap-direcled pointers in c. Wllguuge Design OIlrllJllplellle'llmiol/ (Monllial, Canadn. See Conference Record Oflh", ACM Symposium on June). ACM SIGPlAN No/ices 33, :) (May). Principles ofPrognlmming Languages [1996b], 1-15, POPL 19H8. COIifere,lcc ReCllrd ojille IICM Symposium 11I1 GlllYA. R, liND HENDREN. L. J. 1998. PUlling poinler analysis /'ri,lclplc.\"if PmgramlJllng l.nngllagcs (San Diego, 10 work. Sec Conference Rceord oflhe ACM Symposium on California. Jan_l. Prineiplc,~ of Programming Languages [1998a),121-133, PROEBSTING, T. A •• TOWNSEND. G.. BRIDGIIS. P.. HIIRHIAN, GOSLING, J .. JOY, B .• AND STF.F.LE. G. 1996. The Jm'u J. H .. NEWSHAM. T.. IIND WATTERSON.S. A. 1997, Toba: I1mglluge Spnificmion. Addison-Wesley. Java for applicmions - a way ahead oflime (\VAT) compiler. GOSLING, J.• YIOLLIS. F,. IINIl TIIEJAV,\ TEII~I.1996. Tile In I'roceedillg,< of/lIe n,ird USEN/X CO/iferel/cc un JI/m IIpp/;curirm l'ro}:rw1lIuing IlIlerfl/u. Vol. I: Core Objecr-OrielJled Technologies alld !'.).rle,,~< (Portland, P.ncJ,:~ges. Addison·Wesley. Oregon. June), USENIX. Sec hup:J/www.es.arizona.eduisummr.l!loba. HIISTI, R, ANf) HORWITZ, S. 1998. U~ins ~t::ltie single assignmenl form 10 improve now-insensilive po]nl",r ROSEN. B. K., WEGMAN. M, N .. liND ZADECK, F. K. 1988. analysis. Sec PLDI [19981, 97-105. Global valuc numbers and redundant computalions. See POPL [19881. 12-27. HAVLAK, P. [997. Nc.<;Ling of reducible and irreducible loops, ACM TrollS, Program. wng. Sysl. 19. 4 (July). 557-567. RUF. E. 1995. Come~l-in5ensjli\'e ali:lS analysis reconsldt'red. St'e PLDII1995].I3-22. HOSKING.A. L .• NYSTROM, N .• CUTTS, Q.. liND BRAHNMIITIJ, K. [999. Optimizing lhe read ~nd wrile SASTRY. A. V. S. liND Ju. R. D, C, 1998. A new a1gorllhm fur hllJTiers for orthogon.nl persistcnell, Sec MomsoJl cL al. scalar regisler promulion based on ssa fonn. Set" PLDI [1999],149-[59. [1998],15-25. HUMMF.L, J .• HENDREN, L. J.. AND NrCOL,\U, A. 1994, A SIlIIPIRO. M. AND HORWITZ. S. 1997. Fast and accunlle gcnernldmadependenee It:.\t for dynamic, poinler-based dma l1ow-in>cn~ilive pOiNS'IO ana1y~i~.ln COIiferc,lce Rewrtl'if slruclUrc.,. Sec PLDII1994]. 218-229. I/le ACM !'.)'Jllp".r;WIl rill J'ril1cipl,'.• IJj PmgrWl1IlIing wl/guage.. (Paris. Fr.lJlce. Jan.). 1-14. JAGANNIITH,\N. S .• THIEM liNN. P.• WEEKS, S.. AND WRIGHT. A. 1998. Single :lnd lovins it: Must-:liias analysis for SIMPSON. L, T. 1996. Value·drivcn redundancy cJiminalioll. higher-order langu~ges. Sec Conference Record of the ACM Ph.D. thesis, Rice Univel1iity, Houslon, TCX:L'_ Sympo,;ium on Principle\' of Progr.unm'mg Langu:lges STEENSGIIIIRIJ. B. 1996. Polnl'·lo analysis in almost lInear [1998aJ.329-341. lime. Sec ConfcrenL"C Record ofthe ACM Symposium on LANDI, W. AND RYDER. B. G. 1992, A safe approximme Principles ofProgramllling Languages [1996b]. 32-41. ::llgorilJun for interproccdur,d pointer a1i:L~ing. In Proceedings SunSofl 1997, JUl'I' 011 Solaris 2.6: II Whi,e Pllper. SunSofl. of the ACM Conference on Programming l....lIIguage Design WEG~IAN, M. N, liND ZIIDECK, 1-. K. 1991, Conslam andlmplementmion (S;ln Fr.mciseo. CalIfornia, June).IICM proJX1g~tion Wilh condilional br.lnches. ACM T/lJm, S/GPLIoN Nnrices 27. 7 (July). 235-248. Prograll/. Ln'lg. .'1)','1. 13, 2 (Apr.). 181-210. LANDI, W., RYDER. B, G,. IISD ZIlANG, S. [993. WILSON, R. P. AND LAM. M. S. 1995. Efficient Inlerproccdund moditiemion side elTect analysis Wilh puimer conlCXl-,<;enSlll\'C poinler analysis for c programs. Sec PLDl a1i