Open navigation menu
Close suggestions
Search
Search
en
Change Language
Upload
Sign in
Sign in
Download free for days
0 ratings
0% found this document useful (0 votes)
327 views
Advanced+Compiler+Design+and+Implementation 1997
Advanced+Compiler+Design+and+Implementation
Uploaded by
chirayu mahajan
AI-enhanced title
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content,
claim it here
.
Available Formats
Download as PDF or read online on Scribd
Download now
Download
Save Advanced+Compiler+Design+and+Implementation.1997 For Later
Download
Save
Save Advanced+Compiler+Design+and+Implementation.1997 For Later
0%
0% found this document useful, undefined
0%
, undefined
Embed
Share
Print
Report
0 ratings
0% found this document useful (0 votes)
327 views
Advanced+Compiler+Design+and+Implementation 1997
Advanced+Compiler+Design+and+Implementation
Uploaded by
chirayu mahajan
AI-enhanced title
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content,
claim it here
.
Available Formats
Download as PDF or read online on Scribd
Download now
Download
Save Advanced+Compiler+Design+and+Implementation.1997 For Later
Carousel Previous
Carousel Next
Save
Save Advanced+Compiler+Design+and+Implementation.1997 For Later
0%
0% found this document useful, undefined
0%
, undefined
Embed
Share
Print
Report
Download now
Download
You are on page 1
/ 881
Search
Fullscreen
Advanccd COMPILER DESIGN IMPLEMENTATION Steven S. MuchnickScalar replacement of array references Data-cache optimizations — | Procedure integration Tail-call optimization, including tail-recursion elimination Scalar replacement of aggregates Sparse conditional constant propagation Interprocedural constant propagation Procedure specialization and cloning Sparse conditional constant propagation y Global value numbering Algebraic Local and global copy propagation _»,J| Constant | simplifications, Sparse conditional constant propagation folding including Dead-code elimination reassociation cl Local and global common- subexpression elimination Loop-invariant code motion Dead-code elimination Code hoisting Induction-variable strength reduction Linear-function test replacement Induction-variable removal Unnecessary bounds-checking elimination Control-flow optimizations c4 ---------------------------------- >] J (from box D) Order of Optimizations This flowchart represents a recommended order for performing optimizations in an aggres- sive optimizing compiler. Other orders are possible, and the examples of real-world compilers in Chapter 21 present several alternatives, though none of them includes all of the optimiza- tions in this diagram. The letters at the left in the diagram correspond to the levels of code appropriate for the corresponding optimizations. The correspondence between letters and code levels is as follows: These optimizations typically are applied either to source code or to a high-level intermediate code that preserves loop structure and the sequence in which operations are performed and that has array accesses in essentially their source-code form. Usually, these optimizations are done very early in the compilation process, since compilation tends to lower the level of the code as it proceeds from one phase to the next.(to constant folding, algebraic simplifications, and reassociation) A In-line expansion Leaf-routine optimization Shrink wrapping Machine idioms Tail merging Branch optimizations and conditional moves Dead-code elimination D Software pipelining, with loop unrolling, variable expansion, register renaming, and hierarchical reduction Basic-block and branch scheduling 1 Register allocation by graph coloring Basic-block and branch scheduling 2 Intraprocedural I-cache optimization Instruction prefetching Data prefetching Branch prediction — | Interprocedural register allocation E Aggregation of global references Interprocedural I-cache optimization B,C These optimizations are typically performed on medium- or low-level intermediate code, depending on the overall organization of the compiler. If code selection is done before all optimizations other than those in box A (known as the “low-level” model of optimizer struc- ture), then these optimizations are performed on low-level code. If, on the other hand, some optimizations are performed on a medium-level, relatively machine-independent intermedi- ate code and others are performed on low-level code after code generation (known as the “mixed” model), then these optimizations are generally done on the medium-level interme- diate code. The branches from C1 to C2 and C3 represent a choice of the method used to perform essentially the same optimization (namely, moving computations to places where they are per- formed less frequently without changing the semantics of the program). They also represent a choice of the data-flow analyses used to perform the optimization. D_ These optimizations are almost always done on a low-level form of code—one that may be quite machine-dependent (e.g., a structured assembly language) or that may be somewhat more general, such as the low-level intermediate code used in this book—because they require that addresses have been turned into the form required by the target processor and because several of them require low-level control-flow code. E_ These optimizations are performed at link time, so they operate on relocatable object code. Three optimizations, namely, constant folding, algebraic simplification, and reassociation, are in boxes connected to the other phases of the optimization process by dotted lines because they are best structured as subroutines that can be invoked whenever they are needed. A version of this diagram appears in Chapters 1 and 11 through 20 to guide the reader in ordering optimizer components in a compiler.Advanced Compiler Design and Implementation Steven S. MuchnickSenior Editor Denise E. M. Penrose Director of Production and Manufacturing Yonie Overton Senior Production Editor Cheri Palmer Editorial Coordinator Jane Elliott Cover Design Ross Carron Design Text Design, Composition, and Illustration Windfall Software Copyeditor Jeff Van Bueren Proofreader Jennifer McClain Indexer Ty Koontz Printer Courier Corporation ACADEMIC PRESS A Harcourt Science and Technology Company 525 B Street, Suite 1900, San Diego, CA 92101-4495, USA http:/hwww.academicpress.com Academic Press Harcourt Place, 32 Jamestown Road, London, NW1 7BY, United Kingdom http:/hwww.academicpress.com Morgan Kaufmann Publishers 340 Pine Street, Sixth Floor, San Francisco, CA 94104-3205, USA http:/hwww.mkp.com © 1997 by Academic Press All rights reserved Printed in the United States of America 04 03 6 No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form or by any means—electronic, mechanical, photocopying, recording, or otherwise—without the prior written permission of the publisher. Library of Congress Cataloging-in-Publication Data Muchnick, Steven S., date. Advanced compiler design and implementation / Steve Muchnick. . cm. Includes bibliographical references and index. ISBN 1-55860-320-4 1. Compilers (Computer programs) 2. Systems programming (Computer science). I. Title. QA76.76.C65M8 1997 005.4’53—dc21 97-13063 CIPTo Eric, nihil sine quéForeword ompiler design has been an active topic of research and development since the mid-1950s. Fortran, the first widely used higher-level language, suc- ceeded, in large part, because of the high quality of its early compilers. John Backus and his colleagues at IBM recognized that programmers would not give up the detailed design control they had with assembly language unless the performance of compiled code was sufficiently close to the performance of handwritten machine code. Backus’s group invented several key concepts that underlie the topics in this book. Among them are the treatment of array indexes in loop optimization and methods for local register allocation. Since that time, both researchers and practi- tioners have improved and supplanted them (repeatedly) with more effective ones. In light of the long history of compiler design, and its standing as a relatively mature computing technology, why, one might ask, should there be a new book in the field? The answer is clear. Compilers are tools that generate efficient mappings from programs to machines. The language designs continue to change, the target architectures continue to change, and the programs become ever more ambitious in their scale and complexity. Thus, while the compiler design problem remains the same at a high level, as we zoom in, it is continually changing. Furthermore, the computational resources we can bring to bear in the compilers themselves are increasing. Consequently, modern compilers use more time- and space-intensive algorithms than were possible before. And, of course, researchers continue to invent new and better techniques for solving conventional compiler design problems. In fact, an entire collection of topics in this book are direct consequences of changes in computer architecture. This book takes on the challenges of contemporary languages and architectures and prepares the reader for the new compiling problems that will inevitably arise in the future. For example, in Chapter 3 the book builds on the reader’s knowledge of symbol tables and local scope structure to describe how to deal with imported and exported scopes as found in Ada, Modula-2, and other modern languages. And, since run-time environments model the dynamic semantics of source languages, the discussion of advanced issues in run-time support in Chapter 5, such as compiling shared objects, is particularly valuable. That chapter also addresses the rich type systems found in some modern languages and the diverse strategies for parameter passing dictated by modern architectures.Foreword No compiler book would be complete without a chapter on code generation. The early work in code generation provided approaches to designing handcrafted instruction-selection routines and intermixing instruction selection with register management. The treatment of code generation in Chapter 6 describes automated techniques based on pattern matching, made possible not only by compiler research but also by simpler and more orthogonal instruction sets and by the feasibility of constructing and traversing intermediate-code trees in a compiler. Optimization is the heart of advanced compiler design and the core of this book. Much theoretical work has gone into program analysis, both for the sake of optimization and for other purposes. Chapters 7 through 10 revisit what are, by now, the classic analysis methods, along with newer and more efficient ones previously described only in research papers. These chapters take a collection of diverse techniques and organize them into a unified whole. This synthesis is, in itself, a significant contribution to compiler design. Most of the chapters that follow use the analyses to perform optimizing transformations. The large register sets in recent systems motivate the material on register allo- cation in Chapter 16, which synthesizes over a decade of advances in algorithms and heuristics for this problem. Also, an important source of increased speed is concurrency—the ability to do several things at once. In order to translate a sequen- tial program into one that can exploit hardware concurrency, the compiler may need to rearrange parts of the computation in a way that preserves correctness and in- creases parallelism. Although a full treatment of concurrency is beyond the scope of this book, it does focus on instruction-level parallelism, which motivates the discus- sion of dependence analysis in Chapter 9 and the vital topic of code scheduling in Chapter 17. Chapter 20, on optimization for the memory hierarchy, is also motivated by modern target machines, which introduce a diversity of relative speeds of data access in order to cope with the increasing gap between processor and memory speeds. An additional chapter available from the publisher’s World Wide Web site discusses object-code translation, which builds on compiler technology to translate programs for new architectures, even when the source programs are unavailable. The importance of interprocedural analysis and optimization has increased as new language designs have encouraged programmers to use more sophisticated methods for structuring large programs. Its feasibility has increased as the analysis methods have been refined and tuned and as faster computers have made the requi- site analyses acceptably fast. Chapter 19 is devoted to the determination and use of interprocedural information. Compiler design is, in its essence, an engineering activity. The methods that are used must be ones that provide good solutions to the translation situations that arise in practice—namely, real programs written in real languages executing on real machines. Most of the time, the compiler writer must take the languages and the machines as they come. Rarely is it possible to influence or improve the design of either. It is the engineering choices of what analyses and transformations to perform and when to perform them that determine the speed and quality of an optimizing compiler. Both in the treatment of the optimization material throughout the book and in the case studies in Chapter 21, these design choices are paramount.Foreword ix One of the great strengths of the author, Steve Muchnick, is the wealth and di- versity of his experience. After an early career as a professor of computer science, Dr. Muchnick applied his knowledge of compilers as a vital member of the teams that developed two important computer architectures, namely, PA-RISC at Hewlett- Packard and sparc at Sun Microsystems. After the initial work on each architecture was completed, he served as the leader of the advanced compiler design and im- plementation groups for these systems. Those credentials stand him in good stead in deciding what the reader needs to know about advanced compiler design. His research experience, coupled with his hands-on development experience, are invalu- able in guiding the reader through the many design decisions that a compiler designer must make. Susan Graham University of California, BerkeleyContents Foreword by Susan Graham vii Preface xxi Introduction to Advanced Topics 1 11 1.2 1.3 1.4 LS 1.6 1.7 1.8 1.9 1.10 1.11 1.12 Review of Compiler Structure 1 Advanced Issues in Elementary Topics 3 The Importance of Code Optimization 6 Structure of Optimizing Compilers 7 Placement of Optimizations in Aggressive Optimizing Compilers 11 Reading Flow Among the Chapters 14 Related Topics Not Covered in This Text 16 Target Machines Used in Examples 16 Number Notations and Data Sizes 16 Wrap-Up 17 Further Reading 18 Exercises 18 Informal Compiler Algorithm Notation (ICAN) 19 2.1 2.2 2.3 2.4 2.5 2.6 Extended Backus-Naur Form Syntax Notation 19 Introduction toICAN 20 A Quick Overview of ICAN 23 Whole Programs 25 Type Definitions 25 Declarations 26xii Contents 2.7 Data Types and Expressions 27 2.8 Statements 36 2.9 Wrap-Up 41 2.10 Further Reading 41 2.11 Exercises 41 Symbol-Table Structure 43 3.1 Storage Classes, Visibility, and Lifetimes 43 3.2 Symbol Attributes and Symbol-Table Entries 45 3.3 Local Symbol-Table Management 47 3.4 Global Symbol-Table Structure 49 3.5 Storage Binding and Symbolic Registers 54 3.6 Approaches to Generating Loads and Stores 59 3.7 Wrap-Up 64 3.8 Further Reading 64 3.9 Exercises 64 Intermediate Representations 67 41 Issues in Designing an Intermediate Language 67 4.2 High-Level Intermediate Languages 69 4.3 Medium-Level Intermediate Languages 71 4.4 Low-Level Intermediate Languages 71 4.5 Multi-Level Intermediate Languages 72 4.6 Our Intermediate Languages: MIR, HIR, and LIR 73 4.7 Representing MIR, HIR, and LIRinICAN 81 4.8 ICAN Naming of Data Structures and Routines that Manipulate Intermediate Code 92 4.9 Other Intermediate-Language Forms 96 4.10 Wrap-Up 101 4.11 Further Reading 102 4.12 Exercises 102 Run-Time Support 105 5.1 Data Representations and Instructions 106 5.2 Register Usage 109Contents xiii 5.3 The Local Stack Frame 111 5.4 The Run-Time Stack 114 5.5 Parameter-Passing Disciplines 116 5.6 Procedure Prologues, Epilogues, Calls, and Returns 119 5.7 Code Sharing and Position-Independent Code 127 5.8 Symbolic and Polymorphic Language Support 131 5.9 Wrap-Up 133 5.10 Further Reading 134 5.11 Exercises 135 Producing Code Generators Automatically 137 6.1 Introduction to Automatic Generation of Code Generators 138 6.2 A Syntax-Directed Technique 139 6.3 Introduction to Semantics-Directed Parsing 159 6.4 Tree Pattern Matching and Dynamic Programming 160 6.5 Wrap-Up 165 6.6 Further Reading 166 6.7 Exercises 166 Control-Flow Analysis 169 71 Approaches to Control-Flow Analysis 172 7.2 Depth-First Search, Preorder Traversal, Postorder Traversal, and Breadth-First Search 177 7.3 Dominators and Postdominators 181 7.4 Loops and Strongly Connected Components 191 7.5 Reducibility 196 7.6 Interval Analysis and Control Trees 197 7.7 Structural Analysis 202 7.8 Wrap-Up 214 7.9 Further Reading 214 7.10 Exercises 215 Data-Flow Analysis 217 8.1 An Example: Reaching Definitions 218 8.2 Basic Concepts: Lattices, Flow Functions, and Fixed Points 223xiv 10 Contents 8.3 8.4 8.5 8.6 8.7 8.8 8.9 8.10 8.11 8.12 8.13 8.14 8.15 8.16 8.17 Taxonomy of Data-Flow Problems and Solution Methods 228 Iterative Data-Flow Analysis 231 Lattices of Flow Functions 235 Control-Tree-Based Data-Flow Analysis 236 Structural Analysis 236 Interval Analysis 249 Other Approaches 250 Du-Chains, Ud-Chains, and Webs 251 Static Single-Assignment (SSA) Form 252 Dealing with Arrays, Structures, and Pointers 258 Automating Construction of Data-Flow Analyzers 259 More Ambitious Analyses 261 Wrap-Up 263 Further Reading 264 Exercises 265 Dependence Analysis and Dependence Graphs 267 91 9.2 9.3 9.4 9.5 9.6 9.7 9.8 9.9 Dependence Relations 267 Basic-Block Dependence DAGs 269 Dependences in Loops 274 Dependence Testing 279 Program-Dependence Graphs 284 Dependences Between Dynamically Allocated Objects 286 Wrap-Up 288 Further Reading 289 Exercises 290 Alias Analysis 293 10.1 10.2 10.3 10.4 10.5 10.6 Aliases in Various Real Programming Languages 297 The Alias Gatherer 302 The Alias Propagator 307 Wrap-Up 314 Further Reading 315 Exercises 31611 12 13 14 Contents Introduction to Optimization 319 11.1. Global Optimizations Discussed in Chapters 12 Through 18 321 11.2. Flow Sensitivity and May vs. Must Information 323 11.3. Importance of Individual Optimizations 323 11.4 Order and Repetition of Optimizations 325 11.5 Further Reading 328 11.6 Exercises 328 Early Optimizations 329 12.1 Constant-Expression Evaluation (Constant Folding) 329 12.2 Scalar Replacement of Aggregates 331 12.3 Algebraic Simplifications and Reassociation 333 12.4 Value Numbering 343 12.5 Copy Propagation 356 12.6 Sparse Conditional Constant Propagation 362 12.7. Wrap-Up 371 12.8 Further Reading 373 12.9 Exercises 374 Redundancy Elimination 377 13.1. Common-Subexpression Elimination 378 13.2. Loop-Invariant Code Motion 397 13.3. Partial-Redundancy Elimination 407 13.4 Redundancy Elimination and Reassociation 415 13.5 Code Hoisting 417 13.6 Wrap-Up 420 13.7. Further Reading 422 13.8 Exercises 422 Loop Optimizations 425 14.1. Induction-Variable Optimizations 425 14.2 Unnecessary Bounds-Checking Elimination 454 14.3. Wrap-Up 457 14.4 Further Reading 459 14.5 Exercises 46015 16 17 18 Contents Procedure Optimizations 461 15.1 15.2 15.3 15.4 15.5 15.6 15.7 Tail-Call Optimization and Tail-Recursion Elimination 461 Procedure Integration 465 In-Line Expansion 470 Leaf-Routine Optimization and Shrink Wrapping 472 Wrap-Up 476 Further Reading 478 Exercises 478 Register Allocation 481 16.1 16.2 16.3 16.4 16.5 16.6 16.7 16.8 Register Allocation and Assignment 482 Local Methods 483 Graph Coloring 485 Priority-Based Graph Coloring 524 Other Approaches to Register Allocation 525 Wrap-Up 526 Further Reading 528 Exercises 529 Code Scheduling 531 17.1 17.2 17.3 17.4 17.5 17.6 17.7 17.8 17.9 Instruction Scheduling 532 Speculative Loads and Boosting 547 Speculative Scheduling 548 Software Pipelining 548 Trace Scheduling 569 Percolation Scheduling 571 Wrap-Up 573 Further Reading 575 Exercises 576 Control-Flow and Low-Level Optimizations 579 18.1 18.2 18.3 18.4 Unreachable-Code Elimination 580 Straightening 583 If Simplifications 585 Loop Simplifications 58619 20 Contents 18.5 18.6 18.7 18.8 18.9 18.10 18.11 18.12 18.13 18.14 18.15 Loop Inversion 587 Unswitching 588 Branch Optimizations 589 Tail Merging or Cross Jumping 590 Conditional Moves 591 Dead-Code Elimination 592 Branch Prediction 597 Machine Idioms and Instruction Combining 599 Wrap-Up 602 Further Reading 604 Exercises 605 Interprocedural Analysis and Optimization 607 19.1 19.2 19.3 19.4 19.5 19.6 19.7 19.8 19.9 19.10 19.11 Interprocedural Control-Flow Analysis: The Call Graph 609 Interprocedural Data-Flow Analysis 619 Interprocedural Constant Propagation 637 Interprocedural Alias Analysis 641 Interprocedural Optimizations 656 Interprocedural Register Allocation 659 Aggregation of Global References 663 Other Issues in Interprocedural Program Management 663 Wrap-Up 664 Further Reading 666 Exercises 667 Optimization for the Memory Hierarchy 669 20.1 20.2 20.3 20.4 20.5 20.6 20.7 20.8 Impact of Data and Instruction Caches 670 Instruction-Cache Optimization 672 Scalar Replacement of Array Elements 682 Data-Cache Optimization 687 Scalar vs. Memory-Oriented Optimizations 700 Wrap-Up 700 Further Reading 703 Exercises 704xviii 21 App. A App. B App. C Contents Case Studies of Compilers and Future Trends 705 21.1 The Sun Compilers for SPARC 707 21.2 The IBM XL Compilers for the POWER and PowerPC Architectures 716 21.3. Digital Equipment’s Compilers for Alpha 726 21.4. The Intel Reference Compilers for the Intel 386 Architecture Family 734 21.5 Wrap-Up 744 21.6 Future Trends in Compiler Design and Implementation 745 21.7 Further Reading 746 Guide to Assembly Languages Used in This Book 747 Al Sun SPARC Versions 8 and 9 Assembly Language 747 A.2. IBM POWER and PowerPC Assembly Language 749 A.3. DEC Alpha Assembly Language 750 A.4__ Intel 386 Architecture Assembly Language 752 A.S — Hewlett-Packard’s PA-RISC Assembly Language 753 Representation of Sets, Sequences, Trees, DAGs, and Functions 757 B.1 Representation of Sets 759 B.2 Representation of Sequences 763 B.3 Representation of Trees and DAGs 763 B.4 Representation of Functions 764 B.S Further Reading 765 Software Resources 767 C.1 ‘Finding and Accessing Software on the Internet 767 C.2. Machine Simulators 767 C.3 Compilers 768 C.4_ Code-Generator Generators: BURG and IBURG 769 C.5 Profiling Tools +770 List of Illustrations 773Contents List of Tables 797 Bibliography 801 Technical Index of Mathematical Formulas and 1caN Procedures and Major Data Structures 821 Subject Index 827 xixPreface his book concerns advanced issues in the design and implementation of compilers, for uniprocessors, with its major emphasis (over 60% of the text) on optimization. While it does consider machines with instruction-level parallelism, we ignore almost completely the issues of large-scale parallelization and vectorization. It begins with material on compiler structure, symbol-table management (includ- ing languages that allow scopes to be imported and exported), intermediate code structure, run-time support issues (including shared objects that can be linked to at run time), and automatic generation of code generators from machine descrip- tions. Next it explores methods for intraprocedural (conventionally called global) control-flow, data-flow, dependence, and alias analyses. Then a series of groups of global optimizations are described, including ones that apply to program compo- nents from simple expressions to whole procedures. Next, interprocedural analyses of control flow, data flow, and aliases are described, followed by interprocedural optimizations and use of interprocedural information to improve global optimiza- tions. We then discuss optimizations designed to make effective use of the memory hierarchy. Finally, we describe four commercial compiler systems in detail, namely, ones from Digital Equipment Corporation, IBM, Intel, and Sun Microsysytems, to provide specific examples of approaches to compiler structure, intermediate-code de- sign, optimization choices, and effectiveness. As we shall see, these compiler systems represent a wide range of approaches and often achieve similar results in different ways. How This Book Came to Be Written In June 1990 and 1991, while a Distinguished Engineer at Sun Microsystems, I presented a half-day tutorial entitled “Advanced Compiling Techniques for RISC Systems” at the annual ACM siGpLan Conference on Programming Language De- sign and Implementation. The tutorial was based on approximately 130 transparen- cies on RISC architectures and relevant issues in compilers, particularly optimization. I left that experience with the idea that somewhere within the material covered there was a seed (the mental image was, in fact, of an acorn) yearning for sun, soil, and water to help it grow into the mature oak tree of a book you have before you. Over xxixxii Preface a year later I discussed this idea with Wayne Rosing, then President of Sun Microsys- tems Laboratories, and within a few weeks he decided to nurture this project with a year-and-a-half’s worth of partial funding. The first draft that resulted included quite a lot of material on RISC architectures, as well as material on advanced compilation issues. Before long (with the help of three reviewers) I had decided that there was little point in including the architecture material in the book. New risc architectures are being developed quite frequently, the kind of coverage of them that is needed is provided in architecture courses at most universities, and the real strengths of the text were in the compiler material. This resulted in a major change of direction. Most of the architecture material was dropped, keeping just those parts that support decisions on how to proceed in compilation; the focus of the compiler material was broadened to provide equal coverage of ciscs; and it was decided to focus entirely on uniprocessors and to leave it to other texts to discuss parallelization and vectorization. The focus of the compilation material was deepened and, in some respects narrowed and in others broadened (for example, material on hand-crafted code generation was dropped almost entirely, while advanced methods of scheduling, such as trace and percolation scheduling, were added). The result is what you see before you. About the Cover The design on the cover is of a Chilkat blanket from the author’s collection of Northwest Coast native art. The blanket was woven of fine strands of red-cedar inner bark and mountain-goat wool in the late 19th century by a Tlingit woman from southeastern Alaska. It generally took six to nine months of work to complete such a blanket. The blanket design is divided into three panels, and the center panel depicts a diving whale. The head is the split image at the bottom; the body is the panel with the face in the center (a panel that looks like a face never represents the face in this iconography); the lateral fins are at the sides of the body; and the tail flukes are at the top. Each part of the design is, in itself, functional but meaningless; assembled together in the right way, the elements combine to depict a diving whale and proclaim the rights and prerogatives of the village chief who owned the blanket. In a similar way, each component of a compiler is functional, but it is only when the components are put together in the proper way that they serve their overall purpose. Designing and weaving such a blanket requires skills that are akin to those involved in constructing industrial-strength compilers—each discipline has a set of required tools, materials, design elements, and overall patterns that must be combined in a way that meets the prospective users’ needs and desires. Audience for This Book This book is intended for computer professionals, graduate students, and advanced undergraduates who need to understand the issues involved in designing and con- structing advanced compilers for uniprocessors. The reader is assumed to have had introductory courses in data structures, algorithms, compiler design and implemen-Preface xxiii tation, computer architecture, and assembly-language programming, or equivalent work experience. Overview of the Book’s Contents This volume is divided into 21 chapters and three appendices as follows: Chapter 1. Introduction to Advanced Topics This chapter introduces the subject of the book, namely, advanced topics in the de- sign and construction of compilers, and discusses compiler structure, the importance of optimization, and how the rest of the material in the book works together. Chapter 2. Informal Compiler Algorithm Notation (ICAN) Chapter 2 describes and gives examples of an informal programming notation called ICAN that is used to present algorithms in the text. After describing the notation used to express the language’s syntax, it gives a brief overview of ICAN, followed by a detailed description of the language. The brief description should be sufficient for reading most of the algorithms presented and the full description should need to be referred to only rarely. Chapter 3. Symbol-Table Structure Chapter 3 first discusses the attributes of variables, such as storage class, visibility, volatility, scope, size, type, alignment, structure, addressing method, and so on. Then it describes effective methods for structuring and managing local and global symbol tables, including importation and exportation of scopes (as found, e.g., in Ada, Mesa, and Modula-2); storage binding; and approaches to generating load and store instructions that take the above characteristics into account. Chapter 4. Intermediate Representations This chapter focuses on intermediate language design, three specific intermediate lan- guages used in the remainder of the book, and other basic forms of intermediate code that might be used in a compiler. We use three closely related intermediate forms, one high-level, one medium-level, and one low-level, to allow us to demonstrate vir- tually all the optimizations discussed. We also discuss the relative importance and usefulness of our chosen forms and the others. Two other more elaborate forms of intermediate code, namely, static single- assignment (SSA) form and program dependence graphs, are discussed in Sec- tions 8.11 and 9.5, respectively. Chapter 5. Run-Time Support Chapter 5 concerns the issues involved in supporting programs written in high-level languages at run time. It discusses data representation, register usage, design of the stack frame and overall run-time stack, parameter passing, procedure structure andxxiv Preface linkage, procedure-valued variables, code sharing, position-independent code, and issues involved in supporting symbolic and polymorphic languages. Chapter 6. Producing Code Generators Automatically Chapter 6 discusses automatic approaches for producing code generators from ma- chine descriptions. We present the Graham-Glanville syntax-directed technique in detail and introduce two other approaches, namely, semantics-directed parsing and tree pattern matching. Chapter 7. Control-Flow Analysis This and the following three chapters discuss four types of analyses that apply to procedures and that are vital to doing correct and ambitious optimization. Chapter 7 concentrates on approaches to determining the control flow within a procedure and to constructing a control-flow graph (CFG). It begins with an overview of the possible approaches and then discusses three of them in detail. The first is the classic approach of using depth-first search and dominators. In this area we also discuss flowgraph traversals, such as preorder and postorder, of the CFG and finding the strongly connected components of a CFG. The other two approaches depend on the concept of reducibility, which allows the control flow of a procedure to be composed hierarchically. One of the two is called interval analysis and the other is called structural analysis, and the two differ in what types of structural units they distinguish. We also discuss the representation of a procedure’s hierarchical structure by a so-called control tree. Chapter 8. Data-Flow Analysis Chapter 8 discusses approaches to determining the flow of data in a procedure. It begins with an example and next discusses the basic mathematical concepts un- derlying data-flow analysis, namely, lattices, flow functions, and fixed points. It continues with a taxonomy of data-flow problems and solution methods and then proceeds to discuss in detail three techniques for solving data-flow problems that correspond to the three approaches to control-flow analysis presented in the preced- ing chapter. The first approach is iterative data-flow analysis, which corresponds to the use of depth-first search and dominators. The other two approaches correspond to the control-tree-based approaches to control-flow analysis and are known by the same names as those analyses: interval analysis and structural analysis. This is fol- lowed by an overview of a new sparse technique known as slotwise analysis, and descriptions of methods of representing data-flow information, namely, du-chains, ud-chains, webs, and static single-assignment (or SSA) form. The chapter concludes with thoughts on how to deal with arrays, structures, and pointers and with a dis- cussion of a method for automating construction of data-flow analyzers. Chapter 9. Dependence Analysis and Dependence Graphs Chapter 9 concerns dependence analysis, which is a poor-man’s version of data-flow analysis for arrays and low-level storage references, and a closely related intermedi- ate code form known as the program dependence graph. It first discusses dependencePreface XXV relations and then how to compute dependence relations within a basic block, which is vital to the code-scheduling techniques discussed in Chapter 17. Next it discusses dependence in loops and methods of doing dependence testing, which are essential to the data-storage optimizations discussed in Chapter 20. Finally, it discusses the pro- gram dependence graph, which is an intermediate-code form that represents control and data dependences directly, and that can be used to perform a series of optimiza- tions more effectively than on an intermediate code that leaves such information implicit. Chapter 10. Alias Analysis Chapter 10 discusses alias analysis, which determines whether a storage location may be accessible by more than one access path, such as by name and through a pointer. It discusses how aliases may impact programs in specific languages, such as Fortran 77, Pascal, C, and Fortran 90. Next it discusses a very general approach to determining the aliases present in a procedure that consists of a language-specific alias gatherer and a language-independent alias propagator. The alias gatherer and propagator can be tailored to provide information that depends or not on the control flow of the procedure and that also provides information in a variety of other ways, making it a general approach that can be suited to the needs and time constraints of a particular programming language and compiler. Chapter 11. Introduction to Optimization Chapter 11 introduces the subject of code optimization, discusses the fact that the applicability and effectiveness of most optimizations are recursively undecidable but still worthwhile for programs for which they are determinable, and provides a quick survey of the intraprocedural optimizations covered in Chapters 12 through 18. It then discusses flow sensitivity and may vs. must information and how they apply to optimization, the relative importance of particular optimizations, and the order in which they should be performed. Chapter 12. Early Optimizations Chapter 12 discusses optimizations that are usually performed early in the opti- mization process, namely, scalar replacement of aggregates, local and global value numbering (performed on SSA-form code), local and global copy propagation, and sparse conditional constant propagation (also performed on SSA-form code). It also discusses constant expression evaluation (or constant folding) and algebraic simpli- fication and how they are best included in an optimizer as subroutines that can be called from wherever they are needed. Chapter 13. Redundancy Elimination Chapter 13 concerns several types of redundancy elimination, which, in essence, delete computations that are performed more than once on a path through a pro- cedure. It describes local and global common-subexpression elimination, forward substitution, loop-invariant code motion, partial-redundancy elimination, and code hoisting.
You might also like
Peter Kogge - The Architecture of Symbolic Computers
PDF
100% (2)
Peter Kogge - The Architecture of Symbolic Computers
764 pages
(Steven S. Muchnick) Advanced Compiler Design and
PDF
79% (14)
(Steven S. Muchnick) Advanced Compiler Design and
887 pages
Starting Out With Java - Lab Manual
PDF
100% (1)
Starting Out With Java - Lab Manual
134 pages
A Little Java, A Few Patterns PDF
PDF
100% (1)
A Little Java, A Few Patterns PDF
182 pages
Programming The 65816
PDF
No ratings yet
Programming The 65816
469 pages
UndocumentedNT PDF
PDF
100% (1)
UndocumentedNT PDF
222 pages
A Tour of Scheme in Gambit
PDF
No ratings yet
A Tour of Scheme in Gambit
61 pages
From The Mailbox: The Origins of DOS - Tim Paterson
PDF
No ratings yet
From The Mailbox: The Origins of DOS - Tim Paterson
3 pages
Theory of Computation Lecture Notes
PDF
No ratings yet
Theory of Computation Lecture Notes
38 pages
BIOS and Kernel Developer's Guide (BKDG) For AMD Family 16h Models 00h-0Fh Processors
PDF
100% (1)
BIOS and Kernel Developer's Guide (BKDG) For AMD Family 16h Models 00h-0Fh Processors
921 pages
Principles of Compiler Design - Tutorial 9
PDF
100% (1)
Principles of Compiler Design - Tutorial 9
7 pages
Characteristics of A Good Programming Language
PDF
100% (1)
Characteristics of A Good Programming Language
4 pages
System Design With SystemC
PDF
No ratings yet
System Design With SystemC
236 pages
Introduction To MIPS Assembly Language Programming1
PDF
No ratings yet
Introduction To MIPS Assembly Language Programming1
179 pages
Randomized Algorithms
PDF
No ratings yet
Randomized Algorithms
12 pages
Computer Peripherals & Interfacing
PDF
No ratings yet
Computer Peripherals & Interfacing
128 pages
Building An Optimizing Compiler
PDF
No ratings yet
Building An Optimizing Compiler
363 pages
Complexity Theory - Course Notes - Sebastian A. Terwijn
PDF
No ratings yet
Complexity Theory - Course Notes - Sebastian A. Terwijn
101 pages
Amd x64 Architecture Volume 1
PDF
No ratings yet
Amd x64 Architecture Volume 1
400 pages
Sequential Circuit Analysis: State Tables State Diagrams
PDF
100% (1)
Sequential Circuit Analysis: State Tables State Diagrams
17 pages
Compiler Design - Software Design Project
PDF
0% (1)
Compiler Design - Software Design Project
54 pages
Backtracking Algorithms
PDF
100% (2)
Backtracking Algorithms
42 pages
A Tutorial On Algol 68
PDF
No ratings yet
A Tutorial On Algol 68
67 pages
Complex Vector Spaces PDF
PDF
No ratings yet
Complex Vector Spaces PDF
42 pages
Zhanghongbo Ocaml Book
PDF
No ratings yet
Zhanghongbo Ocaml Book
422 pages
Compiling With Continuations Andrew W Appel 2007
PDF
No ratings yet
Compiling With Continuations Andrew W Appel 2007
270 pages
XDS - Modula 2.IDE - User.guide - en
PDF
No ratings yet
XDS - Modula 2.IDE - User.guide - en
61 pages
Functional Programming With Bananas, Lenses, Envelopes and Barbed Wire
PDF
No ratings yet
Functional Programming With Bananas, Lenses, Envelopes and Barbed Wire
27 pages
Chapter 3 Regular Expressions Notes
PDF
100% (1)
Chapter 3 Regular Expressions Notes
36 pages
Simplexity: Apprenticeship Pitch at The Beginning of The Semester
PDF
No ratings yet
Simplexity: Apprenticeship Pitch at The Beginning of The Semester
9 pages
Compiler Construction
PDF
No ratings yet
Compiler Construction
810 pages
Computer Organization and Architecture (18EC35) - Machine Instructions and Programs - Part 1 (Module 1)
PDF
100% (1)
Computer Organization and Architecture (18EC35) - Machine Instructions and Programs - Part 1 (Module 1)
60 pages
Handout 4: Iii. Turing Machines
PDF
No ratings yet
Handout 4: Iii. Turing Machines
12 pages
Chapter 5 Harris Module2
PDF
100% (1)
Chapter 5 Harris Module2
137 pages
Spatial Swarm Granulation
PDF
No ratings yet
Spatial Swarm Granulation
4 pages
Discrete Mathematics With Graph Theory 1nbsped 3031213203 9783031213205 9783031213212 9789382127185 9783031213236 - Compress
PDF
No ratings yet
Discrete Mathematics With Graph Theory 1nbsped 3031213203 9783031213205 9783031213212 9789382127185 9783031213236 - Compress
657 pages
Programming Language Processors in Java Compilers and Interpreters.9780130257864.25356
PDF
No ratings yet
Programming Language Processors in Java Compilers and Interpreters.9780130257864.25356
438 pages
Alan Turing and His Legacy
PDF
No ratings yet
Alan Turing and His Legacy
26 pages
Theory of Computation
PDF
No ratings yet
Theory of Computation
10 pages
Computer Arithmetic - Algorith
PDF
No ratings yet
Computer Arithmetic - Algorith
510 pages
Graph Algorithms
PDF
No ratings yet
Graph Algorithms
45 pages
Computer Organization
PDF
No ratings yet
Computer Organization
67 pages
Gate Questions On Finite Automata - Theory-of-Computation - AcademyEra2 PDF
PDF
No ratings yet
Gate Questions On Finite Automata - Theory-of-Computation - AcademyEra2 PDF
13 pages
SC - Exploring Analytic Geometry With Mathematica
PDF
100% (7)
SC - Exploring Analytic Geometry With Mathematica
883 pages
Fractals: Siva Sankari, Sathya Meena, Aarthi, Ashok Kumar, Seetharaman Mohamad Habibur Rahman
PDF
No ratings yet
Fractals: Siva Sankari, Sathya Meena, Aarthi, Ashok Kumar, Seetharaman Mohamad Habibur Rahman
31 pages
SRM University: Department of Cse
PDF
No ratings yet
SRM University: Department of Cse
47 pages
Lecture Notes On Graph Theory
PDF
No ratings yet
Lecture Notes On Graph Theory
99 pages
15-745 Optimizing Compilers: What Is A Compiler?
PDF
No ratings yet
15-745 Optimizing Compilers: What Is A Compiler?
13 pages
Compiler Designing GATE Notes
PDF
No ratings yet
Compiler Designing GATE Notes
4 pages
Role of Data Structure in Compiler Design
PDF
67% (3)
Role of Data Structure in Compiler Design
16 pages
handout14
PDF
No ratings yet
handout14
13 pages
COMPI-DESI-CHP-06&7
PDF
No ratings yet
COMPI-DESI-CHP-06&7
25 pages
Week 1 PDF
PDF
100% (1)
Week 1 PDF
38 pages
Chapter 9
PDF
No ratings yet
Chapter 9
10 pages
Spos by Dhamdhere
PDF
50% (2)
Spos by Dhamdhere
456 pages
System Programing PDF
PDF
No ratings yet
System Programing PDF
456 pages
Spos by Dhamdhere PDF
PDF
No ratings yet
Spos by Dhamdhere PDF
456 pages
Compilers
PDF
No ratings yet
Compilers
7 pages
Compiler Theory: 001 - Introduction and Course Outline
PDF
No ratings yet
Compiler Theory: 001 - Introduction and Course Outline
33 pages
The Compilation Process: The Compilation Process Combines Both Translation and Optimisation of High Level Language Code
PDF
No ratings yet
The Compilation Process: The Compilation Process Combines Both Translation and Optimisation of High Level Language Code
20 pages