]> granicus.if.org Git - llvm/commitdiff
[ARM][LowOverheadLoops] Use subs during revert.
authorSam Parker <sam.parker@arm.com>
Mon, 23 Sep 2019 08:57:50 +0000 (08:57 +0000)
committerSam Parker <sam.parker@arm.com>
Mon, 23 Sep 2019 08:57:50 +0000 (08:57 +0000)
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

lib/Target/ARM/ARMLowOverheadLoops.cpp
test/CodeGen/Thumb2/LowOverheadLoops/branch-targets.ll
test/CodeGen/Thumb2/LowOverheadLoops/end-positive-offset.mir
test/CodeGen/Thumb2/LowOverheadLoops/revert-non-header.mir
test/CodeGen/Thumb2/LowOverheadLoops/revert-while.mir

index c1aa21520a44ebf78e26c87b197320cc792c365b..e1c5a9c3e223b2f3a9591eb4bf84a7d243b3c712 100644 (file)
@@ -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);
index c36845b5f26b5f5a983614c919ae84e716cacaf2..a0f13f3af65e21b27cdcb874b20d3bb19ca1a1c8 100644 (file)
@@ -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:
index 259a4c9a7f7b63c0eda9dc5b0ef817df5400eb1d..8fa138a6d987e662f6a35311d0f4715113252919 100644 (file)
@@ -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:
 
index 0d48a4a858c0ee45b9fba1e41d88c28ed63b0206..3837542c2b140180337f86c2f096544bfaa8ad8a 100644 (file)
@@ -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:
 
 --- |
index 9e0944afbc036ee5edebf0838d69403a887f47e1..6e9dcaf3827cc2d80f6fa0dc1994f54bdd3a8369 100644 (file)
@@ -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