[Hexagon] Make sure that new-value jump is packetized with producer
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>
Wed, 11 Oct 2017 21:20:43 +0000 (21:20 +0000)
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>
Wed, 11 Oct 2017 21:20:43 +0000 (21:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315510 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
test/CodeGen/Hexagon/packetize-nvj-no-prune.mir [new file with mode: 0644]

index 2555b50f91cff2ca71afecfb113f806756ce7716..1bc8d45c3dc5e4b5ebc51b26cb2b2559f7bf7c8d 100644 (file)
@@ -1338,11 +1338,9 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
     if (NOp1.isReg() && I.getOperand(0).getReg() == NOp1.getReg())
       secondRegMatch = true;
 
-    for (auto T : CurrentPacketMIs) {
-      SUnit *PacketSU = MIToSUnit.find(T)->second;
-      MachineInstr &PI = *PacketSU->getInstr();
+    for (MachineInstr *PI : CurrentPacketMIs) {
       // NVJ can not be part of the dual jump - Arch Spec: section 7.8.
-      if (PI.isCall()) {
+      if (PI->isCall()) {
         Dependence = true;
         break;
       }
@@ -1354,22 +1352,22 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
       // 3. If the second operand of the nvj is newified, (which means
       //    first operand is also a reg), first reg is not defined in
       //    the same packet.
-      if (PI.getOpcode() == Hexagon::S2_allocframe || PI.mayStore() ||
-          HII->isLoopN(PI)) {
+      if (PI->getOpcode() == Hexagon::S2_allocframe || PI->mayStore() ||
+          HII->isLoopN(*PI)) {
         Dependence = true;
         break;
       }
       // Check #2/#3.
       const MachineOperand &OpR = secondRegMatch ? NOp0 : NOp1;
-      if (OpR.isReg() && PI.modifiesRegister(OpR.getReg(), HRI)) {
+      if (OpR.isReg() && PI->modifiesRegister(OpR.getReg(), HRI)) {
         Dependence = true;
         break;
       }
     }
 
+    GlueToNewValueJump = true;
     if (Dependence)
       return false;
-    GlueToNewValueJump = true;
   }
 
   // There no dependency between a prolog instruction and its successor.
@@ -1613,7 +1611,15 @@ bool HexagonPacketizerList::isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) {
 
   if (ChangedOffset != INT64_MAX)
     undoChangedOffset(I);
-  else if (updateOffset(SUI, SUJ)) {
+
+  if (GlueToNewValueJump) {
+    // Putting I and J together would prevent the new-value jump from being
+    // packetized with the producer. In that case I and J must be separated.
+    GlueToNewValueJump = false;
+    return false;
+  }
+
+  if (ChangedOffset == INT64_MAX && updateOffset(SUI, SUJ)) {
     FoundSequentialDependence = false;
     Dependence = false;
     return true;
diff --git a/test/CodeGen/Hexagon/packetize-nvj-no-prune.mir b/test/CodeGen/Hexagon/packetize-nvj-no-prune.mir
new file mode 100644 (file)
index 0000000..7047968
--- /dev/null
@@ -0,0 +1,31 @@
+# RUN: llc -march=hexagon -run-pass hexagon-packetizer %s -o - | FileCheck %s
+
+# Make sure that the new-value jump is packetized with the producer. In this
+# case, the loads cold be packetized together (with updating the offset in
+# the second load), but then the new-value jump would not be possible to
+# put in the same packet.
+
+# CHECK-LABEL: name: fred
+# CHECK: BUNDLE
+# CHECK-NEXT: %r3 = L2_loadri_io %r1, 0
+# CHECK-NEXT: J4_cmpgtu_f_jumpnv_t internal killed %r3
+
+
+--- |
+  define void @fred() { ret void }
+  @array = external global [256 x i32], align 8
+...
+
+---
+name: fred
+tracksRegLiveness: true
+body: |
+  bb.0:
+    successors: %bb.1
+    %r1 = A2_tfrsi @array
+    %r2, %r1 = L2_loadri_pi %r1, 4
+    %r3 = L2_loadri_io %r1, 0
+    J4_cmpgtu_f_jumpnv_t killed %r3, killed %r2, %bb.1, implicit-def %pc
+
+  bb.1:
+...