diff --git a/llvm/include/llvm/MC/MCSubtargetInfo.h b/llvm/include/llvm/MC/MCSubtargetInfo.h --- a/llvm/include/llvm/MC/MCSubtargetInfo.h +++ b/llvm/include/llvm/MC/MCSubtargetInfo.h @@ -213,9 +213,10 @@ void initInstrItins(InstrItineraryData &InstrItins) const; /// Resolve a variant scheduling class for the given MCInst and CPU. - virtual unsigned - resolveVariantSchedClass(unsigned SchedClass, const MCInst *MI, - unsigned CPUID) const { + virtual unsigned resolveVariantSchedClass(unsigned SchedClass, + const MCInst *MI, + const MCInstrInfo *MCII, + unsigned CPUID) const { return 0; } diff --git a/llvm/include/llvm/Target/TargetInstrPredicate.td b/llvm/include/llvm/Target/TargetInstrPredicate.td --- a/llvm/include/llvm/Target/TargetInstrPredicate.td +++ b/llvm/include/llvm/Target/TargetInstrPredicate.td @@ -254,6 +254,20 @@ string MachineInstrFnName = MachineInstrFn; } +// Similar to CheckFunctionPredicate. However it assumes that MachineInstrFn is +// a method in TargetInstrInfo, and MCInstrFn takes an extra pointer to +// MCInstrInfo. +// +// It Expands to: +// - TIIPointer->MachineInstrFn(MI) +// - MCInstrFn(MI, MCII); +class CheckFunctionPredicateWithTII : MCInstPredicate { + string MCInstFnName = MCInstFn; + string TIIPtrName = TIIPointer; + string MachineInstrFnName = MachineInstrFn; +} + // Used to classify machine instructions based on a machine instruction // predicate. // diff --git a/llvm/lib/MC/MCSchedule.cpp b/llvm/lib/MC/MCSchedule.cpp --- a/llvm/lib/MC/MCSchedule.cpp +++ b/llvm/lib/MC/MCSchedule.cpp @@ -74,7 +74,7 @@ unsigned CPUID = getProcessorID(); while (SCDesc->isVariant()) { - SchedClass = STI.resolveVariantSchedClass(SchedClass, &Inst, CPUID); + SchedClass = STI.resolveVariantSchedClass(SchedClass, &Inst, &MCII, CPUID); SCDesc = getSchedClassDesc(SchedClass); } @@ -120,7 +120,7 @@ unsigned CPUID = getProcessorID(); while (SCDesc->isVariant()) { - SchedClass = STI.resolveVariantSchedClass(SchedClass, &Inst, CPUID); + SchedClass = STI.resolveVariantSchedClass(SchedClass, &Inst, &MCII, CPUID); SCDesc = getSchedClassDesc(SchedClass); } diff --git a/llvm/lib/MCA/InstrBuilder.cpp b/llvm/lib/MCA/InstrBuilder.cpp --- a/llvm/lib/MCA/InstrBuilder.cpp +++ b/llvm/lib/MCA/InstrBuilder.cpp @@ -518,7 +518,8 @@ if (IsVariant) { unsigned CPUID = SM.getProcessorID(); while (SchedClassID && SM.getSchedClassDesc(SchedClassID)->isVariant()) - SchedClassID = STI.resolveVariantSchedClass(SchedClassID, &MCI, CPUID); + SchedClassID = + STI.resolveVariantSchedClass(SchedClassID, &MCI, &MCII, CPUID); if (!SchedClassID) { return make_error>( diff --git a/llvm/lib/Target/ARM/ARMSchedule.td b/llvm/lib/Target/ARM/ARMSchedule.td --- a/llvm/lib/Target/ARM/ARMSchedule.td +++ b/llvm/lib/Target/ARM/ARMSchedule.td @@ -151,7 +151,11 @@ (void)STI; }]>; -def IsPredicatedPred : SchedPredicate<[{TII->isPredicated(*MI)}]>; +def IsPredicated : CheckFunctionPredicateWithTII< + "ARM_MC::isPredicated", + "isPredicated" +>; +def IsPredicatedPred : MCSchedPredicate; //===----------------------------------------------------------------------===// // Instruction Itinerary classes used for ARM diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h @@ -42,6 +42,8 @@ namespace ARM_MC { std::string ParseARMTriple(const Triple &TT, StringRef CPU); +bool isPredicated(const MCInst &MI, const MCInstrInfo *MCII); + /// Create a ARM MCSubtargetInfo instance. This is exposed so Asm parser, etc. /// do not need to go through TargetRegistry. MCSubtargetInfo *createARMMCSubtargetInfo(const Triple &TT, StringRef CPU, diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -180,6 +180,12 @@ return ARMArchFeature; } +bool ARM_MC::isPredicated(const MCInst &MI, const MCInstrInfo *MCII) { + const MCInstrDesc &Desc = MCII->get(MI.getOpcode()); + int PredOpIdx = Desc.findFirstPredOperandIdx(); + return PredOpIdx != -1 && MI.getOperand(PredOpIdx).getImm() != ARMCC::AL; +} + MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) { std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU); diff --git a/llvm/test/tools/llvm-mca/ARM/cortex-a57-basic-instructions.s b/llvm/test/tools/llvm-mca/ARM/cortex-a57-basic-instructions.s --- a/llvm/test/tools/llvm-mca/ARM/cortex-a57-basic-instructions.s +++ b/llvm/test/tools/llvm-mca/ARM/cortex-a57-basic-instructions.s @@ -1205,8 +1205,8 @@ # CHECK-NEXT: 1 1 0.50 mvnseq r2, r3, lsl #10 # CHECK-NEXT: 1 1 0.50 mvn r5, r6, lsl r7 # CHECK-NEXT: 1 1 0.50 mvns r5, r6, lsr r7 -# CHECK-NEXT: 1 1 0.50 mvngt r5, r6, asr r7 -# CHECK-NEXT: 1 1 0.50 mvnslt r5, r6, ror r7 +# CHECK-NEXT: 1 2 0.50 mvngt r5, r6, asr r7 +# CHECK-NEXT: 1 2 0.50 mvnslt r5, r6, ror r7 # CHECK-NEXT: 0 0 0.00 * * U nop # CHECK-NEXT: 0 0 0.00 * * U nopgt # CHECK-NEXT: 1 1 0.50 orr r4, r5, #61440 @@ -1238,12 +1238,12 @@ # CHECK-NEXT: 1 1 0.50 orrseq r4, r5, #61440 # CHECK-NEXT: 1 1 0.50 orrne r4, r5, r6 # CHECK-NEXT: 1 2 1.00 orrseq r4, r5, r6, lsl #5 -# CHECK-NEXT: 1 2 1.00 orrlo r6, r7, r8, ror r9 +# CHECK-NEXT: 1 2 0.50 orrlo r6, r7, r8, ror r9 # CHECK-NEXT: 1 2 1.00 orrshi r4, r5, r6, rrx # CHECK-NEXT: 1 1 0.50 orrhs r5, r5, #61440 # CHECK-NEXT: 1 1 0.50 orrseq r4, r4, r5 -# CHECK-NEXT: 1 2 1.00 orrne r6, r6, r7, asr r9 -# CHECK-NEXT: 1 2 1.00 orrslt r6, r6, r7, ror r9 +# CHECK-NEXT: 1 2 0.50 orrne r6, r6, r7, asr r9 +# CHECK-NEXT: 1 2 0.50 orrslt r6, r6, r7, ror r9 # CHECK-NEXT: 1 2 1.00 orrsgt r4, r4, r5, rrx # CHECK-NEXT: 1 2 1.00 pkhbt r2, r2, r3 # CHECK-NEXT: 1 2 1.00 pkhbt r2, r2, r3, lsl #31 @@ -1312,7 +1312,7 @@ # CHECK-NEXT: 1 2 1.00 rsb r6, r7, r8, lsl r9 # CHECK-NEXT: 1 2 1.00 rsb r6, r7, r8, lsr r9 # CHECK-NEXT: 1 2 1.00 rsb r6, r7, r8, asr r9 -# CHECK-NEXT: 1 2 1.00 rsble r6, r7, r8, ror r9 +# CHECK-NEXT: 1 2 0.50 rsble r6, r7, r8, ror r9 # CHECK-NEXT: 1 2 1.00 rsb r4, r5, r6, rrx # CHECK-NEXT: 1 1 0.50 rsb r5, r5, #61440 # CHECK-NEXT: 1 1 0.50 U rsb r4, r4, r5 @@ -1321,7 +1321,7 @@ # CHECK-NEXT: 1 2 1.00 rsbne r4, r4, r5, lsr #5 # CHECK-NEXT: 1 2 1.00 rsb r4, r4, r5, asr #5 # CHECK-NEXT: 1 2 1.00 rsb r4, r4, r5, ror #5 -# CHECK-NEXT: 1 2 1.00 rsbgt r6, r6, r7, lsl r9 +# CHECK-NEXT: 1 2 0.50 rsbgt r6, r6, r7, lsl r9 # CHECK-NEXT: 1 2 1.00 rsb r6, r6, r7, lsr r9 # CHECK-NEXT: 1 2 1.00 rsb r6, r6, r7, asr r9 # CHECK-NEXT: 1 2 1.00 rsb r6, r6, r7, ror r9 @@ -1340,7 +1340,7 @@ # CHECK-NEXT: 1 2 1.00 rsc r6, r7, r8, lsl r9 # CHECK-NEXT: 1 2 1.00 rsc r6, r7, r8, lsr r9 # CHECK-NEXT: 1 2 1.00 rsc r6, r7, r8, asr r9 -# CHECK-NEXT: 1 2 1.00 rscle r6, r7, r8, ror r9 +# CHECK-NEXT: 1 2 0.50 rscle r6, r7, r8, ror r9 # CHECK-NEXT: 1 1 0.50 rsc r5, r5, #61440 # CHECK-NEXT: 1 1 0.50 U rsc r4, r4, r5 # CHECK-NEXT: 1 2 1.00 rsc r4, r4, r5, lsl #5 @@ -1348,7 +1348,7 @@ # CHECK-NEXT: 1 2 1.00 rscne r4, r4, r5, lsr #5 # CHECK-NEXT: 1 2 1.00 rsc r4, r4, r5, asr #5 # CHECK-NEXT: 1 2 1.00 rsc r4, r4, r5, ror #5 -# CHECK-NEXT: 1 2 1.00 rscgt r6, r6, r7, lsl r9 +# CHECK-NEXT: 1 2 0.50 rscgt r6, r6, r7, lsl r9 # CHECK-NEXT: 1 2 1.00 rsc r6, r6, r7, lsr r9 # CHECK-NEXT: 1 2 1.00 rsc r6, r6, r7, asr r9 # CHECK-NEXT: 1 2 1.00 rsc r6, r6, r7, ror r9 @@ -1361,11 +1361,11 @@ # CHECK-NEXT: 1 1 0.50 rrxs pc, lr # CHECK-NEXT: 1 1 0.50 rrxs lr, sp # CHECK-NEXT: 2 2 1.00 * * U sadd16 r1, r2, r3 -# CHECK-NEXT: 2 2 1.00 * * U sadd16gt r1, r2, r3 +# CHECK-NEXT: 2 4 1.00 * * U sadd16gt r1, r2, r3 # CHECK-NEXT: 2 2 1.00 * * U sadd8 r1, r2, r3 -# CHECK-NEXT: 2 2 1.00 * * U sadd8le r1, r2, r3 +# CHECK-NEXT: 2 4 1.00 * * U sadd8le r1, r2, r3 # CHECK-NEXT: 2 3 1.00 * * U sasx r9, r12, r0 -# CHECK-NEXT: 2 3 1.00 * * U sasxeq r9, r12, r0 +# CHECK-NEXT: 2 5 1.00 * * U sasxeq r9, r12, r0 # CHECK-NEXT: 1 1 0.50 sbc r4, r5, #61440 # CHECK-NEXT: 1 1 0.50 sbc r7, r8, #-2147483638 # CHECK-NEXT: 1 1 0.50 sbc r7, r8, #40, #2 @@ -1393,7 +1393,7 @@ # CHECK-NEXT: 1 1 0.50 U sbfx r4, r5, #16, #1 # CHECK-NEXT: 1 1 0.50 U sbfxgt r4, r5, #16, #16 # CHECK-NEXT: 1 1 0.50 * sel r9, r2, r1 -# CHECK-NEXT: 1 1 0.50 * selne r9, r2, r1 +# CHECK-NEXT: 1 2 0.50 * selne r9, r2, r1 # CHECK-NEXT: 0 0 0.00 U setend be # CHECK-NEXT: 0 0 0.00 U setend le # CHECK-NEXT: 0 0 0.00 * * U sev @@ -1507,11 +1507,11 @@ # CHECK-NEXT: 1 2 1.00 ssat16 r2, #1, r7 # CHECK-NEXT: 1 2 1.00 ssat16 r3, #16, r5 # CHECK-NEXT: 2 3 1.00 * * U ssax r2, r3, r4 -# CHECK-NEXT: 2 3 1.00 * * U ssaxlt r2, r3, r4 +# CHECK-NEXT: 2 5 1.00 * * U ssaxlt r2, r3, r4 # CHECK-NEXT: 2 2 1.00 * * U ssub16 r1, r0, r6 -# CHECK-NEXT: 2 2 1.00 * * U ssub16ne r5, r3, r2 +# CHECK-NEXT: 2 4 1.00 * * U ssub16ne r5, r3, r2 # CHECK-NEXT: 2 2 1.00 * * U ssub8 r9, r2, r4 -# CHECK-NEXT: 2 2 1.00 * * U ssub8eq r5, r1, r2 +# CHECK-NEXT: 2 4 1.00 * * U ssub8eq r5, r1, r2 # CHECK-NEXT: 1 2 1.00 * stm r2, {r1, r3, r4, r5, r6, sp} # CHECK-NEXT: 1 2 1.00 * stm r3, {r1, r3, r4, r5, r6, lr} # CHECK-NEXT: 1 2 1.00 * stmib r4, {r1, r3, r4, r5, r6, sp} @@ -1613,11 +1613,11 @@ # CHECK-NEXT: 1 2 1.00 tst r6, r7, asr r9 # CHECK-NEXT: 1 2 1.00 tst r6, r7, ror r9 # CHECK-NEXT: 2 2 1.00 * * U uadd16 r1, r2, r3 -# CHECK-NEXT: 2 2 1.00 * * U uadd16gt r1, r2, r3 +# CHECK-NEXT: 2 4 1.00 * * U uadd16gt r1, r2, r3 # CHECK-NEXT: 2 2 1.00 * * U uadd8 r1, r2, r3 -# CHECK-NEXT: 2 2 1.00 * * U uadd8le r1, r2, r3 +# CHECK-NEXT: 2 4 1.00 * * U uadd8le r1, r2, r3 # CHECK-NEXT: 2 3 1.00 * * U uasx r9, r12, r0 -# CHECK-NEXT: 2 3 1.00 * * U uasxeq r9, r12, r0 +# CHECK-NEXT: 2 5 1.00 * * U uasxeq r9, r12, r0 # CHECK-NEXT: 1 1 0.50 U ubfx r4, r5, #16, #1 # CHECK-NEXT: 1 1 0.50 U ubfxgt r4, r5, #16, #16 # CHECK-NEXT: 1 2 1.00 uhadd16 r4, r8, r2 @@ -1664,11 +1664,11 @@ # CHECK-NEXT: 1 2 1.00 usat16 r2, #2, r7 # CHECK-NEXT: 1 2 1.00 usat16 r3, #15, r5 # CHECK-NEXT: 2 3 1.00 * * U usax r2, r3, r4 -# CHECK-NEXT: 2 3 1.00 * * U usaxne r2, r3, r4 +# CHECK-NEXT: 2 5 1.00 * * U usaxne r2, r3, r4 # CHECK-NEXT: 2 2 1.00 * * U usub16 r4, r2, r7 -# CHECK-NEXT: 2 2 1.00 * * U usub16hi r1, r1, r3 +# CHECK-NEXT: 2 4 1.00 * * U usub16hi r1, r1, r3 # CHECK-NEXT: 2 2 1.00 * * U usub8 r1, r8, r5 -# CHECK-NEXT: 2 2 1.00 * * U usub8le r9, r2, r3 +# CHECK-NEXT: 2 4 1.00 * * U usub8le r9, r2, r3 # CHECK-NEXT: 1 2 1.00 uxtab r2, r3, r4 # CHECK-NEXT: 1 2 1.00 uxtab r4, r5, r6 # CHECK-NEXT: 1 2 1.00 uxtablt r6, r2, r9, ror #8 @@ -1719,7 +1719,7 @@ # CHECK: Resource pressure per iteration: # CHECK-NEXT: [0] [1.0] [1.1] [2] [3] [4] [5] [6] -# CHECK-NEXT: 8.00 158.50 158.50 171.00 497.00 12.00 - - +# CHECK-NEXT: 8.00 162.00 162.00 171.00 490.00 12.00 - - # CHECK: Resource pressure by instruction: # CHECK-NEXT: [0] [1.0] [1.1] [2] [3] [4] [5] [6] Instructions: @@ -2102,12 +2102,12 @@ # CHECK-NEXT: - 0.50 0.50 - - - - - orrseq r4, r5, #61440 # CHECK-NEXT: - 0.50 0.50 - - - - - orrne r4, r5, r6 # CHECK-NEXT: - - - - 1.00 - - - orrseq r4, r5, r6, lsl #5 -# CHECK-NEXT: - - - - 1.00 - - - orrlo r6, r7, r8, ror r9 +# CHECK-NEXT: - 0.50 0.50 - - - - - orrlo r6, r7, r8, ror r9 # CHECK-NEXT: - - - - 1.00 - - - orrshi r4, r5, r6, rrx # CHECK-NEXT: - 0.50 0.50 - - - - - orrhs r5, r5, #61440 # CHECK-NEXT: - 0.50 0.50 - - - - - orrseq r4, r4, r5 -# CHECK-NEXT: - - - - 1.00 - - - orrne r6, r6, r7, asr r9 -# CHECK-NEXT: - - - - 1.00 - - - orrslt r6, r6, r7, ror r9 +# CHECK-NEXT: - 0.50 0.50 - - - - - orrne r6, r6, r7, asr r9 +# CHECK-NEXT: - 0.50 0.50 - - - - - orrslt r6, r6, r7, ror r9 # CHECK-NEXT: - - - - 1.00 - - - orrsgt r4, r4, r5, rrx # CHECK-NEXT: - - - - 1.00 - - - pkhbt r2, r2, r3 # CHECK-NEXT: - - - - 1.00 - - - pkhbt r2, r2, r3, lsl #31 @@ -2176,7 +2176,7 @@ # CHECK-NEXT: - - - - 1.00 - - - rsb r6, r7, r8, lsl r9 # CHECK-NEXT: - - - - 1.00 - - - rsb r6, r7, r8, lsr r9 # CHECK-NEXT: - - - - 1.00 - - - rsb r6, r7, r8, asr r9 -# CHECK-NEXT: - - - - 1.00 - - - rsble r6, r7, r8, ror r9 +# CHECK-NEXT: - 0.50 0.50 - - - - - rsble r6, r7, r8, ror r9 # CHECK-NEXT: - - - - 1.00 - - - rsb r4, r5, r6, rrx # CHECK-NEXT: - 0.50 0.50 - - - - - rsb r5, r5, #61440 # CHECK-NEXT: - 0.50 0.50 - - - - - rsb r4, r4, r5 @@ -2185,7 +2185,7 @@ # CHECK-NEXT: - - - - 1.00 - - - rsbne r4, r4, r5, lsr #5 # CHECK-NEXT: - - - - 1.00 - - - rsb r4, r4, r5, asr #5 # CHECK-NEXT: - - - - 1.00 - - - rsb r4, r4, r5, ror #5 -# CHECK-NEXT: - - - - 1.00 - - - rsbgt r6, r6, r7, lsl r9 +# CHECK-NEXT: - 0.50 0.50 - - - - - rsbgt r6, r6, r7, lsl r9 # CHECK-NEXT: - - - - 1.00 - - - rsb r6, r6, r7, lsr r9 # CHECK-NEXT: - - - - 1.00 - - - rsb r6, r6, r7, asr r9 # CHECK-NEXT: - - - - 1.00 - - - rsb r6, r6, r7, ror r9 @@ -2204,7 +2204,7 @@ # CHECK-NEXT: - - - - 1.00 - - - rsc r6, r7, r8, lsl r9 # CHECK-NEXT: - - - - 1.00 - - - rsc r6, r7, r8, lsr r9 # CHECK-NEXT: - - - - 1.00 - - - rsc r6, r7, r8, asr r9 -# CHECK-NEXT: - - - - 1.00 - - - rscle r6, r7, r8, ror r9 +# CHECK-NEXT: - 0.50 0.50 - - - - - rscle r6, r7, r8, ror r9 # CHECK-NEXT: - 0.50 0.50 - - - - - rsc r5, r5, #61440 # CHECK-NEXT: - 0.50 0.50 - - - - - rsc r4, r4, r5 # CHECK-NEXT: - - - - 1.00 - - - rsc r4, r4, r5, lsl #5 @@ -2212,7 +2212,7 @@ # CHECK-NEXT: - - - - 1.00 - - - rscne r4, r4, r5, lsr #5 # CHECK-NEXT: - - - - 1.00 - - - rsc r4, r4, r5, asr #5 # CHECK-NEXT: - - - - 1.00 - - - rsc r4, r4, r5, ror #5 -# CHECK-NEXT: - - - - 1.00 - - - rscgt r6, r6, r7, lsl r9 +# CHECK-NEXT: - 0.50 0.50 - - - - - rscgt r6, r6, r7, lsl r9 # CHECK-NEXT: - - - - 1.00 - - - rsc r6, r6, r7, lsr r9 # CHECK-NEXT: - - - - 1.00 - - - rsc r6, r6, r7, asr r9 # CHECK-NEXT: - - - - 1.00 - - - rsc r6, r6, r7, ror r9 diff --git a/llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp b/llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp --- a/llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp +++ b/llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp @@ -217,12 +217,14 @@ } static unsigned ResolveVariantSchedClassId(const MCSubtargetInfo &STI, + const MCInstrInfo &InstrInfo, unsigned SchedClassId, const MCInst &MCI) { const auto &SM = STI.getSchedModel(); - while (SchedClassId && SM.getSchedClassDesc(SchedClassId)->isVariant()) - SchedClassId = - STI.resolveVariantSchedClass(SchedClassId, &MCI, SM.getProcessorID()); + while (SchedClassId && SM.getSchedClassDesc(SchedClassId)->isVariant()) { + SchedClassId = STI.resolveVariantSchedClass(SchedClassId, &MCI, &InstrInfo, + SM.getProcessorID()); + } return SchedClassId; } @@ -234,7 +236,8 @@ const bool WasVariant = SchedClassId && SubtargetInfo.getSchedModel() .getSchedClassDesc(SchedClassId) ->isVariant(); - SchedClassId = ResolveVariantSchedClassId(SubtargetInfo, SchedClassId, MCI); + SchedClassId = + ResolveVariantSchedClassId(SubtargetInfo, InstrInfo, SchedClassId, MCI); return std::make_pair(SchedClassId, WasVariant); } diff --git a/llvm/tools/llvm-mca/Views/InstructionInfoView.cpp b/llvm/tools/llvm-mca/Views/InstructionInfoView.cpp --- a/llvm/tools/llvm-mca/Views/InstructionInfoView.cpp +++ b/llvm/tools/llvm-mca/Views/InstructionInfoView.cpp @@ -103,7 +103,8 @@ // Try to solve variant scheduling classes. while (SchedClassID && SM.getSchedClassDesc(SchedClassID)->isVariant()) - SchedClassID = STI.resolveVariantSchedClass(SchedClassID, &Inst, CPUID); + SchedClassID = + STI.resolveVariantSchedClass(SchedClassID, &Inst, &MCII, CPUID); const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID); IIVDEntry.NumMicroOpcodes = SCDesc.NumMicroOps; diff --git a/llvm/utils/TableGen/PredicateExpander.h b/llvm/utils/TableGen/PredicateExpander.h --- a/llvm/utils/TableGen/PredicateExpander.h +++ b/llvm/utils/TableGen/PredicateExpander.h @@ -79,6 +79,9 @@ void expandCheckInvalidRegOperand(raw_ostream &OS, int OpIndex); void expandCheckFunctionPredicate(raw_ostream &OS, StringRef MCInstFn, StringRef MachineInstrFn); + void expandCheckFunctionPredicateWithTII(raw_ostream &OS, StringRef MCInstFn, + StringRef MachineInstrFn, + StringRef TIIPtr); void expandCheckNonPortable(raw_ostream &OS, StringRef CodeBlock); void expandPredicate(raw_ostream &OS, const Record *Rec); void expandReturnStatement(raw_ostream &OS, const Record *Rec); diff --git a/llvm/utils/TableGen/PredicateExpander.cpp b/llvm/utils/TableGen/PredicateExpander.cpp --- a/llvm/utils/TableGen/PredicateExpander.cpp +++ b/llvm/utils/TableGen/PredicateExpander.cpp @@ -198,6 +198,18 @@ << "getOperand(" << OpIndex << ").isImm() "; } +void PredicateExpander::expandCheckFunctionPredicateWithTII( + raw_ostream &OS, StringRef MCInstFn, StringRef MachineInstrFn, + StringRef TIIPtr) { + if (!shouldExpandForMC()) { + OS << (TIIPtr.empty() ? "TII" : TIIPtr) << "->" << MachineInstrFn; + OS << (isByRef() ? "(MI)" : "(*MI)"); + return; + } + + OS << MCInstFn << (isByRef() ? "(MI" : "(*MI") << ", MCII)"; +} + void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS, StringRef MCInstFn, StringRef MachineInstrFn) { @@ -358,10 +370,18 @@ return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"), /* AllOf */ false); - if (Rec->isSubClassOf("CheckFunctionPredicate")) + if (Rec->isSubClassOf("CheckFunctionPredicate")) { return expandCheckFunctionPredicate( OS, Rec->getValueAsString("MCInstFnName"), Rec->getValueAsString("MachineInstrFnName")); + } + + if (Rec->isSubClassOf("CheckFunctionPredicateWithTII")) { + return expandCheckFunctionPredicateWithTII( + OS, Rec->getValueAsString("MCInstFnName"), + Rec->getValueAsString("MachineInstrFnName"), + Rec->getValueAsString("TIIPtrName")); + } if (Rec->isSubClassOf("CheckNonPortable")) return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock")); diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp --- a/llvm/utils/TableGen/SubtargetEmitter.cpp +++ b/llvm/utils/TableGen/SubtargetEmitter.cpp @@ -1651,9 +1651,9 @@ OS << "unsigned " << ClassName << "\n::resolveVariantSchedClass(unsigned SchedClass, const MCInst *MI," - << " unsigned CPUID) const {\n" + << " const MCInstrInfo *MCII, unsigned CPUID) const {\n" << " return " << Target << "_MC" - << "::resolveVariantSchedClassImpl(SchedClass, MI, CPUID);\n" + << "::resolveVariantSchedClassImpl(SchedClass, MI, MCII, CPUID);\n" << "} // " << ClassName << "::resolveVariantSchedClass\n\n"; STIPredicateExpander PE(Target); @@ -1734,7 +1734,7 @@ void SubtargetEmitter::emitGenMCSubtargetInfo(raw_ostream &OS) { OS << "namespace " << Target << "_MC {\n" << "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,\n" - << " const MCInst *MI, unsigned CPUID) {\n"; + << " const MCInst *MI, const MCInstrInfo *MCII, unsigned CPUID) {\n"; emitSchedModelHelpersImpl(OS, /* OnlyExpandMCPredicates */ true); OS << "}\n"; OS << "} // end namespace " << Target << "_MC\n\n"; @@ -1752,9 +1752,10 @@ << " MCSubtargetInfo(TT, CPU, TuneCPU, FS, PF, PD,\n" << " WPR, WL, RA, IS, OC, FP) { }\n\n" << " unsigned resolveVariantSchedClass(unsigned SchedClass,\n" - << " const MCInst *MI, unsigned CPUID) const override {\n" + << " const MCInst *MI, const MCInstrInfo *MCII,\n" + << " unsigned CPUID) const override {\n" << " return " << Target << "_MC" - << "::resolveVariantSchedClassImpl(SchedClass, MI, CPUID); \n"; + << "::resolveVariantSchedClassImpl(SchedClass, MI, MCII, CPUID); \n"; OS << " }\n"; if (TGT.getHwModes().getNumModeIds() > 1) OS << " unsigned getHwMode() const override;\n"; @@ -1871,7 +1872,7 @@ OS << "class DFAPacketizer;\n"; OS << "namespace " << Target << "_MC {\n" << "unsigned resolveVariantSchedClassImpl(unsigned SchedClass," - << " const MCInst *MI, unsigned CPUID);\n" + << " const MCInst *MI, const MCInstrInfo *MCII, unsigned CPUID);\n" << "} // end namespace " << Target << "_MC\n\n"; OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n" << " explicit " << ClassName << "(const Triple &TT, StringRef CPU, " @@ -1881,7 +1882,8 @@ << " const MachineInstr *DefMI," << " const TargetSchedModel *SchedModel) const override;\n" << " unsigned resolveVariantSchedClass(unsigned SchedClass," - << " const MCInst *MI, unsigned CPUID) const override;\n" + << " const MCInst *MI, const MCInstrInfo *MCII," + << " unsigned CPUID) const override;\n" << " DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)" << " const;\n"; if (TGT.getHwModes().getNumModeIds() > 1)