xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h (revision fe6060f10f634930ff71b7c50291ddc610da2475)
10b57cec5SDimitry Andric //===-- llvm/CodeGen/SDNodeDbgValue.h - SelectionDAG dbg_value --*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file declares the SDDbgValue class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_LIB_CODEGEN_SELECTIONDAG_SDNODEDBGVALUE_H
140b57cec5SDimitry Andric #define LLVM_LIB_CODEGEN_SELECTIONDAG_SDNODEDBGVALUE_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h"
170b57cec5SDimitry Andric #include "llvm/Support/DataTypes.h"
180b57cec5SDimitry Andric #include <utility>
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric namespace llvm {
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric class DIVariable;
230b57cec5SDimitry Andric class DIExpression;
240b57cec5SDimitry Andric class SDNode;
250b57cec5SDimitry Andric class Value;
260b57cec5SDimitry Andric class raw_ostream;
270b57cec5SDimitry Andric 
28*fe6060f1SDimitry Andric /// Holds the information for a single machine location through SDISel; either
29*fe6060f1SDimitry Andric /// an SDNode, a constant, a stack location, or a virtual register.
30*fe6060f1SDimitry Andric class SDDbgOperand {
310b57cec5SDimitry Andric public:
32*fe6060f1SDimitry Andric   enum Kind {
330b57cec5SDimitry Andric     SDNODE = 0,  ///< Value is the result of an expression.
340b57cec5SDimitry Andric     CONST = 1,   ///< Value is a constant.
350b57cec5SDimitry Andric     FRAMEIX = 2, ///< Value is contents of a stack location.
360b57cec5SDimitry Andric     VREG = 3     ///< Value is a virtual register.
370b57cec5SDimitry Andric   };
38*fe6060f1SDimitry Andric   Kind getKind() const { return kind; }
39*fe6060f1SDimitry Andric 
40*fe6060f1SDimitry Andric   /// Returns the SDNode* for a register ref
41*fe6060f1SDimitry Andric   SDNode *getSDNode() const {
42*fe6060f1SDimitry Andric     assert(kind == SDNODE);
43*fe6060f1SDimitry Andric     return u.s.Node;
44*fe6060f1SDimitry Andric   }
45*fe6060f1SDimitry Andric 
46*fe6060f1SDimitry Andric   /// Returns the ResNo for a register ref
47*fe6060f1SDimitry Andric   unsigned getResNo() const {
48*fe6060f1SDimitry Andric     assert(kind == SDNODE);
49*fe6060f1SDimitry Andric     return u.s.ResNo;
50*fe6060f1SDimitry Andric   }
51*fe6060f1SDimitry Andric 
52*fe6060f1SDimitry Andric   /// Returns the Value* for a constant
53*fe6060f1SDimitry Andric   const Value *getConst() const {
54*fe6060f1SDimitry Andric     assert(kind == CONST);
55*fe6060f1SDimitry Andric     return u.Const;
56*fe6060f1SDimitry Andric   }
57*fe6060f1SDimitry Andric 
58*fe6060f1SDimitry Andric   /// Returns the FrameIx for a stack object
59*fe6060f1SDimitry Andric   unsigned getFrameIx() const {
60*fe6060f1SDimitry Andric     assert(kind == FRAMEIX);
61*fe6060f1SDimitry Andric     return u.FrameIx;
62*fe6060f1SDimitry Andric   }
63*fe6060f1SDimitry Andric 
64*fe6060f1SDimitry Andric   /// Returns the Virtual Register for a VReg
65*fe6060f1SDimitry Andric   unsigned getVReg() const {
66*fe6060f1SDimitry Andric     assert(kind == VREG);
67*fe6060f1SDimitry Andric     return u.VReg;
68*fe6060f1SDimitry Andric   }
69*fe6060f1SDimitry Andric 
70*fe6060f1SDimitry Andric   static SDDbgOperand fromNode(SDNode *Node, unsigned ResNo) {
71*fe6060f1SDimitry Andric     return SDDbgOperand(Node, ResNo);
72*fe6060f1SDimitry Andric   }
73*fe6060f1SDimitry Andric   static SDDbgOperand fromFrameIdx(unsigned FrameIdx) {
74*fe6060f1SDimitry Andric     return SDDbgOperand(FrameIdx, FRAMEIX);
75*fe6060f1SDimitry Andric   }
76*fe6060f1SDimitry Andric   static SDDbgOperand fromVReg(unsigned VReg) {
77*fe6060f1SDimitry Andric     return SDDbgOperand(VReg, VREG);
78*fe6060f1SDimitry Andric   }
79*fe6060f1SDimitry Andric   static SDDbgOperand fromConst(const Value *Const) {
80*fe6060f1SDimitry Andric     return SDDbgOperand(Const);
81*fe6060f1SDimitry Andric   }
82*fe6060f1SDimitry Andric 
83*fe6060f1SDimitry Andric   bool operator!=(const SDDbgOperand &Other) const { return !(*this == Other); }
84*fe6060f1SDimitry Andric   bool operator==(const SDDbgOperand &Other) const {
85*fe6060f1SDimitry Andric     if (kind != Other.kind)
86*fe6060f1SDimitry Andric       return false;
87*fe6060f1SDimitry Andric     switch (kind) {
88*fe6060f1SDimitry Andric     case SDNODE:
89*fe6060f1SDimitry Andric       return getSDNode() == Other.getSDNode() && getResNo() == Other.getResNo();
90*fe6060f1SDimitry Andric     case CONST:
91*fe6060f1SDimitry Andric       return getConst() == Other.getConst();
92*fe6060f1SDimitry Andric     case VREG:
93*fe6060f1SDimitry Andric       return getVReg() == Other.getVReg();
94*fe6060f1SDimitry Andric     case FRAMEIX:
95*fe6060f1SDimitry Andric       return getFrameIx() == Other.getFrameIx();
96*fe6060f1SDimitry Andric     }
97*fe6060f1SDimitry Andric     return false;
98*fe6060f1SDimitry Andric   }
99*fe6060f1SDimitry Andric 
1000b57cec5SDimitry Andric private:
101*fe6060f1SDimitry Andric   Kind kind;
1020b57cec5SDimitry Andric   union {
1030b57cec5SDimitry Andric     struct {
1040b57cec5SDimitry Andric       SDNode *Node;   ///< Valid for expressions.
1050b57cec5SDimitry Andric       unsigned ResNo; ///< Valid for expressions.
1060b57cec5SDimitry Andric     } s;
1070b57cec5SDimitry Andric     const Value *Const; ///< Valid for constants.
1080b57cec5SDimitry Andric     unsigned FrameIx;   ///< Valid for stack objects.
1090b57cec5SDimitry Andric     unsigned VReg;      ///< Valid for registers.
1100b57cec5SDimitry Andric   } u;
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   /// Constructor for non-constants.
113*fe6060f1SDimitry Andric   SDDbgOperand(SDNode *N, unsigned R) : kind(SDNODE) {
1140b57cec5SDimitry Andric     u.s.Node = N;
1150b57cec5SDimitry Andric     u.s.ResNo = R;
1160b57cec5SDimitry Andric   }
1170b57cec5SDimitry Andric   /// Constructor for constants.
118*fe6060f1SDimitry Andric   SDDbgOperand(const Value *C) : kind(CONST) { u.Const = C; }
1190b57cec5SDimitry Andric   /// Constructor for virtual registers and frame indices.
120*fe6060f1SDimitry Andric   SDDbgOperand(unsigned VRegOrFrameIdx, Kind Kind) : kind(Kind) {
1210b57cec5SDimitry Andric     assert((Kind == VREG || Kind == FRAMEIX) &&
1220b57cec5SDimitry Andric            "Invalid SDDbgValue constructor");
1230b57cec5SDimitry Andric     if (kind == VREG)
1240b57cec5SDimitry Andric       u.VReg = VRegOrFrameIdx;
1250b57cec5SDimitry Andric     else
1260b57cec5SDimitry Andric       u.FrameIx = VRegOrFrameIdx;
1270b57cec5SDimitry Andric   }
128*fe6060f1SDimitry Andric };
1290b57cec5SDimitry Andric 
130*fe6060f1SDimitry Andric /// Holds the information from a dbg_value node through SDISel.
131*fe6060f1SDimitry Andric /// We do not use SDValue here to avoid including its header.
132*fe6060f1SDimitry Andric class SDDbgValue {
133*fe6060f1SDimitry Andric public:
134*fe6060f1SDimitry Andric 
135*fe6060f1SDimitry Andric private:
136*fe6060f1SDimitry Andric   // SDDbgValues are allocated by a BumpPtrAllocator, which means the destructor
137*fe6060f1SDimitry Andric   // may not be called; therefore all member arrays must also be allocated by
138*fe6060f1SDimitry Andric   // that BumpPtrAllocator, to ensure that they are correctly freed.
139*fe6060f1SDimitry Andric   size_t NumLocationOps;
140*fe6060f1SDimitry Andric   SDDbgOperand *LocationOps;
141*fe6060f1SDimitry Andric   // SDNode dependencies will be calculated as SDNodes that appear in
142*fe6060f1SDimitry Andric   // LocationOps plus these AdditionalDependencies.
143*fe6060f1SDimitry Andric   size_t NumAdditionalDependencies;
144*fe6060f1SDimitry Andric   SDNode **AdditionalDependencies;
145*fe6060f1SDimitry Andric   DIVariable *Var;
146*fe6060f1SDimitry Andric   DIExpression *Expr;
147*fe6060f1SDimitry Andric   DebugLoc DL;
148*fe6060f1SDimitry Andric   unsigned Order;
149*fe6060f1SDimitry Andric   bool IsIndirect;
150*fe6060f1SDimitry Andric   bool IsVariadic;
151*fe6060f1SDimitry Andric   bool Invalid = false;
152*fe6060f1SDimitry Andric   bool Emitted = false;
153*fe6060f1SDimitry Andric 
154*fe6060f1SDimitry Andric public:
155*fe6060f1SDimitry Andric   SDDbgValue(BumpPtrAllocator &Alloc, DIVariable *Var, DIExpression *Expr,
156*fe6060f1SDimitry Andric              ArrayRef<SDDbgOperand> L, ArrayRef<SDNode *> Dependencies,
157*fe6060f1SDimitry Andric              bool IsIndirect, DebugLoc DL, unsigned O, bool IsVariadic)
158*fe6060f1SDimitry Andric       : NumLocationOps(L.size()),
159*fe6060f1SDimitry Andric         LocationOps(Alloc.Allocate<SDDbgOperand>(L.size())),
160*fe6060f1SDimitry Andric         NumAdditionalDependencies(Dependencies.size()),
161*fe6060f1SDimitry Andric         AdditionalDependencies(Alloc.Allocate<SDNode *>(Dependencies.size())),
162*fe6060f1SDimitry Andric         Var(Var), Expr(Expr), DL(DL), Order(O), IsIndirect(IsIndirect),
163*fe6060f1SDimitry Andric         IsVariadic(IsVariadic) {
164*fe6060f1SDimitry Andric     assert(IsVariadic || L.size() == 1);
165*fe6060f1SDimitry Andric     assert(!(IsVariadic && IsIndirect));
166*fe6060f1SDimitry Andric     std::copy(L.begin(), L.end(), LocationOps);
167*fe6060f1SDimitry Andric     std::copy(Dependencies.begin(), Dependencies.end(), AdditionalDependencies);
168*fe6060f1SDimitry Andric   }
169*fe6060f1SDimitry Andric 
170*fe6060f1SDimitry Andric   // We allocate arrays with the BumpPtrAllocator and never free or copy them,
171*fe6060f1SDimitry Andric   // for LocationOps and AdditionalDependencies, as we never expect to copy or
172*fe6060f1SDimitry Andric   // destroy an SDDbgValue. If we ever start copying or destroying instances, we
173*fe6060f1SDimitry Andric   // should manage the allocated memory appropriately.
174*fe6060f1SDimitry Andric   SDDbgValue(const SDDbgValue &Other) = delete;
175*fe6060f1SDimitry Andric   SDDbgValue &operator=(const SDDbgValue &Other) = delete;
176*fe6060f1SDimitry Andric   ~SDDbgValue() = delete;
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric   /// Returns the DIVariable pointer for the variable.
1790b57cec5SDimitry Andric   DIVariable *getVariable() const { return Var; }
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric   /// Returns the DIExpression pointer for the expression.
1820b57cec5SDimitry Andric   DIExpression *getExpression() const { return Expr; }
1830b57cec5SDimitry Andric 
184*fe6060f1SDimitry Andric   ArrayRef<SDDbgOperand> getLocationOps() const {
185*fe6060f1SDimitry Andric     return ArrayRef<SDDbgOperand>(LocationOps, NumLocationOps);
186*fe6060f1SDimitry Andric   }
1870b57cec5SDimitry Andric 
188*fe6060f1SDimitry Andric   SmallVector<SDDbgOperand> copyLocationOps() const {
189*fe6060f1SDimitry Andric     return SmallVector<SDDbgOperand>(LocationOps, LocationOps + NumLocationOps);
190*fe6060f1SDimitry Andric   }
1910b57cec5SDimitry Andric 
192*fe6060f1SDimitry Andric   // Returns the SDNodes which this SDDbgValue depends on.
193*fe6060f1SDimitry Andric   SmallVector<SDNode *> getSDNodes() const {
194*fe6060f1SDimitry Andric     SmallVector<SDNode *> Dependencies;
195*fe6060f1SDimitry Andric     for (SDDbgOperand DbgOp : getLocationOps())
196*fe6060f1SDimitry Andric       if (DbgOp.getKind() == SDDbgOperand::SDNODE)
197*fe6060f1SDimitry Andric         Dependencies.push_back(DbgOp.getSDNode());
198*fe6060f1SDimitry Andric     for (SDNode *Node : getAdditionalDependencies())
199*fe6060f1SDimitry Andric       Dependencies.push_back(Node);
200*fe6060f1SDimitry Andric     return Dependencies;
201*fe6060f1SDimitry Andric   }
2020b57cec5SDimitry Andric 
203*fe6060f1SDimitry Andric   ArrayRef<SDNode *> getAdditionalDependencies() const {
204*fe6060f1SDimitry Andric     return ArrayRef<SDNode *>(AdditionalDependencies,
205*fe6060f1SDimitry Andric                               NumAdditionalDependencies);
206*fe6060f1SDimitry Andric   }
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric   /// Returns whether this is an indirect value.
2090b57cec5SDimitry Andric   bool isIndirect() const { return IsIndirect; }
2100b57cec5SDimitry Andric 
211*fe6060f1SDimitry Andric   bool isVariadic() const { return IsVariadic; }
212*fe6060f1SDimitry Andric 
2130b57cec5SDimitry Andric   /// Returns the DebugLoc.
214*fe6060f1SDimitry Andric   const DebugLoc &getDebugLoc() const { return DL; }
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric   /// Returns the SDNodeOrder.  This is the order of the preceding node in the
2170b57cec5SDimitry Andric   /// input.
2180b57cec5SDimitry Andric   unsigned getOrder() const { return Order; }
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric   /// setIsInvalidated / isInvalidated - Setter / getter of the "Invalidated"
2210b57cec5SDimitry Andric   /// property. A SDDbgValue is invalid if the SDNode that produces the value is
2220b57cec5SDimitry Andric   /// deleted.
2230b57cec5SDimitry Andric   void setIsInvalidated() { Invalid = true; }
2240b57cec5SDimitry Andric   bool isInvalidated() const { return Invalid; }
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric   /// setIsEmitted / isEmitted - Getter/Setter for flag indicating that this
2270b57cec5SDimitry Andric   /// SDDbgValue has been emitted to an MBB.
2280b57cec5SDimitry Andric   void setIsEmitted() { Emitted = true; }
2290b57cec5SDimitry Andric   bool isEmitted() const { return Emitted; }
2300b57cec5SDimitry Andric 
2310b57cec5SDimitry Andric   /// clearIsEmitted - Reset Emitted flag, for certain special cases where
2320b57cec5SDimitry Andric   /// dbg.addr is emitted twice.
2330b57cec5SDimitry Andric   void clearIsEmitted() { Emitted = false; }
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric   LLVM_DUMP_METHOD void dump() const;
2360b57cec5SDimitry Andric   LLVM_DUMP_METHOD void print(raw_ostream &OS) const;
2370b57cec5SDimitry Andric };
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric /// Holds the information from a dbg_label node through SDISel.
2400b57cec5SDimitry Andric /// We do not use SDValue here to avoid including its header.
2410b57cec5SDimitry Andric class SDDbgLabel {
2420b57cec5SDimitry Andric   MDNode *Label;
2430b57cec5SDimitry Andric   DebugLoc DL;
2440b57cec5SDimitry Andric   unsigned Order;
2450b57cec5SDimitry Andric 
2460b57cec5SDimitry Andric public:
2470b57cec5SDimitry Andric   SDDbgLabel(MDNode *Label, DebugLoc dl, unsigned O)
2480b57cec5SDimitry Andric       : Label(Label), DL(std::move(dl)), Order(O) {}
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric   /// Returns the MDNode pointer for the label.
2510b57cec5SDimitry Andric   MDNode *getLabel() const { return Label; }
2520b57cec5SDimitry Andric 
2530b57cec5SDimitry Andric   /// Returns the DebugLoc.
254*fe6060f1SDimitry Andric   const DebugLoc &getDebugLoc() const { return DL; }
2550b57cec5SDimitry Andric 
2560b57cec5SDimitry Andric   /// Returns the SDNodeOrder.  This is the order of the preceding node in the
2570b57cec5SDimitry Andric   /// input.
2580b57cec5SDimitry Andric   unsigned getOrder() const { return Order; }
2590b57cec5SDimitry Andric };
2600b57cec5SDimitry Andric 
2610b57cec5SDimitry Andric } // end llvm namespace
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric #endif
264