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
21namespace llvm {
22
23class DIVariable;
24class DIExpression;
25class SDNode;
26class Value;
27class 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.
31class SDDbgOperand {
32public:
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 };
39 Kind getKind() const { return kind; }
40
41 /// Returns the SDNode* for a register ref
42 SDNode *getSDNode() const {
43 assert(kind == SDNODE);
44 return u.s.Node;
45 }
46
47 /// Returns the ResNo for a register ref
48 unsigned getResNo() const {
49 assert(kind == SDNODE);
50 return u.s.ResNo;
51 }
52
53 /// Returns the Value* for a constant
54 const Value *getConst() const {
55 assert(kind == CONST);
56 return u.Const;
57 }
58
59 /// Returns the FrameIx for a stack object
60 unsigned getFrameIx() const {
61 assert(kind == FRAMEIX);
62 return u.FrameIx;
63 }
64
65 /// Returns the Virtual Register for a VReg
66 unsigned getVReg() const {
67 assert(kind == VREG);
68 return u.VReg;
69 }
70
71 static SDDbgOperand fromNode(SDNode *Node, unsigned ResNo) {
72 return SDDbgOperand(Node, ResNo);
73 }
74 static SDDbgOperand fromFrameIdx(unsigned FrameIdx) {
75 return SDDbgOperand(FrameIdx, FRAMEIX);
76 }
77 static SDDbgOperand fromVReg(unsigned VReg) {
78 return SDDbgOperand(VReg, VREG);
79 }
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
101private:
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.
114 SDDbgOperand(SDNode *N, unsigned R) : kind(SDNODE) {
115 u.s.Node = N;
116 u.s.ResNo = R;
117 }
118 /// Constructor for constants.
119 SDDbgOperand(const Value *C) : kind(CONST) { u.Const = C; }
120 /// Constructor for virtual registers and frame indices.
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.
133class SDDbgValue {
134public:
135
136private:
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
155public:
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>(Num: L.size())),
161 NumAdditionalDependencies(Dependencies.size()),
162 AdditionalDependencies(Alloc.Allocate<SDNode *>(Num: 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.
180 DIVariable *getVariable() const { return Var; }
181
182 /// Returns the DIExpression pointer for the expression.
183 DIExpression *getExpression() const { return Expr; }
184
185 ArrayRef<SDDbgOperand> getLocationOps() const {
186 return ArrayRef<SDDbgOperand>(LocationOps, NumLocationOps);
187 }
188
189 SmallVector<SDDbgOperand> copyLocationOps() const {
190 return SmallVector<SDDbgOperand>(LocationOps, LocationOps + NumLocationOps);
191 }
192
193 // Returns the SDNodes which this SDDbgValue depends on.
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(Elt: DbgOp.getSDNode());
199 for (SDNode *Node : getAdditionalDependencies())
200 Dependencies.push_back(Elt: Node);
201 return Dependencies;
202 }
203
204 ArrayRef<SDNode *> getAdditionalDependencies() const {
205 return ArrayRef<SDNode *>(AdditionalDependencies,
206 NumAdditionalDependencies);
207 }
208
209 /// Returns whether this is an indirect value.
210 bool isIndirect() const { return IsIndirect; }
211
212 bool isVariadic() const { return IsVariadic; }
213
214 /// Returns the DebugLoc.
215 const DebugLoc &getDebugLoc() const { return DL; }
216
217 /// Returns the SDNodeOrder. This is the order of the preceding node in the
218 /// input.
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.
224 void setIsInvalidated() { Invalid = true; }
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.
229 void setIsEmitted() { Emitted = true; }
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.
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.
242class SDDbgLabel {
243 MDNode *Label;
244 DebugLoc DL;
245 unsigned Order;
246
247public:
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.
252 MDNode *getLabel() const { return Label; }
253
254 /// Returns the DebugLoc.
255 const DebugLoc &getDebugLoc() const { return DL; }
256
257 /// Returns the SDNodeOrder. This is the order of the preceding node in the
258 /// input.
259 unsigned getOrder() const { return Order; }
260};
261
262} // end llvm namespace
263
264#endif
265