OSDN Git Service

[Packetizer] Add function to check for aliasing between instructions
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>
Fri, 20 Oct 2017 22:08:40 +0000 (22:08 +0000)
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>
Fri, 20 Oct 2017 22:08:40 +0000 (22:08 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316243 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/DFAPacketizer.h
lib/CodeGen/DFAPacketizer.cpp
lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
test/CodeGen/Hexagon/packetize-load-store-aliasing.mir [new file with mode: 0644]

index 77c37ac..d3aabe2 100644 (file)
@@ -208,6 +208,13 @@ public:
 
   // Add a DAG mutation to be done before the packetization begins.
   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
index 853b9af..cf21316 100644 (file)
@@ -336,6 +336,38 @@ void VLIWPacketizerList::PacketizeMIs(MachineBasicBlock *MBB,
   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.
 void VLIWPacketizerList::addMutation(
       std::unique_ptr<ScheduleDAGMutation> Mutation) {
index 1bc8d45..f43db53 100644 (file)
@@ -1499,7 +1499,7 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
       if (StoreJ) {
         // Two stores are only allowed on V4+. Load following store is never
         // allowed.
-        if (LoadI) {
+        if (LoadI && alias(J, I)) {
           FoundSequentialDependence = true;
           break;
         }
diff --git a/test/CodeGen/Hexagon/packetize-load-store-aliasing.mir b/test/CodeGen/Hexagon/packetize-load-store-aliasing.mir
new file mode 100644 (file)
index 0000000..03835d6
--- /dev/null
@@ -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)
+...
+