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