summaryrefslogtreecommitdiff
path: root/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Hexagon/HexagonVLIWPacketizer.cpp')
-rw-r--r--lib/Target/Hexagon/HexagonVLIWPacketizer.cpp86
1 files changed, 48 insertions, 38 deletions
diff --git a/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
index 56ab69db9bd1a..722699907ca04 100644
--- a/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
+++ b/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
@@ -77,7 +77,7 @@ extern cl::opt<bool> ScheduleInlineAsm;
namespace llvm {
-FunctionPass *createHexagonPacketizer();
+FunctionPass *createHexagonPacketizer(bool Minimal);
void initializeHexagonPacketizerPass(PassRegistry&);
} // end namespace llvm
@@ -88,7 +88,8 @@ namespace {
public:
static char ID;
- HexagonPacketizer() : MachineFunctionPass(ID) {}
+ HexagonPacketizer(bool Min = false)
+ : MachineFunctionPass(ID), Minimal(Min) {}
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesCFG();
@@ -112,6 +113,7 @@ namespace {
private:
const HexagonInstrInfo *HII;
const HexagonRegisterInfo *HRI;
+ const bool Minimal;
};
} // end anonymous namespace
@@ -129,8 +131,9 @@ INITIALIZE_PASS_END(HexagonPacketizer, "hexagon-packetizer",
HexagonPacketizerList::HexagonPacketizerList(MachineFunction &MF,
MachineLoopInfo &MLI, AliasAnalysis *AA,
- const MachineBranchProbabilityInfo *MBPI)
- : VLIWPacketizerList(MF, MLI, AA), MBPI(MBPI), MLI(&MLI) {
+ const MachineBranchProbabilityInfo *MBPI, bool Minimal)
+ : VLIWPacketizerList(MF, MLI, AA), MBPI(MBPI), MLI(&MLI),
+ Minimal(Minimal) {
HII = MF.getSubtarget<HexagonSubtarget>().getInstrInfo();
HRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
@@ -200,9 +203,6 @@ static MachineBasicBlock::iterator moveInstrOut(MachineInstr &MI,
bool HexagonPacketizer::runOnMachineFunction(MachineFunction &MF) {
auto &HST = MF.getSubtarget<HexagonSubtarget>();
- if (DisablePacketizer || !HST.usePackets() || skipFunction(MF.getFunction()))
- return false;
-
HII = HST.getInstrInfo();
HRI = HST.getRegisterInfo();
auto &MLI = getAnalysis<MachineLoopInfo>();
@@ -213,7 +213,9 @@ bool HexagonPacketizer::runOnMachineFunction(MachineFunction &MF) {
HII->genAllInsnTimingClasses(MF);
// Instantiate the packetizer.
- HexagonPacketizerList Packetizer(MF, MLI, AA, MBPI);
+ bool MinOnly = Minimal || DisablePacketizer || !HST.usePackets() ||
+ skipFunction(MF.getFunction());
+ HexagonPacketizerList Packetizer(MF, MLI, AA, MBPI, MinOnly);
// DFA state table should not be empty.
assert(Packetizer.getResourceTracker() && "Empty DFA table!");
@@ -226,7 +228,7 @@ bool HexagonPacketizer::runOnMachineFunction(MachineFunction &MF) {
// Here, Insn 1 will result in the dependence graph not emitting an output
// dependence between Insn 0 and Insn 2. This can lead to incorrect
// packetization
- for (auto &MB : MF) {
+ for (MachineBasicBlock &MB : MF) {
auto End = MB.end();
auto MI = MB.begin();
while (MI != End) {
@@ -766,7 +768,7 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr &MI,
// Make sure that for non-POST_INC stores:
// 1. The only use of reg is DepReg and no other registers.
- // This handles V4 base+index registers.
+ // This handles base+index registers.
// The following store can not be dot new.
// Eg. r0 = add(r0, #3)
// memw(r1+r0<<#2) = r0
@@ -836,11 +838,7 @@ static bool isImplicitDependency(const MachineInstr &I, bool CheckDef,
return false;
}
-// Check to see if an instruction can be dot new
-// There are three kinds.
-// 1. dot new on predicate - V2/V3/V4
-// 2. dot new on stores NV/ST - V4
-// 3. dot new on jump NV/J - V4 -- This is generated in a pass.
+// Check to see if an instruction can be dot new.
bool HexagonPacketizerList::canPromoteToDotNew(const MachineInstr &MI,
const SUnit *PacketSU, unsigned DepReg, MachineBasicBlock::iterator &MII,
const TargetRegisterClass* RC) {
@@ -1073,9 +1071,6 @@ bool HexagonPacketizerList::isSoloInstruction(const MachineInstr &MI) {
if (MI.isInlineAsm() && !ScheduleInlineAsm)
return true;
- // From Hexagon V4 Programmer's Reference Manual 3.4.4 Grouping constraints:
- // trap, pause, barrier, icinva, isync, and syncht are solo instructions.
- // They must not be grouped with other instructions in a packet.
if (isSchedBarrier(MI))
return true;
@@ -1110,6 +1105,10 @@ static bool cannotCoexistAsymm(const MachineInstr &MI, const MachineInstr &MJ,
return MJ.isInlineAsm() || MJ.isBranch() || MJ.isBarrier() ||
MJ.isCall() || MJ.isTerminator();
+ // New-value stores cannot coexist with any other stores.
+ if (HII.isNewValueStore(MI) && MJ.mayStore())
+ return true;
+
switch (MI.getOpcode()) {
case Hexagon::S2_storew_locked:
case Hexagon::S4_stored_locked:
@@ -1283,8 +1282,8 @@ bool HexagonPacketizerList::hasRegMaskDependence(const MachineInstr &I,
return false;
}
-bool HexagonPacketizerList::hasV4SpecificDependence(const MachineInstr &I,
- const MachineInstr &J) {
+bool HexagonPacketizerList::hasDualStoreDependence(const MachineInstr &I,
+ const MachineInstr &J) {
bool SysI = isSystemInstr(I), SysJ = isSystemInstr(J);
bool StoreI = I.mayStore(), StoreJ = J.mayStore();
if ((SysI && StoreJ) || (SysJ && StoreI))
@@ -1337,10 +1336,10 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
if (Dependence)
return false;
- // V4 allows dual stores. It does not allow second store, if the first
- // store is not in SLOT0. New value store, new value jump, dealloc_return
- // and memop always take SLOT0. Arch spec 3.4.4.2.
- Dependence = hasV4SpecificDependence(I, J);
+ // Dual-store does not allow second store, if the first store is not
+ // in SLOT0. New value store, new value jump, dealloc_return and memop
+ // always take SLOT0. Arch spec 3.4.4.2.
+ Dependence = hasDualStoreDependence(I, J);
if (Dependence)
return false;
@@ -1499,10 +1498,10 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
}
// For Order dependences:
- // 1. On V4 or later, volatile loads/stores can be packetized together,
- // unless other rules prevent is.
+ // 1. Volatile loads/stores can be packetized together, unless other
+ // rules prevent is.
// 2. Store followed by a load is not allowed.
- // 3. Store followed by a store is only valid on V4 or later.
+ // 3. Store followed by a store is valid.
// 4. Load followed by any memory operation is allowed.
if (DepType == SDep::Order) {
if (!PacketizeVolatiles) {
@@ -1549,7 +1548,7 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
continue;
}
- // For V4, special case ALLOCFRAME. Even though there is dependency
+ // Special case for ALLOCFRAME: even though there is dependency
// between ALLOCFRAME and subsequent store, allow it to be packetized
// in a same packet. This implies that the store is using the caller's
// SP. Hence, offset needs to be updated accordingly.
@@ -1569,6 +1568,7 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
if (GlueAllocframeStore)
continue;
}
+ break;
default:
break;
}
@@ -1652,6 +1652,9 @@ bool HexagonPacketizerList::isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) {
return false;
}
+ if (!Coexist)
+ return false;
+
if (ChangedOffset == INT64_MAX && updateOffset(SUI, SUJ)) {
FoundSequentialDependence = false;
Dependence = false;
@@ -1759,8 +1762,8 @@ HexagonPacketizerList::addToPacket(MachineInstr &MI) {
}
void HexagonPacketizerList::endPacket(MachineBasicBlock *MBB,
- MachineBasicBlock::iterator MI) {
- // Replace VLIWPacketizerList::endPacket(MBB, MI).
+ MachineBasicBlock::iterator EndMI) {
+ // Replace VLIWPacketizerList::endPacket(MBB, EndMI).
bool memShufDisabled = getmemShufDisabled();
if (memShufDisabled && !foundLSInPacket()) {
@@ -1769,25 +1772,32 @@ void HexagonPacketizerList::endPacket(MachineBasicBlock *MBB,
}
memShufDisabled = getmemShufDisabled();
- if (CurrentPacketMIs.size() > 1) {
- MachineBasicBlock::instr_iterator FirstMI(CurrentPacketMIs.front());
- MachineBasicBlock::instr_iterator LastMI(MI.getInstrIterator());
- finalizeBundle(*MBB, FirstMI, LastMI);
+ OldPacketMIs.clear();
+ for (MachineInstr *MI : CurrentPacketMIs) {
+ MachineBasicBlock::instr_iterator NextMI = std::next(MI->getIterator());
+ for (auto &I : make_range(HII->expandVGatherPseudo(*MI), NextMI))
+ OldPacketMIs.push_back(&I);
+ }
+ CurrentPacketMIs.clear();
+ if (OldPacketMIs.size() > 1) {
+ MachineBasicBlock::instr_iterator FirstMI(OldPacketMIs.front());
+ MachineBasicBlock::instr_iterator LastMI(EndMI.getInstrIterator());
+ finalizeBundle(*MBB, FirstMI, LastMI);
auto BundleMII = std::prev(FirstMI);
if (memShufDisabled)
HII->setBundleNoShuf(BundleMII);
setmemShufDisabled(false);
}
- OldPacketMIs = CurrentPacketMIs;
- CurrentPacketMIs.clear();
ResourceTracker->clearResources();
LLVM_DEBUG(dbgs() << "End packet\n");
}
bool HexagonPacketizerList::shouldAddToPacket(const MachineInstr &MI) {
+ if (Minimal)
+ return false;
return !producesStall(MI);
}
@@ -1860,6 +1870,6 @@ bool HexagonPacketizerList::producesStall(const MachineInstr &I) {
// Public Constructor Functions
//===----------------------------------------------------------------------===//
-FunctionPass *llvm::createHexagonPacketizer() {
- return new HexagonPacketizer();
+FunctionPass *llvm::createHexagonPacketizer(bool Minimal) {
+ return new HexagonPacketizer(Minimal);
}