diff options
Diffstat (limited to 'lib/Target/Hexagon/HexagonInstrInfo.cpp')
| -rw-r--r-- | lib/Target/Hexagon/HexagonInstrInfo.cpp | 1448 |
1 files changed, 757 insertions, 691 deletions
diff --git a/lib/Target/Hexagon/HexagonInstrInfo.cpp b/lib/Target/Hexagon/HexagonInstrInfo.cpp index fe9f97d1d5e76..34ce3e6529958 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -11,18 +11,20 @@ // //===----------------------------------------------------------------------===// +#include "HexagonHazardRecognizer.h" #include "HexagonInstrInfo.h" -#include "Hexagon.h" #include "HexagonRegisterInfo.h" #include "HexagonSubtarget.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/DFAPacketizer.h" +#include "llvm/CodeGen/LivePhysRegs.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/PseudoSourceValue.h" +#include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -39,8 +41,6 @@ using namespace llvm; #include "HexagonGenInstrInfo.inc" #include "HexagonGenDFAPacketizer.inc" -using namespace llvm; - cl::opt<bool> ScheduleInlineAsm("hexagon-sched-inline-asm", cl::Hidden, cl::init(false), cl::desc("Do not consider inline-asm a scheduling/" "packetization boundary.")); @@ -67,6 +67,10 @@ static cl::opt<bool> EnableACCForwarding( static cl::opt<bool> BranchRelaxAsmLarge("branch-relax-asm-large", cl::init(true), cl::Hidden, cl::ZeroOrMore, cl::desc("branch relax asm")); +static cl::opt<bool> UseDFAHazardRec("dfa-hazard-rec", + cl::init(true), cl::Hidden, cl::ZeroOrMore, + cl::desc("Use the DFA based hazard recognizer.")); + /// /// Constants for Hexagon instructions. /// @@ -112,8 +116,8 @@ static bool isIntRegForSubInst(unsigned Reg) { static bool isDblRegForSubInst(unsigned Reg, const HexagonRegisterInfo &HRI) { - return isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::subreg_loreg)) && - isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::subreg_hireg)); + return isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::isub_lo)) && + isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::isub_hi)); } @@ -174,13 +178,13 @@ static MachineInstr *findLoopInstr(MachineBasicBlock *BB, int EndLoopOp, /// Gather register def/uses from MI. /// This treats possible (predicated) defs as actually happening ones /// (conservatively). -static inline void parseOperands(const MachineInstr *MI, +static inline void parseOperands(const MachineInstr &MI, SmallVector<unsigned, 4> &Defs, SmallVector<unsigned, 8> &Uses) { Defs.clear(); Uses.clear(); - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI->getOperand(i); + for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI.getOperand(i); if (!MO.isReg()) continue; @@ -236,10 +240,6 @@ unsigned HexagonInstrInfo::isLoadFromStackSlot(const MachineInstr &MI, switch (MI.getOpcode()) { default: break; - case Hexagon::L2_loadrb_io: - case Hexagon::L2_loadrub_io: - case Hexagon::L2_loadrh_io: - case Hexagon::L2_loadruh_io: case Hexagon::L2_loadri_io: case Hexagon::L2_loadrd_io: case Hexagon::V6_vL32b_ai: @@ -248,14 +248,10 @@ unsigned HexagonInstrInfo::isLoadFromStackSlot(const MachineInstr &MI, case Hexagon::V6_vL32Ub_ai_128B: case Hexagon::LDriw_pred: case Hexagon::LDriw_mod: - case Hexagon::LDriq_pred_V6: - case Hexagon::LDriq_pred_vec_V6: - case Hexagon::LDriv_pseudo_V6: - case Hexagon::LDrivv_pseudo_V6: - case Hexagon::LDriq_pred_V6_128B: - case Hexagon::LDriq_pred_vec_V6_128B: - case Hexagon::LDriv_pseudo_V6_128B: - case Hexagon::LDrivv_pseudo_V6_128B: { + case Hexagon::PS_vloadrq_ai: + case Hexagon::PS_vloadrw_ai: + case Hexagon::PS_vloadrq_ai_128B: + case Hexagon::PS_vloadrw_ai_128B: { const MachineOperand OpFI = MI.getOperand(1); if (!OpFI.isFI()) return 0; @@ -266,14 +262,6 @@ unsigned HexagonInstrInfo::isLoadFromStackSlot(const MachineInstr &MI, return MI.getOperand(0).getReg(); } - case Hexagon::L2_ploadrbt_io: - case Hexagon::L2_ploadrbf_io: - case Hexagon::L2_ploadrubt_io: - case Hexagon::L2_ploadrubf_io: - case Hexagon::L2_ploadrht_io: - case Hexagon::L2_ploadrhf_io: - case Hexagon::L2_ploadruht_io: - case Hexagon::L2_ploadruhf_io: case Hexagon::L2_ploadrit_io: case Hexagon::L2_ploadrif_io: case Hexagon::L2_ploadrdt_io: @@ -313,14 +301,10 @@ unsigned HexagonInstrInfo::isStoreToStackSlot(const MachineInstr &MI, case Hexagon::V6_vS32Ub_ai_128B: case Hexagon::STriw_pred: case Hexagon::STriw_mod: - case Hexagon::STriq_pred_V6: - case Hexagon::STriq_pred_vec_V6: - case Hexagon::STriv_pseudo_V6: - case Hexagon::STrivv_pseudo_V6: - case Hexagon::STriq_pred_V6_128B: - case Hexagon::STriq_pred_vec_V6_128B: - case Hexagon::STriv_pseudo_V6_128B: - case Hexagon::STrivv_pseudo_V6_128B: { + case Hexagon::PS_vstorerq_ai: + case Hexagon::PS_vstorerw_ai: + case Hexagon::PS_vstorerq_ai_128B: + case Hexagon::PS_vstorerw_ai_128B: { const MachineOperand &OpFI = MI.getOperand(0); if (!OpFI.isFI()) return 0; @@ -455,7 +439,7 @@ bool HexagonInstrInfo::analyzeBranch(MachineBasicBlock &MBB, return true; bool LastOpcodeHasJMP_c = PredOpcodeHasJMP_c(LastOpcode); - bool LastOpcodeHasNVJump = isNewValueJump(LastInst); + bool LastOpcodeHasNVJump = isNewValueJump(*LastInst); if (LastOpcodeHasJMP_c && !LastInst->getOperand(1).isMBB()) return true; @@ -493,7 +477,7 @@ bool HexagonInstrInfo::analyzeBranch(MachineBasicBlock &MBB, } bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode); - bool SecLastOpcodeHasNVJump = isNewValueJump(SecondLastInst); + bool SecLastOpcodeHasNVJump = isNewValueJump(*SecondLastInst); if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::J2_jump)) { if (!SecondLastInst->getOperand(1).isMBB()) return true; @@ -541,7 +525,10 @@ bool HexagonInstrInfo::analyzeBranch(MachineBasicBlock &MBB, } -unsigned HexagonInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { +unsigned HexagonInstrInfo::removeBranch(MachineBasicBlock &MBB, + int *BytesRemoved) const { + assert(!BytesRemoved && "code size not handled"); + DEBUG(dbgs() << "\nRemoving branches out of BB#" << MBB.getNumber()); MachineBasicBlock::iterator I = MBB.end(); unsigned Count = 0; @@ -561,17 +548,19 @@ unsigned HexagonInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { return Count; } -unsigned HexagonInstrInfo::InsertBranch(MachineBasicBlock &MBB, +unsigned HexagonInstrInfo::insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, - const DebugLoc &DL) const { + const DebugLoc &DL, + int *BytesAdded) const { unsigned BOpc = Hexagon::J2_jump; unsigned BccOpc = Hexagon::J2_jumpt; assert(validateBranchCond(Cond) && "Invalid branching condition"); - assert(TBB && "InsertBranch must not be told to insert a fallthrough"); + assert(TBB && "insertBranch must not be told to insert a fallthrough"); + assert(!BytesAdded && "code size not handled"); - // Check if ReverseBranchCondition has asked to reverse this branch + // Check if reverseBranchCondition has asked to reverse this branch // If we want to reverse the branch an odd number of times, we want // J2_jumpf. if (!Cond.empty() && Cond[0].isImm()) @@ -587,13 +576,11 @@ unsigned HexagonInstrInfo::InsertBranch(MachineBasicBlock &MBB, SmallVector<MachineOperand, 4> Cond; auto Term = MBB.getFirstTerminator(); if (Term != MBB.end() && isPredicated(*Term) && - !analyzeBranch(MBB, NewTBB, NewFBB, Cond, false)) { - MachineBasicBlock *NextBB = &*++MBB.getIterator(); - if (NewTBB == NextBB) { - ReverseBranchCondition(Cond); - RemoveBranch(MBB); - return InsertBranch(MBB, TBB, nullptr, Cond, DL); - } + !analyzeBranch(MBB, NewTBB, NewFBB, Cond, false) && + MachineFunction::iterator(NewTBB) == ++MBB.getIterator()) { + reverseBranchCondition(Cond); + removeBranch(MBB); + return insertBranch(MBB, TBB, nullptr, Cond, DL); } BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB); } else if (isEndLoopN(Cond[0].getImm())) { @@ -657,6 +644,85 @@ unsigned HexagonInstrInfo::InsertBranch(MachineBasicBlock &MBB, return 2; } +/// Analyze the loop code to find the loop induction variable and compare used +/// to compute the number of iterations. Currently, we analyze loop that are +/// controlled using hardware loops. In this case, the induction variable +/// instruction is null. For all other cases, this function returns true, which +/// means we're unable to analyze it. +bool HexagonInstrInfo::analyzeLoop(MachineLoop &L, + MachineInstr *&IndVarInst, + MachineInstr *&CmpInst) const { + + MachineBasicBlock *LoopEnd = L.getBottomBlock(); + MachineBasicBlock::iterator I = LoopEnd->getFirstTerminator(); + // We really "analyze" only hardware loops right now. + if (I != LoopEnd->end() && isEndLoopN(I->getOpcode())) { + IndVarInst = nullptr; + CmpInst = &*I; + return false; + } + return true; +} + +/// Generate code to reduce the loop iteration by one and check if the loop is +/// finished. Return the value/register of the new loop count. this function +/// assumes the nth iteration is peeled first. +unsigned HexagonInstrInfo::reduceLoopCount(MachineBasicBlock &MBB, + MachineInstr *IndVar, MachineInstr &Cmp, + SmallVectorImpl<MachineOperand> &Cond, + SmallVectorImpl<MachineInstr *> &PrevInsts, + unsigned Iter, unsigned MaxIter) const { + // We expect a hardware loop currently. This means that IndVar is set + // to null, and the compare is the ENDLOOP instruction. + assert((!IndVar) && isEndLoopN(Cmp.getOpcode()) + && "Expecting a hardware loop"); + MachineFunction *MF = MBB.getParent(); + DebugLoc DL = Cmp.getDebugLoc(); + SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs; + MachineInstr *Loop = findLoopInstr(&MBB, Cmp.getOpcode(), VisitedBBs); + if (!Loop) + return 0; + // If the loop trip count is a compile-time value, then just change the + // value. + if (Loop->getOpcode() == Hexagon::J2_loop0i || + Loop->getOpcode() == Hexagon::J2_loop1i) { + int64_t Offset = Loop->getOperand(1).getImm(); + if (Offset <= 1) + Loop->eraseFromParent(); + else + Loop->getOperand(1).setImm(Offset - 1); + return Offset - 1; + } + // The loop trip count is a run-time value. We generate code to subtract + // one from the trip count, and update the loop instruction. + assert(Loop->getOpcode() == Hexagon::J2_loop0r && "Unexpected instruction"); + unsigned LoopCount = Loop->getOperand(1).getReg(); + // Check if we're done with the loop. + unsigned LoopEnd = createVR(MF, MVT::i1); + MachineInstr *NewCmp = BuildMI(&MBB, DL, get(Hexagon::C2_cmpgtui), LoopEnd). + addReg(LoopCount).addImm(1); + unsigned NewLoopCount = createVR(MF, MVT::i32); + MachineInstr *NewAdd = BuildMI(&MBB, DL, get(Hexagon::A2_addi), NewLoopCount). + addReg(LoopCount).addImm(-1); + // Update the previously generated instructions with the new loop counter. + for (SmallVectorImpl<MachineInstr *>::iterator I = PrevInsts.begin(), + E = PrevInsts.end(); I != E; ++I) + (*I)->substituteRegister(LoopCount, NewLoopCount, 0, getRegisterInfo()); + PrevInsts.clear(); + PrevInsts.push_back(NewCmp); + PrevInsts.push_back(NewAdd); + // Insert the new loop instruction if this is the last time the loop is + // decremented. + if (Iter == MaxIter) + BuildMI(&MBB, DL, get(Hexagon::J2_loop0r)). + addMBB(Loop->getOperand(0).getMBB()).addReg(NewLoopCount); + // Delete the old loop instruction. + if (Iter == 0) + Loop->eraseFromParent(); + Cond.push_back(MachineOperand::CreateImm(Hexagon::J2_jumpf)); + Cond.push_back(NewCmp->getOperand(0)); + return NewLoopCount; +} bool HexagonInstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, @@ -743,9 +809,11 @@ void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB, return; } if (Hexagon::VecDblRegsRegClass.contains(SrcReg, DestReg)) { + unsigned LoSrc = HRI.getSubReg(SrcReg, Hexagon::vsub_lo); + unsigned HiSrc = HRI.getSubReg(SrcReg, Hexagon::vsub_hi); BuildMI(MBB, I, DL, get(Hexagon::V6_vcombine), DestReg) - .addReg(HRI.getSubReg(SrcReg, Hexagon::subreg_hireg), KillFlag) - .addReg(HRI.getSubReg(SrcReg, Hexagon::subreg_loreg), KillFlag); + .addReg(HiSrc, KillFlag) + .addReg(LoSrc, KillFlag); return; } if (Hexagon::VecPredRegsRegClass.contains(SrcReg, DestReg)) { @@ -765,12 +833,14 @@ void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB, return; } if (Hexagon::VecPredRegs128BRegClass.contains(SrcReg, DestReg)) { - unsigned DstHi = HRI.getSubReg(DestReg, Hexagon::subreg_hireg); - BuildMI(MBB, I, DL, get(Hexagon::V6_pred_and), DstHi) - .addReg(HRI.getSubReg(SrcReg, Hexagon::subreg_hireg), KillFlag); - unsigned DstLo = HRI.getSubReg(DestReg, Hexagon::subreg_loreg); - BuildMI(MBB, I, DL, get(Hexagon::V6_pred_and), DstLo) - .addReg(HRI.getSubReg(SrcReg, Hexagon::subreg_loreg), KillFlag); + unsigned HiDst = HRI.getSubReg(DestReg, Hexagon::vsub_hi); + unsigned LoDst = HRI.getSubReg(DestReg, Hexagon::vsub_lo); + unsigned HiSrc = HRI.getSubReg(SrcReg, Hexagon::vsub_hi); + unsigned LoSrc = HRI.getSubReg(SrcReg, Hexagon::vsub_lo); + BuildMI(MBB, I, DL, get(Hexagon::V6_pred_and), HiDst) + .addReg(HiSrc, KillFlag); + BuildMI(MBB, I, DL, get(Hexagon::V6_pred_and), LoDst) + .addReg(LoSrc, KillFlag); return; } @@ -789,7 +859,7 @@ void HexagonInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const { DebugLoc DL = MBB.findDebugLoc(I); MachineFunction &MF = *MBB.getParent(); - MachineFrameInfo &MFI = *MF.getFrameInfo(); + MachineFrameInfo &MFI = MF.getFrameInfo(); unsigned Align = MFI.getObjectAlignment(FI); unsigned KillFlag = getKillRegState(isKill); @@ -814,31 +884,35 @@ void HexagonInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, .addFrameIndex(FI).addImm(0) .addReg(SrcReg, KillFlag).addMemOperand(MMO); } else if (Hexagon::VecPredRegs128BRegClass.hasSubClassEq(RC)) { - BuildMI(MBB, I, DL, get(Hexagon::STriq_pred_V6_128B)) + BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerq_ai_128B)) .addFrameIndex(FI).addImm(0) .addReg(SrcReg, KillFlag).addMemOperand(MMO); } else if (Hexagon::VecPredRegsRegClass.hasSubClassEq(RC)) { - BuildMI(MBB, I, DL, get(Hexagon::STriq_pred_V6)) + BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerq_ai)) .addFrameIndex(FI).addImm(0) .addReg(SrcReg, KillFlag).addMemOperand(MMO); } else if (Hexagon::VectorRegs128BRegClass.hasSubClassEq(RC)) { - DEBUG(dbgs() << "++Generating 128B vector spill"); - BuildMI(MBB, I, DL, get(Hexagon::STriv_pseudo_V6_128B)) + unsigned Opc = Align < 128 ? Hexagon::V6_vS32Ub_ai_128B + : Hexagon::V6_vS32b_ai_128B; + BuildMI(MBB, I, DL, get(Opc)) .addFrameIndex(FI).addImm(0) .addReg(SrcReg, KillFlag).addMemOperand(MMO); } else if (Hexagon::VectorRegsRegClass.hasSubClassEq(RC)) { - DEBUG(dbgs() << "++Generating vector spill"); - BuildMI(MBB, I, DL, get(Hexagon::STriv_pseudo_V6)) + unsigned Opc = Align < 64 ? Hexagon::V6_vS32Ub_ai + : Hexagon::V6_vS32b_ai; + BuildMI(MBB, I, DL, get(Opc)) .addFrameIndex(FI).addImm(0) .addReg(SrcReg, KillFlag).addMemOperand(MMO); } else if (Hexagon::VecDblRegsRegClass.hasSubClassEq(RC)) { - DEBUG(dbgs() << "++Generating double vector spill"); - BuildMI(MBB, I, DL, get(Hexagon::STrivv_pseudo_V6)) + unsigned Opc = Align < 64 ? Hexagon::PS_vstorerwu_ai + : Hexagon::PS_vstorerw_ai; + BuildMI(MBB, I, DL, get(Opc)) .addFrameIndex(FI).addImm(0) .addReg(SrcReg, KillFlag).addMemOperand(MMO); } else if (Hexagon::VecDblRegs128BRegClass.hasSubClassEq(RC)) { - DEBUG(dbgs() << "++Generating 128B double vector spill"); - BuildMI(MBB, I, DL, get(Hexagon::STrivv_pseudo_V6_128B)) + unsigned Opc = Align < 128 ? Hexagon::PS_vstorerwu_ai_128B + : Hexagon::PS_vstorerw_ai_128B; + BuildMI(MBB, I, DL, get(Opc)) .addFrameIndex(FI).addImm(0) .addReg(SrcReg, KillFlag).addMemOperand(MMO); } else { @@ -852,7 +926,7 @@ void HexagonInstrInfo::loadRegFromStackSlot( const TargetRegisterInfo *TRI) const { DebugLoc DL = MBB.findDebugLoc(I); MachineFunction &MF = *MBB.getParent(); - MachineFrameInfo &MFI = *MF.getFrameInfo(); + MachineFrameInfo &MFI = MF.getFrameInfo(); unsigned Align = MFI.getObjectAlignment(FI); MachineMemOperand *MMO = MF.getMachineMemOperand( @@ -872,26 +946,30 @@ void HexagonInstrInfo::loadRegFromStackSlot( BuildMI(MBB, I, DL, get(Hexagon::LDriw_mod), DestReg) .addFrameIndex(FI).addImm(0).addMemOperand(MMO); } else if (Hexagon::VecPredRegs128BRegClass.hasSubClassEq(RC)) { - BuildMI(MBB, I, DL, get(Hexagon::LDriq_pred_V6_128B), DestReg) + BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrq_ai_128B), DestReg) .addFrameIndex(FI).addImm(0).addMemOperand(MMO); } else if (Hexagon::VecPredRegsRegClass.hasSubClassEq(RC)) { - BuildMI(MBB, I, DL, get(Hexagon::LDriq_pred_V6), DestReg) + BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrq_ai), DestReg) .addFrameIndex(FI).addImm(0).addMemOperand(MMO); } else if (Hexagon::VecDblRegs128BRegClass.hasSubClassEq(RC)) { - DEBUG(dbgs() << "++Generating 128B double vector restore"); - BuildMI(MBB, I, DL, get(Hexagon::LDrivv_pseudo_V6_128B), DestReg) + unsigned Opc = Align < 128 ? Hexagon::PS_vloadrwu_ai_128B + : Hexagon::PS_vloadrw_ai_128B; + BuildMI(MBB, I, DL, get(Opc), DestReg) .addFrameIndex(FI).addImm(0).addMemOperand(MMO); } else if (Hexagon::VectorRegs128BRegClass.hasSubClassEq(RC)) { - DEBUG(dbgs() << "++Generating 128B vector restore"); - BuildMI(MBB, I, DL, get(Hexagon::LDriv_pseudo_V6_128B), DestReg) + unsigned Opc = Align < 128 ? Hexagon::V6_vL32Ub_ai_128B + : Hexagon::V6_vL32b_ai_128B; + BuildMI(MBB, I, DL, get(Opc), DestReg) .addFrameIndex(FI).addImm(0).addMemOperand(MMO); } else if (Hexagon::VectorRegsRegClass.hasSubClassEq(RC)) { - DEBUG(dbgs() << "++Generating vector restore"); - BuildMI(MBB, I, DL, get(Hexagon::LDriv_pseudo_V6), DestReg) + unsigned Opc = Align < 64 ? Hexagon::V6_vL32Ub_ai + : Hexagon::V6_vL32b_ai; + BuildMI(MBB, I, DL, get(Opc), DestReg) .addFrameIndex(FI).addImm(0).addMemOperand(MMO); } else if (Hexagon::VecDblRegsRegClass.hasSubClassEq(RC)) { - DEBUG(dbgs() << "++Generating double vector restore"); - BuildMI(MBB, I, DL, get(Hexagon::LDrivv_pseudo_V6), DestReg) + unsigned Opc = Align < 64 ? Hexagon::PS_vloadrwu_ai + : Hexagon::PS_vloadrw_ai; + BuildMI(MBB, I, DL, get(Opc), DestReg) .addFrameIndex(FI).addImm(0).addMemOperand(MMO); } else { llvm_unreachable("Can't store this register to stack slot"); @@ -899,6 +977,14 @@ void HexagonInstrInfo::loadRegFromStackSlot( } +static void getLiveRegsAt(LivePhysRegs &Regs, const MachineInstr &MI) { + const MachineBasicBlock &B = *MI.getParent(); + Regs.addLiveOuts(B); + auto E = ++MachineBasicBlock::const_iterator(MI.getIterator()).getReverse(); + for (auto I = B.rbegin(); I != E; ++I) + Regs.stepBackward(*I); +} + /// expandPostRAPseudo - This function is called for all pseudo instructions /// that remain after register allocation. Many pseudo instructions are /// created to help register allocation. This is the place to convert them @@ -912,7 +998,6 @@ bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { DebugLoc DL = MI.getDebugLoc(); unsigned Opc = MI.getOpcode(); const unsigned VecOffset = 1; - bool Is128B = false; switch (Opc) { case TargetOpcode::COPY: { @@ -926,58 +1011,71 @@ bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { MBB.erase(MBBI); return true; } - case Hexagon::ALIGNA: + case Hexagon::PS_aligna: BuildMI(MBB, MI, DL, get(Hexagon::A2_andir), MI.getOperand(0).getReg()) .addReg(HRI.getFrameRegister()) .addImm(-MI.getOperand(1).getImm()); MBB.erase(MI); return true; - case Hexagon::HEXAGON_V6_vassignp_128B: - case Hexagon::HEXAGON_V6_vassignp: { + case Hexagon::V6_vassignp_128B: + case Hexagon::V6_vassignp: { unsigned SrcReg = MI.getOperand(1).getReg(); unsigned DstReg = MI.getOperand(0).getReg(); - if (SrcReg != DstReg) - copyPhysReg(MBB, MI, DL, DstReg, SrcReg, MI.getOperand(1).isKill()); + unsigned Kill = getKillRegState(MI.getOperand(1).isKill()); + BuildMI(MBB, MI, DL, get(Hexagon::V6_vcombine), DstReg) + .addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_hi), Kill) + .addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_lo), Kill); MBB.erase(MI); return true; } - case Hexagon::HEXAGON_V6_lo_128B: - case Hexagon::HEXAGON_V6_lo: { + case Hexagon::V6_lo_128B: + case Hexagon::V6_lo: { unsigned SrcReg = MI.getOperand(1).getReg(); unsigned DstReg = MI.getOperand(0).getReg(); - unsigned SrcSubLo = HRI.getSubReg(SrcReg, Hexagon::subreg_loreg); + unsigned SrcSubLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo); copyPhysReg(MBB, MI, DL, DstReg, SrcSubLo, MI.getOperand(1).isKill()); MBB.erase(MI); MRI.clearKillFlags(SrcSubLo); return true; } - case Hexagon::HEXAGON_V6_hi_128B: - case Hexagon::HEXAGON_V6_hi: { + case Hexagon::V6_hi_128B: + case Hexagon::V6_hi: { unsigned SrcReg = MI.getOperand(1).getReg(); unsigned DstReg = MI.getOperand(0).getReg(); - unsigned SrcSubHi = HRI.getSubReg(SrcReg, Hexagon::subreg_hireg); + unsigned SrcSubHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi); copyPhysReg(MBB, MI, DL, DstReg, SrcSubHi, MI.getOperand(1).isKill()); MBB.erase(MI); MRI.clearKillFlags(SrcSubHi); return true; } - case Hexagon::STrivv_indexed_128B: - Is128B = true; - case Hexagon::STrivv_indexed: { + case Hexagon::PS_vstorerw_ai: + case Hexagon::PS_vstorerwu_ai: + case Hexagon::PS_vstorerw_ai_128B: + case Hexagon::PS_vstorerwu_ai_128B: { + bool Is128B = (Opc == Hexagon::PS_vstorerw_ai_128B || + Opc == Hexagon::PS_vstorerwu_ai_128B); + bool Aligned = (Opc == Hexagon::PS_vstorerw_ai || + Opc == Hexagon::PS_vstorerw_ai_128B); unsigned SrcReg = MI.getOperand(2).getReg(); - unsigned SrcSubHi = HRI.getSubReg(SrcReg, Hexagon::subreg_hireg); - unsigned SrcSubLo = HRI.getSubReg(SrcReg, Hexagon::subreg_loreg); - unsigned NewOpcd = Is128B ? Hexagon::V6_vS32b_ai_128B - : Hexagon::V6_vS32b_ai; + unsigned SrcSubHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi); + unsigned SrcSubLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo); + unsigned NewOpc; + if (Aligned) + NewOpc = Is128B ? Hexagon::V6_vS32b_ai_128B + : Hexagon::V6_vS32b_ai; + else + NewOpc = Is128B ? Hexagon::V6_vS32Ub_ai_128B + : Hexagon::V6_vS32Ub_ai; + unsigned Offset = Is128B ? VecOffset << 7 : VecOffset << 6; MachineInstr *MI1New = - BuildMI(MBB, MI, DL, get(NewOpcd)) + BuildMI(MBB, MI, DL, get(NewOpc)) .addOperand(MI.getOperand(0)) .addImm(MI.getOperand(1).getImm()) .addReg(SrcSubLo) .setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); MI1New->getOperand(0).setIsKill(false); - BuildMI(MBB, MI, DL, get(NewOpcd)) + BuildMI(MBB, MI, DL, get(NewOpc)) .addOperand(MI.getOperand(0)) // The Vectors are indexed in multiples of vector size. .addImm(MI.getOperand(1).getImm() + Offset) @@ -986,23 +1084,32 @@ bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { MBB.erase(MI); return true; } - case Hexagon::LDrivv_pseudo_V6_128B: - case Hexagon::LDrivv_indexed_128B: - Is128B = true; - case Hexagon::LDrivv_pseudo_V6: - case Hexagon::LDrivv_indexed: { - unsigned NewOpcd = Is128B ? Hexagon::V6_vL32b_ai_128B - : Hexagon::V6_vL32b_ai; + case Hexagon::PS_vloadrw_ai: + case Hexagon::PS_vloadrwu_ai: + case Hexagon::PS_vloadrw_ai_128B: + case Hexagon::PS_vloadrwu_ai_128B: { + bool Is128B = (Opc == Hexagon::PS_vloadrw_ai_128B || + Opc == Hexagon::PS_vloadrwu_ai_128B); + bool Aligned = (Opc == Hexagon::PS_vloadrw_ai || + Opc == Hexagon::PS_vloadrw_ai_128B); + unsigned NewOpc; + if (Aligned) + NewOpc = Is128B ? Hexagon::V6_vL32b_ai_128B + : Hexagon::V6_vL32b_ai; + else + NewOpc = Is128B ? Hexagon::V6_vL32Ub_ai_128B + : Hexagon::V6_vL32Ub_ai; + unsigned DstReg = MI.getOperand(0).getReg(); unsigned Offset = Is128B ? VecOffset << 7 : VecOffset << 6; MachineInstr *MI1New = - BuildMI(MBB, MI, DL, get(NewOpcd), - HRI.getSubReg(DstReg, Hexagon::subreg_loreg)) + BuildMI(MBB, MI, DL, get(NewOpc), + HRI.getSubReg(DstReg, Hexagon::vsub_lo)) .addOperand(MI.getOperand(1)) .addImm(MI.getOperand(2).getImm()); MI1New->getOperand(1).setIsKill(false); - BuildMI(MBB, MI, DL, get(NewOpcd), - HRI.getSubReg(DstReg, Hexagon::subreg_hireg)) + BuildMI(MBB, MI, DL, get(NewOpc), + HRI.getSubReg(DstReg, Hexagon::vsub_hi)) .addOperand(MI.getOperand(1)) // The Vectors are indexed in multiples of vector size. .addImm(MI.getOperand(2).getImm() + Offset) @@ -1010,35 +1117,7 @@ bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { MBB.erase(MI); return true; } - case Hexagon::LDriv_pseudo_V6_128B: - Is128B = true; - case Hexagon::LDriv_pseudo_V6: { - unsigned DstReg = MI.getOperand(0).getReg(); - unsigned NewOpc = Is128B ? Hexagon::V6_vL32b_ai_128B - : Hexagon::V6_vL32b_ai; - int32_t Off = MI.getOperand(2).getImm(); - BuildMI(MBB, MI, DL, get(NewOpc), DstReg) - .addOperand(MI.getOperand(1)) - .addImm(Off) - .setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); - MBB.erase(MI); - return true; - } - case Hexagon::STriv_pseudo_V6_128B: - Is128B = true; - case Hexagon::STriv_pseudo_V6: { - unsigned NewOpc = Is128B ? Hexagon::V6_vS32b_ai_128B - : Hexagon::V6_vS32b_ai; - int32_t Off = MI.getOperand(1).getImm(); - BuildMI(MBB, MI, DL, get(NewOpc)) - .addOperand(MI.getOperand(0)) - .addImm(Off) - .addOperand(MI.getOperand(2)) - .setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); - MBB.erase(MI); - return true; - } - case Hexagon::TFR_PdTrue: { + case Hexagon::PS_true: { unsigned Reg = MI.getOperand(0).getReg(); BuildMI(MBB, MI, DL, get(Hexagon::C2_orn), Reg) .addReg(Reg, RegState::Undef) @@ -1046,7 +1125,7 @@ bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { MBB.erase(MI); return true; } - case Hexagon::TFR_PdFalse: { + case Hexagon::PS_false: { unsigned Reg = MI.getOperand(0).getReg(); BuildMI(MBB, MI, DL, get(Hexagon::C2_andn), Reg) .addReg(Reg, RegState::Undef) @@ -1054,21 +1133,21 @@ bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { MBB.erase(MI); return true; } - case Hexagon::VMULW: { + case Hexagon::PS_vmulw: { // Expand a 64-bit vector multiply into 2 32-bit scalar multiplies. unsigned DstReg = MI.getOperand(0).getReg(); unsigned Src1Reg = MI.getOperand(1).getReg(); unsigned Src2Reg = MI.getOperand(2).getReg(); - unsigned Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::subreg_hireg); - unsigned Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::subreg_loreg); - unsigned Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::subreg_hireg); - unsigned Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::subreg_loreg); + unsigned Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::isub_hi); + unsigned Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::isub_lo); + unsigned Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::isub_hi); + unsigned Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::isub_lo); BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_mpyi), - HRI.getSubReg(DstReg, Hexagon::subreg_hireg)) + HRI.getSubReg(DstReg, Hexagon::isub_hi)) .addReg(Src1SubHi) .addReg(Src2SubHi); BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_mpyi), - HRI.getSubReg(DstReg, Hexagon::subreg_loreg)) + HRI.getSubReg(DstReg, Hexagon::isub_lo)) .addReg(Src1SubLo) .addReg(Src2SubLo); MBB.erase(MI); @@ -1078,25 +1157,25 @@ bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { MRI.clearKillFlags(Src2SubLo); return true; } - case Hexagon::VMULW_ACC: { + case Hexagon::PS_vmulw_acc: { // Expand 64-bit vector multiply with addition into 2 scalar multiplies. unsigned DstReg = MI.getOperand(0).getReg(); unsigned Src1Reg = MI.getOperand(1).getReg(); unsigned Src2Reg = MI.getOperand(2).getReg(); unsigned Src3Reg = MI.getOperand(3).getReg(); - unsigned Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::subreg_hireg); - unsigned Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::subreg_loreg); - unsigned Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::subreg_hireg); - unsigned Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::subreg_loreg); - unsigned Src3SubHi = HRI.getSubReg(Src3Reg, Hexagon::subreg_hireg); - unsigned Src3SubLo = HRI.getSubReg(Src3Reg, Hexagon::subreg_loreg); + unsigned Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::isub_hi); + unsigned Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::isub_lo); + unsigned Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::isub_hi); + unsigned Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::isub_lo); + unsigned Src3SubHi = HRI.getSubReg(Src3Reg, Hexagon::isub_hi); + unsigned Src3SubLo = HRI.getSubReg(Src3Reg, Hexagon::isub_lo); BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_maci), - HRI.getSubReg(DstReg, Hexagon::subreg_hireg)) + HRI.getSubReg(DstReg, Hexagon::isub_hi)) .addReg(Src1SubHi) .addReg(Src2SubHi) .addReg(Src3SubHi); BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_maci), - HRI.getSubReg(DstReg, Hexagon::subreg_loreg)) + HRI.getSubReg(DstReg, Hexagon::isub_lo)) .addReg(Src1SubLo) .addReg(Src2SubLo) .addReg(Src3SubLo); @@ -1109,49 +1188,7 @@ bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { MRI.clearKillFlags(Src3SubLo); return true; } - case Hexagon::Insert4: { - unsigned DstReg = MI.getOperand(0).getReg(); - unsigned Src1Reg = MI.getOperand(1).getReg(); - unsigned Src2Reg = MI.getOperand(2).getReg(); - unsigned Src3Reg = MI.getOperand(3).getReg(); - unsigned Src4Reg = MI.getOperand(4).getReg(); - unsigned Src1RegIsKill = getKillRegState(MI.getOperand(1).isKill()); - unsigned Src2RegIsKill = getKillRegState(MI.getOperand(2).isKill()); - unsigned Src3RegIsKill = getKillRegState(MI.getOperand(3).isKill()); - unsigned Src4RegIsKill = getKillRegState(MI.getOperand(4).isKill()); - unsigned DstSubHi = HRI.getSubReg(DstReg, Hexagon::subreg_hireg); - unsigned DstSubLo = HRI.getSubReg(DstReg, Hexagon::subreg_loreg); - BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::S2_insert), - HRI.getSubReg(DstReg, Hexagon::subreg_loreg)) - .addReg(DstSubLo) - .addReg(Src1Reg, Src1RegIsKill) - .addImm(16) - .addImm(0); - BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::S2_insert), - HRI.getSubReg(DstReg, Hexagon::subreg_loreg)) - .addReg(DstSubLo) - .addReg(Src2Reg, Src2RegIsKill) - .addImm(16) - .addImm(16); - BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::S2_insert), - HRI.getSubReg(DstReg, Hexagon::subreg_hireg)) - .addReg(DstSubHi) - .addReg(Src3Reg, Src3RegIsKill) - .addImm(16) - .addImm(0); - BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::S2_insert), - HRI.getSubReg(DstReg, Hexagon::subreg_hireg)) - .addReg(DstSubHi) - .addReg(Src4Reg, Src4RegIsKill) - .addImm(16) - .addImm(16); - MBB.erase(MI); - MRI.clearKillFlags(DstReg); - MRI.clearKillFlags(DstSubHi); - MRI.clearKillFlags(DstSubLo); - return true; - } - case Hexagon::MUX64_rr: { + case Hexagon::PS_pselect: { const MachineOperand &Op0 = MI.getOperand(0); const MachineOperand &Op1 = MI.getOperand(1); const MachineOperand &Op2 = MI.getOperand(2); @@ -1175,64 +1212,96 @@ bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { MBB.erase(MI); return true; } - case Hexagon::VSelectPseudo_V6: { + case Hexagon::PS_vselect: + case Hexagon::PS_vselect_128B: { const MachineOperand &Op0 = MI.getOperand(0); const MachineOperand &Op1 = MI.getOperand(1); const MachineOperand &Op2 = MI.getOperand(2); const MachineOperand &Op3 = MI.getOperand(3); - BuildMI(MBB, MI, DL, get(Hexagon::V6_vcmov)) - .addOperand(Op0) - .addOperand(Op1) - .addOperand(Op2); - BuildMI(MBB, MI, DL, get(Hexagon::V6_vncmov)) - .addOperand(Op0) - .addOperand(Op1) - .addOperand(Op3); + LivePhysRegs LiveAtMI(&HRI); + getLiveRegsAt(LiveAtMI, MI); + bool IsDestLive = !LiveAtMI.available(MRI, Op0.getReg()); + if (Op0.getReg() != Op2.getReg()) { + auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vcmov)) + .addOperand(Op0) + .addOperand(Op1) + .addOperand(Op2); + if (IsDestLive) + T.addReg(Op0.getReg(), RegState::Implicit); + IsDestLive = true; + } + if (Op0.getReg() != Op3.getReg()) { + auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vncmov)) + .addOperand(Op0) + .addOperand(Op1) + .addOperand(Op3); + if (IsDestLive) + T.addReg(Op0.getReg(), RegState::Implicit); + } MBB.erase(MI); return true; } - case Hexagon::VSelectDblPseudo_V6: { + case Hexagon::PS_wselect: + case Hexagon::PS_wselect_128B: { MachineOperand &Op0 = MI.getOperand(0); MachineOperand &Op1 = MI.getOperand(1); MachineOperand &Op2 = MI.getOperand(2); MachineOperand &Op3 = MI.getOperand(3); - unsigned SrcLo = HRI.getSubReg(Op2.getReg(), Hexagon::subreg_loreg); - unsigned SrcHi = HRI.getSubReg(Op2.getReg(), Hexagon::subreg_hireg); - BuildMI(MBB, MI, DL, get(Hexagon::V6_vccombine)) - .addOperand(Op0) - .addOperand(Op1) - .addReg(SrcHi) - .addReg(SrcLo); - SrcLo = HRI.getSubReg(Op3.getReg(), Hexagon::subreg_loreg); - SrcHi = HRI.getSubReg(Op3.getReg(), Hexagon::subreg_hireg); - BuildMI(MBB, MI, DL, get(Hexagon::V6_vnccombine)) - .addOperand(Op0) - .addOperand(Op1) - .addReg(SrcHi) - .addReg(SrcLo); + LivePhysRegs LiveAtMI(&HRI); + getLiveRegsAt(LiveAtMI, MI); + bool IsDestLive = !LiveAtMI.available(MRI, Op0.getReg()); + + if (Op0.getReg() != Op2.getReg()) { + unsigned SrcLo = HRI.getSubReg(Op2.getReg(), Hexagon::vsub_lo); + unsigned SrcHi = HRI.getSubReg(Op2.getReg(), Hexagon::vsub_hi); + auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vccombine)) + .addOperand(Op0) + .addOperand(Op1) + .addReg(SrcHi) + .addReg(SrcLo); + if (IsDestLive) + T.addReg(Op0.getReg(), RegState::Implicit); + IsDestLive = true; + } + if (Op0.getReg() != Op3.getReg()) { + unsigned SrcLo = HRI.getSubReg(Op3.getReg(), Hexagon::vsub_lo); + unsigned SrcHi = HRI.getSubReg(Op3.getReg(), Hexagon::vsub_hi); + auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vnccombine)) + .addOperand(Op0) + .addOperand(Op1) + .addReg(SrcHi) + .addReg(SrcLo); + if (IsDestLive) + T.addReg(Op0.getReg(), RegState::Implicit); + } MBB.erase(MI); return true; } - case Hexagon::TCRETURNi: + case Hexagon::PS_tailcall_i: MI.setDesc(get(Hexagon::J2_jump)); return true; - case Hexagon::TCRETURNr: + case Hexagon::PS_tailcall_r: + case Hexagon::PS_jmpret: MI.setDesc(get(Hexagon::J2_jumpr)); return true; - case Hexagon::TFRI_f: - case Hexagon::TFRI_cPt_f: - case Hexagon::TFRI_cNotPt_f: { - unsigned Opx = (Opc == Hexagon::TFRI_f) ? 1 : 2; - APFloat FVal = MI.getOperand(Opx).getFPImm()->getValueAPF(); - APInt IVal = FVal.bitcastToAPInt(); - MI.RemoveOperand(Opx); - unsigned NewOpc = (Opc == Hexagon::TFRI_f) ? Hexagon::A2_tfrsi : - (Opc == Hexagon::TFRI_cPt_f) ? Hexagon::C2_cmoveit : - Hexagon::C2_cmoveif; - MI.setDesc(get(NewOpc)); - MI.addOperand(MachineOperand::CreateImm(IVal.getZExtValue())); + case Hexagon::PS_jmprett: + MI.setDesc(get(Hexagon::J2_jumprt)); + return true; + case Hexagon::PS_jmpretf: + MI.setDesc(get(Hexagon::J2_jumprf)); + return true; + case Hexagon::PS_jmprettnewpt: + MI.setDesc(get(Hexagon::J2_jumprtnewpt)); + return true; + case Hexagon::PS_jmpretfnewpt: + MI.setDesc(get(Hexagon::J2_jumprfnewpt)); + return true; + case Hexagon::PS_jmprettnew: + MI.setDesc(get(Hexagon::J2_jumprtnew)); + return true; + case Hexagon::PS_jmpretfnew: + MI.setDesc(get(Hexagon::J2_jumprfnew)); return true; - } } return false; @@ -1241,7 +1310,7 @@ bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { // We indicate that we want to reverse the branch by // inserting the reversed branching opcode. -bool HexagonInstrInfo::ReverseBranchCondition( +bool HexagonInstrInfo::reverseBranchCondition( SmallVectorImpl<MachineOperand> &Cond) const { if (Cond.empty()) return true; @@ -1264,6 +1333,11 @@ void HexagonInstrInfo::insertNoop(MachineBasicBlock &MBB, } +bool HexagonInstrInfo::isPostIncrement(const MachineInstr &MI) const { + return getAddrMode(MI) == HexagonII::PostInc; +} + + // Returns true if an instruction is predicated irrespective of the predicate // sense. For example, all of the following will return true. // if (p0) R1 = add(R2, R3) @@ -1372,6 +1446,9 @@ bool HexagonInstrInfo::isSchedulingBoundary(const MachineInstr &MI, // Throwing call is a boundary. if (MI.isCall()) { + // Don't mess around with no return calls. + if (doesNotReturn(MI)) + return true; // If any of the block's successors is a landing pad, this could be a // throwing call. for (auto I : MBB->successors()) @@ -1379,10 +1456,6 @@ bool HexagonInstrInfo::isSchedulingBoundary(const MachineInstr &MI, return true; } - // Don't mess around with no return calls. - if (MI.getOpcode() == Hexagon::CALLv3nr) - return true; - // Terminators and labels can't be scheduled around. if (MI.getDesc().isTerminator() || MI.isPosition()) return true; @@ -1418,8 +1491,8 @@ unsigned HexagonInstrInfo::getInlineAsmLength(const char *Str, Length += MAI.getMaxInstLength(); atInsnStart = false; } - if (atInsnStart && strncmp(Str, MAI.getCommentString(), - strlen(MAI.getCommentString())) == 0) + if (atInsnStart && strncmp(Str, MAI.getCommentString().data(), + MAI.getCommentString().size()) == 0) atInsnStart = false; } @@ -1433,6 +1506,10 @@ unsigned HexagonInstrInfo::getInlineAsmLength(const char *Str, ScheduleHazardRecognizer* HexagonInstrInfo::CreateTargetPostRAHazardRecognizer( const InstrItineraryData *II, const ScheduleDAG *DAG) const { + if (UseDFAHazardRec) { + auto &HST = DAG->MF.getSubtarget<HexagonSubtarget>(); + return new HexagonHazardRecognizer(II, this, HST); + } return TargetInstrInfo::CreateTargetPostRAHazardRecognizer(II, DAG); } @@ -1529,7 +1606,7 @@ bool HexagonInstrInfo::analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, unsigned HexagonInstrInfo::getInstrLatency(const InstrItineraryData *ItinData, const MachineInstr &MI, unsigned *PredCost) const { - return getInstrTimingClassLatency(ItinData, &MI); + return getInstrTimingClassLatency(ItinData, MI); } @@ -1555,16 +1632,16 @@ bool HexagonInstrInfo::areMemAccessesTriviallyDisjoint( // Instructions that are pure loads, not loads and stores like memops are not // dependent. - if (MIa.mayLoad() && !isMemOp(&MIa) && MIb.mayLoad() && !isMemOp(&MIb)) + if (MIa.mayLoad() && !isMemOp(MIa) && MIb.mayLoad() && !isMemOp(MIb)) return true; // Get base, offset, and access size in MIa. - unsigned BaseRegA = getBaseAndOffset(&MIa, OffsetA, SizeA); + unsigned BaseRegA = getBaseAndOffset(MIa, OffsetA, SizeA); if (!BaseRegA || !SizeA) return false; // Get base, offset, and access size in MIb. - unsigned BaseRegB = getBaseAndOffset(&MIb, OffsetB, SizeB); + unsigned BaseRegB = getBaseAndOffset(MIb, OffsetB, SizeB); if (!BaseRegB || !SizeB) return false; @@ -1585,7 +1662,23 @@ bool HexagonInstrInfo::areMemAccessesTriviallyDisjoint( } -unsigned HexagonInstrInfo::createVR(MachineFunction* MF, MVT VT) const { +/// If the instruction is an increment of a constant value, return the amount. +bool HexagonInstrInfo::getIncrementValue(const MachineInstr &MI, + int &Value) const { + if (isPostIncrement(MI)) { + unsigned AccessSize; + return getBaseAndOffset(MI, Value, AccessSize); + } + if (MI.getOpcode() == Hexagon::A2_addi) { + Value = MI.getOperand(2).getImm(); + return true; + } + + return false; +} + + +unsigned HexagonInstrInfo::createVR(MachineFunction *MF, MVT VT) const { MachineRegisterInfo &MRI = MF->getRegInfo(); const TargetRegisterClass *TRC; if (VT == MVT::i1) { @@ -1603,32 +1696,32 @@ unsigned HexagonInstrInfo::createVR(MachineFunction* MF, MVT VT) const { } -bool HexagonInstrInfo::isAbsoluteSet(const MachineInstr* MI) const { +bool HexagonInstrInfo::isAbsoluteSet(const MachineInstr &MI) const { return (getAddrMode(MI) == HexagonII::AbsoluteSet); } -bool HexagonInstrInfo::isAccumulator(const MachineInstr *MI) const { - const uint64_t F = MI->getDesc().TSFlags; +bool HexagonInstrInfo::isAccumulator(const MachineInstr &MI) const { + const uint64_t F = MI.getDesc().TSFlags; return((F >> HexagonII::AccumulatorPos) & HexagonII::AccumulatorMask); } -bool HexagonInstrInfo::isComplex(const MachineInstr *MI) const { - const MachineFunction *MF = MI->getParent()->getParent(); +bool HexagonInstrInfo::isComplex(const MachineInstr &MI) const { + const MachineFunction *MF = MI.getParent()->getParent(); const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; if (!(isTC1(MI)) && !(QII->isTC2Early(MI)) - && !(MI->getDesc().mayLoad()) - && !(MI->getDesc().mayStore()) - && (MI->getDesc().getOpcode() != Hexagon::S2_allocframe) - && (MI->getDesc().getOpcode() != Hexagon::L2_deallocframe) + && !(MI.getDesc().mayLoad()) + && !(MI.getDesc().mayStore()) + && (MI.getDesc().getOpcode() != Hexagon::S2_allocframe) + && (MI.getDesc().getOpcode() != Hexagon::L2_deallocframe) && !(QII->isMemOp(MI)) - && !(MI->isBranch()) - && !(MI->isReturn()) - && !MI->isCall()) + && !(MI.isBranch()) + && !(MI.isReturn()) + && !MI.isCall()) return true; return false; @@ -1636,24 +1729,24 @@ bool HexagonInstrInfo::isComplex(const MachineInstr *MI) const { // Return true if the instruction is a compund branch instruction. -bool HexagonInstrInfo::isCompoundBranchInstr(const MachineInstr *MI) const { - return (getType(MI) == HexagonII::TypeCOMPOUND && MI->isBranch()); +bool HexagonInstrInfo::isCompoundBranchInstr(const MachineInstr &MI) const { + return (getType(MI) == HexagonII::TypeCOMPOUND && MI.isBranch()); } -bool HexagonInstrInfo::isCondInst(const MachineInstr *MI) const { - return (MI->isBranch() && isPredicated(*MI)) || +bool HexagonInstrInfo::isCondInst(const MachineInstr &MI) const { + return (MI.isBranch() && isPredicated(MI)) || isConditionalTransfer(MI) || isConditionalALU32(MI) || isConditionalLoad(MI) || // Predicated stores which don't have a .new on any operands. - (MI->mayStore() && isPredicated(*MI) && !isNewValueStore(MI) && - !isPredicatedNew(*MI)); + (MI.mayStore() && isPredicated(MI) && !isNewValueStore(MI) && + !isPredicatedNew(MI)); } -bool HexagonInstrInfo::isConditionalALU32(const MachineInstr* MI) const { - switch (MI->getOpcode()) { +bool HexagonInstrInfo::isConditionalALU32(const MachineInstr &MI) const { + switch (MI.getOpcode()) { case Hexagon::A2_paddf: case Hexagon::A2_paddfnew: case Hexagon::A2_paddif: @@ -1712,11 +1805,11 @@ bool HexagonInstrInfo::isConditionalALU32(const MachineInstr* MI) const { // FIXME - Function name and it's functionality don't match. // It should be renamed to hasPredNewOpcode() -bool HexagonInstrInfo::isConditionalLoad(const MachineInstr* MI) const { - if (!MI->getDesc().mayLoad() || !isPredicated(*MI)) +bool HexagonInstrInfo::isConditionalLoad(const MachineInstr &MI) const { + if (!MI.getDesc().mayLoad() || !isPredicated(MI)) return false; - int PNewOpcode = Hexagon::getPredNewOpcode(MI->getOpcode()); + int PNewOpcode = Hexagon::getPredNewOpcode(MI.getOpcode()); // Instruction with valid predicated-new opcode can be promoted to .new. return PNewOpcode >= 0; } @@ -1726,8 +1819,8 @@ bool HexagonInstrInfo::isConditionalLoad(const MachineInstr* MI) const { // // Note: It doesn't include conditional new-value stores as they can't be // converted to .new predicate. -bool HexagonInstrInfo::isConditionalStore(const MachineInstr* MI) const { - switch (MI->getOpcode()) { +bool HexagonInstrInfo::isConditionalStore(const MachineInstr &MI) const { + switch (MI.getOpcode()) { default: return false; case Hexagon::S4_storeirbt_io: case Hexagon::S4_storeirbf_io: @@ -1780,8 +1873,8 @@ bool HexagonInstrInfo::isConditionalStore(const MachineInstr* MI) const { } -bool HexagonInstrInfo::isConditionalTransfer(const MachineInstr *MI) const { - switch (MI->getOpcode()) { +bool HexagonInstrInfo::isConditionalTransfer(const MachineInstr &MI) const { + switch (MI.getOpcode()) { case Hexagon::A2_tfrt: case Hexagon::A2_tfrf: case Hexagon::C2_cmoveit: @@ -1803,8 +1896,8 @@ bool HexagonInstrInfo::isConditionalTransfer(const MachineInstr *MI) const { // TODO: In order to have isExtendable for fpimm/f32Ext, we need to handle // isFPImm and later getFPImm as well. -bool HexagonInstrInfo::isConstExtended(const MachineInstr *MI) const { - const uint64_t F = MI->getDesc().TSFlags; +bool HexagonInstrInfo::isConstExtended(const MachineInstr &MI) const { + const uint64_t F = MI.getDesc().TSFlags; unsigned isExtended = (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask; if (isExtended) // Instruction must be extended. return true; @@ -1814,11 +1907,11 @@ bool HexagonInstrInfo::isConstExtended(const MachineInstr *MI) const { if (!isExtendable) return false; - if (MI->isCall()) + if (MI.isCall()) return false; short ExtOpNum = getCExtOpNum(MI); - const MachineOperand &MO = MI->getOperand(ExtOpNum); + const MachineOperand &MO = MI.getOperand(ExtOpNum); // Use MO operand flags to determine if MO // has the HMOTF_ConstExtended flag set. if (MO.getTargetFlags() && HexagonII::HMOTF_ConstExtended) @@ -1835,7 +1928,7 @@ bool HexagonInstrInfo::isConstExtended(const MachineInstr *MI) const { // object we are going to end up with here for now. // In the future we probably should add isSymbol(), etc. if (MO.isGlobal() || MO.isSymbol() || MO.isBlockAddress() || - MO.isJTI() || MO.isCPI()) + MO.isJTI() || MO.isCPI() || MO.isFPImm()) return true; // If the extendable operand is not 'Immediate' type, the instruction should @@ -1850,8 +1943,8 @@ bool HexagonInstrInfo::isConstExtended(const MachineInstr *MI) const { } -bool HexagonInstrInfo::isDeallocRet(const MachineInstr *MI) const { - switch (MI->getOpcode()) { +bool HexagonInstrInfo::isDeallocRet(const MachineInstr &MI) const { + switch (MI.getOpcode()) { case Hexagon::L4_return : case Hexagon::L4_return_t : case Hexagon::L4_return_f : @@ -1866,10 +1959,9 @@ bool HexagonInstrInfo::isDeallocRet(const MachineInstr *MI) const { // Return true when ConsMI uses a register defined by ProdMI. -bool HexagonInstrInfo::isDependent(const MachineInstr *ProdMI, - const MachineInstr *ConsMI) const { - const MCInstrDesc &ProdMCID = ProdMI->getDesc(); - if (!ProdMCID.getNumDefs()) +bool HexagonInstrInfo::isDependent(const MachineInstr &ProdMI, + const MachineInstr &ConsMI) const { + if (!ProdMI.getDesc().getNumDefs()) return false; auto &HRI = getRegisterInfo(); @@ -1904,8 +1996,8 @@ bool HexagonInstrInfo::isDependent(const MachineInstr *ProdMI, // Returns true if the instruction is alread a .cur. -bool HexagonInstrInfo::isDotCurInst(const MachineInstr* MI) const { - switch (MI->getOpcode()) { +bool HexagonInstrInfo::isDotCurInst(const MachineInstr &MI) const { + switch (MI.getOpcode()) { case Hexagon::V6_vL32b_cur_pi: case Hexagon::V6_vL32b_cur_ai: case Hexagon::V6_vL32b_cur_pi_128B: @@ -1918,8 +2010,8 @@ bool HexagonInstrInfo::isDotCurInst(const MachineInstr* MI) const { // Returns true, if any one of the operands is a dot new // insn, whether it is predicated dot new or register dot new. -bool HexagonInstrInfo::isDotNewInst(const MachineInstr* MI) const { - if (isNewValueInst(MI) || (isPredicated(*MI) && isPredicatedNew(*MI))) +bool HexagonInstrInfo::isDotNewInst(const MachineInstr &MI) const { + if (isNewValueInst(MI) || (isPredicated(MI) && isPredicatedNew(MI))) return true; return false; @@ -1927,23 +2019,20 @@ bool HexagonInstrInfo::isDotNewInst(const MachineInstr* MI) const { /// Symmetrical. See if these two instructions are fit for duplex pair. -bool HexagonInstrInfo::isDuplexPair(const MachineInstr *MIa, - const MachineInstr *MIb) const { +bool HexagonInstrInfo::isDuplexPair(const MachineInstr &MIa, + const MachineInstr &MIb) const { HexagonII::SubInstructionGroup MIaG = getDuplexCandidateGroup(MIa); HexagonII::SubInstructionGroup MIbG = getDuplexCandidateGroup(MIb); return (isDuplexPairMatch(MIaG, MIbG) || isDuplexPairMatch(MIbG, MIaG)); } -bool HexagonInstrInfo::isEarlySourceInstr(const MachineInstr *MI) const { - if (!MI) - return false; - - if (MI->mayLoad() || MI->mayStore() || MI->isCompare()) +bool HexagonInstrInfo::isEarlySourceInstr(const MachineInstr &MI) const { + if (MI.mayLoad() || MI.mayStore() || MI.isCompare()) return true; // Multiply - unsigned SchedClass = MI->getDesc().getSchedClass(); + unsigned SchedClass = MI.getDesc().getSchedClass(); if (SchedClass == Hexagon::Sched::M_tc_3or4x_SLOT23) return true; return false; @@ -1971,17 +2060,18 @@ bool HexagonInstrInfo::isExpr(unsigned OpType) const { } -bool HexagonInstrInfo::isExtendable(const MachineInstr *MI) const { - const MCInstrDesc &MID = MI->getDesc(); +bool HexagonInstrInfo::isExtendable(const MachineInstr &MI) const { + const MCInstrDesc &MID = MI.getDesc(); const uint64_t F = MID.TSFlags; if ((F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask) return true; // TODO: This is largely obsolete now. Will need to be removed // in consecutive patches. - switch(MI->getOpcode()) { - // TFR_FI Remains a special case. - case Hexagon::TFR_FI: + switch (MI.getOpcode()) { + // PS_fi and PS_fia remain special cases. + case Hexagon::PS_fi: + case Hexagon::PS_fia: return true; default: return false; @@ -1993,15 +2083,15 @@ bool HexagonInstrInfo::isExtendable(const MachineInstr *MI) const { // This returns true in two cases: // - The OP code itself indicates that this is an extended instruction. // - One of MOs has been marked with HMOTF_ConstExtended flag. -bool HexagonInstrInfo::isExtended(const MachineInstr *MI) const { +bool HexagonInstrInfo::isExtended(const MachineInstr &MI) const { // First check if this is permanently extended op code. - const uint64_t F = MI->getDesc().TSFlags; + const uint64_t F = MI.getDesc().TSFlags; if ((F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask) return true; // Use MO operand flags to determine if one of MI's operands // has HMOTF_ConstExtended flag set. - for (MachineInstr::const_mop_iterator I = MI->operands_begin(), - E = MI->operands_end(); I != E; ++I) { + for (MachineInstr::const_mop_iterator I = MI.operands_begin(), + E = MI.operands_end(); I != E; ++I) { if (I->getTargetFlags() && HexagonII::HMOTF_ConstExtended) return true; } @@ -2009,37 +2099,38 @@ bool HexagonInstrInfo::isExtended(const MachineInstr *MI) const { } -bool HexagonInstrInfo::isFloat(const MachineInstr *MI) const { - unsigned Opcode = MI->getOpcode(); +bool HexagonInstrInfo::isFloat(const MachineInstr &MI) const { + unsigned Opcode = MI.getOpcode(); const uint64_t F = get(Opcode).TSFlags; return (F >> HexagonII::FPPos) & HexagonII::FPMask; } // No V60 HVX VMEM with A_INDIRECT. -bool HexagonInstrInfo::isHVXMemWithAIndirect(const MachineInstr *I, - const MachineInstr *J) const { +bool HexagonInstrInfo::isHVXMemWithAIndirect(const MachineInstr &I, + const MachineInstr &J) const { if (!isV60VectorInstruction(I)) return false; - if (!I->mayLoad() && !I->mayStore()) + if (!I.mayLoad() && !I.mayStore()) return false; - return J->isIndirectBranch() || isIndirectCall(J) || isIndirectL4Return(J); + return J.isIndirectBranch() || isIndirectCall(J) || isIndirectL4Return(J); } -bool HexagonInstrInfo::isIndirectCall(const MachineInstr *MI) const { - switch (MI->getOpcode()) { +bool HexagonInstrInfo::isIndirectCall(const MachineInstr &MI) const { + switch (MI.getOpcode()) { case Hexagon::J2_callr : case Hexagon::J2_callrf : case Hexagon::J2_callrt : + case Hexagon::PS_call_nr : return true; } return false; } -bool HexagonInstrInfo::isIndirectL4Return(const MachineInstr *MI) const { - switch (MI->getOpcode()) { +bool HexagonInstrInfo::isIndirectL4Return(const MachineInstr &MI) const { + switch (MI.getOpcode()) { case Hexagon::L4_return : case Hexagon::L4_return_t : case Hexagon::L4_return_f : @@ -2053,8 +2144,8 @@ bool HexagonInstrInfo::isIndirectL4Return(const MachineInstr *MI) const { } -bool HexagonInstrInfo::isJumpR(const MachineInstr *MI) const { - switch (MI->getOpcode()) { +bool HexagonInstrInfo::isJumpR(const MachineInstr &MI) const { + switch (MI.getOpcode()) { case Hexagon::J2_jumpr : case Hexagon::J2_jumprt : case Hexagon::J2_jumprf : @@ -2068,24 +2159,24 @@ bool HexagonInstrInfo::isJumpR(const MachineInstr *MI) const { } -// Return true if a given MI can accomodate given offset. +// Return true if a given MI can accommodate given offset. // Use abs estimate as oppose to the exact number. // TODO: This will need to be changed to use MC level // definition of instruction extendable field size. -bool HexagonInstrInfo::isJumpWithinBranchRange(const MachineInstr *MI, +bool HexagonInstrInfo::isJumpWithinBranchRange(const MachineInstr &MI, unsigned offset) const { // This selection of jump instructions matches to that what // AnalyzeBranch can parse, plus NVJ. if (isNewValueJump(MI)) // r9:2 return isInt<11>(offset); - switch (MI->getOpcode()) { + switch (MI.getOpcode()) { // Still missing Jump to address condition on register value. default: return false; case Hexagon::J2_jump: // bits<24> dst; // r22:2 case Hexagon::J2_call: - case Hexagon::CALLv3nr: + case Hexagon::PS_call_nr: return isInt<24>(offset); case Hexagon::J2_jumpt: //bits<17> dst; // r15:2 case Hexagon::J2_jumpf: @@ -2113,18 +2204,15 @@ bool HexagonInstrInfo::isJumpWithinBranchRange(const MachineInstr *MI, } -bool HexagonInstrInfo::isLateInstrFeedsEarlyInstr(const MachineInstr *LRMI, - const MachineInstr *ESMI) const { - if (!LRMI || !ESMI) - return false; - +bool HexagonInstrInfo::isLateInstrFeedsEarlyInstr(const MachineInstr &LRMI, + const MachineInstr &ESMI) const { bool isLate = isLateResultInstr(LRMI); bool isEarly = isEarlySourceInstr(ESMI); DEBUG(dbgs() << "V60" << (isLate ? "-LR " : " -- ")); - DEBUG(LRMI->dump()); + DEBUG(LRMI.dump()); DEBUG(dbgs() << "V60" << (isEarly ? "-ES " : " -- ")); - DEBUG(ESMI->dump()); + DEBUG(ESMI.dump()); if (isLate && isEarly) { DEBUG(dbgs() << "++Is Late Result feeding Early Source\n"); @@ -2135,11 +2223,8 @@ bool HexagonInstrInfo::isLateInstrFeedsEarlyInstr(const MachineInstr *LRMI, } -bool HexagonInstrInfo::isLateResultInstr(const MachineInstr *MI) const { - if (!MI) - return false; - - switch (MI->getOpcode()) { +bool HexagonInstrInfo::isLateResultInstr(const MachineInstr &MI) const { + switch (MI.getOpcode()) { case TargetOpcode::EXTRACT_SUBREG: case TargetOpcode::INSERT_SUBREG: case TargetOpcode::SUBREG_TO_REG: @@ -2153,7 +2238,7 @@ bool HexagonInstrInfo::isLateResultInstr(const MachineInstr *MI) const { break; } - unsigned SchedClass = MI->getDesc().getSchedClass(); + unsigned SchedClass = MI.getDesc().getSchedClass(); switch (SchedClass) { case Hexagon::Sched::ALU32_2op_tc_1_SLOT0123: @@ -2175,18 +2260,15 @@ bool HexagonInstrInfo::isLateResultInstr(const MachineInstr *MI) const { } -bool HexagonInstrInfo::isLateSourceInstr(const MachineInstr *MI) const { - if (!MI) - return false; - +bool HexagonInstrInfo::isLateSourceInstr(const MachineInstr &MI) const { // Instructions with iclass A_CVI_VX and attribute A_CVI_LATE uses a multiply // resource, but all operands can be received late like an ALU instruction. - return MI->getDesc().getSchedClass() == Hexagon::Sched::CVI_VX_LATE; + return MI.getDesc().getSchedClass() == Hexagon::Sched::CVI_VX_LATE; } -bool HexagonInstrInfo::isLoopN(const MachineInstr *MI) const { - unsigned Opcode = MI->getOpcode(); +bool HexagonInstrInfo::isLoopN(const MachineInstr &MI) const { + unsigned Opcode = MI.getOpcode(); return Opcode == Hexagon::J2_loop0i || Opcode == Hexagon::J2_loop0r || Opcode == Hexagon::J2_loop0iext || @@ -2198,8 +2280,8 @@ bool HexagonInstrInfo::isLoopN(const MachineInstr *MI) const { } -bool HexagonInstrInfo::isMemOp(const MachineInstr *MI) const { - switch (MI->getOpcode()) { +bool HexagonInstrInfo::isMemOp(const MachineInstr &MI) const { + switch (MI.getOpcode()) { default: return false; case Hexagon::L4_iadd_memopw_io : case Hexagon::L4_isub_memopw_io : @@ -2231,8 +2313,8 @@ bool HexagonInstrInfo::isMemOp(const MachineInstr *MI) const { } -bool HexagonInstrInfo::isNewValue(const MachineInstr* MI) const { - const uint64_t F = MI->getDesc().TSFlags; +bool HexagonInstrInfo::isNewValue(const MachineInstr &MI) const { + const uint64_t F = MI.getDesc().TSFlags; return (F >> HexagonII::NewValuePos) & HexagonII::NewValueMask; } @@ -2243,13 +2325,13 @@ bool HexagonInstrInfo::isNewValue(unsigned Opcode) const { } -bool HexagonInstrInfo::isNewValueInst(const MachineInstr *MI) const { +bool HexagonInstrInfo::isNewValueInst(const MachineInstr &MI) const { return isNewValueJump(MI) || isNewValueStore(MI); } -bool HexagonInstrInfo::isNewValueJump(const MachineInstr *MI) const { - return isNewValue(MI) && MI->isBranch(); +bool HexagonInstrInfo::isNewValueJump(const MachineInstr &MI) const { + return isNewValue(MI) && MI.isBranch(); } @@ -2258,8 +2340,8 @@ bool HexagonInstrInfo::isNewValueJump(unsigned Opcode) const { } -bool HexagonInstrInfo::isNewValueStore(const MachineInstr *MI) const { - const uint64_t F = MI->getDesc().TSFlags; +bool HexagonInstrInfo::isNewValueStore(const MachineInstr &MI) const { + const uint64_t F = MI.getDesc().TSFlags; return (F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask; } @@ -2271,19 +2353,14 @@ bool HexagonInstrInfo::isNewValueStore(unsigned Opcode) const { // Returns true if a particular operand is extendable for an instruction. -bool HexagonInstrInfo::isOperandExtended(const MachineInstr *MI, +bool HexagonInstrInfo::isOperandExtended(const MachineInstr &MI, unsigned OperandNum) const { - const uint64_t F = MI->getDesc().TSFlags; + const uint64_t F = MI.getDesc().TSFlags; return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask) == OperandNum; } -bool HexagonInstrInfo::isPostIncrement(const MachineInstr* MI) const { - return getAddrMode(MI) == HexagonII::PostInc; -} - - bool HexagonInstrInfo::isPredicatedNew(const MachineInstr &MI) const { const uint64_t F = MI.getDesc().TSFlags; assert(isPredicated(MI)); @@ -2334,11 +2411,11 @@ bool HexagonInstrInfo::isPredictedTaken(unsigned Opcode) const { } -bool HexagonInstrInfo::isSaveCalleeSavedRegsCall(const MachineInstr *MI) const { - return MI->getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4 || - MI->getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT || - MI->getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_PIC || - MI->getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC; +bool HexagonInstrInfo::isSaveCalleeSavedRegsCall(const MachineInstr &MI) const { + return MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4 || + MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT || + MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_PIC || + MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC; } bool HexagonInstrInfo::isSignExtendingLoad(const MachineInstr &MI) const { @@ -2420,14 +2497,14 @@ bool HexagonInstrInfo::isSignExtendingLoad(const MachineInstr &MI) const { } -bool HexagonInstrInfo::isSolo(const MachineInstr* MI) const { - const uint64_t F = MI->getDesc().TSFlags; +bool HexagonInstrInfo::isSolo(const MachineInstr &MI) const { + const uint64_t F = MI.getDesc().TSFlags; return (F >> HexagonII::SoloPos) & HexagonII::SoloMask; } -bool HexagonInstrInfo::isSpillPredRegOp(const MachineInstr *MI) const { - switch (MI->getOpcode()) { +bool HexagonInstrInfo::isSpillPredRegOp(const MachineInstr &MI) const { + switch (MI.getOpcode()) { case Hexagon::STriw_pred : case Hexagon::LDriw_pred : return true; @@ -2437,11 +2514,11 @@ bool HexagonInstrInfo::isSpillPredRegOp(const MachineInstr *MI) const { } -bool HexagonInstrInfo::isTailCall(const MachineInstr *MI) const { - if (!MI->isBranch()) +bool HexagonInstrInfo::isTailCall(const MachineInstr &MI) const { + if (!MI.isBranch()) return false; - for (auto &Op : MI->operands()) + for (auto &Op : MI.operands()) if (Op.isGlobal() || Op.isSymbol()) return true; return false; @@ -2449,8 +2526,8 @@ bool HexagonInstrInfo::isTailCall(const MachineInstr *MI) const { // Returns true when SU has a timing class TC1. -bool HexagonInstrInfo::isTC1(const MachineInstr *MI) const { - unsigned SchedClass = MI->getDesc().getSchedClass(); +bool HexagonInstrInfo::isTC1(const MachineInstr &MI) const { + unsigned SchedClass = MI.getDesc().getSchedClass(); switch (SchedClass) { case Hexagon::Sched::ALU32_2op_tc_1_SLOT0123: case Hexagon::Sched::ALU32_3op_tc_1_SLOT0123: @@ -2468,8 +2545,8 @@ bool HexagonInstrInfo::isTC1(const MachineInstr *MI) const { } -bool HexagonInstrInfo::isTC2(const MachineInstr *MI) const { - unsigned SchedClass = MI->getDesc().getSchedClass(); +bool HexagonInstrInfo::isTC2(const MachineInstr &MI) const { + unsigned SchedClass = MI.getDesc().getSchedClass(); switch (SchedClass) { case Hexagon::Sched::ALU32_3op_tc_2_SLOT0123: case Hexagon::Sched::ALU64_tc_2_SLOT23: @@ -2485,8 +2562,8 @@ bool HexagonInstrInfo::isTC2(const MachineInstr *MI) const { } -bool HexagonInstrInfo::isTC2Early(const MachineInstr *MI) const { - unsigned SchedClass = MI->getDesc().getSchedClass(); +bool HexagonInstrInfo::isTC2Early(const MachineInstr &MI) const { + unsigned SchedClass = MI.getDesc().getSchedClass(); switch (SchedClass) { case Hexagon::Sched::ALU32_2op_tc_2early_SLOT0123: case Hexagon::Sched::ALU32_3op_tc_2early_SLOT0123: @@ -2506,41 +2583,33 @@ bool HexagonInstrInfo::isTC2Early(const MachineInstr *MI) const { } -bool HexagonInstrInfo::isTC4x(const MachineInstr *MI) const { - if (!MI) - return false; - - unsigned SchedClass = MI->getDesc().getSchedClass(); +bool HexagonInstrInfo::isTC4x(const MachineInstr &MI) const { + unsigned SchedClass = MI.getDesc().getSchedClass(); return SchedClass == Hexagon::Sched::M_tc_3or4x_SLOT23; } // Schedule this ASAP. -bool HexagonInstrInfo::isToBeScheduledASAP(const MachineInstr *MI1, - const MachineInstr *MI2) const { - if (!MI1 || !MI2) - return false; +bool HexagonInstrInfo::isToBeScheduledASAP(const MachineInstr &MI1, + const MachineInstr &MI2) const { if (mayBeCurLoad(MI1)) { // if (result of SU is used in Next) return true; - unsigned DstReg = MI1->getOperand(0).getReg(); - int N = MI2->getNumOperands(); + unsigned DstReg = MI1.getOperand(0).getReg(); + int N = MI2.getNumOperands(); for (int I = 0; I < N; I++) - if (MI2->getOperand(I).isReg() && DstReg == MI2->getOperand(I).getReg()) + if (MI2.getOperand(I).isReg() && DstReg == MI2.getOperand(I).getReg()) return true; } if (mayBeNewStore(MI2)) - if (MI2->getOpcode() == Hexagon::V6_vS32b_pi) - if (MI1->getOperand(0).isReg() && MI2->getOperand(3).isReg() && - MI1->getOperand(0).getReg() == MI2->getOperand(3).getReg()) + if (MI2.getOpcode() == Hexagon::V6_vS32b_pi) + if (MI1.getOperand(0).isReg() && MI2.getOperand(3).isReg() && + MI1.getOperand(0).getReg() == MI2.getOperand(3).getReg()) return true; return false; } -bool HexagonInstrInfo::isV60VectorInstruction(const MachineInstr *MI) const { - if (!MI) - return false; - +bool HexagonInstrInfo::isV60VectorInstruction(const MachineInstr &MI) const { const uint64_t V = getType(MI); return HexagonII::TypeCVI_FIRST <= V && V <= HexagonII::TypeCVI_LAST; } @@ -2597,16 +2666,10 @@ bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset, // misaligns with respect to load size. switch (Opcode) { - case Hexagon::STriq_pred_V6: - case Hexagon::STriq_pred_vec_V6: - case Hexagon::STriv_pseudo_V6: - case Hexagon::STrivv_pseudo_V6: - case Hexagon::LDriq_pred_V6: - case Hexagon::LDriq_pred_vec_V6: - case Hexagon::LDriv_pseudo_V6: - case Hexagon::LDrivv_pseudo_V6: - case Hexagon::LDrivv_indexed: - case Hexagon::STrivv_indexed: + case Hexagon::PS_vstorerq_ai: + case Hexagon::PS_vstorerw_ai: + case Hexagon::PS_vloadrq_ai: + case Hexagon::PS_vloadrw_ai: case Hexagon::V6_vL32b_ai: case Hexagon::V6_vS32b_ai: case Hexagon::V6_vL32Ub_ai: @@ -2614,16 +2677,10 @@ bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset, return (Offset >= Hexagon_MEMV_OFFSET_MIN) && (Offset <= Hexagon_MEMV_OFFSET_MAX); - case Hexagon::STriq_pred_V6_128B: - case Hexagon::STriq_pred_vec_V6_128B: - case Hexagon::STriv_pseudo_V6_128B: - case Hexagon::STrivv_pseudo_V6_128B: - case Hexagon::LDriq_pred_V6_128B: - case Hexagon::LDriq_pred_vec_V6_128B: - case Hexagon::LDriv_pseudo_V6_128B: - case Hexagon::LDrivv_pseudo_V6_128B: - case Hexagon::LDrivv_indexed_128B: - case Hexagon::STrivv_indexed_128B: + case Hexagon::PS_vstorerq_ai_128B: + case Hexagon::PS_vstorerw_ai_128B: + case Hexagon::PS_vloadrq_ai_128B: + case Hexagon::PS_vloadrw_ai_128B: case Hexagon::V6_vL32b_ai_128B: case Hexagon::V6_vS32b_ai_128B: case Hexagon::V6_vL32Ub_ai_128B: @@ -2713,8 +2770,8 @@ bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset, case Hexagon::LDriw_mod: return true; - case Hexagon::TFR_FI: - case Hexagon::TFR_FIA: + case Hexagon::PS_fi: + case Hexagon::PS_fia: case Hexagon::INLINEASM: return true; @@ -2752,15 +2809,13 @@ bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset, } -bool HexagonInstrInfo::isVecAcc(const MachineInstr *MI) const { - return MI && isV60VectorInstruction(MI) && isAccumulator(MI); +bool HexagonInstrInfo::isVecAcc(const MachineInstr &MI) const { + return isV60VectorInstruction(MI) && isAccumulator(MI); } -bool HexagonInstrInfo::isVecALU(const MachineInstr *MI) const { - if (!MI) - return false; - const uint64_t F = get(MI->getOpcode()).TSFlags; +bool HexagonInstrInfo::isVecALU(const MachineInstr &MI) const { + const uint64_t F = get(MI.getOpcode()).TSFlags; const uint64_t V = ((F >> HexagonII::TypePos) & HexagonII::TypeMask); return V == HexagonII::TypeCVI_VA || @@ -2768,8 +2823,8 @@ bool HexagonInstrInfo::isVecALU(const MachineInstr *MI) const { } -bool HexagonInstrInfo::isVecUsableNextPacket(const MachineInstr *ProdMI, - const MachineInstr *ConsMI) const { +bool HexagonInstrInfo::isVecUsableNextPacket(const MachineInstr &ProdMI, + const MachineInstr &ConsMI) const { if (EnableACCForwarding && isVecAcc(ProdMI) && isVecAcc(ConsMI)) return true; @@ -2862,8 +2917,8 @@ bool HexagonInstrInfo::isZeroExtendingLoad(const MachineInstr &MI) const { // Add latency to instruction. -bool HexagonInstrInfo::addLatencyToSchedule(const MachineInstr *MI1, - const MachineInstr *MI2) const { +bool HexagonInstrInfo::addLatencyToSchedule(const MachineInstr &MI1, + const MachineInstr &MI2) const { if (isV60VectorInstruction(MI1) && isV60VectorInstruction(MI2)) if (!isVecUsableNextPacket(MI1, MI2)) return true; @@ -2871,20 +2926,32 @@ bool HexagonInstrInfo::addLatencyToSchedule(const MachineInstr *MI1, } +/// \brief Get the base register and byte offset of a load/store instr. +bool HexagonInstrInfo::getMemOpBaseRegImmOfs(MachineInstr &LdSt, + unsigned &BaseReg, int64_t &Offset, const TargetRegisterInfo *TRI) + const { + unsigned AccessSize = 0; + int OffsetVal = 0; + BaseReg = getBaseAndOffset(LdSt, OffsetVal, AccessSize); + Offset = OffsetVal; + return BaseReg != 0; +} + + /// \brief Can these instructions execute at the same time in a bundle. -bool HexagonInstrInfo::canExecuteInBundle(const MachineInstr *First, - const MachineInstr *Second) const { +bool HexagonInstrInfo::canExecuteInBundle(const MachineInstr &First, + const MachineInstr &Second) const { if (DisableNVSchedule) return false; if (mayBeNewStore(Second)) { // Make sure the definition of the first instruction is the value being // stored. const MachineOperand &Stored = - Second->getOperand(Second->getNumOperands() - 1); + Second.getOperand(Second.getNumOperands() - 1); if (!Stored.isReg()) return false; - for (unsigned i = 0, e = First->getNumOperands(); i < e; ++i) { - const MachineOperand &Op = First->getOperand(i); + for (unsigned i = 0, e = First.getNumOperands(); i < e; ++i) { + const MachineOperand &Op = First.getOperand(i); if (Op.isReg() && Op.isDef() && Op.getReg() == Stored.getReg()) return true; } @@ -2893,6 +2960,12 @@ bool HexagonInstrInfo::canExecuteInBundle(const MachineInstr *First, } +bool HexagonInstrInfo::doesNotReturn(const MachineInstr &CallMI) const { + unsigned Opc = CallMI.getOpcode(); + return Opc == Hexagon::PS_call_nr || Opc == Hexagon::PS_callr_nr; +} + + bool HexagonInstrInfo::hasEHLabel(const MachineBasicBlock *B) const { for (auto &I : *B) if (I.isEHLabel()) @@ -2903,30 +2976,30 @@ bool HexagonInstrInfo::hasEHLabel(const MachineBasicBlock *B) const { // Returns true if an instruction can be converted into a non-extended // equivalent instruction. -bool HexagonInstrInfo::hasNonExtEquivalent(const MachineInstr *MI) const { +bool HexagonInstrInfo::hasNonExtEquivalent(const MachineInstr &MI) const { short NonExtOpcode; // Check if the instruction has a register form that uses register in place // of the extended operand, if so return that as the non-extended form. - if (Hexagon::getRegForm(MI->getOpcode()) >= 0) + if (Hexagon::getRegForm(MI.getOpcode()) >= 0) return true; - if (MI->getDesc().mayLoad() || MI->getDesc().mayStore()) { + if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) { // Check addressing mode and retrieve non-ext equivalent instruction. switch (getAddrMode(MI)) { case HexagonII::Absolute : // Load/store with absolute addressing mode can be converted into // base+offset mode. - NonExtOpcode = Hexagon::getBaseWithImmOffset(MI->getOpcode()); + NonExtOpcode = Hexagon::getBaseWithImmOffset(MI.getOpcode()); break; case HexagonII::BaseImmOffset : // Load/store with base+offset addressing mode can be converted into // base+register offset addressing mode. However left shift operand should // be set to 0. - NonExtOpcode = Hexagon::getBaseWithRegOffset(MI->getOpcode()); + NonExtOpcode = Hexagon::getBaseWithRegOffset(MI.getOpcode()); break; case HexagonII::BaseLongOffset: - NonExtOpcode = Hexagon::getRegShlForm(MI->getOpcode()); + NonExtOpcode = Hexagon::getRegShlForm(MI.getOpcode()); break; default: return false; @@ -2939,8 +3012,8 @@ bool HexagonInstrInfo::hasNonExtEquivalent(const MachineInstr *MI) const { } -bool HexagonInstrInfo::hasPseudoInstrPair(const MachineInstr *MI) const { - return Hexagon::getRealHWInstr(MI->getOpcode(), +bool HexagonInstrInfo::hasPseudoInstrPair(const MachineInstr &MI) const { + return Hexagon::getRealHWInstr(MI.getOpcode(), Hexagon::InstrType_Pseudo) >= 0; } @@ -2958,23 +3031,23 @@ bool HexagonInstrInfo::hasUncondBranch(const MachineBasicBlock *B) // Returns true, if a LD insn can be promoted to a cur load. -bool HexagonInstrInfo::mayBeCurLoad(const MachineInstr *MI) const { - auto &HST = MI->getParent()->getParent()->getSubtarget<HexagonSubtarget>(); - const uint64_t F = MI->getDesc().TSFlags; +bool HexagonInstrInfo::mayBeCurLoad(const MachineInstr &MI) const { + auto &HST = MI.getParent()->getParent()->getSubtarget<HexagonSubtarget>(); + const uint64_t F = MI.getDesc().TSFlags; return ((F >> HexagonII::mayCVLoadPos) & HexagonII::mayCVLoadMask) && HST.hasV60TOps(); } // Returns true, if a ST insn can be promoted to a new-value store. -bool HexagonInstrInfo::mayBeNewStore(const MachineInstr *MI) const { - const uint64_t F = MI->getDesc().TSFlags; +bool HexagonInstrInfo::mayBeNewStore(const MachineInstr &MI) const { + const uint64_t F = MI.getDesc().TSFlags; return (F >> HexagonII::mayNVStorePos) & HexagonII::mayNVStoreMask; } -bool HexagonInstrInfo::producesStall(const MachineInstr *ProdMI, - const MachineInstr *ConsMI) const { +bool HexagonInstrInfo::producesStall(const MachineInstr &ProdMI, + const MachineInstr &ConsMI) const { // There is no stall when ProdMI is not a V60 vector. if (!isV60VectorInstruction(ProdMI)) return false; @@ -2992,7 +3065,7 @@ bool HexagonInstrInfo::producesStall(const MachineInstr *ProdMI, } -bool HexagonInstrInfo::producesStall(const MachineInstr *MI, +bool HexagonInstrInfo::producesStall(const MachineInstr &MI, MachineBasicBlock::const_instr_iterator BII) const { // There is no stall when I is not a V60 vector. if (!isV60VectorInstruction(MI)) @@ -3001,8 +3074,8 @@ bool HexagonInstrInfo::producesStall(const MachineInstr *MI, MachineBasicBlock::const_instr_iterator MII = BII; MachineBasicBlock::const_instr_iterator MIE = MII->getParent()->instr_end(); - if (!(*MII).isBundle()) { - const MachineInstr *J = &*MII; + if (!MII->isBundle()) { + const MachineInstr &J = *MII; if (!isV60VectorInstruction(J)) return false; else if (isVecUsableNextPacket(J, MI)) @@ -3011,7 +3084,7 @@ bool HexagonInstrInfo::producesStall(const MachineInstr *MI, } for (++MII; MII != MIE && MII->isInsideBundle(); ++MII) { - const MachineInstr *J = &*MII; + const MachineInstr &J = *MII; if (producesStall(J, MI)) return true; } @@ -3019,10 +3092,10 @@ bool HexagonInstrInfo::producesStall(const MachineInstr *MI, } -bool HexagonInstrInfo::predCanBeUsedAsDotNew(const MachineInstr *MI, +bool HexagonInstrInfo::predCanBeUsedAsDotNew(const MachineInstr &MI, unsigned PredReg) const { - for (unsigned opNum = 0; opNum < MI->getNumOperands(); opNum++) { - const MachineOperand &MO = MI->getOperand(opNum); + for (unsigned opNum = 0; opNum < MI.getNumOperands(); opNum++) { + const MachineOperand &MO = MI.getOperand(opNum); if (MO.isReg() && MO.isDef() && MO.isImplicit() && (MO.getReg() == PredReg)) return false; // Predicate register must be explicitly defined. } @@ -3030,7 +3103,7 @@ bool HexagonInstrInfo::predCanBeUsedAsDotNew(const MachineInstr *MI, // Hexagon Programmer's Reference says that decbin, memw_locked, and // memd_locked cannot be used as .new as well, // but we don't seem to have these instructions defined. - return MI->getOpcode() != Hexagon::A4_tlbmatch; + return MI.getOpcode() != Hexagon::A4_tlbmatch; } @@ -3051,20 +3124,20 @@ bool HexagonInstrInfo::predOpcodeHasNot(ArrayRef<MachineOperand> Cond) const { } -short HexagonInstrInfo::getAbsoluteForm(const MachineInstr *MI) const { - return Hexagon::getAbsoluteForm(MI->getOpcode()); +short HexagonInstrInfo::getAbsoluteForm(const MachineInstr &MI) const { + return Hexagon::getAbsoluteForm(MI.getOpcode()); } -unsigned HexagonInstrInfo::getAddrMode(const MachineInstr* MI) const { - const uint64_t F = MI->getDesc().TSFlags; +unsigned HexagonInstrInfo::getAddrMode(const MachineInstr &MI) const { + const uint64_t F = MI.getDesc().TSFlags; return (F >> HexagonII::AddrModePos) & HexagonII::AddrModeMask; } // Returns the base register in a memory access (load/store). The offset is // returned in Offset and the access size is returned in AccessSize. -unsigned HexagonInstrInfo::getBaseAndOffset(const MachineInstr *MI, +unsigned HexagonInstrInfo::getBaseAndOffset(const MachineInstr &MI, int &Offset, unsigned &AccessSize) const { // Return if it is not a base+offset type instruction or a MemOp. if (getAddrMode(MI) != HexagonII::BaseImmOffset && @@ -3092,30 +3165,30 @@ unsigned HexagonInstrInfo::getBaseAndOffset(const MachineInstr *MI, if (isPostIncrement(MI)) Offset = 0; else { - Offset = MI->getOperand(offsetPos).getImm(); + Offset = MI.getOperand(offsetPos).getImm(); } - return MI->getOperand(basePos).getReg(); + return MI.getOperand(basePos).getReg(); } /// Return the position of the base and offset operands for this instruction. -bool HexagonInstrInfo::getBaseAndOffsetPosition(const MachineInstr *MI, +bool HexagonInstrInfo::getBaseAndOffsetPosition(const MachineInstr &MI, unsigned &BasePos, unsigned &OffsetPos) const { // Deal with memops first. if (isMemOp(MI)) { BasePos = 0; OffsetPos = 1; - } else if (MI->mayStore()) { + } else if (MI.mayStore()) { BasePos = 0; OffsetPos = 1; - } else if (MI->mayLoad()) { + } else if (MI.mayLoad()) { BasePos = 1; OffsetPos = 2; } else return false; - if (isPredicated(*MI)) { + if (isPredicated(MI)) { BasePos++; OffsetPos++; } @@ -3124,14 +3197,14 @@ bool HexagonInstrInfo::getBaseAndOffsetPosition(const MachineInstr *MI, OffsetPos++; } - if (!MI->getOperand(BasePos).isReg() || !MI->getOperand(OffsetPos).isImm()) + if (!MI.getOperand(BasePos).isReg() || !MI.getOperand(OffsetPos).isImm()) return false; return true; } -// Inserts branching instructions in reverse order of their occurence. +// Inserts branching instructions in reverse order of their occurrence. // e.g. jump_t t1 (i1) // jump t2 (i2) // Jumpers = {i2, i1} @@ -3200,29 +3273,29 @@ short HexagonInstrInfo::getBaseWithLongOffset(short Opcode) const { } -short HexagonInstrInfo::getBaseWithLongOffset(const MachineInstr *MI) const { - return Hexagon::getBaseWithLongOffset(MI->getOpcode()); +short HexagonInstrInfo::getBaseWithLongOffset(const MachineInstr &MI) const { + return Hexagon::getBaseWithLongOffset(MI.getOpcode()); } -short HexagonInstrInfo::getBaseWithRegOffset(const MachineInstr *MI) const { - return Hexagon::getBaseWithRegOffset(MI->getOpcode()); +short HexagonInstrInfo::getBaseWithRegOffset(const MachineInstr &MI) const { + return Hexagon::getBaseWithRegOffset(MI.getOpcode()); } // Returns Operand Index for the constant extended instruction. -unsigned HexagonInstrInfo::getCExtOpNum(const MachineInstr *MI) const { - const uint64_t F = MI->getDesc().TSFlags; +unsigned HexagonInstrInfo::getCExtOpNum(const MachineInstr &MI) const { + const uint64_t F = MI.getDesc().TSFlags; return (F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask; } // See if instruction could potentially be a duplex candidate. // If so, return its group. Zero otherwise. HexagonII::CompoundGroup HexagonInstrInfo::getCompoundCandidateGroup( - const MachineInstr *MI) const { + const MachineInstr &MI) const { unsigned DstReg, SrcReg, Src1Reg, Src2Reg; - switch (MI->getOpcode()) { + switch (MI.getOpcode()) { default: return HexagonII::HCG_None; // @@ -3234,9 +3307,9 @@ HexagonII::CompoundGroup HexagonInstrInfo::getCompoundCandidateGroup( case Hexagon::C2_cmpeq: case Hexagon::C2_cmpgt: case Hexagon::C2_cmpgtu: - DstReg = MI->getOperand(0).getReg(); - Src1Reg = MI->getOperand(1).getReg(); - Src2Reg = MI->getOperand(2).getReg(); + DstReg = MI.getOperand(0).getReg(); + Src1Reg = MI.getOperand(1).getReg(); + Src2Reg = MI.getOperand(2).getReg(); if (Hexagon::PredRegsRegClass.contains(DstReg) && (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) && isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg)) @@ -3246,19 +3319,19 @@ HexagonII::CompoundGroup HexagonInstrInfo::getCompoundCandidateGroup( case Hexagon::C2_cmpgti: case Hexagon::C2_cmpgtui: // P0 = cmp.eq(Rs,#u2) - DstReg = MI->getOperand(0).getReg(); - SrcReg = MI->getOperand(1).getReg(); + DstReg = MI.getOperand(0).getReg(); + SrcReg = MI.getOperand(1).getReg(); if (Hexagon::PredRegsRegClass.contains(DstReg) && (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) && - isIntRegForSubInst(SrcReg) && MI->getOperand(2).isImm() && - ((isUInt<5>(MI->getOperand(2).getImm())) || - (MI->getOperand(2).getImm() == -1))) + isIntRegForSubInst(SrcReg) && MI.getOperand(2).isImm() && + ((isUInt<5>(MI.getOperand(2).getImm())) || + (MI.getOperand(2).getImm() == -1))) return HexagonII::HCG_A; break; case Hexagon::A2_tfr: // Rd = Rs - DstReg = MI->getOperand(0).getReg(); - SrcReg = MI->getOperand(1).getReg(); + DstReg = MI.getOperand(0).getReg(); + SrcReg = MI.getOperand(1).getReg(); if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg)) return HexagonII::HCG_A; break; @@ -3266,17 +3339,17 @@ HexagonII::CompoundGroup HexagonInstrInfo::getCompoundCandidateGroup( // Rd = #u6 // Do not test for #u6 size since the const is getting extended // regardless and compound could be formed. - DstReg = MI->getOperand(0).getReg(); + DstReg = MI.getOperand(0).getReg(); if (isIntRegForSubInst(DstReg)) return HexagonII::HCG_A; break; case Hexagon::S2_tstbit_i: - DstReg = MI->getOperand(0).getReg(); - Src1Reg = MI->getOperand(1).getReg(); + DstReg = MI.getOperand(0).getReg(); + Src1Reg = MI.getOperand(1).getReg(); if (Hexagon::PredRegsRegClass.contains(DstReg) && (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) && - MI->getOperand(2).isImm() && - isIntRegForSubInst(Src1Reg) && (MI->getOperand(2).getImm() == 0)) + MI.getOperand(2).isImm() && + isIntRegForSubInst(Src1Reg) && (MI.getOperand(2).getImm() == 0)) return HexagonII::HCG_A; break; // The fact that .new form is used pretty much guarantees @@ -3287,7 +3360,7 @@ HexagonII::CompoundGroup HexagonInstrInfo::getCompoundCandidateGroup( case Hexagon::J2_jumpfnew: case Hexagon::J2_jumptnewpt: case Hexagon::J2_jumpfnewpt: - Src1Reg = MI->getOperand(0).getReg(); + Src1Reg = MI.getOperand(0).getReg(); if (Hexagon::PredRegsRegClass.contains(Src1Reg) && (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg)) return HexagonII::HCG_B; @@ -3298,6 +3371,7 @@ HexagonII::CompoundGroup HexagonInstrInfo::getCompoundCandidateGroup( // Do not test for jump range here. case Hexagon::J2_jump: case Hexagon::RESTORE_DEALLOC_RET_JMP_V4: + case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC: return HexagonII::HCG_C; break; } @@ -3307,15 +3381,15 @@ HexagonII::CompoundGroup HexagonInstrInfo::getCompoundCandidateGroup( // Returns -1 when there is no opcode found. -unsigned HexagonInstrInfo::getCompoundOpcode(const MachineInstr *GA, - const MachineInstr *GB) const { +unsigned HexagonInstrInfo::getCompoundOpcode(const MachineInstr &GA, + const MachineInstr &GB) const { assert(getCompoundCandidateGroup(GA) == HexagonII::HCG_A); assert(getCompoundCandidateGroup(GB) == HexagonII::HCG_B); - if ((GA->getOpcode() != Hexagon::C2_cmpeqi) || - (GB->getOpcode() != Hexagon::J2_jumptnew)) + if ((GA.getOpcode() != Hexagon::C2_cmpeqi) || + (GB.getOpcode() != Hexagon::J2_jumptnew)) return -1; - unsigned DestReg = GA->getOperand(0).getReg(); - if (!GB->readsRegister(DestReg)) + unsigned DestReg = GA.getOperand(0).getReg(); + if (!GB.readsRegister(DestReg)) return -1; if (DestReg == Hexagon::P0) return Hexagon::J4_cmpeqi_tp0_jump_nt; @@ -3333,21 +3407,13 @@ int HexagonInstrInfo::getCondOpcode(int Opc, bool invertPredicate) const { if (CondOpcode >= 0) // Valid Conditional opcode/instruction return CondOpcode; - // This switch case will be removed once all the instructions have been - // modified to use relation maps. - switch(Opc) { - case Hexagon::TFRI_f: - return !invertPredicate ? Hexagon::TFRI_cPt_f : - Hexagon::TFRI_cNotPt_f; - } - llvm_unreachable("Unexpected predicable instruction"); } // Return the cur value instruction for a given store. -int HexagonInstrInfo::getDotCurOp(const MachineInstr* MI) const { - switch (MI->getOpcode()) { +int HexagonInstrInfo::getDotCurOp(const MachineInstr &MI) const { + switch (MI.getOpcode()) { default: llvm_unreachable("Unknown .cur type"); case Hexagon::V6_vL32b_pi: return Hexagon::V6_vL32b_cur_pi; @@ -3445,12 +3511,12 @@ int HexagonInstrInfo::getDotCurOp(const MachineInstr* MI) const { // Return the new value instruction for a given store. -int HexagonInstrInfo::getDotNewOp(const MachineInstr* MI) const { - int NVOpcode = Hexagon::getNewValueOpcode(MI->getOpcode()); +int HexagonInstrInfo::getDotNewOp(const MachineInstr &MI) const { + int NVOpcode = Hexagon::getNewValueOpcode(MI.getOpcode()); if (NVOpcode >= 0) // Valid new-value store instruction. return NVOpcode; - switch (MI->getOpcode()) { + switch (MI.getOpcode()) { default: llvm_unreachable("Unknown .new type"); case Hexagon::S4_storerb_ur: return Hexagon::S4_storerbnew_ur; @@ -3490,19 +3556,19 @@ int HexagonInstrInfo::getDotNewOp(const MachineInstr* MI) const { // Returns the opcode to use when converting MI, which is a conditional jump, // into a conditional instruction which uses the .new value of the predicate. // We also use branch probabilities to add a hint to the jump. -int HexagonInstrInfo::getDotNewPredJumpOp(const MachineInstr *MI, +int HexagonInstrInfo::getDotNewPredJumpOp(const MachineInstr &MI, const MachineBranchProbabilityInfo *MBPI) const { // We assume that block can have at most two successors. bool taken = false; - const MachineBasicBlock *Src = MI->getParent(); - const MachineOperand *BrTarget = &MI->getOperand(1); - const MachineBasicBlock *Dst = BrTarget->getMBB(); + const MachineBasicBlock *Src = MI.getParent(); + const MachineOperand &BrTarget = MI.getOperand(1); + const MachineBasicBlock *Dst = BrTarget.getMBB(); const BranchProbability Prediction = MBPI->getEdgeProbability(Src, Dst); if (Prediction >= BranchProbability(1,2)) taken = true; - switch (MI->getOpcode()) { + switch (MI.getOpcode()) { case Hexagon::J2_jumpt: return taken ? Hexagon::J2_jumptnewpt : Hexagon::J2_jumptnew; case Hexagon::J2_jumpf: @@ -3515,13 +3581,13 @@ int HexagonInstrInfo::getDotNewPredJumpOp(const MachineInstr *MI, // Return .new predicate version for an instruction. -int HexagonInstrInfo::getDotNewPredOp(const MachineInstr *MI, +int HexagonInstrInfo::getDotNewPredOp(const MachineInstr &MI, const MachineBranchProbabilityInfo *MBPI) const { - int NewOpcode = Hexagon::getPredNewOpcode(MI->getOpcode()); + int NewOpcode = Hexagon::getPredNewOpcode(MI.getOpcode()); if (NewOpcode >= 0) // Valid predicate new instruction return NewOpcode; - switch (MI->getOpcode()) { + switch (MI.getOpcode()) { // Condtional Jumps case Hexagon::J2_jumpt: case Hexagon::J2_jumpf: @@ -3553,11 +3619,11 @@ int HexagonInstrInfo::getDotOldOp(const int opc) const { // See if instruction could potentially be a duplex candidate. // If so, return its group. Zero otherwise. HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup( - const MachineInstr *MI) const { + const MachineInstr &MI) const { unsigned DstReg, SrcReg, Src1Reg, Src2Reg; auto &HRI = getRegisterInfo(); - switch (MI->getOpcode()) { + switch (MI.getOpcode()) { default: return HexagonII::HSIG_None; // @@ -3566,29 +3632,29 @@ HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup( // Rd = memw(Rs+#u4:2) // Rd = memub(Rs+#u4:0) case Hexagon::L2_loadri_io: - DstReg = MI->getOperand(0).getReg(); - SrcReg = MI->getOperand(1).getReg(); + DstReg = MI.getOperand(0).getReg(); + SrcReg = MI.getOperand(1).getReg(); // Special case this one from Group L2. // Rd = memw(r29+#u5:2) if (isIntRegForSubInst(DstReg)) { if (Hexagon::IntRegsRegClass.contains(SrcReg) && HRI.getStackRegister() == SrcReg && - MI->getOperand(2).isImm() && - isShiftedUInt<5,2>(MI->getOperand(2).getImm())) + MI.getOperand(2).isImm() && + isShiftedUInt<5,2>(MI.getOperand(2).getImm())) return HexagonII::HSIG_L2; // Rd = memw(Rs+#u4:2) if (isIntRegForSubInst(SrcReg) && - (MI->getOperand(2).isImm() && - isShiftedUInt<4,2>(MI->getOperand(2).getImm()))) + (MI.getOperand(2).isImm() && + isShiftedUInt<4,2>(MI.getOperand(2).getImm()))) return HexagonII::HSIG_L1; } break; case Hexagon::L2_loadrub_io: // Rd = memub(Rs+#u4:0) - DstReg = MI->getOperand(0).getReg(); - SrcReg = MI->getOperand(1).getReg(); + DstReg = MI.getOperand(0).getReg(); + SrcReg = MI.getOperand(1).getReg(); if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) && - MI->getOperand(2).isImm() && isUInt<4>(MI->getOperand(2).getImm())) + MI.getOperand(2).isImm() && isUInt<4>(MI.getOperand(2).getImm())) return HexagonII::HSIG_L1; break; // @@ -3604,61 +3670,62 @@ HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup( case Hexagon::L2_loadrh_io: case Hexagon::L2_loadruh_io: // Rd = memh/memuh(Rs+#u3:1) - DstReg = MI->getOperand(0).getReg(); - SrcReg = MI->getOperand(1).getReg(); + DstReg = MI.getOperand(0).getReg(); + SrcReg = MI.getOperand(1).getReg(); if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) && - MI->getOperand(2).isImm() && - isShiftedUInt<3,1>(MI->getOperand(2).getImm())) + MI.getOperand(2).isImm() && + isShiftedUInt<3,1>(MI.getOperand(2).getImm())) return HexagonII::HSIG_L2; break; case Hexagon::L2_loadrb_io: // Rd = memb(Rs+#u3:0) - DstReg = MI->getOperand(0).getReg(); - SrcReg = MI->getOperand(1).getReg(); + DstReg = MI.getOperand(0).getReg(); + SrcReg = MI.getOperand(1).getReg(); if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) && - MI->getOperand(2).isImm() && - isUInt<3>(MI->getOperand(2).getImm())) + MI.getOperand(2).isImm() && + isUInt<3>(MI.getOperand(2).getImm())) return HexagonII::HSIG_L2; break; case Hexagon::L2_loadrd_io: // Rdd = memd(r29+#u5:3) - DstReg = MI->getOperand(0).getReg(); - SrcReg = MI->getOperand(1).getReg(); + DstReg = MI.getOperand(0).getReg(); + SrcReg = MI.getOperand(1).getReg(); if (isDblRegForSubInst(DstReg, HRI) && Hexagon::IntRegsRegClass.contains(SrcReg) && HRI.getStackRegister() == SrcReg && - MI->getOperand(2).isImm() && - isShiftedUInt<5,3>(MI->getOperand(2).getImm())) + MI.getOperand(2).isImm() && + isShiftedUInt<5,3>(MI.getOperand(2).getImm())) return HexagonII::HSIG_L2; break; // dealloc_return is not documented in Hexagon Manual, but marked // with A_SUBINSN attribute in iset_v4classic.py. case Hexagon::RESTORE_DEALLOC_RET_JMP_V4: + case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC: case Hexagon::L4_return: case Hexagon::L2_deallocframe: return HexagonII::HSIG_L2; case Hexagon::EH_RETURN_JMPR: - case Hexagon::JMPret : + case Hexagon::PS_jmpret: // jumpr r31 // Actual form JMPR %PC<imp-def>, %R31<imp-use>, %R0<imp-use,internal>. - DstReg = MI->getOperand(0).getReg(); + DstReg = MI.getOperand(0).getReg(); if (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg)) return HexagonII::HSIG_L2; break; - case Hexagon::JMPrett: - case Hexagon::JMPretf: - case Hexagon::JMPrettnewpt: - case Hexagon::JMPretfnewpt : - case Hexagon::JMPrettnew : - case Hexagon::JMPretfnew : - DstReg = MI->getOperand(1).getReg(); - SrcReg = MI->getOperand(0).getReg(); + case Hexagon::PS_jmprett: + case Hexagon::PS_jmpretf: + case Hexagon::PS_jmprettnewpt: + case Hexagon::PS_jmpretfnewpt: + case Hexagon::PS_jmprettnew: + case Hexagon::PS_jmpretfnew: + DstReg = MI.getOperand(1).getReg(); + SrcReg = MI.getOperand(0).getReg(); // [if ([!]p0[.new])] jumpr r31 if ((Hexagon::PredRegsRegClass.contains(SrcReg) && (Hexagon::P0 == SrcReg)) && (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg))) return HexagonII::HSIG_L2; - break; + break; case Hexagon::L4_return_t : case Hexagon::L4_return_f : case Hexagon::L4_return_tnew_pnt : @@ -3666,7 +3733,7 @@ HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup( case Hexagon::L4_return_tnew_pt : case Hexagon::L4_return_fnew_pt : // [if ([!]p0[.new])] dealloc_return - SrcReg = MI->getOperand(0).getReg(); + SrcReg = MI.getOperand(0).getReg(); if (Hexagon::PredRegsRegClass.contains(SrcReg) && (Hexagon::P0 == SrcReg)) return HexagonII::HSIG_L2; break; @@ -3678,25 +3745,25 @@ HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup( case Hexagon::S2_storeri_io: // Special case this one from Group S2. // memw(r29+#u5:2) = Rt - Src1Reg = MI->getOperand(0).getReg(); - Src2Reg = MI->getOperand(2).getReg(); + Src1Reg = MI.getOperand(0).getReg(); + Src2Reg = MI.getOperand(2).getReg(); if (Hexagon::IntRegsRegClass.contains(Src1Reg) && isIntRegForSubInst(Src2Reg) && - HRI.getStackRegister() == Src1Reg && MI->getOperand(1).isImm() && - isShiftedUInt<5,2>(MI->getOperand(1).getImm())) + HRI.getStackRegister() == Src1Reg && MI.getOperand(1).isImm() && + isShiftedUInt<5,2>(MI.getOperand(1).getImm())) return HexagonII::HSIG_S2; // memw(Rs+#u4:2) = Rt if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) && - MI->getOperand(1).isImm() && - isShiftedUInt<4,2>(MI->getOperand(1).getImm())) + MI.getOperand(1).isImm() && + isShiftedUInt<4,2>(MI.getOperand(1).getImm())) return HexagonII::HSIG_S1; break; case Hexagon::S2_storerb_io: // memb(Rs+#u4:0) = Rt - Src1Reg = MI->getOperand(0).getReg(); - Src2Reg = MI->getOperand(2).getReg(); + Src1Reg = MI.getOperand(0).getReg(); + Src2Reg = MI.getOperand(2).getReg(); if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) && - MI->getOperand(1).isImm() && isUInt<4>(MI->getOperand(1).getImm())) + MI.getOperand(1).isImm() && isUInt<4>(MI.getOperand(1).getImm())) return HexagonII::HSIG_S1; break; // @@ -3710,42 +3777,42 @@ HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup( // allocframe(#u5:3) case Hexagon::S2_storerh_io: // memh(Rs+#u3:1) = Rt - Src1Reg = MI->getOperand(0).getReg(); - Src2Reg = MI->getOperand(2).getReg(); + Src1Reg = MI.getOperand(0).getReg(); + Src2Reg = MI.getOperand(2).getReg(); if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) && - MI->getOperand(1).isImm() && - isShiftedUInt<3,1>(MI->getOperand(1).getImm())) + MI.getOperand(1).isImm() && + isShiftedUInt<3,1>(MI.getOperand(1).getImm())) return HexagonII::HSIG_S1; break; case Hexagon::S2_storerd_io: // memd(r29+#s6:3) = Rtt - Src1Reg = MI->getOperand(0).getReg(); - Src2Reg = MI->getOperand(2).getReg(); + Src1Reg = MI.getOperand(0).getReg(); + Src2Reg = MI.getOperand(2).getReg(); if (isDblRegForSubInst(Src2Reg, HRI) && Hexagon::IntRegsRegClass.contains(Src1Reg) && - HRI.getStackRegister() == Src1Reg && MI->getOperand(1).isImm() && - isShiftedInt<6,3>(MI->getOperand(1).getImm())) + HRI.getStackRegister() == Src1Reg && MI.getOperand(1).isImm() && + isShiftedInt<6,3>(MI.getOperand(1).getImm())) return HexagonII::HSIG_S2; break; case Hexagon::S4_storeiri_io: // memw(Rs+#u4:2) = #U1 - Src1Reg = MI->getOperand(0).getReg(); - if (isIntRegForSubInst(Src1Reg) && MI->getOperand(1).isImm() && - isShiftedUInt<4,2>(MI->getOperand(1).getImm()) && - MI->getOperand(2).isImm() && isUInt<1>(MI->getOperand(2).getImm())) + Src1Reg = MI.getOperand(0).getReg(); + if (isIntRegForSubInst(Src1Reg) && MI.getOperand(1).isImm() && + isShiftedUInt<4,2>(MI.getOperand(1).getImm()) && + MI.getOperand(2).isImm() && isUInt<1>(MI.getOperand(2).getImm())) return HexagonII::HSIG_S2; break; case Hexagon::S4_storeirb_io: // memb(Rs+#u4) = #U1 - Src1Reg = MI->getOperand(0).getReg(); + Src1Reg = MI.getOperand(0).getReg(); if (isIntRegForSubInst(Src1Reg) && - MI->getOperand(1).isImm() && isUInt<4>(MI->getOperand(1).getImm()) && - MI->getOperand(2).isImm() && isUInt<1>(MI->getOperand(2).getImm())) + MI.getOperand(1).isImm() && isUInt<4>(MI.getOperand(1).getImm()) && + MI.getOperand(2).isImm() && isUInt<1>(MI.getOperand(2).getImm())) return HexagonII::HSIG_S2; break; case Hexagon::S2_allocframe: - if (MI->getOperand(0).isImm() && - isShiftedUInt<5,3>(MI->getOperand(0).getImm())) + if (MI.getOperand(0).isImm() && + isShiftedUInt<5,3>(MI.getOperand(0).getImm())) return HexagonII::HSIG_S1; break; // @@ -3767,31 +3834,31 @@ HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup( // Rd = sxth/sxtb/zxtb/zxth(Rs) // Rd = and(Rs,#1) case Hexagon::A2_addi: - DstReg = MI->getOperand(0).getReg(); - SrcReg = MI->getOperand(1).getReg(); + DstReg = MI.getOperand(0).getReg(); + SrcReg = MI.getOperand(1).getReg(); if (isIntRegForSubInst(DstReg)) { // Rd = add(r29,#u6:2) if (Hexagon::IntRegsRegClass.contains(SrcReg) && - HRI.getStackRegister() == SrcReg && MI->getOperand(2).isImm() && - isShiftedUInt<6,2>(MI->getOperand(2).getImm())) + HRI.getStackRegister() == SrcReg && MI.getOperand(2).isImm() && + isShiftedUInt<6,2>(MI.getOperand(2).getImm())) return HexagonII::HSIG_A; // Rx = add(Rx,#s7) - if ((DstReg == SrcReg) && MI->getOperand(2).isImm() && - isInt<7>(MI->getOperand(2).getImm())) + if ((DstReg == SrcReg) && MI.getOperand(2).isImm() && + isInt<7>(MI.getOperand(2).getImm())) return HexagonII::HSIG_A; // Rd = add(Rs,#1) // Rd = add(Rs,#-1) - if (isIntRegForSubInst(SrcReg) && MI->getOperand(2).isImm() && - ((MI->getOperand(2).getImm() == 1) || - (MI->getOperand(2).getImm() == -1))) + if (isIntRegForSubInst(SrcReg) && MI.getOperand(2).isImm() && + ((MI.getOperand(2).getImm() == 1) || + (MI.getOperand(2).getImm() == -1))) return HexagonII::HSIG_A; } break; case Hexagon::A2_add: // Rx = add(Rx,Rs) - DstReg = MI->getOperand(0).getReg(); - Src1Reg = MI->getOperand(1).getReg(); - Src2Reg = MI->getOperand(2).getReg(); + DstReg = MI.getOperand(0).getReg(); + Src1Reg = MI.getOperand(1).getReg(); + Src2Reg = MI.getOperand(2).getReg(); if (isIntRegForSubInst(DstReg) && (DstReg == Src1Reg) && isIntRegForSubInst(Src2Reg)) return HexagonII::HSIG_A; @@ -3800,18 +3867,18 @@ HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup( // Same as zxtb. // Rd16=and(Rs16,#255) // Rd16=and(Rs16,#1) - DstReg = MI->getOperand(0).getReg(); - SrcReg = MI->getOperand(1).getReg(); + DstReg = MI.getOperand(0).getReg(); + SrcReg = MI.getOperand(1).getReg(); if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) && - MI->getOperand(2).isImm() && - ((MI->getOperand(2).getImm() == 1) || - (MI->getOperand(2).getImm() == 255))) + MI.getOperand(2).isImm() && + ((MI.getOperand(2).getImm() == 1) || + (MI.getOperand(2).getImm() == 255))) return HexagonII::HSIG_A; break; case Hexagon::A2_tfr: // Rd = Rs - DstReg = MI->getOperand(0).getReg(); - SrcReg = MI->getOperand(1).getReg(); + DstReg = MI.getOperand(0).getReg(); + SrcReg = MI.getOperand(1).getReg(); if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg)) return HexagonII::HSIG_A; break; @@ -3820,7 +3887,7 @@ HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup( // Do not test for #u6 size since the const is getting extended // regardless and compound could be formed. // Rd = #-1 - DstReg = MI->getOperand(0).getReg(); + DstReg = MI.getOperand(0).getReg(); if (isIntRegForSubInst(DstReg)) return HexagonII::HSIG_A; break; @@ -3831,51 +3898,51 @@ HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup( // if ([!]P0[.new]) Rd = #0 // Actual form: // %R16<def> = C2_cmovenewit %P0<internal>, 0, %R16<imp-use,undef>; - DstReg = MI->getOperand(0).getReg(); - SrcReg = MI->getOperand(1).getReg(); + DstReg = MI.getOperand(0).getReg(); + SrcReg = MI.getOperand(1).getReg(); if (isIntRegForSubInst(DstReg) && Hexagon::PredRegsRegClass.contains(SrcReg) && Hexagon::P0 == SrcReg && - MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0) + MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0) return HexagonII::HSIG_A; break; case Hexagon::C2_cmpeqi: // P0 = cmp.eq(Rs,#u2) - DstReg = MI->getOperand(0).getReg(); - SrcReg = MI->getOperand(1).getReg(); + DstReg = MI.getOperand(0).getReg(); + SrcReg = MI.getOperand(1).getReg(); if (Hexagon::PredRegsRegClass.contains(DstReg) && Hexagon::P0 == DstReg && isIntRegForSubInst(SrcReg) && - MI->getOperand(2).isImm() && isUInt<2>(MI->getOperand(2).getImm())) + MI.getOperand(2).isImm() && isUInt<2>(MI.getOperand(2).getImm())) return HexagonII::HSIG_A; break; case Hexagon::A2_combineii: case Hexagon::A4_combineii: // Rdd = combine(#u2,#U2) - DstReg = MI->getOperand(0).getReg(); + DstReg = MI.getOperand(0).getReg(); if (isDblRegForSubInst(DstReg, HRI) && - ((MI->getOperand(1).isImm() && isUInt<2>(MI->getOperand(1).getImm())) || - (MI->getOperand(1).isGlobal() && - isUInt<2>(MI->getOperand(1).getOffset()))) && - ((MI->getOperand(2).isImm() && isUInt<2>(MI->getOperand(2).getImm())) || - (MI->getOperand(2).isGlobal() && - isUInt<2>(MI->getOperand(2).getOffset())))) + ((MI.getOperand(1).isImm() && isUInt<2>(MI.getOperand(1).getImm())) || + (MI.getOperand(1).isGlobal() && + isUInt<2>(MI.getOperand(1).getOffset()))) && + ((MI.getOperand(2).isImm() && isUInt<2>(MI.getOperand(2).getImm())) || + (MI.getOperand(2).isGlobal() && + isUInt<2>(MI.getOperand(2).getOffset())))) return HexagonII::HSIG_A; break; case Hexagon::A4_combineri: // Rdd = combine(Rs,#0) - DstReg = MI->getOperand(0).getReg(); - SrcReg = MI->getOperand(1).getReg(); + DstReg = MI.getOperand(0).getReg(); + SrcReg = MI.getOperand(1).getReg(); if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) && - ((MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0) || - (MI->getOperand(2).isGlobal() && MI->getOperand(2).getOffset() == 0))) + ((MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0) || + (MI.getOperand(2).isGlobal() && MI.getOperand(2).getOffset() == 0))) return HexagonII::HSIG_A; break; case Hexagon::A4_combineir: // Rdd = combine(#0,Rs) - DstReg = MI->getOperand(0).getReg(); - SrcReg = MI->getOperand(2).getReg(); + DstReg = MI.getOperand(0).getReg(); + SrcReg = MI.getOperand(2).getReg(); if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) && - ((MI->getOperand(1).isImm() && MI->getOperand(1).getImm() == 0) || - (MI->getOperand(1).isGlobal() && MI->getOperand(1).getOffset() == 0))) + ((MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) || + (MI.getOperand(1).isGlobal() && MI.getOperand(1).getOffset() == 0))) return HexagonII::HSIG_A; break; case Hexagon::A2_sxtb: @@ -3883,8 +3950,8 @@ HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup( case Hexagon::A2_zxtb: case Hexagon::A2_zxth: // Rd = sxth/sxtb/zxtb/zxth(Rs) - DstReg = MI->getOperand(0).getReg(); - SrcReg = MI->getOperand(1).getReg(); + DstReg = MI.getOperand(0).getReg(); + SrcReg = MI.getOperand(1).getReg(); if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg)) return HexagonII::HSIG_A; break; @@ -3894,8 +3961,8 @@ HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup( } -short HexagonInstrInfo::getEquivalentHWInstr(const MachineInstr *MI) const { - return Hexagon::getRealHWInstr(MI->getOpcode(), Hexagon::InstrType_Real); +short HexagonInstrInfo::getEquivalentHWInstr(const MachineInstr &MI) const { + return Hexagon::getRealHWInstr(MI.getOpcode(), Hexagon::InstrType_Real); } @@ -3903,30 +3970,30 @@ short HexagonInstrInfo::getEquivalentHWInstr(const MachineInstr *MI) const { MachineInstr *HexagonInstrInfo::getFirstNonDbgInst(MachineBasicBlock *BB) const { for (auto MII = BB->instr_begin(), End = BB->instr_end(); MII != End; MII++) { - MachineInstr *MI = &*MII; - if (MI->isDebugValue()) + MachineInstr &MI = *MII; + if (MI.isDebugValue()) continue; - return MI; + return &MI; } return nullptr; } unsigned HexagonInstrInfo::getInstrTimingClassLatency( - const InstrItineraryData *ItinData, const MachineInstr *MI) const { + const InstrItineraryData *ItinData, const MachineInstr &MI) const { // Default to one cycle for no itinerary. However, an "empty" itinerary may // still have a MinLatency property, which getStageLatency checks. if (!ItinData) - return getInstrLatency(ItinData, *MI); + return getInstrLatency(ItinData, MI); // Get the latency embedded in the itinerary. If we're not using timing class // latencies or if we using BSB scheduling, then restrict the maximum latency // to 1 (that is, either 0 or 1). - if (MI->isTransient()) + if (MI.isTransient()) return 0; - unsigned Latency = ItinData->getStageLatency(MI->getDesc().getSchedClass()); + unsigned Latency = ItinData->getStageLatency(MI.getDesc().getSchedClass()); if (!EnableTimingClassLatency || - MI->getParent()->getParent()->getSubtarget<HexagonSubtarget>(). + MI.getParent()->getParent()->getSubtarget<HexagonSubtarget>(). useBSBScheduling()) if (Latency > 1) Latency = 1; @@ -3959,8 +4026,8 @@ unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const { // Returns the max value that doesn't need to be extended. -int HexagonInstrInfo::getMaxValue(const MachineInstr *MI) const { - const uint64_t F = MI->getDesc().TSFlags; +int HexagonInstrInfo::getMaxValue(const MachineInstr &MI) const { + const uint64_t F = MI.getDesc().TSFlags; unsigned isSigned = (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; unsigned bits = (F >> HexagonII::ExtentBitsPos) @@ -3973,15 +4040,15 @@ int HexagonInstrInfo::getMaxValue(const MachineInstr *MI) const { } -unsigned HexagonInstrInfo::getMemAccessSize(const MachineInstr* MI) const { - const uint64_t F = MI->getDesc().TSFlags; +unsigned HexagonInstrInfo::getMemAccessSize(const MachineInstr &MI) const { + const uint64_t F = MI.getDesc().TSFlags; return (F >> HexagonII::MemAccessSizePos) & HexagonII::MemAccesSizeMask; } // Returns the min value that doesn't need to be extended. -int HexagonInstrInfo::getMinValue(const MachineInstr *MI) const { - const uint64_t F = MI->getDesc().TSFlags; +int HexagonInstrInfo::getMinValue(const MachineInstr &MI) const { + const uint64_t F = MI.getDesc().TSFlags; unsigned isSigned = (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; unsigned bits = (F >> HexagonII::ExtentBitsPos) @@ -3995,22 +4062,22 @@ int HexagonInstrInfo::getMinValue(const MachineInstr *MI) const { // Returns opcode of the non-extended equivalent instruction. -short HexagonInstrInfo::getNonExtOpcode(const MachineInstr *MI) const { +short HexagonInstrInfo::getNonExtOpcode(const MachineInstr &MI) const { // Check if the instruction has a register form that uses register in place // of the extended operand, if so return that as the non-extended form. - short NonExtOpcode = Hexagon::getRegForm(MI->getOpcode()); + short NonExtOpcode = Hexagon::getRegForm(MI.getOpcode()); if (NonExtOpcode >= 0) return NonExtOpcode; - if (MI->getDesc().mayLoad() || MI->getDesc().mayStore()) { + if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) { // Check addressing mode and retrieve non-ext equivalent instruction. switch (getAddrMode(MI)) { case HexagonII::Absolute : - return Hexagon::getBaseWithImmOffset(MI->getOpcode()); + return Hexagon::getBaseWithImmOffset(MI.getOpcode()); case HexagonII::BaseImmOffset : - return Hexagon::getBaseWithRegOffset(MI->getOpcode()); + return Hexagon::getBaseWithRegOffset(MI.getOpcode()); case HexagonII::BaseLongOffset: - return Hexagon::getRegShlForm(MI->getOpcode()); + return Hexagon::getRegShlForm(MI.getOpcode()); default: return -1; @@ -4026,8 +4093,8 @@ bool HexagonInstrInfo::getPredReg(ArrayRef<MachineOperand> Cond, return false; assert(Cond.size() == 2); if (isNewValueJump(Cond[0].getImm()) || Cond[1].isMBB()) { - DEBUG(dbgs() << "No predregs for new-value jumps/endloop"); - return false; + DEBUG(dbgs() << "No predregs for new-value jumps/endloop"); + return false; } PredReg = Cond[1].getReg(); PredRegPos = 1; @@ -4041,13 +4108,13 @@ bool HexagonInstrInfo::getPredReg(ArrayRef<MachineOperand> Cond, } -short HexagonInstrInfo::getPseudoInstrPair(const MachineInstr *MI) const { - return Hexagon::getRealHWInstr(MI->getOpcode(), Hexagon::InstrType_Pseudo); +short HexagonInstrInfo::getPseudoInstrPair(const MachineInstr &MI) const { + return Hexagon::getRealHWInstr(MI.getOpcode(), Hexagon::InstrType_Pseudo); } -short HexagonInstrInfo::getRegForm(const MachineInstr *MI) const { - return Hexagon::getRegForm(MI->getOpcode()); +short HexagonInstrInfo::getRegForm(const MachineInstr &MI) const { + return Hexagon::getRegForm(MI.getOpcode()); } @@ -4055,11 +4122,11 @@ short HexagonInstrInfo::getRegForm(const MachineInstr *MI) const { // Hexagon instructions are fixed length, 4 bytes, unless they // use a constant extender, which requires another 4 bytes. // For debug instructions and prolog labels, return 0. -unsigned HexagonInstrInfo::getSize(const MachineInstr *MI) const { - if (MI->isDebugValue() || MI->isPosition()) +unsigned HexagonInstrInfo::getSize(const MachineInstr &MI) const { + if (MI.isDebugValue() || MI.isPosition()) return 0; - unsigned Size = MI->getDesc().getSize(); + unsigned Size = MI.getDesc().getSize(); if (!Size) // Assume the default insn size in case it cannot be determined // for whatever reason. @@ -4069,20 +4136,20 @@ unsigned HexagonInstrInfo::getSize(const MachineInstr *MI) const { Size += HEXAGON_INSTR_SIZE; // Try and compute number of instructions in asm. - if (BranchRelaxAsmLarge && MI->getOpcode() == Hexagon::INLINEASM) { - const MachineBasicBlock &MBB = *MI->getParent(); + if (BranchRelaxAsmLarge && MI.getOpcode() == Hexagon::INLINEASM) { + const MachineBasicBlock &MBB = *MI.getParent(); const MachineFunction *MF = MBB.getParent(); const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo(); // Count the number of register definitions to find the asm string. unsigned NumDefs = 0; - for (; MI->getOperand(NumDefs).isReg() && MI->getOperand(NumDefs).isDef(); + for (; MI.getOperand(NumDefs).isReg() && MI.getOperand(NumDefs).isDef(); ++NumDefs) - assert(NumDefs != MI->getNumOperands()-2 && "No asm string?"); + assert(NumDefs != MI.getNumOperands()-2 && "No asm string?"); - assert(MI->getOperand(NumDefs).isSymbol() && "No asm string?"); + assert(MI.getOperand(NumDefs).isSymbol() && "No asm string?"); // Disassemble the AsmStr and approximate number of instructions. - const char *AsmStr = MI->getOperand(NumDefs).getSymbolName(); + const char *AsmStr = MI.getOperand(NumDefs).getSymbolName(); Size = getInlineAsmLength(AsmStr, *MAI); } @@ -4090,16 +4157,16 @@ unsigned HexagonInstrInfo::getSize(const MachineInstr *MI) const { } -uint64_t HexagonInstrInfo::getType(const MachineInstr* MI) const { - const uint64_t F = MI->getDesc().TSFlags; +uint64_t HexagonInstrInfo::getType(const MachineInstr &MI) const { + const uint64_t F = MI.getDesc().TSFlags; return (F >> HexagonII::TypePos) & HexagonII::TypeMask; } -unsigned HexagonInstrInfo::getUnits(const MachineInstr* MI) const { - const TargetSubtargetInfo &ST = MI->getParent()->getParent()->getSubtarget(); +unsigned HexagonInstrInfo::getUnits(const MachineInstr &MI) const { + const TargetSubtargetInfo &ST = MI.getParent()->getParent()->getSubtarget(); const InstrItineraryData &II = *ST.getInstrItineraryData(); - const InstrStage &IS = *II.beginStage(MI->getDesc().getSchedClass()); + const InstrStage &IS = *II.beginStage(MI.getDesc().getSchedClass()); return IS.getUnits(); } @@ -4122,18 +4189,18 @@ unsigned HexagonInstrInfo::nonDbgBundleSize( assert(BundleHead->isBundle() && "Not a bundle header"); auto MII = BundleHead.getInstrIterator(); // Skip the bundle header. - return nonDbgMICount(++MII, getBundleEnd(*BundleHead)); + return nonDbgMICount(++MII, getBundleEnd(BundleHead.getInstrIterator())); } /// immediateExtend - Changes the instruction in place to one using an immediate /// extender. -void HexagonInstrInfo::immediateExtend(MachineInstr *MI) const { +void HexagonInstrInfo::immediateExtend(MachineInstr &MI) const { assert((isExtendable(MI)||isConstExtended(MI)) && "Instruction must be extendable"); // Find which operand is extendable. short ExtOpNum = getCExtOpNum(MI); - MachineOperand &MO = MI->getOperand(ExtOpNum); + MachineOperand &MO = MI.getOperand(ExtOpNum); // This needs to be something we understand. assert((MO.isMBB() || MO.isImm()) && "Branch with unknown extendable field type"); @@ -4143,22 +4210,22 @@ void HexagonInstrInfo::immediateExtend(MachineInstr *MI) const { bool HexagonInstrInfo::invertAndChangeJumpTarget( - MachineInstr* MI, MachineBasicBlock* NewTarget) const { + MachineInstr &MI, MachineBasicBlock *NewTarget) const { DEBUG(dbgs() << "\n[invertAndChangeJumpTarget] to BB#" - << NewTarget->getNumber(); MI->dump();); - assert(MI->isBranch()); - unsigned NewOpcode = getInvertedPredicatedOpcode(MI->getOpcode()); - int TargetPos = MI->getNumOperands() - 1; + << NewTarget->getNumber(); MI.dump();); + assert(MI.isBranch()); + unsigned NewOpcode = getInvertedPredicatedOpcode(MI.getOpcode()); + int TargetPos = MI.getNumOperands() - 1; // In general branch target is the last operand, // but some implicit defs added at the end might change it. - while ((TargetPos > -1) && !MI->getOperand(TargetPos).isMBB()) + while ((TargetPos > -1) && !MI.getOperand(TargetPos).isMBB()) --TargetPos; - assert((TargetPos >= 0) && MI->getOperand(TargetPos).isMBB()); - MI->getOperand(TargetPos).setMBB(NewTarget); - if (EnableBranchPrediction && isPredicatedNew(*MI)) { + assert((TargetPos >= 0) && MI.getOperand(TargetPos).isMBB()); + MI.getOperand(TargetPos).setMBB(NewTarget); + if (EnableBranchPrediction && isPredicatedNew(MI)) { NewOpcode = reversePrediction(NewOpcode); } - MI->setDesc(get(NewOpcode)); + MI.setDesc(get(NewOpcode)); return true; } @@ -4168,13 +4235,12 @@ void HexagonInstrInfo::genAllInsnTimingClasses(MachineFunction &MF) const { MachineFunction::iterator A = MF.begin(); MachineBasicBlock &B = *A; MachineBasicBlock::iterator I = B.begin(); - MachineInstr *MI = &*I; - DebugLoc DL = MI->getDebugLoc(); + DebugLoc DL = I->getDebugLoc(); MachineInstr *NewMI; for (unsigned insn = TargetOpcode::GENERIC_OP_END+1; insn < Hexagon::INSTRUCTION_LIST_END; ++insn) { - NewMI = BuildMI(B, MI, DL, get(insn)); + NewMI = BuildMI(B, I, DL, get(insn)); DEBUG(dbgs() << "\n" << getName(NewMI->getOpcode()) << " Class: " << NewMI->getDesc().getSchedClass()); NewMI->eraseFromParent(); @@ -4186,9 +4252,9 @@ void HexagonInstrInfo::genAllInsnTimingClasses(MachineFunction &MF) const { // inverts the predication logic. // p -> NotP // NotP -> P -bool HexagonInstrInfo::reversePredSense(MachineInstr* MI) const { - DEBUG(dbgs() << "\nTrying to reverse pred. sense of:"; MI->dump()); - MI->setDesc(get(getInvertedPredicatedOpcode(MI->getOpcode()))); +bool HexagonInstrInfo::reversePredSense(MachineInstr &MI) const { + DEBUG(dbgs() << "\nTrying to reverse pred. sense of:"; MI.dump()); + MI.setDesc(get(getInvertedPredicatedOpcode(MI.getOpcode()))); return true; } @@ -4212,6 +4278,6 @@ bool HexagonInstrInfo::validateBranchCond(const ArrayRef<MachineOperand> &Cond) } -short HexagonInstrInfo::xformRegToImmOffset(const MachineInstr *MI) const { - return Hexagon::xformRegToImmOffset(MI->getOpcode()); +short HexagonInstrInfo::xformRegToImmOffset(const MachineInstr &MI) const { + return Hexagon::xformRegToImmOffset(MI.getOpcode()); } |
