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; // skip debug value if (CurrI->isDebugValue()) continue; if (terminateSearch(*CurrI)) break; assert((!CurrI->isCall() && !CurrI->isReturn() && !CurrI->isBranch()) && "Cannot put calls, returns or branches in delay slot."); 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<MipsSubtarget>(); if (STI.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(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(&(*CurrI)) == 2 && (Opcode == Mips::JR || Opcode == Mips::PseudoIndirectBranch || Opcode == Mips::PseudoReturn)) continue; Filler = CurrI; return true; } return false; }
bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, RegDefsUses &RegDU, InspectMemInstr& IM, IterTy &Filler) const { for (IterTy I = Begin; I != End; ++I) { // skip debug value if (I->isDebugValue()) continue; if (terminateSearch(*I)) break; assert((!I->isCall() && !I->isReturn() && !I->isBranch()) && "Cannot put calls, returns or branches in delay slot."); 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; } return false; }
bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, RegDefsUses &RegDU, InspectMemInstr& IM, Iter Slot, IterTy &Filler) const { for (IterTy I = Begin; I != End; ++I) { // skip debug value if (I->isDebugValue()) continue; if (terminateSearch(*I)) break; assert((!I->isCall() && !I->isReturn() && !I->isBranch()) && "Cannot put calls, returns or branches in delay slot."); if (delayHasHazard(*I, RegDU, IM)) continue; const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>(); if (STI.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, STI.getRegisterInfo())) continue; } bool InMicroMipsMode = STI.inMicroMipsMode(); const MipsInstrInfo *TII = STI.getInstrInfo(); unsigned Opcode = (*Slot).getOpcode(); if (InMicroMipsMode && TII->GetInstSizeInBytes(&(*I)) == 2 && (Opcode == Mips::JR || Opcode == Mips::PseudoIndirectBranch || Opcode == Mips::PseudoReturn)) continue; Filler = I; return true; } return false; }
bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, RegDefsUses &RegDU, InspectMemInstr& IM, IterTy &Filler) const { for (IterTy I = Begin; I != End; ++I) { // skip debug value if (I->isDebugValue()) continue; // @LOCALMOD-START // Don't put in delay slot instructions that could be masked. // Should not allow: // ERET, DERET or WAIT, PAUSE. Need to add these to instruction // list. TBD. if (Triple(TM.getTargetTriple()).isOSNaCl()) { int Dummy; if (terminateSearch(*I) || (IsDangerousLoad(*I, &Dummy) || IsDangerousStore(*I, &Dummy) || I->modifiesRegister(Mips::SP, TM.getRegisterInfo()))) break; } else { if (terminateSearch(*I)) break; } // @LOCALMOD-END assert((!I->isCall() && !I->isReturn() && !I->isBranch()) && "Cannot put calls, returns or branches in delay slot."); if (delayHasHazard(*I, RegDU, IM)) continue; Filler = I; return true; } return false; }