Compiler Principles Fall 2014-2015 Compiler Principles Lecture 8: Intermediate Representation Roman Manevich Ben-Gurion University.

Slides:



Advertisements
Similar presentations
Intermediate Code Generation
Advertisements

Compiler Principles Fall Compiler Principles Lecture 4: Parsing part 3 Roman Manevich Ben-Gurion University.
1 Code generation Our book's target machine (appendix A): opcode source1, source2, destination add r1, r2, r3 addI r1, c, r2 loadI c, r2 load r1, r2 loadAI.
1 CS 201 Compiler Construction Machine Code Generation.
Intermediate Representation III. 2 PAs PA2 deadline is
8. Code Generation. Generate executable code for a target machine that is a faithful representation of the semantics of the source code Depends not only.
Code Generation Steve Johnson. May 23, 2005Copyright (c) Stephen C. Johnson The Problem Given an expression tree and a machine architecture, generate.
Components of representation Control dependencies: sequencing of operations –evaluation of if & then –side-effects of statements occur in right order Data.
Program Representations. Representing programs Goals.
Compiler Construction Intermediate Representation III Activation Records Ran Shaham and Ohad Shacham School of Computer Science Tel-Aviv University.
Compiler Principles Fall Compiler Principles Lecture 7: Intermediate Representation Roman Manevich Ben-Gurion University.
CS412/413 Introduction to Compilers Radu Rugina Lecture 16: Efficient Translation to Low IR 25 Feb 02.
Common Sub-expression Elim Want to compute when an expression is available in a var Domain:
Representing programs Goals. Representing programs Primary goals –analysis is easy and effective just a few cases to handle directly link related things.
1 Semantic Processing. 2 Contents Introduction Introduction A Simple Compiler A Simple Compiler Scanning – Theory and Practice Scanning – Theory and Practice.
1 Intermediate representation Goals: –encode knowledge about the program –facilitate analysis –facilitate retargeting –facilitate optimization scanning.
Code Generation Simple Register Allocation Mooly Sagiv html:// Chapter
Arithmetic Expression Consider the expression arithmetic expression: (a – b) + ((c + d) + (e * f)) that can be represented as the following tree.
Instruction Selection, II Tree-pattern matching Copyright 2003, Keith D. Cooper, Ken Kennedy & Linda Torczon, all rights reserved. Students enrolled in.
Code Generation Mooly Sagiv html:// Chapter 4.
Compiler Construction Recap Rina Zviel-Girshin and Ohad Shacham School of Computer Science Tel-Aviv University.
Topic 6 -Code Generation Dr. William A. Maniatty Assistant Prof. Dept. of Computer Science University At Albany CSI 511 Programming Languages and Systems.
Compiler Construction A Compulsory Module for Students in Computer Science Department Faculty of IT / Al – Al Bayt University Second Semester 2008/2009.
Code Generation Mooly Sagiv html:// Chapter 4.
2.2 A Simple Syntax-Directed Translator Syntax-Directed Translation 2.4 Parsing 2.5 A Translator for Simple Expressions 2.6 Lexical Analysis.
CS412/413 Introduction to Compilers Radu Rugina Lecture 15: Translating High IR to Low IR 22 Feb 02.
Compilation /15a Lecture 7 Getting into the back-end Noam Rinetzky 1.
10/1/2015© Hal Perkins & UW CSEG-1 CSE P 501 – Compilers Intermediate Representations Hal Perkins Autumn 2009.
Compiler course 1. Introduction. Outline Scope of the course Disciplines involved in it Abstract view for a compiler Front-end and back-end tasks Modules.
Data Structures : Project 5 Data Structures Project 5 – Expression Trees and Code Generation.
COP4020 Programming Languages Semantics Prof. Xin Yuan.
Compiler Chapter# 5 Intermediate code generation.
Chapter 7 Syntax-Directed Compilation (AST & Target Code) 1.
Unit-1 Introduction Prepared by: Prof. Harish I Rathod
Compiler Principles Fall Compiler Principles Lecture 0: Local Optimizations Roman Manevich Ben-Gurion University.
Introduction to Code Generation and Intermediate Representations
1 Compiler Design (40-414)  Main Text Book: Compilers: Principles, Techniques & Tools, 2 nd ed., Aho, Lam, Sethi, and Ullman, 2007  Evaluation:  Midterm.
Compiler Principles Fall Compiler Principles Lecture 6: Parsing part 5 Roman Manevich Ben-Gurion University.
Query Processing – Query Trees. Evaluation of SQL Conceptual order of evaluation – Cartesian product of all tables in from clause – Rows not satisfying.
Compilation /15a Lecture 6 Getting into the back-end Noam Rinetzky 1.
Compiler Principles Fall Compiler Principles Lecture 12: Register Allocation Roman Manevich Ben-Gurion University.
Compiler Principles Fall Compiler Principles Lecture 7: Lowering Correctness Roman Manevich Ben-Gurion University of the Negev.
C H A P T E R T W O Linking Syntax And Semantics Programming Languages – Principles and Paradigms by Allen Tucker, Robert Noonan.
Compiler Principles Fall Compiler Principles Exercise Set: Lowering and Formal Semantics Roman Manevich Ben-Gurion University of the Negev.
Compiler Principles Fall Compiler Principles Lecture 6: Intermediate Representation Roman Manevich Ben-Gurion University of the Negev.
Compiler Construction Recap. 2 Announcements PA4: extension until end of exam period – Not a single day more, for any reason! PA5: bonus exercise – Will.
1 March 16, March 16, 2016March 16, 2016March 16, 2016 Azusa, CA Sheldon X. Liang Ph. D. Azusa Pacific University, Azusa, CA 91702, Tel: (800)
CS 404Ahmed Ezzat 1 CS 404 Introduction to Compiler Design Lecture 10 Ahmed Ezzat.
CS416 Compiler Design1. 2 Course Information Instructor : Dr. Ilyas Cicekli –Office: EA504, –Phone: , – Course Web.
1 Compiler Construction (CS-636) Muhammad Bilal Bashir UIIT, Rawalpindi.
Review 1.Structure of the course Lexical Analysis Syntax Analysis Grammar & Language RG & DFA Top-down LL(1) Parsing Bottom-Up LR Layered Automation Semantic.
©SoftMoore ConsultingSlide 1 Code Optimization. ©SoftMoore ConsultingSlide 2 Code Optimization Code generation techniques and transformations that result.
Compiler Principles Fall Compiler Principles Lecture 8: Dataflow & Optimizations 1 Roman Manevich Ben-Gurion University of the Negev.
Lecture 12 Intermediate Code Generation Translating Expressions
Compilation (Semester A, 2013/14)
Compiler Design (40-414) Main Text Book:
System Software Unit-1 (Language Processors) A TOY Compiler
Optimization Code Optimization ©SoftMoore Consulting.
Fall Compiler Principles Lecture 5: Intermediate Representation
Fall Compiler Principles Lecture 8: Loop Optimizations
CS 201 Compiler Construction
Fall Compiler Principles Lecture 10: Loop Optimizations
Local Optimizations.
Getting into the back-end Noam Rinetzky
Fall Compiler Principles Lecture 5: Intermediate Representation
Optimization 薛智文 (textbook ch# 9) 薛智文 96 Spring.
Intermediate Code Generation
Compiler Construction
Lec00-outline May 18, 2019 Compiler Design CS416 Compiler Design.
Fall Compiler Principles Lecture 13: Summary
Presentation transcript:

Compiler Principles Fall Compiler Principles Lecture 8: Intermediate Representation Roman Manevich Ben-Gurion University

Tentative syllabus Front End Scanning Top-down Parsing (LL) Bottom-up Parsing (LR) Intermediate Representation Lowering Optimizations Local Optimizations Dataflow Analysis Loop Optimizations Code Generation Register Allocation Instruction Selection 2 mid-termexam

Previously Why compilers need Intermediate Representations (IR) Translating from abstract syntax (AST) to IR – Three-Address Code Local optimizations – Sethi-Ullman algorithm for efficient code generation 3

cgen for basic expressions 4 cgen(k) = { // k is a constant Choose a new temporary t Emit( t := k ) Return t { cgen(id) = { // id is an identifier Choose a new temporary t Emit( t := id ) Return t {

Naive cgen for binary expressions Maintain a counter for temporaries in c Initially: c = 0 cgen(e 1 op e 2 ) = { Let A = cgen(e 1 ) c = c + 1 Let B = cgen(e 2 ) c = c + 1 Emit( _tc := A op B; ) Return _tc } 5 The translation emits code to evaluate e 1 before e 2. Why is that?

Example: cgen for binary expressions 6 cgen( (a*b)-d)

Example: cgen for binary expressions 7 c = 0 cgen( (a*b)-d)

Example: cgen for binary expressions 8 c = 0 cgen( (a*b)-d) = { Let A = cgen(a*b) c = c + 1 Let B = cgen(d) c = c + 1 Emit( _tc := A - B; ) Return _tc }

Example: cgen for binary expressions 9 c = 0 cgen( (a*b)-d) = { Let A = { Let A = cgen(a) c = c + 1 Let B = cgen(b) c = c + 1 Emit( _tc := A * B; ) Return tc } c = c + 1 Let B = cgen(d) c = c + 1 Emit( _tc := A - B; ) Return _tc }

Example: cgen for binary expressions 10 c = 0 cgen( (a*b)-d) = { Let A = { Let A = { Emit(_tc := a;), return _tc } c = c + 1 Let B = { Emit(_tc := b;), return _tc } c = c + 1 Emit( _tc := A * B; ) Return _tc } c = c + 1 Let B = { Emit(_tc := d;), return _tc } c = c + 1 Emit( _tc := A - B; ) Return _tc } Code here A=_t0

Example: cgen for binary expressions 11 c = 0 cgen( (a*b)-d) = { Let A = { Let A = { Emit(_tc := a;), return _tc } c = c + 1 Let B = { Emit(_tc := b;), return _tc } c = c + 1 Emit( _tc := A * B; ) Return _tc } c = c + 1 Let B = { Emit(_tc := d;), return _tc } c = c + 1 Emit( _tc := A - B; ) Return _tc } Code _t0:=a; here A=_t0

Example: cgen for binary expressions 12 c = 0 cgen( (a*b)-d) = { Let A = { Let A = { Emit(_tc := a;), return _tc } c = c + 1 Let B = { Emit(_tc := b;), return _tc } c = c + 1 Emit( _tc := A * B; ) Return _tc } c = c + 1 Let B = { Emit(_tc := d;), return _tc } c = c + 1 Emit( _tc := A - B; ) Return _tc } Code _t0:=a; _t1:=b; here A=_t0

Example: cgen for binary expressions 13 c = 0 cgen( (a*b)-d) = { Let A = { Let A = { Emit(_tc := a;), return _tc } c = c + 1 Let B = { Emit(_tc := b;), return _tc } c = c + 1 Emit( _tc := A * B; ) Return _tc } c = c + 1 Let B = { Emit(_tc := d;), return _tc } c = c + 1 Emit( _tc := A - B; ) Return _tc } Code _t0:=a; _t1:=b; _t2:=_t0*_t1 here A=_t0

Example: cgen for binary expressions 14 c = 0 cgen( (a*b)-d) = { Let A = { Let A = { Emit(_tc := a;), return _tc } c = c + 1 Let B = { Emit(_tc := b;), return _tc } c = c + 1 Emit( _tc := A * B; ) Return _tc } c = c + 1 Let B = { Emit(_tc := d;), return _tc } c = c + 1 Emit( _tc := A - B; ) Return _tc } Code _t0:=a; _t1:=b; _t2:=_t0*_t1 here A=_t0 here A=_t2

Example: cgen for binary expressions 15 c = 0 cgen( (a*b)-d) = { Let A = { Let A = { Emit(_tc := a;), return _tc } c = c + 1 Let B = { Emit(_tc := b;), return _tc } c = c + 1 Emit( _tc := A * B; ) Return _tc } c = c + 1 Let B = { Emit(_tc := d;), return _tc } c = c + 1 Emit( _tc := A - B; ) Return _tc } Code _t0:=a; _t1:=b; _t2:=_t0*_t1 _t3:=d; here A=_t0 here A=_t2

Example: cgen for binary expressions 16 c = 0 cgen( (a*b)-d) = { Let A = { Let A = { Emit(_tc := a;), return _tc } c = c + 1 Let B = { Emit(_tc := b;), return _tc } c = c + 1 Emit( _tc := A * B; ) Return _tc } c = c + 1 Let B = { Emit(_tc := d;), return _tc } c = c + 1 Emit( _tc := A - B; ) Return _tc } Code _t0:=a; _t1:=b; _t2:=_t0*_t1 _t3:=d; _t4:=_t2-_t3 here A=_t0 here A=_t2

Naïve translation cgen translation shown so far very inefficient – Generates (too) many temporaries – one per sub- expression – Generates many instructions – at least one per sub-expression Expensive in terms of running time and space Code bloat We can do much better 17

agenda Lowering optimizations – Sethi-Ullman algorithm for efficient code generation 18

19 Lowering optimization

Improving cgen for expressions 1.Improve translation for leaves 2.Reuse temporaries 3.Weighted register allocation for expression trees – Reorder computations 20

21 Optimization 1: leaves

Improving cgen for leaves cases Observation – naïve translation needlessly generates temporaries for leaf expressions Solution: treat leaves as special cases by returning them immediately without storing them in temporaries 22

23 Optimization 2: reusing temporaries

cgen with temporaries recycling Observation – temporaries used exactly once – Once a temporary has been read it can be reused for another sub-expression Want to implement cgen(x := e 1 op e 2 ) with small number of temporaries cgen(x := e 1 op e 2 ) = { c = 0 Emit(x := cgen(e 1 op e 2 )) } 24 How can we make this more efficient?

Improved cgen c = 0 cgen(e 1 op e 2 ) = { cgen(e 1 ) c = c + 1 cgen(e 2 ) c = c - 1 Emit( _tc := _tc op _tc+1; ) } 25

Example 26 c = 0 cgen( (a*b)-d) = { { { Emit(_tc := a;), return _tc } c = c + 1 { Emit(_tc := b;), return _tc } c = c - 1 Emit( _tc := _tc * _tc+1; ) } c = c + 1 { Emit(_tc := d;), return _tc } c = c - 1 Emit( _tc := _tc - _tc+1; ) } Code c=0

Example 27 c = 0 cgen( (a*b)-d) = { Let _tc = { Let _tc = { Emit(_tc := a;), return _tc } c = c + 1 Let _tc = { Emit(_tc := b;), return _tc } c = c - 1 Emit( _tc := _tc * _tc+1; ) Return _tc } c = c + 1 Let _tc = { Emit(_tc := d;), return _tc } c = c - 1 Emit( _tc := _tc - _tc+1; ) Return _tc } Code _t0:=a; c=1

Example 28 c = 0 cgen( (a*b)-d) = { Let _tc = { Let _tc = { Emit(_tc := a;), return _tc } c = c + 1 Let _tc = { Emit(_tc := b;), return _tc } c = c - 1 Emit( _tc := _tc * _tc+1; ) Return _tc } c = c + 1 Let _tc = { Emit(_tc := d;), return _tc } c = c - 1 Emit( _tc := _tc - _tc+1; ) Return _tc } Code _t0:=a; _t1:=b; c=1

Example 29 c = 0 cgen( (a*b)-d) = { Let _tc = { Let _tc = { Emit(_tc := a;), return _tc } c = c + 1 Let _tc = { Emit(_tc := b;), return _tc } c = c - 1 Emit( _tc := _tc * _tc+1; ) Return _tc } c = c + 1 Let _tc = { Emit(_tc := d;), return _tc } c = c - 1 Emit( _tc := _tc - _tc+1; ) Return _tc } Code _t0:=a; _t1:=b; c=0

Example 30 c = 0 cgen( (a*b)-d) = { Let _tc = { Let _tc = { Emit(_tc := a;), return _tc } c = c + 1 Let _tc = { Emit(_tc := b;), return _tc } c = c - 1 Emit( _tc := _tc * _tc+1; ) Return _tc } c = c + 1 Let _tc = { Emit(_tc := d;), return _tc } c = c - 1 Emit( _tc := _tc - _tc+1; ) Return _tc } Code _t0:=a; _t1:=b; _t0:=_t0*_t1 c=0

Example 31 c = 0 cgen( (a*b)-d) = { Let _tc = { Let _tc = { Emit(_tc := a;), return _tc } c = c + 1 Let _tc = { Emit(_tc := b;), return _tc } c = c - 1 Emit( _tc := _tc * _tc+1; ) Return _tc } c = c + 1 Let _tc = { Emit(_tc := d;), return _tc } c = c - 1 Emit( _tc := _tc - _tc+1; ) Return _tc } Code _t0:=a; _t1:=b; _t0:=_t0*_t1; c=1

Example 32 c = 0 cgen( (a*b)-d) = { Let _tc = { Let _tc = { Emit(_tc := a;), return _tc } c = c + 1 Let _tc = { Emit(_tc := b;), return _tc } c = c - 1 Emit( _tc := _tc * _tc+1; ) Return _tc } c = c + 1 Let _tc = { Emit(_tc := d;), return _tc } c = c - 1 Emit( _tc := _tc - _tc+1; ) Return _tc } Code _t0:=a; _t1:=b; _t0:=_t0*_t1; _t1:=d; c=1

Example 33 c = 0 cgen( (a*b)-d) = { Let _tc = { Let _tc = { Emit(_tc := a;), return _tc } c = c + 1 Let _tc = { Emit(_tc := b;), return _tc } c = c - 1 Emit( _tc := _tc * _tc+1; ) Return _tc } c = c + 1 Let _tc = { Emit(_tc := d;), return _tc } c = c - 1 Emit( _tc := _tc - _tc+1; ) Return _tc } Code _t0:=a; _t1:=b; _t0:=_t0*_t1; _t1:=d; c=0

Example 34 c = 0 cgen( (a*b)-d) = { Let _tc = { Let _tc = { Emit(_tc := a;), return _tc } c = c + 1 Let _tc = { Emit(_tc := b;), return _tc } c = c - 1 Emit( _tc := _tc * _tc+1; ) Return _tc } c = c + 1 Let _tc = { Emit(_tc := d;), return _tc } c = c - 1 Emit( _tc := _tc - _tc+1; ) Return _tc } Code _t0:=a; _t1:=b; _t0:=_t0*_t1; _t1:=d; _t0:=_t0-_t1; c=0

Example 2 _t0 := cgen( ((c*d)-(e*f))+(a*b) ) _t0 := c*d _t1 := e*f _t0 := _t0 -_t1 c = c + 1 c = c - 1 c = 0 _t0 := cgen(c*d)-(e*f)) _t1 := a*b c = c + 1 _t0 := _t0 + _t1 c = c

36 Optimization 3: weighted register allocation

Sethi-Ullman translation Algorithm by Ravi Sethi and Jeffrey D. Ullman to emit optimal TAC – Minimizes number of temporaries – (Minimizes number of instructions by reducing spills) – A kind of local register allocation (within single expressions) Uses two ideas 1.Reusing temporaries 2.Choosing order of translation 37

Weighted register allocation Suppose we have expression e 1 op e 2 – e 1, e 2 without side-effects That is, no function calls, memory accesses, ++x – Does order of translation matter? … Yes Sethi & Ullman’s algorithm translates heavier sub-tree first – Optimal local (per-statement) allocation for side- effect-free statements 38

Example 1 (assuming leaves require temporaries) _t0 := cgen( a+(b+(c*d)) ) b cd * + + a _t0 _t1 _t2 4 temporaries _t2 _t1 left child first b cd * + + a _t0 2 temporaries _t0 right child first _t0 39 _t1 _t3

Sethi-Ullman: weighted register allocation Can save registers by re-ordering subtree computations Phase 1: check that no side-effects exist and otherwise revert to translation following pre-defined order of computation Phase 2: assign weight to each node – Weight = number of registers needed – Leaf weight known – Internal node weight w(left) > w(right) then w = left w(right) > w(left) then w = right w(right) = w(left) then w = left + 1 Phase 3: translate by following heavier child first 40

Sethi-Ullman algorithm example cgen( g := (a+b)+((c+d)+(e+f))) ef ab + w=1 w=2w=1 w=2w=3 Code _t0 := c; _t1 := d; _t0 := _t0 * _t1; _t1 := e; _t2 := f; _t1 := _t1 * _t2; _t0 := _t0 - _t1 _t1 := a; _t2 := b; _t1 := _t1 -_t2 _t0 := _t1 - _t0 g := _t0 cd + w=1 w=2

Example with side effects b 5c * array access + a baseindex w=1 w=2w=1w=2 Phase 1: check absence of side-effects in expression tree Phase 2: assign weight to each AST node 42 _t0 := cgen( a+b[5*c] )

Example with side effects b 5c * array access + a _t0 baseindex W=2 Phase 2: use weights to decide on order of translation Heavier sub-tree _t0 := _t1 * _t0 _t0 := _t1[_t0] _t0 := _t1 + _t0 43 _t0 := cgen( a+b[5*c] ) w=1 w=2w=1w=2 _t0_t1 _t0 := c _t1 := 5 _t1 := b _t1 := a

Note on weighted register allocation The algorithm is local – works for a single expression Must reset temporaries counter after every statement: – x := y; y := z; should not be translated to _t0 := y; x := _t0; _t1 := z; y := _t1; – But rather to _t0 := y; x := _t0; # Finished translating statement. Set c=0 _t0 := z; y := _t0; 44

Going beyond the basic SU algorithm There exist advanced extensions of SU – Take into account semantics of operators – Take into account latency 45

Can we do better than basic SU here? cgen( g := (a+b)+((c+d)+(e+f))) ef ab + w=1 w=2w=1 w=2w=3 Code _t0 := c; _t1 := d; _t0 := _t0 + _t1; _t1 := e; _t2 := f; _t1 := _t1 + _t2; _t0 := _t0 + _t1 _t1 := a; _t2 := b; _t1 := _t1 +_t2 _t0 := _t1 + _t0 g := _t0 cd + w=1 w=2 What if we are allowed to rewrite expressions?

Can we do better than basic SU here? cgen( g := (a+b)+((c+d)+(e+f))) = cgen( g := a + (b + (c + (d + (e + f))))) a Code _t0 := e; _t1 := f; _t0 := _t0 + _t1; _t1 := d; _t0 := _t0 + _t1; _t1 := c; _t0 := _t0 + _t1; _t1 := b; _t0 := _t0 + _t1; _t1 := a; _t0 := _t0 + _t1; g := _t0 +b +c +d fe w=1 w=2w=1w=2w=1w=2w=1w=2w=1w=2 Can rewrite since + is associative and commutative

Next lecture: Local Optimizations