Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "1 Intermediate Code generation. 2 Intermediate Code Generation l Intermediate languages l Declarations l Expressions l Statements l Reference: »Chapter."— Presentation transcript:

1 1 Intermediate Code generation

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

3 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 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 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 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 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 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 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 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 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 12 Symbol tables for Nested Procedures P  D D  D “;” D | id “:” T | proc id “;” D “;” S

13 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 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 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 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 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 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 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 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 21 A[i,j] base A a = base A + (i-low1) x n2 x W a + (j – low2) x W

22 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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}


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

Similar presentations


Ads by Google