OSDN Git Service

[Hexagon] Allow redefinition with immediates for hw loop conversion
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>
Fri, 20 Oct 2017 16:56:33 +0000 (16:56 +0000)
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>
Fri, 20 Oct 2017 16:56:33 +0000 (16:56 +0000)
Normally, if the registers holding the induction variable's bounds
are redefined inside of the loop's body, the loop cannot be converted
to a hardware loop. However, if the redefining instruction is actually
loading an immediate value into the register, this conversion is both
possible and legal (since the immediate itself will be used in the
loop setup in the preheader).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316218 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Hexagon/HexagonHardwareLoops.cpp
lib/Target/Hexagon/HexagonTargetMachine.cpp
test/CodeGen/Hexagon/hwloop-redef-imm.mir [new file with mode: 0644]

index d504bf8..d01ff01 100644 (file)
@@ -111,9 +111,7 @@ namespace {
   public:
     static char ID;
 
-    HexagonHardwareLoops() : MachineFunctionPass(ID) {
-      initializeHexagonHardwareLoopsPass(*PassRegistry::getPassRegistry());
-    }
+    HexagonHardwareLoops() : MachineFunctionPass(ID) {}
 
     bool runOnMachineFunction(MachineFunction &MF) override;
 
@@ -685,15 +683,21 @@ CountValue *HexagonHardwareLoops::getLoopTripCount(MachineLoop *L,
   if (InitialValue->isReg()) {
     unsigned R = InitialValue->getReg();
     MachineBasicBlock *DefBB = MRI->getVRegDef(R)->getParent();
-    if (!MDT->properlyDominates(DefBB, Header))
-      return nullptr;
+    if (!MDT->properlyDominates(DefBB, Header)) {
+      int64_t V;
+      if (!checkForImmediate(*InitialValue, V))
+        return nullptr;
+    }
     OldInsts.push_back(MRI->getVRegDef(R));
   }
   if (EndValue->isReg()) {
     unsigned R = EndValue->getReg();
     MachineBasicBlock *DefBB = MRI->getVRegDef(R)->getParent();
-    if (!MDT->properlyDominates(DefBB, Header))
-      return nullptr;
+    if (!MDT->properlyDominates(DefBB, Header)) {
+      int64_t V;
+      if (!checkForImmediate(*EndValue, V))
+        return nullptr;
+    }
     OldInsts.push_back(MRI->getVRegDef(R));
   }
 
index 6d7518a..a66e212 100644 (file)
@@ -126,6 +126,7 @@ namespace llvm {
   void initializeHexagonEarlyIfConversionPass(PassRegistry&);
   void initializeHexagonExpandCondsetsPass(PassRegistry&);
   void initializeHexagonGenMuxPass(PassRegistry&);
+  void initializeHexagonHardwareLoopsPass(PassRegistry&);
   void initializeHexagonLoopIdiomRecognizePass(PassRegistry&);
   void initializeHexagonVectorLoopCarriedReusePass(PassRegistry&);
   void initializeHexagonNewValueJumpPass(PassRegistry&);
@@ -184,6 +185,7 @@ extern "C" void LLVMInitializeHexagonTarget() {
   initializeHexagonConstExtendersPass(PR);
   initializeHexagonEarlyIfConversionPass(PR);
   initializeHexagonGenMuxPass(PR);
+  initializeHexagonHardwareLoopsPass(PR);
   initializeHexagonLoopIdiomRecognizePass(PR);
   initializeHexagonVectorLoopCarriedReusePass(PR);
   initializeHexagonNewValueJumpPass(PR);
diff --git a/test/CodeGen/Hexagon/hwloop-redef-imm.mir b/test/CodeGen/Hexagon/hwloop-redef-imm.mir
new file mode 100644 (file)
index 0000000..d1bb1ef
--- /dev/null
@@ -0,0 +1,63 @@
+# RUN: llc -march=hexagon -run-pass hwloops %s -o - | FileCheck %s
+
+# Normally, if the registers holding the induction variable's bounds
+# are redefined inside of the loop's body, the loop cannot be converted
+# to a hardware loop. However, if the redefining instruction is actually
+# loading an immediate value into the register, this conversion is both
+# possible and legal (since the immediate itself will be used in the
+# loop setup in the preheader).
+
+# CHECK:  [[R0:%[0-9]+]] = A2_tfrsi 1920
+# CHECK:  J2_loop0r %bb.1.b1, [[R0]]
+#
+# CHECK: bb.1.b1 (address-taken):
+# CHECK:   ENDLOOP0 %bb.1.b1
+
+
+--- |
+  define void @fred() {
+  b0:
+    br label %b1
+  b1:
+    br label %b2
+  b2:
+    ret void
+  }
+...
+
+---
+name: fred
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: intregs }
+  - { id: 1, class: intregs }
+  - { id: 2, class: intregs }
+  - { id: 3, class: intregs }
+  - { id: 4, class: intregs }
+  - { id: 5, class: intregs }
+  - { id: 6, class: intregs }
+  - { id: 7, class: intregs }
+  - { id: 8, class: predregs }
+body: |
+  bb.0.b0:
+    liveins: %r0
+    successors: %bb.1
+    %0 = A2_tfrsi 0
+    %1 = A2_tfrsi 0
+    %2 = COPY %r0
+
+  bb.1.b1:
+    successors: %bb.1, %bb.2
+    %3 = PHI %0, %bb.0, %6, %bb.1
+    %4 = PHI %1, %bb.0, %5, %bb.1
+    S4_storerh_rr %2, %4, 0, %3
+    %5 = A2_addi %4, 2
+    %6 = A2_addi %3, 1
+    ; This definition of %7 should not prevent conversion to hardware loop.
+    %7 = A2_tfrsi 3840
+    %8 = C2_cmpeq %5, %7
+    J2_jumpf %8, %bb.1, implicit-def %pc
+    J2_jump %bb.2, implicit-def %pc
+
+  bb.2.b2:
+...