summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp100
1 files changed, 84 insertions, 16 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
index 0f5e297af4d..b6258907ca6 100644
--- a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
@@ -57,6 +57,10 @@ static cl::opt<bool> DisablePacketizer("disable-packetizer", cl::Hidden,
cl::ZeroOrMore, cl::init(false),
cl::desc("Disable Hexagon packetizer pass"));
+cl::opt<bool> Slot1Store("slot1-store-slot0-load", cl::Hidden,
+ cl::ZeroOrMore, cl::init(true),
+ cl::desc("Allow slot1 store and slot0 load"));
+
static cl::opt<bool> PacketizeVolatiles("hexagon-packetize-volatiles",
cl::ZeroOrMore, cl::Hidden, cl::init(true),
cl::desc("Allow non-solo packetization of volatile memory references"));
@@ -1050,6 +1054,10 @@ bool HexagonPacketizerList::ignorePseudoInstruction(const MachineInstr &MI,
}
bool HexagonPacketizerList::isSoloInstruction(const MachineInstr &MI) {
+ // Ensure any bundles created by gather packetize remain seperate.
+ if (MI.isBundle())
+ return true;
+
if (MI.isEHLabel() || MI.isCFIInstruction())
return true;
@@ -1099,11 +1107,12 @@ static bool cannotCoexistAsymm(const MachineInstr &MI, const MachineInstr &MJ,
MJ.isCall() || MJ.isTerminator();
switch (MI.getOpcode()) {
- case (Hexagon::S2_storew_locked):
- case (Hexagon::S4_stored_locked):
- case (Hexagon::L2_loadw_locked):
- case (Hexagon::L4_loadd_locked):
- case (Hexagon::Y4_l2fetch): {
+ case Hexagon::S2_storew_locked:
+ case Hexagon::S4_stored_locked:
+ case Hexagon::L2_loadw_locked:
+ case Hexagon::L4_loadd_locked:
+ case Hexagon::Y4_l2fetch:
+ case Hexagon::Y5_l2fetch: {
// These instructions can only be grouped with ALU32 or non-floating-point
// XTYPE instructions. Since there is no convenient way of identifying fp
// XTYPE instructions, only allow grouping with ALU32 for now.
@@ -1166,6 +1175,8 @@ static bool isSystemInstr(const MachineInstr &MI) {
switch (Opc) {
case Hexagon::Y2_barrier:
case Hexagon::Y2_dcfetchbo:
+ case Hexagon::Y4_l2fetch:
+ case Hexagon::Y5_l2fetch:
return true;
}
return false;
@@ -1496,19 +1507,33 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
// J is first, I is second.
bool LoadJ = J.mayLoad(), StoreJ = J.mayStore();
bool LoadI = I.mayLoad(), StoreI = I.mayStore();
- if (StoreJ) {
- // Two stores are only allowed on V4+. Load following store is never
- // allowed.
- if (LoadI && alias(J, I)) {
+ bool NVStoreJ = HII->isNewValueStore(J);
+ bool NVStoreI = HII->isNewValueStore(I);
+ bool IsVecJ = HII->isHVXVec(J);
+ bool IsVecI = HII->isHVXVec(I);
+
+ if (Slot1Store && MF.getSubtarget<HexagonSubtarget>().hasV65TOps() &&
+ ((LoadJ && StoreI && !NVStoreI) ||
+ (StoreJ && LoadI && !NVStoreJ)) &&
+ (J.getOpcode() != Hexagon::S2_allocframe &&
+ I.getOpcode() != Hexagon::S2_allocframe) &&
+ (J.getOpcode() != Hexagon::L2_deallocframe &&
+ I.getOpcode() != Hexagon::L2_deallocframe) &&
+ (!HII->isMemOp(J) && !HII->isMemOp(I)) && (!IsVecJ && !IsVecI))
+ setmemShufDisabled(true);
+ else
+ if (StoreJ && LoadI && alias(J, I)) {
+ FoundSequentialDependence = true;
+ break;
+ }
+
+ if (!StoreJ)
+ if (!LoadJ || (!LoadI && !StoreI)) {
+ // If J is neither load nor store, assume a dependency.
+ // If J is a load, but I is neither, also assume a dependency.
FoundSequentialDependence = true;
break;
}
- } else if (!LoadJ || (!LoadI && !StoreI)) {
- // If J is neither load nor store, assume a dependency.
- // If J is a load, but I is neither, also assume a dependency.
- FoundSequentialDependence = true;
- break;
- }
// Store followed by store: not OK on V2.
// Store followed by load: not OK on all.
// Load followed by store: OK on all.
@@ -1628,6 +1653,26 @@ bool HexagonPacketizerList::isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) {
return false;
}
+
+bool HexagonPacketizerList::foundLSInPacket() {
+ bool FoundLoad = false;
+ bool FoundStore = false;
+
+ for (auto MJ : CurrentPacketMIs) {
+ unsigned Opc = MJ->getOpcode();
+ if (Opc == Hexagon::S2_allocframe || Opc == Hexagon::L2_deallocframe)
+ continue;
+ if (HII->isMemOp(*MJ))
+ continue;
+ if (MJ->mayLoad())
+ FoundLoad = true;
+ if (MJ->mayStore() && !HII->isNewValueStore(*MJ))
+ FoundStore = true;
+ }
+ return FoundLoad && FoundStore;
+}
+
+
MachineBasicBlock::iterator
HexagonPacketizerList::addToPacket(MachineInstr &MI) {
MachineBasicBlock::iterator MII = MI.getIterator();
@@ -1703,8 +1748,31 @@ HexagonPacketizerList::addToPacket(MachineInstr &MI) {
void HexagonPacketizerList::endPacket(MachineBasicBlock *MBB,
MachineBasicBlock::iterator MI) {
+ // Replace VLIWPacketizerList::endPacket(MBB, MI).
+
+ bool memShufDisabled = getmemShufDisabled();
+ if (memShufDisabled && !foundLSInPacket()) {
+ setmemShufDisabled(false);
+ DEBUG(dbgs() << " Not added to NoShufPacket\n");
+ }
+ memShufDisabled = getmemShufDisabled();
+
+ if (CurrentPacketMIs.size() > 1) {
+ MachineBasicBlock::instr_iterator FirstMI(CurrentPacketMIs.front());
+ MachineBasicBlock::instr_iterator LastMI(MI.getInstrIterator());
+ finalizeBundle(*MBB, FirstMI, LastMI);
+
+ auto BundleMII = std::prev(FirstMI);
+ if (memShufDisabled)
+ HII->setBundleNoShuf(BundleMII);
+
+ setmemShufDisabled(false);
+ }
OldPacketMIs = CurrentPacketMIs;
- VLIWPacketizerList::endPacket(MBB, MI);
+ CurrentPacketMIs.clear();
+
+ ResourceTracker->clearResources();
+ DEBUG(dbgs() << "End packet\n");
}
bool HexagonPacketizerList::shouldAddToPacket(const MachineInstr &MI) {
OpenPOWER on IntegriCloud