//===- 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.
  enum class Property : unsigned {
    IsSSA,
    NoPHIs,
    TracksLiveness,
    NoVRegs,
    FailedISel,
    Legalized,
    RegBankSelected,
    Selected,
    TiedOpsRewritten,
    FailsVerification,
    LastProperty = FailsVerification,
  };

  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, const 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
