Intermediate Code Generation Part II

Slides:



Advertisements
Similar presentations
Chapter 6 Intermediate Code Generation
Advertisements

Intermediate Code Generation
Intermediate Code Generation. 2 Intermediate languages Declarations Expressions Statements.
Backpatching: The syntax directed definition we discussed before can be implemented in two or more passes (we have both synthesized attributes and inheritent.
Lecture 08a – Backpatching & Recap Eran Yahav 1 Reference: Dragon 6.2,6.3,6.4,6.6.
Short circuit code for boolean expressions: Boolean expressions are typically used in the flow of control statements, such as if, while and for statements,
8 Intermediate code generation
Chapter 8 Intermediate Code Generation. Intermediate languages: Syntax trees, three-address code, quadruples. Types of Three – Address Statements: x :=
1 Compiler Construction Intermediate Code Generation.
Generation of Intermediate Code Compiler Design Lecture (03/30//98) Computer Science Rensselaer Polytechnic.
PSUCS322 HM 1 Languages and Compiler Design II IR Code Generation I Material provided by Prof. Jingke Li Stolen with pride and modified by Herb Mayer PSU.
Compiler Construction Sohail Aslam Lecture Boolean Expressions E → E 1 and M E 2 {backpatch(E 1.truelist, M.quad); E.truelist = E 2.truelist; E.falselist.
Compiler Designs and Constructions
Three Address Code Generation Backpatching-I Prepared By: Siddharth Tiwary 04CS3010.
Lecture 09 – IR (Backpatching) Eran Yahav 1 Reference: Dragon 6.2,6.3,6.4,6.6
Lecture 15 Control Flow Topics Review Positional Encoding of Booleans Short Circuit Evaluation Control Flow Statements Readings: 8.4, 8.6 March 13, 2006.
1 Intermediate Code generation. 2 Intermediate Code Generation l Intermediate languages l Declarations l Expressions l Statements l Reference: »Chapter.
Lecture 22 Code Generation Topics Arrays Code Generation Readings: 9 April 10, 2006 CSCE 531 Compiler Construction.
Test Yourself #2 Test Yourself #3 Initial code: a := x ** 2 b := 3 c := x d := c * c e := b * 2 f := a + d g := e * f.
What is Three Address Code? A statement of the form x = y op z is a three address statement. x, y and z here are the three operands and op is any logical.
CSc 453 Intermediate Code Generation Saumya Debray The University of Arizona Tucson.
1 Structure of a Compiler Front end of a compiler is efficient and can be automated Back end is generally hard to automate and finding the optimum solution.
1 Intermediate Code Generation Part I Chapter 8 COP5621 Compiler Construction Copyright Robert van Engelen, Florida State University, 2007.
Chapter 8: Intermediate Code Generation
Review: –What is an activation record? –What are the typical fields in an activation record? –What are the storage allocation strategies? Which program.
1 October 25, October 25, 2015October 25, 2015October 25, 2015 Azusa, CA Sheldon X. Liang Ph. D. Computer Science at Azusa Pacific University Azusa.
Intermediate Code Generation
Topic #7: Intermediate Code EE 456 – Compiling Techniques Prof. Carl Sable Fall 2003.
Intermediate Code Generation CS308 Compiler Theory1.
1 Intermediate Code Generation Abstraction at the source level identifiers, operators, expressions, statements, conditionals, iteration, functions (user.
Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.
Chap. 4, Intermediate Code Generation
1 February 28, February 28, 2016February 28, 2016February 28, 2016 Azusa, CA Sheldon X. Liang Ph. D. Computer Science at Azusa Pacific University.
Three Address Code Generation of Control Statements continued..
1 Chapter 6: Semantic Analysis. 2 Semantic Analyzer ==> Semantic Structure - What is the program supposed to do? - Semantics analysis can be done during.
CS 404Ahmed Ezzat 1 CS 404 Introduction to Compiler Design Lecture 10 Ahmed Ezzat.
Translation Scheme for Addressing Array Elements
CS 404 Introduction to Compiler Design
Compilers Principles, Techniques, & Tools Taught by Jing Zhang
Intermediate code generation Jakub Yaghob
Compiler Construction
Subject Name:COMPILER DESIGN Subject Code:10CS63
Compiler Optimization and Code Generation
Intermediate Code Generation Part I
Three Address Code Generations for Boolean Functions
Chapter 6 Intermediate-Code Generation
Intermediate Code Generation Part II
Intermediate Code Generation Part I
Intermediate Code Generation Part II
Intermediate code generation
Three-address code A more common representation is THREE-ADDRESS CODE . Three address code is close to assembly language, making machine code generation.
7.4 Boolean Expression and Control Flow Statements
Syntax-Directed Translation Part II
Compiler Design 21. Intermediate Code Generation
Intermediate Code Generation Part I
Three Address Code Generation – Backpatching
Intermediate Code Generation
THREE ADDRESS CODE GENERATION
Intermediate Code Generation Part II
Intermediate Code Generation
Syntax-Directed Translation Part II
Compiler Construction
Intermediate Code Generation
Intermediate Code Generation Part II
Review: For array a[2,5], how would the memory for this array looks like using row major layout? What about column major layout? How to compute the address.
Intermediate Code Generation Part I
Compiler Construction
Compiler Design 21. Intermediate Code Generation
Review: What is an activation record?
Code generation and data types
Presentation transcript:

Intermediate Code Generation Part II Chapter 6 (1st ed Chapter 8) COP5621 Compiler Construction Copyright Robert van Engelen, Florida State University, 2007-2013

Advanced Intermediate Code Generation Techniques Reusing temporary names Addressing array elements Translating logical and relational expressions Translating short-circuit Boolean expressions and flow-of-control statements with backpatching lists Translating procedure calls

Reusing Temporary Names generate E1 + E2 Evaluate E1 into t1 Evaluate E2 into t2 t3 := t1 + t2 If t1 no longer used, can reuse t1 instead of using new temp t3 Modify newtemp() to use a “stack”: Keep a counter c, initialized to 0 Decrement counter on each use of a $i in a three-address statement newtemp() returns temporary $c++ (that is, c is post incremented)

Reusing Temporary Names (cont’d) x := a * b + c * d - e * f Statement c → cdecr → cincr 0 0 → 0 → 1 1 → 1 → 2 2 → 0 → 1 1 → 1 → 2 2 → 0 → 1 1 → 0 → 0 $0 := a * b $1 := c * d $0 := $0 + $1 $1 := e * f $0 := $0 - $1 x := $0

Addressing Array Elements: One-Dimensional Arrays A : array [10..20] of integer; … := A[i] = baseA + (i - low) * w = i * w + c where c = baseA - low * w with low = 10; w = 4 (= type width) t1 := c // c = baseA - 10 * 4 t2 := i * 4 t3 := t1[t2] … := t3

Addressing Array Elements: Multi-Dimensional Arrays A : array [1..2,1..3] of integer; low1 = 1, low2 = 1, n1 = 2, n2 = 3, w = 4 baseA baseA A[1,1] A[1,1] A[1,2] A[2,1] A[1,3] A[1,2] A[2,1] A[2,2] A[2,2] A[1,3] A[2,3] A[2,3] Row-major Column-major

Addressing Array Elements: Multi-Dimensional Arrays A : array [1..2,1..3] of integer; (Row-major) … := A[i,j] = baseA + ((i1 - low1) * n2 + i2 - low2) * w = ((i1 * n2) + i2) * w + c where c = baseA - ((low1 * n2) + low2) * w with low1 = 1; low2 = 1; n2 = 3; w = 4 t1 := i * 3 t1 := t1 + j t2 := c // c = baseA - (1 * 3 + 1) * 4 t3 := t1 * 4 t4 := t2[t3] // t4 := mem[((i * 3) + j) * 4 + c] … := t4

Addressing Array Elements: Grammar S  L := E E  E + E | ( E ) | L L  Elist ] | id Elist  Elist , E | id [ E Synthesized attributes: E.place name of temp holding value of E Elist.array array name Elist.place name of temp holding index value Elist.ndim number of array dimensions L.place lvalue (=name of temp) L.offset index into array (=name of temp) null indicates non-array simple id

Addressing Array Elements S  L := E { if L.offset = null then emit(L.place ‘:=’ E.place) else emit(L.place[L.offset] ‘:=’ E.place) } E  E1 + E2 { E.place := newtemp(); emit(E.place ‘:=’ E1.place ‘+’ E2.place) } E  ( E1 ) { E.place := E1.place } E  L { if L.offset = null then E.place := L.place else E.place := newtemp(); emit(E.place ‘:=’ L.place[L.offset] }

Addressing Array Elements L  Elist ] { L.place := newtemp(); L.offset := newtemp(); emit(L.place ‘:=’ c(Elist.array)); emit(L.offset ‘:=’ Elist.place ‘*’ width(Elist.array)) } L  id { L.place := id.place; L.offset := null } Elist  Elist1 , E { t := newtemp(); m := Elist1.ndim + 1; emit(t ‘:=’ Elist1.place ‘*’ limit(Elist1.array, m)); emit(t ‘:=’ t ‘+’ E.place); Elist.array := Elist1.array; Elist.place := t; Elist.ndim := m } Elist  id [ E { Elist.array := id.place; Elist.place := E.place; Elist.ndim := 1 }

Translating Logical and Relational Expressions t1 := not c t2 := b and t1 t3 := a or t2 a or b and not c if a < b goto L1 t1 := 0 goto L2 L1: t1 := 1 L2: a < b

Translating Short-Circuit Expressions Using Backpatching E  E or M E | E and M E | not E | ( E ) | id relop id | true | false M   Synthesized attributes: E.truelist backpatch list for jumps on true E.falselist backpatch list for jumps on false M.quad location of current three-address quad

Backpatch Operations with Lists makelist(i) creates a new list containing three-address location i, returns a pointer to the list merge(p1, p2) concatenates lists pointed to by p1 and p2, returns a pointer to the concatenates list backpatch(p, i) inserts i as the target label for each of the statements in the list pointed to by p

Backpatching with Lists: Example 100: if a < b goto _ 101: goto _ 102: if c < d goto _ 103: goto _ 104: if e < f goto _ 105: goto _ a < b or c < d and e < f backpatch 100: if a < b goto TRUE 101: goto 102 102: if c < d goto 104 103: goto FALSE 104: if e < f goto TRUE 105: goto FALSE

Backpatching with Lists: Translation Scheme M   { M.quad := nextquad() } E  E1 or M E2 { backpatch(E1.falselist, M.quad); E.truelist := merge(E1.truelist, E2.truelist); E.falselist := E2.falselist } E  E1 and M E2 { backpatch(E1.truelist, M.quad); E.truelist := E2.truelist; E.falselist := merge(E1.falselist, E2.falselist); } E  not E1 { E.truelist := E1.falselist; E.falselist := E1.truelist } E  ( E1 ) { E.truelist := E1.truelist; E.falselist := E1.falselist }

Backpatching with Lists: Translation Scheme (cont’d) E  id1 relop id2 { E.truelist := makelist(nextquad()); E.falselist := makelist(nextquad() + 1); emit(‘if’ id1.place relop.op id2.place ‘goto _’); emit(‘goto _’) } E  true { E.truelist := makelist(nextquad()); E.falselist := nil; emit(‘goto _’) } E  false { E.falselist := makelist(nextquad()); E.truelist := nil; emit(‘goto _’) }

Flow-of-Control Statements and Backpatching: Grammar S  if E then S | if E then S else S | while E do S | begin L end | A L  L ; S | S Synthesized attributes: S.nextlist backpatch list for jumps to the next statement after S (or nil) L.nextlist backpatch list for jumps to the next statement after L (or nil) Jumps out of S1 S1 ; S2 ; S3 ; S4 ; S5 … 100: Code for S1 200: Code for S2 300: Code for S3 400: Code for S4 500: Code for S5 backpatch(S1.nextlist, 200) backpatch(S2.nextlist, 300) backpatch(S3.nextlist, 400) backpatch(S4.nextlist, 500)

Flow-of-Control Statements and Backpatching S  A { S.nextlist := nil } S  begin L end { S.nextlist := L.nextlist } S  if E then M S1 { backpatch(E.truelist, M.quad); S.nextlist := merge(E.falselist, S1.nextlist) } L  L1 ; M S { backpatch(L1.nextlist, M.quad); L.nextlist := S.nextlist; } L  S { L.nextlist := S.nextlist; } M   { M.quad := nextquad() } A  … Non-compound statements, e.g. assignment, function call

Flow-of-Control Statements and Backpatching (cont’d) S  if E then M1 S1 N else M2 S2 { backpatch(E.truelist, M1.quad); backpatch(E.falselist, M2.quad); S.nextlist := merge(S1.nextlist, merge(N.nextlist, S2.nextlist)) } S  while M1 E do M2 S1 { backpatch(S1,nextlist, M1.quad); backpatch(E.truelist, M2.quad); S.nextlist := E.falselist; emit(‘goto M1.quad’) } N   { N.nextlist := makelist(nextquad()); emit(‘goto _’) }

Translating Procedure Calls S  call id ( Elist ) Elist  Elist , E | E call foo(a+1, b, 7) t1 := a + 1 t2 := 7 param t1 param b param t2 call foo 3

Translating Procedure Calls S  call id ( Elist ) { for each item p on queue do emit(‘param’ p); emit(‘call’ id.place |queue|) } Elist  Elist , E { append E.place to the end of queue } Elist  E { initialize queue to contain only E.place }