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 "
68 class BranchInformation {
88 BranchInformation(MachineInstrBundleIterator<MachineInstr> CurrentSlot,
89 MachineInstrBundleIterator<MachineInstr> MBBEnd,
90 const MachineInstr *NextMBBInstr)
93 ? BranchInformation::filterPseudoInstr(&(*CurrentSlot))
96 (++CurrentSlot) == MBBEnd
97 ? BranchInformation::filterPseudoInstr(NextMBBInstr)
98 : BranchInformation::filterPseudoInstr(&(*CurrentSlot))) {}
101 constexpr bool hasBranchInstr()
const {
return this->BranchInstr; }
104 constexpr bool hasBranchElseInstr()
const {
return this->ElseBranchInstr; }
107 constexpr bool isIndirectBranch()
const {
108 if (this->BranchInstr) {
109 return this->BranchInstr->isIndirectBranch();
115 constexpr bool isUnconditionalBranch()
const {
116 if (this->BranchInstr) {
117 return this->BranchInstr->isUnconditionalBranch();
123 const MachineInstr *getBranchInstr()
const {
return this->BranchInstr; }
126 const MachineInstr *getBranchElseInstr()
const {
127 return this->ElseBranchInstr;
131 const MachineBasicBlock *getBranchTarget()
const {
132 if (this->isIndirectBranch() || !this->hasBranchInstr()) {
137 for (
const MachineOperand &MO : this->BranchInstr->operands()) {
148 RegDefsUses(
const TargetRegisterInfo &TRI);
150 void init(
const MachineInstr &
MI);
153 void setCallerSaved(
const MachineInstr &
MI);
160 void addLiveOut(
const MachineBasicBlock &
MBB,
161 const MachineBasicBlock &SuccBB);
163 bool update(
const MachineInstr &
MI,
unsigned Begin,
unsigned End);
166 bool checkRegDefsUses(BitVector &NewDefs, BitVector &NewUses,
unsigned Reg,
170 bool isRegInSet(
const BitVector &RegSet,
unsigned Reg)
const;
172 const TargetRegisterInfo &TRI;
173 BitVector Defs, Uses;
177 class InspectMemInstr {
179 InspectMemInstr(
bool ForbidMemInstr_) : ForbidMemInstr(ForbidMemInstr_) {}
180 virtual ~InspectMemInstr() =
default;
187 bool OrigSeenLoad =
false;
188 bool OrigSeenStore =
false;
189 bool SeenLoad =
false;
190 bool SeenStore =
false;
197 virtual bool hasHazard_(
const MachineInstr &
MI) = 0;
201 class NoMemInstr :
public InspectMemInstr {
203 NoMemInstr() : InspectMemInstr(
true) {}
206 bool hasHazard_(
const MachineInstr &
MI)
override {
return true; }
210 class LoadFromStackOrConst :
public InspectMemInstr {
212 LoadFromStackOrConst() : InspectMemInstr(
false) {}
215 bool hasHazard_(
const MachineInstr &
MI)
override;
220 class MemDefsUses :
public InspectMemInstr {
222 explicit MemDefsUses(
const MachineFrameInfo *MFI);
225 using ValueType = PointerUnion<const Value *, const PseudoSourceValue *>;
227 bool hasHazard_(
const MachineInstr &
MI)
override;
232 bool updateDefsUses(ValueType V,
bool MayStore);
236 SmallVectorImpl<ValueType> &Objects)
const;
238 const MachineFrameInfo *MFI;
239 SmallPtrSet<ValueType, 4> Uses, Defs;
243 bool SeenNoObjLoad =
false;
244 bool SeenNoObjStore =
false;
249 MipsDelaySlotFiller() : MachineFunctionPass(ID) {}
251 StringRef getPassName()
const override {
return "Mips Delay Slot Filler"; }
255 CLOpts = &
F.getSubtarget<MipsSubtarget>().getCLOpts();
261 Changed |= runOnMachineBasicBlock(
262 *curMBB, (
MBB !=
F.
end() && !(*MBB).empty()) ? &(*MBB).instr_front()
270 F.getRegInfo().invalidateLiveness();
275 MachineFunctionProperties getRequiredProperties()
const override {
276 return MachineFunctionProperties().setNoVRegs();
279 void getAnalysisUsage(AnalysisUsage &AU)
const override {
280 AU.
addRequired<MachineBranchProbabilityInfoWrapperPass>();
287 bool runOnMachineBasicBlock(MachineBasicBlock &
MBB,
288 MachineInstr *FirstNextMBBInstr);
290 Iter replaceWithCompactBranch(MachineBasicBlock &
MBB, Iter Branch,
296 bool delayHasHazard(
const MipsSubtarget &STI,
const MachineInstr &Candidate,
297 const BranchInformation &BranchInfo, RegDefsUses &RegDU,
298 InspectMemInstr &IM)
const;
302 template <
typename IterTy>
303 bool searchRange(MachineBasicBlock &
MBB, IterTy Begin, IterTy
End,
304 const BranchInformation &BranchInfo, RegDefsUses &RegDU,
305 InspectMemInstr &IM, Iter Slot, IterTy &Filler)
const;
309 bool searchBackward(MachineBasicBlock &
MBB, MachineInstr &Slot,
310 const BranchInformation &BranchInfo)
const;
314 bool searchForward(MachineBasicBlock &
MBB, Iter Slot,
315 const BranchInformation &BranchInfo)
const;
320 bool searchSuccBBs(MachineBasicBlock &
MBB, Iter Slot,
321 const BranchInformation &BranchInfo)
const;
325 MachineBasicBlock *selectSuccBB(MachineBasicBlock &
B)
const;
329 std::pair<MipsInstrInfo::BranchType, MachineInstr *>
330 getBranch(MachineBasicBlock &
MBB,
const MachineBasicBlock &Dst)
const;
334 bool examinePred(MachineBasicBlock &Pred,
const MachineBasicBlock &Succ,
335 RegDefsUses &RegDU,
bool &HasMultipleSuccs,
336 BB2BrMap &
BrMap)
const;
338 bool terminateSearch(
const MachineInstr &Candidate)
const;
340 const TargetMachine *TM =
nullptr;
341 const MipsOptions *CLOpts =
nullptr;
346char MipsDelaySlotFiller::ID = 0;
349 return MI->hasDelaySlot() && !
MI->isBundledWithSucc();
373 if (!
MI->isBranch() ||
MI->isIndirectBranch())
380 TargetMBB = MO.getMBB();
386 if (!TargetMBB || TargetMBB != &
MBB)
393 bool HasOtherBranch =
false;
400 if (Instr.isDebugInstr() || Instr.isTransient())
406 if (Instr.isBranch() || Instr.isCall()) {
407 HasOtherBranch =
true;
424 "Fill delay slot for MIPS",
false,
false)
427static
void insertDelayFiller(Iter Filler,
const BB2BrMap &
BrMap) {
435 I.first->push_back(MF->CloneMachineInstr(&*Filler));
445 if (!MO.isReg() || !MO.isDef() || !(R = MO.getReg()))
451 "Shouldn't move an instruction with unallocatable registers across "
452 "basic block boundaries.");
455 if (!
MBB.isLiveIn(R))
465 update(
MI, 0,
MI.getDesc().getNumOperands());
475 update(
MI,
MI.getDesc().getNumOperands(),
MI.getNumOperands());
476 Defs.
reset(Mips::AT);
480void RegDefsUses::setCallerSaved(
const MachineInstr &
MI) {
486 if (
MI.definesRegister(Mips::RA,
nullptr) ||
487 MI.definesRegister(Mips::RA_64,
nullptr)) {
489 Defs.
set(Mips::RA_64);
493 BitVector CallerSavedRegs(
TRI.getNumRegs(),
true);
495 CallerSavedRegs.reset(Mips::ZERO);
496 CallerSavedRegs.reset(Mips::ZERO_64);
498 for (
const MCPhysReg *R =
TRI.getCalleeSavedRegs(
MI.getParent()->getParent());
500 for (MCRegAliasIterator AI(*R, &
TRI,
true); AI.isValid(); ++AI)
501 CallerSavedRegs.reset(*AI);
503 Defs |= CallerSavedRegs;
507 BitVector AllocSet =
TRI.getAllocatableSet(MF);
509 for (
unsigned R : AllocSet.
set_bits())
510 for (MCRegAliasIterator AI(R, &
TRI,
false); AI.isValid(); ++AI)
513 AllocSet.
set(Mips::ZERO);
514 AllocSet.
set(Mips::ZERO_64);
516 Defs |= AllocSet.
flip();
519void RegDefsUses::addLiveOut(
const MachineBasicBlock &
MBB,
520 const MachineBasicBlock &SuccBB) {
523 for (
const auto &LI : S->liveins())
527bool RegDefsUses::update(
const MachineInstr &
MI,
unsigned Begin,
unsigned End) {
528 BitVector NewDefs(
TRI.getNumRegs()), NewUses(
TRI.getNumRegs());
529 bool HasHazard =
false;
531 for (
unsigned I = Begin;
I !=
End; ++
I) {
532 const MachineOperand &MO =
MI.getOperand(
I);
535 if (checkRegDefsUses(NewDefs, NewUses, MO.
getReg(), MO.
isDef())) {
550bool RegDefsUses::checkRegDefsUses(BitVector &NewDefs, BitVector &NewUses,
551 unsigned Reg,
bool IsDef)
const {
555 return (isRegInSet(Defs,
Reg) || isRegInSet(
Uses,
Reg));
560 return isRegInSet(Defs,
Reg);
563bool RegDefsUses::isRegInSet(
const BitVector &RegSet,
unsigned Reg)
const {
565 for (MCRegAliasIterator AI(
Reg, &
TRI,
true); AI.isValid(); ++AI)
566 if (RegSet.
test(*AI))
571bool InspectMemInstr::hasHazard(
const MachineInstr &
MI) {
572 if (!
MI.mayStore() && !
MI.mayLoad())
578 OrigSeenLoad = SeenLoad;
579 OrigSeenStore = SeenStore;
580 SeenLoad |=
MI.mayLoad();
581 SeenStore |=
MI.mayStore();
585 if (
MI.hasOrderedMemoryRef() && (OrigSeenLoad || OrigSeenStore)) {
586 ForbidMemInstr =
true;
590 return hasHazard_(
MI);
593bool LoadFromStackOrConst::hasHazard_(
const MachineInstr &
MI) {
597 if (!
MI.hasOneMemOperand() || !(*
MI.memoperands_begin())->getPseudoValue())
600 if (
const PseudoSourceValue *PSV =
601 (*
MI.memoperands_begin())->getPseudoValue()) {
604 return !PSV->isConstant(
nullptr) && !PSV->isStack();
610MemDefsUses::MemDefsUses(
const MachineFrameInfo *MFI_)
611 : InspectMemInstr(
false), MFI(MFI_) {}
614 bool HasHazard =
false;
617 SmallVector<ValueType, 4> Objs;
620 HasHazard |= updateDefsUses(VT,
MI.mayStore());
625 HasHazard =
MI.mayStore() && (OrigSeenLoad || OrigSeenStore);
626 HasHazard |=
MI.mayLoad() || OrigSeenStore;
628 SeenNoObjLoad |=
MI.mayLoad();
629 SeenNoObjStore |=
MI.mayStore();
634bool MemDefsUses::updateDefsUses(
ValueType V,
bool MayStore) {
636 return !Defs.insert(V).second ||
Uses.count(V) || SeenNoObjStore ||
640 return Defs.count(V) || SeenNoObjStore;
644getUnderlyingObjects(
const MachineInstr &
MI,
645 SmallVectorImpl<ValueType> &Objects)
const {
646 if (!
MI.hasOneMemOperand())
649 auto & MMO = **
MI.memoperands_begin();
651 if (
const PseudoSourceValue *PSV = MMO.getPseudoValue()) {
652 if (!PSV->isAliased(MFI))
658 if (
const Value *V = MMO.getValue()) {
662 for (
const Value *UValue : Objs) {
675Iter MipsDelaySlotFiller::replaceWithCompactBranch(MachineBasicBlock &
MBB,
681 unsigned NewOpcode =
TII->getEquivalentCompactForm(Branch);
682 Branch =
TII->genInstrWithNewOpc(NewOpcode, Branch);
686 if (ToErase->shouldUpdateAdditionalCallInfo())
687 ToErase->getMF()->moveAdditionalCallInfo(ToErase,
689 ToErase->eraseFromParent();
701 return Mips::BGEZALS_MM;
703 return Mips::BLTZALS_MM;
706 return Mips::JALS_MM;
708 return Mips::JALRS_MM;
709 case Mips::JALR16_MM:
710 return Mips::JALRS16_MM;
711 case Mips::TAILCALL_MM:
713 case Mips::TAILCALLREG:
714 return Mips::JR16_MM;
722bool MipsDelaySlotFiller::runOnMachineBasicBlock(
723 MachineBasicBlock &
MBB, MachineInstr *FirstNextMBBInstr) {
736 bool SkipForFixR5900 =
false;
739 "short loop branch.\n");
740 ++R5900ShortLoopNops;
741 SkipForFixR5900 =
true;
746 if (!CLOpts->disable_mips_delay_filler &&
748 !(InMicroMipsMode && STI.
hasMips32r6()) && !SkipForFixR5900) {
751 const auto BranchInfo =
752 BranchInformation(
I,
MBB.
end(), FirstNextMBBInstr);
754 if (CLOpts->compact_branches != CompactBranchPolicy::Always ||
755 !
TII->getEquivalentCompactForm(
I)) {
756 if (searchBackward(
MBB, *
I, BranchInfo)) {
758 " in backwards search.\n");
760 }
else if (
I->isTerminator()) {
761 if (searchSuccBBs(
MBB,
I, BranchInfo)) {
764 " in successor BB search.\n");
766 }
else if (searchForward(
MBB,
I, BranchInfo)) {
768 " in forwards search.\n");
777 if (InMicroMipsMode &&
TII->getInstSizeInBytes(*std::next(DSI)) == 2 &&
804 if ((InMicroMipsMode ||
806 CLOpts->compact_branches != CompactBranchPolicy::Never)) &&
807 TII->getEquivalentCompactForm(
I)) {
808 I = replaceWithCompactBranch(
MBB,
I,
I->getDebugLoc());
816 TII->insertNop(
MBB, std::next(
I),
I->getDebugLoc());
817 MIBundleBuilder(
MBB,
I, std::next(
I, 2));
824template <
typename IterTy>
825bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &
MBB, IterTy Begin,
827 const BranchInformation &BranchInfo,
828 RegDefsUses &RegDU, InspectMemInstr &IM,
829 Iter Slot, IterTy &Filler)
const {
830 for (IterTy
I = Begin;
I !=
End;) {
835 if (terminateSearch(*CurrI)) {
843 if (CurrI->isDebugInstr() || CurrI->isJumpTableDebugInfo() ||
844 CurrI->isMetaInstruction()) {
850 if (CurrI->isBundle()) {
854 RegDU.update(*CurrI, 0, CurrI->getNumOperands());
858 assert((!CurrI->isCall() && !CurrI->isReturn() && !CurrI->isBranch()) &&
859 "Cannot put calls, returns or branches in delay slot.");
861 if (CurrI->isKill()) {
862 CurrI->eraseFromParent();
867 if (delayHasHazard(STI, *CurrI, BranchInfo, RegDU, IM))
872 unsigned Opcode = (*Slot).getOpcode();
884 if (InMicroMipsMode &&
TII->getInstSizeInBytes(*CurrI) == 2 &&
885 (Opcode == Mips::JR || Opcode == Mips::PseudoIndirectBranch ||
886 Opcode == Mips::PseudoIndirectBranch_MM ||
887 Opcode == Mips::PseudoReturn || Opcode == Mips::TAILCALL))
891 if (InMicroMipsMode && (Opcode == Mips::LWP_MM || Opcode == Mips::SWP_MM ||
892 Opcode == Mips::MOVEP_MM))
905bool MipsDelaySlotFiller::searchBackward(
906 MachineBasicBlock &
MBB, MachineInstr &Slot,
907 const BranchInformation &BranchInfo)
const {
908 if (CLOpts->disable_mips_df_backward_search)
912 RegDefsUses RegDU(*Fn->getSubtarget().getRegisterInfo());
913 MemDefsUses MemDU(&Fn->getFrameInfo());
920 MemDU, Slot, Filler)) {
922 "slot using backwards search.\n");
926 MBB.
splice(std::next(SlotI), &
MBB, Filler.getReverse());
927 MIBundleBuilder(
MBB, SlotI, std::next(SlotI, 2));
932bool MipsDelaySlotFiller::searchForward(
933 MachineBasicBlock &
MBB, Iter Slot,
934 const BranchInformation &BranchInfo)
const {
936 if (CLOpts->disable_mips_df_forward_search || !
Slot->isCall())
943 RegDU.setCallerSaved(*Slot);
945 if (!searchRange(
MBB, std::next(Slot),
MBB.
end(), BranchInfo, RegDU, NM, Slot,
948 "slot using forwards search.\n");
953 MIBundleBuilder(
MBB, Slot, std::next(Slot, 2));
958bool MipsDelaySlotFiller::searchSuccBBs(
959 MachineBasicBlock &
MBB, Iter Slot,
960 const BranchInformation &BranchInfo)
const {
961 if (CLOpts->disable_mips_df_succbb_search)
964 MachineBasicBlock *SuccBB = selectSuccBB(
MBB);
970 bool HasMultipleSuccs =
false;
972 std::unique_ptr<InspectMemInstr> IM;
978 if (!examinePred(*Pred, *SuccBB, RegDU, HasMultipleSuccs,
BrMap))
983 RegDU.setUnallocatableRegs(*Fn);
987 if (HasMultipleSuccs) {
988 IM.reset(
new LoadFromStackOrConst());
990 const MachineFrameInfo &MFI = Fn->getFrameInfo();
991 IM.reset(
new MemDefsUses(&MFI));
994 if (!searchRange(
MBB, SuccBB->
begin(), SuccBB->
end(), BranchInfo, RegDU, *IM,
998 insertDelayFiller(Filler,
BrMap);
1000 Filler->eraseFromParent();
1006MipsDelaySlotFiller::selectSuccBB(MachineBasicBlock &
B)
const {
1011 auto &Prob = getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
1012 MachineBasicBlock *S =
1014 const MachineBasicBlock *Dst1) {
1015 return Prob.getEdgeProbability(&B, Dst0) <
1016 Prob.getEdgeProbability(&B, Dst1);
1018 return S->
isEHPad() ? nullptr : S;
1021std::pair<MipsInstrInfo::BranchType, MachineInstr *>
1022MipsDelaySlotFiller::getBranch(MachineBasicBlock &
MBB,
1023 const MachineBasicBlock &Dst)
const {
1024 const MipsInstrInfo *
TII =
1026 MachineBasicBlock *TrueBB =
nullptr, *FalseBB =
nullptr;
1027 SmallVector<MachineInstr*, 2> BranchInstrs;
1034 return std::make_pair(R,
nullptr);
1042 return std::make_pair(R, BranchInstrs[0]);
1045 assert((TrueBB == &Dst) || (FalseBB == &Dst));
1058bool MipsDelaySlotFiller::examinePred(MachineBasicBlock &Pred,
1059 const MachineBasicBlock &Succ,
1061 bool &HasMultipleSuccs,
1062 BB2BrMap &
BrMap)
const {
1063 std::pair<MipsInstrInfo::BranchType, MachineInstr *>
P =
1064 getBranch(Pred, Succ);
1073 HasMultipleSuccs =
true;
1074 RegDU.addLiveOut(Pred, Succ);
1085 const BranchInformation &BranchInfo,
const MachineInstr &Candidate,
1089 if (!BranchInfo.hasBranchInstr() || BranchInfo.isIndirectBranch())
1093 if (!TargetMBB || TargetMBB->
empty())
1096 bool Exposed = !IsSafe(TargetMBB->
instr_front(), Candidate);
1100 if (!BranchInfo.isUnconditionalBranch()) {
1101 if (!BranchInfo.hasBranchElseInstr())
1103 Exposed |= !IsSafe(*BranchInfo.getBranchElseInstr(), Candidate);
1109bool MipsDelaySlotFiller::delayHasHazard(
const MipsSubtarget &STI,
1110 const MachineInstr &Candidate,
1111 const BranchInformation &BranchInfo,
1113 InspectMemInstr &IM)
const {
1115 "KILL instructions should have been eliminated at this point.");
1119 HasHazard |= IM.hasHazard(Candidate);
1120 HasHazard |= RegDU.update(Candidate, 0, Candidate.
getNumOperands());
1129 BranchInfo, Candidate,
1130 [
TII](
const MachineInstr &InShadow,
const MachineInstr &Cand) {
1131 return TII->SafeInLoadDelaySlot(InShadow, Cand);
1138 BranchInfo, Candidate,
1139 [
TII](
const MachineInstr &InShadow,
const MachineInstr &Cand) {
1140 return TII->SafeInFPUDelaySlot(InShadow, Cand);
1147bool MipsDelaySlotFiller::terminateSearch(
const MachineInstr &Candidate)
const {
1156 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 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 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...
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
@ End
Run the machine verifier once, at the end of the pipeline.
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.