diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:17:04 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:17:04 +0000 |
| commit | b915e9e0fc85ba6f398b3fab0db6a81a8913af94 (patch) | |
| tree | 98b8f811c7aff2547cab8642daf372d6c59502fb /include/llvm/CodeGen/MachineFunction.h | |
| parent | 6421cca32f69ac849537a3cff78c352195e99f1b (diff) | |
Notes
Diffstat (limited to 'include/llvm/CodeGen/MachineFunction.h')
| -rw-r--r-- | include/llvm/CodeGen/MachineFunction.h | 352 |
1 files changed, 297 insertions, 55 deletions
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index 4aa9a92e6bee4..0c21b3254631e 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -20,10 +20,14 @@ #include "llvm/ADT/BitVector.h" #include "llvm/ADT/ilist.h" +#include "llvm/ADT/Optional.h" +#include "llvm/Analysis/EHPersonalities.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/Metadata.h" +#include "llvm/MC/MCDwarf.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/ArrayRecycler.h" #include "llvm/Support/Compiler.h" @@ -48,29 +52,18 @@ class TargetRegisterClass; struct MachinePointerInfo; struct WinEHFuncInfo; -template <> -struct ilist_traits<MachineBasicBlock> - : public ilist_default_traits<MachineBasicBlock> { - mutable ilist_half_node<MachineBasicBlock> Sentinel; -public: - // FIXME: This downcast is UB. See llvm.org/PR26753. - LLVM_NO_SANITIZE("object-size") - MachineBasicBlock *createSentinel() const { - return static_cast<MachineBasicBlock*>(&Sentinel); - } - void destroySentinel(MachineBasicBlock *) const {} - - MachineBasicBlock *provideInitialHead() const { return createSentinel(); } - MachineBasicBlock *ensureHead(MachineBasicBlock*) const { - return createSentinel(); - } - static void noteHead(MachineBasicBlock*, MachineBasicBlock*) {} +template <> struct ilist_alloc_traits<MachineBasicBlock> { + void deleteNode(MachineBasicBlock *MBB); +}; +template <> struct ilist_callback_traits<MachineBasicBlock> { void addNodeToList(MachineBasicBlock* MBB); void removeNodeFromList(MachineBasicBlock* MBB); - void deleteNode(MachineBasicBlock *MBB); -private: - void createNode(const MachineBasicBlock &); + + template <class Iterator> + void transferNodesFromList(ilist_callback_traits &OldList, Iterator, Iterator) { + llvm_unreachable("Never transfer between lists"); + } }; /// MachineFunctionInfo - This class can be derived from and used by targets to @@ -94,8 +87,6 @@ struct MachineFunctionInfo { /// Each of these has checking code in the MachineVerifier, and passes can /// require that a property be set. class MachineFunctionProperties { - // TODO: Add MachineVerifier checks for AllVRegsAllocated - // TODO: Add a way to print the properties and make more useful error messages // 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 @@ -108,6 +99,7 @@ public: // 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 @@ -115,13 +107,31 @@ public: // that affect the values in registers, for example by the register // scavenger. // When this property is clear, liveness is no longer reliable. - // AllVRegsAllocated: All virtual registers have been allocated; i.e. all - // register operands are physical registers. + // 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. enum class Property : unsigned { IsSSA, + NoPHIs, TracksLiveness, - AllVRegsAllocated, - LastProperty, + NoVRegs, + FailedISel, + Legalized, + RegBankSelected, + Selected, + LastProperty = Selected, }; bool hasProperty(Property P) const { @@ -131,15 +141,20 @@ public: Properties.set(static_cast<unsigned>(P)); return *this; } - MachineFunctionProperties &clear(Property P) { + 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 &clear(const MachineFunctionProperties &MFP) { + MachineFunctionProperties &reset(const MachineFunctionProperties &MFP) { Properties.reset(MFP.Properties); return *this; } @@ -149,13 +164,34 @@ public: return !V.Properties.test(Properties); } - // Print the MachineFunctionProperties in human-readable form. If OnlySet is - // true, only print the properties that are set. - void print(raw_ostream &ROS, bool OnlySet=false) const; + /// Print the MachineFunctionProperties in human-readable form. + void print(raw_ostream &OS) const; private: BitVector Properties = - BitVector(static_cast<unsigned>(Property::LastProperty)); + 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; // Label at beginning of landing pad. + std::vector<int> TypeIds; // List of type ids (filters negative). + + explicit LandingPadInfo(MachineBasicBlock *MBB) + : LandingPadBlock(MBB), LandingPadLabel(nullptr) {} }; class MachineFunction { @@ -224,6 +260,9 @@ class MachineFunction { /// True if the function includes any inline assembly. bool HasInlineAsm = false; + /// True if any WinCFI instruction have been emitted in this function. + Optional<bool> HasWinCFI; + /// Current high-level properties of the IR of the function (e.g. is in SSA /// form or whether registers have been allocated) MachineFunctionProperties Properties; @@ -231,13 +270,77 @@ class MachineFunction { // 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; + + /// \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 of invoke call site index values to associated begin EH_LABEL. + DenseMap<MCSymbol*, unsigned> CallSiteMap; + + bool CallsEHReturn = false; + bool CallsUnwindInit = false; + bool HasEHFunclets = false; + + /// 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; + + /// \} + MachineFunction(const MachineFunction &) = delete; void operator=(const MachineFunction&) = delete; + + /// 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; + unsigned Slot; + const DILocation *Loc; + + VariableDbgInfo(const DILocalVariable *Var, const DIExpression *Expr, + unsigned Slot, const DILocation *Loc) + : Var(Var), Expr(Expr), Slot(Slot), Loc(Loc) {} + }; + typedef SmallVector<VariableDbgInfo, 4> VariableDbgInfoMapTy; + VariableDbgInfoMapTy VariableDbgInfos; + MachineFunction(const Function *Fn, const TargetMachine &TM, unsigned FunctionNum, MachineModuleInfo &MMI); ~MachineFunction(); + /// Reset the instance as if it was just created. + void reset() { + clear(); + init(); + } + MachineModuleInfo &getMMI() const { return MMI; } MCContext &getContext() const { return Ctx; } @@ -283,8 +386,8 @@ public: /// 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; } + 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 @@ -345,6 +448,12 @@ public: HasInlineAsm = B; } + bool hasWinCFI() const { + assert(HasWinCFI.hasValue() && "HasWinCFI not set yet!"); + return *HasWinCFI; + } + void setHasWinCFI(bool v) { HasWinCFI = v; } + /// Get the function properties const MachineFunctionProperties &getProperties() const { return Properties; } MachineFunctionProperties &getProperties() { return Properties; } @@ -422,8 +531,8 @@ public: // Provide accessors for the MachineBasicBlock list... typedef BasicBlockListType::iterator iterator; typedef BasicBlockListType::const_iterator const_iterator; - typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - typedef std::reverse_iterator<iterator> reverse_iterator; + typedef BasicBlockListType::const_reverse_iterator const_reverse_iterator; + typedef BasicBlockListType::reverse_iterator reverse_iterator; /// Support for MachineBasicBlock::getNextNode(). static BasicBlockListType MachineFunction::* @@ -530,11 +639,13 @@ public: /// 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, unsigned base_alignment, - const AAMDNodes &AAInfo = AAMDNodes(), - const MDNode *Ranges = nullptr); + MachineMemOperand *getMachineMemOperand( + MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, + unsigned base_alignment, const AAMDNodes &AAInfo = AAMDNodes(), + const MDNode *Ranges = nullptr, + SynchronizationScope SynchScope = CrossThread, + 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. @@ -601,8 +712,139 @@ public: /// 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) { + FrameInstructions.push_back(Inst); + return FrameInstructions.size() - 1; + } + + /// \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 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); + + /// 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. 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 *RecoverLabel); + + 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); + + /// 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); + } + + /// 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, + unsigned Slot, const DILocation *Loc) { + VariableDbgInfos.emplace_back(Var, Expr, Slot, Loc); + } + + VariableDbgInfoMapTy &getVariableDbgInfo() { return VariableDbgInfos; } + const VariableDbgInfoMapTy &getVariableDbgInfo() const { + return VariableDbgInfos; + } }; +/// \name Exception Handling +/// \{ + +/// Extract the exception handling information from the landingpad instruction +/// and add them to the specified machine module info. +void addLandingPadInfo(const LandingPadInst &I, MachineBasicBlock &MBB); + +/// \} + //===--------------------------------------------------------------------===// // GraphTraits specializations for function basic block graphs (CFGs) //===--------------------------------------------------------------------===// @@ -614,29 +856,29 @@ public: // template <> struct GraphTraits<MachineFunction*> : public GraphTraits<MachineBasicBlock*> { - static NodeType *getEntryNode(MachineFunction *F) { - return &F->front(); - } + static NodeRef getEntryNode(MachineFunction *F) { return &F->front(); } // nodes_iterator/begin/end - Allow iteration over all nodes in the graph - typedef MachineFunction::iterator nodes_iterator; - static nodes_iterator nodes_begin(MachineFunction *F) { return F->begin(); } - static nodes_iterator nodes_end (MachineFunction *F) { return F->end(); } + typedef pointer_iterator<MachineFunction::iterator> nodes_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 NodeType *getEntryNode(const MachineFunction *F) { - return &F->front(); - } + static NodeRef getEntryNode(const MachineFunction *F) { return &F->front(); } // nodes_iterator/begin/end - Allow iteration over all nodes in the graph - typedef MachineFunction::const_iterator nodes_iterator; + typedef pointer_iterator<MachineFunction::const_iterator> nodes_iterator; static nodes_iterator nodes_begin(const MachineFunction *F) { - return F->begin(); + return nodes_iterator(F->begin()); } static nodes_iterator nodes_end (const MachineFunction *F) { - return F->end(); + return nodes_iterator(F->end()); } static unsigned size (const MachineFunction *F) { return F->size(); @@ -651,13 +893,13 @@ template <> struct GraphTraits<const MachineFunction*> : // template <> struct GraphTraits<Inverse<MachineFunction*> > : public GraphTraits<Inverse<MachineBasicBlock*> > { - static NodeType *getEntryNode(Inverse<MachineFunction*> G) { + static NodeRef getEntryNode(Inverse<MachineFunction *> G) { return &G.Graph->front(); } }; template <> struct GraphTraits<Inverse<const MachineFunction*> > : public GraphTraits<Inverse<const MachineBasicBlock*> > { - static NodeType *getEntryNode(Inverse<const MachineFunction *> G) { + static NodeRef getEntryNode(Inverse<const MachineFunction *> G) { return &G.Graph->front(); } }; |
