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