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
20namespace llvm {
21
22class DIVariable;
23class DIExpression;
24class SDNode;
25class Value;
26class 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.
30class SDDbgOperand {
31public:
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
100private:
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.
132class SDDbgValue {
133public:
134
135private:
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
154public:
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 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.
241class SDDbgLabel {
242 MDNode *Label;
243 DebugLoc DL;
244 unsigned Order;
245
246public:
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 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