diff options
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp')
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp | 100 |
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) { |