@@ -62,6 +62,71 @@ static RegisterRegAlloc fastRegAlloc("fast", "fast register allocator",
62
62
63
63
namespace {
64
64
65
+ // / Assign ascending index for instructions in machine basic block. The index
66
+ // / can be used to determine dominance between instructions in same MBB.
67
+ class InstrPosIndexes {
68
+ public:
69
+ void init (const MachineBasicBlock &MBB) {
70
+ CurMBB = &MBB;
71
+ Instr2PosIndex.clear ();
72
+ uint64_t LastIndex = 0 ;
73
+ for (const MachineInstr &MI : MBB) {
74
+ LastIndex += InstrDist;
75
+ Instr2PosIndex[&MI] = LastIndex;
76
+ }
77
+ }
78
+
79
+ // / Set \p Index to index of \p MI. If \p MI is new inserted, it try to assign
80
+ // / index without affecting existing instruction's index. Return true if all
81
+ // / instructions index has been reassigned.
82
+ bool getIndex (const MachineInstr &MI, uint64_t &Index) {
83
+ assert (MI.getParent () == CurMBB && " MI is not in CurMBB" );
84
+ if (Instr2PosIndex.count (&MI)) {
85
+ Index = Instr2PosIndex[&MI];
86
+ return false ;
87
+ }
88
+
89
+ unsigned Distance = 1 ;
90
+ MachineBasicBlock::const_iterator Start = MI.getIterator (),
91
+ End = std::next (Start);
92
+ while (Start != CurMBB->begin () &&
93
+ !Instr2PosIndex.count (&*std::prev (Start))) {
94
+ --Start;
95
+ ++Distance;
96
+ }
97
+ while (End != CurMBB->end () && !Instr2PosIndex.count (&*(End))) {
98
+ ++End;
99
+ ++Distance;
100
+ }
101
+
102
+ uint64_t LastIndex =
103
+ Start == CurMBB->begin () ? 0 : Instr2PosIndex.at (&*std::prev (Start));
104
+ uint64_t Step = End == CurMBB->end ()
105
+ ? static_cast <uint64_t >(InstrDist)
106
+ : (Instr2PosIndex.at (&*End) - LastIndex - 1 ) / Distance;
107
+
108
+ // Reassign index for all instructions if number of new inserted
109
+ // instructions exceed slot or all instructions are new.
110
+ if (LLVM_UNLIKELY (!Step || (!LastIndex && Step == InstrDist))) {
111
+ init (*CurMBB);
112
+ Index = Instr2PosIndex.at (&MI);
113
+ return true ;
114
+ }
115
+
116
+ for (auto I = Start; I != End; ++I) {
117
+ LastIndex += Step;
118
+ Instr2PosIndex[&*I] = LastIndex;
119
+ }
120
+ Index = Instr2PosIndex.at (&MI);
121
+ return false ;
122
+ }
123
+
124
+ private:
125
+ enum { InstrDist = 1024 };
126
+ const MachineBasicBlock *CurMBB = nullptr ;
127
+ DenseMap<const MachineInstr *, uint64_t > Instr2PosIndex;
128
+ };
129
+
65
130
class RegAllocFast : public MachineFunctionPass {
66
131
public:
67
132
static char ID;
@@ -153,6 +218,9 @@ class RegAllocFast : public MachineFunctionPass {
153
218
// Register masks attached to the current instruction.
154
219
SmallVector<const uint32_t *> RegMasks;
155
220
221
+ // Assign index for each instruction to quickly determine dominance.
222
+ InstrPosIndexes PosIndexes;
223
+
156
224
void setPhysRegState (MCPhysReg PhysReg, unsigned NewState);
157
225
bool isPhysRegFree (MCPhysReg PhysReg) const ;
158
226
@@ -339,18 +407,13 @@ int RegAllocFast::getStackSpaceFor(Register VirtReg) {
339
407
return FrameIdx;
340
408
}
341
409
342
- static bool dominates (MachineBasicBlock &MBB,
343
- MachineBasicBlock::const_iterator A,
344
- MachineBasicBlock::const_iterator B) {
345
- auto MBBEnd = MBB.end ();
346
- if (B == MBBEnd)
347
- return true ;
348
-
349
- MachineBasicBlock::const_iterator I = MBB.begin ();
350
- for (; &*I != A && &*I != B; ++I)
351
- ;
352
-
353
- return &*I == A;
410
+ static bool dominates (InstrPosIndexes &PosIndexes, const MachineInstr &A,
411
+ const MachineInstr &B) {
412
+ uint64_t IndexA, IndexB;
413
+ PosIndexes.getIndex (A, IndexA);
414
+ if (LLVM_UNLIKELY (PosIndexes.getIndex (B, IndexB)))
415
+ PosIndexes.getIndex (A, IndexA);
416
+ return IndexA < IndexB;
354
417
}
355
418
356
419
// / Returns false if \p VirtReg is known to not live out of the current block.
@@ -371,7 +434,7 @@ bool RegAllocFast::mayLiveOut(Register VirtReg) {
371
434
MayLiveAcrossBlocks.set (Register::virtReg2Index (VirtReg));
372
435
return true ;
373
436
} else {
374
- if (!SelfLoopDef || dominates (*MBB , DefInst. getIterator (), SelfLoopDef))
437
+ if (!SelfLoopDef || dominates (PosIndexes , DefInst, * SelfLoopDef))
375
438
SelfLoopDef = &DefInst;
376
439
}
377
440
}
@@ -396,7 +459,7 @@ bool RegAllocFast::mayLiveOut(Register VirtReg) {
396
459
// Try to handle some simple cases to avoid spilling and reloading every
397
460
// value inside a self looping block.
398
461
if (SelfLoopDef == &UseInst ||
399
- !dominates (*MBB, SelfLoopDef-> getIterator () , UseInst. getIterator () )) {
462
+ !dominates (PosIndexes, * SelfLoopDef, UseInst)) {
400
463
MayLiveAcrossBlocks.set (Register::virtReg2Index (VirtReg));
401
464
return true ;
402
465
}
@@ -1570,6 +1633,7 @@ void RegAllocFast::allocateBasicBlock(MachineBasicBlock &MBB) {
1570
1633
this ->MBB = &MBB;
1571
1634
LLVM_DEBUG (dbgs () << " \n Allocating " << MBB);
1572
1635
1636
+ PosIndexes.init (MBB);
1573
1637
RegUnitStates.assign (TRI->getNumRegUnits (), regFree);
1574
1638
assert (LiveVirtRegs.empty () && " Mapping not cleared from last block?" );
1575
1639
0 commit comments