]> granicus.if.org Git - llvm/commitdiff
[Hexagon] Be careful about anti-dependencies with a call in packetizer
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>
Fri, 6 May 2016 19:13:38 +0000 (19:13 +0000)
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>
Fri, 6 May 2016 19:13:38 +0000 (19:13 +0000)
In a case like
  J2_callr <ga:@foo>, %R0<imp-use>, ...
  R0<def> = ...
the anti-dependency on R0 cannot be ignored and the two instructions
cannot be packetized together, since if they were, the assignment to
R0 would take place before the call.

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

lib/Target/Hexagon/HexagonVLIWPacketizer.cpp

index 4630c98b46fedeeaf560432b98d665a1464f9293..b4a5d2a48766213462e42598ff1bdd1ee75d57e5 100644 (file)
@@ -1402,8 +1402,30 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
       }
     }
 
-    // Skip over anti-dependences. Two instructions that are anti-dependent
-    // can share a packet.
+    // There are certain anti-dependencies that cannot be ignored.
+    // Specifically:
+    //   J2_call ... %R0<imp-def>   ; SUJ
+    //   R0 = ...                   ; SUI
+    // Those cannot be packetized together, since the call will observe
+    // the effect of the assignment to R0.
+    if (DepType == SDep::Anti && J->isCall()) {
+      // Check if I defines any volatile register. We should also check
+      // registers that the call may read, but these happen to be a
+      // subset of the volatile register set.
+      for (const MCPhysReg *P = J->getDesc().ImplicitDefs; P && *P; ++P) {
+        if (!I->modifiesRegister(*P, HRI))
+          continue;
+        FoundSequentialDependence = true;
+        break;
+      }
+    }
+
+    // Skip over remaining anti-dependences. Two instructions that are
+    // anti-dependent can share a packet, since in most such cases all
+    // operands are read before any modifications take place.
+    // The exceptions are branch and call instructions, since they are
+    // executed after all other instructions have completed (at least
+    // conceptually).
     if (DepType != SDep::Anti) {
       FoundSequentialDependence = true;
       break;