intermediate code generationcsci 565 - compiler design spring 2016 pedro diniz [email protected]...

55
Spring 2016 CSCI 565 - Compiler Design Pedro Diniz [email protected] Intermediate Code Generation Control-Flow Statements Short-Circuit Predicate Evaluation Back-Patching Copyright 2016, Pedro C. Diniz, all rights reserved. Students enrolled in the Compilers class at the University of Southern California have explicit permission to make copies of these materials for their personal use. 1

Upload: others

Post on 01-Aug-2020

30 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Intermediate Code Generation

Control-Flow StatementsShort-Circuit Predicate Evaluation

Back-PatchingCopyright 2016, Pedro C. Diniz, all rights reserved.Students enrolled in the Compilers class at the University of Southern California have explicit permission to make copies of these materials for their personal use.

1

Page 2: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Intermediate Code Generation

• Direct Translation– Using SDT scheme– Parse Tree to Three-Address Instructions– Can be done while parsing in a single pass

• Indirect Translation– First validate parsing constructing of AST– Uses SDT Scheme to build AST– Traverse the AST and generate Three Address Instructions

IntermediateCode Generation

O(n)

IR IR

Three-Address Instructions∞ regs

Parse tree

AST

2

Page 3: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Control Flow Statements: Code Layout

S → if E then S1

S → if E then S1else S2

E.code

S1.code

to E.trueto E.falseE.true:

E.false:

E.code

S1.code

S2.code

goto S.next

to E.trueto E.falseE.true:

E.false:

S.next:

• Attributes:– E.true: the label to which control flows if E is true (inherited)– E.false: the label to which control flows if E is false (inherited)– S.next: an inherited attribute with the symbolic label of the code following S

3

Page 4: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Code Layout

S → while E do S1

• Difficulty: Need to know where to jump to– Introduce a Symbolic labels using the newlabel function– Use Inherited Attributes– Back-patch it with the actual value (later…)

E.code

S1.code

goto S.begin

to E.trueto E.false

E.true:

E.false:

S.begin:

4

Page 5: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Grammar and ActionsS → if E then S1 ‖

E.true = newlabel()E.false = S.nextS1.next = S.nextS.code = append(E.code,gen(E.true:),S1.code)

S → if E then S1 else S2 ‖E.true = newlabel()E.false = newlabel()S1.next = S.nextS2.next = S.nextS.code = append(E.code,gen(E.true:),S1.code,

gen(goto S.next),gen(E.false :),S2.code)

S → while E do S1 ‖S.begin = newlabel()E.true = newlabel()E.false = S.nextS1.next = S.beginS.code = append(gen(S.begin:),E.code,gen(E.true:),S1.code,

gen(goto S.begin)

E.code

S1.code

to E.trueto E.false

E.true:

E.false:

E.code

S1.code

S2.code

goto S.next

to E.trueto E.falseE.true:

E.false:S.next:

E.code

S1.code

goto S.begin

to E.trueto E.false

E.true:

E.false:

S.begin:

5

Page 6: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Control Flow Translation of Boolean Expressions

• Short-Circuit Evaluation– No need to Evaluate portions of the Expression if the outcome is

already determined– Examples:

• E1 or E2 : need not evaluate E2 if E1 is known to be true. • E1 and E2 : need not evaluate E2 if E1 is known to be false.

• Use Control Flow– Jump over code that evaluates boolean terms of the expression– Use Inherited E.false and E.true attributes and link evaluation of E

6

Page 7: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Control Flow for Boolean ExpressionsE → id1 relop id2 ‖

E.code = append(gen(if id1.place relop id2.place goto E.true),gen(goto E.false))

E → true ‖ E.code = gen(goto E.true)

E → false ‖ E.code = gen(goto E.false)

E → E1 or E2 ‖E1.true = E.trueE1.false = newlabelE2.true = E.trueE2.false = E.falseE.code = append(E1.code,gen(E1.false:),E2.code)

E → E1 and E2 ‖E1.false = E.falseE1.true = newlabelE2.true = E.trueE2.false = E.falseE.code = append(E1.code,gen(E1.true:),E2.code)

E → not E1 ‖E1.true = E.false E1.false = E.trueE.code = E1.code

E → ( E1 ) ‖E1.true = E.true E1.false = E.falseE.code = E1.code

7

Page 8: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Short Circuit Evaluationa < b or c < d and e < f

E

E

E

id relop id

E

id relop id

E

a b

c d e f<<

<

or

andid relop id

8

Page 9: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

a < b or c < d and e < f

E

E

E

id relop id

E

id relop id

E

a b

c d e f<<

<

or

and

E.true = LtrueE.false = Lfalse

E1.true = LtrueE1.false = L1

id relop id

E → id1 relop id2 ‖E.code = append(

gen(if id1.place relop id2.place goto E.true),gen(goto E.false))

E → E1 or E2 ‖E1.true = E.true E1.false = newlabelE2.true = E.trueE2.false = E.false E.code = append(E1.code,

gen(E1.false:),E2.code)

E2.true = LtrueE2.false = Lfalse

if a < b goto Ltruegoto L1

L1:

Short Circuit Evaluation

9

Page 10: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

a < b or c < d and e < f

E

E

E

id relop id

E

id relop id

E

a b

c d e f<<

<

or

and

E.true = LtrueE.false = Lfalse

E1.true = LtrueE1.false = L1

id relop id

E → id1 relop id2 ‖E.code = append(

gen(if id1.place relop id2.place goto E.true),gen(goto E.false))

E → E1 and E2 ‖E1.false = E.false E1.true = newlabelE2.true = E.trueE2.false = E.false E.code = append(E1.code,

gen(E1.true:),E2.code)

E2.true = LtrueE2.false = Lfalse

if a < b goto Ltruegoto L1

E2.true = LtrueE2.false = LfalseE1.true = L2

E1.false = Lfalse

L1: if c < d goto L2goto Lfalse

L2:

Short Circuit Evaluation

10

Page 11: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

a < b or c < d and e < f

E

E

E

id relop id

E

id relop id

E

a b

c d e f<<

<

or

and

E.true = LtrueE.false = Lfalse

E1.true = LtrueE1.false = L1

id relop id

E → id1 relop id2 ‖E.code = append(

gen(if id1.place relop id2.place goto E.true),gen(goto E.false))

E → E1 and E2 ‖E1.false = E.false E1.true = newlabelE2.true = E.trueE2.false = E.false E.code = append(E1.code,

gen(E1.true:),E2.code)

E2.true = LtrueE2.false = Lfalse

if a < b goto Ltruegoto L1

E2.true = LtrueE2.false = LfalseE1.true = L2

E1.false = Lfalse

L1: if c < d goto L2goto Lfalse

L2: if e < f goto Ltruegoto Lfalse

Short Circuit Evaluation

11

Page 12: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

a < b or c < d and e < f

E

E

E

id relop id

E

id relop id

E

a b

c d e f<<

<

or

andid relop id

if a < b goto Ltruegoto L1

L1: if c < d goto L2goto Lfalse

L2: if e < f goto Ltruegoto Lfalse

Short Circuit Evaluation

12

Page 13: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Combining Boolean and Control Flow Statements

while a < b do

if c < d then

x = y + z

else

x = y - z

S → while E do S1 ‖S.begin = newlabelE.true = newlabelE.false = S.nextS1.next = S.beginS.code = append(gen(S.begin:),E.code,

gen(E.true:),S1.code,gen(goto S.begin))

S

S

E

id relop id

S

E

b

c d<

<

do

ifid relop id

while

a

then Sthen

13

Page 14: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

while a < b do

if c < d then

x = y + z

else

x = y - z

S → while E do S1 ‖S.begin = newlabelE.true = newlabelE.false = S.nextS1.next = S.beginS.code = append(gen(S.begin:),E.code,

gen(E.true:),S1.code,gen(goto S.begin))

S

S

E

id relop id

S

E

b

c d<

<

do

ifid relop id

while

a

then Sthen

S.next = Lnext

S.begin = L1

E.true = L2

E.false = Lnext

S.next = L1

Combining Boolean and Control Flow Statements

14

Page 15: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

while a < b do

if c < d then

x = y + z

else

x = y - z

S → while E do S1 ‖S.begin = newlabelE.true = newlabelE.false = S.nextS1.next = S.beginS.code = append(gen(S.begin:),E.code,

gen(E.true:),S1.code,gen(goto S.begin))

S

S

E

id relop id

S

E

b

c d<

<

do

ifid relop id

while

a

then Sthen

S.next = Lnext

S.begin = L1

E.true = L2

E.false = Lnext

S.next = L1

L1: if a < b goto L2

goto Lnext

L2:

Combining Boolean and Control Flow Statements

15

Page 16: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

while a < b do

if c < d then

x = y + z

else

x = y - z

S → while E do S1 ‖S.begin = newlabelE.true = newlabelE.false = S.nextS1.next = S.beginS.code = append(gen(S.begin:),E.code,

gen(E.true:),S1.code,gen(goto S.begin))

S

S

E

id relop id

S

E

b

c d<

<

do

ifid relop id

while

a

then Sthen

S.next = Lnext

S.begin = L1

E.true = L2

E.false = Lnext

S.next = L1

L1: if a < b goto L2

goto Lnext

L2: if c < d goto L3

goto L4

L3: E.true = L3E.false = L4 S1.next = L1

S2.next = L1

Combining Boolean and Control Flow Statements

16

Page 17: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

while a < b do

if c < d then

x = y + z

else

x = y - z

S → while E do S1 ‖S.begin = newlabelE.true = newlabelE.false = S.nextS1.next = S.beginS.code = append(gen(S.begin:),E.code,

gen(E.true:),S1.code,gen(goto S.begin))

S

S

E

id relop id

S

E

b

c d<

<

do

ifid relop id

while

a

then Sthen

S.next = Lnext

S.begin = L1

E.true = L2

E.false = Lnext

S.next = L1

L1: if a < b goto L2

goto Lnext

L2: if c < d goto L3

goto L4

L3: t1 = x + z

x = t1

goto L1

L4:

E.true = L3E.false = L4 S1.next = L1

S2.next = L1

Combining Boolean and Control Flow Statements

17

Page 18: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

while a < b do

if c < d then

x = y + z

else

x = y - z

S → while E do S1 ‖S.begin = newlabelE.true = newlabelE.false = S.nextS1.next = S.beginS.code = append(gen(S.begin:),E.code,

gen(E.true:),S1.code,gen(goto S.begin))

S

S

E

id relop id

S

E

b

c d<

<

do

ifid relop id

while

a

then Sthen

S.next = Lnext

S.begin = L1

E.true = L2

E.false = Lnext

S.next = L1

L1: if a < b goto L2

goto Lnext

L2: if c < d goto L3

goto L4

L3: t1 = x + z

x = t1

goto L1

L4: t2 = x - z

x = t2

goto L1

Lnext:

E.true = L3E.false = L4 S1.next = L1

S2.next = L1

Combining Boolean and Control Flow Statements

18

Page 19: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

while a < b do

if c < d then

x = y + z

else

x = y - z

S → while E do S1 ‖S.begin = newlabelE.true = newlabelE.false = S.nextS1.next = S.beginS.code = append(gen(S.begin:),E.code,

gen(E.true:),S1.code,gen(goto S.begin))

S

S

E

id relop id

S

E

b

c d<

<

do

ifid relop id

while

a

then Sthen

L1: if a < b goto L2

goto Lnext

L2: if c < d goto L3

goto L4

L3: t1 = x + z

x = t1

goto L1

L4: t2 = x - z

x = t2

goto L1

Lnext:

Combining Boolean and Control Flow Statements

19

Page 20: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Loop Constructs• Loops

– Evaluate condition before loop (if needed)– Evaluate condition after loop – Branch back to the top (if needed)

• Why this Structure?– Merges test with last block of loop body– Pre-test block to hold loop-invariant code– Post-test for increment instructions and test

• while, for, do, & until all fit this basic model

Pre-test

Loop head

Post-test

Next block

B1 B2

20

Page 21: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Break & Skip StatementsMany modern programming languages include a break• Exits from the innermost control-flow statement

– Out of the innermost loop– Out of a case statement

Translates into a jump• Targets statement outside control- flow

construct• Creates multiple-exit construct• skip in loop goes to next iteration

Only make sense if loop has > 1 block

Pre-test

Loop head

Post-test

Next block

B1 B2Break in B1

Skip in B2

21

Page 22: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Break and Skip Statements• Need to Keep Track of Enclosing Control-Flow Constructs• Harder to have Clean SDT Scheme…

– Keep a Stack of control-flow constructs– Using S.next in the stack as the target for the break statement– For skip statements need to keep track of the label of the code of the post-test

block to advance to the next iteration. This is harder since the code has not been generated yet.

• Back-Patching helps– Use a breaklist and a skiplist to be patched later.

22

Page 23: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Case Statements

case or switch Statements Semantics1 Evaluate the controlling expression2 Branch to the selected case3 Execute the code for that case4 Branch to the statement after the case

Parts 1, 3, & 4 are well understood, part 2 is the key

• Strategies– Linear search (nested if-then-else constructs)– Build a table of case expressions & binary search it– Directly compute an address (requires dense case set)

Surprisingly many compilers do this

for all cases!

23

Page 24: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Case Statement: Code Layout

switch Ebegincase V1: S1

case V2: S2

…case Vn-1: Sn-1

default: Sn

end

code to Evaluate E into t

goto LtestL1: code for S1

goto LnextL2: code for S2

goto Lnext…

Ln-1: code for Sn-1

goto Lnext

Ln: code for Sn

goto LnextLtest: if t = V1 goto L1

if t = V2 goto L2

…if t = Vn-1 goto Ln-1

goto Ln

Lnext:

Linear Search

24

Page 25: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

SDT scheme for Case Statements• Issue: Need to Save the Labels and Values for the

various cases for the test code at the end– Use a Right-Recursive Grammar

• Use queue to save pairs (value, label) for generation of search code• In the end pop values from queue to generate the linear search

– Use a Left-Recursive Grammar• Cleaner; No queue is needed• Use of the parsing stack to accumulate the non-terminals and

corresponding attribute

25

Page 26: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Grammar and ActionsS → switch E List end ‖

S.code = append(E.code,gen(‘goto Ltest’),List.code,gen(‘Ltest:’)while(queue not empty) do {

(vi,Li) = pop.queue;if (vi = default)

S.code = append(S.code,gen(‘goto Li’));else

S.code = append(S.code,gen(‘if t = vi goto Li’));

Case → case Value : S ‖Case.code = append(gen(‘Li:’),S.code,gen(‘goto Lnext’);queue.push((Value.val,Li));

List → Case ; List1 ‖List.code = append(Case.code,List1.code);

List → default : S ‖List.code = append(gen(‘Li:’),S.code,gen(‘goto Lnext’);queue.push((default,Li))

List → ε ‖ List.code = append(gen(‘Li:’),gen(‘goto Lnext’);queue.push((default,Li))

26

Page 27: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Case Statement: Code Layout

switch Ebegincase V1: S1

case V2: S2

…case Vn-1: Sn-1

default: Sn

end

code to Evaluate E into t

goto LtestL1: code for S1

goto LnextL2: code for S2

goto Lnext…

Ln-1: code for Sn-1

goto Lnext

Ln: code for Sn

goto LnextLtest: if t = V1 goto L1

if t = V2 goto L2

…if t = Vn-1 goto Ln-1

goto Ln

Lnext:

Linear Search

27

Page 28: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Other Statements• Declarations

– Just save information in Symbol Table– For Structures, Unions compute offsets for each field

• Function Calls– Generate code to evaluate each argument in order into temporaries– Emit the call instruction using the temporary variables

• Structures, Variants Records and Unions– Use the offsets from Symbol Table for address generation

• Unstructured Control-Flow– Breaks the SDT scheme, just use a global table and backpatch it.

28

Page 29: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Back-Patching• Single Pass Solution to Code Generation?

– No more symbolic labels - symbolic addresses instead– Emit code directly into an array of instructions– Actions associated with Productions– Executed when Bottom-Up Parser “Reduces” a production

• Problem:– Need to know the labels for target branches before actually generating

the code for them.

• Solution:– Leave Branches undefined and patch them later– Requires: carrying around a list of the places that need to be patched

until the value to be patched with is known.

29

Page 30: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Boolean Expressions Revisited

• Use Additional ε-Production– Just a Marker M– Label Value M.addr

• Attributes:– E.truelist: code places that need to be

filled-in corresponding to the evaluation of E as “true”.

– E.falselist: same for “false”

(1) E → E1 or M E2(2) | E1 and M E2(3) | not E1(4) | ( E1 ) (5) | id1 relop id2(6) | true(7) | false(8) M → ε

30

Page 31: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Boolean Expressions: Code Outline

E1.code

E2.code

E1 and E2

false

?

true

false?true

E1.code

E2.code

E1 or E2

truefalse

?

false true

31

Page 32: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Auxiliary Functions• Functions:

– makelist(i): make a list with the label i– merge(p1,p2): creates a new list of labels with lists p1 and p2– backpatch(p,i): fills the locations in p with the address i– newAddr() : returns a new symbolic address in sequence and

increments the value for the next call

• Array of Instructions– Linearly sequence of instructions– Function emit to generate actual instructions in the array– Symbolic Addresses

32

Page 33: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Using the Actions & List Attributes

{

E.truelist := makelist(newlabel);

E.falselist := makelist(newlabel);

emit(“if id1.place relop id2.place goto _”);

emit(“goto _”);

}

(5) E → id1 relop id2

100: if a < b then goto _

101: goto _

102:

E.truelist =

E.falselist =

a < b

E{101}

{100}

33

Page 34: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

More Actions

(3) E → not E1 { E.truelist := E1.falselist; E.falselist := E1.truelist; }

(4) E → (E1) { E.truelist := E1.truelist; E.falselist := E1.falselist; }

(6) E → true { E.truelist := makelist(nextAddr()); emit(“goto _”); }

(7) E → false { E.falselist := makelist(nextAddr()); emit(“goto _”); }

(5) E → id1 relop id2{

E.truelist := makelist(nextAddr());

E.falselist := makelist(nextAddr());

emit(“if id1.place relop.op id2.place goto _”);

emit(“goto _”);

}

34

Page 35: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

More Actions

(8) M → ε { M.Addr := nextAddr; }

(1) E → E1 or M E2 { backpatch(E1.falselist,M.Addr);

E.truelist := merge(E1.truelist,E2.truelist);

E.falselist := E2.falselist; }

(2) E → E1 and M E2 { backpatch(E1.truelist,M.Addr);

E.truelist := E2.truelist;

E.falselist := merge(E1.falselist, E2.falselist); }

35

Page 36: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Back-Patching Example

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist = E.falselist =

E.truelist = E.falselist =

M.addr =

M.addr =or

anda < b

c < d

e < f

ε

ε

E

E

E

E

E

M

M

EE.truelistE.falselist

M.addrM

Generated CodeExecuting Action

36

Page 37: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Back-Patching Example

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist = E.falselist =

E.truelist = E.falselist =

M.addr =

M.addr =or

anda < b

c < d

e < f

ε

ε

E

E

E

E

E

M

M

EE.truelistE.falselist

M.addrM

Generated CodeExecuting Action

100: if a < b goto _

101: goto _

{100}

{101}

{ E.truelist := makelist(nextquad());

E.falselist := makelist(nextquad());

emit(“if id1.place relop.op id2.place goto _”);

emit(“goto _”); }

37

Page 38: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Back-Patching Example

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist = E.falselist =

E.truelist = E.falselist =

M.addr =

M.addr =or

anda < b

c < d

e < f

ε

ε

E

E

E

E

E

M

M

EE.truelistE.falselist

M.addrM

Generated CodeExecuting Action

{100}

102

{101}

100: if a < b goto _

101: goto _

{ M.quad = nextquad(); }

38

Page 39: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Back-Patching Example

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist = E.falselist =

E.truelist = E.falselist =

M.addr =

M.addr =or

anda < b

c < d

e < f

ε

ε

E

E

E

E

E

M

M

EE.truelistE.falselist

M.addrM

Generated CodeExecuting Action

{100}

102

{101}

100: if a < b goto _

101: goto _

{ E.truelist := makelist(nextquad());

E.falselist := makelist(nextquad());

emit(“if id1.place relop.op id2.place goto _”);

emit(“goto _”); }

{102}{103}

102: if c < d goto _

103: goto _

39

Page 40: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Back-Patching Example

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist = E.falselist =

E.truelist = E.falselist =

M.addr =

M.addr =or

anda < b

c < d

e < f

ε

ε

E

E

E

E

E

M

M

EE.truelistE.falselist

M.addrM

Generated CodeExecuting Action

{100}

102

{101}

100: if a < b goto _

101: goto _

{103}

102: if c < d goto _

103: goto _

{ M.quad = nextquad(); }

104

{102}

40

Page 41: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Back-Patching Example

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist = E.falselist =

E.truelist = E.falselist =

M.addr =

M.addr =or

anda < b

c < d

e < f

ε

ε

E

E

E

E

E

M

M

EE.truelistE.falselist

M.addrM

Generated CodeExecuting Action

{100}

102

{101}

100: if a < b goto _

101: goto _

{103}

102: if c < d goto _

103: goto _

104

{ E.truelist := makelist(nextquad());

E.falselist := makelist(nextquad());

emit(“if id1.place relop.op id2.place goto _”);

emit(“goto _”); }

104: if e < f goto _

105: goto _

{102}

{105}{104}

41

Page 42: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Back-Patching Example

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist = E.falselist =

E.truelist = E.falselist =

M.addr =

M.addr =or

anda < b

c < d

e < f

ε

ε

E

E

E

E

E

M

M

EE.truelistE.falselist

M.addrM

Generated CodeExecuting Action

{100}

102

{101}

100: if a < b goto _

101: goto _

{103}

102: if c < d goto _

103: goto _

104

104: if e < f goto _

105: goto _

{102}

{105}{104}

{ backpatch(E1.truelist,M.quad);

E.truelist := E2.truelist;

E.falselist := merge(E1.falselist,E2.falselist; }

42

Page 43: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Back-Patching Example

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist = E.falselist =

E.truelist = E.falselist =

M.addr =

M.addr =or

anda < b

c < d

e < f

ε

ε

E

E

E

E

E

M

M

EE.truelistE.falselist

M.addrM

Generated CodeExecuting Action

{100}

102

{101}

100: if a < b goto _

101: goto _

{103}

102: if c < d goto _

103: goto _

104

104: if e < f goto _

105: goto _

{102}

{105}{104}

{ backpatch(E1.truelist,M.quad);

E.truelist := E2.truelist;

E.falselist := merge(E1.falselist,E2.falselist; }

43

Page 44: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Back-Patching Example

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist = E.falselist =

E.truelist = E.falselist =

M.addr =

M.addr =or

anda < b

c < d

e < f

ε

ε

E

E

E

E

E

M

M

EE.truelistE.falselist

M.addrM

Generated CodeExecuting Action

{100}

102

{101}

100: if a < b goto _

101: goto _

{103}

102: if c < d goto 104

103: goto _

104

104: if e < f goto _

105: goto _

{102}

{105}{104}

{ backpatch(E1.truelist,M.quad);

E.truelist := E2.truelist;

E.falselist := merge(E1.falselist,E2.falselist; }

44

Page 45: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Back-Patching Example

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist = E.falselist =

E.truelist = E.falselist =

M.addr =

M.addr =or

anda < b

c < d

e < f

ε

ε

E

E

E

E

E

M

M

EE.truelistE.falselist

M.addrM

Generated CodeExecuting Action

{100}

102

{101}

100: if a < b goto _

101: goto _

{103}

102: if c < d goto 104

103: goto _

104

104: if e < f goto _

105: goto _

{102}

{105}{104}

{ backpatch(E1.truelist,M.quad);

E.truelist := E2.truelist;

E.falselist := merge(E1.falselist,E2.falselist; }

{104}{103, 105}

45

Page 46: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Back-Patching Example

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist =

E.falselist =

E.truelist = E.falselist =

E.truelist = E.falselist =

M.addr =

M.addr =or

anda < b

c < d

e < f

ε

ε

E

E

E

E

E

M

M

EE.truelistE.falselist

M.addrM

Generated CodeExecuting Action

{100}

102

{101}

100: if a < b goto _

101: goto 102

{103}

102: if c < d goto 104

103: goto _

104

104: if e < f goto _

105: goto _

{102}

{105}{104}

{104}{103, 105}

{103, 105}

{100, 104}

{ backpatch(E1.truelist,M.quad);

E.truelist := E2.truelist;

E.falselist := merge(E1.falselist,E2.falselist; }

46

Page 47: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Back-Patching Example

E

100: if a < b goto _

101: goto 102

102: if c < d goto 104

103: goto _

104: if e < f goto _

105: goto _

E.truelist =

E.falselist = {103, 105}

{100, 104}

S → while M1 E do M2 S1 { backpatch(S1.nextlist, M1.addr);backpatch(E.truelist,M2.addr);S.nextlist := E.falselist;emit(“goto M1.addr”);

}

47

Page 48: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Back-Patching Example

E

100: if a < b goto _

101: goto 102

102: if c < d goto 104

103: goto _

104: if e < f goto _

105: goto _

E.truelist =

E.falselist = {103, 105}

{100, 104}

S → while M1 E do M2 S1 { backpatch(S1.nextlist, M1.addr);backpatch(E.truelist,M2.addr);S.nextlist := E.falselist;emit(“goto M1.addr”);

}

S1

48

Page 49: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Back-Patching Example

E

100: if a < b goto _

101: goto 102

102: if c < d goto 104

103: goto _

104: if e < f goto _

105: goto _

E.truelist =

E.falselist = {103, 105}

{100, 104}

S → while M1 E do M2 S1 { backpatch(S1.nextlist, M1.addr);backpatch(E.truelist,M2.addr);S.nextlist := E.falselist;emit(“goto M1.addr”);

}

S1

49

Page 50: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Control Flow Code Structures

.

.

.

E.code

S1.codeE.true:

E.false:

if E then S1

.

.

.

E.code

S1.codeE.true:

E.false:

if E then S1 else S2

S.next:

S2.code

goto S.next

.

.

.

E.code

S1.codeE.true:

E.false:

while E do S1

goto S.begin

S.begin:

50

Page 51: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Control Flow Constructs: Conditionals

(4) S → if E then M S1 { backpatch(E.truelist, M.addr);S.nextlist := merge(E.falselist,S1.nextlist);

}

(3) M → ε { M.quad := nextAddr; }

(2) N → ε { N.nextlist := makelist(nextAddr();

emit(“goto _”); }

(1) S → if E then M1 S1 N else M2 S2 { backpatch(E.truelist, M1.addr);backpatch(E.falselist,M2.addr);

S.nextlist := merge(S1.nextlist,merge(N.nextlist,S2.nextlist));}

• Add the nextlist attribute to S and N– denotes the set of locations in the S code to be patched with the

address that follows the execution of S– Can be either due to control flow or fall-through

51

Page 52: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Control Flow Constructs: Loops(5) S → while M1 E do M2 S1 {

backpatch(S1.nextlist, M1.addr),);backpatch(E.truelist,M2.addr);S.nextlist := E.falselist;

emit(“goto M1.addr”);}

52

Page 53: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Sequencing: List of Statements

(6) S → begin L end { S.nextlist = L.nextlist; }

(7) S → A { S.nextlist = nil; }

(8) L → L1; M S { backpatch(L1.nextlist, M.addr); L.nextlist = S.nextlist; }

(9) L → S { L.nextlist = S.nextlist; }

• Additional Symbols– L for list of statements– S for Assignment statement

53

Page 54: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Extended Examplei = 0;while (i < n) dobeginif(a <= k) then

a = a + 1; i++;

end

L

L M1 S

A

while M1 E do M2 S1

( E )begin L end

L1 M1 S1

S

AS

if E then M1 S1

A( E )

ε

ε ε

ε

ε

id rel id

id rel id54

Page 55: Intermediate Code GenerationCSCI 565 - Compiler Design Spring 2016 Pedro Diniz pedro@isi.edu Intermediate Code Generation • Direct Translation – Using SDT scheme – Parse Tree

Spring 2016CSCI 565 - Compiler Design

Pedro [email protected]

Summary• Intermediate Code Generation

– Using Syntax-Directed Translation Schemes– Conditional – Boolean using Short-Circuit Evaluation– Control-Flow

• Back-Patching– Allows Code Generation in a Single Pass

55