diff options
Diffstat (limited to 'lib/Target/Mips/MipsDelaySlotFiller.cpp')
-rw-r--r-- | lib/Target/Mips/MipsDelaySlotFiller.cpp | 76 |
1 files changed, 48 insertions, 28 deletions
diff --git a/lib/Target/Mips/MipsDelaySlotFiller.cpp b/lib/Target/Mips/MipsDelaySlotFiller.cpp index e06b57e41834..33f03b954a8c 100644 --- a/lib/Target/Mips/MipsDelaySlotFiller.cpp +++ b/lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -51,7 +51,7 @@ using namespace llvm; -#define DEBUG_TYPE "delay-slot-filler" +#define DEBUG_TYPE "mips-delay-slot-filler" STATISTIC(FilledSlots, "Number of delay slots filled"); STATISTIC(UsefulSlots, "Number of delay slots filled with instructions that" @@ -210,9 +210,11 @@ namespace { bool SeenNoObjStore = false; }; - class Filler : public MachineFunctionPass { + class MipsDelaySlotFiller : public MachineFunctionPass { public: - Filler() : MachineFunctionPass(ID) {} + MipsDelaySlotFiller() : MachineFunctionPass(ID) { + initializeMipsDelaySlotFillerPass(*PassRegistry::getPassRegistry()); + } StringRef getPassName() const override { return "Mips Delay Slot Filler"; } @@ -242,6 +244,8 @@ namespace { MachineFunctionPass::getAnalysisUsage(AU); } + static char ID; + private: bool runOnMachineBasicBlock(MachineBasicBlock &MBB); @@ -292,18 +296,19 @@ namespace { bool terminateSearch(const MachineInstr &Candidate) const; const TargetMachine *TM = nullptr; - - static char ID; }; } // end anonymous namespace -char Filler::ID = 0; +char MipsDelaySlotFiller::ID = 0; static bool hasUnoccupiedSlot(const MachineInstr *MI) { return MI->hasDelaySlot() && !MI->isBundledWithSucc(); } +INITIALIZE_PASS(MipsDelaySlotFiller, DEBUG_TYPE, + "Fill delay slot for MIPS", false, false) + /// This function inserts clones of Filler into predecessor blocks. static void insertDelayFiller(Iter Filler, const BB2BrMap &BrMap) { MachineFunction *MF = Filler->getParent()->getParent(); @@ -551,8 +556,9 @@ getUnderlyingObjects(const MachineInstr &MI, } // Replace Branch with the compact branch instruction. -Iter Filler::replaceWithCompactBranch(MachineBasicBlock &MBB, Iter Branch, - const DebugLoc &DL) { +Iter MipsDelaySlotFiller::replaceWithCompactBranch(MachineBasicBlock &MBB, + Iter Branch, + const DebugLoc &DL) { const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>(); const MipsInstrInfo *TII = STI.getInstrInfo(); @@ -575,6 +581,7 @@ static int getEquivalentCallShort(int Opcode) { case Mips::BLTZAL: return Mips::BLTZALS_MM; case Mips::JAL: + case Mips::JAL_MM: return Mips::JALS_MM; case Mips::JALR: return Mips::JALRS_MM; @@ -591,7 +598,7 @@ static int getEquivalentCallShort(int Opcode) { /// runOnMachineBasicBlock - Fill in delay slots for the given basic block. /// We assume there is only one delay slot per delayed instruction. -bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { +bool MipsDelaySlotFiller::runOnMachineBasicBlock(MachineBasicBlock &MBB) { bool Changed = false; const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>(); bool InMicroMipsMode = STI.inMicroMipsMode(); @@ -632,7 +639,7 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { // TODO: Implement an instruction mapping table of 16bit opcodes to // 32bit opcodes so that an instruction can be expanded. This would // save 16 bits as a TAILCALL_MM pseudo requires a fullsized nop. - // TODO: Permit b16 when branching backwards to the the same function + // TODO: Permit b16 when branching backwards to the same function // if it is in range. DSI->setDesc(TII->get(getEquivalentCallShort(DSI->getOpcode()))); } @@ -669,16 +676,17 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { return Changed; } -template<typename IterTy> -bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, - RegDefsUses &RegDU, InspectMemInstr& IM, Iter Slot, - IterTy &Filler) const { +template <typename IterTy> +bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin, + IterTy End, RegDefsUses &RegDU, + InspectMemInstr &IM, Iter Slot, + IterTy &Filler) const { for (IterTy I = Begin; I != End;) { IterTy CurrI = I; ++I; // skip debug value - if (CurrI->isDebugValue()) + if (CurrI->isDebugInstr()) continue; if (terminateSearch(*CurrI)) @@ -720,6 +728,10 @@ bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, (Opcode == Mips::JR || Opcode == Mips::PseudoIndirectBranch || Opcode == Mips::PseudoReturn || Opcode == Mips::TAILCALL)) continue; + // Instructions LWP/SWP should not be in a delay slot as that + // results in unpredictable behaviour + if (InMicroMipsMode && (Opcode == Mips::LWP_MM || Opcode == Mips::SWP_MM)) + continue; Filler = CurrI; return true; @@ -728,7 +740,8 @@ bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, return false; } -bool Filler::searchBackward(MachineBasicBlock &MBB, MachineInstr &Slot) const { +bool MipsDelaySlotFiller::searchBackward(MachineBasicBlock &MBB, + MachineInstr &Slot) const { if (DisableBackwardSearch) return false; @@ -750,7 +763,8 @@ bool Filler::searchBackward(MachineBasicBlock &MBB, MachineInstr &Slot) const { return true; } -bool Filler::searchForward(MachineBasicBlock &MBB, Iter Slot) const { +bool MipsDelaySlotFiller::searchForward(MachineBasicBlock &MBB, + Iter Slot) const { // Can handle only calls. if (DisableForwardSearch || !Slot->isCall()) return false; @@ -770,7 +784,8 @@ bool Filler::searchForward(MachineBasicBlock &MBB, Iter Slot) const { return true; } -bool Filler::searchSuccBBs(MachineBasicBlock &MBB, Iter Slot) const { +bool MipsDelaySlotFiller::searchSuccBBs(MachineBasicBlock &MBB, + Iter Slot) const { if (DisableSuccBBSearch) return false; @@ -816,7 +831,8 @@ bool Filler::searchSuccBBs(MachineBasicBlock &MBB, Iter Slot) const { return true; } -MachineBasicBlock *Filler::selectSuccBB(MachineBasicBlock &B) const { +MachineBasicBlock * +MipsDelaySlotFiller::selectSuccBB(MachineBasicBlock &B) const { if (B.succ_empty()) return nullptr; @@ -832,7 +848,8 @@ MachineBasicBlock *Filler::selectSuccBB(MachineBasicBlock &B) const { } std::pair<MipsInstrInfo::BranchType, MachineInstr *> -Filler::getBranch(MachineBasicBlock &MBB, const MachineBasicBlock &Dst) const { +MipsDelaySlotFiller::getBranch(MachineBasicBlock &MBB, + const MachineBasicBlock &Dst) const { const MipsInstrInfo *TII = MBB.getParent()->getSubtarget<MipsSubtarget>().getInstrInfo(); MachineBasicBlock *TrueBB = nullptr, *FalseBB = nullptr; @@ -867,11 +884,13 @@ Filler::getBranch(MachineBasicBlock &MBB, const MachineBasicBlock &Dst) const { return std::make_pair(MipsInstrInfo::BT_None, nullptr); } -bool Filler::examinePred(MachineBasicBlock &Pred, const MachineBasicBlock &Succ, - RegDefsUses &RegDU, bool &HasMultipleSuccs, - BB2BrMap &BrMap) const { +bool MipsDelaySlotFiller::examinePred(MachineBasicBlock &Pred, + const MachineBasicBlock &Succ, + RegDefsUses &RegDU, + bool &HasMultipleSuccs, + BB2BrMap &BrMap) const { std::pair<MipsInstrInfo::BranchType, MachineInstr *> P = - getBranch(Pred, Succ); + getBranch(Pred, Succ); // Return if either getBranch wasn't able to analyze the branches or there // were no branches with unoccupied slots. @@ -888,8 +907,9 @@ bool Filler::examinePred(MachineBasicBlock &Pred, const MachineBasicBlock &Succ, return true; } -bool Filler::delayHasHazard(const MachineInstr &Candidate, RegDefsUses &RegDU, - InspectMemInstr &IM) const { +bool MipsDelaySlotFiller::delayHasHazard(const MachineInstr &Candidate, + RegDefsUses &RegDU, + InspectMemInstr &IM) const { assert(!Candidate.isKill() && "KILL instructions should have been eliminated at this point."); @@ -901,7 +921,7 @@ bool Filler::delayHasHazard(const MachineInstr &Candidate, RegDefsUses &RegDU, return HasHazard; } -bool Filler::terminateSearch(const MachineInstr &Candidate) const { +bool MipsDelaySlotFiller::terminateSearch(const MachineInstr &Candidate) const { return (Candidate.isTerminator() || Candidate.isCall() || Candidate.isPosition() || Candidate.isInlineAsm() || Candidate.hasUnmodeledSideEffects()); @@ -909,4 +929,4 @@ bool Filler::terminateSearch(const MachineInstr &Candidate) const { /// createMipsDelaySlotFillerPass - Returns a pass that fills in delay /// slots in Mips MachineFunctions -FunctionPass *llvm::createMipsDelaySlotFillerPass() { return new Filler(); } +FunctionPass *llvm::createMipsDelaySlotFillerPass() { return new MipsDelaySlotFiller(); } |