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/DataTypes.h" |

18 | #include <utility> |

19 | |

20 | namespace llvm { |

21 | |

22 | class DIVariable; |

23 | class DIExpression; |

24 | class SDNode; |

25 | class Value; |

26 | class raw_ostream; |

27 | |

28 | /// Holds the information for a single machine location through SDISel; either |

29 | /// an SDNode, a constant, a stack location, or a virtual register. |

30 | class SDDbgOperand { |

31 | public: |

32 | enum Kind { |

33 | SDNODE = 0, ///< Value is the result of an expression. |

34 | CONST = 1, ///< Value is a constant. |

35 | FRAMEIX = 2, ///< Value is contents of a stack location. |

36 | VREG = 3 ///< Value is a virtual register. |

37 | }; |

38 | Kind getKind() const { return kind; } |

39 | |

40 | /// Returns the SDNode* for a register ref |

41 | SDNode *getSDNode() const { |

42 | assert(kind == SDNODE); |

43 | return u.s.Node; |

44 | } |

45 | |

46 | /// Returns the ResNo for a register ref |

47 | unsigned getResNo() const { |

48 | assert(kind == SDNODE); |

49 | return u.s.ResNo; |

50 | } |

51 | |

52 | /// Returns the Value* for a constant |

53 | const Value *getConst() const { |

54 | assert(kind == CONST); |

55 | return u.Const; |

56 | } |

57 | |

58 | /// Returns the FrameIx for a stack object |

59 | unsigned getFrameIx() const { |

60 | assert(kind == FRAMEIX); |

61 | return u.FrameIx; |

62 | } |

63 | |

64 | /// Returns the Virtual Register for a VReg |

65 | unsigned getVReg() const { |

66 | assert(kind == VREG); |

67 | return u.VReg; |

68 | } |

69 | |

70 | static SDDbgOperand fromNode(SDNode *Node, unsigned ResNo) { |

71 | return SDDbgOperand(Node, ResNo); |

72 | } |

73 | static SDDbgOperand fromFrameIdx(unsigned FrameIdx) { |

74 | return SDDbgOperand(FrameIdx, FRAMEIX); |

75 | } |

76 | static SDDbgOperand fromVReg(unsigned VReg) { |

77 | return SDDbgOperand(VReg, VREG); |

78 | } |

79 | static SDDbgOperand fromConst(const Value *Const) { |

80 | return SDDbgOperand(Const); |

81 | } |

82 | |

83 | bool operator!=(const SDDbgOperand &Other) const { return !(*this == Other); } |

84 | bool operator==(const SDDbgOperand &Other) const { |

85 | if (kind != Other.kind) |

86 | return false; |

87 | switch (kind) { |

88 | case SDNODE: |

89 | return getSDNode() == Other.getSDNode() && getResNo() == Other.getResNo(); |

90 | case CONST: |

91 | return getConst() == Other.getConst(); |

92 | case VREG: |

93 | return getVReg() == Other.getVReg(); |

94 | case FRAMEIX: |

95 | return getFrameIx() == Other.getFrameIx(); |

96 | } |

97 | return false; |

98 | } |

99 | |

100 | private: |

101 | Kind kind; |

102 | union { |

103 | struct { |

104 | SDNode *Node; ///< Valid for expressions. |

105 | unsigned ResNo; ///< Valid for expressions. |

106 | } s; |

107 | const Value *Const; ///< Valid for constants. |

108 | unsigned FrameIx; ///< Valid for stack objects. |

109 | unsigned VReg; ///< Valid for registers. |

110 | } u; |

111 | |

112 | /// Constructor for non-constants. |

113 | SDDbgOperand(SDNode *N, unsigned R) : kind(SDNODE) { |

114 | u.s.Node = N; |

115 | u.s.ResNo = R; |

116 | } |

117 | /// Constructor for constants. |

118 | SDDbgOperand(const Value *C) : kind(CONST) { u.Const = C; } |

119 | /// Constructor for virtual registers and frame indices. |

120 | SDDbgOperand(unsigned VRegOrFrameIdx, Kind Kind) : kind(Kind) { |

121 | assert((Kind == VREG || Kind == FRAMEIX) && |

122 | "Invalid SDDbgValue constructor"); |

123 | if (kind == VREG) |

124 | u.VReg = VRegOrFrameIdx; |

125 | else |

126 | u.FrameIx = VRegOrFrameIdx; |

127 | } |

128 | }; |

129 | |

130 | /// Holds the information from a dbg_value node through SDISel. |

131 | /// We do not use SDValue here to avoid including its header. |

132 | class SDDbgValue { |

133 | public: |

134 | |

135 | private: |

136 | // SDDbgValues are allocated by a BumpPtrAllocator, which means the destructor |

137 | // may not be called; therefore all member arrays must also be allocated by |

138 | // that BumpPtrAllocator, to ensure that they are correctly freed. |

139 | size_t NumLocationOps; |

140 | SDDbgOperand *LocationOps; |

141 | // SDNode dependencies will be calculated as SDNodes that appear in |

142 | // LocationOps plus these AdditionalDependencies. |

143 | size_t NumAdditionalDependencies; |

144 | SDNode **AdditionalDependencies; |

145 | DIVariable *Var; |

146 | DIExpression *Expr; |

147 | DebugLoc DL; |

148 | unsigned Order; |

149 | bool IsIndirect; |

150 | bool IsVariadic; |

151 | bool Invalid = false; |

152 | bool Emitted = false; |

153 | |

154 | public: |

155 | SDDbgValue(BumpPtrAllocator &Alloc, DIVariable *Var, DIExpression *Expr, |

156 | ArrayRef<SDDbgOperand> L, ArrayRef<SDNode *> Dependencies, |

157 | bool IsIndirect, DebugLoc DL, unsigned O, bool IsVariadic) |

158 | : NumLocationOps(L.size()), |

159 | LocationOps(Alloc.Allocate<SDDbgOperand>(L.size())), |

160 | NumAdditionalDependencies(Dependencies.size()), |

161 | AdditionalDependencies(Alloc.Allocate<SDNode *>(Dependencies.size())), |

162 | Var(Var), Expr(Expr), DL(DL), Order(O), IsIndirect(IsIndirect), |

163 | IsVariadic(IsVariadic) { |

164 | assert(IsVariadic || L.size() == 1); |

165 | assert(!(IsVariadic && IsIndirect)); |

166 | std::copy(L.begin(), L.end(), LocationOps); |

167 | std::copy(Dependencies.begin(), Dependencies.end(), AdditionalDependencies); |

168 | } |

169 | |

170 | // We allocate arrays with the BumpPtrAllocator and never free or copy them, |

171 | // for LocationOps and AdditionalDependencies, as we never expect to copy or |

172 | // destroy an SDDbgValue. If we ever start copying or destroying instances, we |

173 | // should manage the allocated memory appropriately. |

174 | SDDbgValue(const SDDbgValue &Other) = delete; |

175 | SDDbgValue &operator=(const SDDbgValue &Other) = delete; |

176 | ~SDDbgValue() = delete; |

177 | |

178 | /// Returns the DIVariable pointer for the variable. |

179 | DIVariable *getVariable() const { return Var; } |

180 | |

181 | /// Returns the DIExpression pointer for the expression. |

182 | DIExpression *getExpression() const { return Expr; } |

183 | |

184 | ArrayRef<SDDbgOperand> getLocationOps() const { |

185 | return ArrayRef<SDDbgOperand>(LocationOps, NumLocationOps); |

186 | } |

187 | |

188 | SmallVector<SDDbgOperand> copyLocationOps() const { |

189 | return SmallVector<SDDbgOperand>(LocationOps, LocationOps + NumLocationOps); |

190 | } |

191 | |

192 | // Returns the SDNodes which this SDDbgValue depends on. |

193 | SmallVector<SDNode *> getSDNodes() const { |

194 | SmallVector<SDNode *> Dependencies; |

195 | for (SDDbgOperand DbgOp : getLocationOps()) |

196 | if (DbgOp.getKind() == SDDbgOperand::SDNODE) |

197 | Dependencies.push_back(DbgOp.getSDNode()); |

198 | for (SDNode *Node : getAdditionalDependencies()) |

199 | Dependencies.push_back(Node); |

200 | return Dependencies; |

201 | } |

202 | |

203 | ArrayRef<SDNode *> getAdditionalDependencies() const { |

204 | return ArrayRef<SDNode *>(AdditionalDependencies, |

205 | NumAdditionalDependencies); |

206 | } |

207 | |

208 | /// Returns whether this is an indirect value. |

209 | bool isIndirect() const { return IsIndirect; } |

210 | |

211 | bool isVariadic() const { return IsVariadic; } |

212 | |

213 | /// Returns the DebugLoc. |

214 | DebugLoc getDebugLoc() const { return DL; } |

215 | |

216 | /// Returns the SDNodeOrder. This is the order of the preceding node in the |

217 | /// input. |

218 | unsigned getOrder() const { return Order; } |

219 | |

220 | /// setIsInvalidated / isInvalidated - Setter / getter of the "Invalidated" |

221 | /// property. A SDDbgValue is invalid if the SDNode that produces the value is |

222 | /// deleted. |

223 | void setIsInvalidated() { Invalid = true; } |

224 | bool isInvalidated() const { return Invalid; } |

225 | |

226 | /// setIsEmitted / isEmitted - Getter/Setter for flag indicating that this |

227 | /// SDDbgValue has been emitted to an MBB. |

228 | void setIsEmitted() { Emitted = true; } |

229 | bool isEmitted() const { return Emitted; } |

230 | |

231 | /// clearIsEmitted - Reset Emitted flag, for certain special cases where |

232 | /// dbg.addr is emitted twice. |

233 | void clearIsEmitted() { Emitted = false; } |

234 | |

235 | LLVM_DUMP_METHOD void dump() const; |

236 | LLVM_DUMP_METHOD void print(raw_ostream &OS) const; |

237 | }; |

238 | |

239 | /// Holds the information from a dbg_label node through SDISel. |

240 | /// We do not use SDValue here to avoid including its header. |

241 | class SDDbgLabel { |

242 | MDNode *Label; |

243 | DebugLoc DL; |

244 | unsigned Order; |

245 | |

246 | public: |

247 | SDDbgLabel(MDNode *Label, DebugLoc dl, unsigned O) |

248 | : Label(Label), DL(std::move(dl)), Order(O) {} |

249 | |

250 | /// Returns the MDNode pointer for the label. |

251 | MDNode *getLabel() const { return Label; } |

252 | |

253 | /// Returns the DebugLoc. |

254 | DebugLoc getDebugLoc() const { return DL; } |

255 | |

256 | /// Returns the SDNodeOrder. This is the order of the preceding node in the |

257 | /// input. |

258 | unsigned getOrder() const { return Order; } |

259 | }; |

260 | |

261 | } // end llvm namespace |

262 | |

263 | #endif |

264 |