Intermediate Representation (IR)

Similar documents
Intermediate Representations

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

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

Intermediate Representations

Intermediate representation

Intermediate Representations Part II

CS415 Compilers. Intermediate Represeation & Code Generation

Intermediate Representations & Symbol Tables

CSE 401/M501 Compilers

Intermediate Representations

Intermediate Representations

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

Intermediate Code Generation

Alternatives for semantic processing

6. Intermediate Representation!

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

6. Intermediate Representation

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

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

Goals of Program Optimization (1 of 2)

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

Principles of Compiler Design

Front End. Hwansoo Han

SSA Construction. Daniel Grund & Sebastian Hack. CC Winter Term 09/10. Saarland University

ECE 5775 (Fall 17) High-Level Digital Design Automation. Static Single Assignment

Lecture 3 Local Optimizations, Intro to SSA

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 Representations. Reading & Topics. Intermediate Representations CS2210

PSD3A Principles of Compiler Design Unit : I-V. PSD3A- Principles of Compiler Design

CSE P 501 Compilers. SSA Hal Perkins Spring UW CSE P 501 Spring 2018 V-1

Control flow graphs and loop optimizations. Thursday, October 24, 13

9/5/17. The Design and Implementation of Programming Languages. Compilation. Interpretation. Compilation vs. Interpretation. Hybrid Implementation

Run-time Environments. Lecture 13. Prof. Alex Aiken Original Slides (Modified by Prof. Vijay Ganesh) Lecture 13

Lecture 23 CIS 341: COMPILERS

An Overview of GCC Architecture (source: wikipedia) Control-Flow Analysis and Loop Detection

What is a compiler? var a var b mov 3 a mov 4 r1 cmpi a r1 jge l_e mov 2 b jmp l_d l_e: mov 3 b l_d: ;done

Compiler Optimization Intermediate Representation

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

Code generation for modern processors

Intermediate Code & Local Optimizations

Advanced C Programming

Code generation for modern processors

Lecture 31: Building a Runnable Program

Middle End. Code Improvement (or Optimization) Analyzes IR and rewrites (or transforms) IR Primary goal is to reduce running time of the compiled code

CS 406/534 Compiler Construction Intermediate Representation and Procedure Abstraction

Administration CS 412/413. Why build a compiler? Compilers. Architectural independence. Source-to-source translator

Topic I (d): Static Single Assignment Form (SSA)

Lecture 21 CIS 341: COMPILERS

Compiler Passes. Optimization. The Role of the Optimizer. Optimizations. The Optimizer (or Middle End) Traditional Three-pass Compiler

CS5363 Final Review. cs5363 1

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

A Bad Name. CS 2210: Optimization. Register Allocation. Optimization. Reaching Definitions. Dataflow Analyses 4/10/2013

Why Global Dataflow Analysis?

CSE443 Compilers. Dr. Carl Alphonce 343 Davis Hall

Code Generation. Lecture 30

Compiler Construction 2009/2010 SSA Static Single Assignment Form

A Propagation Engine for GCC

Introduction to Optimization Local Value Numbering

COP4020 Programming Languages. Compilers and Interpreters Robert van Engelen & Chris Lacher

Compiler Design. Code Shaping. Hwansoo Han

Syntax Errors; Static Semantics

What If. Static Single Assignment Form. Phi Functions. What does φ(v i,v j ) Mean?

Time : 1 Hour Max Marks : 30

Where we are. What makes a good IR? Intermediate Code. CS 4120 Introduction to Compilers

ECE 5775 High-Level Digital Design Automation Fall More CFG Static Single Assignment

Separate compilation. Topic 6: Runtime Environments p.1/21. CS 526 Topic 6: Runtime Environments The linkage convention

Code generation and optimization

Building a Runnable Program and Code Improvement. Dario Marasco, Greg Klepic, Tess DiStefano

CS 432 Fall Mike Lam, Professor. Code Generation

CST-402(T): Language Processors

Intermediate Code Generation

Announcements. My office hours are today in Gates 160 from 1PM-3PM. Programming Project 3 checkpoint due tomorrow night at 11:59PM.

Code generation and local optimization

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

Code generation and local optimization

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

CONTROL FLOW ANALYSIS. The slides adapted from Vikram Adve

Calvin Lin The University of Texas at Austin

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

CMSC430 Spring 2014 Midterm 2 Solutions

Principles of Compiler Design

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

Compiling and Interpreting Programming. Overview of Compilers and Interpreters

CSE 501: Compiler Construction. Course outline. Goals for language implementation. Why study compilers? Models of compilation

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

CS 406/534 Compiler Construction Putting It All Together

Intermediate Code Generation (ICG)

CODE GENERATION Monday, May 31, 2010

UNIT-V. Symbol Table & Run-Time Environments Symbol Table

Intermediate representations IR #1: CPS/L 3. Code example. Advanced Compiler Construction Michel Schinz

The structure of a compiler

Fall Compiler Principles Lecture 6: Intermediate Representation. Roman Manevich Ben-Gurion University of the Negev

Control Flow Analysis

Compilers and computer architecture: A realistic compiler to MIPS

Tour of common optimizations

Intermediate Representations

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

What is a compiler? Xiaokang Qiu Purdue University. August 21, 2017 ECE 573

Intermediate Code Generation

Transcription:

Intermediate Representation (IR) Components and Design Goals for an IR IR encodes all knowledge the compiler has derived about source program. Simple compiler structure source code More typical compiler structure front IR optimizer end IR back target end code Components of IR Code representation: actual statements or instructions Symbol table with links to/from code Analysis information with mapping to/from code Constants table: strings, initializers,... Storage map: stack frame layout, register assignments Design Goals for an IR? There is no universally good IR. Many forms of IR have been used. The right choice depends strongly on the goals of the compiler system. source code semantic front HIR HIR Lower checks LIR LIR back LLO targ end IR end cod & HLO Topic 5: Internal Representations p.1/32 Topic 5: Internal Representations p.2/32 Common Code and Analysis Representations Categories of IRs By Structure Code representations Usually have only one at a time Common alternatives: Abstract Syntax Tree (AST) SSA form + CFG 3-address code [+ CFG] Stack code Influences: semantic information types of optimizations ease of transformations speed of code generation size Analysis representations May have several at a time Common choices: Control Flow Graph (CFG) Symbolic expression DAGs Data dependence graph (DDG) SSA form Points-to graph / Alias sets Call graph Influences: analysis capabilities optimization capabilities Graphical IRs trees, directed graphs, DAGs node / edge data structures tend to be large harder to rearrange Examples: AST, CFG, SSA, DDG, Expression DAG, Points-to graph Hybrid IRs as the Code Representation CFG + 3-address code (SSA or non-ssa) CFG + 3-address code + expression DAG Linear IRs pseudo-code for abstract machine many possible semantic levels simple, compact data structures easier to rearrange AST (for control flow) + 3-address code (for basic blocks) AST (for control flow) + expression DAG (for basic blocks) Examples: 3-address, 2-address, accumulator, or stack code Topic 5: Internal Representations p.3/32 Topic 5: Internal Representations p.4/32

Abstract syntax tree Abstract syntax tree: Examples An Abstract Syntax Tree (AST) is a simplified parse tree. It retains syntactic structure of code. Well-suited for source code Widely used in source-source translators Captures both control flow constructs and straight-line code explicitly Traversal and transformations are both relatively expensive both are pointer-intensive transformations are memory-allocation-intensive Topic 5: Internal Representations p.5/32 Topic 5: Internal Representations p.6/32 Directed acyclic graph Control Flow Graph: CFG Example A Directed Acyclic Graph (DAG) is similar to an x 2*y + sin(2*x AST but with a unique node for each value. z x / 2 Advantages sharing of values is explicit z 1 / exposes redundancy (value computed twice) powerful representation for symbolic expressions x 1 + Disadvantages * sin difficult to transform (e.g., delete a stmt) y 0 * not useful for showing control flow structure Better for analysis than transformation 2 x 0 Definitions Basic Block a consecutive sequence of statements (or instructions) S 1...S n such that (a) the flow of control must enter the block at S 1, and (b) if S 1 is executed, then S 2...S n are all executed in that order (unless one of the statements causes the program to halt). Leader the first statement of a basic block Maximal Basic Block a maximal-length basic block CFG a directed graph (usually for a single procedure) in which: Each node is a single basic block There is an edge b 1 b 2 if control may flow from last stmt of b 1 to first stmt of b 2 in some execution NOTE: A CFG is a conservative approximation of the control flow! Why? Topic 5: Internal Representations p.7/32 Topic 5: Internal Representations p.8/32

Examples 1 - Conditional Control Flow Examples 2 - Loops Conditional branch in C: if (x == y) stmtlist 1 else stmtlist 2 stmtlist 3 switch statement in C: switch (V) { case 1: stmtlist 1 case 2: stmtlist 2... case n: stmtlist n default: stmtlist n } stmtlist n+1 while loop in C: while (x < k) stmtlist 1 stmtlist 2 do-while loop in C: do stmtlist 1 while (x < k); stmtlist 2 Topic 5: Internal Representations p.9/32 Topic 5: Internal Representations p.10/32 Examples 3 - Exceptions Dominance in Control Flow Graphs try-catch-finally in Java: try { S 0 ; S 1 ; } catch (etype 1 e1) { S 2 ; } catch (etype 2 e2) { S 3 ; } finally { S 4 ; } stmtlist 1 // may throw // may throw // simple statement // simple statement // simple statement Dominates B 1 dominates B 2 iff all paths from entry node to B 2 include B 1. Intuitively, B 1 is always executed before executing B 2 (or B 1 = B 2 ). Which assignments dominate (X+Y)?: X = 1; if (...) { Y = 4; }... = X + Y; Which assignments dominate (X+Y)?: X = 1; if (...) { Y = 4;... = X + Y; } Topic 5: Internal Representations p.11/32 Topic 5: Internal Representations p.12/32

Static Single Assignment (SSA) Form Static Single Assignment with Control Flow Informally, a program can be converted into SSA form as follows: Each assignment to a variable is given a unique name All of the uses reached by that assignment are renamed. Easy for straight-line code: V 4 2V 0 4 V + 5 2 V 0 + 5 V 6 2V 1 6 V + 7 2 V 1 + 7 What about flow of control? Introduce φ-functions! 2-way branch: if (...) X = 5; else X = 3; While loop: Y = X; j = 1; S: // while (j < x) if (j >= X) goto E; j = j+1; goto S E: N = j; if (...) X 0 = 5; else X 1 = 3; X 2 = φ(x 0, X 1 ); Y 0 = X 2 ; j 5 = 1; S: j 2 = φ(j 5, j 4 ); if (j 2 >= X) goto E; j 4 = j 2 +1; goto S E: N = j 2 ; Topic 5: Internal Representations p.13/32 Topic 5: Internal Representations p.14/32 Definition of SSA Form The SSA Graph Definition (φ Functions): In a basic block B with N predecessors, P 1, P 2,..., P N, X = φ(v 1, V 2,...,V N ) assigns X = V j if control enters block B from P j, 1 j N. Properties of φ-functions: φ is not an executable operation. φ has exactly as many arguments as the number of incoming BB edges Think about φ argument V i as being evaluated on CFG edge from predecessor P i to B Definition (SSA Graph): The SSA Graph is a directed graph in which: Nodes = All definitions and uses of SSA variables Edges = { (d, u) : u uses the SSA variable defined in d } Examples Draw the SSA graphs for the examples with control flow Definition (SSA form): A program is in SSA form if: 1. each variable is assigned a value in exactly one statement 2. each use of a variable is dominated by the definition Topic 5: Internal Representations p.15/32 Topic 5: Internal Representations p.16/32

So Where Do We Need Phi Functions? So Where Do We Need Phi Functions? Choices (for each variable X): At every merge point in the CFG? At every merge point after a write to X? At every merge point (after a write to X) that reaches a read of X? At some proper subset of the above merge points? Informal Conditions: If basic block B contains an assignment to a variable V, then a φ must be inserted in each basic block Z such that all of these are true: 1. there is a non-empty path B + Z; 2. there is a path from ENTRY to Z that does not go through B; 3. Z is the first node on the path B + Z that satisfies (2). These conditions must be reapplied for every Φ inserted in the code! Intuition for Placement Conditions: (1) = the value of V computed in B reaches Z (2) = there is a path that does not go through B, so some other value of V reaches Z along that pat (ignore bugs due to uses of uninitialized variables). So, two values must be merged at B with a φ. (3) = The φ for the value coming from B itself has not been placed in some earlier node on the path B + Z. Topic 5: Internal Representations p.17/32 Topic 5: Internal Representations p.18/32 So Where Do We Need Phi Functions? Tradeoffs of SSA form A constructive description PhiFunctionPlacement 1 Worklist <-- all assignments to scalars 2 while (Worklist is not empty) { 3 Remove one assignment, S, from Worklist; 4 B <-- the basic block containing S; 5 for (every basic block, Z, such that 6 B dominates some predecessor of Z, and 7 B is not a proper dominator of Z) { 8 Place a Phi assignment at the start of block Z; 9 Add this Phi assignment to WorkList; 10 } 11 } Does the inner (for) loop above compute exactly the set of nodes satisfying the Informal Conditions on the previous slide? Strengths: 1. Each use is reached by a single definition = Can sometimes use simpler analyses (flow-insensitive instead of flow-sensitive) 2. Def-use pairs are explicit : compact dataflow information 3. No write-after-read and write-after-write dependences 4. Can be directly transformed during optimizations (1-3) = Many dataflow optimizations are much faster Weaknesses: 1. Space requirement: many variables, many φ functions 2. Limited to scalar values; an array is treated as one big scalar 3. When target is low-level machine code, limited to virtual registers (memory is not in SSA form) 4. Copies introduced when converting back to real code Topic 5: Internal Representations p.19/32 Topic 5: Internal Representations p.20/32

Stack machine code Three address code Used in compilers for stack architectures: B5500, B1700, P-code, BCPL Popular again for bytecode languages: JVM, MSIL A term used to describe many different representations Each statement single operator + at most three operands Advantages compact form introduced names are implicit, not explicit simple to generate & execute code Disadvantages does not match current architectures many spurious dependences due to stack: difficult to do reordering transformations cannot reuse expressions easily (must store and re-load) difficult to express optimized code Example x 2 y 2 z Stack machine code: push x push 2 push y multiply push 2 push z multiply add subtract Advantages compact and very uniform makes intermediates values explicit suitable for many levels (high, mid, low): Disadvantages high-level: e.g., array refs, min / max ops mid-level : e.g., virtual regs, simple ops low-level : close to assembly code Large name space (due to temporaries) Loses syntatic structure of source Example if (x > y) z = x - 2 * y 3-address code: t 1 load x t 2 load y t 3 t 1 gt t 2 br t 3 L 2 L 1 L 1 : t 4 2 * t 2 t 5 t 1 - t 4 z store t 5 L 2 : Topic 5: Internal Representations p.21/32 Topic 5: Internal Representations p.22/32 Storage Formats for Three Address Code Quadruples x - 2 * y load t 1 y loadi t 2 2 mult t 3 t 2 t 1 load t 4 x sub t 5 t 3 t 4 table of k 4 small integers (indexes into symbol table) not very easy to reorder fast to traverse all names are explicit Size vs. Ease of Reordering vs. Locality Indirect Triples Order x - 2 * y Code op arg1 arg2 (103) (100) load y (100) (101) loadi 2 (101) (102) mult (100) (101) (102) (103) load x (104) (104) sub (103) (102) index is implicit name easier to reorder stmts more expensive to traverse Linked li explicit name easy to reord costly to trave Compilation Strategies High-level Model Retain high-level data types: Structs, Arrays, Pointers, Classes Retain high-level control constructs (AST) OR 3-address code Generally operate directly on program variables (i.e., no registers) Mid-level Model Retain some high-level data types: Structs, Arrays, Pointers Linear 3-address code + CFG Distinguish virtual regs from memory No low-level architectural details Low-level Model Linear memory model (no high-level data types) Distinguish virtual registers from memory Low-level 3-address code + CFG Explicit addressing arithmetic Expose all low-level architectural details: Addressing modes, stack frame, calling conventions, data layout Topic 5: Internal Representations p.23/32 Topic 5: Internal Representations p.24/32

Some Examples of Real Systems Examples of Real Systems (continued) Example 1: Sun Compilers for SPARC (C, C++, Fortran, Pascal) Code 2 different IRs Analysis info CFG + dependence graph +??? High-level IR: linked-list of triples Low-level IR : SPARC-assembly-like operations Example 2: IBM Compilers for Power, PowerPC (Same as Sun + PL.8) Muchnick, Chapter 21 Code Low-level IR (+ optional high-level IR with SSA) Analysis info CFG + intervals + value graph + dataflow graphs Example 3: LLVM Compiler (C, C++,...) Code CFG + Mostly 3-address IR in SSA form Analysis info Value Numbering + Points-to graph + Call graph Basic blocks: doubly linked list of LLVM instructions Example 4: dhpf Compiler (Fortran90 + HPF) dhpf.cs.rice.edu Code AST Analysis info CFG + SSA + Value DAG + Call Graph Low-level IR: indirect list of variable-length instructions Topic 5: Internal Representations p.25/32 Topic 5: Internal Representations p.26/32 O Brien et al., IR 95. Key Design Assumptions in XIL Low-level IR with no source-level semantic assumptions Must be capable of supporting multiple targets All loads, stores, and addressing computations must be exposed from front-end onwards. Main disadvantage : Slower compile time due to larger code volume Loops and source-level branches are lowered to compares, and conditional branches to labels Loop structure and induction vars. must be recovered via program analysis Some exotic or complex macro instructions, expanded by Macro Expansion phase: String operations; multi-dim array refs; unlimited args; unlimited size for immediate operands Formal identities: Identities found by hashing: hash(op, arg1,..., argn) All defs of a symbolic register must be formally identical = A symbolic register is name of a unique value Dataflow optimizations operate on symbolic registers (including loads and stores) Structural Design Assumptions in XIL Code representation: Doubly linked list of pointers to instructions Instructions live in a separate (unordered) table: Computation Table More complex than just triples: complex operands; multiple results Analysis representations: DAG representation of symbolic expressions Control-flow graph Symbol information: types, line numbers, literal value table IR allows flexible ordering of compiler passes Structure stays fixed throughout optimization and code generation Passes may be used in different orders, and repeated Computation Table (CT): Enforces formal identities Uses the hash function so each instruction is entered only once Symbolic registers are simply pointers to unique instructions in CT Exception: By client request. Called non-canonical instructions Topic 5: Internal Representations p.27/32 Topic 5: Internal Representations p.28/32

Key Design Assumptions in YIL Require higher-level abstractions (than XIL) to support: Dependence analysis for array subscripts Loop transformations: memory hierarchy opts, auto-par, auto-vec YIL abstractions can be constructed from XIL (instead of separate generato from front-end) This is unusual: Most compilers successively lower the IR Adding a layer of structural abstraction over XIL is better than designing a brand new IR: YIL links back to XIL to share expression DAGs in CT YIL exploits XIL functionality for manipulating expressions Structural Design of YIL Code representation: Statement graph : doubly linked list of statement nodes Nodes for Loop, If, Assign, Call Loops and loop nests are explicit Assign node represents a store and all computations feeding it Analysis representations: SSA form for variables (probably scalars only) Explicit use-def chains for all variables Dependence graph with dependence distances Links to expression DAGs and symbol information of XIL Loop optimizations focus on unimodular transformations. Described by a loop transformation matrix SSA form is updated incrementally by many optimizations (that don t change control flow) Topic 5: Internal Representations p.29/32 Topic 5: Internal Representations p.30/32 Critique of XIL Reasonable design for the very back end = Want dataflow optimization of machine-specific computations = Want rich symbolic expression manipulation But... XIL also serves as mid-level optimizer, i.e., many machine-independent opts Code volume is a significant cost Many such optimizations require both XIL and YIL features Unclear if XIL preserves important type information E.g., structures, arrays, pointers These are needed for pointer and dependence analysis (important for both dataflow opts and scheduling) Critique of hierarchical IL (XIL+YIL) Hierarchical two separate simultaneous ILs: YIL is not a full-fledged IL with complete analysis, optimization suite YIL relies on XIL for dataflow opts, low-level opts Lack of dataflow opts in YIL could be a weakness: Many high-level optimizations depend on good low-level opts E.g., Dep. analysis needs pointer analysis, which needs extensive low-level opts Also, many high-level opts. must be followed by good low-level opts Interprocedural optimization (IPO) important for both high-level and low-level opts Unclear how IPO can work with the XIL / YIL dichotomy Code volume of XIL could slow down IPO Topic 5: Internal Representations p.31/32 Topic 5: Internal Representations p.32/32