Optimization Techniques Code Optimizations High-Level Optimizations Intermediate Code Optimizations

Total Page:16

File Type:pdf, Size:1020Kb

Optimization Techniques Code Optimizations High-Level Optimizations Intermediate Code Optimizations Optimization Techniques Code Optimizations z The most complex component of modern compilers z High-level optimizations z Must always be sound, i.e., semantics-preserving • Operate at a level close to that of source-code • Need to pay attention to exception cases as well • Use a conservative approach: risk missing out optimization rather • Often language-dependent than changing semantics z Intermediate code optimizations z Reduce runtime resource requirements (most of the time)‏ • Usually, runtime, but there are memory optimizations as well • Most optimizations fall here • Runtime optimizations focus on frequently executed code • Typically, language-independent • How to determine what parts are frequently executed? • Assume: loops are executed frequently z Low-level optimizations • Alternative: profile-based optimizations • Some optimizations involve trade-offs, e.g., more memory for • Usually specific to each architecture faster execution z Cost-effective, i.e., benefits of optimization must be worth the effort of its implementation 1 2 High-level optimizations Intermediate code optimizations • Inlining • Common subexpression elimination •Replace function call with the function body • Constant propagation • Partial evaluation • Jump-threading •Statically evaluate those components of a • Loop-invariant code motion program that can be evaluated • Dead-code elimination • Tail recursion elimination • Strength reduction • Loop reordering • Array alignment, padding, layout 3 4 1 Constant Propagation Strength Reduction z Identify expressions that can be evaluated at •Replace expensive operations with equivalent compile time, and replace them with their cheaper (more efficient) ones. values. y = 2; => y = 2; z x = 5; => x = 5; => x = 5; z = x^y; z = x*x; y = 2; y = 2; y = 2; ... ... v = u + y; v = u + y; v = u + 2; •The underlying architecture may determine z = x * y; z = x * y; z = 10; which operations are cheaper and which w = v + z + 2; w = v + z + 2; w = v + 12; ones are more expensive. ... ... ... 5 6 Loop-Invariant Code Motion Low-level Optimizations •Move code whose effect is independent of • Register allocation the loop's iteration outside the loop. • Instruction Scheduling for pipelined machines. for (i=0; i<N; i++) { => for (i=0; i<N; i++) { • loop unrolling for (j=0; j<N; i++) { base = a + (i * dim1); • instruction reordering ... a[i][j] ... for (j=0; j<N; i++) { ... (base + j) ... • delay slot filling • Utilizing features of specialized components, e.g., floating-point units. • Branch Prediction 7 8 2 Peephole Optimization Profile-based Optimization • Optimizations that examine small code sections at a time, • A compiler has difficulty in predicting: and transform them • likely outcome of branches • Peephole: a small, moving window in the target program • functions and/or loops that are most frequently • Much simpler to implement than global optimizations executed • Typically applied at machine code, and some times at • sizes of arrays intermediate code level as well • or more generally, any thing that depends on • Any optimization can be a peephole optimization, dynamic rogram behavior. provided it operates on the code within the peephole. • Runtime profiles can provide this missing information, • redundant instruction elimination making it easier for compilers to decide when certain • flow-of control optimizations • algebraic simplifications • ... 9 10 Example Program: Quicksort 3-address code for Quicksort z Most optimizations opportunities arise in intermediate code • Several aspects of execution (e.g., address calculation for array access) aren’t exposed in source code z Explicit representations provide most opportunities for optimization z It is best for programmers to focus on writing readable code, leaving simple optimizations to a compiler 11 12 3 Organization of Optimizer Flow Graph for Quicksort z B1,…,B6 are basic blocks • sequence of statements where control enters at beginning, with no branches in the middle z Possible optimizations • Common subexpression elimination (CSE)‏ • Copy propagation • Generalization of constant folding to handle assignments of the form x = y • Dead code elimination • Loop optimizations • Code motion • Strength reduction • Induction variable elimination 13 14 Common Subexpression Elimination Copy Propagation z Expression z Consider x = y; previously z = x*u; computed w = y*u; Clearly, we can replace z Values of all assignment on w by variables in w = z z This requires recognition of expression have cases where multiple variables not changed. have same value (i.e., they are copies of each other)‏ z Based on z One optimization may expose available opportunities for another • Even the simplest expressions optimizations can pay off analysis • Need to iterate optimizations a few times 15 16 4 Induction Vars, Strength Reduction Dead Code Elimination and IV Elimination z Dead variable: a z Induction Var: a variable whose value variable whose value is changes in lock-step with a loop index no longer used z If expensive operations are used for z Live variable: opposite of dead variable computing IV values, they can be replaced by less expensive operations z Dead code: a statement that assigns to a dead z When there are multiple IVs, some can be variable eliminated z Copy propagation turns copy statement into dead code. 17 18 Strength Reduction on IVs After IV Elimination … 19 20 5 Program Analysis Applications of Program Analysis z Compiler optimization z Optimization is usually expressed as a z Debugging/Bug-finding program transformation • “Enhanced” type checking C ⇔ C when property P holds • Use before assign 1 2 • Null pointer dereference z Whether property P holds is determined by a • Returning pointer to stack-allocated data z Vulnerability analysis/mitigation program analysis • Information flow analysis • Detect propagation of sensitive data, e.g., passwords z Most program properties are undecidable in • Detect use of untrustworthy data in security-critical context general • Find potential buffer overflows • Solution: Relax the problem so that the answer is z Testing – automatic generation of test cases z Verification: Show that program satisfies a specified an “yes” or “don’t know” property, e.g., no deadlocks • model-checking 21 22 Dataflow Analysis Dataflow Analysis zAnswers questions relating to how data flows z Equations typically of the form through a program out[S] = gen[S] ∪ (in[S] – kill[S]) • What can be asserted about the value of a variable (or where the definitions of out, gen, in and kill more generally, an expression) at a program point differ for different analysis zExamples z When statements have multiple • Reaching definitions: which assignments reach a program statement predecessors, the equations have to be • Available expressions modified accordingly • Live variables z Procedure calls, pointers and arrays require • Dead code careful treatment • … 23 24 6 Points and Paths Reaching Definitions z A definition of a variable x is a statement that assigns to x • Ambiguous definition: In the presence of aliasing, a statement may define a variable, but it may be impossible to determine this for sure. z A definition d reaches a point p provided: • There is a path from d to p, and this definition is not “killed” along p • “Kill” means an unambiguous redefinition z Ambiguity Î approximation • Need to ensure that approximation is in the right direction, so that the analysis will be sound 25 26 DFA of Structured Programs DF Equations for Reaching Defns z S Æ id := E | S;S | if E then S else S | do S while E z E Æ E + E | id 27 28 7 DF Equations for Reaching Defns Direction of Approximation z Actual kill is a superset of the set computed by the dataflow equations z Actual gen is a subset of the set computed by these equations z Are other choices possible? • Subset approximation of kill, superset approximation of gen • Subset approximation of both • Superset approximation of both z Which approximation is suitable depends on the intended use of analysis results 29 30 Solving Dataflow Equations Computing Fixpoints: Equation for Loop z Dataflow equations are recursive z Rewrite equations using more compact notation, with: J standing for in[S] and z Need to compute so-called fixpoints, to solve I, G, K, and O for in[S1], gen[S1], kill[S1] and out[S1]: I = J ∪ O, these equations O = G ∪ (I – K) z Fixpoint computations uses an interative z Letting I0 = O0 = φ, we have: I1 = J O1 = G ∪ (I0 – K) = G procedure I2 = J ∪ O1 = J ∪ G O2 = G ∪ (I1 – K) = G ∪ (J – K) out0 = φ I3 = J ∪ O2 O3 = G ∪ (I2 – K) • = J ∪ G ∪ (J – K)= G ∪ (J ∪ G – K) i = J ∪ G = I2 = G ∪ (J – K) = O2 • out is computed using the equations by (Note that for all sets A and B, A U (A-B) = A, and i-1 substituting out for occurrences of out on the rhs for all sets A, B and C, A U (A U C –B) = A U (C-B).) Thus, we have a fixpoint. • Fixpoint is a solution, i.e., outi = outi-1 31 32 8 Use-Definition Chains Available Expressions z Convenient way to represent reaching z An expression e is available at point p if definition information • every path to p evaluates e • none of the variables in e are assigned after last z ud-chain for a variable links each use of the computation of e variable to its reaching definitions z A block kills e if it assigns to some variable in e and does not recompute e. • One list for each use of a variable z A block generates e if it computes e and doesn’t subsequently assign to variables in e z Exercise: Set up data-flow equations for available expressions. Give an example use for which your equations are sound, and another example for which they aren’t 33 34 Available expressions -- Example Live Variable Analysis z A variable x is live at a program point p if the a := b+c value of x is used in some path from p z Otherwise, x is dead.
Recommended publications
  • A Methodology for Assessing Javascript Software Protections
    A methodology for Assessing JavaScript Software Protections Pedro Fortuna A methodology for Assessing JavaScript Software Protections Pedro Fortuna About me Pedro Fortuna Co-Founder & CTO @ JSCRAMBLER OWASP Member SECURITY, JAVASCRIPT @pedrofortuna 2 A methodology for Assessing JavaScript Software Protections Pedro Fortuna Agenda 1 4 7 What is Code Protection? Testing Resilience 2 5 Code Obfuscation Metrics Conclusions 3 6 JS Software Protections Q & A Checklist 3 What is Code Protection Part 1 A methodology for Assessing JavaScript Software Protections Pedro Fortuna Intellectual Property Protection Legal or Technical Protection? Alice Bob Software Developer Reverse Engineer Sells her software over the Internet Wants algorithms and data structures Does not need to revert back to original source code 5 A methodology for Assessing JavaScript Software Protections Pedro Fortuna Intellectual Property IP Protection Protection Legal Technical Encryption ? Trusted Computing Server-Side Execution Obfuscation 6 A methodology for Assessing JavaScript Software Protections Pedro Fortuna Code Obfuscation Obfuscation “transforms a program into a form that is more difficult for an adversary to understand or change than the original code” [1] More Difficult “requires more human time, more money, or more computing power to analyze than the original program.” [1] in Collberg, C., and Nagra, J., “Surreptitious software: obfuscation, watermarking, and tamperproofing for software protection.”, Addison- Wesley Professional, 2010. 7 A methodology for Assessing
    [Show full text]
  • Generalized Jump Threading in Libfirm
    Institut für Programmstrukturen und Datenorganisation (IPD) Lehrstuhl Prof. Dr.-Ing. Snelting Generalized Jump Threading in libFIRM Masterarbeit von Joachim Priesner an der Fakultät für Informatik Erstgutachter: Prof. Dr.-Ing. Gregor Snelting Zweitgutachter: Prof. Dr.-Ing. Jörg Henkel Betreuender Mitarbeiter: Dipl.-Inform. Andreas Zwinkau Bearbeitungszeit: 5. Oktober 2016 – 23. Januar 2017 KIT – Die Forschungsuniversität in der Helmholtz-Gemeinschaft www.kit.edu Zusammenfassung/Abstract Jump Threading (dt. „Sprünge fädeln“) ist eine Compileroptimierung, die statisch vorhersagbare bedingte Sprünge in unbedingte Sprünge umwandelt. Bei der Ausfüh- rung kann ein Prozessor bedingte Sprünge zunächst nur heuristisch mit Hilfe der Sprungvorhersage auswerten. Sie stellen daher generell ein Performancehindernis dar. Die Umwandlung ist insbesondere auch dann möglich, wenn das Sprungziel nur auf einer Teilmenge der zu dem Sprung führenden Ausführungspfade statisch be- stimmbar ist. In diesem Fall, der den überwiegenden Teil der durch Jump Threading optimierten Sprünge betrifft, muss die Optimierung Grundblöcke duplizieren, um jene Ausführungspfade zu isolieren. Verschiedene aktuelle Compiler enthalten sehr unterschiedliche Implementierungen von Jump Threading. In dieser Masterarbeit wird zunächst ein theoretischer Rahmen für Jump Threading vorgestellt. Sodann wird eine allgemeine Fassung eines Jump- Threading-Algorithmus entwickelt, implementiert und in diverser Hinsicht untersucht, insbesondere auf Wechselwirkungen mit anderen Optimierungen wie If
    [Show full text]
  • Attacking Client-Side JIT Compilers.Key
    Attacking Client-Side JIT Compilers Samuel Groß (@5aelo) !1 A JavaScript Engine Parser JIT Compiler Interpreter Runtime Garbage Collector !2 A JavaScript Engine • Parser: entrypoint for script execution, usually emits custom Parser bytecode JIT Compiler • Bytecode then consumed by interpreter or JIT compiler • Executing code interacts with the Interpreter runtime which defines the Runtime representation of various data structures, provides builtin functions and objects, etc. Garbage • Garbage collector required to Collector deallocate memory !3 A JavaScript Engine • Parser: entrypoint for script execution, usually emits custom Parser bytecode JIT Compiler • Bytecode then consumed by interpreter or JIT compiler • Executing code interacts with the Interpreter runtime which defines the Runtime representation of various data structures, provides builtin functions and objects, etc. Garbage • Garbage collector required to Collector deallocate memory !4 A JavaScript Engine • Parser: entrypoint for script execution, usually emits custom Parser bytecode JIT Compiler • Bytecode then consumed by interpreter or JIT compiler • Executing code interacts with the Interpreter runtime which defines the Runtime representation of various data structures, provides builtin functions and objects, etc. Garbage • Garbage collector required to Collector deallocate memory !5 A JavaScript Engine • Parser: entrypoint for script execution, usually emits custom Parser bytecode JIT Compiler • Bytecode then consumed by interpreter or JIT compiler • Executing code interacts with the Interpreter runtime which defines the Runtime representation of various data structures, provides builtin functions and objects, etc. Garbage • Garbage collector required to Collector deallocate memory !6 Agenda 1. Background: Runtime Parser • Object representation and Builtins JIT Compiler 2. JIT Compiler Internals • Problem: missing type information • Solution: "speculative" JIT Interpreter 3.
    [Show full text]
  • Equality Saturation: a New Approach to Optimization
    Logical Methods in Computer Science Vol. 7 (1:10) 2011, pp. 1–37 Submitted Oct. 12, 2009 www.lmcs-online.org Published Mar. 28, 2011 EQUALITY SATURATION: A NEW APPROACH TO OPTIMIZATION ROSS TATE, MICHAEL STEPP, ZACHARY TATLOCK, AND SORIN LERNER Department of Computer Science and Engineering, University of California, San Diego e-mail address: {rtate,mstepp,ztatlock,lerner}@cs.ucsd.edu Abstract. Optimizations in a traditional compiler are applied sequentially, with each optimization destructively modifying the program to produce a transformed program that is then passed to the next optimization. We present a new approach for structuring the optimization phase of a compiler. In our approach, optimizations take the form of equality analyses that add equality information to a common intermediate representation. The op- timizer works by repeatedly applying these analyses to infer equivalences between program fragments, thus saturating the intermediate representation with equalities. Once saturated, the intermediate representation encodes multiple optimized versions of the input program. At this point, a profitability heuristic picks the final optimized program from the various programs represented in the saturated representation. Our proposed way of structuring optimizers has a variety of benefits over previous approaches: our approach obviates the need to worry about optimization ordering, enables the use of a global optimization heuris- tic that selects among fully optimized programs, and can be used to perform translation validation, even on compilers other than our own. We present our approach, formalize it, and describe our choice of intermediate representation. We also present experimental results showing that our approach is practical in terms of time and space overhead, is effective at discovering intricate optimization opportunities, and is effective at performing translation validation for a realistic optimizer.
    [Show full text]
  • CS153: Compilers Lecture 19: Optimization
    CS153: Compilers Lecture 19: Optimization Stephen Chong https://www.seas.harvard.edu/courses/cs153 Contains content from lecture notes by Steve Zdancewic and Greg Morrisett Announcements •HW5: Oat v.2 out •Due in 2 weeks •HW6 will be released next week •Implementing optimizations! (and more) Stephen Chong, Harvard University 2 Today •Optimizations •Safety •Constant folding •Algebraic simplification • Strength reduction •Constant propagation •Copy propagation •Dead code elimination •Inlining and specialization • Recursive function inlining •Tail call elimination •Common subexpression elimination Stephen Chong, Harvard University 3 Optimizations •The code generated by our OAT compiler so far is pretty inefficient. •Lots of redundant moves. •Lots of unnecessary arithmetic instructions. •Consider this OAT program: int foo(int w) { var x = 3 + 5; var y = x * w; var z = y - 0; return z * 4; } Stephen Chong, Harvard University 4 Unoptimized vs. Optimized Output .globl _foo _foo: •Hand optimized code: pushl %ebp movl %esp, %ebp _foo: subl $64, %esp shlq $5, %rdi __fresh2: movq %rdi, %rax leal -64(%ebp), %eax ret movl %eax, -48(%ebp) movl 8(%ebp), %eax •Function foo may be movl %eax, %ecx movl -48(%ebp), %eax inlined by the compiler, movl %ecx, (%eax) movl $3, %eax so it can be implemented movl %eax, -44(%ebp) movl $5, %eax by just one instruction! movl %eax, %ecx addl %ecx, -44(%ebp) leal -60(%ebp), %eax movl %eax, -40(%ebp) movl -44(%ebp), %eax Stephen Chong,movl Harvard %eax,University %ecx 5 Why do we need optimizations? •To help programmers… •They write modular, clean, high-level programs •Compiler generates efficient, high-performance assembly •Programmers don’t write optimal code •High-level languages make avoiding redundant computation inconvenient or impossible •e.g.
    [Show full text]
  • Quaxe, Infinity and Beyond
    Quaxe, infinity and beyond Daniel Glazman — WWX 2015 /usr/bin/whoami Primary architect and developer of the leading Web and Ebook editors Nvu and BlueGriffon Former member of the Netscape CSS and Editor engineering teams Involved in Internet and Web Standards since 1990 Currently co-chair of CSS Working Group at W3C New-comer in the Haxe ecosystem Desktop Frameworks Visual Studio (Windows only) Xcode (OS X only) Qt wxWidgets XUL Adobe Air Mobile Frameworks Adobe PhoneGap/Air Xcode (iOS only) Qt Mobile AppCelerator Visual Studio Two solutions but many issues Fragmentation desktop/mobile Heavy runtimes Can’t easily reuse existing c++ libraries Complex to have native-like UI Qt/QtMobile still require c++ Qt’s QML is a weak and convoluted UI language Haxe 9 years success of Multiplatform OSS language Strong affinity to gaming Wide and vibrant community Some press recognition Dead code elimination Compiles to native on all But no native GUI… platforms through c++ and java Best of all worlds Haxe + Qt/QtMobile Multiplatform Native apps, native performance through c++/Java C++/Java lib reusability Introducing Quaxe Native apps w/o c++ complexity Highly dynamic applications on desktop and mobile Native-like UI through Qt HTML5-based UI, CSS-based styling Benefits from Haxe and Qt communities Going from HTML5 to native GUI completeness DOM dynamism in native UI var b: Element = document.getElementById("thirdButton"); var t: Element = document.createElement("input"); t.setAttribute("type", "text"); t.setAttribute("value", "a text field"); b.parentNode.insertBefore(t,
    [Show full text]
  • 9. Optimization
    9. Optimization Marcus Denker Optimization Roadmap > Introduction > Optimizations in the Back-end > The Optimizer > SSA Optimizations > Advanced Optimizations © Marcus Denker 2 Optimization Roadmap > Introduction > Optimizations in the Back-end > The Optimizer > SSA Optimizations > Advanced Optimizations © Marcus Denker 3 Optimization Optimization: The Idea > Transform the program to improve efficiency > Performance: faster execution > Size: smaller executable, smaller memory footprint Tradeoffs: 1) Performance vs. Size 2) Compilation speed and memory © Marcus Denker 4 Optimization No Magic Bullet! > There is no perfect optimizer > Example: optimize for simplicity Opt(P): Smallest Program Q: Program with no output, does not stop Opt(Q)? © Marcus Denker 5 Optimization No Magic Bullet! > There is no perfect optimizer > Example: optimize for simplicity Opt(P): Smallest Program Q: Program with no output, does not stop Opt(Q)? L1 goto L1 © Marcus Denker 6 Optimization No Magic Bullet! > There is no perfect optimizer > Example: optimize for simplicity Opt(P): Smallest ProgramQ: Program with no output, does not stop Opt(Q)? L1 goto L1 Halting problem! © Marcus Denker 7 Optimization Another way to look at it... > Rice (1953): For every compiler there is a modified compiler that generates shorter code. > Proof: Assume there is a compiler U that generates the shortest optimized program Opt(P) for all P. — Assume P to be a program that does not stop and has no output — Opt(P) will be L1 goto L1 — Halting problem. Thus: U does not exist. > There will
    [Show full text]
  • Scalable Conditional Induction Variables (CIV) Analysis
    Scalable Conditional Induction Variables (CIV) Analysis ifact Cosmin E. Oancea Lawrence Rauchwerger rt * * Comple A t te n * A te s W i E * s e n l C l o D C O Department of Computer Science Department of Computer Science and Engineering o * * c u e G m s E u e C e n R t v e o d t * y * s E University of Copenhagen Texas A & M University a a l d u e a [email protected] [email protected] t Abstract k = k0 Ind. k = k0 DO i = 1, N DO i =1,N Var. DO i = 1, N IF(cond(b(i)))THEN Subscripts using induction variables that cannot be ex- k = k+2 ) a(k0+2*i)=.. civ = civ+1 )? pressed as a formula in terms of the enclosing-loop indices a(k)=.. Sub. ENDDO a(civ) = ... appear in the low-level implementation of common pro- ENDDO k=k0+MAX(2N,0) ENDIF ENDDO gramming abstractions such as filter, or stack operations and (a) (b) (c) pose significant challenges to automatic parallelization. Be- Figure 1. Loops with affine and CIV array accesses. cause the complexity of such induction variables is often due to their conditional evaluation across the iteration space of its closed-form equivalent k0+2*i, which enables its in- loops we name them Conditional Induction Variables (CIV). dependent evaluation by all iterations. More importantly, This paper presents a flow-sensitive technique that sum- the resulted code, shown in Figure 1(b), allows the com- marizes both such CIV-based and affine subscripts to pro- piler to verify that the set of points written by any dis- gram level, using the same representation.
    [Show full text]
  • Induction Variable Analysis with Delayed Abstractions1
    Induction Variable Analysis with Delayed Abstractions1 SEBASTIAN POP, and GEORGES-ANDRE´ SILBER CRI, Mines Paris, France and ALBERT COHEN ALCHEMY group, INRIA Futurs, Orsay, France We present the design of an induction variable analyzer suitable for the analysis of typed, low-level, three address representations in SSA form. At the heart of our analyzer stands a new algorithm that recognizes scalar evolutions. We define a representation called trees of recurrences that is able to capture different levels of abstractions: from the finer level that is a subset of the SSA representation restricted to arithmetic operations on scalar variables, to the coarser levels such as the evolution envelopes that abstract sets of possible evolutions in loops. Unlike previous work, our algorithm tracks induction variables without prior classification of a few evolution patterns: different levels of abstraction can be obtained on demand. The low complexity of the algorithm fits the constraints of a production compiler as illustrated by the evaluation of our implementation on standard benchmark programs. Categories and Subject Descriptors: D.3.4 [Programming Languages]: Processors—compilers, interpreters, optimization, retargetable compilers; F.3.2 [Logics and Meanings of Programs]: Semantics of Programming Languages—partial evaluation, program analysis General Terms: Compilers Additional Key Words and Phrases: Scalar evolutions, static analysis, static single assignment representation, assessing compilers heuristics regressions. 1Extension of Conference Paper:
    [Show full text]
  • Control Flow Analysis in Scheme
    Control Flow Analysis in Scheme Olin Shivers Carnegie Mellon University [email protected] Abstract Fortran). Representative texts describing these techniques are [Dragon], and in more detail, [Hecht]. Flow analysis is perhaps Traditional ¯ow analysis techniques, such as the ones typically the chief tool in the optimising compiler writer's bag of tricks; employed by optimising Fortran compilers, do not work for an incomplete list of the problems that can be addressed with Scheme-like languages. This paper presents a ¯ow analysis ¯ow analysis includes global constant subexpression elimina- technique Ð control ¯ow analysis Ð which is applicable to tion, loop invariant detection, redundant assignment detection, Scheme-like languages. As a demonstration application, the dead code elimination, constant propagation, range analysis, information gathered by control ¯ow analysis is used to per- code hoisting, induction variable elimination, copy propaga- form a traditional ¯ow analysis problem, induction variable tion, live variable analysis, loop unrolling, and loop jamming. elimination. Extensions and limitations are discussed. However, these traditional ¯ow analysis techniques have The techniques presented in this paper are backed up by never successfully been applied to the Lisp family of computer working code. They are applicable not only to Scheme, but languages. This is a curious omission. The Lisp community also to related languages, such as Common Lisp and ML. has had suf®cient time to consider the problem. Flow analysis dates back at least to 1960, ([Dragon], pp. 516), and Lisp is 1 The Task one of the oldest computer programming languages currently in use, rivalled only by Fortran and COBOL. Flow analysis is a traditional optimising compiler technique Indeed, the Lisp community has long been concerned with for determining useful information about a program at compile the execution speed of their programs.
    [Show full text]
  • Value Numbering
    SOFTWARE—PRACTICE AND EXPERIENCE, VOL. 0(0), 1–18 (MONTH 1900) Value Numbering PRESTON BRIGGS Tera Computer Company, 2815 Eastlake Avenue East, Seattle, WA 98102 AND KEITH D. COOPER L. TAYLOR SIMPSON Rice University, 6100 Main Street, Mail Stop 41, Houston, TX 77005 SUMMARY Value numbering is a compiler-based program analysis method that allows redundant computations to be removed. This paper compares hash-based approaches derived from the classic local algorithm1 with partitioning approaches based on the work of Alpern, Wegman, and Zadeck2. Historically, the hash-based algorithm has been applied to single basic blocks or extended basic blocks. We have improved the technique to operate over the routine’s dominator tree. The partitioning approach partitions the values in the routine into congruence classes and removes computations when one congruent value dominates another. We have extended this technique to remove computations that define a value in the set of available expressions (AVA IL )3. Also, we are able to apply a version of Morel and Renvoise’s partial redundancy elimination4 to remove even more redundancies. The paper presents a series of hash-based algorithms and a series of refinements to the partitioning technique. Within each series, it can be proved that each method discovers at least as many redundancies as its predecessors. Unfortunately, no such relationship exists between the hash-based and global techniques. On some programs, the hash-based techniques eliminate more redundancies than the partitioning techniques, while on others, partitioning wins. We experimentally compare the improvements made by these techniques when applied to real programs. These results will be useful for commercial compiler writers who wish to assess the potential impact of each technique before implementation.
    [Show full text]
  • Language and Compiler Support for Dynamic Code Generation by Massimiliano A
    Language and Compiler Support for Dynamic Code Generation by Massimiliano A. Poletto S.B., Massachusetts Institute of Technology (1995) M.Eng., Massachusetts Institute of Technology (1995) Submitted to the Department of Electrical Engineering and Computer Science in partial fulfillment of the requirements for the degree of Doctor of Philosophy at the MASSACHUSETTS INSTITUTE OF TECHNOLOGY September 1999 © Massachusetts Institute of Technology 1999. All rights reserved. A u th or ............................................................................ Department of Electrical Engineering and Computer Science June 23, 1999 Certified by...............,. ...*V .,., . .* N . .. .*. *.* . -. *.... M. Frans Kaashoek Associate Pro essor of Electrical Engineering and Computer Science Thesis Supervisor A ccepted by ................ ..... ............ ............................. Arthur C. Smith Chairman, Departmental CommitteA on Graduate Students me 2 Language and Compiler Support for Dynamic Code Generation by Massimiliano A. Poletto Submitted to the Department of Electrical Engineering and Computer Science on June 23, 1999, in partial fulfillment of the requirements for the degree of Doctor of Philosophy Abstract Dynamic code generation, also called run-time code generation or dynamic compilation, is the cre- ation of executable code for an application while that application is running. Dynamic compilation can significantly improve the performance of software by giving the compiler access to run-time infor- mation that is not available to a traditional static compiler. A well-designed programming interface to dynamic compilation can also simplify the creation of important classes of computer programs. Until recently, however, no system combined efficient dynamic generation of high-performance code with a powerful and portable language interface. This thesis describes a system that meets these requirements, and discusses several applications of dynamic compilation.
    [Show full text]