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