Эх сурвалжийг харах

[Packetizer] Add function to check for aliasing between instructions

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316243 91177308-0d34-0410-b5e6-96231b3b80d8
Krzysztof Parzyszek 7 жил өмнө
parent
commit
26843fd82c

+ 7 - 0
include/llvm/CodeGen/DFAPacketizer.h

@@ -208,6 +208,13 @@ public:
 
 
   // Add a DAG mutation to be done before the packetization begins.
   // Add a DAG mutation to be done before the packetization begins.
   void addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation);
   void addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation);
+
+  bool alias(const MachineInstr &MI1, const MachineInstr &MI2,
+             bool UseTBAA = true) const;
+
+private:
+  bool alias(const MachineMemOperand &Op1, const MachineMemOperand &Op2,
+             bool UseTBAA = true) const;
 };
 };
 
 
 } // end namespace llvm
 } // end namespace llvm

+ 32 - 0
lib/CodeGen/DFAPacketizer.cpp

@@ -336,6 +336,38 @@ void VLIWPacketizerList::PacketizeMIs(MachineBasicBlock *MBB,
   VLIWScheduler->finishBlock();
   VLIWScheduler->finishBlock();
 }
 }
 
 
+bool VLIWPacketizerList::alias(const MachineMemOperand &Op1,
+                               const MachineMemOperand &Op2,
+                               bool UseTBAA) const {
+  if (!Op1.getValue() || !Op2.getValue())
+    return true;
+
+  int64_t MinOffset = std::min(Op1.getOffset(), Op2.getOffset());
+  int64_t Overlapa = Op1.getSize() + Op1.getOffset() - MinOffset;
+  int64_t Overlapb = Op2.getSize() + Op2.getOffset() - MinOffset;
+
+  AliasResult AAResult =
+      AA->alias(MemoryLocation(Op1.getValue(), Overlapa,
+                               UseTBAA ? Op1.getAAInfo() : AAMDNodes()),
+                MemoryLocation(Op2.getValue(), Overlapb,
+                               UseTBAA ? Op2.getAAInfo() : AAMDNodes()));
+
+  return AAResult != NoAlias;
+}
+
+bool VLIWPacketizerList::alias(const MachineInstr &MI1,
+                               const MachineInstr &MI2,
+                               bool UseTBAA) const {
+  if (MI1.memoperands_empty() || MI2.memoperands_empty())
+    return true;
+
+  for (const MachineMemOperand *Op1 : MI1.memoperands())
+    for (const MachineMemOperand *Op2 : MI2.memoperands())
+      if (alias(*Op1, *Op2, UseTBAA))
+        return true;
+  return false;
+}
+
 // Add a DAG mutation object to the ordered list.
 // Add a DAG mutation object to the ordered list.
 void VLIWPacketizerList::addMutation(
 void VLIWPacketizerList::addMutation(
       std::unique_ptr<ScheduleDAGMutation> Mutation) {
       std::unique_ptr<ScheduleDAGMutation> Mutation) {

+ 1 - 1
lib/Target/Hexagon/HexagonVLIWPacketizer.cpp

@@ -1499,7 +1499,7 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
       if (StoreJ) {
       if (StoreJ) {
         // Two stores are only allowed on V4+. Load following store is never
         // Two stores are only allowed on V4+. Load following store is never
         // allowed.
         // allowed.
-        if (LoadI) {
+        if (LoadI && alias(J, I)) {
           FoundSequentialDependence = true;
           FoundSequentialDependence = true;
           break;
           break;
         }
         }

+ 41 - 0
test/CodeGen/Hexagon/packetize-load-store-aliasing.mir

@@ -0,0 +1,41 @@
+# RUN: llc -march=hexagon -mcpu=hexagonv60 -run-pass hexagon-packetizer %s -o - | FileCheck %s
+
+# Check that a store can be packetized with a load that happens later
+# if these instructions are not aliased (the load will actually execute
+# first).
+# CHECK-LABEL: name: danny
+# CHECK: BUNDLE
+
+---
+name: danny
+tracksRegLiveness: true
+stack:
+  - { id: 0, type: default, size: 4, alignment: 4 }
+  - { id: 1, type: default, size: 4, alignment: 4 }
+body: |
+  bb.0:
+    liveins: %r0
+    S2_storeri_io %r29, 0, %r0 :: (store 4 into %stack.0)
+    %r1 = L2_loadri_io %r29, 4 :: (load 4 from %stack.1)
+...
+
+
+# Check that a store cannot be packetized with a load that happens later
+# if these instructions are aliased.
+# CHECK-LABEL: name: sammy
+# CHECK-NOT: BUNDLE
+# CHECK: S2_storeri_io %r29, 0, %r0
+# CHECK: %r1 = L2_loadri_io %r29, 0
+
+---
+name: sammy
+tracksRegLiveness: true
+stack:
+  - { id: 0, type: default, size: 4, alignment: 4 }
+body: |
+  bb.0:
+    liveins: %r0
+    S2_storeri_io %r29, 0, %r0 :: (store 4 into %stack.0)
+    %r1 = L2_loadri_io %r29, 0 :: (load 4 from %stack.0)
+...
+