SlideShare a Scribd company logo
LLVM Register
Allocation
Kai
kai@skymizer.com
Outline
• Introduction to Register Allocation Problem
• LLVM Base Register Allocation Interface
• LLVM Basic Register Allocation
• LLVM Greedy Register Allocation
Introduction to Register
Allocation
• Definition
• Register allocation is the problem of mapping
program variables to either machine registers or
memory addresses.
• Best solution
• minimise the number of loads/stores from/to memory
• NP-complete
int main()
{
int i, j;
int answer;
for (i = 1; i < 10; i++)
for (j = 1; j < 10; j++) {
answer = i * j;
}
return 0;
}
_main:
@ BB#0:
sub sp, #16
movs r0, #0
str r0, [sp, #12]
movs r0, #1
str r0, [sp, #8]
b LBB0_2
LBB0_1:
adds r1, #1
str r1, [sp, #8]
LBB0_2:
ldr r1, [sp, #8]
cmp r1, #9
bgt LBB0_6
@ BB#3:
str r0, [sp, #4]
b LBB0_5
LBB0_4:
ldr r2, [sp, #4]
muls r1, r2, r1
str r1, [sp]
ldr r1, [sp, #4]
adds r1, #1
Graph Coloring
• For an arbitrary graph G; a coloring of G assigns a
color to each node in G so that no pair of adjacent
nodes have the same color.
2-colorable 3-colorable
Graph Coloring for RA
• Node: Live interval
• Edge: Two live intervals have interference
• Color: Physical register
• Find a feasible colouring for the graph
…
a0 = …
b0 = …
… = b0
d0 = …
c0 = …
…
d1 = c0
… = a0
… = d1
B0
B1 B2
B3
…
LIa = …
LIb = …
… = LIb
LIc = …
…
LId = LIc
… = LIa
… = LId
B0
B1 B2
B3
LRa
LRb LRc
LRd
…
LIa = …
LIb = …
… = LIb
LIc = …
…
LId = LIc
… = LIa
… = LId
B0
B1 B2
B3
An Example from “Engineering A Compiler”
Why Not Graph Coloring
• Interference graph is expensive to build
• Spill code placement is more important than
colouring
• Need to model aliases and overlapping register
classes
• Flexibility is more important than the coloring
algorithm
(Adopted from “Register Allocation in LLVM 3.0”)
Excerpt from tricore_llvm.pdf
SSA Properties
* Each definition in the procedure creates a unique name.
* Each use refers to a single definition.
LLVM Register Allocation
• Basic
• Provide a minimal implementation of the basic register allocator
• Greedy
• Global live range splitting.
• Fast
• This register allocator allocates registers to a basic block at a
time.
• PBQP
• Partitioned Boolean Quadratic Programming (PBQP) based
register allocator for LLVM
LLVM Base Register Allocation Interface
Calculate
LiveInterval Weight
Enqueue All
LiveInterval
selectOrSplit for One
LiveInterval
Assign the Physical
Register
Enqueue Split
LiveInterval
dequeue
physical register is available
split live interval
update LiveInterval.weight
(spill cost)
allocatePhysRegs
enqueue
seedLiveRegs
Q
customised by new RA algorithm
for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
if (MRI->reg_nodbg_empty(Reg))
continue;
enqueue(&LIS->getInterval(Reg));
}
LLVM Basic Register Allocation
Calculate
LiveInterval Weight
Enqueue All
LiveInterval
RABasic::selectOrSplit
Assign the Physical
Register
Enqueue Split
LiveInterval
dequeue
physical register is available
split live interval
update LiveInterval.weight
(spill cost)
allocatePhysRegs
enqueue
seedLiveRegs
priority Q
(spill cost)
customised by RABasic algorithm
struct CompSpillWeight {
bool operator()(LiveInterval *A, LiveInterval *B) const {
return A->weight < B->weight;
}
};
// Check for an available register in this class.
AllocationOrder Order(VirtReg.reg, *VRM, RegClassInfo);
while (unsigned PhysReg = Order.next()) {
// Check for interference in PhysReg
switch (Matrix->checkInterference(VirtReg, PhysReg)) {
case LiveRegMatrix::IK_Free:
// PhysReg is available, allocate it.
return PhysReg;
case LiveRegMatrix::IK_VirtReg:
// Only virtual registers in the way, we may be able to spill them.
PhysRegSpillCands.push_back(PhysReg);
continue;
default:
// RegMask or RegUnit interference.
continue;
}
}
LiveInterval Weight
• Weight for one instruction with the register
• weight = (isDef + isUse) * (Block Frequency / Entry Frequency)
• loop induction variable: weight *= 3
• For all instructions with the register
• totalWeight += weight
• Hint: totalWeight *= 1.01
• Re-materializable: totalWeight *= 0.5
• LiveInterval.weight = totalWeight / size of LiveInterval
Matrix->checkInterference()
• How to represent live/dead points?
• SlotIndex
• How to represent a value?
• VNInfo
• How to represent a live interval?
• LiveInterval
• How to check interference between live intervals?
• LiveIntervalUnion & LiveRegMatrix
Liveness Slot
• There are four kind of slots to describe a position at which a register can become live, or cease to be
live.
• Block (B)
• entering or leaving a block
• PHI-def
• Early Clobber (e)
• kill slot for early-clobber def
• A = A op B ( )
• Register (r)
• normal register use/def slot
• Dead (d)
• dead def
********** INTERVALS **********
%vreg0 [208r,320r:0)[416B,432r:0) 0@208r
%vreg1 [16r,32r:0) 0@16r
%vreg2 [48r,480B:0) 0@48r
%vreg3 [96r,112r:0) 0@96r
%vreg4 [496r,512r:0) 0@496r
%vreg6 [224r,240r:0) 0@224r
%vreg7 [432r,448r:0) 0@432r
%vreg8 [304r,320r:0) 0@304r
%vreg9 [320r,336r:0) 0@320r
%vreg10 [352r,368r:0) 0@352r
%vreg11 [368r,384r:0) 0@368r
SlotIndex
((MachineInstr *, index), slot)
Slot_Block
Slot_EarlyClobber
Slot_Register
Slot_Dead
unsigned getIndex() const {
return listEntry()->getIndex() | getSlot();
}
listEntry()
Numbering of Machine
Instruction
0B BB#0: derived from LLVM BB %entry
16B %vreg1<def> = t2MOVi 0, pred:14, pred:%noreg, opt:%noreg; rGPR:%vreg1
32B t2STRi12 %vreg1, <fi#0>, 0, pred:14, pred:%noreg; mem:ST4[%retval] rGPR:%vreg1
48B %vreg2<def> = t2MOVi 1, pred:14, pred:%noreg, opt:%noreg; rGPR:%vreg2
64B t2STRi12 %vreg2, <fi#1>, 0, pred:14, pred:%noreg; mem:ST4[%i] rGPR:%vreg2
Successors according to CFG: BB#1
for (MachineBasicBlock::iterator miItr = mbb->begin(), miEnd = mbb->end();
miItr != miEnd; ++miItr) {
MachineInstr *mi = miItr;
if (mi->isDebugValue())
continue;
// Insert a store index for the instr.
indexList.push_back(createEntry(mi, index += SlotIndex::InstrDist));
// Save this base index in the maps.
mi2iMap.insert(std::make_pair(mi, SlotIndex(&indexList.back(),
SlotIndex::Slot_Block)));
}
VNInfo
• hold information about a machine level value
• (id, def)
• def: SlotIndex of the defining instruction
Live Interval
• Segment
• start, end, valno
• LiveRange
• an ordered list of Segment
• LiveInterval
• LiveRange with register and weight (spill cost)
********** INTERVALS **********
%vreg0 [208r,320r:0)[416B,432r:0) 0@208r
%vreg1 [16r,32r:0) 0@16r
%vreg2 [48r,480B:0) 0@48r
%vreg3 [96r,112r:0) 0@96r
%vreg4 [496r,512r:0) 0@496r
%vreg6 [224r,240r:0) 0@224r
%vreg7 [432r,448r:0) 0@432r
%vreg8 [304r,320r:0) 0@304r
%vreg9 [320r,336r:0) 0@320r
%vreg10 [352r,368r:0) 0@352r
%vreg11 [368r,384r:0) 0@368r
Segment
LiveRange
LiveInterval VNInfo
Example
192B BB#3: derived from LLVM BB %for.cond.1
208B %vreg0<def> = t2LDRi12 <fi#1>, 0
224B %vreg6<def> = t2LDRi12 <fi#2>, 0
240B t2CMPri %vreg6, 9
256B t2Bcc <BB#5>
272B t2B <BB#4>
416B BB#5: derived from LLVM BB %for.inc.4
432B %vreg7<def> = t2ADDri %vreg0, 1
448B t2STRi12 %vreg7, <fi#1>, 0
********** INTERVALS **********
%vreg0 [208r,320r:0)[416B,432r:0) 0@208r
%vreg1 [16r,32r:0) 0@16r
%vreg2 [48r,480B:0) 0@48r
%vreg3 [96r,112r:0) 0@96r
%vreg4 [496r,512r:0) 0@496r
%vreg6 [224r,240r:0) 0@224r
%vreg7 [432r,448r:0) 0@432r
%vreg8 [304r,320r:0) 0@304r
%vreg9 [320r,336r:0) 0@320r
%vreg10 [352r,368r:0) 0@352r
%vreg11 [368r,384r:0) 0@368r
288B BB#4: derived from LLVM BB %for.body.3
304B %vreg8<def> = t2LDRi12 <fi#2>, 0
320B %vreg9<def> = t2MUL %vreg0, %vreg8
336B t2STRi12 %vreg9, <fi#3>, 0
352B %vreg10<def> = t2LDRi12 <fi#2>, 0
368B %vreg11<def> = t2ADDri %vreg10, 1
384B t2STRi12 %vreg11, <fi#2>, 0
400B t2B <BB#3>
208r
320r
416B
432r
LiveRegMatrix
AH AL BH BL XMM31
V3
V3
V5
V0
V4
V1
V2
V6
RegUnit
LiveIntervalUnion
EAX => AH, AL
AX => AH, AL
AH => AH
AL => AL
Check Interference
unsigned LiveIntervalUnion::Query::
collectInterferingVRegs(unsigned MaxInterferingRegs) {
…
// Check for overlapping interference.
while (VirtRegI->start < LiveUnionI.stop() &&
VirtRegI->end > LiveUnionI.start()) {
// This is an overlap, record the interfering register.
LiveInterval *VReg = LiveUnionI.value();
if (VReg != RecentReg && !isSeenInterference(VReg)) {
RecentReg = VReg;
InterferingVRegs.push_back(VReg);
if (InterferingVRegs.size() >= MaxInterferingRegs)
return InterferingVRegs.size();
}
// This LiveUnion segment is no longer interesting.
if (!(++LiveUnionI).valid()) {
SeenAllInterferences = true;
return InterferingVRegs.size();
}
}
…
}
LiveIntervalUnion VirtReg
start()
stop()
start
end
start()
stop()
start
end
start()
stop()
start
end
start()
stop()
start
end
Check Interference
AH AL BH BL XMM31
V3
V3
V5
V0
V4
V1
V2
V6
V7
// Check the matrix for virtual register interference.
for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units)
if (query(VirtReg, *Units).checkInterference())
return IK_VirtReg;
Greedy Register
Allocation
Use Split to Improve RA
• Live Range Splitting
• Insert copy/re-materialize to split up live ranges
• hopefully reduces need for spilling
• Also control spill code placement
• Example
Q0
D0 D1
Q1
D2 D3
V1
V2
V3 V4
V5
Q0
D0 D1
Q1
D2 D3
V1
V2
V3 V4
V5
• No physical register for V1
Q0
D0 D1
Q1
D2 D3
V1
V2
V3 V4
V5
• Evict V2
Q0
D0 D1
Q1
D2 D3
V1
V2
V3V4
V5
stack
• Split V2
Q0
D0 D1
Q1
D2 D3
V1
V2b
V3V4
V5
V2a
V2c
• Split V2
Q0
D0 D1
Q1
D2 D3
V1
V2b
V3V4
V5
V2a
V2c
stack
Greedy RA Stages
• RS_New: created
• RS_Assign: enqueue
• RS_Split: need to split
• RS_Split2
• used for split products that may not be making progress
• RS_Spill: need to spill
• RS_Done: assigned a physical register or created by spill
RS_Split2
• The live intervals created by split will enqueue to
process again.
• There is a risk of creating infinite loops.
… = vreg1 …
… = vreg1 …
… = vreg1 …
vreg2 = COPY vreg1
… = vreg2 …
vreg3 = COPY vreg1
… = vreg3 …
… = vreg3 …
RS_New
RS_Split2
Greedy Register Allocation
try to assign physical register
(hint > zero cost reg > low cost reg)
try to evict to find better register
enter RS_Split
stage
try last chance
recoloring
split
spill
pick a physical register and evict all
interference
found
register
stage >= RS_Done stage < RS_Split
selectOrSplit(d+1)
enter RS_Done
stage
selectOrSplit(d)
Last Chance Recoloring
• Try to assign a color to VirtReg by recoloring its
interferences.
• The recoloring process may recursively use the
last chance recoloring. Therefore, when a virtual
register has been assigned a color by this
mechanism, it is marked as Fixed.
vA can use {R1, R2 }
vB can use { R2, R3}
vC can use {R1 }
vA => R1
vB => R2
vC => fails
vA => R2
vB => R3
vC => R1 (fixed)
How to Split?
is stage
beyond
RS_Spill?
is in one BB? tryLocalSplit
tryInstructionSplit
No
Yes
tryRegionSplit
is stage less
than RS_Split2?
No
spill
Yes
success?
No
success?
spill
No
tryBlockSplit
Yes
No
success?
No
success?
spill
No
done
Yes
Yes
done
Yes
Yes
BlockInfo
(LiveIn)
(LiveOut)
FirstInstr: First instruction accessing current reg.
LastInstr: Last instruction accessing current reg.
Live-through blocks without any uses don’t get BlockInfo entries.
tryLocalSplit
• Try to split virtual register interval into smaller
intervals inside its only basic block.
• calculate gap weights
• adjust the split region
Calculate Gap Weights
NumGaps = 4
Calculate Gap Weights
LI.weight
VirtReg LI
If there is a RegUnit occupied by VirtReg:0
0
Calculate Gap Weights
LI.weight
Fixed RegUnit
If there is a fixed RegUnit:0
0
huge_valf
Adjust Split Region
SplitAfter = 1
SplitBefore = 0
normalise
spill weight >
max gap
BestBefore = SplitBefore
BestAfter = SplitAfter
SplitAfter++
SplitBefore++
YesNo
normalise spill weight = spill cost / distance
= (#gap * block_freq) / distance(SplitBefore, SplitAfter)
Adjust Split Region
BestAfter
BestBefore
normalise
spill weight >
max gap
BestBefore = SplitBefore
BestAfter = SplitAfter
SplitAfter++
SplitBefore++
YesNo
normalise spill weight = spill cost / distance
= (#gap * block_freq) / distance(SplitBefore, SplitAfter)
RS_New
(or RS_Split2)
RS_New
Find the most critical range.
tryInstructionSplit
• Split a live range around individual instructions.
• Every “use” instruction has its own live interval.
tryBlockSplit
• Split a global live range around every block with
uses.
FirstInstr
LastInstr
tryRegionSplit
• For every physical register
• Prepare interference cache
• Construct Hopfield Network
• Construct block constraints
• Update Hopfield Network biases and values according to block
constraints
• Add links in Hopfield Network and iterate
• Get the best candidate (minimize split cost + spill cost)
• Do region split
Hopfield Network
• A form of recurrent artificial neural network popularised by John
Hopfield in 1982.
• Guaranteed to converge to a local minimum.
Hopfield Network
• Node: edge bundle
• Link: transparent basic blocks have the variable
live through.
• Energy function (the cost of spilling)
• Weight: block frequency
• Bias: according to block constraints
Block Constraints
No Interference
PrefReg
Intf.first()
MustSpill PrefSpill
FirstInstr
LastInstr
PrefReg
FirstInstr
LastInstr
FirstInstr
LastInstr
FirstInstr
LastInstr
PrefReg
MustSpill
FirstInstr
LastInstr
PrefReg
FirstInstr
LastInstr
FirstInstr
LastInstr
FirstInstr
LastInstr
PrefSpill
Last Split Point
Edge Bundle
BB #0
BB #1
BB #3
BB #2
BB #4 BB #5
BB #6
// Join the outgoing bundle with the ingoing bundles of all successors.
for (MachineBasicBlock::const_succ_iterator SI = MBB.succ_begin(),
SE = MBB.succ_end(); SI != SE; ++SI)
EC.join(OutE, 2 * (*SI)->getNumber());
EC:
(BB#0, in) Bundle #0: 0 0 0
(BB#0, out) Bundle #1: 1 1 1
(BB#1, in) Bundle #2: 2 1 1
(BB#1, out) Bundle #3: 3 3 2
(BB#2, in) Bundle #4: 4 3 2
(BB#2, out) Bundle #5: 5 5 3
(BB#3, in) Bundle #6: 6 5 3
(BB#3, out) Bundle #7: 7 7 4
(BB#4, in) Bundle #8: 8 7 4
(BB#4, out) Bundle #9: 9 5 3
(BB#5, in) Bundle #10: 10 7 4
(BB#5, out) Bundle #11: 11 1 1
(BB#6, in) Bundle #12: 12 3 2
(BB#6, out) Bundle #13: 13 13 5
void join(unsigned a, unsigned b) {
unsigned eca = EC[a];
unsigned ecb = EC[b];
while (eca != ecb)
if (eca < ecb)
EC[b] = eca, b = ecb, ecb = EC[b];
else
EC[a] = ecb, a = eca, eca = EC[a];
}
Edge Bundle
BB #0
BB #1
BB #3
BB #2
BB #4 BB #5
BB #6 Blocks:
Bundle #0: BB#0
Bundle #1: BB#0, BB#1, BB#5
Bundle #2: BB#1, BB#2, BB#6
Bundle #3: BB#2, BB#3, BB#4
Bundle #4: BB#3, BB#4, BB#5
Bundle #5: BB#6
Bundle #6:
Bundle #7:
Bundle #8:
Bundle #9:
Bundle #10:
Bundle #11:
Bundle #12:
Bundle #13:
EC:
(BB#0, in) Bundle #0: 0 0 0
(BB#0, out) Bundle #1: 1 1 1
(BB#1, in) Bundle #2: 2 1 1
(BB#1, out) Bundle #3: 3 3 2
(BB#2, in) Bundle #4: 4 3 2
(BB#2, out) Bundle #5: 5 5 3
(BB#3, in) Bundle #6: 6 5 3
(BB#3, out) Bundle #7: 7 7 4
(BB#4, in) Bundle #8: 8 7 4
(BB#4, out) Bundle #9: 9 5 3
(BB#5, in) Bundle #10: 10 7 4
(BB#5, out) Bundle #11: 11 1 1
(BB#6, in) Bundle #12: 12 3 2
(BB#6, out) Bundle #13: 13 13 5
Edge Bundle
BB #0
BB #1
BB #3
BB #2
BB #4 BB #5
BB #6 Blocks:
Bundle #0: BB#0
Bundle #1: BB#0, BB#1, BB#5
Bundle #2: BB#1, BB#2, BB#6
Bundle #3: BB#2, BB#3, BB#4
Bundle #4: BB#3, BB#4, BB#5
Bundle #5: BB#6
Bundle #6:
Bundle #7:
Bundle #8:
Bundle #9:
Bundle #10:
Bundle #11:
Bundle #12:
Bundle #13:
EC:
(BB#0, in) Bundle #0: 0 0 0
(BB#0, out) Bundle #1: 1 1 1
(BB#1, in) Bundle #2: 2 1 1
(BB#1, out) Bundle #3: 3 3 2
(BB#2, in) Bundle #4: 4 3 2
(BB#2, out) Bundle #5: 5 5 3
(BB#3, in) Bundle #6: 6 5 3
(BB#3, out) Bundle #7: 7 7 4
(BB#4, in) Bundle #8: 8 7 4
(BB#4, out) Bundle #9: 9 5 3
(BB#5, in) Bundle #10: 10 7 4
(BB#5, out) Bundle #11: 11 1 1
(BB#6, in) Bundle #12: 12 3 2
(BB#6, out) Bundle #13: 13 13 5
Edge Bundle
BB #0
BB #1
BB #3
BB #2
BB #4 BB #5
BB #6 Blocks:
Bundle #0: BB#0
Bundle #1: BB#0, BB#1, BB#5
Bundle #2: BB#1, BB#2, BB#6
Bundle #3: BB#2, BB#3, BB#4
Bundle #4: BB#3, BB#4, BB#5
Bundle #5: BB#6
Bundle #6:
Bundle #7:
Bundle #8:
Bundle #9:
Bundle #10:
Bundle #11:
Bundle #12:
Bundle #13:
EC:
(BB#0, in) Bundle #0: 0 0 0
(BB#0, out) Bundle #1: 1 1 1
(BB#1, in) Bundle #2: 2 1 1
(BB#1, out) Bundle #3: 3 3 2
(BB#2, in) Bundle #4: 4 3 2
(BB#2, out) Bundle #5: 5 5 3
(BB#3, in) Bundle #6: 6 5 3
(BB#3, out) Bundle #7: 7 7 4
(BB#4, in) Bundle #8: 8 7 4
(BB#4, out) Bundle #9: 9 5 3
(BB#5, in) Bundle #10: 10 7 4
(BB#5, out) Bundle #11: 11 1 1
(BB#6, in) Bundle #12: 12 3 2
(BB#6, out) Bundle #13: 13 13 5
Edge Bundle
BB #0
BB #1
BB #3
BB #2
BB #4 BB #5
BB #6 Blocks:
Bundle #0: BB#0
Bundle #1: BB#0, BB#1, BB#5
Bundle #2: BB#1, BB#2, BB#6
Bundle #3: BB#2, BB#3, BB#4
Bundle #4: BB#3, BB#4, BB#5
Bundle #5: BB#6
Bundle #6:
Bundle #7:
Bundle #8:
Bundle #9:
Bundle #10:
Bundle #11:
Bundle #12:
Bundle #13:
EC:
(BB#0, in) Bundle #0: 0 0 0
(BB#0, out) Bundle #1: 1 1 1
(BB#1, in) Bundle #2: 2 1 1
(BB#1, out) Bundle #3: 3 3 2
(BB#2, in) Bundle #4: 4 3 2
(BB#2, out) Bundle #5: 5 5 3
(BB#3, in) Bundle #6: 6 5 3
(BB#3, out) Bundle #7: 7 7 4
(BB#4, in) Bundle #8: 8 7 4
(BB#4, out) Bundle #9: 9 5 3
(BB#5, in) Bundle #10: 10 7 4
(BB#5, out) Bundle #11: 11 1 1
(BB#6, in) Bundle #12: 12 3 2
(BB#6, out) Bundle #13: 13 13 5
Edge Bundle
BB #0
BB #1
BB #3
BB #2
BB #4 BB #5
BB #6 Blocks:
Bundle #0: BB#0
Bundle #1: BB#0, BB#1, BB#5
Bundle #2: BB#1, BB#2, BB#6
Bundle #3: BB#2, BB#3, BB#4
Bundle #4: BB#3, BB#4, BB#5
Bundle #5: BB#6
Bundle #6:
Bundle #7:
Bundle #8:
Bundle #9:
Bundle #10:
Bundle #11:
Bundle #12:
Bundle #13:
EC:
(BB#0, in) Bundle #0: 0 0 0
(BB#0, out) Bundle #1: 1 1 1
(BB#1, in) Bundle #2: 2 1 1
(BB#1, out) Bundle #3: 3 3 2
(BB#2, in) Bundle #4: 4 3 2
(BB#2, out) Bundle #5: 5 5 3
(BB#3, in) Bundle #6: 6 5 3
(BB#3, out) Bundle #7: 7 7 4
(BB#4, in) Bundle #8: 8 7 4
(BB#4, out) Bundle #9: 9 5 3
(BB#5, in) Bundle #10: 10 7 4
(BB#5, out) Bundle #11: 11 1 1
(BB#6, in) Bundle #12: 12 3 2
(BB#6, out) Bundle #13: 13 13 5
Edge Bundle
BB #0
BB #1
BB #3
BB #2
BB #4 BB #5
BB #6 Blocks:
Bundle #0: BB#0
Bundle #1: BB#0, BB#1, BB#5
Bundle #2: BB#1, BB#2, BB#6
Bundle #3: BB#2, BB#3, BB#4
Bundle #4: BB#3, BB#4, BB#5
Bundle #5: BB#6
Bundle #6:
Bundle #7:
Bundle #8:
Bundle #9:
Bundle #10:
Bundle #11:
Bundle #12:
Bundle #13:
EC:
(BB#0, in) Bundle #0: 0 0 0
(BB#0, out) Bundle #1: 1 1 1
(BB#1, in) Bundle #2: 2 1 1
(BB#1, out) Bundle #3: 3 3 2
(BB#2, in) Bundle #4: 4 3 2
(BB#2, out) Bundle #5: 5 5 3
(BB#3, in) Bundle #6: 6 5 3
(BB#3, out) Bundle #7: 7 7 4
(BB#4, in) Bundle #8: 8 7 4
(BB#4, out) Bundle #9: 9 5 3
(BB#5, in) Bundle #10: 10 7 4
(BB#5, out) Bundle #11: 11 1 1
(BB#6, in) Bundle #12: 12 3 2
(BB#6, out) Bundle #13: 13 13 5
Edge Bundle
BB #0
BB #1
BB #3
BB #2
BB #4 BB #5
BB #6 Blocks:
Bundle #0: BB#0
Bundle #1: BB#0, BB#1, BB#5
Bundle #2: BB#1, BB#2, BB#6
Bundle #3: BB#2, BB#3, BB#4
Bundle #4: BB#3, BB#4, BB#5
Bundle #5: BB#6
Bundle #6:
Bundle #7:
Bundle #8:
Bundle #9:
Bundle #10:
Bundle #11:
Bundle #12:
Bundle #13:
EC:
(BB#0, in) Bundle #0: 0 0 0
(BB#0, out) Bundle #1: 1 1 1
(BB#1, in) Bundle #2: 2 1 1
(BB#1, out) Bundle #3: 3 3 2
(BB#2, in) Bundle #4: 4 3 2
(BB#2, out) Bundle #5: 5 5 3
(BB#3, in) Bundle #6: 6 5 3
(BB#3, out) Bundle #7: 7 7 4
(BB#4, in) Bundle #8: 8 7 4
(BB#4, out) Bundle #9: 9 5 3
(BB#5, in) Bundle #10: 10 7 4
(BB#5, out) Bundle #11: 11 1 1
(BB#6, in) Bundle #12: 12 3 2
(BB#6, out) Bundle #13: 13 13 5
SpillPlacement::addConstraints
• update BiasN, BiasP according to BorderConstraint
BB #n (freq)
… = Y op …
PrefReg
PrefSpill
Bundle ib
BiasP += freq
Bundle ob
BiasN += freq
void addBias(BlockFrequency freq, BorderConstraint direction) {
switch (direction) {
default:
break;
case PrefReg:
BiasP += freq;
break;
case PrefSpill:
BiasN += freq;
break;
case MustSpill:
BiasN = BlockFrequency::getMaxFrequency(); // (uint64_t)-1ULL
break;
}
}
Hopfield Network Node
• Node.update(nodes, Threshold)
Bundle X
BiasN
BiasP
Value
Bundle A
Value = -1
Bundle B
Value = 1
Bundle C
Value = 1
Bundle D
Value = 1
Links
SumN = BiasN + freqA
SunP = BiasP + freqB + freqC + freqD
(freqA, A) (freqB, B) (freqC, C) (freqD, D)
if (SumN >= SumP + Threshold)
Value = -1;
else if (SumP >= SumN + Threshold)
Value = 1;
else
Value = 0;
Grow Region
• Live through blocks in positive bundles.
No Interference
Intf.first()
MustSpill PrefSpill
Used as links
between bundles
SpillPlacement::addConstraints
Intf.last()
MustSpill PrefSpill
SpillPlacement::addLinks
BB #n (freq)
Bundle ib
Bundle ob
Bundle ib
Bundle ob
(freq, ob)
(freq, ib)
SpillPlacement::iterate
for (unsigned iteration = 0; iteration != 10; ++iteration) {
bool Changed = false;
for (SmallVectorImpl<unsigned>::const_reverse_iterator I =
iteration == 0 ? Linked.rbegin() : std::next(Linked.rbegin()),
E = Linked.rend(); I != E; ++I) {
unsigned n = *I;
if (nodes[n].update(nodes, Threshold)) {
Changed = true;
if (nodes[n].preferReg())
RecentPositive.push_back(n);
}
}
if (!Changed || !RecentPositive.empty())
return;
Changed = false;
for (SmallVectorImpl<unsigned>::const_iterator I =
std::next(Linked.begin()), E = Linked.end(); I != E; ++I) {
unsigned n = *I;
if (nodes[n].update(nodes, Threshold)) {
Changed = true;
if (nodes[n].preferReg())
RecentPositive.push_back(n);
}
}
if (!Changed || !RecentPositive.empty())
return;
}
Spill Cost
No Interference
PrefReg
Intf.first()
MustSpill PrefSpill
FirstInstr
LastInstr
PrefReg
FirstInstr
LastInstr
FirstInstr
LastInstr
FirstInstr
LastInstr
PrefReg
MustSpill
FirstInstr
LastInstr
PrefReg
FirstInstr
LastInstr
FirstInstr
LastInstr
FirstInstr
LastInstr
PrefSpill
Last Split Point
++Ins ++Ins ++Ins
++Ins ++Ins ++Ins
Cost = Block_Frequency * Ins
Split Cost
BB #n (freq)
… = Y op …
Bundle ib
Value
Bundle ob
Value
Use Block
RegIn
RegOut
BC.Entry
BC.Exit
if (BI.LiveIn)
Ins += RegIn != (BC.Entry == SpillPlacement::PrefReg);
if (BI.LiveOut)
Ins += RegOut != (BC.Exit == SpillPlacement::PrefReg);
while (Ins--)
GlobalCost += SpillPlacer->getBlockFrequency(BC.Number);
Live Through
BB #n (freq)
Bundle ib
Value
Bundle ob
Value
RegIn
RegOut
RegIn RegOut Cost
0 0 0
0 1 freq
1 0 freq
1 1 2 x freq
(interfer)
The Best Candidate
• For all physical registers, calculate region split
cost.
• Cost = block constraints cost (spill cost) + global
split cost
• The best candidate has the lowest cost.
Split
• splitLiveThroughBlock
• splitRegInBlock
• splitRegOutBlock
splitLiveThroughBlock
Bundle ib
Value == 1
Bundle ob
Value != 1
Live Through
LiveOut on Stack
first non-PHI
Start
New Int
Bundle ib
Value != 1
Bundle ob
Value == 1
Live Through
LiveIn on Stack
last split point
End
New Int
Live Through
No Interference
Bundle ib
Value == 1
Bundle ob
Value == 1
End
New Int
Start
splitLiveThroughBlock
Bundle ib
Value == 1
Bundle ob
Value == 1
LiveThrough
Non-overlapping interference
New Int
Interference.fist()
Interference.last()
New Int
Bundle ib
Value == 1
Bundle ob
Value == 1
LiveThrough
Overlapping interference
New Int
Interference.fist()
Interference.last()
New Int
splitRegInBlock
Bundle ib
Value == 1
No LiveOut
Interference after kill
Start
New Int
Bundle ib
Value == 1
Bundle ob
Value != 1
LiveOut on Stack
Interference after last use
LiveOut on Stack
Interference after last use
Interference.fist()
LastInstr
LastInstr
last split point
New Int
Start
Bundle ib
Value == 1
Bundle ob
Value != 1
LastInstr
last split point
New Int
Start
Interference.fist()
Interference.fist()
splitRegInBlock
Bundle ib
Value == 1
LiveOut on Stack
Interference overlapping uses
Start
New Int
Bundle ib
Value == 1
Interference.fist()
LastInstr
last split point
New Int
Start
New Int
Interference.fist()
LastInstr
last split point
New Int
Bundle ob
Value != 1
Bundle ob
Value != 1
LiveOut on Stack
Interference overlapping uses
splitRegOutBlock
No LiveIn
Interference before def
End
New Int
Bundle ib
Value != 1
Bundle ob
Value == 1
Live Through
Interference before def
Live Through
Interference overlapping uses
Interference.last()
FirstInstr
Bundle ib
Value != 1
Bundle ob
Value == 1
Bundle ob
Value == 1
End
New Int
Interference.last()
FirstInstr
last split point
End
New Int
Interference.last()
FirstInstr
New Int

More Related Content

What's hot (20)

PDF
Instruction Combine in LLVM
Wang Hsiangkai
 
PPTX
LLVM Instruction Selection
Shiva Chen
 
PPTX
LLVM Backend Porting
Shiva Chen
 
PDF
LLVM Backend の紹介
Akira Maruoka
 
PDF
Pwning in c++ (basic)
Angel Boy
 
PDF
Design and Implementation of GCC Register Allocation
Kito Cheng
 
ODP
eBPF maps 101
SUSE Labs Taipei
 
PPTX
Integrated Register Allocation introduction
Shiva Chen
 
PDF
Play with FILE Structure - Yet Another Binary Exploit Technique
Angel Boy
 
PDF
LAS16-501: Introduction to LLVM - Projects, Components, Integration, Internals
Linaro
 
PDF
A whirlwind tour of the LLVM optimizer
Nikita Popov
 
PDF
BUD17-302: LLVM Internals #2
Linaro
 
PDF
Build Programming Language Runtime with LLVM
National Cheng Kung University
 
PDF
条件分岐とcmovとmaxps
MITSUNARI Shigeo
 
PDF
DWARF Data Representation
Wang Hsiangkai
 
PDF
CRC-32
7shi
 
PDF
Git tutorial
Elli Kanal
 
PDF
組み込み関数(intrinsic)によるSIMD入門
Norishige Fukushima
 
PDF
Heap exploitation
Angel Boy
 
PPT
Gcc porting
Shiva Chen
 
Instruction Combine in LLVM
Wang Hsiangkai
 
LLVM Instruction Selection
Shiva Chen
 
LLVM Backend Porting
Shiva Chen
 
LLVM Backend の紹介
Akira Maruoka
 
Pwning in c++ (basic)
Angel Boy
 
Design and Implementation of GCC Register Allocation
Kito Cheng
 
eBPF maps 101
SUSE Labs Taipei
 
Integrated Register Allocation introduction
Shiva Chen
 
Play with FILE Structure - Yet Another Binary Exploit Technique
Angel Boy
 
LAS16-501: Introduction to LLVM - Projects, Components, Integration, Internals
Linaro
 
A whirlwind tour of the LLVM optimizer
Nikita Popov
 
BUD17-302: LLVM Internals #2
Linaro
 
Build Programming Language Runtime with LLVM
National Cheng Kung University
 
条件分岐とcmovとmaxps
MITSUNARI Shigeo
 
DWARF Data Representation
Wang Hsiangkai
 
CRC-32
7shi
 
Git tutorial
Elli Kanal
 
組み込み関数(intrinsic)によるSIMD入門
Norishige Fukushima
 
Heap exploitation
Angel Boy
 
Gcc porting
Shiva Chen
 

Similar to LLVM Register Allocation (20)

PPTX
The Little Register Allocator
Ian Wang
 
PDF
Code generation in Compiler Design
Kuppusamy P
 
PPT
COMPILER_DESIGN_CLASS 2.ppt
ssuserebb9821
 
PPTX
COMPILER_DESIGN_CLASS 1.pptx
ssuserebb9821
 
PPTX
Code Generation Part-3 in Compiler Construction
ProfMonikaShah
 
PDF
Register Allocation
Eelco Visser
 
PPT
0015.register allocation-graph-coloring
sean chen
 
PDF
Part II: LLVM Intermediate Representation
Wei-Ren Chen
 
PDF
TMPA-2017: Vellvm - Verifying the LLVM
Iosif Itkin
 
PPT
Code Generations - 1 compiler design.ppt
SreepriyaPilla
 
PDF
PPU Optimisation Lesson
slantsixgames
 
PDF
OptimizingARM
Jan-Lieuwe Koopmans
 
PDF
This is my code- #include -llvm-IR-LegacyPassManager-h- #include -llv.pdf
EricvtJFraserr
 
PPTX
Arm instruction set
PriyangaKR1
 
PPT
Single instruction multiple data
Syed Zaid Irshad
 
PPTX
Chapter_04_ARM_Assembly.pptx ARM ASSEMBLY CODE
NagarathnaRajur2
 
PPTX
UNIT IV Compiler.pptx RUNTIMEENVIRONMENT
KavithaNagendran1
 
PPTX
Как работает LLVM бэкенд в C#. Егор Богатов ➠ CoreHard Autumn 2019
corehard_by
 
PDF
LLVM Overview
Constantin Lungu
 
The Little Register Allocator
Ian Wang
 
Code generation in Compiler Design
Kuppusamy P
 
COMPILER_DESIGN_CLASS 2.ppt
ssuserebb9821
 
COMPILER_DESIGN_CLASS 1.pptx
ssuserebb9821
 
Code Generation Part-3 in Compiler Construction
ProfMonikaShah
 
Register Allocation
Eelco Visser
 
0015.register allocation-graph-coloring
sean chen
 
Part II: LLVM Intermediate Representation
Wei-Ren Chen
 
TMPA-2017: Vellvm - Verifying the LLVM
Iosif Itkin
 
Code Generations - 1 compiler design.ppt
SreepriyaPilla
 
PPU Optimisation Lesson
slantsixgames
 
OptimizingARM
Jan-Lieuwe Koopmans
 
This is my code- #include -llvm-IR-LegacyPassManager-h- #include -llv.pdf
EricvtJFraserr
 
Arm instruction set
PriyangaKR1
 
Single instruction multiple data
Syed Zaid Irshad
 
Chapter_04_ARM_Assembly.pptx ARM ASSEMBLY CODE
NagarathnaRajur2
 
UNIT IV Compiler.pptx RUNTIMEENVIRONMENT
KavithaNagendran1
 
Как работает LLVM бэкенд в C#. Егор Богатов ➠ CoreHard Autumn 2019
corehard_by
 
LLVM Overview
Constantin Lungu
 
Ad

More from Wang Hsiangkai (10)

PDF
Debug Line Issues After Relaxation.
Wang Hsiangkai
 
PDF
Machine Trace Metrics
Wang Hsiangkai
 
PDF
GCC LTO
Wang Hsiangkai
 
PDF
LTO plugin
Wang Hsiangkai
 
PDF
Something About Dynamic Linking
Wang Hsiangkai
 
PDF
Effective Modern C++
Wang Hsiangkai
 
PDF
GCC GENERIC
Wang Hsiangkai
 
PDF
Perf File Format
Wang Hsiangkai
 
PDF
Introduction to Perf
Wang Hsiangkai
 
PDF
SSA - PHI-functions Placements
Wang Hsiangkai
 
Debug Line Issues After Relaxation.
Wang Hsiangkai
 
Machine Trace Metrics
Wang Hsiangkai
 
LTO plugin
Wang Hsiangkai
 
Something About Dynamic Linking
Wang Hsiangkai
 
Effective Modern C++
Wang Hsiangkai
 
GCC GENERIC
Wang Hsiangkai
 
Perf File Format
Wang Hsiangkai
 
Introduction to Perf
Wang Hsiangkai
 
SSA - PHI-functions Placements
Wang Hsiangkai
 
Ad

Recently uploaded (20)

PDF
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
PPTX
Finding Your License Details in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
Dipole Tech Innovations – Global IT Solutions for Business Growth
dipoletechi3
 
PDF
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
PPTX
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
PDF
ERP Consulting Services and Solutions by Contetra Pvt Ltd
jayjani123
 
PDF
AI Prompts Cheat Code prompt engineering
Avijit Kumar Roy
 
PPTX
Build a Custom Agent for Agentic Testing.pptx
klpathrudu
 
PPTX
OpenChain @ OSS NA - In From the Cold: Open Source as Part of Mainstream Soft...
Shane Coughlan
 
PDF
Wondershare PDFelement Pro Crack for MacOS New Version Latest 2025
bashirkhan333g
 
PPTX
Get Started with Maestro: Agent, Robot, and Human in Action – Session 5 of 5
klpathrudu
 
PDF
Technical-Careers-Roadmap-in-Software-Market.pdf
Hussein Ali
 
PPTX
Comprehensive Risk Assessment Module for Smarter Risk Management
EHA Soft Solutions
 
PPTX
Customise Your Correlation Table in IBM SPSS Statistics.pptx
Version 1 Analytics
 
PDF
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
PPTX
Coefficient of Variance in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
PDF
Add Background Images to Charts in IBM SPSS Statistics Version 31.pdf
Version 1 Analytics
 
PPTX
Change Common Properties in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
Simplify React app login with asgardeo-sdk
vaibhav289687
 
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
Finding Your License Details in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
Dipole Tech Innovations – Global IT Solutions for Business Growth
dipoletechi3
 
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
ERP Consulting Services and Solutions by Contetra Pvt Ltd
jayjani123
 
AI Prompts Cheat Code prompt engineering
Avijit Kumar Roy
 
Build a Custom Agent for Agentic Testing.pptx
klpathrudu
 
OpenChain @ OSS NA - In From the Cold: Open Source as Part of Mainstream Soft...
Shane Coughlan
 
Wondershare PDFelement Pro Crack for MacOS New Version Latest 2025
bashirkhan333g
 
Get Started with Maestro: Agent, Robot, and Human in Action – Session 5 of 5
klpathrudu
 
Technical-Careers-Roadmap-in-Software-Market.pdf
Hussein Ali
 
Comprehensive Risk Assessment Module for Smarter Risk Management
EHA Soft Solutions
 
Customise Your Correlation Table in IBM SPSS Statistics.pptx
Version 1 Analytics
 
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
Coefficient of Variance in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
Add Background Images to Charts in IBM SPSS Statistics Version 31.pdf
Version 1 Analytics
 
Change Common Properties in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
Simplify React app login with asgardeo-sdk
vaibhav289687
 

LLVM Register Allocation

  • 2. Outline • Introduction to Register Allocation Problem • LLVM Base Register Allocation Interface • LLVM Basic Register Allocation • LLVM Greedy Register Allocation
  • 3. Introduction to Register Allocation • Definition • Register allocation is the problem of mapping program variables to either machine registers or memory addresses. • Best solution • minimise the number of loads/stores from/to memory • NP-complete
  • 4. int main() { int i, j; int answer; for (i = 1; i < 10; i++) for (j = 1; j < 10; j++) { answer = i * j; } return 0; } _main: @ BB#0: sub sp, #16 movs r0, #0 str r0, [sp, #12] movs r0, #1 str r0, [sp, #8] b LBB0_2 LBB0_1: adds r1, #1 str r1, [sp, #8] LBB0_2: ldr r1, [sp, #8] cmp r1, #9 bgt LBB0_6 @ BB#3: str r0, [sp, #4] b LBB0_5 LBB0_4: ldr r2, [sp, #4] muls r1, r2, r1 str r1, [sp] ldr r1, [sp, #4] adds r1, #1
  • 5. Graph Coloring • For an arbitrary graph G; a coloring of G assigns a color to each node in G so that no pair of adjacent nodes have the same color. 2-colorable 3-colorable
  • 6. Graph Coloring for RA • Node: Live interval • Edge: Two live intervals have interference • Color: Physical register • Find a feasible colouring for the graph
  • 7. … a0 = … b0 = … … = b0 d0 = … c0 = … … d1 = c0 … = a0 … = d1 B0 B1 B2 B3 … LIa = … LIb = … … = LIb LIc = … … LId = LIc … = LIa … = LId B0 B1 B2 B3
  • 8. LRa LRb LRc LRd … LIa = … LIb = … … = LIb LIc = … … LId = LIc … = LIa … = LId B0 B1 B2 B3 An Example from “Engineering A Compiler”
  • 9. Why Not Graph Coloring • Interference graph is expensive to build • Spill code placement is more important than colouring • Need to model aliases and overlapping register classes • Flexibility is more important than the coloring algorithm (Adopted from “Register Allocation in LLVM 3.0”)
  • 10. Excerpt from tricore_llvm.pdf SSA Properties * Each definition in the procedure creates a unique name. * Each use refers to a single definition.
  • 11. LLVM Register Allocation • Basic • Provide a minimal implementation of the basic register allocator • Greedy • Global live range splitting. • Fast • This register allocator allocates registers to a basic block at a time. • PBQP • Partitioned Boolean Quadratic Programming (PBQP) based register allocator for LLVM
  • 12. LLVM Base Register Allocation Interface Calculate LiveInterval Weight Enqueue All LiveInterval selectOrSplit for One LiveInterval Assign the Physical Register Enqueue Split LiveInterval dequeue physical register is available split live interval update LiveInterval.weight (spill cost) allocatePhysRegs enqueue seedLiveRegs Q customised by new RA algorithm for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) { unsigned Reg = TargetRegisterInfo::index2VirtReg(i); if (MRI->reg_nodbg_empty(Reg)) continue; enqueue(&LIS->getInterval(Reg)); }
  • 13. LLVM Basic Register Allocation Calculate LiveInterval Weight Enqueue All LiveInterval RABasic::selectOrSplit Assign the Physical Register Enqueue Split LiveInterval dequeue physical register is available split live interval update LiveInterval.weight (spill cost) allocatePhysRegs enqueue seedLiveRegs priority Q (spill cost) customised by RABasic algorithm struct CompSpillWeight { bool operator()(LiveInterval *A, LiveInterval *B) const { return A->weight < B->weight; } }; // Check for an available register in this class. AllocationOrder Order(VirtReg.reg, *VRM, RegClassInfo); while (unsigned PhysReg = Order.next()) { // Check for interference in PhysReg switch (Matrix->checkInterference(VirtReg, PhysReg)) { case LiveRegMatrix::IK_Free: // PhysReg is available, allocate it. return PhysReg; case LiveRegMatrix::IK_VirtReg: // Only virtual registers in the way, we may be able to spill them. PhysRegSpillCands.push_back(PhysReg); continue; default: // RegMask or RegUnit interference. continue; } }
  • 14. LiveInterval Weight • Weight for one instruction with the register • weight = (isDef + isUse) * (Block Frequency / Entry Frequency) • loop induction variable: weight *= 3 • For all instructions with the register • totalWeight += weight • Hint: totalWeight *= 1.01 • Re-materializable: totalWeight *= 0.5 • LiveInterval.weight = totalWeight / size of LiveInterval
  • 15. Matrix->checkInterference() • How to represent live/dead points? • SlotIndex • How to represent a value? • VNInfo • How to represent a live interval? • LiveInterval • How to check interference between live intervals? • LiveIntervalUnion & LiveRegMatrix
  • 16. Liveness Slot • There are four kind of slots to describe a position at which a register can become live, or cease to be live. • Block (B) • entering or leaving a block • PHI-def • Early Clobber (e) • kill slot for early-clobber def • A = A op B ( ) • Register (r) • normal register use/def slot • Dead (d) • dead def ********** INTERVALS ********** %vreg0 [208r,320r:0)[416B,432r:0) 0@208r %vreg1 [16r,32r:0) 0@16r %vreg2 [48r,480B:0) 0@48r %vreg3 [96r,112r:0) 0@96r %vreg4 [496r,512r:0) 0@496r %vreg6 [224r,240r:0) 0@224r %vreg7 [432r,448r:0) 0@432r %vreg8 [304r,320r:0) 0@304r %vreg9 [320r,336r:0) 0@320r %vreg10 [352r,368r:0) 0@352r %vreg11 [368r,384r:0) 0@368r
  • 17. SlotIndex ((MachineInstr *, index), slot) Slot_Block Slot_EarlyClobber Slot_Register Slot_Dead unsigned getIndex() const { return listEntry()->getIndex() | getSlot(); } listEntry()
  • 18. Numbering of Machine Instruction 0B BB#0: derived from LLVM BB %entry 16B %vreg1<def> = t2MOVi 0, pred:14, pred:%noreg, opt:%noreg; rGPR:%vreg1 32B t2STRi12 %vreg1, <fi#0>, 0, pred:14, pred:%noreg; mem:ST4[%retval] rGPR:%vreg1 48B %vreg2<def> = t2MOVi 1, pred:14, pred:%noreg, opt:%noreg; rGPR:%vreg2 64B t2STRi12 %vreg2, <fi#1>, 0, pred:14, pred:%noreg; mem:ST4[%i] rGPR:%vreg2 Successors according to CFG: BB#1 for (MachineBasicBlock::iterator miItr = mbb->begin(), miEnd = mbb->end(); miItr != miEnd; ++miItr) { MachineInstr *mi = miItr; if (mi->isDebugValue()) continue; // Insert a store index for the instr. indexList.push_back(createEntry(mi, index += SlotIndex::InstrDist)); // Save this base index in the maps. mi2iMap.insert(std::make_pair(mi, SlotIndex(&indexList.back(), SlotIndex::Slot_Block))); }
  • 19. VNInfo • hold information about a machine level value • (id, def) • def: SlotIndex of the defining instruction
  • 20. Live Interval • Segment • start, end, valno • LiveRange • an ordered list of Segment • LiveInterval • LiveRange with register and weight (spill cost) ********** INTERVALS ********** %vreg0 [208r,320r:0)[416B,432r:0) 0@208r %vreg1 [16r,32r:0) 0@16r %vreg2 [48r,480B:0) 0@48r %vreg3 [96r,112r:0) 0@96r %vreg4 [496r,512r:0) 0@496r %vreg6 [224r,240r:0) 0@224r %vreg7 [432r,448r:0) 0@432r %vreg8 [304r,320r:0) 0@304r %vreg9 [320r,336r:0) 0@320r %vreg10 [352r,368r:0) 0@352r %vreg11 [368r,384r:0) 0@368r Segment LiveRange LiveInterval VNInfo
  • 21. Example 192B BB#3: derived from LLVM BB %for.cond.1 208B %vreg0<def> = t2LDRi12 <fi#1>, 0 224B %vreg6<def> = t2LDRi12 <fi#2>, 0 240B t2CMPri %vreg6, 9 256B t2Bcc <BB#5> 272B t2B <BB#4> 416B BB#5: derived from LLVM BB %for.inc.4 432B %vreg7<def> = t2ADDri %vreg0, 1 448B t2STRi12 %vreg7, <fi#1>, 0 ********** INTERVALS ********** %vreg0 [208r,320r:0)[416B,432r:0) 0@208r %vreg1 [16r,32r:0) 0@16r %vreg2 [48r,480B:0) 0@48r %vreg3 [96r,112r:0) 0@96r %vreg4 [496r,512r:0) 0@496r %vreg6 [224r,240r:0) 0@224r %vreg7 [432r,448r:0) 0@432r %vreg8 [304r,320r:0) 0@304r %vreg9 [320r,336r:0) 0@320r %vreg10 [352r,368r:0) 0@352r %vreg11 [368r,384r:0) 0@368r 288B BB#4: derived from LLVM BB %for.body.3 304B %vreg8<def> = t2LDRi12 <fi#2>, 0 320B %vreg9<def> = t2MUL %vreg0, %vreg8 336B t2STRi12 %vreg9, <fi#3>, 0 352B %vreg10<def> = t2LDRi12 <fi#2>, 0 368B %vreg11<def> = t2ADDri %vreg10, 1 384B t2STRi12 %vreg11, <fi#2>, 0 400B t2B <BB#3> 208r 320r 416B 432r
  • 22. LiveRegMatrix AH AL BH BL XMM31 V3 V3 V5 V0 V4 V1 V2 V6 RegUnit LiveIntervalUnion EAX => AH, AL AX => AH, AL AH => AH AL => AL
  • 23. Check Interference unsigned LiveIntervalUnion::Query:: collectInterferingVRegs(unsigned MaxInterferingRegs) { … // Check for overlapping interference. while (VirtRegI->start < LiveUnionI.stop() && VirtRegI->end > LiveUnionI.start()) { // This is an overlap, record the interfering register. LiveInterval *VReg = LiveUnionI.value(); if (VReg != RecentReg && !isSeenInterference(VReg)) { RecentReg = VReg; InterferingVRegs.push_back(VReg); if (InterferingVRegs.size() >= MaxInterferingRegs) return InterferingVRegs.size(); } // This LiveUnion segment is no longer interesting. if (!(++LiveUnionI).valid()) { SeenAllInterferences = true; return InterferingVRegs.size(); } } … } LiveIntervalUnion VirtReg start() stop() start end start() stop() start end start() stop() start end start() stop() start end
  • 24. Check Interference AH AL BH BL XMM31 V3 V3 V5 V0 V4 V1 V2 V6 V7 // Check the matrix for virtual register interference. for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) if (query(VirtReg, *Units).checkInterference()) return IK_VirtReg;
  • 26. Use Split to Improve RA • Live Range Splitting • Insert copy/re-materialize to split up live ranges • hopefully reduces need for spilling • Also control spill code placement
  • 27. • Example Q0 D0 D1 Q1 D2 D3 V1 V2 V3 V4 V5
  • 29. • No physical register for V1 Q0 D0 D1 Q1 D2 D3 V1 V2 V3 V4 V5
  • 30. • Evict V2 Q0 D0 D1 Q1 D2 D3 V1 V2 V3V4 V5 stack
  • 31. • Split V2 Q0 D0 D1 Q1 D2 D3 V1 V2b V3V4 V5 V2a V2c
  • 32. • Split V2 Q0 D0 D1 Q1 D2 D3 V1 V2b V3V4 V5 V2a V2c stack
  • 33. Greedy RA Stages • RS_New: created • RS_Assign: enqueue • RS_Split: need to split • RS_Split2 • used for split products that may not be making progress • RS_Spill: need to spill • RS_Done: assigned a physical register or created by spill
  • 34. RS_Split2 • The live intervals created by split will enqueue to process again. • There is a risk of creating infinite loops. … = vreg1 … … = vreg1 … … = vreg1 … vreg2 = COPY vreg1 … = vreg2 … vreg3 = COPY vreg1 … = vreg3 … … = vreg3 … RS_New RS_Split2
  • 35. Greedy Register Allocation try to assign physical register (hint > zero cost reg > low cost reg) try to evict to find better register enter RS_Split stage try last chance recoloring split spill pick a physical register and evict all interference found register stage >= RS_Done stage < RS_Split selectOrSplit(d+1) enter RS_Done stage selectOrSplit(d)
  • 36. Last Chance Recoloring • Try to assign a color to VirtReg by recoloring its interferences. • The recoloring process may recursively use the last chance recoloring. Therefore, when a virtual register has been assigned a color by this mechanism, it is marked as Fixed. vA can use {R1, R2 } vB can use { R2, R3} vC can use {R1 } vA => R1 vB => R2 vC => fails vA => R2 vB => R3 vC => R1 (fixed)
  • 37. How to Split? is stage beyond RS_Spill? is in one BB? tryLocalSplit tryInstructionSplit No Yes tryRegionSplit is stage less than RS_Split2? No spill Yes success? No success? spill No tryBlockSplit Yes No success? No success? spill No done Yes Yes done Yes Yes
  • 38. BlockInfo (LiveIn) (LiveOut) FirstInstr: First instruction accessing current reg. LastInstr: Last instruction accessing current reg. Live-through blocks without any uses don’t get BlockInfo entries.
  • 39. tryLocalSplit • Try to split virtual register interval into smaller intervals inside its only basic block. • calculate gap weights • adjust the split region
  • 41. Calculate Gap Weights LI.weight VirtReg LI If there is a RegUnit occupied by VirtReg:0 0
  • 42. Calculate Gap Weights LI.weight Fixed RegUnit If there is a fixed RegUnit:0 0 huge_valf
  • 43. Adjust Split Region SplitAfter = 1 SplitBefore = 0 normalise spill weight > max gap BestBefore = SplitBefore BestAfter = SplitAfter SplitAfter++ SplitBefore++ YesNo normalise spill weight = spill cost / distance = (#gap * block_freq) / distance(SplitBefore, SplitAfter)
  • 44. Adjust Split Region BestAfter BestBefore normalise spill weight > max gap BestBefore = SplitBefore BestAfter = SplitAfter SplitAfter++ SplitBefore++ YesNo normalise spill weight = spill cost / distance = (#gap * block_freq) / distance(SplitBefore, SplitAfter) RS_New (or RS_Split2) RS_New Find the most critical range.
  • 45. tryInstructionSplit • Split a live range around individual instructions. • Every “use” instruction has its own live interval.
  • 46. tryBlockSplit • Split a global live range around every block with uses. FirstInstr LastInstr
  • 47. tryRegionSplit • For every physical register • Prepare interference cache • Construct Hopfield Network • Construct block constraints • Update Hopfield Network biases and values according to block constraints • Add links in Hopfield Network and iterate • Get the best candidate (minimize split cost + spill cost) • Do region split
  • 48. Hopfield Network • A form of recurrent artificial neural network popularised by John Hopfield in 1982. • Guaranteed to converge to a local minimum.
  • 49. Hopfield Network • Node: edge bundle • Link: transparent basic blocks have the variable live through. • Energy function (the cost of spilling) • Weight: block frequency • Bias: according to block constraints
  • 50. Block Constraints No Interference PrefReg Intf.first() MustSpill PrefSpill FirstInstr LastInstr PrefReg FirstInstr LastInstr FirstInstr LastInstr FirstInstr LastInstr PrefReg MustSpill FirstInstr LastInstr PrefReg FirstInstr LastInstr FirstInstr LastInstr FirstInstr LastInstr PrefSpill Last Split Point
  • 51. Edge Bundle BB #0 BB #1 BB #3 BB #2 BB #4 BB #5 BB #6 // Join the outgoing bundle with the ingoing bundles of all successors. for (MachineBasicBlock::const_succ_iterator SI = MBB.succ_begin(), SE = MBB.succ_end(); SI != SE; ++SI) EC.join(OutE, 2 * (*SI)->getNumber()); EC: (BB#0, in) Bundle #0: 0 0 0 (BB#0, out) Bundle #1: 1 1 1 (BB#1, in) Bundle #2: 2 1 1 (BB#1, out) Bundle #3: 3 3 2 (BB#2, in) Bundle #4: 4 3 2 (BB#2, out) Bundle #5: 5 5 3 (BB#3, in) Bundle #6: 6 5 3 (BB#3, out) Bundle #7: 7 7 4 (BB#4, in) Bundle #8: 8 7 4 (BB#4, out) Bundle #9: 9 5 3 (BB#5, in) Bundle #10: 10 7 4 (BB#5, out) Bundle #11: 11 1 1 (BB#6, in) Bundle #12: 12 3 2 (BB#6, out) Bundle #13: 13 13 5 void join(unsigned a, unsigned b) { unsigned eca = EC[a]; unsigned ecb = EC[b]; while (eca != ecb) if (eca < ecb) EC[b] = eca, b = ecb, ecb = EC[b]; else EC[a] = ecb, a = eca, eca = EC[a]; }
  • 52. Edge Bundle BB #0 BB #1 BB #3 BB #2 BB #4 BB #5 BB #6 Blocks: Bundle #0: BB#0 Bundle #1: BB#0, BB#1, BB#5 Bundle #2: BB#1, BB#2, BB#6 Bundle #3: BB#2, BB#3, BB#4 Bundle #4: BB#3, BB#4, BB#5 Bundle #5: BB#6 Bundle #6: Bundle #7: Bundle #8: Bundle #9: Bundle #10: Bundle #11: Bundle #12: Bundle #13: EC: (BB#0, in) Bundle #0: 0 0 0 (BB#0, out) Bundle #1: 1 1 1 (BB#1, in) Bundle #2: 2 1 1 (BB#1, out) Bundle #3: 3 3 2 (BB#2, in) Bundle #4: 4 3 2 (BB#2, out) Bundle #5: 5 5 3 (BB#3, in) Bundle #6: 6 5 3 (BB#3, out) Bundle #7: 7 7 4 (BB#4, in) Bundle #8: 8 7 4 (BB#4, out) Bundle #9: 9 5 3 (BB#5, in) Bundle #10: 10 7 4 (BB#5, out) Bundle #11: 11 1 1 (BB#6, in) Bundle #12: 12 3 2 (BB#6, out) Bundle #13: 13 13 5
  • 53. Edge Bundle BB #0 BB #1 BB #3 BB #2 BB #4 BB #5 BB #6 Blocks: Bundle #0: BB#0 Bundle #1: BB#0, BB#1, BB#5 Bundle #2: BB#1, BB#2, BB#6 Bundle #3: BB#2, BB#3, BB#4 Bundle #4: BB#3, BB#4, BB#5 Bundle #5: BB#6 Bundle #6: Bundle #7: Bundle #8: Bundle #9: Bundle #10: Bundle #11: Bundle #12: Bundle #13: EC: (BB#0, in) Bundle #0: 0 0 0 (BB#0, out) Bundle #1: 1 1 1 (BB#1, in) Bundle #2: 2 1 1 (BB#1, out) Bundle #3: 3 3 2 (BB#2, in) Bundle #4: 4 3 2 (BB#2, out) Bundle #5: 5 5 3 (BB#3, in) Bundle #6: 6 5 3 (BB#3, out) Bundle #7: 7 7 4 (BB#4, in) Bundle #8: 8 7 4 (BB#4, out) Bundle #9: 9 5 3 (BB#5, in) Bundle #10: 10 7 4 (BB#5, out) Bundle #11: 11 1 1 (BB#6, in) Bundle #12: 12 3 2 (BB#6, out) Bundle #13: 13 13 5
  • 54. Edge Bundle BB #0 BB #1 BB #3 BB #2 BB #4 BB #5 BB #6 Blocks: Bundle #0: BB#0 Bundle #1: BB#0, BB#1, BB#5 Bundle #2: BB#1, BB#2, BB#6 Bundle #3: BB#2, BB#3, BB#4 Bundle #4: BB#3, BB#4, BB#5 Bundle #5: BB#6 Bundle #6: Bundle #7: Bundle #8: Bundle #9: Bundle #10: Bundle #11: Bundle #12: Bundle #13: EC: (BB#0, in) Bundle #0: 0 0 0 (BB#0, out) Bundle #1: 1 1 1 (BB#1, in) Bundle #2: 2 1 1 (BB#1, out) Bundle #3: 3 3 2 (BB#2, in) Bundle #4: 4 3 2 (BB#2, out) Bundle #5: 5 5 3 (BB#3, in) Bundle #6: 6 5 3 (BB#3, out) Bundle #7: 7 7 4 (BB#4, in) Bundle #8: 8 7 4 (BB#4, out) Bundle #9: 9 5 3 (BB#5, in) Bundle #10: 10 7 4 (BB#5, out) Bundle #11: 11 1 1 (BB#6, in) Bundle #12: 12 3 2 (BB#6, out) Bundle #13: 13 13 5
  • 55. Edge Bundle BB #0 BB #1 BB #3 BB #2 BB #4 BB #5 BB #6 Blocks: Bundle #0: BB#0 Bundle #1: BB#0, BB#1, BB#5 Bundle #2: BB#1, BB#2, BB#6 Bundle #3: BB#2, BB#3, BB#4 Bundle #4: BB#3, BB#4, BB#5 Bundle #5: BB#6 Bundle #6: Bundle #7: Bundle #8: Bundle #9: Bundle #10: Bundle #11: Bundle #12: Bundle #13: EC: (BB#0, in) Bundle #0: 0 0 0 (BB#0, out) Bundle #1: 1 1 1 (BB#1, in) Bundle #2: 2 1 1 (BB#1, out) Bundle #3: 3 3 2 (BB#2, in) Bundle #4: 4 3 2 (BB#2, out) Bundle #5: 5 5 3 (BB#3, in) Bundle #6: 6 5 3 (BB#3, out) Bundle #7: 7 7 4 (BB#4, in) Bundle #8: 8 7 4 (BB#4, out) Bundle #9: 9 5 3 (BB#5, in) Bundle #10: 10 7 4 (BB#5, out) Bundle #11: 11 1 1 (BB#6, in) Bundle #12: 12 3 2 (BB#6, out) Bundle #13: 13 13 5
  • 56. Edge Bundle BB #0 BB #1 BB #3 BB #2 BB #4 BB #5 BB #6 Blocks: Bundle #0: BB#0 Bundle #1: BB#0, BB#1, BB#5 Bundle #2: BB#1, BB#2, BB#6 Bundle #3: BB#2, BB#3, BB#4 Bundle #4: BB#3, BB#4, BB#5 Bundle #5: BB#6 Bundle #6: Bundle #7: Bundle #8: Bundle #9: Bundle #10: Bundle #11: Bundle #12: Bundle #13: EC: (BB#0, in) Bundle #0: 0 0 0 (BB#0, out) Bundle #1: 1 1 1 (BB#1, in) Bundle #2: 2 1 1 (BB#1, out) Bundle #3: 3 3 2 (BB#2, in) Bundle #4: 4 3 2 (BB#2, out) Bundle #5: 5 5 3 (BB#3, in) Bundle #6: 6 5 3 (BB#3, out) Bundle #7: 7 7 4 (BB#4, in) Bundle #8: 8 7 4 (BB#4, out) Bundle #9: 9 5 3 (BB#5, in) Bundle #10: 10 7 4 (BB#5, out) Bundle #11: 11 1 1 (BB#6, in) Bundle #12: 12 3 2 (BB#6, out) Bundle #13: 13 13 5
  • 57. Edge Bundle BB #0 BB #1 BB #3 BB #2 BB #4 BB #5 BB #6 Blocks: Bundle #0: BB#0 Bundle #1: BB#0, BB#1, BB#5 Bundle #2: BB#1, BB#2, BB#6 Bundle #3: BB#2, BB#3, BB#4 Bundle #4: BB#3, BB#4, BB#5 Bundle #5: BB#6 Bundle #6: Bundle #7: Bundle #8: Bundle #9: Bundle #10: Bundle #11: Bundle #12: Bundle #13: EC: (BB#0, in) Bundle #0: 0 0 0 (BB#0, out) Bundle #1: 1 1 1 (BB#1, in) Bundle #2: 2 1 1 (BB#1, out) Bundle #3: 3 3 2 (BB#2, in) Bundle #4: 4 3 2 (BB#2, out) Bundle #5: 5 5 3 (BB#3, in) Bundle #6: 6 5 3 (BB#3, out) Bundle #7: 7 7 4 (BB#4, in) Bundle #8: 8 7 4 (BB#4, out) Bundle #9: 9 5 3 (BB#5, in) Bundle #10: 10 7 4 (BB#5, out) Bundle #11: 11 1 1 (BB#6, in) Bundle #12: 12 3 2 (BB#6, out) Bundle #13: 13 13 5
  • 58. Edge Bundle BB #0 BB #1 BB #3 BB #2 BB #4 BB #5 BB #6 Blocks: Bundle #0: BB#0 Bundle #1: BB#0, BB#1, BB#5 Bundle #2: BB#1, BB#2, BB#6 Bundle #3: BB#2, BB#3, BB#4 Bundle #4: BB#3, BB#4, BB#5 Bundle #5: BB#6 Bundle #6: Bundle #7: Bundle #8: Bundle #9: Bundle #10: Bundle #11: Bundle #12: Bundle #13: EC: (BB#0, in) Bundle #0: 0 0 0 (BB#0, out) Bundle #1: 1 1 1 (BB#1, in) Bundle #2: 2 1 1 (BB#1, out) Bundle #3: 3 3 2 (BB#2, in) Bundle #4: 4 3 2 (BB#2, out) Bundle #5: 5 5 3 (BB#3, in) Bundle #6: 6 5 3 (BB#3, out) Bundle #7: 7 7 4 (BB#4, in) Bundle #8: 8 7 4 (BB#4, out) Bundle #9: 9 5 3 (BB#5, in) Bundle #10: 10 7 4 (BB#5, out) Bundle #11: 11 1 1 (BB#6, in) Bundle #12: 12 3 2 (BB#6, out) Bundle #13: 13 13 5
  • 59. SpillPlacement::addConstraints • update BiasN, BiasP according to BorderConstraint BB #n (freq) … = Y op … PrefReg PrefSpill Bundle ib BiasP += freq Bundle ob BiasN += freq void addBias(BlockFrequency freq, BorderConstraint direction) { switch (direction) { default: break; case PrefReg: BiasP += freq; break; case PrefSpill: BiasN += freq; break; case MustSpill: BiasN = BlockFrequency::getMaxFrequency(); // (uint64_t)-1ULL break; } }
  • 60. Hopfield Network Node • Node.update(nodes, Threshold) Bundle X BiasN BiasP Value Bundle A Value = -1 Bundle B Value = 1 Bundle C Value = 1 Bundle D Value = 1 Links SumN = BiasN + freqA SunP = BiasP + freqB + freqC + freqD (freqA, A) (freqB, B) (freqC, C) (freqD, D) if (SumN >= SumP + Threshold) Value = -1; else if (SumP >= SumN + Threshold) Value = 1; else Value = 0;
  • 61. Grow Region • Live through blocks in positive bundles. No Interference Intf.first() MustSpill PrefSpill Used as links between bundles SpillPlacement::addConstraints Intf.last() MustSpill PrefSpill
  • 62. SpillPlacement::addLinks BB #n (freq) Bundle ib Bundle ob Bundle ib Bundle ob (freq, ob) (freq, ib)
  • 63. SpillPlacement::iterate for (unsigned iteration = 0; iteration != 10; ++iteration) { bool Changed = false; for (SmallVectorImpl<unsigned>::const_reverse_iterator I = iteration == 0 ? Linked.rbegin() : std::next(Linked.rbegin()), E = Linked.rend(); I != E; ++I) { unsigned n = *I; if (nodes[n].update(nodes, Threshold)) { Changed = true; if (nodes[n].preferReg()) RecentPositive.push_back(n); } } if (!Changed || !RecentPositive.empty()) return; Changed = false; for (SmallVectorImpl<unsigned>::const_iterator I = std::next(Linked.begin()), E = Linked.end(); I != E; ++I) { unsigned n = *I; if (nodes[n].update(nodes, Threshold)) { Changed = true; if (nodes[n].preferReg()) RecentPositive.push_back(n); } } if (!Changed || !RecentPositive.empty()) return; }
  • 64. Spill Cost No Interference PrefReg Intf.first() MustSpill PrefSpill FirstInstr LastInstr PrefReg FirstInstr LastInstr FirstInstr LastInstr FirstInstr LastInstr PrefReg MustSpill FirstInstr LastInstr PrefReg FirstInstr LastInstr FirstInstr LastInstr FirstInstr LastInstr PrefSpill Last Split Point ++Ins ++Ins ++Ins ++Ins ++Ins ++Ins Cost = Block_Frequency * Ins
  • 65. Split Cost BB #n (freq) … = Y op … Bundle ib Value Bundle ob Value Use Block RegIn RegOut BC.Entry BC.Exit if (BI.LiveIn) Ins += RegIn != (BC.Entry == SpillPlacement::PrefReg); if (BI.LiveOut) Ins += RegOut != (BC.Exit == SpillPlacement::PrefReg); while (Ins--) GlobalCost += SpillPlacer->getBlockFrequency(BC.Number); Live Through BB #n (freq) Bundle ib Value Bundle ob Value RegIn RegOut RegIn RegOut Cost 0 0 0 0 1 freq 1 0 freq 1 1 2 x freq (interfer)
  • 66. The Best Candidate • For all physical registers, calculate region split cost. • Cost = block constraints cost (spill cost) + global split cost • The best candidate has the lowest cost.
  • 68. splitLiveThroughBlock Bundle ib Value == 1 Bundle ob Value != 1 Live Through LiveOut on Stack first non-PHI Start New Int Bundle ib Value != 1 Bundle ob Value == 1 Live Through LiveIn on Stack last split point End New Int Live Through No Interference Bundle ib Value == 1 Bundle ob Value == 1 End New Int Start
  • 69. splitLiveThroughBlock Bundle ib Value == 1 Bundle ob Value == 1 LiveThrough Non-overlapping interference New Int Interference.fist() Interference.last() New Int Bundle ib Value == 1 Bundle ob Value == 1 LiveThrough Overlapping interference New Int Interference.fist() Interference.last() New Int
  • 70. splitRegInBlock Bundle ib Value == 1 No LiveOut Interference after kill Start New Int Bundle ib Value == 1 Bundle ob Value != 1 LiveOut on Stack Interference after last use LiveOut on Stack Interference after last use Interference.fist() LastInstr LastInstr last split point New Int Start Bundle ib Value == 1 Bundle ob Value != 1 LastInstr last split point New Int Start Interference.fist() Interference.fist()
  • 71. splitRegInBlock Bundle ib Value == 1 LiveOut on Stack Interference overlapping uses Start New Int Bundle ib Value == 1 Interference.fist() LastInstr last split point New Int Start New Int Interference.fist() LastInstr last split point New Int Bundle ob Value != 1 Bundle ob Value != 1 LiveOut on Stack Interference overlapping uses
  • 72. splitRegOutBlock No LiveIn Interference before def End New Int Bundle ib Value != 1 Bundle ob Value == 1 Live Through Interference before def Live Through Interference overlapping uses Interference.last() FirstInstr Bundle ib Value != 1 Bundle ob Value == 1 Bundle ob Value == 1 End New Int Interference.last() FirstInstr last split point End New Int Interference.last() FirstInstr New Int