0% found this document useful (0 votes)
1 views

lecture-7

The document discusses compiler optimization with a focus on register allocation, detailing local and global allocation techniques, including spill code and graph coloring methods. It outlines the requirements for effective register allocation, definitions of key concepts such as interference and live ranges, and algorithms like Chaitin's and Chaitin-Briggs for coloring interference graphs. Additionally, it explores techniques for minimizing spill costs and alternative approaches to improve allocation efficiency.

Uploaded by

Walter
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1 views

lecture-7

The document discusses compiler optimization with a focus on register allocation, detailing local and global allocation techniques, including spill code and graph coloring methods. It outlines the requirements for effective register allocation, definitions of key concepts such as interference and live ranges, and algorithms like Chaitin's and Chaitin-Briggs for coloring interference graphs. Additionally, it explores techniques for minimizing spill costs and alternative approaches to improve allocation efficiency.

Uploaded by

Walter
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 66

Compiler Optimisation

7 – Register Allocation

Hugh Leather
IF 1.18a
[email protected]

Institute for Computing Systems Architecture


School of Informatics
University of Edinburgh

2019
Introduction

This lecture:
Local Allocation - spill code
Global Allocation based on graph colouring
Techniques to reduce spill code
Register allocation

Physical machines have limited number of registers


Scheduling and selection typically assume infinite registers
Register allocation and assignment ∞ → k registers

Requirements
Produce correct code that uses k (or fewer) registers
Minimise added loads and stores
Minimise space used to hold spilled values
Operate efficiently
O(n), O(nlog2 n), maybe O(n2 ), but not O(2n )
Register allocation
Definitions

Allocation versus assignment


Allocation is deciding which values to keep in registers
Assignment is choosing specific registers for values

Interference
Two valuesa cannot be mapped to the same register wherever they
are both liveb
Such values are said to interfere
a
A value is stored in a variable
b
A value is live from its definition to its last use

Live range
The live range of a value is the set of statements at which it is live
May be conservatively overestimated (e.g. just begin → end)
Register allocation
Definitions

Spilling
Spilling saves a value from a register to memory
That register is then free – Another value often loaded
Requires F registers to be reserved

Clean and dirty values


A previously spilled value is clean if not changed since last spill
Otherwise it is dirty
A clean value can b spilled without a new store instruction

Spilling in ILOC
F is 0 (assuming rarp already reserved)
Dirty value Clean value
storeAI rx → rarp , @x loadAI rarp , @y ⇒ ry
loadAI rarp , @y ⇒ ry
Local register allocation

Register allocation only on basic block


MAXLIVE
Let MAXLIVE be the maximum, over each instruction i in the
block, of the number of values (pseudo-registers) live at i.
If MAXLIVE ≤ k, allocation should be easy
If MAXLIVE ≤ k, no need to reserve F registers for spilling
If MAXLIVE > k, some values must be spilled to memory
If MAXLIVE > k, need to reserve F registers for spilling

Two main forms:


Top down
Bottom up
Local register allocation
MAXLIVE

Example MAXLIVE computation


Some simple code with virtual registers
Local register allocation
MAXLIVE

Example MAXLIVE computation


Live registers
Local register allocation
MAXLIVE

Example MAXLIVE computation


MAXLIVE is 4
Local register allocation
Top down

Algorithm:
If number of values > k
Rank values by occurrences
Allocate first k - F values to registers
Spill other values
Local register allocation
Top down

Example top down


Usage counts
Local register allocation
Top down

Example top down


Spill rc . Now only 3 values live at once
Local register allocation
Top down

Example top down


Spill code inserted
Local register allocation
Top down

Example top down


Register assignment straightforward
Local register allocation
Bottom up

Algorithm:
Start with empty register set
Load on demand
When no register is available, free one
Replacement:
Spill the value whose next use is farthest in the future
Prefer clean value to dirty value
Local register allocation
Top down

Example bottom down


Spill ra . Now only 3 values live at once
Local register allocation
Top down

Example bottom down


Spill code inserted
Global register allocation

Local allocation does not capture reuse of values across multiple


blocks
Most modern, global allocators use a graph-colouring paradigm
Build a “conflict graph” or “interference graph”
Data flow based liveness analysis for interference
Find a k-colouring for the graph, or change the code to a
nearby problem that it can k-colour
NP-complete under nearly all assumptions1

1
Local allocation is NP-complete with dirty vs clean
Global register allocation
Algorithm sketch

From live ranges construct an interference graph


Colour interference graph so that no two neighbouring nodes
have same colour
If graph needs more than k colours - transform code
Coalesce merge-able copies
Split live ranges
Spill
Colouring is NP-complete so we will need heuristics
Map colours onto physical registers
Global register allocation
Graph colouring

Definition
A graph G is said to be k-colourable iff the nodes can be labeled
with integers 1 ... k so that no edge in G connects two nodes with
the same label

Examples
Global register allocation
Interference graph

The interference graph, GI = (NI , EI )


Nodes in GI represent values, or live ranges
Edges in GI represent individual interferences
∀x , y ∈ NI , x → y ∈ EI iff x and y interfere2
A k-colouring of GI can be mapped into an allocation to k registers

2
Two values interfere wherever they are both live
Two live ranges interfere if their values interfere at any point
Global register allocation
Colouring the interference graph

Degree3 of a node (n°) is a loose upper bound on colourability


Any node, n, such that n° < k is always trivially k-colourable
Trivially colourable nodes cannot adversely affect the
colourability of neighbours4
Can remove them from graph
Reduces degree of neighbours - may be trivially colourable
If left with any nodes such that n° ≥ k spill one
Reduces degree of neighbours - may be trivially colourable

3
Degree is number of neighbours
4
Proof as exercise
Global register allocation
Chaitin’s algorithm

1 While ∃ vertices with < k neighbours in GI


Pick any vertex n such that n° < k and put it on the stack
Remove n and all edges incident to it from GI
2 If GI is non-empty (n° >= k, ∀n ∈ GI ) then:
Pick vertex n (heuristic), spill live range of n
Remove vertex n and edges from GI , put n on “spill list”
Goto step 1
3 If the spill list is not empty, insert spill code, then rebuild the
interference graph and try to allocate, again
4 Otherwise, successively pop vertices off the stack and colour
them in the lowest colour not used by some neighbour
Global register allocation
Chaitin’s algorithm

Example: colouring with Chaitin’s algorithm


Colour with k = 3 colours
Global register allocation
Chaitin’s algorithm

Example: colouring with Chaitin’s algorithm


a° = 2 < k Choose a
Global register allocation
Chaitin’s algorithm

Example: colouring with Chaitin’s algorithm


Push a and remove from graph
Global register allocation
Chaitin’s algorithm

Example: colouring with Chaitin’s algorithm


b° = 2 < k and c° = 2 < k Choose b
Global register allocation
Chaitin’s algorithm

Example: colouring with Chaitin’s algorithm


Push b and remove from graph
Global register allocation
Chaitin’s algorithm

Example: colouring with Chaitin’s algorithm


c° = 2 < k, d° = 2 < k, and e° = 2 < k Choose c
Global register allocation
Chaitin’s algorithm

Example: colouring with Chaitin’s algorithm


Push c and remove from graph
Global register allocation
Chaitin’s algorithm

Example: colouring with Chaitin’s algorithm


d° = 1 < k and e° = 1 < k Choose d
Global register allocation
Chaitin’s algorithm

Example: colouring with Chaitin’s algorithm


Push d and remove from graph
Global register allocation
Chaitin’s algorithm

Example: colouring with Chaitin’s algorithm


e° = 0 < k Choose e
Global register allocation
Chaitin’s algorithm

Example: colouring with Chaitin’s algorithm


Push e and remove from graph
Global register allocation
Chaitin’s algorithm

Example: colouring with Chaitin’s algorithm


Pop e, neighbours use no colours, choose red
Global register allocation
Chaitin’s algorithm

Example: colouring with Chaitin’s algorithm


Pop d, neighbours use red, choose green
Global register allocation
Chaitin’s algorithm

Example: colouring with Chaitin’s algorithm


Pop c, neighbours use red and green choose blue
Global register allocation
Chaitin’s algorithm

Example: colouring with Chaitin’s algorithm


Pop b, neighbours use red and green choose blue
Global register allocation
Chaitin’s algorithm

Example: colouring with Chaitin’s algorithm


Pop a, neighbours use blue choose red
Global register allocation
Optimistic colouring

If Chaitins algorithm reaches a state where every node has k


or more neighbours, it chooses a node to spill.

Example of Chaitin overzealous spilling

k=2
Graph is 2-colourable
Chaitin must immediately spill one of these nodes

Briggs said, take that same node and push it on the stack
When you pop it off, a colour might be available for it!
Chaitin-Briggs algorithm uses this to colour that graph
Global register allocation
Chaitin-Briggs algorithm

1 While ∃ vertices with < k neighbours in GI


Pick any vertex n such that n° < k and put it on the stack
Remove n and all edges incident to it from GI
2 If GI is non-empty (n° >= k, ∀n ∈ GI ) then:
Pick vertex n (heuristic) (Do not spill)
Remove vertex n from GI , put n on stack (Not spill list)
Goto step 1
3 Otherwise, successively pop vertices off the stack and colour
them in the lowest colour not used by some neighbour
If some vertex cannot be coloured, then pick an uncoloured
vertex to spill, spill it, and restart at step 1
Step 3 is also different
Global register allocation
Chaitin-Briggs algorithm

Example: colouring with Chaitin-Briggs algorithm


Colour with k = 2 colours
Global register allocation
Chaitin-Briggs algorithm

Example: colouring with Chaitin-Briggs algorithm


a° = 2 ≥ k Don’t Spill! Choose a
Global register allocation
Chaitin-Briggs algorithm

Example: colouring with Chaitin-Briggs algorithm


Push a and remove from graph
Global register allocation
Chaitin-Briggs algorithm

Example: colouring with Chaitin-Briggs algorithm


b° = 1 < k and c° = 1 < k Choose b
Global register allocation
Chaitin-Briggs algorithm

Example: colouring with Chaitin-Briggs algorithm


Push b and remove from graph
Global register allocation
Chaitin-Briggs algorithm

Example: colouring with Chaitin-Briggs algorithm


c° = 1 < k, and d° = 1 < k Choose c
Global register allocation
Chaitin-Briggs algorithm

Example: colouring with Chaitin-Briggs algorithm


Push c and remove from graph
Global register allocation
Chaitin-Briggs algorithm

Example: colouring with Chaitin-Briggs algorithm


d° = 1 < k Choose d
Global register allocation
Chaitin-Briggs algorithm

Example: colouring with Chaitin-Briggs algorithm


Push d and remove from graph
Global register allocation
Chaitin-Briggs algorithm

Example: colouring with Chaitin-Briggs algorithm


Pop d, neighbours use no colours, choose red
Global register allocation
Chaitin-Briggs algorithm

Example: colouring with Chaitin-Briggs algorithm


Pop c, neighbours use red choose green
Global register allocation
Chaitin-Briggs algorithm

Example: colouring with Chaitin-Briggs algorithm


Pop b, neighbours use red choose green
Global register allocation
Chaitin-Briggs algorithm

Example: colouring with Chaitin-Briggs algorithm


Pop a, neighbours use green choose red
Global register allocation
Spill candidates

Minimise spill cost/ degree


Spill cost is the loads and stores needed. Weighted by scope -
i.e. avoid inner loops
The higher the degree of a node to spill the greater the
chance that it will help colouring
Negative spill cost load and store to same memory location
with no other uses
Infinite cost - definition immediately followed by use. Spilling
does not decrease live range
Global register allocation
Alternative spilling

Splitting live ranges


Coalesce
Global register allocation
Live range splitting

A whole live range may have many interferences, but perhaps


not all at the same time
Split live range into two variables connected by copy
Can reduce degree of interference graph
Smart splitting allows spilling to occur in “cheap” regions
Global register allocation
Live ranges splitting

Splitting example
Non contiguous live ranges - cannot be 2 coloured
Global register allocation
Live ranges splitting

Splitting example
Split live ranges - can be 2 coloured
Global register allocation
Coalescing

If two ranges don’t interfere and are connected by a copy


coalesce into one – opposite of splitting
Reduces degree of nodes that interfered with both
If x := y and x → y ∈ GI then can combine LRx and LRy
Eliminates the copy operation
Reduces degree of LRs that interfere with both x and y
If a node interfered with both both before, coalescing helps
As it reduces degree, often applied before colouring takes place
Global register allocation
Coalescing

Coalescing can make the graph harder to color


Typically, LRxy ° > max (LRx °, LRy °)
If max (LRx °, LRy °) < k and k < LRxy ° then LRxy might spill,
while LRx and LRy would not spill
Global register allocation
Coalescing

Observation led to conservative coalescing


Conceptually, coalesce x and y iff x → y ∈ GI and LRxy ° < k
We can do better
Coalesce LRx and LRy iff LRxy has < k neighbours with
degree > k
Only neighbours of “significant degree” can force LRxy to spill
Always safe to perform that coalesce
Cannot introduce a node of non-trivial degree
Cannot introduce a new spill
Global register allocation
Other approaches

Top-down uses high level priorities to decide on colouring


Hierarchical approaches - use control flow structure to guide
allocation
Exhaustive allocation - go through combinatorial options -
very expensive but occasional improvement
Re-materialisation - if easy to recreate a value do so rather
than spill
Passive splitting using a containment graph to make spills
effective
Linear scan - fast but weak; useful for JITs
Global register allocation
Ongoing work

Eisenbeis et al examining optimality of combined reg alloc and


scheduling. Difficulty with general control-flow
Partitioned register sets complicate matters. Allocation can
require insertion of code which in turn affects allocation.
Leupers investigated use of genetic algs for TM series
partitioned reg sets.
New work by Fabrice Rastello and others. Chordal graphs
reduce complexity
As latency increases see work in combined code generation,
instruction scheduling and register allocation
Summary

Local Allocation - spill code


Global Allocation based on graph colouring
Techniques to reduce spill code
PPar CDT Advert

• 4-year programme: • Research topics in software,


MSc by Research + PhD hardware, theory and
application of:
▶ Parallelism
• Research-focused:
▶ Concurrency
Work on your thesis topic ▶ Distribution
from the start
The biggest revolution
• Full funding available in the technological
• Collaboration between: landscape for fifty years
▶ University of Edinburgh’s
School of Informatics • Industrial engagement
✴ Ranked top in the UK by programme includes
2014 REF internships at leading
▶ Edinburgh Parallel Computing companies
Centre
✴ UK’s largest supercomputing
centre
Now accepting applications!
Find out more and apply at:
pervasiveparallelism.inf.ed.ac.uk

You might also like