52#define DEBUG_TYPE "mips-delay-slot-filler"
54STATISTIC(FilledSlots,
"Number of delay slots filled");
55STATISTIC(UsefulSlots,
"Number of delay slots filled with instructions that"
57STATISTIC(R5900ShortLoopNops,
"Number of delay slots left as NOP for R5900 "
61 "disable-mips-delay-filler",
63 cl::desc(
"Fill all delay slots with NOPs."),
67 "disable-mips-df-forward-search",
69 cl::desc(
"Disallow MIPS delay filler to search forward."),
73 "disable-mips-df-succbb-search",
75 cl::desc(
"Disallow MIPS delay filler to search successor basic blocks."),
79 "disable-mips-df-backward-search",
81 cl::desc(
"Disallow MIPS delay filler to search backward."),
95 class BranchInformation {
115 BranchInformation(MachineInstrBundleIterator<MachineInstr> CurrentSlot,
116 MachineInstrBundleIterator<MachineInstr> MBBEnd,
117 const MachineInstr *NextMBBInstr)
120 ? BranchInformation::filterPseudoInstr(&(*CurrentSlot))
123 (++CurrentSlot) == MBBEnd
124 ? BranchInformation::filterPseudoInstr(NextMBBInstr)
125 : BranchInformation::filterPseudoInstr(&(*CurrentSlot))) {}
128 constexpr bool hasBranchInstr()
const {
return this->BranchInstr; }
131 constexpr bool hasBranchElseInstr()
const {
return this->ElseBranchInstr; }
134 constexpr bool isIndirectBranch()
const {
135 if (this->BranchInstr) {
136 return this->BranchInstr->isIndirectBranch();
142 constexpr bool isUnconditionalBranch()
const {
143 if (this->BranchInstr) {
144 return this->BranchInstr->isUnconditionalBranch();
150 const MachineInstr *getBranchInstr()
const {
return this->BranchInstr; }
153 const MachineInstr *getBranchElseInstr()
const {
154 return this->ElseBranchInstr;
158 const MachineBasicBlock *getBranchTarget()
const {
159 if (this->isIndirectBranch() || !this->hasBranchInstr()) {
164 for (
const MachineOperand &MO : this->BranchInstr->operands()) {
175 RegDefsUses(
const TargetRegisterInfo &TRI);
177 void init(
const MachineInstr &
MI);
180 void setCallerSaved(
const MachineInstr &
MI);
187 void addLiveOut(
const MachineBasicBlock &
MBB,
188 const MachineBasicBlock &SuccBB);
190 bool update(
const MachineInstr &
MI,
unsigned Begin,
unsigned End);
193 bool checkRegDefsUses(BitVector &NewDefs, BitVector &NewUses,
unsigned Reg,
197 bool isRegInSet(
const BitVector &RegSet,
unsigned Reg)
const;
199 const TargetRegisterInfo &TRI;
200 BitVector Defs, Uses;
204 class InspectMemInstr {
206 InspectMemInstr(
bool ForbidMemInstr_) : ForbidMemInstr(ForbidMemInstr_) {}
207 virtual ~InspectMemInstr() =
default;
214 bool OrigSeenLoad =
false;
215 bool OrigSeenStore =
false;
216 bool SeenLoad =
false;
217 bool SeenStore =
false;
224 virtual bool hasHazard_(
const MachineInstr &
MI) = 0;
228 class NoMemInstr :
public InspectMemInstr {
230 NoMemInstr() : InspectMemInstr(
true) {}
233 bool hasHazard_(
const MachineInstr &
MI)
override {
return true; }
237 class LoadFromStackOrConst :
public InspectMemInstr {
239 LoadFromStackOrConst() : InspectMemInstr(
false) {}
242 bool hasHazard_(
const MachineInstr &
MI)
override;
247 class MemDefsUses :
public InspectMemInstr {
249 explicit MemDefsUses(
const MachineFrameInfo *MFI);
252 using ValueType = PointerUnion<const Value *, const PseudoSourceValue *>;
254 bool hasHazard_(
const MachineInstr &
MI)
override;
259 bool updateDefsUses(ValueType V,
bool MayStore);
263 SmallVectorImpl<ValueType> &Objects)
const;
265 const MachineFrameInfo *MFI;
266 SmallPtrSet<ValueType, 4> Uses, Defs;
270 bool SeenNoObjLoad =
false;
271 bool SeenNoObjStore =
false;
276 MipsDelaySlotFiller() : MachineFunctionPass(ID) {}
278 StringRef getPassName()
const override {
return "Mips Delay Slot Filler"; }
287 Changed |= runOnMachineBasicBlock(
288 *curMBB, (
MBB !=
F.
end() && !(*MBB).empty()) ? &(*MBB).instr_front()
296 F.getRegInfo().invalidateLiveness();
301 MachineFunctionProperties getRequiredProperties()
const override {
302 return MachineFunctionProperties().setNoVRegs();
305 void getAnalysisUsage(AnalysisUsage &AU)
const override {
306 AU.
addRequired<MachineBranchProbabilityInfoWrapperPass>();
313 bool runOnMachineBasicBlock(MachineBasicBlock &
MBB,
314 MachineInstr *FirstNextMBBInstr);
316 Iter replaceWithCompactBranch(MachineBasicBlock &
MBB, Iter Branch,
322 bool delayHasHazard(
const MipsSubtarget &STI,
const MachineInstr &Candidate,
323 const BranchInformation &BranchInfo, RegDefsUses &RegDU,
324 InspectMemInstr &IM)
const;
328 template <
typename IterTy>
329 bool searchRange(MachineBasicBlock &
MBB, IterTy Begin, IterTy End,
330 const BranchInformation &BranchInfo, RegDefsUses &RegDU,
331 InspectMemInstr &IM, Iter Slot, IterTy &Filler)
const;
335 bool searchBackward(MachineBasicBlock &
MBB, MachineInstr &Slot,
336 const BranchInformation &BranchInfo)
const;
340 bool searchForward(MachineBasicBlock &
MBB, Iter Slot,
341 const BranchInformation &BranchInfo)
const;
346 bool searchSuccBBs(MachineBasicBlock &
MBB, Iter Slot,
347 const BranchInformation &BranchInfo)
const;
351 MachineBasicBlock *selectSuccBB(MachineBasicBlock &
B)
const;
355 std::pair<MipsInstrInfo::BranchType, MachineInstr *>
356 getBranch(MachineBasicBlock &
MBB,
const MachineBasicBlock &Dst)
const;
360 bool examinePred(MachineBasicBlock &Pred,
const MachineBasicBlock &Succ,
361 RegDefsUses &RegDU,
bool &HasMultipleSuccs,
362 BB2BrMap &
BrMap)
const;
364 bool terminateSearch(
const MachineInstr &Candidate)
const;
366 const TargetMachine *TM =
nullptr;
371char MipsDelaySlotFiller::ID = 0;
374 return MI->hasDelaySlot() && !
MI->isBundledWithSucc();
398 if (!
MI->isBranch() ||
MI->isIndirectBranch())
405 TargetMBB = MO.getMBB();
411 if (!TargetMBB || TargetMBB != &
MBB)
418 bool HasOtherBranch =
false;
425 if (Instr.isDebugInstr() || Instr.isTransient())
431 if (Instr.isBranch() || Instr.isCall()) {
432 HasOtherBranch =
true;
449 "Fill delay slot for MIPS",
false,
false)
452static
void insertDelayFiller(Iter Filler,
const BB2BrMap &
BrMap) {
460 I.first->push_back(MF->CloneMachineInstr(&*Filler));
470 if (!MO.isReg() || !MO.isDef() || !(R = MO.getReg()))
476 "Shouldn't move an instruction with unallocatable registers across "
477 "basic block boundaries.");
480 if (!
MBB.isLiveIn(R))
490 update(
MI, 0,
MI.getDesc().getNumOperands());
500 update(
MI,
MI.getDesc().getNumOperands(),
MI.getNumOperands());
501 Defs.
reset(Mips::AT);
505void RegDefsUses::setCallerSaved(
const MachineInstr &
MI) {
511 if (
MI.definesRegister(Mips::RA,
nullptr) ||
512 MI.definesRegister(Mips::RA_64,
nullptr)) {
514 Defs.
set(Mips::RA_64);
518 BitVector CallerSavedRegs(
TRI.getNumRegs(),
true);
520 CallerSavedRegs.reset(Mips::ZERO);
521 CallerSavedRegs.reset(Mips::ZERO_64);
523 for (
const MCPhysReg *R =
TRI.getCalleeSavedRegs(
MI.getParent()->getParent());
525 for (MCRegAliasIterator AI(*R, &
TRI,
true); AI.isValid(); ++AI)
526 CallerSavedRegs.reset(*AI);
528 Defs |= CallerSavedRegs;
532 BitVector AllocSet =
TRI.getAllocatableSet(MF);
534 for (
unsigned R : AllocSet.
set_bits())
535 for (MCRegAliasIterator AI(R, &
TRI,
false); AI.isValid(); ++AI)
538 AllocSet.
set(Mips::ZERO);
539 AllocSet.
set(Mips::ZERO_64);
541 Defs |= AllocSet.
flip();
544void RegDefsUses::addLiveOut(
const MachineBasicBlock &
MBB,
545 const MachineBasicBlock &SuccBB) {
548 for (
const auto &LI : S->liveins())
552bool RegDefsUses::update(
const MachineInstr &
MI,
unsigned Begin,
unsigned End) {
553 BitVector NewDefs(
TRI.getNumRegs()), NewUses(
TRI.getNumRegs());
554 bool HasHazard =
false;
556 for (
unsigned I = Begin;
I != End; ++
I) {
557 const MachineOperand &MO =
MI.getOperand(
I);
560 if (checkRegDefsUses(NewDefs, NewUses, MO.
getReg(), MO.
isDef())) {
575bool RegDefsUses::checkRegDefsUses(BitVector &NewDefs, BitVector &NewUses,
576 unsigned Reg,
bool IsDef)
const {
580 return (isRegInSet(Defs,
Reg) || isRegInSet(
Uses,
Reg));
585 return isRegInSet(Defs,
Reg);
588bool RegDefsUses::isRegInSet(
const BitVector &RegSet,
unsigned Reg)
const {
590 for (MCRegAliasIterator AI(
Reg, &
TRI,
true); AI.isValid(); ++AI)
591 if (RegSet.
test(*AI))
596bool InspectMemInstr::hasHazard(
const MachineInstr &
MI) {
597 if (!
MI.mayStore() && !
MI.mayLoad())
603 OrigSeenLoad = SeenLoad;
604 OrigSeenStore = SeenStore;
605 SeenLoad |=
MI.mayLoad();
606 SeenStore |=
MI.mayStore();
610 if (
MI.hasOrderedMemoryRef() && (OrigSeenLoad || OrigSeenStore)) {
611 ForbidMemInstr =
true;
615 return hasHazard_(
MI);
618bool LoadFromStackOrConst::hasHazard_(
const MachineInstr &
MI) {
622 if (!
MI.hasOneMemOperand() || !(*
MI.memoperands_begin())->getPseudoValue())
625 if (
const PseudoSourceValue *PSV =
626 (*
MI.memoperands_begin())->getPseudoValue()) {
629 return !PSV->isConstant(
nullptr) && !PSV->isStack();
635MemDefsUses::MemDefsUses(
const MachineFrameInfo *MFI_)
636 : InspectMemInstr(
false), MFI(MFI_) {}
639 bool HasHazard =
false;
642 SmallVector<ValueType, 4> Objs;
645 HasHazard |= updateDefsUses(VT,
MI.mayStore());
650 HasHazard =
MI.mayStore() && (OrigSeenLoad || OrigSeenStore);
651 HasHazard |=
MI.mayLoad() || OrigSeenStore;
653 SeenNoObjLoad |=
MI.mayLoad();
654 SeenNoObjStore |=
MI.mayStore();
659bool MemDefsUses::updateDefsUses(
ValueType V,
bool MayStore) {
661 return !Defs.insert(V).second ||
Uses.count(V) || SeenNoObjStore ||
665 return Defs.count(V) || SeenNoObjStore;
669getUnderlyingObjects(
const MachineInstr &
MI,
670 SmallVectorImpl<ValueType> &Objects)
const {
671 if (!
MI.hasOneMemOperand())
674 auto & MMO = **
MI.memoperands_begin();
676 if (
const PseudoSourceValue *PSV = MMO.getPseudoValue()) {
677 if (!PSV->isAliased(MFI))
683 if (
const Value *V = MMO.getValue()) {
687 for (
const Value *UValue : Objs) {
700Iter MipsDelaySlotFiller::replaceWithCompactBranch(MachineBasicBlock &
MBB,
706 unsigned NewOpcode =
TII->getEquivalentCompactForm(Branch);
707 Branch =
TII->genInstrWithNewOpc(NewOpcode, Branch);
711 if (ToErase->shouldUpdateAdditionalCallInfo())
712 ToErase->getMF()->moveAdditionalCallInfo(ToErase,
714 ToErase->eraseFromParent();
726 return Mips::BGEZALS_MM;
728 return Mips::BLTZALS_MM;
731 return Mips::JALS_MM;
733 return Mips::JALRS_MM;
734 case Mips::JALR16_MM:
735 return Mips::JALRS16_MM;
736 case Mips::TAILCALL_MM:
738 case Mips::TAILCALLREG:
739 return Mips::JR16_MM;
747bool MipsDelaySlotFiller::runOnMachineBasicBlock(
748 MachineBasicBlock &
MBB, MachineInstr *FirstNextMBBInstr) {
761 bool SkipForFixR5900 =
false;
764 "short loop branch.\n");
765 ++R5900ShortLoopNops;
766 SkipForFixR5900 =
true;
773 !(InMicroMipsMode && STI.
hasMips32r6()) && !SkipForFixR5900) {
776 const auto BranchInfo =
777 BranchInformation(
I,
MBB.
end(), FirstNextMBBInstr);
780 !
TII->getEquivalentCompactForm(
I)) {
781 if (searchBackward(
MBB, *
I, BranchInfo)) {
783 " in backwards search.\n");
785 }
else if (
I->isTerminator()) {
786 if (searchSuccBBs(
MBB,
I, BranchInfo)) {
789 " in successor BB search.\n");
791 }
else if (searchForward(
MBB,
I, BranchInfo)) {
793 " in forwards search.\n");
802 if (InMicroMipsMode &&
TII->getInstSizeInBytes(*std::next(DSI)) == 2 &&
829 if ((InMicroMipsMode ||
831 TII->getEquivalentCompactForm(
I)) {
832 I = replaceWithCompactBranch(
MBB,
I,
I->getDebugLoc());
840 TII->insertNop(
MBB, std::next(
I),
I->getDebugLoc());
841 MIBundleBuilder(
MBB,
I, std::next(
I, 2));
848template <
typename IterTy>
849bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &
MBB, IterTy Begin,
851 const BranchInformation &BranchInfo,
852 RegDefsUses &RegDU, InspectMemInstr &IM,
853 Iter Slot, IterTy &Filler)
const {
854 for (IterTy
I = Begin;
I != End;) {
859 if (terminateSearch(*CurrI)) {
867 if (CurrI->isDebugInstr() || CurrI->isJumpTableDebugInfo() ||
868 CurrI->isMetaInstruction()) {
874 if (CurrI->isBundle()) {
878 RegDU.update(*CurrI, 0, CurrI->getNumOperands());
882 assert((!CurrI->isCall() && !CurrI->isReturn() && !CurrI->isBranch()) &&
883 "Cannot put calls, returns or branches in delay slot.");
885 if (CurrI->isKill()) {
886 CurrI->eraseFromParent();
891 if (delayHasHazard(STI, *CurrI, BranchInfo, RegDU, IM))
896 unsigned Opcode = (*Slot).getOpcode();
908 if (InMicroMipsMode &&
TII->getInstSizeInBytes(*CurrI) == 2 &&
909 (Opcode == Mips::JR || Opcode == Mips::PseudoIndirectBranch ||
910 Opcode == Mips::PseudoIndirectBranch_MM ||
911 Opcode == Mips::PseudoReturn || Opcode == Mips::TAILCALL))
915 if (InMicroMipsMode && (Opcode == Mips::LWP_MM || Opcode == Mips::SWP_MM ||
916 Opcode == Mips::MOVEP_MM))
929bool MipsDelaySlotFiller::searchBackward(
930 MachineBasicBlock &
MBB, MachineInstr &Slot,
931 const BranchInformation &BranchInfo)
const {
936 RegDefsUses RegDU(*Fn->getSubtarget().getRegisterInfo());
937 MemDefsUses MemDU(&Fn->getFrameInfo());
944 MemDU, Slot, Filler)) {
946 "slot using backwards search.\n");
950 MBB.
splice(std::next(SlotI), &
MBB, Filler.getReverse());
951 MIBundleBuilder(
MBB, SlotI, std::next(SlotI, 2));
956bool MipsDelaySlotFiller::searchForward(
957 MachineBasicBlock &
MBB, Iter Slot,
958 const BranchInformation &BranchInfo)
const {
967 RegDU.setCallerSaved(*Slot);
969 if (!searchRange(
MBB, std::next(Slot),
MBB.
end(), BranchInfo, RegDU, NM, Slot,
972 "slot using forwards search.\n");
977 MIBundleBuilder(
MBB, Slot, std::next(Slot, 2));
982bool MipsDelaySlotFiller::searchSuccBBs(
983 MachineBasicBlock &
MBB, Iter Slot,
984 const BranchInformation &BranchInfo)
const {
988 MachineBasicBlock *SuccBB = selectSuccBB(
MBB);
994 bool HasMultipleSuccs =
false;
996 std::unique_ptr<InspectMemInstr> IM;
1002 if (!examinePred(*Pred, *SuccBB, RegDU, HasMultipleSuccs,
BrMap))
1007 RegDU.setUnallocatableRegs(*Fn);
1011 if (HasMultipleSuccs) {
1012 IM.reset(
new LoadFromStackOrConst());
1014 const MachineFrameInfo &MFI = Fn->getFrameInfo();
1015 IM.reset(
new MemDefsUses(&MFI));
1018 if (!searchRange(
MBB, SuccBB->
begin(), SuccBB->
end(), BranchInfo, RegDU, *IM,
1022 insertDelayFiller(Filler,
BrMap);
1024 Filler->eraseFromParent();
1030MipsDelaySlotFiller::selectSuccBB(MachineBasicBlock &
B)
const {
1035 auto &Prob = getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
1036 MachineBasicBlock *S =
1038 const MachineBasicBlock *Dst1) {
1039 return Prob.getEdgeProbability(&B, Dst0) <
1040 Prob.getEdgeProbability(&B, Dst1);
1042 return S->
isEHPad() ? nullptr : S;
1045std::pair<MipsInstrInfo::BranchType, MachineInstr *>
1046MipsDelaySlotFiller::getBranch(MachineBasicBlock &
MBB,
1047 const MachineBasicBlock &Dst)
const {
1048 const MipsInstrInfo *
TII =
1050 MachineBasicBlock *TrueBB =
nullptr, *FalseBB =
nullptr;
1051 SmallVector<MachineInstr*, 2> BranchInstrs;
1058 return std::make_pair(R,
nullptr);
1066 return std::make_pair(R, BranchInstrs[0]);
1069 assert((TrueBB == &Dst) || (FalseBB == &Dst));
1082bool MipsDelaySlotFiller::examinePred(MachineBasicBlock &Pred,
1083 const MachineBasicBlock &Succ,
1085 bool &HasMultipleSuccs,
1086 BB2BrMap &
BrMap)
const {
1087 std::pair<MipsInstrInfo::BranchType, MachineInstr *>
P =
1088 getBranch(Pred, Succ);
1097 HasMultipleSuccs =
true;
1098 RegDU.addLiveOut(Pred, Succ);
1109 const BranchInformation &BranchInfo,
const MachineInstr &Candidate,
1113 if (!BranchInfo.hasBranchInstr() || BranchInfo.isIndirectBranch())
1117 if (!TargetMBB || TargetMBB->
empty())
1120 bool Exposed = !IsSafe(TargetMBB->
instr_front(), Candidate);
1124 if (!BranchInfo.isUnconditionalBranch()) {
1125 if (!BranchInfo.hasBranchElseInstr())
1127 Exposed |= !IsSafe(*BranchInfo.getBranchElseInstr(), Candidate);
1133bool MipsDelaySlotFiller::delayHasHazard(
const MipsSubtarget &STI,
1134 const MachineInstr &Candidate,
1135 const BranchInformation &BranchInfo,
1137 InspectMemInstr &IM)
const {
1139 "KILL instructions should have been eliminated at this point.");
1143 HasHazard |= IM.hasHazard(Candidate);
1144 HasHazard |= RegDU.update(Candidate, 0, Candidate.
getNumOperands());
1153 BranchInfo, Candidate,
1154 [
TII](
const MachineInstr &InShadow,
const MachineInstr &Cand) {
1155 return TII->SafeInLoadDelaySlot(InShadow, Cand);
1162 BranchInfo, Candidate,
1163 [
TII](
const MachineInstr &InShadow,
const MachineInstr &Cand) {
1164 return TII->SafeInFPUDelaySlot(InShadow, Cand);
1171bool MipsDelaySlotFiller::terminateSearch(
const MachineInstr &Candidate)
const {
1180 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)
static bool delayExposesHazard(const BranchInformation &BranchInfo, const MachineInstr &Candidate, function_ref< bool(const MachineInstr &, const MachineInstr &)> IsSafe)
Returns true if putting the candidate in the delay slot could let the branch target,...
#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
Returns true if bit Idx is set.
BitVector & reset()
Reset all bits in the bitvector.
BitVector & set()
Set all bits in the bitvector.
BitVector & flip()
Flip all bits in the bitvector.
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.
An efficient, type-erasing, non-owning reference to a callable.
#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.
RelativeUniformCounterPtr ValuesPtrExpr 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.