Subject Name:COMPILER DESIGN Subject Code:10CS63

Slides:



Advertisements
Similar presentations
Chapter 6 Intermediate Code Generation
Advertisements

Intermediate Code Generation
Intermediate Code Generation. 2 Intermediate languages Declarations Expressions Statements.
Backpatching: The syntax directed definition we discussed before can be implemented in two or more passes (we have both synthesized attributes and inheritent.
Lecture 08a – Backpatching & Recap Eran Yahav 1 Reference: Dragon 6.2,6.3,6.4,6.6.
Short circuit code for boolean expressions: Boolean expressions are typically used in the flow of control statements, such as if, while and for statements,
8 Intermediate code generation
Chapter 8 Intermediate Code Generation. Intermediate languages: Syntax trees, three-address code, quadruples. Types of Three – Address Statements: x :=
1 Compiler Construction Intermediate Code Generation.
Generation of Intermediate Code Compiler Design Lecture (03/30//98) Computer Science Rensselaer Polytechnic.
PSUCS322 HM 1 Languages and Compiler Design II IR Code Generation I Material provided by Prof. Jingke Li Stolen with pride and modified by Herb Mayer PSU.
Compiler Designs and Constructions
Three Address Code Generation Backpatching-I Prepared By: Siddharth Tiwary 04CS3010.
Theory of Compilation Erez Petrank Lecture 6: Intermediate Representation 1.
1 CMPSC 160 Translation of Programming Languages Fall 2002 Lecture-Modules 17 and 18 slides derived from Tevfik Bultan, Keith Cooper, and Linda Torczon.
1 Intermediate Code generation. 2 Intermediate Code Generation l Intermediate languages l Declarations l Expressions l Statements l Reference: »Chapter.
CH4.1 CSE244 Intermediate Code Generation Aggelos Kiayias Computer Science & Engineering Department The University of Connecticut 371 Fairfield Road, Unit.
Static checking and symbol table Chapter 6, Chapter 7.6 and Chapter 8.2 Static checking: check whether the program follows both the syntactic and semantic.
CS412/413 Introduction to Compilers Radu Rugina Lecture 15: Translating High IR to Low IR 22 Feb 02.
What is Three Address Code? A statement of the form x = y op z is a three address statement. x, y and z here are the three operands and op is any logical.
1 Structure of a Compiler Front end of a compiler is efficient and can be automated Back end is generally hard to automate and finding the optimum solution.
Compiler Chapter# 5 Intermediate code generation.
1 Intermediate Code Generation Part I Chapter 8 COP5621 Compiler Construction Copyright Robert van Engelen, Florida State University, 2007.
Chapter 8: Intermediate Code Generation
1 October 25, October 25, 2015October 25, 2015October 25, 2015 Azusa, CA Sheldon X. Liang Ph. D. Computer Science at Azusa Pacific University Azusa.
國立台灣大學 資訊工程學系 薛智文 98 Spring Intermediate Code Generation (textbook ch# 6.1–6.4, 6.5.1–6.5.3,
Intermediate Code Generation
1 June 3, June 3, 2016June 3, 2016June 3, 2016 Azusa, CA Sheldon X. Liang Ph. D. Computer Science at Azusa Pacific University Azusa Pacific University,
Topic #7: Intermediate Code EE 456 – Compiling Techniques Prof. Carl Sable Fall 2003.
1 Intermediate Code Generation Abstraction at the source level identifiers, operators, expressions, statements, conditionals, iteration, functions (user.
Review: Syntax directed translation. –Translation is done according to the parse tree. Each production (when used in the parsing) is a sub- structure of.
Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.
Chap. 4, Intermediate Code Generation
Theory of Compilation Erez Petrank Lecture 6: Intermediate Representation and Attribute Grammars 1.
1 February 28, February 28, 2016February 28, 2016February 28, 2016 Azusa, CA Sheldon X. Liang Ph. D. Computer Science at Azusa Pacific University.
Three Address Code Generation of Control Statements continued..
CS 404Ahmed Ezzat 1 CS 404 Introduction to Compiler Design Lecture 10 Ahmed Ezzat.
1 Compiler Construction (CS-636) Muhammad Bilal Bashir UIIT, Rawalpindi.
Intermediate code Jakub Yaghob
Compilers Principles, Techniques, & Tools Taught by Jing Zhang
Intermediate code generation Jakub Yaghob
Compiler Construction
Compiler Construction
Compiler Optimization and Code Generation
Intermediate Code Generation Part I
Intermediate Code Generation
Intermediate Code Generation Part II
Three Address Code Generation Control Statement
Chapter 6 Intermediate-Code Generation
Intermediate Code Generation Part II
Three Address Code Generation - Control Statements
Intermediate Code Generation Part I
Intermediate Code Generation Part II
Intermediate code generation
Three-address code A more common representation is THREE-ADDRESS CODE . Three address code is close to assembly language, making machine code generation.
7.4 Boolean Expression and Control Flow Statements
CSc 453 Intermediate Code Generation
Compiler Design 21. Intermediate Code Generation
Intermediate Code Generation Part I
Three Address Code Generation – Backpatching
Intermediate Code Generation
THREE ADDRESS CODE GENERATION
Intermediate Code Generation Part II
Intermediate Code Generation
Intermediate Code Generation Part II
Intermediate Code Generation Part I
Compiler Construction
Compiler Design 21. Intermediate Code Generation
Review: What is an activation record?
Intermediate Code Generating machine-independent intermediate form.
Presentation transcript:

Subject Name:COMPILER DESIGN Subject Code:10CS63 Prepared By: BESTY HARIS,DEEPA,DHARMALINGAM.K Department:CSE Date:06.04.15 9/22/2018

INTERMEDIATE CODE GENERATION UNIT - 6 INTERMEDIATE CODE GENERATION 9/22/2018

OBJECTIVES Syntax Tree Three address code Translation of expression Control flow Back patching Switch statements

Separating Analysis and Synthesis The front-end generates intermediate code The back-end generates code for target machines Advantages For k languages and n target architectures we need only k+n compilers, instead of k*n Language independent optimizations only once

Three-Address Code Simulates a hypothetical computer For intermediate results temporary variables are created Basic form of statements x := y op z; // result:= operand1 op operand2 x := op y; // for unary operations (e.g. -, !) x := y; // assignment goto L; // jump to statement labeled by L if b goto L // conditional jump if x relop y goto L;

Three-Address Code param x1, x2,…, xn; call Proc, n; Proc(x1, x2,…, xn) → y return y x := y[i]; // The value at y+i assigned to x x[i] := y; // Value of y assigned to x+i x := & y ≡ x := ADR (y) // The address of y assigned to x x := * y ≡ x := y↑ // The value y points at, assigned to x * x : = y ≡ x↑ := y // Value of y assigned to the place // x points at

Three-Address Code - Example Compile: a : = b * -c + b * -c Code for syntax tree t1 := - c t2 := b * t1 t3 := - c t4 : = b * t3 t5 := t2 + t4 a := t5 Code for DAG t5 := t2 + t2

SDD generating 3-A Code for Assignments Production Semantic Rule S → id:= E E → E1 + E2 E → E1 * E2 E → -E1 E → (E1) E → (E) E->id S.code:= E.code || gen(id.place ‘:=‘E.place) E.place := newtemp; E.code:= E1.code || E2.code || gen(E.place ‘:=‘E1.place ‘+’ E2.place) E.place := newtemp; E.code:= E1.code || E2.code || gen(E.place ‘:=‘E1.place ‘*’ E2.place) E.place := newtemp; E.code:= E1.code || gen(E.place ‘:= ‘uminus’ E1.place) E.place := E1.place; E.code:= E1.code E.place := id.place; E.code:= ‘’

SDD generating 3-A Code for While-St. Production Semantic Rule S → while E do S1 S.begin:= newlabel; S.after:= newlabel; S.code:= gen(S.begin ‘:’) || E.code|| gen(‘if’ E.place ‘=‘ 0’ ‘goto’ S.after) || S1.code || gen(‘goto’ S.begin || gen (S.after ‘:’)

Implementation of 3-Addr. Code (1) With a quadruple Operator, argument1, argument2, result Operator Arg1 Arg2 Result Code 0 uminus c t1 t1:= -c 1 * b t1 t2 t2:= b * t1 2 uminus c t3 t3:= -c 3 * b t3 t4 t4:= b * t3 4 + t2 t4 t5 t5:= t2 + t4 5 := t5 a a:= t5

Implementation of 3-Addr. Code (2) With a triple Operator Arg1 Arg2 0 uminus c 1 * b (0) 2 uminus c 3 * b (2) 4 + (1) (3) 5 := a (4)

Static Single-Assignment (SSA) All assignments with different names at the left side Easier to find dependencies Optimization and parallelization gets easier p:= a + b; p1:= a + b; q:= p - c; q1:= p1 - c; p:= q * d; p2:= q1 * d; p:= e - p; p3:= e - p2; q:= p + q; q2:= p3 + q1; In case of two different control flows: Ф(x1, x2) if flag then x:= -1else x:= 1; y:= x * a; → if flag then x1:= -1else x2:= 1; x3:= Ф(x1, x2); y:= x3 * a;

Declarations Memory assignment for variables Offsets relative to a basis (local or global) Scope management •Help functions mktable (previous) Generates a new symbol table, and chains it to the previous one enter (table, name, type, offset) New entry for name in the symbol table (table maybe omitted if obvious) Type and offset will be set addwith (table, width) Stores width (the total length of all variables in the scope) in a descriptor of the actual scope (table) enterproc (table, name, newtable) New entry for a procedure in table, called name newtable points to the symbol table of this procedure

Declarations Type and offset for the declared variables 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 → real {T.type := real; T.width := 8} T → array [ num ] of T1 {T.type := array(num.val, T1.type) T.width:= num.val * T1.width} T → ↑T1 {T.type := pointer(T1.type); T.width := 4} Turning offset into a synthesized attribute P → {offset := 0} D ≡ P → M D M → ε {offset := 0}

Declarations 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 → D1 ; D2 D → proc id ; N D1 ; 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) } Nested records 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) }

Boolean Expressions Two different roles Alter the flow of control Compute logical values Possibilities of compilation Similarly to arithmetic expressions Using numerical values (e.g. 0 for false and 1 for true) By altering the control flow (“jumping” code) Enables lazy evaluation – as many languages need (e.g. Java) Logical expressions E → E || E | E && E | ! E | (E) | E rel E | true | false rel : <, <=, ==, != , >, >= || (or) and && (and) are left associative ! ≻ rel ≻ && ≻ || (≻ for higher precedence)

Numerical Representation - Example a || b && ! c ≡ a || (b && (! c)) ~ (a+b*-c) t1 := ! c t2 := b && t1 t3 := a || t2 a < b Evaluates to 1 if true, to 0 if false 0: if a < b goto 3 1: t:= 0 2: goto 4 3: t:= 1 4: . . . // t = 0 if false, 1 if true

Numerical Representation – Translation scheme E → E1 || E2 {E.place:= newtemp; gen(E.place ‘:=‘E1.place ‘||’ E2.place)} E → E1 && E2 {E.place:= newtemp; gen(E.place ‘:=‘E1.place ‘&&’ E2.place)} E → !E1 {E.place:= newtemp; gen(E.place ‘:=‘ ‘!’ E1.place)} E → E1 rel E2 {E.place:= newtemp; gen(‘if’ E1.place rel E2.place ‘goto’ next+3); gen(E.place ‘:=‘ ‘0’); gen(‘goto’ next+2); gen(E.place ‘:=‘ ‘1’);} E → (E1) {E.place:= E1.place} E → true {E.place:= newtemp; gen(E.place ‘:=‘ ‘1’)} E → false {E.place:= newtemp; gen(E.place ‘:=‘ ‘0’)}

Example a < b || c < d && e < f ≡ (a < b) || ((c < d) && (e < f)) 00: if a < b goto 03 01: t1: = 0 02: goto 04 03: t1 := 1 04: if c < d goto 07 05: t2:= 0 06: goto 08 07: t2:= 1 08: if e < f goto 11 09: t3:= 0 10: goto 12 11: t3:= 1 12: t4:= t2 && t3 13: t5:= t1 || t4 14: . . .

Flow-of-Control Statements (1) Grammar for conditional statements S → if (B) S1 | if (B) S1 else S2 | while (B) S1 Help functions and attributes newlabel - Generates a new label label(L) - Attaches label L to the next 3-addr. stat. E.true The label of the target to spring if E true E.false The label of the target to spring if E false S.next - Inherited attribute Denotes the label pointing at the place after statement S S.code, E.code - contains the code for S resp. E r

Flow-of-Control Statements Production Semantic Rule P → S S.next:= newlabel; P.code:= S.code || label(S.next) S → if (B) S1 B.true:= newlabel; B.false:= S1.next:= S.next; S.code:= B.code || label(B.true) || S1.code || label(S.next) S → if (B) S1 else S2 B.true:= newlabel; B.false:= newlabel; S1.next:= S2.next:= S.next; S.code:= B.code || label(B.true) || S1.code || Gen(‘goto’ S.next) || label(B.false) || S2.code || label(S.next) S → while (B) S1 begin:= newlabel; B.true:= newlabel; B.false:= S.next; S1.next:= begin; S.code:= label(begin) || B.code || label(B.true) || S1.code || gen(‘goto’ begin) || label(S.next)

Control-Flow Transl. of Boolean Expr. Instead of generating numerical values, we jump to the proper place E: a < b if a < b goto E.true goto E.false E: E1 || E2 (E1 or E2 ) if E1 == true, then E == true, otherwise E == E2 E: E1 && E2 (E1 and E2 ) if E1 == false, then E == false, otherwise E == E2 E: !E1 (not E1) We just swap the true and false exits if E and E1

Control-Flow Transl. of Boolean Expr. Production Semantic Rule B → B1 || B2 B1.true:= B.true; B1.false:= newlabel; B2.true:= B.true; B2.false:= B.false; B.code:= B1.code || label(B1.false) || B2.code B → B1 && B2 B1.true:= newlabel; B1.false:= B.false; B.code:= B1.code || label(B1.true) || B2.code B → !B1 B1.true:= B.false; B1.false:= B.true; B.code:= B1.code B → true B.code:= gen(‘goto’ B.true) B → false B.code:= gen(‘goto’ B.false)

Control-Flow Transl. of Boolean Expr. a < b || c < d && e < f if a < b goto Ltrue // Ltrue is set by the environment goto L1 // This jump is redundant L1: if c < d goto L2 // if c >= d goto Lfalse were better goto Lfalse // Lfalse is set by the environment L2: if e < f goto Ltrue // if e >= f goto Lfalse were better goto Lfalse Ltrue resp. Lfalse are the targets if the entire expression evaluates to true resp. false Ltrue and Lfalse are set by the environment Code is suboptimal: redundant jumps Can be reduced by inverting the condition

Inversion of the conditions Number of jumps can be reduced WHILE a < b DO IF c < d THEN x:= y + z ELSE x:= y – z END END (*WHILE*) L1: if a < b goto L2 if a >= b goto Lnext goto Lnext L2: if c < d goto L3 if c >= d goto L4 goto L4 L3: t1:= y + z x:= t1 goto L1 L4: t2:= y – z x:= t2 Lnext: . .

Switch statement Switch (case) statement Efficient with jump-tables If the range is large, the jump-table becomes too big break jumps to S.next break is a bad construction in switch, is o.k. in a loop •Continue in a loop jumps to the start of the iteration switch (E) { 0: S0 …; break; 1: S1 …; break; … n: Sn …; break; } 0: goto 0 1: goto 1 ... n: goto n n+1: Next statement

Backpatching Backpatching While generating forward jumps, target is not known We generate jumps with open target We keep such jumps on a list (e.g. E.truelist, E.falselist) We update the jumps when the target has been reached •Help functions makelist(i) creates new patch-list, pointing at statement-i (i is an index of the code-array) merge(p1,p2): merges two patch-lists backpatch(p,i): sets i as target in all statements of p

Backpatching E → E1 or M E2 | E1 and M E2 | not E1 | (E1) | id1 relop id2 | true | false M → ε truelist resp. falselist contain open targets for the case, the expression evaluates to true resp. to false nextquad points at the next index value M.quad contains the number of the first statement of E2.code {M.quad := nextquad}

Backpatching

Backpatching a < b || c < d && e < f