diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td --- a/llvm/include/llvm/Target/Target.td +++ b/llvm/include/llvm/Target/Target.td @@ -186,6 +186,10 @@ 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 diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.h b/llvm/lib/Target/AArch64/AArch64RegisterInfo.h --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.h +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.h @@ -91,7 +91,6 @@ 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; diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp @@ -366,10 +366,6 @@ 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 { diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -97,6 +97,7 @@ 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; let SubRegIndices = [sub_32] in { @@ -132,6 +133,7 @@ def FP : AArch64Reg<29, "x29", [W29]>, DwarfRegAlias; def LR : AArch64Reg<30, "x30", [W30]>, DwarfRegAlias; def SP : AArch64Reg<31, "sp", [WSP]>, DwarfRegAlias; +let isConstant = true in def XZR : AArch64Reg<31, "xzr", [WZR]>, DwarfRegAlias; } diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.h b/llvm/lib/Target/AMDGPU/SIRegisterInfo.h --- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.h +++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.h @@ -289,8 +289,6 @@ return isVGPR(MRI, Reg) || isAGPR(MRI, Reg); } - bool isConstantPhysReg(MCRegister PhysReg) const override; - bool isDivergentRegClass(const TargetRegisterClass *RC) const override { return !isSGPRClass(RC); } diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp --- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp @@ -3083,20 +3083,6 @@ 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 SIRegisterInfo::getAllSGPR128(const MachineFunction &MF) const { return makeArrayRef(AMDGPU::SGPR_128RegClass.begin(), diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.td b/llvm/lib/Target/AMDGPU/SIRegisterInfo.td --- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.td +++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.td @@ -219,21 +219,25 @@ 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>; defm SRC_POPS_EXITING_WAVE_ID : SIRegLoHi16<"src_pops_exiting_wave_id", 239>; +} // isConstant = true // Not addressable def MODE : SIReg <"mode", 0>; diff --git a/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.h b/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.h --- a/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.h +++ b/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.h @@ -31,7 +31,6 @@ 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, diff --git a/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp b/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp --- a/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp @@ -96,10 +96,6 @@ return Reserved; } -bool LoongArchRegisterInfo::isConstantPhysReg(MCRegister PhysReg) const { - return PhysReg == LoongArch::R0; -} - Register LoongArchRegisterInfo::getFrameRegister(const MachineFunction &MF) const { const TargetFrameLowering *TFI = getFrameLowering(MF); diff --git a/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td b/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td --- a/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.td @@ -40,6 +40,7 @@ // 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]>; diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.h b/llvm/lib/Target/Mips/MipsRegisterInfo.h --- a/llvm/lib/Target/Mips/MipsRegisterInfo.h +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.h @@ -69,8 +69,6 @@ /// 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; diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp --- a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp @@ -318,7 +318,3 @@ // sized objects. return MF.getRegInfo().canReserveReg(BP); } - -bool MipsRegisterInfo::isConstantPhysReg(MCRegister PhysReg) const { - return PhysReg == Mips::ZERO_64 || PhysReg == Mips::ZERO; -} diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.td b/llvm/lib/Target/Mips/MipsRegisterInfo.td --- a/llvm/lib/Target/Mips/MipsRegisterInfo.td +++ b/llvm/lib/Target/Mips/MipsRegisterInfo.td @@ -84,6 +84,7 @@ 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 @@ 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]>; diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.td b/llvm/lib/Target/PowerPC/PPCRegisterInfo.td --- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.td +++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.td @@ -185,8 +185,10 @@ } // The representation of r0 when treated as the constant 0. +let isConstant = true in { def ZERO : GPR<0, "0">, DwarfRegAlias; def ZERO8 : GP8, DwarfRegAlias; +} // isConstant = true // Representations of the frame pointer used by ISD::FRAMEADDR. def FP : GPR<0 /* arbitrary */, "**FRAME POINTER**">; diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.h b/llvm/lib/Target/RISCV/RISCVRegisterInfo.h --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.h +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.h @@ -33,8 +33,6 @@ 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, diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp @@ -117,10 +117,6 @@ return !MF.getSubtarget().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; } diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td @@ -77,6 +77,7 @@ // 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 @@ 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)]>; } diff --git a/llvm/lib/Target/VE/VERegisterInfo.h b/llvm/lib/Target/VE/VERegisterInfo.h --- a/llvm/lib/Target/VE/VERegisterInfo.h +++ b/llvm/lib/Target/VE/VERegisterInfo.h @@ -30,7 +30,6 @@ 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; diff --git a/llvm/lib/Target/VE/VERegisterInfo.cpp b/llvm/lib/Target/VE/VERegisterInfo.cpp --- a/llvm/lib/Target/VE/VERegisterInfo.cpp +++ b/llvm/lib/Target/VE/VERegisterInfo.cpp @@ -96,16 +96,6 @@ 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 { diff --git a/llvm/lib/Target/VE/VERegisterInfo.td b/llvm/lib/Target/VE/VERegisterInfo.td --- a/llvm/lib/Target/VE/VERegisterInfo.td +++ b/llvm/lib/Target/VE/VERegisterInfo.td @@ -148,10 +148,13 @@ 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, 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 diff --git a/llvm/utils/TableGen/CodeGenRegisters.h b/llvm/utils/TableGen/CodeGenRegisters.h --- a/llvm/utils/TableGen/CodeGenRegisters.h +++ b/llvm/utils/TableGen/CodeGenRegisters.h @@ -154,6 +154,7 @@ bool CoveredBySubRegs; bool HasDisjunctSubRegs; bool Artificial; + bool Constant; // Map SubRegIndex -> Register. typedef std::mapgetValueAsListOfInts("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"); } diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp --- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp +++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp @@ -1190,6 +1190,7 @@ << "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 @@ 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 " << ClassName << "::getRegMaskNames() const {\n"; if (!CSRSets.empty()) {