diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h @@ -186,10 +186,6 @@ bool isLdstSoMinusReg(const MachineInstr &MI, unsigned Op) const; // Scaled register offset in address mode 2 bool isAm2ScaledReg(const MachineInstr &MI, unsigned Op) const; - // Load multiple, base reg in list - bool isLDMBaseRegInList(const MachineInstr &MI) const; - // get LDM variable defs size - unsigned getLDMVariableDefsSize(const MachineInstr &MI) const; /// GetInstSize - Returns the size of the specified MachineInstr. /// diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -3854,22 +3854,6 @@ return DefCycle; } -bool ARMBaseInstrInfo::isLDMBaseRegInList(const MachineInstr &MI) const { - Register BaseReg = MI.getOperand(0).getReg(); - for (unsigned i = 1, sz = MI.getNumOperands(); i < sz; ++i) { - const auto &Op = MI.getOperand(i); - if (Op.isReg() && Op.getReg() == BaseReg) - return true; - } - return false; -} -unsigned -ARMBaseInstrInfo::getLDMVariableDefsSize(const MachineInstr &MI) const { - // ins GPR:$Rn, $p (2xOp), reglist:$regs, variable_ops - // (outs GPR:$wb), (ins GPR:$Rn, $p (2xOp), reglist:$regs, variable_ops) - return MI.getNumOperands() + 1 - MI.getDesc().getNumOperands(); -} - int ARMBaseInstrInfo::getLDMDefCycle(const InstrItineraryData *ItinData, const MCInstrDesc &DefMCID, 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 @@ -168,6 +168,9 @@ def CheckExtNoShift : CheckImmOperand_s<4, "ARM_AM::no_shift">; } +def IsLDMBaseRegInList : CheckFunctionPredicate< + "ARM_MC::isLDMBaseRegInList", "ARM_MC::isLDMBaseRegInList" +>; //===----------------------------------------------------------------------===// // Instruction Itinerary classes used for ARM // diff --git a/llvm/lib/Target/ARM/ARMScheduleA57.td b/llvm/lib/Target/ARM/ARMScheduleA57.td --- a/llvm/lib/Target/ARM/ARMScheduleA57.td +++ b/llvm/lib/Target/ARM/ARMScheduleA57.td @@ -63,8 +63,7 @@ SchedPredicate<[{TII->isAm2ScaledReg(*MI, 1)}]>; // LDM, base reg in list -def IsLdmBaseRegInList : - SchedPredicate<[{TII->isLDMBaseRegInList(*MI)}]>; +def IsLDMBaseRegInListPred : MCSchedPredicate; class A57WriteLMOpsListType writes> { list Writes = writes; @@ -508,8 +507,12 @@ // --- Load multiple instructions --- foreach NumAddr = 1-8 in { - def A57LMAddrPred#NumAddr : - SchedPredicate<"(TII->getLDMVariableDefsSize(*MI)+1)/2 == "#NumAddr>; + def A57LMAddrPred#NumAddr : MCSchedPredicate, + CheckNumOperands]>>; + def A57LMAddrUpdPred#NumAddr : MCSchedPredicate, + CheckNumOperands]>>; } def A57LDMOpsListNoregin : A57WriteLMOpsListType< @@ -565,20 +568,20 @@ A57Write_9cyc_1L_1I, A57Write_9cyc_1L_1I, A57Write_10cyc_1L_1I, A57Write_10cyc_1L_1I]>; def A57WriteLDM_Upd : SchedWriteVariant<[ - SchedVar, - SchedVar, - SchedVar, - SchedVar, - SchedVar, - SchedVar, - SchedVar, - SchedVar, - SchedVar + SchedVar, + SchedVar, + SchedVar, + SchedVar, + SchedVar, + SchedVar, + SchedVar, + SchedVar, + SchedVar ]> { let Variadic=1; } def A57WriteLDM : SchedWriteVariant<[ - SchedVar, - SchedVar + SchedVar, + SchedVar ]> { let Variadic=1; } def : InstRW<[A57WriteLDM], (instregex "(t|t2|sys)?LDM(IA|DA|DB|IB)$")>; 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 @@ -46,6 +46,17 @@ bool isPredicated(const MCInst &MI, const MCInstrInfo *MCII); bool isCPSRDefined(const MCInst &MI, const MCInstrInfo *MCII); +template +bool isLDMBaseRegInList(const Inst &MI) { + auto BaseReg = MI.getOperand(0).getReg(); + for (unsigned I = 1, E = MI.getNumOperands(); I < E; ++I) { + const auto &Op = MI.getOperand(I); + if (Op.isReg() && Op.getReg() == BaseReg) + return true; + } + return false; +} + /// 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/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 @@ -1105,14 +1105,14 @@ # CHECK-NEXT: 1 2 1.00 eor r4, r4, r5, rrx # CHECK-NEXT: 0 0 0.00 * * U isb sy # CHECK-NEXT: 0 0 0.00 * * U isb #0xa -# CHECK-NEXT: 16 10 16.00 * ldm r2, {r1, r3, r4, r5, r6, sp} -# CHECK-NEXT: 16 10 16.00 * ldmib r2, {r1, r3, r4, r5, r6, sp} -# CHECK-NEXT: 16 10 16.00 * ldmda r2, {r1, r3, r4, r5, r6, sp} -# CHECK-NEXT: 16 10 16.00 * ldmdb r2, {r1, r3, r4, r5, r6, sp} -# CHECK-NEXT: 32 10 16.00 * ldm r2!, {r1, r3, r4, r5, r6, sp} -# CHECK-NEXT: 32 10 16.00 * ldmib r2!, {r1, r3, r4, r5, r6, sp} -# CHECK-NEXT: 32 10 16.00 * ldmda r2!, {r1, r3, r4, r5, r6, sp} -# CHECK-NEXT: 32 10 16.00 * ldmdb r2!, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: 6 5 6.00 * ldm r2, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: 6 5 6.00 * ldmib r2, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: 6 5 6.00 * ldmda r2, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: 6 5 6.00 * ldmdb r2, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: 12 5 6.00 * ldm r2!, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: 12 5 6.00 * ldmib r2!, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: 12 5 6.00 * ldmda r2!, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: 12 5 6.00 * ldmdb r2!, {r1, r3, r4, r5, r6, sp} # CHECK-NEXT: 0 0 0.00 * * U ldrexb r3, [r4] # CHECK-NEXT: 0 0 0.00 * * U ldrexh r2, [r5] # CHECK-NEXT: 0 0 0.00 * * U ldrex r1, [r7] @@ -1253,9 +1253,9 @@ # CHECK-NEXT: 1 2 1.00 pkhtb r2, r2, r3, asr #31 # CHECK-NEXT: 1 2 1.00 pkhtb r2, r2, r3, asr #15 # CHECK-NEXT: 2 4 1.00 * pop {r7} -# CHECK-NEXT: 32 10 16.00 * pop {r7, r8, r9, r10} +# CHECK-NEXT: 8 4 4.00 * pop {r7, r8, r9, r10} # CHECK-NEXT: 2 1 1.00 * push {r7} -# CHECK-NEXT: 2 2 1.00 * push {r7, r8, r9, r10} +# CHECK-NEXT: 2 3 1.00 * push {r7, r8, r9, r10} # CHECK-NEXT: 1 2 1.00 U qadd r1, r2, r3 # CHECK-NEXT: 1 2 1.00 U qaddne r1, r2, r3 # CHECK-NEXT: 1 2 1.00 U qadd16 r1, r2, r3 @@ -1512,16 +1512,16 @@ # 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 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} -# CHECK-NEXT: 1 2 1.00 * stmda r5, {r1, r3, r4, r5, r6, sp} -# CHECK-NEXT: 1 2 1.00 * stmdb r6, {r1, r3, r4, r5, r6, r8} -# CHECK-NEXT: 1 2 1.00 * stmdb sp, {r1, r3, r4, r5, r6, sp} -# CHECK-NEXT: 2 2 1.00 * stm r8!, {r1, r3, r4, r5, r6, sp} -# CHECK-NEXT: 2 2 1.00 * stmib r9!, {r1, r3, r4, r5, r6, sp} -# CHECK-NEXT: 2 2 1.00 * stmda sp!, {r1, r3, r4, r5, r6} -# CHECK-NEXT: 2 2 1.00 * stmdb r0!, {r1, r5, r7, sp} +# CHECK-NEXT: 1 3 1.00 * stm r2, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: 1 3 1.00 * stm r3, {r1, r3, r4, r5, r6, lr} +# CHECK-NEXT: 1 3 1.00 * stmib r4, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: 1 3 1.00 * stmda r5, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: 1 3 1.00 * stmdb r6, {r1, r3, r4, r5, r6, r8} +# CHECK-NEXT: 1 3 1.00 * stmdb sp, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: 2 4 1.00 * stm r8!, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: 2 4 1.00 * stmib r9!, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: 2 3 1.00 * stmda sp!, {r1, r3, r4, r5, r6} +# CHECK-NEXT: 2 3 1.00 * stmdb r0!, {r1, r5, r7, sp} # CHECK-NEXT: 0 0 0.00 * * U strexb r1, r3, [r4] # CHECK-NEXT: 0 0 0.00 * * U strexh r4, r2, [r5] # CHECK-NEXT: 0 0 0.00 * * U strex r2, r1, [r7] @@ -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 159.00 159.00 171.00 496.00 12.00 - - +# CHECK-NEXT: 8.00 133.00 133.00 79.00 496.00 12.00 - - # CHECK: Resource pressure by instruction: # CHECK-NEXT: [0] [1.0] [1.1] [2] [3] [4] [5] [6] Instructions: @@ -1969,14 +1969,14 @@ # CHECK-NEXT: - - - - 1.00 - - - eor r4, r4, r5, rrx # CHECK-NEXT: - - - - - - - - isb sy # CHECK-NEXT: - - - - - - - - isb #0xa -# CHECK-NEXT: - - - 16.00 - - - - ldm r2, {r1, r3, r4, r5, r6, sp} -# CHECK-NEXT: - - - 16.00 - - - - ldmib r2, {r1, r3, r4, r5, r6, sp} -# CHECK-NEXT: - - - 16.00 - - - - ldmda r2, {r1, r3, r4, r5, r6, sp} -# CHECK-NEXT: - - - 16.00 - - - - ldmdb r2, {r1, r3, r4, r5, r6, sp} -# CHECK-NEXT: - 8.00 8.00 16.00 - - - - ldm r2!, {r1, r3, r4, r5, r6, sp} -# CHECK-NEXT: - 8.00 8.00 16.00 - - - - ldmib r2!, {r1, r3, r4, r5, r6, sp} -# CHECK-NEXT: - 8.00 8.00 16.00 - - - - ldmda r2!, {r1, r3, r4, r5, r6, sp} -# CHECK-NEXT: - 8.00 8.00 16.00 - - - - ldmdb r2!, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: - - - 6.00 - - - - ldm r2, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: - - - 6.00 - - - - ldmib r2, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: - - - 6.00 - - - - ldmda r2, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: - - - 6.00 - - - - ldmdb r2, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: - 3.00 3.00 6.00 - - - - ldm r2!, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: - 3.00 3.00 6.00 - - - - ldmib r2!, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: - 3.00 3.00 6.00 - - - - ldmda r2!, {r1, r3, r4, r5, r6, sp} +# CHECK-NEXT: - 3.00 3.00 6.00 - - - - ldmdb r2!, {r1, r3, r4, r5, r6, sp} # CHECK-NEXT: - - - - - - - - ldrexb r3, [r4] # CHECK-NEXT: - - - - - - - - ldrexh r2, [r5] # CHECK-NEXT: - - - - - - - - ldrex r1, [r7] @@ -2117,7 +2117,7 @@ # CHECK-NEXT: - - - - 1.00 - - - pkhtb r2, r2, r3, asr #31 # CHECK-NEXT: - - - - 1.00 - - - pkhtb r2, r2, r3, asr #15 # CHECK-NEXT: - 0.50 0.50 1.00 - - - - pop {r7} -# CHECK-NEXT: - 8.00 8.00 16.00 - - - - pop {r7, r8, r9, r10} +# CHECK-NEXT: - 2.00 2.00 4.00 - - - - pop {r7, r8, r9, r10} # CHECK-NEXT: - 0.50 0.50 - - 1.00 - - push {r7} # CHECK-NEXT: - 0.50 0.50 - - 1.00 - - push {r7, r8, r9, r10} # CHECK-NEXT: - - - - 1.00 - - - qadd r1, r2, r3 diff --git a/llvm/test/tools/llvm-mca/ARM/cortex-a57-memory-instructions.s b/llvm/test/tools/llvm-mca/ARM/cortex-a57-memory-instructions.s --- a/llvm/test/tools/llvm-mca/ARM/cortex-a57-memory-instructions.s +++ b/llvm/test/tools/llvm-mca/ARM/cortex-a57-memory-instructions.s @@ -241,18 +241,18 @@ # CHECK-NEXT: 2 4 1.00 * ldrsht r3, [r8], #-12 # CHECK-NEXT: 2 4 1.00 * ldrsht r8, [r9], r5 # CHECK-NEXT: 2 4 1.00 * ldrsht r2, [r1], -r4 -# CHECK-NEXT: 16 10 16.00 * ldm r2, {r1, r2, r4, r5, r6} -# CHECK-NEXT: 16 10 16.00 * ldm r2, {r1, r2, r4, r5, r6} -# CHECK-NEXT: 16 10 16.00 * ldm r2, {r1, r3, r4, r5, r6} -# CHECK-NEXT: 16 10 16.00 * ldmib r2, {r1, r2} -# CHECK-NEXT: 16 10 16.00 * ldmdb r2, {r1, r2} -# CHECK-NEXT: 16 10 16.00 * ldmib r2, {r1, r3} -# CHECK-NEXT: 16 10 16.00 * ldmib r2, {r1, r3, r5} -# CHECK-NEXT: 16 10 16.00 * ldmib r2, {r1, r2, r5} -# CHECK-NEXT: 16 10 16.00 * ldmdbeq r2, {r1, r2} -# CHECK-NEXT: 16 10 16.00 * ldmibeq r2, {r1, r3} +# CHECK-NEXT: 12 6 6.00 * ldm r2, {r1, r2, r4, r5, r6} +# CHECK-NEXT: 12 6 6.00 * ldm r2, {r1, r2, r4, r5, r6} +# CHECK-NEXT: 6 5 6.00 * ldm r2, {r1, r3, r4, r5, r6} +# CHECK-NEXT: 4 4 2.00 * ldmib r2, {r1, r2} +# CHECK-NEXT: 4 4 2.00 * ldmdb r2, {r1, r2} +# CHECK-NEXT: 2 3 2.00 * ldmib r2, {r1, r3} +# CHECK-NEXT: 4 4 4.00 * ldmib r2, {r1, r3, r5} +# CHECK-NEXT: 8 5 4.00 * ldmib r2, {r1, r2, r5} +# CHECK-NEXT: 4 4 2.00 * ldmdbeq r2, {r1, r2} +# CHECK-NEXT: 2 3 2.00 * ldmibeq r2, {r1, r3} # CHECK-NEXT: 16 10 16.00 * ldm r2, {r0, r1, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr, pc} -# CHECK-NEXT: 16 10 16.00 * ldm r2, {r0, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr, pc} +# CHECK-NEXT: 32 11 16.00 * ldm r2, {r0, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr, pc} # CHECK-NEXT: 1 1 1.00 * str r8, [r12] # CHECK-NEXT: 1 1 1.00 * str r7, [r1, #12] # CHECK-NEXT: 2 1 1.00 * str r3, [r5, #40]! @@ -321,7 +321,7 @@ # CHECK: Resource pressure per iteration: # CHECK-NEXT: [0] [1.0] [1.1] [2] [3] [4] [5] [6] -# CHECK-NEXT: - 44.00 44.00 284.00 9.00 55.00 - - +# CHECK-NEXT: - 63.00 63.00 160.00 9.00 55.00 - - # CHECK: Resource pressure by instruction: # CHECK-NEXT: [0] [1.0] [1.1] [2] [3] [4] [5] [6] Instructions: @@ -406,18 +406,18 @@ # CHECK-NEXT: - 0.50 0.50 1.00 - - - - ldrsht r3, [r8], #-12 # CHECK-NEXT: - 0.50 0.50 1.00 - - - - ldrsht r8, [r9], r5 # CHECK-NEXT: - 0.50 0.50 1.00 - - - - ldrsht r2, [r1], -r4 -# CHECK-NEXT: - - - 16.00 - - - - ldm r2, {r1, r2, r4, r5, r6} -# CHECK-NEXT: - - - 16.00 - - - - ldm r2, {r1, r2, r4, r5, r6} -# CHECK-NEXT: - - - 16.00 - - - - ldm r2, {r1, r3, r4, r5, r6} -# CHECK-NEXT: - - - 16.00 - - - - ldmib r2, {r1, r2} -# CHECK-NEXT: - - - 16.00 - - - - ldmdb r2, {r1, r2} -# CHECK-NEXT: - - - 16.00 - - - - ldmib r2, {r1, r3} -# CHECK-NEXT: - - - 16.00 - - - - ldmib r2, {r1, r3, r5} -# CHECK-NEXT: - - - 16.00 - - - - ldmib r2, {r1, r2, r5} -# CHECK-NEXT: - - - 16.00 - - - - ldmdbeq r2, {r1, r2} -# CHECK-NEXT: - - - 16.00 - - - - ldmibeq r2, {r1, r3} +# CHECK-NEXT: - 3.00 3.00 6.00 - - - - ldm r2, {r1, r2, r4, r5, r6} +# CHECK-NEXT: - 3.00 3.00 6.00 - - - - ldm r2, {r1, r2, r4, r5, r6} +# CHECK-NEXT: - - - 6.00 - - - - ldm r2, {r1, r3, r4, r5, r6} +# CHECK-NEXT: - 1.00 1.00 2.00 - - - - ldmib r2, {r1, r2} +# CHECK-NEXT: - 1.00 1.00 2.00 - - - - ldmdb r2, {r1, r2} +# CHECK-NEXT: - - - 2.00 - - - - ldmib r2, {r1, r3} +# CHECK-NEXT: - - - 4.00 - - - - ldmib r2, {r1, r3, r5} +# CHECK-NEXT: - 2.00 2.00 4.00 - - - - ldmib r2, {r1, r2, r5} +# CHECK-NEXT: - 1.00 1.00 2.00 - - - - ldmdbeq r2, {r1, r2} +# CHECK-NEXT: - - - 2.00 - - - - ldmibeq r2, {r1, r3} # CHECK-NEXT: - - - 16.00 - - - - ldm r2, {r0, r1, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr, pc} -# CHECK-NEXT: - - - 16.00 - - - - ldm r2, {r0, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr, pc} +# CHECK-NEXT: - 8.00 8.00 16.00 - - - - ldm r2, {r0, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr, pc} # CHECK-NEXT: - - - - - 1.00 - - str r8, [r12] # CHECK-NEXT: - - - - - 1.00 - - str r7, [r1, #12] # CHECK-NEXT: - 0.50 0.50 - - 1.00 - - str r3, [r5, #40]!