Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h
Line
Count
Source (jump to first uncovered line)
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-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file declares the SDDbgValue class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#ifndef LLVM_LIB_CODEGEN_SELECTIONDAG_SDNODEDBGVALUE_H
14
#define LLVM_LIB_CODEGEN_SELECTIONDAG_SDNODEDBGVALUE_H
15
16
#include "llvm/IR/DebugLoc.h"
17
#include "llvm/Support/Allocator.h"
18
#include "llvm/Support/DataTypes.h"
19
#include <utility>
20
21
namespace llvm {
22
23
class DIVariable;
24
class DIExpression;
25
class SDNode;
26
class Value;
27
class raw_ostream;
28
29
/// Holds the information for a single machine location through SDISel; either
30
/// an SDNode, a constant, a stack location, or a virtual register.
31
class SDDbgOperand {
32
public:
33
  enum Kind {
34
    SDNODE = 0,  ///< Value is the result of an expression.
35
    CONST = 1,   ///< Value is a constant.
36
    FRAMEIX = 2, ///< Value is contents of a stack location.
37
    VREG = 3     ///< Value is a virtual register.
38
  };
39
6.33k
  Kind getKind() const { return kind; }
40
41
  /// Returns the SDNode* for a register ref
42
3.85k
  SDNode *getSDNode() const {
43
3.85k
    assert(kind == SDNODE);
44
0
    return u.s.Node;
45
3.85k
  }
46
47
  /// Returns the ResNo for a register ref
48
1.56k
  unsigned getResNo() const {
49
1.56k
    assert(kind == SDNODE);
50
0
    return u.s.ResNo;
51
1.56k
  }
52
53
  /// Returns the Value* for a constant
54
1.09k
  const Value *getConst() const {
55
1.09k
    assert(kind == CONST);
56
0
    return u.Const;
57
1.09k
  }
58
59
  /// Returns the FrameIx for a stack object
60
12
  unsigned getFrameIx() const {
61
12
    assert(kind == FRAMEIX);
62
0
    return u.FrameIx;
63
12
  }
64
65
  /// Returns the Virtual Register for a VReg
66
44
  unsigned getVReg() const {
67
44
    assert(kind == VREG);
68
0
    return u.VReg;
69
44
  }
70
71
1.36k
  static SDDbgOperand fromNode(SDNode *Node, unsigned ResNo) {
72
1.36k
    return SDDbgOperand(Node, ResNo);
73
1.36k
  }
74
12
  static SDDbgOperand fromFrameIdx(unsigned FrameIdx) {
75
12
    return SDDbgOperand(FrameIdx, FRAMEIX);
76
12
  }
77
45
  static SDDbgOperand fromVReg(unsigned VReg) {
78
45
    return SDDbgOperand(VReg, VREG);
79
45
  }
80
878
  static SDDbgOperand fromConst(const Value *Const) {
81
878
    return SDDbgOperand(Const);
82
878
  }
83
84
0
  bool operator!=(const SDDbgOperand &Other) const { return !(*this == Other); }
85
306
  bool operator==(const SDDbgOperand &Other) const {
86
306
    if (kind != Other.kind)
87
0
      return false;
88
306
    switch (kind) {
89
306
    case SDNODE:
90
306
      return getSDNode() == Other.getSDNode() && getResNo() == Other.getResNo();
91
0
    case CONST:
92
0
      return getConst() == Other.getConst();
93
0
    case VREG:
94
0
      return getVReg() == Other.getVReg();
95
0
    case FRAMEIX:
96
0
      return getFrameIx() == Other.getFrameIx();
97
306
    }
98
0
    return false;
99
306
  }
100
101
private:
102
  Kind kind;
103
  union {
104
    struct {
105
      SDNode *Node;   ///< Valid for expressions.
106
      unsigned ResNo; ///< Valid for expressions.
107
    } s;
108
    const Value *Const; ///< Valid for constants.
109
    unsigned FrameIx;   ///< Valid for stack objects.
110
    unsigned VReg;      ///< Valid for registers.
111
  } u;
112
113
  /// Constructor for non-constants.
114
1.36k
  SDDbgOperand(SDNode *N, unsigned R) : kind(SDNODE) {
115
1.36k
    u.s.Node = N;
116
1.36k
    u.s.ResNo = R;
117
1.36k
  }
118
  /// Constructor for constants.
119
878
  SDDbgOperand(const Value *C) : kind(CONST) { u.Const = C; }
120
  /// Constructor for virtual registers and frame indices.
121
57
  SDDbgOperand(unsigned VRegOrFrameIdx, Kind Kind) : kind(Kind) {
122
57
    assert((Kind == VREG || Kind == FRAMEIX) &&
123
57
           "Invalid SDDbgValue constructor");
124
57
    if (kind == VREG)
125
45
      u.VReg = VRegOrFrameIdx;
126
12
    else
127
12
      u.FrameIx = VRegOrFrameIdx;
128
57
  }
129
};
130
131
/// Holds the information from a dbg_value node through SDISel.
132
/// We do not use SDValue here to avoid including its header.
133
class SDDbgValue {
134
public:
135
136
private:
137
  // SDDbgValues are allocated by a BumpPtrAllocator, which means the destructor
138
  // may not be called; therefore all member arrays must also be allocated by
139
  // that BumpPtrAllocator, to ensure that they are correctly freed.
140
  size_t NumLocationOps;
141
  SDDbgOperand *LocationOps;
142
  // SDNode dependencies will be calculated as SDNodes that appear in
143
  // LocationOps plus these AdditionalDependencies.
144
  size_t NumAdditionalDependencies;
145
  SDNode **AdditionalDependencies;
146
  DIVariable *Var;
147
  DIExpression *Expr;
148
  DebugLoc DL;
149
  unsigned Order;
150
  bool IsIndirect;
151
  bool IsVariadic;
152
  bool Invalid = false;
153
  bool Emitted = false;
154
155
public:
156
  SDDbgValue(BumpPtrAllocator &Alloc, DIVariable *Var, DIExpression *Expr,
157
             ArrayRef<SDDbgOperand> L, ArrayRef<SDNode *> Dependencies,
158
             bool IsIndirect, DebugLoc DL, unsigned O, bool IsVariadic)
159
      : NumLocationOps(L.size()),
160
        LocationOps(Alloc.Allocate<SDDbgOperand>(L.size())),
161
        NumAdditionalDependencies(Dependencies.size()),
162
        AdditionalDependencies(Alloc.Allocate<SDNode *>(Dependencies.size())),
163
        Var(Var), Expr(Expr), DL(DL), Order(O), IsIndirect(IsIndirect),
164
1.46k
        IsVariadic(IsVariadic) {
165
1.46k
    assert(IsVariadic || L.size() == 1);
166
0
    assert(!(IsVariadic && IsIndirect));
167
0
    std::copy(L.begin(), L.end(), LocationOps);
168
1.46k
    std::copy(Dependencies.begin(), Dependencies.end(), AdditionalDependencies);
169
1.46k
  }
170
171
  // We allocate arrays with the BumpPtrAllocator and never free or copy them,
172
  // for LocationOps and AdditionalDependencies, as we never expect to copy or
173
  // destroy an SDDbgValue. If we ever start copying or destroying instances, we
174
  // should manage the allocated memory appropriately.
175
  SDDbgValue(const SDDbgValue &Other) = delete;
176
  SDDbgValue &operator=(const SDDbgValue &Other) = delete;
177
  ~SDDbgValue() = delete;
178
179
  /// Returns the DIVariable pointer for the variable.
180
2.74k
  DIVariable *getVariable() const { return Var; }
181
182
  /// Returns the DIExpression pointer for the expression.
183
1.48k
  DIExpression *getExpression() const { return Expr; }
184
185
7.14k
  ArrayRef<SDDbgOperand> getLocationOps() const {
186
7.14k
    return ArrayRef<SDDbgOperand>(LocationOps, NumLocationOps);
187
7.14k
  }
188
189
247
  SmallVector<SDDbgOperand> copyLocationOps() const {
190
247
    return SmallVector<SDDbgOperand>(LocationOps, LocationOps + NumLocationOps);
191
247
  }
192
193
  // Returns the SDNodes which this SDDbgValue depends on.
194
3.14k
  SmallVector<SDNode *> getSDNodes() const {
195
3.14k
    SmallVector<SDNode *> Dependencies;
196
3.14k
    for (const SDDbgOperand &DbgOp : getLocationOps())
197
3.48k
      if (DbgOp.getKind() == SDDbgOperand::SDNODE)
198
2.21k
        Dependencies.push_back(DbgOp.getSDNode());
199
3.14k
    for (SDNode *Node : getAdditionalDependencies())
200
0
      Dependencies.push_back(Node);
201
3.14k
    return Dependencies;
202
3.14k
  }
203
204
3.36k
  ArrayRef<SDNode *> getAdditionalDependencies() const {
205
3.36k
    return ArrayRef<SDNode *>(AdditionalDependencies,
206
3.36k
                              NumAdditionalDependencies);
207
3.36k
  }
208
209
  /// Returns whether this is an indirect value.
210
1.37k
  bool isIndirect() const { return IsIndirect; }
211
212
2.84k
  bool isVariadic() const { return IsVariadic; }
213
214
  /// Returns the DebugLoc.
215
2.74k
  const DebugLoc &getDebugLoc() const { return DL; }
216
217
  /// Returns the SDNodeOrder.  This is the order of the preceding node in the
218
  /// input.
219
16.0k
  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 is
223
  /// deleted.
224
1.20k
  void setIsInvalidated() { Invalid = true; }
225
2.03k
  bool isInvalidated() const { return Invalid; }
226
227
  /// setIsEmitted / isEmitted - Getter/Setter for flag indicating that this
228
  /// SDDbgValue has been emitted to an MBB.
229
1.47k
  void setIsEmitted() { Emitted = true; }
230
2.04k
  bool isEmitted() const { return Emitted; }
231
232
  /// clearIsEmitted - Reset Emitted flag, for certain special cases where
233
  /// SDDbgValue is emitted twice. DBG_INSTR_REF depends on this behaviour.
234
24
  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.
242
class SDDbgLabel {
243
  MDNode *Label;
244
  DebugLoc DL;
245
  unsigned Order;
246
247
public:
248
  SDDbgLabel(MDNode *Label, DebugLoc dl, unsigned O)
249
0
      : Label(Label), DL(std::move(dl)), Order(O) {}
250
251
  /// Returns the MDNode pointer for the label.
252
0
  MDNode *getLabel() const { return Label; }
253
254
  /// Returns the DebugLoc.
255
0
  const DebugLoc &getDebugLoc() const { return DL; }
256
257
  /// Returns the SDNodeOrder.  This is the order of the preceding node in the
258
  /// input.
259
0
  unsigned getOrder() const { return Order; }
260
};
261
262
} // end llvm namespace
263
264
#endif