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.
65 lines
2.2 KiB
TableGen
65 lines
2.2 KiB
TableGen
// 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
|