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 @@ -276,6 +276,10 @@ // constrained classes first. The value has to be in the range [0,63]. int AllocationPriority = 0; + // Generate register pressure set for this register class and any class + // synthesized from it. Set to 0 to inhibit unneeded pressure sets. + bit GeneratePressureSet = 1; + // Weight override for register pressure calculation. This is the value // TargetRegisterClass::getRegClassWeight() will return. The weight is in // units of pressure for this register class. If unset tablegen will 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 @@ -247,6 +247,7 @@ // Give all SGPR classes higher priority than VGPR classes, because // we want to spill SGPRs to VGPRs. let AllocationPriority = 9; + let GeneratePressureSet = 0; } // SGPR 64-bit registers @@ -443,6 +444,7 @@ let CopyCost = -1; } +let GeneratePressureSet = 0 in { // Subset of SReg_32 without M0 for SMRD instructions and alike. // See comments in SIInstructions.td for more info. def SReg_32_XM0_XEXEC : RegisterClass<"AMDGPU", [i32, f32, i16, f16, v2i16, v2f16, i1], 32, @@ -462,6 +464,7 @@ (add SReg_32_XM0_XEXEC, EXEC_LO, EXEC_HI)> { let AllocationPriority = 10; } +} // End GeneratePressureSet = 0 // Register class for all scalar registers (SGPRs + Special Registers) def SReg_32 : RegisterClass<"AMDGPU", [i32, f32, i16, f16, v2i16, v2f16, i1], 32, @@ -469,6 +472,7 @@ let AllocationPriority = 10; } +let GeneratePressureSet = 0 in { def SRegOrLds_32 : RegisterClass<"AMDGPU", [i32, f32, i16, f16, v2i16, v2f16], 32, (add SReg_32, LDS_DIRECT_CLASS)> { let isAllocatable = 0; @@ -696,7 +700,7 @@ let CopyCost = 65; let AllocationPriority = 8; } - +} // End GeneratePressureSet = 0 // This is not a real register. This is just to have a register to add // to VReg_1 that does not alias any real register that would @@ -705,6 +709,7 @@ let isArtificial = 1; } +let GeneratePressureSet = 0 in { // FIXME: Should specify an empty set for this. No register should // ever be allocated using VReg_1. This is a hack for SelectionDAG // that should always be lowered by SILowerI1Copies. TableGen crashes @@ -733,6 +738,7 @@ (add AReg_64, VReg_64)> { let isAllocatable = 0; } +} // End GeneratePressureSet = 0 //===----------------------------------------------------------------------===// // Register operands diff --git a/llvm/test/TableGen/inhibit-pset.td b/llvm/test/TableGen/inhibit-pset.td new file mode 100644 --- /dev/null +++ b/llvm/test/TableGen/inhibit-pset.td @@ -0,0 +1,33 @@ +// RUN: llvm-tblgen -gen-register-info -I %p/../../include -I %p/Common %s | FileCheck %s + +include "reg-with-subregs-common.td" + +// CHECK-DAG: GPR32_AND_XR32RegClassID = +// CHECK-DAG: XR32RegClassID = + +def X0 : Register <"x0">; + +// CHECK-LABEL: getRegPressureSetName(unsigned Idx) const { +// CHECK-NEXT: static const char *const PressureNameTable[] = { +// CHECK-NEXT: "GPR32", +// CHECK-NEXT: }; +// CHECK-NEXT: return PressureNameTable[Idx]; +// CHECK-NEXT: } + +// CHECK: unsigned TestTargetGenRegisterInfo:: +// CHECK-NEXT: getRegPressureSetLimit(const MachineFunction &MF, unsigned Idx) const { +// CHECK-NEXT: static const uint16_t PressureLimitTable[] = { +// CHECK-NEXT: {{[0-9]+}}, // 0: GPR32 +// CHECK-NEXT: }; +// CHECK-NEXT: return PressureLimitTable[Idx]; +// CHECK-NEXT:} + +// CHECK: static const int RCSetsTable[] = { +// CHECK-NEXT: /* 0 */ 0, -1, +// CHECK-NEXT: }; + +def XR32 : RegisterClass<"TestTarget", [i32], 32, (add X0)> { + let GeneratePressureSet = 0; +} + +def GPR32_AND_XR32 : RegisterClass<"TestTarget", [i32], 32, (add GPR32, X0)>; 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 @@ -339,6 +339,9 @@ bool CoveredBySubRegs; /// A register class is artificial if all its members are artificial. bool Artificial; + /// Generate register pressure set for this register class and any class + /// synthesized from it. + bool GeneratePressureSet; // Return the Record that defined this class, or NULL if the class was // created by TableGen. diff --git a/llvm/utils/TableGen/CodeGenRegisters.cpp b/llvm/utils/TableGen/CodeGenRegisters.cpp --- a/llvm/utils/TableGen/CodeGenRegisters.cpp +++ b/llvm/utils/TableGen/CodeGenRegisters.cpp @@ -741,6 +741,7 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R) : TheDef(R), Name(std::string(R->getName())), TopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1) { + GeneratePressureSet = R->getValueAsBit("GeneratePressureSet"); std::vector TypeList = R->getValueAsListOfDefs("RegTypes"); for (unsigned i = 0, e = TypeList.size(); i != e; ++i) { Record *Type = TypeList[i]; @@ -817,6 +818,7 @@ TopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1), RSI(Props.RSI), CopyCost(0), Allocatable(true), AllocationPriority(0) { Artificial = true; + GeneratePressureSet = false; for (const auto R : Members) { TopoSigs.set(R->getTopoSig()); Artificial &= R->Artificial; @@ -839,6 +841,7 @@ Allocatable = Super.Allocatable; AltOrderSelect = Super.AltOrderSelect; AllocationPriority = Super.AllocationPriority; + GeneratePressureSet |= Super.GeneratePressureSet; // Copy all allocation orders, filter out foreign registers from the larger // super-class. @@ -1892,7 +1895,7 @@ // Compute a unique RegUnitSet for each RegClass. auto &RegClasses = getRegClasses(); for (auto &RC : RegClasses) { - if (!RC.Allocatable || RC.Artificial) + if (!RC.Allocatable || RC.Artificial || !RC.GeneratePressureSet) continue; // Speculatively grow the RegUnitSets to hold the new set.