Home | History | Annotate | Line # | Download | only in SelectionDAG
      1 //===-- llvm/CodeGen/SDNodeDbgValue.h - SelectionDAG dbg_value --*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // This file declares the SDDbgValue class.
     10 //
     11 //===----------------------------------------------------------------------===//
     12 
     13 #ifndef LLVM_LIB_CODEGEN_SELECTIONDAG_SDNODEDBGVALUE_H
     14 #define LLVM_LIB_CODEGEN_SELECTIONDAG_SDNODEDBGVALUE_H
     15 
     16 #include "llvm/IR/DebugLoc.h"
     17 #include "llvm/Support/DataTypes.h"
     18 #include <utility>
     19 
     20 namespace llvm {
     21 
     22 class DIVariable;
     23 class DIExpression;
     24 class SDNode;
     25 class Value;
     26 class raw_ostream;
     27 
     28 /// Holds the information for a single machine location through SDISel; either
     29 /// an SDNode, a constant, a stack location, or a virtual register.
     30 class SDDbgOperand {
     31 public:
     32   enum Kind {
     33     SDNODE = 0,  ///< Value is the result of an expression.
     34     CONST = 1,   ///< Value is a constant.
     35     FRAMEIX = 2, ///< Value is contents of a stack location.
     36     VREG = 3     ///< Value is a virtual register.
     37   };
     38   Kind getKind() const { return kind; }
     39 
     40   /// Returns the SDNode* for a register ref
     41   SDNode *getSDNode() const {
     42     assert(kind == SDNODE);
     43     return u.s.Node;
     44   }
     45 
     46   /// Returns the ResNo for a register ref
     47   unsigned getResNo() const {
     48     assert(kind == SDNODE);
     49     return u.s.ResNo;
     50   }
     51 
     52   /// Returns the Value* for a constant
     53   const Value *getConst() const {
     54     assert(kind == CONST);
     55     return u.Const;
     56   }
     57 
     58   /// Returns the FrameIx for a stack object
     59   unsigned getFrameIx() const {
     60     assert(kind == FRAMEIX);
     61     return u.FrameIx;
     62   }
     63 
     64   /// Returns the Virtual Register for a VReg
     65   unsigned getVReg() const {
     66     assert(kind == VREG);
     67     return u.VReg;
     68   }
     69 
     70   static SDDbgOperand fromNode(SDNode *Node, unsigned ResNo) {
     71     return SDDbgOperand(Node, ResNo);
     72   }
     73   static SDDbgOperand fromFrameIdx(unsigned FrameIdx) {
     74     return SDDbgOperand(FrameIdx, FRAMEIX);
     75   }
     76   static SDDbgOperand fromVReg(unsigned VReg) {
     77     return SDDbgOperand(VReg, VREG);
     78   }
     79   static SDDbgOperand fromConst(const Value *Const) {
     80     return SDDbgOperand(Const);
     81   }
     82 
     83   bool operator!=(const SDDbgOperand &Other) const { return !(*this == Other); }
     84   bool operator==(const SDDbgOperand &Other) const {
     85     if (kind != Other.kind)
     86       return false;
     87     switch (kind) {
     88     case SDNODE:
     89       return getSDNode() == Other.getSDNode() && getResNo() == Other.getResNo();
     90     case CONST:
     91       return getConst() == Other.getConst();
     92     case VREG:
     93       return getVReg() == Other.getVReg();
     94     case FRAMEIX:
     95       return getFrameIx() == Other.getFrameIx();
     96     }
     97     return false;
     98   }
     99 
    100 private:
    101   Kind kind;
    102   union {
    103     struct {
    104       SDNode *Node;   ///< Valid for expressions.
    105       unsigned ResNo; ///< Valid for expressions.
    106     } s;
    107     const Value *Const; ///< Valid for constants.
    108     unsigned FrameIx;   ///< Valid for stack objects.
    109     unsigned VReg;      ///< Valid for registers.
    110   } u;
    111 
    112   /// Constructor for non-constants.
    113   SDDbgOperand(SDNode *N, unsigned R) : kind(SDNODE) {
    114     u.s.Node = N;
    115     u.s.ResNo = R;
    116   }
    117   /// Constructor for constants.
    118   SDDbgOperand(const Value *C) : kind(CONST) { u.Const = C; }
    119   /// Constructor for virtual registers and frame indices.
    120   SDDbgOperand(unsigned VRegOrFrameIdx, Kind Kind) : kind(Kind) {
    121     assert((Kind == VREG || Kind == FRAMEIX) &&
    122            "Invalid SDDbgValue constructor");
    123     if (kind == VREG)
    124       u.VReg = VRegOrFrameIdx;
    125     else
    126       u.FrameIx = VRegOrFrameIdx;
    127   }
    128 };
    129 
    130 /// Holds the information from a dbg_value node through SDISel.
    131 /// We do not use SDValue here to avoid including its header.
    132 class SDDbgValue {
    133 public:
    134 
    135 private:
    136   // SDDbgValues are allocated by a BumpPtrAllocator, which means the destructor
    137   // may not be called; therefore all member arrays must also be allocated by
    138   // that BumpPtrAllocator, to ensure that they are correctly freed.
    139   size_t NumLocationOps;
    140   SDDbgOperand *LocationOps;
    141   // SDNode dependencies will be calculated as SDNodes that appear in
    142   // LocationOps plus these AdditionalDependencies.
    143   size_t NumAdditionalDependencies;
    144   SDNode **AdditionalDependencies;
    145   DIVariable *Var;
    146   DIExpression *Expr;
    147   DebugLoc DL;
    148   unsigned Order;
    149   bool IsIndirect;
    150   bool IsVariadic;
    151   bool Invalid = false;
    152   bool Emitted = false;
    153 
    154 public:
    155   SDDbgValue(BumpPtrAllocator &Alloc, DIVariable *Var, DIExpression *Expr,
    156              ArrayRef<SDDbgOperand> L, ArrayRef<SDNode *> Dependencies,
    157              bool IsIndirect, DebugLoc DL, unsigned O, bool IsVariadic)
    158       : NumLocationOps(L.size()),
    159         LocationOps(Alloc.Allocate<SDDbgOperand>(L.size())),
    160         NumAdditionalDependencies(Dependencies.size()),
    161         AdditionalDependencies(Alloc.Allocate<SDNode *>(Dependencies.size())),
    162         Var(Var), Expr(Expr), DL(DL), Order(O), IsIndirect(IsIndirect),
    163         IsVariadic(IsVariadic) {
    164     assert(IsVariadic || L.size() == 1);
    165     assert(!(IsVariadic && IsIndirect));
    166     std::copy(L.begin(), L.end(), LocationOps);
    167     std::copy(Dependencies.begin(), Dependencies.end(), AdditionalDependencies);
    168   }
    169 
    170   // We allocate arrays with the BumpPtrAllocator and never free or copy them,
    171   // for LocationOps and AdditionalDependencies, as we never expect to copy or
    172   // destroy an SDDbgValue. If we ever start copying or destroying instances, we
    173   // should manage the allocated memory appropriately.
    174   SDDbgValue(const SDDbgValue &Other) = delete;
    175   SDDbgValue &operator=(const SDDbgValue &Other) = delete;
    176   ~SDDbgValue() = delete;
    177 
    178   /// Returns the DIVariable pointer for the variable.
    179   DIVariable *getVariable() const { return Var; }
    180 
    181   /// Returns the DIExpression pointer for the expression.
    182   DIExpression *getExpression() const { return Expr; }
    183 
    184   ArrayRef<SDDbgOperand> getLocationOps() const {
    185     return ArrayRef<SDDbgOperand>(LocationOps, NumLocationOps);
    186   }
    187 
    188   SmallVector<SDDbgOperand> copyLocationOps() const {
    189     return SmallVector<SDDbgOperand>(LocationOps, LocationOps + NumLocationOps);
    190   }
    191 
    192   // Returns the SDNodes which this SDDbgValue depends on.
    193   SmallVector<SDNode *> getSDNodes() const {
    194     SmallVector<SDNode *> Dependencies;
    195     for (SDDbgOperand DbgOp : getLocationOps())
    196       if (DbgOp.getKind() == SDDbgOperand::SDNODE)
    197         Dependencies.push_back(DbgOp.getSDNode());
    198     for (SDNode *Node : getAdditionalDependencies())
    199       Dependencies.push_back(Node);
    200     return Dependencies;
    201   }
    202 
    203   ArrayRef<SDNode *> getAdditionalDependencies() const {
    204     return ArrayRef<SDNode *>(AdditionalDependencies,
    205                               NumAdditionalDependencies);
    206   }
    207 
    208   /// Returns whether this is an indirect value.
    209   bool isIndirect() const { return IsIndirect; }
    210 
    211   bool isVariadic() const { return IsVariadic; }
    212 
    213   /// Returns the DebugLoc.
    214   const DebugLoc &getDebugLoc() const { return DL; }
    215 
    216   /// Returns the SDNodeOrder.  This is the order of the preceding node in the
    217   /// input.
    218   unsigned getOrder() const { return Order; }
    219 
    220   /// setIsInvalidated / isInvalidated - Setter / getter of the "Invalidated"
    221   /// property. A SDDbgValue is invalid if the SDNode that produces the value is
    222   /// deleted.
    223   void setIsInvalidated() { Invalid = true; }
    224   bool isInvalidated() const { return Invalid; }
    225 
    226   /// setIsEmitted / isEmitted - Getter/Setter for flag indicating that this
    227   /// SDDbgValue has been emitted to an MBB.
    228   void setIsEmitted() { Emitted = true; }
    229   bool isEmitted() const { return Emitted; }
    230 
    231   /// clearIsEmitted - Reset Emitted flag, for certain special cases where
    232   /// dbg.addr is emitted twice.
    233   void clearIsEmitted() { Emitted = false; }
    234 
    235   LLVM_DUMP_METHOD void dump() const;
    236   LLVM_DUMP_METHOD void print(raw_ostream &OS) const;
    237 };
    238 
    239 /// Holds the information from a dbg_label node through SDISel.
    240 /// We do not use SDValue here to avoid including its header.
    241 class SDDbgLabel {
    242   MDNode *Label;
    243   DebugLoc DL;
    244   unsigned Order;
    245 
    246 public:
    247   SDDbgLabel(MDNode *Label, DebugLoc dl, unsigned O)
    248       : Label(Label), DL(std::move(dl)), Order(O) {}
    249 
    250   /// Returns the MDNode pointer for the label.
    251   MDNode *getLabel() const { return Label; }
    252 
    253   /// Returns the DebugLoc.
    254   const DebugLoc &getDebugLoc() const { return DL; }
    255 
    256   /// Returns the SDNodeOrder.  This is the order of the preceding node in the
    257   /// input.
    258   unsigned getOrder() const { return Order; }
    259 };
    260 
    261 } // end llvm namespace
    262 
    263 #endif
    264