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