Topic 12: Register Allocation

Similar documents
Register allocation. Register allocation: ffl have value in a register when used. ffl limited resources. ffl changes instruction choices

Register allocation. instruction selection. machine code. register allocation. errors

Variables vs. Registers/Memory. Simple Approach. Register Allocation. Interference Graph. Register Allocation Algorithm CS412/CS413

Lecture 21 CIS 341: COMPILERS

Low-Level Issues. Register Allocation. Last lecture! Liveness analysis! Register allocation. ! More register allocation. ! Instruction scheduling

Fall Compiler Principles Lecture 12: Register Allocation. Roman Manevich Ben-Gurion University

Register Allocation & Liveness Analysis

Compiler Design. Register Allocation. Hwansoo Han

Liveness Analysis and Register Allocation. Xiao Jia May 3 rd, 2013

Rematerialization. Graph Coloring Register Allocation. Some expressions are especially simple to recompute: Last Time

Code generation for modern processors

Register Allocation. CS 502 Lecture 14 11/25/08

Code generation for modern processors

register allocation saves energy register allocation reduces memory accesses.

Register allocation. TDT4205 Lecture 31

The C2 Register Allocator. Niclas Adlertz

Outline. Register Allocation. Issues. Storing values between defs and uses. Issues. Issues P3 / 2006

CSE P 501 Compilers. Register Allocation Hal Perkins Autumn /22/ Hal Perkins & UW CSE P-1

Liveness Analysis and Register Allocation

Compiler Architecture

Global Register Allocation

Compilation /17a Lecture 10. Register Allocation Noam Rinetzky

Register Allocation via Hierarchical Graph Coloring

Global Register Allocation via Graph Coloring

Compilers and Code Optimization EDOARDO FUSELLA

CSC D70: Compiler Optimization Register Allocation

Register Allocation. Note by Baris Aktemur: Our slides are adapted from Cooper and Torczon s slides that they prepared for COMP 412 at Rice.

Global Register Allocation

Today More register allocation Clarifications from last time Finish improvements on basic graph coloring concept Procedure calls Interprocedural

April 15, 2015 More Register Allocation 1. Problem Register values may change across procedure calls The allocator must be sensitive to this

Functions in MIPS. Functions in MIPS 1

Global Register Allocation - Part 3

Register Allocation. Global Register Allocation Webs and Graph Coloring Node Splitting and Other Transformations

Lectures 5. Announcements: Today: Oops in Strings/pointers (example from last time) Functions in MIPS

COS 320. Compiling Techniques

Lecture 5. Announcements: Today: Finish up functions in MIPS

Register Allocation. Preston Briggs Reservoir Labs

Register Allocation. Lecture 16

Today. Putting it all together

Register allocation. CS Compiler Design. Liveness analysis. Register allocation. Liveness analysis and Register allocation. V.

Global Register Allocation - Part 2

Register Allocation. Register Allocation. Local Register Allocation. Live range. Register Allocation for Loops

CSE 504: Compiler Design. Runtime Environments

Code Generation. CS 540 George Mason University

A Bad Name. CS 2210: Optimization. Register Allocation. Optimization. Reaching Definitions. Dataflow Analyses 4/10/2013

Lecture Notes on Register Allocation

Control Instructions. Computer Organization Architectures for Embedded Computing. Thursday, 26 September Summary

Control Instructions

Register Allocation (wrapup) & Code Scheduling. Constructing and Representing the Interference Graph. Adjacency List CS2210

Chapter 2A Instructions: Language of the Computer

CHAPTER 3. Register allocation

CHAPTER 3. Register allocation

Procedure Calls Main Procedure. MIPS Calling Convention. MIPS-specific info. Procedure Calls. MIPS-specific info who cares? Chapter 2.7 Appendix A.

Do-While Example. In C++ In assembly language. do { z--; while (a == b); z = b; loop: addi $s2, $s2, -1 beq $s0, $s1, loop or $s2, $s1, $zero

CS 406/534 Compiler Construction Instruction Selection and Global Register Allocation

Lecture Overview Register Allocation

Lecture Compiler Backend

Lecture 25: Register Allocation

Topic 7: Intermediate Representations

Register Allocation. Michael O Boyle. February, 2014

Compiling Code, Procedures and Stacks

CSE Lecture In Class Example Handout

Branch Addressing. Jump Addressing. Target Addressing Example. The University of Adelaide, School of Computer Science 28 September 2015

CSc 553. Principles of Compilation. 23 : Register Allocation. Department of Computer Science University of Arizona

CA Compiler Construction

Topic 9: Control Flow

CSc 453 Intermediate Code Generation

Compiler Theory. (Semantic Analysis and Run-Time Environments)

Implementing Functions at the Machine Level

COMP 303 Computer Architecture Lecture 3. Comp 303 Computer Architecture

Lecture 5: Procedure Calls

Register Allocation (via graph coloring) Lecture 25. CS 536 Spring

Calling Conventions. Hakim Weatherspoon CS 3410, Spring 2012 Computer Science Cornell University. See P&H 2.8 and 2.12

LAB C Translating Utility Classes

Compiler Optimization Techniques

Lecture 6. Register Allocation. I. Introduction. II. Abstraction and the Problem III. Algorithm

Redundant Computation Elimination Optimizations. Redundancy Elimination. Value Numbering CS2210

CS356: Discussion #6 Assembly Procedures and Arrays. Marco Paolieri

Register Allocation 3/16/11. What a Smart Allocator Needs to Do. Global Register Allocation. Global Register Allocation. Outline.

Computer Architecture Prof. Mainak Chaudhuri Department of Computer Science & Engineering Indian Institute of Technology, Kanpur

Abstract Interpretation Continued

6.823 Computer System Architecture

Compiler Passes. Optimization. The Role of the Optimizer. Optimizations. The Optimizer (or Middle End) Traditional Three-pass Compiler

Algorithm classification

Introduction to Optimization Local Value Numbering

Register Allocation 1

Register allocation. Overview

CS 352 Compilers: Principles and Practice Final Examination, 12/11/05

Agenda. CSE P 501 Compilers. Big Picture. Compiler Organization. Intermediate Representations. IR for Code Generation. CSE P 501 Au05 N-1

CS 406/534 Compiler Construction Putting It All Together

A TASK OPTIMIZATION FRAMEWORK FOR MSSP RAHUL ULHAS JOSHI

Register Allocation. Lecture 38

Run-time Environment

CS 61c: Great Ideas in Computer Architecture

Subroutines. int main() { int i, j; i = 5; j = celtokel(i); i = j; return 0;}

Topic 14: Scheduling COS 320. Compiling Techniques. Princeton University Spring Lennart Beringer

Assembly Language: Function Calls

CSC 8400: Computer Systems. Using the Stack for Function Calls

Assembly Language: Function Calls

Princeton University Computer Science 217: Introduction to Programming Systems. Assembly Language: Function Calls

Transcription:

Topic 12: Register Allocation COS 320 Compiling Techniques Princeton University Spring 2016 Lennart Beringer 1

Structure of backend Register allocation assigns machine registers (finite supply!) to virtual registers based on liveness analysis: interference graph primary approach: graph coloring spilling needed in case of insufficient supply of machine registers idea: hold values in memory (stack frame) transfer to/from registers to perform arithmetic ops, conditional branches, architecture-specific requirements: caller/callee-save floating point vs integer,

Recap: interference graph Liveness conflicts: virtual registers x and y interfere if there is a node n in the CFG such that x and y are both LiveOut at n. Representation: conflict/interference graph: each virtual register represented by one node Interference between x and y: undirected edge between nodes x and y

Interference graph: optimization for MOVEs n 1 : n 2 : n 3 : t s (*move*) x... s... (*use of s*) y... t... (*use of t*) Virtual registers s and t are both live-out at n 1 hence interfere formally s will hence be assigned different registers t But: we d like them to share a register, and to eliminate the move instruction! Solution: treat move instructions differently during interference analysis For n: a c (*move*) and liveout(n) = {b 1,, b k }, only add edges a b i for those b i that are different from c.

Graph coloring using Kempe s heuristics (1879) Observation: suppose G has a node m with < K neighbors if G {m} can be K-1 colored, G can be K-colored: m s neighbors use at most K-1 colors in G - {m} so can reinsert m into G and select a color remove a node of degree < 6 color the remaining graph K = 6 reinsert the node and select a color recursive (stack-based) algorithm

Optimistic coloring using Kempe Build construct interference graph

Optimistic coloring using Kempe Build construct interference graph Simplify repeatedly remove nodes of degree < K push removed nodes on stack each removal reduces degree of other nodes!

Optimistic coloring using Kempe Spill Build construct interference graph Simplify repeatedly remove nodes of degree < K push removed nodes on stack each removal reduces degree of other nodes! simplify fails if all nodes have degree >= K select a node n for (potential) spilling remove n from G, and push n into onto stack

Optimistic coloring using Kempe Select Spill Build construct interference graph Simplify repeatedly remove nodes of degree < K push removed nodes on stack each removal reduces degree of other nodes! simplify fails if all nodes have degree >= K select a node n for (potential) spilling remove n from G, and push n into onto stack starting from empty graph, successively pop nodes, select color, and add node back into graph when a potential spill node is popped: 1. all K neighbors have different color actual spill; don t assign color but continue selecting to identify other spills 2. the K neighbors use < K colors use the free color - spill did not need to be realized ( optimistic coloring )

Select Spill Optimistic coloring using Kempe Build construct interference graph Start over When all required spills have been identified rewrite program: realize spills recompute liveness live ranges of spills typically short Simplify repeatedly remove nodes of degree < K push removed nodes on stack each removal reduces degree of other nodes! simplify fails if all nodes have degree >= K select a node n for (potential) spilling remove n from G, and push n into onto stack starting from empty graph, successively pop nodes, select color, and add node back into graph when a potential spill node is popped: 1. all K neighbors have different color actual spill; don t assign color but continue selecting to identify other spills 2. the K neighbors use < K colors use the free color - spill did not need to be realized ( optimistic coloring )

Basic coloring: example (K = 4) // livein: k, j g := M [ j+12 ] h := k 1 f = g * h e := M [ j + 8 ] m := M [ j + 16 ] b := M [ f ] c := e + 8 d := c k := m + 4 j := b // liveout d k j j g f h e k d b c move (relevant later) interference m

Basic coloring: example (K = 4) // livein: k, j g := M [ j+12 ] h := k 1 f = g * h e := M [ j + 8 ] m := M [ j + 16 ] b := M [ f ] c := e + 8 d := c k := m + 4 j := b // liveout d k j j g f h e k d b c move (relevant later) interference m Nodes of degree < K: c, g, h, f push g, h

Basic coloring: example (K = 4) // livein: k, j g := M [ j+12 ] h := k 1 f = g * h e := M [ j + 8 ] m := M [ j + 16 ] b := M [ f ] c := e + 8 d := c k := m + 4 j := b // liveout d k j j g f h e k d b c move (relevant later) interference m Nodes of degree < K: c, f push g, h Next: push k, d, j, e, f, b, c

Basic coloring: example (K = 4) // livein: k, j g := M [ j+12 ] h := k 1 f = g * h e := M [ j + 8 ] m := M [ j + 16 ] b := M [ f ] c := e + 8 d := c k := m + 4 j := b // liveout d k j j g f h e k d b c move (relevant later) interference m Nodes of degree < K: m push g, h, k, d, j, e, f, b, c Next: push m, pop m

Basic coloring: example (K = 4) // livein: k, j g := M [ j+12 ] h := k 1 f = g * h e := M [ j + 8 ] m := M [ j + 16 ] b := M [ f ] c := e + 8 d := c k := m + 4 j := b // liveout d k j j g f h e k d b c move (relevant later) interference m Nodes of degree < K: push g, h, k, d, j, e, f, b, c Next: pop c, b, f

Basic coloring: example (K = 4) // livein: k, j g := M [ j+12 ] h := k 1 f = g * h e := M [ j + 8 ] m := M [ j + 16 ] b := M [ f ] c := e + 8 d := c k := m + 4 j := b // liveout d k j j g f h e k d b c move (relevant later) interference m Nodes of degree < K: push g, h, k, d, j, e Next: pop e, j, d

Basic coloring: example (K = 4) // livein: k, j g := M [ j+12 ] h := k 1 f = g * h e := M [ j + 8 ] m := M [ j + 16 ] b := M [ f ] c := e + 8 d := c k := m + 4 j := b // liveout d k j j g f h e k d b c move (relevant later) interference m Nodes of degree < K: push g, h, k Next: pop k, h, g

Basic coloring: example (K = 4) // livein: k, j g := M [ j+12 ] h := k 1 f = g * h e := M [ j + 8 ] m := M [ j + 16 ] b := M [ f ] c := e + 8 d := c k := m + 4 j := b // liveout d k j j g f h e k d b c move (relevant later) interference m Nodes of degree < K: Stack empty Done no spilling needed

Register coalescing Nodes in the conflict graph can be coalesced, provided that they don t interfere; edges of coalesced node = union of edges associated with original nodes a c a bc b In particular: if source and dest of a move don t interfere, coalescing allows one to eliminate the move instruction.

Register coalescing Nodes in the conflict graph can be coalesced, provided that they don t interfere; edges of coalesced node = union of edges associated with original nodes a c a bc b In particular: if source and dest of a move don t interfere, coalescing allows one to eliminate the move instruction. But: coalescing before coloring may make graph not colorable! a c a c Example: is 2-colorable:. But b d b d b a cd is not.

Safe coalescing heuristics: Briggs Coalesce nodes that don t interfere, provided that the resulting merged node has less than K neighbors of degree K. Example: a b c d Don t merge c with d, since deg(a)=deg(b) = 2 in b a cd.

Safe coalescing heuristics: Briggs Coalesce nodes that don t interfere, provided that the resulting merged node has less than K neighbors of degree K. Example: a b c d Don t merge c with d, since deg(a)=deg(b) = 2 in b a cd. Why is this safe?

Safe coalescing heuristics: Briggs Coalesce nodes that don t interfere, provided that the resulting merged node has less than K neighbors of degree K. Example: a b c d Don t merge c with d, since deg(a)=deg(b) = 2 in b a cd. Why is this safe? after simplification, all nodes of degree < K have been eliminated

Safe coalescing heuristics: Briggs Coalesce nodes that don t interfere, provided that the resulting merged node has less than K neighbors of degree K. Example: a b c d Don t merge c with d, since deg(a)=deg(b) = 2 in b a cd. Why is this safe? after simplification, all nodes of degree < K have been eliminated so only high-degree neighbors of merge remain

Safe coalescing heuristics: Briggs Coalesce nodes that don t interfere, provided that the resulting merged node has less than K neighbors of degree K. Example: a b c d Don t merge c with d, since deg(a)=deg(b) = 2 in b a cd. Why is this safe? after simplification, all nodes of degree < K have been eliminated so only high-degree neighbors of merge remain if there are < K of such neighbors, the degree of the merge is < K, so we can simplify merge Hence, merging does not render a colorable graph incolorable.

Safe coalescing heuristics: George Coalesce noninterfering nodes x and y only if every neighbor t of x already interferes with y or is of degree < K. Example: a b c d Don t merge c with d, since deg(a)= 2 and a does not yet interfere with d. Similarly, don t merge d with c, since...

Safe coalescing heuristics: George Coalesce noninterfering nodes x and y only if every neighbor t of x already interferes with y or is of degree < K. Example: a b c d Don t merge c with d, since deg(a)= 2 and a does not yet interfere with d. Similarly, don t merge d with c, since... Why is this safe?

Safe coalescing heuristics: George Coalesce noninterfering nodes x and y only if every neighbor t of x already interferes with y or is of degree < K. Example: a b c d Don t merge c with d, since deg(a)= 2 and a does not yet interfere with d. Similarly, don t merge d with c, since... Why is this safe? let S be the set of neighbors of x in G that have degree < K

Safe coalescing heuristics: George Coalesce noninterfering nodes x and y only if every neighbor t of x already interferes with y or is of degree < K. Example: a b c d Don t merge c with d, since deg(a)= 2 and a does not yet interfere with d. Similarly, don t merge d with c, since... Why is this safe? let S be the set of neighbors of x in G that have degree < K if coalescing is not performed, all nodes in S simplify, leaving a reduced graph G 1

Safe coalescing heuristics: George Coalesce noninterfering nodes x and y only if every neighbor t of x already interferes with y or is of degree < K. Example: a b c d Don t merge c with d, since deg(a)= 2 and a does not yet interfere with d. Similarly, don t merge d with c, since... Why is this safe? let S be the set of neighbors of x in G that have degree < K if coalescing is not performed, all nodes in S simplify, leaving a reduced graph G 1 if coalescing is performed, simplify also removes all nodes in S: each s є S is of degree < K or is already adjacent to both x and y in G, so still simplifies after merging of x and y

Safe coalescing heuristics: George Coalesce noninterfering nodes x and y only if every neighbor t of x already interferes with y or is of degree < K. Example: a b c d Don t merge c with d, since deg(a)= 2 and a does not yet interfere with d. Similarly, don t merge d with c, since... Why is this safe? let S be the set of neighbors of x in G that have degree < K if coalescing is not performed, all nodes in S simplify, leaving a reduced graph G 1 if coalescing is performed, simplify also removes all nodes in S: each s є S is of degree < K or is already adjacent to both x and y in G, so still simplifies after merging of x and y the resulting G 2 is a subgraph of G 1 ( merge in G 2 corresponds to y in G 1 ), so if G 1 can be colored, so can G 2 Again, merging does not render a colorable graph incolorable.

Safe coalescing heuristics: Briggs, George Both heuristics are conservative: we may miss some opportunities to coalesce (HW: example?) specifically, we may fail to eliminate some move instructions but that s preferable to not coalescing at all, which results in more spills; spills significantly more expensive (time: load+store versus move; space)

Safe coalescing heuristics: Briggs, George Both heuristics are conservative: we may miss some opportunities to coalesce (HW: example?) specifically, we may fail to eliminate some move instructions but that s preferable to not coalescing at all, which results in more spills; spills significantly more expensive (time: load+store versus move; space) interleaving simplify with coalescing eliminates many moves, while still avoiding many spills. Thus, refine our allocation procedure:

Safe coalescing heuristics: Briggs, George Both heuristics are conservative: we may miss some opportunities to coalesce (HW: example?) specifically, we may fail to eliminate some move instructions but that s preferable to not coalescing at all, which results in more spills; spills significantly more expensive (time: load+store versus move; space) interleaving simplify with coalescing eliminates many moves, while still avoiding many spills. Thus, refine our allocation procedure: Build Simplify Coalesce construct interference graph mark nodes that are the src or dest or a move successively remove nodes that are of degree < K, and are not move-related conservative: use Briggs or George simplify reduced many degrees, so many opportunities delete move instructions involved in coalescing correct move-related classification of merged node if necessary back to simplification!

Allocation with coalescing: freezing Build Simplify Coalesce Freeze NEW PHASE: select a low-degree node n that is marked move-related mark it non-move-related give up hope to ever coalesce it also mark n s move-partner non-move-related, unless it participates in some other move(s) back to simplify: at least the now unmarked nodes can be simplified

Allocation with coalescing: completing the algorithm Remaining phases as before: Build Simplify Coalesce rewrite program, recompute interferences Actual spill / start over remember realization of spill no actual spill Select pop node, select color push push potential spill node but keep selecting low-degree nodes exhausted graph empty Freeze no freezable node of low degree (Potential) spill simplify/coalesce exhausted

Coloring with coalescing: example (K = 4) // livein: k, j g := M [ j+12 ] h := k 1 f = g * h e := M [ j + 8 ] m := M [ j + 16 ] b := M [ f ] c := e + 8 d := c k := m + 4 j := b // liveout d k j j g f h e k d b c m move interference Non-marked nodes of degree < K: g, h, f push g, h, k

Coloring with coalescing: example (K = 4) // livein: k, j g := M [ j+12 ] h := k 1 f = g * h e := M [ j + 8 ] m := M [ j + 16 ] b := M [ f ] c := e + 8 d := c k := m + 4 j := b // liveout d k j j g f h e k d b c m move interference Non-marked nodes of degree < K: f push g, h, k Next: coalesce c & d could still simplify f instead! George: all neighbors of c already interfere with d Briggs: merged node has < K neighbors of degree K

Coloring with coalescing: example (K = 4) // livein: k, j g := M [ j+12 ] h := k 1 f = g * h e := M [ j + 8 ] m := M [ j + 16 ] b := M [ f ] c := e + 8 d := c k := m + 4 j := b // liveout d k j j g f h e k c&d b m move interference Non-marked nodes of degree < K: f push g, h, k could still simplify f instead! Next: coalesce j & b Briggs: merged node has < K neighbors of degree K

Coloring with coalescing: example (K = 4) // livein: k, j g := M [ j+12 ] h := k 1 f = g * h e := M [ j + 8 ] m := M [ j + 16 ] b := M [ f ] c := e + 8 d := c k := m + 4 j := b // liveout d k j j&b g f h e k c&d m move interference Non-marked nodes of degree < K: f, e, c&d push g, h, k Next: push c&d, j&b, f, m, e pop e

Coloring with coalescing: example (K = 4) // livein: k, j g := M [ j+12 ] h := k 1 f = g * h e := M [ j + 8 ] m := M [ j + 16 ] b := M [ f ] c := e + 8 d := c k := m + 4 j := b // liveout d k j j&b g f h e k c&d m move interference Non-marked nodes of degree < K: push g, h, k, c&d, j&b, f, m Next: pop m, f, j&b, c&d

Coloring with coalescing: example (K = 4) // livein: k, j g := M [ j+12 ] h := k 1 f = g * h e := M [ j + 8 ] m := M [ j + 16 ] b := M [ f ] c := e + 8 d := c k := m + 4 j := b // liveout d k j j&b g f h e k c&d m move interference Non-marked nodes of degree < K: push g, h, k Next: pop k, h, g

Coloring with coalescing: example (K = 4) // livein: k, j g := M [ j+12 ] h := k 1 f = g * h e := M [ j + 8 ] m := M [ j + 16 ] b := M [ f ] c := e + 8 d := c k := m + 4 j := b // liveout d k j j&b g f h e k c&d m move interference Done

Spilling heuristics // livein: k, j g := M [ j+12 ] h := k 1 f = g * h e := M [ j + 8 ] m := M [ j + 16 ] M [ m loc ] := m b := M [ f ] c := e + 8 d := c m := M [ m loc ] k := m + 4 j := b // liveout d k j SPILL m splits single large liveness range of m into two short liveness ranges eliminates interference c m General heuristics: spill nodes that have high degree, but few uses particularly if the live-range is long but sparse

Spilling heuristics // livein: k, j g := M [ j+12 ] h := k 1 f = g * h e := M [ j + 8 ] m := M [ j + 16 ] M [ m loc ] := m b := M [ f ] c := e + 8 d := c m := M [ m loc ] k := m + 4 j := b // liveout d k j SPILL m splits single large liveness range of m into two short liveness ranges eliminates interference c m

Spilling heuristics Naïve spilling: when rewriting program, undo all register coalescing Improvement: remember all coalescing done before the first potential spill was discovered they will tend to be rediscovered -- but undo the later coalescings.

Spilling heuristics Naïve spilling: when rewriting program, undo all register coalescing Improvement: remember all coalescing done before the first potential spill was discovered they will tend to be rediscovered -- but undo the later coalescings. Coalescing spills: many spill locations large stack frames don t need to keep spill locations apart if their virtual registers don t interfere! further benefit: eliminate spill-to-spill-moves: a b when both a and b are spilled: t M [b loc ]; M[a loc ] t (typo in MCIL here see errata list!) All done during Start Over, before spill code is generated and new register interference is computed Hence, can use coloring to minimize spill locations: infinitely many colors: no bound on size of frame liveness info yields interference between spilled nodes first, coalesce all spill nodes related by moves then, simplify and select (try to reuse colors) resulting # colors is # spill locations

Precolored temporaries / nodes some temporaries correspond directly to machine registers: stack / frame pointer, standard argument registers 1 & 2, these special temporaries implicitly interfere with each other but: ordinary temporaries can share color with precolored node (see example below)

Precolored temporaries / nodes some temporaries correspond directly to machine registers: stack / frame pointer, standard argument registers 1 & 2, these special temporaries implicitly interfere with each other but: ordinary temporaries can share color with precolored node (see example below) K-register machine: introduce precolored K nodes, all interfering with each other liveness range of special-purpose registers (frame pointer etc) interfere with all ordinary temporaries that are live general-purpose registers have no additional interferences precolored nodes can t be simplified (they already have a color!), and can t be spilled (they are registers!) hence, consider them to be of infinite degree and start selection phase not from empty graph but graph of precolored nodes to keep live ranges of precolored nodes short, front-end can copy them away, to freshly introduced temps

Copying away precolored temporaries suppose register r7 is callee-save: considering function entry as definition of r7, and function exit as use ensures it s live throughout the body, so it will be preserved but: we don t want to block the callee-saveregister color for the entire body entry: def(r7) : exit: use(r7)

Copying away precolored temporaries suppose register r7 is callee-save: considering function entry as definition of r7, and function exit as use ensures it s live throughout the body, so it will be preserved but: we don t want to block the callee-saveregister color for the entire body so: introduce a new temporary t and insert moves if register pressure is low, allocator will coalesce and eliminate moves if register pressure is high, allocator will spill entry: def(r7) : exit: use(r7) entry: def(r7) t r7 : r7 t exit: use(r7)

Copying away precolored temporaries suppose register r7 is callee-save: considering function entry as definition of r7, and function exit as use ensures it s live throughout the body, so it will be preserved but: we don t want to block the callee-saveregister color for the entire body so: introduce a new temporary t and insert moves if register pressure is low, allocator will coalesce and eliminate moves if register pressure is high, allocator will spill entry: def(r7) : exit: use(r7) entry: def(r7) t r7 : r7 t exit: use(r7) Note: the thus introduced temps t (one for each callee-save register) interfere with each other, with later other callee-save regs, and with most variables defined + used in the body, and are hence of high degree and low #uses. entry: def(r7, r8) t r7 u r8 : r8 u r7 t exit: use(r7, r8) t r8 u r7

Liveness-across-call and caller/callee-save preference Body of g(): : x := 5 y := x + 1 z := f () return z + y Temporary x is not live across the call to f allocating x to a callee-save register r will force body of f to store r away to some t (previous slide), and restore r before returning but caller does not need x

Liveness-across-call and caller/callee-save preference Body of g(): : x := 5 y := x + 1 z := f () return z + y Temporary x is not live across the call to f allocating x to a callee-save register r will force body of f to store r away to some t (previous slide), and restore r before returning but caller does not need x prefer allocation of x to caller-save register s: callee f is free to overwrite s that s ok: x is not used after function return caller even does not even need to store s away prior to call and knows this (liveness info)

Liveness-across-call and caller/callee-save preference Body of g(): : x := 5 y := x + 1 z := f () return z + y Temporary x is not live across the call to f allocating x to a callee-save register r will force body of f to store r away to some t (previous slide), and restore r before returning but caller does not need x prefer allocation of x to caller-save register s: callee f is free to overwrite s that s ok: x is not used after function return caller even does not even need to store s away prior to call and knows this (liveness info) Temps not live across calls should be allocated to caller-save registers.

Liveness-across-call and caller/callee-save preference Body of g(): : x := 5 y := x + 1 z := f () return z + y Temporary y is live across the call to f allocating y to a caller-save register s would mean that f is free to overwrite s but caller does need y/s after function return so y/s would additionally need to be spilled / copied away prior to call we don t want to spill all variables that are live across calls!

Liveness-across-call and caller/callee-save preference Body of g(): : x := 5 y := x + 1 z := f () return z + y Temporary y is live across the call to f allocating y to a caller-save register s would mean that f is free to overwrite s but caller does need y/s after function return so y/s would additionally need to be spilled / copied away prior to call we don t want to spill all variables that are live across calls! prefer allocation of y to callee-save register r: callee f copies r away to some t (coalesce if possible) and will restore r prior to return no additional work needed on caller side

Liveness-across-call and caller/callee-save preference Body of g(): : x := 5 y := x + 1 z := f () return z + y Temporary y is live across the call to f allocating y to a caller-save register s would mean that f is free to overwrite s but caller does need y/s after function return so y/s would additionally need to be spilled / copied away prior to call we don t want to spill all variables that are live across calls! prefer allocation of y to callee-save register r: callee f copies r away to some t (coalesce if possible) and will restore r prior to return no additional work needed on caller side Temps live across calls should be allocated to callee-save registers.

Liveness-across-call and caller/callee-save preference Temps not live across calls should be allocated to caller-save registers. Temps live across calls should be allocated to callee-save registers. How can we nudge the allocator to do this?

Liveness-across-call and caller/callee-save preference Temps not live across calls should be allocated to caller-save registers. Temps live across calls should be allocated to callee-save registers. How can we nudge the allocator to do this? In CALL instruction, understand all N caller-save registers to be defined/live-out. They interfere with each other s 1 s 2 s N s 4 s 3

Liveness-across-call and caller/callee-save preference Temps not live across calls should be allocated to caller-save registers. Temps live across calls should be allocated to callee-save registers. How can we nudge the allocator to do this? In CALL instruction, understand all N caller-save registers to be defined/live-out. They interfere with each other but not with x, so a good allocator will tend to assign x to the precolor of one of the s i. s 1 s 2 x s N s 4 s 3

Liveness-across-call and caller/callee-save preference Temps live across calls should be allocated to callee-save registers. How can we nudge the allocator to do this? In CALL instruction, understand all N caller-save registers to be defined/live-out. They interfere with each other and also with y. s 1 s 2 x s N y s 4 s 3

Liveness-across-call and caller/callee-save preference Temps live across calls should be allocated to callee-save registers. How can we nudge the allocator to do this? In CALL instruction, understand all N caller-save registers to be defined/live-out. They interfere with each other and also with y. But y also interferes with the t i created by the front-end in the body of g. s 1 s 2 t 1 x s N y : s 4 s 3 t K

Liveness-across-call and caller/callee-save preference Temps live across calls should be allocated to callee-save registers. How can we nudge the allocator to do this? In CALL instruction, understand all N caller-save registers to be defined/live-out. They interfere with each other and also with y. But y also interferes with the t i created by the front-end in the body of g. So a spill is likely. Since the t i are high degree, low use, they are more likely to be selected for spill. So, the color of one callee-save registers is available for y. s 1 s 2 t 1 x s N y : s 4 s 3 t K

Register allocation for expression trees Can avoid liveness calculation, interference graph construction, coloring. Flashback to instruction selection: tiling, ie covering the tree with patterns corresponding to machine instructions. In IR phase, had suggested use of separate (virtual) registers for each tile. Clearly, can do better

Register allocation for expression trees Algorithm 1: simple postorder traversal can be combined with maximal munch (optimal but not optimum) r1 r1 r1 r2 r1 r2 r1 r1 r2 r1 r2 r1 r2 r1 r2 r2 r2 r2 r2 r2

Register allocation for expression trees Algorithm 2: dynamic programming label each tile with number of registers needed for its evaluation when visiting node u with children u left u right, with needs n l and n r, respectively: evaluating left child; hold result while evaluating right child: cost = max(u left, 1 + u right ) evaluating right child; hold result while evaluating left child: cost = max(1 + u left, u right ) choose cheaper evaluation order