Skip to content

Commit 0ae6cfc

Browse files
authored
[RegAllocFast] Handle single-vdef instrs faster (#96284)
On x86, many instructions have tied operands, so allocateInstruction uses the more complex assignment strategy, which computes the assignment order of virtual defs first. This involves iterating over all register classes (or register aliases for physical defs) to compute the possible number of defs per register class. However, this information is only used for sorting virtual defs and therefore not required when there's only one virtual def -- which is a very common case. As iterating over all register classes/aliases is not cheap, do this only when there's more than one virtual def.
1 parent b1ec1a2 commit 0ae6cfc

File tree

1 file changed

+20
-12
lines changed

1 file changed

+20
-12
lines changed

llvm/lib/CodeGen/RegAllocFast.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ class RegAllocFastImpl {
322322
private:
323323
void allocateBasicBlock(MachineBasicBlock &MBB);
324324

325-
void addRegClassDefCounts(std::vector<unsigned> &RegClassDefCounts,
325+
void addRegClassDefCounts(MutableArrayRef<unsigned> RegClassDefCounts,
326326
Register Reg) const;
327327

328328
void findAndSortDefOperandIndexes(const MachineInstr &MI);
@@ -1253,7 +1253,7 @@ void RegAllocFastImpl::dumpState() const {
12531253

12541254
/// Count number of defs consumed from each register class by \p Reg
12551255
void RegAllocFastImpl::addRegClassDefCounts(
1256-
std::vector<unsigned> &RegClassDefCounts, Register Reg) const {
1256+
MutableArrayRef<unsigned> RegClassDefCounts, Register Reg) const {
12571257
assert(RegClassDefCounts.size() == TRI->getNumRegClasses());
12581258

12591259
if (Reg.isVirtual()) {
@@ -1289,10 +1289,6 @@ void RegAllocFastImpl::addRegClassDefCounts(
12891289
void RegAllocFastImpl::findAndSortDefOperandIndexes(const MachineInstr &MI) {
12901290
DefOperandIndexes.clear();
12911291

1292-
// Track number of defs which may consume a register from the class.
1293-
std::vector<unsigned> RegClassDefCounts(TRI->getNumRegClasses(), 0);
1294-
assert(RegClassDefCounts[0] == 0);
1295-
12961292
LLVM_DEBUG(dbgs() << "Need to assign livethroughs\n");
12971293
for (unsigned I = 0, E = MI.getNumOperands(); I < E; ++I) {
12981294
const MachineOperand &MO = MI.getOperand(I);
@@ -1306,14 +1302,26 @@ void RegAllocFastImpl::findAndSortDefOperandIndexes(const MachineInstr &MI) {
13061302
}
13071303
}
13081304

1309-
if (MO.isDef()) {
1310-
if (Reg.isVirtual() && shouldAllocateRegister(Reg))
1311-
DefOperandIndexes.push_back(I);
1312-
1313-
addRegClassDefCounts(RegClassDefCounts, Reg);
1314-
}
1305+
if (MO.isDef() && Reg.isVirtual() && shouldAllocateRegister(Reg))
1306+
DefOperandIndexes.push_back(I);
13151307
}
13161308

1309+
// Most instructions only have one virtual def, so there's no point in
1310+
// computing the possible number of defs for every register class.
1311+
if (DefOperandIndexes.size() <= 1)
1312+
return;
1313+
1314+
// Track number of defs which may consume a register from the class. This is
1315+
// used to assign registers for possibly-too-small classes first. Example:
1316+
// defs are eax, 3 * gr32_abcd, 2 * gr32 => we want to assign the gr32_abcd
1317+
// registers first so that the gr32 don't use the gr32_abcd registers before
1318+
// we assign these.
1319+
SmallVector<unsigned> RegClassDefCounts(TRI->getNumRegClasses(), 0);
1320+
1321+
for (const MachineOperand &MO : MI.operands())
1322+
if (MO.isReg() && MO.isDef())
1323+
addRegClassDefCounts(RegClassDefCounts, MO.getReg());
1324+
13171325
llvm::sort(DefOperandIndexes, [&](unsigned I0, unsigned I1) {
13181326
const MachineOperand &MO0 = MI.getOperand(I0);
13191327
const MachineOperand &MO1 = MI.getOperand(I1);

0 commit comments

Comments
 (0)