llvm register allocation (2nd version)
TRANSCRIPT
![Page 2: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/2.jpg)
Outline• Introduction to Register Allocation Problem
• LLVM Register Allocation Template Method
• LLVM Basic Register Allocation
• LLVM Greedy Register Allocation
![Page 3: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/3.jpg)
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
![Page 4: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/4.jpg)
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: @ %entry
sub sp, #16movsr0, #0str r0, [sp, #12]movsr0, #1str r0, [sp, #8]b LBB0_2
LBB0_1: @ %for.inc.4 @ in Loop: Header=BB0_2 Depth=1
addsr1, #1str r1, [sp, #8]
LBB0_2: @ %for.cond @ =>This Loop Header: Depth=1 @ Child Loop BB0_5 Depth 2
ldr r1, [sp, #8]cmp r1, #9bgt LBB0_6
@ BB#3: @ %for.body @ in Loop: Header=BB0_2 Depth=1
str r0, [sp, #4]b LBB0_5
LBB0_4: @ %for.body.3 @ in Loop: Header=BB0_5 Depth=2
ldr r2, [sp, #4]mulsr1, r2, r1str r1, [sp]ldr r1, [sp, #4]addsr1, #1str r1, [sp, #4]
![Page 5: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/5.jpg)
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
![Page 6: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/6.jpg)
Graph Coloring for RA• Node: Live interval
• Edge: Two live intervals have interference
• Color: Physical register
• Find a optimal colouring for the graph
![Page 7: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/7.jpg)
… 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
![Page 8: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/8.jpg)
LIa
LIb LIc
LId
… LIa = …
LIb = … … = LIb
LIc = … …
LId = LIc
… = LIa … = LId
B0
B1 B2
B3
![Page 9: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/9.jpg)
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
![Page 10: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/10.jpg)
Template Method• Define the skeleton of an algorithm in an operation,
deferring some steps to subclasses.
![Page 11: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/11.jpg)
LLVM Register Allocation Template Method
Enqueue All LiveInterval
selectOrSplit for One LiveInterval
Assign the Physical Register
Enqueue Split LiveInterval
dequeue
physical register is available
split live interval
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)); }
![Page 12: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/12.jpg)
Basic Register Allocation
![Page 13: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/13.jpg)
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 intervalupdate 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; } };
1.Assign physical registers to Live Interval with highest spill cost.2.If there is no physical registers for current Live Interval, select
the highest spill cost Live Interval between current one and interferences to assign physical registers.
3.Spill the unassigned Live Intervals.
![Page 14: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/14.jpg)
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
![Page 15: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/15.jpg)
Greedy Register Allocation
![Page 16: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/16.jpg)
• Example (assign physical registers by length)Q0
D0 D1Q1
D2 D3
V1
V2
V3 V4V5
![Page 17: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/17.jpg)
Q0D0 D1
Q1D2 D3
V1
V2
V3 V4V5
![Page 18: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/18.jpg)
• No physical register for V1Q0
D0 D1Q1
D2 D3
V1
V2
V3 V4V5
![Page 19: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/19.jpg)
• Evict V2 (evict Live Interval with lower spill cost)Q0
D0 D1Q1
D2 D3
V1
V2
V3V4V5
stack
![Page 20: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/20.jpg)
• Split V2Q0
D0 D1Q1
D2 D3
V1
V2b
V3V4V5
V2a
V2c
![Page 21: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/21.jpg)
• Split V2Q0
D0 D1Q1
D2 D3
V1
V2b
V3V4V5
V2a
V2c
stack
![Page 22: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/22.jpg)
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
![Page 23: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/23.jpg)
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
![Page 24: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/24.jpg)
Greedy Register Allocation
try to assign physical register
try to evict to find better register
enter RS_Split stage
try last chance recoloring split
spillpick a physical register and evict all interference
found register
stage >= RS_Done or Live Interval is unspillable
stage < RS_Split
selectOrSplit(d+1)
selectOrSplit(d)
stage is RS_Split or RS_Split2
![Page 25: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/25.jpg)
Last Chance Recoloring• Try to assign a physical register to Live Interval by
evicting all 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)
selectOrSplit(d) selectOrSplit(d + 1)
![Page 26: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/26.jpg)
How to Split?is stage beyond
RS_Spill?
is in one BB? tryLocalSplit
tryInstructionSplit
No
Yes
tryRegionSplit
is stage less than RS_Split2?
No
spillYes
success?
No
success?
spill
No
tryBlockSplit
Yes
No
success?No
success?
spill
No
done
Yes
Yes
done
Yes
Yes
![Page 27: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/27.jpg)
tryLocalSplit• Try to split virtual register interval into smaller
intervals inside its only basic block.
• calculate gap weights
• adjust the split region
![Page 28: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/28.jpg)
Calculate Gap Weights
NumGaps = 4
define
use
use
use
use
![Page 29: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/29.jpg)
Calculate Gap Weights
LI.weight
VirtReg Live Interval
If there is a physical register occupied by VirtReg.0
0
define
use
use
use
use
![Page 30: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/30.jpg)
Calculate Gap Weights
LI.weight
physical Live Interval
If there is a fixed physical register.0
0
huge_valf
define
use
use
use
use
![Page 31: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/31.jpg)
Adjust Split Region
SplitAfter = 1
SplitBefore = 0
normalise spill weight >
max gap
if Diff > BestDiff: BestBefore = SplitBefore BestAfter = SplitAfter SplitAfter++
SplitBefore++
YesNo
normalise spill weight = spill cost / distance = (#gap * block_freq) / distance(SplitBefore, SplitAfter)
![Page 32: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/32.jpg)
Adjust Split Region
BestAfter
BestBefore
normalise spill weight >
max gap
if Diff > BestDiff: 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
Go through all physical registers. Find the most critical range.
![Page 33: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/33.jpg)
tryRegionSplit• Use Hopfield Network to find optimal splits.
• Guaranteed to converge to a local minimum.
![Page 34: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/34.jpg)
Hopfield Networka(t)s⇥1 =
⇢ps⇥1 : t = 0S(Ws⇥s ⇥ a(t� 1)s⇥1 + bs⇥1) : t � 1
S(x) =
⇢+1 : x � ✓
�1 : x < ✓
![Page 35: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/35.jpg)
tryRegionSplit1. For every physical register, construct Hopfield Network
• Initialize border constraints
• Initialize Hopfield Network nodes according to border constraints
• Add links to Hopfield Network and iterate
2. Get the best candidate
3. Do region split
![Page 36: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/36.jpg)
Initialize Border Constraints• No Interference.
LiveIn ? PrefReg : DontCare;
LiveOut ? PrefReg : DontCare;
enum BorderConstraint { DontCare, PrefReg, PrefSpill, PrefBoth, MustSpill };
![Page 37: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/37.jpg)
Initialize Border Constraints• There are Interferences.
MustSpill PrefSpill
FirstInstr
LastInstr
PrefReg/DontCare
FirstInstr
LastInstr
FirstInstr
LastInstr
MustSpill
FirstInstr
LastInstr
FirstInstr
LastInstr
FirstInstr
LastInstr
PrefSpill PrefReg/DontCare
![Page 38: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/38.jpg)
Edge BundleBB #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 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];}
![Page 39: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/39.jpg)
Edge Bundle
BB #0
BB #1
BB #3
BB #2
BB #4 BB #5
BB #6 Blocks:Bundle #0: BB#0Bundle #1: BB#0, BB#1, BB#5Bundle #2: BB#1, BB#2, BB#6Bundle #3: BB#2, BB#3, BB#4Bundle #4: BB#3, BB#4, BB#5Bundle #5: BB#6Bundle #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
![Page 40: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/40.jpg)
Edge Bundle
BB #0
BB #1
BB #3
BB #2
BB #4 BB #5
BB #6 Blocks:Bundle #0: BB#0Bundle #1: BB#0, BB#1, BB#5Bundle #2: BB#1, BB#2, BB#6Bundle #3: BB#2, BB#3, BB#4Bundle #4: BB#3, BB#4, BB#5Bundle #5: BB#6Bundle #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
![Page 41: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/41.jpg)
Edge Bundle
BB #0
BB #1
BB #3
BB #2
BB #4 BB #5
BB #6 Blocks:Bundle #0: BB#0Bundle #1: BB#0, BB#1, BB#5Bundle #2: BB#1, BB#2, BB#6Bundle #3: BB#2, BB#3, BB#4Bundle #4: BB#3, BB#4, BB#5Bundle #5: BB#6Bundle #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
![Page 42: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/42.jpg)
Edge Bundle
BB #0
BB #1
BB #3
BB #2
BB #4 BB #5
BB #6 Blocks:Bundle #0: BB#0Bundle #1: BB#0, BB#1, BB#5Bundle #2: BB#1, BB#2, BB#6Bundle #3: BB#2, BB#3, BB#4Bundle #4: BB#3, BB#4, BB#5Bundle #5: BB#6Bundle #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
![Page 43: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/43.jpg)
Edge Bundle
BB #0
BB #1
BB #3
BB #2
BB #4 BB #5
BB #6 Blocks:Bundle #0: BB#0Bundle #1: BB#0, BB#1, BB#5Bundle #2: BB#1, BB#2, BB#6Bundle #3: BB#2, BB#3, BB#4Bundle #4: BB#3, BB#4, BB#5Bundle #5: BB#6Bundle #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
![Page 44: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/44.jpg)
Edge Bundle
BB #0
BB #1
BB #3
BB #2
BB #4 BB #5
BB #6 Blocks:Bundle #0: BB#0Bundle #1: BB#0, BB#1, BB#5Bundle #2: BB#1, BB#2, BB#6Bundle #3: BB#2, BB#3, BB#4Bundle #4: BB#3, BB#4, BB#5Bundle #5: BB#6Bundle #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
![Page 45: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/45.jpg)
Edge Bundle
BB #0
BB #1
BB #3
BB #2
BB #4 BB #5
BB #6 Blocks:Bundle #0: BB#0Bundle #1: BB#0, BB#1, BB#5Bundle #2: BB#1, BB#2, BB#6Bundle #3: BB#2, BB#3, BB#4Bundle #4: BB#3, BB#4, BB#5Bundle #5: BB#6Bundle #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
![Page 46: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/46.jpg)
Initialize Hopfield Network Node• 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; } }
![Page 47: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/47.jpg)
Add Links to Hopfield Network• add weight to links
Live Through BB #n (freq)
Bundle ib
Bundle ob
void addLink(unsigned b, BlockFrequency w) { // Update cached sum. SumLinkWeights += w;
// There can be multiple links to the same bundle, add them up. for (LinkVector::iterator I = Links.begin(), E = Links.end(); I != E; ++I) if (I->second == b) { I->first += w; return; } // This must be the first link to b. Links.push_back(std::make_pair(w, b)); }
(freq, ob)
(freq, ib)
![Page 48: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/48.jpg)
Update Hopfield Network
Bundle X BiasN BiasP Value = 0
Bundle A Value = -1
Bundle B Value = 1
Bundle C Value = 1
Bundle D Value = 1
SumN = BiasN + freqASunP = 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;
a(t)s⇥1 =
⇢ps⇥1 : t = 0S(Ws⇥s ⇥ a(t� 1)s⇥1 + bs⇥1) : t � 1
2
66664
· · ·· · ·· · ·· · ·
FA FB FC FD 0
3
77775⇥
2
66664
�11110
3
77775+
2
666664
...
Biasp �Biasn
3
777775
![Page 49: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/49.jpg)
Region Split• splitLiveThroughBlock
• splitRegInBlock
• splitRegOutBlock
![Page 50: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/50.jpg)
splitLiveThroughBlock
Bundle ib Value == 1
Bundle ob Value != 1
Live Through LiveOut on Stack
first non-PHIStart
New Int
Bundle ib Value != 1
Bundle ob Value == 1
Live Through LiveIn on Stack
last split point
EndNew Int
Live Through No Interference
Bundle ib Value == 1
Bundle ob Value == 1
End
New Int
Start
![Page 51: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/51.jpg)
splitLiveThroughBlock
Bundle ib Value == 1
Bundle ob Value == 1
LiveThrough Non-overlapping interference
New Int
Interference.first()
Interference.last()
New Int
Bundle ib Value == 1
Bundle ob Value == 1
LiveThrough Overlapping interference
New IntInterference.first()
Interference.last()New Int
![Page 52: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/52.jpg)
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
LastInstrlast split point
New IntStart
Bundle ib Value == 1
Bundle ob Value != 1
LastInstr
last split point
New Int
Start
Interference.fist() Interference.fist()
![Page 53: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/53.jpg)
splitRegInBlock
Bundle ib Value == 1
LiveOut on Stack Interference overlapping uses
Start
New Int
Bundle ib Value == 1
Interference.fist()LastInstrlast split point
New Int
Start
New Int
Interference.fist()
LastInstrlast split point
New Int
Bundle ob Value != 1
Bundle ob Value != 1
LiveOut on Stack Interference overlapping uses
![Page 54: LLVM Register Allocation (2nd Version)](https://reader034.vdocuments.site/reader034/viewer/2022042610/58a2797d1a28ab94628b78d5/html5/thumbnails/54.jpg)
splitRegOutBlockNo LiveIn
Interference before def
EndNew 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()
FirstInstrlast split point
EndNew Int
Interference.last()
FirstInstrNew Int