summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp')
-rw-r--r--contrib/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp446
1 files changed, 250 insertions, 196 deletions
diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
index d326b94..7b1247d 100644
--- a/contrib/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
+++ b/contrib/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
@@ -22,7 +22,6 @@
#include "HexagonVLIWPacketizer.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/MachineDominators.h"
-#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
@@ -75,13 +74,11 @@ namespace {
AU.addPreserved<MachineLoopInfo>();
MachineFunctionPass::getAnalysisUsage(AU);
}
- const char *getPassName() const override {
- return "Hexagon Packetizer";
- }
+ StringRef getPassName() const override { return "Hexagon Packetizer"; }
bool runOnMachineFunction(MachineFunction &Fn) override;
MachineFunctionProperties getRequiredProperties() const override {
return MachineFunctionProperties().set(
- MachineFunctionProperties::Property::AllVRegsAllocated);
+ MachineFunctionProperties::Property::NoVRegs);
}
private:
@@ -101,7 +98,6 @@ INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_END(HexagonPacketizer, "packets", "Hexagon Packetizer",
false, false)
-
HexagonPacketizerList::HexagonPacketizerList(MachineFunction &MF,
MachineLoopInfo &MLI, AliasAnalysis *AA,
const MachineBranchProbabilityInfo *MBPI)
@@ -127,7 +123,7 @@ static bool hasWriteToReadDep(const MachineInstr &FirstI,
}
-static MachineBasicBlock::iterator moveInstrOut(MachineInstr *MI,
+static MachineBasicBlock::iterator moveInstrOut(MachineInstr &MI,
MachineBasicBlock::iterator BundleIt, bool Before) {
MachineBasicBlock::instr_iterator InsertPt;
if (Before)
@@ -135,20 +131,20 @@ static MachineBasicBlock::iterator moveInstrOut(MachineInstr *MI,
else
InsertPt = std::next(BundleIt).getInstrIterator();
- MachineBasicBlock &B = *MI->getParent();
+ MachineBasicBlock &B = *MI.getParent();
// The instruction should at least be bundled with the preceding instruction
// (there will always be one, i.e. BUNDLE, if nothing else).
- assert(MI->isBundledWithPred());
- if (MI->isBundledWithSucc()) {
- MI->clearFlag(MachineInstr::BundledSucc);
- MI->clearFlag(MachineInstr::BundledPred);
+ assert(MI.isBundledWithPred());
+ if (MI.isBundledWithSucc()) {
+ MI.clearFlag(MachineInstr::BundledSucc);
+ MI.clearFlag(MachineInstr::BundledPred);
} else {
// If it's not bundled with the successor (i.e. it is the last one
// in the bundle), then we can simply unbundle it from the predecessor,
// which will take care of updating the predecessor's flag.
- MI->unbundleFromPred();
+ MI.unbundleFromPred();
}
- B.splice(InsertPt, &B, MI);
+ B.splice(InsertPt, &B, MI.getIterator());
// Get the size of the bundle without asserting.
MachineBasicBlock::const_instr_iterator I = BundleIt.getInstrIterator();
@@ -164,9 +160,9 @@ static MachineBasicBlock::iterator moveInstrOut(MachineInstr *MI,
// Otherwise, extract the single instruction out and delete the bundle.
MachineBasicBlock::iterator NextIt = std::next(BundleIt);
- MachineInstr *SingleI = BundleIt->getNextNode();
- SingleI->unbundleFromPred();
- assert(!SingleI->isBundledWithSucc());
+ MachineInstr &SingleI = *BundleIt->getNextNode();
+ SingleI.unbundleFromPred();
+ assert(!SingleI.isBundledWithSucc());
BundleIt->eraseFromParent();
return NextIt;
}
@@ -267,7 +263,7 @@ bool HexagonPacketizerList::tryAllocateResourcesForConstExt(bool Reserve) {
}
-bool HexagonPacketizerList::isCallDependent(const MachineInstr* MI,
+bool HexagonPacketizerList::isCallDependent(const MachineInstr &MI,
SDep::Kind DepType, unsigned DepReg) {
// Check for LR dependence.
if (DepReg == HRI->getRARegister())
@@ -284,11 +280,18 @@ bool HexagonPacketizerList::isCallDependent(const MachineInstr* MI,
// Assumes that the first operand of the CALLr is the function address.
if (HII->isIndirectCall(MI) && (DepType == SDep::Data)) {
- MachineOperand MO = MI->getOperand(0);
+ const MachineOperand MO = MI.getOperand(0);
if (MO.isReg() && MO.isUse() && (MO.getReg() == DepReg))
return true;
}
+ if (HII->isJumpR(MI)) {
+ const MachineOperand &MO = HII->isPredicated(MI) ? MI.getOperand(1)
+ : MI.getOperand(0);
+ assert(MO.isReg() && MO.isUse());
+ if (MO.getReg() == DepReg)
+ return true;
+ }
return false;
}
@@ -297,54 +300,60 @@ static bool isRegDependence(const SDep::Kind DepType) {
DepType == SDep::Output;
}
-static bool isDirectJump(const MachineInstr* MI) {
- return MI->getOpcode() == Hexagon::J2_jump;
+static bool isDirectJump(const MachineInstr &MI) {
+ return MI.getOpcode() == Hexagon::J2_jump;
}
-static bool isSchedBarrier(const MachineInstr* MI) {
- switch (MI->getOpcode()) {
+static bool isSchedBarrier(const MachineInstr &MI) {
+ switch (MI.getOpcode()) {
case Hexagon::Y2_barrier:
return true;
}
return false;
}
-static bool isControlFlow(const MachineInstr* MI) {
- return (MI->getDesc().isTerminator() || MI->getDesc().isCall());
+static bool isControlFlow(const MachineInstr &MI) {
+ return MI.getDesc().isTerminator() || MI.getDesc().isCall();
}
/// Returns true if the instruction modifies a callee-saved register.
-static bool doesModifyCalleeSavedReg(const MachineInstr *MI,
+static bool doesModifyCalleeSavedReg(const MachineInstr &MI,
const TargetRegisterInfo *TRI) {
- const MachineFunction &MF = *MI->getParent()->getParent();
+ const MachineFunction &MF = *MI.getParent()->getParent();
for (auto *CSR = TRI->getCalleeSavedRegs(&MF); CSR && *CSR; ++CSR)
- if (MI->modifiesRegister(*CSR, TRI))
+ if (MI.modifiesRegister(*CSR, TRI))
return true;
return false;
}
-// TODO: MI->isIndirectBranch() and IsRegisterJump(MI)
// Returns true if an instruction can be promoted to .new predicate or
// new-value store.
-bool HexagonPacketizerList::isNewifiable(const MachineInstr* MI) {
- return HII->isCondInst(MI) || MI->isReturn() || HII->mayBeNewStore(MI);
+bool HexagonPacketizerList::isNewifiable(const MachineInstr &MI,
+ const TargetRegisterClass *NewRC) {
+ // Vector stores can be predicated, and can be new-value stores, but
+ // they cannot be predicated on a .new predicate value.
+ if (NewRC == &Hexagon::PredRegsRegClass)
+ if (HII->isV60VectorInstruction(MI) && MI.mayStore())
+ return false;
+ return HII->isCondInst(MI) || HII->isJumpR(MI) || MI.isReturn() ||
+ HII->mayBeNewStore(MI);
}
// Promote an instructiont to its .cur form.
// At this time, we have already made a call to canPromoteToDotCur and made
// sure that it can *indeed* be promoted.
-bool HexagonPacketizerList::promoteToDotCur(MachineInstr* MI,
+bool HexagonPacketizerList::promoteToDotCur(MachineInstr &MI,
SDep::Kind DepType, MachineBasicBlock::iterator &MII,
const TargetRegisterClass* RC) {
assert(DepType == SDep::Data);
int CurOpcode = HII->getDotCurOp(MI);
- MI->setDesc(HII->get(CurOpcode));
+ MI.setDesc(HII->get(CurOpcode));
return true;
}
void HexagonPacketizerList::cleanUpDotCur() {
- MachineInstr *MI = NULL;
+ MachineInstr *MI = nullptr;
for (auto BI : CurrentPacketMIs) {
DEBUG(dbgs() << "Cleanup packet has "; BI->dump(););
if (BI->getOpcode() == Hexagon::V6_vL32b_cur_ai) {
@@ -365,12 +374,12 @@ void HexagonPacketizerList::cleanUpDotCur() {
}
// Check to see if an instruction can be dot cur.
-bool HexagonPacketizerList::canPromoteToDotCur(const MachineInstr *MI,
+bool HexagonPacketizerList::canPromoteToDotCur(const MachineInstr &MI,
const SUnit *PacketSU, unsigned DepReg, MachineBasicBlock::iterator &MII,
const TargetRegisterClass *RC) {
if (!HII->isV60VectorInstruction(MI))
return false;
- if (!HII->isV60VectorInstruction(&*MII))
+ if (!HII->isV60VectorInstruction(*MII))
return false;
// Already a dot new instruction.
@@ -386,14 +395,14 @@ bool HexagonPacketizerList::canPromoteToDotCur(const MachineInstr *MI,
// Make sure candidate instruction uses cur.
DEBUG(dbgs() << "Can we DOT Cur Vector MI\n";
- MI->dump();
+ MI.dump();
dbgs() << "in packet\n";);
MachineInstr &MJ = *MII;
DEBUG({
dbgs() << "Checking CUR against ";
MJ.dump();
});
- unsigned DestReg = MI->getOperand(0).getReg();
+ unsigned DestReg = MI.getOperand(0).getReg();
bool FoundMatch = false;
for (auto &MO : MJ.operands())
if (MO.isReg() && MO.getReg() == DestReg)
@@ -409,7 +418,7 @@ bool HexagonPacketizerList::canPromoteToDotCur(const MachineInstr *MI,
return false;
}
- DEBUG(dbgs() << "Can Dot CUR MI\n"; MI->dump(););
+ DEBUG(dbgs() << "Can Dot CUR MI\n"; MI.dump(););
// We can convert the opcode into a .cur.
return true;
}
@@ -417,7 +426,7 @@ bool HexagonPacketizerList::canPromoteToDotCur(const MachineInstr *MI,
// Promote an instruction to its .new form. At this time, we have already
// made a call to canPromoteToDotNew and made sure that it can *indeed* be
// promoted.
-bool HexagonPacketizerList::promoteToDotNew(MachineInstr* MI,
+bool HexagonPacketizerList::promoteToDotNew(MachineInstr &MI,
SDep::Kind DepType, MachineBasicBlock::iterator &MII,
const TargetRegisterClass* RC) {
assert (DepType == SDep::Data);
@@ -426,16 +435,53 @@ bool HexagonPacketizerList::promoteToDotNew(MachineInstr* MI,
NewOpcode = HII->getDotNewPredOp(MI, MBPI);
else
NewOpcode = HII->getDotNewOp(MI);
- MI->setDesc(HII->get(NewOpcode));
+ MI.setDesc(HII->get(NewOpcode));
return true;
}
-bool HexagonPacketizerList::demoteToDotOld(MachineInstr* MI) {
- int NewOpcode = HII->getDotOldOp(MI->getOpcode());
- MI->setDesc(HII->get(NewOpcode));
+bool HexagonPacketizerList::demoteToDotOld(MachineInstr &MI) {
+ int NewOpcode = HII->getDotOldOp(MI.getOpcode());
+ MI.setDesc(HII->get(NewOpcode));
return true;
}
+bool HexagonPacketizerList::useCallersSP(MachineInstr &MI) {
+ unsigned Opc = MI.getOpcode();
+ switch (Opc) {
+ case Hexagon::S2_storerd_io:
+ case Hexagon::S2_storeri_io:
+ case Hexagon::S2_storerh_io:
+ case Hexagon::S2_storerb_io:
+ break;
+ default:
+ llvm_unreachable("Unexpected instruction");
+ }
+ unsigned FrameSize = MF.getFrameInfo().getStackSize();
+ MachineOperand &Off = MI.getOperand(1);
+ int64_t NewOff = Off.getImm() - (FrameSize + HEXAGON_LRFP_SIZE);
+ if (HII->isValidOffset(Opc, NewOff)) {
+ Off.setImm(NewOff);
+ return true;
+ }
+ return false;
+}
+
+void HexagonPacketizerList::useCalleesSP(MachineInstr &MI) {
+ unsigned Opc = MI.getOpcode();
+ switch (Opc) {
+ case Hexagon::S2_storerd_io:
+ case Hexagon::S2_storeri_io:
+ case Hexagon::S2_storerh_io:
+ case Hexagon::S2_storerb_io:
+ break;
+ default:
+ llvm_unreachable("Unexpected instruction");
+ }
+ unsigned FrameSize = MF.getFrameInfo().getStackSize();
+ MachineOperand &Off = MI.getOperand(1);
+ Off.setImm(Off.getImm() + FrameSize + HEXAGON_LRFP_SIZE);
+}
+
enum PredicateKind {
PK_False,
PK_True,
@@ -453,7 +499,7 @@ static PredicateKind getPredicateSense(const MachineInstr &MI,
return PK_False;
}
-static const MachineOperand &getPostIncrementOperand(const MachineInstr *MI,
+static const MachineOperand &getPostIncrementOperand(const MachineInstr &MI,
const HexagonInstrInfo *HII) {
assert(HII->isPostIncrement(MI) && "Not a post increment operation.");
#ifndef NDEBUG
@@ -461,22 +507,22 @@ static const MachineOperand &getPostIncrementOperand(const MachineInstr *MI,
// list. Caution: Densemap initializes with the minimum of 64 buckets,
// whereas there are at most 5 operands in the post increment.
DenseSet<unsigned> DefRegsSet;
- for (auto &MO : MI->operands())
+ for (auto &MO : MI.operands())
if (MO.isReg() && MO.isDef())
DefRegsSet.insert(MO.getReg());
- for (auto &MO : MI->operands())
+ for (auto &MO : MI.operands())
if (MO.isReg() && MO.isUse() && DefRegsSet.count(MO.getReg()))
return MO;
#else
- if (MI->mayLoad()) {
- const MachineOperand &Op1 = MI->getOperand(1);
+ if (MI.mayLoad()) {
+ const MachineOperand &Op1 = MI.getOperand(1);
// The 2nd operand is always the post increment operand in load.
assert(Op1.isReg() && "Post increment operand has be to a register.");
return Op1;
}
- if (MI->getDesc().mayStore()) {
- const MachineOperand &Op0 = MI->getOperand(0);
+ if (MI.getDesc().mayStore()) {
+ const MachineOperand &Op0 = MI.getOperand(0);
// The 1st operand is always the post increment operand in store.
assert(Op0.isReg() && "Post increment operand has be to a register.");
return Op0;
@@ -487,13 +533,13 @@ static const MachineOperand &getPostIncrementOperand(const MachineInstr *MI,
}
// Get the value being stored.
-static const MachineOperand& getStoreValueOperand(const MachineInstr *MI) {
+static const MachineOperand& getStoreValueOperand(const MachineInstr &MI) {
// value being stored is always the last operand.
- return MI->getOperand(MI->getNumOperands()-1);
+ return MI.getOperand(MI.getNumOperands()-1);
}
-static bool isLoadAbsSet(const MachineInstr *MI) {
- unsigned Opc = MI->getOpcode();
+static bool isLoadAbsSet(const MachineInstr &MI) {
+ unsigned Opc = MI.getOpcode();
switch (Opc) {
case Hexagon::L4_loadrd_ap:
case Hexagon::L4_loadrb_ap:
@@ -506,9 +552,9 @@ static bool isLoadAbsSet(const MachineInstr *MI) {
return false;
}
-static const MachineOperand &getAbsSetOperand(const MachineInstr *MI) {
+static const MachineOperand &getAbsSetOperand(const MachineInstr &MI) {
assert(isLoadAbsSet(MI));
- return MI->getOperand(1);
+ return MI.getOperand(1);
}
@@ -529,8 +575,8 @@ static const MachineOperand &getAbsSetOperand(const MachineInstr *MI) {
// if there is a new value store in the packet. Corollary: if there is
// already a store in a packet, there can not be a new value store.
// Arch Spec: 3.4.4.2
-bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
- const MachineInstr *PacketMI, unsigned DepReg) {
+bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr &MI,
+ const MachineInstr &PacketMI, unsigned DepReg) {
// Make sure we are looking at the store, that can be promoted.
if (!HII->mayBeNewStore(MI))
return false;
@@ -540,7 +586,7 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
if (Val.isReg() && Val.getReg() != DepReg)
return false;
- const MCInstrDesc& MCID = PacketMI->getDesc();
+ const MCInstrDesc& MCID = PacketMI.getDesc();
// First operand is always the result.
const TargetRegisterClass *PacketRC = HII->getRegClass(MCID, 0, HRI, MF);
@@ -563,7 +609,7 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
return false;
}
- if (HII->isPostIncrement(PacketMI) && PacketMI->mayLoad() &&
+ if (HII->isPostIncrement(PacketMI) && PacketMI.mayLoad() &&
getPostIncrementOperand(PacketMI, HII).getReg() == DepReg) {
// If source is post_inc, or absolute-set addressing, it can not feed
// into new value store
@@ -578,8 +624,8 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
// If the source that feeds the store is predicated, new value store must
// also be predicated.
- if (HII->isPredicated(*PacketMI)) {
- if (!HII->isPredicated(*MI))
+ if (HII->isPredicated(PacketMI)) {
+ if (!HII->isPredicated(MI))
return false;
// Check to make sure that they both will have their predicates
@@ -589,7 +635,7 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
const TargetRegisterClass* predRegClass = nullptr;
// Get predicate register used in the source instruction.
- for (auto &MO : PacketMI->operands()) {
+ for (auto &MO : PacketMI.operands()) {
if (!MO.isReg())
continue;
predRegNumSrc = MO.getReg();
@@ -601,7 +647,7 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
"predicate register not found in a predicated PacketMI instruction");
// Get predicate register used in new-value store instruction.
- for (auto &MO : MI->operands()) {
+ for (auto &MO : MI.operands()) {
if (!MO.isReg())
continue;
predRegNumDst = MO.getReg();
@@ -622,7 +668,7 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
// sense, i.e, either both should be negated or both should be non-negated.
if (predRegNumDst != predRegNumSrc ||
HII->isDotNewInst(PacketMI) != HII->isDotNewInst(MI) ||
- getPredicateSense(*MI, HII) != getPredicateSense(*PacketMI, HII))
+ getPredicateSense(MI, HII) != getPredicateSense(PacketMI, HII))
return false;
}
@@ -638,19 +684,19 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
for (auto I : CurrentPacketMIs) {
SUnit *TempSU = MIToSUnit.find(I)->second;
- MachineInstr* TempMI = TempSU->getInstr();
+ MachineInstr &TempMI = *TempSU->getInstr();
// Following condition is true for all the instructions until PacketMI is
// reached (StartCheck is set to 0 before the for loop).
// StartCheck flag is 1 for all the instructions after PacketMI.
- if (TempMI != PacketMI && !StartCheck) // Start processing only after
- continue; // encountering PacketMI.
+ if (&TempMI != &PacketMI && !StartCheck) // Start processing only after
+ continue; // encountering PacketMI.
StartCheck = 1;
- if (TempMI == PacketMI) // We don't want to check PacketMI for dependence.
+ if (&TempMI == &PacketMI) // We don't want to check PacketMI for dependence.
continue;
- for (auto &MO : MI->operands())
+ for (auto &MO : MI.operands())
if (MO.isReg() && TempSU->getInstr()->modifiesRegister(MO.getReg(), HRI))
return false;
}
@@ -662,8 +708,8 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
// Eg. r0 = add(r0, #3)
// memw(r1+r0<<#2) = r0
if (!HII->isPostIncrement(MI)) {
- for (unsigned opNum = 0; opNum < MI->getNumOperands()-1; opNum++) {
- const MachineOperand &MO = MI->getOperand(opNum);
+ for (unsigned opNum = 0; opNum < MI.getNumOperands()-1; opNum++) {
+ const MachineOperand &MO = MI.getOperand(opNum);
if (MO.isReg() && MO.getReg() == DepReg)
return false;
}
@@ -673,7 +719,7 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
// do not newify the store. Eg.
// %R9<def> = ZXTH %R12, %D6<imp-use>, %R12<imp-def>
// S2_storerh_io %R8, 2, %R12<kill>; mem:ST2[%scevgep343]
- for (auto &MO : PacketMI->operands()) {
+ for (auto &MO : PacketMI.operands()) {
if (!MO.isReg() || !MO.isDef() || !MO.isImplicit())
continue;
unsigned R = MO.getReg();
@@ -686,7 +732,7 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
// just-in-case. For example, we cannot newify R2 in the following case:
// %R3<def> = A2_tfrsi 0;
// S2_storeri_io %R0<kill>, 0, %R2<kill>, %D1<imp-use,kill>;
- for (auto &MO : MI->operands()) {
+ for (auto &MO : MI.operands()) {
if (MO.isReg() && MO.isUse() && MO.isImplicit() && MO.getReg() == DepReg)
return false;
}
@@ -696,14 +742,14 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
}
// Can this MI to promoted to either new value store or new value jump.
-bool HexagonPacketizerList::canPromoteToNewValue(const MachineInstr *MI,
+bool HexagonPacketizerList::canPromoteToNewValue(const MachineInstr &MI,
const SUnit *PacketSU, unsigned DepReg,
MachineBasicBlock::iterator &MII) {
if (!HII->mayBeNewStore(MI))
return false;
// Check to see the store can be new value'ed.
- MachineInstr *PacketMI = PacketSU->getInstr();
+ MachineInstr &PacketMI = *PacketSU->getInstr();
if (canPromoteToNewValueStore(MI, PacketMI, DepReg))
return true;
@@ -712,8 +758,8 @@ bool HexagonPacketizerList::canPromoteToNewValue(const MachineInstr *MI,
return false;
}
-static bool isImplicitDependency(const MachineInstr *I, unsigned DepReg) {
- for (auto &MO : I->operands())
+static bool isImplicitDependency(const MachineInstr &I, unsigned DepReg) {
+ for (auto &MO : I.operands())
if (MO.isReg() && MO.isDef() && (MO.getReg() == DepReg) && MO.isImplicit())
return true;
return false;
@@ -724,25 +770,25 @@ static bool isImplicitDependency(const MachineInstr *I, unsigned DepReg) {
// 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.
-bool HexagonPacketizerList::canPromoteToDotNew(const MachineInstr *MI,
+bool HexagonPacketizerList::canPromoteToDotNew(const MachineInstr &MI,
const SUnit *PacketSU, unsigned DepReg, MachineBasicBlock::iterator &MII,
const TargetRegisterClass* RC) {
// Already a dot new instruction.
if (HII->isDotNewInst(MI) && !HII->mayBeNewStore(MI))
return false;
- if (!isNewifiable(MI))
+ if (!isNewifiable(MI, RC))
return false;
- const MachineInstr *PI = PacketSU->getInstr();
+ const MachineInstr &PI = *PacketSU->getInstr();
// The "new value" cannot come from inline asm.
- if (PI->isInlineAsm())
+ if (PI.isInlineAsm())
return false;
// IMPLICIT_DEFs won't materialize as real instructions, so .new makes no
// sense.
- if (PI->isImplicitDef())
+ if (PI.isImplicitDef())
return false;
// If dependency is trough an implicitly defined register, we should not
@@ -750,16 +796,14 @@ bool HexagonPacketizerList::canPromoteToDotNew(const MachineInstr *MI,
if (isImplicitDependency(PI, DepReg))
return false;
- const MCInstrDesc& MCID = PI->getDesc();
+ const MCInstrDesc& MCID = PI.getDesc();
const TargetRegisterClass *VecRC = HII->getRegClass(MCID, 0, HRI, MF);
if (DisableVecDblNVStores && VecRC == &Hexagon::VecDblRegsRegClass)
return false;
// predicate .new
- // bug 5670: until that is fixed
- // TODO: MI->isIndirectBranch() and IsRegisterJump(MI)
if (RC == &Hexagon::PredRegsRegClass)
- if (HII->isCondInst(MI) || MI->isReturn())
+ if (HII->isCondInst(MI) || HII->isJumpR(MI) || MI.isReturn())
return HII->predCanBeUsedAsDotNew(PI, DepReg);
if (RC != &Hexagon::PredRegsRegClass && !HII->mayBeNewStore(MI))
@@ -795,9 +839,9 @@ bool HexagonPacketizerList::canPromoteToDotNew(const MachineInstr *MI,
// The P3 from a) and d) will be complements after
// a)'s P3 is converted to .new form
// Anti-dep between c) and b) is irrelevant for this case
-bool HexagonPacketizerList::restrictingDepExistInPacket(MachineInstr* MI,
+bool HexagonPacketizerList::restrictingDepExistInPacket(MachineInstr &MI,
unsigned DepReg) {
- SUnit *PacketSUDep = MIToSUnit.find(MI)->second;
+ SUnit *PacketSUDep = MIToSUnit.find(&MI)->second;
for (auto I : CurrentPacketMIs) {
// We only care for dependencies to predicated instructions
@@ -889,7 +933,7 @@ bool HexagonPacketizerList::arePredicatesComplements(MachineInstr &MI1,
// above example. Now I need to see if there is an anti dependency
// from c) to any other instruction in the same packet on the pred
// reg of interest.
- if (restrictingDepExistInPacket(I, Dep.getReg()))
+ if (restrictingDepExistInPacket(*I, Dep.getReg()))
return false;
}
}
@@ -906,7 +950,7 @@ bool HexagonPacketizerList::arePredicatesComplements(MachineInstr &MI1,
Hexagon::PredRegsRegClass.contains(PReg1) &&
Hexagon::PredRegsRegClass.contains(PReg2) &&
getPredicateSense(MI1, HII) != getPredicateSense(MI2, HII) &&
- HII->isDotNewInst(&MI1) == HII->isDotNewInst(&MI2);
+ HII->isDotNewInst(MI1) == HII->isDotNewInst(MI2);
}
// Initialize packetizer flags.
@@ -957,10 +1001,10 @@ bool HexagonPacketizerList::isSoloInstruction(const MachineInstr &MI) {
// 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))
+ if (isSchedBarrier(MI))
return true;
- if (HII->isSolo(&MI))
+ if (HII->isSolo(MI))
return true;
if (MI.getOpcode() == Hexagon::A2_nop)
@@ -977,9 +1021,9 @@ bool HexagonPacketizerList::isSoloInstruction(const MachineInstr &MI) {
// cannotCoexistAsymm(MI, MJ) || cannotCoexistAsymm(MJ, MI)
// Doing the test only one way saves the amount of code in this function,
// since every test would need to be repeated with the MI and MJ reversed.
-static bool cannotCoexistAsymm(const MachineInstr *MI, const MachineInstr *MJ,
+static bool cannotCoexistAsymm(const MachineInstr &MI, const MachineInstr &MJ,
const HexagonInstrInfo &HII) {
- const MachineFunction *MF = MI->getParent()->getParent();
+ const MachineFunction *MF = MI.getParent()->getParent();
if (MF->getSubtarget<HexagonSubtarget>().hasV60TOpsOnly() &&
HII.isHVXMemWithAIndirect(MI, MJ))
return true;
@@ -988,9 +1032,27 @@ static bool cannotCoexistAsymm(const MachineInstr *MI, const MachineInstr *MJ,
// able to remove the asm out after packetizing (i.e. if the asm must be
// moved past the bundle). Similarly, two asms cannot be together to avoid
// complications when determining their relative order outside of a bundle.
- if (MI->isInlineAsm())
- return MJ->isInlineAsm() || MJ->isBranch() || MJ->isBarrier() ||
- MJ->isCall() || MJ->isTerminator();
+ if (MI.isInlineAsm())
+ return MJ.isInlineAsm() || MJ.isBranch() || MJ.isBarrier() ||
+ 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): {
+ // 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.
+ unsigned TJ = HII.getType(MJ);
+ if (TJ != HexagonII::TypeALU32)
+ return true;
+ break;
+ }
+ default:
+ break;
+ }
// "False" really means that the quick check failed to determine if
// I and J cannot coexist.
@@ -999,8 +1061,8 @@ static bool cannotCoexistAsymm(const MachineInstr *MI, const MachineInstr *MJ,
// Full, symmetric check.
-bool HexagonPacketizerList::cannotCoexist(const MachineInstr *MI,
- const MachineInstr *MJ) {
+bool HexagonPacketizerList::cannotCoexist(const MachineInstr &MI,
+ const MachineInstr &MJ) {
return cannotCoexistAsymm(MI, MJ, *HII) || cannotCoexistAsymm(MJ, MI, *HII);
}
@@ -1010,10 +1072,10 @@ void HexagonPacketizerList::unpacketizeSoloInstrs(MachineFunction &MF) {
MachineBasicBlock::instr_iterator NextI;
for (auto I = B.instr_begin(), E = B.instr_end(); I != E; I = NextI) {
NextI = std::next(I);
- MachineInstr *MI = &*I;
- if (MI->isBundle())
+ MachineInstr &MI = *I;
+ if (MI.isBundle())
BundleIt = I;
- if (!MI->isInsideBundle())
+ if (!MI.isInsideBundle())
continue;
// Decide on where to insert the instruction that we are pulling out.
@@ -1023,9 +1085,9 @@ void HexagonPacketizerList::unpacketizeSoloInstrs(MachineFunction &MF) {
// other instructions in the bundle read, then we need to place it
// after the bundle (to preserve the bundle semantics).
bool InsertBeforeBundle;
- if (MI->isInlineAsm())
- InsertBeforeBundle = !hasWriteToReadDep(*MI, *BundleIt, HRI);
- else if (MI->isDebugValue())
+ if (MI.isInlineAsm())
+ InsertBeforeBundle = !hasWriteToReadDep(MI, *BundleIt, HRI);
+ else if (MI.isDebugValue())
InsertBeforeBundle = true;
else
continue;
@@ -1036,8 +1098,8 @@ void HexagonPacketizerList::unpacketizeSoloInstrs(MachineFunction &MF) {
}
// Check if a given instruction is of class "system".
-static bool isSystemInstr(const MachineInstr *MI) {
- unsigned Opc = MI->getOpcode();
+static bool isSystemInstr(const MachineInstr &MI) {
+ unsigned Opc = MI.getOpcode();
switch (Opc) {
case Hexagon::Y2_barrier:
case Hexagon::Y2_dcfetchbo:
@@ -1046,24 +1108,24 @@ static bool isSystemInstr(const MachineInstr *MI) {
return false;
}
-bool HexagonPacketizerList::hasDeadDependence(const MachineInstr *I,
- const MachineInstr *J) {
+bool HexagonPacketizerList::hasDeadDependence(const MachineInstr &I,
+ const MachineInstr &J) {
// The dependence graph may not include edges between dead definitions,
// so without extra checks, we could end up packetizing two instruction
// defining the same (dead) register.
- if (I->isCall() || J->isCall())
+ if (I.isCall() || J.isCall())
return false;
- if (HII->isPredicated(*I) || HII->isPredicated(*J))
+ if (HII->isPredicated(I) || HII->isPredicated(J))
return false;
BitVector DeadDefs(Hexagon::NUM_TARGET_REGS);
- for (auto &MO : I->operands()) {
+ for (auto &MO : I.operands()) {
if (!MO.isReg() || !MO.isDef() || !MO.isDead())
continue;
DeadDefs[MO.getReg()] = true;
}
- for (auto &MO : J->operands()) {
+ for (auto &MO : J.operands()) {
if (!MO.isReg() || !MO.isDef() || !MO.isDead())
continue;
unsigned R = MO.getReg();
@@ -1073,8 +1135,8 @@ bool HexagonPacketizerList::hasDeadDependence(const MachineInstr *I,
return false;
}
-bool HexagonPacketizerList::hasControlDependence(const MachineInstr *I,
- const MachineInstr *J) {
+bool HexagonPacketizerList::hasControlDependence(const MachineInstr &I,
+ const MachineInstr &J) {
// A save callee-save register function call can only be in a packet
// with instructions that don't write to the callee-save registers.
if ((HII->isSaveCalleeSavedRegsCall(I) &&
@@ -1090,10 +1152,10 @@ bool HexagonPacketizerList::hasControlDependence(const MachineInstr *I,
// \ref-manual (7.3.4) A loop setup packet in loopN or spNloop0 cannot
// contain a speculative indirect jump,
// a new-value compare jump or a dealloc_return.
- auto isBadForLoopN = [this] (const MachineInstr *MI) -> bool {
- if (MI->isCall() || HII->isDeallocRet(MI) || HII->isNewValueJump(MI))
+ auto isBadForLoopN = [this] (const MachineInstr &MI) -> bool {
+ if (MI.isCall() || HII->isDeallocRet(MI) || HII->isNewValueJump(MI))
return true;
- if (HII->isPredicated(*MI) && HII->isPredicatedNew(*MI) && HII->isJumpR(MI))
+ if (HII->isPredicated(MI) && HII->isPredicatedNew(MI) && HII->isJumpR(MI))
return true;
return false;
};
@@ -1106,13 +1168,13 @@ bool HexagonPacketizerList::hasControlDependence(const MachineInstr *I,
// dealloc_return cannot appear in the same packet as a conditional or
// unconditional jump.
return HII->isDeallocRet(I) &&
- (J->isBranch() || J->isCall() || J->isBarrier());
+ (J.isBranch() || J.isCall() || J.isBarrier());
}
-bool HexagonPacketizerList::hasV4SpecificDependence(const MachineInstr *I,
- const MachineInstr *J) {
+bool HexagonPacketizerList::hasV4SpecificDependence(const MachineInstr &I,
+ const MachineInstr &J) {
bool SysI = isSystemInstr(I), SysJ = isSystemInstr(J);
- bool StoreI = I->mayStore(), StoreJ = J->mayStore();
+ bool StoreI = I.mayStore(), StoreJ = J.mayStore();
if ((SysI && StoreJ) || (SysJ && StoreI))
return true;
@@ -1135,19 +1197,18 @@ bool HexagonPacketizerList::hasV4SpecificDependence(const MachineInstr *I,
// SUJ is the current instruction inside the current packet against which that
// SUI will be packetized.
bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
- MachineInstr *I = SUI->getInstr();
- MachineInstr *J = SUJ->getInstr();
- assert(I && J && "Unable to packetize null instruction!");
+ assert(SUI->getInstr() && SUJ->getInstr());
+ MachineInstr &I = *SUI->getInstr();
+ MachineInstr &J = *SUJ->getInstr();
// Clear IgnoreDepMIs when Packet starts.
if (CurrentPacketMIs.size() == 1)
IgnoreDepMIs.clear();
- MachineBasicBlock::iterator II = I;
- const unsigned FrameSize = MF.getFrameInfo()->getStackSize();
+ MachineBasicBlock::iterator II = I.getIterator();
// Solo instructions cannot go in the packet.
- assert(!isSoloInstruction(*I) && "Unexpected solo instr!");
+ assert(!isSoloInstruction(I) && "Unexpected solo instr!");
if (cannotCoexist(I, J))
return false;
@@ -1164,23 +1225,23 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
return false;
// If an instruction feeds new value jump, glue it.
- MachineBasicBlock::iterator NextMII = I;
+ MachineBasicBlock::iterator NextMII = I.getIterator();
++NextMII;
- if (NextMII != I->getParent()->end() && HII->isNewValueJump(&*NextMII)) {
+ if (NextMII != I.getParent()->end() && HII->isNewValueJump(*NextMII)) {
MachineInstr &NextMI = *NextMII;
bool secondRegMatch = false;
const MachineOperand &NOp0 = NextMI.getOperand(0);
const MachineOperand &NOp1 = NextMI.getOperand(1);
- if (NOp1.isReg() && I->getOperand(0).getReg() == NOp1.getReg())
+ if (NOp1.isReg() && I.getOperand(0).getReg() == NOp1.getReg())
secondRegMatch = true;
- for (auto I : CurrentPacketMIs) {
- SUnit *PacketSU = MIToSUnit.find(I)->second;
- MachineInstr *PI = PacketSU->getInstr();
+ for (auto T : CurrentPacketMIs) {
+ SUnit *PacketSU = MIToSUnit.find(T)->second;
+ MachineInstr &PI = *PacketSU->getInstr();
// NVJ can not be part of the dual jump - Arch Spec: section 7.8.
- if (PI->isCall()) {
+ if (PI.isCall()) {
Dependence = true;
break;
}
@@ -1192,14 +1253,14 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
// 3. If the second operand of the nvj is newified, (which means
// first operand is also a reg), first reg is not defined in
// the same packet.
- if (PI->getOpcode() == Hexagon::S2_allocframe || PI->mayStore() ||
+ if (PI.getOpcode() == Hexagon::S2_allocframe || PI.mayStore() ||
HII->isLoopN(PI)) {
Dependence = true;
break;
}
// Check #2/#3.
const MachineOperand &OpR = secondRegMatch ? NOp0 : NOp1;
- if (OpR.isReg() && PI->modifiesRegister(OpR.getReg(), HRI)) {
+ if (OpR.isReg() && PI.modifiesRegister(OpR.getReg(), HRI)) {
Dependence = true;
break;
}
@@ -1237,12 +1298,6 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
// dealloc return unless we have dependencies on the explicit uses
// of the registers used by jumpr (like r31) or dealloc return
// (like r29 or r30).
- //
- // TODO: Currently, jumpr is handling only return of r31. So, the
- // following logic (specificaly isCallDependent) is working fine.
- // We need to enable jumpr for register other than r31 and then,
- // we need to rework the last part, where it handles indirect call
- // of that (isCallDependent) function. Bug 6216 is opened for this.
unsigned DepReg = 0;
const TargetRegisterClass *RC = nullptr;
if (DepType == SDep::Data) {
@@ -1250,7 +1305,7 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
RC = HRI->getMinimalPhysRegClass(DepReg);
}
- if (I->isCall() || I->isReturn() || HII->isTailCall(I)) {
+ if (I.isCall() || HII->isJumpR(I) || I.isReturn() || HII->isTailCall(I)) {
if (!isRegDependence(DepType))
continue;
if (!isCallDependent(I, DepType, SUJ->Succs[i].getReg()))
@@ -1283,8 +1338,8 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
// For predicated instructions, if the predicates are complements then
// there can be no dependence.
- if (HII->isPredicated(*I) && HII->isPredicated(*J) &&
- arePredicatesComplements(*I, *J)) {
+ if (HII->isPredicated(I) && HII->isPredicated(J) &&
+ arePredicatesComplements(I, J)) {
// Not always safe to do this translation.
// DAG Builder attempts to reduce dependence edges using transitive
// nature of dependencies. Here is an example:
@@ -1297,24 +1352,24 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
// However, there is no dependence edge between (1)->(3). This results
// in all 3 instructions going in the same packet. We ignore dependce
// only once to avoid this situation.
- auto Itr = std::find(IgnoreDepMIs.begin(), IgnoreDepMIs.end(), J);
+ auto Itr = find(IgnoreDepMIs, &J);
if (Itr != IgnoreDepMIs.end()) {
Dependence = true;
return false;
}
- IgnoreDepMIs.push_back(I);
+ IgnoreDepMIs.push_back(&I);
continue;
}
// Ignore Order dependences between unconditional direct branches
// and non-control-flow instructions.
- if (isDirectJump(I) && !J->isBranch() && !J->isCall() &&
+ if (isDirectJump(I) && !J.isBranch() && !J.isCall() &&
DepType == SDep::Order)
continue;
// Ignore all dependences for jumps except for true and output
// dependences.
- if (I->isConditionalBranch() && DepType != SDep::Data &&
+ if (I.isConditionalBranch() && DepType != SDep::Data &&
DepType != SDep::Output)
continue;
@@ -1336,7 +1391,7 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
unsigned DepReg = SUJ->Succs[i].getReg();
// Check if I and J really defines DepReg.
- if (!I->definesRegister(DepReg) && !J->definesRegister(DepReg))
+ if (!I.definesRegister(DepReg) && !J.definesRegister(DepReg))
continue;
FoundSequentialDependence = true;
break;
@@ -1350,15 +1405,15 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
// 4. Load followed by any memory operation is allowed.
if (DepType == SDep::Order) {
if (!PacketizeVolatiles) {
- bool OrdRefs = I->hasOrderedMemoryRef() || J->hasOrderedMemoryRef();
+ bool OrdRefs = I.hasOrderedMemoryRef() || J.hasOrderedMemoryRef();
if (OrdRefs) {
FoundSequentialDependence = true;
break;
}
}
// J is first, I is second.
- bool LoadJ = J->mayLoad(), StoreJ = J->mayStore();
- bool LoadI = I->mayLoad(), StoreI = I->mayStore();
+ 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.
@@ -1383,25 +1438,21 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
// 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.
- if (DepType == SDep::Data && J->getOpcode() == Hexagon::S2_allocframe) {
- unsigned Opc = I->getOpcode();
+ if (DepType == SDep::Data && J.getOpcode() == Hexagon::S2_allocframe) {
+ unsigned Opc = I.getOpcode();
switch (Opc) {
case Hexagon::S2_storerd_io:
case Hexagon::S2_storeri_io:
case Hexagon::S2_storerh_io:
case Hexagon::S2_storerb_io:
- if (I->getOperand(0).getReg() == HRI->getStackRegister()) {
- int64_t Imm = I->getOperand(1).getImm();
- int64_t NewOff = Imm - (FrameSize + HEXAGON_LRFP_SIZE);
- if (HII->isValidOffset(Opc, NewOff)) {
- GlueAllocframeStore = true;
- // Since this store is to be glued with allocframe in the same
- // packet, it will use SP of the previous stack frame, i.e.
- // caller's SP. Therefore, we need to recalculate offset
- // according to this change.
- I->getOperand(1).setImm(NewOff);
+ if (I.getOperand(0).getReg() == HRI->getStackRegister()) {
+ // Since this store is to be glued with allocframe in the same
+ // packet, it will use SP of the previous stack frame, i.e.
+ // caller's SP. Therefore, we need to recalculate offset
+ // according to this change.
+ GlueAllocframeStore = useCallersSP(I);
+ if (GlueAllocframeStore)
continue;
- }
}
default:
break;
@@ -1414,12 +1465,12 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
// R0 = ... ; SUI
// Those cannot be packetized together, since the call will observe
// the effect of the assignment to R0.
- if (DepType == SDep::Anti && J->isCall()) {
+ if (DepType == SDep::Anti && J.isCall()) {
// Check if I defines any volatile register. We should also check
// registers that the call may read, but these happen to be a
// subset of the volatile register set.
- for (const MCPhysReg *P = J->getDesc().ImplicitDefs; P && *P; ++P) {
- if (!I->modifiesRegister(*P, HRI))
+ for (const MCPhysReg *P = J.getDesc().ImplicitDefs; P && *P; ++P) {
+ if (!I.modifiesRegister(*P, HRI))
continue;
FoundSequentialDependence = true;
break;
@@ -1447,9 +1498,9 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
}
bool HexagonPacketizerList::isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) {
- MachineInstr *I = SUI->getInstr();
- MachineInstr *J = SUJ->getInstr();
- assert(I && J && "Unable to packetize null instruction!");
+ assert(SUI->getInstr() && SUJ->getInstr());
+ MachineInstr &I = *SUI->getInstr();
+ MachineInstr &J = *SUJ->getInstr();
if (cannotCoexist(I, J))
return false;
@@ -1467,16 +1518,15 @@ bool HexagonPacketizerList::isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) {
// instruction. If so, restore its offset to its original value, i.e. use
// current SP instead of caller's SP.
if (GlueAllocframeStore) {
- unsigned FrameSize = MF.getFrameInfo()->getStackSize();
- MachineOperand &MOff = I->getOperand(1);
- MOff.setImm(MOff.getImm() + FrameSize + HEXAGON_LRFP_SIZE);
+ useCalleesSP(I);
+ GlueAllocframeStore = false;
}
return false;
}
MachineBasicBlock::iterator
HexagonPacketizerList::addToPacket(MachineInstr &MI) {
- MachineBasicBlock::iterator MII = MI;
+ MachineBasicBlock::iterator MII = MI.getIterator();
MachineBasicBlock *MBB = MI.getParent();
if (MI.isImplicitDef()) {
unsigned R = MI.getOperand(0).getReg();
@@ -1488,7 +1538,7 @@ HexagonPacketizerList::addToPacket(MachineInstr &MI) {
}
assert(ResourceTracker->canReserveResources(MI));
- bool ExtMI = HII->isExtended(&MI) || HII->isConstExtended(&MI);
+ bool ExtMI = HII->isExtended(MI) || HII->isConstExtended(MI);
bool Good = true;
if (GlueToNewValueJump) {
@@ -1501,7 +1551,7 @@ HexagonPacketizerList::addToPacket(MachineInstr &MI) {
if (ExtMI)
Good = tryAllocateResourcesForConstExt(true);
- bool ExtNvjMI = HII->isExtended(&NvjMI) || HII->isConstExtended(&NvjMI);
+ bool ExtNvjMI = HII->isExtended(NvjMI) || HII->isConstExtended(NvjMI);
if (Good) {
if (ResourceTracker->canReserveResources(NvjMI))
ResourceTracker->reserveResources(NvjMI);
@@ -1535,7 +1585,11 @@ HexagonPacketizerList::addToPacket(MachineInstr &MI) {
if (ExtMI && !tryAllocateResourcesForConstExt(true)) {
endPacket(MBB, MI);
if (PromotedToDotNew)
- demoteToDotOld(&MI);
+ demoteToDotOld(MI);
+ if (GlueAllocframeStore) {
+ useCalleesSP(MI);
+ GlueAllocframeStore = false;
+ }
ResourceTracker->reserveResources(MI);
reserveResourcesForConstExt();
}
@@ -1551,18 +1605,18 @@ void HexagonPacketizerList::endPacket(MachineBasicBlock *MBB,
}
bool HexagonPacketizerList::shouldAddToPacket(const MachineInstr &MI) {
- return !producesStall(&MI);
+ return !producesStall(MI);
}
// Return true when ConsMI uses a register defined by ProdMI.
-static bool isDependent(const MachineInstr *ProdMI,
- const MachineInstr *ConsMI) {
- if (!ProdMI->getOperand(0).isReg())
+static bool isDependent(const MachineInstr &ProdMI,
+ const MachineInstr &ConsMI) {
+ if (!ProdMI.getOperand(0).isReg())
return false;
- unsigned DstReg = ProdMI->getOperand(0).getReg();
+ unsigned DstReg = ProdMI.getOperand(0).getReg();
- for (auto &Op : ConsMI->operands())
+ for (auto &Op : ConsMI.operands())
if (Op.isReg() && Op.isUse() && Op.getReg() == DstReg)
// The MIs depend on each other.
return true;
@@ -1571,7 +1625,7 @@ static bool isDependent(const MachineInstr *ProdMI,
}
// V60 forward scheduling.
-bool HexagonPacketizerList::producesStall(const MachineInstr *I) {
+bool HexagonPacketizerList::producesStall(const MachineInstr &I) {
// Check whether the previous packet is in a different loop. If this is the
// case, there is little point in trying to avoid a stall because that would
// favor the rare case (loop entry) over the common case (loop iteration).
@@ -1581,7 +1635,7 @@ bool HexagonPacketizerList::producesStall(const MachineInstr *I) {
// backedge.
if (!OldPacketMIs.empty()) {
auto *OldBB = OldPacketMIs.front()->getParent();
- auto *ThisBB = I->getParent();
+ auto *ThisBB = I.getParent();
if (MLI->getLoopFor(OldBB) != MLI->getLoopFor(ThisBB))
return false;
}
@@ -1589,9 +1643,9 @@ bool HexagonPacketizerList::producesStall(const MachineInstr *I) {
// Check for stall between two vector instructions.
if (HII->isV60VectorInstruction(I)) {
for (auto J : OldPacketMIs) {
- if (!HII->isV60VectorInstruction(J))
+ if (!HII->isV60VectorInstruction(*J))
continue;
- if (isDependent(J, I) && !HII->isVecUsableNextPacket(J, I))
+ if (isDependent(*J, I) && !HII->isVecUsableNextPacket(*J, I))
return true;
}
return false;
@@ -1601,17 +1655,17 @@ bool HexagonPacketizerList::producesStall(const MachineInstr *I) {
// there is no definition of a use in the current packet, because it
// may be a candidate for .new.
for (auto J : CurrentPacketMIs)
- if (!HII->isV60VectorInstruction(J) && isDependent(J, I))
+ if (!HII->isV60VectorInstruction(*J) && isDependent(*J, I))
return false;
// Check for stall between I and instructions in the previous packet.
if (MF.getSubtarget<HexagonSubtarget>().useBSBScheduling()) {
for (auto J : OldPacketMIs) {
- if (HII->isV60VectorInstruction(J))
+ if (HII->isV60VectorInstruction(*J))
continue;
- if (!HII->isLateInstrFeedsEarlyInstr(J, I))
+ if (!HII->isLateInstrFeedsEarlyInstr(*J, I))
continue;
- if (isDependent(J, I) && !HII->canExecuteInBundle(J, I))
+ if (isDependent(*J, I) && !HII->canExecuteInBundle(*J, I))
return true;
}
}
OpenPOWER on IntegriCloud