Code Generation

24
Code Generation CPSC 388 Ellen Walker Hiram College

description

Code Generation. CPSC 388 Ellen Walker Hiram College. Intermediate Representations. Source code Parse tree (or abstract syntax tree) Symbol table Intermediate code Target code. Why Intermediate Code?. Easier analysis for optimization Multiple target machines - PowerPoint PPT Presentation

Transcript of Code Generation

Page 1: Code Generation

Code Generation

CPSC 388 Ellen WalkerHiram College

Page 2: Code Generation

Intermediate Representations

• Source code– Parse tree (or abstract syntax tree)

– Symbol table– Intermediate code

• Target code

Page 3: Code Generation

Why Intermediate Code?

• Easier analysis for optimization

• Multiple target machines• Direct interpretation (e.g. Java P-code)

Page 4: Code Generation

3-Address Code

• Statements like x = y op z• Generous use of temp. variables

– One for each internal node of (abstract) parse tree

• Closely related to arithmetic expression– Example: a = b*(c+d) becomes:tmp1 = c+da = b*tmp1

Page 5: Code Generation

Beyond Math Operations

• No standardized 3 address code• Other operators in textbook

– Comparison operators (e.g. x = y == z)

– I/O (read x and write x)– Conditional & unconditional branch operators (if_true x goto L1, goto L2)

– Label instructions (label L1)– Halt instruction (halt)

Page 6: Code Generation

Representing 3-address code

• Quadruple implementation– 4 fields: (op,y,z,x) for x=y op z– Fields are null if not needed, e.g. (rd,x,,)

– Instead of names, put pointers into symbol table

• Triple implementation– 4th element is always a temp– Don’t name temp, use triple index instead

Page 7: Code Generation

Example: a = b+(c*d)

• [quadruple] [triple]• (rd,c,_,_) 1: (rd,c,_)• (rd,d,_,_) 2: (rd,d,_)• (mul,c,d,t1) 3: (mul,c,d)• (rd,b,_,_) 4: (rd,b,_)• (add,b,t1,t2) 5: (add,b,3)• (asn,a,t2,_) 6: (asn,a,5)

Page 8: Code Generation

P-Code

• Developed for Pascal compilers• Code for hypothetical P-machine• P-machine is a stack (0-address) machine [Load inst. takes 1-address]– Load = push, Store = pop– Operators act on top element(s) of stack

– No temp. variable names needed

Page 9: Code Generation

P-Code operators

LDC x - load const. xLDA x - load addr. xLOD x - load var. xSTO - store val in addr

STN - store & pushMPI - multiply integers

SBI - subtract integers

ADI - add integers

RDI -read intWRI - write intLAB - labelFJP - jump on false

GRT - >EQU - =STP - stop

Page 10: Code Generation

Example: a = b+(c*d)

• LDA a• LOD d• LOD c• MPI• LOD b• ADI• STO

Page 11: Code Generation

P-Code as attribute

• Include code (so far) as attribute in attribute grammar– exp -> id = exp

•$$.code = LDA $1.name; $3.code; STN

– aexp -> aexp+factor•$$.code = $1.code;$3.code;ADI

– factor -> id•$$.code = LOD $1.name

Page 12: Code Generation

Generating 3 address code

• Need a meta-function to generate temp names (newtemp())– exp -> id = exp

•$$.code = $3.code; “$1.name = $3.name”

– aexp -> aexp+factor•$$.name = newtemp()•$$.code = “$1.code;$3.code;$$.name=$1.name+$3.name”

Page 13: Code Generation

Why real compilers don’t do this

• Generating strings is inefficient– Lots of copying– Code, when generated, isn’t saved; just copied around until done

– Code generation depends on inherited (not just synthesized) attributes•E.g. object type for assignment•This complicates grammars!

Page 14: Code Generation

Practical code generation

• Modified postorder traversal of syntax tree

• Remember postorder:– Act on the children recursively– Act on the parent directly

• In this case, the action is “generate code”

Page 15: Code Generation

Code Generation

Gen_code(node *n){switch(n->op){case ‘+’:gen_code(n->first);gen_code(n->first->next);cout << “ADI”;break;

Page 16: Code Generation

More Code Generation

case ‘=’:cout << “LDA “ << t-

>name;Gen_code(t->first);cout << “STN”);break;

…}

Page 17: Code Generation

Nothing new!

• Postorder traversal executes in the same order as LALR parsing!

• Code for code generation looks almost like the attribute grammar– $n.code --> Generate_code(child N);

– $$.attr --> n->attr; (where n is param)

Page 18: Code Generation

Code Gen in YACC

• Looks like attribute grammar, almost

• Use code inside expression for assignmentExp : id {//generate lda code} ‘=‘ exp {generate rest}

• Can we combine code generation with other attribute computation?

Page 19: Code Generation

Intermediate -> Target Code

• Macro expansion– Direct replacement of intermediate statement with target statement(s)

– Prepend a definition file to the code, then assemble

– But it’s not as easy as it seems•Different data types require different code

•Compiler tracks locations, etc. separately

Page 20: Code Generation

Intermediate -> Target Code (cont)

• Static simulation– Simulate results of intermediate code (i.e. interpret it)

– Then generate equivalent assembly code to get results

– Might include abstract interpretation (e.g. symbolic algebra)

Page 21: Code Generation

P-code -> 3 address code

• We must “run” the p-code to see what is on the stack for the 3 address code

• Use a stack data structure during translation– “new top” = “old top” + “old second”– New temp. for “new top”– Temp or variable names stored in stack elements

• Code is generated when stack is popped (only)

Page 22: Code Generation

3 address code -> pcode

• Each instruction a = b op c translates to:– LDA a– LOD b– LOD c– ADI -- or other operator based on “op”

– STO

Page 23: Code Generation

Too much Pcode!

• 3 address code has many temps• Temps are simply loaded & stored without changing!

• Sequence “lda x, lod x, sto” is useless!

• Similarly, “lda x, lda t1, … sto, sto” doesn’t really need t1

Page 24: Code Generation

Cleaning it up

• Instead, use a tree form– Parent is op, has label of variable name– Children are id, num, or another op

• Assignment statements generate no code, only an alternative label

• Pcode generated from the eventual tree (which is essentially an expression tree)– Extra tmp names are ignored (p. 416)