Intermediate Code Generation - Part 2 Y.N. Srikant Department of Computer Science and Automation Indian Institute of Science Bangalore 560 012 NPTEL Course on Principles of Compiler Design Y.N. Srikant Intermediate Code Generation
Outline of the Lecture Introduction (covered in part 1) Different types of intermediate code (covered in part 1) Intermediate code generation for various constructs Y.N. Srikant Intermediate Code Generation
SATG for If-Then-Else Statement IFEXP → if E { IFEXP .falselist := makelist(nextquad); gen(‘if E.result ≤ 0 goto __’); } S → IFEXP S 1 ; N else M S 2 { backpatch(IFEXP .falselist, M.quad); S.next := merge( S 1 .next, S 2 .next, N.next); } S → IFEXP S 1 ; { S.next := merge( S 1 .next, IFEXP .falselist); } N → ǫ { N.next := makelist(nextquad); gen(‘goto __’); } M → ǫ { M.quad := nextquad; } Y.N. Srikant Intermediate Code Generation
SATG for Other Statements S → ‘{’ L ‘}’ { S.next := L.next; } S → A { S.next := makelist(nil); } S → return E { gen(‘return E.result’); S.next := makelist(nil); } L → L 1 ‘;’ M S { backpatch( L 1 .next, M.quad); L.next := S.next; } L → S { L.next := S.next; } When the body of a procedure ends, we perform the following actions in addition to other actions: { backpatch(S.next, nextquad); gen(‘func end’); } Y.N. Srikant Intermediate Code Generation
Translation Trace for If-Then-Else Statement A i are all assignments, and E i are all expressions if ( E 1 ) { if ( E 2 ) A 1 ; else A 2 ; }else A 3 ; A 4 ; S ⇒ IFEXP S 1 ; N 1 else M 1 S 2 ⇒ ∗ IFEXP 1 IFEXP 2 S 21 ; N 2 else M 2 S 22 ; N 1 else M 1 S 2 Consider outer if-then-else 1 Code generation for E 1 gen(‘if E 1 .result ≤ 0 goto __’) 2 on reduction by IFEXP 1 → if E 1 Remember the above quad address in IFEXP 1 .falselist Consider inner if-then-else 3 Code generation for E 2 gen(‘if E 2 .result ≤ 0 goto __’) 4 on reduction by IFEXP 2 → if E 2 Remember the above quad address in IFEXP 2 .falselist Y.N. Srikant Intermediate Code Generation
Translation Trace for If-Then-Else Statement(contd.) if ( E 1 ) { if ( E 2 ) A 1 ; else A 2 ; }else A 3 ; A 4 ; S ⇒ ∗ IFEXP 1 IFEXP 2 S 21 ; N 2 else M 2 S 22 ; N 1 else M 1 S 2 Code generated so far: Code for E 1 ; if E 1 .result ≤ 0 goto __ (on IFEXP 1 .falselist); Code for E 2 ; if E 2 .result ≤ 0 goto __ (on IFEXP 2 .falselist); Code generation for S 21 5 gen(‘goto __’), on reduction by N 2 → ǫ 6 (remember in N 2 .next) L1: remember in M 2 .quad, on reduction by M 2 → ǫ 7 Code generation for S 22 8 backpatch( IFEXP 2 .falselist, L1) (processing E 2 == false) 9 on reduction by S 1 → IFEXP 2 S 21 N 2 else M 2 S 22 N 2 .next is not yet patched; put on S 1 .next Y.N. Srikant Intermediate Code Generation
Translation Trace for If-Then-Else Statement(contd.) if ( E 1 ) { if ( E 2 ) A 1 ; else A 2 ; }else A 3 ; A 4 ; S ⇒ IFEXP S 1 ; N 1 else M 1 S 2 S ⇒ ∗ IFEXP 1 IFEXP 2 S 21 ; N 2 else M 2 S 22 ; N 1 else M 1 S 2 Code generated so far: Code for E 1 ; if E 1 .result ≤ 0 goto __ (on IFEXP 1 .falselist) Code for E 2 ; if E 2 .result ≤ 0 goto L1 Code for S 21 ; goto __ (on S 1 .next) L1: Code for S 22 10 gen(‘goto __’), on reduction by N 1 → ǫ (remember in N 1 .next) 11 L2: remember in M 1 .quad, on reduction by M 1 → ǫ 12 Code generation for S 2 13 backpatch(IFEXP .falselist, L2) (processing E 1 == false) on reduction by S → IFEXP S 1 N 1 else M 1 S 2 N 1 .next is merged with S 1 .next, and put on S.next Y.N. Srikant Intermediate Code Generation
Translation Trace for If-Then-Else Statement(contd.) if ( E 1 ) { if ( E 2 ) A 1 ; else A 2 ; }else A 3 ; A 4 ; S ⇒ ∗ IFEXP 1 IFEXP 2 S 21 ; N 2 else M 2 S 22 ; N 1 else M 1 S 2 L ⇒ ∗ L 1 ‘;’ M 3 S 4 ⇒ ∗ S 3 ‘;’ M 3 S 4 Code generated so far (for S 3 / L 1 above): Code for E 1 ; if E 1 .result ≤ 0 goto L2 Code for E 2 ; if E 2 .result ≤ 0 goto L1 Code for S 21 ; goto __ (on S 3 .next/ L 1 .next) L1: Code for S 22 goto __ (on S 3 .next/ L 1 .next) L2: Code for S 2 14 L3: remember in M 3 .quad, on reduction by M 3 → ǫ 15 Code generation for S 4 16 backpatch( L 1 .next, L3), on reduction by L → L 1 ‘;’ M 3 S 4 17 L.next is empty Y.N. Srikant Intermediate Code Generation
Translation Trace for If-Then-Else Statement(contd.) if ( E 1 ) { if ( E 2 ) A 1 ; else A 2 ; }else A 3 ; A 4 ; S ⇒ ∗ IFEXP 1 IFEXP 2 S 21 ; N 2 else M 2 S 22 ; N 1 else M 1 S 2 L ⇒ ∗ L 1 ‘;’ M 3 S 4 ⇒ ∗ S 3 ‘;’ M 3 S 4 Final generated code Code for E 1 ; if E 1 .result ≤ 0 goto L2 Code for E 2 ; if E 2 .result ≤ 0 goto L1 Code for S 21 ; goto L3 L1: Code for S 22 goto L3 L2: Code for S 2 L3: Code for S 4 Y.N. Srikant Intermediate Code Generation
SATG for While-do Statement WHILEXEP → while M E { WHILEEXP .falselist := makelist(nextquad); gen(‘if E.result ≤ 0 goto __’); WHILEEXP .begin := M.quad; } S → WHILEXEP do S 1 { gen(‘goto WHILEEXP .begin’); backpatch( S 1 .next, WHILEEXP .begin); S.next := WHILEEXP .falselist; } M → ǫ (repeated here for convenience) { M.quad := nextquad; } Y.N. Srikant Intermediate Code Generation
Code Template for Function Declaration and Call Assumtion: No nesting of functions result foo(parameter list){ variable declarations; Statement list; } func begin foo /* creates activation record for foo - */ /* - space for local variables and temporaries */ code for Statement list func end /* releases activation record and return */ x = bar(p1,p2,p3); code for evaluation of p1, p2, p3 (result in T1, T2, T3) /* result is supposed to be returned in T4 */ param T1; param T2; param T3; refparam T4; call bar, 4 /* creates appropriate access links, pushes return address */ /* and jumps to code for bar */ x = T4 Y.N. Srikant Intermediate Code Generation
SATG for Function Call Assumtion: No nesting of functions FUNC _ CALL → id {action 1} ( PARAMLIST ) {action 2} {action 1:} {search_func(id.name, found, fnptr); call_name_ptr := fnptr } {action 2:} { result_var := newtemp(get_result_type(call_name_ptr)); gen(‘refparam result_var’); /* Machine code for return a places a in result_var */ gen(‘call call_name_ptr, PARAMLIST.pno+1’); } PARAMLIST → PLIST { PARAMLIST.pno := PLIST.pno } PARAMLIST → ǫ {PARAMLIST.pno := 0 } PLIST → E { PLIST.pno := 1; gen(‘param E.result’); } PLIST 1 → PLIST 2 , E { PLIST 1 .pno := PLIST 2 .pno + 1; gen(‘param E.result’); } Y.N. Srikant Intermediate Code Generation
SATG for Function Declaration Assumtion: No nesting of functions FUNC _ DECL → FUNC _ HEAD { VAR _ DECL BODY } { backpatch(BODY.next, nextquad); gen(‘func end’);} FUNC _ HEAD → RESULT id ( DECL _ PLIST ) { search_func(id.name, found, namptr); active_func_ptr := namptr; gen(‘func begin active_func_ptr’); } Y.N. Srikant Intermediate Code Generation
1-D Representation of 3-D Array Y.N. Srikant Intermediate Code Generation
Code Template for Expressions and Assignments int a[10][20][35], b; b = exp1; code for evaluation of exp1 (result in T1) b = T1 /* Assuming the array access to be, a[i][j][k] */ /* base address = addr(a), offset = (((i*n2)+j)*n3)+k)*ele_size */ a[exp2][exp3][exp4] = exp5; 10: code for exp2 (result in T2) | | 141: T8 = T7+T6 70: code for exp3 (result in T3) | | 142: T9 = T8*intsize 105: T4 = T2*20 | | 143: T10 = addr(a) 106: T5 = T4+T3 | | 144: code for exp5 (result in T11) 107: code for exp4 (result in T6)| | 186: T10[T9] = T11 140: T7 = T5*35 Y.N. Srikant Intermediate Code Generation
SATG for Expressions and Assignments S → L := E /* L has two attributes, L.place, pointing to the name of the variable or temporary in the symbol table, and L.offset, pointing to the temporary holding the offset into the array (NULL in the case of a simple variable) */ { if (L.offset == NULL) gen(‘L.place = E.result’); else gen(‘L.place[L.offset] = E.result’);} E → ( E 1 ) {E.result := E 1 .result; } E → L { if (L.offset == NULL) E.result := L.place; else { E.result := newtemp(L.type); gen(‘E.result = L.place[L.offset]’); } E → num { E.result := newtemp(num.type); gen(‘E.result = num.value’); } Y.N. Srikant Intermediate Code Generation
SATG for Expressions and Assignments (contd.) E → E 1 + E 2 { result_type := compatible_type( E 1 .type, E 2 .type); E.result := newtemp(result_type); if ( E 1 .type == result_type) operand_1 := E 1 .result; else if ( E 1 .type == integer && result_type == real) { operand_1 := newtemp(real); gen(‘operand_1 = cnvrt_float( E 1 .result); }; if ( E 2 .type == result_type) operand_2 := E 2 .result; else if ( E 2 .type == integer && result_type == real) { operand_2 := newtemp(real); gen(‘operand_2 = cnvrt_float( E 2 .result); }; gen(‘E.result = operand_1 + operand_2’); } Y.N. Srikant Intermediate Code Generation
SATG for Expressions and Assignments (contd.) E → E 1 || E 2 { E.result := newtemp(integer); gen(‘E.result = E 1 .result || E 2 .result’); E → E 1 < E 2 { E.result := newtemp(integer); gen(‘E.result = 1’); gen(‘if E 1 .result < E 2 .result goto nextquad+2’); gen(‘E.result = 0’); } L → id { search_var_param(id.name, active_func_ptr, level, found, vn); L.place := vn; L.offset := NULL; } Note: search_var_param () searches for id.name in the variable list first, and if not found, in the parameter list next. Y.N. Srikant Intermediate Code Generation
Recommend
More recommend