265 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			265 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===-- llvm/CodeGen/SDNodeDbgValue.h - SelectionDAG dbg_value --*- 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
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| // This file declares the SDDbgValue class.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #ifndef LLVM_LIB_CODEGEN_SELECTIONDAG_SDNODEDBGVALUE_H
 | |
| #define LLVM_LIB_CODEGEN_SELECTIONDAG_SDNODEDBGVALUE_H
 | |
| 
 | |
| #include "llvm/IR/DebugLoc.h"
 | |
| #include "llvm/Support/Allocator.h"
 | |
| #include "llvm/Support/DataTypes.h"
 | |
| #include <utility>
 | |
| 
 | |
| namespace llvm {
 | |
| 
 | |
| class DIVariable;
 | |
| class DIExpression;
 | |
| class SDNode;
 | |
| class Value;
 | |
| class raw_ostream;
 | |
| 
 | |
| /// Holds the information for a single machine location through SDISel; either
 | |
| /// an SDNode, a constant, a stack location, or a virtual register.
 | |
| class SDDbgOperand {
 | |
| public:
 | |
|   enum Kind {
 | |
|     SDNODE = 0,  ///< Value is the result of an expression.
 | |
|     CONST = 1,   ///< Value is a constant.
 | |
|     FRAMEIX = 2, ///< Value is contents of a stack location.
 | |
|     VREG = 3     ///< Value is a virtual register.
 | |
|   };
 | |
|   Kind getKind() const { return kind; }
 | |
| 
 | |
|   /// Returns the SDNode* for a register ref
 | |
|   SDNode *getSDNode() const {
 | |
|     assert(kind == SDNODE);
 | |
|     return u.s.Node;
 | |
|   }
 | |
| 
 | |
|   /// Returns the ResNo for a register ref
 | |
|   unsigned getResNo() const {
 | |
|     assert(kind == SDNODE);
 | |
|     return u.s.ResNo;
 | |
|   }
 | |
| 
 | |
|   /// Returns the Value* for a constant
 | |
|   const Value *getConst() const {
 | |
|     assert(kind == CONST);
 | |
|     return u.Const;
 | |
|   }
 | |
| 
 | |
|   /// Returns the FrameIx for a stack object
 | |
|   unsigned getFrameIx() const {
 | |
|     assert(kind == FRAMEIX);
 | |
|     return u.FrameIx;
 | |
|   }
 | |
| 
 | |
|   /// Returns the Virtual Register for a VReg
 | |
|   unsigned getVReg() const {
 | |
|     assert(kind == VREG);
 | |
|     return u.VReg;
 | |
|   }
 | |
| 
 | |
|   static SDDbgOperand fromNode(SDNode *Node, unsigned ResNo) {
 | |
|     return SDDbgOperand(Node, ResNo);
 | |
|   }
 | |
|   static SDDbgOperand fromFrameIdx(unsigned FrameIdx) {
 | |
|     return SDDbgOperand(FrameIdx, FRAMEIX);
 | |
|   }
 | |
|   static SDDbgOperand fromVReg(unsigned VReg) {
 | |
|     return SDDbgOperand(VReg, VREG);
 | |
|   }
 | |
|   static SDDbgOperand fromConst(const Value *Const) {
 | |
|     return SDDbgOperand(Const);
 | |
|   }
 | |
| 
 | |
|   bool operator!=(const SDDbgOperand &Other) const { return !(*this == Other); }
 | |
|   bool operator==(const SDDbgOperand &Other) const {
 | |
|     if (kind != Other.kind)
 | |
|       return false;
 | |
|     switch (kind) {
 | |
|     case SDNODE:
 | |
|       return getSDNode() == Other.getSDNode() && getResNo() == Other.getResNo();
 | |
|     case CONST:
 | |
|       return getConst() == Other.getConst();
 | |
|     case VREG:
 | |
|       return getVReg() == Other.getVReg();
 | |
|     case FRAMEIX:
 | |
|       return getFrameIx() == Other.getFrameIx();
 | |
|     }
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
| private:
 | |
|   Kind kind;
 | |
|   union {
 | |
|     struct {
 | |
|       SDNode *Node;   ///< Valid for expressions.
 | |
|       unsigned ResNo; ///< Valid for expressions.
 | |
|     } s;
 | |
|     const Value *Const; ///< Valid for constants.
 | |
|     unsigned FrameIx;   ///< Valid for stack objects.
 | |
|     unsigned VReg;      ///< Valid for registers.
 | |
|   } u;
 | |
| 
 | |
|   /// Constructor for non-constants.
 | |
|   SDDbgOperand(SDNode *N, unsigned R) : kind(SDNODE) {
 | |
|     u.s.Node = N;
 | |
|     u.s.ResNo = R;
 | |
|   }
 | |
|   /// Constructor for constants.
 | |
|   SDDbgOperand(const Value *C) : kind(CONST) { u.Const = C; }
 | |
|   /// Constructor for virtual registers and frame indices.
 | |
|   SDDbgOperand(unsigned VRegOrFrameIdx, Kind Kind) : kind(Kind) {
 | |
|     assert((Kind == VREG || Kind == FRAMEIX) &&
 | |
|            "Invalid SDDbgValue constructor");
 | |
|     if (kind == VREG)
 | |
|       u.VReg = VRegOrFrameIdx;
 | |
|     else
 | |
|       u.FrameIx = VRegOrFrameIdx;
 | |
|   }
 | |
| };
 | |
| 
 | |
| /// Holds the information from a dbg_value node through SDISel.
 | |
| /// We do not use SDValue here to avoid including its header.
 | |
| class SDDbgValue {
 | |
| public:
 | |
| 
 | |
| private:
 | |
|   // SDDbgValues are allocated by a BumpPtrAllocator, which means the destructor
 | |
|   // may not be called; therefore all member arrays must also be allocated by
 | |
|   // that BumpPtrAllocator, to ensure that they are correctly freed.
 | |
|   size_t NumLocationOps;
 | |
|   SDDbgOperand *LocationOps;
 | |
|   // SDNode dependencies will be calculated as SDNodes that appear in
 | |
|   // LocationOps plus these AdditionalDependencies.
 | |
|   size_t NumAdditionalDependencies;
 | |
|   SDNode **AdditionalDependencies;
 | |
|   DIVariable *Var;
 | |
|   DIExpression *Expr;
 | |
|   DebugLoc DL;
 | |
|   unsigned Order;
 | |
|   bool IsIndirect;
 | |
|   bool IsVariadic;
 | |
|   bool Invalid = false;
 | |
|   bool Emitted = false;
 | |
| 
 | |
| public:
 | |
|   SDDbgValue(BumpPtrAllocator &Alloc, DIVariable *Var, DIExpression *Expr,
 | |
|              ArrayRef<SDDbgOperand> L, ArrayRef<SDNode *> Dependencies,
 | |
|              bool IsIndirect, DebugLoc DL, unsigned O, bool IsVariadic)
 | |
|       : NumLocationOps(L.size()),
 | |
|         LocationOps(Alloc.Allocate<SDDbgOperand>(L.size())),
 | |
|         NumAdditionalDependencies(Dependencies.size()),
 | |
|         AdditionalDependencies(Alloc.Allocate<SDNode *>(Dependencies.size())),
 | |
|         Var(Var), Expr(Expr), DL(DL), Order(O), IsIndirect(IsIndirect),
 | |
|         IsVariadic(IsVariadic) {
 | |
|     assert(IsVariadic || L.size() == 1);
 | |
|     assert(!(IsVariadic && IsIndirect));
 | |
|     std::copy(L.begin(), L.end(), LocationOps);
 | |
|     std::copy(Dependencies.begin(), Dependencies.end(), AdditionalDependencies);
 | |
|   }
 | |
| 
 | |
|   // We allocate arrays with the BumpPtrAllocator and never free or copy them,
 | |
|   // for LocationOps and AdditionalDependencies, as we never expect to copy or
 | |
|   // destroy an SDDbgValue. If we ever start copying or destroying instances, we
 | |
|   // should manage the allocated memory appropriately.
 | |
|   SDDbgValue(const SDDbgValue &Other) = delete;
 | |
|   SDDbgValue &operator=(const SDDbgValue &Other) = delete;
 | |
|   ~SDDbgValue() = delete;
 | |
| 
 | |
|   /// Returns the DIVariable pointer for the variable.
 | |
|   DIVariable *getVariable() const { return Var; }
 | |
| 
 | |
|   /// Returns the DIExpression pointer for the expression.
 | |
|   DIExpression *getExpression() const { return Expr; }
 | |
| 
 | |
|   ArrayRef<SDDbgOperand> getLocationOps() const {
 | |
|     return ArrayRef<SDDbgOperand>(LocationOps, NumLocationOps);
 | |
|   }
 | |
| 
 | |
|   SmallVector<SDDbgOperand> copyLocationOps() const {
 | |
|     return SmallVector<SDDbgOperand>(LocationOps, LocationOps + NumLocationOps);
 | |
|   }
 | |
| 
 | |
|   // Returns the SDNodes which this SDDbgValue depends on.
 | |
|   SmallVector<SDNode *> getSDNodes() const {
 | |
|     SmallVector<SDNode *> Dependencies;
 | |
|     for (const SDDbgOperand &DbgOp : getLocationOps())
 | |
|       if (DbgOp.getKind() == SDDbgOperand::SDNODE)
 | |
|         Dependencies.push_back(DbgOp.getSDNode());
 | |
|     for (SDNode *Node : getAdditionalDependencies())
 | |
|       Dependencies.push_back(Node);
 | |
|     return Dependencies;
 | |
|   }
 | |
| 
 | |
|   ArrayRef<SDNode *> getAdditionalDependencies() const {
 | |
|     return ArrayRef<SDNode *>(AdditionalDependencies,
 | |
|                               NumAdditionalDependencies);
 | |
|   }
 | |
| 
 | |
|   /// Returns whether this is an indirect value.
 | |
|   bool isIndirect() const { return IsIndirect; }
 | |
| 
 | |
|   bool isVariadic() const { return IsVariadic; }
 | |
| 
 | |
|   /// Returns the DebugLoc.
 | |
|   const DebugLoc &getDebugLoc() const { return DL; }
 | |
| 
 | |
|   /// Returns the SDNodeOrder.  This is the order of the preceding node in the
 | |
|   /// input.
 | |
|   unsigned getOrder() const { return Order; }
 | |
| 
 | |
|   /// setIsInvalidated / isInvalidated - Setter / getter of the "Invalidated"
 | |
|   /// property. A SDDbgValue is invalid if the SDNode that produces the value is
 | |
|   /// deleted.
 | |
|   void setIsInvalidated() { Invalid = true; }
 | |
|   bool isInvalidated() const { return Invalid; }
 | |
| 
 | |
|   /// setIsEmitted / isEmitted - Getter/Setter for flag indicating that this
 | |
|   /// SDDbgValue has been emitted to an MBB.
 | |
|   void setIsEmitted() { Emitted = true; }
 | |
|   bool isEmitted() const { return Emitted; }
 | |
| 
 | |
|   /// clearIsEmitted - Reset Emitted flag, for certain special cases where
 | |
|   /// dbg.addr is emitted twice.
 | |
|   void clearIsEmitted() { Emitted = false; }
 | |
| 
 | |
|   LLVM_DUMP_METHOD void dump() const;
 | |
|   LLVM_DUMP_METHOD void print(raw_ostream &OS) const;
 | |
| };
 | |
| 
 | |
| /// Holds the information from a dbg_label node through SDISel.
 | |
| /// We do not use SDValue here to avoid including its header.
 | |
| class SDDbgLabel {
 | |
|   MDNode *Label;
 | |
|   DebugLoc DL;
 | |
|   unsigned Order;
 | |
| 
 | |
| public:
 | |
|   SDDbgLabel(MDNode *Label, DebugLoc dl, unsigned O)
 | |
|       : Label(Label), DL(std::move(dl)), Order(O) {}
 | |
| 
 | |
|   /// Returns the MDNode pointer for the label.
 | |
|   MDNode *getLabel() const { return Label; }
 | |
| 
 | |
|   /// Returns the DebugLoc.
 | |
|   const DebugLoc &getDebugLoc() const { return DL; }
 | |
| 
 | |
|   /// Returns the SDNodeOrder.  This is the order of the preceding node in the
 | |
|   /// input.
 | |
|   unsigned getOrder() const { return Order; }
 | |
| };
 | |
| 
 | |
| } // end llvm namespace
 | |
| 
 | |
| #endif
 |