1 Intermediate Code generation. 2 Intermediate Code Generation l Intermediate languages l...
-
date post
20-Dec-2015 -
Category
Documents
-
view
310 -
download
0
Transcript of 1 Intermediate Code generation. 2 Intermediate Code Generation l Intermediate languages l...
1
Intermediate Code generation
2
Intermediate Code Generation Intermediate languages Declarations Expressions Statements
Reference: » Chapter 8, Compilers Principles, techniques, and
Tools.
3
Intermediate Languages a := b * - c + b * - c
Syntax tree
Postfix notation» a b c - * b c - * + :=
Three-address code
4
Types of Three-Address Code Assignment statement x := y op z Assignment statement x := op y Copy statement x := y Unconditional jump goto L Conditional jump if x relop y goto L Procedural call param x
call p, n
return y
5
Types of Three-Address Code Indexed assignment: x := y[i]
x[i] := y Address and pointer assignment :
x := &y
x := *y
*x := y
6
Implementation of Three-Address Code Quadruples
op arg1 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 Temporary names generated for holding the
value of internal node of a syntax tree. E1 + E2
» E1 + E2 computed into a new temporary t id := E
» E’s result is assumed to be at E.place» id.place ‘:=‘ E.place generated
E is an id (say,y)» E.palce = y.» id.place = id.name
8
Notations and functions Function newtemp() returns a new name for each call Function newlabel() returns a new label for each call 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. gen(String) : generate a three address code instruction.
» gen(id.place ‘:=‘ ‘3’) => “x := 3”. || : 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 Compute the types and relative addresses of namesP {offset := 0} DD D “;” DD 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 xT1.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 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. Stacks
» tblptr: [pointers to] the stack of symbol tables» offset :[pointer to ] the stack of the next available relative
address
14
Declarations 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 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. 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) } PS P | e { } P T Id | P, T Id {
enter(top(tblptr), id.name, T.type, top(offset));
top(offset) := top(offset) + T.width } DS D | S
16
D T id; | D T id ; {
enter(top(tblptr), id.name, T.type, top(offset));
top(offset) := top(offset) + T.width } S … | { M2 DS }. {
t := top(tblptr); pop(tblptr);
enterblock(top(tblptr), t) } 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 A[i]:
baseA + (i - low) *w
(i *w) + (baseA - low *w)
A[i1, i2]:
base + ((i1 - low1) *n2 + i2 - low2) *w
(((i1* n2) + i2) *w) + (base - ((low1*n2) + low2) *w) c(id.place), width(id.place), limit(id.place, i) recurrence rules:
» e1 = i1,
» em = e m-1 x nm + im = em-1 x limit(id.place, m) + im
» id[i1,..im] = c + em x w.
21
A[i,j]
baseA
a = baseA + (i-low1) x n2 x W
a + (j – low2) x W
22
Array Accesses Use inherited attributes
L id “[” Elist “]” | id
Elist Elist “,” E | E
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 nm + im 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 idE.place := L.place ;else { // array elementE.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 elementemit(L.place ‘[’ L.offset ‘]’ ‘:=’ E.place) ;
}
26
An Example x := A[y, z] n1 = 10, n2 = 20, w = 4 c = baseA - ((1 20) + 1) *4 = baseA – 84
t1 := y * 20 t1 := t1 + z t2 := c t3 := t1 * 4 t4 := t2[t3] 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
} .code is a
synthesis attribute 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 E E1 or E2 | E1 and E2
| not E1 | (E1) | E1 relop E2 | true | false 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 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 }
| E1 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 a < b or c < d and e < f
if a < b goto Ltrue goto L1 L1: if c < d goto L2 goto Lfalse L2: if e < f goto Ltrue goto Lfalse
37
Examplewhile (a < b) {
if( c < d)
x := y + z ;
else
x := y – z ;
}
L1: if a < b goto L2goto Lnext
L2: if c < d goto L3goto L4
L3: t1 := y + zx := t1goto L1
L4: t2 := y - zx := t2goto L1
Lnext:
38
Backpatching goto __ if () goto ___
Let i be an instruction with target address unfilled. makeList(i) = [ i ]. merge(p1, p2) = p1 . p2 backpatch(p, i) :
» filled all unfilled targets in p by i.
39
E E1 or M E2
| E1 and M E2
| not E1
| (E1)
| E1 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
E E1 or M E2 {
backpatch(E1.falseList, M.quard);
E.trueList = merge(E1.trueList, E2.trueList);
E.falseList = E2.falseList } E E1 and M E2 {…} E not E1 {E.falseList = E1.trueList ;
E.falseList = E1.trueList} E (E) {…} E false | true {
E.trueList = makeList(nextquard) ;
emit(goto ‘ __’) ;}
41
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 a < b or M1(102) c < d and M2(104) e < f
100 if a < b goto ___ 101 goto ___ // 102 102 if c < d goto ___ 103 goto ____ 104 if e < f goto ____ 105 goto _____
43
S.nextList (L.nextList) is a list of all conditional /unconditional jumps to the quarduple following S (L) in executin order.
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 ); N { N.nextList = [ nextquard ] ;
emit(goto ___ ); }
44
Backpatching Control Flows M {M.quard = nextquard } S if E then M S1 { backpatch(E.truList , M.quard); S.nextList = merge(E.falseList, S1.nextList); } S while M1 E do M2 S1 { backpatch(S1.nextList, M1.quard); backpatch(E.truList , M2.quard); S.nextList = E.falseList; emit(‘goto’ M1.quard); S { L } { s.nextList = L.nextList ;} L L1 ; M S { backpatch(L1.nextList, M.quard); L.nextList = S.nextList } S A {S.nextList :== [] } // A is assignment
45
Case Statements Conditional goto’s
» less than 10 cases Jump table
» more than 10 cases» dense value range
Hash table» more than 10 cases» sparse value range
46
Conditional Goto’scode to evaluate E into
tgoto test
L1: code for S1goto L2…
Ln: code for Sngoto L0
L0: code for Sgoto next
test: if t = V1 goto L1…if t = Vn goto Lngoto L0
next:
switch(E) {
case v1 : S1case v2: S2…case vn : Sndefault: S}
47
Jump Tablecode 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 : S1case v2: S2…case vn : Sndefault: S}
48
Hash Table
code to evaluate E into t
i := hash(t)
L := hashTable[i]
goto L
switch(E) {
case v1 : S1case v2: S2…case vn : Sndefault: 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}