265 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file declares the SDDbgValue class.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_LIB_CODEGEN_SELECTIONDAG_SDNODEDBGVALUE_H14#define LLVM_LIB_CODEGEN_SELECTIONDAG_SDNODEDBGVALUE_H15 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 22namespace llvm {23 24class DIVariable;25class DIExpression;26class SDNode;27class Value;28class raw_ostream;29 30/// Holds the information for a single machine location through SDISel; either31/// an SDNode, a constant, a stack location, or a virtual register.32class SDDbgOperand {33public: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 };40 Kind getKind() const { return kind; }41 42 /// Returns the SDNode* for a register ref43 SDNode *getSDNode() const {44 assert(kind == SDNODE);45 return u.s.Node;46 }47 48 /// Returns the ResNo for a register ref49 unsigned getResNo() const {50 assert(kind == SDNODE);51 return u.s.ResNo;52 }53 54 /// Returns the Value* for a constant55 const Value *getConst() const {56 assert(kind == CONST);57 return u.Const;58 }59 60 /// Returns the FrameIx for a stack object61 unsigned getFrameIx() const {62 assert(kind == FRAMEIX);63 return u.FrameIx;64 }65 66 /// Returns the Virtual Register for a VReg67 Register getVReg() const {68 assert(kind == VREG);69 return u.VReg;70 }71 72 static SDDbgOperand fromNode(SDNode *Node, unsigned ResNo) {73 return SDDbgOperand(Node, ResNo);74 }75 static SDDbgOperand fromFrameIdx(unsigned FrameIdx) {76 return SDDbgOperand(FrameIdx, FRAMEIX);77 }78 static SDDbgOperand fromVReg(Register VReg) {79 return SDDbgOperand(VReg.id(), VREG);80 }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 102private: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.115 SDDbgOperand(SDNode *N, unsigned R) : kind(SDNODE) {116 u.s.Node = N;117 u.s.ResNo = R;118 }119 /// Constructor for constants.120 SDDbgOperand(const Value *C) : kind(CONST) { u.Const = C; }121 /// Constructor for virtual registers and frame indices.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 else128 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.134class SDDbgValue {135public:136 137private:138 // SDDbgValues are allocated by a BumpPtrAllocator, which means the destructor139 // may not be called; therefore all member arrays must also be allocated by140 // 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 in144 // 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 156public: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 or174 // destroy an SDDbgValue. If we ever start copying or destroying instances, we175 // 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.181 DIVariable *getVariable() const { return Var; }182 183 /// Returns the DIExpression pointer for the expression.184 DIExpression *getExpression() const { return Expr; }185 186 ArrayRef<SDDbgOperand> getLocationOps() const {187 return ArrayRef<SDDbgOperand>(LocationOps, NumLocationOps);188 }189 190 SmallVector<SDDbgOperand> copyLocationOps() const {191 return SmallVector<SDDbgOperand>(LocationOps, LocationOps + NumLocationOps);192 }193 194 // Returns the SDNodes which this SDDbgValue depends on.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 204 ArrayRef<SDNode *> getAdditionalDependencies() const {205 return ArrayRef<SDNode *>(AdditionalDependencies,206 NumAdditionalDependencies);207 }208 209 /// Returns whether this is an indirect value.210 bool isIndirect() const { return IsIndirect; }211 212 bool isVariadic() const { return IsVariadic; }213 214 /// Returns the DebugLoc.215 const DebugLoc &getDebugLoc() const { return DL; }216 217 /// Returns the SDNodeOrder. This is the order of the preceding node in the218 /// input.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 is223 /// deleted.224 void setIsInvalidated() { Invalid = true; }225 bool isInvalidated() const { return Invalid; }226 227 /// setIsEmitted / isEmitted - Getter/Setter for flag indicating that this228 /// SDDbgValue has been emitted to an MBB.229 void setIsEmitted() { Emitted = true; }230 bool isEmitted() const { return Emitted; }231 232 /// clearIsEmitted - Reset Emitted flag, for certain special cases where233 /// SDDbgValue is emitted twice. DBG_INSTR_REF depends on this behaviour.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.242class SDDbgLabel {243 MDNode *Label;244 DebugLoc DL;245 unsigned Order;246 247public: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.252 MDNode *getLabel() const { return Label; }253 254 /// Returns the DebugLoc.255 const DebugLoc &getDebugLoc() const { return DL; }256 257 /// Returns the SDNodeOrder. This is the order of the preceding node in the258 /// input.259 unsigned getOrder() const { return Order; }260};261 262} // end llvm namespace263 264#endif265