diff options
Diffstat (limited to 'lib/Target/Mips/MipsDelaySlotFiller.cpp')
-rw-r--r-- | lib/Target/Mips/MipsDelaySlotFiller.cpp | 51 |
1 files changed, 27 insertions, 24 deletions
diff --git a/lib/Target/Mips/MipsDelaySlotFiller.cpp b/lib/Target/Mips/MipsDelaySlotFiller.cpp index ffbd83b..eef9f38 100644 --- a/lib/Target/Mips/MipsDelaySlotFiller.cpp +++ b/lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -13,6 +13,7 @@ #define DEBUG_TYPE "delay-slot-filler" +#include "MCTargetDesc/MipsMCNaCl.h" #include "Mips.h" #include "MipsInstrInfo.h" #include "MipsTargetMachine.h" @@ -65,20 +66,6 @@ namespace { typedef MachineBasicBlock::reverse_iterator ReverseIter; typedef SmallDenseMap<MachineBasicBlock*, MachineInstr*, 2> BB2BrMap; - /// \brief A functor comparing edge weight of two blocks. - struct CmpWeight { - CmpWeight(const MachineBasicBlock &S, - const MachineBranchProbabilityInfo &P) : Src(S), Prob(P) {} - - bool operator()(const MachineBasicBlock *Dst0, - const MachineBasicBlock *Dst1) const { - return Prob.getEdgeWeight(&Src, Dst0) < Prob.getEdgeWeight(&Src, Dst1); - } - - const MachineBasicBlock &Src; - const MachineBranchProbabilityInfo &Prob; - }; - class RegDefsUses { public: RegDefsUses(TargetMachine &TM); @@ -514,8 +501,8 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { // Bundle the NOP to the instruction with the delay slot. const MipsInstrInfo *TII = static_cast<const MipsInstrInfo*>(TM.getInstrInfo()); - BuildMI(MBB, llvm::next(I), I->getDebugLoc(), TII->get(Mips::NOP)); - MIBundleBuilder(MBB, I, llvm::next(llvm::next(I))); + BuildMI(MBB, std::next(I), I->getDebugLoc(), TII->get(Mips::NOP)); + MIBundleBuilder(MBB, I, std::next(I, 2)); } return Changed; @@ -545,6 +532,18 @@ bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, if (delayHasHazard(*I, RegDU, IM)) continue; + if (TM.getSubtarget<MipsSubtarget>().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.getRegisterInfo())) + continue; + } + Filler = I; return true; } @@ -565,8 +564,8 @@ bool Filler::searchBackward(MachineBasicBlock &MBB, Iter Slot) const { if (!searchRange(MBB, ReverseIter(Slot), MBB.rend(), RegDU, MemDU, Filler)) return false; - MBB.splice(llvm::next(Slot), &MBB, llvm::next(Filler).base()); - MIBundleBuilder(MBB, Slot, llvm::next(llvm::next(Slot))); + MBB.splice(std::next(Slot), &MBB, std::next(Filler).base()); + MIBundleBuilder(MBB, Slot, std::next(Slot, 2)); ++UsefulSlots; return true; } @@ -582,11 +581,11 @@ bool Filler::searchForward(MachineBasicBlock &MBB, Iter Slot) const { RegDU.setCallerSaved(*Slot); - if (!searchRange(MBB, llvm::next(Slot), MBB.end(), RegDU, NM, Filler)) + if (!searchRange(MBB, std::next(Slot), MBB.end(), RegDU, NM, Filler)) return false; - MBB.splice(llvm::next(Slot), &MBB, Filler); - MIBundleBuilder(MBB, Slot, llvm::next(llvm::next(Slot))); + MBB.splice(std::next(Slot), &MBB, Filler); + MIBundleBuilder(MBB, Slot, std::next(Slot, 2)); ++UsefulSlots; return true; } @@ -640,8 +639,12 @@ MachineBasicBlock *Filler::selectSuccBB(MachineBasicBlock &B) const { return NULL; // Select the successor with the larget edge weight. - CmpWeight Cmp(B, getAnalysis<MachineBranchProbabilityInfo>()); - MachineBasicBlock *S = *std::max_element(B.succ_begin(), B.succ_end(), Cmp); + auto &Prob = getAnalysis<MachineBranchProbabilityInfo>(); + MachineBasicBlock *S = *std::max_element(B.succ_begin(), B.succ_end(), + [&](const MachineBasicBlock *Dst0, + const MachineBasicBlock *Dst1) { + return Prob.getEdgeWeight(&B, Dst0) < Prob.getEdgeWeight(&B, Dst1); + }); return S->isLandingPad() ? NULL : S; } @@ -714,6 +717,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()); } |