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