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   // FIXME: These SmallVector sizes were chosen without any kind of performance
135   // testing.
136   using LocOpVector = SmallVector<SDDbgOperand, 2>;
137   using SDNodeVector = SmallVector<SDNode *, 2>;
138 
139 private:
140   LocOpVector LocationOps;
141   SDNodeVector SDNodes;
142   DIVariable *Var;
143   DIExpression *Expr;
144   DebugLoc DL;
145   unsigned Order;
146   bool IsIndirect;
147   bool IsVariadic;
148   bool Invalid = false;
149   bool Emitted = false;
150 
151 public:
152   SDDbgValue(DIVariable *Var, DIExpression *Expr, ArrayRef<SDDbgOperand> L,
153              ArrayRef<SDNode *> Dependencies, bool IsIndirect, DebugLoc DL,
154              unsigned O, bool IsVariadic)
155       : LocationOps(L.begin(), L.end()),
156         SDNodes(Dependencies.begin(), Dependencies.end()), Var(Var), Expr(Expr),
157         DL(DL), Order(O), IsIndirect(IsIndirect), IsVariadic(IsVariadic) {
158     assert(IsVariadic || L.size() == 1);
159     assert(!(IsVariadic && IsIndirect));
160   }
161 
162   /// Returns the DIVariable pointer for the variable.
163   DIVariable *getVariable() const { return Var; }
164 
165   /// Returns the DIExpression pointer for the expression.
166   DIExpression *getExpression() const { return Expr; }
167 
168   ArrayRef<SDDbgOperand> getLocationOps() const { return LocationOps; }
169 
170   LocOpVector copyLocationOps() const { return LocationOps; }
171 
172   // Returns the SDNodes which this SDDbgValue depends on.
173   ArrayRef<SDNode *> getSDNodes() const { return SDNodes; }
174 
175   SDNodeVector copySDNodes() const { return SDNodes; }
176 
177   /// Returns whether this is an indirect value.
178   bool isIndirect() const { return IsIndirect; }
179 
180   bool isVariadic() const { return IsVariadic; }
181 
182   /// Returns the DebugLoc.
183   DebugLoc getDebugLoc() const { return DL; }
184 
185   /// Returns the SDNodeOrder.  This is the order of the preceding node in the
186   /// input.
187   unsigned getOrder() const { return Order; }
188 
189   /// setIsInvalidated / isInvalidated - Setter / getter of the "Invalidated"
190   /// property. A SDDbgValue is invalid if the SDNode that produces the value is
191   /// deleted.
192   void setIsInvalidated() { Invalid = true; }
193   bool isInvalidated() const { return Invalid; }
194 
195   /// setIsEmitted / isEmitted - Getter/Setter for flag indicating that this
196   /// SDDbgValue has been emitted to an MBB.
197   void setIsEmitted() { Emitted = true; }
198   bool isEmitted() const { return Emitted; }
199 
200   /// clearIsEmitted - Reset Emitted flag, for certain special cases where
201   /// dbg.addr is emitted twice.
202   void clearIsEmitted() { Emitted = false; }
203 
204   LLVM_DUMP_METHOD void dump() const;
205   LLVM_DUMP_METHOD void print(raw_ostream &OS) const;
206 };
207 
208 /// Holds the information from a dbg_label node through SDISel.
209 /// We do not use SDValue here to avoid including its header.
210 class SDDbgLabel {
211   MDNode *Label;
212   DebugLoc DL;
213   unsigned Order;
214 
215 public:
216   SDDbgLabel(MDNode *Label, DebugLoc dl, unsigned O)
217       : Label(Label), DL(std::move(dl)), Order(O) {}
218 
219   /// Returns the MDNode pointer for the label.
220   MDNode *getLabel() const { return Label; }
221 
222   /// Returns the DebugLoc.
223   DebugLoc getDebugLoc() const { return DL; }
224 
225   /// Returns the SDNodeOrder.  This is the order of the preceding node in the
226   /// input.
227   unsigned getOrder() const { return Order; }
228 };
229 
230 } // end llvm namespace
231 
232 #endif
233