[llvm] [TableGen][CodeGen] Remove feature string from HwMode (PR #157600)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 9 03:12:46 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-loongarch
Author: Sergei Barannikov (s-barannikov)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/157600.diff
12 Files Affected:
- (modified) llvm/include/llvm/Target/Target.td (+14-9)
- (modified) llvm/lib/Target/AArch64/AArch64RegisterInfo.td (+1-1)
- (modified) llvm/lib/Target/Hexagon/Hexagon.td (+5-2)
- (modified) llvm/lib/Target/LoongArch/LoongArch.td (+1-1)
- (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+1-1)
- (modified) llvm/lib/Target/SystemZ/SystemZFeatures.td (+1-2)
- (modified) llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp (+7-2)
- (modified) llvm/utils/TableGen/Common/CodeGenHwModes.cpp (+8-14)
- (modified) llvm/utils/TableGen/Common/CodeGenHwModes.h (+1-2)
- (modified) llvm/utils/TableGen/Common/SubtargetFeatureInfo.cpp (+32)
- (modified) llvm/utils/TableGen/Common/SubtargetFeatureInfo.h (+6)
- (modified) llvm/utils/TableGen/SubtargetEmitter.cpp (+26-6)
``````````diff
diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td
index 38c3b6064d267..6a7ecf78b2131 100644
--- a/llvm/include/llvm/Target/Target.td
+++ b/llvm/include/llvm/Target/Target.td
@@ -20,15 +20,20 @@ class Predicate; // Forward def
// Register file description - These classes are used to fill in the target
// description classes.
-class HwMode<string FS, list<Predicate> Ps> {
- // A string representing subtarget features that turn on this HW mode.
- // For example, "+feat1,-feat2" will indicate that the mode is active
- // when "feat1" is enabled and "feat2" is disabled at the same time.
- // Any other features are not checked.
- // When multiple modes are used, they should be mutually exclusive,
- // otherwise the results are unpredictable.
- string Features = FS;
+// Code that will be inserted at the start of the generated
+// `*GenSubtargetInfo::getHwModeSet()` method. It is expected to define
+// variables used in Predicate::CondString. If this class is never instantiated,
+// the default
+//
+// [[maybe_unused]] const auto *Subtarget =
+// static_cast<const <TargetName>Subtarget *>(this);
+//
+// will be inserted, where <TargetName> is the name of the Target record.
+class HwModePredicateProlog<code c> {
+ code Code = c;
+}
+class HwMode<list<Predicate> Ps> {
// A list of predicates that turn on this HW mode.
list<Predicate> Predicates = Ps;
}
@@ -36,7 +41,7 @@ class HwMode<string FS, list<Predicate> Ps> {
// A special mode recognized by tablegen. This mode is considered active
// when no other mode is active. For targets that do not use specific hw
// modes, this is the only mode.
-def DefaultMode : HwMode<"", []>;
+def DefaultMode : HwMode<[]>;
// A class used to associate objects with HW modes. It is only intended to
// be used as a base class, where the derived class should contain a member
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
index 1a7609bfee8a1..431ed6ec34e74 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
@@ -983,7 +983,7 @@ class ZPRRegOp <string Suffix, AsmOperandClass C, ElementSizeEnum Size,
// Note: This hardware mode is enabled in AArch64Subtarget::getHwModeSet()
// (without the use of the table-gen'd predicates).
-def SMEWithZPRPredicateSpills : HwMode<"", [Predicate<"false">]>;
+def SMEWithZPRPredicateSpills : HwMode<[Predicate<"false">]>;
def PPRSpillFillRI : RegInfoByHwMode<
[DefaultMode, SMEWithZPRPredicateSpills],
diff --git a/llvm/lib/Target/Hexagon/Hexagon.td b/llvm/lib/Target/Hexagon/Hexagon.td
index 0dbe743d13ede..6d0529fb42779 100644
--- a/llvm/lib/Target/Hexagon/Hexagon.td
+++ b/llvm/lib/Target/Hexagon/Hexagon.td
@@ -176,8 +176,11 @@ def UseSmallData : Predicate<"HST->useSmallData()">;
def UseCabac : Predicate<"HST->useCabac()">,
AssemblerPredicate<(any_of FeatureCabac)>;
-def Hvx64: HwMode<"+hvx-length64b", [UseHVX64B]>;
-def Hvx128: HwMode<"+hvx-length128b", [UseHVX128B]>;
+def : HwModePredicateProlog<[{
+ const auto *HST = static_cast<const HexagonSubtarget *>(this);
+}]>;
+def Hvx64: HwMode<[UseHVX64B]>;
+def Hvx128: HwMode<[UseHVX128B]>;
//===----------------------------------------------------------------------===//
// Classes used for relation maps.
diff --git a/llvm/lib/Target/LoongArch/LoongArch.td b/llvm/lib/Target/LoongArch/LoongArch.td
index 39948b31fb9b9..6497ff999f6fa 100644
--- a/llvm/lib/Target/LoongArch/LoongArch.td
+++ b/llvm/lib/Target/LoongArch/LoongArch.td
@@ -39,7 +39,7 @@ def IsLA32
"LA32 Basic Integer and Privilege Instruction Set">;
defvar LA32 = DefaultMode;
-def LA64 : HwMode<"+64bit", [IsLA64]>;
+def LA64 : HwMode<[IsLA64]>;
// Single Precision floating point
def FeatureBasicF
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index bf5dca481cd2b..063963d4ec36b 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1682,7 +1682,7 @@ def IsRV32 : Predicate<"!Subtarget->is64Bit()">,
"RV32I Base Instruction Set">;
defvar RV32 = DefaultMode;
-def RV64 : HwMode<"+64bit", [IsRV64]>;
+def RV64 : HwMode<[IsRV64]>;
def FeatureRelax
: SubtargetFeature<"relax", "EnableLinkerRelax", "true",
diff --git a/llvm/lib/Target/SystemZ/SystemZFeatures.td b/llvm/lib/Target/SystemZ/SystemZFeatures.td
index 2c48da8320fb9..4ccc3d3079fc2 100644
--- a/llvm/lib/Target/SystemZ/SystemZFeatures.td
+++ b/llvm/lib/Target/SystemZ/SystemZFeatures.td
@@ -196,7 +196,7 @@ def FeatureVector : SystemZFeature<
>;
def FeatureNoVector : SystemZMissingFeature<"Vector">;
-def NoVecHwMode : HwMode<"-vector", [FeatureNoVector]>;
+def NoVecHwMode : HwMode<[FeatureNoVector]>;
def Arch11NewFeatures : SystemZFeatureList<[
FeatureLoadAndZeroRightmostByte,
@@ -426,4 +426,3 @@ def Arch9UnsupportedFeatures
: SystemZFeatureAdd<Arch10UnsupportedFeatures.List, Arch10NewFeatures.List>;
def Arch8UnsupportedFeatures
: SystemZFeatureAdd<Arch9UnsupportedFeatures.List, Arch9NewFeatures.List>;
-
diff --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
index c3b406a545072..f1f7cd72ef9f2 100644
--- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
@@ -14,6 +14,7 @@
#include "CodeGenDAGPatterns.h"
#include "CodeGenInstruction.h"
#include "CodeGenRegisters.h"
+#include "SubtargetFeatureInfo.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
@@ -4498,13 +4499,17 @@ void CodeGenDAGPatterns::ExpandHwModeBasedTypes() {
// Fill the map entry for this mode.
const HwMode &HM = CGH.getMode(M);
- AppendPattern(P, M, HM.Predicates);
+
+ SmallString<128> PredicateCheck;
+ raw_svector_ostream PS(PredicateCheck);
+ SubtargetFeatureInfo::emitPredicateCheck(PS, HM.Predicates);
+ AppendPattern(P, M, PredicateCheck);
// Add negations of the HM's predicates to the default predicate.
if (!DefaultCheck.empty())
DefaultCheck += " && ";
DefaultCheck += "!(";
- DefaultCheck += HM.Predicates;
+ DefaultCheck.append(PredicateCheck);
DefaultCheck += ")";
}
diff --git a/llvm/utils/TableGen/Common/CodeGenHwModes.cpp b/llvm/utils/TableGen/Common/CodeGenHwModes.cpp
index 09765113a4e7b..5a93c83be5933 100644
--- a/llvm/utils/TableGen/Common/CodeGenHwModes.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenHwModes.cpp
@@ -20,23 +20,17 @@ StringRef CodeGenHwModes::DefaultModeName = "DefaultMode";
HwMode::HwMode(const Record *R) {
Name = R->getName();
- Features = R->getValueAsString("Features").str();
-
- SmallString<128> PredicateCheck;
- raw_svector_ostream OS(PredicateCheck);
- ListSeparator LS(" && ");
- for (const Record *Pred : R->getValueAsListOfDefs("Predicates")) {
- StringRef CondString = Pred->getValueAsString("CondString");
- if (CondString.empty())
- continue;
- OS << LS << '(' << CondString << ')';
- }
-
- Predicates = std::string(PredicateCheck);
+ Predicates = R->getValueAsListOfDefs("Predicates");
}
LLVM_DUMP_METHOD
-void HwMode::dump() const { dbgs() << Name << ": " << Features << '\n'; }
+void HwMode::dump() const {
+ dbgs() << Name << ": ";
+ ListSeparator LS;
+ for (const Record *R : Predicates)
+ dbgs() << LS << R->getName();
+ dbgs() << '\n';
+}
HwModeSelect::HwModeSelect(const Record *R, CodeGenHwModes &CGH) {
std::vector<const Record *> Modes = R->getValueAsListOfDefs("Modes");
diff --git a/llvm/utils/TableGen/Common/CodeGenHwModes.h b/llvm/utils/TableGen/Common/CodeGenHwModes.h
index 4ced4208cea07..5e1b31ae39e43 100644
--- a/llvm/utils/TableGen/Common/CodeGenHwModes.h
+++ b/llvm/utils/TableGen/Common/CodeGenHwModes.h
@@ -30,8 +30,7 @@ struct CodeGenHwModes;
struct HwMode {
HwMode(const Record *R);
StringRef Name;
- std::string Features;
- std::string Predicates;
+ std::vector<const Record *> Predicates;
void dump() const;
};
diff --git a/llvm/utils/TableGen/Common/SubtargetFeatureInfo.cpp b/llvm/utils/TableGen/Common/SubtargetFeatureInfo.cpp
index 738ddf7760247..004e4b0c27ea5 100644
--- a/llvm/utils/TableGen/Common/SubtargetFeatureInfo.cpp
+++ b/llvm/utils/TableGen/Common/SubtargetFeatureInfo.cpp
@@ -163,6 +163,38 @@ static bool emitFeaturesAux(StringRef TargetName, const Init &Val,
return true;
}
+void SubtargetFeatureInfo::emitPredicateCheck(
+ raw_ostream &OS, ArrayRef<const Record *> Predicates) {
+ ListSeparator LS(" && ");
+ for (const Record *R : Predicates) {
+ StringRef CondString = R->getValueAsString("CondString");
+ if (CondString.empty())
+ continue;
+ OS << LS << '(' << CondString << ')';
+ }
+}
+
+void SubtargetFeatureInfo::emitMCPredicateCheck(
+ raw_ostream &OS, StringRef TargetName,
+ ArrayRef<const Record *> Predicates) {
+ auto MCPredicates = make_filter_range(Predicates, [](const Record *R) {
+ return R->getValueAsBit("AssemblerMatcherPredicate");
+ });
+
+ if (MCPredicates.empty()) {
+ OS << "false";
+ return;
+ }
+
+ ListSeparator LS(" && ");
+ bool ParenIfBinOp = range_size(MCPredicates) > 1;
+ for (const Record *R : Predicates) {
+ OS << LS;
+ emitFeaturesAux(TargetName, *R->getValueAsDag("AssemblerCondDag"),
+ ParenIfBinOp, OS);
+ }
+}
+
void SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
StringRef TargetName, StringRef ClassName, StringRef FuncName,
SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {
diff --git a/llvm/utils/TableGen/Common/SubtargetFeatureInfo.h b/llvm/utils/TableGen/Common/SubtargetFeatureInfo.h
index d75a9a41636de..2b2577b93c284 100644
--- a/llvm/utils/TableGen/Common/SubtargetFeatureInfo.h
+++ b/llvm/utils/TableGen/Common/SubtargetFeatureInfo.h
@@ -101,6 +101,12 @@ struct SubtargetFeatureInfo {
static void emitComputeAssemblerAvailableFeatures(
StringRef TargetName, StringRef ClassName, StringRef FuncName,
SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS);
+
+ static void emitPredicateCheck(raw_ostream &OS,
+ ArrayRef<const Record *> Predicates);
+
+ static void emitMCPredicateCheck(raw_ostream &OS, StringRef TargetName,
+ ArrayRef<const Record *> Predicates);
};
} // end namespace llvm
diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp
index 408fe544d260f..e218927621dd3 100644
--- a/llvm/utils/TableGen/SubtargetEmitter.cpp
+++ b/llvm/utils/TableGen/SubtargetEmitter.cpp
@@ -15,6 +15,7 @@
#include "Common/CodeGenSchedule.h"
#include "Common/CodeGenTarget.h"
#include "Common/PredicateExpander.h"
+#include "Common/SubtargetFeatureInfo.h"
#include "Common/Utils.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -124,7 +125,8 @@ class SubtargetEmitter : TargetFeaturesEmitter {
void emitSchedModel(raw_ostream &OS);
void emitGetMacroFusions(const std::string &ClassName, raw_ostream &OS);
- void emitHwModeCheck(const std::string &ClassName, raw_ostream &OS);
+ void emitHwModeCheck(const std::string &ClassName, raw_ostream &OS,
+ bool IsMC);
void parseFeaturesFunction(raw_ostream &OS);
public:
@@ -1772,7 +1774,7 @@ void SubtargetEmitter::emitSchedModelHelpers(const std::string &ClassName,
}
void SubtargetEmitter::emitHwModeCheck(const std::string &ClassName,
- raw_ostream &OS) {
+ raw_ostream &OS, bool IsMC) {
const CodeGenHwModes &CGH = TGT.getHwModes();
assert(CGH.getNumModeIds() > 0);
if (CGH.getNumModeIds() == 1)
@@ -1800,12 +1802,30 @@ void SubtargetEmitter::emitHwModeCheck(const std::string &ClassName,
// Start emitting for getHwModeSet().
OS << "unsigned " << ClassName << "::getHwModeSet() const {\n";
+ if (IsMC) {
+ OS << " [[maybe_unused]] const FeatureBitset &FB = getFeatureBits();\n";
+ } else {
+ const ArrayRef<const Record *> &Prologs =
+ Records.getAllDerivedDefinitions("HwModePredicateProlog");
+ if (!Prologs.empty()) {
+ for (const Record *P : Prologs)
+ OS << P->getValueAsString("Code") << '\n';
+ } else {
+ // Works for most targets.
+ OS << " [[maybe_unused]] const auto *Subtarget =\n"
+ << " static_cast<const " << Target << "Subtarget *>(this);\n";
+ }
+ }
OS << " // Collect HwModes and store them as a bit set.\n";
OS << " unsigned Modes = 0;\n";
for (unsigned M = 1, NumModes = CGH.getNumModeIds(); M != NumModes; ++M) {
const HwMode &HM = CGH.getMode(M);
- OS << " if (checkFeatures(\"" << HM.Features << "\")) Modes |= (1 << "
- << (M - 1) << ");\n";
+ OS << " if (";
+ if (IsMC)
+ SubtargetFeatureInfo::emitMCPredicateCheck(OS, Target, HM.Predicates);
+ else
+ SubtargetFeatureInfo::emitPredicateCheck(OS, HM.Predicates);
+ OS << ") Modes |= (1 << " << (M - 1) << ");\n";
}
OS << " return Modes;\n}\n";
// End emitting for getHwModeSet().
@@ -1937,7 +1957,7 @@ void SubtargetEmitter::emitGenMCSubtargetInfo(raw_ostream &OS) {
<< " return MCSubtargetInfo::isCPUStringValid(CPU);\n"
<< " }\n";
OS << "};\n";
- emitHwModeCheck(Target + "GenMCSubtargetInfo", OS);
+ emitHwModeCheck(Target + "GenMCSubtargetInfo", OS, /*IsMC=*/true);
}
void SubtargetEmitter::emitMcInstrAnalysisPredicateFunctions(raw_ostream &OS) {
@@ -2160,7 +2180,7 @@ void SubtargetEmitter::run(raw_ostream &OS) {
OS << ") {}\n\n";
emitSchedModelHelpers(ClassName, OS);
- emitHwModeCheck(ClassName, OS);
+ emitHwModeCheck(ClassName, OS, /*IsMC=*/false);
emitGetMacroFusions(ClassName, OS);
OS << "} // end namespace llvm\n\n";
``````````
</details>
https://github.com/llvm/llvm-project/pull/157600
More information about the llvm-commits
mailing list