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

source code of llvm/lib/IR/LLVMContextImpl.h