From: Sam Parker Date: Mon, 23 Sep 2019 08:57:50 +0000 (+0000) Subject: [ARM][LowOverheadLoops] Use subs during revert. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b80c6924248a94d172eee847d9c5739e77650126;p=llvm [ARM][LowOverheadLoops] Use subs during revert. Check whether there are any uses or defs between the LoopDec and LoopEnd. If there's not, then we can use a subs to set the cpsr and skip generating a cmp. Differential Revision: https://reviews.llvm.org/D67801 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@372560 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMLowOverheadLoops.cpp b/lib/Target/ARM/ARMLowOverheadLoops.cpp index c1aa21520a4..e1c5a9c3e22 100644 --- a/lib/Target/ARM/ARMLowOverheadLoops.cpp +++ b/lib/Target/ARM/ARMLowOverheadLoops.cpp @@ -70,9 +70,9 @@ namespace { void RevertWhile(MachineInstr *MI) const; - void RevertLoopDec(MachineInstr *MI) const; + bool RevertLoopDec(MachineInstr *MI, bool AllowFlags = false) const; - void RevertLoopEnd(MachineInstr *MI) const; + void RevertLoopEnd(MachineInstr *MI, bool SkipCmp = false) const; void Expand(MachineLoop *ML, MachineInstr *Start, MachineInstr *InsertPt, MachineInstr *Dec, @@ -377,10 +377,21 @@ void ARMLowOverheadLoops::RevertWhile(MachineInstr *MI) const { MI->eraseFromParent(); } -// TODO: Check flags so that we can possibly generate a tSubs or tSub. -void ARMLowOverheadLoops::RevertLoopDec(MachineInstr *MI) const { +bool ARMLowOverheadLoops::RevertLoopDec(MachineInstr *MI, + bool AllowFlags) const { LLVM_DEBUG(dbgs() << "ARM Loops: Reverting to sub: " << *MI); MachineBasicBlock *MBB = MI->getParent(); + + // If nothing uses or defines CPSR between LoopDec and LoopEnd, use a t2SUBS. + bool SetFlags = false; + if (AllowFlags) { + if (auto *Def = SearchForDef(MI, MBB->end(), ARM::CPSR)) { + if (!SearchForUse(MI, MBB->end(), ARM::CPSR) && + Def->getOpcode() == ARM::t2LoopEnd) + SetFlags = true; + } + } + MachineInstrBuilder MIB = BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2SUBri)); MIB.addDef(ARM::LR); @@ -388,29 +399,39 @@ void ARMLowOverheadLoops::RevertLoopDec(MachineInstr *MI) const { MIB.add(MI->getOperand(2)); MIB.addImm(ARMCC::AL); MIB.addReg(0); - MIB.addReg(0); + + if (SetFlags) { + MIB.addReg(ARM::CPSR); + MIB->getOperand(5).setIsDef(true); + } else + MIB.addReg(0); + MI->eraseFromParent(); + return SetFlags; } // Generate a subs, or sub and cmp, and a branch instead of an LE. -void ARMLowOverheadLoops::RevertLoopEnd(MachineInstr *MI) const { +void ARMLowOverheadLoops::RevertLoopEnd(MachineInstr *MI, bool SkipCmp) const { LLVM_DEBUG(dbgs() << "ARM Loops: Reverting to cmp, br: " << *MI); - // Create cmp MachineBasicBlock *MBB = MI->getParent(); - MachineInstrBuilder MIB = BuildMI(*MBB, MI, MI->getDebugLoc(), - TII->get(ARM::t2CMPri)); - MIB.addReg(ARM::LR); - MIB.addImm(0); - MIB.addImm(ARMCC::AL); - MIB.addReg(ARM::NoRegister); + // Create cmp + if (!SkipCmp) { + MachineInstrBuilder MIB = BuildMI(*MBB, MI, MI->getDebugLoc(), + TII->get(ARM::t2CMPri)); + MIB.addReg(ARM::LR); + MIB.addImm(0); + MIB.addImm(ARMCC::AL); + MIB.addReg(ARM::NoRegister); + } MachineBasicBlock *DestBB = MI->getOperand(1).getMBB(); unsigned BrOpc = BBUtils->isBBInRange(MI, DestBB, 254) ? ARM::tBcc : ARM::t2Bcc; // Create bne - MIB = BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(BrOpc)); + MachineInstrBuilder MIB = + BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(BrOpc)); MIB.add(MI->getOperand(1)); // branch target MIB.addImm(ARMCC::NE); // condition code MIB.addReg(ARM::CPSR); @@ -480,8 +501,8 @@ void ARMLowOverheadLoops::Expand(MachineLoop *ML, MachineInstr *Start, RevertWhile(Start); else Start->eraseFromParent(); - RevertLoopDec(Dec); - RevertLoopEnd(End); + bool FlagsAlreadySet = RevertLoopDec(Dec, true); + RevertLoopEnd(End, FlagsAlreadySet); } else { Start = ExpandLoopStart(ML, Start, InsertPt); RemoveDeadBranch(Start); diff --git a/test/CodeGen/Thumb2/LowOverheadLoops/branch-targets.ll b/test/CodeGen/Thumb2/LowOverheadLoops/branch-targets.ll index c36845b5f26..a0f13f3af65 100644 --- a/test/CodeGen/Thumb2/LowOverheadLoops/branch-targets.ll +++ b/test/CodeGen/Thumb2/LowOverheadLoops/branch-targets.ll @@ -14,8 +14,7 @@ ; CHECK-END: .LBB0_1: ; CHECK-END: b .LBB0_3 ; CHECK-END: .LBB0_2: -; CHECK-END: sub.w lr, lr, #1 -; CHECK-END: cmp.w lr, #0 +; CHECK-END: subs.w lr, lr, #1 ; CHECK-END: bne .LBB0_3 ; CHECK-END: b .LBB0_4 ; CHECK-END: .LBB0_3: diff --git a/test/CodeGen/Thumb2/LowOverheadLoops/end-positive-offset.mir b/test/CodeGen/Thumb2/LowOverheadLoops/end-positive-offset.mir index 259a4c9a7f7..8fa138a6d98 100644 --- a/test/CodeGen/Thumb2/LowOverheadLoops/end-positive-offset.mir +++ b/test/CodeGen/Thumb2/LowOverheadLoops/end-positive-offset.mir @@ -3,9 +3,10 @@ # CHECK-NOT: DoLoopStart # CHECK-NOT: DLS # CHECK: bb.1.for.body: -# CHECK: t2CMPri $lr, 0, 14, $noreg, implicit-def $cpsr -# CHECK: tBcc %bb.3, 1, $cpsr -# CHECK: tB %bb.2, 14, $noreg +# CHECK: $lr = t2SUBri killed renamable $lr, 1, 14, $noreg, def $cpsr +# CHECK-NOT: t2CMPri $lr +# CHECK: tBcc %bb.3, 1, $cpsr +# CHECK: tB %bb.2, 14, $noreg # CHECK: bb.2.for.cond.cleanup: # CHECK: bb.3.for.header: diff --git a/test/CodeGen/Thumb2/LowOverheadLoops/revert-non-header.mir b/test/CodeGen/Thumb2/LowOverheadLoops/revert-non-header.mir index 0d48a4a858c..3837542c2b1 100644 --- a/test/CodeGen/Thumb2/LowOverheadLoops/revert-non-header.mir +++ b/test/CodeGen/Thumb2/LowOverheadLoops/revert-non-header.mir @@ -1,10 +1,10 @@ # RUN: llc -mtriple=thumbv8.1m.main -run-pass=arm-low-overhead-loops --verify-machineinstrs %s -o - | FileCheck %s # CHECK-NOT: t2DLS # CHECK: bb.5.for.inc16: -# CHECK: $lr = t2SUBri killed renamable $lr, 1, 14 -# CHECK: t2CMPri $lr, 0, 14 -# CHECK: tBcc %bb.6, 1 -# CHECK: tB %bb.2 +# CHECK: $lr = t2SUBri killed renamable $lr, 1, 14, $noreg, def $cpsr +# CHECK-NOT: t2CMPri $lr +# CHECK: tBcc %bb.6, 1 +# CHECK: tB %bb.2 # CHECK: bb.6.for.cond4.preheader: --- | diff --git a/test/CodeGen/Thumb2/LowOverheadLoops/revert-while.mir b/test/CodeGen/Thumb2/LowOverheadLoops/revert-while.mir index 9e0944afbc0..6e9dcaf3827 100644 --- a/test/CodeGen/Thumb2/LowOverheadLoops/revert-while.mir +++ b/test/CodeGen/Thumb2/LowOverheadLoops/revert-while.mir @@ -7,8 +7,7 @@ # CHECK: bb.1.do.body.preheader: # CHECK: $lr = tMOVr killed $r3 # CHECK: bb.2.do.body: -# CHECK: $lr = t2SUBri killed renamable $lr, 1, 14 -# CHECK-NEXT: t2CMPri $lr, 0, 14, $noreg, implicit-def $cpsr +# CHECK: $lr = t2SUBri killed renamable $lr, 1, 14, $noreg, def $cpsr # CHECK-NEXT: t2Bcc %bb.2, 1, $cpsr # CHECK-NEXT: tB %bb.3, 14