File indexing completed on 2026-05-10 08:43:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_CODEGEN_MACHINEBASICBLOCK_H
0014 #define LLVM_CODEGEN_MACHINEBASICBLOCK_H
0015
0016 #include "llvm/ADT/DenseMapInfo.h"
0017 #include "llvm/ADT/GraphTraits.h"
0018 #include "llvm/ADT/SparseBitVector.h"
0019 #include "llvm/ADT/ilist.h"
0020 #include "llvm/ADT/iterator_range.h"
0021 #include "llvm/CodeGen/MachineInstr.h"
0022 #include "llvm/CodeGen/MachineInstrBundleIterator.h"
0023 #include "llvm/IR/DebugLoc.h"
0024 #include "llvm/MC/LaneBitmask.h"
0025 #include "llvm/Support/BranchProbability.h"
0026 #include <cassert>
0027 #include <cstdint>
0028 #include <iterator>
0029 #include <string>
0030 #include <vector>
0031
0032 namespace llvm {
0033
0034 class BasicBlock;
0035 class MachineDomTreeUpdater;
0036 class MachineFunction;
0037 class MCSymbol;
0038 class ModuleSlotTracker;
0039 class Pass;
0040 class Printable;
0041 class SlotIndexes;
0042 class StringRef;
0043 class raw_ostream;
0044 class LiveIntervals;
0045 class TargetRegisterClass;
0046 class TargetRegisterInfo;
0047 template <typename IRUnitT, typename... ExtraArgTs> class AnalysisManager;
0048 using MachineFunctionAnalysisManager = AnalysisManager<MachineFunction>;
0049
0050
0051
0052
0053
0054
0055 struct MBBSectionID {
0056 enum SectionType {
0057 Default = 0,
0058
0059 Exception,
0060 Cold,
0061 } Type;
0062 unsigned Number;
0063
0064 MBBSectionID(unsigned N) : Type(Default), Number(N) {}
0065
0066
0067 const static MBBSectionID ColdSectionID;
0068 const static MBBSectionID ExceptionSectionID;
0069
0070 bool operator==(const MBBSectionID &Other) const {
0071 return Type == Other.Type && Number == Other.Number;
0072 }
0073
0074 bool operator!=(const MBBSectionID &Other) const { return !(*this == Other); }
0075
0076 private:
0077
0078 MBBSectionID(SectionType T) : Type(T), Number(0) {}
0079 };
0080
0081 template <> struct DenseMapInfo<MBBSectionID> {
0082 using TypeInfo = DenseMapInfo<MBBSectionID::SectionType>;
0083 using NumberInfo = DenseMapInfo<unsigned>;
0084
0085 static inline MBBSectionID getEmptyKey() {
0086 return MBBSectionID(NumberInfo::getEmptyKey());
0087 }
0088 static inline MBBSectionID getTombstoneKey() {
0089 return MBBSectionID(NumberInfo::getTombstoneKey());
0090 }
0091 static unsigned getHashValue(const MBBSectionID &SecID) {
0092 return detail::combineHashValue(TypeInfo::getHashValue(SecID.Type),
0093 NumberInfo::getHashValue(SecID.Number));
0094 }
0095 static bool isEqual(const MBBSectionID &LHS, const MBBSectionID &RHS) {
0096 return LHS == RHS;
0097 }
0098 };
0099
0100
0101
0102 struct UniqueBBID {
0103 unsigned BaseID;
0104 unsigned CloneID;
0105 };
0106
0107 template <> struct ilist_traits<MachineInstr> {
0108 private:
0109 friend class MachineBasicBlock;
0110
0111 MachineBasicBlock *Parent;
0112
0113 using instr_iterator =
0114 simple_ilist<MachineInstr, ilist_sentinel_tracking<true>>::iterator;
0115
0116 public:
0117 void addNodeToList(MachineInstr *N);
0118 void removeNodeFromList(MachineInstr *N);
0119 void transferNodesFromList(ilist_traits &FromList, instr_iterator First,
0120 instr_iterator Last);
0121 void deleteNode(MachineInstr *MI);
0122 };
0123
0124 class MachineBasicBlock
0125 : public ilist_node_with_parent<MachineBasicBlock, MachineFunction> {
0126 public:
0127
0128
0129
0130 struct RegisterMaskPair {
0131 public:
0132 MCRegister PhysReg;
0133 LaneBitmask LaneMask;
0134
0135 RegisterMaskPair(MCPhysReg PhysReg, LaneBitmask LaneMask)
0136 : PhysReg(PhysReg), LaneMask(LaneMask) {}
0137
0138 bool operator==(const RegisterMaskPair &other) const {
0139 return PhysReg == other.PhysReg && LaneMask == other.LaneMask;
0140 }
0141 };
0142
0143 private:
0144 using Instructions = ilist<MachineInstr, ilist_sentinel_tracking<true>>;
0145
0146 const BasicBlock *BB;
0147 int Number;
0148
0149
0150
0151
0152
0153
0154
0155 unsigned CallFrameSize = 0;
0156
0157 MachineFunction *xParent;
0158 Instructions Insts;
0159
0160
0161 SmallVector<MachineBasicBlock *, 4> Predecessors;
0162 SmallVector<MachineBasicBlock *, 2> Successors;
0163
0164
0165
0166
0167 std::vector<BranchProbability> Probs;
0168 using probability_iterator = std::vector<BranchProbability>::iterator;
0169 using const_probability_iterator =
0170 std::vector<BranchProbability>::const_iterator;
0171
0172 std::optional<uint64_t> IrrLoopHeaderWeight;
0173
0174
0175 using LiveInVector = std::vector<RegisterMaskPair>;
0176 LiveInVector LiveIns;
0177
0178
0179
0180 Align Alignment;
0181
0182
0183
0184 unsigned MaxBytesForAlignment = 0;
0185
0186
0187 bool IsEHPad = false;
0188
0189
0190
0191 bool MachineBlockAddressTaken = false;
0192
0193
0194
0195 BasicBlock *AddressTakenIRBlock = nullptr;
0196
0197
0198
0199 bool LabelMustBeEmitted = false;
0200
0201
0202
0203
0204 bool IsEHScopeEntry = false;
0205
0206
0207 bool IsEHCatchretTarget = false;
0208
0209
0210 bool IsEHFuncletEntry = false;
0211
0212
0213 bool IsCleanupFuncletEntry = false;
0214
0215
0216
0217 std::optional<UniqueBBID> BBID;
0218
0219
0220 MBBSectionID SectionID{0};
0221
0222
0223 bool IsBeginSection = false;
0224
0225
0226 bool IsEndSection = false;
0227
0228
0229 bool IsInlineAsmBrIndirectTarget = false;
0230
0231
0232
0233 mutable MCSymbol *CachedMCSymbol = nullptr;
0234
0235
0236 mutable MCSymbol *CachedEHCatchretMCSymbol = nullptr;
0237
0238
0239
0240 mutable MCSymbol *CachedEndMCSymbol = nullptr;
0241
0242
0243 MachineBasicBlock() = default;
0244
0245 explicit MachineBasicBlock(MachineFunction &MF, const BasicBlock *BB);
0246
0247 ~MachineBasicBlock();
0248
0249
0250 friend class MachineFunction;
0251
0252 public:
0253
0254
0255
0256 const BasicBlock *getBasicBlock() const { return BB; }
0257
0258
0259
0260 void clearBasicBlock() {
0261 BB = nullptr;
0262 }
0263
0264
0265 bool hasName() const;
0266
0267
0268 StringRef getName() const;
0269
0270
0271 std::string getFullName() const;
0272
0273
0274
0275
0276
0277 bool hasAddressTaken() const {
0278 return MachineBlockAddressTaken || AddressTakenIRBlock;
0279 }
0280
0281
0282
0283
0284
0285 bool isMachineBlockAddressTaken() const { return MachineBlockAddressTaken; }
0286
0287
0288
0289 bool isIRBlockAddressTaken() const { return AddressTakenIRBlock; }
0290
0291
0292 BasicBlock *getAddressTakenIRBlock() const { return AddressTakenIRBlock; }
0293
0294
0295
0296
0297 void setMachineBlockAddressTaken() { MachineBlockAddressTaken = true; }
0298
0299
0300
0301 void setAddressTakenIRBlock(BasicBlock *BB) { AddressTakenIRBlock = BB; }
0302
0303
0304 bool hasLabelMustBeEmitted() const { return LabelMustBeEmitted; }
0305
0306
0307
0308 void setLabelMustBeEmitted() { LabelMustBeEmitted = true; }
0309
0310
0311 const MachineFunction *getParent() const { return xParent; }
0312 MachineFunction *getParent() { return xParent; }
0313
0314
0315
0316 bool terminatorIsComputedGoto() const {
0317 return back().isIndirectBranch() &&
0318 llvm::all_of(successors(), [](const MachineBasicBlock *Succ) {
0319 return Succ->isIRBlockAddressTaken();
0320 });
0321 }
0322
0323 using instr_iterator = Instructions::iterator;
0324 using const_instr_iterator = Instructions::const_iterator;
0325 using reverse_instr_iterator = Instructions::reverse_iterator;
0326 using const_reverse_instr_iterator = Instructions::const_reverse_iterator;
0327
0328 using iterator = MachineInstrBundleIterator<MachineInstr>;
0329 using const_iterator = MachineInstrBundleIterator<const MachineInstr>;
0330 using reverse_iterator = MachineInstrBundleIterator<MachineInstr, true>;
0331 using const_reverse_iterator =
0332 MachineInstrBundleIterator<const MachineInstr, true>;
0333
0334 unsigned size() const { return (unsigned)Insts.size(); }
0335 bool sizeWithoutDebugLargerThan(unsigned Limit) const;
0336 bool empty() const { return Insts.empty(); }
0337
0338 MachineInstr &instr_front() { return Insts.front(); }
0339 MachineInstr &instr_back() { return Insts.back(); }
0340 const MachineInstr &instr_front() const { return Insts.front(); }
0341 const MachineInstr &instr_back() const { return Insts.back(); }
0342
0343 MachineInstr &front() { return Insts.front(); }
0344 MachineInstr &back() { return *--end(); }
0345 const MachineInstr &front() const { return Insts.front(); }
0346 const MachineInstr &back() const { return *--end(); }
0347
0348 instr_iterator instr_begin() { return Insts.begin(); }
0349 const_instr_iterator instr_begin() const { return Insts.begin(); }
0350 instr_iterator instr_end() { return Insts.end(); }
0351 const_instr_iterator instr_end() const { return Insts.end(); }
0352 reverse_instr_iterator instr_rbegin() { return Insts.rbegin(); }
0353 const_reverse_instr_iterator instr_rbegin() const { return Insts.rbegin(); }
0354 reverse_instr_iterator instr_rend () { return Insts.rend(); }
0355 const_reverse_instr_iterator instr_rend () const { return Insts.rend(); }
0356
0357 using instr_range = iterator_range<instr_iterator>;
0358 using const_instr_range = iterator_range<const_instr_iterator>;
0359 instr_range instrs() { return instr_range(instr_begin(), instr_end()); }
0360 const_instr_range instrs() const {
0361 return const_instr_range(instr_begin(), instr_end());
0362 }
0363
0364 iterator begin() { return instr_begin(); }
0365 const_iterator begin() const { return instr_begin(); }
0366 iterator end () { return instr_end(); }
0367 const_iterator end () const { return instr_end(); }
0368 reverse_iterator rbegin() {
0369 return reverse_iterator::getAtBundleBegin(instr_rbegin());
0370 }
0371 const_reverse_iterator rbegin() const {
0372 return const_reverse_iterator::getAtBundleBegin(instr_rbegin());
0373 }
0374 reverse_iterator rend() { return reverse_iterator(instr_rend()); }
0375 const_reverse_iterator rend() const {
0376 return const_reverse_iterator(instr_rend());
0377 }
0378
0379
0380 static Instructions MachineBasicBlock::*getSublistAccess(MachineInstr *) {
0381 return &MachineBasicBlock::Insts;
0382 }
0383
0384 inline iterator_range<iterator> terminators() {
0385 return make_range(getFirstTerminator(), end());
0386 }
0387 inline iterator_range<const_iterator> terminators() const {
0388 return make_range(getFirstTerminator(), end());
0389 }
0390
0391
0392 inline iterator_range<iterator> phis() {
0393 return make_range(begin(), getFirstNonPHI());
0394 }
0395 inline iterator_range<const_iterator> phis() const {
0396 return const_cast<MachineBasicBlock *>(this)->phis();
0397 }
0398
0399
0400 using pred_iterator = SmallVectorImpl<MachineBasicBlock *>::iterator;
0401 using const_pred_iterator =
0402 SmallVectorImpl<MachineBasicBlock *>::const_iterator;
0403 using succ_iterator = SmallVectorImpl<MachineBasicBlock *>::iterator;
0404 using const_succ_iterator =
0405 SmallVectorImpl<MachineBasicBlock *>::const_iterator;
0406 using pred_reverse_iterator =
0407 SmallVectorImpl<MachineBasicBlock *>::reverse_iterator;
0408 using const_pred_reverse_iterator =
0409 SmallVectorImpl<MachineBasicBlock *>::const_reverse_iterator;
0410 using succ_reverse_iterator =
0411 SmallVectorImpl<MachineBasicBlock *>::reverse_iterator;
0412 using const_succ_reverse_iterator =
0413 SmallVectorImpl<MachineBasicBlock *>::const_reverse_iterator;
0414 pred_iterator pred_begin() { return Predecessors.begin(); }
0415 const_pred_iterator pred_begin() const { return Predecessors.begin(); }
0416 pred_iterator pred_end() { return Predecessors.end(); }
0417 const_pred_iterator pred_end() const { return Predecessors.end(); }
0418 pred_reverse_iterator pred_rbegin()
0419 { return Predecessors.rbegin();}
0420 const_pred_reverse_iterator pred_rbegin() const
0421 { return Predecessors.rbegin();}
0422 pred_reverse_iterator pred_rend()
0423 { return Predecessors.rend(); }
0424 const_pred_reverse_iterator pred_rend() const
0425 { return Predecessors.rend(); }
0426 unsigned pred_size() const {
0427 return (unsigned)Predecessors.size();
0428 }
0429 bool pred_empty() const { return Predecessors.empty(); }
0430 succ_iterator succ_begin() { return Successors.begin(); }
0431 const_succ_iterator succ_begin() const { return Successors.begin(); }
0432 succ_iterator succ_end() { return Successors.end(); }
0433 const_succ_iterator succ_end() const { return Successors.end(); }
0434 succ_reverse_iterator succ_rbegin()
0435 { return Successors.rbegin(); }
0436 const_succ_reverse_iterator succ_rbegin() const
0437 { return Successors.rbegin(); }
0438 succ_reverse_iterator succ_rend()
0439 { return Successors.rend(); }
0440 const_succ_reverse_iterator succ_rend() const
0441 { return Successors.rend(); }
0442 unsigned succ_size() const {
0443 return (unsigned)Successors.size();
0444 }
0445 bool succ_empty() const { return Successors.empty(); }
0446
0447 inline iterator_range<pred_iterator> predecessors() {
0448 return make_range(pred_begin(), pred_end());
0449 }
0450 inline iterator_range<const_pred_iterator> predecessors() const {
0451 return make_range(pred_begin(), pred_end());
0452 }
0453 inline iterator_range<succ_iterator> successors() {
0454 return make_range(succ_begin(), succ_end());
0455 }
0456 inline iterator_range<const_succ_iterator> successors() const {
0457 return make_range(succ_begin(), succ_end());
0458 }
0459
0460
0461
0462
0463
0464
0465 void addLiveIn(MCRegister PhysReg,
0466 LaneBitmask LaneMask = LaneBitmask::getAll()) {
0467 LiveIns.push_back(RegisterMaskPair(PhysReg, LaneMask));
0468 }
0469 void addLiveIn(const RegisterMaskPair &RegMaskPair) {
0470 LiveIns.push_back(RegMaskPair);
0471 }
0472
0473
0474
0475
0476 void sortUniqueLiveIns();
0477
0478
0479 void clearLiveIns();
0480
0481
0482
0483 void clearLiveIns(std::vector<RegisterMaskPair> &OldLiveIns);
0484
0485
0486
0487
0488 Register addLiveIn(MCRegister PhysReg, const TargetRegisterClass *RC);
0489
0490
0491 void removeLiveIn(MCRegister Reg,
0492 LaneBitmask LaneMask = LaneBitmask::getAll());
0493
0494
0495 bool isLiveIn(MCRegister Reg,
0496 LaneBitmask LaneMask = LaneBitmask::getAll()) const;
0497
0498
0499
0500 using livein_iterator = LiveInVector::const_iterator;
0501
0502
0503
0504
0505
0506 livein_iterator livein_begin_dbg() const { return LiveIns.begin(); }
0507 iterator_range<livein_iterator> liveins_dbg() const {
0508 return make_range(livein_begin_dbg(), livein_end());
0509 }
0510
0511 livein_iterator livein_begin() const;
0512 livein_iterator livein_end() const { return LiveIns.end(); }
0513 bool livein_empty() const { return LiveIns.empty(); }
0514 iterator_range<livein_iterator> liveins() const {
0515 return make_range(livein_begin(), livein_end());
0516 }
0517
0518
0519 livein_iterator removeLiveIn(livein_iterator I);
0520
0521 const std::vector<RegisterMaskPair> &getLiveIns() const { return LiveIns; }
0522
0523 class liveout_iterator {
0524 public:
0525 using iterator_category = std::input_iterator_tag;
0526 using difference_type = std::ptrdiff_t;
0527 using value_type = RegisterMaskPair;
0528 using pointer = const RegisterMaskPair *;
0529 using reference = const RegisterMaskPair &;
0530
0531 liveout_iterator(const MachineBasicBlock &MBB, MCPhysReg ExceptionPointer,
0532 MCPhysReg ExceptionSelector, bool End)
0533 : ExceptionPointer(ExceptionPointer),
0534 ExceptionSelector(ExceptionSelector), BlockI(MBB.succ_begin()),
0535 BlockEnd(MBB.succ_end()) {
0536 if (End)
0537 BlockI = BlockEnd;
0538 else if (BlockI != BlockEnd) {
0539 LiveRegI = (*BlockI)->livein_begin();
0540 if (!advanceToValidPosition())
0541 return;
0542 if (LiveRegI->PhysReg == ExceptionPointer ||
0543 LiveRegI->PhysReg == ExceptionSelector)
0544 ++(*this);
0545 }
0546 }
0547
0548 liveout_iterator &operator++() {
0549 do {
0550 ++LiveRegI;
0551 if (!advanceToValidPosition())
0552 return *this;
0553 } while ((*BlockI)->isEHPad() &&
0554 (LiveRegI->PhysReg == ExceptionPointer ||
0555 LiveRegI->PhysReg == ExceptionSelector));
0556 return *this;
0557 }
0558
0559 liveout_iterator operator++(int) {
0560 liveout_iterator Tmp = *this;
0561 ++(*this);
0562 return Tmp;
0563 }
0564
0565 reference operator*() const {
0566 return *LiveRegI;
0567 }
0568
0569 pointer operator->() const {
0570 return &*LiveRegI;
0571 }
0572
0573 bool operator==(const liveout_iterator &RHS) const {
0574 if (BlockI != BlockEnd)
0575 return BlockI == RHS.BlockI && LiveRegI == RHS.LiveRegI;
0576 return RHS.BlockI == BlockEnd;
0577 }
0578
0579 bool operator!=(const liveout_iterator &RHS) const {
0580 return !(*this == RHS);
0581 }
0582 private:
0583 bool advanceToValidPosition() {
0584 if (LiveRegI != (*BlockI)->livein_end())
0585 return true;
0586
0587 do {
0588 ++BlockI;
0589 } while (BlockI != BlockEnd && (*BlockI)->livein_empty());
0590 if (BlockI == BlockEnd)
0591 return false;
0592
0593 LiveRegI = (*BlockI)->livein_begin();
0594 return true;
0595 }
0596
0597 MCPhysReg ExceptionPointer, ExceptionSelector;
0598 const_succ_iterator BlockI;
0599 const_succ_iterator BlockEnd;
0600 livein_iterator LiveRegI;
0601 };
0602
0603
0604
0605
0606 liveout_iterator liveout_begin() const;
0607 liveout_iterator liveout_end() const {
0608 return liveout_iterator(*this, 0, 0, true);
0609 }
0610 iterator_range<liveout_iterator> liveouts() const {
0611 return make_range(liveout_begin(), liveout_end());
0612 }
0613
0614
0615
0616 const uint32_t *getBeginClobberMask(const TargetRegisterInfo *TRI) const;
0617
0618
0619
0620 const uint32_t *getEndClobberMask(const TargetRegisterInfo *TRI) const;
0621
0622
0623 Align getAlignment() const { return Alignment; }
0624
0625
0626 void setAlignment(Align A) { Alignment = A; }
0627
0628 void setAlignment(Align A, unsigned MaxBytes) {
0629 setAlignment(A);
0630 setMaxBytesForAlignment(MaxBytes);
0631 }
0632
0633
0634 unsigned getMaxBytesForAlignment() const { return MaxBytesForAlignment; }
0635
0636
0637 void setMaxBytesForAlignment(unsigned MaxBytes) {
0638 MaxBytesForAlignment = MaxBytes;
0639 }
0640
0641
0642
0643 bool isEHPad() const { return IsEHPad; }
0644
0645
0646
0647 void setIsEHPad(bool V = true) { IsEHPad = V; }
0648
0649 bool hasEHPadSuccessor() const;
0650
0651
0652 bool isEntryBlock() const;
0653
0654
0655
0656 bool isEHScopeEntry() const { return IsEHScopeEntry; }
0657
0658
0659
0660 void setIsEHScopeEntry(bool V = true) { IsEHScopeEntry = V; }
0661
0662
0663 bool isEHCatchretTarget() const { return IsEHCatchretTarget; }
0664
0665
0666 void setIsEHCatchretTarget(bool V = true) { IsEHCatchretTarget = V; }
0667
0668
0669 bool isEHFuncletEntry() const { return IsEHFuncletEntry; }
0670
0671
0672 void setIsEHFuncletEntry(bool V = true) { IsEHFuncletEntry = V; }
0673
0674
0675 bool isCleanupFuncletEntry() const { return IsCleanupFuncletEntry; }
0676
0677
0678 void setIsCleanupFuncletEntry(bool V = true) { IsCleanupFuncletEntry = V; }
0679
0680
0681 bool isBeginSection() const { return IsBeginSection; }
0682
0683
0684 bool isEndSection() const { return IsEndSection; }
0685
0686 void setIsBeginSection(bool V = true) { IsBeginSection = V; }
0687
0688 void setIsEndSection(bool V = true) { IsEndSection = V; }
0689
0690 std::optional<UniqueBBID> getBBID() const { return BBID; }
0691
0692
0693 MBBSectionID getSectionID() const { return SectionID; }
0694
0695
0696 void setBBID(const UniqueBBID &V) {
0697 assert(!BBID.has_value() && "Cannot change BBID.");
0698 BBID = V;
0699 }
0700
0701
0702 void setSectionID(MBBSectionID V) { SectionID = V; }
0703
0704
0705 MCSymbol *getEndSymbol() const;
0706
0707
0708
0709
0710 bool mayHaveInlineAsmBr() const;
0711
0712
0713 bool isInlineAsmBrIndirectTarget() const {
0714 return IsInlineAsmBrIndirectTarget;
0715 }
0716
0717
0718 void setIsInlineAsmBrIndirectTarget(bool V = true) {
0719 IsInlineAsmBrIndirectTarget = V;
0720 }
0721
0722
0723 bool isLegalToHoistInto() const;
0724
0725
0726
0727
0728
0729
0730 void moveBefore(MachineBasicBlock *NewAfter);
0731 void moveAfter(MachineBasicBlock *NewBefore);
0732
0733
0734 bool sameSection(const MachineBasicBlock *MBB) const {
0735 return getSectionID() == MBB->getSectionID();
0736 }
0737
0738
0739
0740
0741
0742
0743
0744 void updateTerminator(MachineBasicBlock *PreviousLayoutSuccessor);
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756 void addSuccessor(MachineBasicBlock *Succ,
0757 BranchProbability Prob = BranchProbability::getUnknown());
0758
0759
0760
0761
0762
0763 void addSuccessorWithoutProb(MachineBasicBlock *Succ);
0764
0765
0766 void setSuccProbability(succ_iterator I, BranchProbability Prob);
0767
0768
0769
0770
0771
0772
0773 void normalizeSuccProbs() {
0774 BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
0775 }
0776
0777
0778
0779 void validateSuccProbs() const;
0780
0781
0782
0783
0784
0785 void removeSuccessor(MachineBasicBlock *Succ,
0786 bool NormalizeSuccProbs = false);
0787
0788
0789
0790
0791
0792
0793 succ_iterator removeSuccessor(succ_iterator I,
0794 bool NormalizeSuccProbs = false);
0795
0796
0797 void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New);
0798
0799
0800
0801
0802
0803
0804 void copySuccessor(const MachineBasicBlock *Orig, succ_iterator I);
0805
0806
0807
0808 void splitSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New,
0809 bool NormalizeSuccProbs = false);
0810
0811
0812
0813
0814 void transferSuccessors(MachineBasicBlock *FromMBB);
0815
0816
0817
0818 void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB);
0819
0820
0821 bool hasSuccessorProbabilities() const { return !Probs.empty(); }
0822
0823
0824 bool isPredecessor(const MachineBasicBlock *MBB) const;
0825
0826
0827 bool isSuccessor(const MachineBasicBlock *MBB) const;
0828
0829
0830
0831
0832
0833
0834 bool isLayoutSuccessor(const MachineBasicBlock *MBB) const;
0835
0836
0837
0838
0839 const MachineBasicBlock *getSingleSuccessor() const;
0840 MachineBasicBlock *getSingleSuccessor() {
0841 return const_cast<MachineBasicBlock *>(
0842 static_cast<const MachineBasicBlock *>(this)->getSingleSuccessor());
0843 }
0844
0845
0846
0847
0848 const MachineBasicBlock *getSinglePredecessor() const;
0849 MachineBasicBlock *getSinglePredecessor() {
0850 return const_cast<MachineBasicBlock *>(
0851 static_cast<const MachineBasicBlock *>(this)->getSinglePredecessor());
0852 }
0853
0854
0855
0856
0857
0858
0859 MachineBasicBlock *getFallThrough(bool JumpToFallThrough = true);
0860
0861
0862
0863
0864 MachineBasicBlock *getLogicalFallThrough() { return getFallThrough(false); }
0865
0866
0867
0868
0869
0870
0871 bool canFallThrough();
0872
0873
0874
0875
0876
0877
0878 iterator getFirstNonPHI();
0879 const_iterator getFirstNonPHI() const {
0880 return const_cast<MachineBasicBlock *>(this)->getFirstNonPHI();
0881 }
0882
0883
0884
0885
0886 iterator SkipPHIsAndLabels(iterator I);
0887
0888
0889
0890
0891
0892 iterator SkipPHIsLabelsAndDebug(iterator I, Register Reg = Register(),
0893 bool SkipPseudoOp = true);
0894
0895
0896
0897 iterator getFirstTerminator();
0898 const_iterator getFirstTerminator() const {
0899 return const_cast<MachineBasicBlock *>(this)->getFirstTerminator();
0900 }
0901
0902
0903
0904 instr_iterator getFirstInstrTerminator();
0905
0906
0907
0908
0909 iterator getFirstTerminatorForward();
0910
0911
0912
0913
0914
0915
0916
0917
0918
0919
0920
0921
0922
0923
0924
0925
0926
0927 iterator getFirstNonDebugInstr(bool SkipPseudoOp = true);
0928 const_iterator getFirstNonDebugInstr(bool SkipPseudoOp = true) const {
0929 return const_cast<MachineBasicBlock *>(this)->getFirstNonDebugInstr(
0930 SkipPseudoOp);
0931 }
0932
0933
0934
0935
0936
0937
0938
0939
0940
0941
0942
0943
0944
0945
0946
0947
0948
0949 iterator getLastNonDebugInstr(bool SkipPseudoOp = true);
0950 const_iterator getLastNonDebugInstr(bool SkipPseudoOp = true) const {
0951 return const_cast<MachineBasicBlock *>(this)->getLastNonDebugInstr(
0952 SkipPseudoOp);
0953 }
0954
0955
0956
0957 bool isReturnBlock() const {
0958 return !empty() && back().isReturn();
0959 }
0960
0961
0962
0963 bool isEHScopeReturnBlock() const {
0964 return !empty() && back().isEHScopeReturn();
0965 }
0966
0967
0968
0969
0970
0971
0972
0973
0974
0975 MachineBasicBlock *splitAt(MachineInstr &SplitInst, bool UpdateLiveIns = true,
0976 LiveIntervals *LIS = nullptr);
0977
0978
0979
0980
0981
0982
0983 MachineBasicBlock *
0984 SplitCriticalEdge(MachineBasicBlock *Succ, Pass &P,
0985 std::vector<SparseBitVector<>> *LiveInSets = nullptr,
0986 MachineDomTreeUpdater *MDTU = nullptr) {
0987 return SplitCriticalEdge(Succ, &P, nullptr, LiveInSets, MDTU);
0988 }
0989
0990 MachineBasicBlock *
0991 SplitCriticalEdge(MachineBasicBlock *Succ,
0992 MachineFunctionAnalysisManager &MFAM,
0993 std::vector<SparseBitVector<>> *LiveInSets = nullptr,
0994 MachineDomTreeUpdater *MDTU = nullptr) {
0995 return SplitCriticalEdge(Succ, nullptr, &MFAM, LiveInSets, MDTU);
0996 }
0997
0998
0999 MachineBasicBlock *SplitCriticalEdge(
1000 MachineBasicBlock *Succ, Pass *P, MachineFunctionAnalysisManager *MFAM,
1001 std::vector<SparseBitVector<>> *LiveInSets, MachineDomTreeUpdater *MDTU);
1002
1003
1004
1005
1006
1007 bool canSplitCriticalEdge(const MachineBasicBlock *Succ) const;
1008
1009 void pop_front() { Insts.pop_front(); }
1010 void pop_back() { Insts.pop_back(); }
1011 void push_back(MachineInstr *MI) { Insts.push_back(MI); }
1012
1013
1014
1015
1016
1017
1018
1019 instr_iterator insert(instr_iterator I, MachineInstr *M);
1020
1021
1022 template<typename IT>
1023 void insert(iterator I, IT S, IT E) {
1024 assert((I == end() || I->getParent() == this) &&
1025 "iterator points outside of basic block");
1026 Insts.insert(I.getInstrIterator(), S, E);
1027 }
1028
1029
1030 iterator insert(iterator I, MachineInstr *MI) {
1031 assert((I == end() || I->getParent() == this) &&
1032 "iterator points outside of basic block");
1033 assert(!MI->isBundledWithPred() && !MI->isBundledWithSucc() &&
1034 "Cannot insert instruction with bundle flags");
1035 return Insts.insert(I.getInstrIterator(), MI);
1036 }
1037
1038
1039 iterator insertAfter(iterator I, MachineInstr *MI) {
1040 assert((I == end() || I->getParent() == this) &&
1041 "iterator points outside of basic block");
1042 assert(!MI->isBundledWithPred() && !MI->isBundledWithSucc() &&
1043 "Cannot insert instruction with bundle flags");
1044 return Insts.insertAfter(I.getInstrIterator(), MI);
1045 }
1046
1047
1048
1049 instr_iterator insertAfterBundle(instr_iterator I, MachineInstr *MI) {
1050 assert((I == instr_end() || I->getParent() == this) &&
1051 "iterator points outside of basic block");
1052 assert(!MI->isBundledWithPred() && !MI->isBundledWithSucc() &&
1053 "Cannot insert instruction with bundle flags");
1054 while (I->isBundledWithSucc())
1055 ++I;
1056 return Insts.insertAfter(I, MI);
1057 }
1058
1059
1060
1061
1062
1063 instr_iterator erase(instr_iterator I);
1064
1065
1066
1067
1068
1069 instr_iterator erase_instr(MachineInstr *I) {
1070 return erase(instr_iterator(I));
1071 }
1072
1073
1074 iterator erase(iterator I, iterator E) {
1075 return Insts.erase(I.getInstrIterator(), E.getInstrIterator());
1076 }
1077
1078
1079
1080
1081 iterator erase(iterator I) {
1082 return erase(I, std::next(I));
1083 }
1084
1085
1086
1087
1088
1089 iterator erase(MachineInstr *I) {
1090 return erase(iterator(I));
1091 }
1092
1093
1094
1095
1096
1097
1098 MachineInstr *remove(MachineInstr *I) {
1099 assert(!I->isBundled() && "Cannot remove bundled instructions");
1100 return Insts.remove(instr_iterator(I));
1101 }
1102
1103
1104
1105
1106
1107
1108 MachineInstr *remove_instr(MachineInstr *I);
1109
1110 void clear() {
1111 Insts.clear();
1112 }
1113
1114
1115
1116
1117
1118 void splice(iterator Where, MachineBasicBlock *Other, iterator From) {
1119
1120 if (Where != From)
1121 splice(Where, Other, From, std::next(From));
1122 }
1123
1124
1125
1126
1127
1128
1129 void splice(iterator Where, MachineBasicBlock *Other,
1130 iterator From, iterator To) {
1131 Insts.splice(Where.getInstrIterator(), Other->Insts,
1132 From.getInstrIterator(), To.getInstrIterator());
1133 }
1134
1135
1136
1137 MachineBasicBlock *removeFromParent();
1138
1139
1140 void eraseFromParent();
1141
1142
1143
1144 void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New);
1145
1146
1147
1148 void replacePhiUsesWith(MachineBasicBlock *Old, MachineBasicBlock *New);
1149
1150
1151
1152 DebugLoc findDebugLoc(instr_iterator MBBI);
1153 DebugLoc findDebugLoc(iterator MBBI) {
1154 return findDebugLoc(MBBI.getInstrIterator());
1155 }
1156
1157
1158
1159
1160 DebugLoc rfindDebugLoc(reverse_instr_iterator MBBI);
1161 DebugLoc rfindDebugLoc(reverse_iterator MBBI) {
1162 return rfindDebugLoc(MBBI.getInstrIterator());
1163 }
1164
1165
1166
1167
1168 DebugLoc findPrevDebugLoc(instr_iterator MBBI);
1169 DebugLoc findPrevDebugLoc(iterator MBBI) {
1170 return findPrevDebugLoc(MBBI.getInstrIterator());
1171 }
1172
1173
1174
1175
1176
1177 DebugLoc rfindPrevDebugLoc(reverse_instr_iterator MBBI);
1178 DebugLoc rfindPrevDebugLoc(reverse_iterator MBBI) {
1179 return rfindPrevDebugLoc(MBBI.getInstrIterator());
1180 }
1181
1182
1183
1184 DebugLoc findBranchDebugLoc();
1185
1186
1187 enum LivenessQueryResult {
1188 LQR_Live,
1189 LQR_Dead,
1190 LQR_Unknown
1191 };
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201 LivenessQueryResult computeRegisterLiveness(const TargetRegisterInfo *TRI,
1202 MCRegister Reg,
1203 const_iterator Before,
1204 unsigned Neighborhood = 10) const;
1205
1206
1207 void dump() const;
1208 void print(raw_ostream &OS, const SlotIndexes * = nullptr,
1209 bool IsStandalone = true) const;
1210 void print(raw_ostream &OS, ModuleSlotTracker &MST,
1211 const SlotIndexes * = nullptr, bool IsStandalone = true) const;
1212
1213 enum PrintNameFlag {
1214 PrintNameIr = (1 << 0),
1215 PrintNameAttributes = (1 << 1),
1216 };
1217
1218 void printName(raw_ostream &os, unsigned printNameFlags = PrintNameIr,
1219 ModuleSlotTracker *moduleSlotTracker = nullptr) const;
1220
1221
1222 void printAsOperand(raw_ostream &OS, bool PrintType = true) const;
1223
1224
1225
1226 int getNumber() const { return Number; }
1227 void setNumber(int N) { Number = N; }
1228
1229
1230 unsigned getCallFrameSize() const { return CallFrameSize; }
1231
1232 void setCallFrameSize(unsigned N) { CallFrameSize = N; }
1233
1234
1235 MCSymbol *getSymbol() const;
1236
1237
1238 MCSymbol *getEHCatchretSymbol() const;
1239
1240 std::optional<uint64_t> getIrrLoopHeaderWeight() const {
1241 return IrrLoopHeaderWeight;
1242 }
1243
1244 void setIrrLoopHeaderWeight(uint64_t Weight) {
1245 IrrLoopHeaderWeight = Weight;
1246 }
1247
1248
1249
1250
1251 BranchProbability getSuccProbability(const_succ_iterator Succ) const;
1252
1253 private:
1254
1255 probability_iterator getProbabilityIterator(succ_iterator I);
1256 const_probability_iterator
1257 getProbabilityIterator(const_succ_iterator I) const;
1258
1259 friend class MachineBranchProbabilityInfo;
1260 friend class MIPrinter;
1261
1262
1263 friend struct ilist_callback_traits<MachineBasicBlock>;
1264
1265
1266
1267
1268
1269
1270 void addPredecessor(MachineBasicBlock *Pred);
1271
1272
1273
1274
1275 void removePredecessor(MachineBasicBlock *Pred);
1276 };
1277
1278 raw_ostream& operator<<(raw_ostream &OS, const MachineBasicBlock &MBB);
1279
1280
1281
1282
1283
1284
1285
1286 Printable printMBBReference(const MachineBasicBlock &MBB);
1287
1288
1289 struct MBB2NumberFunctor {
1290 using argument_type = const MachineBasicBlock *;
1291 unsigned operator()(const MachineBasicBlock *MBB) const {
1292 return MBB->getNumber();
1293 }
1294 };
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304 template <> struct GraphTraits<MachineBasicBlock *> {
1305 using NodeRef = MachineBasicBlock *;
1306 using ChildIteratorType = MachineBasicBlock::succ_iterator;
1307
1308 static NodeRef getEntryNode(MachineBasicBlock *BB) { return BB; }
1309 static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
1310 static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
1311
1312 static unsigned getNumber(MachineBasicBlock *BB) {
1313 assert(BB->getNumber() >= 0 && "negative block number");
1314 return BB->getNumber();
1315 }
1316 };
1317
1318 static_assert(GraphHasNodeNumbers<MachineBasicBlock *>,
1319 "GraphTraits getNumber() not detected");
1320
1321 template <> struct GraphTraits<const MachineBasicBlock *> {
1322 using NodeRef = const MachineBasicBlock *;
1323 using ChildIteratorType = MachineBasicBlock::const_succ_iterator;
1324
1325 static NodeRef getEntryNode(const MachineBasicBlock *BB) { return BB; }
1326 static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
1327 static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
1328
1329 static unsigned getNumber(const MachineBasicBlock *BB) {
1330 assert(BB->getNumber() >= 0 && "negative block number");
1331 return BB->getNumber();
1332 }
1333 };
1334
1335 static_assert(GraphHasNodeNumbers<const MachineBasicBlock *>,
1336 "GraphTraits getNumber() not detected");
1337
1338
1339
1340
1341
1342
1343
1344 template <> struct GraphTraits<Inverse<MachineBasicBlock*>> {
1345 using NodeRef = MachineBasicBlock *;
1346 using ChildIteratorType = MachineBasicBlock::pred_iterator;
1347
1348 static NodeRef getEntryNode(Inverse<MachineBasicBlock *> G) {
1349 return G.Graph;
1350 }
1351
1352 static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
1353 static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
1354
1355 static unsigned getNumber(MachineBasicBlock *BB) {
1356 assert(BB->getNumber() >= 0 && "negative block number");
1357 return BB->getNumber();
1358 }
1359 };
1360
1361 static_assert(GraphHasNodeNumbers<Inverse<MachineBasicBlock *>>,
1362 "GraphTraits getNumber() not detected");
1363
1364 template <> struct GraphTraits<Inverse<const MachineBasicBlock*>> {
1365 using NodeRef = const MachineBasicBlock *;
1366 using ChildIteratorType = MachineBasicBlock::const_pred_iterator;
1367
1368 static NodeRef getEntryNode(Inverse<const MachineBasicBlock *> G) {
1369 return G.Graph;
1370 }
1371
1372 static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
1373 static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
1374
1375 static unsigned getNumber(const MachineBasicBlock *BB) {
1376 assert(BB->getNumber() >= 0 && "negative block number");
1377 return BB->getNumber();
1378 }
1379 };
1380
1381 static_assert(GraphHasNodeNumbers<Inverse<const MachineBasicBlock *>>,
1382 "GraphTraits getNumber() not detected");
1383
1384
1385 inline auto successors(const MachineBasicBlock *BB) { return BB->successors(); }
1386 inline auto predecessors(const MachineBasicBlock *BB) {
1387 return BB->predecessors();
1388 }
1389 inline auto succ_size(const MachineBasicBlock *BB) { return BB->succ_size(); }
1390 inline auto pred_size(const MachineBasicBlock *BB) { return BB->pred_size(); }
1391 inline auto succ_begin(const MachineBasicBlock *BB) { return BB->succ_begin(); }
1392 inline auto pred_begin(const MachineBasicBlock *BB) { return BB->pred_begin(); }
1393 inline auto succ_end(const MachineBasicBlock *BB) { return BB->succ_end(); }
1394 inline auto pred_end(const MachineBasicBlock *BB) { return BB->pred_end(); }
1395
1396
1397
1398
1399
1400 class MachineInstrSpan {
1401 MachineBasicBlock &MBB;
1402 MachineBasicBlock::iterator I, B, E;
1403
1404 public:
1405 MachineInstrSpan(MachineBasicBlock::iterator I, MachineBasicBlock *BB)
1406 : MBB(*BB), I(I), B(I == MBB.begin() ? MBB.end() : std::prev(I)),
1407 E(std::next(I)) {
1408 assert(I == BB->end() || I->getParent() == BB);
1409 }
1410
1411 MachineBasicBlock::iterator begin() {
1412 return B == MBB.end() ? MBB.begin() : std::next(B);
1413 }
1414 MachineBasicBlock::iterator end() { return E; }
1415 bool empty() { return begin() == end(); }
1416
1417 MachineBasicBlock::iterator getInitial() { return I; }
1418 };
1419
1420
1421
1422
1423
1424 template <typename IterT>
1425 inline IterT skipDebugInstructionsForward(IterT It, IterT End,
1426 bool SkipPseudoOp = true) {
1427 while (It != End &&
1428 (It->isDebugInstr() || (SkipPseudoOp && It->isPseudoProbe())))
1429 ++It;
1430 return It;
1431 }
1432
1433
1434
1435
1436
1437 template <class IterT>
1438 inline IterT skipDebugInstructionsBackward(IterT It, IterT Begin,
1439 bool SkipPseudoOp = true) {
1440 while (It != Begin &&
1441 (It->isDebugInstr() || (SkipPseudoOp && It->isPseudoProbe())))
1442 --It;
1443 return It;
1444 }
1445
1446
1447
1448 template <typename IterT>
1449 inline IterT next_nodbg(IterT It, IterT End, bool SkipPseudoOp = true) {
1450 return skipDebugInstructionsForward(std::next(It), End, SkipPseudoOp);
1451 }
1452
1453
1454
1455 template <typename IterT>
1456 inline IterT prev_nodbg(IterT It, IterT Begin, bool SkipPseudoOp = true) {
1457 return skipDebugInstructionsBackward(std::prev(It), Begin, SkipPseudoOp);
1458 }
1459
1460
1461
1462 template <typename IterT>
1463 inline auto instructionsWithoutDebug(IterT It, IterT End,
1464 bool SkipPseudoOp = true) {
1465 return make_filter_range(make_range(It, End), [=](const MachineInstr &MI) {
1466 return !MI.isDebugInstr() && !(SkipPseudoOp && MI.isPseudoProbe());
1467 });
1468 }
1469
1470 }
1471
1472 #endif