diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 62 |
1 files changed, 35 insertions, 27 deletions
diff --git a/contrib/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/contrib/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp index b5ba770..c821084 100644 --- a/contrib/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp +++ b/contrib/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -79,8 +79,7 @@ static cl::opt<CompactBranchPolicy> MipsCompactBranchPolicy( cl::values( clEnumValN(CB_Never, "never", "Do not use compact branches if possible."), clEnumValN(CB_Optimal, "optimal", "Use compact branches where appropiate (default)."), - clEnumValN(CB_Always, "always", "Always use compact branches if possible."), - clEnumValEnd + clEnumValN(CB_Always, "always", "Always use compact branches if possible.") ) ); @@ -192,9 +191,7 @@ namespace { Filler(TargetMachine &tm) : MachineFunctionPass(ID), TM(tm) { } - const char *getPassName() const override { - return "Mips Delay Slot Filler"; - } + StringRef getPassName() const override { return "Mips Delay Slot Filler"; } bool runOnMachineFunction(MachineFunction &F) override { bool Changed = false; @@ -213,7 +210,7 @@ namespace { MachineFunctionProperties getRequiredProperties() const override { return MachineFunctionProperties().set( - MachineFunctionProperties::Property::AllVRegsAllocated); + MachineFunctionProperties::Property::NoVRegs); } void getAnalysisUsage(AnalysisUsage &AU) const override { @@ -242,7 +239,7 @@ namespace { /// This function searches in the backward direction for an instruction that /// can be moved to the delay slot. Returns true on success. - bool searchBackward(MachineBasicBlock &MBB, Iter Slot) const; + bool searchBackward(MachineBasicBlock &MBB, MachineInstr &Slot) const; /// This function searches MBB in the forward direction for an instruction /// that can be moved to the delay slot. Returns true on success. @@ -543,6 +540,9 @@ Iter Filler::replaceWithCompactBranch(MachineBasicBlock &MBB, Iter Branch, // For given opcode returns opcode of corresponding instruction with short // delay slot. +// For the pseudo TAILCALL*_MM instrunctions return the short delay slot +// form. Unfortunately, TAILCALL<->b16 is denied as b16 has a limited range +// that is too short to make use of for tail calls. static int getEquivalentCallShort(int Opcode) { switch (Opcode) { case Mips::BGEZAL: @@ -555,6 +555,10 @@ static int getEquivalentCallShort(int Opcode) { return Mips::JALRS_MM; case Mips::JALR16_MM: return Mips::JALRS16_MM; + case Mips::TAILCALL_MM: + llvm_unreachable("Attempting to shorten the TAILCALL_MM pseudo!"); + case Mips::TAILCALLREG: + return Mips::JR16_MM; default: llvm_unreachable("Unexpected call instruction for microMIPS."); } @@ -587,7 +591,7 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { if (MipsCompactBranchPolicy.getValue() != CB_Always || !TII->getEquivalentCompactForm(I)) { - if (searchBackward(MBB, I)) { + if (searchBackward(MBB, *I)) { Filled = true; } else if (I->isTerminator()) { if (searchSuccBBs(MBB, I)) { @@ -602,10 +606,16 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { // Get instruction with delay slot. MachineBasicBlock::instr_iterator DSI = I.getInstrIterator(); - if (InMicroMipsMode && TII->GetInstSizeInBytes(*std::next(DSI)) == 2 && + if (InMicroMipsMode && TII->getInstSizeInBytes(*std::next(DSI)) == 2 && DSI->isCall()) { // If instruction in delay slot is 16b change opcode to // corresponding instruction with short delay slot. + + // 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 + // if it is in range. DSI->setDesc(TII->get(getEquivalentCallShort(DSI->getOpcode()))); } continue; @@ -646,8 +656,6 @@ template<typename IterTy> bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, RegDefsUses &RegDU, InspectMemInstr& IM, Iter Slot, IterTy &Filler) const { - bool IsReverseIter = std::is_convertible<IterTy, ReverseIter>::value; - for (IterTy I = Begin; I != End;) { IterTy CurrI = I; ++I; @@ -664,12 +672,6 @@ bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, 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; } @@ -692,9 +694,14 @@ bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, bool InMicroMipsMode = STI.inMicroMipsMode(); const MipsInstrInfo *TII = STI.getInstrInfo(); unsigned Opcode = (*Slot).getOpcode(); - if (InMicroMipsMode && TII->GetInstSizeInBytes(*CurrI) == 2 && + // This is complicated by the tail call optimization. For non-PIC code + // there is only a 32bit sized unconditional branch which can be assumed + // to be able to reach the target. b16 only has a range of +/- 1 KB. + // It's entirely possible that the target function is reachable with b16 + // but we don't have enough information to make that decision. + if (InMicroMipsMode && TII->getInstSizeInBytes(*CurrI) == 2 && (Opcode == Mips::JR || Opcode == Mips::PseudoIndirectBranch || - Opcode == Mips::PseudoReturn)) + Opcode == Mips::PseudoReturn || Opcode == Mips::TAILCALL)) continue; Filler = CurrI; @@ -704,23 +711,24 @@ bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, return false; } -bool Filler::searchBackward(MachineBasicBlock &MBB, Iter Slot) const { +bool Filler::searchBackward(MachineBasicBlock &MBB, MachineInstr &Slot) const { if (DisableBackwardSearch) return false; auto *Fn = MBB.getParent(); RegDefsUses RegDU(*Fn->getSubtarget().getRegisterInfo()); - MemDefsUses MemDU(Fn->getDataLayout(), Fn->getFrameInfo()); + MemDefsUses MemDU(Fn->getDataLayout(), &Fn->getFrameInfo()); ReverseIter Filler; - RegDU.init(*Slot); + RegDU.init(Slot); - if (!searchRange(MBB, ReverseIter(Slot), MBB.rend(), RegDU, MemDU, Slot, + MachineBasicBlock::iterator SlotI = Slot; + if (!searchRange(MBB, ++SlotI.getReverse(), MBB.rend(), RegDU, MemDU, Slot, Filler)) return false; - MBB.splice(std::next(Slot), &MBB, std::next(Filler).base()); - MIBundleBuilder(MBB, Slot, std::next(Slot, 2)); + MBB.splice(std::next(SlotI), &MBB, Filler.getReverse()); + MIBundleBuilder(MBB, SlotI, std::next(SlotI, 2)); ++UsefulSlots; return true; } @@ -776,8 +784,8 @@ bool Filler::searchSuccBBs(MachineBasicBlock &MBB, Iter Slot) const { if (HasMultipleSuccs) { IM.reset(new LoadFromStackOrConst()); } else { - const MachineFrameInfo *MFI = Fn->getFrameInfo(); - IM.reset(new MemDefsUses(Fn->getDataLayout(), MFI)); + const MachineFrameInfo &MFI = Fn->getFrameInfo(); + IM.reset(new MemDefsUses(Fn->getDataLayout(), &MFI)); } if (!searchRange(MBB, SuccBB->begin(), SuccBB->end(), RegDU, *IM, Slot, |