1 Intermediate Code generation. 2 Intermediate Code Generation l Intermediate languages l Declarations l Expressions l Statements l Reference: »Chapter.

Slides:



Advertisements
Similar presentations
Intermediate Code Generation. 2 Intermediate languages Runtime environments Declarations Expressions Statements.
Advertisements

Chapter 6 Intermediate Code Generation
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.
Compiler Designs and Constructions
Three Address Code Generation Backpatching-I Prepared By: Siddharth Tiwary 04CS3010.
Theory of Compilation Erez Petrank Lecture 6: Intermediate Representation 1.
1 CMPSC 160 Translation of Programming Languages Fall 2002 Lecture-Modules 17 and 18 slides derived from Tevfik Bultan, Keith Cooper, and Linda Torczon.
1 Pertemuan 12 Intermidiate Code Genarator Matakuliah: T0522 / Teknik Kompilasi Tahun: 2005 Versi: 1/6.
CH4.1 CSE244 Intermediate Code Generation Aggelos Kiayias Computer Science & Engineering Department The University of Connecticut 371 Fairfield Road, Unit.
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.
Static checking and symbol table Chapter 6, Chapter 7.6 and Chapter 8.2 Static checking: check whether the program follows both the syntactic and semantic.
CS412/413 Introduction to Compilers Radu Rugina Lecture 15: Translating High IR to Low IR 22 Feb 02.
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.
國立台灣大學 資訊工程學系 薛智文 98 Spring Intermediate Code Generation (textbook ch# 6.1–6.4, 6.5.1–6.5.3,
Intermediate Code Generation
Intermediate Code Generation
1 June 3, June 3, 2016June 3, 2016June 3, 2016 Azusa, CA Sheldon X. Liang Ph. D. Computer Science at Azusa Pacific University Azusa Pacific University,
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.
Review: Syntax directed translation. –Translation is done according to the parse tree. Each production (when used in the parsing) is a sub- structure of.
Chap. 4, Intermediate Code Generation
Theory of Compilation Erez Petrank Lecture 6: Intermediate Representation and Attribute Grammars 1.
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
Compilers Principles, Techniques, & Tools Taught by Jing Zhang
Compiler Construction
Compiler Construction
Subject Name:COMPILER DESIGN Subject Code:10CS63
Compiler Optimization and Code Generation
Intermediate Code Generation Part I
Intermediate Code Generation
Intermediate Code Generation Part II
Three Address Code Generation Control Statement
Chapter 6 Intermediate-Code Generation
Intermediate Code Generation Part II
Three Address Code Generation - Control Statements
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
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
Compiler Construction
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
Presentation transcript:

1 Intermediate Code generation

2 Intermediate Code Generation l Intermediate languages l Declarations l Expressions l Statements l Reference: »Chapter 8, Compilers Principles, techniques, and Tools.

3 Intermediate Languages l a := b * - c + b * - c l Syntax tree l Postfix notation »a b c - * b c - * + := l Three-address code

4 Types of Three-Address Code l Assignment statement x := y op z l Assignment statement x := op y l Copy statement x := y l Unconditional jump goto L l Conditional jump if x relop y goto L l Procedural call param x call p, n return y

5 Types of Three-Address Code l Indexed assignment: x := y[i] x[i] := y l Address and pointer assignment : x := &y x := *y *x := y

6 Implementation of Three-Address Code l Quadruples oparg1 arg2 result (0) - c t1 (1) * b t1 t2 (2) - c t3 (3) * b t3 t4 (4) + t2 t4 t5 (5) := t5 a

7 Syntax-Directed translation into Three-address Code l Temporary names generated for holding the value of internal node of a syntax tree. l E1 + E2 »E1 + E2 computed into a new temporary t l id := E »E’s result is assumed to be at E.place »id.place ‘:=‘ E.place generated l E is an id (say,y) »E.palce = y. »id.place = id.name

8 Notations and functions l Function newtemp() returns a new name for each call l Function newlabel() returns a new label for each call l For each Expression E and Statement S: »E.code (S.code) is the list of generated 3-address statements for E (and S, respectively). »E.place is a name (symbolic location) that will hold the value of E. –if E is id => id.place is the name for id. »S.begin : first statement for S ; »S.after : statement immediately following the code for S. l gen(String) : generate a three address code instruction. »gen(id.place ‘:=‘ ‘3’) => “x := 3”. l || : Code concatation.

9 Assignments (Syntax-directed Definition) S  id “:=” E {S.code := E.code|| gen(id.place ‘:=‘ E.place ) } E  E1 “+” E2 {E.place = newtemp(); E.code = E1.code || E2.code || gen(E.place ‘:=‘ E1.place ‘+’ E2.place) } E  E1 “*” E2 { E.place = newtemp(); E.code = E1.code || E2.code || gen(E.place ‘:=‘ E1.place ‘*’ E2.place) } E  “-” E1 { E.place := newtemp(); E.code = E1.code || gen(E.place ‘:=‘ ‘-’ E1.place) } E  “(” E1 “)” { E.place := E1.place; C.code = E1.code ;} E  id { E.place = id.place ; E.code = “”}

10 Assignments (Syntax-Directed Translation) S  id “:=” E { p := lookup(id.name); if(p != null) emit(p ‘:=’ E.place); else error(); } E  E1 “+” E2 { E.place := newtemp(); emit(E.place ‘:=’ E1.place ‘+’ E2.place)} E  E1 “*” E2 {E.place := newtemp(); emit(E.place ‘:=’ E1.place ‘*’ E2.place)} E  “-” E1 {E.place := newtemp(); emit(E.place ‘:=’ ‘-’ E1.place)} E  “(” E1 “)” {E.place := E1.place} E  id {p := lookup(id.name); if(p != null) E.place := p; else error(); }

11 Declarations l Compute the types and relative addresses of names P  {offset := 0} D D  D “;” D D  id “:” T { enter(id.name, T.type, offset); offset := offset + T.width} T  integer {T.type := integer; T.width := 4} T  float {T.type := float; T.width := 8} T  array “[” num “]” of T1 { T.type := array(num.val, T1.type); T.width := num.val x  T1.width} T  “*” T1 { T.type := pointer(T1.type); T.width := 4}

12 Symbol tables for Nested Procedures P  D D  D “;” D | id “:” T | proc id “;” D “;” S

13 Symbol Table Handling l Operations »mktable(previous): creates a new table and returns a pointer to the table »enter(table, name, type, offset): creates a new entry for name in the table »addwidth(table, width): records the cumulative width of entries in the header »enterproc(table, name, newtable): creates a new entry for procedure name in the table »enterblock(table, newTable) : add a child table. l Stacks »tblptr: [pointers to] the stack of symbol tables »offset :[pointer to ] the stack of the next available relative address

14 Declarations l Processing declarations in nested procedures P  M D { addwidth(top(tblptr), top(offset)); pop(tblptr); pop(offset)} M  {t := mktable(nil); push(t, tblptr); push(0, offset)} D  D “;” D D  proc id “;” N D “;” S { t := top(tblptr); addwidth(t, top(offset)); pop(tblptr); pop(offset); enterproc(top(tblptr), id.name, t)} D  id “:” T { enter(top(tblptr), id.name, T.type, top(offset)); top(offset) := top(offset) + T.width} N  { t := mktable(top(tblptr)); push(t, tblptr); push(0, offset)}

15 Declaratinos l Processing declarations in procedures and nested blocks Nested blocks share a common offset. It is not needed to push/pop offset for enter/exit of block. l M  T Id M1 ( PS ) { DS } { t := top(tblptr); addwidth(t, top(offset)); pop(tblptr); pop(offset); enterproc(top(tblptr), id.name, t)} M1  e { t := mktable(global); push(t, tblptr); push(0, offset) } l PS  P | e { } P  T Id | P, T Id { enter(top(tblptr), id.name, T.type, top(offset)); top(offset) := top(offset) + T.width } l DS  D | S

16 l D  T id; | D T id ; { enter(top(tblptr), id.name, T.type, top(offset)); top(offset) := top(offset) + T.width } l S  … | { M2 DS }. { t := top(tblptr); pop(tblptr); enterblock(top(tblptr), t) } l M2  e { t := mktable(top(tblptr)); push(t, tblptr); }

17 Records T  record D end T  record L D end { T.type := record(top(tblptr)); T.width := top(offset); pop(tblptr); pop(offset)} L  { t := mktable(nil); push(t, tblptr); push(0, offset)}

18 Assignments (Syntax-directed Definition) S  id “:=” E {S.code := E.code|| gen(id.place ‘:=‘ E.place ) } E  E1 “+” E2 {E.place = newtemp(); E.code = E1.code || E2.code || gen(E.place ‘:=‘ E1.place ‘+’ E2.place) } E  E1 “*” E2 { E.place = newtemp(); E.code = E1.code || E2.code || gen(E.place ‘:=‘ E1.place ‘*’ E2.place) } E  “-” E1 { E.place := newtemp(); E.code = E1.code || gen(E.place ‘:=‘ ‘-’ E1.place) } E  “(” E1 “)” { E.place := E1.place; C.code = E1.code ;} E  id { E.place = id.place ; E.code = “”}

19 Assignments (translation) S  id “:=” E { p := lookup(id.name); if p <> nil then emit(p ‘:=’ E.place) else error} E  E1 “+” E2 { E.place := newtemp(); emit(E.place ‘:=’ E1.place ‘+’ E2.place)} E  E1 “*” E2 {E.place := newtemp(); emit(E.place ‘:=’ E1.place ‘*’ E2.place)} E  “-” E1 {E.place := newtemp(); emit(E.place ‘:=’ ‘-’ E1.place)} E  “(” E1 “)” {E.place := E1.place} E  id {p := lookup(id.name); if p <> nil then E.place := p else error}

20 Array Accesses l A[i]: base A + (i - low) *  w   (i *  w) + (base A - low *  w) l A[i1, i2]: base + ((i1 - low1) *  n2 + i2 - low2) *  w  (((i1* n2) + i2) *  w) + (base - ((low1*n2) + low2) *  w) l c(id.place), width(id.place), limit(id.place, i) l recurrence rules: »e1 = i1, »e m = e m-1 x n m + i m = e m-1 x limit(id.place, m) + i m »id[i1,..im] = c + e m x w.

21 A[i,j] base A a = base A + (i-low1) x n2 x W a + (j – low2) x W

22 Array Accesses l Use inherited attributes L  id “[” Elist “]” | id Elist  Elist “,” E | E l Use synthesized attributes L  Elist “]” | id Elist  Elist “,” E | id “[” E

23 Array Accesses Elist  id “[” E {Elist.place := E.place; // e1 Elist.ndim := 1; Elist.array := id.place // id entry } Elist  Elist1 “,” E {t := newtemp(); m := Elist.ndim + 1; emit(t ‘:=’ Elist1.place ‘*’ limit(Elist1.array, m)); emit(t ‘:=’ t ‘+’ E.place); // em = e m-1 x n m + i m Elist.array := Elist1.array; Elist.place := t; Elist.ndim := m }

24 Array Accesses L  id {L.place := id.place; L.offset := null } L  Elist “]” {L.place := newtemp(); L.offset := newtemp(); emit(L.place ‘:=’ c(Elist.array)); emit(L.offset ‘:=’ Elist.place ‘*’ width(Elist.array)) // e k x w }

25 Array Accesses E  L {if (L.offset = null) // simple id E.place := L.place ; else { // array element E.place := newtemp(); emit(E.place ‘:=’ L.place ‘[’ L.offset ‘]’);} S  L “:=” E {if( L.offset = null) // simple id emit(L.place ‘:=’ E.place) ; else // array element emit(L.place ‘[’ L.offset ‘]’ ‘:=’ E.place) ; }

26 An Example l x := A[y, z] l n1 = 10, n2 = 20, w = 4 c = base A - ((1  20) + 1) *  4 = base A – 84 l t1 := y * 20 l t1 := t1 + z l t2 := c l t3 := t1 * 4 l t4 := t2[t3] l x := t4

27 Type Conversion E  E1 + E2 {E.place := newtemp; if (E1.type = integer and E2.type = integer){ emit(E.place ‘:=’ E1.place ‘iadd’ E2.place); E.type := integer } else if(E1.type = real and E2.type = real){ emit(E.place ‘:=’ E1.place ‘radd’ E2.place); E.type := real; } else if(E1.type = integer and E2.type = real){ u := newtemp; emit(u ‘:=’ ‘i2r’ E1.place); emit(E.place ‘:=’ u ‘radd’ E2.place); E.type := real } else if … }

28 Flow-of-Control Statements S  if E then S1 | if E then S1 else S2 | while E do S1 | switch(E) { case V1: S1 case V2: S2… case Vn: Sn default: S0 }

29 Conditional Statement S  if E then S1 { E.true := newlabel(); E.false := S.next; S1.next := S.next; S.code := E.code || gen(E.true ‘:’) || S1.code } l.code is a synthesis attribute l E.false/true and S1.next are inherited attribute

30 Conditional Statements S  if E then S1 else S2 {E.true := newlabel(); E.false := newlabel(); S1.next := S.next; S2.next := S.next; S.code := E.code || gen(E.true ‘:’) || S1.code || gen(‘goto’ S.next) || gen(E.false ‘:’) || S2.code }

31 While Statement S  while E do S1 {S.begin := newlabel(); E.true := newlabel(); E.false := S.next; S1.next := S.begin; S.code := gen(S.begin ‘:’) || E.code || gen(E.true ‘:’) || S1.code || gen(‘goto’ S.begin) } S.begin

32 Boolean Expressions l E  E1 or E2 | E1 and E2 | not E1 | (E1) | E 1 relop E2 | true | false l two kinds of translations: »Numerical Representations : (like arithExpr) – E is evaluated to a temp. »Short-circuit code : –E true  goto E.true ; E false  goto E.false

33 Numerical representation l E  E1 or E2 { E.place = newtemp(); emit(E.place ‘:=‘ E1.palce ‘or’ E2.place ) } | E1 and E2 {…} | not E1 {…} | (E1) {E.place = E1.place } | E 1 relop E2 { E.place.newtemp(); emit( ‘if’ E1.place ‘relop’ E2.place goto nextstat +3); emit(‘goto’ nextstat + 2); emit(E.place ‘:=‘ 1) } | true { E.place = newtemp(); emit(E.place ‘:=‘ 1) } | false { E.lace = newtemp(); emit(E.place ‘:=‘ 0) }

34 Boolean Expressions E  E1 or E2 { E1.true := E.true; E1.false := newlabel(); E2.true := E.true; E2.false := E.false; E.code := E1.code || gen(E1.false ‘:’) || E2.code } E  E1 and E2 { E1.true := newlabel(); E1.false := E.false; E2.true := E.true; E2.false := E.false; E.code := E1.code || gen(E1.true ‘:’) || E2.code} E  not E1 { E1.true := E.false; E1.false := E.true; E.code := E1.code }

35 Boolean Expressions E  “(” E1 “)” { E1.true := E.true; E1.false := E.false; E.code := E1.code} E  1 relop E2 { E.code := gen(‘if’ E1.place relop.op E2.place ‘goto’ E.true) || gen(‘goto’ E.false)} E  true {E.code := gen(‘goto’ E.true)} E  false {E.code := gen(‘goto’ E.false)}

36 Example l a < b or c < d and e < f l if a < b goto Ltrue l goto L1 l L1: if c < d goto L2 l goto Lfalse l L2: if e < f goto Ltrue l goto Lfalse

37 Example while (a < b) { if( c < d) x := y + z ; else x := y – z ; } L1: if a < b goto L2 goto Lnext L2: if c < d goto L3 goto L4 L3: t1 := y + z x := t1 goto L1 L4: t2 := y - z x := t2 goto L1 Lnext:

38 Backpatching l goto __ l if () goto ___ l Let i be an instruction with target address unfilled. l makeList(i) = [ i ]. l merge(p1, p2) = p1. p2 l backpatch(p, i) : »filled all unfilled targets in p by i.

39 l E  E1 or M E2 | E1 and M E2 | not E1 | (E1) | E 1 relop E2 | true | false M  { M.quard = nexquard } E.trueList : are list of instrucitons to branch to E.true. E.falseList : are list of instrucitons to branch to E.false. M.quard : number of next instruction.

40 l E  E1 or M E2 { backpatch(E1.falseList, M.quard); E.trueList = merge(E1.trueList, E2.trueList); E.falseList = E2.falseList } l E  E1 and M E2 {…} l E  not E1 {E.falseList = E1.trueList ; E.falseList = E1.trueList} l E  (E) {…} l E  false | true { E.trueList = makeList(nextquard) ; emit(goto ‘ __’) ;}

41 l E  E1 relop E2 { E.truelist = makeList( nextquard); E.falseList = makeList(nextquard + 1); emit( ‘if’ E1.place relop E2.place ‘goto ___’ ); emit( ‘goto ___ ‘) }

42 Example l a < b or M1(102) c < d and M2(104) e < f l 100 if a < b goto ___ l 101 goto ___ // 102 l 102 if c < d goto ___ l 103 goto ____ l 104 if e < f goto ____ l 105 goto _____

43 l S.nextList (L.nextList) is a list of all conditional /unconditional jumps to the quarduple following S (L) in executin order. l S  if E then M1 S1 N else M2 S2 { backpatch(E.trueList, M1.quard); backpatch(E.falseList, M2.quard); S.next = merge(S1.nextList, N.nextList, S2.nextList ); l N  { N.nextList = [ nextquard ] ; emit(goto ___ ); }

44 Backpatching Control Flows l M  {M.quard = nextquard } l S  if E then M S1 { l backpatch(E.truList, M.quard); l S.nextList = merge(E.falseList, S1.nextList); l } l S  while M1 E do M2 S1 { l backpatch(S1.nextList, M1.quard); l backpatch(E.truList, M2.quard); l S.nextList = E.falseList; l emit(‘goto’ M1.quard); l S  { L } { s.nextList = L.nextList ;} l L  L1 ; M S { backpatch(L1.nextList, M.quard); l L.nextList = S.nextList } l S  A {S.nextList :== [] } // A is assignment

45 Case Statements l Conditional goto’s »less than 10 cases l Jump table »more than 10 cases »dense value range l Hash table »more than 10 cases »sparse value range

46 Conditional Goto’s code to evaluate E into t goto test L1: code for S1 goto L2 … Ln: code for Sn goto L0 L0: code for S goto next test: if t = V1 goto L1 … if t = Vn goto Ln goto L0 next: switch(E) { case v1 : S1 case v2: S2 … case vn : Sn default: S }

47 Jump Table code to evaluate E into t if t < Vmin goto Ldefault if t > Vmax goto Ldefault i := t - Vmin L := jumpTable[i] goto L switch(E) { case v1 : S1 case v2: S2 … case vn : Sn default: S }

48 Hash Table code to evaluate E into t i := hash(t) L := hashTable[i] goto L switch(E) { case v1 : S1 case v2: S2 … case vn : Sn default: S }

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