51#define DEBUG_TYPE "mips-delay-slot-filler"
53STATISTIC(FilledSlots,
"Number of delay slots filled");
54STATISTIC(UsefulSlots,
"Number of delay slots filled with instructions that"
56STATISTIC(R5900ShortLoopNops,
"Number of delay slots left as NOP for R5900 "
60 "disable-mips-delay-filler",
62 cl::desc(
"Fill all delay slots with NOPs."),
66 "disable-mips-df-forward-search",
68 cl::desc(
"Disallow MIPS delay filler to search forward."),
72 "disable-mips-df-succbb-search",
74 cl::desc(
"Disallow MIPS delay filler to search successor basic blocks."),
78 "disable-mips-df-backward-search",
80 cl::desc(
"Disallow MIPS delay filler to search backward."),
94 class BranchInformation {
114 BranchInformation(MachineInstrBundleIterator<MachineInstr> CurrentSlot,
115 MachineInstrBundleIterator<MachineInstr> MBBEnd,
116 const MachineInstr *NextMBBInstr)
119 ? BranchInformation::filterPseudoInstr(&(*CurrentSlot))
122 (++CurrentSlot) == MBBEnd
123 ? BranchInformation::filterPseudoInstr(NextMBBInstr)
124 : BranchInformation::filterPseudoInstr(&(*CurrentSlot))) {}
127 constexpr bool hasBranchInstr()
const {
return this->BranchInstr; }
130 constexpr bool hasBranchElseInstr()
const {
return this->ElseBranchInstr; }
133 constexpr bool isIndirectBranch()
const {
134 if (this->BranchInstr) {
135 return this->BranchInstr->isIndirectBranch();
141 constexpr bool isUnconditionalBranch()
const {
142 if (this->BranchInstr) {
143 return this->BranchInstr->isUnconditionalBranch();
149 const MachineInstr *getBranchInstr()
const {
return this->BranchInstr; }
152 const MachineInstr *getBranchElseInstr()
const {
153 return this->ElseBranchInstr;
157 const MachineBasicBlock *getBranchTarget()
const {
158 if (this->isIndirectBranch() || !this->hasBranchInstr()) {
163 for (
const MachineOperand &MO : this->BranchInstr->operands()) {
174 RegDefsUses(
const TargetRegisterInfo &TRI);
176 void init(
const MachineInstr &
MI);
179 void setCallerSaved(
const MachineInstr &
MI);
182 void setUnallocatableRegs(
const MachineFunction &MF);
186 void addLiveOut(
const MachineBasicBlock &
MBB,
187 const MachineBasicBlock &SuccBB);
189 bool update(
const MachineInstr &
MI,
unsigned Begin,
unsigned End);
192 bool checkRegDefsUses(BitVector &NewDefs, BitVector &NewUses,
unsigned Reg,
196 bool isRegInSet(
const BitVector &RegSet,
unsigned Reg)
const;
198 const TargetRegisterInfo &TRI;
199 BitVector Defs, Uses;
203 class InspectMemInstr {
205 InspectMemInstr(
bool ForbidMemInstr_) : ForbidMemInstr(ForbidMemInstr_) {}
206 virtual ~InspectMemInstr() =
default;
213 bool OrigSeenLoad =
false;
214 bool OrigSeenStore =
false;
215 bool SeenLoad =
false;
216 bool SeenStore =
false;
223 virtual bool hasHazard_(
const MachineInstr &
MI) = 0;
227 class NoMemInstr :
public InspectMemInstr {
229 NoMemInstr() : InspectMemInstr(
true) {}
232 bool hasHazard_(
const MachineInstr &
MI)
override {
return true; }
236 class LoadFromStackOrConst :
public InspectMemInstr {
238 LoadFromStackOrConst() : InspectMemInstr(
false) {}
241 bool hasHazard_(
const MachineInstr &
MI)
override;
246 class MemDefsUses :
public InspectMemInstr {
248 explicit MemDefsUses(
const MachineFrameInfo *MFI);
251 using ValueType = PointerUnion<const Value *, const PseudoSourceValue *>;
253 bool hasHazard_(
const MachineInstr &
MI)
override;
258 bool updateDefsUses(ValueType V,
bool MayStore);
262 SmallVectorImpl<ValueType> &Objects)
const;
264 const MachineFrameInfo *MFI;
265 SmallPtrSet<ValueType, 4> Uses, Defs;
269 bool SeenNoObjLoad =
false;
270 bool SeenNoObjStore =
false;
275 MipsDelaySlotFiller() : MachineFunctionPass(ID) {}
277 StringRef getPassName()
const override {
return "Mips Delay Slot Filler"; }
279 bool runOnMachineFunction(MachineFunction &
F)
override {
286 Changed |= runOnMachineBasicBlock(
287 *curMBB, (
MBB !=
F.
end() && !(*MBB).empty()) ? &(*MBB).instr_front()
295 F.getRegInfo().invalidateLiveness();
300 MachineFunctionProperties getRequiredProperties()
const override {
301 return MachineFunctionProperties().setNoVRegs();
304 void getAnalysisUsage(AnalysisUsage &AU)
const override {
305 AU.
addRequired<MachineBranchProbabilityInfoWrapperPass>();
312 bool runOnMachineBasicBlock(MachineBasicBlock &
MBB,
313 MachineInstr *FirstNextMBBInstr);
315 Iter replaceWithCompactBranch(MachineBasicBlock &
MBB, Iter Branch,
321 bool delayHasHazard(
const MipsSubtarget &STI,
const MachineInstr &Candidate,
322 const BranchInformation &BranchInfo, RegDefsUses &RegDU,
323 InspectMemInstr &IM)
const;
327 template <
typename IterTy>
328 bool searchRange(MachineBasicBlock &
MBB, IterTy Begin, IterTy End,
329 const BranchInformation &BranchInfo, RegDefsUses &RegDU,
330 InspectMemInstr &IM, Iter Slot, IterTy &Filler)
const;
334 bool searchBackward(MachineBasicBlock &
MBB, MachineInstr &Slot,
335 const BranchInformation &BranchInfo)
const;
339 bool searchForward(MachineBasicBlock &
MBB, Iter Slot,
340 const BranchInformation &BranchInfo)
const;
345 bool searchSuccBBs(MachineBasicBlock &
MBB, Iter Slot,
346 const BranchInformation &BranchInfo)
const;
350 MachineBasicBlock *selectSuccBB(MachineBasicBlock &
B)
const;
354 std::pair<MipsInstrInfo::BranchType, MachineInstr *>
355 getBranch(MachineBasicBlock &
MBB,
const MachineBasicBlock &Dst)
const;
359 bool examinePred(MachineBasicBlock &Pred,
const MachineBasicBlock &Succ,
360 RegDefsUses &RegDU,
bool &HasMultipleSuccs,
361 BB2BrMap &
BrMap)
const;
363 bool terminateSearch(
const MachineInstr &Candidate)
const;
365 const TargetMachine *TM =
nullptr;
370char MipsDelaySlotFiller::ID = 0;
373 return MI->hasDelaySlot() && !
MI->isBundledWithSucc();
397 if (!
MI->isBranch() ||
MI->isIndirectBranch())
404 TargetMBB = MO.getMBB();
410 if (!TargetMBB || TargetMBB != &
MBB)
417 bool HasOtherBranch =
false;
424 if (Instr.isDebugInstr() || Instr.isTransient())
430 if (Instr.isBranch() || Instr.isCall()) {
431 HasOtherBranch =
true;
448 "Fill delay slot for MIPS",
false,
false)
451static
void insertDelayFiller(Iter Filler,
const BB2BrMap &
BrMap) {
459 I.first->push_back(MF->CloneMachineInstr(&*Filler));
469 if (!MO.isReg() || !MO.isDef() || !(R = MO.getReg()))
475 "Shouldn't move an instruction with unallocatable registers across "
476 "basic block boundaries.");
479 if (!
MBB.isLiveIn(R))
489 update(
MI, 0,
MI.getDesc().getNumOperands());
499 update(
MI,
MI.getDesc().getNumOperands(),
MI.getNumOperands());
500 Defs.
reset(Mips::AT);
504void RegDefsUses::setCallerSaved(
const MachineInstr &
MI) {
510 if (
MI.definesRegister(Mips::RA,
nullptr) ||
511 MI.definesRegister(Mips::RA_64,
nullptr)) {
513 Defs.
set(Mips::RA_64);
517 BitVector CallerSavedRegs(
TRI.getNumRegs(),
true);
519 CallerSavedRegs.reset(Mips::ZERO);
520 CallerSavedRegs.reset(Mips::ZERO_64);
522 for (
const MCPhysReg *R =
TRI.getCalleeSavedRegs(
MI.getParent()->getParent());
524 for (MCRegAliasIterator AI(*R, &
TRI,
true); AI.isValid(); ++AI)
525 CallerSavedRegs.reset(*AI);
527 Defs |= CallerSavedRegs;
530void RegDefsUses::setUnallocatableRegs(
const MachineFunction &MF) {
531 BitVector AllocSet =
TRI.getAllocatableSet(MF);
533 for (
unsigned R : AllocSet.
set_bits())
534 for (MCRegAliasIterator AI(R, &
TRI,
false); AI.isValid(); ++AI)
537 AllocSet.
set(Mips::ZERO);
538 AllocSet.
set(Mips::ZERO_64);
540 Defs |= AllocSet.
flip();
543void RegDefsUses::addLiveOut(
const MachineBasicBlock &
MBB,
544 const MachineBasicBlock &SuccBB) {
547 for (
const auto &LI : S->liveins())
551bool RegDefsUses::update(
const MachineInstr &
MI,
unsigned Begin,
unsigned End) {
552 BitVector NewDefs(
TRI.getNumRegs()), NewUses(
TRI.getNumRegs());
553 bool HasHazard =
false;
555 for (
unsigned I = Begin;
I != End; ++
I) {
556 const MachineOperand &MO =
MI.getOperand(
I);
559 if (checkRegDefsUses(NewDefs, NewUses, MO.
getReg(), MO.
isDef())) {
574bool RegDefsUses::checkRegDefsUses(BitVector &NewDefs, BitVector &NewUses,
575 unsigned Reg,
bool IsDef)
const {
579 return (isRegInSet(Defs,
Reg) || isRegInSet(
Uses,
Reg));
584 return isRegInSet(Defs,
Reg);
587bool RegDefsUses::isRegInSet(
const BitVector &RegSet,
unsigned Reg)
const {
589 for (MCRegAliasIterator AI(
Reg, &
TRI,
true); AI.isValid(); ++AI)
590 if (RegSet.
test(*AI))
595bool InspectMemInstr::hasHazard(
const MachineInstr &
MI) {
596 if (!
MI.mayStore() && !
MI.mayLoad())
602 OrigSeenLoad = SeenLoad;
603 OrigSeenStore = SeenStore;
604 SeenLoad |=
MI.mayLoad();
605 SeenStore |=
MI.mayStore();
609 if (
MI.hasOrderedMemoryRef() && (OrigSeenLoad || OrigSeenStore)) {
610 ForbidMemInstr =
true;
614 return hasHazard_(
MI);
617bool LoadFromStackOrConst::hasHazard_(
const MachineInstr &
MI) {
621 if (!
MI.hasOneMemOperand() || !(*
MI.memoperands_begin())->getPseudoValue())
624 if (
const PseudoSourceValue *PSV =
625 (*
MI.memoperands_begin())->getPseudoValue()) {
628 return !PSV->isConstant(
nullptr) && !PSV->isStack();
634MemDefsUses::MemDefsUses(
const MachineFrameInfo *MFI_)
635 : InspectMemInstr(
false), MFI(MFI_) {}
638 bool HasHazard =
false;
644 HasHazard |= updateDefsUses(VT,
MI.mayStore());
649 HasHazard =
MI.mayStore() && (OrigSeenLoad || OrigSeenStore);
650 HasHazard |=
MI.mayLoad() || OrigSeenStore;
652 SeenNoObjLoad |=
MI.mayLoad();
653 SeenNoObjStore |=
MI.mayStore();
658bool MemDefsUses::updateDefsUses(
ValueType V,
bool MayStore) {
660 return !Defs.insert(V).second ||
Uses.count(V) || SeenNoObjStore ||
664 return Defs.count(V) || SeenNoObjStore;
668getUnderlyingObjects(
const MachineInstr &
MI,
669 SmallVectorImpl<ValueType> &Objects)
const {
670 if (!
MI.hasOneMemOperand())
673 auto & MMO = **
MI.memoperands_begin();
675 if (
const PseudoSourceValue *PSV = MMO.getPseudoValue()) {
676 if (!PSV->isAliased(MFI))
682 if (
const Value *V = MMO.getValue()) {
686 for (
const Value *UValue : Objs) {
699Iter MipsDelaySlotFiller::replaceWithCompactBranch(MachineBasicBlock &
MBB,
705 unsigned NewOpcode =
TII->getEquivalentCompactForm(Branch);
706 Branch =
TII->genInstrWithNewOpc(NewOpcode, Branch);
710 if (ToErase->shouldUpdateAdditionalCallInfo())
711 ToErase->getMF()->moveAdditionalCallInfo(ToErase,
713 ToErase->eraseFromParent();
725 return Mips::BGEZALS_MM;
727 return Mips::BLTZALS_MM;
730 return Mips::JALS_MM;
732 return Mips::JALRS_MM;
733 case Mips::JALR16_MM:
734 return Mips::JALRS16_MM;
735 case Mips::TAILCALL_MM:
737 case Mips::TAILCALLREG:
738 return Mips::JR16_MM;
746bool MipsDelaySlotFiller::runOnMachineBasicBlock(
747 MachineBasicBlock &
MBB, MachineInstr *FirstNextMBBInstr) {
760 bool SkipForFixR5900 =
false;
763 "short loop branch.\n");
764 ++R5900ShortLoopNops;
765 SkipForFixR5900 =
true;
772 !(InMicroMipsMode && STI.
hasMips32r6()) && !SkipForFixR5900) {
775 const auto BranchInfo =
776 BranchInformation(
I,
MBB.
end(), FirstNextMBBInstr);
779 !
TII->getEquivalentCompactForm(
I)) {
780 if (searchBackward(
MBB, *
I, BranchInfo)) {
782 " in backwards search.\n");
784 }
else if (
I->isTerminator()) {
785 if (searchSuccBBs(
MBB,
I, BranchInfo)) {
788 " in successor BB search.\n");
790 }
else if (searchForward(
MBB,
I, BranchInfo)) {
792 " in forwards search.\n");
801 if (InMicroMipsMode &&
TII->getInstSizeInBytes(*std::next(DSI)) == 2 &&
828 if ((InMicroMipsMode ||
830 TII->getEquivalentCompactForm(
I)) {
831 I = replaceWithCompactBranch(
MBB,
I,
I->getDebugLoc());
839 TII->insertNop(
MBB, std::next(
I),
I->getDebugLoc());
840 MIBundleBuilder(
MBB,
I, std::next(
I, 2));
847template <
typename IterTy>
848bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &
MBB, IterTy Begin,
850 const BranchInformation &BranchInfo,
851 RegDefsUses &RegDU, InspectMemInstr &IM,
852 Iter Slot, IterTy &Filler)
const {
853 for (IterTy
I = Begin;
I != End;) {
860 if (CurrI->isDebugInstr() || CurrI->isJumpTableDebugInfo()) {
866 if (CurrI->isBundle()) {
870 RegDU.update(*CurrI, 0, CurrI->getNumOperands());
874 if (terminateSearch(*CurrI)) {
880 assert((!CurrI->isCall() && !CurrI->isReturn() && !CurrI->isBranch()) &&
881 "Cannot put calls, returns or branches in delay slot.");
883 if (CurrI->isKill()) {
884 CurrI->eraseFromParent();
889 if (delayHasHazard(STI, *CurrI, BranchInfo, RegDU, IM))
894 unsigned Opcode = (*Slot).getOpcode();
906 if (InMicroMipsMode &&
TII->getInstSizeInBytes(*CurrI) == 2 &&
907 (Opcode == Mips::JR || Opcode == Mips::PseudoIndirectBranch ||
908 Opcode == Mips::PseudoIndirectBranch_MM ||
909 Opcode == Mips::PseudoReturn || Opcode == Mips::TAILCALL))
913 if (InMicroMipsMode && (Opcode == Mips::LWP_MM || Opcode == Mips::SWP_MM ||
914 Opcode == Mips::MOVEP_MM))
927bool MipsDelaySlotFiller::searchBackward(
928 MachineBasicBlock &
MBB, MachineInstr &Slot,
929 const BranchInformation &BranchInfo)
const {
934 RegDefsUses RegDU(*Fn->getSubtarget().getRegisterInfo());
935 MemDefsUses MemDU(&Fn->getFrameInfo());
942 MemDU, Slot, Filler)) {
944 "slot using backwards search.\n");
948 MBB.
splice(std::next(SlotI), &
MBB, Filler.getReverse());
949 MIBundleBuilder(
MBB, SlotI, std::next(SlotI, 2));
954bool MipsDelaySlotFiller::searchForward(
955 MachineBasicBlock &
MBB, Iter Slot,
956 const BranchInformation &BranchInfo)
const {
965 RegDU.setCallerSaved(*Slot);
967 if (!searchRange(
MBB, std::next(Slot),
MBB.
end(), BranchInfo, RegDU, NM, Slot,
970 "slot using forwards search.\n");
975 MIBundleBuilder(
MBB, Slot, std::next(Slot, 2));
980bool MipsDelaySlotFiller::searchSuccBBs(
981 MachineBasicBlock &
MBB, Iter Slot,
982 const BranchInformation &BranchInfo)
const {
986 MachineBasicBlock *SuccBB = selectSuccBB(
MBB);
992 bool HasMultipleSuccs =
false;
994 std::unique_ptr<InspectMemInstr> IM;
1000 if (!examinePred(*Pred, *SuccBB, RegDU, HasMultipleSuccs,
BrMap))
1005 RegDU.setUnallocatableRegs(*Fn);
1009 if (HasMultipleSuccs) {
1010 IM.reset(
new LoadFromStackOrConst());
1012 const MachineFrameInfo &MFI = Fn->getFrameInfo();
1013 IM.reset(
new MemDefsUses(&MFI));
1016 if (!searchRange(
MBB, SuccBB->
begin(), SuccBB->
end(), BranchInfo, RegDU, *IM,
1020 insertDelayFiller(Filler,
BrMap);
1022 Filler->eraseFromParent();
1028MipsDelaySlotFiller::selectSuccBB(MachineBasicBlock &
B)
const {
1033 auto &Prob = getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
1034 MachineBasicBlock *S =
1036 const MachineBasicBlock *Dst1) {
1037 return Prob.getEdgeProbability(&B, Dst0) <
1038 Prob.getEdgeProbability(&B, Dst1);
1040 return S->
isEHPad() ? nullptr : S;
1043std::pair<MipsInstrInfo::BranchType, MachineInstr *>
1044MipsDelaySlotFiller::getBranch(MachineBasicBlock &
MBB,
1045 const MachineBasicBlock &Dst)
const {
1046 const MipsInstrInfo *
TII =
1048 MachineBasicBlock *TrueBB =
nullptr, *FalseBB =
nullptr;
1049 SmallVector<MachineInstr*, 2> BranchInstrs;
1056 return std::make_pair(R,
nullptr);
1064 return std::make_pair(R, BranchInstrs[0]);
1067 assert((TrueBB == &Dst) || (FalseBB == &Dst));
1080bool MipsDelaySlotFiller::examinePred(MachineBasicBlock &Pred,
1081 const MachineBasicBlock &Succ,
1083 bool &HasMultipleSuccs,
1084 BB2BrMap &
BrMap)
const {
1085 std::pair<MipsInstrInfo::BranchType, MachineInstr *>
P =
1086 getBranch(Pred, Succ);
1095 HasMultipleSuccs =
true;
1096 RegDU.addLiveOut(Pred, Succ);
1103bool MipsDelaySlotFiller::delayHasHazard(
const MipsSubtarget &STI,
1104 const MachineInstr &Candidate,
1105 const BranchInformation &BranchInfo,
1107 InspectMemInstr &IM)
const {
1109 "KILL instructions should have been eliminated at this point.");
1113 HasHazard |= IM.hasHazard(Candidate);
1114 HasHazard |= RegDU.update(Candidate, 0, Candidate.
getNumOperands());
1119 const bool HasLoadDelaySlot =
TII->HasLoadDelaySlot(Candidate);
1122 if (HasLoadDelaySlot) {
1125 if (!BranchInfo.hasBranchInstr()) {
1131 if (BranchInfo.isIndirectBranch()) {
1137 const MachineBasicBlock *TargetMBB = BranchInfo.getBranchTarget();
1138 if (!TargetMBB || TargetMBB->
empty()) {
1142 const auto &BranchTargetInstr = TargetMBB->
instr_front();
1144 !
TII->SafeInLoadDelaySlot(BranchTargetInstr, Candidate);
1147 if (!BranchInfo.isUnconditionalBranch()) {
1149 if (BranchInfo.hasBranchElseInstr()) {
1150 HasNewHazard |= !
TII->SafeInLoadDelaySlot(
1151 *BranchInfo.getBranchElseInstr(), Candidate);
1154 HasNewHazard =
true;
1157 return HasNewHazard;
1164bool MipsDelaySlotFiller::terminateSearch(
const MachineInstr &Candidate)
const {
1173 return new MipsDelaySlotFiller();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
static const Function * getParent(const Value *V)
This file implements the BitVector class.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static unsigned InstrCount
This file defines the DenseMap class.
static bool hasHazard(StateT InitialState, function_ref< HazardFnResult(StateT &, const MachineInstr &)> IsHazard, function_ref< void(StateT &, const MachineInstr &)> UpdateState, const MachineBasicBlock *InitialMBB, MachineBasicBlock::const_reverse_instr_iterator InitialI)
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
static bool hasUnoccupiedSlot(const MachineInstr *MI)
static cl::opt< bool > DisableDelaySlotFiller("disable-mips-delay-filler", cl::init(false), cl::desc("Fill all delay slots with NOPs."), cl::Hidden)
static cl::opt< bool > DisableBackwardSearch("disable-mips-df-backward-search", cl::init(false), cl::desc("Disallow MIPS delay filler to search backward."), cl::Hidden)
static void addLiveInRegs(Iter Filler, MachineBasicBlock &MBB)
This function adds registers Filler defines to MBB's live-in register list.
static bool isR5900ShortLoopBranch(const MachineInstr *MI, const MachineBasicBlock &MBB)
Check if a branch is a short backward loop that triggers the R5900 erratum.
static cl::opt< bool > DisableSuccBBSearch("disable-mips-df-succbb-search", cl::init(true), cl::desc("Disallow MIPS delay filler to search successor basic blocks."), cl::Hidden)
static cl::opt< bool > DisableForwardSearch("disable-mips-df-forward-search", cl::init(true), cl::desc("Disallow MIPS delay filler to search forward."), cl::Hidden)
cl::opt< CompactBranchPolicy > MipsCompactBranchPolicy
static int getEquivalentCallShort(int Opcode)
#define IsMFLOMFHI(instr)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file defines the PointerUnion class, which is a discriminated union of pointer types.
static bool isBranch(unsigned Opcode)
const SmallVectorImpl< MachineOperand > & Cond
Remove Loads Into Fake Uses
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
AnalysisUsage & addRequired()
bool test(unsigned Idx) const
iterator_range< const_set_bits_iterator > set_bits() const
FunctionPass class - This class is used to implement most global optimizations.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
Helper class for constructing bundles of MachineInstrs.
MIBundleBuilder & append(MachineInstr *MI)
Insert MI into MBB by appending it to the instructions in the bundle.
bool isEHPad() const
Returns true if the block is a landing pad.
Instructions::iterator instr_iterator
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< succ_iterator > successors()
iterator_range< pred_iterator > predecessors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
MachineInstr & instr_front()
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
Representation of each machine instruction.
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
bool isImplicitDef() const
bool isCall(QueryType Type=AnyInBundle) const
unsigned getNumOperands() const
Retuns the total number of operands.
LLVM_ABI bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
bool isPseudo(QueryType Type=IgnoreBundle) const
Return true if this is a pseudo instruction that doesn't correspond to a real machine instruction.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void dump() const
Register getReg() const
getReg - Returns the register number.
bool inMicroMipsMode() const
const MipsInstrInfo * getInstrInfo() const override
void push_back(const T &Elt)
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
BitVector getAllocatableSet(const MachineFunction &MF, const TargetRegisterClass *RC=nullptr) const
Returns a bitset indexed by register number indicating if a register is allocatable or not.
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ CB_Never
The policy 'never' may in some circumstances or for some ISAs not be absolutely adhered to.
@ CB_Always
'always' may in some circumstances may not be absolutely adhered to, there may not be a corresponding...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
auto max_element(R &&Range)
Provide wrappers to std::max_element which take ranges instead of having to pass begin/end explicitly...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
PointerUnion< const Value *, const PseudoSourceValue * > ValueType
FunctionPass * createMipsDelaySlotFillerPass()
createMipsDelaySlotFillerPass - Returns a pass that fills in delay slots in Mips MachineFunctions
LLVM_ABI void getUnderlyingObjects(const Value *V, SmallVectorImpl< const Value * > &Objects, const LoopInfo *LI=nullptr, unsigned MaxLookup=MaxLookupSearchDepth)
This method is similar to getUnderlyingObject except that it can look through phi and select instruct...
LLVM_ABI bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.