Skip to content

Commit 977b546

Browse files
authored
[TableGen][SchedModel] Introduce a new SchedPredicate that checks against SubtargetFeature (llvm#161888)
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.
1 parent 910e536 commit 977b546

File tree

3 files changed

+72
-1
lines changed

3 files changed

+72
-1
lines changed

llvm/include/llvm/Target/TargetSchedule.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,12 @@ class MCSchedPredicate<MCInstPredicate P> : SchedPredicateBase {
377377
SchedMachineModel SchedModel = ?;
378378
}
379379

380+
// A scheduling predicate whose logic depends on a SubtargetFeature.
381+
class FeatureSchedPredicate<SubtargetFeature SF> : SchedPredicateBase {
382+
SubtargetFeature Feature = SF;
383+
SchedMachineModel SchedModel = ?;
384+
}
385+
380386
// Define a predicate to determine which SchedVariant applies to a
381387
// particular MachineInstr. The code snippet is used as an
382388
// if-statement's expression. Available variables are MI, SchedModel,

llvm/test/TableGen/ResolveSchedClass.td

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,57 @@ def TestTarget : Target {
88
let InstructionSet = TestTargetInstrInfo;
99
}
1010

11+
def FeatureFoo : SubtargetFeature<"foo", "HasFoo", "true", "enable foo">;
12+
13+
def ResX0 : ProcResource<1>;
14+
15+
let OutOperandList = (outs), InOperandList = (ins) in
16+
def Inst_A : Instruction;
17+
18+
def SchedModel_A: SchedMachineModel {
19+
let CompleteModel = false;
20+
}
21+
22+
let SchedModel = SchedModel_A in {
23+
def SchedWriteResA : SchedWriteRes<[ResX0]> {
24+
let Latency = 2;
25+
}
26+
def SchedWriteResB : SchedWriteRes<[ResX0]> {
27+
let Latency = 4;
28+
}
29+
30+
// Check SchedPredicate with subtarget feature.
31+
def FeatureFooPred : FeatureSchedPredicate<FeatureFoo>;
32+
33+
def Variant : SchedWriteVariant<[
34+
SchedVar<FeatureFooPred, [SchedWriteResA]>,
35+
SchedVar<NoSchedPred, [SchedWriteResB]>
36+
]>;
37+
38+
def : InstRW<[Variant], (instrs Inst_A)>;
39+
}
40+
41+
def ProcessorA: ProcessorModel<"ProcessorA", SchedModel_A, []>;
42+
1143
// CHECK: unsigned resolveVariantSchedClassImpl(unsigned SchedClass,
1244
// CHECK-NEXT: const MCInst *MI, const MCInstrInfo *MCII, const MCSubtargetInfo &STI, unsigned CPUID)
45+
// CHECK: case {{.*}}: // Inst_A
46+
// CHECK-NEXT: if (CPUID == {{.*}}) { // SchedModel_A
47+
// CHECK-NEXT: if (STI.hasFeature(TestTarget::FeatureFoo))
48+
// CHECK-NEXT: return {{.*}}; // SchedWriteResA
49+
// CHECK-NEXT: return {{.*}}; // SchedWriteResB
1350

1451
// CHECK: unsigned resolveVariantSchedClass(unsigned SchedClass,
1552
// CHECK-NEXT: const MCInst *MI, const MCInstrInfo *MCII,
1653
// CHECK-NEXT: unsigned CPUID) const override {
1754
// CHECK-NEXT: return TestTarget_MC::resolveVariantSchedClassImpl(SchedClass, MI, MCII, *this, CPUID);
1855
// CHECK-NEXT: }
56+
57+
// CHECK: unsigned TestTargetGenSubtargetInfo
58+
// CHECK-NEXT: ::resolveSchedClass(unsigned SchedClass, const MachineInstr *MI, const TargetSchedModel *SchedModel) const {
59+
// CHECK-NEXT: switch (SchedClass) {
60+
// CHECK-NEXT: case {{.*}}: // Inst_A
61+
// CHECK-NEXT: if (SchedModel->getProcessorID() == {{.*}}) { // SchedModel_A
62+
// CHECK-NEXT: if (this->hasFeature(TestTarget::FeatureFoo))
63+
// CHECK-NEXT: return {{.*}}; // SchedWriteResA
64+
// CHECK-NEXT: return {{.*}}; // SchedWriteResB

llvm/utils/TableGen/SubtargetEmitter.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1586,6 +1586,24 @@ static void emitPredicates(const CodeGenSchedTransition &T,
15861586
continue;
15871587
}
15881588

1589+
if (Rec->isSubClassOf("FeatureSchedPredicate")) {
1590+
const Record *FR = Rec->getValueAsDef("Feature");
1591+
if (PE.shouldExpandForMC()) {
1592+
// MC version of this predicate will be emitted into
1593+
// resolveVariantSchedClassImpl, which accesses MCSubtargetInfo
1594+
// through argument STI.
1595+
SS << "STI.";
1596+
} else {
1597+
// Otherwise, this predicate will be emitted directly into
1598+
// TargetGenSubtargetInfo::resolveSchedClass, which can just access
1599+
// TargetSubtargetInfo / MCSubtargetInfo through `this`.
1600+
SS << "this->";
1601+
}
1602+
SS << "hasFeature(" << PE.getTargetName() << "::" << FR->getName()
1603+
<< ")";
1604+
continue;
1605+
}
1606+
15891607
// Expand this legacy predicate and wrap it around braces if there is more
15901608
// than one predicate to expand.
15911609
SS << ((NumNonTruePreds > 1) ? "(" : "")
@@ -1618,7 +1636,8 @@ static void emitSchedModelHelperEpilogue(raw_ostream &OS,
16181636

16191637
static bool hasMCSchedPredicates(const CodeGenSchedTransition &T) {
16201638
return all_of(T.PredTerm, [](const Record *Rec) {
1621-
return Rec->isSubClassOf("MCSchedPredicate");
1639+
return Rec->isSubClassOf("MCSchedPredicate") ||
1640+
Rec->isSubClassOf("FeatureSchedPredicate");
16221641
});
16231642
}
16241643

0 commit comments

Comments
 (0)