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