[llvm] [TableGen][SchedModel] Introduce a new SchedPredicate that checks against SubtargetFeature (PR #161888)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 3 11:18:22 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-tablegen
Author: Min-Yih Hsu (mshockwave)
<details>
<summary>Changes</summary>
Introduce a new SchedPredicate, `FeatureSchedPredicate`, that holds true when a certain SubtargetFeature is enabled. This could be useful when we want to configure a scheduling model with subtarget features.
I add this as a separate SchedPredicate rather than piggy-back on the existing `SchedPredicate<[{....}]>` because first and foremost, `SchedPredicate` is expected to only operate on MachineInstr, so it does _not_ appear in `MCGenSubtargetInfo::resolveVariantSchedClass` but only show up in `TargetGenSubtargetInfo::resolveSchedClass`. Yet I think `FeatureSchedPredicate` will be useful for both MCInst and MachineInstr. There is another subtle difference between `resolveVariantSchedClass` and `resolveSchedClass` regarding how we access the MCSubtargetInfo instance, if we really want to express `FeatureSchedPredicate` using `SchedPredicate<[{.....}]>`.
So I thought it'll be easier to add another new SchedPredicate for SubtargetFeature.
------
This stacks on top of #<!-- -->161886
---
Full diff: https://github.com/llvm/llvm-project/pull/161888.diff
3 Files Affected:
- (modified) llvm/include/llvm/Target/TargetSchedule.td (+5)
- (added) llvm/test/TableGen/ResolveSchedClass.td (+64)
- (modified) llvm/utils/TableGen/SubtargetEmitter.cpp (+19-5)
``````````diff
diff --git a/llvm/include/llvm/Target/TargetSchedule.td b/llvm/include/llvm/Target/TargetSchedule.td
index f55bff16dcecd..95622b8e73e8b 100644
--- a/llvm/include/llvm/Target/TargetSchedule.td
+++ b/llvm/include/llvm/Target/TargetSchedule.td
@@ -377,6 +377,11 @@ class MCSchedPredicate<MCInstPredicate P> : SchedPredicateBase {
SchedMachineModel SchedModel = ?;
}
+class FeatureSchedPredicate<SubtargetFeature SF> : SchedPredicateBase {
+ SubtargetFeature Feature = SF;
+ SchedMachineModel SchedModel = ?;
+}
+
// Define a predicate to determine which SchedVariant applies to a
// particular MachineInstr. The code snippet is used as an
// if-statement's expression. Available variables are MI, SchedModel,
diff --git a/llvm/test/TableGen/ResolveSchedClass.td b/llvm/test/TableGen/ResolveSchedClass.td
new file mode 100644
index 0000000000000..c1cadb359ca03
--- /dev/null
+++ b/llvm/test/TableGen/ResolveSchedClass.td
@@ -0,0 +1,64 @@
+// RUN: llvm-tblgen -gen-subtarget -I %p/../../include %s -o - | FileCheck %s
+
+include "llvm/Target/Target.td"
+
+def TestTargetInstrInfo : InstrInfo;
+
+def TestTarget : Target {
+ let InstructionSet = TestTargetInstrInfo;
+}
+
+def FeatureFoo : SubtargetFeature<"foo", "HasFoo", "true", "enable foo">;
+
+def ResX0 : ProcResource<1>;
+
+let OutOperandList = (outs), InOperandList = (ins) in
+def Inst_A : Instruction;
+
+def SchedModel_A: SchedMachineModel {
+ let CompleteModel = false;
+}
+
+let SchedModel = SchedModel_A in {
+def SchedWriteResA : SchedWriteRes<[ResX0]> {
+ let Latency = 2;
+}
+def SchedWriteResB : SchedWriteRes<[ResX0]> {
+ let Latency = 4;
+}
+
+// Check SchedPredicate with subtarget feature.
+def FeatureFooPred : FeatureSchedPredicate<FeatureFoo>;
+
+def Variant : SchedWriteVariant<[
+ SchedVar<FeatureFooPred, [SchedWriteResA]>,
+ SchedVar<NoSchedPred, [SchedWriteResB]>
+]>;
+
+def : InstRW<[Variant], (instrs Inst_A)>;
+}
+
+def ProcessorA: ProcessorModel<"ProcessorA", SchedModel_A, []>;
+
+// CHECK: unsigned resolveVariantSchedClassImpl(unsigned SchedClass,
+// CHECK-NEXT: const MCInst *MI, const MCInstrInfo *MCII, const MCSubtargetInfo &STI, unsigned CPUID)
+// CHECK: case {{.*}}: // Inst_A
+// CHECK-NEXT: if (CPUID == {{.*}}) { // SchedModel_A
+// CHECK-NEXT: if (STI.hasFeature(TestTarget::FeatureFoo))
+// CHECK-NEXT: return {{.*}}; // SchedWriteResA
+// CHECK-NEXT: return {{.*}}; // SchedWriteResB
+
+// CHECK: unsigned resolveVariantSchedClass(unsigned SchedClass,
+// CHECK-NEXT: const MCInst *MI, const MCInstrInfo *MCII,
+// CHECK-NEXT: unsigned CPUID) const override {
+// CHECK-NEXT: return TestTarget_MC::resolveVariantSchedClassImpl(SchedClass, MI, MCII, *this, CPUID);
+// CHECK-NEXT: }
+
+// CHECK: unsigned TestTargetGenSubtargetInfo
+// CHECK-NEXT: ::resolveSchedClass(unsigned SchedClass, const MachineInstr *MI, const TargetSchedModel *SchedModel) const {
+// CHECK-NEXT: switch (SchedClass) {
+// CHECK-NEXT: case {{.*}}: // Inst_A
+// CHECK-NEXT: if (SchedModel->getProcessorID() == {{.*}}) { // SchedModel_A
+// CHECK-NEXT: if (this->hasFeature(TestTarget::FeatureFoo))
+// CHECK-NEXT: return {{.*}}; // SchedWriteResA
+// CHECK-NEXT: return {{.*}}; // SchedWriteResB
diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp
index 0f42d49a6bea1..9d463228be682 100644
--- a/llvm/utils/TableGen/SubtargetEmitter.cpp
+++ b/llvm/utils/TableGen/SubtargetEmitter.cpp
@@ -1586,6 +1586,17 @@ static void emitPredicates(const CodeGenSchedTransition &T,
continue;
}
+ if (Rec->isSubClassOf("FeatureSchedPredicate")) {
+ const Record *FR = Rec->getValueAsDef("Feature");
+ if (PE.shouldExpandForMC())
+ SS << "STI.";
+ else
+ SS << "this->";
+ SS << "hasFeature(" << PE.getTargetName() << "::" << FR->getName()
+ << ")";
+ continue;
+ }
+
// Expand this legacy predicate and wrap it around braces if there is more
// than one predicate to expand.
SS << ((NumNonTruePreds > 1) ? "(" : "")
@@ -1618,7 +1629,8 @@ static void emitSchedModelHelperEpilogue(raw_ostream &OS,
static bool hasMCSchedPredicates(const CodeGenSchedTransition &T) {
return all_of(T.PredTerm, [](const Record *Rec) {
- return Rec->isSubClassOf("MCSchedPredicate");
+ return Rec->isSubClassOf("MCSchedPredicate") ||
+ Rec->isSubClassOf("FeatureSchedPredicate");
});
}
@@ -1761,7 +1773,7 @@ void SubtargetEmitter::emitSchedModelHelpers(const std::string &ClassName,
<< "\n::resolveVariantSchedClass(unsigned SchedClass, const MCInst *MI,"
<< " const MCInstrInfo *MCII, unsigned CPUID) const {\n"
<< " return " << Target << "_MC"
- << "::resolveVariantSchedClassImpl(SchedClass, MI, MCII, CPUID);\n"
+ << "::resolveVariantSchedClassImpl(SchedClass, MI, MCII, *this, CPUID);\n"
<< "} // " << ClassName << "::resolveVariantSchedClass\n\n";
STIPredicateExpander PE(Target, /*Indent=*/0);
@@ -1923,7 +1935,8 @@ void SubtargetEmitter::parseFeaturesFunction(raw_ostream &OS) {
void SubtargetEmitter::emitGenMCSubtargetInfo(raw_ostream &OS) {
OS << "namespace " << Target << "_MC {\n"
<< "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,\n"
- << " const MCInst *MI, const MCInstrInfo *MCII, unsigned CPUID) {\n";
+ << " const MCInst *MI, const MCInstrInfo *MCII, "
+ << "const MCSubtargetInfo &STI, unsigned CPUID) {\n";
emitSchedModelHelpersImpl(OS, /* OnlyExpandMCPredicates */ true);
OS << "}\n";
OS << "} // end namespace " << Target << "_MC\n\n";
@@ -1945,7 +1958,7 @@ void SubtargetEmitter::emitGenMCSubtargetInfo(raw_ostream &OS) {
<< " const MCInst *MI, const MCInstrInfo *MCII,\n"
<< " unsigned CPUID) const override {\n"
<< " return " << Target << "_MC"
- << "::resolveVariantSchedClassImpl(SchedClass, MI, MCII, CPUID);\n";
+ << "::resolveVariantSchedClassImpl(SchedClass, MI, MCII, *this, CPUID);\n";
OS << " }\n";
if (TGT.getHwModes().getNumModeIds() > 1) {
OS << " unsigned getHwModeSet() const override;\n";
@@ -2073,7 +2086,8 @@ void SubtargetEmitter::run(raw_ostream &OS) {
OS << "class DFAPacketizer;\n";
OS << "namespace " << Target << "_MC {\n"
<< "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,"
- << " const MCInst *MI, const MCInstrInfo *MCII, unsigned CPUID);\n"
+ << " const MCInst *MI, const MCInstrInfo *MCII, "
+ << "const MCSubtargetInfo &STI, unsigned CPUID);\n"
<< "} // end namespace " << Target << "_MC\n\n";
OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n"
<< " explicit " << ClassName << "(const Triple &TT, StringRef CPU, "
``````````
</details>
https://github.com/llvm/llvm-project/pull/161888
More information about the llvm-commits
mailing list