LLVM 17.0.0git
LLVMContextImpl.h
Go to the documentation of this file.
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"
23#include "llvm/ADT/DenseSet.h"
24#include "llvm/ADT/FoldingSet.h"
25#include "llvm/ADT/Hashing.h"
26#include "llvm/ADT/STLExtras.h"
29#include "llvm/ADT/StringMap.h"
31#include "llvm/IR/Constants.h"
34#include "llvm/IR/LLVMContext.h"
35#include "llvm/IR/Metadata.h"
36#include "llvm/IR/Module.h"
38#include "llvm/IR/Type.h"
39#include "llvm/IR/Value.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;
59struct DiagnosticHandler;
60class ElementCount;
61class Function;
62class GlobalObject;
63class GlobalValue;
64class InlineAsm;
65class LLVMRemarkStreamer;
66class OptPassGate;
67namespace remarks {
68class RemarkStreamer;
69}
70template <typename T> class StringMapEntry;
71class StringRef;
72class TypedPointerType;
73class ValueHandleBase;
74
76
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(Key));
85 }
86
87 static bool isEqual(const APFloat &LHS, const APFloat &RHS) {
88 return LHS.bitwiseIsEqual(RHS);
89 }
90};
91
93 struct KeyTy {
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() {
114 }
115
116 static inline StructType *getTombstoneKey() {
118 }
119
120 static unsigned getHashValue(const KeyTy &Key) {
121 return hash_combine(
122 hash_combine_range(Key.ETypes.begin(), Key.ETypes.end()), Key.isPacked);
123 }
124
125 static unsigned getHashValue(const StructType *ST) {
126 return getHashValue(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
141 struct KeyTy {
145
146 KeyTy(const Type *R, const ArrayRef<Type *> &P, bool V)
147 : ReturnType(R), Params(P), isVarArg(V) {}
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() {
166 }
167
168 static inline FunctionType *getTombstoneKey() {
170 }
171
172 static unsigned getHashValue(const KeyTy &Key) {
173 return hash_combine(
174 Key.ReturnType,
175 hash_combine_range(Key.Params.begin(), Key.Params.end()), Key.isVarArg);
176 }
177
178 static unsigned getHashValue(const FunctionType *FT) {
179 return getHashValue(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
194 struct KeyTy {
198
200 : Name(N), TypeParams(TP), IntParams(IP) {}
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() {
214 }
215
218 }
219
220 static unsigned getHashValue(const KeyTy &Key) {
221 return hash_combine(
222 Key.Name,
223 hash_combine_range(Key.TypeParams.begin(), Key.TypeParams.end()),
224 hash_combine_range(Key.IntParams.begin(), Key.IntParams.end()));
225 }
226
227 static unsigned getHashValue(const TargetExtType *FT) {
228 return getHashValue(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.
246 unsigned Hash;
247
248protected:
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 {
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 {
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) {
311 }
312};
313
314/// DenseMapInfo for DILocation.
315template <> struct MDNodeKeyImpl<DILocation> {
316 unsigned Line;
317 unsigned Column;
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) {}
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(Line, Column, Scope, InlinedAt, ImplicitCode);
338 }
339};
340
341/// DenseMapInfo for GenericDINode.
343 unsigned Tag;
345
346 MDNodeKeyImpl(unsigned Tag, MDString *Header, ArrayRef<Metadata *> DwarfOps)
347 : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {}
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, 1);
354 }
355
356 unsigned getHashValue() const { return hash_combine(getHash(), Tag, Header); }
357
358 static unsigned calculateHash(GenericDINode *N) {
360 }
361};
362
363template <> struct MDNodeKeyImpl<DISubrange> {
368
369 MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound,
370 Metadata *Stride)
371 : CountNode(CountNode), LowerBound(LowerBound), UpperBound(UpperBound),
372 Stride(Stride) {}
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>(Node1);
383 ConstantAsMetadata *MD2 = dyn_cast_or_null<ConstantAsMetadata>(Node2);
384 if (MD1 && MD2) {
385 ConstantInt *CV1 = cast<ConstantInt>(MD1->getValue());
386 ConstantInt *CV2 = cast<ConstantInt>(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>(CountNode))
402 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
403 LowerBound, UpperBound, Stride);
404 return hash_combine(CountNode, LowerBound, UpperBound, Stride);
405 }
406};
407
408template <> struct MDNodeKeyImpl<DIGenericSubrange> {
413
414 MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound,
415 Metadata *Stride)
416 : CountNode(CountNode), LowerBound(LowerBound), UpperBound(UpperBound),
417 Stride(Stride) {}
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>(CountNode);
431 if (CountNode && MD)
432 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
433 LowerBound, UpperBound, Stride);
434 return hash_combine(CountNode, LowerBound, UpperBound, Stride);
435 }
436};
437
438template <> struct MDNodeKeyImpl<DIEnumerator> {
442
444 : Value(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) {}
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(Value, Name); }
459};
460
461template <> struct MDNodeKeyImpl<DIBasicType> {
462 unsigned Tag;
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) {}
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(Tag, Name, SizeInBits, AlignInBits, Encoding);
487 }
488};
489
490template <> struct MDNodeKeyImpl<DIStringType> {
491 unsigned Tag;
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) {}
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 SizeInBits == RHS->getSizeInBits() &&
517 AlignInBits == RHS->getAlignInBits() &&
518 Encoding == RHS->getEncoding();
519 }
520 unsigned getHashValue() const { return hash_combine(Tag, Name, Encoding); }
521};
522
523template <> struct MDNodeKeyImpl<DIDerivedType> {
524 unsigned Tag;
527 unsigned Line;
533 std::optional<unsigned> DWARFAddressSpace;
534 unsigned Flags;
537
538 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
539 Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
540 uint32_t AlignInBits, uint64_t OffsetInBits,
541 std::optional<unsigned> DWARFAddressSpace, unsigned Flags,
542 Metadata *ExtraData, Metadata *Annotations)
543 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
544 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
545 AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace),
546 Flags(Flags), ExtraData(ExtraData), Annotations(Annotations) {}
548 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
549 Line(N->getLine()), Scope(N->getRawScope()),
550 BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
551 OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()),
552 DWARFAddressSpace(N->getDWARFAddressSpace()), Flags(N->getFlags()),
553 ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {}
554
555 bool isKeyOf(const DIDerivedType *RHS) const {
556 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
557 File == RHS->getRawFile() && Line == RHS->getLine() &&
558 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
559 SizeInBits == RHS->getSizeInBits() &&
560 AlignInBits == RHS->getAlignInBits() &&
561 OffsetInBits == RHS->getOffsetInBits() &&
562 DWARFAddressSpace == RHS->getDWARFAddressSpace() &&
563 Flags == RHS->getFlags() && ExtraData == RHS->getRawExtraData() &&
564 Annotations == RHS->getRawAnnotations();
565 }
566
567 unsigned getHashValue() const {
568 // If this is a member inside an ODR type, only hash the type and the name.
569 // Otherwise the hash will be stronger than
570 // MDNodeSubsetEqualImpl::isODRMember().
571 if (Tag == dwarf::DW_TAG_member && Name)
572 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
573 if (CT->getRawIdentifier())
574 return hash_combine(Name, Scope);
575
576 // Intentionally computes the hash on a subset of the operands for
577 // performance reason. The subset has to be significant enough to avoid
578 // collision "most of the time". There is no correctness issue in case of
579 // collision because of the full check above.
580 return hash_combine(Tag, Name, File, Line, Scope, BaseType, Flags);
581 }
582};
583
586
587 static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) {
588 return isODRMember(LHS.Tag, LHS.Scope, LHS.Name, RHS);
589 }
590
591 static bool isSubsetEqual(const DIDerivedType *LHS,
592 const DIDerivedType *RHS) {
593 return isODRMember(LHS->getTag(), LHS->getRawScope(), LHS->getRawName(),
594 RHS);
595 }
596
597 /// Subprograms compare equal if they declare the same function in an ODR
598 /// type.
599 static bool isODRMember(unsigned Tag, const Metadata *Scope,
600 const MDString *Name, const DIDerivedType *RHS) {
601 // Check whether the LHS is eligible.
602 if (Tag != dwarf::DW_TAG_member || !Name)
603 return false;
604
605 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
606 if (!CT || !CT->getRawIdentifier())
607 return false;
608
609 // Compare to the RHS.
610 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
611 Scope == RHS->getRawScope();
612 }
613};
614
615template <> struct MDNodeKeyImpl<DICompositeType> {
616 unsigned Tag;
619 unsigned Line;
625 unsigned Flags;
627 unsigned RuntimeLang;
637
638 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
639 Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
640 uint32_t AlignInBits, uint64_t OffsetInBits, unsigned Flags,
641 Metadata *Elements, unsigned RuntimeLang,
642 Metadata *VTableHolder, Metadata *TemplateParams,
643 MDString *Identifier, Metadata *Discriminator,
644 Metadata *DataLocation, Metadata *Associated,
645 Metadata *Allocated, Metadata *Rank, Metadata *Annotations)
646 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
647 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
648 AlignInBits(AlignInBits), Flags(Flags), Elements(Elements),
649 RuntimeLang(RuntimeLang), VTableHolder(VTableHolder),
650 TemplateParams(TemplateParams), Identifier(Identifier),
651 Discriminator(Discriminator), DataLocation(DataLocation),
652 Associated(Associated), Allocated(Allocated), Rank(Rank),
655 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
656 Line(N->getLine()), Scope(N->getRawScope()),
657 BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
658 OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()),
659 Flags(N->getFlags()), Elements(N->getRawElements()),
660 RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()),
661 TemplateParams(N->getRawTemplateParams()),
662 Identifier(N->getRawIdentifier()),
663 Discriminator(N->getRawDiscriminator()),
664 DataLocation(N->getRawDataLocation()),
665 Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()),
666 Rank(N->getRawRank()), Annotations(N->getRawAnnotations()) {}
667
668 bool isKeyOf(const DICompositeType *RHS) const {
669 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
670 File == RHS->getRawFile() && Line == RHS->getLine() &&
671 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
672 SizeInBits == RHS->getSizeInBits() &&
673 AlignInBits == RHS->getAlignInBits() &&
674 OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() &&
675 Elements == RHS->getRawElements() &&
676 RuntimeLang == RHS->getRuntimeLang() &&
677 VTableHolder == RHS->getRawVTableHolder() &&
678 TemplateParams == RHS->getRawTemplateParams() &&
679 Identifier == RHS->getRawIdentifier() &&
680 Discriminator == RHS->getRawDiscriminator() &&
681 DataLocation == RHS->getRawDataLocation() &&
682 Associated == RHS->getRawAssociated() &&
683 Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() &&
684 Annotations == RHS->getRawAnnotations();
685 }
686
687 unsigned getHashValue() const {
688 // Intentionally computes the hash on a subset of the operands for
689 // performance reason. The subset has to be significant enough to avoid
690 // collision "most of the time". There is no correctness issue in case of
691 // collision because of the full check above.
692 return hash_combine(Name, File, Line, BaseType, Scope, Elements,
693 TemplateParams, Annotations);
694 }
695};
696
697template <> struct MDNodeKeyImpl<DISubroutineType> {
698 unsigned Flags;
699 uint8_t CC;
701
702 MDNodeKeyImpl(unsigned Flags, uint8_t CC, Metadata *TypeArray)
703 : Flags(Flags), CC(CC), TypeArray(TypeArray) {}
705 : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()) {}
706
707 bool isKeyOf(const DISubroutineType *RHS) const {
708 return Flags == RHS->getFlags() && CC == RHS->getCC() &&
709 TypeArray == RHS->getRawTypeArray();
710 }
711
712 unsigned getHashValue() const { return hash_combine(Flags, CC, TypeArray); }
713};
714
715template <> struct MDNodeKeyImpl<DIFile> {
718 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum;
720
721 MDNodeKeyImpl(MDString *Filename, MDString *Directory,
722 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum,
723 MDString *Source)
724 : Filename(Filename), Directory(Directory), Checksum(Checksum),
725 Source(Source) {}
727 : Filename(N->getRawFilename()), Directory(N->getRawDirectory()),
728 Checksum(N->getRawChecksum()), Source(N->getRawSource()) {}
729
730 bool isKeyOf(const DIFile *RHS) const {
731 return Filename == RHS->getRawFilename() &&
732 Directory == RHS->getRawDirectory() &&
733 Checksum == RHS->getRawChecksum() && Source == RHS->getRawSource();
734 }
735
736 unsigned getHashValue() const {
737 return hash_combine(Filename, Directory, Checksum ? Checksum->Kind : 0,
738 Checksum ? Checksum->Value : nullptr, Source);
739 }
740};
741
742template <> struct MDNodeKeyImpl<DISubprogram> {
747 unsigned Line;
749 unsigned ScopeLine;
751 unsigned VirtualIndex;
753 unsigned Flags;
754 unsigned SPFlags;
762
764 Metadata *File, unsigned Line, Metadata *Type,
765 unsigned ScopeLine, Metadata *ContainingType,
766 unsigned VirtualIndex, int ThisAdjustment, unsigned Flags,
767 unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams,
768 Metadata *Declaration, Metadata *RetainedNodes,
769 Metadata *ThrownTypes, Metadata *Annotations,
770 MDString *TargetFuncName)
771 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
772 Line(Line), Type(Type), ScopeLine(ScopeLine),
773 ContainingType(ContainingType), VirtualIndex(VirtualIndex),
774 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags),
775 Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration),
776 RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes),
777 Annotations(Annotations), TargetFuncName(TargetFuncName) {}
779 : Scope(N->getRawScope()), Name(N->getRawName()),
780 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
781 Line(N->getLine()), Type(N->getRawType()), ScopeLine(N->getScopeLine()),
782 ContainingType(N->getRawContainingType()),
783 VirtualIndex(N->getVirtualIndex()),
784 ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()),
785 SPFlags(N->getSPFlags()), Unit(N->getRawUnit()),
786 TemplateParams(N->getRawTemplateParams()),
787 Declaration(N->getRawDeclaration()),
788 RetainedNodes(N->getRawRetainedNodes()),
789 ThrownTypes(N->getRawThrownTypes()),
790 Annotations(N->getRawAnnotations()),
791 TargetFuncName(N->getRawTargetFuncName()) {}
792
793 bool isKeyOf(const DISubprogram *RHS) const {
794 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
795 LinkageName == RHS->getRawLinkageName() &&
796 File == RHS->getRawFile() && Line == RHS->getLine() &&
797 Type == RHS->getRawType() && ScopeLine == RHS->getScopeLine() &&
798 ContainingType == RHS->getRawContainingType() &&
799 VirtualIndex == RHS->getVirtualIndex() &&
800 ThisAdjustment == RHS->getThisAdjustment() &&
801 Flags == RHS->getFlags() && SPFlags == RHS->getSPFlags() &&
802 Unit == RHS->getUnit() &&
803 TemplateParams == RHS->getRawTemplateParams() &&
804 Declaration == RHS->getRawDeclaration() &&
805 RetainedNodes == RHS->getRawRetainedNodes() &&
806 ThrownTypes == RHS->getRawThrownTypes() &&
807 Annotations == RHS->getRawAnnotations() &&
808 TargetFuncName == RHS->getRawTargetFuncName();
809 }
810
811 bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; }
812
813 unsigned getHashValue() const {
814 // If this is a declaration inside an ODR type, only hash the type and the
815 // name. Otherwise the hash will be stronger than
816 // MDNodeSubsetEqualImpl::isDeclarationOfODRMember().
817 if (!isDefinition() && LinkageName)
818 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
819 if (CT->getRawIdentifier())
820 return hash_combine(LinkageName, Scope);
821
822 // Intentionally computes the hash on a subset of the operands for
823 // performance reason. The subset has to be significant enough to avoid
824 // collision "most of the time". There is no correctness issue in case of
825 // collision because of the full check above.
826 return hash_combine(Name, Scope, File, Type, Line);
827 }
828};
829
832
833 static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) {
834 return isDeclarationOfODRMember(LHS.isDefinition(), LHS.Scope,
835 LHS.LinkageName, LHS.TemplateParams, RHS);
836 }
837
838 static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) {
839 return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(),
840 LHS->getRawLinkageName(),
841 LHS->getRawTemplateParams(), RHS);
842 }
843
844 /// Subprograms compare equal if they declare the same function in an ODR
845 /// type.
846 static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope,
847 const MDString *LinkageName,
848 const Metadata *TemplateParams,
849 const DISubprogram *RHS) {
850 // Check whether the LHS is eligible.
851 if (IsDefinition || !Scope || !LinkageName)
852 return false;
853
854 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
855 if (!CT || !CT->getRawIdentifier())
856 return false;
857
858 // Compare to the RHS.
859 // FIXME: We need to compare template parameters here to avoid incorrect
860 // collisions in mapMetadata when RF_ReuseAndMutateDistinctMDs and a
861 // ODR-DISubprogram has a non-ODR template parameter (i.e., a
862 // DICompositeType that does not have an identifier). Eventually we should
863 // decouple ODR logic from uniquing logic.
864 return IsDefinition == RHS->isDefinition() && Scope == RHS->getRawScope() &&
865 LinkageName == RHS->getRawLinkageName() &&
866 TemplateParams == RHS->getRawTemplateParams();
867 }
868};
869
870template <> struct MDNodeKeyImpl<DILexicalBlock> {
873 unsigned Line;
874 unsigned Column;
875
876 MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Line, unsigned Column)
877 : Scope(Scope), File(File), Line(Line), Column(Column) {}
879 : Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()),
880 Column(N->getColumn()) {}
881
882 bool isKeyOf(const DILexicalBlock *RHS) const {
883 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
884 Line == RHS->getLine() && Column == RHS->getColumn();
885 }
886
887 unsigned getHashValue() const {
888 return hash_combine(Scope, File, Line, Column);
889 }
890};
891
896
897 MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator)
898 : Scope(Scope), File(File), Discriminator(Discriminator) {}
900 : Scope(N->getRawScope()), File(N->getRawFile()),
901 Discriminator(N->getDiscriminator()) {}
902
903 bool isKeyOf(const DILexicalBlockFile *RHS) const {
904 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
905 Discriminator == RHS->getDiscriminator();
906 }
907
908 unsigned getHashValue() const {
909 return hash_combine(Scope, File, Discriminator);
910 }
911};
912
913template <> struct MDNodeKeyImpl<DINamespace> {
917
918 MDNodeKeyImpl(Metadata *Scope, MDString *Name, bool ExportSymbols)
919 : Scope(Scope), Name(Name), ExportSymbols(ExportSymbols) {}
921 : Scope(N->getRawScope()), Name(N->getRawName()),
922 ExportSymbols(N->getExportSymbols()) {}
923
924 bool isKeyOf(const DINamespace *RHS) const {
925 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
926 ExportSymbols == RHS->getExportSymbols();
927 }
928
929 unsigned getHashValue() const { return hash_combine(Scope, Name); }
930};
931
932template <> struct MDNodeKeyImpl<DICommonBlock> {
937 unsigned LineNo;
938
940 unsigned LineNo)
941 : Scope(Scope), Decl(Decl), Name(Name), File(File), LineNo(LineNo) {}
943 : Scope(N->getRawScope()), Decl(N->getRawDecl()), Name(N->getRawName()),
944 File(N->getRawFile()), LineNo(N->getLineNo()) {}
945
946 bool isKeyOf(const DICommonBlock *RHS) const {
947 return Scope == RHS->getRawScope() && Decl == RHS->getRawDecl() &&
948 Name == RHS->getRawName() && File == RHS->getRawFile() &&
949 LineNo == RHS->getLineNo();
950 }
951
952 unsigned getHashValue() const {
953 return hash_combine(Scope, Decl, Name, File, LineNo);
954 }
955};
956
957template <> struct MDNodeKeyImpl<DIModule> {
964 unsigned LineNo;
965 bool IsDecl;
966
968 MDString *ConfigurationMacros, MDString *IncludePath,
969 MDString *APINotesFile, unsigned LineNo, bool IsDecl)
970 : File(File), Scope(Scope), Name(Name),
971 ConfigurationMacros(ConfigurationMacros), IncludePath(IncludePath),
972 APINotesFile(APINotesFile), LineNo(LineNo), IsDecl(IsDecl) {}
974 : File(N->getRawFile()), Scope(N->getRawScope()), Name(N->getRawName()),
975 ConfigurationMacros(N->getRawConfigurationMacros()),
976 IncludePath(N->getRawIncludePath()),
977 APINotesFile(N->getRawAPINotesFile()), LineNo(N->getLineNo()),
978 IsDecl(N->getIsDecl()) {}
979
980 bool isKeyOf(const DIModule *RHS) const {
981 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
982 ConfigurationMacros == RHS->getRawConfigurationMacros() &&
983 IncludePath == RHS->getRawIncludePath() &&
984 APINotesFile == RHS->getRawAPINotesFile() &&
985 File == RHS->getRawFile() && LineNo == RHS->getLineNo() &&
986 IsDecl == RHS->getIsDecl();
987 }
988
989 unsigned getHashValue() const {
990 return hash_combine(Scope, Name, ConfigurationMacros, IncludePath);
991 }
992};
993
998
1000 : Name(Name), Type(Type), IsDefault(IsDefault) {}
1002 : Name(N->getRawName()), Type(N->getRawType()),
1003 IsDefault(N->isDefault()) {}
1004
1006 return Name == RHS->getRawName() && Type == RHS->getRawType() &&
1007 IsDefault == RHS->isDefault();
1008 }
1009
1010 unsigned getHashValue() const { return hash_combine(Name, Type, IsDefault); }
1011};
1012
1014 unsigned Tag;
1019
1020 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *Type, bool IsDefault,
1021 Metadata *Value)
1022 : Tag(Tag), Name(Name), Type(Type), IsDefault(IsDefault), Value(Value) {}
1024 : Tag(N->getTag()), Name(N->getRawName()), Type(N->getRawType()),
1025 IsDefault(N->isDefault()), Value(N->getValue()) {}
1026
1028 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
1029 Type == RHS->getRawType() && IsDefault == RHS->isDefault() &&
1030 Value == RHS->getValue();
1031 }
1032
1033 unsigned getHashValue() const {
1034 return hash_combine(Tag, Name, Type, IsDefault, Value);
1035 }
1036};
1037
1038template <> struct MDNodeKeyImpl<DIGlobalVariable> {
1043 unsigned Line;
1051
1053 Metadata *File, unsigned Line, Metadata *Type,
1054 bool IsLocalToUnit, bool IsDefinition,
1055 Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
1056 uint32_t AlignInBits, Metadata *Annotations)
1057 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
1058 Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit),
1059 IsDefinition(IsDefinition),
1060 StaticDataMemberDeclaration(StaticDataMemberDeclaration),
1061 TemplateParams(TemplateParams), AlignInBits(AlignInBits),
1064 : Scope(N->getRawScope()), Name(N->getRawName()),
1065 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
1066 Line(N->getLine()), Type(N->getRawType()),
1067 IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
1068 StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()),
1069 TemplateParams(N->getRawTemplateParams()),
1070 AlignInBits(N->getAlignInBits()), Annotations(N->getRawAnnotations()) {}
1071
1072 bool isKeyOf(const DIGlobalVariable *RHS) const {
1073 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1074 LinkageName == RHS->getRawLinkageName() &&
1075 File == RHS->getRawFile() && Line == RHS->getLine() &&
1076 Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() &&
1077 IsDefinition == RHS->isDefinition() &&
1078 StaticDataMemberDeclaration ==
1079 RHS->getRawStaticDataMemberDeclaration() &&
1080 TemplateParams == RHS->getRawTemplateParams() &&
1081 AlignInBits == RHS->getAlignInBits() &&
1082 Annotations == RHS->getRawAnnotations();
1083 }
1084
1085 unsigned getHashValue() const {
1086 // We do not use AlignInBits in hashing function here on purpose:
1087 // in most cases this param for local variable is zero (for function param
1088 // it is always zero). This leads to lots of hash collisions and errors on
1089 // cases with lots of similar variables.
1090 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1091 // generated IR is random for each run and test fails with Align included.
1092 // TODO: make hashing work fine with such situations
1093 return hash_combine(Scope, Name, LinkageName, File, Line, Type,
1094 IsLocalToUnit, IsDefinition, /* AlignInBits, */
1095 StaticDataMemberDeclaration, Annotations);
1096 }
1097};
1098
1099template <> struct MDNodeKeyImpl<DILocalVariable> {
1103 unsigned Line;
1105 unsigned Arg;
1106 unsigned Flags;
1109
1110 MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line,
1111 Metadata *Type, unsigned Arg, unsigned Flags,
1112 uint32_t AlignInBits, Metadata *Annotations)
1113 : Scope(Scope), Name(Name), File(File), Line(Line), Type(Type), Arg(Arg),
1114 Flags(Flags), AlignInBits(AlignInBits), Annotations(Annotations) {}
1116 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1117 Line(N->getLine()), Type(N->getRawType()), Arg(N->getArg()),
1118 Flags(N->getFlags()), AlignInBits(N->getAlignInBits()),
1119 Annotations(N->getRawAnnotations()) {}
1120
1121 bool isKeyOf(const DILocalVariable *RHS) const {
1122 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1123 File == RHS->getRawFile() && Line == RHS->getLine() &&
1124 Type == RHS->getRawType() && Arg == RHS->getArg() &&
1125 Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits() &&
1126 Annotations == RHS->getRawAnnotations();
1127 }
1128
1129 unsigned getHashValue() const {
1130 // We do not use AlignInBits in hashing function here on purpose:
1131 // in most cases this param for local variable is zero (for function param
1132 // it is always zero). This leads to lots of hash collisions and errors on
1133 // cases with lots of similar variables.
1134 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1135 // generated IR is random for each run and test fails with Align included.
1136 // TODO: make hashing work fine with such situations
1137 return hash_combine(Scope, Name, File, Line, Type, Arg, Flags, Annotations);
1138 }
1139};
1140
1141template <> struct MDNodeKeyImpl<DILabel> {
1145 unsigned Line;
1146
1147 MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line)
1148 : Scope(Scope), Name(Name), File(File), Line(Line) {}
1150 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1151 Line(N->getLine()) {}
1152
1153 bool isKeyOf(const DILabel *RHS) const {
1154 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1155 File == RHS->getRawFile() && Line == RHS->getLine();
1156 }
1157
1158 /// Using name and line to get hash value. It should already be mostly unique.
1159 unsigned getHashValue() const { return hash_combine(Scope, Name, Line); }
1160};
1161
1162template <> struct MDNodeKeyImpl<DIExpression> {
1164
1165 MDNodeKeyImpl(ArrayRef<uint64_t> Elements) : Elements(Elements) {}
1166 MDNodeKeyImpl(const DIExpression *N) : Elements(N->getElements()) {}
1167
1168 bool isKeyOf(const DIExpression *RHS) const {
1169 return Elements == RHS->getElements();
1170 }
1171
1172 unsigned getHashValue() const {
1173 return hash_combine_range(Elements.begin(), Elements.end());
1174 }
1175};
1176
1180
1182 : Variable(Variable), Expression(Expression) {}
1184 : Variable(N->getRawVariable()), Expression(N->getRawExpression()) {}
1185
1187 return Variable == RHS->getRawVariable() &&
1188 Expression == RHS->getRawExpression();
1189 }
1190
1191 unsigned getHashValue() const { return hash_combine(Variable, Expression); }
1192};
1193
1194template <> struct MDNodeKeyImpl<DIObjCProperty> {
1197 unsigned Line;
1200 unsigned Attributes;
1202
1203 MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line,
1204 MDString *GetterName, MDString *SetterName, unsigned Attributes,
1205 Metadata *Type)
1206 : Name(Name), File(File), Line(Line), GetterName(GetterName),
1207 SetterName(SetterName), Attributes(Attributes), Type(Type) {}
1209 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
1210 GetterName(N->getRawGetterName()), SetterName(N->getRawSetterName()),
1211 Attributes(N->getAttributes()), Type(N->getRawType()) {}
1212
1213 bool isKeyOf(const DIObjCProperty *RHS) const {
1214 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
1215 Line == RHS->getLine() && GetterName == RHS->getRawGetterName() &&
1216 SetterName == RHS->getRawSetterName() &&
1217 Attributes == RHS->getAttributes() && Type == RHS->getRawType();
1218 }
1219
1220 unsigned getHashValue() const {
1221 return hash_combine(Name, File, Line, GetterName, SetterName, Attributes,
1222 Type);
1223 }
1224};
1225
1226template <> struct MDNodeKeyImpl<DIImportedEntity> {
1227 unsigned Tag;
1231 unsigned Line;
1234
1235 MDNodeKeyImpl(unsigned Tag, Metadata *Scope, Metadata *Entity, Metadata *File,
1236 unsigned Line, MDString *Name, Metadata *Elements)
1237 : Tag(Tag), Scope(Scope), Entity(Entity), File(File), Line(Line),
1238 Name(Name), Elements(Elements) {}
1240 : Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()),
1241 File(N->getRawFile()), Line(N->getLine()), Name(N->getRawName()),
1242 Elements(N->getRawElements()) {}
1243
1244 bool isKeyOf(const DIImportedEntity *RHS) const {
1245 return Tag == RHS->getTag() && Scope == RHS->getRawScope() &&
1246 Entity == RHS->getRawEntity() && File == RHS->getFile() &&
1247 Line == RHS->getLine() && Name == RHS->getRawName() &&
1248 Elements == RHS->getRawElements();
1249 }
1250
1251 unsigned getHashValue() const {
1252 return hash_combine(Tag, Scope, Entity, File, Line, Name, Elements);
1253 }
1254};
1255
1256template <> struct MDNodeKeyImpl<DIMacro> {
1257 unsigned MIType;
1258 unsigned Line;
1261
1262 MDNodeKeyImpl(unsigned MIType, unsigned Line, MDString *Name, MDString *Value)
1263 : MIType(MIType), Line(Line), Name(Name), Value(Value) {}
1265 : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getRawName()),
1266 Value(N->getRawValue()) {}
1267
1268 bool isKeyOf(const DIMacro *RHS) const {
1269 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1270 Name == RHS->getRawName() && Value == RHS->getRawValue();
1271 }
1272
1273 unsigned getHashValue() const {
1274 return hash_combine(MIType, Line, Name, Value);
1275 }
1276};
1277
1278template <> struct MDNodeKeyImpl<DIMacroFile> {
1279 unsigned MIType;
1280 unsigned Line;
1283
1284 MDNodeKeyImpl(unsigned MIType, unsigned Line, Metadata *File,
1285 Metadata *Elements)
1286 : MIType(MIType), Line(Line), File(File), Elements(Elements) {}
1288 : MIType(N->getMacinfoType()), Line(N->getLine()), File(N->getRawFile()),
1289 Elements(N->getRawElements()) {}
1290
1291 bool isKeyOf(const DIMacroFile *RHS) const {
1292 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1293 File == RHS->getRawFile() && Elements == RHS->getRawElements();
1294 }
1295
1296 unsigned getHashValue() const {
1297 return hash_combine(MIType, Line, File, Elements);
1298 }
1299};
1300
1301template <> struct MDNodeKeyImpl<DIArgList> {
1303
1305 MDNodeKeyImpl(const DIArgList *N) : Args(N->getArgs()) {}
1306
1307 bool isKeyOf(const DIArgList *RHS) const { return Args == RHS->getArgs(); }
1308
1309 unsigned getHashValue() const {
1310 return hash_combine_range(Args.begin(), Args.end());
1311 }
1312};
1313
1314/// DenseMapInfo for MDNode subclasses.
1315template <class NodeTy> struct MDNodeInfo {
1318
1319 static inline NodeTy *getEmptyKey() {
1321 }
1322
1323 static inline NodeTy *getTombstoneKey() {
1325 }
1326
1327 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1328
1329 static unsigned getHashValue(const NodeTy *N) {
1330 return KeyTy(N).getHashValue();
1331 }
1332
1333 static bool isEqual(const KeyTy &LHS, const NodeTy *RHS) {
1334 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1335 return false;
1336 return SubsetEqualTy::isSubsetEqual(LHS, RHS) || LHS.isKeyOf(RHS);
1337 }
1338
1339 static bool isEqual(const NodeTy *LHS, const NodeTy *RHS) {
1340 if (LHS == RHS)
1341 return true;
1342 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1343 return false;
1345 }
1346};
1347
1348#define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>;
1349#include "llvm/IR/Metadata.def"
1350
1351/// Multimap-like storage for metadata attachments.
1353public:
1354 struct Attachment {
1355 unsigned MDKind;
1357 };
1358
1359private:
1360 SmallVector<Attachment, 1> Attachments;
1361
1362public:
1363 bool empty() const { return Attachments.empty(); }
1364 size_t size() const { return Attachments.size(); }
1365
1366 /// Returns the first attachment with the given ID or nullptr if no such
1367 /// attachment exists.
1368 MDNode *lookup(unsigned ID) const;
1369
1370 /// Appends all attachments with the given ID to \c Result in insertion order.
1371 /// If the global has no attachments with the given ID, or if ID is invalid,
1372 /// leaves Result unchanged.
1373 void get(unsigned ID, SmallVectorImpl<MDNode *> &Result) const;
1374
1375 /// Appends all attachments for the global to \c Result, sorting by attachment
1376 /// ID. Attachments with the same ID appear in insertion order. This function
1377 /// does \em not clear \c Result.
1378 void getAll(SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const;
1379
1380 /// Set an attachment to a particular node.
1381 ///
1382 /// Set the \c ID attachment to \c MD, replacing the current attachments at \c
1383 /// ID (if anyway).
1384 void set(unsigned ID, MDNode *MD);
1385
1386 /// Adds an attachment to a particular node.
1387 void insert(unsigned ID, MDNode &MD);
1388
1389 /// Remove attachments with the given ID.
1390 ///
1391 /// Remove the attachments at \c ID, if any.
1392 bool erase(unsigned ID);
1393
1394 /// Erase matching attachments.
1395 ///
1396 /// Erases all attachments matching the \c shouldRemove predicate.
1397 template <class PredTy> void remove_if(PredTy shouldRemove) {
1398 llvm::erase_if(Attachments, shouldRemove);
1399 }
1400};
1401
1403public:
1404 /// OwnedModules - The set of modules instantiated in this context, and which
1405 /// will be automatically deleted if this context is deleted.
1407
1408 /// The main remark streamer used by all the other streamers (e.g. IR, MIR,
1409 /// frontends, etc.). This should only be used by the specific streamers, and
1410 /// never directly.
1411 std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer;
1412
1413 std::unique_ptr<DiagnosticHandler> DiagHandler;
1416 /// The minimum hotness value a diagnostic needs in order to be included in
1417 /// optimization diagnostics.
1418 ///
1419 /// The threshold is an Optional value, which maps to one of the 3 states:
1420 /// 1). 0 => threshold disabled. All emarks will be printed.
1421 /// 2). positive int => manual threshold by user. Remarks with hotness exceed
1422 /// threshold will be printed.
1423 /// 3). None => 'auto' threshold by user. The actual value is not
1424 /// available at command line, but will be synced with
1425 /// hotness threhold from profile summary during
1426 /// compilation.
1427 ///
1428 /// State 1 and 2 are considered as terminal states. State transition is
1429 /// only allowed from 3 to 2, when the threshold is first synced with profile
1430 /// summary. This ensures that the threshold is set only once and stays
1431 /// constant.
1432 ///
1433 /// If threshold option is not specified, it is disabled (0) by default.
1434 std::optional<uint64_t> DiagnosticsHotnessThreshold = 0;
1435
1436 /// The percentage of difference between profiling branch weights and
1437 /// llvm.expect branch weights to tolerate when emiting MisExpect diagnostics
1438 std::optional<uint32_t> DiagnosticsMisExpectTolerance = 0;
1440
1441 /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
1442 std::unique_ptr<LLVMRemarkStreamer> LLVMRS;
1443
1445 void *YieldOpaqueHandle = nullptr;
1446
1448
1449 using IntMapTy =
1452
1453 using FPMapTy =
1456
1460
1464
1465#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
1466 DenseSet<CLASS *, CLASS##Info> CLASS##s;
1467#include "llvm/IR/Metadata.def"
1468
1469 // Optional map for looking up composite types by identifier.
1470 std::optional<DenseMap<const MDString *, DICompositeType *>> DITypeMap;
1471
1472 // MDNodes may be uniqued or not uniqued. When they're not uniqued, they
1473 // aren't in the MDNodeSet, but they're still shared between objects, so no
1474 // one object can destroy them. Keep track of them here so we can delete
1475 // them on context teardown.
1476 std::vector<MDNode *> DistinctMDNodes;
1477
1479
1482
1485
1488
1490
1492
1494
1496
1498
1501
1503
1505
1507
1509
1512
1513 // Basic type instances.
1518
1519 std::unique_ptr<ConstantTokenNone> TheNoneToken;
1520
1523
1525
1532
1535
1538 DenseMap<Type *, PointerType *> PointerTypes; // Pointers in AddrSpace = 0
1541
1542 /// ValueHandles - This map keeps track of all of the value handles that are
1543 /// watching a Value*. The Value::HasValueHandle bit is used to know
1544 /// whether or not a value has an entry in this map.
1547
1548 /// CustomMDKindNames - Map to hold the metadata string to ID mapping.
1550
1551 /// Collection of metadata used in this context.
1553
1554 /// Map DIAssignID -> Instructions with that attachment.
1555 /// Managed by Instruction via Instruction::updateDIAssignIDMapping.
1556 /// Query using the at:: functions defined in DebugInfo.h.
1558
1559 /// Collection of per-GlobalObject sections used in this context.
1561
1562 /// Collection of per-GlobalValue partitions used in this context.
1564
1567
1568 /// DiscriminatorTable - This table maps file:line locations to an
1569 /// integer representing the next DWARF path discriminator to assign to
1570 /// instructions in different blocks at the same location.
1572
1573 /// A set of interned tags for operand bundles. The StringMap maps
1574 /// bundle tags to their IDs.
1575 ///
1576 /// \see LLVMContext::getOperandBundleTagID
1578
1582
1583 /// A set of interned synchronization scopes. The StringMap maps
1584 /// synchronization scope names to their respective synchronization scope IDs.
1586
1587 /// getOrInsertSyncScopeID - Maps synchronization scope name to
1588 /// synchronization scope ID. Every synchronization scope registered with
1589 /// LLVMContext has unique ID except pre-defined ones.
1591
1592 /// getSyncScopeNames - Populates client supplied SmallVector with
1593 /// synchronization scope names registered with LLVMContext. Synchronization
1594 /// scope names are ordered by increasing synchronization scope IDs.
1596
1597 /// Maintain the GC name for each function.
1598 ///
1599 /// This saves allocating an additional word in Function for programs which
1600 /// do not use GC (i.e., most programs) at the cost of increased overhead for
1601 /// clients which do use GC.
1603
1604 /// Flag to indicate if Value (other than GlobalValue) retains their name or
1605 /// not.
1606 bool DiscardValueNames = false;
1607
1610
1611 /// Destroy the ConstantArrays if they are not used.
1613
1614 mutable OptPassGate *OPG = nullptr;
1615
1616 /// Access the object which can disable optional passes and individual
1617 /// optimizations at compile time.
1618 OptPassGate &getOptPassGate() const;
1619
1620 /// Set the object which can disable optional passes and individual
1621 /// optimizations at compile time.
1622 ///
1623 /// The lifetime of the object must be guaranteed to extend as long as the
1624 /// LLVMContext is used by compilation.
1626
1627 // TODO: clean up the following after we no longer support non-opaque pointer
1628 // types.
1629 bool getOpaquePointers();
1630 void setOpaquePointers(bool OP);
1631
1632private:
1633 std::optional<bool> OpaquePointers;
1634};
1635
1636} // end namespace llvm
1637
1638#endif // LLVM_LIB_IR_LLVMCONTEXTIMPL_H
This file defines the StringMap class.
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
AMDGPU Kernel Attributes
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines DenseMapInfo traits for DenseMap.
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
This file contains constants used for implementing Dwarf debug support.
std::string Name
This file defines a hash set that can be used to remove duplication of nodes in a graph.
This file contains the declarations for metadata subclasses.
Module.h This file contains the declarations for the Module class.
#define P(N)
static StringRef getName(Value *V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static uint32_t getFlags(const Symbol *Sym)
Definition: TapiFile.cpp:27
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition: APInt.h:75
Annotations lets you mark points and ranges inside source code, for tests:
Definition: Annotations.h:53
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
iterator end() const
Definition: ArrayRef.h:152
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:163
iterator begin() const
Definition: ArrayRef.h:151
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:158
Class to represent array types.
Definition: DerivedTypes.h:357
The address of a basic block.
Definition: Constants.h:875
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:66
Constant * getValue() const
Definition: Metadata.h:427
This is the shared class of boolean and integer constants.
Definition: Constants.h:78
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
Definition: Constants.h:147
List of ValueAsMetadata, to be used as an argument to a dbg.value intrinsic.
Basic type, like 'int' or 'float'.
Enumeration value.
DWARF expression.
A pair of DIGlobalVariable and DIExpression.
An imported module (C++ using directive or similar).
Debug location.
Represents a module in the programming language, for example, a Clang module, or a Fortran module.
String type, Fortran CHARACTER(n)
Subprogram description.
Array subrange.
Type array for a subprogram.
Class representing an expression and its matching format.
FoldingSet - This template class is used to instantiate a specialized implementation of the folding s...
Definition: FoldingSet.h:520
Class to represent function types.
Definition: DerivedTypes.h:103
Generic tagged DWARF-like metadata node.
Class to represent integer types.
Definition: DerivedTypes.h:40
DenseMap< const GlobalValue *, StringRef > GlobalValuePartitions
Collection of per-GlobalValue partitions used in this context.
DenseMap< const GlobalValue *, GlobalValue::SanitizerMetadata > GlobalValueSanitizerMetadata
void getSyncScopeNames(SmallVectorImpl< StringRef > &SSNs) const
getSyncScopeNames - Populates client supplied SmallVector with synchronization scope names registered...
DenseMap< Metadata *, MetadataAsValue * > MetadataAsValues
DenseMap< std::pair< Type *, unsigned >, PointerType * > ASPointerTypes
SmallPtrSet< Module *, 4 > OwnedModules
OwnedModules - The set of modules instantiated in this context, and which will be automatically delet...
DenseMap< PointerType *, std::unique_ptr< ConstantPointerNull > > CPNConstants
DenseMap< Type *, std::unique_ptr< ConstantAggregateZero > > CAZConstants
StringMap< MDString, BumpPtrAllocator > MDStringCache
TargetExtTypeSet TargetExtTypes
DenseMap< DIAssignID *, SmallVector< Instruction *, 1 > > AssignmentIDToInstrs
Map DIAssignID -> Instructions with that attachment.
DenseMap< Type *, std::unique_ptr< PoisonValue > > PVConstants
DenseMap< std::pair< const Function *, const BasicBlock * >, BlockAddress * > BlockAddresses
std::vector< MDNode * > DistinctMDNodes
std::optional< uint32_t > DiagnosticsMisExpectTolerance
The percentage of difference between profiling branch weights and llvm.expect branch weights to toler...
FoldingSet< AttributeImpl > AttrsSet
StructTypeSet AnonStructTypes
std::unique_ptr< ConstantTokenNone > TheNoneToken
DenseMap< const Value *, ValueName * > ValueNames
DenseMap< Type *, PointerType * > PointerTypes
SyncScope::ID getOrInsertSyncScopeID(StringRef SSN)
getOrInsertSyncScopeID - Maps synchronization scope name to synchronization scope ID.
void dropTriviallyDeadConstantArrays()
Destroy the ConstantArrays if they are not used.
void setOptPassGate(OptPassGate &)
Set the object which can disable optional passes and individual optimizations at compile time.
VectorConstantsTy VectorConstants
std::unique_ptr< LLVMRemarkStreamer > LLVMRS
The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
bool DiscardValueNames
Flag to indicate if Value (other than GlobalValue) retains their name or not.
DenseMap< const GlobalValue *, NoCFIValue * > NoCFIValues
DenseMap< const Function *, std::string > GCNames
Maintain the GC name for each function.
DenseMap< Type *, std::unique_ptr< UndefValue > > UVConstants
OptPassGate & getOptPassGate() const
Access the object which can disable optional passes and individual optimizations at compile time.
DenseMap< std::pair< Type *, unsigned >, TypedPointerType * > ASTypedPointerTypes
DenseMap< std::pair< Type *, uint64_t >, ArrayType * > ArrayTypes
DenseMap< const Value *, MDAttachments > ValueMetadata
Collection of metadata used in this context.
StringMap< unsigned > CustomMDKindNames
CustomMDKindNames - Map to hold the metadata string to ID mapping.
StringMapEntry< uint32_t > * getOrInsertBundleTag(StringRef Tag)
std::unique_ptr< DiagnosticHandler > DiagHandler
StringMap< uint32_t > BundleTagCache
A set of interned tags for operand bundles.
BumpPtrAllocator Alloc
DenseMap< const GlobalObject *, StringRef > GlobalObjectSections
Collection of per-GlobalObject sections used in this context.
StringMap< std::unique_ptr< ConstantDataSequential > > CDSConstants
StructConstantsTy StructConstants
DenseMap< std::pair< Type *, ElementCount >, VectorType * > VectorTypes
std::unique_ptr< remarks::RemarkStreamer > MainRemarkStreamer
The main remark streamer used by all the other streamers (e.g.
void getOperandBundleTags(SmallVectorImpl< StringRef > &Tags) const
FoldingSet< AttributeSetNode > AttrsSetNodes
FoldingSet< AttributeListImpl > AttrsLists
void setOpaquePointers(bool OP)
DenseMap< TargetExtType *, std::unique_ptr< ConstantTargetNone > > CTNConstants
std::optional< uint64_t > DiagnosticsHotnessThreshold
The minimum hotness value a diagnostic needs in order to be included in optimization diagnostics.
ConstantUniqueMap< ConstantExpr > ExprConstants
uint32_t getOperandBundleTagID(StringRef Tag) const
StringMap< SyncScope::ID > SSC
A set of interned synchronization scopes.
UniqueStringSaver Saver
LLVMContext::YieldCallbackTy YieldCallback
DenseMap< unsigned, IntegerType * > IntegerTypes
StringMap< StructType * > NamedStructTypes
ValueHandlesTy ValueHandles
ArrayConstantsTy ArrayConstants
DenseMap< Value *, ValueAsMetadata * > ValuesAsMetadata
ConstantUniqueMap< InlineAsm > InlineAsms
DenseMap< std::pair< const char *, unsigned >, unsigned > DiscriminatorTable
DiscriminatorTable - This table maps file:line locations to an integer representing the next DWARF pa...
DenseMap< const GlobalValue *, DSOLocalEquivalent * > DSOLocalEquivalents
FunctionTypeSet FunctionTypes
std::optional< DenseMap< const MDString *, DICompositeType * > > DITypeMap
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
void(*)(LLVMContext *Context, void *OpaqueHandle) YieldCallbackTy
Defines the type of a yield callback.
Definition: LLVMContext.h:159
Multimap-like storage for metadata attachments.
void insert(unsigned ID, MDNode &MD)
Adds an attachment to a particular node.
Definition: Metadata.cpp:1268
void remove_if(PredTy shouldRemove)
Erase matching attachments.
void get(unsigned ID, SmallVectorImpl< MDNode * > &Result) const
Appends all attachments with the given ID to Result in insertion order.
Definition: Metadata.cpp:1245
void getAll(SmallVectorImpl< std::pair< unsigned, MDNode * > > &Result) const
Appends all attachments for the global to Result, sorting by attachment ID.
Definition: Metadata.cpp:1251
void set(unsigned ID, MDNode *MD)
Set an attachment to a particular node.
Definition: Metadata.cpp:1262
MDNode * lookup(unsigned ID) const
Returns the first attachment with the given ID or nullptr if no such attachment exists.
Definition: Metadata.cpp:1238
bool erase(unsigned ID)
Remove attachments with the given ID.
Definition: Metadata.cpp:1272
Structure for hashing arbitrary MDNode operands.
MDNodeOpsKey(const NodeTy *N, unsigned Offset=0)
bool compareOps(const NodeTy *RHS, unsigned Offset=0) const
unsigned getHash() const
MDNodeOpsKey(ArrayRef< Metadata * > Ops)
static unsigned calculateHash(MDNode *N, unsigned Offset=0)
Metadata node.
Definition: Metadata.h:943
A single uniqued string.
Definition: Metadata.h:611
Tuple of metadata.
Definition: Metadata.h:1328
Root of the metadata hierarchy.
Definition: Metadata.h:61
Extensions to this class implement mechanisms to disable passes and individual optimizations at compi...
Definition: OptBisect.h:26
Class to represent pointers.
Definition: DerivedTypes.h:632
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:450
bool empty() const
Definition: SmallVector.h:94
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:111
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Class to represent struct types.
Definition: DerivedTypes.h:213
Class to represent target extensions types, which are generally unintrospectable from target-independ...
Definition: DerivedTypes.h:739
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
A few GPU targets, such as DXIL and SPIR-V, have typed pointers.
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
Definition: StringSaver.h:44
LLVM Value Representation.
Definition: Value.h:74
Base class of all SIMD vector types.
Definition: DerivedTypes.h:389
unsigned getTag(StringRef TagString)
Definition: Dwarf.cpp:32
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ BasicBlock
Various leaf nodes.
Definition: ISDOpcodes.h:71
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:406
hash_code hash_value(const FixedPointSemantics &Val)
Definition: APFixedPoint.h:128
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition: STLExtras.h:1998
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition: Hashing.h:608
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
Definition: Hashing.h:486
#define N
#define OP(n)
Definition: regex2.h:73
static const fltSemantics & Bogus() LLVM_READNONE
A Pseudo fltsemantic used to construct APFloats that cannot conflict with anything real.
Definition: APFloat.cpp:216
KeyTy(const ArrayRef< Type * > &E, bool P)
bool operator==(const KeyTy &that) const
bool operator!=(const KeyTy &that) const
static StructType * getEmptyKey()
static bool isEqual(const StructType *LHS, const StructType *RHS)
static unsigned getHashValue(const StructType *ST)
static unsigned getHashValue(const KeyTy &Key)
static StructType * getTombstoneKey()
static bool isEqual(const KeyTy &LHS, const StructType *RHS)
A single checksum, represented by a Kind and a Value (a string).
static unsigned getHashValue(const APFloat &Key)
static APFloat getTombstoneKey()
static bool isEqual(const APFloat &LHS, const APFloat &RHS)
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:51
bool operator==(const KeyTy &that) const
bool operator!=(const KeyTy &that) const
KeyTy(const Type *R, const ArrayRef< Type * > &P, bool V)
KeyTy(const FunctionType *FT)
static unsigned getHashValue(const FunctionType *FT)
static FunctionType * getTombstoneKey()
static bool isEqual(const KeyTy &LHS, const FunctionType *RHS)
static unsigned getHashValue(const KeyTy &Key)
static bool isEqual(const FunctionType *LHS, const FunctionType *RHS)
static FunctionType * getEmptyKey()
DenseMapInfo for MDNode subclasses.
static unsigned getHashValue(const KeyTy &Key)
static bool isEqual(const NodeTy *LHS, const NodeTy *RHS)
static bool isEqual(const KeyTy &LHS, const NodeTy *RHS)
static unsigned getHashValue(const NodeTy *N)
MDNodeKeyImpl< NodeTy > KeyTy
static NodeTy * getTombstoneKey()
static NodeTy * getEmptyKey()
ArrayRef< ValueAsMetadata * > Args
MDNodeKeyImpl(ArrayRef< ValueAsMetadata * > Args)
bool isKeyOf(const DIArgList *RHS) const
bool isKeyOf(const DIBasicType *RHS) const
MDNodeKeyImpl(const DIBasicType *N)
MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, unsigned Flags)
bool isKeyOf(const DICommonBlock *RHS) const
MDNodeKeyImpl(const DICommonBlock *N)
MDNodeKeyImpl(Metadata *Scope, Metadata *Decl, MDString *Name, Metadata *File, unsigned LineNo)
MDNodeKeyImpl(const DICompositeType *N)
bool isKeyOf(const DICompositeType *RHS) const
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, Metadata *Rank, Metadata *Annotations)
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, std::optional< unsigned > DWARFAddressSpace, unsigned Flags, Metadata *ExtraData, Metadata *Annotations)
MDNodeKeyImpl(const DIDerivedType *N)
bool isKeyOf(const DIDerivedType *RHS) const
std::optional< unsigned > DWARFAddressSpace
MDNodeKeyImpl(APInt Value, bool IsUnsigned, MDString *Name)
MDNodeKeyImpl(int64_t Value, bool IsUnsigned, MDString *Name)
bool isKeyOf(const DIEnumerator *RHS) const
MDNodeKeyImpl(const DIEnumerator *N)
bool isKeyOf(const DIExpression *RHS) const
MDNodeKeyImpl(const DIExpression *N)
MDNodeKeyImpl(ArrayRef< uint64_t > Elements)
std::optional< DIFile::ChecksumInfo< MDString * > > Checksum
bool isKeyOf(const DIFile *RHS) const
MDNodeKeyImpl(MDString *Filename, MDString *Directory, std::optional< DIFile::ChecksumInfo< MDString * > > Checksum, MDString *Source)
bool isKeyOf(const DIGenericSubrange *RHS) const
MDNodeKeyImpl(const DIGenericSubrange *N)
MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound, Metadata *Stride)
MDNodeKeyImpl(Metadata *Variable, Metadata *Expression)
bool isKeyOf(const DIGlobalVariableExpression *RHS) const
MDNodeKeyImpl(const DIGlobalVariableExpression *N)
bool isKeyOf(const DIGlobalVariable *RHS) const
MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, uint32_t AlignInBits, Metadata *Annotations)
MDNodeKeyImpl(const DIGlobalVariable *N)
bool isKeyOf(const DIImportedEntity *RHS) const
MDNodeKeyImpl(unsigned Tag, Metadata *Scope, Metadata *Entity, Metadata *File, unsigned Line, MDString *Name, Metadata *Elements)
MDNodeKeyImpl(const DIImportedEntity *N)
unsigned getHashValue() const
Using name and line to get hash value. It should already be mostly unique.
bool isKeyOf(const DILabel *RHS) const
MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line)
MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator)
MDNodeKeyImpl(const DILexicalBlockFile *N)
bool isKeyOf(const DILexicalBlockFile *RHS) const
bool isKeyOf(const DILexicalBlock *RHS) const
MDNodeKeyImpl(const DILexicalBlock *N)
MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Line, unsigned Column)
bool isKeyOf(const DILocalVariable *RHS) const
MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line, Metadata *Type, unsigned Arg, unsigned Flags, uint32_t AlignInBits, Metadata *Annotations)
MDNodeKeyImpl(const DILocalVariable *N)
MDNodeKeyImpl(unsigned Line, unsigned Column, Metadata *Scope, Metadata *InlinedAt, bool ImplicitCode)
MDNodeKeyImpl(const DILocation *L)
bool isKeyOf(const DILocation *RHS) const
MDNodeKeyImpl(unsigned MIType, unsigned Line, Metadata *File, Metadata *Elements)
bool isKeyOf(const DIMacroFile *RHS) const
MDNodeKeyImpl(unsigned MIType, unsigned Line, MDString *Name, MDString *Value)
bool isKeyOf(const DIMacro *RHS) const
MDNodeKeyImpl(Metadata *File, Metadata *Scope, MDString *Name, MDString *ConfigurationMacros, MDString *IncludePath, MDString *APINotesFile, unsigned LineNo, bool IsDecl)
bool isKeyOf(const DIModule *RHS) const
MDNodeKeyImpl(const DINamespace *N)
MDNodeKeyImpl(Metadata *Scope, MDString *Name, bool ExportSymbols)
bool isKeyOf(const DINamespace *RHS) const
MDNodeKeyImpl(const DIObjCProperty *N)
bool isKeyOf(const DIObjCProperty *RHS) const
MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line, MDString *GetterName, MDString *SetterName, unsigned Attributes, Metadata *Type)
MDNodeKeyImpl(const DIStringType *N)
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *StringLength, Metadata *StringLengthExp, Metadata *StringLocationExp, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding)
bool isKeyOf(const DIStringType *RHS) const
MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex, int ThisAdjustment, unsigned Flags, unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes, Metadata *ThrownTypes, Metadata *Annotations, MDString *TargetFuncName)
bool isKeyOf(const DISubprogram *RHS) const
MDNodeKeyImpl(const DISubprogram *N)
MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound, Metadata *Stride)
bool isKeyOf(const DISubrange *RHS) const
MDNodeKeyImpl(const DISubrange *N)
bool isKeyOf(const DISubroutineType *RHS) const
MDNodeKeyImpl(unsigned Flags, uint8_t CC, Metadata *TypeArray)
MDNodeKeyImpl(const DISubroutineType *N)
MDNodeKeyImpl(const DITemplateTypeParameter *N)
bool isKeyOf(const DITemplateTypeParameter *RHS) const
MDNodeKeyImpl(MDString *Name, Metadata *Type, bool IsDefault)
MDNodeKeyImpl(const DITemplateValueParameter *N)
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *Type, bool IsDefault, Metadata *Value)
bool isKeyOf(const DITemplateValueParameter *RHS) const
static unsigned calculateHash(GenericDINode *N)
MDNodeKeyImpl(const GenericDINode *N)
MDNodeKeyImpl(unsigned Tag, MDString *Header, ArrayRef< Metadata * > DwarfOps)
bool isKeyOf(const GenericDINode *RHS) const
bool isKeyOf(const MDTuple *RHS) const
MDNodeKeyImpl(ArrayRef< Metadata * > Ops)
static unsigned calculateHash(MDTuple *N)
static bool isSubsetEqual(const DIDerivedType *LHS, const DIDerivedType *RHS)
static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS)
static bool isODRMember(unsigned Tag, const Metadata *Scope, const MDString *Name, const DIDerivedType *RHS)
Subprograms compare equal if they declare the same function in an ODR type.
static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS)
static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS)
static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope, const MDString *LinkageName, const Metadata *TemplateParams, const DISubprogram *RHS)
Subprograms compare equal if they declare the same function in an ODR type.
Configuration point for MDNodeInfo::isEqual().
static bool isSubsetEqual(const KeyTy &LHS, const NodeTy *RHS)
static bool isSubsetEqual(const NodeTy *LHS, const NodeTy *RHS)
KeyTy(StringRef N, const ArrayRef< Type * > &TP, const ArrayRef< unsigned > &IP)
bool operator==(const KeyTy &that) const
KeyTy(const TargetExtType *TT)
bool operator!=(const KeyTy &that) const
static unsigned getHashValue(const TargetExtType *FT)
static bool isEqual(const TargetExtType *LHS, const TargetExtType *RHS)
static bool isEqual(const KeyTy &LHS, const TargetExtType *RHS)
static unsigned getHashValue(const KeyTy &Key)
static TargetExtType * getTombstoneKey()
static TargetExtType * getEmptyKey()