Skip to content

Commit c4484e8

Browse files
authored
[CodeGen] De-type getMinimalPhysRegClass and related APIs (llvm#197495)
Follow-up llvm#193438 to de-type getMinimalPhysRegClass so it can be replaced with the precomputed getDefaultMinimalPhysRegClass. Type is also removed from related APIs. There's very few uses of getMinimalPhysRegClass with a non-default type (MVT::Other) and none at all for getCommonMinimalPhysRegClass. Rather than trying to also handle the type when precomputing at compile-time it seems better to remove the type altogether and simplify the APIs. This also improves compile-time for a number of targets and configurations: CTMark geomean: - stage1-O3: -0.23% - stage1-ReleaseThinLTO: -0.19% - stage1-ReleaseLTO-g: -0.15% - stage1-aarch64-O3: -0.57% - stage2-O3: -0.23% - clang: -0.13% https://llvm-compile-time-tracker.com/compare.php?from=eae0b6b2498305ee29dc85a405ede9ccdc10ce7d&to=08c052a2db407d2a21d468001fd2035d3720acf7&stat=instructions%3Au Assisted-by: codex
1 parent b8e768f commit c4484e8

13 files changed

Lines changed: 49 additions & 167 deletions

File tree

llvm/docs/ReleaseNotes.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ Makes programs 10x faster by doing Special New Thing.
140140
Use the new ``remove_if`` member to erase matching elements in a single pass
141141
instead of erasing while iterating.
142142

143+
* ``TargetRegisterInfo::getMinimalPhysRegClass`` and related APIs have been
144+
refactored and no longer take a type. This API is also now precomputed in
145+
TableGen to improve compile-time.
146+
143147
### Changes to building LLVM
144148

145149
### Changes to TableGen

llvm/include/llvm/CodeGen/TargetRegisterInfo.h

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -353,33 +353,15 @@ class LLVM_ABI TargetRegisterInfo : public MCRegisterInfo {
353353
return I;
354354
}
355355

356-
/// Returns the Register Class of a physical register of the given type,
357-
/// picking the most sub register class of the right type that contains this
358-
/// physreg.
359-
const TargetRegisterClass *getMinimalPhysRegClass(MCRegister Reg,
360-
MVT VT = MVT::Other) const;
361-
362-
/// Returns the common Register Class of two physical registers of the given
363-
/// type, picking the most sub register class of the right type that contains
364-
/// these two physregs.
365-
const TargetRegisterClass *
366-
getCommonMinimalPhysRegClass(MCRegister Reg1, MCRegister Reg2,
367-
MVT VT = MVT::Other) const;
368-
369-
/// Returns the Register Class of a physical register of the given type,
370-
/// picking the most sub register class of the right type that contains this
371-
/// physreg. If there is no register class compatible with the given type,
372-
/// returns nullptr.
373-
const TargetRegisterClass *getMinimalPhysRegClassLLT(MCRegister Reg,
374-
LLT Ty = LLT()) const;
375-
376-
/// Returns the common Register Class of two physical registers of the given
377-
/// type, picking the most sub register class of the right type that contains
378-
/// these two physregs. If there is no register class compatible with the
379-
/// given type, returns nullptr.
356+
/// Returns the Register Class of a physical register, picking the smallest
357+
/// register subclass that contains this physreg.
358+
virtual const TargetRegisterClass *
359+
getMinimalPhysRegClass(MCRegister Reg) const = 0;
360+
361+
/// Returns the common Register Class of two physical registers, picking the
362+
/// smallest register subclass that contains these two physregs.
380363
const TargetRegisterClass *
381-
getCommonMinimalPhysRegClassLLT(MCRegister Reg1, MCRegister Reg2,
382-
LLT Ty = LLT()) const;
364+
getCommonMinimalPhysRegClass(MCRegister Reg1, MCRegister Reg2) const;
383365

384366
/// Return the maximal subclass of the given register class that is
385367
/// allocatable or NULL.
@@ -829,13 +811,6 @@ class LLVM_ABI TargetRegisterInfo : public MCRegisterInfo {
829811
return nullptr;
830812
}
831813

832-
/// Returns the target-defined minimal register class for an untyped physical
833-
/// register query or nullptr if the register is not in any register class.
834-
virtual const TargetRegisterClass *
835-
getDefaultMinimalPhysRegClass(MCRegister Reg) const {
836-
return nullptr;
837-
}
838-
839814
protected:
840815
/// Overridden by TableGen in targets that have sub-registers.
841816
virtual unsigned composeSubRegIndicesImpl(unsigned, unsigned) const {

llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -606,8 +606,7 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
606606
// FIXME: Using getMinimalPhysRegClass is very conservative. We should
607607
// check every use of the register and find the largest register class
608608
// that can be used in all of them.
609-
const TargetRegisterClass *SuperRC =
610-
TRI->getMinimalPhysRegClass(SuperReg, MVT::Other);
609+
const TargetRegisterClass *SuperRC = TRI->getMinimalPhysRegClass(SuperReg);
611610

612611
ArrayRef<MCPhysReg> Order = RegClassInfo.getOrder(SuperRC);
613612
if (Order.empty()) {

llvm/lib/CodeGen/MachineVerifier.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,20 @@ namespace {
9999
/// at one time.
100100
static ManagedStatic<sys::SmartMutex<true>> ReportedErrorsLock;
101101

102+
static bool hasPhysRegClassForType(const TargetRegisterInfo &TRI,
103+
MCRegister Reg, LLT Ty) {
104+
assert(Reg.isPhysical() && "reg must be a physical register");
105+
assert(Ty.isValid() && "expected a valid type");
106+
107+
const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg);
108+
if (TRI.isTypeLegalForClass(*RC, Ty))
109+
return true;
110+
111+
return llvm::any_of(TRI.regclasses(), [&](const TargetRegisterClass *RC) {
112+
return RC->contains(Reg) && TRI.isTypeLegalForClass(*RC, Ty);
113+
});
114+
}
115+
102116
struct MachineVerifier {
103117
MachineVerifier(MachineFunctionAnalysisManager &MFAM, const char *b,
104118
raw_ostream *OS, bool AbortOnError = true)
@@ -2420,18 +2434,14 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
24202434
TypeSize SrcSize = TypeSize::getZero();
24212435
TypeSize DstSize = TypeSize::getZero();
24222436
if (SrcReg.isPhysical() && DstTy.isValid()) {
2423-
const TargetRegisterClass *SrcRC =
2424-
TRI->getMinimalPhysRegClassLLT(SrcReg, DstTy);
2425-
if (!SrcRC)
2437+
if (!hasPhysRegClassForType(*TRI, SrcReg, DstTy))
24262438
SrcSize = TRI->getRegSizeInBits(SrcReg, *MRI);
24272439
} else {
24282440
SrcSize = TRI->getRegSizeInBits(SrcReg, *MRI);
24292441
}
24302442

24312443
if (DstReg.isPhysical() && SrcTy.isValid()) {
2432-
const TargetRegisterClass *DstRC =
2433-
TRI->getMinimalPhysRegClassLLT(DstReg, SrcTy);
2434-
if (!DstRC)
2444+
if (!hasPhysRegClassForType(*TRI, DstReg, SrcTy))
24352445
DstSize = TRI->getRegSizeInBits(DstReg, *MRI);
24362446
} else {
24372447
DstSize = TRI->getRegSizeInBits(DstReg, *MRI);

llvm/lib/CodeGen/RegisterBankInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ RegisterBankInfo::getMinimalPhysRegClass(MCRegister Reg,
104104
const TargetRegisterInfo &TRI) const {
105105
const auto [RegRCIt, Inserted] = PhysRegMinimalRCs.try_emplace(Reg);
106106
if (Inserted)
107-
RegRCIt->second = TRI.getMinimalPhysRegClassLLT(Reg, LLT());
107+
RegRCIt->second = TRI.getMinimalPhysRegClass(Reg);
108108
return RegRCIt->second;
109109
}
110110

llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ void InstrEmitter::EmitCopyFromReg(SDValue Op, bool IsClone, Register SrcReg,
151151
}
152152

153153
const TargetRegisterClass *SrcRC = nullptr, *DstRC = nullptr;
154-
SrcRC = TRI->getMinimalPhysRegClass(SrcReg, VT);
154+
SrcRC = TRI->getMinimalPhysRegClass(SrcReg);
155155

156156
// Figure out the register class to create for the destreg.
157157
if (VRBase) {

llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -404,29 +404,6 @@ void ScheduleDAGFast::InsertCopiesAndMoveSuccs(SUnit *SU, unsigned Reg,
404404
++NumPRCopies;
405405
}
406406

407-
/// getPhysicalRegisterVT - Returns the ValueType of the physical register
408-
/// definition of the specified node.
409-
/// FIXME: Move to SelectionDAG?
410-
static MVT getPhysicalRegisterVT(SDNode *N, unsigned Reg,
411-
const TargetInstrInfo *TII) {
412-
unsigned NumRes;
413-
if (N->getOpcode() == ISD::CopyFromReg) {
414-
// CopyFromReg has: "chain, Val, glue" so operand 1 gives the type.
415-
NumRes = 1;
416-
} else {
417-
const MCInstrDesc &MCID = TII->get(N->getMachineOpcode());
418-
assert(!MCID.implicit_defs().empty() &&
419-
"Physical reg def must be in implicit def list!");
420-
NumRes = MCID.getNumDefs();
421-
for (MCPhysReg ImpDef : MCID.implicit_defs()) {
422-
if (Reg == ImpDef)
423-
break;
424-
++NumRes;
425-
}
426-
}
427-
return N->getSimpleValueType(NumRes);
428-
}
429-
430407
/// CheckForLiveRegDef - Return true and update live register vector if the
431408
/// specified register def of the specified SUnit clobbers any "live" registers.
432409
static bool CheckForLiveRegDef(SUnit *SU, MCRegister Reg,
@@ -572,9 +549,7 @@ void ScheduleDAGFast::ListScheduleBottomUp() {
572549
assert(LRegs.size() == 1 && "Can't handle this yet!");
573550
unsigned Reg = LRegs[0];
574551
SUnit *LRDef = LiveRegDefs[Reg];
575-
MVT VT = getPhysicalRegisterVT(LRDef->getNode(), Reg, TII);
576-
const TargetRegisterClass *RC =
577-
TRI->getMinimalPhysRegClass(Reg, VT);
552+
const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
578553
const TargetRegisterClass *DestRC = TRI->getCrossCopyRegClass(RC);
579554

580555
// If cross copy register class is the same as RC, then it must be

llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,29 +1268,6 @@ void ScheduleDAGRRList::InsertCopiesAndMoveSuccs(SUnit *SU, unsigned Reg,
12681268
++NumPRCopies;
12691269
}
12701270

1271-
/// getPhysicalRegisterVT - Returns the ValueType of the physical register
1272-
/// definition of the specified node.
1273-
/// FIXME: Move to SelectionDAG?
1274-
static MVT getPhysicalRegisterVT(SDNode *N, unsigned Reg,
1275-
const TargetInstrInfo *TII) {
1276-
unsigned NumRes;
1277-
if (N->getOpcode() == ISD::CopyFromReg) {
1278-
// CopyFromReg has: "chain, Val, glue" so operand 1 gives the type.
1279-
NumRes = 1;
1280-
} else {
1281-
const MCInstrDesc &MCID = TII->get(N->getMachineOpcode());
1282-
assert(!MCID.implicit_defs().empty() &&
1283-
"Physical reg def must be in implicit def list!");
1284-
NumRes = MCID.getNumDefs();
1285-
for (MCPhysReg ImpDef : MCID.implicit_defs()) {
1286-
if (Reg == ImpDef)
1287-
break;
1288-
++NumRes;
1289-
}
1290-
}
1291-
return N->getSimpleValueType(NumRes);
1292-
}
1293-
12941271
/// CheckForLiveRegDef - Return true and update live register vector if the
12951272
/// specified register def of the specified SUnit clobbers any "live" registers.
12961273
static void CheckForLiveRegDef(SUnit *SU, MCRegister Reg, SUnit **LiveRegDefs,
@@ -1561,9 +1538,7 @@ SUnit *ScheduleDAGRRList::PickNodeToScheduleBottomUp() {
15611538
assert(LRegs.size() == 1 && "Can't handle this yet!");
15621539
unsigned Reg = LRegs[0];
15631540
SUnit *LRDef = LiveRegDefs[Reg];
1564-
MVT VT = getPhysicalRegisterVT(LRDef->getNode(), Reg, TII);
1565-
const TargetRegisterClass *RC =
1566-
TRI->getMinimalPhysRegClass(Reg, VT);
1541+
const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
15671542
const TargetRegisterClass *DestRC = TRI->getCrossCopyRegClass(RC);
15681543

15691544
// If cross copy register class is the same as RC, then it must be possible

llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,7 @@ static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
130130
}
131131

132132
if (PhysReg) {
133-
const TargetRegisterClass *RC =
134-
TRI->getMinimalPhysRegClass(Reg, Def->getSimpleValueType(ResNo));
133+
const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
135134
Cost = RC->expensiveOrImpossibleToCopy() ? -1 : RC->getCopyCost();
136135
}
137136
}

llvm/lib/CodeGen/TargetRegisterInfo.cpp

Lines changed: 7 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -204,86 +204,27 @@ TargetRegisterInfo::getAllocatableClass(const TargetRegisterClass *RC) const {
204204
return nullptr;
205205
}
206206

207-
template <typename TypeT>
208-
static const TargetRegisterClass *
209-
getMinimalPhysRegClass(const TargetRegisterInfo *TRI, MCRegister Reg,
210-
TypeT Ty) {
211-
static_assert(std::is_same_v<TypeT, MVT> || std::is_same_v<TypeT, LLT>);
212-
assert(Reg.isPhysical() && "reg must be a physical register");
213-
214-
bool IsDefault = [&]() {
215-
if constexpr (std::is_same_v<TypeT, MVT>)
216-
return Ty == MVT::Other;
217-
else
218-
return !Ty.isValid();
219-
}();
220-
221-
if (IsDefault) {
222-
if (const TargetRegisterClass *RC = TRI->getDefaultMinimalPhysRegClass(Reg))
223-
return RC;
224-
}
225-
226-
// Pick the most sub register class of the right type that contains
227-
// this physreg.
228-
const TargetRegisterClass *BestRC = nullptr;
229-
for (const TargetRegisterClass *RC : TRI->regclasses()) {
230-
if ((IsDefault || TRI->isTypeLegalForClass(*RC, Ty)) && RC->contains(Reg) &&
231-
(!BestRC || BestRC->hasSubClass(RC)))
232-
BestRC = RC;
233-
}
234-
235-
if constexpr (std::is_same_v<TypeT, MVT>)
236-
assert(BestRC && "Couldn't find the register class");
237-
return BestRC;
238-
}
239-
240-
template <typename TypeT>
241207
static const TargetRegisterClass *
242208
getCommonMinimalPhysRegClass(const TargetRegisterInfo *TRI, MCRegister Reg1,
243-
MCRegister Reg2, TypeT Ty) {
244-
static_assert(std::is_same_v<TypeT, MVT> || std::is_same_v<TypeT, LLT>);
209+
MCRegister Reg2) {
245210
assert(Reg1.isPhysical() && Reg2.isPhysical() &&
246211
"Reg1/Reg2 must be a physical register");
247212

248-
bool IsDefault = [&]() {
249-
if constexpr (std::is_same_v<TypeT, MVT>)
250-
return Ty == MVT::Other;
251-
else
252-
return !Ty.isValid();
253-
}();
254-
255-
// Pick the most sub register class of the right type that contains
256-
// this physreg.
213+
// Pick the most specific register class that contains both physregs.
257214
const TargetRegisterClass *BestRC = nullptr;
258215
for (const TargetRegisterClass *RC : TRI->regclasses()) {
259-
if ((IsDefault || TRI->isTypeLegalForClass(*RC, Ty)) &&
260-
RC->contains(Reg1, Reg2) && (!BestRC || BestRC->hasSubClass(RC)))
216+
if (RC->contains(Reg1, Reg2) && (!BestRC || BestRC->hasSubClass(RC)))
261217
BestRC = RC;
262218
}
263219

264-
if constexpr (std::is_same_v<TypeT, MVT>)
265-
assert(BestRC && "Couldn't find the register class");
220+
assert(BestRC && "Couldn't find the register class");
266221
return BestRC;
267222
}
268223

269224
const TargetRegisterClass *
270-
TargetRegisterInfo::getMinimalPhysRegClass(MCRegister Reg, MVT VT) const {
271-
return ::getMinimalPhysRegClass(this, Reg, VT);
272-
}
273-
274-
const TargetRegisterClass *TargetRegisterInfo::getCommonMinimalPhysRegClass(
275-
MCRegister Reg1, MCRegister Reg2, MVT VT) const {
276-
return ::getCommonMinimalPhysRegClass(this, Reg1, Reg2, VT);
277-
}
278-
279-
const TargetRegisterClass *
280-
TargetRegisterInfo::getMinimalPhysRegClassLLT(MCRegister Reg, LLT Ty) const {
281-
return ::getMinimalPhysRegClass(this, Reg, Ty);
282-
}
283-
284-
const TargetRegisterClass *TargetRegisterInfo::getCommonMinimalPhysRegClassLLT(
285-
MCRegister Reg1, MCRegister Reg2, LLT Ty) const {
286-
return ::getCommonMinimalPhysRegClass(this, Reg1, Reg2, Ty);
225+
TargetRegisterInfo::getCommonMinimalPhysRegClass(MCRegister Reg1,
226+
MCRegister Reg2) const {
227+
return ::getCommonMinimalPhysRegClass(this, Reg1, Reg2);
287228
}
288229

289230
/// getAllocatableSetForRC - Toggle the bits that represent allocatable

0 commit comments

Comments
 (0)