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/CodeGen/Register.h" 17 #include "llvm/IR/DebugLoc.h" 18 #include "llvm/Support/Allocator.h" 19 #include "llvm/Support/DataTypes.h" 20 #include <utility> 21 22 namespace llvm { 23 24 class DIVariable; 25 class DIExpression; 26 class SDNode; 27 class Value; 28 class raw_ostream; 29 30 /// Holds the information for a single machine location through SDISel; either 31 /// an SDNode, a constant, a stack location, or a virtual register. 32 class SDDbgOperand { 33 public: 34 enum Kind { 35 SDNODE = 0, ///< Value is the result of an expression. 36 CONST = 1, ///< Value is a constant. 37 FRAMEIX = 2, ///< Value is contents of a stack location. 38 VREG = 3 ///< Value is a virtual register. 39 }; getKind()40 Kind getKind() const { return kind; } 41 42 /// Returns the SDNode* for a register ref getSDNode()43 SDNode *getSDNode() const { 44 assert(kind == SDNODE); 45 return u.s.Node; 46 } 47 48 /// Returns the ResNo for a register ref getResNo()49 unsigned getResNo() const { 50 assert(kind == SDNODE); 51 return u.s.ResNo; 52 } 53 54 /// Returns the Value* for a constant getConst()55 const Value *getConst() const { 56 assert(kind == CONST); 57 return u.Const; 58 } 59 60 /// Returns the FrameIx for a stack object getFrameIx()61 unsigned getFrameIx() const { 62 assert(kind == FRAMEIX); 63 return u.FrameIx; 64 } 65 66 /// Returns the Virtual Register for a VReg getVReg()67 Register getVReg() const { 68 assert(kind == VREG); 69 return u.VReg; 70 } 71 fromNode(SDNode * Node,unsigned ResNo)72 static SDDbgOperand fromNode(SDNode *Node, unsigned ResNo) { 73 return SDDbgOperand(Node, ResNo); 74 } fromFrameIdx(unsigned FrameIdx)75 static SDDbgOperand fromFrameIdx(unsigned FrameIdx) { 76 return SDDbgOperand(FrameIdx, FRAMEIX); 77 } fromVReg(Register VReg)78 static SDDbgOperand fromVReg(Register VReg) { 79 return SDDbgOperand(VReg.id(), VREG); 80 } fromConst(const Value * Const)81 static SDDbgOperand fromConst(const Value *Const) { 82 return SDDbgOperand(Const); 83 } 84 85 bool operator!=(const SDDbgOperand &Other) const { return !(*this == Other); } 86 bool operator==(const SDDbgOperand &Other) const { 87 if (kind != Other.kind) 88 return false; 89 switch (kind) { 90 case SDNODE: 91 return getSDNode() == Other.getSDNode() && getResNo() == Other.getResNo(); 92 case CONST: 93 return getConst() == Other.getConst(); 94 case VREG: 95 return getVReg() == Other.getVReg(); 96 case FRAMEIX: 97 return getFrameIx() == Other.getFrameIx(); 98 } 99 return false; 100 } 101 102 private: 103 Kind kind; 104 union { 105 struct { 106 SDNode *Node; ///< Valid for expressions. 107 unsigned ResNo; ///< Valid for expressions. 108 } s; 109 const Value *Const; ///< Valid for constants. 110 unsigned FrameIx; ///< Valid for stack objects. 111 unsigned VReg; ///< Valid for registers. 112 } u; 113 114 /// Constructor for non-constants. SDDbgOperand(SDNode * N,unsigned R)115 SDDbgOperand(SDNode *N, unsigned R) : kind(SDNODE) { 116 u.s.Node = N; 117 u.s.ResNo = R; 118 } 119 /// Constructor for constants. SDDbgOperand(const Value * C)120 SDDbgOperand(const Value *C) : kind(CONST) { u.Const = C; } 121 /// Constructor for virtual registers and frame indices. SDDbgOperand(unsigned VRegOrFrameIdx,Kind Kind)122 SDDbgOperand(unsigned VRegOrFrameIdx, Kind Kind) : kind(Kind) { 123 assert((Kind == VREG || Kind == FRAMEIX) && 124 "Invalid SDDbgValue constructor"); 125 if (kind == VREG) 126 u.VReg = VRegOrFrameIdx; 127 else 128 u.FrameIx = VRegOrFrameIdx; 129 } 130 }; 131 132 /// Holds the information from a dbg_value node through SDISel. 133 /// We do not use SDValue here to avoid including its header. 134 class SDDbgValue { 135 public: 136 137 private: 138 // SDDbgValues are allocated by a BumpPtrAllocator, which means the destructor 139 // may not be called; therefore all member arrays must also be allocated by 140 // that BumpPtrAllocator, to ensure that they are correctly freed. 141 size_t NumLocationOps; 142 SDDbgOperand *LocationOps; 143 // SDNode dependencies will be calculated as SDNodes that appear in 144 // LocationOps plus these AdditionalDependencies. 145 size_t NumAdditionalDependencies; 146 SDNode **AdditionalDependencies; 147 DIVariable *Var; 148 DIExpression *Expr; 149 DebugLoc DL; 150 unsigned Order; 151 bool IsIndirect; 152 bool IsVariadic; 153 bool Invalid = false; 154 bool Emitted = false; 155 156 public: SDDbgValue(BumpPtrAllocator & Alloc,DIVariable * Var,DIExpression * Expr,ArrayRef<SDDbgOperand> L,ArrayRef<SDNode * > Dependencies,bool IsIndirect,DebugLoc DL,unsigned O,bool IsVariadic)157 SDDbgValue(BumpPtrAllocator &Alloc, DIVariable *Var, DIExpression *Expr, 158 ArrayRef<SDDbgOperand> L, ArrayRef<SDNode *> Dependencies, 159 bool IsIndirect, DebugLoc DL, unsigned O, bool IsVariadic) 160 : NumLocationOps(L.size()), 161 LocationOps(Alloc.Allocate<SDDbgOperand>(L.size())), 162 NumAdditionalDependencies(Dependencies.size()), 163 AdditionalDependencies(Alloc.Allocate<SDNode *>(Dependencies.size())), 164 Var(Var), Expr(Expr), DL(DL), Order(O), IsIndirect(IsIndirect), 165 IsVariadic(IsVariadic) { 166 assert(IsVariadic || L.size() == 1); 167 assert(!(IsVariadic && IsIndirect)); 168 llvm::copy(L, LocationOps); 169 llvm::copy(Dependencies, AdditionalDependencies); 170 } 171 172 // We allocate arrays with the BumpPtrAllocator and never free or copy them, 173 // for LocationOps and AdditionalDependencies, as we never expect to copy or 174 // destroy an SDDbgValue. If we ever start copying or destroying instances, we 175 // should manage the allocated memory appropriately. 176 SDDbgValue(const SDDbgValue &Other) = delete; 177 SDDbgValue &operator=(const SDDbgValue &Other) = delete; 178 ~SDDbgValue() = delete; 179 180 /// Returns the DIVariable pointer for the variable. getVariable()181 DIVariable *getVariable() const { return Var; } 182 183 /// Returns the DIExpression pointer for the expression. getExpression()184 DIExpression *getExpression() const { return Expr; } 185 getLocationOps()186 ArrayRef<SDDbgOperand> getLocationOps() const { 187 return ArrayRef<SDDbgOperand>(LocationOps, NumLocationOps); 188 } 189 copyLocationOps()190 SmallVector<SDDbgOperand> copyLocationOps() const { 191 return SmallVector<SDDbgOperand>(LocationOps, LocationOps + NumLocationOps); 192 } 193 194 // Returns the SDNodes which this SDDbgValue depends on. getSDNodes()195 SmallVector<SDNode *> getSDNodes() const { 196 SmallVector<SDNode *> Dependencies; 197 for (const SDDbgOperand &DbgOp : getLocationOps()) 198 if (DbgOp.getKind() == SDDbgOperand::SDNODE) 199 Dependencies.push_back(DbgOp.getSDNode()); 200 llvm::append_range(Dependencies, getAdditionalDependencies()); 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