annotate llvm/lib/IR/LLVMContextImpl.h @ 152:e8a9b4f4d755

pull from 146
author anatofuz
date Wed, 11 Mar 2020 18:29:16 +0900
parents 1d019706d866
children f935e5e0dbe7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===- LLVMContextImpl.h - The LLVMContextImpl opaque class -----*- C++ -*-===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8 //
anatofuz
parents:
diff changeset
9 // This file declares LLVMContextImpl, the opaque implementation
anatofuz
parents:
diff changeset
10 // of LLVMContext.
anatofuz
parents:
diff changeset
11 //
anatofuz
parents:
diff changeset
12 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
13
anatofuz
parents:
diff changeset
14 #ifndef LLVM_LIB_IR_LLVMCONTEXTIMPL_H
anatofuz
parents:
diff changeset
15 #define LLVM_LIB_IR_LLVMCONTEXTIMPL_H
anatofuz
parents:
diff changeset
16
anatofuz
parents:
diff changeset
17 #include "AttributeImpl.h"
anatofuz
parents:
diff changeset
18 #include "ConstantsContext.h"
anatofuz
parents:
diff changeset
19 #include "llvm/ADT/APFloat.h"
anatofuz
parents:
diff changeset
20 #include "llvm/ADT/APInt.h"
anatofuz
parents:
diff changeset
21 #include "llvm/ADT/ArrayRef.h"
anatofuz
parents:
diff changeset
22 #include "llvm/ADT/DenseMap.h"
anatofuz
parents:
diff changeset
23 #include "llvm/ADT/DenseMapInfo.h"
anatofuz
parents:
diff changeset
24 #include "llvm/ADT/DenseSet.h"
anatofuz
parents:
diff changeset
25 #include "llvm/ADT/FoldingSet.h"
anatofuz
parents:
diff changeset
26 #include "llvm/ADT/Hashing.h"
anatofuz
parents:
diff changeset
27 #include "llvm/ADT/Optional.h"
anatofuz
parents:
diff changeset
28 #include "llvm/ADT/STLExtras.h"
anatofuz
parents:
diff changeset
29 #include "llvm/ADT/SmallPtrSet.h"
anatofuz
parents:
diff changeset
30 #include "llvm/ADT/SmallVector.h"
anatofuz
parents:
diff changeset
31 #include "llvm/ADT/StringMap.h"
anatofuz
parents:
diff changeset
32 #include "llvm/ADT/StringRef.h"
anatofuz
parents:
diff changeset
33 #include "llvm/BinaryFormat/Dwarf.h"
anatofuz
parents:
diff changeset
34 #include "llvm/IR/Constants.h"
anatofuz
parents:
diff changeset
35 #include "llvm/IR/DebugInfoMetadata.h"
anatofuz
parents:
diff changeset
36 #include "llvm/IR/DerivedTypes.h"
anatofuz
parents:
diff changeset
37 #include "llvm/IR/LLVMContext.h"
anatofuz
parents:
diff changeset
38 #include "llvm/IR/LLVMRemarkStreamer.h"
anatofuz
parents:
diff changeset
39 #include "llvm/IR/Metadata.h"
anatofuz
parents:
diff changeset
40 #include "llvm/IR/TrackingMDRef.h"
anatofuz
parents:
diff changeset
41 #include "llvm/Support/Allocator.h"
anatofuz
parents:
diff changeset
42 #include "llvm/Support/Casting.h"
anatofuz
parents:
diff changeset
43 #include "llvm/Support/StringSaver.h"
anatofuz
parents:
diff changeset
44 #include "llvm/Support/YAMLTraits.h"
anatofuz
parents:
diff changeset
45 #include <algorithm>
anatofuz
parents:
diff changeset
46 #include <cassert>
anatofuz
parents:
diff changeset
47 #include <cstddef>
anatofuz
parents:
diff changeset
48 #include <cstdint>
anatofuz
parents:
diff changeset
49 #include <memory>
anatofuz
parents:
diff changeset
50 #include <string>
anatofuz
parents:
diff changeset
51 #include <utility>
anatofuz
parents:
diff changeset
52 #include <vector>
anatofuz
parents:
diff changeset
53
anatofuz
parents:
diff changeset
54 namespace llvm {
anatofuz
parents:
diff changeset
55
anatofuz
parents:
diff changeset
56 class ConstantFP;
anatofuz
parents:
diff changeset
57 class ConstantInt;
anatofuz
parents:
diff changeset
58 class Type;
anatofuz
parents:
diff changeset
59 class Value;
anatofuz
parents:
diff changeset
60 class ValueHandleBase;
anatofuz
parents:
diff changeset
61
anatofuz
parents:
diff changeset
62 struct DenseMapAPIntKeyInfo {
anatofuz
parents:
diff changeset
63 static inline APInt getEmptyKey() {
anatofuz
parents:
diff changeset
64 APInt V(nullptr, 0);
anatofuz
parents:
diff changeset
65 V.U.VAL = 0;
anatofuz
parents:
diff changeset
66 return V;
anatofuz
parents:
diff changeset
67 }
anatofuz
parents:
diff changeset
68
anatofuz
parents:
diff changeset
69 static inline APInt getTombstoneKey() {
anatofuz
parents:
diff changeset
70 APInt V(nullptr, 0);
anatofuz
parents:
diff changeset
71 V.U.VAL = 1;
anatofuz
parents:
diff changeset
72 return V;
anatofuz
parents:
diff changeset
73 }
anatofuz
parents:
diff changeset
74
anatofuz
parents:
diff changeset
75 static unsigned getHashValue(const APInt &Key) {
anatofuz
parents:
diff changeset
76 return static_cast<unsigned>(hash_value(Key));
anatofuz
parents:
diff changeset
77 }
anatofuz
parents:
diff changeset
78
anatofuz
parents:
diff changeset
79 static bool isEqual(const APInt &LHS, const APInt &RHS) {
anatofuz
parents:
diff changeset
80 return LHS.getBitWidth() == RHS.getBitWidth() && LHS == RHS;
anatofuz
parents:
diff changeset
81 }
anatofuz
parents:
diff changeset
82 };
anatofuz
parents:
diff changeset
83
anatofuz
parents:
diff changeset
84 struct DenseMapAPFloatKeyInfo {
anatofuz
parents:
diff changeset
85 static inline APFloat getEmptyKey() { return APFloat(APFloat::Bogus(), 1); }
anatofuz
parents:
diff changeset
86 static inline APFloat getTombstoneKey() { return APFloat(APFloat::Bogus(), 2); }
anatofuz
parents:
diff changeset
87
anatofuz
parents:
diff changeset
88 static unsigned getHashValue(const APFloat &Key) {
anatofuz
parents:
diff changeset
89 return static_cast<unsigned>(hash_value(Key));
anatofuz
parents:
diff changeset
90 }
anatofuz
parents:
diff changeset
91
anatofuz
parents:
diff changeset
92 static bool isEqual(const APFloat &LHS, const APFloat &RHS) {
anatofuz
parents:
diff changeset
93 return LHS.bitwiseIsEqual(RHS);
anatofuz
parents:
diff changeset
94 }
anatofuz
parents:
diff changeset
95 };
anatofuz
parents:
diff changeset
96
anatofuz
parents:
diff changeset
97 struct AnonStructTypeKeyInfo {
anatofuz
parents:
diff changeset
98 struct KeyTy {
anatofuz
parents:
diff changeset
99 ArrayRef<Type*> ETypes;
anatofuz
parents:
diff changeset
100 bool isPacked;
anatofuz
parents:
diff changeset
101
anatofuz
parents:
diff changeset
102 KeyTy(const ArrayRef<Type*>& E, bool P) :
anatofuz
parents:
diff changeset
103 ETypes(E), isPacked(P) {}
anatofuz
parents:
diff changeset
104
anatofuz
parents:
diff changeset
105 KeyTy(const StructType *ST)
anatofuz
parents:
diff changeset
106 : ETypes(ST->elements()), isPacked(ST->isPacked()) {}
anatofuz
parents:
diff changeset
107
anatofuz
parents:
diff changeset
108 bool operator==(const KeyTy& that) const {
anatofuz
parents:
diff changeset
109 if (isPacked != that.isPacked)
anatofuz
parents:
diff changeset
110 return false;
anatofuz
parents:
diff changeset
111 if (ETypes != that.ETypes)
anatofuz
parents:
diff changeset
112 return false;
anatofuz
parents:
diff changeset
113 return true;
anatofuz
parents:
diff changeset
114 }
anatofuz
parents:
diff changeset
115 bool operator!=(const KeyTy& that) const {
anatofuz
parents:
diff changeset
116 return !this->operator==(that);
anatofuz
parents:
diff changeset
117 }
anatofuz
parents:
diff changeset
118 };
anatofuz
parents:
diff changeset
119
anatofuz
parents:
diff changeset
120 static inline StructType* getEmptyKey() {
anatofuz
parents:
diff changeset
121 return DenseMapInfo<StructType*>::getEmptyKey();
anatofuz
parents:
diff changeset
122 }
anatofuz
parents:
diff changeset
123
anatofuz
parents:
diff changeset
124 static inline StructType* getTombstoneKey() {
anatofuz
parents:
diff changeset
125 return DenseMapInfo<StructType*>::getTombstoneKey();
anatofuz
parents:
diff changeset
126 }
anatofuz
parents:
diff changeset
127
anatofuz
parents:
diff changeset
128 static unsigned getHashValue(const KeyTy& Key) {
anatofuz
parents:
diff changeset
129 return hash_combine(hash_combine_range(Key.ETypes.begin(),
anatofuz
parents:
diff changeset
130 Key.ETypes.end()),
anatofuz
parents:
diff changeset
131 Key.isPacked);
anatofuz
parents:
diff changeset
132 }
anatofuz
parents:
diff changeset
133
anatofuz
parents:
diff changeset
134 static unsigned getHashValue(const StructType *ST) {
anatofuz
parents:
diff changeset
135 return getHashValue(KeyTy(ST));
anatofuz
parents:
diff changeset
136 }
anatofuz
parents:
diff changeset
137
anatofuz
parents:
diff changeset
138 static bool isEqual(const KeyTy& LHS, const StructType *RHS) {
anatofuz
parents:
diff changeset
139 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
anatofuz
parents:
diff changeset
140 return false;
anatofuz
parents:
diff changeset
141 return LHS == KeyTy(RHS);
anatofuz
parents:
diff changeset
142 }
anatofuz
parents:
diff changeset
143
anatofuz
parents:
diff changeset
144 static bool isEqual(const StructType *LHS, const StructType *RHS) {
anatofuz
parents:
diff changeset
145 return LHS == RHS;
anatofuz
parents:
diff changeset
146 }
anatofuz
parents:
diff changeset
147 };
anatofuz
parents:
diff changeset
148
anatofuz
parents:
diff changeset
149 struct FunctionTypeKeyInfo {
anatofuz
parents:
diff changeset
150 struct KeyTy {
anatofuz
parents:
diff changeset
151 const Type *ReturnType;
anatofuz
parents:
diff changeset
152 ArrayRef<Type*> Params;
anatofuz
parents:
diff changeset
153 bool isVarArg;
anatofuz
parents:
diff changeset
154
anatofuz
parents:
diff changeset
155 KeyTy(const Type* R, const ArrayRef<Type*>& P, bool V) :
anatofuz
parents:
diff changeset
156 ReturnType(R), Params(P), isVarArg(V) {}
anatofuz
parents:
diff changeset
157 KeyTy(const FunctionType *FT)
anatofuz
parents:
diff changeset
158 : ReturnType(FT->getReturnType()), Params(FT->params()),
anatofuz
parents:
diff changeset
159 isVarArg(FT->isVarArg()) {}
anatofuz
parents:
diff changeset
160
anatofuz
parents:
diff changeset
161 bool operator==(const KeyTy& that) const {
anatofuz
parents:
diff changeset
162 if (ReturnType != that.ReturnType)
anatofuz
parents:
diff changeset
163 return false;
anatofuz
parents:
diff changeset
164 if (isVarArg != that.isVarArg)
anatofuz
parents:
diff changeset
165 return false;
anatofuz
parents:
diff changeset
166 if (Params != that.Params)
anatofuz
parents:
diff changeset
167 return false;
anatofuz
parents:
diff changeset
168 return true;
anatofuz
parents:
diff changeset
169 }
anatofuz
parents:
diff changeset
170 bool operator!=(const KeyTy& that) const {
anatofuz
parents:
diff changeset
171 return !this->operator==(that);
anatofuz
parents:
diff changeset
172 }
anatofuz
parents:
diff changeset
173 };
anatofuz
parents:
diff changeset
174
anatofuz
parents:
diff changeset
175 static inline FunctionType* getEmptyKey() {
anatofuz
parents:
diff changeset
176 return DenseMapInfo<FunctionType*>::getEmptyKey();
anatofuz
parents:
diff changeset
177 }
anatofuz
parents:
diff changeset
178
anatofuz
parents:
diff changeset
179 static inline FunctionType* getTombstoneKey() {
anatofuz
parents:
diff changeset
180 return DenseMapInfo<FunctionType*>::getTombstoneKey();
anatofuz
parents:
diff changeset
181 }
anatofuz
parents:
diff changeset
182
anatofuz
parents:
diff changeset
183 static unsigned getHashValue(const KeyTy& Key) {
anatofuz
parents:
diff changeset
184 return hash_combine(Key.ReturnType,
anatofuz
parents:
diff changeset
185 hash_combine_range(Key.Params.begin(),
anatofuz
parents:
diff changeset
186 Key.Params.end()),
anatofuz
parents:
diff changeset
187 Key.isVarArg);
anatofuz
parents:
diff changeset
188 }
anatofuz
parents:
diff changeset
189
anatofuz
parents:
diff changeset
190 static unsigned getHashValue(const FunctionType *FT) {
anatofuz
parents:
diff changeset
191 return getHashValue(KeyTy(FT));
anatofuz
parents:
diff changeset
192 }
anatofuz
parents:
diff changeset
193
anatofuz
parents:
diff changeset
194 static bool isEqual(const KeyTy& LHS, const FunctionType *RHS) {
anatofuz
parents:
diff changeset
195 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
anatofuz
parents:
diff changeset
196 return false;
anatofuz
parents:
diff changeset
197 return LHS == KeyTy(RHS);
anatofuz
parents:
diff changeset
198 }
anatofuz
parents:
diff changeset
199
anatofuz
parents:
diff changeset
200 static bool isEqual(const FunctionType *LHS, const FunctionType *RHS) {
anatofuz
parents:
diff changeset
201 return LHS == RHS;
anatofuz
parents:
diff changeset
202 }
anatofuz
parents:
diff changeset
203 };
anatofuz
parents:
diff changeset
204
anatofuz
parents:
diff changeset
205 /// Structure for hashing arbitrary MDNode operands.
anatofuz
parents:
diff changeset
206 class MDNodeOpsKey {
anatofuz
parents:
diff changeset
207 ArrayRef<Metadata *> RawOps;
anatofuz
parents:
diff changeset
208 ArrayRef<MDOperand> Ops;
anatofuz
parents:
diff changeset
209 unsigned Hash;
anatofuz
parents:
diff changeset
210
anatofuz
parents:
diff changeset
211 protected:
anatofuz
parents:
diff changeset
212 MDNodeOpsKey(ArrayRef<Metadata *> Ops)
anatofuz
parents:
diff changeset
213 : RawOps(Ops), Hash(calculateHash(Ops)) {}
anatofuz
parents:
diff changeset
214
anatofuz
parents:
diff changeset
215 template <class NodeTy>
anatofuz
parents:
diff changeset
216 MDNodeOpsKey(const NodeTy *N, unsigned Offset = 0)
anatofuz
parents:
diff changeset
217 : Ops(N->op_begin() + Offset, N->op_end()), Hash(N->getHash()) {}
anatofuz
parents:
diff changeset
218
anatofuz
parents:
diff changeset
219 template <class NodeTy>
anatofuz
parents:
diff changeset
220 bool compareOps(const NodeTy *RHS, unsigned Offset = 0) const {
anatofuz
parents:
diff changeset
221 if (getHash() != RHS->getHash())
anatofuz
parents:
diff changeset
222 return false;
anatofuz
parents:
diff changeset
223
anatofuz
parents:
diff changeset
224 assert((RawOps.empty() || Ops.empty()) && "Two sets of operands?");
anatofuz
parents:
diff changeset
225 return RawOps.empty() ? compareOps(Ops, RHS, Offset)
anatofuz
parents:
diff changeset
226 : compareOps(RawOps, RHS, Offset);
anatofuz
parents:
diff changeset
227 }
anatofuz
parents:
diff changeset
228
anatofuz
parents:
diff changeset
229 static unsigned calculateHash(MDNode *N, unsigned Offset = 0);
anatofuz
parents:
diff changeset
230
anatofuz
parents:
diff changeset
231 private:
anatofuz
parents:
diff changeset
232 template <class T>
anatofuz
parents:
diff changeset
233 static bool compareOps(ArrayRef<T> Ops, const MDNode *RHS, unsigned Offset) {
anatofuz
parents:
diff changeset
234 if (Ops.size() != RHS->getNumOperands() - Offset)
anatofuz
parents:
diff changeset
235 return false;
anatofuz
parents:
diff changeset
236 return std::equal(Ops.begin(), Ops.end(), RHS->op_begin() + Offset);
anatofuz
parents:
diff changeset
237 }
anatofuz
parents:
diff changeset
238
anatofuz
parents:
diff changeset
239 static unsigned calculateHash(ArrayRef<Metadata *> Ops);
anatofuz
parents:
diff changeset
240
anatofuz
parents:
diff changeset
241 public:
anatofuz
parents:
diff changeset
242 unsigned getHash() const { return Hash; }
anatofuz
parents:
diff changeset
243 };
anatofuz
parents:
diff changeset
244
anatofuz
parents:
diff changeset
245 template <class NodeTy> struct MDNodeKeyImpl;
anatofuz
parents:
diff changeset
246
anatofuz
parents:
diff changeset
247 /// Configuration point for MDNodeInfo::isEqual().
anatofuz
parents:
diff changeset
248 template <class NodeTy> struct MDNodeSubsetEqualImpl {
anatofuz
parents:
diff changeset
249 using KeyTy = MDNodeKeyImpl<NodeTy>;
anatofuz
parents:
diff changeset
250
anatofuz
parents:
diff changeset
251 static bool isSubsetEqual(const KeyTy &LHS, const NodeTy *RHS) {
anatofuz
parents:
diff changeset
252 return false;
anatofuz
parents:
diff changeset
253 }
anatofuz
parents:
diff changeset
254
anatofuz
parents:
diff changeset
255 static bool isSubsetEqual(const NodeTy *LHS, const NodeTy *RHS) {
anatofuz
parents:
diff changeset
256 return false;
anatofuz
parents:
diff changeset
257 }
anatofuz
parents:
diff changeset
258 };
anatofuz
parents:
diff changeset
259
anatofuz
parents:
diff changeset
260 /// DenseMapInfo for MDTuple.
anatofuz
parents:
diff changeset
261 ///
anatofuz
parents:
diff changeset
262 /// Note that we don't need the is-function-local bit, since that's implicit in
anatofuz
parents:
diff changeset
263 /// the operands.
anatofuz
parents:
diff changeset
264 template <> struct MDNodeKeyImpl<MDTuple> : MDNodeOpsKey {
anatofuz
parents:
diff changeset
265 MDNodeKeyImpl(ArrayRef<Metadata *> Ops) : MDNodeOpsKey(Ops) {}
anatofuz
parents:
diff changeset
266 MDNodeKeyImpl(const MDTuple *N) : MDNodeOpsKey(N) {}
anatofuz
parents:
diff changeset
267
anatofuz
parents:
diff changeset
268 bool isKeyOf(const MDTuple *RHS) const { return compareOps(RHS); }
anatofuz
parents:
diff changeset
269
anatofuz
parents:
diff changeset
270 unsigned getHashValue() const { return getHash(); }
anatofuz
parents:
diff changeset
271
anatofuz
parents:
diff changeset
272 static unsigned calculateHash(MDTuple *N) {
anatofuz
parents:
diff changeset
273 return MDNodeOpsKey::calculateHash(N);
anatofuz
parents:
diff changeset
274 }
anatofuz
parents:
diff changeset
275 };
anatofuz
parents:
diff changeset
276
anatofuz
parents:
diff changeset
277 /// DenseMapInfo for DILocation.
anatofuz
parents:
diff changeset
278 template <> struct MDNodeKeyImpl<DILocation> {
anatofuz
parents:
diff changeset
279 unsigned Line;
anatofuz
parents:
diff changeset
280 unsigned Column;
anatofuz
parents:
diff changeset
281 Metadata *Scope;
anatofuz
parents:
diff changeset
282 Metadata *InlinedAt;
anatofuz
parents:
diff changeset
283 bool ImplicitCode;
anatofuz
parents:
diff changeset
284
anatofuz
parents:
diff changeset
285 MDNodeKeyImpl(unsigned Line, unsigned Column, Metadata *Scope,
anatofuz
parents:
diff changeset
286 Metadata *InlinedAt, bool ImplicitCode)
anatofuz
parents:
diff changeset
287 : Line(Line), Column(Column), Scope(Scope), InlinedAt(InlinedAt),
anatofuz
parents:
diff changeset
288 ImplicitCode(ImplicitCode) {}
anatofuz
parents:
diff changeset
289 MDNodeKeyImpl(const DILocation *L)
anatofuz
parents:
diff changeset
290 : Line(L->getLine()), Column(L->getColumn()), Scope(L->getRawScope()),
anatofuz
parents:
diff changeset
291 InlinedAt(L->getRawInlinedAt()), ImplicitCode(L->isImplicitCode()) {}
anatofuz
parents:
diff changeset
292
anatofuz
parents:
diff changeset
293 bool isKeyOf(const DILocation *RHS) const {
anatofuz
parents:
diff changeset
294 return Line == RHS->getLine() && Column == RHS->getColumn() &&
anatofuz
parents:
diff changeset
295 Scope == RHS->getRawScope() && InlinedAt == RHS->getRawInlinedAt() &&
anatofuz
parents:
diff changeset
296 ImplicitCode == RHS->isImplicitCode();
anatofuz
parents:
diff changeset
297 }
anatofuz
parents:
diff changeset
298
anatofuz
parents:
diff changeset
299 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
300 return hash_combine(Line, Column, Scope, InlinedAt, ImplicitCode);
anatofuz
parents:
diff changeset
301 }
anatofuz
parents:
diff changeset
302 };
anatofuz
parents:
diff changeset
303
anatofuz
parents:
diff changeset
304 /// DenseMapInfo for GenericDINode.
anatofuz
parents:
diff changeset
305 template <> struct MDNodeKeyImpl<GenericDINode> : MDNodeOpsKey {
anatofuz
parents:
diff changeset
306 unsigned Tag;
anatofuz
parents:
diff changeset
307 MDString *Header;
anatofuz
parents:
diff changeset
308
anatofuz
parents:
diff changeset
309 MDNodeKeyImpl(unsigned Tag, MDString *Header, ArrayRef<Metadata *> DwarfOps)
anatofuz
parents:
diff changeset
310 : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {}
anatofuz
parents:
diff changeset
311 MDNodeKeyImpl(const GenericDINode *N)
anatofuz
parents:
diff changeset
312 : MDNodeOpsKey(N, 1), Tag(N->getTag()), Header(N->getRawHeader()) {}
anatofuz
parents:
diff changeset
313
anatofuz
parents:
diff changeset
314 bool isKeyOf(const GenericDINode *RHS) const {
anatofuz
parents:
diff changeset
315 return Tag == RHS->getTag() && Header == RHS->getRawHeader() &&
anatofuz
parents:
diff changeset
316 compareOps(RHS, 1);
anatofuz
parents:
diff changeset
317 }
anatofuz
parents:
diff changeset
318
anatofuz
parents:
diff changeset
319 unsigned getHashValue() const { return hash_combine(getHash(), Tag, Header); }
anatofuz
parents:
diff changeset
320
anatofuz
parents:
diff changeset
321 static unsigned calculateHash(GenericDINode *N) {
anatofuz
parents:
diff changeset
322 return MDNodeOpsKey::calculateHash(N, 1);
anatofuz
parents:
diff changeset
323 }
anatofuz
parents:
diff changeset
324 };
anatofuz
parents:
diff changeset
325
anatofuz
parents:
diff changeset
326 template <> struct MDNodeKeyImpl<DISubrange> {
anatofuz
parents:
diff changeset
327 Metadata *CountNode;
anatofuz
parents:
diff changeset
328 int64_t LowerBound;
anatofuz
parents:
diff changeset
329
anatofuz
parents:
diff changeset
330 MDNodeKeyImpl(Metadata *CountNode, int64_t LowerBound)
anatofuz
parents:
diff changeset
331 : CountNode(CountNode), LowerBound(LowerBound) {}
anatofuz
parents:
diff changeset
332 MDNodeKeyImpl(const DISubrange *N)
anatofuz
parents:
diff changeset
333 : CountNode(N->getRawCountNode()),
anatofuz
parents:
diff changeset
334 LowerBound(N->getLowerBound()) {}
anatofuz
parents:
diff changeset
335
anatofuz
parents:
diff changeset
336 bool isKeyOf(const DISubrange *RHS) const {
anatofuz
parents:
diff changeset
337 if (LowerBound != RHS->getLowerBound())
anatofuz
parents:
diff changeset
338 return false;
anatofuz
parents:
diff changeset
339
anatofuz
parents:
diff changeset
340 if (auto *RHSCount = RHS->getCount().dyn_cast<ConstantInt*>())
anatofuz
parents:
diff changeset
341 if (auto *MD = dyn_cast<ConstantAsMetadata>(CountNode))
anatofuz
parents:
diff changeset
342 if (RHSCount->getSExtValue() ==
anatofuz
parents:
diff changeset
343 cast<ConstantInt>(MD->getValue())->getSExtValue())
anatofuz
parents:
diff changeset
344 return true;
anatofuz
parents:
diff changeset
345
anatofuz
parents:
diff changeset
346 return CountNode == RHS->getRawCountNode();
anatofuz
parents:
diff changeset
347 }
anatofuz
parents:
diff changeset
348
anatofuz
parents:
diff changeset
349 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
350 if (auto *MD = dyn_cast<ConstantAsMetadata>(CountNode))
anatofuz
parents:
diff changeset
351 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
anatofuz
parents:
diff changeset
352 LowerBound);
anatofuz
parents:
diff changeset
353 return hash_combine(CountNode, LowerBound);
anatofuz
parents:
diff changeset
354 }
anatofuz
parents:
diff changeset
355 };
anatofuz
parents:
diff changeset
356
anatofuz
parents:
diff changeset
357 template <> struct MDNodeKeyImpl<DIEnumerator> {
anatofuz
parents:
diff changeset
358 int64_t Value;
anatofuz
parents:
diff changeset
359 MDString *Name;
anatofuz
parents:
diff changeset
360 bool IsUnsigned;
anatofuz
parents:
diff changeset
361
anatofuz
parents:
diff changeset
362 MDNodeKeyImpl(int64_t Value, bool IsUnsigned, MDString *Name)
anatofuz
parents:
diff changeset
363 : Value(Value), Name(Name), IsUnsigned(IsUnsigned) {}
anatofuz
parents:
diff changeset
364 MDNodeKeyImpl(const DIEnumerator *N)
anatofuz
parents:
diff changeset
365 : Value(N->getValue()), Name(N->getRawName()),
anatofuz
parents:
diff changeset
366 IsUnsigned(N->isUnsigned()) {}
anatofuz
parents:
diff changeset
367
anatofuz
parents:
diff changeset
368 bool isKeyOf(const DIEnumerator *RHS) const {
anatofuz
parents:
diff changeset
369 return Value == RHS->getValue() && IsUnsigned == RHS->isUnsigned() &&
anatofuz
parents:
diff changeset
370 Name == RHS->getRawName();
anatofuz
parents:
diff changeset
371 }
anatofuz
parents:
diff changeset
372
anatofuz
parents:
diff changeset
373 unsigned getHashValue() const { return hash_combine(Value, Name); }
anatofuz
parents:
diff changeset
374 };
anatofuz
parents:
diff changeset
375
anatofuz
parents:
diff changeset
376 template <> struct MDNodeKeyImpl<DIBasicType> {
anatofuz
parents:
diff changeset
377 unsigned Tag;
anatofuz
parents:
diff changeset
378 MDString *Name;
anatofuz
parents:
diff changeset
379 uint64_t SizeInBits;
anatofuz
parents:
diff changeset
380 uint32_t AlignInBits;
anatofuz
parents:
diff changeset
381 unsigned Encoding;
anatofuz
parents:
diff changeset
382 unsigned Flags;
anatofuz
parents:
diff changeset
383
anatofuz
parents:
diff changeset
384 MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits,
anatofuz
parents:
diff changeset
385 uint32_t AlignInBits, unsigned Encoding, unsigned Flags)
anatofuz
parents:
diff changeset
386 : Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits),
anatofuz
parents:
diff changeset
387 Encoding(Encoding), Flags(Flags) {}
anatofuz
parents:
diff changeset
388 MDNodeKeyImpl(const DIBasicType *N)
anatofuz
parents:
diff changeset
389 : Tag(N->getTag()), Name(N->getRawName()), SizeInBits(N->getSizeInBits()),
anatofuz
parents:
diff changeset
390 AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()), Flags(N->getFlags()) {}
anatofuz
parents:
diff changeset
391
anatofuz
parents:
diff changeset
392 bool isKeyOf(const DIBasicType *RHS) const {
anatofuz
parents:
diff changeset
393 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
anatofuz
parents:
diff changeset
394 SizeInBits == RHS->getSizeInBits() &&
anatofuz
parents:
diff changeset
395 AlignInBits == RHS->getAlignInBits() &&
anatofuz
parents:
diff changeset
396 Encoding == RHS->getEncoding() &&
anatofuz
parents:
diff changeset
397 Flags == RHS->getFlags();
anatofuz
parents:
diff changeset
398 }
anatofuz
parents:
diff changeset
399
anatofuz
parents:
diff changeset
400 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
401 return hash_combine(Tag, Name, SizeInBits, AlignInBits, Encoding);
anatofuz
parents:
diff changeset
402 }
anatofuz
parents:
diff changeset
403 };
anatofuz
parents:
diff changeset
404
anatofuz
parents:
diff changeset
405 template <> struct MDNodeKeyImpl<DIDerivedType> {
anatofuz
parents:
diff changeset
406 unsigned Tag;
anatofuz
parents:
diff changeset
407 MDString *Name;
anatofuz
parents:
diff changeset
408 Metadata *File;
anatofuz
parents:
diff changeset
409 unsigned Line;
anatofuz
parents:
diff changeset
410 Metadata *Scope;
anatofuz
parents:
diff changeset
411 Metadata *BaseType;
anatofuz
parents:
diff changeset
412 uint64_t SizeInBits;
anatofuz
parents:
diff changeset
413 uint64_t OffsetInBits;
anatofuz
parents:
diff changeset
414 uint32_t AlignInBits;
anatofuz
parents:
diff changeset
415 Optional<unsigned> DWARFAddressSpace;
anatofuz
parents:
diff changeset
416 unsigned Flags;
anatofuz
parents:
diff changeset
417 Metadata *ExtraData;
anatofuz
parents:
diff changeset
418
anatofuz
parents:
diff changeset
419 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
anatofuz
parents:
diff changeset
420 Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
anatofuz
parents:
diff changeset
421 uint32_t AlignInBits, uint64_t OffsetInBits,
anatofuz
parents:
diff changeset
422 Optional<unsigned> DWARFAddressSpace, unsigned Flags,
anatofuz
parents:
diff changeset
423 Metadata *ExtraData)
anatofuz
parents:
diff changeset
424 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
anatofuz
parents:
diff changeset
425 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
anatofuz
parents:
diff changeset
426 AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace),
anatofuz
parents:
diff changeset
427 Flags(Flags), ExtraData(ExtraData) {}
anatofuz
parents:
diff changeset
428 MDNodeKeyImpl(const DIDerivedType *N)
anatofuz
parents:
diff changeset
429 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
anatofuz
parents:
diff changeset
430 Line(N->getLine()), Scope(N->getRawScope()),
anatofuz
parents:
diff changeset
431 BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
anatofuz
parents:
diff changeset
432 OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()),
anatofuz
parents:
diff changeset
433 DWARFAddressSpace(N->getDWARFAddressSpace()), Flags(N->getFlags()),
anatofuz
parents:
diff changeset
434 ExtraData(N->getRawExtraData()) {}
anatofuz
parents:
diff changeset
435
anatofuz
parents:
diff changeset
436 bool isKeyOf(const DIDerivedType *RHS) const {
anatofuz
parents:
diff changeset
437 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
anatofuz
parents:
diff changeset
438 File == RHS->getRawFile() && Line == RHS->getLine() &&
anatofuz
parents:
diff changeset
439 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
anatofuz
parents:
diff changeset
440 SizeInBits == RHS->getSizeInBits() &&
anatofuz
parents:
diff changeset
441 AlignInBits == RHS->getAlignInBits() &&
anatofuz
parents:
diff changeset
442 OffsetInBits == RHS->getOffsetInBits() &&
anatofuz
parents:
diff changeset
443 DWARFAddressSpace == RHS->getDWARFAddressSpace() &&
anatofuz
parents:
diff changeset
444 Flags == RHS->getFlags() &&
anatofuz
parents:
diff changeset
445 ExtraData == RHS->getRawExtraData();
anatofuz
parents:
diff changeset
446 }
anatofuz
parents:
diff changeset
447
anatofuz
parents:
diff changeset
448 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
449 // If this is a member inside an ODR type, only hash the type and the name.
anatofuz
parents:
diff changeset
450 // Otherwise the hash will be stronger than
anatofuz
parents:
diff changeset
451 // MDNodeSubsetEqualImpl::isODRMember().
anatofuz
parents:
diff changeset
452 if (Tag == dwarf::DW_TAG_member && Name)
anatofuz
parents:
diff changeset
453 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
anatofuz
parents:
diff changeset
454 if (CT->getRawIdentifier())
anatofuz
parents:
diff changeset
455 return hash_combine(Name, Scope);
anatofuz
parents:
diff changeset
456
anatofuz
parents:
diff changeset
457 // Intentionally computes the hash on a subset of the operands for
anatofuz
parents:
diff changeset
458 // performance reason. The subset has to be significant enough to avoid
anatofuz
parents:
diff changeset
459 // collision "most of the time". There is no correctness issue in case of
anatofuz
parents:
diff changeset
460 // collision because of the full check above.
anatofuz
parents:
diff changeset
461 return hash_combine(Tag, Name, File, Line, Scope, BaseType, Flags);
anatofuz
parents:
diff changeset
462 }
anatofuz
parents:
diff changeset
463 };
anatofuz
parents:
diff changeset
464
anatofuz
parents:
diff changeset
465 template <> struct MDNodeSubsetEqualImpl<DIDerivedType> {
anatofuz
parents:
diff changeset
466 using KeyTy = MDNodeKeyImpl<DIDerivedType>;
anatofuz
parents:
diff changeset
467
anatofuz
parents:
diff changeset
468 static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) {
anatofuz
parents:
diff changeset
469 return isODRMember(LHS.Tag, LHS.Scope, LHS.Name, RHS);
anatofuz
parents:
diff changeset
470 }
anatofuz
parents:
diff changeset
471
anatofuz
parents:
diff changeset
472 static bool isSubsetEqual(const DIDerivedType *LHS, const DIDerivedType *RHS) {
anatofuz
parents:
diff changeset
473 return isODRMember(LHS->getTag(), LHS->getRawScope(), LHS->getRawName(),
anatofuz
parents:
diff changeset
474 RHS);
anatofuz
parents:
diff changeset
475 }
anatofuz
parents:
diff changeset
476
anatofuz
parents:
diff changeset
477 /// Subprograms compare equal if they declare the same function in an ODR
anatofuz
parents:
diff changeset
478 /// type.
anatofuz
parents:
diff changeset
479 static bool isODRMember(unsigned Tag, const Metadata *Scope,
anatofuz
parents:
diff changeset
480 const MDString *Name, const DIDerivedType *RHS) {
anatofuz
parents:
diff changeset
481 // Check whether the LHS is eligible.
anatofuz
parents:
diff changeset
482 if (Tag != dwarf::DW_TAG_member || !Name)
anatofuz
parents:
diff changeset
483 return false;
anatofuz
parents:
diff changeset
484
anatofuz
parents:
diff changeset
485 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
anatofuz
parents:
diff changeset
486 if (!CT || !CT->getRawIdentifier())
anatofuz
parents:
diff changeset
487 return false;
anatofuz
parents:
diff changeset
488
anatofuz
parents:
diff changeset
489 // Compare to the RHS.
anatofuz
parents:
diff changeset
490 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
anatofuz
parents:
diff changeset
491 Scope == RHS->getRawScope();
anatofuz
parents:
diff changeset
492 }
anatofuz
parents:
diff changeset
493 };
anatofuz
parents:
diff changeset
494
anatofuz
parents:
diff changeset
495 template <> struct MDNodeKeyImpl<DICompositeType> {
anatofuz
parents:
diff changeset
496 unsigned Tag;
anatofuz
parents:
diff changeset
497 MDString *Name;
anatofuz
parents:
diff changeset
498 Metadata *File;
anatofuz
parents:
diff changeset
499 unsigned Line;
anatofuz
parents:
diff changeset
500 Metadata *Scope;
anatofuz
parents:
diff changeset
501 Metadata *BaseType;
anatofuz
parents:
diff changeset
502 uint64_t SizeInBits;
anatofuz
parents:
diff changeset
503 uint64_t OffsetInBits;
anatofuz
parents:
diff changeset
504 uint32_t AlignInBits;
anatofuz
parents:
diff changeset
505 unsigned Flags;
anatofuz
parents:
diff changeset
506 Metadata *Elements;
anatofuz
parents:
diff changeset
507 unsigned RuntimeLang;
anatofuz
parents:
diff changeset
508 Metadata *VTableHolder;
anatofuz
parents:
diff changeset
509 Metadata *TemplateParams;
anatofuz
parents:
diff changeset
510 MDString *Identifier;
anatofuz
parents:
diff changeset
511 Metadata *Discriminator;
anatofuz
parents:
diff changeset
512
anatofuz
parents:
diff changeset
513 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
anatofuz
parents:
diff changeset
514 Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
anatofuz
parents:
diff changeset
515 uint32_t AlignInBits, uint64_t OffsetInBits, unsigned Flags,
anatofuz
parents:
diff changeset
516 Metadata *Elements, unsigned RuntimeLang,
anatofuz
parents:
diff changeset
517 Metadata *VTableHolder, Metadata *TemplateParams,
anatofuz
parents:
diff changeset
518 MDString *Identifier, Metadata *Discriminator)
anatofuz
parents:
diff changeset
519 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
anatofuz
parents:
diff changeset
520 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
anatofuz
parents:
diff changeset
521 AlignInBits(AlignInBits), Flags(Flags), Elements(Elements),
anatofuz
parents:
diff changeset
522 RuntimeLang(RuntimeLang), VTableHolder(VTableHolder),
anatofuz
parents:
diff changeset
523 TemplateParams(TemplateParams), Identifier(Identifier),
anatofuz
parents:
diff changeset
524 Discriminator(Discriminator) {}
anatofuz
parents:
diff changeset
525 MDNodeKeyImpl(const DICompositeType *N)
anatofuz
parents:
diff changeset
526 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
anatofuz
parents:
diff changeset
527 Line(N->getLine()), Scope(N->getRawScope()),
anatofuz
parents:
diff changeset
528 BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
anatofuz
parents:
diff changeset
529 OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()),
anatofuz
parents:
diff changeset
530 Flags(N->getFlags()), Elements(N->getRawElements()),
anatofuz
parents:
diff changeset
531 RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()),
anatofuz
parents:
diff changeset
532 TemplateParams(N->getRawTemplateParams()),
anatofuz
parents:
diff changeset
533 Identifier(N->getRawIdentifier()),
anatofuz
parents:
diff changeset
534 Discriminator(N->getRawDiscriminator()) {}
anatofuz
parents:
diff changeset
535
anatofuz
parents:
diff changeset
536 bool isKeyOf(const DICompositeType *RHS) const {
anatofuz
parents:
diff changeset
537 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
anatofuz
parents:
diff changeset
538 File == RHS->getRawFile() && Line == RHS->getLine() &&
anatofuz
parents:
diff changeset
539 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
anatofuz
parents:
diff changeset
540 SizeInBits == RHS->getSizeInBits() &&
anatofuz
parents:
diff changeset
541 AlignInBits == RHS->getAlignInBits() &&
anatofuz
parents:
diff changeset
542 OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() &&
anatofuz
parents:
diff changeset
543 Elements == RHS->getRawElements() &&
anatofuz
parents:
diff changeset
544 RuntimeLang == RHS->getRuntimeLang() &&
anatofuz
parents:
diff changeset
545 VTableHolder == RHS->getRawVTableHolder() &&
anatofuz
parents:
diff changeset
546 TemplateParams == RHS->getRawTemplateParams() &&
anatofuz
parents:
diff changeset
547 Identifier == RHS->getRawIdentifier() &&
anatofuz
parents:
diff changeset
548 Discriminator == RHS->getRawDiscriminator();
anatofuz
parents:
diff changeset
549 }
anatofuz
parents:
diff changeset
550
anatofuz
parents:
diff changeset
551 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
552 // Intentionally computes the hash on a subset of the operands for
anatofuz
parents:
diff changeset
553 // performance reason. The subset has to be significant enough to avoid
anatofuz
parents:
diff changeset
554 // collision "most of the time". There is no correctness issue in case of
anatofuz
parents:
diff changeset
555 // collision because of the full check above.
anatofuz
parents:
diff changeset
556 return hash_combine(Name, File, Line, BaseType, Scope, Elements,
anatofuz
parents:
diff changeset
557 TemplateParams);
anatofuz
parents:
diff changeset
558 }
anatofuz
parents:
diff changeset
559 };
anatofuz
parents:
diff changeset
560
anatofuz
parents:
diff changeset
561 template <> struct MDNodeKeyImpl<DISubroutineType> {
anatofuz
parents:
diff changeset
562 unsigned Flags;
anatofuz
parents:
diff changeset
563 uint8_t CC;
anatofuz
parents:
diff changeset
564 Metadata *TypeArray;
anatofuz
parents:
diff changeset
565
anatofuz
parents:
diff changeset
566 MDNodeKeyImpl(unsigned Flags, uint8_t CC, Metadata *TypeArray)
anatofuz
parents:
diff changeset
567 : Flags(Flags), CC(CC), TypeArray(TypeArray) {}
anatofuz
parents:
diff changeset
568 MDNodeKeyImpl(const DISubroutineType *N)
anatofuz
parents:
diff changeset
569 : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()) {}
anatofuz
parents:
diff changeset
570
anatofuz
parents:
diff changeset
571 bool isKeyOf(const DISubroutineType *RHS) const {
anatofuz
parents:
diff changeset
572 return Flags == RHS->getFlags() && CC == RHS->getCC() &&
anatofuz
parents:
diff changeset
573 TypeArray == RHS->getRawTypeArray();
anatofuz
parents:
diff changeset
574 }
anatofuz
parents:
diff changeset
575
anatofuz
parents:
diff changeset
576 unsigned getHashValue() const { return hash_combine(Flags, CC, TypeArray); }
anatofuz
parents:
diff changeset
577 };
anatofuz
parents:
diff changeset
578
anatofuz
parents:
diff changeset
579 template <> struct MDNodeKeyImpl<DIFile> {
anatofuz
parents:
diff changeset
580 MDString *Filename;
anatofuz
parents:
diff changeset
581 MDString *Directory;
anatofuz
parents:
diff changeset
582 Optional<DIFile::ChecksumInfo<MDString *>> Checksum;
anatofuz
parents:
diff changeset
583 Optional<MDString *> Source;
anatofuz
parents:
diff changeset
584
anatofuz
parents:
diff changeset
585 MDNodeKeyImpl(MDString *Filename, MDString *Directory,
anatofuz
parents:
diff changeset
586 Optional<DIFile::ChecksumInfo<MDString *>> Checksum,
anatofuz
parents:
diff changeset
587 Optional<MDString *> Source)
anatofuz
parents:
diff changeset
588 : Filename(Filename), Directory(Directory), Checksum(Checksum),
anatofuz
parents:
diff changeset
589 Source(Source) {}
anatofuz
parents:
diff changeset
590 MDNodeKeyImpl(const DIFile *N)
anatofuz
parents:
diff changeset
591 : Filename(N->getRawFilename()), Directory(N->getRawDirectory()),
anatofuz
parents:
diff changeset
592 Checksum(N->getRawChecksum()), Source(N->getRawSource()) {}
anatofuz
parents:
diff changeset
593
anatofuz
parents:
diff changeset
594 bool isKeyOf(const DIFile *RHS) const {
anatofuz
parents:
diff changeset
595 return Filename == RHS->getRawFilename() &&
anatofuz
parents:
diff changeset
596 Directory == RHS->getRawDirectory() &&
anatofuz
parents:
diff changeset
597 Checksum == RHS->getRawChecksum() &&
anatofuz
parents:
diff changeset
598 Source == RHS->getRawSource();
anatofuz
parents:
diff changeset
599 }
anatofuz
parents:
diff changeset
600
anatofuz
parents:
diff changeset
601 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
602 return hash_combine(
anatofuz
parents:
diff changeset
603 Filename, Directory, Checksum ? Checksum->Kind : 0,
anatofuz
parents:
diff changeset
604 Checksum ? Checksum->Value : nullptr, Source.getValueOr(nullptr));
anatofuz
parents:
diff changeset
605 }
anatofuz
parents:
diff changeset
606 };
anatofuz
parents:
diff changeset
607
anatofuz
parents:
diff changeset
608 template <> struct MDNodeKeyImpl<DISubprogram> {
anatofuz
parents:
diff changeset
609 Metadata *Scope;
anatofuz
parents:
diff changeset
610 MDString *Name;
anatofuz
parents:
diff changeset
611 MDString *LinkageName;
anatofuz
parents:
diff changeset
612 Metadata *File;
anatofuz
parents:
diff changeset
613 unsigned Line;
anatofuz
parents:
diff changeset
614 Metadata *Type;
anatofuz
parents:
diff changeset
615 unsigned ScopeLine;
anatofuz
parents:
diff changeset
616 Metadata *ContainingType;
anatofuz
parents:
diff changeset
617 unsigned VirtualIndex;
anatofuz
parents:
diff changeset
618 int ThisAdjustment;
anatofuz
parents:
diff changeset
619 unsigned Flags;
anatofuz
parents:
diff changeset
620 unsigned SPFlags;
anatofuz
parents:
diff changeset
621 Metadata *Unit;
anatofuz
parents:
diff changeset
622 Metadata *TemplateParams;
anatofuz
parents:
diff changeset
623 Metadata *Declaration;
anatofuz
parents:
diff changeset
624 Metadata *RetainedNodes;
anatofuz
parents:
diff changeset
625 Metadata *ThrownTypes;
anatofuz
parents:
diff changeset
626
anatofuz
parents:
diff changeset
627 MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
anatofuz
parents:
diff changeset
628 Metadata *File, unsigned Line, Metadata *Type,
anatofuz
parents:
diff changeset
629 unsigned ScopeLine, Metadata *ContainingType,
anatofuz
parents:
diff changeset
630 unsigned VirtualIndex, int ThisAdjustment, unsigned Flags,
anatofuz
parents:
diff changeset
631 unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams,
anatofuz
parents:
diff changeset
632 Metadata *Declaration, Metadata *RetainedNodes,
anatofuz
parents:
diff changeset
633 Metadata *ThrownTypes)
anatofuz
parents:
diff changeset
634 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
anatofuz
parents:
diff changeset
635 Line(Line), Type(Type), ScopeLine(ScopeLine),
anatofuz
parents:
diff changeset
636 ContainingType(ContainingType), VirtualIndex(VirtualIndex),
anatofuz
parents:
diff changeset
637 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags),
anatofuz
parents:
diff changeset
638 Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration),
anatofuz
parents:
diff changeset
639 RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes) {}
anatofuz
parents:
diff changeset
640 MDNodeKeyImpl(const DISubprogram *N)
anatofuz
parents:
diff changeset
641 : Scope(N->getRawScope()), Name(N->getRawName()),
anatofuz
parents:
diff changeset
642 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
anatofuz
parents:
diff changeset
643 Line(N->getLine()), Type(N->getRawType()), ScopeLine(N->getScopeLine()),
anatofuz
parents:
diff changeset
644 ContainingType(N->getRawContainingType()),
anatofuz
parents:
diff changeset
645 VirtualIndex(N->getVirtualIndex()),
anatofuz
parents:
diff changeset
646 ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()),
anatofuz
parents:
diff changeset
647 SPFlags(N->getSPFlags()), Unit(N->getRawUnit()),
anatofuz
parents:
diff changeset
648 TemplateParams(N->getRawTemplateParams()),
anatofuz
parents:
diff changeset
649 Declaration(N->getRawDeclaration()),
anatofuz
parents:
diff changeset
650 RetainedNodes(N->getRawRetainedNodes()),
anatofuz
parents:
diff changeset
651 ThrownTypes(N->getRawThrownTypes()) {}
anatofuz
parents:
diff changeset
652
anatofuz
parents:
diff changeset
653 bool isKeyOf(const DISubprogram *RHS) const {
anatofuz
parents:
diff changeset
654 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
anatofuz
parents:
diff changeset
655 LinkageName == RHS->getRawLinkageName() &&
anatofuz
parents:
diff changeset
656 File == RHS->getRawFile() && Line == RHS->getLine() &&
anatofuz
parents:
diff changeset
657 Type == RHS->getRawType() && ScopeLine == RHS->getScopeLine() &&
anatofuz
parents:
diff changeset
658 ContainingType == RHS->getRawContainingType() &&
anatofuz
parents:
diff changeset
659 VirtualIndex == RHS->getVirtualIndex() &&
anatofuz
parents:
diff changeset
660 ThisAdjustment == RHS->getThisAdjustment() &&
anatofuz
parents:
diff changeset
661 Flags == RHS->getFlags() && SPFlags == RHS->getSPFlags() &&
anatofuz
parents:
diff changeset
662 Unit == RHS->getUnit() &&
anatofuz
parents:
diff changeset
663 TemplateParams == RHS->getRawTemplateParams() &&
anatofuz
parents:
diff changeset
664 Declaration == RHS->getRawDeclaration() &&
anatofuz
parents:
diff changeset
665 RetainedNodes == RHS->getRawRetainedNodes() &&
anatofuz
parents:
diff changeset
666 ThrownTypes == RHS->getRawThrownTypes();
anatofuz
parents:
diff changeset
667 }
anatofuz
parents:
diff changeset
668
anatofuz
parents:
diff changeset
669 bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; }
anatofuz
parents:
diff changeset
670
anatofuz
parents:
diff changeset
671 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
672 // If this is a declaration inside an ODR type, only hash the type and the
anatofuz
parents:
diff changeset
673 // name. Otherwise the hash will be stronger than
anatofuz
parents:
diff changeset
674 // MDNodeSubsetEqualImpl::isDeclarationOfODRMember().
anatofuz
parents:
diff changeset
675 if (!isDefinition() && LinkageName)
anatofuz
parents:
diff changeset
676 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
anatofuz
parents:
diff changeset
677 if (CT->getRawIdentifier())
anatofuz
parents:
diff changeset
678 return hash_combine(LinkageName, Scope);
anatofuz
parents:
diff changeset
679
anatofuz
parents:
diff changeset
680 // Intentionally computes the hash on a subset of the operands for
anatofuz
parents:
diff changeset
681 // performance reason. The subset has to be significant enough to avoid
anatofuz
parents:
diff changeset
682 // collision "most of the time". There is no correctness issue in case of
anatofuz
parents:
diff changeset
683 // collision because of the full check above.
anatofuz
parents:
diff changeset
684 return hash_combine(Name, Scope, File, Type, Line);
anatofuz
parents:
diff changeset
685 }
anatofuz
parents:
diff changeset
686 };
anatofuz
parents:
diff changeset
687
anatofuz
parents:
diff changeset
688 template <> struct MDNodeSubsetEqualImpl<DISubprogram> {
anatofuz
parents:
diff changeset
689 using KeyTy = MDNodeKeyImpl<DISubprogram>;
anatofuz
parents:
diff changeset
690
anatofuz
parents:
diff changeset
691 static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) {
anatofuz
parents:
diff changeset
692 return isDeclarationOfODRMember(LHS.isDefinition(), LHS.Scope,
anatofuz
parents:
diff changeset
693 LHS.LinkageName, LHS.TemplateParams, RHS);
anatofuz
parents:
diff changeset
694 }
anatofuz
parents:
diff changeset
695
anatofuz
parents:
diff changeset
696 static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) {
anatofuz
parents:
diff changeset
697 return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(),
anatofuz
parents:
diff changeset
698 LHS->getRawLinkageName(),
anatofuz
parents:
diff changeset
699 LHS->getRawTemplateParams(), RHS);
anatofuz
parents:
diff changeset
700 }
anatofuz
parents:
diff changeset
701
anatofuz
parents:
diff changeset
702 /// Subprograms compare equal if they declare the same function in an ODR
anatofuz
parents:
diff changeset
703 /// type.
anatofuz
parents:
diff changeset
704 static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope,
anatofuz
parents:
diff changeset
705 const MDString *LinkageName,
anatofuz
parents:
diff changeset
706 const Metadata *TemplateParams,
anatofuz
parents:
diff changeset
707 const DISubprogram *RHS) {
anatofuz
parents:
diff changeset
708 // Check whether the LHS is eligible.
anatofuz
parents:
diff changeset
709 if (IsDefinition || !Scope || !LinkageName)
anatofuz
parents:
diff changeset
710 return false;
anatofuz
parents:
diff changeset
711
anatofuz
parents:
diff changeset
712 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
anatofuz
parents:
diff changeset
713 if (!CT || !CT->getRawIdentifier())
anatofuz
parents:
diff changeset
714 return false;
anatofuz
parents:
diff changeset
715
anatofuz
parents:
diff changeset
716 // Compare to the RHS.
anatofuz
parents:
diff changeset
717 // FIXME: We need to compare template parameters here to avoid incorrect
anatofuz
parents:
diff changeset
718 // collisions in mapMetadata when RF_MoveDistinctMDs and a ODR-DISubprogram
anatofuz
parents:
diff changeset
719 // has a non-ODR template parameter (i.e., a DICompositeType that does not
anatofuz
parents:
diff changeset
720 // have an identifier). Eventually we should decouple ODR logic from
anatofuz
parents:
diff changeset
721 // uniquing logic.
anatofuz
parents:
diff changeset
722 return IsDefinition == RHS->isDefinition() && Scope == RHS->getRawScope() &&
anatofuz
parents:
diff changeset
723 LinkageName == RHS->getRawLinkageName() &&
anatofuz
parents:
diff changeset
724 TemplateParams == RHS->getRawTemplateParams();
anatofuz
parents:
diff changeset
725 }
anatofuz
parents:
diff changeset
726 };
anatofuz
parents:
diff changeset
727
anatofuz
parents:
diff changeset
728 template <> struct MDNodeKeyImpl<DILexicalBlock> {
anatofuz
parents:
diff changeset
729 Metadata *Scope;
anatofuz
parents:
diff changeset
730 Metadata *File;
anatofuz
parents:
diff changeset
731 unsigned Line;
anatofuz
parents:
diff changeset
732 unsigned Column;
anatofuz
parents:
diff changeset
733
anatofuz
parents:
diff changeset
734 MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Line, unsigned Column)
anatofuz
parents:
diff changeset
735 : Scope(Scope), File(File), Line(Line), Column(Column) {}
anatofuz
parents:
diff changeset
736 MDNodeKeyImpl(const DILexicalBlock *N)
anatofuz
parents:
diff changeset
737 : Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()),
anatofuz
parents:
diff changeset
738 Column(N->getColumn()) {}
anatofuz
parents:
diff changeset
739
anatofuz
parents:
diff changeset
740 bool isKeyOf(const DILexicalBlock *RHS) const {
anatofuz
parents:
diff changeset
741 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
anatofuz
parents:
diff changeset
742 Line == RHS->getLine() && Column == RHS->getColumn();
anatofuz
parents:
diff changeset
743 }
anatofuz
parents:
diff changeset
744
anatofuz
parents:
diff changeset
745 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
746 return hash_combine(Scope, File, Line, Column);
anatofuz
parents:
diff changeset
747 }
anatofuz
parents:
diff changeset
748 };
anatofuz
parents:
diff changeset
749
anatofuz
parents:
diff changeset
750 template <> struct MDNodeKeyImpl<DILexicalBlockFile> {
anatofuz
parents:
diff changeset
751 Metadata *Scope;
anatofuz
parents:
diff changeset
752 Metadata *File;
anatofuz
parents:
diff changeset
753 unsigned Discriminator;
anatofuz
parents:
diff changeset
754
anatofuz
parents:
diff changeset
755 MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator)
anatofuz
parents:
diff changeset
756 : Scope(Scope), File(File), Discriminator(Discriminator) {}
anatofuz
parents:
diff changeset
757 MDNodeKeyImpl(const DILexicalBlockFile *N)
anatofuz
parents:
diff changeset
758 : Scope(N->getRawScope()), File(N->getRawFile()),
anatofuz
parents:
diff changeset
759 Discriminator(N->getDiscriminator()) {}
anatofuz
parents:
diff changeset
760
anatofuz
parents:
diff changeset
761 bool isKeyOf(const DILexicalBlockFile *RHS) const {
anatofuz
parents:
diff changeset
762 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
anatofuz
parents:
diff changeset
763 Discriminator == RHS->getDiscriminator();
anatofuz
parents:
diff changeset
764 }
anatofuz
parents:
diff changeset
765
anatofuz
parents:
diff changeset
766 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
767 return hash_combine(Scope, File, Discriminator);
anatofuz
parents:
diff changeset
768 }
anatofuz
parents:
diff changeset
769 };
anatofuz
parents:
diff changeset
770
anatofuz
parents:
diff changeset
771 template <> struct MDNodeKeyImpl<DINamespace> {
anatofuz
parents:
diff changeset
772 Metadata *Scope;
anatofuz
parents:
diff changeset
773 MDString *Name;
anatofuz
parents:
diff changeset
774 bool ExportSymbols;
anatofuz
parents:
diff changeset
775
anatofuz
parents:
diff changeset
776 MDNodeKeyImpl(Metadata *Scope, MDString *Name, bool ExportSymbols)
anatofuz
parents:
diff changeset
777 : Scope(Scope), Name(Name), ExportSymbols(ExportSymbols) {}
anatofuz
parents:
diff changeset
778 MDNodeKeyImpl(const DINamespace *N)
anatofuz
parents:
diff changeset
779 : Scope(N->getRawScope()), Name(N->getRawName()),
anatofuz
parents:
diff changeset
780 ExportSymbols(N->getExportSymbols()) {}
anatofuz
parents:
diff changeset
781
anatofuz
parents:
diff changeset
782 bool isKeyOf(const DINamespace *RHS) const {
anatofuz
parents:
diff changeset
783 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
anatofuz
parents:
diff changeset
784 ExportSymbols == RHS->getExportSymbols();
anatofuz
parents:
diff changeset
785 }
anatofuz
parents:
diff changeset
786
anatofuz
parents:
diff changeset
787 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
788 return hash_combine(Scope, Name);
anatofuz
parents:
diff changeset
789 }
anatofuz
parents:
diff changeset
790 };
anatofuz
parents:
diff changeset
791
anatofuz
parents:
diff changeset
792 template <> struct MDNodeKeyImpl<DICommonBlock> {
anatofuz
parents:
diff changeset
793 Metadata *Scope;
anatofuz
parents:
diff changeset
794 Metadata *Decl;
anatofuz
parents:
diff changeset
795 MDString *Name;
anatofuz
parents:
diff changeset
796 Metadata *File;
anatofuz
parents:
diff changeset
797 unsigned LineNo;
anatofuz
parents:
diff changeset
798
anatofuz
parents:
diff changeset
799 MDNodeKeyImpl(Metadata *Scope, Metadata *Decl, MDString *Name,
anatofuz
parents:
diff changeset
800 Metadata *File, unsigned LineNo)
anatofuz
parents:
diff changeset
801 : Scope(Scope), Decl(Decl), Name(Name), File(File), LineNo(LineNo) {}
anatofuz
parents:
diff changeset
802 MDNodeKeyImpl(const DICommonBlock *N)
anatofuz
parents:
diff changeset
803 : Scope(N->getRawScope()), Decl(N->getRawDecl()), Name(N->getRawName()),
anatofuz
parents:
diff changeset
804 File(N->getRawFile()), LineNo(N->getLineNo()) {}
anatofuz
parents:
diff changeset
805
anatofuz
parents:
diff changeset
806 bool isKeyOf(const DICommonBlock *RHS) const {
anatofuz
parents:
diff changeset
807 return Scope == RHS->getRawScope() && Decl == RHS->getRawDecl() &&
anatofuz
parents:
diff changeset
808 Name == RHS->getRawName() && File == RHS->getRawFile() &&
anatofuz
parents:
diff changeset
809 LineNo == RHS->getLineNo();
anatofuz
parents:
diff changeset
810 }
anatofuz
parents:
diff changeset
811
anatofuz
parents:
diff changeset
812 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
813 return hash_combine(Scope, Decl, Name, File, LineNo);
anatofuz
parents:
diff changeset
814 }
anatofuz
parents:
diff changeset
815 };
anatofuz
parents:
diff changeset
816
anatofuz
parents:
diff changeset
817 template <> struct MDNodeKeyImpl<DIModule> {
anatofuz
parents:
diff changeset
818 Metadata *Scope;
anatofuz
parents:
diff changeset
819 MDString *Name;
anatofuz
parents:
diff changeset
820 MDString *ConfigurationMacros;
anatofuz
parents:
diff changeset
821 MDString *IncludePath;
anatofuz
parents:
diff changeset
822
anatofuz
parents:
diff changeset
823 MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *ConfigurationMacros,
anatofuz
parents:
diff changeset
824 MDString *IncludePath)
anatofuz
parents:
diff changeset
825 : Scope(Scope), Name(Name), ConfigurationMacros(ConfigurationMacros),
anatofuz
parents:
diff changeset
826 IncludePath(IncludePath) {}
anatofuz
parents:
diff changeset
827 MDNodeKeyImpl(const DIModule *N)
anatofuz
parents:
diff changeset
828 : Scope(N->getRawScope()), Name(N->getRawName()),
anatofuz
parents:
diff changeset
829 ConfigurationMacros(N->getRawConfigurationMacros()),
anatofuz
parents:
diff changeset
830 IncludePath(N->getRawIncludePath()) {}
anatofuz
parents:
diff changeset
831
anatofuz
parents:
diff changeset
832 bool isKeyOf(const DIModule *RHS) const {
anatofuz
parents:
diff changeset
833 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
anatofuz
parents:
diff changeset
834 ConfigurationMacros == RHS->getRawConfigurationMacros() &&
anatofuz
parents:
diff changeset
835 IncludePath == RHS->getRawIncludePath();
anatofuz
parents:
diff changeset
836 }
anatofuz
parents:
diff changeset
837
anatofuz
parents:
diff changeset
838 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
839 return hash_combine(Scope, Name, ConfigurationMacros, IncludePath);
anatofuz
parents:
diff changeset
840 }
anatofuz
parents:
diff changeset
841 };
anatofuz
parents:
diff changeset
842
anatofuz
parents:
diff changeset
843 template <> struct MDNodeKeyImpl<DITemplateTypeParameter> {
anatofuz
parents:
diff changeset
844 MDString *Name;
anatofuz
parents:
diff changeset
845 Metadata *Type;
anatofuz
parents:
diff changeset
846
anatofuz
parents:
diff changeset
847 MDNodeKeyImpl(MDString *Name, Metadata *Type) : Name(Name), Type(Type) {}
anatofuz
parents:
diff changeset
848 MDNodeKeyImpl(const DITemplateTypeParameter *N)
anatofuz
parents:
diff changeset
849 : Name(N->getRawName()), Type(N->getRawType()) {}
anatofuz
parents:
diff changeset
850
anatofuz
parents:
diff changeset
851 bool isKeyOf(const DITemplateTypeParameter *RHS) const {
anatofuz
parents:
diff changeset
852 return Name == RHS->getRawName() && Type == RHS->getRawType();
anatofuz
parents:
diff changeset
853 }
anatofuz
parents:
diff changeset
854
anatofuz
parents:
diff changeset
855 unsigned getHashValue() const { return hash_combine(Name, Type); }
anatofuz
parents:
diff changeset
856 };
anatofuz
parents:
diff changeset
857
anatofuz
parents:
diff changeset
858 template <> struct MDNodeKeyImpl<DITemplateValueParameter> {
anatofuz
parents:
diff changeset
859 unsigned Tag;
anatofuz
parents:
diff changeset
860 MDString *Name;
anatofuz
parents:
diff changeset
861 Metadata *Type;
anatofuz
parents:
diff changeset
862 Metadata *Value;
anatofuz
parents:
diff changeset
863
anatofuz
parents:
diff changeset
864 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *Type, Metadata *Value)
anatofuz
parents:
diff changeset
865 : Tag(Tag), Name(Name), Type(Type), Value(Value) {}
anatofuz
parents:
diff changeset
866 MDNodeKeyImpl(const DITemplateValueParameter *N)
anatofuz
parents:
diff changeset
867 : Tag(N->getTag()), Name(N->getRawName()), Type(N->getRawType()),
anatofuz
parents:
diff changeset
868 Value(N->getValue()) {}
anatofuz
parents:
diff changeset
869
anatofuz
parents:
diff changeset
870 bool isKeyOf(const DITemplateValueParameter *RHS) const {
anatofuz
parents:
diff changeset
871 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
anatofuz
parents:
diff changeset
872 Type == RHS->getRawType() && Value == RHS->getValue();
anatofuz
parents:
diff changeset
873 }
anatofuz
parents:
diff changeset
874
anatofuz
parents:
diff changeset
875 unsigned getHashValue() const { return hash_combine(Tag, Name, Type, Value); }
anatofuz
parents:
diff changeset
876 };
anatofuz
parents:
diff changeset
877
anatofuz
parents:
diff changeset
878 template <> struct MDNodeKeyImpl<DIGlobalVariable> {
anatofuz
parents:
diff changeset
879 Metadata *Scope;
anatofuz
parents:
diff changeset
880 MDString *Name;
anatofuz
parents:
diff changeset
881 MDString *LinkageName;
anatofuz
parents:
diff changeset
882 Metadata *File;
anatofuz
parents:
diff changeset
883 unsigned Line;
anatofuz
parents:
diff changeset
884 Metadata *Type;
anatofuz
parents:
diff changeset
885 bool IsLocalToUnit;
anatofuz
parents:
diff changeset
886 bool IsDefinition;
anatofuz
parents:
diff changeset
887 Metadata *StaticDataMemberDeclaration;
anatofuz
parents:
diff changeset
888 Metadata *TemplateParams;
anatofuz
parents:
diff changeset
889 uint32_t AlignInBits;
anatofuz
parents:
diff changeset
890
anatofuz
parents:
diff changeset
891 MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
anatofuz
parents:
diff changeset
892 Metadata *File, unsigned Line, Metadata *Type,
anatofuz
parents:
diff changeset
893 bool IsLocalToUnit, bool IsDefinition,
anatofuz
parents:
diff changeset
894 Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
anatofuz
parents:
diff changeset
895 uint32_t AlignInBits)
anatofuz
parents:
diff changeset
896 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
anatofuz
parents:
diff changeset
897 Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit),
anatofuz
parents:
diff changeset
898 IsDefinition(IsDefinition),
anatofuz
parents:
diff changeset
899 StaticDataMemberDeclaration(StaticDataMemberDeclaration),
anatofuz
parents:
diff changeset
900 TemplateParams(TemplateParams), AlignInBits(AlignInBits) {}
anatofuz
parents:
diff changeset
901 MDNodeKeyImpl(const DIGlobalVariable *N)
anatofuz
parents:
diff changeset
902 : Scope(N->getRawScope()), Name(N->getRawName()),
anatofuz
parents:
diff changeset
903 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
anatofuz
parents:
diff changeset
904 Line(N->getLine()), Type(N->getRawType()),
anatofuz
parents:
diff changeset
905 IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
anatofuz
parents:
diff changeset
906 StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()),
anatofuz
parents:
diff changeset
907 TemplateParams(N->getRawTemplateParams()),
anatofuz
parents:
diff changeset
908 AlignInBits(N->getAlignInBits()) {}
anatofuz
parents:
diff changeset
909
anatofuz
parents:
diff changeset
910 bool isKeyOf(const DIGlobalVariable *RHS) const {
anatofuz
parents:
diff changeset
911 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
anatofuz
parents:
diff changeset
912 LinkageName == RHS->getRawLinkageName() &&
anatofuz
parents:
diff changeset
913 File == RHS->getRawFile() && Line == RHS->getLine() &&
anatofuz
parents:
diff changeset
914 Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() &&
anatofuz
parents:
diff changeset
915 IsDefinition == RHS->isDefinition() &&
anatofuz
parents:
diff changeset
916 StaticDataMemberDeclaration ==
anatofuz
parents:
diff changeset
917 RHS->getRawStaticDataMemberDeclaration() &&
anatofuz
parents:
diff changeset
918 TemplateParams == RHS->getRawTemplateParams() &&
anatofuz
parents:
diff changeset
919 AlignInBits == RHS->getAlignInBits();
anatofuz
parents:
diff changeset
920 }
anatofuz
parents:
diff changeset
921
anatofuz
parents:
diff changeset
922 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
923 // We do not use AlignInBits in hashing function here on purpose:
anatofuz
parents:
diff changeset
924 // in most cases this param for local variable is zero (for function param
anatofuz
parents:
diff changeset
925 // it is always zero). This leads to lots of hash collisions and errors on
anatofuz
parents:
diff changeset
926 // cases with lots of similar variables.
anatofuz
parents:
diff changeset
927 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
anatofuz
parents:
diff changeset
928 // generated IR is random for each run and test fails with Align included.
anatofuz
parents:
diff changeset
929 // TODO: make hashing work fine with such situations
anatofuz
parents:
diff changeset
930 return hash_combine(Scope, Name, LinkageName, File, Line, Type,
anatofuz
parents:
diff changeset
931 IsLocalToUnit, IsDefinition, /* AlignInBits, */
anatofuz
parents:
diff changeset
932 StaticDataMemberDeclaration);
anatofuz
parents:
diff changeset
933 }
anatofuz
parents:
diff changeset
934 };
anatofuz
parents:
diff changeset
935
anatofuz
parents:
diff changeset
936 template <> struct MDNodeKeyImpl<DILocalVariable> {
anatofuz
parents:
diff changeset
937 Metadata *Scope;
anatofuz
parents:
diff changeset
938 MDString *Name;
anatofuz
parents:
diff changeset
939 Metadata *File;
anatofuz
parents:
diff changeset
940 unsigned Line;
anatofuz
parents:
diff changeset
941 Metadata *Type;
anatofuz
parents:
diff changeset
942 unsigned Arg;
anatofuz
parents:
diff changeset
943 unsigned Flags;
anatofuz
parents:
diff changeset
944 uint32_t AlignInBits;
anatofuz
parents:
diff changeset
945
anatofuz
parents:
diff changeset
946 MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line,
anatofuz
parents:
diff changeset
947 Metadata *Type, unsigned Arg, unsigned Flags,
anatofuz
parents:
diff changeset
948 uint32_t AlignInBits)
anatofuz
parents:
diff changeset
949 : Scope(Scope), Name(Name), File(File), Line(Line), Type(Type), Arg(Arg),
anatofuz
parents:
diff changeset
950 Flags(Flags), AlignInBits(AlignInBits) {}
anatofuz
parents:
diff changeset
951 MDNodeKeyImpl(const DILocalVariable *N)
anatofuz
parents:
diff changeset
952 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
anatofuz
parents:
diff changeset
953 Line(N->getLine()), Type(N->getRawType()), Arg(N->getArg()),
anatofuz
parents:
diff changeset
954 Flags(N->getFlags()), AlignInBits(N->getAlignInBits()) {}
anatofuz
parents:
diff changeset
955
anatofuz
parents:
diff changeset
956 bool isKeyOf(const DILocalVariable *RHS) const {
anatofuz
parents:
diff changeset
957 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
anatofuz
parents:
diff changeset
958 File == RHS->getRawFile() && Line == RHS->getLine() &&
anatofuz
parents:
diff changeset
959 Type == RHS->getRawType() && Arg == RHS->getArg() &&
anatofuz
parents:
diff changeset
960 Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits();
anatofuz
parents:
diff changeset
961 }
anatofuz
parents:
diff changeset
962
anatofuz
parents:
diff changeset
963 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
964 // We do not use AlignInBits in hashing function here on purpose:
anatofuz
parents:
diff changeset
965 // in most cases this param for local variable is zero (for function param
anatofuz
parents:
diff changeset
966 // it is always zero). This leads to lots of hash collisions and errors on
anatofuz
parents:
diff changeset
967 // cases with lots of similar variables.
anatofuz
parents:
diff changeset
968 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
anatofuz
parents:
diff changeset
969 // generated IR is random for each run and test fails with Align included.
anatofuz
parents:
diff changeset
970 // TODO: make hashing work fine with such situations
anatofuz
parents:
diff changeset
971 return hash_combine(Scope, Name, File, Line, Type, Arg, Flags);
anatofuz
parents:
diff changeset
972 }
anatofuz
parents:
diff changeset
973 };
anatofuz
parents:
diff changeset
974
anatofuz
parents:
diff changeset
975 template <> struct MDNodeKeyImpl<DILabel> {
anatofuz
parents:
diff changeset
976 Metadata *Scope;
anatofuz
parents:
diff changeset
977 MDString *Name;
anatofuz
parents:
diff changeset
978 Metadata *File;
anatofuz
parents:
diff changeset
979 unsigned Line;
anatofuz
parents:
diff changeset
980
anatofuz
parents:
diff changeset
981 MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line)
anatofuz
parents:
diff changeset
982 : Scope(Scope), Name(Name), File(File), Line(Line) {}
anatofuz
parents:
diff changeset
983 MDNodeKeyImpl(const DILabel *N)
anatofuz
parents:
diff changeset
984 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
anatofuz
parents:
diff changeset
985 Line(N->getLine()) {}
anatofuz
parents:
diff changeset
986
anatofuz
parents:
diff changeset
987 bool isKeyOf(const DILabel *RHS) const {
anatofuz
parents:
diff changeset
988 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
anatofuz
parents:
diff changeset
989 File == RHS->getRawFile() && Line == RHS->getLine();
anatofuz
parents:
diff changeset
990 }
anatofuz
parents:
diff changeset
991
anatofuz
parents:
diff changeset
992 /// Using name and line to get hash value. It should already be mostly unique.
anatofuz
parents:
diff changeset
993 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
994 return hash_combine(Scope, Name, Line);
anatofuz
parents:
diff changeset
995 }
anatofuz
parents:
diff changeset
996 };
anatofuz
parents:
diff changeset
997
anatofuz
parents:
diff changeset
998 template <> struct MDNodeKeyImpl<DIExpression> {
anatofuz
parents:
diff changeset
999 ArrayRef<uint64_t> Elements;
anatofuz
parents:
diff changeset
1000
anatofuz
parents:
diff changeset
1001 MDNodeKeyImpl(ArrayRef<uint64_t> Elements) : Elements(Elements) {}
anatofuz
parents:
diff changeset
1002 MDNodeKeyImpl(const DIExpression *N) : Elements(N->getElements()) {}
anatofuz
parents:
diff changeset
1003
anatofuz
parents:
diff changeset
1004 bool isKeyOf(const DIExpression *RHS) const {
anatofuz
parents:
diff changeset
1005 return Elements == RHS->getElements();
anatofuz
parents:
diff changeset
1006 }
anatofuz
parents:
diff changeset
1007
anatofuz
parents:
diff changeset
1008 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
1009 return hash_combine_range(Elements.begin(), Elements.end());
anatofuz
parents:
diff changeset
1010 }
anatofuz
parents:
diff changeset
1011 };
anatofuz
parents:
diff changeset
1012
anatofuz
parents:
diff changeset
1013 template <> struct MDNodeKeyImpl<DIGlobalVariableExpression> {
anatofuz
parents:
diff changeset
1014 Metadata *Variable;
anatofuz
parents:
diff changeset
1015 Metadata *Expression;
anatofuz
parents:
diff changeset
1016
anatofuz
parents:
diff changeset
1017 MDNodeKeyImpl(Metadata *Variable, Metadata *Expression)
anatofuz
parents:
diff changeset
1018 : Variable(Variable), Expression(Expression) {}
anatofuz
parents:
diff changeset
1019 MDNodeKeyImpl(const DIGlobalVariableExpression *N)
anatofuz
parents:
diff changeset
1020 : Variable(N->getRawVariable()), Expression(N->getRawExpression()) {}
anatofuz
parents:
diff changeset
1021
anatofuz
parents:
diff changeset
1022 bool isKeyOf(const DIGlobalVariableExpression *RHS) const {
anatofuz
parents:
diff changeset
1023 return Variable == RHS->getRawVariable() &&
anatofuz
parents:
diff changeset
1024 Expression == RHS->getRawExpression();
anatofuz
parents:
diff changeset
1025 }
anatofuz
parents:
diff changeset
1026
anatofuz
parents:
diff changeset
1027 unsigned getHashValue() const { return hash_combine(Variable, Expression); }
anatofuz
parents:
diff changeset
1028 };
anatofuz
parents:
diff changeset
1029
anatofuz
parents:
diff changeset
1030 template <> struct MDNodeKeyImpl<DIObjCProperty> {
anatofuz
parents:
diff changeset
1031 MDString *Name;
anatofuz
parents:
diff changeset
1032 Metadata *File;
anatofuz
parents:
diff changeset
1033 unsigned Line;
anatofuz
parents:
diff changeset
1034 MDString *GetterName;
anatofuz
parents:
diff changeset
1035 MDString *SetterName;
anatofuz
parents:
diff changeset
1036 unsigned Attributes;
anatofuz
parents:
diff changeset
1037 Metadata *Type;
anatofuz
parents:
diff changeset
1038
anatofuz
parents:
diff changeset
1039 MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line,
anatofuz
parents:
diff changeset
1040 MDString *GetterName, MDString *SetterName, unsigned Attributes,
anatofuz
parents:
diff changeset
1041 Metadata *Type)
anatofuz
parents:
diff changeset
1042 : Name(Name), File(File), Line(Line), GetterName(GetterName),
anatofuz
parents:
diff changeset
1043 SetterName(SetterName), Attributes(Attributes), Type(Type) {}
anatofuz
parents:
diff changeset
1044 MDNodeKeyImpl(const DIObjCProperty *N)
anatofuz
parents:
diff changeset
1045 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
anatofuz
parents:
diff changeset
1046 GetterName(N->getRawGetterName()), SetterName(N->getRawSetterName()),
anatofuz
parents:
diff changeset
1047 Attributes(N->getAttributes()), Type(N->getRawType()) {}
anatofuz
parents:
diff changeset
1048
anatofuz
parents:
diff changeset
1049 bool isKeyOf(const DIObjCProperty *RHS) const {
anatofuz
parents:
diff changeset
1050 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
anatofuz
parents:
diff changeset
1051 Line == RHS->getLine() && GetterName == RHS->getRawGetterName() &&
anatofuz
parents:
diff changeset
1052 SetterName == RHS->getRawSetterName() &&
anatofuz
parents:
diff changeset
1053 Attributes == RHS->getAttributes() && Type == RHS->getRawType();
anatofuz
parents:
diff changeset
1054 }
anatofuz
parents:
diff changeset
1055
anatofuz
parents:
diff changeset
1056 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
1057 return hash_combine(Name, File, Line, GetterName, SetterName, Attributes,
anatofuz
parents:
diff changeset
1058 Type);
anatofuz
parents:
diff changeset
1059 }
anatofuz
parents:
diff changeset
1060 };
anatofuz
parents:
diff changeset
1061
anatofuz
parents:
diff changeset
1062 template <> struct MDNodeKeyImpl<DIImportedEntity> {
anatofuz
parents:
diff changeset
1063 unsigned Tag;
anatofuz
parents:
diff changeset
1064 Metadata *Scope;
anatofuz
parents:
diff changeset
1065 Metadata *Entity;
anatofuz
parents:
diff changeset
1066 Metadata *File;
anatofuz
parents:
diff changeset
1067 unsigned Line;
anatofuz
parents:
diff changeset
1068 MDString *Name;
anatofuz
parents:
diff changeset
1069
anatofuz
parents:
diff changeset
1070 MDNodeKeyImpl(unsigned Tag, Metadata *Scope, Metadata *Entity, Metadata *File,
anatofuz
parents:
diff changeset
1071 unsigned Line, MDString *Name)
anatofuz
parents:
diff changeset
1072 : Tag(Tag), Scope(Scope), Entity(Entity), File(File), Line(Line),
anatofuz
parents:
diff changeset
1073 Name(Name) {}
anatofuz
parents:
diff changeset
1074 MDNodeKeyImpl(const DIImportedEntity *N)
anatofuz
parents:
diff changeset
1075 : Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()),
anatofuz
parents:
diff changeset
1076 File(N->getRawFile()), Line(N->getLine()), Name(N->getRawName()) {}
anatofuz
parents:
diff changeset
1077
anatofuz
parents:
diff changeset
1078 bool isKeyOf(const DIImportedEntity *RHS) const {
anatofuz
parents:
diff changeset
1079 return Tag == RHS->getTag() && Scope == RHS->getRawScope() &&
anatofuz
parents:
diff changeset
1080 Entity == RHS->getRawEntity() && File == RHS->getFile() &&
anatofuz
parents:
diff changeset
1081 Line == RHS->getLine() && Name == RHS->getRawName();
anatofuz
parents:
diff changeset
1082 }
anatofuz
parents:
diff changeset
1083
anatofuz
parents:
diff changeset
1084 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
1085 return hash_combine(Tag, Scope, Entity, File, Line, Name);
anatofuz
parents:
diff changeset
1086 }
anatofuz
parents:
diff changeset
1087 };
anatofuz
parents:
diff changeset
1088
anatofuz
parents:
diff changeset
1089 template <> struct MDNodeKeyImpl<DIMacro> {
anatofuz
parents:
diff changeset
1090 unsigned MIType;
anatofuz
parents:
diff changeset
1091 unsigned Line;
anatofuz
parents:
diff changeset
1092 MDString *Name;
anatofuz
parents:
diff changeset
1093 MDString *Value;
anatofuz
parents:
diff changeset
1094
anatofuz
parents:
diff changeset
1095 MDNodeKeyImpl(unsigned MIType, unsigned Line, MDString *Name, MDString *Value)
anatofuz
parents:
diff changeset
1096 : MIType(MIType), Line(Line), Name(Name), Value(Value) {}
anatofuz
parents:
diff changeset
1097 MDNodeKeyImpl(const DIMacro *N)
anatofuz
parents:
diff changeset
1098 : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getRawName()),
anatofuz
parents:
diff changeset
1099 Value(N->getRawValue()) {}
anatofuz
parents:
diff changeset
1100
anatofuz
parents:
diff changeset
1101 bool isKeyOf(const DIMacro *RHS) const {
anatofuz
parents:
diff changeset
1102 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
anatofuz
parents:
diff changeset
1103 Name == RHS->getRawName() && Value == RHS->getRawValue();
anatofuz
parents:
diff changeset
1104 }
anatofuz
parents:
diff changeset
1105
anatofuz
parents:
diff changeset
1106 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
1107 return hash_combine(MIType, Line, Name, Value);
anatofuz
parents:
diff changeset
1108 }
anatofuz
parents:
diff changeset
1109 };
anatofuz
parents:
diff changeset
1110
anatofuz
parents:
diff changeset
1111 template <> struct MDNodeKeyImpl<DIMacroFile> {
anatofuz
parents:
diff changeset
1112 unsigned MIType;
anatofuz
parents:
diff changeset
1113 unsigned Line;
anatofuz
parents:
diff changeset
1114 Metadata *File;
anatofuz
parents:
diff changeset
1115 Metadata *Elements;
anatofuz
parents:
diff changeset
1116
anatofuz
parents:
diff changeset
1117 MDNodeKeyImpl(unsigned MIType, unsigned Line, Metadata *File,
anatofuz
parents:
diff changeset
1118 Metadata *Elements)
anatofuz
parents:
diff changeset
1119 : MIType(MIType), Line(Line), File(File), Elements(Elements) {}
anatofuz
parents:
diff changeset
1120 MDNodeKeyImpl(const DIMacroFile *N)
anatofuz
parents:
diff changeset
1121 : MIType(N->getMacinfoType()), Line(N->getLine()), File(N->getRawFile()),
anatofuz
parents:
diff changeset
1122 Elements(N->getRawElements()) {}
anatofuz
parents:
diff changeset
1123
anatofuz
parents:
diff changeset
1124 bool isKeyOf(const DIMacroFile *RHS) const {
anatofuz
parents:
diff changeset
1125 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
anatofuz
parents:
diff changeset
1126 File == RHS->getRawFile() && Elements == RHS->getRawElements();
anatofuz
parents:
diff changeset
1127 }
anatofuz
parents:
diff changeset
1128
anatofuz
parents:
diff changeset
1129 unsigned getHashValue() const {
anatofuz
parents:
diff changeset
1130 return hash_combine(MIType, Line, File, Elements);
anatofuz
parents:
diff changeset
1131 }
anatofuz
parents:
diff changeset
1132 };
anatofuz
parents:
diff changeset
1133
anatofuz
parents:
diff changeset
1134 /// DenseMapInfo for MDNode subclasses.
anatofuz
parents:
diff changeset
1135 template <class NodeTy> struct MDNodeInfo {
anatofuz
parents:
diff changeset
1136 using KeyTy = MDNodeKeyImpl<NodeTy>;
anatofuz
parents:
diff changeset
1137 using SubsetEqualTy = MDNodeSubsetEqualImpl<NodeTy>;
anatofuz
parents:
diff changeset
1138
anatofuz
parents:
diff changeset
1139 static inline NodeTy *getEmptyKey() {
anatofuz
parents:
diff changeset
1140 return DenseMapInfo<NodeTy *>::getEmptyKey();
anatofuz
parents:
diff changeset
1141 }
anatofuz
parents:
diff changeset
1142
anatofuz
parents:
diff changeset
1143 static inline NodeTy *getTombstoneKey() {
anatofuz
parents:
diff changeset
1144 return DenseMapInfo<NodeTy *>::getTombstoneKey();
anatofuz
parents:
diff changeset
1145 }
anatofuz
parents:
diff changeset
1146
anatofuz
parents:
diff changeset
1147 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
anatofuz
parents:
diff changeset
1148
anatofuz
parents:
diff changeset
1149 static unsigned getHashValue(const NodeTy *N) {
anatofuz
parents:
diff changeset
1150 return KeyTy(N).getHashValue();
anatofuz
parents:
diff changeset
1151 }
anatofuz
parents:
diff changeset
1152
anatofuz
parents:
diff changeset
1153 static bool isEqual(const KeyTy &LHS, const NodeTy *RHS) {
anatofuz
parents:
diff changeset
1154 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
anatofuz
parents:
diff changeset
1155 return false;
anatofuz
parents:
diff changeset
1156 return SubsetEqualTy::isSubsetEqual(LHS, RHS) || LHS.isKeyOf(RHS);
anatofuz
parents:
diff changeset
1157 }
anatofuz
parents:
diff changeset
1158
anatofuz
parents:
diff changeset
1159 static bool isEqual(const NodeTy *LHS, const NodeTy *RHS) {
anatofuz
parents:
diff changeset
1160 if (LHS == RHS)
anatofuz
parents:
diff changeset
1161 return true;
anatofuz
parents:
diff changeset
1162 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
anatofuz
parents:
diff changeset
1163 return false;
anatofuz
parents:
diff changeset
1164 return SubsetEqualTy::isSubsetEqual(LHS, RHS);
anatofuz
parents:
diff changeset
1165 }
anatofuz
parents:
diff changeset
1166 };
anatofuz
parents:
diff changeset
1167
anatofuz
parents:
diff changeset
1168 #define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>;
anatofuz
parents:
diff changeset
1169 #include "llvm/IR/Metadata.def"
anatofuz
parents:
diff changeset
1170
anatofuz
parents:
diff changeset
1171 /// Map-like storage for metadata attachments.
anatofuz
parents:
diff changeset
1172 class MDAttachmentMap {
anatofuz
parents:
diff changeset
1173 SmallVector<std::pair<unsigned, TrackingMDNodeRef>, 2> Attachments;
anatofuz
parents:
diff changeset
1174
anatofuz
parents:
diff changeset
1175 public:
anatofuz
parents:
diff changeset
1176 bool empty() const { return Attachments.empty(); }
anatofuz
parents:
diff changeset
1177 size_t size() const { return Attachments.size(); }
anatofuz
parents:
diff changeset
1178
anatofuz
parents:
diff changeset
1179 /// Get a particular attachment (if any).
anatofuz
parents:
diff changeset
1180 MDNode *lookup(unsigned ID) const;
anatofuz
parents:
diff changeset
1181
anatofuz
parents:
diff changeset
1182 /// Set an attachment to a particular node.
anatofuz
parents:
diff changeset
1183 ///
anatofuz
parents:
diff changeset
1184 /// Set the \c ID attachment to \c MD, replacing the current attachment at \c
anatofuz
parents:
diff changeset
1185 /// ID (if anyway).
anatofuz
parents:
diff changeset
1186 void set(unsigned ID, MDNode &MD);
anatofuz
parents:
diff changeset
1187
anatofuz
parents:
diff changeset
1188 /// Remove an attachment.
anatofuz
parents:
diff changeset
1189 ///
anatofuz
parents:
diff changeset
1190 /// Remove the attachment at \c ID, if any.
anatofuz
parents:
diff changeset
1191 bool erase(unsigned ID);
anatofuz
parents:
diff changeset
1192
anatofuz
parents:
diff changeset
1193 /// Copy out all the attachments.
anatofuz
parents:
diff changeset
1194 ///
anatofuz
parents:
diff changeset
1195 /// Copies all the current attachments into \c Result, sorting by attachment
anatofuz
parents:
diff changeset
1196 /// ID. This function does \em not clear \c Result.
anatofuz
parents:
diff changeset
1197 void getAll(SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const;
anatofuz
parents:
diff changeset
1198
anatofuz
parents:
diff changeset
1199 /// Erase matching attachments.
anatofuz
parents:
diff changeset
1200 ///
anatofuz
parents:
diff changeset
1201 /// Erases all attachments matching the \c shouldRemove predicate.
anatofuz
parents:
diff changeset
1202 template <class PredTy> void remove_if(PredTy shouldRemove) {
anatofuz
parents:
diff changeset
1203 Attachments.erase(llvm::remove_if(Attachments, shouldRemove),
anatofuz
parents:
diff changeset
1204 Attachments.end());
anatofuz
parents:
diff changeset
1205 }
anatofuz
parents:
diff changeset
1206 };
anatofuz
parents:
diff changeset
1207
anatofuz
parents:
diff changeset
1208 /// Multimap-like storage for metadata attachments for globals. This differs
anatofuz
parents:
diff changeset
1209 /// from MDAttachmentMap in that it allows multiple attachments per metadata
anatofuz
parents:
diff changeset
1210 /// kind.
anatofuz
parents:
diff changeset
1211 class MDGlobalAttachmentMap {
anatofuz
parents:
diff changeset
1212 struct Attachment {
anatofuz
parents:
diff changeset
1213 unsigned MDKind;
anatofuz
parents:
diff changeset
1214 TrackingMDNodeRef Node;
anatofuz
parents:
diff changeset
1215 };
anatofuz
parents:
diff changeset
1216 SmallVector<Attachment, 1> Attachments;
anatofuz
parents:
diff changeset
1217
anatofuz
parents:
diff changeset
1218 public:
anatofuz
parents:
diff changeset
1219 bool empty() const { return Attachments.empty(); }
anatofuz
parents:
diff changeset
1220
anatofuz
parents:
diff changeset
1221 /// Appends all attachments with the given ID to \c Result in insertion order.
anatofuz
parents:
diff changeset
1222 /// If the global has no attachments with the given ID, or if ID is invalid,
anatofuz
parents:
diff changeset
1223 /// leaves Result unchanged.
anatofuz
parents:
diff changeset
1224 void get(unsigned ID, SmallVectorImpl<MDNode *> &Result) const;
anatofuz
parents:
diff changeset
1225
anatofuz
parents:
diff changeset
1226 /// Returns the first attachment with the given ID or nullptr if no such
anatofuz
parents:
diff changeset
1227 /// attachment exists.
anatofuz
parents:
diff changeset
1228 MDNode *lookup(unsigned ID) const;
anatofuz
parents:
diff changeset
1229
anatofuz
parents:
diff changeset
1230 void insert(unsigned ID, MDNode &MD);
anatofuz
parents:
diff changeset
1231 bool erase(unsigned ID);
anatofuz
parents:
diff changeset
1232
anatofuz
parents:
diff changeset
1233 /// Appends all attachments for the global to \c Result, sorting by attachment
anatofuz
parents:
diff changeset
1234 /// ID. Attachments with the same ID appear in insertion order. This function
anatofuz
parents:
diff changeset
1235 /// does \em not clear \c Result.
anatofuz
parents:
diff changeset
1236 void getAll(SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const;
anatofuz
parents:
diff changeset
1237 };
anatofuz
parents:
diff changeset
1238
anatofuz
parents:
diff changeset
1239 class LLVMContextImpl {
anatofuz
parents:
diff changeset
1240 public:
anatofuz
parents:
diff changeset
1241 /// OwnedModules - The set of modules instantiated in this context, and which
anatofuz
parents:
diff changeset
1242 /// will be automatically deleted if this context is deleted.
anatofuz
parents:
diff changeset
1243 SmallPtrSet<Module*, 4> OwnedModules;
anatofuz
parents:
diff changeset
1244
anatofuz
parents:
diff changeset
1245 LLVMContext::InlineAsmDiagHandlerTy InlineAsmDiagHandler = nullptr;
anatofuz
parents:
diff changeset
1246 void *InlineAsmDiagContext = nullptr;
anatofuz
parents:
diff changeset
1247
anatofuz
parents:
diff changeset
1248 /// The main remark streamer used by all the other streamers (e.g. IR, MIR,
anatofuz
parents:
diff changeset
1249 /// frontends, etc.). This should only be used by the specific streamers, and
anatofuz
parents:
diff changeset
1250 /// never directly.
anatofuz
parents:
diff changeset
1251 std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer;
anatofuz
parents:
diff changeset
1252
anatofuz
parents:
diff changeset
1253 std::unique_ptr<DiagnosticHandler> DiagHandler;
anatofuz
parents:
diff changeset
1254 bool RespectDiagnosticFilters = false;
anatofuz
parents:
diff changeset
1255 bool DiagnosticsHotnessRequested = false;
anatofuz
parents:
diff changeset
1256 uint64_t DiagnosticsHotnessThreshold = 0;
anatofuz
parents:
diff changeset
1257 /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
anatofuz
parents:
diff changeset
1258 std::unique_ptr<LLVMRemarkStreamer> LLVMRS;
anatofuz
parents:
diff changeset
1259
anatofuz
parents:
diff changeset
1260 LLVMContext::YieldCallbackTy YieldCallback = nullptr;
anatofuz
parents:
diff changeset
1261 void *YieldOpaqueHandle = nullptr;
anatofuz
parents:
diff changeset
1262
anatofuz
parents:
diff changeset
1263 using IntMapTy =
anatofuz
parents:
diff changeset
1264 DenseMap<APInt, std::unique_ptr<ConstantInt>, DenseMapAPIntKeyInfo>;
anatofuz
parents:
diff changeset
1265 IntMapTy IntConstants;
anatofuz
parents:
diff changeset
1266
anatofuz
parents:
diff changeset
1267 using FPMapTy =
anatofuz
parents:
diff changeset
1268 DenseMap<APFloat, std::unique_ptr<ConstantFP>, DenseMapAPFloatKeyInfo>;
anatofuz
parents:
diff changeset
1269 FPMapTy FPConstants;
anatofuz
parents:
diff changeset
1270
anatofuz
parents:
diff changeset
1271 FoldingSet<AttributeImpl> AttrsSet;
anatofuz
parents:
diff changeset
1272 FoldingSet<AttributeListImpl> AttrsLists;
anatofuz
parents:
diff changeset
1273 FoldingSet<AttributeSetNode> AttrsSetNodes;
anatofuz
parents:
diff changeset
1274
anatofuz
parents:
diff changeset
1275 StringMap<MDString, BumpPtrAllocator> MDStringCache;
anatofuz
parents:
diff changeset
1276 DenseMap<Value *, ValueAsMetadata *> ValuesAsMetadata;
anatofuz
parents:
diff changeset
1277 DenseMap<Metadata *, MetadataAsValue *> MetadataAsValues;
anatofuz
parents:
diff changeset
1278
anatofuz
parents:
diff changeset
1279 DenseMap<const Value*, ValueName*> ValueNames;
anatofuz
parents:
diff changeset
1280
anatofuz
parents:
diff changeset
1281 #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
anatofuz
parents:
diff changeset
1282 DenseSet<CLASS *, CLASS##Info> CLASS##s;
anatofuz
parents:
diff changeset
1283 #include "llvm/IR/Metadata.def"
anatofuz
parents:
diff changeset
1284
anatofuz
parents:
diff changeset
1285 // Optional map for looking up composite types by identifier.
anatofuz
parents:
diff changeset
1286 Optional<DenseMap<const MDString *, DICompositeType *>> DITypeMap;
anatofuz
parents:
diff changeset
1287
anatofuz
parents:
diff changeset
1288 // MDNodes may be uniqued or not uniqued. When they're not uniqued, they
anatofuz
parents:
diff changeset
1289 // aren't in the MDNodeSet, but they're still shared between objects, so no
anatofuz
parents:
diff changeset
1290 // one object can destroy them. Keep track of them here so we can delete
anatofuz
parents:
diff changeset
1291 // them on context teardown.
anatofuz
parents:
diff changeset
1292 std::vector<MDNode *> DistinctMDNodes;
anatofuz
parents:
diff changeset
1293
anatofuz
parents:
diff changeset
1294 DenseMap<Type *, std::unique_ptr<ConstantAggregateZero>> CAZConstants;
anatofuz
parents:
diff changeset
1295
anatofuz
parents:
diff changeset
1296 using ArrayConstantsTy = ConstantUniqueMap<ConstantArray>;
anatofuz
parents:
diff changeset
1297 ArrayConstantsTy ArrayConstants;
anatofuz
parents:
diff changeset
1298
anatofuz
parents:
diff changeset
1299 using StructConstantsTy = ConstantUniqueMap<ConstantStruct>;
anatofuz
parents:
diff changeset
1300 StructConstantsTy StructConstants;
anatofuz
parents:
diff changeset
1301
anatofuz
parents:
diff changeset
1302 using VectorConstantsTy = ConstantUniqueMap<ConstantVector>;
anatofuz
parents:
diff changeset
1303 VectorConstantsTy VectorConstants;
anatofuz
parents:
diff changeset
1304
anatofuz
parents:
diff changeset
1305 DenseMap<PointerType *, std::unique_ptr<ConstantPointerNull>> CPNConstants;
anatofuz
parents:
diff changeset
1306
anatofuz
parents:
diff changeset
1307 DenseMap<Type *, std::unique_ptr<UndefValue>> UVConstants;
anatofuz
parents:
diff changeset
1308
anatofuz
parents:
diff changeset
1309 StringMap<ConstantDataSequential*> CDSConstants;
anatofuz
parents:
diff changeset
1310
anatofuz
parents:
diff changeset
1311 DenseMap<std::pair<const Function *, const BasicBlock *>, BlockAddress *>
anatofuz
parents:
diff changeset
1312 BlockAddresses;
anatofuz
parents:
diff changeset
1313 ConstantUniqueMap<ConstantExpr> ExprConstants;
anatofuz
parents:
diff changeset
1314
anatofuz
parents:
diff changeset
1315 ConstantUniqueMap<InlineAsm> InlineAsms;
anatofuz
parents:
diff changeset
1316
anatofuz
parents:
diff changeset
1317 ConstantInt *TheTrueVal = nullptr;
anatofuz
parents:
diff changeset
1318 ConstantInt *TheFalseVal = nullptr;
anatofuz
parents:
diff changeset
1319
anatofuz
parents:
diff changeset
1320 std::unique_ptr<ConstantTokenNone> TheNoneToken;
anatofuz
parents:
diff changeset
1321
anatofuz
parents:
diff changeset
1322 // Basic type instances.
anatofuz
parents:
diff changeset
1323 Type VoidTy, LabelTy, HalfTy, FloatTy, DoubleTy, MetadataTy, TokenTy;
anatofuz
parents:
diff changeset
1324 Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy;
152
e8a9b4f4d755 pull from 146
anatofuz
parents: 150
diff changeset
1325 #ifndef noCbC
e8a9b4f4d755 pull from 146
anatofuz
parents: 150
diff changeset
1326 Type __CodeTy;
e8a9b4f4d755 pull from 146
anatofuz
parents: 150
diff changeset
1327 #endif
150
anatofuz
parents:
diff changeset
1328 IntegerType Int1Ty, Int8Ty, Int16Ty, Int32Ty, Int64Ty, Int128Ty;
anatofuz
parents:
diff changeset
1329
anatofuz
parents:
diff changeset
1330 BumpPtrAllocator Alloc;
anatofuz
parents:
diff changeset
1331 UniqueStringSaver Saver{Alloc};
anatofuz
parents:
diff changeset
1332
anatofuz
parents:
diff changeset
1333 DenseMap<unsigned, IntegerType*> IntegerTypes;
anatofuz
parents:
diff changeset
1334
anatofuz
parents:
diff changeset
1335 using FunctionTypeSet = DenseSet<FunctionType *, FunctionTypeKeyInfo>;
anatofuz
parents:
diff changeset
1336 FunctionTypeSet FunctionTypes;
anatofuz
parents:
diff changeset
1337 using StructTypeSet = DenseSet<StructType *, AnonStructTypeKeyInfo>;
anatofuz
parents:
diff changeset
1338 StructTypeSet AnonStructTypes;
anatofuz
parents:
diff changeset
1339 StringMap<StructType*> NamedStructTypes;
anatofuz
parents:
diff changeset
1340 unsigned NamedStructTypesUniqueID = 0;
anatofuz
parents:
diff changeset
1341
anatofuz
parents:
diff changeset
1342 DenseMap<std::pair<Type *, uint64_t>, ArrayType*> ArrayTypes;
anatofuz
parents:
diff changeset
1343 DenseMap<std::pair<Type *, ElementCount>, VectorType*> VectorTypes;
anatofuz
parents:
diff changeset
1344 DenseMap<Type*, PointerType*> PointerTypes; // Pointers in AddrSpace = 0
anatofuz
parents:
diff changeset
1345 DenseMap<std::pair<Type*, unsigned>, PointerType*> ASPointerTypes;
anatofuz
parents:
diff changeset
1346
anatofuz
parents:
diff changeset
1347 /// ValueHandles - This map keeps track of all of the value handles that are
anatofuz
parents:
diff changeset
1348 /// watching a Value*. The Value::HasValueHandle bit is used to know
anatofuz
parents:
diff changeset
1349 /// whether or not a value has an entry in this map.
anatofuz
parents:
diff changeset
1350 using ValueHandlesTy = DenseMap<Value *, ValueHandleBase *>;
anatofuz
parents:
diff changeset
1351 ValueHandlesTy ValueHandles;
anatofuz
parents:
diff changeset
1352
anatofuz
parents:
diff changeset
1353 /// CustomMDKindNames - Map to hold the metadata string to ID mapping.
anatofuz
parents:
diff changeset
1354 StringMap<unsigned> CustomMDKindNames;
anatofuz
parents:
diff changeset
1355
anatofuz
parents:
diff changeset
1356 /// Collection of per-instruction metadata used in this context.
anatofuz
parents:
diff changeset
1357 DenseMap<const Instruction *, MDAttachmentMap> InstructionMetadata;
anatofuz
parents:
diff changeset
1358
anatofuz
parents:
diff changeset
1359 /// Collection of per-GlobalObject metadata used in this context.
anatofuz
parents:
diff changeset
1360 DenseMap<const GlobalObject *, MDGlobalAttachmentMap> GlobalObjectMetadata;
anatofuz
parents:
diff changeset
1361
anatofuz
parents:
diff changeset
1362 /// Collection of per-GlobalObject sections used in this context.
anatofuz
parents:
diff changeset
1363 DenseMap<const GlobalObject *, StringRef> GlobalObjectSections;
anatofuz
parents:
diff changeset
1364
anatofuz
parents:
diff changeset
1365 /// Collection of per-GlobalValue partitions used in this context.
anatofuz
parents:
diff changeset
1366 DenseMap<const GlobalValue *, StringRef> GlobalValuePartitions;
anatofuz
parents:
diff changeset
1367
anatofuz
parents:
diff changeset
1368 /// DiscriminatorTable - This table maps file:line locations to an
anatofuz
parents:
diff changeset
1369 /// integer representing the next DWARF path discriminator to assign to
anatofuz
parents:
diff changeset
1370 /// instructions in different blocks at the same location.
anatofuz
parents:
diff changeset
1371 DenseMap<std::pair<const char *, unsigned>, unsigned> DiscriminatorTable;
anatofuz
parents:
diff changeset
1372
anatofuz
parents:
diff changeset
1373 int getOrAddScopeRecordIdxEntry(MDNode *N, int ExistingIdx);
anatofuz
parents:
diff changeset
1374 int getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,int ExistingIdx);
anatofuz
parents:
diff changeset
1375
anatofuz
parents:
diff changeset
1376 /// A set of interned tags for operand bundles. The StringMap maps
anatofuz
parents:
diff changeset
1377 /// bundle tags to their IDs.
anatofuz
parents:
diff changeset
1378 ///
anatofuz
parents:
diff changeset
1379 /// \see LLVMContext::getOperandBundleTagID
anatofuz
parents:
diff changeset
1380 StringMap<uint32_t> BundleTagCache;
anatofuz
parents:
diff changeset
1381
anatofuz
parents:
diff changeset
1382 StringMapEntry<uint32_t> *getOrInsertBundleTag(StringRef Tag);
anatofuz
parents:
diff changeset
1383 void getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const;
anatofuz
parents:
diff changeset
1384 uint32_t getOperandBundleTagID(StringRef Tag) const;
anatofuz
parents:
diff changeset
1385
anatofuz
parents:
diff changeset
1386 /// A set of interned synchronization scopes. The StringMap maps
anatofuz
parents:
diff changeset
1387 /// synchronization scope names to their respective synchronization scope IDs.
anatofuz
parents:
diff changeset
1388 StringMap<SyncScope::ID> SSC;
anatofuz
parents:
diff changeset
1389
anatofuz
parents:
diff changeset
1390 /// getOrInsertSyncScopeID - Maps synchronization scope name to
anatofuz
parents:
diff changeset
1391 /// synchronization scope ID. Every synchronization scope registered with
anatofuz
parents:
diff changeset
1392 /// LLVMContext has unique ID except pre-defined ones.
anatofuz
parents:
diff changeset
1393 SyncScope::ID getOrInsertSyncScopeID(StringRef SSN);
anatofuz
parents:
diff changeset
1394
anatofuz
parents:
diff changeset
1395 /// getSyncScopeNames - Populates client supplied SmallVector with
anatofuz
parents:
diff changeset
1396 /// synchronization scope names registered with LLVMContext. Synchronization
anatofuz
parents:
diff changeset
1397 /// scope names are ordered by increasing synchronization scope IDs.
anatofuz
parents:
diff changeset
1398 void getSyncScopeNames(SmallVectorImpl<StringRef> &SSNs) const;
anatofuz
parents:
diff changeset
1399
anatofuz
parents:
diff changeset
1400 /// Maintain the GC name for each function.
anatofuz
parents:
diff changeset
1401 ///
anatofuz
parents:
diff changeset
1402 /// This saves allocating an additional word in Function for programs which
anatofuz
parents:
diff changeset
1403 /// do not use GC (i.e., most programs) at the cost of increased overhead for
anatofuz
parents:
diff changeset
1404 /// clients which do use GC.
anatofuz
parents:
diff changeset
1405 DenseMap<const Function*, std::string> GCNames;
anatofuz
parents:
diff changeset
1406
anatofuz
parents:
diff changeset
1407 /// Flag to indicate if Value (other than GlobalValue) retains their name or
anatofuz
parents:
diff changeset
1408 /// not.
anatofuz
parents:
diff changeset
1409 bool DiscardValueNames = false;
anatofuz
parents:
diff changeset
1410
anatofuz
parents:
diff changeset
1411 LLVMContextImpl(LLVMContext &C);
anatofuz
parents:
diff changeset
1412 ~LLVMContextImpl();
anatofuz
parents:
diff changeset
1413
anatofuz
parents:
diff changeset
1414 /// Destroy the ConstantArrays if they are not used.
anatofuz
parents:
diff changeset
1415 void dropTriviallyDeadConstantArrays();
anatofuz
parents:
diff changeset
1416
anatofuz
parents:
diff changeset
1417 mutable OptPassGate *OPG = nullptr;
anatofuz
parents:
diff changeset
1418
anatofuz
parents:
diff changeset
1419 /// Access the object which can disable optional passes and individual
anatofuz
parents:
diff changeset
1420 /// optimizations at compile time.
anatofuz
parents:
diff changeset
1421 OptPassGate &getOptPassGate() const;
anatofuz
parents:
diff changeset
1422
anatofuz
parents:
diff changeset
1423 /// Set the object which can disable optional passes and individual
anatofuz
parents:
diff changeset
1424 /// optimizations at compile time.
anatofuz
parents:
diff changeset
1425 ///
anatofuz
parents:
diff changeset
1426 /// The lifetime of the object must be guaranteed to extend as long as the
anatofuz
parents:
diff changeset
1427 /// LLVMContext is used by compilation.
anatofuz
parents:
diff changeset
1428 void setOptPassGate(OptPassGate&);
anatofuz
parents:
diff changeset
1429 };
anatofuz
parents:
diff changeset
1430
anatofuz
parents:
diff changeset
1431 } // end namespace llvm
anatofuz
parents:
diff changeset
1432
anatofuz
parents:
diff changeset
1433 #endif // LLVM_LIB_IR_LLVMCONTEXTIMPL_H