// 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
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) {
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;
}
--- /dev/null
+# 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)
+...
+