scispace - formally typeset
Search or ask a question
Journal ArticleDOI

Combining analyses, combining optimizations

01 Mar 1995-ACM Transactions on Programming Languages and Systems (ACM)-Vol. 17, Iss: 2, pp 181-196
TL;DR: This article presents a framework for combining constant propagation, value numbering, and unreachable-code elimination, and shows how to combine two such frameworks and how to reason about the properties of the resulting framework.
Abstract: Modern optimizing compilers use several passes over a program's intermediate representation to generate good code. Many of these optimizations exhibit a phase-ordering problem. Getting the best code may require iterating optimizations until a fixed point is reached. Combining these phases can lead to the discovery of more facts about the program, exposing more opportunities for optimization. This article presents a framework for describing optimizations. It shows how to combine two such frameworks and how to reason about the properties of the resulting framework. The structure of the frame work provides insight into when a combination yields better results. To make the ideas more concrete, this article presents a framework for combining constant propagation, value numbering, and unreachable-code elimination. It is an open question as to what other frameworks can be combined in this way.

Content maybe subject to copyright    Report






Citations
More filters
23 Apr 2001
TL;DR: The Java HotSpotTM Server Compiler achieves improved asymptotic performance through a combination of object-oriented and classical-compiler optimizations.
Abstract: The Java HotSpotTM Server Compiler achieves improved asymptotic performance through a combination of object-oriented and classical-compiler optimizations. Aggressive inlining using class-hierarchy analysis reduces function call overhead and provides opportunities for many compiler optimizations.

300 citations

Proceedings ArticleDOI
01 May 1996
TL;DR: This work targets general- purpose, imperative programming languages, initially C, and strives for both fast dynamic compilation and high-quality dynamically-compiled code.
Abstract: Dynamic compilation enables optimization based on the values of invariant data computed at run-time. Using the values of these run-time constants, a dynamic compiler can eliminate their memory loads, perform constant propagation and folding, remove branches they determine, and fully unroll loops they bound. However, the performance benefits of the more efficient, dynamically-compiled code are offset by the run-time cost of the dynamic compile. Our approach to dynamic compilation strives for both fast dynamic compilation and high-quality dynamically-compiled code: the programmer annotates regions of the programs that should be compiled dynamically; a static, optimizing compiler automatically produces pre-optimized machine-code templates, using a pair of dataflow analyses that identify which variables will be constant at run-time; and a simple, dynamic compiler copies the templates, patching in the computed values of the run-time constants, to produce optimized, executable code. Our work targets general- purpose, imperative programming languages, initially C. Initial experiments applying dynamic compilation to C programs have produced speedups ranging from 1.2 to 1.8.

203 citations

Proceedings ArticleDOI
27 Feb 2021
TL;DR: MLIR as discussed by the authors is an approach to building reusable and extensible compiler infrastructure that facilitates the design and implementation of code generators, translators and optimizers at different levels of abstraction and across application domains, hardware targets and execution environments.
Abstract: This work presents MLIR, a novel approach to building reusable and extensible compiler infrastructure. MLIR addresses software fragmentation, compilation for heterogeneous hardware, significantly reducing the cost of building domain specific compilers, and connecting existing compilers together. MLIR facilitates the design and implementation of code generators, translators and optimizers at different levels of abstraction and across application domains, hardware targets and execution environments. The contribution of this work includes (1) discussion of MLIR as a research artifact, built for extension and evolution, while identifying the challenges and opportunities posed by this novel design, semantics, optimization specification, system, and engineering. (2) evaluation of MLIR as a generalized infrastructure that reduces the cost of building compilers---describing diverse use-cases to show research and educational opportunities for future programming languages, compilers, execution environments, and computer architecture. The paper also presents the rationale for MLIR, its original design principles, structures and semantics.

162 citations

Proceedings ArticleDOI
Cliff Click1
01 Jun 1995
TL;DR: This paper argues that optimizing compilers should treat the machine-independent optimizations (e.g., conditional constant propagation, global value numbering) and code motion issues separately, which allows stronger optimizations using simpler algorithms.
Abstract: We believe that optimizing compilers should treat the machine-independent optimizations (e.g., conditional constant propagation, global value numbering) and code motion issues separately.’ Removing the code motion requirements from the machine-independent optimization allows stronger optimizations using simpler algorithms. Preserving a legal schedule is one of the prime sources of complexity in algorithms like PRE [18, 13] or global congruence finding [2, 20].

158 citations

Proceedings ArticleDOI
01 Oct 1996
TL;DR: The Vortex compiler infrastructure is developed, a language-independent optimizing compiler for object-oriented languages, with front-ends for Cecil, C++, Java, and Modula-3, and the results of experiments assessing the effectiveness of different combinations of optimizations on sizable applications across these four languages are reported.
Abstract: Previously, techniques such as class hierarchy analysis and profile-guided receiver class prediction have been demonstrated to greatly improve the performance of applications written in pure object-oriented languages, but the degree to which these results are transferable to applications written in hybrid languages has been unclear. In part to answer this question, we have developed the Vortex compiler infrastructure, a language-independent optimizing compiler for object-oriented languages, with front-ends for Cecil, C++, Java, and Modula-3. In this paper, we describe the Vortex compiler's intermediate language, internal structure, and optimization suite, and then we report the results of experiments assessing the effectiveness of different combinations of optimizations on sizable applications across these four languages. We characterize the benchmark programs in terms of a collection of static and dynamic metrics, intended to quantify aspects of the "object-orientedness" of a program.

154 citations

References
More filters
Book
01 Jan 1986
TL;DR: This book discusses the design of a Code Generator, the role of the Lexical Analyzer, and other topics related to code generation and optimization.
Abstract: 1 Introduction 1.1 Language Processors 1.2 The Structure of a Compiler 1.3 The Evolution of Programming Languages 1.4 The Science of Building a Compiler 1.5 Applications of Compiler Technology 1.6 Programming Language Basics 1.7 Summary of Chapter 1 1.8 References for Chapter 1 2 A Simple Syntax-Directed Translator 2.1 Introduction 2.2 Syntax Definition 2.3 Syntax-Directed Translation 2.4 Parsing 2.5 A Translator for Simple Expressions 2.6 Lexical Analysis 2.7 Symbol Tables 2.8 Intermediate Code Generation 2.9 Summary of Chapter 2 3 Lexical Analysis 3.1 The Role of the Lexical Analyzer 3.2 Input Buffering 3.3 Specification of Tokens 3.4 Recognition of Tokens 3.5 The Lexical-Analyzer Generator Lex 3.6 Finite Automata 3.7 From Regular Expressions to Automata 3.8 Design of a Lexical-Analyzer Generator 3.9 Optimization of DFA-Based Pattern Matchers 3.10 Summary of Chapter 3 3.11 References for Chapter 3 4 Syntax Analysis 4.1 Introduction 4.2 Context-Free Grammars 4.3 Writing a Grammar 4.4 Top-Down Parsing 4.5 Bottom-Up Parsing 4.6 Introduction to LR Parsing: Simple LR 4.7 More Powerful LR Parsers 4.8 Using Ambiguous Grammars 4.9 Parser Generators 4.10 Summary of Chapter 4 4.11 References for Chapter 4 5 Syntax-Directed Translation 5.1 Syntax-Directed Definitions 5.2 Evaluation Orders for SDD's 5.3 Applications of Syntax-Directed Translation 5.4 Syntax-Directed Translation Schemes 5.5 Implementing L-Attributed SDD's 5.6 Summary of Chapter 5 5.7 References for Chapter 5 6 Intermediate-Code Generation 6.1 Variants of Syntax Trees 6.2 Three-Address Code 6.3 Types and Declarations 6.4 Translation of Expressions 6.5 Type Checking 6.6 Control Flow 6.7 Backpatching 6.8 Switch-Statements 6.9 Intermediate Code for Procedures 6.10 Summary of Chapter 6 6.11 References for Chapter 6 7 Run-Time Environments 7.1 Storage Organization 7.2 Stack Allocation of Space 7.3 Access to Nonlocal Data on the Stack 7.4 Heap Management 7.5 Introduction to Garbage Collection 7.6 Introduction to Trace-Based Collection 7.7 Short-Pause Garbage Collection 7.8 Advanced Topics in Garbage Collection 7.9 Summary of Chapter 7 7.10 References for Chapter 7 8 Code Generation 8.1 Issues in the Design of a Code Generator 8.2 The Target Language 8.3 Addresses in the Target Code 8.4 Basic Blocks and Flow Graphs 8.5 Optimization of Basic Blocks 8.6 A Simple Code Generator 8.7 Peephole Optimization 8.8 Register Allocation and Assignment 8.9 Instruction Selection by Tree Rewriting 8.10 Optimal Code Generation for Expressions 8.11 Dynamic Programming Code-Generation 8.12 Summary of Chapter 8 8.13 References for Chapter 8 9 Machine-Independent Optimizations 9.1 The Principal Sources of Optimization 9.2 Introduction to Data-Flow Analysis 9.3 Foundations of Data-Flow Analysis 9.4 Constant Propagation 9.5 Partial-Redundancy Elimination 9.6 Loops in Flow Graphs 9.7 Region-Based Analysis 9.8 Symbolic Analysis 9.9 Summary of Chapter 9 9.10 References for Chapter 9 10 Instruction-Level Parallelism 10.1 Processor Architectures 10.2 Code-Scheduling Constraints 10.3 Basic-Block Scheduling 10.4 Global Code Scheduling 10.5 Software Pipelining 10.6 Summary of Chapter 10 10.7 References for Chapter 10 11 Optimizing for Parallelism and Locality 11.1 Basic Concepts 11.2 Matrix Multiply: An In-Depth Example 11.3 Iteration Spaces 11.4 Affine Array Indexes 11.5 Data Reuse 11.6 Array Data-Dependence Analysis 11.7 Finding Synchronization-Free Parallelism 11.8 Synchronization Between Parallel Loops 11.9 Pipelining 11.10 Locality Optimizations 11.11 Other Uses of Affine Transforms 11.12 Summary of Chapter 11 11.13 References for Chapter 11 12 Interprocedural Analysis 12.1 Basic Concepts 12.2 Why Interprocedural Analysis? 12.3 A Logical Representation of Data Flow 12.4 A Simple Pointer-Analysis Algorithm 12.5 Context-Insensitive Interprocedural Analysis 12.6 Context-Sensitive Pointer Analysis 12.7 Datalog Implementation by BDD's 12.8 Summary of Chapter 12 12.9 References for Chapter 12 A A Complete Front End A.1 The Source Language A.2 Main A.3 Lexical Analyzer A.4 Symbol Tables and Types A.5 Intermediate Code for Expressions A.6 Jumping Code for Boolean Expressions A.7 Intermediate Code for Statements A.8 Parser A.9 Creating the Front End B Finding Linearly Independent Solutions Index

8,437 citations


"Combining analyses, combining optim..." refers background or methods in this paper

  • ...EndBlock( Node *end ) { // Find the block ended by Node end if( end→visit ) return; // Already visited this basic block end→visit := TRUE; // Mark as visited Node *start := end→control; // Find the control source for end if( start→Name ≠ RegionNode::Name ) { // If the block will not start with a Region RegionNode *r := new RegionNode; // Make a new RegionNode r→in1 := start; // Its one input is the original control src end→control := r; // The block-ending Node use the new ctrl start := r; // Now we have a Region to start the blk } Block *b := new Block( start, end ); // Make a basic block, using the Region start→block := b; // Record RegionNode’s block in the Region int max := start→incnt(); // Input count to the RegionNode for( int i := 1; i<max; i++ ) { // For all control inputs to the Region Node *c := (*start)[i]; // Get ith control input Node *d := (c→Name = ProjNode::Name) ? (*c)[1] : c; // Skip thru Projections if( d→Name = RegionNode::Name || // Back-to-back RegionNodes (d→Name = IfNode::Name && max > 2) ) {// or control-dependent block d := new JumpNode( c ); // New block ending Node *p := new ProjNode( d ); // Projection from the Jump (*start)[i] := p; // Get control from the Jump’s projection } EndBlock( d ); // Recurse on the incoming block ender AddCFGEdge( d→control→block, b );// Add CFG edge from d’s block to block b } }...

    [...]

  • ...A better method is to record use-def chains with each quad [32, 1]....

    [...]

  • ...This occurs because the two optimizations, constant propagation and unreachable code elimination, interact; they exhibit a phase-ordering problem [1]....

    [...]

  • ...then schedule it } if( n→control ) return; // Exit if we were a root Block *b := (*n)[1]→control→block; // Get block of 1st input for( i := 2; i<max; i++ ) { // For all remaining inputs Block *inb := (*n)[i]→control→block; // Get block of ith input if( b→dom_depth < inb→dom_depth ) // If ith input is deeper b := inb; // ....

    [...]

  • ...A common intermediate representation in use today is the Control Flow Graph (CFG) with basic blocks of quads [1]....

    [...]

Journal ArticleDOI
TL;DR: In this paper, the authors formulate and prove an elementary fixpoint theorem which holds in arbitrary complete lattices, and give various applications (and extensions) of this result in the theories of simply ordered sets, real functions, Boolean algebras, as well as in general set theory and topology.
Abstract: 1. A lattice-theoretical fixpoint theorem. In this section we formulate and prove an elementary fixpoint theorem which holds in arbitrary complete lattices. In the following sections we give various applications (and extensions) of this result in the theories of simply ordered sets, real functions, Boolean algebras, as well as in general set theory and topology. * By a lattice we understand as usual a system 21 = (A 9 <) formed by a non-empty set A and a binary relation <; it is assumed that < establishes a partial order in A and that for any two elements a f b E A there is a least upper bound (join) a u b and a greatest lower bound (meet) an b. The relations >L, <, and > are defined in the usual way in terms of <. The lattice 21 = (A, <) is called complete if every subset B of A has a least upper bound ΌB and a greatest lower bound Πβ. Such a lattice has in particular two elements 0 and 1 defined by the formulas 0 = ΓU and 1 = 11,4. Given any two elements a 9 b E A with a < b, we denote by [a 9 b] the interval with the endpoints a and b, that is, the set of all elements x E A for which a < x < b; in symbols, [ a,b] = E x [x E A and a .< x .< b ]. The system \[α,6], <) is clearly a lattice; it is a complete if 21 is complete. We shall consider functions on A to A and, more generally, on a subset B of A to another subset C of A. Such a function / is called increasing if, for any 1 For notions and facts concerning lattices, simply ordered systems, and Boolean algebras consult [l].

2,873 citations


"Combining analyses, combining optim..." refers methods in this paper

  • ...By design, the equations have a minimal solution called the Greatest Fixed Point (gfp) [Cousot and Cousot 1979; Tarski 1955].3 Functions in F represent complete programs via composition....

    [...]

  • ...As a final exercise, we combine CCP with partition-based GVN [Alpern et al. 1988] to 3The properties described in Section 2.2 ensure the existence of a gfp [Tarski 1955]....

    [...]

Journal ArticleDOI
TL;DR: An intermediate program representation, called the program dependence graph (PDG), that makes explicit both the data and control dependences for each operation in a program, allowing transformations to be triggered by one another and applied only to affected dependences.
Abstract: In this paper we present an intermediate program representation, called the program dependence graph (PDG), that makes explicit both the data and control dependences for each operation in a program. Data dependences have been used to represent only the relevant data flow relationships of a program. Control dependences are introduced to analogously represent only the essential control flow relationships of a program. Control dependences are derived from the usual control flow graph. Many traditional optimizations operate more efficiently on the PDG. Since dependences in the PDG connect computationally related parts of the program, a single walk of these dependences is sufficient to perform many optimizations. The PDG allows transformations such as vectorization, that previously required special treatment of control dependence, to be performed in a manner that is uniform for both control and data dependences. Program transformations that require interaction of the two dependence types can also be easily handled with our representation. As an example, an incremental approach to modifying data dependences resulting from branch deletion or loop unrolling is introduced. The PDG supports incremental optimization, permitting transformations to be triggered by one another and applied only to affected dependences.

2,631 citations


"Combining analyses, combining optim..." refers methods in this paper

  • ...We correct this in our implemen­tation by using an operator-level (instead of basic-block level) Program Dependence Graph (PDG) in SSA form [Ferrante et al. 1987; Pingali et al. 1990]....

    [...]

Book
01 Jan 1972
TL;DR: A comparison of first- and second-order logic in the case of SETs shows that the former is more likely to be correct and the latter is less likely.
Abstract: USEFUL FACTS ABOUT SETS. SENTENTIAL LOGIC. FIRST-ORDER LOGIC. UNDECIDABILITY. SECOND-ORDER LOGIC.

2,216 citations


"Combining analyses, combining optim..." refers background in this paper

  • ...Enderton [19] defines a set as a collection of rules applied to some universe....

    [...]