Skip to content

Commit 2e30032

Browse files
authored
[TRI][RISCV] Add methods to get common register class of two registers (#118435)
Here we add two methods `getCommonMinimalPhysRegClass` and a LLT version `getCommonMinimalPhysRegClassLLT`, which return the most sub register class of the right type that contains these two input registers. We don't overload the `getMinimalPhysRegClass` as there will be ambiguities. We use it to simplify some code in RISC-V target.
1 parent 8db7327 commit 2e30032

File tree

3 files changed

+80
-30
lines changed

3 files changed

+80
-30
lines changed

Diff for: llvm/include/llvm/CodeGen/TargetRegisterInfo.h

+15
Original file line numberDiff line numberDiff line change
@@ -347,13 +347,28 @@ class TargetRegisterInfo : public MCRegisterInfo {
347347
const TargetRegisterClass *getMinimalPhysRegClass(MCRegister Reg,
348348
MVT VT = MVT::Other) const;
349349

350+
/// Returns the common Register Class of two physical registers of the given
351+
/// type, picking the most sub register class of the right type that contains
352+
/// these two physregs.
353+
const TargetRegisterClass *
354+
getCommonMinimalPhysRegClass(MCRegister Reg1, MCRegister Reg2,
355+
MVT VT = MVT::Other) const;
356+
350357
/// Returns the Register Class of a physical register of the given type,
351358
/// picking the most sub register class of the right type that contains this
352359
/// physreg. If there is no register class compatible with the given type,
353360
/// returns nullptr.
354361
const TargetRegisterClass *getMinimalPhysRegClassLLT(MCRegister Reg,
355362
LLT Ty = LLT()) const;
356363

364+
/// Returns the common Register Class of two physical registers of the given
365+
/// type, picking the most sub register class of the right type that contains
366+
/// these two physregs. If there is no register class compatible with the
367+
/// given type, returns nullptr.
368+
const TargetRegisterClass *
369+
getCommonMinimalPhysRegClassLLT(MCRegister Reg1, MCRegister Reg2,
370+
LLT Ty = LLT()) const;
371+
357372
/// Return the maximal subclass of the given register class that is
358373
/// allocatable or NULL.
359374
const TargetRegisterClass *

Diff for: llvm/lib/CodeGen/TargetRegisterInfo.cpp

+59-18
Original file line numberDiff line numberDiff line change
@@ -201,44 +201,85 @@ TargetRegisterInfo::getAllocatableClass(const TargetRegisterClass *RC) const {
201201
return nullptr;
202202
}
203203

204-
/// getMinimalPhysRegClass - Returns the Register Class of a physical
205-
/// register of the given type, picking the most sub register class of
206-
/// the right type that contains this physreg.
207-
const TargetRegisterClass *
208-
TargetRegisterInfo::getMinimalPhysRegClass(MCRegister reg, MVT VT) const {
209-
assert(Register::isPhysicalRegister(reg) &&
204+
template <typename TypeT>
205+
static const TargetRegisterClass *
206+
getMinimalPhysRegClass(const TargetRegisterInfo *TRI, MCRegister Reg,
207+
TypeT Ty) {
208+
static_assert(std::is_same_v<TypeT, MVT> || std::is_same_v<TypeT, LLT>);
209+
assert(Register::isPhysicalRegister(Reg) &&
210210
"reg must be a physical register");
211211

212+
bool IsDefault = [&]() {
213+
if constexpr (std::is_same_v<TypeT, MVT>)
214+
return Ty == MVT::Other;
215+
else
216+
return !Ty.isValid();
217+
}();
218+
212219
// Pick the most sub register class of the right type that contains
213220
// this physreg.
214-
const TargetRegisterClass* BestRC = nullptr;
215-
for (const TargetRegisterClass* RC : regclasses()) {
216-
if ((VT == MVT::Other || isTypeLegalForClass(*RC, VT)) &&
217-
RC->contains(reg) && (!BestRC || BestRC->hasSubClass(RC)))
221+
const TargetRegisterClass *BestRC = nullptr;
222+
for (const TargetRegisterClass *RC : TRI->regclasses()) {
223+
if ((IsDefault || TRI->isTypeLegalForClass(*RC, Ty)) && RC->contains(Reg) &&
224+
(!BestRC || BestRC->hasSubClass(RC)))
218225
BestRC = RC;
219226
}
220227

221-
assert(BestRC && "Couldn't find the register class");
228+
if constexpr (std::is_same_v<TypeT, MVT>)
229+
assert(BestRC && "Couldn't find the register class");
222230
return BestRC;
223231
}
224232

225-
const TargetRegisterClass *
226-
TargetRegisterInfo::getMinimalPhysRegClassLLT(MCRegister reg, LLT Ty) const {
227-
assert(Register::isPhysicalRegister(reg) &&
228-
"reg must be a physical register");
233+
template <typename TypeT>
234+
static const TargetRegisterClass *
235+
getCommonMinimalPhysRegClass(const TargetRegisterInfo *TRI, MCRegister Reg1,
236+
MCRegister Reg2, TypeT Ty) {
237+
static_assert(std::is_same_v<TypeT, MVT> || std::is_same_v<TypeT, LLT>);
238+
assert(Register::isPhysicalRegister(Reg1) &&
239+
Register::isPhysicalRegister(Reg2) &&
240+
"Reg1/Reg2 must be a physical register");
241+
242+
bool IsDefault = [&]() {
243+
if constexpr (std::is_same_v<TypeT, MVT>)
244+
return Ty == MVT::Other;
245+
else
246+
return !Ty.isValid();
247+
}();
229248

230249
// Pick the most sub register class of the right type that contains
231250
// this physreg.
232251
const TargetRegisterClass *BestRC = nullptr;
233-
for (const TargetRegisterClass *RC : regclasses()) {
234-
if ((!Ty.isValid() || isTypeLegalForClass(*RC, Ty)) && RC->contains(reg) &&
235-
(!BestRC || BestRC->hasSubClass(RC)))
252+
for (const TargetRegisterClass *RC : TRI->regclasses()) {
253+
if ((IsDefault || TRI->isTypeLegalForClass(*RC, Ty)) &&
254+
RC->contains(Reg1, Reg2) && (!BestRC || BestRC->hasSubClass(RC)))
236255
BestRC = RC;
237256
}
238257

258+
if constexpr (std::is_same_v<TypeT, MVT>)
259+
assert(BestRC && "Couldn't find the register class");
239260
return BestRC;
240261
}
241262

263+
const TargetRegisterClass *
264+
TargetRegisterInfo::getMinimalPhysRegClass(MCRegister Reg, MVT VT) const {
265+
return ::getMinimalPhysRegClass(this, Reg, VT);
266+
}
267+
268+
const TargetRegisterClass *TargetRegisterInfo::getCommonMinimalPhysRegClass(
269+
MCRegister Reg1, MCRegister Reg2, MVT VT) const {
270+
return ::getCommonMinimalPhysRegClass(this, Reg1, Reg2, VT);
271+
}
272+
273+
const TargetRegisterClass *
274+
TargetRegisterInfo::getMinimalPhysRegClassLLT(MCRegister Reg, LLT Ty) const {
275+
return ::getMinimalPhysRegClass(this, Reg, Ty);
276+
}
277+
278+
const TargetRegisterClass *TargetRegisterInfo::getCommonMinimalPhysRegClassLLT(
279+
MCRegister Reg1, MCRegister Reg2, LLT Ty) const {
280+
return ::getCommonMinimalPhysRegClass(this, Reg1, Reg2, Ty);
281+
}
282+
242283
/// getAllocatableSetForRC - Toggle the bits that represent allocatable
243284
/// registers for the specific register class.
244285
static void getAllocatableSetForRC(const MachineFunction &MF,

Diff for: llvm/lib/Target/RISCV/RISCVInstrInfo.cpp

+6-12
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ void RISCVInstrInfo::copyPhysRegVector(
390390
auto FindRegWithEncoding = [TRI](const TargetRegisterClass &RegClass,
391391
uint16_t Encoding) {
392392
MCRegister Reg = RISCV::V0 + Encoding;
393-
if (&RegClass == &RISCV::VRRegClass)
393+
if (RISCVRI::getLMul(RegClass.TSFlags) == RISCVII::LMUL_1)
394394
return Reg;
395395
return TRI->getMatchingSuperReg(Reg, RISCV::sub_vrm1_0, &RegClass);
396396
};
@@ -564,17 +564,11 @@ void RISCVInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
564564
}
565565

566566
// VR->VR copies.
567-
static const TargetRegisterClass *RVVRegClasses[] = {
568-
&RISCV::VRRegClass, &RISCV::VRM2RegClass, &RISCV::VRM4RegClass,
569-
&RISCV::VRM8RegClass, &RISCV::VRN2M1RegClass, &RISCV::VRN2M2RegClass,
570-
&RISCV::VRN2M4RegClass, &RISCV::VRN3M1RegClass, &RISCV::VRN3M2RegClass,
571-
&RISCV::VRN4M1RegClass, &RISCV::VRN4M2RegClass, &RISCV::VRN5M1RegClass,
572-
&RISCV::VRN6M1RegClass, &RISCV::VRN7M1RegClass, &RISCV::VRN8M1RegClass};
573-
for (const auto &RegClass : RVVRegClasses) {
574-
if (RegClass->contains(DstReg, SrcReg)) {
575-
copyPhysRegVector(MBB, MBBI, DL, DstReg, SrcReg, KillSrc, RegClass);
576-
return;
577-
}
567+
const TargetRegisterClass *RegClass =
568+
TRI->getCommonMinimalPhysRegClass(SrcReg, DstReg);
569+
if (RISCVRegisterInfo::isRVVRegClass(RegClass)) {
570+
copyPhysRegVector(MBB, MBBI, DL, DstReg, SrcReg, KillSrc, RegClass);
571+
return;
578572
}
579573

580574
llvm_unreachable("Impossible reg-to-reg copy");

0 commit comments

Comments
 (0)