Download presentation
Presentation is loading. Please wait.
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}
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.