X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FMips%2FMipsDelaySlotFiller.cpp;h=f8daec9e50f0550f0ec5ec4685076d45b4e5a88e;hb=ecadea992afb933085a388edfa5d9d1a8832b969;hp=bf76fab79685e05890b0def70f3f1b2406e0acb4;hpb=d628f19f5df9e4033adce5af969049e90a90ae5d;p=oota-llvm.git diff --git a/lib/Target/Mips/MipsDelaySlotFiller.cpp b/lib/Target/Mips/MipsDelaySlotFiller.cpp index bf76fab7968..f8daec9e50f 100644 --- a/lib/Target/Mips/MipsDelaySlotFiller.cpp +++ b/lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -11,8 +11,7 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "delay-slot-filler" - +#include "MCTargetDesc/MipsMCNaCl.h" #include "Mips.h" #include "MipsInstrInfo.h" #include "MipsTargetMachine.h" @@ -24,6 +23,7 @@ #include "llvm/CodeGen/MachineBranchProbabilityInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetInstrInfo.h" @@ -32,6 +32,8 @@ using namespace llvm; +#define DEBUG_TYPE "delay-slot-filler" + STATISTIC(FilledSlots, "Number of delay slots filled"); STATISTIC(UsefulSlots, "Number of delay slots filled with instructions that" " are not NOP."); @@ -123,7 +125,7 @@ namespace { public: NoMemInstr() : InspectMemInstr(true) {} private: - virtual bool hasHazard_(const MachineInstr &MI) { return true; } + bool hasHazard_(const MachineInstr &MI) override { return true; } }; /// This subclass accepts loads from stacks and constant loads. @@ -131,7 +133,7 @@ namespace { public: LoadFromStackOrConst() : InspectMemInstr(false) {} private: - virtual bool hasHazard_(const MachineInstr &MI); + bool hasHazard_(const MachineInstr &MI) override; }; /// This subclass uses memory dependence information to determine whether a @@ -141,19 +143,21 @@ namespace { MemDefsUses(const MachineFrameInfo *MFI); private: - virtual bool hasHazard_(const MachineInstr &MI); + typedef PointerUnion ValueType; + + bool hasHazard_(const MachineInstr &MI) override; /// Update Defs and Uses. Return true if there exist dependences that /// disqualify the delay slot candidate between V and values in Uses and /// Defs. - bool updateDefsUses(const Value *V, bool MayStore); + bool updateDefsUses(ValueType V, bool MayStore); /// Get the list of underlying objects of MI's memory operand. bool getUnderlyingObjects(const MachineInstr &MI, - SmallVectorImpl &Objects) const; + SmallVectorImpl &Objects) const; const MachineFrameInfo *MFI; - SmallPtrSet Uses, Defs; + SmallPtrSet Uses, Defs; /// Flags indicating whether loads or stores with no underlying objects have /// been seen. @@ -165,19 +169,26 @@ namespace { Filler(TargetMachine &tm) : MachineFunctionPass(ID), TM(tm) { } - virtual const char *getPassName() const { + const char *getPassName() const override { return "Mips Delay Slot Filler"; } - bool runOnMachineFunction(MachineFunction &F) { + bool runOnMachineFunction(MachineFunction &F) override { bool Changed = false; for (MachineFunction::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) Changed |= runOnMachineBasicBlock(*FI); + + // This pass invalidates liveness information when it reorders + // instructions to fill delay slot. Without this, -verify-machineinstrs + // will fail. + if (Changed) + F.getRegInfo().invalidateLiveness(); + return Changed; } - void getAnalysisUsage(AnalysisUsage &AU) const { + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -264,7 +275,11 @@ static void addLiveInRegs(Iter Filler, MachineBasicBlock &MBB) { #ifndef NDEBUG const MachineFunction &MF = *MBB.getParent(); - assert(MF.getTarget().getRegisterInfo()->getAllocatableSet(MF).test(R) && + assert(MF.getTarget() + .getSubtargetImpl() + ->getRegisterInfo() + ->getAllocatableSet(MF) + .test(R) && "Shouldn't move an instruction with unallocatable registers across " "basic block boundaries."); #endif @@ -275,8 +290,8 @@ static void addLiveInRegs(Iter Filler, MachineBasicBlock &MBB) { } RegDefsUses::RegDefsUses(TargetMachine &TM) - : TRI(*TM.getRegisterInfo()), Defs(TRI.getNumRegs(), false), - Uses(TRI.getNumRegs(), false) {} + : TRI(*TM.getSubtargetImpl()->getRegisterInfo()), + Defs(TRI.getNumRegs(), false), Uses(TRI.getNumRegs(), false) {} void RegDefsUses::init(const MachineInstr &MI) { // Add all register operands which are explicit and non-variadic. @@ -398,16 +413,15 @@ bool LoadFromStackOrConst::hasHazard_(const MachineInstr &MI) { if (MI.mayStore()) return true; - if (!MI.hasOneMemOperand() || !(*MI.memoperands_begin())->getValue()) + if (!MI.hasOneMemOperand() || !(*MI.memoperands_begin())->getPseudoValue()) return true; - const Value *V = (*MI.memoperands_begin())->getValue(); - - if (isa(V)) - return false; - - if (const PseudoSourceValue *PSV = dyn_cast(V)) - return !PSV->isConstant(0) && V != PseudoSourceValue::getStack(); + if (const PseudoSourceValue *PSV = + (*MI.memoperands_begin())->getPseudoValue()) { + if (isa(PSV)) + return false; + return !PSV->isConstant(nullptr) && PSV != PseudoSourceValue::getStack(); + } return true; } @@ -418,11 +432,11 @@ MemDefsUses::MemDefsUses(const MachineFrameInfo *MFI_) bool MemDefsUses::hasHazard_(const MachineInstr &MI) { bool HasHazard = false; - SmallVector Objs; + SmallVector Objs; // Check underlying object list. if (getUnderlyingObjects(MI, Objs)) { - for (SmallVectorImpl::const_iterator I = Objs.begin(); + for (SmallVectorImpl::const_iterator I = Objs.begin(); I != Objs.end(); ++I) HasHazard |= updateDefsUses(*I, MI.mayStore()); @@ -439,7 +453,7 @@ bool MemDefsUses::hasHazard_(const MachineInstr &MI) { return HasHazard; } -bool MemDefsUses::updateDefsUses(const Value *V, bool MayStore) { +bool MemDefsUses::updateDefsUses(ValueType V, bool MayStore) { if (MayStore) return !Defs.insert(V) || Uses.count(V) || SeenNoObjStore || SeenNoObjLoad; @@ -449,10 +463,20 @@ bool MemDefsUses::updateDefsUses(const Value *V, bool MayStore) { bool MemDefsUses:: getUnderlyingObjects(const MachineInstr &MI, - SmallVectorImpl &Objects) const { - if (!MI.hasOneMemOperand() || !(*MI.memoperands_begin())->getValue()) + SmallVectorImpl &Objects) const { + if (!MI.hasOneMemOperand() || + (!(*MI.memoperands_begin())->getValue() && + !(*MI.memoperands_begin())->getPseudoValue())) return false; + if (const PseudoSourceValue *PSV = + (*MI.memoperands_begin())->getPseudoValue()) { + if (!PSV->isAliased(MFI)) + return false; + Objects.push_back(PSV); + return true; + } + const Value *V = (*MI.memoperands_begin())->getValue(); SmallVector Objs; @@ -460,10 +484,7 @@ getUnderlyingObjects(const MachineInstr &MI, for (SmallVectorImpl::iterator I = Objs.begin(), E = Objs.end(); I != E; ++I) { - if (const PseudoSourceValue *PSV = dyn_cast(*I)) { - if (PSV->isAliased(MFI)) - return false; - } else if (!isIdentifiedObject(V)) + if (!isIdentifiedObject(V)) return false; Objects.push_back(*I); @@ -498,8 +519,8 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { } // Bundle the NOP to the instruction with the delay slot. - const MipsInstrInfo *TII = - static_cast(TM.getInstrInfo()); + const MipsInstrInfo *TII = static_cast( + TM.getSubtargetImpl()->getInstrInfo()); BuildMI(MBB, std::next(I), I->getDebugLoc(), TII->get(Mips::NOP)); MIBundleBuilder(MBB, I, std::next(I, 2)); } @@ -531,6 +552,19 @@ bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, if (delayHasHazard(*I, RegDU, IM)) continue; + if (TM.getSubtarget().isTargetNaCl()) { + // In NaCl, instructions that must be masked are forbidden in delay slots. + // We only check for loads, stores and SP changes. Calls, returns and + // 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, + TM.getSubtargetImpl()->getRegisterInfo())) + continue; + } + Filler = I; return true; } @@ -589,7 +623,7 @@ bool Filler::searchSuccBBs(MachineBasicBlock &MBB, Iter Slot) const { RegDefsUses RegDU(TM); bool HasMultipleSuccs = false; BB2BrMap BrMap; - OwningPtr IM; + std::unique_ptr IM; Iter Filler; // Iterate over SuccBB's predecessor list. @@ -623,7 +657,7 @@ bool Filler::searchSuccBBs(MachineBasicBlock &MBB, Iter Slot) const { MachineBasicBlock *Filler::selectSuccBB(MachineBasicBlock &B) const { if (B.succ_empty()) - return NULL; + return nullptr; // Select the successor with the larget edge weight. auto &Prob = getAnalysis(); @@ -632,14 +666,14 @@ MachineBasicBlock *Filler::selectSuccBB(MachineBasicBlock &B) const { const MachineBasicBlock *Dst1) { return Prob.getEdgeWeight(&B, Dst0) < Prob.getEdgeWeight(&B, Dst1); }); - return S->isLandingPad() ? NULL : S; + return S->isLandingPad() ? nullptr : S; } std::pair Filler::getBranch(MachineBasicBlock &MBB, const MachineBasicBlock &Dst) const { const MipsInstrInfo *TII = - static_cast(TM.getInstrInfo()); - MachineBasicBlock *TrueBB = 0, *FalseBB = 0; + static_cast(TM.getSubtargetImpl()->getInstrInfo()); + MachineBasicBlock *TrueBB = nullptr, *FalseBB = nullptr; SmallVector BranchInstrs; SmallVector Cond; @@ -647,11 +681,11 @@ Filler::getBranch(MachineBasicBlock &MBB, const MachineBasicBlock &Dst) const { TII->AnalyzeBranch(MBB, TrueBB, FalseBB, Cond, false, BranchInstrs); if ((R == MipsInstrInfo::BT_None) || (R == MipsInstrInfo::BT_NoBranch)) - return std::make_pair(R, (MachineInstr*)NULL); + return std::make_pair(R, nullptr); if (R != MipsInstrInfo::BT_CondUncond) { if (!hasUnoccupiedSlot(BranchInstrs[0])) - return std::make_pair(MipsInstrInfo::BT_None, (MachineInstr*)NULL); + return std::make_pair(MipsInstrInfo::BT_None, nullptr); assert(((R != MipsInstrInfo::BT_Uncond) || (TrueBB == &Dst))); @@ -668,7 +702,7 @@ Filler::getBranch(MachineBasicBlock &MBB, const MachineBasicBlock &Dst) const { if (hasUnoccupiedSlot(BranchInstrs[1]) && (FalseBB == &Dst)) return std::make_pair(MipsInstrInfo::BT_Uncond, BranchInstrs[1]); - return std::make_pair(MipsInstrInfo::BT_None, (MachineInstr*)NULL); + return std::make_pair(MipsInstrInfo::BT_None, nullptr); } bool Filler::examinePred(MachineBasicBlock &Pred, const MachineBasicBlock &Succ, @@ -704,6 +738,6 @@ bool Filler::delayHasHazard(const MachineInstr &Candidate, RegDefsUses &RegDU, bool Filler::terminateSearch(const MachineInstr &Candidate) const { return (Candidate.isTerminator() || Candidate.isCall() || - Candidate.isLabel() || Candidate.isInlineAsm() || + Candidate.isPosition() || Candidate.isInlineAsm() || Candidate.hasUnmodeledSideEffects()); }