CS415 Compilers. Intermediate Represeation & Code Generation

Similar documents
Code Shape II Expressions & Assignment

Compiler Design. Code Shaping. Hwansoo Han

Copyright 2003, Keith D. Cooper, Ken Kennedy & Linda Torczon, all rights reserved. Students enrolled in Comp 412 at Rice University have explicit

Intermediate Representations

CS 406/534 Compiler Construction Instruction Scheduling beyond Basic Block and Code Generation

Intermediate Representations

Intermediate Representations

Code Shape Comp 412 COMP 412 FALL Chapters 4, 5, 6 & 7 in EaC2e. source code. IR IR target. code. Front End Optimizer Back End

Intermediate Representations

COMP 181. Prelude. Intermediate representations. Today. High-level IR. Types of IRs. Intermediate representations and code generation

Intermediate Representations & Symbol Tables

Instruction Selection: Preliminaries. Comp 412

opt. front end produce an intermediate representation optimizer transforms the code in IR form into an back end transforms the code in IR form into

Generating Code for Assignment Statements back to work. Comp 412 COMP 412 FALL Chapters 4, 6 & 7 in EaC2e. source code. IR IR target.

Compilers. Intermediate representations and code generation. Yannis Smaragdakis, U. Athens (original slides by Sam

Instruction Selection, II Tree-pattern matching

Intermediate Representations Part II

Alternatives for semantic processing

CS 406/534 Compiler Construction Intermediate Representation and Procedure Abstraction

Intermediate Representation (IR)

6. Intermediate Representation

CS415 Compilers Register Allocation. These slides are based on slides copyrighted by Keith Cooper, Ken Kennedy & Linda Torczon at Rice University

Front End. Hwansoo Han

CSE P 501 Compilers. Intermediate Representations Hal Perkins Spring UW CSE P 501 Spring 2018 G-1

CS 406/534 Compiler Construction Putting It All Together

Acknowledgement. CS Compiler Design. Intermediate representations. Intermediate representations. Semantic Analysis - IR Generation

CSE 401/M501 Compilers

6. Intermediate Representation!

Introduction to Optimization, Instruction Selection and Scheduling, and Register Allocation

Instruction Selection: Peephole Matching. Copyright 2003, Keith D. Cooper, Ken Kennedy & Linda Torczon, all rights reserved.

Lecture 12: Compiler Backend

Handling Assignment Comp 412

Computing Inside The Parser Syntax-Directed Translation, II. Comp 412 COMP 412 FALL Chapter 4 in EaC2e. source code. IR IR target.

Data Structures and Algorithms in Compiler Optimization. Comp314 Lecture Dave Peixotto

Syntax-directed translation. Context-sensitive analysis. What context-sensitive questions might the compiler ask?

Intermediate representation

The Software Stack: From Assembly Language to Machine Code

CS 432 Fall Mike Lam, Professor. Code Generation

Computing Inside The Parser Syntax-Directed Translation, II. Comp 412

Agenda. CSE P 501 Compilers. Big Picture. Compiler Organization. Intermediate Representations. IR for Code Generation. CSE P 501 Au05 N-1

Code Shape Comp 412 COMP 412 FALL Chapters 4, 5, 6 & 7 in EaC2e. source code. IR IR target. code. Front End Optimizer Back End

Introduction to Compiler

Intermediate Code Generation

CS5363 Final Review. cs5363 1

Local Optimization: Value Numbering The Desert Island Optimization. Comp 412 COMP 412 FALL Chapter 8 in EaC2e. target code

Prof. Mohamed Hamada Software Engineering Lab. The University of Aizu Japan

CS415 Compilers. Instruction Scheduling and Lexical Analysis

CS415 Compilers. Procedure Abstractions. These slides are based on slides copyrighted by Keith Cooper, Ken Kennedy & Linda Torczon at Rice University

Implementing Control Flow Constructs Comp 412

Context-sensitive analysis. Semantic Processing. Alternatives for semantic processing. Context-sensitive analysis

CS415 Compilers Overview of the Course. These slides are based on slides copyrighted by Keith Cooper, Ken Kennedy & Linda Torczon at Rice University

The View from 35,000 Feet

Intermediate Code Generation (ICG)

Compiler Optimisation

Computing Inside The Parser Syntax-Directed Translation. Comp 412 COMP 412 FALL Chapter 4 in EaC2e. source code. IR IR target.

Instruction Selection and Scheduling

CSc 453. Compilers and Systems Software. 13 : Intermediate Code I. Department of Computer Science University of Arizona

Intermediate Representations

CMPT 379 Compilers. Parse trees

Topic 6 Basic Back-End Optimization

Advanced C Programming

CS 406/534 Compiler Construction Instruction Selection and Global Register Allocation

CS1622. Semantic Analysis. The Compiler So Far. Lecture 15 Semantic Analysis. How to build symbol tables How to use them to find

Procedure and Function Calls, Part II. Comp 412 COMP 412 FALL Chapter 6 in EaC2e. target code. source code Front End Optimizer Back End

Local Register Allocation (critical content for Lab 2) Comp 412

Computing Inside The Parser Syntax-Directed Translation. Comp 412

Parsing III. CS434 Lecture 8 Spring 2005 Department of Computer Science University of Alabama Joel Jones

COMP-421 Compiler Design. Presented by Dr Ioanna Dionysiou

CS 406/534 Compiler Construction Instruction Scheduling

Intermediate Code Generation

Arrays and Functions

CSE443 Compilers. Dr. Carl Alphonce 343 Davis Hall

The structure of a compiler

CST-402(T): Language Processors

Project Compiler. CS031 TA Help Session November 28, 2011

Intermediate Code Generation

Semantic Analysis computes additional information related to the meaning of the program once the syntactic structure is known.

Computer Science Department Carlos III University of Madrid Leganés (Spain) David Griol Barres

Semantic analysis and intermediate representations. Which methods / formalisms are used in the various phases during the analysis?

Grammars. CS434 Lecture 15 Spring 2005 Department of Computer Science University of Alabama Joel Jones

CS 432 Fall Mike Lam, Professor. Compilers. Advanced Systems Elective

CS 432 Fall Mike Lam, Professor. Compilers. Advanced Systems Elective

9/21/17. Outline. Expression Evaluation and Control Flow. Arithmetic Expressions. Operators. Operators. Notation & Placement

CSE 504: Compiler Design. Instruction Selection

Comp 204: Computer Systems and Their Implementation. Lecture 22: Code Generation and Optimisation

CS415 Compilers. Lexical Analysis

Lab 3, Tutorial 1 Comp 412

Code Generation. The Main Idea of Today s Lecture. We can emit stack-machine-style code for expressions via recursion. Lecture Outline.

Intermediate Code Generation

We can emit stack-machine-style code for expressions via recursion

Compiler Code Generation COMP360

Lecture Outline. Code Generation. Lecture 30. Example of a Stack Machine Program. Stack Machines

CODE GENERATION Monday, May 31, 2010

Principles of Compiler Design

Compiler Optimization Intermediate Representation

Register Allocation. Note by Baris Aktemur: Our slides are adapted from Cooper and Torczon s slides that they prepared for COMP 412 at Rice.

Code generation for modern processors

G Compiler Construction Lecture 12: Code Generation I. Mohamed Zahran (aka Z)

Code generation for modern processors

Code Generation. Lecture 30

Transcription:

CS415 Compilers Intermediate Represeation & Code Generation These slides are based on slides copyrighted by Keith Cooper, Ken Kennedy & Linda Torczon at Rice University

Review - Types of Intermediate Representations Three major categories Structural Graphically oriented Heavily used in source-to-source translators Tend to be large Linear Pseudo-code for an abstract machine Level of abstraction varies Simple, compact data structures Easier to rearrange Hybrid Combination of graphs and linear code Examples: Trees, DAGs Examples: 3 address code Stack machine code Example: Control-flow graph 2

Review - Abstract Syntax Tree An abstract syntax tree is the procedure s parse tree with the nodes for most non-terminal nodes removed - x * x - 2 * y Can use linearized form of the tree Easier to manipulate than pointers x 2 y * - 2 y in postfix form - * y 2 x in prefix form S-expressions are (essentially) ASTs (remember functional languages such as Scheme or Lisp!) 3

Review - Directed Acyclic Graph A directed acyclic graph (DAG) is an AST with a unique node for each value z - w / x * 2 y z x - 2 * y w x / 2 Makes sharing explicit Encodes redundancy Same expression twice means that the compiler might arrange to evaluate it just once! 4

Review - Stack Machine Code Originally used for stack-based computers, now Java Example: push x! x - 2 * y becomes push 2! push y! multiply! subtract! Advantages Compact form Introduced names are implicit, not explicit Simple to generate and execute code Useful where code is transmitted over slow communication links (the net ) Implicit names take up no space, where explicit ones do! 5

Review - Three Address Code Several different representations of three address code In general, three address code has statements of the form: x y op z With 1 operator (op ) and, at most, 3 names (x, y, z) Example: z x - 2 * y becomes t 2 * y! z x - t! Advantages: Resembles many machines Introduces a new set of names Compact form 6

Review - Three Address Code: Quadruples Naïve representation of three address code Table of k * 4 small integers Simple record structure Easy to reorder Explicit names load r1, y! loadi r2, 2! mult r3, r2, r1! load r4, x! sub r5, r4, r3! load loadi mult load sub The original FORTRAN compiler used quads 1 2 3 4 5 Y [2] 2 X 4 1 2 RISC assembly code Quadruples 7

Review - Three Address Code: Triples Index used as implicit name 25% less space consumed than quads Much harder to reorder (1) load y (2) loadi 2 (3) mult (1) (2) (4) load x (5) sub (4) (3) Implicit names take no space! 8

Review - Control-flow Graph (CFG) Models the transfer of control in the procedure Nodes in the graph are basic blocks Can be represented with quads or any other linear representation Edges in the graph represent control flow Example a 2 b 5 if (x == y) a 3 b 4 Basic blocks Maximal length sequences of straight-line code c a * b 9

Review - Static Single Assignment Form (SSA) The main idea: each name defined exactly once in program Introduce φ-functions to make it work Original! x...! y...! while (x < k)! x x 1! y y x! SSA-form Strengths of SSA-form Sharper analysis φ-functions give hints about placement (sometimes) faster algorithms x 0...! y 0...! if (x 0 > k) goto next! loop: x 1 φ(x 0,x 2 )! y 1 φ(y 0,y 2 )! x 2 x 1 1! y 2 y 1 x 2! if (x 2 < k) goto loop! next:...! 10

Code Generation: Structure of a Compiler (EaC Ch. 7) O(n) O(n) O(n), O(n log n), NP-Complete Scanner words Parser IR Analysis & Optimization IR Instruction Selection Either fast or NP-Complete asm asm asm regs Instruction Scheduling NP-Complete regs Register Allocation NP-Complete k regs A compiler is a lot of fast stuff followed by some hard problems The hard stuff is mostly in code generation and optimization For superscalars, its allocation & scheduling that is particularly important 11

Review - The Big Picture Conventional wisdom says that we lose little by solving these problems independently Instruction selection Use some form of pattern matching Assume enough registers or target important values Instruction scheduling Within a block, list scheduling is close to optimal Across blocks, build framework to apply list scheduling Register allocation Start from virtual registers & map into k Focus on good priority heuristic Note: many fuzzy terms here! 12

Code Shape Definition All those nebulous properties of the code that impact performance & code quality Includes code, approach for different constructs, cost, storage requirements & mapping, & choice of operations Code shape is the end product of many decisions (big & small) Impact Code shape influences algorithm choice & results Code shape can encode important facts, or hide them Rule of thumb: expose as much derived information as possible Example: explicit branch targets in ILOC simplify analysis 13

Code Shape An example x y z x y t1 x z t1 y z t1 t1 z t2 t1 y t2 t1 x t2 x y z What if x is 2 and z is 3? What if yz is evaluated earlier? x y z x z y y z Addition is commutative & associative for integers x The best shape for xyz depends on contextual knowledge There may be several conflicting options 14

Code Shape An example x y z x y t1 x z t1 y z t1 t1 z t2 t1 y t2 t1 x t2 x y z What if x is 2 and z is 3? What if yz is evaluated earlier? x y z x z y y z Addition is commutative & associative for integers x The best shape for xyz depends on contextual knowledge There may be several conflicting options x (5 y)*7 15

Code Shape Another example -- the case statement Implement it as cascaded if-then-else statements Cost depends on where your case actually occurs O(number of cases) Implement it as a binary search Uniform (log n) cost Implement it as a jump table Lookup address in a table & jump to it Uniform (constant) cost Switch (var) { case 1: statement 1; break; case 2: statement 2; break; case 3: statement 3: break; default:. } Lecture 20 16

Generating Code for Expressions The key code quality issue is holding values in registers When can a value be safely allocated to a register? When only 1 name can reference its value (no aliasing) int *a, b;.; a = &b; b = ; ; c = *a; Pointers, parameters, aggregates & arrays all cause trouble When should a value be allocated to a register? When it is both safe & profitable Encoding this knowledge into the IR (register-register model) Use code shape to make it known to every later phase Assign a virtual register to anything that can go into one Load or store the others at each reference Relies on a strong register allocator Lecture 20 17

Generating Code for Expressions expr(node) { int result, t1, t2; switch (type(node)) { case,,,- : t1 expr(left child(node)); t2 expr(right child(node)); result NextRegister(); emit (op(node), t1, t2, result); break; case IDENTIFIER: t1 base(node); t2 offset(node); result NextRegister(); emit (loadao, t1, t2, result); break; case NUMBER: result NextRegister(); emit (loadi, val(node), none, result); break; } return result; } Expr returns virtual register number that will contain result of subtree evaluation at runtime The concept Use a simple treewalk evaluator Bury complexity in routines it calls > base(), offset(), & val() Implements expected behavior > Visits & evaluates children > Emits code for the op itself > Returns register with result Works for simple expressions Easily extended to other operators Does not handle control flow Lecture 20 18

Generating Code for Expressions expr(node) { int result, t1, t2; switch (type(node)) { case,,,- : t1 expr(left child(node)); t2 expr(right child(node)); result NextRegister(); emit (op(node), t1, t2, result); break; case IDENTIFIER: t1 base(node); t2 offset(node); result NextRegister(); emit (loadao, t1, t2, result); break; case NUMBER: result NextRegister(); emit (loadi, val(node), none, result); break; } return result; } Example: x y Produces: expr( x ) loadi @x r1 loadao r0, r1 r2 expr( y ) loadi @y r3 loadao r0, r3 r4 NextRegister() r5 emit(add,r2,r4,r5) add r2, r4 r5 Lecture 20 19

Generating Code for Expressions expr(node) { int result, t1, t2; switch (type(node)) { case,,,- : t1 expr(left child(node)); t2 expr(right child(node)); result NextRegister(); emit (op(node), t1, t2, result); break; case IDENTIFIER: t1 base(node); t2 offset(node); result NextRegister(); emit (loadao, t1, t2, result); break; case NUMBER: result NextRegister(); emit (loadi, val(node), none, result); break; } return result; } Example: Generates: x - 2 loadi @x r1 loadao r0, r1 r2 loadi 2 r3 loadi @y r4 loadao r0,r4 r5 mult r3, r5 r6 sub r2, r6 r7 y Lecture 20 20

Extending the Simple Treewalk Algorithm More complex cases for IDENTIFIER What about values in registers? Modify the IDENTIFIER case Already in a register return the register name Not in a register load it as before, but record the fact Choose names to avoid creating false dependences ( fresh virtual register) What about parameter values? Many linkages pass the first several values in registers Call-by-value just a local variable with funny offset Call-by-reference needs an extra indirection What about function calls in expressions? Generate the calling sequence & load the return value Severely limits compiler s ability to reorder operations (We will learn about this later) Lecture 20 21

Extending the Simple Treewalk Algorithm Adding other operators (in addition to, -, *, /) Evaluate the operands, then perform the operation Complex operations may turn into library calls Handle assignment as an operator Mixed-type expressions Insert conversions as needed from conversion table Most languages have symmetric & rational conversion tables Typical Addition Table Integer Real Double Complex Integer Integer Real Double Complex Real Real Real Double Complex Double Double Double Double Complex Complex Complex Complex Complex Complex Lecture 20 22

Extending the Simple Treewalk Algorithm What about evaluation order? Can use commutativity & associativity to improve code This problem is truly hard What about order of evaluating operands? 1 st operand must be preserved while 2 nd is evaluated Takes an extra register for 2 nd operand Should evaluate more demanding operand expression first (Ershov in the 1950 s, Sethi in the 1970 s) Taken to its logical conclusion, this creates Sethi-Ullman register allocation scheme (ASU p. 571) Lecture 20 23

Generating Code in the Parser Need to generate an initial IR form Might generate an AST, use it for some high-level, nearsource work (type checking, optimization), then traverse it and emit a lower-level IR similar to ILOC The big picture Recursive expr(node) algorithm really works bottom-up Actions on non-leaves occur after children are done Can encode same basic structure into ad-hoc SDT scheme Identifiers load themselves & stack (live in parser stack) virtual register name Operators emit appropriate code & stack resulting VR name Assignment requires evaluation to an lvalue or an rvalue Lecture 20 24

Ad-hoc SDT versus a Recursive Treewalk expr(node) { int result, t1, t2; switch (type(node)) { case,,,- : t1 expr(left child(node)); t2 expr(right child(node)); result NextRegister(); emit (op(node), t1, t2, result); break; case IDENTIFIER: t1 base(node); t2 offset(node); result NextRegister(); emit (loadao, t1, t2, result); break; case NUMBER: result NextRegister(); emit (loadi, val(node), none, result); break; } return result; } Goal : Expr { $$ = $1; } ; Expr: Expr PLUS Term { t = NextRegister(); emit(add,$1,$3,t); $$ = t; } Expr MINUS Term { } Term { $$ = $1; } ; Term: Term TIMES Factor { t = NextRegister(); emit(mult,$1,$3,t); $$ = t; }; Term DIVIDES Factor { } Factor { $$ = $1; }; Factor: NUMBER { t = NextRegister(); emit(loadi,val($1),none, t ); $$ = t; } ID { t1 = base($1); t2 = offset($1); t = NextRegister(); emit(loadao,t1,t2,t); $$ = t; } Lecture 20 25

Next class More code generation Read EaC: Chapter 7.1 7.5 26