@@ -253,11 +253,22 @@ class RegAllocFastImpl {
253
253
254
254
SmallVector<MachineInstr *, 32 > Coalesced;
255
255
256
- using RegUnitSet = SparseSet<uint16_t , identity<uint16_t >>;
257
- // / Set of register units that are used in the current instruction, and so
256
+ // / Track register units that are used in the current instruction, and so
258
257
// / cannot be allocated.
259
- RegUnitSet UsedInInstr;
260
- RegUnitSet PhysRegUses;
258
+ // /
259
+ // / In the first phase (tied defs/early clobber), we consider also physical
260
+ // / uses, afterwards, we don't. If the lowest bit isn't set, it's a solely
261
+ // / physical use (markPhysRegUsedInInstr), otherwise, it's a normal use. To
262
+ // / avoid resetting the entire vector after every instruction, we track the
263
+ // / instruction "generation" in the remaining 31 bits -- this means, that if
264
+ // / UsedInInstr[Idx] < InstrGen, the register unit is unused. InstrGen is
265
+ // / never zero and always incremented by two.
266
+ // /
267
+ // / Don't allocate inline storage: the number of register units is typically
268
+ // / quite large (e.g., AArch64 > 100, X86 > 200, AMDGPU > 1000).
269
+ uint32_t InstrGen;
270
+ SmallVector<unsigned , 0 > UsedInInstr;
271
+
261
272
SmallVector<unsigned , 8 > DefOperandIndexes;
262
273
// Register masks attached to the current instruction.
263
274
SmallVector<const uint32_t *> RegMasks;
@@ -271,7 +282,7 @@ class RegAllocFastImpl {
271
282
// / Mark a physreg as used in this instruction.
272
283
void markRegUsedInInstr (MCPhysReg PhysReg) {
273
284
for (MCRegUnit Unit : TRI->regunits (PhysReg))
274
- UsedInInstr. insert ( Unit) ;
285
+ UsedInInstr[ Unit] = InstrGen | 1 ;
275
286
}
276
287
277
288
// Check if physreg is clobbered by instruction's regmask(s).
@@ -285,26 +296,25 @@ class RegAllocFastImpl {
285
296
bool isRegUsedInInstr (MCPhysReg PhysReg, bool LookAtPhysRegUses) const {
286
297
if (LookAtPhysRegUses && isClobberedByRegMasks (PhysReg))
287
298
return true ;
288
- for (MCRegUnit Unit : TRI->regunits (PhysReg)) {
289
- if (UsedInInstr.count (Unit))
290
- return true ;
291
- if (LookAtPhysRegUses && PhysRegUses.count (Unit))
299
+ for (MCRegUnit Unit : TRI->regunits (PhysReg))
300
+ if (UsedInInstr[Unit] >= (InstrGen | !LookAtPhysRegUses))
292
301
return true ;
293
- }
294
302
return false ;
295
303
}
296
304
297
305
// / Mark physical register as being used in a register use operand.
298
306
// / This is only used by the special livethrough handling code.
299
307
void markPhysRegUsedInInstr (MCPhysReg PhysReg) {
300
- for (MCRegUnit Unit : TRI->regunits (PhysReg))
301
- PhysRegUses.insert (Unit);
308
+ for (MCRegUnit Unit : TRI->regunits (PhysReg)) {
309
+ assert (UsedInInstr[Unit] <= InstrGen && " non-phys use before phys use?" );
310
+ UsedInInstr[Unit] = InstrGen;
311
+ }
302
312
}
303
313
304
314
// / Remove mark of physical register being used in the instruction.
305
315
void unmarkRegUsedInInstr (MCPhysReg PhysReg) {
306
316
for (MCRegUnit Unit : TRI->regunits (PhysReg))
307
- UsedInInstr. erase ( Unit) ;
317
+ UsedInInstr[ Unit] = 0 ;
308
318
}
309
319
310
320
enum : unsigned {
@@ -1382,7 +1392,12 @@ void RegAllocFastImpl::allocateInstruction(MachineInstr &MI) {
1382
1392
// - The "free def operands" step has to come last instead of first for tied
1383
1393
// operands and early-clobbers.
1384
1394
1385
- UsedInInstr.clear ();
1395
+ InstrGen += 2 ;
1396
+ // In the event we ever get more than 2**31 instructions...
1397
+ if (LLVM_UNLIKELY (InstrGen == 0 )) {
1398
+ UsedInInstr.assign (UsedInInstr.size (), 0 );
1399
+ InstrGen = 2 ;
1400
+ }
1386
1401
RegMasks.clear ();
1387
1402
BundleVirtRegsMap.clear ();
1388
1403
@@ -1443,8 +1458,6 @@ void RegAllocFastImpl::allocateInstruction(MachineInstr &MI) {
1443
1458
// heuristic to figure out a good operand order before doing
1444
1459
// assignments.
1445
1460
if (NeedToAssignLiveThroughs) {
1446
- PhysRegUses.clear ();
1447
-
1448
1461
while (ReArrangedImplicitOps) {
1449
1462
ReArrangedImplicitOps = false ;
1450
1463
findAndSortDefOperandIndexes (MI);
@@ -1769,10 +1782,8 @@ bool RegAllocFastImpl::runOnMachineFunction(MachineFunction &MF) {
1769
1782
MRI->freezeReservedRegs ();
1770
1783
RegClassInfo.runOnMachineFunction (MF);
1771
1784
unsigned NumRegUnits = TRI->getNumRegUnits ();
1772
- UsedInInstr.clear ();
1773
- UsedInInstr.setUniverse (NumRegUnits);
1774
- PhysRegUses.clear ();
1775
- PhysRegUses.setUniverse (NumRegUnits);
1785
+ InstrGen = 0 ;
1786
+ UsedInInstr.assign (NumRegUnits, 0 );
1776
1787
1777
1788
// initialize the virtual->physical register map to have a 'null'
1778
1789
// mapping for all virtual registers
0 commit comments