diff options
author | vitalyisaev <vitalyisaev@yandex-team.com> | 2023-06-29 10:00:50 +0300 |
---|---|---|
committer | vitalyisaev <vitalyisaev@yandex-team.com> | 2023-06-29 10:00:50 +0300 |
commit | 6ffe9e53658409f212834330e13564e4952558f6 (patch) | |
tree | 85b1e00183517648b228aafa7c8fb07f5276f419 /contrib/libs/llvm14/include/llvm/CodeGen/MachineFunction.h | |
parent | 726057070f9c5a91fc10fde0d5024913d10f1ab9 (diff) | |
download | ydb-6ffe9e53658409f212834330e13564e4952558f6.tar.gz |
YQ Connector: support managed ClickHouse
Со стороны dqrun можно обратиться к инстансу коннектора, который работает на streaming стенде, и извлечь данные из облачного CH.
Diffstat (limited to 'contrib/libs/llvm14/include/llvm/CodeGen/MachineFunction.h')
-rw-r--r-- | contrib/libs/llvm14/include/llvm/CodeGen/MachineFunction.h | 1320 |
1 files changed, 1320 insertions, 0 deletions
diff --git a/contrib/libs/llvm14/include/llvm/CodeGen/MachineFunction.h b/contrib/libs/llvm14/include/llvm/CodeGen/MachineFunction.h new file mode 100644 index 0000000000..939efbc1f7 --- /dev/null +++ b/contrib/libs/llvm14/include/llvm/CodeGen/MachineFunction.h @@ -0,0 +1,1320 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- llvm/CodeGen/MachineFunction.h ---------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Collect native machine code for a function. This class contains a list of +// MachineBasicBlock instances that make up the current compiled function. +// +// This class also contains pointers to various classes which hold +// target-specific information about the generated code. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_MACHINEFUNCTION_H +#define LLVM_CODEGEN_MACHINEFUNCTION_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/GraphTraits.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/ilist.h" +#include "llvm/ADT/iterator.h" +#include "llvm/Analysis/EHPersonalities.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineMemOperand.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/ArrayRecycler.h" +#include "llvm/Support/AtomicOrdering.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Recycler.h" +#include "llvm/Target/TargetOptions.h" +#include <cassert> +#include <cstdint> +#include <memory> +#include <utility> +#include <vector> + +namespace llvm { + +class BasicBlock; +class BlockAddress; +class DataLayout; +class DebugLoc; +struct DenormalMode; +class DIExpression; +class DILocalVariable; +class DILocation; +class Function; +class GISelChangeObserver; +class GlobalValue; +class LLVMTargetMachine; +class MachineConstantPool; +class MachineFrameInfo; +class MachineFunction; +class MachineJumpTableInfo; +class MachineModuleInfo; +class MachineRegisterInfo; +class MCContext; +class MCInstrDesc; +class MCSymbol; +class MCSection; +class Pass; +class PseudoSourceValueManager; +class raw_ostream; +class SlotIndexes; +class StringRef; +class TargetRegisterClass; +class TargetSubtargetInfo; +struct WasmEHFuncInfo; +struct WinEHFuncInfo; + +template <> struct ilist_alloc_traits<MachineBasicBlock> { + void deleteNode(MachineBasicBlock *MBB); +}; + +template <> struct ilist_callback_traits<MachineBasicBlock> { + void addNodeToList(MachineBasicBlock* N); + void removeNodeFromList(MachineBasicBlock* N); + + template <class Iterator> + void transferNodesFromList(ilist_callback_traits &OldList, Iterator, Iterator) { + assert(this == &OldList && "never transfer MBBs between functions"); + } +}; + +/// MachineFunctionInfo - This class can be derived from and used by targets to +/// hold private target-specific information for each MachineFunction. Objects +/// of type are accessed/created with MF::getInfo and destroyed when the +/// MachineFunction is destroyed. +struct MachineFunctionInfo { + virtual ~MachineFunctionInfo(); + + /// Factory function: default behavior is to call new using the + /// supplied allocator. + /// + /// This function can be overridden in a derive class. + template<typename Ty> + static Ty *create(BumpPtrAllocator &Allocator, MachineFunction &MF) { + return new (Allocator.Allocate<Ty>()) Ty(MF); + } +}; + +/// Properties which a MachineFunction may have at a given point in time. +/// Each of these has checking code in the MachineVerifier, and passes can +/// require that a property be set. +class MachineFunctionProperties { + // Possible TODO: Allow targets to extend this (perhaps by allowing the + // constructor to specify the size of the bit vector) + // Possible TODO: Allow requiring the negative (e.g. VRegsAllocated could be + // stated as the negative of "has vregs" + +public: + // The properties are stated in "positive" form; i.e. a pass could require + // that the property hold, but not that it does not hold. + + // Property descriptions: + // IsSSA: True when the machine function is in SSA form and virtual registers + // have a single def. + // NoPHIs: The machine function does not contain any PHI instruction. + // TracksLiveness: True when tracking register liveness accurately. + // While this property is set, register liveness information in basic block + // live-in lists and machine instruction operands (e.g. implicit defs) is + // accurate, kill flags are conservatively accurate (kill flag correctly + // indicates the last use of a register, an operand without kill flag may or + // may not be the last use of a register). This means it can be used to + // change the code in ways that affect the values in registers, for example + // by the register scavenger. + // When this property is cleared at a very late time, liveness is no longer + // reliable. + // NoVRegs: The machine function does not use any virtual registers. + // Legalized: In GlobalISel: the MachineLegalizer ran and all pre-isel generic + // instructions have been legalized; i.e., all instructions are now one of: + // - generic and always legal (e.g., COPY) + // - target-specific + // - legal pre-isel generic instructions. + // RegBankSelected: In GlobalISel: the RegBankSelect pass ran and all generic + // virtual registers have been assigned to a register bank. + // Selected: In GlobalISel: the InstructionSelect pass ran and all pre-isel + // generic instructions have been eliminated; i.e., all instructions are now + // target-specific or non-pre-isel generic instructions (e.g., COPY). + // Since only pre-isel generic instructions can have generic virtual register + // operands, this also means that all generic virtual registers have been + // constrained to virtual registers (assigned to register classes) and that + // all sizes attached to them have been eliminated. + // TiedOpsRewritten: The twoaddressinstruction pass will set this flag, it + // means that tied-def have been rewritten to meet the RegConstraint. + // FailsVerification: Means that the function is not expected to pass machine + // verification. This can be set by passes that introduce known problems that + // have not been fixed yet. + // TracksDebugUserValues: Without this property enabled, debug instructions + // such as DBG_VALUE are allowed to reference virtual registers even if those + // registers do not have a definition. With the property enabled virtual + // registers must only be used if they have a definition. This property + // allows earlier passes in the pipeline to skip updates of `DBG_VALUE` + // instructions to save compile time. + enum class Property : unsigned { + IsSSA, + NoPHIs, + TracksLiveness, + NoVRegs, + FailedISel, + Legalized, + RegBankSelected, + Selected, + TiedOpsRewritten, + FailsVerification, + TracksDebugUserValues, + LastProperty = TracksDebugUserValues, + }; + + bool hasProperty(Property P) const { + return Properties[static_cast<unsigned>(P)]; + } + + MachineFunctionProperties &set(Property P) { + Properties.set(static_cast<unsigned>(P)); + return *this; + } + + MachineFunctionProperties &reset(Property P) { + Properties.reset(static_cast<unsigned>(P)); + return *this; + } + + /// Reset all the properties. + MachineFunctionProperties &reset() { + Properties.reset(); + return *this; + } + + MachineFunctionProperties &set(const MachineFunctionProperties &MFP) { + Properties |= MFP.Properties; + return *this; + } + + MachineFunctionProperties &reset(const MachineFunctionProperties &MFP) { + Properties.reset(MFP.Properties); + return *this; + } + + // Returns true if all properties set in V (i.e. required by a pass) are set + // in this. + bool verifyRequiredProperties(const MachineFunctionProperties &V) const { + return !V.Properties.test(Properties); + } + + /// Print the MachineFunctionProperties in human-readable form. + void print(raw_ostream &OS) const; + +private: + BitVector Properties = + BitVector(static_cast<unsigned>(Property::LastProperty)+1); +}; + +struct SEHHandler { + /// Filter or finally function. Null indicates a catch-all. + const Function *FilterOrFinally; + + /// Address of block to recover at. Null for a finally handler. + const BlockAddress *RecoverBA; +}; + +/// This structure is used to retain landing pad info for the current function. +struct LandingPadInfo { + MachineBasicBlock *LandingPadBlock; // Landing pad block. + SmallVector<MCSymbol *, 1> BeginLabels; // Labels prior to invoke. + SmallVector<MCSymbol *, 1> EndLabels; // Labels after invoke. + SmallVector<SEHHandler, 1> SEHHandlers; // SEH handlers active at this lpad. + MCSymbol *LandingPadLabel = nullptr; // Label at beginning of landing pad. + std::vector<int> TypeIds; // List of type ids (filters negative). + + explicit LandingPadInfo(MachineBasicBlock *MBB) + : LandingPadBlock(MBB) {} +}; + +class LLVM_EXTERNAL_VISIBILITY MachineFunction { + Function &F; + const LLVMTargetMachine &Target; + const TargetSubtargetInfo *STI; + MCContext &Ctx; + MachineModuleInfo &MMI; + + // RegInfo - Information about each register in use in the function. + MachineRegisterInfo *RegInfo; + + // Used to keep track of target-specific per-machine function information for + // the target implementation. + MachineFunctionInfo *MFInfo; + + // Keep track of objects allocated on the stack. + MachineFrameInfo *FrameInfo; + + // Keep track of constants which are spilled to memory + MachineConstantPool *ConstantPool; + + // Keep track of jump tables for switch instructions + MachineJumpTableInfo *JumpTableInfo; + + // Keep track of the function section. + MCSection *Section = nullptr; + + // Keeps track of Wasm exception handling related data. This will be null for + // functions that aren't using a wasm EH personality. + WasmEHFuncInfo *WasmEHInfo = nullptr; + + // Keeps track of Windows exception handling related data. This will be null + // for functions that aren't using a funclet-based EH personality. + WinEHFuncInfo *WinEHInfo = nullptr; + + // Function-level unique numbering for MachineBasicBlocks. When a + // MachineBasicBlock is inserted into a MachineFunction is it automatically + // numbered and this vector keeps track of the mapping from ID's to MBB's. + std::vector<MachineBasicBlock*> MBBNumbering; + + // Unary encoding of basic block symbols is used to reduce size of ".strtab". + // Basic block number 'i' gets a prefix of length 'i'. The ith character also + // denotes the type of basic block number 'i'. Return blocks are marked with + // 'r', landing pads with 'l' and regular blocks with 'a'. + std::vector<char> BBSectionsSymbolPrefix; + + // Pool-allocate MachineFunction-lifetime and IR objects. + BumpPtrAllocator Allocator; + + // Allocation management for instructions in function. + Recycler<MachineInstr> InstructionRecycler; + + // Allocation management for operand arrays on instructions. + ArrayRecycler<MachineOperand> OperandRecycler; + + // Allocation management for basic blocks in function. + Recycler<MachineBasicBlock> BasicBlockRecycler; + + // List of machine basic blocks in function + using BasicBlockListType = ilist<MachineBasicBlock>; + BasicBlockListType BasicBlocks; + + /// FunctionNumber - This provides a unique ID for each function emitted in + /// this translation unit. + /// + unsigned FunctionNumber; + + /// Alignment - The alignment of the function. + Align Alignment; + + /// ExposesReturnsTwice - True if the function calls setjmp or related + /// functions with attribute "returns twice", but doesn't have + /// the attribute itself. + /// This is used to limit optimizations which cannot reason + /// about the control flow of such functions. + bool ExposesReturnsTwice = false; + + /// True if the function includes any inline assembly. + bool HasInlineAsm = false; + + /// True if any WinCFI instruction have been emitted in this function. + bool HasWinCFI = false; + + /// Current high-level properties of the IR of the function (e.g. is in SSA + /// form or whether registers have been allocated) + MachineFunctionProperties Properties; + + // Allocation management for pseudo source values. + std::unique_ptr<PseudoSourceValueManager> PSVManager; + + /// List of moves done by a function's prolog. Used to construct frame maps + /// by debug and exception handling consumers. + std::vector<MCCFIInstruction> FrameInstructions; + + /// List of basic blocks immediately following calls to _setjmp. Used to + /// construct a table of valid longjmp targets for Windows Control Flow Guard. + std::vector<MCSymbol *> LongjmpTargets; + + /// List of basic blocks that are the target of catchrets. Used to construct + /// a table of valid targets for Windows EHCont Guard. + std::vector<MCSymbol *> CatchretTargets; + + /// \name Exception Handling + /// \{ + + /// List of LandingPadInfo describing the landing pad information. + std::vector<LandingPadInfo> LandingPads; + + /// Map a landing pad's EH symbol to the call site indexes. + DenseMap<MCSymbol*, SmallVector<unsigned, 4>> LPadToCallSiteMap; + + /// Map a landing pad to its index. + DenseMap<const MachineBasicBlock *, unsigned> WasmLPadToIndexMap; + + /// Map of invoke call site index values to associated begin EH_LABEL. + DenseMap<MCSymbol*, unsigned> CallSiteMap; + + /// CodeView label annotations. + std::vector<std::pair<MCSymbol *, MDNode *>> CodeViewAnnotations; + + bool CallsEHReturn = false; + bool CallsUnwindInit = false; + bool HasEHCatchret = false; + bool HasEHScopes = false; + bool HasEHFunclets = false; + + /// Section Type for basic blocks, only relevant with basic block sections. + BasicBlockSection BBSectionsType = BasicBlockSection::None; + + /// List of C++ TypeInfo used. + std::vector<const GlobalValue *> TypeInfos; + + /// List of typeids encoding filters used. + std::vector<unsigned> FilterIds; + + /// List of the indices in FilterIds corresponding to filter terminators. + std::vector<unsigned> FilterEnds; + + EHPersonality PersonalityTypeCache = EHPersonality::Unknown; + + /// \} + + /// Clear all the members of this MachineFunction, but the ones used + /// to initialize again the MachineFunction. + /// More specifically, this deallocates all the dynamically allocated + /// objects and get rid of all the XXXInfo data structure, but keep + /// unchanged the references to Fn, Target, MMI, and FunctionNumber. + void clear(); + /// Allocate and initialize the different members. + /// In particular, the XXXInfo data structure. + /// \pre Fn, Target, MMI, and FunctionNumber are properly set. + void init(); + +public: + struct VariableDbgInfo { + const DILocalVariable *Var; + const DIExpression *Expr; + // The Slot can be negative for fixed stack objects. + int Slot; + const DILocation *Loc; + + VariableDbgInfo(const DILocalVariable *Var, const DIExpression *Expr, + int Slot, const DILocation *Loc) + : Var(Var), Expr(Expr), Slot(Slot), Loc(Loc) {} + }; + + class Delegate { + virtual void anchor(); + + public: + virtual ~Delegate() = default; + /// Callback after an insertion. This should not modify the MI directly. + virtual void MF_HandleInsertion(MachineInstr &MI) = 0; + /// Callback before a removal. This should not modify the MI directly. + virtual void MF_HandleRemoval(MachineInstr &MI) = 0; + }; + + /// Structure used to represent pair of argument number after call lowering + /// and register used to transfer that argument. + /// For now we support only cases when argument is transferred through one + /// register. + struct ArgRegPair { + Register Reg; + uint16_t ArgNo; + ArgRegPair(Register R, unsigned Arg) : Reg(R), ArgNo(Arg) { + assert(Arg < (1 << 16) && "Arg out of range"); + } + }; + /// Vector of call argument and its forwarding register. + using CallSiteInfo = SmallVector<ArgRegPair, 1>; + using CallSiteInfoImpl = SmallVectorImpl<ArgRegPair>; + +private: + Delegate *TheDelegate = nullptr; + GISelChangeObserver *Observer = nullptr; + + using CallSiteInfoMap = DenseMap<const MachineInstr *, CallSiteInfo>; + /// Map a call instruction to call site arguments forwarding info. + CallSiteInfoMap CallSitesInfo; + + /// A helper function that returns call site info for a give call + /// instruction if debug entry value support is enabled. + CallSiteInfoMap::iterator getCallSiteInfo(const MachineInstr *MI); + + // Callbacks for insertion and removal. + void handleInsertion(MachineInstr &MI); + void handleRemoval(MachineInstr &MI); + friend struct ilist_traits<MachineInstr>; + +public: + using VariableDbgInfoMapTy = SmallVector<VariableDbgInfo, 4>; + VariableDbgInfoMapTy VariableDbgInfos; + + /// A count of how many instructions in the function have had numbers + /// assigned to them. Used for debug value tracking, to determine the + /// next instruction number. + unsigned DebugInstrNumberingCount = 0; + + /// Set value of DebugInstrNumberingCount field. Avoid using this unless + /// you're deserializing this data. + void setDebugInstrNumberingCount(unsigned Num); + + /// Pair of instruction number and operand number. + using DebugInstrOperandPair = std::pair<unsigned, unsigned>; + + /// Replacement definition for a debug instruction reference. Made up of a + /// source instruction / operand pair, destination pair, and a qualifying + /// subregister indicating what bits in the operand make up the substitution. + // For example, a debug user + /// of %1: + /// %0:gr32 = someinst, debug-instr-number 1 + /// %1:gr16 = %0.some_16_bit_subreg, debug-instr-number 2 + /// Would receive the substitution {{2, 0}, {1, 0}, $subreg}, where $subreg is + /// the subregister number for some_16_bit_subreg. + class DebugSubstitution { + public: + DebugInstrOperandPair Src; ///< Source instruction / operand pair. + DebugInstrOperandPair Dest; ///< Replacement instruction / operand pair. + unsigned Subreg; ///< Qualifier for which part of Dest is read. + + DebugSubstitution(const DebugInstrOperandPair &Src, + const DebugInstrOperandPair &Dest, unsigned Subreg) + : Src(Src), Dest(Dest), Subreg(Subreg) {} + + /// Order only by source instruction / operand pair: there should never + /// be duplicate entries for the same source in any collection. + bool operator<(const DebugSubstitution &Other) const { + return Src < Other.Src; + } + }; + + /// Debug value substitutions: a collection of DebugSubstitution objects, + /// recording changes in where a value is defined. For example, when one + /// instruction is substituted for another. Keeping a record allows recovery + /// of variable locations after compilation finishes. + SmallVector<DebugSubstitution, 8> DebugValueSubstitutions; + + /// Location of a PHI instruction that is also a debug-info variable value, + /// for the duration of register allocation. Loaded by the PHI-elimination + /// pass, and emitted as DBG_PHI instructions during VirtRegRewriter, with + /// maintenance applied by intermediate passes that edit registers (such as + /// coalescing and the allocator passes). + class DebugPHIRegallocPos { + public: + MachineBasicBlock *MBB; ///< Block where this PHI was originally located. + Register Reg; ///< VReg where the control-flow-merge happens. + unsigned SubReg; ///< Optional subreg qualifier within Reg. + DebugPHIRegallocPos(MachineBasicBlock *MBB, Register Reg, unsigned SubReg) + : MBB(MBB), Reg(Reg), SubReg(SubReg) {} + }; + + /// Map of debug instruction numbers to the position of their PHI instructions + /// during register allocation. See DebugPHIRegallocPos. + DenseMap<unsigned, DebugPHIRegallocPos> DebugPHIPositions; + + /// Create a substitution between one <instr,operand> value to a different, + /// new value. + void makeDebugValueSubstitution(DebugInstrOperandPair, DebugInstrOperandPair, + unsigned SubReg = 0); + + /// Create substitutions for any tracked values in \p Old, to point at + /// \p New. Needed when we re-create an instruction during optimization, + /// which has the same signature (i.e., def operands in the same place) but + /// a modified instruction type, flags, or otherwise. An example: X86 moves + /// are sometimes transformed into equivalent LEAs. + /// If the two instructions are not the same opcode, limit which operands to + /// examine for substitutions to the first N operands by setting + /// \p MaxOperand. + void substituteDebugValuesForInst(const MachineInstr &Old, MachineInstr &New, + unsigned MaxOperand = UINT_MAX); + + /// Find the underlying defining instruction / operand for a COPY instruction + /// while in SSA form. Copies do not actually define values -- they move them + /// between registers. Labelling a COPY-like instruction with an instruction + /// number is to be avoided as it makes value numbers non-unique later in + /// compilation. This method follows the definition chain for any sequence of + /// COPY-like instructions to find whatever non-COPY-like instruction defines + /// the copied value; or for parameters, creates a DBG_PHI on entry. + /// May insert instructions into the entry block! + /// \p MI The copy-like instruction to salvage. + /// \returns An instruction/operand pair identifying the defining value. + DebugInstrOperandPair salvageCopySSA(MachineInstr &MI); + + /// Finalise any partially emitted debug instructions. These are DBG_INSTR_REF + /// instructions where we only knew the vreg of the value they use, not the + /// instruction that defines that vreg. Once isel finishes, we should have + /// enough information for every DBG_INSTR_REF to point at an instruction + /// (or DBG_PHI). + void finalizeDebugInstrRefs(); + + /// Returns true if the function's variable locations should be tracked with + /// instruction referencing. + bool useDebugInstrRef() const; + + /// A reserved operand number representing the instructions memory operand, + /// for instructions that have a stack spill fused into them. + const static unsigned int DebugOperandMemNumber; + + MachineFunction(Function &F, const LLVMTargetMachine &Target, + const TargetSubtargetInfo &STI, unsigned FunctionNum, + MachineModuleInfo &MMI); + MachineFunction(const MachineFunction &) = delete; + MachineFunction &operator=(const MachineFunction &) = delete; + ~MachineFunction(); + + /// Reset the instance as if it was just created. + void reset() { + clear(); + init(); + } + + /// Reset the currently registered delegate - otherwise assert. + void resetDelegate(Delegate *delegate) { + assert(TheDelegate == delegate && + "Only the current delegate can perform reset!"); + TheDelegate = nullptr; + } + + /// Set the delegate. resetDelegate must be called before attempting + /// to set. + void setDelegate(Delegate *delegate) { + assert(delegate && !TheDelegate && + "Attempted to set delegate to null, or to change it without " + "first resetting it!"); + + TheDelegate = delegate; + } + + void setObserver(GISelChangeObserver *O) { Observer = O; } + + GISelChangeObserver *getObserver() const { return Observer; } + + MachineModuleInfo &getMMI() const { return MMI; } + MCContext &getContext() const { return Ctx; } + + /// Returns the Section this function belongs to. + MCSection *getSection() const { return Section; } + + /// Indicates the Section this function belongs to. + void setSection(MCSection *S) { Section = S; } + + PseudoSourceValueManager &getPSVManager() const { return *PSVManager; } + + /// Return the DataLayout attached to the Module associated to this MF. + const DataLayout &getDataLayout() const; + + /// Return the LLVM function that this machine code represents + Function &getFunction() { return F; } + + /// Return the LLVM function that this machine code represents + const Function &getFunction() const { return F; } + + /// getName - Return the name of the corresponding LLVM function. + StringRef getName() const; + + /// getFunctionNumber - Return a unique ID for the current function. + unsigned getFunctionNumber() const { return FunctionNumber; } + + /// Returns true if this function has basic block sections enabled. + bool hasBBSections() const { + return (BBSectionsType == BasicBlockSection::All || + BBSectionsType == BasicBlockSection::List || + BBSectionsType == BasicBlockSection::Preset); + } + + /// Returns true if basic block labels are to be generated for this function. + bool hasBBLabels() const { + return BBSectionsType == BasicBlockSection::Labels; + } + + void setBBSectionsType(BasicBlockSection V) { BBSectionsType = V; } + + /// Assign IsBeginSection IsEndSection fields for basic blocks in this + /// function. + void assignBeginEndSections(); + + /// getTarget - Return the target machine this machine code is compiled with + const LLVMTargetMachine &getTarget() const { return Target; } + + /// getSubtarget - Return the subtarget for which this machine code is being + /// compiled. + const TargetSubtargetInfo &getSubtarget() const { return *STI; } + + /// getSubtarget - This method returns a pointer to the specified type of + /// TargetSubtargetInfo. In debug builds, it verifies that the object being + /// returned is of the correct type. + template<typename STC> const STC &getSubtarget() const { + return *static_cast<const STC *>(STI); + } + + /// getRegInfo - Return information about the registers currently in use. + MachineRegisterInfo &getRegInfo() { return *RegInfo; } + const MachineRegisterInfo &getRegInfo() const { return *RegInfo; } + + /// getFrameInfo - Return the frame info object for the current function. + /// This object contains information about objects allocated on the stack + /// frame of the current function in an abstract way. + MachineFrameInfo &getFrameInfo() { return *FrameInfo; } + const MachineFrameInfo &getFrameInfo() const { return *FrameInfo; } + + /// getJumpTableInfo - Return the jump table info object for the current + /// function. This object contains information about jump tables in the + /// current function. If the current function has no jump tables, this will + /// return null. + const MachineJumpTableInfo *getJumpTableInfo() const { return JumpTableInfo; } + MachineJumpTableInfo *getJumpTableInfo() { return JumpTableInfo; } + + /// getOrCreateJumpTableInfo - Get the JumpTableInfo for this function, if it + /// does already exist, allocate one. + MachineJumpTableInfo *getOrCreateJumpTableInfo(unsigned JTEntryKind); + + /// getConstantPool - Return the constant pool object for the current + /// function. + MachineConstantPool *getConstantPool() { return ConstantPool; } + const MachineConstantPool *getConstantPool() const { return ConstantPool; } + + /// getWasmEHFuncInfo - Return information about how the current function uses + /// Wasm exception handling. Returns null for functions that don't use wasm + /// exception handling. + const WasmEHFuncInfo *getWasmEHFuncInfo() const { return WasmEHInfo; } + WasmEHFuncInfo *getWasmEHFuncInfo() { return WasmEHInfo; } + + /// getWinEHFuncInfo - Return information about how the current function uses + /// Windows exception handling. Returns null for functions that don't use + /// funclets for exception handling. + const WinEHFuncInfo *getWinEHFuncInfo() const { return WinEHInfo; } + WinEHFuncInfo *getWinEHFuncInfo() { return WinEHInfo; } + + /// getAlignment - Return the alignment of the function. + Align getAlignment() const { return Alignment; } + + /// setAlignment - Set the alignment of the function. + void setAlignment(Align A) { Alignment = A; } + + /// ensureAlignment - Make sure the function is at least A bytes aligned. + void ensureAlignment(Align A) { + if (Alignment < A) + Alignment = A; + } + + /// exposesReturnsTwice - Returns true if the function calls setjmp or + /// any other similar functions with attribute "returns twice" without + /// having the attribute itself. + bool exposesReturnsTwice() const { + return ExposesReturnsTwice; + } + + /// setCallsSetJmp - Set a flag that indicates if there's a call to + /// a "returns twice" function. + void setExposesReturnsTwice(bool B) { + ExposesReturnsTwice = B; + } + + /// Returns true if the function contains any inline assembly. + bool hasInlineAsm() const { + return HasInlineAsm; + } + + /// Set a flag that indicates that the function contains inline assembly. + void setHasInlineAsm(bool B) { + HasInlineAsm = B; + } + + bool hasWinCFI() const { + return HasWinCFI; + } + void setHasWinCFI(bool v) { HasWinCFI = v; } + + /// True if this function needs frame moves for debug or exceptions. + bool needsFrameMoves() const; + + /// Get the function properties + const MachineFunctionProperties &getProperties() const { return Properties; } + MachineFunctionProperties &getProperties() { return Properties; } + + /// getInfo - Keep track of various per-function pieces of information for + /// backends that would like to do so. + /// + template<typename Ty> + Ty *getInfo() { + if (!MFInfo) + MFInfo = Ty::template create<Ty>(Allocator, *this); + return static_cast<Ty*>(MFInfo); + } + + template<typename Ty> + const Ty *getInfo() const { + return const_cast<MachineFunction*>(this)->getInfo<Ty>(); + } + + /// Returns the denormal handling type for the default rounding mode of the + /// function. + DenormalMode getDenormalMode(const fltSemantics &FPType) const; + + /// getBlockNumbered - MachineBasicBlocks are automatically numbered when they + /// are inserted into the machine function. The block number for a machine + /// basic block can be found by using the MBB::getNumber method, this method + /// provides the inverse mapping. + MachineBasicBlock *getBlockNumbered(unsigned N) const { + assert(N < MBBNumbering.size() && "Illegal block number"); + assert(MBBNumbering[N] && "Block was removed from the machine function!"); + return MBBNumbering[N]; + } + + /// Should we be emitting segmented stack stuff for the function + bool shouldSplitStack() const; + + /// getNumBlockIDs - Return the number of MBB ID's allocated. + unsigned getNumBlockIDs() const { return (unsigned)MBBNumbering.size(); } + + /// RenumberBlocks - This discards all of the MachineBasicBlock numbers and + /// recomputes them. This guarantees that the MBB numbers are sequential, + /// dense, and match the ordering of the blocks within the function. If a + /// specific MachineBasicBlock is specified, only that block and those after + /// it are renumbered. + void RenumberBlocks(MachineBasicBlock *MBBFrom = nullptr); + + /// print - Print out the MachineFunction in a format suitable for debugging + /// to the specified stream. + void print(raw_ostream &OS, const SlotIndexes* = nullptr) const; + + /// viewCFG - This function is meant for use from the debugger. You can just + /// say 'call F->viewCFG()' and a ghostview window should pop up from the + /// program, displaying the CFG of the current function with the code for each + /// basic block inside. This depends on there being a 'dot' and 'gv' program + /// in your path. + void viewCFG() const; + + /// viewCFGOnly - This function is meant for use from the debugger. It works + /// just like viewCFG, but it does not include the contents of basic blocks + /// into the nodes, just the label. If you are only interested in the CFG + /// this can make the graph smaller. + /// + void viewCFGOnly() const; + + /// dump - Print the current MachineFunction to cerr, useful for debugger use. + void dump() const; + + /// Run the current MachineFunction through the machine code verifier, useful + /// for debugger use. + /// \returns true if no problems were found. + bool verify(Pass *p = nullptr, const char *Banner = nullptr, + bool AbortOnError = true) const; + + // Provide accessors for the MachineBasicBlock list... + using iterator = BasicBlockListType::iterator; + using const_iterator = BasicBlockListType::const_iterator; + using const_reverse_iterator = BasicBlockListType::const_reverse_iterator; + using reverse_iterator = BasicBlockListType::reverse_iterator; + + /// Support for MachineBasicBlock::getNextNode(). + static BasicBlockListType MachineFunction::* + getSublistAccess(MachineBasicBlock *) { + return &MachineFunction::BasicBlocks; + } + + /// addLiveIn - Add the specified physical register as a live-in value and + /// create a corresponding virtual register for it. + Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC); + + //===--------------------------------------------------------------------===// + // BasicBlock accessor functions. + // + iterator begin() { return BasicBlocks.begin(); } + const_iterator begin() const { return BasicBlocks.begin(); } + iterator end () { return BasicBlocks.end(); } + const_iterator end () const { return BasicBlocks.end(); } + + reverse_iterator rbegin() { return BasicBlocks.rbegin(); } + const_reverse_iterator rbegin() const { return BasicBlocks.rbegin(); } + reverse_iterator rend () { return BasicBlocks.rend(); } + const_reverse_iterator rend () const { return BasicBlocks.rend(); } + + unsigned size() const { return (unsigned)BasicBlocks.size();} + bool empty() const { return BasicBlocks.empty(); } + const MachineBasicBlock &front() const { return BasicBlocks.front(); } + MachineBasicBlock &front() { return BasicBlocks.front(); } + const MachineBasicBlock & back() const { return BasicBlocks.back(); } + MachineBasicBlock & back() { return BasicBlocks.back(); } + + void push_back (MachineBasicBlock *MBB) { BasicBlocks.push_back (MBB); } + void push_front(MachineBasicBlock *MBB) { BasicBlocks.push_front(MBB); } + void insert(iterator MBBI, MachineBasicBlock *MBB) { + BasicBlocks.insert(MBBI, MBB); + } + void splice(iterator InsertPt, iterator MBBI) { + BasicBlocks.splice(InsertPt, BasicBlocks, MBBI); + } + void splice(iterator InsertPt, MachineBasicBlock *MBB) { + BasicBlocks.splice(InsertPt, BasicBlocks, MBB); + } + void splice(iterator InsertPt, iterator MBBI, iterator MBBE) { + BasicBlocks.splice(InsertPt, BasicBlocks, MBBI, MBBE); + } + + void remove(iterator MBBI) { BasicBlocks.remove(MBBI); } + void remove(MachineBasicBlock *MBBI) { BasicBlocks.remove(MBBI); } + void erase(iterator MBBI) { BasicBlocks.erase(MBBI); } + void erase(MachineBasicBlock *MBBI) { BasicBlocks.erase(MBBI); } + + template <typename Comp> + void sort(Comp comp) { + BasicBlocks.sort(comp); + } + + /// Return the number of \p MachineInstrs in this \p MachineFunction. + unsigned getInstructionCount() const { + unsigned InstrCount = 0; + for (const MachineBasicBlock &MBB : BasicBlocks) + InstrCount += MBB.size(); + return InstrCount; + } + + //===--------------------------------------------------------------------===// + // Internal functions used to automatically number MachineBasicBlocks + + /// Adds the MBB to the internal numbering. Returns the unique number + /// assigned to the MBB. + unsigned addToMBBNumbering(MachineBasicBlock *MBB) { + MBBNumbering.push_back(MBB); + return (unsigned)MBBNumbering.size()-1; + } + + /// removeFromMBBNumbering - Remove the specific machine basic block from our + /// tracker, this is only really to be used by the MachineBasicBlock + /// implementation. + void removeFromMBBNumbering(unsigned N) { + assert(N < MBBNumbering.size() && "Illegal basic block #"); + MBBNumbering[N] = nullptr; + } + + /// CreateMachineInstr - Allocate a new MachineInstr. Use this instead + /// of `new MachineInstr'. + MachineInstr *CreateMachineInstr(const MCInstrDesc &MCID, DebugLoc DL, + bool NoImplicit = false); + + /// Create a new MachineInstr which is a copy of \p Orig, identical in all + /// ways except the instruction has no parent, prev, or next. Bundling flags + /// are reset. + /// + /// Note: Clones a single instruction, not whole instruction bundles. + /// Does not perform target specific adjustments; consider using + /// TargetInstrInfo::duplicate() instead. + MachineInstr *CloneMachineInstr(const MachineInstr *Orig); + + /// Clones instruction or the whole instruction bundle \p Orig and insert + /// into \p MBB before \p InsertBefore. + /// + /// Note: Does not perform target specific adjustments; consider using + /// TargetInstrInfo::duplicate() intead. + MachineInstr & + cloneMachineInstrBundle(MachineBasicBlock &MBB, + MachineBasicBlock::iterator InsertBefore, + const MachineInstr &Orig); + + /// DeleteMachineInstr - Delete the given MachineInstr. + void deleteMachineInstr(MachineInstr *MI); + + /// CreateMachineBasicBlock - Allocate a new MachineBasicBlock. Use this + /// instead of `new MachineBasicBlock'. + MachineBasicBlock *CreateMachineBasicBlock(const BasicBlock *bb = nullptr); + + /// DeleteMachineBasicBlock - Delete the given MachineBasicBlock. + void deleteMachineBasicBlock(MachineBasicBlock *MBB); + + /// getMachineMemOperand - Allocate a new MachineMemOperand. + /// MachineMemOperands are owned by the MachineFunction and need not be + /// explicitly deallocated. + MachineMemOperand *getMachineMemOperand( + MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, + Align base_alignment, const AAMDNodes &AAInfo = AAMDNodes(), + const MDNode *Ranges = nullptr, SyncScope::ID SSID = SyncScope::System, + AtomicOrdering Ordering = AtomicOrdering::NotAtomic, + AtomicOrdering FailureOrdering = AtomicOrdering::NotAtomic); + + MachineMemOperand *getMachineMemOperand( + MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, + Align base_alignment, const AAMDNodes &AAInfo = AAMDNodes(), + const MDNode *Ranges = nullptr, SyncScope::ID SSID = SyncScope::System, + AtomicOrdering Ordering = AtomicOrdering::NotAtomic, + AtomicOrdering FailureOrdering = AtomicOrdering::NotAtomic); + + /// getMachineMemOperand - Allocate a new MachineMemOperand by copying + /// an existing one, adjusting by an offset and using the given size. + /// MachineMemOperands are owned by the MachineFunction and need not be + /// explicitly deallocated. + MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO, + int64_t Offset, LLT Ty); + MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO, + int64_t Offset, uint64_t Size) { + return getMachineMemOperand( + MMO, Offset, Size == ~UINT64_C(0) ? LLT() : LLT::scalar(8 * Size)); + } + + /// getMachineMemOperand - Allocate a new MachineMemOperand by copying + /// an existing one, replacing only the MachinePointerInfo and size. + /// MachineMemOperands are owned by the MachineFunction and need not be + /// explicitly deallocated. + MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO, + const MachinePointerInfo &PtrInfo, + uint64_t Size); + MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO, + const MachinePointerInfo &PtrInfo, + LLT Ty); + + /// Allocate a new MachineMemOperand by copying an existing one, + /// replacing only AliasAnalysis information. MachineMemOperands are owned + /// by the MachineFunction and need not be explicitly deallocated. + MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO, + const AAMDNodes &AAInfo); + + /// Allocate a new MachineMemOperand by copying an existing one, + /// replacing the flags. MachineMemOperands are owned + /// by the MachineFunction and need not be explicitly deallocated. + MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO, + MachineMemOperand::Flags Flags); + + using OperandCapacity = ArrayRecycler<MachineOperand>::Capacity; + + /// Allocate an array of MachineOperands. This is only intended for use by + /// internal MachineInstr functions. + MachineOperand *allocateOperandArray(OperandCapacity Cap) { + return OperandRecycler.allocate(Cap, Allocator); + } + + /// Dellocate an array of MachineOperands and recycle the memory. This is + /// only intended for use by internal MachineInstr functions. + /// Cap must be the same capacity that was used to allocate the array. + void deallocateOperandArray(OperandCapacity Cap, MachineOperand *Array) { + OperandRecycler.deallocate(Cap, Array); + } + + /// Allocate and initialize a register mask with @p NumRegister bits. + uint32_t *allocateRegMask(); + + ArrayRef<int> allocateShuffleMask(ArrayRef<int> Mask); + + /// Allocate and construct an extra info structure for a `MachineInstr`. + /// + /// This is allocated on the function's allocator and so lives the life of + /// the function. + MachineInstr::ExtraInfo *createMIExtraInfo( + ArrayRef<MachineMemOperand *> MMOs, MCSymbol *PreInstrSymbol = nullptr, + MCSymbol *PostInstrSymbol = nullptr, MDNode *HeapAllocMarker = nullptr); + + /// Allocate a string and populate it with the given external symbol name. + const char *createExternalSymbolName(StringRef Name); + + //===--------------------------------------------------------------------===// + // Label Manipulation. + + /// getJTISymbol - Return the MCSymbol for the specified non-empty jump table. + /// If isLinkerPrivate is specified, an 'l' label is returned, otherwise a + /// normal 'L' label is returned. + MCSymbol *getJTISymbol(unsigned JTI, MCContext &Ctx, + bool isLinkerPrivate = false) const; + + /// getPICBaseSymbol - Return a function-local symbol to represent the PIC + /// base. + MCSymbol *getPICBaseSymbol() const; + + /// Returns a reference to a list of cfi instructions in the function's + /// prologue. Used to construct frame maps for debug and exception handling + /// comsumers. + const std::vector<MCCFIInstruction> &getFrameInstructions() const { + return FrameInstructions; + } + + LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst); + + /// Returns a reference to a list of symbols immediately following calls to + /// _setjmp in the function. Used to construct the longjmp target table used + /// by Windows Control Flow Guard. + const std::vector<MCSymbol *> &getLongjmpTargets() const { + return LongjmpTargets; + } + + /// Add the specified symbol to the list of valid longjmp targets for Windows + /// Control Flow Guard. + void addLongjmpTarget(MCSymbol *Target) { LongjmpTargets.push_back(Target); } + + /// Returns a reference to a list of symbols that we have catchrets. + /// Used to construct the catchret target table used by Windows EHCont Guard. + const std::vector<MCSymbol *> &getCatchretTargets() const { + return CatchretTargets; + } + + /// Add the specified symbol to the list of valid catchret targets for Windows + /// EHCont Guard. + void addCatchretTarget(MCSymbol *Target) { + CatchretTargets.push_back(Target); + } + + /// \name Exception Handling + /// \{ + + bool callsEHReturn() const { return CallsEHReturn; } + void setCallsEHReturn(bool b) { CallsEHReturn = b; } + + bool callsUnwindInit() const { return CallsUnwindInit; } + void setCallsUnwindInit(bool b) { CallsUnwindInit = b; } + + bool hasEHCatchret() const { return HasEHCatchret; } + void setHasEHCatchret(bool V) { HasEHCatchret = V; } + + bool hasEHScopes() const { return HasEHScopes; } + void setHasEHScopes(bool V) { HasEHScopes = V; } + + bool hasEHFunclets() const { return HasEHFunclets; } + void setHasEHFunclets(bool V) { HasEHFunclets = V; } + + /// Find or create an LandingPadInfo for the specified MachineBasicBlock. + LandingPadInfo &getOrCreateLandingPadInfo(MachineBasicBlock *LandingPad); + + /// Remap landing pad labels and remove any deleted landing pads. + void tidyLandingPads(DenseMap<MCSymbol *, uintptr_t> *LPMap = nullptr, + bool TidyIfNoBeginLabels = true); + + /// Return a reference to the landing pad info for the current function. + const std::vector<LandingPadInfo> &getLandingPads() const { + return LandingPads; + } + + /// Provide the begin and end labels of an invoke style call and associate it + /// with a try landing pad block. + void addInvoke(MachineBasicBlock *LandingPad, + MCSymbol *BeginLabel, MCSymbol *EndLabel); + + /// Add a new panding pad, and extract the exception handling information from + /// the landingpad instruction. Returns the label ID for the landing pad + /// entry. + MCSymbol *addLandingPad(MachineBasicBlock *LandingPad); + + /// Provide the catch typeinfo for a landing pad. + void addCatchTypeInfo(MachineBasicBlock *LandingPad, + ArrayRef<const GlobalValue *> TyInfo); + + /// Provide the filter typeinfo for a landing pad. + void addFilterTypeInfo(MachineBasicBlock *LandingPad, + ArrayRef<const GlobalValue *> TyInfo); + + /// Add a cleanup action for a landing pad. + void addCleanup(MachineBasicBlock *LandingPad); + + void addSEHCatchHandler(MachineBasicBlock *LandingPad, const Function *Filter, + const BlockAddress *RecoverBA); + + void addSEHCleanupHandler(MachineBasicBlock *LandingPad, + const Function *Cleanup); + + /// Return the type id for the specified typeinfo. This is function wide. + unsigned getTypeIDFor(const GlobalValue *TI); + + /// Return the id of the filter encoded by TyIds. This is function wide. + int getFilterIDFor(std::vector<unsigned> &TyIds); + + /// Map the landing pad's EH symbol to the call site indexes. + void setCallSiteLandingPad(MCSymbol *Sym, ArrayRef<unsigned> Sites); + + /// Map the landing pad to its index. Used for Wasm exception handling. + void setWasmLandingPadIndex(const MachineBasicBlock *LPad, unsigned Index) { + WasmLPadToIndexMap[LPad] = Index; + } + + /// Returns true if the landing pad has an associate index in wasm EH. + bool hasWasmLandingPadIndex(const MachineBasicBlock *LPad) const { + return WasmLPadToIndexMap.count(LPad); + } + + /// Get the index in wasm EH for a given landing pad. + unsigned getWasmLandingPadIndex(const MachineBasicBlock *LPad) const { + assert(hasWasmLandingPadIndex(LPad)); + return WasmLPadToIndexMap.lookup(LPad); + } + + /// Get the call site indexes for a landing pad EH symbol. + SmallVectorImpl<unsigned> &getCallSiteLandingPad(MCSymbol *Sym) { + assert(hasCallSiteLandingPad(Sym) && + "missing call site number for landing pad!"); + return LPadToCallSiteMap[Sym]; + } + + /// Return true if the landing pad Eh symbol has an associated call site. + bool hasCallSiteLandingPad(MCSymbol *Sym) { + return !LPadToCallSiteMap[Sym].empty(); + } + + /// Map the begin label for a call site. + void setCallSiteBeginLabel(MCSymbol *BeginLabel, unsigned Site) { + CallSiteMap[BeginLabel] = Site; + } + + /// Get the call site number for a begin label. + unsigned getCallSiteBeginLabel(MCSymbol *BeginLabel) const { + assert(hasCallSiteBeginLabel(BeginLabel) && + "Missing call site number for EH_LABEL!"); + return CallSiteMap.lookup(BeginLabel); + } + + /// Return true if the begin label has a call site number associated with it. + bool hasCallSiteBeginLabel(MCSymbol *BeginLabel) const { + return CallSiteMap.count(BeginLabel); + } + + /// Record annotations associated with a particular label. + void addCodeViewAnnotation(MCSymbol *Label, MDNode *MD) { + CodeViewAnnotations.push_back({Label, MD}); + } + + ArrayRef<std::pair<MCSymbol *, MDNode *>> getCodeViewAnnotations() const { + return CodeViewAnnotations; + } + + /// Return a reference to the C++ typeinfo for the current function. + const std::vector<const GlobalValue *> &getTypeInfos() const { + return TypeInfos; + } + + /// Return a reference to the typeids encoding filters used in the current + /// function. + const std::vector<unsigned> &getFilterIds() const { + return FilterIds; + } + + /// \} + + /// Collect information used to emit debugging information of a variable. + void setVariableDbgInfo(const DILocalVariable *Var, const DIExpression *Expr, + int Slot, const DILocation *Loc) { + VariableDbgInfos.emplace_back(Var, Expr, Slot, Loc); + } + + VariableDbgInfoMapTy &getVariableDbgInfo() { return VariableDbgInfos; } + const VariableDbgInfoMapTy &getVariableDbgInfo() const { + return VariableDbgInfos; + } + + /// Start tracking the arguments passed to the call \p CallI. + void addCallArgsForwardingRegs(const MachineInstr *CallI, + CallSiteInfoImpl &&CallInfo) { + assert(CallI->isCandidateForCallSiteEntry()); + bool Inserted = + CallSitesInfo.try_emplace(CallI, std::move(CallInfo)).second; + (void)Inserted; + assert(Inserted && "Call site info not unique"); + } + + const CallSiteInfoMap &getCallSitesInfo() const { + return CallSitesInfo; + } + + /// Following functions update call site info. They should be called before + /// removing, replacing or copying call instruction. + + /// Erase the call site info for \p MI. It is used to remove a call + /// instruction from the instruction stream. + void eraseCallSiteInfo(const MachineInstr *MI); + /// Copy the call site info from \p Old to \ New. Its usage is when we are + /// making a copy of the instruction that will be inserted at different point + /// of the instruction stream. + void copyCallSiteInfo(const MachineInstr *Old, + const MachineInstr *New); + + const std::vector<char> &getBBSectionsSymbolPrefix() const { + return BBSectionsSymbolPrefix; + } + + /// Move the call site info from \p Old to \New call site info. This function + /// is used when we are replacing one call instruction with another one to + /// the same callee. + void moveCallSiteInfo(const MachineInstr *Old, + const MachineInstr *New); + + unsigned getNewDebugInstrNum() { + return ++DebugInstrNumberingCount; + } +}; + +//===--------------------------------------------------------------------===// +// GraphTraits specializations for function basic block graphs (CFGs) +//===--------------------------------------------------------------------===// + +// Provide specializations of GraphTraits to be able to treat a +// machine function as a graph of machine basic blocks... these are +// the same as the machine basic block iterators, except that the root +// node is implicitly the first node of the function. +// +template <> struct GraphTraits<MachineFunction*> : + public GraphTraits<MachineBasicBlock*> { + static NodeRef getEntryNode(MachineFunction *F) { return &F->front(); } + + // nodes_iterator/begin/end - Allow iteration over all nodes in the graph + using nodes_iterator = pointer_iterator<MachineFunction::iterator>; + + static nodes_iterator nodes_begin(MachineFunction *F) { + return nodes_iterator(F->begin()); + } + + static nodes_iterator nodes_end(MachineFunction *F) { + return nodes_iterator(F->end()); + } + + static unsigned size (MachineFunction *F) { return F->size(); } +}; +template <> struct GraphTraits<const MachineFunction*> : + public GraphTraits<const MachineBasicBlock*> { + static NodeRef getEntryNode(const MachineFunction *F) { return &F->front(); } + + // nodes_iterator/begin/end - Allow iteration over all nodes in the graph + using nodes_iterator = pointer_iterator<MachineFunction::const_iterator>; + + static nodes_iterator nodes_begin(const MachineFunction *F) { + return nodes_iterator(F->begin()); + } + + static nodes_iterator nodes_end (const MachineFunction *F) { + return nodes_iterator(F->end()); + } + + static unsigned size (const MachineFunction *F) { + return F->size(); + } +}; + +// Provide specializations of GraphTraits to be able to treat a function as a +// graph of basic blocks... and to walk it in inverse order. Inverse order for +// a function is considered to be when traversing the predecessor edges of a BB +// instead of the successor edges. +// +template <> struct GraphTraits<Inverse<MachineFunction*>> : + public GraphTraits<Inverse<MachineBasicBlock*>> { + static NodeRef getEntryNode(Inverse<MachineFunction *> G) { + return &G.Graph->front(); + } +}; +template <> struct GraphTraits<Inverse<const MachineFunction*>> : + public GraphTraits<Inverse<const MachineBasicBlock*>> { + static NodeRef getEntryNode(Inverse<const MachineFunction *> G) { + return &G.Graph->front(); + } +}; + +class MachineFunctionAnalysisManager; +void verifyMachineFunction(MachineFunctionAnalysisManager *, + const std::string &Banner, + const MachineFunction &MF); + +} // end namespace llvm + +#endif // LLVM_CODEGEN_MACHINEFUNCTION_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif |