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
22namespace llvm {
23
24class DIVariable;
25class DIExpression;
26class SDNode;
27class Value;
28class 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.
32class SDDbgOperand {
33public:
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 };
40 Kind getKind() const { return kind; }
41
42 /// Returns the SDNode* for a register ref
43 SDNode *getSDNode() const {
44 assert(kind == SDNODE);
45 return u.s.Node;
46 }
47
48 /// Returns the ResNo for a register ref
49 unsigned getResNo() const {
50 assert(kind == SDNODE);
51 return u.s.ResNo;
52 }
53
54 /// Returns the Value* for a constant
55 const Value *getConst() const {
56 assert(kind == CONST);
57 return u.Const;
58 }
59
60 /// Returns the FrameIx for a stack object
61 unsigned getFrameIx() const {
62 assert(kind == FRAMEIX);
63 return u.FrameIx;
64 }
65
66 /// Returns the Virtual Register for a VReg
67 Register getVReg() const {
68 assert(kind == VREG);
69 return u.VReg;
70 }
71
72 static SDDbgOperand fromNode(SDNode *Node, unsigned ResNo) {
73 return SDDbgOperand(Node, ResNo);
74 }
75 static SDDbgOperand fromFrameIdx(unsigned FrameIdx) {
76 return SDDbgOperand(FrameIdx, FRAMEIX);
77 }
78 static SDDbgOperand fromVReg(Register VReg) {
79 return SDDbgOperand(VReg.id(), VREG);
80 }
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
102private:
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.
115 SDDbgOperand(SDNode *N, unsigned R) : kind(SDNODE) {
116 u.s.Node = N;
117 u.s.ResNo = R;
118 }
119 /// Constructor for constants.
120 SDDbgOperand(const Value *C) : kind(CONST) { u.Const = C; }
121 /// Constructor for virtual registers and frame indices.
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.
134class SDDbgValue {
135public:
136
137private:
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
156public:
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>(Num: L.size())),
162 NumAdditionalDependencies(Dependencies.size()),
163 AdditionalDependencies(Alloc.Allocate<SDNode *>(Num: 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(Range&: L, Out: LocationOps);
169 llvm::copy(Range&: Dependencies, Out: 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.
181 DIVariable *getVariable() const { return Var; }
182
183 /// Returns the DIExpression pointer for the expression.
184 DIExpression *getExpression() const { return Expr; }
185
186 ArrayRef<SDDbgOperand> getLocationOps() const {
187 return ArrayRef<SDDbgOperand>(LocationOps, NumLocationOps);
188 }
189
190 SmallVector<SDDbgOperand> copyLocationOps() const {
191 return SmallVector<SDDbgOperand>(LocationOps, LocationOps + NumLocationOps);
192 }
193
194 // Returns the SDNodes which this SDDbgValue depends on.
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(Elt: DbgOp.getSDNode());
200 llvm::append_range(C&: Dependencies, R: getAdditionalDependencies());
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