07. intermediate code generation

Upload: sridharanc23

Post on 03-Apr-2018

245 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/28/2019 07. Intermediate Code Generation

    1/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 1

    Compilers

    7. Intermediate Code Generation

  • 7/28/2019 07. Intermediate Code Generation

    2/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 2

    Separating Analysis and Synthesis

    The front-end generates intermediate code

    The back-end generates code for target machines

    Advantages

    StaticChecker IntermediateCode Generator Code GeneratorParserScanner

    Optimizer

    For k languages and n target

    architectures we need onlyk+n compilers, instead of k*n

    Language independentoptimizations only once

    L1

    L2

    Lk

    M1

    M2

    Mn

    Interm.Code

  • 7/28/2019 07. Intermediate Code Generation

    3/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 3

    Three-Address Code (1)

    Simulates a hypothetical computer

    For intermediate results temporary variables are created

    Basic form of statements

    x := y op z; // resul:= 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;

  • 7/28/2019 07. Intermediate Code Generation

    4/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 4

    Three-Address Code (2)

    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

  • 7/28/2019 07. Intermediate Code Generation

    5/31Laszlo Bszrmenyi Compilers Intermediate Code - 5

    Three-Address Code - Example

    Compile: a : = b * -c + b * -cCode for syntax tree

    t1 := - c

    t2 := b * t1

    t3 := - c

    t4 : = b * t3

    t5 := t2 + t4a := t5

    Code for DAG

    t1 := - c

    t2 := b * t1t5 := t2 + t2

    a := t5

  • 7/28/2019 07. Intermediate Code Generation

    6/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 6

    SDD generating 3-A Code for Assignments

    Production Semantic Rule

    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 := uminusE1.place)

    E (E1) E.place := E1.place; E.code:= E1.code

    E id E.place :=id.place; E.code:=

    concatenation(not or)!concatenation(not or)!

  • 7/28/2019 07. Intermediate Code Generation

    7/31

  • 7/28/2019 07. Intermediate Code Generation

    8/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 8

    Implementation of 3-Addr. Code (1)

    With a quadrupel

    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 + t45 := t5 a a:= t5

  • 7/28/2019 07. Intermediate Code Generation

    9/31

  • 7/28/2019 07. Intermediate Code Generation

    10/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 10

    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

    )

    ifflag then x:= -1else x:= 1; y:= x * a;

    ifflag then x1:= -1else x2:= 1; x3:=(x1, x2); y:= x3 * a;

    Swapallowed?Swapallowed?

    Swapallowed?Swapallowed?

  • 7/28/2019 07. Intermediate Code Generation

    11/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 11

    Declarations (1)

    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

  • 7/28/2019 07. Intermediate Code Generation

    12/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 12

    Declarations (2)

    Type and offset for the declared variablesP {offset := 0} D

    D D; D

    Did : 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 ] ofT1 {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 attributeP {offset := 0}D

    P M D

    M e{offset := 0}

  • 7/28/2019 07. Intermediate Code Generation

    13/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 13

    Declarations (3)

    Nested proceduresP M D {addwidth(top(tblptr), top(offset));

    pop(tblptr); pop(offset) }

    Me {t := mktable(nil); push(t, tblptr); push(0, offset) }

    D D1 ; D2

    Dproc id ; N D1 ; S {t := top(tblptr); addwidth(t, top(offset));

    pop(tblptr); pop(offset); enterproc(top(tblptr), id.name, t) }Did: T {enter(top(tblptr), id.name, T.type, top(offset));

    top(offset) := top(offset) + T.width }

    Ne {t := mktable(top(tblptr)); push(t, tblptr); push(0, offset) }

    Nested recordsT record L D end {T.type := record(top(tblptr));

    T.width := top(offset); pop(tblptr); pop(offset) }

    Le {t := mktable(nil); push(t, tblptr); push(0, offset) }

  • 7/28/2019 07. Intermediate Code Generation

    14/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 14

    Array-Addressing

    1 dimensional arrays (ARRAY [n] OF T)Array limits: [0.. n-1]; w: T.widthComputing address of A [i]

    base + i * w (base is relative address of A[0])

    2 dimensional arrays (ARRAY [n1, n2] OF T)

    n1 lines, width w1 (w1=n2*w); n2 columns, width w2 (w2=w)A [i1, i2] (must be mapped to the 1-dimensional memory)

    base + i1 * w1 + i2* w2 base + (i1 * n2+ i2 )* w

    Many dimensional arrays (ARRAY [n1, nk] OF T)

    A [i1, i2 , , ik]base + i1 * w1 + i2* w2 + + ik * wk

    base + ((... (( i1 * n2 + i2) * n3 + i3) ... ) * nk + ik) * w

  • 7/28/2019 07. Intermediate Code Generation

    15/31

  • 7/28/2019 07. Intermediate Code Generation

    16/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 16

    t1 = i * 12 //w1 = 3*4

    t2 = j * 4 //w2 = 4t3 = t1 + t2

    t4 = a [t3]

    t5 = c + t4

    3-addr. code

    Array References - Example

    E.addr = t5

    E.addr = cE.addr = t4

    L.type = intL.addr = t3

    L.array = a

    L.type = array(3, int)L.addr = t1

    L.array = a

    E.addr = j

    a.type = array( 2,array(3, int))

    E.addr = i

    [ ]

    +

    [ ]

    i

    c

    j

    Annotated

    parse tree

    VAR c: INTEGER;

    a: ARRAY [2, 3] OF INTEGER;

    BEGIN c + a[i, j]

  • 7/28/2019 07. Intermediate Code Generation

    17/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 17

    Boolean Expressions

    Two different roles

    1. Alter the flow of control2. 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. J ava)

    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)

  • 7/28/2019 07. Intermediate Code Generation

    18/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 18

    Numerical Representation - Example

    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

  • 7/28/2019 07. Intermediate Code Generation

    19/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 19

    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

    E1rel

    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)}

  • 7/28/2019 07. Intermediate Code Generation

    20/31

  • 7/28/2019 07. Intermediate Code Generation

    21/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 21

    Flow-of-Control Statements (1)

    Grammar for conditional statements

    S if(B) S1 | if(B) S1else S2 | while (B) S1

    Help functions and attributesnewlabel - 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

  • 7/28/2019 07. Intermediate Code Generation

    22/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 22

    Flow-of-Control Statements (2)

    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) S1begin:= 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)

    B.code

    S1.code

    S2.code

    goto S.next

    B.true

    B.false

    S.next

    B.code

    S1.code

    goto begin

    B.true

    B.false

    begin

    B.code

    S1.codeB.true

    B.false

    B.tB.f

    B.tB.f

  • 7/28/2019 07. Intermediate Code Generation

    23/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 23

    Control-Flow Transl. of Boolean Expr. (1)

    Instead of generating numerical values, we jump

    to the proper placeE: a < b

    if a < b goto E.true

    goto E.false

    E: E1 || E2 (E1orE2 )if E1 ==true, then E ==true, otherwise E == E2

    E: E1 && E2 (E1and 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

  • 7/28/2019 07. Intermediate Code Generation

    24/31

  • 7/28/2019 07. Intermediate Code Generation

    25/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 25

    Control-Flow Transl. of Boolean Expr. (3)

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

    if a < b goto Ltruegoto L1 // This jump is redundant

    L1: if c < d goto L2 // if c >= d goto Lfalse were better

    goto Lfalse

    L2: if e < f goto Ltrue // if e >= f goto Lfalse were bettergoto Lfalse

    Ltrue resp. Lfalse are the targets if the entireexpression 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

  • 7/28/2019 07. Intermediate Code Generation

    26/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 26

    Inversion of the conditions

    Number of jumps can be reduced

    WHILE a < b DOIF c < d THEN x:= y + z ELSE x:= y z ENDEND (*WHILE*)

    L1: if a < b goto L2 if a >= b goto Lnextgoto Lnext

    L2: if c < d goto L3 if c >= d goto L4goto L4

    L3: t1:= y + zx:= t1goto L1

    L4: t2:= y z

    x:= t2goto L1

    Lnext: . . .

  • 7/28/2019 07. Intermediate Code Generation

    27/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 27

    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 iterationswitch (E) {

    0: S0 ; break;

    1: S1 ; break;

    n: Sn ; break;

    }

    0: goto 0

    1: goto 1

    ...

    n: goto n

    n+1: Next statement

  • 7/28/2019 07. Intermediate Code Generation

    28/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 28

    Backpatching (1)

    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

  • 7/28/2019 07. Intermediate Code Generation

    29/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 29

    Backpatching (2)

    E E1 orM E2 |

    E1 and M E2 |not E1 |

    (E1) |

    id1relopid2 |

    true |

    false

    Me

    truelist resp. falselist contain open targets for the case, the expressionevaluates to true resp. to false

    nextquad points at the next index value

    M.quad contains the number of the first statement ofE2.code {M.quad := nextquad}

  • 7/28/2019 07. Intermediate Code Generation

    30/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 30

    Backpatching (3)

  • 7/28/2019 07. Intermediate Code Generation

    31/31

    Laszlo Bszrmenyi Compilers Intermediate Code - 31

    Backpatching (4)

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