Compilerconstructie najaar 2017 http://www.liacs.leidenuniv.nl/~vlietrvan1/coco/ Rudy van Vliet kamer 140 Snellius, tel. 071-527 2876 rvvliet(at)liacs(dot)nl college 7, vrijdag 3 november 2017 + werkcollege Intermediate Code Generation 2 1
FME Hackathon http://www.fme.nl/hackathon 2
Today • Translation of control flow – Top-down passing of labels (inherited attributes) – Backpatching (synthesized attributes) • Translation of switch-statements 3
6.6 Control Flow • Boolean expressions used to 1. Alter flow of control: if ( E ) S 2. Compute logical values, cf. arithmetic expressions • Generated by → P S → id = num ; | S SS | if ( B ) S | if ( B ) S else S | while ( B ) S → B || B | B && B | ! B | ( B ) | E rel E | true | false B • In B 1 || B 2 , if B 1 is true, then expression is true In B 1 && B 2 , if . . . 4
6.6.2 Short-Circuit Code or jumping code Boolean operators || , && and ! translate into jumps Example if ( x < 100 || x > 200 && x!=y ) x = 0; Precedence: || && ! < < if x < 100 goto L2 ifFalse x > 200 goto L1 ifFalse x != y goto L1 L2: x = 0 L1: 5
6.6.3 Flow-of-Control Statements Translation using • synthesized attributes B. code and S. code • inherited attributes (labels) B. true , B. false and S. next 6
Syntax-Directed Definition Production Semantic Rules → P S 7
Syntax-Directed Definition Production Semantic Rules S. next = newlabel () P → S P. code = S. code || label ( S. next ) id = num ; S → 8
Syntax-Directed Definition Production Semantic Rules → S. next = newlabel () P S P. code = S. code || label ( S. next ) S. code = gen ( id . addr ′ = ′ num . val ); → id = num ; S → S S 1 S 2 9
Syntax-Directed Definition Production Semantic Rules S. next = newlabel () P → S P. code = S. code || label ( S. next ) S. code = gen ( id . addr ′ = ′ num . val ); id = num ; S → S 1 . next = newlabel () S → S 1 S 2 S 2 . next = S. next S. code = S 1 . code || label ( S 1 . next ) || S 2 . code → if ( B ) S 1 S 10
Syntax-Directed Definition Production Semantic Rules → S. next = newlabel () P S P. code = S. code || label ( S. next ) S. code = gen ( id . addr ′ = ′ num . val ); → id = num ; S → S 1 . next = newlabel () S S 1 S 2 S 2 . next = S. next S. code = S 1 . code || label ( S 1 . next ) || S 2 . code → if ( B ) S 1 B. true = newlabel () S B. false = S 1 . next = S. next S. code = B. code || label ( B. true ) || S 1 . code → if ( B ) S 1 else S 2 S 11
Syntax-Directed Definition Production Semantic Rules → S. next = newlabel () P S P. code = S. code || label ( S. next ) S. code = gen ( id . addr ′ = ′ num . val ); id = num ; S → S 1 . next = newlabel () S → S 1 S 2 S 2 . next = S. next S. code = S 1 . code || label ( S 1 . next ) || S 2 . code if ( B ) S 1 B. true = newlabel () S → B. false = S 1 . next = S. next S. code = B. code || label ( B. true ) || S 1 . code if ( B ) S 1 else S 2 B. true = newlabel () S → B. false = newlabel () S 1 . next = S 2 . next = S. next S. code = B. code || label ( B. true ) || S 1 . code || gen ( ′ goto ′ S. next ) || label ( B. false ) || S 2 . code → while ( B ) S 1 S 12
Syntax-Directed Definition Production Semantic Rules → S. next = newlabel () P S P. code = S. code || label ( S. next ) S. code = gen ( id . addr ′ = ′ num . val ); → id = num ; S → S 1 . next = newlabel () S S 1 S 2 S 2 . next = S. next S. code = S 1 . code || label ( S 1 . next ) || S 2 . code → if ( B ) S 1 B. true = newlabel () S B. false = S 1 . next = S. next S. code = B. code || label ( B. true ) || S 1 . code → if ( B ) S 1 else S 2 B. true = newlabel () S B. false = newlabel () S 1 . next = S 2 . next = S. next S. code = B. code || label ( B. true ) || S 1 . code || gen ( ′ goto ′ S. next ) || label ( B. false ) || S 2 . code → while ( B ) S 1 begin = newlabel () S B. true = newlabel () B. false = S. next S 1 . next = begin S. code = label ( begin ) || B. code || label ( B. true ) || S 1 . code || gen ( ′ goto ′ begin ) 13
6.6.3 Flow-of-Control Statements → if ( B ) S 1 S → if ( B ) S 1 else S 2 S → while ( B ) S 1 S to B. true to B. true ✲ ✲ B. code B. code to B. false to B. false ✲ ✲ B. true : B. true : S 1 . code S 1 . code . . . goto S. next B. false : B. false : if S 2 . code . . . S. next : if-else 14
Syntax-Directed Definition Production Semantic Rules → E 1 rel E 2 B 15
Syntax-Directed Definition Production Semantic Rules → E 1 rel E 2 B. code = E 1 . code || E 2 . code B || gen ( ′ if ′ E 1 . addr rel . op E 2 . addr ′ goto ′ B. true ) || gen ( ′ goto ′ B. false ) → B 1 | | B 2 B 16
Syntax-Directed Definition Production Semantic Rules → E 1 rel E 2 B. code = E 1 . code || E 2 . code B || gen ( ′ if ′ E 1 . addr rel . op E 2 . addr ′ goto ′ B. true ) || gen ( ′ goto ′ B. false ) B 1 . true = B. true B → B 1 | | B 2 B 1 . false = newlabel () B 2 . true = B. true B 2 . false = B. false B. code = B 1 . code || label ( B 1 . false ) || B 2 . code B 1 && B 2 B 1 . true = newlabel () B → B 1 . false = B. false B 2 . true = B. true B 2 . false = B. false B. code = B 1 . code || label ( B 1 . true ) || B 2 . code 17
Syntax-Directed Definition Production Semantic Rules S. next = newlabel () P → S P. code = S. code || label ( S. next ) if ( B ) S 1 B. true = newlabel () S → B. false = S 1 . next = S. next S. code = B. code || label ( B. true ) || S 1 . code → B 1 | | B 2 B 1 . true = B. true B B 1 . false = newlabel () B 2 . true = B. true B 2 . false = B. false B. code = B 1 . code || label ( B 1 . false ) || B 2 . code → E 1 rel E 2 B 1 . code = E 1 . code || E 2 . code B 1 || gen ( ′ if ′ E 1 . addr rel . op E 2 . addr ′ goto ′ B 1 . true ) || gen ( ′ goto ′ B 1 . false ) → B 3 && B 4 B 3 . true = newlabel () B 2 B 3 . false = B 2 . false B 4 . true = B 2 . true B 4 . false = B 2 . false B 2 . code = B 3 . code || label ( B 3 . true ) || B 4 . code S 1 . code = gen ( id . addr ′ = ′ num . val ); → id = num ; S 1 Example: if ( x < 100 || x > 200 && x != y ) x = 0; 18
6.6.5 Avoiding Redundant Gotos if x < 100 goto L2 goto L3 L3: if x > 200 goto L4 goto L1 L4: if x != y goto L2 goto L1 L2: x = 0 L1: Versus if x < 100 goto L2 ifFalse x > 200 goto L1 ifFalse x != y goto L1 L2: x = 0 L1: 19
6.7 Backpatching B. code 103 goto B. true • Code generation problem: 107 goto B. false – Labels (addresses) that control 110 goto B. false must go to may not be known at the time that jump statements are generated 118 goto B. true • One solution: – Separate pass to bind labels to B. true : 128 . . . addresses B. false : 135 . . . 20
6.7 Backpatching • Code generation problem: – Labels (addresses) that control must go to may not be known at the time that jump statements are generated • Other solution: backpatching – Generate jump statements with empty target – Add such statements to a list – Fill in targets when proper address is determined 21
6.7.1 One-Pass Code Generation Using Backpatching • Synthesized attributes B. truelist , B. falselist , S. nextlist con- taining lists of jumps • Three functions 1. makelist ( i ) creates new list containing index i 2. merge ( p 1 , p 2 ) concatenates lists pointed to by p 1 and p 2 3. backpatch ( p, i ) inserts i as target label for each instruction on list pointed to by p 22
B. true /B. false vs B. truelist /B. falselist B. code B. code 103 goto B. true 103 goto 107 goto 107 goto B. false 110 goto 110 goto B. false 118 goto 118 goto B. true B. true : 128 . . . 128 . . . B. false : 135 . . . 135 . . . B. truelist = { 103 , 118 } B. falselist = { 107 , 110 } Analogous: S. next vs S. nextlist 23
Grammars for Backpatching • Grammar for boolean expressions: → B 1 || MB 2 | B 1 && MB 2 | ! B 1 | ( B 1 ) B | E 1 rel E 2 | true | false → M ǫ M is marker nonterminal • Grammar for flow-of-control statements (marker nonterminals omitted for readability) → if ( B ) S 1 | if ( B ) S 1 else S 2 S | while ( B ) S 1 | { L } | id = num ; → | L L 1 S S 24
Translation Scheme for Backpatching B → E 1 rel E 2 25
Translation Scheme for Backpatching B → E 1 rel E 2 { B. truelist = makelist ( nextinstr ); B. falselist = makelist ( nextinstr + 1); gen ( ′ if ′ E 1 . addr rel . op E 2 . addr ′ goto ′ ); gen ( ′ goto ′ ); } M → ǫ { M. instr = nextinstr ; } B → B 1 || MB 2 26
Translation Scheme for Backpatching B → E 1 rel E 2 { B. truelist = makelist ( nextinstr ); B. falselist = makelist ( nextinstr + 1); gen ( ′ if ′ E 1 . addr rel . op E 2 . addr ′ goto ′ ); gen ( ′ goto ′ ); } M. instr = nextinstr ; } M → ǫ { backpatch ( B 1 . falselist , M. instr ); B → B 1 || MB 2 { B. truelist = merge ( B 1 . truelist , B 2 . truelist ); B. falselist = B 2 . falselist ; } B → B 1 && MB 2 { backpatch ( B 1 . truelist , M. instr ); B. truelist = B 2 . truelist ; B. falselist = merge ( B 1 . falselist , B 2 . falselist ); } S → id = num ; 27
Recommend
More recommend