diff options
| author | orivej <[email protected]> | 2022-02-10 16:44:49 +0300 |
|---|---|---|
| committer | Daniil Cherednik <[email protected]> | 2022-02-10 16:44:49 +0300 |
| commit | 718c552901d703c502ccbefdfc3c9028d608b947 (patch) | |
| tree | 46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/libs/llvm12/include/llvm/CodeGen/MachineFunction.h | |
| parent | e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff) | |
Restoring authorship annotation for <[email protected]>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/llvm12/include/llvm/CodeGen/MachineFunction.h')
| -rw-r--r-- | contrib/libs/llvm12/include/llvm/CodeGen/MachineFunction.h | 2288 |
1 files changed, 1144 insertions, 1144 deletions
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachineFunction.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachineFunction.h index 8b89caedf64..d7c89fd2146 100644 --- a/contrib/libs/llvm12/include/llvm/CodeGen/MachineFunction.h +++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachineFunction.h @@ -1,443 +1,443 @@ -#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. kill flags, implicit - // defs) is accurate. 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 clear, 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. - enum class Property : unsigned { - IsSSA, - NoPHIs, - TracksLiveness, - NoVRegs, - FailedISel, - Legalized, - RegBankSelected, - Selected, - TiedOpsRewritten, - LastProperty = TiedOpsRewritten, - }; - - 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 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; - - /// \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 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; - +#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. kill flags, implicit + // defs) is accurate. 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 clear, 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. + enum class Property : unsigned { + IsSSA, + NoPHIs, + TracksLiveness, + NoVRegs, + FailedISel, + Legalized, + RegBankSelected, + Selected, + TiedOpsRewritten, + LastProperty = TiedOpsRewritten, + }; + + 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 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; + + /// \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 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. @@ -471,388 +471,388 @@ public: void substituteDebugValuesForInst(const MachineInstr &Old, MachineInstr &New, unsigned MaxOperand = UINT_MAX); - 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 || + 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, + } + + /// 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); - - /// 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, uint64_t Size); - + + /// 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); + + /// 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, uint64_t 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 @@ -861,337 +861,337 @@ public: MachinePointerInfo &PtrInfo, uint64_t Size); - /// 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); } - - /// \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 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); + /// 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); } + + /// \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 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(); - } -}; - +}; + +//===--------------------------------------------------------------------===// +// 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 +} // end namespace llvm + +#endif // LLVM_CODEGEN_MACHINEFUNCTION_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif |
