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,13 @@ // constrained classes first. The value has to be in the range [0,63]. int AllocationPriority = 0; + // 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 + // calculate a weight based on a number of register units in this register + // class registers. The weight is per register. + int Weight = ?; + // The diagnostic type to present when referencing this operand in a match // failure error message. If this is empty, the default Match_InvalidOperand // diagnostic type will be used. If this is "", a Match_ enum diff --git a/llvm/lib/Target/AMDGPU/R600RegisterInfo.h b/llvm/lib/Target/AMDGPU/R600RegisterInfo.h --- a/llvm/lib/Target/AMDGPU/R600RegisterInfo.h +++ b/llvm/lib/Target/AMDGPU/R600RegisterInfo.h @@ -20,9 +20,7 @@ namespace llvm { struct R600RegisterInfo final : public R600GenRegisterInfo { - RegClassWeight RCW; - - R600RegisterInfo(); + R600RegisterInfo() : R600GenRegisterInfo(0) {} /// \returns the sub reg enum value for the given \p Channel /// (e.g. getSubRegFromChannel(0) -> R600::sub0) @@ -41,9 +39,6 @@ /// CFGStructurizer const TargetRegisterClass *getCFGStructurizerRegClass(MVT VT) const; - const RegClassWeight & - getRegClassWeight(const TargetRegisterClass *RC) const override; - bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override { return false; } diff --git a/llvm/lib/Target/AMDGPU/R600RegisterInfo.cpp b/llvm/lib/Target/AMDGPU/R600RegisterInfo.cpp --- a/llvm/lib/Target/AMDGPU/R600RegisterInfo.cpp +++ b/llvm/lib/Target/AMDGPU/R600RegisterInfo.cpp @@ -20,11 +20,6 @@ using namespace llvm; -R600RegisterInfo::R600RegisterInfo() : R600GenRegisterInfo(0) { - RCW.RegWeight = 0; - RCW.WeightLimit = 0; -} - #define GET_REGINFO_TARGET_DESC #include "R600GenRegisterInfo.inc" @@ -99,11 +94,6 @@ } } -const RegClassWeight &R600RegisterInfo::getRegClassWeight( - const TargetRegisterClass *RC) const { - return RCW; -} - bool R600RegisterInfo::isPhysRegLiveAcrossClauses(unsigned Reg) const { assert(!Register::isVirtualRegister(Reg)); diff --git a/llvm/lib/Target/AMDGPU/R600RegisterInfo.td b/llvm/lib/Target/AMDGPU/R600RegisterInfo.td --- a/llvm/lib/Target/AMDGPU/R600RegisterInfo.td +++ b/llvm/lib/Target/AMDGPU/R600RegisterInfo.td @@ -150,13 +150,16 @@ def INDIRECT_BASE_ADDR : R600Reg <"INDIRECT_BASE_ADDR", 0>; def R600_ArrayBase : RegisterClass <"AMDGPU", [f32, i32], 32, - (add (sequence "ArrayBase%u", 448, 480))>; + (add (sequence "ArrayBase%u", 448, 480))> { + let Weight = 0; +} // special registers for ALU src operands // const buffer reference, SRCx_SEL contains index def ALU_CONST : R600Reg<"CBuf", 0>; // interpolation param reference, SRCx_SEL contains index def ALU_PARAM : R600Reg<"Param", 0>; +let Weight = 0 in { let isAllocatable = 0 in { def R600_Addr : RegisterClass <"AMDGPU", [i32], 32, (add (sequence "Addr%u_X", 0, 127))>; @@ -251,3 +254,4 @@ def R600_Reg64Vertical : RegisterClass<"AMDGPU", [v2f32, v2i32], 64, (add V01_X, V01_Y, V01_Z, V01_W, V23_X, V23_Y, V23_Z, V23_W)>; +} // End let Weight = 0 diff --git a/llvm/test/TableGen/rc-weight-override.td b/llvm/test/TableGen/rc-weight-override.td new file mode 100644 --- /dev/null +++ b/llvm/test/TableGen/rc-weight-override.td @@ -0,0 +1,24 @@ +// RUN: llvm-tblgen -gen-register-info -I %p/../../include -I %p/Common %s | FileCheck %s + +include "reg-with-subregs-common.td" + +// CHECK-LABEL: static const RegClassWeight RCWeightTable[] = { +// CHECK: {1, 256}, // GPR32 +// CHECK: {2, 256}, // GPR_64 + +// CHECK: {0, 256}, // GPR_64_W0 +def GPR_64_W0 : RegisterClass<"", [v2i32], 64, (add GPR64)> { + let Weight = 0; +} + +// CHECK: {1, 256}, // GPR_64_W1 +def GPR_64_W1 : RegisterClass<"", [v2i32], 64, (add GPR64)> { + let Weight = 1; +} + +// CHECK: {8, 256}, // GPR_64_W8 +def GPR_64_W8 : RegisterClass<"", [v2i32], 64, (add GPR64)> { + let Weight = 8; +} + +// CHECK: {32, 256}, // GPR_1024 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 @@ -438,6 +438,9 @@ // Get a bit vector of TopoSigs present in this register class. const BitVector &getTopoSigs() const { return TopoSigs; } + // Get a weight of this register class. + unsigned getWeight(const CodeGenRegBank&) const; + // Populate a unique sorted list of units from a register set. void buildRegUnitSet(const CodeGenRegBank &RegBank, std::vector &RegUnits) const; 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 @@ -854,6 +854,16 @@ deref>()); } +unsigned CodeGenRegisterClass::getWeight(const CodeGenRegBank& RegBank) const { + if (TheDef && !TheDef->isValueUnset("Weight")) + return TheDef->getValueAsInt("Weight"); + + if (Members.empty() || Artificial) + return 0; + + return (*Members.begin())->getWeight(RegBank); +} + namespace llvm { raw_ostream &operator<<(raw_ostream &OS, const CodeGenRegisterClass::Key &K) { 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 @@ -202,13 +202,13 @@ << " static const RegClassWeight RCWeightTable[] = {\n"; for (const auto &RC : RegBank.getRegClasses()) { const CodeGenRegister::Vec &Regs = RC.getMembers(); + OS << " {" << RC.getWeight(RegBank) << ", "; if (Regs.empty() || RC.Artificial) - OS << " {0, 0"; + OS << '0'; else { std::vector RegUnits; RC.buildRegUnitSet(RegBank, RegUnits); - OS << " {" << (*Regs.begin())->getWeight(RegBank) - << ", " << RegBank.getRegUnitSetWeight(RegUnits); + OS << RegBank.getRegUnitSetWeight(RegUnits); } OS << "}, \t// " << RC.getName() << "\n"; }