CS 515 Programming Language and Compilers I Lecture 1: Compiler Backend (The lectures are based on the slides copyrighted by Keith Cooper and Linda Torczon from Rice University.) Zheng (Eddy) Zhang Rutgers University Fall 017, 1/1/017
Review: Compiler Middle End (Optimizer) Front End IR Middle End IR Back End Machine code Errors Front End works from the syntax of the source code Middle End works from intermediate representation (IR) Analyzes IR to learn about the code Transforms IR to improve final code s 1. Parallelization. Redundancy elimination 3. Data flow analysis (DFA) framework. Single static assignment (SSA)
3 Compiler Back End Source code Front End IR Middle End IR Back End Machine code Errors Back End converts intermediate representation (IR) into machine code 1. Instruction Selection: IR > Assembly code (ASM) assuming registers. Instruction Scheduling: Assembly (ASM) > Reordered assembly (ASM) 3. Register Allocation: Assembly assuming registers > Assembly assuming finite registers
Input to Back End Source code Front End IR Middle End IR Back End Machine code Errors Back End deals with either linear IR or treelike IR Encode information: Branches, memory tags, hierarchy of memory operations, and etc. s: clang is RISC like, gcc is a lower level, linear IR. Assumptions: Enough register names Order of operations & flow of values
5 Compiler Back End Instruction Selection Mapping IR into assembly code Assumes a fixed storage mapping & code shape Combining operations, using address modes Instruction Scheduling Reordering operations to hide latencies Assumes a fixed choice of operations Changes demand for registers Register Allocation Deciding which values will reside in registers Assumes a fixed order of existing operations Changes name space; may add false sharing
6 Compiler Back End Instruction Selection Mapping IR into assembly code Assumes a fixed storage mapping & code shape Combining operations, using address modes Instruction Scheduling Reordering operations to hide latencies Assumes a fixed choice of operations Changes demand for registers Register Allocation Deciding which values will reside in registers Assumes a fixed order of existing operations Changes name space; may add false sharing
7 The Fundamental Problem Consider the registertoregister copy operation Using ILOC (an RISClike intermediate representation in EAC) An obvious implementation: ii ra rb Other potential implementations (algebraic identify) addi r a,0 Þ r b subi r a,0 Þ r b lshifti r a,0 Þ r b multi r a,1 Þ r b divi r a,1 Þ r b rshifti r a,0 Þ r b ori r a,0 Þ r b xori r a,0 Þ r b and others
8 Instruction Selection Modeled as A Pattern Matching Method Must produce good code What is good code? Must run quickly Tree Naive Code Desired Code x loadi r5 loadao r0, r5 r6 loadai r0, r5 IDENT <a, r0, > IDENT <b, r0, 8> loadi 8 r7 loadao r0,r7 r8 loadai r0, 8 r6 mult r5, r6 r7 mult r6, r8 r9
9 Instruction Selection Modeled as A Pattern Matching Method Must produce good code What is good code? Must run quickly Tree Naive Code Desired Code x loadi r5 loadao r0, r5 r6 loadai r0, r5 IDENT <a, r0, > BER <> loadi r7 mult r6, r7 r8 multi r5, r7
10 Instruction Selection Modeled as A Pattern Matching Method Must produce good code What is good code? Must run quickly Tree Naive Code Desired Code x loadi r5 loadao r0, r5 r6 loadai r0, r5 IDENT <a, r0, > BER <> loadi r7 mult r6, r7 r8 add r5, r5 r7
11 Instruction Selection Modeled as A Pattern Matching Method Must produce good code What is good code? Must run quickly Tree Naive Code Desired Code IDENT <c,, > x IDENT <d, @H, > loadi r5 loadi r6 loadao r5, r6 r7 loadi @H r8 loadi r9 loadi r5 loadai r5, r6 loadai r5, @H r7 mult r6, r7 r8 common offset loadao r8, r9 r10 mult r7, r10 r11
1 Tree Pattern Matching Tree Patterns and LowLevel AST as Input Match treepatterns against a lowlevel AST tree Each pattern maps to a sequence of targetmachine ops a code template Each pattern is associated with a cost Tree Pattern x Template shows how to implement the subtree Cost is used to drive process to lowcost code sequences IDENT <a, r0, > BER <>
13 Lowlevel Abstract Syntax Tree (AST) for w x y w: at x: its reference at 6 y: at 1 : in a register : a constant : label 6 1
1 Tree Pattern Matching Goal is to tile the lowlevel AST Each tile corresponds to a tree pattern (also a sequence of operations) 6 1
15 Tiling Definition A tiling is a collection of <node, op> pairs node is a node in the AST op is a tree pattern op also represents a sequence of operations (a code template) A tiling implements an AST if it covers every node in the AST: <node, op> tiling the over lap between any two trees occurs at most at one node when two tree patterns overlap, they must be compatible
16 Prefix Notation A concise notation to describe the machine operations Tree Tree (r, c) (c, r) r c c r Describes both linear code IR and tree IR
17 Tile the Tree Specify a mapping from AST to operations Provide a set of rewrite rules that describe the AST Encode tree syntax, in linear prefix form Each rule also has a code template and a cost
18 Building a rule for load Tree ILOC Rule Reg load ri rj Regi (Regj)
19 Building a rule for loadai (load address immediate) Tree ILOC Rule loadai ri, cj rk Regk ((Regi, j)) Reg
0 Building a rule for loadao (load address offset) Tree ILOC Rule loadao ri, rj rk Regk ((Regi, Regj)) Reg Reg
1 The Simplification Step Each rule implements one operator A complex operation is broken into multiple single operator rules Reg ( (Reg1,)), cost: 1 (rule for loadai) Reg (T1), cost: 1 T1 (Reg1,), cost: 0 } Total cost is still 1 Use a unique LHS or class or type to tie them together
Rewrite Rules Rule Cost Template 0 Goal Goal Stmt 0 1 Goal Stmt 0 Stmt (Reg1, Reg) 1 store r r1 3 Stmt (T1, Reg3) 1 storeao r3 T1.r1, T1.r Stmt (T, Reg3) 1 storeai r3 T.r1, T.n 5 Reg 1 1 loadi l1 rnew 6 Reg 1 0 7 Reg 1 1 loadi n1 rnew 8 Reg (Reg1) 1 load r1 rnew 9 Reg (T1) 1 loadao T1.r1, T1.r rnew 10 Reg (T) 1 loadai T.r1, T.n rnew 11 Reg (Reg1,Reg) 1 add r1, r rnew 1 Reg (Reg1,T3) 1 addi r1, n rnew 13 Reg (T31,Reg) 1 addi r, n1 rnew 1 Reg (Reg1,Reg) 1 sub r1, r rnew 15 Reg (Reg1,T3) 1 subi r1, n rnew 16 Reg (T31,Reg) 1 subi r, n1 rnew 17 Reg (Reg1,Reg) 1 mult r1, r rnew 18 Reg (Reg1,T3) 1 multi r1, n rnew 19 Reg (T31,Reg) 1 multi r, n1 rnew 0 T1 (Reg1,Reg) 0 // reg reg for loadao 1 T (Reg1, T3) 0 // reg con for loadai T (T3, Reg1) 0 // con reg for loadai 3 T3 1 0 // con for immed arith ops
3 Tile the Tree Tile(n) for each class c, Label(n,c) Ø if n has two children then Tile (IR left child(n)) Tile (IR right child(n)) for each rule r that implements n if (Label(IR left child(n),left(r)) Ø ) and (Label(IR right child(n),right(r)) Ø ) then Label(n, lhs(r)) Label(n,lhs(r)) U { r } else if n has one child Tile(IR child of n) for each rule r that implements n if (Label(IR child(n),rhs(r)) Ø) then Label(n,lhs(r)) Label(n,lhs(r)) U { r } else / n is a leaf / Label(n,) { all rules that implement n } class corresponds to the lhs of a rule Label(node, class) is an array of rule numbers IR left child(n) & IR right child(n) are functions to navigate the IR tree lhs(r), left(r), & right(r) return symbols in rule r. If r has children, then left & right must be classes. left(r) and right(r) navigate the pattern tree. Similar navigation primitives for unary nodes (child rather than left child) and the rules (rhs rather than left & right).
Tile the Tree Tile(n) for each class c, Label(n,c) Ø if n has two children then Tile (IR left child(n)) Tile (IR right child(n)) for each rule r that implements n if (Label(IR left child(n),left(r)) Ø ) and (Label(IR right child(n),right(r)) Ø ) then Label(n, lhs(r)) Label(n,lhs(r)) U { r } else if n has one child Tile(IR child of n) for each rule r that implements n if (Label(IR child(n),rhs(r)) Ø) then Label(n,lhs(r)) Label(n,lhs(r)) U { r } else / n is a leaf / Label(n,) { all rules that implement n } class corresponds to the lhs of a rule. class = Goal, or class = Reg, or Rule 0 Goal Goal Stmt 1 Goal Stmt Stmt (Reg1, Reg) 3 Stmt (T1, Reg 3 ) Stmt (T, Reg 3 ) 5 Reg 1 6 Reg 1 7 Reg 1
5 Tile the Tree Tile(n) for each class c, Label(n,c) Ø if n has two children then Tile (IR left child(n)) Tile (IR right child(n)) for each rule r that implements n if (Label(IR left child(n), left(r)) Ø ) and (Label(IR right child(n), right(r)) Ø ) then Label(n, lhs(r)) Label(n, lhs(r)) U { r } else if n has one child Tile(IR child of n) for each rule r that implements n if (Label(IR child(n),rhs(r)) Ø) then Label(n,lhs(r)) Label(n,lhs(r)) U { r } else / n is a leaf / Label(n,) { all rules that implement n } class corresponds to the lhs of a rule. : class = Goal, or class = Reg, or Label(node, class) is an array of rule numbers : Label(nodeA, Reg) = {6} nodea: nodeb: Rule 0 Goal Goal Stmt. 6 Reg 1
6 Step by step rewriting Stmt T1 T T3 Reg 1 3 7 3 0 1 11, 1 6 5 3 7 6 0 1 11, 1 9 3 7 11 3 7 1 0 1 11, 1 6 1 1 17, 19 15 1 16, 3,
7 Step by step rewriting Stmt T1 T T3 Reg 1 1 3 7 3 0 1 11, 1 Rule 0 Goal Goal Stmt 1 Goal Stmt Stmt (Reg1, 3 Stmt (T1, Stmt (T, 5 Reg 1 6 Reg 1 7 Reg 1 6 5 3 7 6 0 1 11, 1 9 3 7 11 3 7 1 0 1 11, 1 6 1 1 17, 19 15 1 16, 3,
8 Step by step rewriting Stmt T1 T T3 Reg 1 6 1 3 7 3 0 1 11, 1 Rule 0 Goal Goal Stmt 1 Goal Stmt Stmt (Reg1, 3 Stmt (T1, Stmt (T, 5 Reg 1 6 Reg 1 7 Reg 1 6 5 3 7 6 0 1 11, 1 9 3 7 11 3 7 1 0 1 11, 1 6 1 1 17, 19 15 1 16, 3,
9 Step by step rewriting Stmt T1 T T3 Reg 1 6 3 0 1 11, 1 Rule 0 Goal Goal Stmt 1 Goal Stmt Stmt (Reg1, 3 Stmt (T1, Stmt (T, 5 Reg 1 6 Reg 1 7 Reg 1 6 5 3 7 6 0 1 11, 1 9 3 7 11 3 7 1 0 1 11, 1 6 1 1 17, 19 3 T3 1 15 1 // constant for immed arith ops 16, 3,
30 Step by step rewriting Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 Rule 0 Goal Goal Stmt 1 Goal Stmt Stmt (Reg1, 3 Stmt (T1, Stmt (T, 5 Reg 1 6 Reg 1 7 Reg 1 6 5 3 7 6 0 1 11, 1 9 3 7 11 3 7 1 0 1 11, 1 6 1 1 17, 19 3 T3 1 15 1 // constant for immed arith ops 16, 3,
31 Step by step rewriting Stmt T1 T T3 Reg 1 6 3 3 7 3 6 5 3 7 1 {Reg} {T3, Reg} 6 1 6 0 1 11, 1 1 Goal Goal Stmt 11 Reg (Reg 1,Reg ) 9 3 7 1 Reg (Reg 1,T3 ) 11 3 7 1 0 1 11, 1 0 T1 (Reg 1,Reg ) 1 T (Reg 1, T3) 1 17, 19 15 1 16, 3,
3 Step by step rewriting Stmt T1 T T3 Reg 1 6 3 3 7 3 11, 1 6 5 3 7 1 {Reg} {T3, Reg} 6 1 6 0 1 11, 1 1 Goal Goal Stmt 11 Reg (Reg 1,Reg ) 9 3 7 1 Reg (Reg 1,T3 ) 11 3 7 1 0 1 11, 1 0 T1 (Reg 1,Reg ) 1 T (Reg 1, T3) 1 17, 19 15 1 16, 3,
33 Step by step rewriting Stmt T1 T T3 Reg 1 6 3 3 7 3 0 1 11, 1 6 5 3 7 1 {Reg} {T3, Reg} 6 1 6 0 1 11, 1 1 Goal Goal Stmt 11 Reg (Reg 1,Reg ) 9 3 7 1 Reg (Reg 1,T3 ) 11 3 7 1 0 1 11, 1 0 T1 (Reg 1,Reg ) 1 T (Reg 1, T3) 1 17, 19 15 1 16, 3,
3 Step by step rewriting Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 6 5 3 7 6 0 1 11, 1 9 3 7 11 3 7 1 0 1 11, 1 6 1 1 17, 19 15 1 16, 3,
35 Step by step rewriting Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 6 5 3 7 6 0 1 11, 1 9 3 7 11 3 7 1 0 1 11, 1 5 6 1 1 17, 19 15 1 16, 3,
36 Step by step rewriting Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 6 5 3 7 6 0 1 11, 1 6 9 3 7 11 3 7 1 0 1 11, 1 6 1 1 17, 19 15 1 16, 3,
37 Step by step rewriting Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 6 5 3 7 6 0 1 11, 1 7 9 3 7 11 3 7 1 0 1 11, 1 6 1 1 17, 19 15 1 16, 3,
38 Step by step rewriting Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 6 5 3 7 8 6 0 1 11, 1 9 3 7 11 3 7 1 0 1 11, 1 6 1 1 17, 19 15 1 16, 3,
39 Step by step rewriting Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 6 5 3 7 6 0 1 11, 1 9 9 3 7 11 3 7 1 0 1 11, 1 6 1 1 17, 19 15 1 16, 3,
0 Step by step rewriting Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 6 5 3 7 6 0 1 11, 1 9 3 7 11 3 7 1 0 1 11, 1 6 10 1 1 17, 19 15 1 16, 3,
1 Step by step rewriting Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 6 5 3 7 6 0 1 11, 1 6 1 11 9 3 7 11 3 7 1 0 1 11, 1 1 17, 19 15 1 16, 3,
Step by step rewriting Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 6 5 3 7 6 0 1 11, 1 1 9 3 7 11 3 7 1 0 1 11, 1 6 1 1 17, 19 15 1 16, 3,
3 Step by step rewriting Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 6 5 3 7 6 0 1 11, 1 13 9 3 7 11 3 7 1 0 1 11, 1 6 1 1 17, 19 15 1 16, 3,
Step by step rewriting Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 6 5 3 7 1 6 0 1 11, 1 9 3 7 11 3 7 1 0 1 11, 1 6 1 1 17, 19 15 1 16, 3,
5 Step by step rewriting Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 15 6 5 3 7 6 0 1 11, 1 9 3 7 11 3 7 1 0 1 11, 1 6 1 1 17, 19 15 1 16, 3,
6 Step by step rewriting Stmt T1 T T3 Reg 1 6 16 3 7 3 0 1 11, 1 6 5 3 7 6 0 1 11, 1 9 3 7 11 3 7 1 0 1 11, 1 6 1 1 17, 19 15 1 16, 3,
7 Step by step rewriting Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 6 5 3 7 6 0 1 11, 1 9 3 7 11 3 7 1 0 1 11, 1 6 1 1 17, 19 15 1 16, 3,
8 Step by step rewriting Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 6 5 3 7 6 0 1 11, 1 9 3 7 11 3 7 1 0 1 11, 1 6 1 1 17, 19 15 1 16, 3,
9 Step by step rewriting 6 Label(1, Reg) = { rule 11, rule 1 } 1 Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 6 5 3 7 6 0 1 11, 1 9 3 7 11 3 7 1 0 1 11, 1 1 17, 19 15 1 16, 3,
50 Step by step rewriting 3 7 16 6 1 13 6 1 1 Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 6 5 3 7 6 0 1 11, 1 9 3 7 11 3 7 1 0 1 11, 1 1 17, 19 15 1 16, 3,
51 Cost Selection When there are multiple rules for one tree node Rule 8: requires 11, 6, 7 Rule 9: requires 0, 6, 7 Rule 10: requires 1, 6, 3 7 6 5 6 1 Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 6 5 3 7 6 0 1 11, 1 Rule 9 3 7 8 Reg (Reg1) 1 load r1 rnew 9 Reg 11 (T1) 1 loadao 3T1.r1, T1.r 7 rnew 10 Reg (T) 1 loadai T.r1, T.n rnew 1 0 1 11, 1 0 T1 (Reg1,Reg) 0 // reg reg for loadao 1 T (Reg1, T3) 0 // reg con for loadai 1 17, 19 6 Reg 1 0 7 Reg 1 1 loadi n1 rnew 15 1 16, 3, Cost Template 3 T3 1 0 // con for immed arith ops 11 Reg (Reg1,Reg) 1 add r1, r rnew 1 Reg (Reg1,T3) 1 addi r1, n rnew
5 Cost Selection When there are multiple rules for one tree node Rule 8: requires 11, 6, 7 Rule 9: requires 0, 6, 7 Rule 10: requires 1, 6, 3 7 6 5 6 1 Node 7 Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 6 5 3 7 6 0 1 11, 1 Rule 9 3 7 8 Reg (Reg1) 1 load r1 rnew 9 Reg 11 (T1) 1 loadao 3T1.r1, T1.r 7 rnew 10 Reg (T) 1 loadai T.r1, T.n rnew 1 0 1 11, 1 0 T1 (Reg1,Reg) 0 // reg reg for loadao 1 T (Reg1, T3) 0 // reg con for loadai 1 17, 19 6 Reg 1 0 7 Reg 1 1 loadi n1 rnew 15 1 16, 3, Cost Template 3 T3 1 0 // con for immed arith ops 11 Reg (Reg1,Reg) 1 add r1, r rnew 1 Reg (Reg1,T3) 1 addi r1, n rnew
53 Cost Selection When there are multiple rules for one tree node Rule 8: requires 11, 6, 7 Rule 9: requires 0, 6, 7 Rule 10: requires 1, 6, 3 7 6 5 6 Node 7 Node 6 1 Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 6 5 3 7 6 0 1 11, 1 Rule 9 3 7 8 Reg (Reg1) 1 load r1 rnew 9 Reg 11 (T1) 1 loadao 3T1.r1, T1.r 7 rnew 10 Reg (T) 1 loadai T.r1, T.n rnew 1 0 1 11, 1 0 T1 (Reg1,Reg) 0 // reg reg for loadao 1 T (Reg1, T3) 0 // reg con for loadai 1 17, 19 6 Reg 1 0 7 Reg 1 1 loadi n1 rnew 15 1 16, 3, Cost Template 3 T3 1 0 // con for immed arith ops 11 Reg (Reg1,Reg) 1 add r1, r rnew 1 Reg (Reg1,T3) 1 addi r1, n rnew
5 Cost Selection When there are multiple rules for one tree node Rule 8: requires 11, 6, 7 Rule 9: requires 0, 6, 7 Rule 10: requires 1, 6, 3 7 6 5 6 Node 7 Node 6 1 Node Node 5 Stmt T1 T T3 Reg 1 6 3 7 3 0 1 11, 1 6 5 3 7 6 0 1 11, 1 Rule 9 3 7 8 Reg (Reg1) 1 load r1 rnew 9 Reg 11 (T1) 1 loadao 3T1.r1, T1.r 7 rnew 10 Reg (T) 1 loadai T.r1, T.n rnew 1 0 1 11, 1 0 T1 (Reg1,Reg) 0 // reg reg for loadao 1 T (Reg1, T3) 0 // reg con for loadai 1 17, 19 6 Reg 1 0 7 Reg 1 1 loadi n1 rnew 15 1 16, 3, Cost Template 3 T3 1 0 // con for immed arith ops 11 Reg (Reg1,Reg) 1 add r1, r rnew 1 Reg (Reg1,T3) 1 addi r1, n rnew
Tile the Tree A Further Optimization 55 Tile(n) for each class c, Label(n,c) Ø if n has two children then Tile (IR left child(n)) Tile (IR right child(n)) for each rule r that implements n if (Label(IR left child(n),left(r)) Ø ) and (Label(IR right child(n),right(r)) Ø ) then Label(n,lhs(r)) Label(n,lhs(r)) U { r } else if n has one child Tile(IR child of n) for each rule r that implements n if (Label(IR child(n),rhs(r)) Ø) then Label(n,lhs(r)) Label(n,lhs(r)) { r } else / n is a leaf / Label(n,) { all rules that implement n } Cost(n, ) {costs corresponding to precomputed set of rules} For a particular node n in the IR tree and a particular class c, we only need to track the lowestcost match. That is, Label(n, c) contains only one match at any point of tree pattern matching. Cost(n,c) largest integer NewCost RuleCost(r) Cost(n,left(r)) Cost(n,right(r)) If (NewCost < Cost(n,lhs(r)) then Label(n,lhs(r)) r Cost(n,lhs(r)) NewCost NewCost RuleCost(r) Cost(n,rhs(r)) If (NewCost < Cost(n,lhs(r)) then Label(n,lhs(r)) r Cost(n,lhs(r)) NewCost
56 Code Generation Two step process: mark the choices & emit the code Pass 1: Walk the tree, top to bottom, and mark choice of rules If we have a choice, pick the low cost label. Choice of one tile often determines the choices at its subtrees. Pass : Walk the tree, bottom to top, and emit code Tie together tiles with temporary register names. Stmt T1 T T3 Reg 1 6 3 7 One node might correspond to different classes (lhs)
Reading Engineering A Compiler Chapter 11