File indexing completed on 2026-05-10 08:43:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef LLVM_CODEGEN_MACHINEFUNCTION_H
0018 #define LLVM_CODEGEN_MACHINEFUNCTION_H
0019
0020 #include "llvm/ADT/ArrayRef.h"
0021 #include "llvm/ADT/DenseMap.h"
0022 #include "llvm/ADT/GraphTraits.h"
0023 #include "llvm/ADT/SmallVector.h"
0024 #include "llvm/ADT/ilist.h"
0025 #include "llvm/ADT/iterator.h"
0026 #include "llvm/CodeGen/MachineBasicBlock.h"
0027 #include "llvm/CodeGen/MachineInstr.h"
0028 #include "llvm/CodeGen/MachineMemOperand.h"
0029 #include "llvm/IR/EHPersonalities.h"
0030 #include "llvm/Support/Allocator.h"
0031 #include "llvm/Support/ArrayRecycler.h"
0032 #include "llvm/Support/AtomicOrdering.h"
0033 #include "llvm/Support/Compiler.h"
0034 #include "llvm/Support/Recycler.h"
0035 #include "llvm/Target/TargetOptions.h"
0036 #include <bitset>
0037 #include <cassert>
0038 #include <cstdint>
0039 #include <memory>
0040 #include <utility>
0041 #include <variant>
0042 #include <vector>
0043
0044 namespace llvm {
0045
0046 class BasicBlock;
0047 class BlockAddress;
0048 class DataLayout;
0049 class DebugLoc;
0050 struct DenormalMode;
0051 class DIExpression;
0052 class DILocalVariable;
0053 class DILocation;
0054 class Function;
0055 class GISelChangeObserver;
0056 class GlobalValue;
0057 class TargetMachine;
0058 class MachineConstantPool;
0059 class MachineFrameInfo;
0060 class MachineFunction;
0061 class MachineJumpTableInfo;
0062 class MachineRegisterInfo;
0063 class MCContext;
0064 class MCInstrDesc;
0065 class MCSymbol;
0066 class MCSection;
0067 class Pass;
0068 class PseudoSourceValueManager;
0069 class raw_ostream;
0070 class SlotIndexes;
0071 class StringRef;
0072 class TargetRegisterClass;
0073 class TargetSubtargetInfo;
0074 struct WasmEHFuncInfo;
0075 struct WinEHFuncInfo;
0076
0077 template <> struct ilist_alloc_traits<MachineBasicBlock> {
0078 void deleteNode(MachineBasicBlock *MBB);
0079 };
0080
0081 template <> struct ilist_callback_traits<MachineBasicBlock> {
0082 void addNodeToList(MachineBasicBlock* N);
0083 void removeNodeFromList(MachineBasicBlock* N);
0084
0085 template <class Iterator>
0086 void transferNodesFromList(ilist_callback_traits &OldList, Iterator, Iterator) {
0087 assert(this == &OldList && "never transfer MBBs between functions");
0088 }
0089 };
0090
0091
0092
0093
0094 enum class MachineFunctionDataHotness {
0095 Unknown,
0096 Cold,
0097 Hot,
0098 };
0099
0100
0101
0102
0103
0104 struct MachineFunctionInfo {
0105 virtual ~MachineFunctionInfo();
0106
0107
0108
0109
0110
0111 template <typename FuncInfoTy, typename SubtargetTy = TargetSubtargetInfo>
0112 static FuncInfoTy *create(BumpPtrAllocator &Allocator, const Function &F,
0113 const SubtargetTy *STI) {
0114 return new (Allocator.Allocate<FuncInfoTy>()) FuncInfoTy(F, STI);
0115 }
0116
0117 template <typename Ty>
0118 static Ty *create(BumpPtrAllocator &Allocator, const Ty &MFI) {
0119 return new (Allocator.Allocate<Ty>()) Ty(MFI);
0120 }
0121
0122
0123
0124
0125
0126 virtual MachineFunctionInfo *
0127 clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
0128 const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)
0129 const {
0130 return nullptr;
0131 }
0132 };
0133
0134
0135
0136
0137 class MachineFunctionProperties {
0138
0139
0140
0141
0142
0143 public:
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187 enum class Property : unsigned {
0188 IsSSA,
0189 NoPHIs,
0190 TracksLiveness,
0191 NoVRegs,
0192 FailedISel,
0193 Legalized,
0194 RegBankSelected,
0195 Selected,
0196 TiedOpsRewritten,
0197 FailsVerification,
0198 FailedRegAlloc,
0199 TracksDebugUserValues,
0200 LastProperty = TracksDebugUserValues,
0201 };
0202
0203 bool hasProperty(Property P) const {
0204 return Properties[static_cast<unsigned>(P)];
0205 }
0206
0207 MachineFunctionProperties &set(Property P) {
0208 Properties.set(static_cast<unsigned>(P));
0209 return *this;
0210 }
0211
0212 MachineFunctionProperties &reset(Property P) {
0213 Properties.reset(static_cast<unsigned>(P));
0214 return *this;
0215 }
0216
0217
0218 MachineFunctionProperties &reset() {
0219 Properties.reset();
0220 return *this;
0221 }
0222
0223 MachineFunctionProperties &set(const MachineFunctionProperties &MFP) {
0224 Properties |= MFP.Properties;
0225 return *this;
0226 }
0227
0228 MachineFunctionProperties &reset(const MachineFunctionProperties &MFP) {
0229 Properties &= ~MFP.Properties;
0230 return *this;
0231 }
0232
0233
0234
0235 bool verifyRequiredProperties(const MachineFunctionProperties &V) const {
0236 return (Properties | ~V.Properties).all();
0237 }
0238
0239
0240 void print(raw_ostream &OS) const;
0241
0242 private:
0243 std::bitset<static_cast<unsigned>(Property::LastProperty) + 1> Properties;
0244 };
0245
0246 struct SEHHandler {
0247
0248 const Function *FilterOrFinally;
0249
0250
0251 const BlockAddress *RecoverBA;
0252 };
0253
0254
0255 struct LandingPadInfo {
0256 MachineBasicBlock *LandingPadBlock;
0257 SmallVector<MCSymbol *, 1> BeginLabels;
0258 SmallVector<MCSymbol *, 1> EndLabels;
0259 SmallVector<SEHHandler, 1> SEHHandlers;
0260 MCSymbol *LandingPadLabel = nullptr;
0261 std::vector<int> TypeIds;
0262
0263 explicit LandingPadInfo(MachineBasicBlock *MBB)
0264 : LandingPadBlock(MBB) {}
0265 };
0266
0267 class LLVM_ABI MachineFunction {
0268 Function &F;
0269 const TargetMachine &Target;
0270 const TargetSubtargetInfo *STI;
0271 MCContext &Ctx;
0272
0273
0274 MachineRegisterInfo *RegInfo;
0275
0276
0277
0278 MachineFunctionInfo *MFInfo;
0279
0280
0281 MachineFrameInfo *FrameInfo;
0282
0283
0284 MachineConstantPool *ConstantPool;
0285
0286
0287 MachineJumpTableInfo *JumpTableInfo;
0288
0289
0290 MCSection *Section = nullptr;
0291
0292
0293
0294
0295 WasmEHFuncInfo *WasmEHInfo = nullptr;
0296
0297
0298
0299 WinEHFuncInfo *WinEHInfo = nullptr;
0300
0301
0302
0303
0304 std::vector<MachineBasicBlock*> MBBNumbering;
0305
0306
0307
0308 unsigned MBBNumberingEpoch = 0;
0309
0310
0311 BumpPtrAllocator Allocator;
0312
0313
0314 Recycler<MachineInstr> InstructionRecycler;
0315
0316
0317 ArrayRecycler<MachineOperand> OperandRecycler;
0318
0319
0320 Recycler<MachineBasicBlock> BasicBlockRecycler;
0321
0322
0323 using BasicBlockListType = ilist<MachineBasicBlock>;
0324 BasicBlockListType BasicBlocks;
0325
0326
0327
0328
0329 unsigned FunctionNumber;
0330
0331
0332 Align Alignment;
0333
0334
0335
0336
0337
0338
0339 bool ExposesReturnsTwice = false;
0340
0341
0342 bool HasInlineAsm = false;
0343
0344
0345 bool HasWinCFI = false;
0346
0347
0348
0349 MachineFunctionProperties Properties;
0350
0351
0352 std::unique_ptr<PseudoSourceValueManager> PSVManager;
0353
0354
0355
0356 std::vector<MCCFIInstruction> FrameInstructions;
0357
0358
0359
0360 std::vector<MCSymbol *> LongjmpTargets;
0361
0362
0363
0364 std::vector<MCSymbol *> CatchretTargets;
0365
0366
0367
0368
0369
0370 std::vector<LandingPadInfo> LandingPads;
0371
0372
0373 DenseMap<MCSymbol*, SmallVector<unsigned, 4>> LPadToCallSiteMap;
0374
0375
0376 DenseMap<const MachineBasicBlock *, unsigned> WasmLPadToIndexMap;
0377
0378
0379 DenseMap<MCSymbol*, unsigned> CallSiteMap;
0380
0381
0382 std::vector<std::pair<MCSymbol *, MDNode *>> CodeViewAnnotations;
0383
0384 bool CallsEHReturn = false;
0385 bool CallsUnwindInit = false;
0386 bool HasEHCatchret = false;
0387 bool HasEHScopes = false;
0388 bool HasEHFunclets = false;
0389 bool HasFakeUses = false;
0390 bool IsOutlined = false;
0391
0392
0393 unsigned NextBBID = 0;
0394
0395
0396 BasicBlockSection BBSectionsType = BasicBlockSection::None;
0397
0398
0399 std::vector<const GlobalValue *> TypeInfos;
0400
0401
0402 std::vector<unsigned> FilterIds;
0403
0404
0405 std::vector<unsigned> FilterEnds;
0406
0407 EHPersonality PersonalityTypeCache = EHPersonality::Unknown;
0408
0409
0410
0411
0412
0413
0414
0415
0416 void clear();
0417
0418
0419
0420 void init();
0421
0422 public:
0423
0424
0425
0426
0427 class VariableDbgInfo {
0428 std::variant<int, MCRegister> Address;
0429
0430 public:
0431 const DILocalVariable *Var;
0432 const DIExpression *Expr;
0433 const DILocation *Loc;
0434
0435 VariableDbgInfo(const DILocalVariable *Var, const DIExpression *Expr,
0436 int Slot, const DILocation *Loc)
0437 : Address(Slot), Var(Var), Expr(Expr), Loc(Loc) {}
0438
0439 VariableDbgInfo(const DILocalVariable *Var, const DIExpression *Expr,
0440 MCRegister EntryValReg, const DILocation *Loc)
0441 : Address(EntryValReg), Var(Var), Expr(Expr), Loc(Loc) {}
0442
0443
0444 bool inStackSlot() const { return std::holds_alternative<int>(Address); }
0445
0446
0447 bool inEntryValueRegister() const {
0448 return std::holds_alternative<MCRegister>(Address);
0449 }
0450
0451
0452
0453 int getStackSlot() const { return std::get<int>(Address); }
0454
0455
0456
0457 MCRegister getEntryValueRegister() const {
0458 return std::get<MCRegister>(Address);
0459 }
0460
0461
0462
0463 void updateStackSlot(int NewSlot) {
0464 assert(inStackSlot());
0465 Address = NewSlot;
0466 }
0467 };
0468
0469 class Delegate {
0470 virtual void anchor();
0471
0472 public:
0473 virtual ~Delegate() = default;
0474
0475 virtual void MF_HandleInsertion(MachineInstr &MI) = 0;
0476
0477 virtual void MF_HandleRemoval(MachineInstr &MI) = 0;
0478
0479
0480 virtual void MF_HandleChangeDesc(MachineInstr &MI, const MCInstrDesc &TID) {
0481 }
0482 };
0483
0484
0485
0486
0487
0488 struct ArgRegPair {
0489 Register Reg;
0490 uint16_t ArgNo;
0491 ArgRegPair(Register R, unsigned Arg) : Reg(R), ArgNo(Arg) {
0492 assert(Arg < (1 << 16) && "Arg out of range");
0493 }
0494 };
0495
0496 struct CallSiteInfo {
0497
0498 SmallVector<ArgRegPair, 1> ArgRegPairs;
0499 };
0500
0501 struct CalledGlobalInfo {
0502 const GlobalValue *Callee;
0503 unsigned TargetFlags;
0504 };
0505
0506 private:
0507 Delegate *TheDelegate = nullptr;
0508 GISelChangeObserver *Observer = nullptr;
0509
0510 using CallSiteInfoMap = DenseMap<const MachineInstr *, CallSiteInfo>;
0511
0512 CallSiteInfoMap CallSitesInfo;
0513
0514
0515
0516 CallSiteInfoMap::iterator getCallSiteInfo(const MachineInstr *MI);
0517
0518 using CalledGlobalsMap = DenseMap<const MachineInstr *, CalledGlobalInfo>;
0519
0520
0521 CalledGlobalsMap CalledGlobalsInfo;
0522
0523
0524 void handleInsertion(MachineInstr &MI);
0525 void handleRemoval(MachineInstr &MI);
0526 friend struct ilist_traits<MachineInstr>;
0527
0528 public:
0529
0530 void handleChangeDesc(MachineInstr &MI, const MCInstrDesc &TID);
0531
0532 using VariableDbgInfoMapTy = SmallVector<VariableDbgInfo, 4>;
0533 VariableDbgInfoMapTy VariableDbgInfos;
0534
0535
0536
0537
0538 unsigned DebugInstrNumberingCount = 0;
0539
0540
0541
0542 void setDebugInstrNumberingCount(unsigned Num);
0543
0544
0545 using DebugInstrOperandPair = std::pair<unsigned, unsigned>;
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556 class DebugSubstitution {
0557 public:
0558 DebugInstrOperandPair Src;
0559 DebugInstrOperandPair Dest;
0560 unsigned Subreg;
0561
0562 DebugSubstitution(const DebugInstrOperandPair &Src,
0563 const DebugInstrOperandPair &Dest, unsigned Subreg)
0564 : Src(Src), Dest(Dest), Subreg(Subreg) {}
0565
0566
0567
0568 bool operator<(const DebugSubstitution &Other) const {
0569 return Src < Other.Src;
0570 }
0571 };
0572
0573
0574
0575
0576
0577 SmallVector<DebugSubstitution, 8> DebugValueSubstitutions;
0578
0579
0580
0581
0582
0583
0584 class DebugPHIRegallocPos {
0585 public:
0586 MachineBasicBlock *MBB;
0587 Register Reg;
0588 unsigned SubReg;
0589 DebugPHIRegallocPos(MachineBasicBlock *MBB, Register Reg, unsigned SubReg)
0590 : MBB(MBB), Reg(Reg), SubReg(SubReg) {}
0591 };
0592
0593
0594
0595 DenseMap<unsigned, DebugPHIRegallocPos> DebugPHIPositions;
0596
0597
0598
0599 bool UseDebugInstrRef = false;
0600
0601
0602
0603 void makeDebugValueSubstitution(DebugInstrOperandPair, DebugInstrOperandPair,
0604 unsigned SubReg = 0);
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614 void substituteDebugValuesForInst(const MachineInstr &Old, MachineInstr &New,
0615 unsigned MaxOperand = UINT_MAX);
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628 DebugInstrOperandPair
0629 salvageCopySSA(MachineInstr &MI,
0630 DenseMap<Register, DebugInstrOperandPair> &DbgPHICache);
0631
0632 DebugInstrOperandPair salvageCopySSAImpl(MachineInstr &MI);
0633
0634
0635
0636
0637
0638
0639 void finalizeDebugInstrRefs();
0640
0641
0642
0643 bool shouldUseDebugInstrRef() const;
0644
0645
0646
0647 bool useDebugInstrRef() const;
0648
0649
0650 void setUseDebugInstrRef(bool UseInstrRef);
0651
0652
0653
0654 const static unsigned int DebugOperandMemNumber;
0655
0656 MachineFunction(Function &F, const TargetMachine &Target,
0657 const TargetSubtargetInfo &STI, MCContext &Ctx,
0658 unsigned FunctionNum);
0659 MachineFunction(const MachineFunction &) = delete;
0660 MachineFunction &operator=(const MachineFunction &) = delete;
0661 ~MachineFunction();
0662
0663
0664 void reset() {
0665 clear();
0666 init();
0667 }
0668
0669
0670 void resetDelegate(Delegate *delegate) {
0671 assert(TheDelegate == delegate &&
0672 "Only the current delegate can perform reset!");
0673 TheDelegate = nullptr;
0674 }
0675
0676
0677
0678 void setDelegate(Delegate *delegate) {
0679 assert(delegate && !TheDelegate &&
0680 "Attempted to set delegate to null, or to change it without "
0681 "first resetting it!");
0682
0683 TheDelegate = delegate;
0684 }
0685
0686 void setObserver(GISelChangeObserver *O) { Observer = O; }
0687
0688 GISelChangeObserver *getObserver() const { return Observer; }
0689
0690 MCContext &getContext() const { return Ctx; }
0691
0692
0693 MCSection *getSection() const { return Section; }
0694
0695
0696 void setSection(MCSection *S) { Section = S; }
0697
0698 PseudoSourceValueManager &getPSVManager() const { return *PSVManager; }
0699
0700
0701 const DataLayout &getDataLayout() const;
0702
0703
0704 Function &getFunction() { return F; }
0705
0706
0707 const Function &getFunction() const { return F; }
0708
0709
0710 StringRef getName() const;
0711
0712
0713 unsigned getFunctionNumber() const { return FunctionNumber; }
0714
0715
0716 bool hasBBSections() const {
0717 return (BBSectionsType == BasicBlockSection::All ||
0718 BBSectionsType == BasicBlockSection::List ||
0719 BBSectionsType == BasicBlockSection::Preset);
0720 }
0721
0722 void setBBSectionsType(BasicBlockSection V) { BBSectionsType = V; }
0723
0724
0725
0726 void assignBeginEndSections();
0727
0728
0729 const TargetMachine &getTarget() const { return Target; }
0730
0731
0732
0733 const TargetSubtargetInfo &getSubtarget() const { return *STI; }
0734
0735
0736
0737
0738 template<typename STC> const STC &getSubtarget() const {
0739 return *static_cast<const STC *>(STI);
0740 }
0741
0742
0743 MachineRegisterInfo &getRegInfo() { return *RegInfo; }
0744 const MachineRegisterInfo &getRegInfo() const { return *RegInfo; }
0745
0746
0747
0748
0749 MachineFrameInfo &getFrameInfo() { return *FrameInfo; }
0750 const MachineFrameInfo &getFrameInfo() const { return *FrameInfo; }
0751
0752
0753
0754
0755
0756 const MachineJumpTableInfo *getJumpTableInfo() const { return JumpTableInfo; }
0757 MachineJumpTableInfo *getJumpTableInfo() { return JumpTableInfo; }
0758
0759
0760
0761 MachineJumpTableInfo *getOrCreateJumpTableInfo(unsigned JTEntryKind);
0762
0763
0764
0765 MachineConstantPool *getConstantPool() { return ConstantPool; }
0766 const MachineConstantPool *getConstantPool() const { return ConstantPool; }
0767
0768
0769
0770
0771 const WasmEHFuncInfo *getWasmEHFuncInfo() const { return WasmEHInfo; }
0772 WasmEHFuncInfo *getWasmEHFuncInfo() { return WasmEHInfo; }
0773
0774
0775
0776
0777 const WinEHFuncInfo *getWinEHFuncInfo() const { return WinEHInfo; }
0778 WinEHFuncInfo *getWinEHFuncInfo() { return WinEHInfo; }
0779
0780
0781 Align getAlignment() const { return Alignment; }
0782
0783
0784 void setAlignment(Align A) { Alignment = A; }
0785
0786
0787 void ensureAlignment(Align A) {
0788 if (Alignment < A)
0789 Alignment = A;
0790 }
0791
0792
0793
0794
0795 bool exposesReturnsTwice() const {
0796 return ExposesReturnsTwice;
0797 }
0798
0799
0800
0801 void setExposesReturnsTwice(bool B) {
0802 ExposesReturnsTwice = B;
0803 }
0804
0805
0806 bool hasInlineAsm() const {
0807 return HasInlineAsm;
0808 }
0809
0810
0811 void setHasInlineAsm(bool B) {
0812 HasInlineAsm = B;
0813 }
0814
0815 bool hasWinCFI() const {
0816 return HasWinCFI;
0817 }
0818 void setHasWinCFI(bool v) { HasWinCFI = v; }
0819
0820
0821 bool needsFrameMoves() const;
0822
0823
0824 const MachineFunctionProperties &getProperties() const { return Properties; }
0825 MachineFunctionProperties &getProperties() { return Properties; }
0826
0827
0828
0829
0830 template<typename Ty>
0831 Ty *getInfo() {
0832 return static_cast<Ty*>(MFInfo);
0833 }
0834
0835 template<typename Ty>
0836 const Ty *getInfo() const {
0837 return static_cast<const Ty *>(MFInfo);
0838 }
0839
0840 template <typename Ty> Ty *cloneInfo(const Ty &Old) {
0841 assert(!MFInfo);
0842 MFInfo = Ty::template create<Ty>(Allocator, Old);
0843 return static_cast<Ty *>(MFInfo);
0844 }
0845
0846
0847 void initTargetMachineFunctionInfo(const TargetSubtargetInfo &STI);
0848
0849 MachineFunctionInfo *cloneInfoFrom(
0850 const MachineFunction &OrigMF,
0851 const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB) {
0852 assert(!MFInfo && "new function already has MachineFunctionInfo");
0853 if (!OrigMF.MFInfo)
0854 return nullptr;
0855 return OrigMF.MFInfo->clone(Allocator, *this, Src2DstMBB);
0856 }
0857
0858
0859
0860 DenormalMode getDenormalMode(const fltSemantics &FPType) const;
0861
0862
0863
0864
0865
0866 MachineBasicBlock *getBlockNumbered(unsigned N) const {
0867 assert(N < MBBNumbering.size() && "Illegal block number");
0868 assert(MBBNumbering[N] && "Block was removed from the machine function!");
0869 return MBBNumbering[N];
0870 }
0871
0872
0873 bool shouldSplitStack() const;
0874
0875
0876 unsigned getNumBlockIDs() const { return (unsigned)MBBNumbering.size(); }
0877
0878
0879
0880
0881 unsigned getBlockNumberEpoch() const { return MBBNumberingEpoch; }
0882
0883
0884
0885
0886
0887
0888 void RenumberBlocks(MachineBasicBlock *MBBFrom = nullptr);
0889
0890
0891
0892 int64_t estimateFunctionSizeInBytes();
0893
0894
0895
0896 void print(raw_ostream &OS, const SlotIndexes* = nullptr) const;
0897
0898
0899
0900
0901
0902
0903 void viewCFG() const;
0904
0905
0906
0907
0908
0909
0910 void viewCFGOnly() const;
0911
0912
0913 void dump() const;
0914
0915
0916
0917
0918 bool verify(Pass *p = nullptr, const char *Banner = nullptr,
0919 raw_ostream *OS = nullptr, bool AbortOnError = true) const;
0920
0921
0922
0923
0924 bool verify(LiveIntervals *LiveInts, SlotIndexes *Indexes,
0925 const char *Banner = nullptr, raw_ostream *OS = nullptr,
0926 bool AbortOnError = true) const;
0927
0928
0929 using iterator = BasicBlockListType::iterator;
0930 using const_iterator = BasicBlockListType::const_iterator;
0931 using const_reverse_iterator = BasicBlockListType::const_reverse_iterator;
0932 using reverse_iterator = BasicBlockListType::reverse_iterator;
0933
0934
0935 static BasicBlockListType MachineFunction::*
0936 getSublistAccess(MachineBasicBlock *) {
0937 return &MachineFunction::BasicBlocks;
0938 }
0939
0940
0941
0942 Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC);
0943
0944
0945
0946
0947 iterator begin() { return BasicBlocks.begin(); }
0948 const_iterator begin() const { return BasicBlocks.begin(); }
0949 iterator end () { return BasicBlocks.end(); }
0950 const_iterator end () const { return BasicBlocks.end(); }
0951
0952 reverse_iterator rbegin() { return BasicBlocks.rbegin(); }
0953 const_reverse_iterator rbegin() const { return BasicBlocks.rbegin(); }
0954 reverse_iterator rend () { return BasicBlocks.rend(); }
0955 const_reverse_iterator rend () const { return BasicBlocks.rend(); }
0956
0957 unsigned size() const { return (unsigned)BasicBlocks.size();}
0958 bool empty() const { return BasicBlocks.empty(); }
0959 const MachineBasicBlock &front() const { return BasicBlocks.front(); }
0960 MachineBasicBlock &front() { return BasicBlocks.front(); }
0961 const MachineBasicBlock & back() const { return BasicBlocks.back(); }
0962 MachineBasicBlock & back() { return BasicBlocks.back(); }
0963
0964 void push_back (MachineBasicBlock *MBB) { BasicBlocks.push_back (MBB); }
0965 void push_front(MachineBasicBlock *MBB) { BasicBlocks.push_front(MBB); }
0966 void insert(iterator MBBI, MachineBasicBlock *MBB) {
0967 BasicBlocks.insert(MBBI, MBB);
0968 }
0969 void splice(iterator InsertPt, iterator MBBI) {
0970 BasicBlocks.splice(InsertPt, BasicBlocks, MBBI);
0971 }
0972 void splice(iterator InsertPt, MachineBasicBlock *MBB) {
0973 BasicBlocks.splice(InsertPt, BasicBlocks, MBB);
0974 }
0975 void splice(iterator InsertPt, iterator MBBI, iterator MBBE) {
0976 BasicBlocks.splice(InsertPt, BasicBlocks, MBBI, MBBE);
0977 }
0978
0979 void remove(iterator MBBI) { BasicBlocks.remove(MBBI); }
0980 void remove(MachineBasicBlock *MBBI) { BasicBlocks.remove(MBBI); }
0981 void erase(iterator MBBI) { BasicBlocks.erase(MBBI); }
0982 void erase(MachineBasicBlock *MBBI) { BasicBlocks.erase(MBBI); }
0983
0984 template <typename Comp>
0985 void sort(Comp comp) {
0986 BasicBlocks.sort(comp);
0987 }
0988
0989
0990 unsigned getInstructionCount() const {
0991 unsigned InstrCount = 0;
0992 for (const MachineBasicBlock &MBB : BasicBlocks)
0993 InstrCount += MBB.size();
0994 return InstrCount;
0995 }
0996
0997
0998
0999
1000
1001
1002 unsigned addToMBBNumbering(MachineBasicBlock *MBB) {
1003 MBBNumbering.push_back(MBB);
1004 return (unsigned)MBBNumbering.size()-1;
1005 }
1006
1007
1008
1009
1010 void removeFromMBBNumbering(unsigned N) {
1011 assert(N < MBBNumbering.size() && "Illegal basic block #");
1012 MBBNumbering[N] = nullptr;
1013 }
1014
1015
1016
1017 MachineInstr *CreateMachineInstr(const MCInstrDesc &MCID, DebugLoc DL,
1018 bool NoImplicit = false);
1019
1020
1021
1022
1023
1024
1025
1026
1027 MachineInstr *CloneMachineInstr(const MachineInstr *Orig);
1028
1029
1030
1031
1032
1033
1034 MachineInstr &
1035 cloneMachineInstrBundle(MachineBasicBlock &MBB,
1036 MachineBasicBlock::iterator InsertBefore,
1037 const MachineInstr &Orig);
1038
1039
1040 void deleteMachineInstr(MachineInstr *MI);
1041
1042
1043
1044
1045 MachineBasicBlock *
1046 CreateMachineBasicBlock(const BasicBlock *BB = nullptr,
1047 std::optional<UniqueBBID> BBID = std::nullopt);
1048
1049
1050 void deleteMachineBasicBlock(MachineBasicBlock *MBB);
1051
1052
1053
1054
1055 MachineMemOperand *getMachineMemOperand(
1056 MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy,
1057 Align base_alignment, const AAMDNodes &AAInfo = AAMDNodes(),
1058 const MDNode *Ranges = nullptr, SyncScope::ID SSID = SyncScope::System,
1059 AtomicOrdering Ordering = AtomicOrdering::NotAtomic,
1060 AtomicOrdering FailureOrdering = AtomicOrdering::NotAtomic);
1061 MachineMemOperand *getMachineMemOperand(
1062 MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LocationSize Size,
1063 Align BaseAlignment, const AAMDNodes &AAInfo = AAMDNodes(),
1064 const MDNode *Ranges = nullptr, SyncScope::ID SSID = SyncScope::System,
1065 AtomicOrdering Ordering = AtomicOrdering::NotAtomic,
1066 AtomicOrdering FailureOrdering = AtomicOrdering::NotAtomic);
1067 MachineMemOperand *getMachineMemOperand(
1068 MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, uint64_t Size,
1069 Align BaseAlignment, const AAMDNodes &AAInfo = AAMDNodes(),
1070 const MDNode *Ranges = nullptr, SyncScope::ID SSID = SyncScope::System,
1071 AtomicOrdering Ordering = AtomicOrdering::NotAtomic,
1072 AtomicOrdering FailureOrdering = AtomicOrdering::NotAtomic) {
1073 return getMachineMemOperand(PtrInfo, F, LocationSize::precise(Size),
1074 BaseAlignment, AAInfo, Ranges, SSID, Ordering,
1075 FailureOrdering);
1076 }
1077
1078
1079
1080
1081
1082 MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
1083 int64_t Offset, LLT Ty);
1084 MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
1085 int64_t Offset, LocationSize Size) {
1086 return getMachineMemOperand(
1087 MMO, Offset,
1088 !Size.hasValue() ? LLT()
1089 : Size.isScalable()
1090 ? LLT::scalable_vector(1, 8 * Size.getValue().getKnownMinValue())
1091 : LLT::scalar(8 * Size.getValue().getKnownMinValue()));
1092 }
1093 MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
1094 int64_t Offset, uint64_t Size) {
1095 return getMachineMemOperand(MMO, Offset, LocationSize::precise(Size));
1096 }
1097
1098
1099
1100
1101
1102 MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
1103 const MachinePointerInfo &PtrInfo,
1104 LocationSize Size);
1105 MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
1106 const MachinePointerInfo &PtrInfo,
1107 LLT Ty);
1108 MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
1109 const MachinePointerInfo &PtrInfo,
1110 uint64_t Size) {
1111 return getMachineMemOperand(MMO, PtrInfo, LocationSize::precise(Size));
1112 }
1113
1114
1115
1116
1117 MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
1118 const AAMDNodes &AAInfo);
1119
1120
1121
1122
1123 MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
1124 MachineMemOperand::Flags Flags);
1125
1126 using OperandCapacity = ArrayRecycler<MachineOperand>::Capacity;
1127
1128
1129
1130 MachineOperand *allocateOperandArray(OperandCapacity Cap) {
1131 return OperandRecycler.allocate(Cap, Allocator);
1132 }
1133
1134
1135
1136
1137 void deallocateOperandArray(OperandCapacity Cap, MachineOperand *Array) {
1138 OperandRecycler.deallocate(Cap, Array);
1139 }
1140
1141
1142 uint32_t *allocateRegMask();
1143
1144 ArrayRef<int> allocateShuffleMask(ArrayRef<int> Mask);
1145
1146
1147
1148
1149
1150 MachineInstr::ExtraInfo *createMIExtraInfo(
1151 ArrayRef<MachineMemOperand *> MMOs, MCSymbol *PreInstrSymbol = nullptr,
1152 MCSymbol *PostInstrSymbol = nullptr, MDNode *HeapAllocMarker = nullptr,
1153 MDNode *PCSections = nullptr, uint32_t CFIType = 0,
1154 MDNode *MMRAs = nullptr);
1155
1156
1157 const char *createExternalSymbolName(StringRef Name);
1158
1159
1160
1161
1162
1163
1164
1165 MCSymbol *getJTISymbol(unsigned JTI, MCContext &Ctx,
1166 bool isLinkerPrivate = false) const;
1167
1168
1169
1170 MCSymbol *getPICBaseSymbol() const;
1171
1172
1173
1174
1175 const std::vector<MCCFIInstruction> &getFrameInstructions() const {
1176 return FrameInstructions;
1177 }
1178
1179 [[nodiscard]] unsigned addFrameInst(const MCCFIInstruction &Inst);
1180
1181
1182
1183
1184 const std::vector<MCSymbol *> &getLongjmpTargets() const {
1185 return LongjmpTargets;
1186 }
1187
1188
1189
1190 void addLongjmpTarget(MCSymbol *Target) { LongjmpTargets.push_back(Target); }
1191
1192
1193
1194 const std::vector<MCSymbol *> &getCatchretTargets() const {
1195 return CatchretTargets;
1196 }
1197
1198
1199
1200 void addCatchretTarget(MCSymbol *Target) {
1201 CatchretTargets.push_back(Target);
1202 }
1203
1204
1205
1206 CalledGlobalInfo tryGetCalledGlobal(const MachineInstr *MI) const {
1207 return CalledGlobalsInfo.lookup(MI);
1208 }
1209
1210
1211 void addCalledGlobal(const MachineInstr *MI, CalledGlobalInfo Details) {
1212 assert(MI && "MI must not be null");
1213 assert(Details.Callee && "Global must not be null");
1214 CalledGlobalsInfo.insert({MI, Details});
1215 }
1216
1217
1218 auto getCalledGlobals() const {
1219 return llvm::make_range(CalledGlobalsInfo.begin(), CalledGlobalsInfo.end());
1220 }
1221
1222
1223
1224
1225 bool callsEHReturn() const { return CallsEHReturn; }
1226 void setCallsEHReturn(bool b) { CallsEHReturn = b; }
1227
1228 bool callsUnwindInit() const { return CallsUnwindInit; }
1229 void setCallsUnwindInit(bool b) { CallsUnwindInit = b; }
1230
1231 bool hasEHCatchret() const { return HasEHCatchret; }
1232 void setHasEHCatchret(bool V) { HasEHCatchret = V; }
1233
1234 bool hasEHScopes() const { return HasEHScopes; }
1235 void setHasEHScopes(bool V) { HasEHScopes = V; }
1236
1237 bool hasEHFunclets() const { return HasEHFunclets; }
1238 void setHasEHFunclets(bool V) { HasEHFunclets = V; }
1239
1240 bool hasFakeUses() const { return HasFakeUses; }
1241 void setHasFakeUses(bool V) { HasFakeUses = V; }
1242
1243 bool isOutlined() const { return IsOutlined; }
1244 void setIsOutlined(bool V) { IsOutlined = V; }
1245
1246
1247 LandingPadInfo &getOrCreateLandingPadInfo(MachineBasicBlock *LandingPad);
1248
1249
1250 const std::vector<LandingPadInfo> &getLandingPads() const {
1251 return LandingPads;
1252 }
1253
1254
1255
1256 void addInvoke(MachineBasicBlock *LandingPad,
1257 MCSymbol *BeginLabel, MCSymbol *EndLabel);
1258
1259
1260
1261
1262 MCSymbol *addLandingPad(MachineBasicBlock *LandingPad);
1263
1264
1265 unsigned getTypeIDFor(const GlobalValue *TI);
1266
1267
1268 int getFilterIDFor(ArrayRef<unsigned> TyIds);
1269
1270
1271 void setCallSiteLandingPad(MCSymbol *Sym, ArrayRef<unsigned> Sites);
1272
1273
1274 bool hasAnyWasmLandingPadIndex() const {
1275 return !WasmLPadToIndexMap.empty();
1276 }
1277
1278
1279 void setWasmLandingPadIndex(const MachineBasicBlock *LPad, unsigned Index) {
1280 WasmLPadToIndexMap[LPad] = Index;
1281 }
1282
1283
1284 bool hasWasmLandingPadIndex(const MachineBasicBlock *LPad) const {
1285 return WasmLPadToIndexMap.count(LPad);
1286 }
1287
1288
1289 unsigned getWasmLandingPadIndex(const MachineBasicBlock *LPad) const {
1290 assert(hasWasmLandingPadIndex(LPad));
1291 return WasmLPadToIndexMap.lookup(LPad);
1292 }
1293
1294 bool hasAnyCallSiteLandingPad() const {
1295 return !LPadToCallSiteMap.empty();
1296 }
1297
1298
1299 SmallVectorImpl<unsigned> &getCallSiteLandingPad(MCSymbol *Sym) {
1300 assert(hasCallSiteLandingPad(Sym) &&
1301 "missing call site number for landing pad!");
1302 return LPadToCallSiteMap[Sym];
1303 }
1304
1305
1306 bool hasCallSiteLandingPad(MCSymbol *Sym) {
1307 return !LPadToCallSiteMap[Sym].empty();
1308 }
1309
1310 bool hasAnyCallSiteLabel() const {
1311 return !CallSiteMap.empty();
1312 }
1313
1314
1315 void setCallSiteBeginLabel(MCSymbol *BeginLabel, unsigned Site) {
1316 CallSiteMap[BeginLabel] = Site;
1317 }
1318
1319
1320 unsigned getCallSiteBeginLabel(MCSymbol *BeginLabel) const {
1321 assert(hasCallSiteBeginLabel(BeginLabel) &&
1322 "Missing call site number for EH_LABEL!");
1323 return CallSiteMap.lookup(BeginLabel);
1324 }
1325
1326
1327 bool hasCallSiteBeginLabel(MCSymbol *BeginLabel) const {
1328 return CallSiteMap.count(BeginLabel);
1329 }
1330
1331
1332 void addCodeViewAnnotation(MCSymbol *Label, MDNode *MD) {
1333 CodeViewAnnotations.push_back({Label, MD});
1334 }
1335
1336 ArrayRef<std::pair<MCSymbol *, MDNode *>> getCodeViewAnnotations() const {
1337 return CodeViewAnnotations;
1338 }
1339
1340
1341 const std::vector<const GlobalValue *> &getTypeInfos() const {
1342 return TypeInfos;
1343 }
1344
1345
1346
1347 const std::vector<unsigned> &getFilterIds() const {
1348 return FilterIds;
1349 }
1350
1351
1352
1353
1354
1355 void setVariableDbgInfo(const DILocalVariable *Var, const DIExpression *Expr,
1356 int Slot, const DILocation *Loc) {
1357 VariableDbgInfos.emplace_back(Var, Expr, Slot, Loc);
1358 }
1359
1360
1361
1362 void setVariableDbgInfo(const DILocalVariable *Var, const DIExpression *Expr,
1363 MCRegister Reg, const DILocation *Loc) {
1364 VariableDbgInfos.emplace_back(Var, Expr, Reg, Loc);
1365 }
1366
1367 VariableDbgInfoMapTy &getVariableDbgInfo() { return VariableDbgInfos; }
1368 const VariableDbgInfoMapTy &getVariableDbgInfo() const {
1369 return VariableDbgInfos;
1370 }
1371
1372
1373
1374 auto getInStackSlotVariableDbgInfo() {
1375 return make_filter_range(getVariableDbgInfo(), [](auto &VarInfo) {
1376 return VarInfo.inStackSlot();
1377 });
1378 }
1379
1380
1381
1382 auto getInStackSlotVariableDbgInfo() const {
1383 return make_filter_range(getVariableDbgInfo(), [](const auto &VarInfo) {
1384 return VarInfo.inStackSlot();
1385 });
1386 }
1387
1388
1389
1390 auto getEntryValueVariableDbgInfo() const {
1391 return make_filter_range(getVariableDbgInfo(), [](const auto &VarInfo) {
1392 return VarInfo.inEntryValueRegister();
1393 });
1394 }
1395
1396
1397 void addCallSiteInfo(const MachineInstr *CallI, CallSiteInfo &&CallInfo) {
1398 assert(CallI->isCandidateForAdditionalCallInfo());
1399 bool Inserted =
1400 CallSitesInfo.try_emplace(CallI, std::move(CallInfo)).second;
1401 (void)Inserted;
1402 assert(Inserted && "Call site info not unique");
1403 }
1404
1405 const CallSiteInfoMap &getCallSitesInfo() const {
1406 return CallSitesInfo;
1407 }
1408
1409
1410
1411
1412
1413
1414 void eraseAdditionalCallInfo(const MachineInstr *MI);
1415
1416
1417
1418 void copyAdditionalCallInfo(const MachineInstr *Old, const MachineInstr *New);
1419
1420
1421
1422
1423 void moveAdditionalCallInfo(const MachineInstr *Old, const MachineInstr *New);
1424
1425 unsigned getNewDebugInstrNum() {
1426 return ++DebugInstrNumberingCount;
1427 }
1428 };
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439 template <> struct GraphTraits<MachineFunction*> :
1440 public GraphTraits<MachineBasicBlock*> {
1441 static NodeRef getEntryNode(MachineFunction *F) { return &F->front(); }
1442
1443
1444 using nodes_iterator = pointer_iterator<MachineFunction::iterator>;
1445
1446 static nodes_iterator nodes_begin(MachineFunction *F) {
1447 return nodes_iterator(F->begin());
1448 }
1449
1450 static nodes_iterator nodes_end(MachineFunction *F) {
1451 return nodes_iterator(F->end());
1452 }
1453
1454 static unsigned size (MachineFunction *F) { return F->size(); }
1455
1456 static unsigned getMaxNumber(MachineFunction *F) {
1457 return F->getNumBlockIDs();
1458 }
1459 static unsigned getNumberEpoch(MachineFunction *F) {
1460 return F->getBlockNumberEpoch();
1461 }
1462 };
1463 template <> struct GraphTraits<const MachineFunction*> :
1464 public GraphTraits<const MachineBasicBlock*> {
1465 static NodeRef getEntryNode(const MachineFunction *F) { return &F->front(); }
1466
1467
1468 using nodes_iterator = pointer_iterator<MachineFunction::const_iterator>;
1469
1470 static nodes_iterator nodes_begin(const MachineFunction *F) {
1471 return nodes_iterator(F->begin());
1472 }
1473
1474 static nodes_iterator nodes_end (const MachineFunction *F) {
1475 return nodes_iterator(F->end());
1476 }
1477
1478 static unsigned size (const MachineFunction *F) {
1479 return F->size();
1480 }
1481
1482 static unsigned getMaxNumber(const MachineFunction *F) {
1483 return F->getNumBlockIDs();
1484 }
1485 static unsigned getNumberEpoch(const MachineFunction *F) {
1486 return F->getBlockNumberEpoch();
1487 }
1488 };
1489
1490
1491
1492
1493
1494
1495 template <> struct GraphTraits<Inverse<MachineFunction*>> :
1496 public GraphTraits<Inverse<MachineBasicBlock*>> {
1497 static NodeRef getEntryNode(Inverse<MachineFunction *> G) {
1498 return &G.Graph->front();
1499 }
1500
1501 static unsigned getMaxNumber(MachineFunction *F) {
1502 return F->getNumBlockIDs();
1503 }
1504 static unsigned getNumberEpoch(MachineFunction *F) {
1505 return F->getBlockNumberEpoch();
1506 }
1507 };
1508 template <> struct GraphTraits<Inverse<const MachineFunction*>> :
1509 public GraphTraits<Inverse<const MachineBasicBlock*>> {
1510 static NodeRef getEntryNode(Inverse<const MachineFunction *> G) {
1511 return &G.Graph->front();
1512 }
1513
1514 static unsigned getMaxNumber(const MachineFunction *F) {
1515 return F->getNumBlockIDs();
1516 }
1517 static unsigned getNumberEpoch(const MachineFunction *F) {
1518 return F->getBlockNumberEpoch();
1519 }
1520 };
1521
1522 void verifyMachineFunction(const std::string &Banner,
1523 const MachineFunction &MF);
1524
1525 }
1526
1527 #endif