Skip to content

Commit 7f4c297

Browse files
authored
[TableGen][CodeGen] Remove feature string from HwMode (#157600)
`Predicates` and `Features` fields serve the same purpose. They should be kept in sync, but not all predicates are based on features. This resulted in introducing dummy features for that only reason. This patch removes `Features` field and changes TableGen emitters to use `Predicates` instead. Historically, predicates were written with the assumption that the checking code will be used in `SelectionDAGISel` subclasses, meaning they will have access to the subclass variables, such as `Subtarget`. There are no such variables in the generated `GenSubtargetInfo::getHwModeSet()`, so we need to provide them. This can be achieved by subclassing `HwModePredicateProlog`, see an example in `Hexagon.td`.
1 parent d4f7995 commit 7f4c297

21 files changed

+150
-67
lines changed

llvm/include/llvm/Target/Target.td

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,28 @@ class Predicate; // Forward def
2020
// Register file description - These classes are used to fill in the target
2121
// description classes.
2222

23-
class HwMode<string FS, list<Predicate> Ps> {
24-
// A string representing subtarget features that turn on this HW mode.
25-
// For example, "+feat1,-feat2" will indicate that the mode is active
26-
// when "feat1" is enabled and "feat2" is disabled at the same time.
27-
// Any other features are not checked.
28-
// When multiple modes are used, they should be mutually exclusive,
29-
// otherwise the results are unpredictable.
30-
string Features = FS;
23+
// Code that will be inserted at the start of the generated
24+
// `*GenSubtargetInfo::getHwModeSet()` method. It is expected to define
25+
// variables used in Predicate::CondString. If this class is never instantiated,
26+
// the default
27+
//
28+
// [[maybe_unused]] const auto *Subtarget =
29+
// static_cast<const <TargetName>Subtarget *>(this);
30+
//
31+
// will be inserted, where <TargetName> is the name of the Target record.
32+
class HwModePredicateProlog<code c> {
33+
code Code = c;
34+
}
3135

36+
class HwMode<list<Predicate> Ps> {
3237
// A list of predicates that turn on this HW mode.
3338
list<Predicate> Predicates = Ps;
3439
}
3540

3641
// A special mode recognized by tablegen. This mode is considered active
3742
// when no other mode is active. For targets that do not use specific hw
3843
// modes, this is the only mode.
39-
def DefaultMode : HwMode<"", []>;
44+
def DefaultMode : HwMode<[]>;
4045

4146
// A class used to associate objects with HW modes. It is only intended to
4247
// be used as a base class, where the derived class should contain a member

llvm/lib/Target/AArch64/AArch64RegisterInfo.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,7 @@ class ZPRRegOp <string Suffix, AsmOperandClass C, ElementSizeEnum Size,
983983

984984
// Note: This hardware mode is enabled in AArch64Subtarget::getHwModeSet()
985985
// (without the use of the table-gen'd predicates).
986-
def SMEWithZPRPredicateSpills : HwMode<"", [Predicate<"false">]>;
986+
def SMEWithZPRPredicateSpills : HwMode<[Predicate<"false">]>;
987987

988988
def PPRSpillFillRI : RegInfoByHwMode<
989989
[DefaultMode, SMEWithZPRPredicateSpills],

llvm/lib/Target/Hexagon/Hexagon.td

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,11 @@ def UseSmallData : Predicate<"HST->useSmallData()">;
176176
def UseCabac : Predicate<"HST->useCabac()">,
177177
AssemblerPredicate<(any_of FeatureCabac)>;
178178

179-
def Hvx64: HwMode<"+hvx-length64b", [UseHVX64B]>;
180-
def Hvx128: HwMode<"+hvx-length128b", [UseHVX128B]>;
179+
def : HwModePredicateProlog<[{
180+
const auto *HST = static_cast<const HexagonSubtarget *>(this);
181+
}]>;
182+
def Hvx64: HwMode<[UseHVX64B]>;
183+
def Hvx128: HwMode<[UseHVX128B]>;
181184

182185
//===----------------------------------------------------------------------===//
183186
// Classes used for relation maps.

llvm/lib/Target/LoongArch/LoongArch.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def IsLA32
3939
"LA32 Basic Integer and Privilege Instruction Set">;
4040

4141
defvar LA32 = DefaultMode;
42-
def LA64 : HwMode<"+64bit", [IsLA64]>;
42+
def LA64 : HwMode<[IsLA64]>;
4343

4444
// Single Precision floating point
4545
def FeatureBasicF

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1682,7 +1682,7 @@ def IsRV32 : Predicate<"!Subtarget->is64Bit()">,
16821682
"RV32I Base Instruction Set">;
16831683

16841684
defvar RV32 = DefaultMode;
1685-
def RV64 : HwMode<"+64bit", [IsRV64]>;
1685+
def RV64 : HwMode<[IsRV64]>;
16861686

16871687
def FeatureRelax
16881688
: SubtargetFeature<"relax", "EnableLinkerRelax", "true",

llvm/lib/Target/SystemZ/SystemZFeatures.td

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ def FeatureVector : SystemZFeature<
196196
>;
197197
def FeatureNoVector : SystemZMissingFeature<"Vector">;
198198

199-
def NoVecHwMode : HwMode<"-vector", [FeatureNoVector]>;
199+
def NoVecHwMode : HwMode<[FeatureNoVector]>;
200200

201201
def Arch11NewFeatures : SystemZFeatureList<[
202202
FeatureLoadAndZeroRightmostByte,
@@ -426,4 +426,3 @@ def Arch9UnsupportedFeatures
426426
: SystemZFeatureAdd<Arch10UnsupportedFeatures.List, Arch10NewFeatures.List>;
427427
def Arch8UnsupportedFeatures
428428
: SystemZFeatureAdd<Arch9UnsupportedFeatures.List, Arch9NewFeatures.List>;
429-

llvm/test/TableGen/GlobalISelEmitter/HwModes.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ class MyTargetGenericInstruction : GenericInstruction {
1313
//def Has32 : Predicate<"Subtarget->has32()">;
1414
def Has64 : Predicate<"Subtarget->has64()">;
1515

16-
//def Mode32 : HwMode<"+a", [Has32]>;
17-
def Mode64 : HwMode<"+b", [Has64]>;
16+
//def Mode32 : HwMode<[Has32]>;
17+
def Mode64 : HwMode<[Has64]>;
1818

1919
def ModeVT : ValueTypeByHwMode<[DefaultMode, Mode64],
2020
[i32, i64]>;

llvm/test/TableGen/HwModeBitSet.td

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,17 @@ def TestTarget : Target {
1111
let InstructionSet = TestTargetInstrInfo;
1212
}
1313

14-
def TestMode : HwMode<"+feat", []>;
15-
def TestMode1 : HwMode<"+feat1", []>;
16-
def TestMode2 : HwMode<"+feat2", []>;
14+
def Feat1 : SubtargetFeature<"feat1", "HasFeat1", "true", "enable feature 1">;
15+
def Feat2 : SubtargetFeature<"feat2", "HasFeat2", "true", "enable feature 2">;
16+
17+
def HasFeat1 : Predicate<"Subtarget->hasFeat1()">,
18+
AssemblerPredicate<(all_of Feat1)>;
19+
def HasFeat2 : Predicate<"Subtarget->hasFeat2()">,
20+
AssemblerPredicate<(all_of Feat2)>;
21+
22+
def TestMode : HwMode<[HasFeat1]>;
23+
def TestMode1 : HwMode<[HasFeat2]>;
24+
def TestMode2 : HwMode<[HasFeat1, HasFeat2]>;
1725

1826
class MyReg<string n>
1927
: Register<n> {
@@ -120,13 +128,26 @@ def foo : Instruction {
120128
let AsmString = "foo $factor";
121129
}
122130

131+
// CHECK-SUBTARGET-LABEL: unsigned TestTargetGenMCSubtargetInfo::getHwModeSet() const {
132+
// CHECK-SUBTARGET{LITERAL}:[[maybe_unused]] const FeatureBitset &FB = getFeatureBits();
133+
// CHECK-SUBTARGET-NEXT: // Collect HwModes and store them as a bit set.
134+
// CHECK-SUBTARGET-NEXT: unsigned Modes = 0;
135+
// CHECK-SUBTARGET-NEXT: if (FB[TestTarget::Feat1]) Modes |= (1 << 0);
136+
// CHECK-SUBTARGET-NEXT: if (FB[TestTarget::Feat2]) Modes |= (1 << 1);
137+
// CHECK-SUBTARGET-NEXT: if (FB[TestTarget::Feat1] && FB[TestTarget::Feat2]) Modes |= (1 << 2);
138+
// CHECK-SUBTARGET-NEXT: return Modes;
139+
// CHECK-SUBTARGET-NEXT: }
140+
123141
// CHECK-SUBTARGET-LABEL: unsigned TestTargetGenSubtargetInfo::getHwModeSet() const {
124-
// CHECK-SUBTARGET: unsigned Modes = 0;
125-
// CHECK-SUBTARGET: if (checkFeatures("+feat")) Modes |= (1 << 0);
126-
// CHECK-SUBTARGET: if (checkFeatures("+feat1")) Modes |= (1 << 1);
127-
// CHECK-SUBTARGET: if (checkFeatures("+feat2")) Modes |= (1 << 2);
128-
// CHECK-SUBTARGET: return Modes;
129-
// CHECK-SUBTARGET: }
142+
// CHECK-SUBTARGET{LITERAL}:[[maybe_unused]] const auto *Subtarget =
143+
// CHECK-SUBTARGET-NEXT: static_cast<const TestTargetSubtarget *>(this);
144+
// CHECK-SUBTARGET-NEXT: // Collect HwModes and store them as a bit set.
145+
// CHECK-SUBTARGET-NEXT: unsigned Modes = 0;
146+
// CHECK-SUBTARGET-NEXT: if ((Subtarget->hasFeat1())) Modes |= (1 << 0);
147+
// CHECK-SUBTARGET-NEXT: if ((Subtarget->hasFeat2())) Modes |= (1 << 1);
148+
// CHECK-SUBTARGET-NEXT: if ((Subtarget->hasFeat1()) && (Subtarget->hasFeat2())) Modes |= (1 << 2);
149+
// CHECK-SUBTARGET-NEXT: return Modes;
150+
// CHECK-SUBTARGET-NEXT: }
130151
// CHECK-SUBTARGET-LABEL: unsigned TestTargetGenSubtargetInfo::getHwMode(enum HwModeType type) const {
131152
// CHECK-SUBTARGET: unsigned Modes = getHwModeSet();
132153
// CHECK-SUBTARGET: if (!Modes)
@@ -159,4 +180,3 @@ def foo : Instruction {
159180
// CHECK-SUBTARGET: llvm_unreachable("unexpected HwModeType");
160181
// CHECK-SUBTARGET: return 0; // should not get here
161182
// CHECK-SUBTARGET: }
162-

llvm/test/TableGen/HwModeEncodeAPInt.td

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ def Myi32 : Operand<i32> {
1717
def HasA : Predicate<"Subtarget->hasA()">;
1818
def HasB : Predicate<"Subtarget->hasB()">;
1919

20-
def ModeA : HwMode<"+a", [HasA]>; // Mode 1
21-
def ModeB : HwMode<"+b", [HasB]>; // Mode 2
22-
def ModeC : HwMode<"+c", []>; // Mode 3
20+
def ModeA : HwMode<[HasA]>; // Mode 1
21+
def ModeB : HwMode<[HasB]>; // Mode 2
22+
def ModeC : HwMode<[]>; // Mode 3
2323

2424

2525
def fooTypeEncDefault : InstructionEncoding {

llvm/test/TableGen/HwModeEncodeDecode.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ def Myi32 : Operand<i32> {
1616
def HasA : Predicate<"Subtarget->hasA()">;
1717
def HasB : Predicate<"Subtarget->hasB()">;
1818

19-
def ModeA : HwMode<"+a", [HasA]>;
20-
def ModeB : HwMode<"+b", [HasB]>;
19+
def ModeA : HwMode<[HasA]>;
20+
def ModeB : HwMode<[HasB]>;
2121

2222

2323
def fooTypeEncA : InstructionEncoding {

0 commit comments

Comments
 (0)