2 Code generation Let's start with some examples. Generate code from a tree representing x = a+2 - (c+d-4) Issues: which children should go first? what if we already had a-c in a register? Does it make a difference if a and c are floating point as opposed to integer? Generate code for a switch statement Generate code for w = w*2*x*y*zw = w*2*x*y*z
4 Instruction selection IR to assembly Why is it an issue? Example: copy a value from r1 to r2 Let me count the ways... Criteria How hard is it? Use a cost model to choose. How about register usage?
5 Instruction selection How hard is it? Can make locally optimal choices Global optimality is NP-complete Criteria speed of generated code size of generated code power consumption Considering registers Assume enough registers are available, let register allocator figure it out.
9 Instruction scheduling Reorder instructions to hide latencies. We need to collect dependence info Scheduling affects register lifetimes ==> different demand for registers Should we do register allocation before or after? How hard is it? more than one instructions may be ready too many variables may be live at the same time NP-complete!
10 Register allocation Consists of two parts: register allocation register assignment Goal : minimize spills How hard is it? BB w/ one size of data: polynomial otherwise, NP-complete based on graph coloring.
11 Code generation Generating code for simple expressions If the expression is represented by a tree, a post-order walk gives an evaluation sequence Changing the evaluation sequence may result in code that uses fewer registers. Idea: find out how many registers are needed for each subtree and evaluate the most expensive one first. Consider the following algorithm that labels tree nodes with the number of registers needed (for the ILOC architecture): 1 if n is a left leaf, or right leaf and variable 0 if n is a right leaf and constant max(label lchild, label rchild ) if label lchild label rchild label lchild +1 if label lchild == label rchild label(n) =
12 Code generation Generating code for simple expressions The idea behind our algorithm: Variables need to be loaded in registers, so leaves need one register For rhs constants we can use opI operations, so no extra register needed If we need k registers for each subtree, we'll use k for the left one, keep 1 for the result, and then use another k for the right subtree. That's a total of k+1 registers If we need k registers for one subtree and m
"name": "12 Code generation Generating code for simple expressions The idea behind our algorithm: Variables need to be loaded in registers, so leaves need one register For rhs constants we can use opI operations, so no extra register needed If we need k registers for each subtree, we ll use k for the left one, keep 1 for the result, and then use another k for the right subtree.",
"description": "That s a total of k+1 registers If we need k registers for one subtree and m
13 Code generation Generating code for expressions What if an expression contains a function call? Should the compiler be allowed to change the evaluation order? Big idea #1 wrt to optimizing or moving code around : Be conservative! Generating code for boolean operators relational operators read the book array references