X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FMips%2FMipsDelaySlotFiller.cpp;h=12df2c85aa00b11e2963fab0b0d60e308ceed4ff;hb=de0129ac0821e693b08df7269f956f5418b2b5f7;hp=ac03c0bd3dde4b5c560d21736813cae1149033bd;hpb=85e08ed8a4f5b390c79227238d2ec5e1f7369dcd;p=oota-llvm.git diff --git a/lib/Target/Mips/MipsDelaySlotFiller.cpp b/lib/Target/Mips/MipsDelaySlotFiller.cpp index ac03c0bd3dd..12df2c85aa0 100644 --- a/lib/Target/Mips/MipsDelaySlotFiller.cpp +++ b/lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -140,7 +140,7 @@ namespace { /// memory instruction can be moved to a delay slot. class MemDefsUses : public InspectMemInstr { public: - MemDefsUses(const MachineFrameInfo *MFI); + MemDefsUses(const DataLayout &DL, const MachineFrameInfo *MFI); private: typedef PointerUnion ValueType; @@ -158,6 +158,7 @@ namespace { const MachineFrameInfo *MFI; SmallPtrSet Uses, Defs; + const DataLayout &DL; /// Flags indicating whether loads or stores with no underlying objects have /// been seen. @@ -212,8 +213,8 @@ namespace { /// moved to the delay slot. Returns true on success. template bool searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, - RegDefsUses &RegDU, InspectMemInstr &IM, - IterTy &Filler, Iter Slot) const; + RegDefsUses &RegDU, InspectMemInstr &IM, Iter Slot, + IterTy &Filler) const; /// This function searches in the backward direction for an instruction that /// can be moved to the delay slot. Returns true on success. @@ -314,13 +315,22 @@ void RegDefsUses::init(const MachineInstr &MI) { void RegDefsUses::setCallerSaved(const MachineInstr &MI) { assert(MI.isCall()); + // Add RA/RA_64 to Defs to prevent users of RA/RA_64 from going into + // the delay slot. The reason is that RA/RA_64 must not be changed + // in the delay slot so that the callee can return to the caller. + if (MI.definesRegister(Mips::RA) || MI.definesRegister(Mips::RA_64)) { + Defs.set(Mips::RA); + Defs.set(Mips::RA_64); + } + // If MI is a call, add all caller-saved registers to Defs. BitVector CallerSavedRegs(TRI.getNumRegs(), true); CallerSavedRegs.reset(Mips::ZERO); CallerSavedRegs.reset(Mips::ZERO_64); - for (const MCPhysReg *R = TRI.getCalleeSavedRegs(); *R; ++R) + for (const MCPhysReg *R = TRI.getCalleeSavedRegs(MI.getParent()->getParent()); + *R; ++R) for (MCRegAliasIterator AI(*R, &TRI, true); AI.isValid(); ++AI) CallerSavedRegs.reset(*AI); @@ -421,15 +431,15 @@ bool LoadFromStackOrConst::hasHazard_(const MachineInstr &MI) { (*MI.memoperands_begin())->getPseudoValue()) { if (isa(PSV)) return false; - return !PSV->isConstant(nullptr) && PSV != PseudoSourceValue::getStack(); + return !PSV->isConstant(nullptr) && !PSV->isStack(); } return true; } -MemDefsUses::MemDefsUses(const MachineFrameInfo *MFI_) - : InspectMemInstr(false), MFI(MFI_), SeenNoObjLoad(false), - SeenNoObjStore(false) {} +MemDefsUses::MemDefsUses(const DataLayout &DL, const MachineFrameInfo *MFI_) + : InspectMemInstr(false), MFI(MFI_), DL(DL), SeenNoObjLoad(false), + SeenNoObjStore(false) {} bool MemDefsUses::hasHazard_(const MachineInstr &MI) { bool HasHazard = false; @@ -482,7 +492,7 @@ getUnderlyingObjects(const MachineInstr &MI, const Value *V = (*MI.memoperands_begin())->getValue(); SmallVector Objs; - GetUnderlyingObjects(const_cast(V), Objs); + GetUnderlyingObjects(const_cast(V), Objs, DL); for (SmallVectorImpl::iterator I = Objs.begin(), E = Objs.end(); I != E; ++I) { @@ -639,20 +649,36 @@ FunctionPass *llvm::createMipsDelaySlotFillerPass(MipsTargetMachine &tm) { template bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, - RegDefsUses &RegDU, InspectMemInstr& IM, - IterTy &Filler, Iter Slot) const { - for (IterTy I = Begin; I != End; ++I) { + RegDefsUses &RegDU, InspectMemInstr& IM, Iter Slot, + IterTy &Filler) const { + bool IsReverseIter = std::is_convertible::value; + + for (IterTy I = Begin; I != End;) { + IterTy CurrI = I; + ++I; + // skip debug value - if (I->isDebugValue()) + if (CurrI->isDebugValue()) continue; - if (terminateSearch(*I)) + if (terminateSearch(*CurrI)) break; - assert((!I->isCall() && !I->isReturn() && !I->isBranch()) && + assert((!CurrI->isCall() && !CurrI->isReturn() && !CurrI->isBranch()) && "Cannot put calls, returns or branches in delay slot."); - if (delayHasHazard(*I, RegDU, IM)) + if (CurrI->isKill()) { + CurrI->eraseFromParent(); + + // This special case is needed for reverse iterators, because when we + // erase an instruction, the iterators are updated to point to the next + // instruction. + if (IsReverseIter && I != End) + I = CurrI; + continue; + } + + if (delayHasHazard(*CurrI, RegDU, IM)) continue; const MipsSubtarget &STI = MBB.getParent()->getSubtarget(); @@ -662,21 +688,21 @@ bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, // branches are not checked because non-NaCl targets never put them in // delay slots. unsigned AddrIdx; - if ((isBasePlusOffsetMemoryAccess(I->getOpcode(), &AddrIdx) && - baseRegNeedsLoadStoreMask(I->getOperand(AddrIdx).getReg())) || - I->modifiesRegister(Mips::SP, STI.getRegisterInfo())) + if ((isBasePlusOffsetMemoryAccess(CurrI->getOpcode(), &AddrIdx) && + baseRegNeedsLoadStoreMask(CurrI->getOperand(AddrIdx).getReg())) || + CurrI->modifiesRegister(Mips::SP, STI.getRegisterInfo())) continue; } bool InMicroMipsMode = STI.inMicroMipsMode(); const MipsInstrInfo *TII = STI.getInstrInfo(); unsigned Opcode = (*Slot).getOpcode(); - if (InMicroMipsMode && TII->GetInstSizeInBytes(&(*I)) == 2 && + if (InMicroMipsMode && TII->GetInstSizeInBytes(&(*CurrI)) == 2 && (Opcode == Mips::JR || Opcode == Mips::PseudoIndirectBranch || Opcode == Mips::PseudoReturn)) continue; - Filler = I; + Filler = CurrI; return true; } @@ -687,14 +713,15 @@ bool Filler::searchBackward(MachineBasicBlock &MBB, Iter Slot) const { if (DisableBackwardSearch) return false; - RegDefsUses RegDU(*MBB.getParent()->getSubtarget().getRegisterInfo()); - MemDefsUses MemDU(MBB.getParent()->getFrameInfo()); + auto *Fn = MBB.getParent(); + RegDefsUses RegDU(*Fn->getSubtarget().getRegisterInfo()); + MemDefsUses MemDU(Fn->getDataLayout(), Fn->getFrameInfo()); ReverseIter Filler; RegDU.init(*Slot); - if (!searchRange(MBB, ReverseIter(Slot), MBB.rend(), RegDU, MemDU, Filler, - Slot)) + if (!searchRange(MBB, ReverseIter(Slot), MBB.rend(), RegDU, MemDU, Slot, + Filler)) return false; MBB.splice(std::next(Slot), &MBB, std::next(Filler).base()); @@ -714,7 +741,7 @@ bool Filler::searchForward(MachineBasicBlock &MBB, Iter Slot) const { RegDU.setCallerSaved(*Slot); - if (!searchRange(MBB, std::next(Slot), MBB.end(), RegDU, NM, Filler, Slot)) + if (!searchRange(MBB, std::next(Slot), MBB.end(), RegDU, NM, Slot, Filler)) return false; MBB.splice(std::next(Slot), &MBB, Filler); @@ -737,6 +764,7 @@ bool Filler::searchSuccBBs(MachineBasicBlock &MBB, Iter Slot) const { BB2BrMap BrMap; std::unique_ptr IM; Iter Filler; + auto *Fn = MBB.getParent(); // Iterate over SuccBB's predecessor list. for (MachineBasicBlock::pred_iterator PI = SuccBB->pred_begin(), @@ -746,19 +774,19 @@ bool Filler::searchSuccBBs(MachineBasicBlock &MBB, Iter Slot) const { // Do not allow moving instructions which have unallocatable register operands // across basic block boundaries. - RegDU.setUnallocatableRegs(*MBB.getParent()); + RegDU.setUnallocatableRegs(*Fn); // Only allow moving loads from stack or constants if any of the SuccBB's // predecessors have multiple successors. if (HasMultipleSuccs) { IM.reset(new LoadFromStackOrConst()); } else { - const MachineFrameInfo *MFI = MBB.getParent()->getFrameInfo(); - IM.reset(new MemDefsUses(MFI)); + const MachineFrameInfo *MFI = Fn->getFrameInfo(); + IM.reset(new MemDefsUses(Fn->getDataLayout(), MFI)); } - if (!searchRange(MBB, SuccBB->begin(), SuccBB->end(), RegDU, *IM, Filler, - Slot)) + if (!searchRange(MBB, SuccBB->begin(), SuccBB->end(), RegDU, *IM, Slot, + Filler)) return false; insertDelayFiller(Filler, BrMap); @@ -841,7 +869,10 @@ bool Filler::examinePred(MachineBasicBlock &Pred, const MachineBasicBlock &Succ, bool Filler::delayHasHazard(const MachineInstr &Candidate, RegDefsUses &RegDU, InspectMemInstr &IM) const { - bool HasHazard = (Candidate.isImplicitDef() || Candidate.isKill()); + assert(!Candidate.isKill() && + "KILL instructions should have been eliminated at this point."); + + bool HasHazard = Candidate.isImplicitDef(); HasHazard |= IM.hasHazard(Candidate); HasHazard |= RegDU.update(Candidate, 0, Candidate.getNumOperands());