[RegisterInfoEmitter] Generate isConstantPhysReg(). NFCI
authorAlex Richardson <alexrichardson@google.com>
Wed, 24 Aug 2022 13:42:50 +0000 (13:42 +0000)
committerAlex Richardson <alexrichardson@google.com>
Wed, 24 Aug 2022 14:16:20 +0000 (14:16 +0000)
This commit moves the information on whether a register is constant into
the Tablegen files to allow generating the implementaiton of
isConstantPhysReg(). I've marked isConstantPhysReg() as final in this
generated file to ensure that changes are made to tablegen instead of
overriding this function, but if that turns out to be too restrictive,
we can remove the qualifier.

This should be pretty much NFC, but I did notice that e.g. the AMDGPU
generated file also includes the LO16/HI16 registers now.

The new isConstant flag will also be used by D131958 to ensure that
constant registers are marked as call-preserved.

Differential Revision: https://reviews.llvm.org/D131962

23 files changed:
llvm/include/llvm/Target/Target.td
llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
llvm/lib/Target/AArch64/AArch64RegisterInfo.h
llvm/lib/Target/AArch64/AArch64RegisterInfo.td
llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
llvm/lib/Target/AMDGPU/SIRegisterInfo.h
llvm/lib/Target/AMDGPU/SIRegisterInfo.td
llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp
llvm/lib/Target/LoongArch/LoongArchRegisterInfo.h
llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td
llvm/lib/Target/Mips/MipsRegisterInfo.cpp
llvm/lib/Target/Mips/MipsRegisterInfo.h
llvm/lib/Target/Mips/MipsRegisterInfo.td
llvm/lib/Target/PowerPC/PPCRegisterInfo.td
llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
llvm/lib/Target/RISCV/RISCVRegisterInfo.h
llvm/lib/Target/RISCV/RISCVRegisterInfo.td
llvm/lib/Target/VE/VERegisterInfo.cpp
llvm/lib/Target/VE/VERegisterInfo.h
llvm/lib/Target/VE/VERegisterInfo.td
llvm/utils/TableGen/CodeGenRegisters.cpp
llvm/utils/TableGen/CodeGenRegisters.h
llvm/utils/TableGen/RegisterInfoEmitter.cpp

index c5b2462..d865704 100644 (file)
@@ -186,6 +186,10 @@ class Register<string n, list<string> altNames = []> {
   bits<16> HWEncoding = 0;
 
   bit isArtificial = false;
+
+  // isConstant - This register always holds a constant value (e.g. the zero
+  // register in architectures such as MIPS)
+  bit isConstant = false;
 }
 
 // RegisterWithSubRegs - This can be used to define instances of Register which
index caabaee..007ec5b 100644 (file)
@@ -366,10 +366,6 @@ bool AArch64RegisterInfo::isAsmClobberable(const MachineFunction &MF,
   return !isReservedReg(MF, PhysReg);
 }
 
-bool AArch64RegisterInfo::isConstantPhysReg(MCRegister PhysReg) const {
-  return PhysReg == AArch64::WZR || PhysReg == AArch64::XZR;
-}
-
 const TargetRegisterClass *
 AArch64RegisterInfo::getPointerRegClass(const MachineFunction &MF,
                                       unsigned Kind) const {
index 12dd70f..91a5af1 100644 (file)
@@ -91,7 +91,6 @@ public:
   BitVector getReservedRegs(const MachineFunction &MF) const override;
   bool isAsmClobberable(const MachineFunction &MF,
                        MCRegister PhysReg) const override;
-  bool isConstantPhysReg(MCRegister PhysReg) const override;
   const TargetRegisterClass *
   getPointerRegClass(const MachineFunction &MF,
                      unsigned Kind = 0) const override;
index 7a2b165..eeca8a6 100644 (file)
@@ -97,6 +97,7 @@ def W28   : AArch64Reg<28, "w28">, DwarfRegNum<[28]>;
 def W29   : AArch64Reg<29, "w29">, DwarfRegNum<[29]>;
 def W30   : AArch64Reg<30, "w30">, DwarfRegNum<[30]>;
 def WSP   : AArch64Reg<31, "wsp">, DwarfRegNum<[31]>;
+let isConstant = true in
 def WZR   : AArch64Reg<31, "wzr">, DwarfRegAlias<WSP>;
 
 let SubRegIndices = [sub_32] in {
@@ -132,6 +133,7 @@ def X28   : AArch64Reg<28, "x28", [W28]>, DwarfRegAlias<W28>;
 def FP    : AArch64Reg<29, "x29", [W29]>, DwarfRegAlias<W29>;
 def LR    : AArch64Reg<30, "x30", [W30]>, DwarfRegAlias<W30>;
 def SP    : AArch64Reg<31, "sp",  [WSP]>, DwarfRegAlias<WSP>;
+let isConstant = true in
 def XZR   : AArch64Reg<31, "xzr", [WZR]>, DwarfRegAlias<WSP>;
 }
 
index 417c348..e20e1eb 100644 (file)
@@ -3083,20 +3083,6 @@ SIRegisterInfo::getProperlyAlignedRC(const TargetRegisterClass *RC) const {
   return RC;
 }
 
-bool SIRegisterInfo::isConstantPhysReg(MCRegister PhysReg) const {
-  switch (PhysReg) {
-  case AMDGPU::SGPR_NULL:
-  case AMDGPU::SGPR_NULL64:
-  case AMDGPU::SRC_SHARED_BASE:
-  case AMDGPU::SRC_PRIVATE_BASE:
-  case AMDGPU::SRC_SHARED_LIMIT:
-  case AMDGPU::SRC_PRIVATE_LIMIT:
-    return true;
-  default:
-    return false;
-  }
-}
-
 ArrayRef<MCPhysReg>
 SIRegisterInfo::getAllSGPR128(const MachineFunction &MF) const {
   return makeArrayRef(AMDGPU::SGPR_128RegClass.begin(),
index 6024158..289c5ba 100644 (file)
@@ -289,8 +289,6 @@ public:
     return isVGPR(MRI, Reg) || isAGPR(MRI, Reg);
   }
 
-  bool isConstantPhysReg(MCRegister PhysReg) const override;
-
   bool isDivergentRegClass(const TargetRegisterClass *RC) const override {
     return !isSGPRClass(RC);
   }
index fccb08f..e5095e9 100644 (file)
@@ -219,20 +219,25 @@ defm M0 : SIRegLoHi16 <"m0", 0>;
 
 defm SGPR_NULL_gfxpre11 : SIRegLoHi16 <"null", 125>;
 defm SGPR_NULL_gfx11plus : SIRegLoHi16 <"null", 124>;
+let isConstant = true in {
 defm SGPR_NULL : SIRegLoHi16 <"null", 0>;
 defm SGPR_NULL_HI : SIRegLoHi16 <"", 0>;
+} // isConstant = true
 
 def SGPR_NULL64 :
     RegisterWithSubRegs<"null", [SGPR_NULL, SGPR_NULL_HI]> {
   let Namespace = "AMDGPU";
   let SubRegIndices = [sub0, sub1];
   let HWEncoding = SGPR_NULL.HWEncoding;
+  let isConstant = true;
 }
 
+let isConstant = true in {
 defm SRC_SHARED_BASE : SIRegLoHi16<"src_shared_base", 235>;
 defm SRC_SHARED_LIMIT : SIRegLoHi16<"src_shared_limit", 236>;
 defm SRC_PRIVATE_BASE : SIRegLoHi16<"src_private_base", 237>;
 defm SRC_PRIVATE_LIMIT : SIRegLoHi16<"src_private_limit", 238>;
+} // isConstant = true
 defm SRC_POPS_EXITING_WAVE_ID : SIRegLoHi16<"src_pops_exiting_wave_id", 239>;
 
 // Not addressable
index 05902eb..4244255 100644 (file)
@@ -96,10 +96,6 @@ LoongArchRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
   return Reserved;
 }
 
-bool LoongArchRegisterInfo::isConstantPhysReg(MCRegister PhysReg) const {
-  return PhysReg == LoongArch::R0;
-}
-
 Register
 LoongArchRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
   const TargetFrameLowering *TFI = getFrameLowering(MF);
index cca130c..cf9ece4 100644 (file)
@@ -31,7 +31,6 @@ struct LoongArchRegisterInfo : public LoongArchGenRegisterInfo {
   const uint32_t *getNoPreservedMask() const override;
 
   BitVector getReservedRegs(const MachineFunction &MF) const override;
-  bool isConstantPhysReg(MCRegister PhysReg) const override;
 
   const TargetRegisterClass *
   getPointerRegClass(const MachineFunction &MF,
index 2d5ad99..2a46c6e 100644 (file)
@@ -40,6 +40,7 @@ def RegAliasName : RegAltNameIndex;
 // Integer registers
 
 let RegAltNameIndices = [RegAliasName] in {
+  let isConstant = true in
   def R0  : LoongArchReg<0,  "r0", ["zero"]>, DwarfRegNum<[0]>;
   def R1  : LoongArchReg<1,  "r1", ["ra"]>, DwarfRegNum<[1]>;
   def R2  : LoongArchReg<2,  "r2", ["tp"]>, DwarfRegNum<[2]>;
index 6aa5610..390ab9d 100644 (file)
@@ -318,7 +318,3 @@ bool MipsRegisterInfo::canRealignStack(const MachineFunction &MF) const {
   // sized objects.
   return MF.getRegInfo().canReserveReg(BP);
 }
-
-bool MipsRegisterInfo::isConstantPhysReg(MCRegister PhysReg) const {
-  return PhysReg == Mips::ZERO_64 || PhysReg == Mips::ZERO;
-}
index 1f45f6a..06f214c 100644 (file)
@@ -69,8 +69,6 @@ public:
   /// Debug information queries.
   Register getFrameRegister(const MachineFunction &MF) const override;
 
-  bool isConstantPhysReg(MCRegister PhysReg) const override;
-
   /// Return GPR register class.
   virtual const TargetRegisterClass *intRegClass(unsigned Size) const = 0;
 
index 7d4dcca..237ccdc 100644 (file)
@@ -84,6 +84,7 @@ class HWR<bits<16> Enc, string n> : MipsReg<Enc, n>;
 
 let Namespace = "Mips" in {
   // General Purpose Registers
+  let isConstant = true in
   def ZERO : MipsGPRReg< 0, "zero">, DwarfRegNum<[0]>;
   def AT   : MipsGPRReg< 1, "1">,    DwarfRegNum<[1]>;
   def V0   : MipsGPRReg< 2, "2">,    DwarfRegNum<[2]>;
@@ -118,6 +119,7 @@ let Namespace = "Mips" in {
   def RA   : MipsGPRReg< 31, "ra">,  DwarfRegNum<[31]>;
 
   // General Purpose 64-bit Registers
+  let isConstant = true in
   def ZERO_64 : Mips64GPRReg< 0, "zero", [ZERO]>, DwarfRegNum<[0]>;
   def AT_64   : Mips64GPRReg< 1, "1",    [AT]>, DwarfRegNum<[1]>;
   def V0_64   : Mips64GPRReg< 2, "2",    [V0]>, DwarfRegNum<[2]>;
index 7892b0d..49b26cd 100644 (file)
@@ -185,8 +185,10 @@ foreach Index = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 } in
 }
 
 // The representation of r0 when treated as the constant 0.
+let isConstant = true in {
 def ZERO  : GPR<0, "0">,    DwarfRegAlias<R0>;
 def ZERO8 : GP8<ZERO, "0">, DwarfRegAlias<X0>;
+} // isConstant = true
 
 // Representations of the frame pointer used by ISD::FRAMEADDR.
 def FP   : GPR<0 /* arbitrary */, "**FRAME POINTER**">;
index 0c92190..7e8fd12 100644 (file)
@@ -117,10 +117,6 @@ bool RISCVRegisterInfo::isAsmClobberable(const MachineFunction &MF,
   return !MF.getSubtarget<RISCVSubtarget>().isRegisterReservedByUser(PhysReg);
 }
 
-bool RISCVRegisterInfo::isConstantPhysReg(MCRegister PhysReg) const {
-  return PhysReg == RISCV::X0 || PhysReg == RISCV::VLENB;
-}
-
 const uint32_t *RISCVRegisterInfo::getNoPreservedMask() const {
   return CSR_NoRegs_RegMask;
 }
index 9e0ef79..1c66e94 100644 (file)
@@ -33,8 +33,6 @@ struct RISCVRegisterInfo : public RISCVGenRegisterInfo {
   bool isAsmClobberable(const MachineFunction &MF,
                         MCRegister PhysReg) const override;
 
-  bool isConstantPhysReg(MCRegister PhysReg) const override;
-
   const uint32_t *getNoPreservedMask() const override;
 
   bool hasReservedSpillSlot(const MachineFunction &MF, Register Reg,
index 4ff60eb..7825249 100644 (file)
@@ -77,6 +77,7 @@ def sub_32_hi  : SubRegIndex<32, 32>;
 // instructions.
 
 let RegAltNameIndices = [ABIRegAltName] in {
+  let isConstant = true in
   def X0  : RISCVReg<0, "x0", ["zero"]>, DwarfRegNum<[0]>;
   let CostPerUse = [0, 1] in {
   def X1  : RISCVReg<1, "x1", ["ra"]>, DwarfRegNum<[1]>;
@@ -458,6 +459,7 @@ let RegAltNameIndices = [ABIRegAltName] in {
   def VL     : RISCVReg<0, "vl", ["vl"]>;
   def VXSAT  : RISCVReg<0, "vxsat", ["vxsat"]>;
   def VXRM   : RISCVReg<0, "vxrm", ["vxrm"]>;
+  let isConstant = true in
   def VLENB  : RISCVReg<0, "vlenb", ["vlenb"]>,
                DwarfRegNum<[!add(4096, SysRegVLENB.Encoding)]>;
 }
index 1c1ffb4..70e5e6e 100644 (file)
@@ -96,16 +96,6 @@ BitVector VERegisterInfo::getReservedRegs(const MachineFunction &MF) const {
   return Reserved;
 }
 
-bool VERegisterInfo::isConstantPhysReg(MCRegister PhysReg) const {
-  switch (PhysReg) {
-  case VE::VM0:
-  case VE::VMP0:
-    return true;
-  default:
-    return false;
-  }
-}
-
 const TargetRegisterClass *
 VERegisterInfo::getPointerRegClass(const MachineFunction &MF,
                                    unsigned Kind) const {
index 334fb96..bc1838f 100644 (file)
@@ -30,7 +30,6 @@ public:
   const uint32_t *getNoPreservedMask() const override;
 
   BitVector getReservedRegs(const MachineFunction &MF) const override;
-  bool isConstantPhysReg(MCRegister PhysReg) const override;
 
   const TargetRegisterClass *getPointerRegClass(const MachineFunction &MF,
                                                 unsigned Kind) const override;
index cca0ad2..fbe71d3 100644 (file)
@@ -148,10 +148,13 @@ foreach I = 0-63 in
 def VIX : VEVecReg<255, "vix", [], ["vix"]>;
 
 // Vector mask registers - 256 bits wide
-foreach I = 0-15 in
+let isConstant = true in
+def VM0 : VEMaskReg<0, "vm0", [], ["vm0"]>, DwarfRegNum<[128]>;
+foreach I = 1-15 in
   def VM#I : VEMaskReg<I, "vm"#I, [], ["vm"#I]>, DwarfRegNum<[!add(128,I)]>;
 
 // Aliases of VMs to use as a pair of two VM for packed instructions
+let isConstant = true in
 def VMP0 : VEMaskReg<0, "vm0", [], ["vm0"]>;
 
 let SubRegIndices = [sub_vm_even, sub_vm_odd], CoveredBySubRegs = 1 in
index 93ed86c..a35c2af 100644 (file)
@@ -154,8 +154,8 @@ CodeGenRegister::CodeGenRegister(Record *R, unsigned Enum)
     : TheDef(R), EnumValue(Enum),
       CostPerUse(R->getValueAsListOfInts("CostPerUse")),
       CoveredBySubRegs(R->getValueAsBit("CoveredBySubRegs")),
-      HasDisjunctSubRegs(false), SubRegsComplete(false),
-      SuperRegsComplete(false), TopoSig(~0u) {
+      HasDisjunctSubRegs(false), Constant(R->getValueAsBit("isConstant")),
+      SubRegsComplete(false), SuperRegsComplete(false), TopoSig(~0u) {
   Artificial = R->getValueAsBit("isArtificial");
 }
 
index e5e92fc..f269a52 100644 (file)
@@ -154,6 +154,7 @@ namespace llvm {
     bool CoveredBySubRegs;
     bool HasDisjunctSubRegs;
     bool Artificial;
+    bool Constant;
 
     // Map SubRegIndex -> Register.
     typedef std::map<CodeGenSubRegIndex *, CodeGenRegister *,
index 3a0fa56..2f7d85f 100644 (file)
@@ -1190,6 +1190,7 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,
      << "MCRegister) const override;\n"
      << "  bool isArgumentRegister(const MachineFunction &, "
      << "MCRegister) const override;\n"
+     << "  bool isConstantPhysReg(MCRegister PhysReg) const override final;\n"
      << "  /// Devirtualized TargetFrameLowering.\n"
      << "  static const " << TargetName << "FrameLowering *getFrameLowering(\n"
      << "      const MachineFunction &MF);\n"
@@ -1678,6 +1679,15 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
   OS << "      false;\n";
   OS << "}\n\n";
 
+  OS << "bool " << ClassName << "::\n"
+     << "isConstantPhysReg(MCRegister PhysReg) const {\n"
+     << "  return\n";
+  for (const auto &Reg : Regs)
+    if (Reg.Constant)
+      OS << "      PhysReg == " << getQualifiedName(Reg.TheDef) << " ||\n";
+  OS << "      false;\n";
+  OS << "}\n\n";
+
   OS << "ArrayRef<const char *> " << ClassName
      << "::getRegMaskNames() const {\n";
   if (!CSRSets.empty()) {