Instruction Selection Compiler Backend Intermediate Representations

Total Page:16

File Type:pdf, Size:1020Kb

Instruction Selection Compiler Backend Intermediate Representations Instruction Selection 15-745 Optimizing Compilers Spring 2007 1 School of Computer Science School of Computer Science Compiler Backend Intermediate Representations instruction IR IR IR Assem Source Front Middle Back Target selector Code End End End Code Front end - produces an intermediate representation (IR) register TempMap allocator Middle end - transforms the IR into an equivalent IR that runs more efficiently Back end - transforms the IR into native code instruction Assem scheduler IR encodes the compiler’s knowledge of the program Middle end usually consists of several passes 2 3 School of Computer Science School of Computer Science Page ‹#› Types of Intermediate Intermediate Representations Representations Decisions in IR design affect the speed and efficiency of Structural the compiler – Graphically oriented Examples: Some important IR properties – Heavily used in source-to-source translators Trees, DAGs – Ease of generation – Tend to be large – Ease of manipulation Linear – Procedure size – Pseudo-code for an abstract machine Examples: – Freedom of expression – Level of abstraction varies 3 address code Stack machine code – Level of abstraction – Simple, compact data structures The importance of different properties varies between – Easier to rearrange compilers Hybrid Example: – Selecting an appropriate IR for a compiler is critical – Combination of graphs and linear code Control-flow graph 4 5 School of Computer Science School of Computer Science Level of Abstraction Level of Abstraction The level of detail exposed in an IR influences the Structural IRs are usually considered high-level profitability and feasibility of different optimizations. Linear IRs are usually considered low-level Not necessarily true: Two different representations of an array reference: load loadI 1 => r1 Low level AST sub rj, r1 => r2 loadArray A,i,j + subscript loadI 10 => r3 High level linear code mult r2, r3 => r4 @A sub ri, r1 => r5 + A i j add r4, r5 => r6 * - loadI @A => r7 add r7, r6 => r8 High level AST: load r => r - 10 j 1 Good for memory 8 Aij disambiguation Low level linear code: j 1 Good for address calculation 6 7 School of Computer Science School of Computer Science Page ‹#› Abstract Syntax Tree Structural IR Directed Acyclic Graph Structural IR An abstract syntax tree is the procedure’s parse A directed acyclic graph (DAG) is an AST with a unique tree with the nodes for most non-terminal nodes node for each value removed ← ← z - w / x * - x - 2 * y 2 y z ← x - 2 * y x * w ← x / 2 2 y Same expression twice means Makes sharing explicit that the compiler might arrange When is an AST a good IR? to evaluate it just once! Encodes redundancy 8 9 School of Computer Science School of Computer Science Pegasus IR Structural IR Stack Machine Code Linear IR Originally used for stack-based computers, now Java Predicated Explicit Example: push x GAted Simple x - 2 * y becomes push 2 Uniform SSA push y multiply subtract Advantages Structural IR used in – Compact form Implicit names take up CASH (Compiler for – Introduced names are implicit, not explicit no space, where explicit Application Specific – Simple to generate and execute code ones do! Hardware) Useful where code is transmitted over slow communication links (the net ) 10 11 School of Computer Science School of Computer Science Page ‹#› Three Address Code Linear IR Two Address Code Linear IR Three address code has statements of the form: Allows statements of the form x ← y op z x ← x op y With 1 operator (op ) and, at most, 3 names (x, y, & z) Has 1 operator (op ) and, at most, 2 names (x and y) t 2 Example: 1 ← Example: t load y t ← 2 * y 2 ← z ← x - 2 * y becomes t2 ← t2 * t1 z ← x - t z ← x - 2 * y becomes z ← load x z ← z - t Advantages: – Can be very compact 2 – Resembles many machines (RISC) – Destructive operations make reuse hard – Compact form – Good model for machines with destructive ops (x86) 12 13 School of Computer Science School of Computer Science Control-flow Graph Hybrid IR Using Multiple Representations Models the transfer of control in the procedure Source Front IR 1 Middle IR 2 Middle IR 3 Back Target Nodes in the graph are basic blocks Code End End End End Code – Straight-line code – Either linear or structural representation Repeatedly lower the level of the intermediate representation Edges in the graph represent control flow – Each intermediate representation is suited towards certain optimizations Example: the Open64 compiler – WHIRL intermediate format Example if (x = y) Basic blocks — • Consists of 5 different IRs that are progressively more detailed Maximal length – gcc sequences of • but not explicit about it :-( a ← 2 a ← 3 straight-line code b ← 5 b ← 4 c ← a * b 14 15 School of Computer Science School of Computer Science Page ‹#› Instruction Selection Instruction selection example Suppose we have IR -> Assem MOVE(TEMP r, templates MEM(BINOP(TIMES,TEMP s,CONST c))) We can generate the x86 code… instruction IR Assem movl %(,s,c), %r selector …if c = 1, 2, or 4; otherwise… imull $c, %s, %r movl (%r), %r 16 17 School of Computer Science School of Computer Science Selection dependencies Example, cont’d We can see that the selection of instructions can For depend on the constants MEM(BINOP(TIMES,TEMP s,CONST c)) The context of an IR expression can also affect the choice of instruction we might sometimes want to generate Consider testl $0,(,%s,c) MOVE(TEMP r, je L MEM(BINOP(TIMES,TEMP s,CONST c))) What context might cause us to do this? 18 19 School of Computer Science School of Computer Science Page ‹#› Instruction selection as tree matching Sample tree-matching rules In order to take context into account, instruction IR pattern code cost selectors often use pattern-matching on IR trees BINOP(PLUS,i,j) leal (i,j),r 1 BINOP(TIMES,i,j) movl j,r 2 – each pattern specifies what instructions to select imull i,r BINOP(PLUS,i,CONST c) leal c(i),r 1 MEM(BINOP(PLUS,i,CONST c)) movl c(i),r 1 MOVE(MEM(BINOP(PLUS,i,j)),k) movl k,(i,j) 1 BINOP(TIMES,i,CONST c) leal (,i,c),r 1 If c is 1, 2, or 4 BINOP(TIMES,i,CONST c) movl c,r 2 imull i,r MEM(i) movl (i),r 1 MOVE(MEM(i),j) movl j,(i) 1 MOVE(MEM(i),MEM(j)) movl (j),t 2 movl t,(i) 20 21 School of Computer Science … School of Computer Science Tiling an IR tree, v.1 Tiling an IR tree, v.2 a[x] = *y; a[x] = *y; MOVE MOVE r3 MEM MEM MEM MEM leal $a(%ebp),r1 r4 movl $a(%ebp),r1 y movl (r1),r2 y + leal (,x,4),r2 leal (,x,$4),r3 movl (y),r3 + leal (r2,r3),r4 r2 r3 movl r3,(r1,r2) r1 r2 movl (y),r5 MEM movl r5,(r4) * MEM r1 * + x CONST 4 + x CONST 4 (assume a is a EBP CONST a formal parameter BP CONST a passed on the stack) 22 23 School of Computer Science School of Computer Science Page ‹#› Tiling choices The best tiling? In general, for any given tree, many tilings are We want the “lowest cost” tiling possible – usually, the shortest sequence – each resulting in a different instruction sequence – but can also take into account cost/delay of each instruction Optimum tiling We can ensure pattern coverage by covering, at a – lowest-cost tiling minimum, all atomic IR trees Locally Optimal tiling – no two adjacent tiles can be combined into one tile of lower cost 24 25 School of Computer Science School of Computer Science Locally optimal tilings Maximal munch MOVE MEM MEM Locally optimal tiling is easy Choose the largest pattern with lowest y – A simple greedy algorithm works extremely cost, i.e., the + well in practice: “maximal munch” – Maximal munch MEM * • start at root + x CONST 4 • use “biggest” match (in # of nodes) – use cost to break ties BP CONST a IR pattern code cost MOVE(MEM(BINOP(PLUS,i,j)),k) movl k,(i,j) 1 MOVE(MEM(i),j) movl j,(i) 1 MOVE(MEM(i),MEM(j)) movl (j),t 2 26 27 movl t,(i) School of Computer Science School of Computer Science Page ‹#› Maximal munch Maximal munch is not optimum Maximal munch does not necessarily produce the Consider what happens, for example, if two of our optimum selection of instructions rules are changed as follows: But: – it is easy to implement – it tends to work well for current instruction-set IR pattern code cost architectures MEM(BINOP(PLUS,i,CONST c)) movl c,r 3 addl i,r movl (r),r MOVE(MEM(BINOP(PLUS,i,j)),k) movl j,r 3 addl i,r movl k,(r) 28 29 School of Computer Science School of Computer Science Sample tree-matching rules Tiling an IR tree, new rules Rule # IR pattern cost a[x] = *y; 0 TEMP t 0 MOVE r3 1 CONST c 1 MEM MEM 2 BINOP(PLUS,i,j) 1 movl $a,r1 3 BINOP(TIMES,i,j) 2 addl %ebp,r1 y 4 BINOP(PLUS,i,CONST c) 1 movl (r1),r1 + 5 MEM(BINOP(PLUS,i,CONST c)) 3 leal (,x,4),r2 r1 r2 6 MOVE(MEM(BINOP(PLUS,i,j)),k) 3 movl (y),r3 MEM * 7 BINOP(TIMES,i,CONST c) 1 If c is 1, 2, or 4 movl r2,r4 addl r1,r4 8 BINOP(TIMES,i,CONST c) 2 + movl r3,(r4) x CONST 4 9 MEM(i) 1 10 MOVE(MEM(i),j) 1 BP CONST a 11 MOVE(MEM(i),MEM(j)) 2 30 31 School of Computer Science School of Computer Science Page ‹#› Optimum selection Dynamic programming To achieve optimum instruction selection, we must The idea is fairly simple use a more complex algorithm – Working bottom up… – dynamic programming – Given the optimum tilings of all subtrees, generate In contrast to maximal munch, the trees are optimum tiling of the current tree matched bottom-up • consider all tiles for the root of the current tree • sum cost of best subtree tiles and each tile • choose tile with minimum total cost Second pass generates the code using the results from the bottom-up pass 32 33 School of Computer Science School of Computer Science Bottom-up CG, pass 1 Bottom-up CG, pass 2 (10,6),(11,6) (10,6),(11,6) MOVE MOVE (9,4) (9,2) (9,4)
Recommended publications
  • Metaheuristics1
    METAHEURISTICS1 Kenneth Sörensen University of Antwerp, Belgium Fred Glover University of Colorado and OptTek Systems, Inc., USA 1 Definition A metaheuristic is a high-level problem-independent algorithmic framework that provides a set of guidelines or strategies to develop heuristic optimization algorithms (Sörensen and Glover, To appear). Notable examples of metaheuristics include genetic/evolutionary algorithms, tabu search, simulated annealing, and ant colony optimization, although many more exist. A problem-specific implementation of a heuristic optimization algorithm according to the guidelines expressed in a metaheuristic framework is also referred to as a metaheuristic. The term was coined by Glover (1986) and combines the Greek prefix meta- (metá, beyond in the sense of high-level) with heuristic (from the Greek heuriskein or euriskein, to search). Metaheuristic algorithms, i.e., optimization methods designed according to the strategies laid out in a metaheuristic framework, are — as the name suggests — always heuristic in nature. This fact distinguishes them from exact methods, that do come with a proof that the optimal solution will be found in a finite (although often prohibitively large) amount of time. Metaheuristics are therefore developed specifically to find a solution that is “good enough” in a computing time that is “small enough”. As a result, they are not subject to combinatorial explosion – the phenomenon where the computing time required to find the optimal solution of NP- hard problems increases as an exponential function of the problem size. Metaheuristics have been demonstrated by the scientific community to be a viable, and often superior, alternative to more traditional (exact) methods of mixed- integer optimization such as branch and bound and dynamic programming.
    [Show full text]
  • Modern Compiler Implementation in Java. Second Edition
    Team-Fly Modern Compiler Implementation in Java, Second Edition by Andrew W. ISBN:052182060x Appel and Jens Palsberg Cambridge University Press © 2002 (501 pages) This textbook describes all phases of a compiler, and thorough coverage of current techniques in code generation and register allocation, and the compilation of functional and object-oriented languages. Table of Contents Modern Compiler Implementation in Java, Second Edition Preface Part One - Fundamentals of Compilation Ch apt - Introduction er 1 Ch apt - Lexical Analysis er 2 Ch apt - Parsing er 3 Ch apt - Abstract Syntax er 4 Ch apt - Semantic Analysis er 5 Ch apt - Activation Records er 6 Ch apt - Translation to Intermediate Code er 7 Ch apt - Basic Blocks and Traces er 8 Ch apt - Instruction Selection er 9 Ch apt - Liveness Analysis er 10 Ch apt - Register Allocation er 11 Ch apt - Putting It All Together er 12 Part Two - Advanced Topics Ch apt - Garbage Collection er 13 Ch apt - Object-Oriented Languages er 14 Ch apt - Functional Programming Languages er 15 Ch apt - Polymorphic Types er 16 Ch apt - Dataflow Analysis er 17 Ch apt - Loop Optimizations er 18 Ch apt - Static Single-Assignment Form er 19 Ch apt - Pipelining and Scheduling er 20 Ch apt - The Memory Hierarchy er 21 Ap pe ndi - MiniJava Language Reference Manual x A Bibliography Index List of Figures List of Tables List of Examples Team-Fly Team-Fly Back Cover This textbook describes all phases of a compiler: lexical analysis, parsing, abstract syntax, semantic actions, intermediate representations, instruction selection via tree matching, dataflow analysis, graph-coloring register allocation, and runtime systems.
    [Show full text]
  • Resourceable, Retargetable, Modular Instruction Selection Using a Machine-Independent, Type-Based Tiling of Low-Level Intermediate Code
    Reprinted from Proceedings of the 2011 ACM Symposium on Principles of Programming Languages (POPL’11) Resourceable, Retargetable, Modular Instruction Selection Using a Machine-Independent, Type-Based Tiling of Low-Level Intermediate Code Norman Ramsey Joao˜ Dias Department of Computer Science, Tufts University Department of Computer Science, Tufts University [email protected] [email protected] Abstract Our compiler infrastructure is built on C--, an abstraction that encapsulates an optimizing code generator so it can be reused We present a novel variation on the standard technique of selecting with multiple source languages and multiple target machines (Pey- instructions by tiling an intermediate-code tree. Typical compilers ton Jones, Ramsey, and Reig 1999; Ramsey and Peyton Jones use a different set of tiles for every target machine. By analyzing a 2000). C-- accommodates multiple source languages by providing formal model of machine-level computation, we have developed a two main interfaces: the C-- language is a machine-independent, single set of tiles that is machine-independent while retaining the language-independent target language for front ends; the C-- run- expressive power of machine code. Using this tileset, we reduce the time interface is an API which gives the run-time system access to number of tilers required from one per machine to one per archi- the states of suspended computations. tectural family (e.g., register architecture or stack architecture). Be- cause the tiler is the part of the instruction selector that is most dif- C-- is not a universal intermediate language (Conway 1958) or ficult to reason about, our technique makes it possible to retarget an a “write-once, run-anywhere” intermediate language encapsulating instruction selector with significantly less effort than standard tech- a rigidly defined compiler and run-time system (Lindholm and niques.
    [Show full text]
  • Lecture 4 Dynamic Programming
    1/17 Lecture 4 Dynamic Programming Last update: Jan 19, 2021 References: Algorithms, Jeff Erickson, Chapter 3. Algorithms, Gopal Pandurangan, Chapter 6. Dynamic Programming 2/17 Backtracking is incredible powerful in solving all kinds of hard prob- lems, but it can often be very slow; usually exponential. Example: Fibonacci numbers is defined as recurrence: 0 if n = 0 Fn =8 1 if n = 1 > Fn 1 + Fn 2 otherwise < ¡ ¡ > A direct translation in:to recursive program to compute Fibonacci number is RecFib(n): if n=0 return 0 if n=1 return 1 return RecFib(n-1) + RecFib(n-2) Fibonacci Number 3/17 The recursive program has horrible time complexity. How bad? Let's try to compute. Denote T(n) as the time complexity of computing RecFib(n). Based on the recursion, we have the recurrence: T(n) = T(n 1) + T(n 2) + 1; T(0) = T(1) = 1 ¡ ¡ Solving this recurrence, we get p5 + 1 T(n) = O(n); = 1.618 2 So the RecFib(n) program runs at exponential time complexity. RecFib Recursion Tree 4/17 Intuitively, why RecFib() runs exponentially slow. Problem: redun- dant computation! How about memorize the intermediate computa- tion result to avoid recomputation? Fib: Memoization 5/17 To optimize the performance of RecFib, we can memorize the inter- mediate Fn into some kind of cache, and look it up when we need it again. MemFib(n): if n = 0 n = 1 retujrjn n if F[n] is undefined F[n] MemFib(n-1)+MemFib(n-2) retur n F[n] How much does it improve upon RecFib()? Assuming accessing F[n] takes constant time, then at most n additions will be performed (we never recompute).
    [Show full text]
  • Dynamic Programming Via Static Incrementalization 1 Introduction
    Dynamic Programming via Static Incrementalization Yanhong A. Liu and Scott D. Stoller Abstract Dynamic programming is an imp ortant algorithm design technique. It is used for solving problems whose solutions involve recursively solving subproblems that share subsubproblems. While a straightforward recursive program solves common subsubproblems rep eatedly and of- ten takes exp onential time, a dynamic programming algorithm solves every subsubproblem just once, saves the result, reuses it when the subsubproblem is encountered again, and takes p oly- nomial time. This pap er describ es a systematic metho d for transforming programs written as straightforward recursions into programs that use dynamic programming. The metho d extends the original program to cache all p ossibly computed values, incrementalizes the extended pro- gram with resp ect to an input increment to use and maintain all cached results, prunes out cached results that are not used in the incremental computation, and uses the resulting in- cremental program to form an optimized new program. Incrementalization statically exploits semantics of b oth control structures and data structures and maintains as invariants equalities characterizing cached results. The principle underlying incrementalization is general for achiev- ing drastic program sp eedups. Compared with previous metho ds that p erform memoization or tabulation, the metho d based on incrementalization is more powerful and systematic. It has b een implemented and applied to numerous problems and succeeded on all of them. 1 Intro duction Dynamic programming is an imp ortant technique for designing ecient algorithms [2, 44 , 13 ]. It is used for problems whose solutions involve recursively solving subproblems that overlap.
    [Show full text]
  • Automatic Code Generation Using Dynamic Programming Techniques
    ! Automatic Code Generation using Dynamic Programming Techniques MASTERARBEIT zur Erlangung des akademischen Grades Diplom-Ingenieur im Masterstudium INFORMATIK Eingereicht von: Igor Böhm, 0155477 Angefertigt am: Institut für System Software Betreuung: o.Univ.-Prof.Dipl.-Ing. Dr. Dr.h.c. Hanspeter Mössenböck Linz, Oktober 2007 Abstract Building compiler back ends from declarative specifications that map tree structured intermediate representations onto target machine code is the topic of this thesis. Although many tools and approaches have been devised to tackle the problem of automated code generation, there is still room for improvement. In this context we present Hburg, an implementation of a code generator generator that emits compiler back ends from concise tree pattern specifications written in our code generator description language. The language features attribute grammar style specifications and allows for great flexibility with respect to the placement of semantic actions. Our main contribution is to show that these language features can be integrated into automatically generated code generators that perform optimal instruction selection based on tree pattern matching combined with dynamic program- ming. In order to substantiate claims about the usefulness of our language we provide two complete examples that demonstrate how to specify code generators for Risc and Cisc architectures. Kurzfassung Diese Diplomarbeit beschreibt Hburg, ein Werkzeug das aus einer Spezi- fikation des abstrakten Syntaxbaums eines Programms und der Spezifika- tion der gewuns¨ chten Zielmaschine automatisch einen Codegenerator fur¨ diese Maschine erzeugt. Abbildungen zwischen abstrakten Syntaxb¨aumen und einer Zielmaschine werden durch Baummuster definiert. Fur¨ diesen Zweck haben wir eine deklarative Beschreibungssprache entwickelt, die es erm¨oglicht den Baummustern Attribute beizugeben, wodurch diese gleich- sam parametrisiert werden k¨onnen.
    [Show full text]
  • Maximal-Munch” Tokenization in Linear Time Tom Reps [TOPLAS 1998]
    Fall 2016-2017 Compiler Principles Lecture 1: Lexical Analysis Roman Manevich Ben-Gurion University of the Negev Agenda • Understand role of lexical analysis in a compiler • Regular languages reminder • Lexical analysis algorithms • Scanner generation 2 Javascript example • Can you some identify basic units in this code? var currOption = 0; // Choose content to display in lower pane. function choose ( id ) { var menu = ["about-me", "publications", "teaching", "software", "activities"]; for (i = 0; i < menu.length; i++) { currOption = menu[i]; var elt = document.getElementById(currOption); if (currOption == id && elt.style.display == "none") { elt.style.display = "block"; } else { elt.style.display = "none"; } } } 3 Javascript example • Can you some identify basic units in this code? keyword ? ? ? ? ? var currOption = 0; // Choose content to display in lower pane. ? function choose ( id ) { var menu = ["about-me", "publications", "teaching", "software", "activities"]; ? for (i = 0; i < menu.length; i++) { currOption = menu[i]; var elt = document.getElementById(currOption); if (currOption == id && elt.style.display == "none") { elt.style.display = "block"; } else { elt.style.display = "none"; } } } 4 Javascript example • Can you some identify basic units in this code? keyword identifier operator numeric literal punctuation comment var currOption = 0; // Choose content to display in lower pane. string literal function choose ( id ) { var menu = ["about-me", "publications", "teaching", "software", "activities"]; whitespace for (i = 0; i < menu.length; i++) { currOption = menu[i]; var elt = document.getElementById(currOption); if (currOption == id && elt.style.display == "none") { elt.style.display = "block"; } else { elt.style.display = "none"; } } } 5 Role of lexical analysis • First part of compiler front-end Lexical Syntax AST Symbol Inter. Code High-level Analysis Analysis Table Rep.
    [Show full text]
  • 1 Introduction 2 Dijkstra's Algorithm
    15-451/651: Design & Analysis of Algorithms September 3, 2019 Lecture #3: Dynamic Programming II last changed: August 30, 2019 In this lecture we continue our discussion of dynamic programming, focusing on using it for a variety of path-finding problems in graphs. Topics in this lecture include: • The Bellman-Ford algorithm for single-source (or single-sink) shortest paths. • Matrix-product algorithms for all-pairs shortest paths. • Algorithms for all-pairs shortest paths, including Floyd-Warshall and Johnson. • Dynamic programming for the Travelling Salesperson Problem (TSP). 1 Introduction As a reminder of basic terminology: a graph is a set of nodes or vertices, with edges between some of the nodes. We will use V to denote the set of vertices and E to denote the set of edges. If there is an edge between two vertices, we call them neighbors. The degree of a vertex is the number of neighbors it has. Unless otherwise specified, we will not allow self-loops or multi-edges (multiple edges between the same pair of nodes). As is standard with discussing graphs, we will use n = jV j, and m = jEj, and we will let V = f1; : : : ; ng. The above describes an undirected graph. In a directed graph, each edge now has a direction (and as we said earlier, we will sometimes call the edges in a directed graph arcs). For each node, we can now talk about out-neighbors (and out-degree) and in-neighbors (and in-degree). In a directed graph you may have both an edge from u to v and an edge from v to u.
    [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]
  • Bellman-Ford Algorithm
    The many cases offinding shortest paths Dynamic programming Bellman-Ford algorithm We’ve already seen how to calculate the shortest path in an Tyler Moore unweighted graph (BFS traversal) We’ll now study how to compute the shortest path in different CSE 3353, SMU, Dallas, TX circumstances for weighted graphs Lecture 18 1 Single-source shortest path on a weighted DAG 2 Single-source shortest path on a weighted graph with nonnegative weights (Dijkstra’s algorithm) 3 Single-source shortest path on a weighted graph including negative weights (Bellman-Ford algorithm) Some slides created by or adapted from Dr. Kevin Wayne. For more information see http://www.cs.princeton.edu/~wayne/kleinberg-tardos. Some code reused from Python Algorithms by Magnus Lie Hetland. 2 / 13 �������������� Shortest path problem. Given a digraph ����������, with arbitrary edge 6. DYNAMIC PROGRAMMING II weights or costs ���, find cheapest path from node � to node �. ‣ sequence alignment ‣ Hirschberg's algorithm ‣ Bellman-Ford 1 -3 3 5 ‣ distance vector protocols 4 12 �������� 0 -5 ‣ negative cycles in a digraph 8 7 7 2 9 9 -1 1 11 ����������� 5 5 -3 13 4 10 6 ������������� ���������������������������������� 22 3 / 13 4 / 13 �������������������������������� ��������������� Dijkstra. Can fail if negative edge weights. Def. A negative cycle is a directed cycle such that the sum of its edge weights is negative. s 2 u 1 3 v -8 w 5 -3 -3 Reweighting. Adding a constant to every edge weight can fail. 4 -4 u 5 5 2 2 ���������������������� c(W) = ce < 0 t s e W 6 6 �∈ 3 3 0 v -3 w 23 24 5 / 13 6 / 13 ���������������������������������� ���������������������������������� Lemma 1.
    [Show full text]
  • CS415 Compilers Register Allocation and Introduction to Instruction Scheduling
    CS415 Compilers Register Allocation and Introduction to Instruction Scheduling These slides are based on slides copyrighted by Keith Cooper, Ken Kennedy & Linda Torczon at Rice University Announcement • First homework out → Due tomorrow 11:59pm EST. → Sakai submission window open. → pdf format only. • Late policy → 20% penalty for first 24 hours late. → Not accepted 24 hours after deadline. If you have personal overriding reasons that prevents you from submitting homework online, please let me know in advance. cs415, spring 16 2 Lecture 3 Review: ILOC Register allocation on basic blocks in “ILOC” (local register allocation) • Pseudo-code for a simple, abstracted RISC machine → generated by the instruction selection process • Simple, compact data structures • Here: we only use a small subset of ILOC → ILOC simulator at ~zhang/cs415_2016/ILOC_Simulator on ilab cluster Naïve Representation: Quadruples: loadI 2 r1 • table of k x 4 small integers loadAI r0 @y r2 • simple record structure add r1 r2 r3 • easy to reorder loadAI r0 @x r4 • all names are explicit sub r4 r3 r5 ILOC is described in Appendix A of EAC cs415, spring 16 3 Lecture 3 Review: F – Set of Feasible Registers Allocator may need to reserve registers to ensure feasibility • Must be able to compute addresses Notation: • Requires some minimal set of registers, F k is the number of → F depends on target architecture registers on the • F contains registers to make spilling work target machine (set F registers “aside”, i.e., not available for register assignment) cs415, spring 16 4 Lecture 3 Live Range of a Value (Virtual Register) A value is live between its definition and its uses • Find definitions (x ← …) and uses (y ← … x ...) • From definition to last use is its live range → How does a second definition affect this? • Can represent live range as an interval [i,j] (in block) → live on exit Let MAXLIVE be the maximum, over each instruction i in the block, of the number of values (pseudo-registers) live at i.
    [Show full text]
  • CS 444: Compiler Construction
    CS 444: Compiler Construction Gabriel Wong Contents Introduction 3 Front-end Analysis . .3 Formal Languages . .3 Lexical Analysis / Scanning 3 Regular Expressions . .3 Regex to DFA . .4 Definition of NFA and DFA . .4 Computing -closure . .4 NFA to DFA Conversion . .5 Scanning . .6 Constructing Scanning DFA . .6 Parsing 7 Context-Free Grammar . .7 Top-down / Bottom-up Parsing . .8 LL(1) Parsing . .9 Augmented Grammar . 10 LL(1) Algorithm . 10 LR(0) Parsing . 11 LR(1) Parsing . 15 SLR(1) Parser . 15 Comparison Between LR Parsers . 16 LR(1) NFA . 16 LALR(1) Parser . 17 Abstract Syntax Tree . 19 Semantic Analysis 19 Implementing Environments . 20 Namespaces . 20 Java Name Resolution . 21 1. Create class environment . 21 2. Resolve type names . 21 3. Check class hierachy . 21 4. Disambiguate ambiguous names . 23 5. Resolve expressions (variables, fields) . 23 6. Type checking . 24 7. Resolve methods and instance fields . 27 Static Analysis 28 Java Reachability Analysis (JLS 14.20) . 28 Java Definite Assignment Analysis (JLS 16) . 29 1 CONTENTS CONTENTS Live Variable Analysis . 30 Code Generation 31 IA-32 Assembly . 32 Assembler Directives . 32 Strategy for Code Generation . 33 Data Layout . 33 Constants . 34 Local Variables . 34 Method Calls . 35 Object Layout . 36 Vtables . 37 Dispatching Interface Methods . 37 Subtype Testing . 38 Arrays................................................. 38 2 Regular Expressions LEXICAL ANALYSIS / SCANNING Notes taken from lectures by Ondřej Lhoták in Winter 2016. Introduction A compiler translates from a source language (eg. Java) to a target machine language (eg. x86). Scanning, parsing (A1) and context sensitive analysis (A234) are part of the compiler front end.
    [Show full text]