1 / 38

Code Generation

Code Generation. Professor Yihjia Tsai Tamkang University. Outline. Introduction Run-time Storage Management Basic Blocks Flow Graphs Liveness Analysis Student Presentations. Introduction. Requirements of a code generator Code generated must be correct

Download Presentation

Code Generation

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Code Generation Professor Yihjia Tsai Tamkang University

  2. Outline • Introduction • Run-time Storage Management • Basic Blocks • Flow Graphs • Liveness Analysis • Student Presentations

  3. Introduction • Requirements of a code generator • Code generated must be correct • Code generated must be high quality (which uses resources effectively on target machine) • Code must have very low cost (where cost is execution time or code size etc.,…) • Code generator itself must be efficient

  4. Code Generation: Overview • Identify program segments in IR as a dag • Partition the dag into a set of disjoint trees • Machine instructions are (tree) patterns • Each pattern has a cost • Selection of machine instructions means covering (or tiling) each tree of the dag by patterns • So that total cost is the lowest (or very low)

  5. Issues to Consider • What is the input (form of IR)? • May assume input is error-free • What is the target? • Machine, absolute/relocatable/assembly • Memory mgmt. • Names in IR become memory addresses • Instruction selection • Register allocation

  6. Run-time Storage Mgmt. • How to manage activation records? • Static allocation • Position of activation record fixed at compile time • Stack allocation • New activation record pushed onto stack at each invocation of a function • Record popped when activation ends

  7. Static Allocation • A “call” statement in IR implemented by a sequence of 2 target-code instructions • MOV (save return addr in callee activation record ) and a GOTO (to callee code) • Return from callee implemented by GOTO (to location pointed by callee activation record) • Example (E.g. 9.1, p. 523, Dragon book) • Assume “action” instruction takes 20 bytes

  8. Example Activation record for c (64 bytes) 0: return addr • Input: 3AC // code for c action call p action halt // code for p action return 60: j Activation record for p (88 bytes) 0: return addr 84: n

  9. Example …contd // code for c 100: action // c’s activation record 120: MOV #140, 364 300: ….. 132: GOTO 200 304: ….. 140: action ……. 160: halt 360: …. // p’s activation record //code for p 364: … 200: action 368: … 220: GOTO *364 ……. 448: …

  10. Stack Allocation • Uses relative addresses for storage in activation records • Positions not known until run-time • Relative addresses taken as offsets from a known position (e.g., SP register) • Function call: caller increments SP, saves return addr and transfers control to callee • Return: callee transfers control back, caller restores SP

  11. Example // code for s action call q action halt // code for p action return // code for q action call p action call q action call q return Input: 3AC How can we generate code with stack allocation? (Assume: stack grows upwards)

  12. Example …contd // code for s 100: MOV #600, SP 108: action 128: ADD #ssize, SP 136: MOV #152, *SP 144: GOTO 300 152: SUB #ssize, SP 160: action 180: halt // code for p 200: action 220: GOTO *0(SP) // stack starts here 600: #ssize, #qsize : sizes of activation records for s, q

  13. Example …contd // code for q 300: action 320: ADD #qsize, SP 328: MOV #344, *SP 336: GOTO 200 344: SUB #qsize, SP 352: action 372: ADD #qsize, SP 380: MOV #396, *SP 388: GOTO 300 396: SUB #qsize, SP 404: action … // code for p 200: action 220: GOTO *0(SP) // stack starts here 600:

  14. Basic Blocks • A basic block is a sequence of consecutive statements in which flow of control: • Enters at the beginning • Leaves at the end • (no halt or branch except at the end) • Ignore calculations and storage operations • Can lump together non-branch instructions

  15. Algorithm to Obtain Basic Blocks • Input: a program of 3AC statements • Output: a list of basic blocks (each 3AC statement in exactly one basic block) • Determine the set of leaders, i.e., 1st stmts • The 1st stmt of the program is a leader • A target stmt of a GOTO is a leader • A stmt immediately following a GOTO is a leader • For each leader, its basic block ends before next basic block or at the end of program

  16. Exercise • Given the following code segment, obtain: • The 3AC statements for this computation • The list of basic blocks by applying the algorithm to the 3AC prod = 0; i = 1; do { prod = prod + a[i] * b[i]; i = i + 1; } while ( i <= 20 );

  17. Flow Graphs • A directed graph representing a program • Also called control-flow graph • Nodes in the graph represent computation • Each statement (or basic block) is a node • One node is distinguished as initial • Directed edges represent flow of control • There is an edge from node n1 to node n2 if n2 can immediately follow n1 in execution

  18. Flow Graphs …contd • Edge from n1 to n2 exists if: • There is a GOTO from (the last stmt of) n1 to (the 1st stmt of) n2 • n2 immediately follows n1 in the sequence of the program and n1 does not end with GOTO • Here, we say: • n1 a predecessor of n2, n2 a successor of n1 • Example : for code in slide 9-16

  19. Exercise • Draw the flow graph for the following code segment (may consider a stmt as a node) a ← 0 L1: b ← a + 1 c ← c + b a ← b * 2 if a < N goto L1 return c

  20. Liveness Analysis • An example application • IR code (say 3AC) may have large # of temps and program vars • But we have limited # of registers • Need to know which temps/vars are in use at the same time (for efficient use of registers) • A variable is live if it holds a value needed in the future • This analysis is called liveness analysis

  21. Liveness Analysis …contd • Within a basic block context • A var is live at a given point if its value is used after that point (maybe in another basic block) • A var is dead if it is never used later • Liveness analysis is done using a flow graph in which each stmt is a node • We analyze liveness by going backward in a basic block starting from the end

  22. Example 1)a ← 0 2) L1: b ← a + 1 3) c ← c + b 4) a ← b * 2 5) if a < N goto L1 6) return c • Live range of b:{34, 23}, a: {12, 452}, c:{12…6} • Vars a and b can share one register

  23. Liveness Analysis …contd • Next-use info collected in this analysis • Can be used in different situations • Register assignment, temp’s in stack frame • “Use” of a var/name • Suppose stmt i is “x := k”; stmt j has x as an operand; control can flow from i to j with no intervening stmt assigning a value to x • We say stmt jusesvalue of x computed at i

  24. Liveness Analysis …contd • At a stmt k: “x := y <op> z”, check symbol table and update info as follows • Attach to stmt k, current info in symbol table on status (live/dead) & next use for x, y and z • In symbol table, set x to dead and no next use • In symbol table, set y, z to live and their next uses to k • Steps 2 and 3 must be in that order! (because we may have “x := x <op> y”

  25. Example • Suppose we have: “d = (a+b) * (c-b);” • Suppose the 3AC for this is in a basic block as: (1) u := a + b (2) v := c – b (3) w := u * v (4) d := w • Show how the liveness analysis proceeds

  26. Example (1) u := a + b (2) v := c – b (3) w := u * v (4) d := w • At the end of block, in the symbol table • Program vars a, b, c, d are marked “live” • Temp vars u, v, w marked “dead” • All vars marked “no next use”

  27. Symbol Table (at start)

  28. While at line (4): Attached Info

  29. Symbol Table [after line (4)]

  30. While at line (3): Attached Info

  31. Symbol Table [after line (3)]

  32. At the end: Attached Info This info used later during code generation

  33. Dataflow Problems • Liveness of variables flows along edges of flow graps • Determining the live range of each var is an example of a dataflow problem • Other examples • Estimate values of a var at a given point • Finding available expressions and deleting duplicates • Reaching expressions analysis

  34. Storage for Temp’s • Temporary names are generated by the compiler during compilation (e.g., in 3AC) • Temp’s can be held in activation records • But with many temp’s, storage requirement can be large • But we may be able to pack 2 temp’s in the same location if they are not live simultaneously • Next-use info within basic blocks can be used

  35. Transformations on Basic Blocks • A basic block computes a set of expressions that are live on exit from block • Many transformations possible within a block without changing these expressions • Local optimizations • Improve the target code for the block

  36. Example Transformations • Common sub-expression elimination • Dead-code elimination • Suppose x is dead (never used subsequently) at the point of stmt “x = y + z;” in a basic block • Then this stmt can be safely removed

  37. Example Transformations …contd • Constant folding • Sub-expressions whose operands are constants can be replaced by the values at compile-time • Copy propagation • If we have “x = y;” followed later by a use of x as an operand, we may substitute y for x; the copy stmt may become useless code

  38. Example Transformations …contd • Reduction in strength • Replacing expensive operations by cheaper ones • E.g., replace multiplication by two by shifting • Renaming temp variables • Interchange of statements

More Related