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