LLVM 23.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;
58class BasicBlock;
62class DbgMarker;
63class ElementCount;
64class Function;
65class GlobalObject;
66class GlobalValue;
67class InlineAsm;
69class OptPassGate;
70namespace remarks {
71class RemarkStreamer;
72}
73template <typename T> class StringMapEntry;
74class StringRef;
76class ValueHandleBase;
77
78template <> struct DenseMapInfo<APFloat> {
79 static inline APFloat getEmptyKey() { return APFloat(APFloat::Bogus(), 1); }
80 static inline APFloat getTombstoneKey() {
81 return APFloat(APFloat::Bogus(), 2);
82 }
83
84 static unsigned getHashValue(const APFloat &Key) {
85 return static_cast<unsigned>(hash_value(Key));
86 }
87
88 static bool isEqual(const APFloat &LHS, const APFloat &RHS) {
89 return LHS.bitwiseIsEqual(RHS);
90 }
91};
92
94 struct KeyTy {
97
98 KeyTy(const ArrayRef<Type *> &E, bool P) : ETypes(E), isPacked(P) {}
99
100 KeyTy(const StructType *ST)
101 : ETypes(ST->elements()), isPacked(ST->isPacked()) {}
102
103 bool operator==(const KeyTy &that) const {
104 if (isPacked != that.isPacked)
105 return false;
106 if (ETypes != that.ETypes)
107 return false;
108 return true;
109 }
110 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
111 };
112
113 static inline StructType *getEmptyKey() {
115 }
116
120
121 static unsigned getHashValue(const KeyTy &Key) {
122 return hash_combine(hash_combine_range(Key.ETypes), 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
167
171
172 static unsigned getHashValue(const KeyTy &Key) {
173 return hash_combine(Key.ReturnType, hash_combine_range(Key.Params),
174 Key.isVarArg);
175 }
176
177 static unsigned getHashValue(const FunctionType *FT) {
178 return getHashValue(KeyTy(FT));
179 }
180
181 static bool isEqual(const KeyTy &LHS, const FunctionType *RHS) {
182 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
183 return false;
184 return LHS == KeyTy(RHS);
185 }
186
187 static bool isEqual(const FunctionType *LHS, const FunctionType *RHS) {
188 return LHS == RHS;
189 }
190};
191
193 struct KeyTy {
197
199 : Name(N), TypeParams(TP), IntParams(IP) {}
201 : Name(TT->getName()), TypeParams(TT->type_params()),
202 IntParams(TT->int_params()) {}
203
204 bool operator==(const KeyTy &that) const {
205 return Name == that.Name && TypeParams == that.TypeParams &&
206 IntParams == that.IntParams;
207 }
208 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
209 };
210
214
218
219 static unsigned getHashValue(const KeyTy &Key) {
220 return hash_combine(Key.Name, hash_combine_range(Key.TypeParams),
221 hash_combine_range(Key.IntParams));
222 }
223
224 static unsigned getHashValue(const TargetExtType *FT) {
225 return getHashValue(KeyTy(FT));
226 }
227
228 static bool isEqual(const KeyTy &LHS, const TargetExtType *RHS) {
229 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
230 return false;
231 return LHS == KeyTy(RHS);
232 }
233
234 static bool isEqual(const TargetExtType *LHS, const TargetExtType *RHS) {
235 return LHS == RHS;
236 }
237};
238
239/// Structure for hashing arbitrary MDNode operands.
243 unsigned Hash;
244
245protected:
247 : RawOps(Ops), Hash(calculateHash(Ops)) {}
248
249 template <class NodeTy>
250 MDNodeOpsKey(const NodeTy *N, unsigned Offset = 0)
251 : Ops(N->op_begin() + Offset, N->op_end()), Hash(N->getHash()) {}
252
253 template <class NodeTy>
254 bool compareOps(const NodeTy *RHS, unsigned Offset = 0) const {
255 if (getHash() != RHS->getHash())
256 return false;
257
258 assert((RawOps.empty() || Ops.empty()) && "Two sets of operands?");
259 return RawOps.empty() ? compareOps(Ops, RHS, Offset)
260 : compareOps(RawOps, RHS, Offset);
261 }
262
263 static unsigned calculateHash(MDNode *N, unsigned Offset = 0);
264
265private:
266 template <class T>
267 static bool compareOps(ArrayRef<T> Ops, const MDNode *RHS, unsigned Offset) {
268 if (Ops.size() != RHS->getNumOperands() - Offset)
269 return false;
270 return std::equal(Ops.begin(), Ops.end(), RHS->op_begin() + Offset);
271 }
272
273 static unsigned calculateHash(ArrayRef<Metadata *> Ops);
274
275public:
276 unsigned getHash() const { return Hash; }
277};
278
279template <class NodeTy> struct MDNodeKeyImpl;
280
281/// Configuration point for MDNodeInfo::isEqual().
282template <class NodeTy> struct MDNodeSubsetEqualImpl {
284
285 static bool isSubsetEqual(const KeyTy &LHS, const NodeTy *RHS) {
286 return false;
287 }
288
289 static bool isSubsetEqual(const NodeTy *LHS, const NodeTy *RHS) {
290 return false;
291 }
292};
293
294/// DenseMapInfo for MDTuple.
295///
296/// Note that we don't need the is-function-local bit, since that's implicit in
297/// the operands.
298template <> struct MDNodeKeyImpl<MDTuple> : MDNodeOpsKey {
301
302 bool isKeyOf(const MDTuple *RHS) const { return compareOps(RHS); }
303
304 unsigned getHashValue() const { return getHash(); }
305
306 static unsigned calculateHash(MDTuple *N) {
308 }
309};
310
311/// DenseMapInfo for DILocation.
312template <> struct MDNodeKeyImpl<DILocation> {
317 unsigned Line;
320
327
329 : Scope(L->getRawScope()), InlinedAt(L->getRawInlinedAt()),
330 AtomGroup(L->getAtomGroup()), AtomRank(L->getAtomRank()),
331 Line(L->getLine()), Column(L->getColumn()),
332 ImplicitCode(L->isImplicitCode()) {}
333
334 bool isKeyOf(const DILocation *RHS) const {
335 return Line == RHS->getLine() && Column == RHS->getColumn() &&
336 Scope == RHS->getRawScope() && InlinedAt == RHS->getRawInlinedAt() &&
337 ImplicitCode == RHS->isImplicitCode() &&
338 AtomGroup == RHS->getAtomGroup() && AtomRank == RHS->getAtomRank();
339 }
340
341 unsigned getHashValue() const {
342 // Hashing AtomGroup and AtomRank substantially impacts performance whether
343 // Key Instructions is enabled or not. We can't detect whether it's enabled
344 // here cheaply; avoiding hashing zero values is a good approximation. This
345 // affects Key Instruction builds too, but any potential costs incurred by
346 // messing with the hash distribution* appear to still be massively
347 // outweighed by the overall compile time savings by performing this check.
348 // * (hash_combine(x) != hash_combine(x, 0))
349 if (AtomGroup || AtomRank)
353 }
354};
355
356/// DenseMapInfo for GenericDINode.
358 unsigned Tag;
360
362 : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {}
364 : MDNodeOpsKey(N, 1), Tag(N->getTag()), Header(N->getRawHeader()) {}
365
366 bool isKeyOf(const GenericDINode *RHS) const {
367 return Tag == RHS->getTag() && Header == RHS->getRawHeader() &&
368 compareOps(RHS, 1);
369 }
370
371 unsigned getHashValue() const { return hash_combine(getHash(), Tag, Header); }
372
373 static unsigned calculateHash(GenericDINode *N) {
375 }
376};
377
378template <> struct MDNodeKeyImpl<DISubrange> {
383
389 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
390 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
391
392 bool isKeyOf(const DISubrange *RHS) const {
393 auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool {
394 if (Node1 == Node2)
395 return true;
396
399 if (MD1 && MD2) {
402 if (CV1->getSExtValue() == CV2->getSExtValue())
403 return true;
404 }
405 return false;
406 };
407
408 return BoundsEqual(CountNode, RHS->getRawCountNode()) &&
409 BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
410 BoundsEqual(UpperBound, RHS->getRawUpperBound()) &&
411 BoundsEqual(Stride, RHS->getRawStride());
412 }
413
414 unsigned getHashValue() const {
415 if (CountNode)
417 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
420 }
421};
422
423template <> struct MDNodeKeyImpl<DIGenericSubrange> {
428
434 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
435 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
436
437 bool isKeyOf(const DIGenericSubrange *RHS) const {
438 return (CountNode == RHS->getRawCountNode()) &&
439 (LowerBound == RHS->getRawLowerBound()) &&
440 (UpperBound == RHS->getRawUpperBound()) &&
441 (Stride == RHS->getRawStride());
442 }
443
444 unsigned getHashValue() const {
446 if (CountNode && MD)
447 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
450 }
451};
452
453template <> struct MDNodeKeyImpl<DIEnumerator> {
457
464 : Value(N->getValue()), Name(N->getRawName()),
465 IsUnsigned(N->isUnsigned()) {}
466
467 bool isKeyOf(const DIEnumerator *RHS) const {
468 return Value.getBitWidth() == RHS->getValue().getBitWidth() &&
469 Value == RHS->getValue() && IsUnsigned == RHS->isUnsigned() &&
470 Name == RHS->getRawName();
471 }
472
473 unsigned getHashValue() const { return hash_combine(Value, Name); }
474};
475
476template <> struct MDNodeKeyImpl<DIBasicType> {
477 unsigned Tag;
480 unsigned LineNo;
484 unsigned Encoding;
487 unsigned Flags;
488
498 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
499 LineNo(N->getLine()), Scope(N->getRawScope()),
500 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
501 Encoding(N->getEncoding()),
502 NumExtraInhabitants(N->getNumExtraInhabitants()),
503 DataSizeInBits(N->getDataSizeInBits()), Flags(N->getFlags()) {}
504
505 bool isKeyOf(const DIBasicType *RHS) const {
506 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
507 File == RHS->getRawFile() && LineNo == RHS->getLine() &&
508 Scope == RHS->getRawScope() &&
509 SizeInBits == RHS->getRawSizeInBits() &&
510 AlignInBits == RHS->getAlignInBits() &&
511 Encoding == RHS->getEncoding() &&
512 NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
513 DataSizeInBits == RHS->getDataSizeInBits() &&
514 Flags == RHS->getFlags();
515 }
516
517 unsigned getHashValue() const {
519 Encoding);
520 }
521};
522
523template <> struct MDNodeKeyImpl<DIFixedPointType> {
524 unsigned Tag;
527 unsigned LineNo;
531 unsigned Encoding;
532 unsigned Flags;
533 unsigned Kind;
537
547 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
548 LineNo(N->getLine()), Scope(N->getRawScope()),
549 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
550 Encoding(N->getEncoding()), Flags(N->getFlags()), Kind(N->getKind()),
551 Factor(N->getFactorRaw()), Numerator(N->getNumeratorRaw()),
552 Denominator(N->getDenominatorRaw()) {}
553
554 bool isKeyOf(const DIFixedPointType *RHS) const {
555 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
556 LineNo == RHS->getLine() && Scope == RHS->getRawScope() &&
557 SizeInBits == RHS->getRawSizeInBits() &&
558 AlignInBits == RHS->getAlignInBits() && Kind == RHS->getKind() &&
559 (RHS->isRational() ? (Numerator == RHS->getNumerator() &&
560 Denominator == RHS->getDenominator())
561 : Factor == RHS->getFactor());
562 }
563
564 unsigned getHashValue() const {
567 }
568};
569
570template <> struct MDNodeKeyImpl<DIStringType> {
571 unsigned Tag;
578 unsigned Encoding;
579
587 : Tag(N->getTag()), Name(N->getRawName()),
588 StringLength(N->getRawStringLength()),
589 StringLengthExp(N->getRawStringLengthExp()),
590 StringLocationExp(N->getRawStringLocationExp()),
591 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
592 Encoding(N->getEncoding()) {}
593
594 bool isKeyOf(const DIStringType *RHS) const {
595 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
596 StringLength == RHS->getRawStringLength() &&
597 StringLengthExp == RHS->getRawStringLengthExp() &&
598 StringLocationExp == RHS->getRawStringLocationExp() &&
599 SizeInBits == RHS->getRawSizeInBits() &&
600 AlignInBits == RHS->getAlignInBits() &&
601 Encoding == RHS->getEncoding();
602 }
603 unsigned getHashValue() const {
604 // Intentionally computes the hash on a subset of the operands for
605 // performance reason. The subset has to be significant enough to avoid
606 // collision "most of the time". There is no correctness issue in case of
607 // collision because of the full check above.
609 }
610};
611
612template <> struct MDNodeKeyImpl<DIDerivedType> {
613 unsigned Tag;
614 MDString *Name;
615 Metadata *File;
616 unsigned Line;
617 Metadata *Scope;
619 Metadata *SizeInBits;
620 Metadata *OffsetInBits;
621 uint32_t AlignInBits;
622 std::optional<unsigned> DWARFAddressSpace;
623 std::optional<DIDerivedType::PtrAuthData> PtrAuthData;
624 unsigned Flags;
626 Metadata *Annotations;
627
628 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
629 Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
630 uint32_t AlignInBits, Metadata *OffsetInBits,
631 std::optional<unsigned> DWARFAddressSpace,
632 std::optional<DIDerivedType::PtrAuthData> PtrAuthData,
633 unsigned Flags, Metadata *ExtraData, Metadata *Annotations)
634 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
635 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
636 AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace),
637 PtrAuthData(PtrAuthData), Flags(Flags), ExtraData(ExtraData),
638 Annotations(Annotations) {}
639 MDNodeKeyImpl(const DIDerivedType *N)
640 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
641 Line(N->getLine()), Scope(N->getRawScope()),
642 BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
643 OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
644 DWARFAddressSpace(N->getDWARFAddressSpace()),
645 PtrAuthData(N->getPtrAuthData()), Flags(N->getFlags()),
646 ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {}
647
648 bool isKeyOf(const DIDerivedType *RHS) const {
649 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
650 File == RHS->getRawFile() && Line == RHS->getLine() &&
651 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
652 SizeInBits == RHS->getRawSizeInBits() &&
653 AlignInBits == RHS->getAlignInBits() &&
654 OffsetInBits == RHS->getRawOffsetInBits() &&
655 DWARFAddressSpace == RHS->getDWARFAddressSpace() &&
656 PtrAuthData == RHS->getPtrAuthData() && Flags == RHS->getFlags() &&
657 ExtraData == RHS->getRawExtraData() &&
658 Annotations == RHS->getRawAnnotations();
659 }
660
661 unsigned getHashValue() const {
662 // If this is a member inside an ODR type, only hash the type and the name.
663 // Otherwise the hash will be stronger than
664 // MDNodeSubsetEqualImpl::isODRMember().
665 if (Tag == dwarf::DW_TAG_member && Name)
666 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
667 if (CT->getRawIdentifier())
668 return hash_combine(Name, Scope);
669
670 // Intentionally computes the hash on a subset of the operands for
671 // performance reason. The subset has to be significant enough to avoid
672 // collision "most of the time". There is no correctness issue in case of
673 // collision because of the full check above.
674 return hash_combine(Tag, Name, File, Line, Scope, BaseType, Flags);
675 }
676};
677
678template <> struct MDNodeKeyImpl<DISubrangeType> {
681 unsigned Line;
685 unsigned Flags;
691
701 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
702 Scope(N->getRawScope()), SizeInBits(N->getRawSizeInBits()),
703 AlignInBits(N->getAlignInBits()), Flags(N->getFlags()),
704 BaseType(N->getRawBaseType()), LowerBound(N->getRawLowerBound()),
705 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()),
706 Bias(N->getRawBias()) {}
707
708 bool isKeyOf(const DISubrangeType *RHS) const {
709 auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool {
710 if (Node1 == Node2)
711 return true;
712
715 if (MD1 && MD2) {
718 if (CV1->getSExtValue() == CV2->getSExtValue())
719 return true;
720 }
721 return false;
722 };
723
724 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
725 Line == RHS->getLine() && Scope == RHS->getRawScope() &&
726 SizeInBits == RHS->getRawSizeInBits() &&
727 AlignInBits == RHS->getAlignInBits() && Flags == RHS->getFlags() &&
728 BaseType == RHS->getRawBaseType() &&
729 BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
730 BoundsEqual(UpperBound, RHS->getRawUpperBound()) &&
731 BoundsEqual(Stride, RHS->getRawStride()) &&
732 BoundsEqual(Bias, RHS->getRawBias());
733 }
734
735 unsigned getHashValue() const {
736 unsigned val = 0;
737 auto HashBound = [&](Metadata *Node) -> void {
739 if (MD) {
741 val = hash_combine(val, CV->getSExtValue());
742 } else {
743 val = hash_combine(val, Node);
744 }
745 };
746
747 HashBound(LowerBound);
748 HashBound(UpperBound);
749 HashBound(Stride);
750 HashBound(Bias);
751
752 return hash_combine(val, Name, File, Line, Scope, BaseType, Flags);
753 }
754};
755
758
759 static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) {
760 return isODRMember(LHS.Tag, LHS.Scope, LHS.Name, RHS);
761 }
762
763 static bool isSubsetEqual(const DIDerivedType *LHS,
764 const DIDerivedType *RHS) {
765 return isODRMember(LHS->getTag(), LHS->getRawScope(), LHS->getRawName(),
766 RHS);
767 }
768
769 /// Subprograms compare equal if they declare the same function in an ODR
770 /// type.
771 static bool isODRMember(unsigned Tag, const Metadata *Scope,
772 const MDString *Name, const DIDerivedType *RHS) {
773 // Check whether the LHS is eligible.
774 if (Tag != dwarf::DW_TAG_member || !Name)
775 return false;
776
777 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
778 if (!CT || !CT->getRawIdentifier())
779 return false;
780
781 // Compare to the RHS.
782 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
783 Scope == RHS->getRawScope();
784 }
785};
786
787template <> struct MDNodeKeyImpl<DICompositeType> {
788 unsigned Tag;
791 unsigned Line;
797 unsigned Flags;
799 unsigned RuntimeLang;
812
833 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
834 Line(N->getLine()), Scope(N->getRawScope()),
835 BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
836 OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
837 Flags(N->getFlags()), Elements(N->getRawElements()),
838 RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()),
839 TemplateParams(N->getRawTemplateParams()),
840 Identifier(N->getRawIdentifier()),
841 Discriminator(N->getRawDiscriminator()),
842 DataLocation(N->getRawDataLocation()),
843 Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()),
844 Rank(N->getRawRank()), Annotations(N->getRawAnnotations()),
845 Specification(N->getSpecification()),
846 NumExtraInhabitants(N->getNumExtraInhabitants()),
847 BitStride(N->getRawBitStride()) {}
848
849 bool isKeyOf(const DICompositeType *RHS) const {
850 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
851 File == RHS->getRawFile() && Line == RHS->getLine() &&
852 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
853 SizeInBits == RHS->getRawSizeInBits() &&
854 AlignInBits == RHS->getAlignInBits() &&
855 OffsetInBits == RHS->getRawOffsetInBits() &&
856 Flags == RHS->getFlags() && Elements == RHS->getRawElements() &&
857 RuntimeLang == RHS->getRuntimeLang() &&
858 VTableHolder == RHS->getRawVTableHolder() &&
859 TemplateParams == RHS->getRawTemplateParams() &&
860 Identifier == RHS->getRawIdentifier() &&
861 Discriminator == RHS->getRawDiscriminator() &&
862 DataLocation == RHS->getRawDataLocation() &&
863 Associated == RHS->getRawAssociated() &&
864 Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() &&
865 Annotations == RHS->getRawAnnotations() &&
866 Specification == RHS->getSpecification() &&
867 NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
868 BitStride == RHS->getRawBitStride();
869 }
870
871 unsigned getHashValue() const {
872 // Intentionally computes the hash on a subset of the operands for
873 // performance reason. The subset has to be significant enough to avoid
874 // collision "most of the time". There is no correctness issue in case of
875 // collision because of the full check above.
878 }
879};
880
881template <> struct MDNodeKeyImpl<DISubroutineType> {
882 unsigned Flags;
885
889 : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()) {}
890
891 bool isKeyOf(const DISubroutineType *RHS) const {
892 return Flags == RHS->getFlags() && CC == RHS->getCC() &&
893 TypeArray == RHS->getRawTypeArray();
894 }
895
896 unsigned getHashValue() const { return hash_combine(Flags, CC, TypeArray); }
897};
898
899template <> struct MDNodeKeyImpl<DIFile> {
902 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum;
904
911 : Filename(N->getRawFilename()), Directory(N->getRawDirectory()),
912 Checksum(N->getRawChecksum()), Source(N->getRawSource()) {}
913
914 bool isKeyOf(const DIFile *RHS) const {
915 return Filename == RHS->getRawFilename() &&
916 Directory == RHS->getRawDirectory() &&
917 Checksum == RHS->getRawChecksum() && Source == RHS->getRawSource();
918 }
919
920 unsigned getHashValue() const {
921 return hash_combine(Filename, Directory, Checksum ? Checksum->Kind : 0,
922 Checksum ? Checksum->Value : nullptr, Source);
923 }
924};
925
926template <> struct MDNodeKeyImpl<DISubprogram> {
927 Metadata *Scope;
928 MDString *Name;
929 MDString *LinkageName;
930 Metadata *File;
931 unsigned Line;
932 unsigned ScopeLine;
933 Metadata *Type;
934 Metadata *ContainingType;
935 unsigned VirtualIndex;
936 int ThisAdjustment;
937 unsigned Flags;
938 unsigned SPFlags;
939 Metadata *Unit;
940 Metadata *TemplateParams;
941 Metadata *Declaration;
942 Metadata *RetainedNodes;
943 Metadata *ThrownTypes;
944 Metadata *Annotations;
945 MDString *TargetFuncName;
946 bool UsesKeyInstructions;
947
948 MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
949 Metadata *File, unsigned Line, Metadata *Type,
950 unsigned ScopeLine, Metadata *ContainingType,
951 unsigned VirtualIndex, int ThisAdjustment, unsigned Flags,
952 unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams,
953 Metadata *Declaration, Metadata *RetainedNodes,
954 Metadata *ThrownTypes, Metadata *Annotations,
955 MDString *TargetFuncName, bool UsesKeyInstructions)
956 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
957 Line(Line), ScopeLine(ScopeLine), Type(Type),
958 ContainingType(ContainingType), VirtualIndex(VirtualIndex),
959 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags),
960 Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration),
961 RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes),
962 Annotations(Annotations), TargetFuncName(TargetFuncName),
963 UsesKeyInstructions(UsesKeyInstructions) {}
964 MDNodeKeyImpl(const DISubprogram *N)
965 : Scope(N->getRawScope()), Name(N->getRawName()),
966 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
967 Line(N->getLine()), ScopeLine(N->getScopeLine()), Type(N->getRawType()),
968 ContainingType(N->getRawContainingType()),
969 VirtualIndex(N->getVirtualIndex()),
970 ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()),
971 SPFlags(N->getSPFlags()), Unit(N->getRawUnit()),
972 TemplateParams(N->getRawTemplateParams()),
973 Declaration(N->getRawDeclaration()),
974 RetainedNodes(N->getRawRetainedNodes()),
975 ThrownTypes(N->getRawThrownTypes()),
976 Annotations(N->getRawAnnotations()),
977 TargetFuncName(N->getRawTargetFuncName()),
978 UsesKeyInstructions(N->getKeyInstructionsEnabled()) {}
979
980 bool isKeyOf(const DISubprogram *RHS) const {
981 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
982 LinkageName == RHS->getRawLinkageName() &&
983 File == RHS->getRawFile() && Line == RHS->getLine() &&
984 Type == RHS->getRawType() && ScopeLine == RHS->getScopeLine() &&
985 ContainingType == RHS->getRawContainingType() &&
986 VirtualIndex == RHS->getVirtualIndex() &&
987 ThisAdjustment == RHS->getThisAdjustment() &&
988 Flags == RHS->getFlags() && SPFlags == RHS->getSPFlags() &&
989 Unit == RHS->getUnit() &&
990 TemplateParams == RHS->getRawTemplateParams() &&
991 Declaration == RHS->getRawDeclaration() &&
992 RetainedNodes == RHS->getRawRetainedNodes() &&
993 ThrownTypes == RHS->getRawThrownTypes() &&
994 Annotations == RHS->getRawAnnotations() &&
995 TargetFuncName == RHS->getRawTargetFuncName() &&
996 UsesKeyInstructions == RHS->getKeyInstructionsEnabled();
997 }
998
999 bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; }
1000
1001 unsigned getHashValue() const {
1002 // Use the Scope's linkage name instead of using the scope directly, as the
1003 // scope may be a temporary one which can replaced, which would produce a
1004 // different hash for the same DISubprogram.
1005 llvm::StringRef ScopeLinkageName;
1006 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
1007 if (auto *ID = CT->getRawIdentifier())
1008 ScopeLinkageName = ID->getString();
1009
1010 // If this is a declaration inside an ODR type, only hash the type and the
1011 // name. Otherwise the hash will be stronger than
1012 // MDNodeSubsetEqualImpl::isDeclarationOfODRMember().
1013 if (!isDefinition() && LinkageName &&
1015 return hash_combine(LinkageName, ScopeLinkageName);
1016
1017 // Intentionally computes the hash on a subset of the operands for
1018 // performance reason. The subset has to be significant enough to avoid
1019 // collision "most of the time". There is no correctness issue in case of
1020 // collision because of the full check above.
1021 return hash_combine(Name, ScopeLinkageName, File, Type, Line);
1022 }
1023};
1024
1027
1028 static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) {
1029 return isDeclarationOfODRMember(LHS.isDefinition(), LHS.Scope,
1030 LHS.LinkageName, LHS.TemplateParams, RHS);
1031 }
1032
1033 static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) {
1034 return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(),
1035 LHS->getRawLinkageName(),
1036 LHS->getRawTemplateParams(), RHS);
1037 }
1038
1039 /// Subprograms compare equal if they declare the same function in an ODR
1040 /// type.
1041 static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope,
1042 const MDString *LinkageName,
1043 const Metadata *TemplateParams,
1044 const DISubprogram *RHS) {
1045 // Check whether the LHS is eligible.
1046 if (IsDefinition || !Scope || !LinkageName)
1047 return false;
1048
1049 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
1050 if (!CT || !CT->getRawIdentifier())
1051 return false;
1052
1053 // Compare to the RHS.
1054 // FIXME: We need to compare template parameters here to avoid incorrect
1055 // collisions in mapMetadata when RF_ReuseAndMutateDistinctMDs and a
1056 // ODR-DISubprogram has a non-ODR template parameter (i.e., a
1057 // DICompositeType that does not have an identifier). Eventually we should
1058 // decouple ODR logic from uniquing logic.
1059 return IsDefinition == RHS->isDefinition() && Scope == RHS->getRawScope() &&
1060 LinkageName == RHS->getRawLinkageName() &&
1061 TemplateParams == RHS->getRawTemplateParams();
1062 }
1063};
1064
1065template <> struct MDNodeKeyImpl<DILexicalBlock> {
1068 unsigned Line;
1069 unsigned Column;
1070
1074 : Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()),
1075 Column(N->getColumn()) {}
1076
1077 bool isKeyOf(const DILexicalBlock *RHS) const {
1078 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
1079 Line == RHS->getLine() && Column == RHS->getColumn();
1080 }
1081
1082 unsigned getHashValue() const {
1083 return hash_combine(Scope, File, Line, Column);
1084 }
1085};
1086
1091
1095 : Scope(N->getRawScope()), File(N->getRawFile()),
1096 Discriminator(N->getDiscriminator()) {}
1097
1098 bool isKeyOf(const DILexicalBlockFile *RHS) const {
1099 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
1100 Discriminator == RHS->getDiscriminator();
1101 }
1102
1103 unsigned getHashValue() const {
1105 }
1106};
1107
1108template <> struct MDNodeKeyImpl<DINamespace> {
1112
1116 : Scope(N->getRawScope()), Name(N->getRawName()),
1117 ExportSymbols(N->getExportSymbols()) {}
1118
1119 bool isKeyOf(const DINamespace *RHS) const {
1120 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1121 ExportSymbols == RHS->getExportSymbols();
1122 }
1123
1124 unsigned getHashValue() const { return hash_combine(Scope, Name); }
1125};
1126
1127template <> struct MDNodeKeyImpl<DICommonBlock> {
1132 unsigned LineNo;
1133
1138 : Scope(N->getRawScope()), Decl(N->getRawDecl()), Name(N->getRawName()),
1139 File(N->getRawFile()), LineNo(N->getLineNo()) {}
1140
1141 bool isKeyOf(const DICommonBlock *RHS) const {
1142 return Scope == RHS->getRawScope() && Decl == RHS->getRawDecl() &&
1143 Name == RHS->getRawName() && File == RHS->getRawFile() &&
1144 LineNo == RHS->getLineNo();
1145 }
1146
1147 unsigned getHashValue() const {
1148 return hash_combine(Scope, Decl, Name, File, LineNo);
1149 }
1150};
1151
1152template <> struct MDNodeKeyImpl<DIModule> {
1159 unsigned LineNo;
1161
1169 : File(N->getRawFile()), Scope(N->getRawScope()), Name(N->getRawName()),
1170 ConfigurationMacros(N->getRawConfigurationMacros()),
1171 IncludePath(N->getRawIncludePath()),
1172 APINotesFile(N->getRawAPINotesFile()), LineNo(N->getLineNo()),
1173 IsDecl(N->getIsDecl()) {}
1174
1175 bool isKeyOf(const DIModule *RHS) const {
1176 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1177 ConfigurationMacros == RHS->getRawConfigurationMacros() &&
1178 IncludePath == RHS->getRawIncludePath() &&
1179 APINotesFile == RHS->getRawAPINotesFile() &&
1180 File == RHS->getRawFile() && LineNo == RHS->getLineNo() &&
1181 IsDecl == RHS->getIsDecl();
1182 }
1183
1184 unsigned getHashValue() const {
1186 }
1187};
1188
1193
1197 : Name(N->getRawName()), Type(N->getRawType()),
1198 IsDefault(N->isDefault()) {}
1199
1201 return Name == RHS->getRawName() && Type == RHS->getRawType() &&
1202 IsDefault == RHS->isDefault();
1203 }
1204
1205 unsigned getHashValue() const { return hash_combine(Name, Type, IsDefault); }
1206};
1207
1209 unsigned Tag;
1214
1219 : Tag(N->getTag()), Name(N->getRawName()), Type(N->getRawType()),
1220 IsDefault(N->isDefault()), Value(N->getValue()) {}
1221
1223 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
1224 Type == RHS->getRawType() && IsDefault == RHS->isDefault() &&
1225 Value == RHS->getValue();
1226 }
1227
1228 unsigned getHashValue() const {
1230 }
1231};
1232
1233template <> struct MDNodeKeyImpl<DIGlobalVariable> {
1238 unsigned Line;
1246
1259 : Scope(N->getRawScope()), Name(N->getRawName()),
1260 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
1261 Line(N->getLine()), Type(N->getRawType()),
1262 IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
1263 StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()),
1264 TemplateParams(N->getRawTemplateParams()),
1265 AlignInBits(N->getAlignInBits()), Annotations(N->getRawAnnotations()) {}
1266
1267 bool isKeyOf(const DIGlobalVariable *RHS) const {
1268 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1269 LinkageName == RHS->getRawLinkageName() &&
1270 File == RHS->getRawFile() && Line == RHS->getLine() &&
1271 Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() &&
1272 IsDefinition == RHS->isDefinition() &&
1274 RHS->getRawStaticDataMemberDeclaration() &&
1275 TemplateParams == RHS->getRawTemplateParams() &&
1276 AlignInBits == RHS->getAlignInBits() &&
1277 Annotations == RHS->getRawAnnotations();
1278 }
1279
1280 unsigned getHashValue() const {
1281 // We do not use AlignInBits in hashing function here on purpose:
1282 // in most cases this param for local variable is zero (for function param
1283 // it is always zero). This leads to lots of hash collisions and errors on
1284 // cases with lots of similar variables.
1285 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1286 // generated IR is random for each run and test fails with Align included.
1287 // TODO: make hashing work fine with such situations
1289 IsLocalToUnit, IsDefinition, /* AlignInBits, */
1291 }
1292};
1293
1294template <> struct MDNodeKeyImpl<DILocalVariable> {
1298 unsigned Line;
1300 unsigned Arg;
1301 unsigned Flags;
1304
1311 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1312 Line(N->getLine()), Type(N->getRawType()), Arg(N->getArg()),
1313 Flags(N->getFlags()), AlignInBits(N->getAlignInBits()),
1314 Annotations(N->getRawAnnotations()) {}
1315
1316 bool isKeyOf(const DILocalVariable *RHS) const {
1317 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1318 File == RHS->getRawFile() && Line == RHS->getLine() &&
1319 Type == RHS->getRawType() && Arg == RHS->getArg() &&
1320 Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits() &&
1321 Annotations == RHS->getRawAnnotations();
1322 }
1323
1324 unsigned getHashValue() const {
1325 // We do not use AlignInBits in hashing function here on purpose:
1326 // in most cases this param for local variable is zero (for function param
1327 // it is always zero). This leads to lots of hash collisions and errors on
1328 // cases with lots of similar variables.
1329 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1330 // generated IR is random for each run and test fails with Align included.
1331 // TODO: make hashing work fine with such situations
1333 }
1334};
1335
1336template <> struct MDNodeKeyImpl<DILabel> {
1340 unsigned Line;
1341 unsigned Column;
1343 std::optional<unsigned> CoroSuspendIdx;
1344
1351 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1352 Line(N->getLine()), Column(N->getColumn()),
1353 IsArtificial(N->isArtificial()),
1354 CoroSuspendIdx(N->getCoroSuspendIdx()) {}
1355
1356 bool isKeyOf(const DILabel *RHS) const {
1357 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1358 File == RHS->getRawFile() && Line == RHS->getLine() &&
1359 Column == RHS->getColumn() && IsArtificial == RHS->isArtificial() &&
1360 CoroSuspendIdx == RHS->getCoroSuspendIdx();
1361 }
1362
1363 /// Using name and line to get hash value. It should already be mostly unique.
1364 unsigned getHashValue() const {
1367 }
1368};
1369
1370template <> struct MDNodeKeyImpl<DIExpression> {
1372
1374 MDNodeKeyImpl(const DIExpression *N) : Elements(N->getElements()) {}
1375
1376 bool isKeyOf(const DIExpression *RHS) const {
1377 return Elements == RHS->getElements();
1378 }
1379
1380 unsigned getHashValue() const { return hash_combine_range(Elements); }
1381};
1382
1386
1390 : Variable(N->getRawVariable()), Expression(N->getRawExpression()) {}
1391
1393 return Variable == RHS->getRawVariable() &&
1394 Expression == RHS->getRawExpression();
1395 }
1396
1397 unsigned getHashValue() const { return hash_combine(Variable, Expression); }
1398};
1399
1400template <> struct MDNodeKeyImpl<DIObjCProperty> {
1403 unsigned Line;
1406 unsigned Attributes;
1408
1415 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
1416 GetterName(N->getRawGetterName()), SetterName(N->getRawSetterName()),
1417 Attributes(N->getAttributes()), Type(N->getRawType()) {}
1418
1419 bool isKeyOf(const DIObjCProperty *RHS) const {
1420 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
1421 Line == RHS->getLine() && GetterName == RHS->getRawGetterName() &&
1422 SetterName == RHS->getRawSetterName() &&
1423 Attributes == RHS->getAttributes() && Type == RHS->getRawType();
1424 }
1425
1426 unsigned getHashValue() const {
1428 Type);
1429 }
1430};
1431
1432template <> struct MDNodeKeyImpl<DIImportedEntity> {
1433 unsigned Tag;
1437 unsigned Line;
1440
1446 : Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()),
1447 File(N->getRawFile()), Line(N->getLine()), Name(N->getRawName()),
1448 Elements(N->getRawElements()) {}
1449
1450 bool isKeyOf(const DIImportedEntity *RHS) const {
1451 return Tag == RHS->getTag() && Scope == RHS->getRawScope() &&
1452 Entity == RHS->getRawEntity() && File == RHS->getFile() &&
1453 Line == RHS->getLine() && Name == RHS->getRawName() &&
1454 Elements == RHS->getRawElements();
1455 }
1456
1457 unsigned getHashValue() const {
1459 }
1460};
1461
1462template <> struct MDNodeKeyImpl<DIMacro> {
1463 unsigned MIType;
1464 unsigned Line;
1467
1471 : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getRawName()),
1472 Value(N->getRawValue()) {}
1473
1474 bool isKeyOf(const DIMacro *RHS) const {
1475 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1476 Name == RHS->getRawName() && Value == RHS->getRawValue();
1477 }
1478
1479 unsigned getHashValue() const {
1480 return hash_combine(MIType, Line, Name, Value);
1481 }
1482};
1483
1484template <> struct MDNodeKeyImpl<DIMacroFile> {
1485 unsigned MIType;
1486 unsigned Line;
1489
1494 : MIType(N->getMacinfoType()), Line(N->getLine()), File(N->getRawFile()),
1495 Elements(N->getRawElements()) {}
1496
1497 bool isKeyOf(const DIMacroFile *RHS) const {
1498 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1499 File == RHS->getRawFile() && Elements == RHS->getRawElements();
1500 }
1501
1502 unsigned getHashValue() const {
1504 }
1505};
1506
1507// DIArgLists are not MDNodes, but we still want to unique them in a DenseSet
1508// based on a hash of their arguments.
1511
1513 DIArgListKeyInfo(const DIArgList *N) : Args(N->getArgs()) {}
1514
1515 bool isKeyOf(const DIArgList *RHS) const { return Args == RHS->getArgs(); }
1516
1517 unsigned getHashValue() const { return hash_combine_range(Args); }
1518};
1519
1520/// DenseMapInfo for DIArgList.
1523
1524 static inline DIArgList *getEmptyKey() {
1526 }
1527
1531
1532 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1533
1534 static unsigned getHashValue(const DIArgList *N) {
1535 return KeyTy(N).getHashValue();
1536 }
1537
1538 static bool isEqual(const KeyTy &LHS, const DIArgList *RHS) {
1539 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1540 return false;
1541 return LHS.isKeyOf(RHS);
1542 }
1543
1544 static bool isEqual(const DIArgList *LHS, const DIArgList *RHS) {
1545 return LHS == RHS;
1546 }
1547};
1548
1549/// DenseMapInfo for MDNode subclasses.
1550template <class NodeTy> struct MDNodeInfo {
1553
1554 static inline NodeTy *getEmptyKey() {
1556 }
1557
1558 static inline NodeTy *getTombstoneKey() {
1560 }
1561
1562 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1563
1564 static unsigned getHashValue(const NodeTy *N) {
1565 return KeyTy(N).getHashValue();
1566 }
1567
1568 static bool isEqual(const KeyTy &LHS, const NodeTy *RHS) {
1569 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1570 return false;
1571 return SubsetEqualTy::isSubsetEqual(LHS, RHS) || LHS.isKeyOf(RHS);
1572 }
1573
1574 static bool isEqual(const NodeTy *LHS, const NodeTy *RHS) {
1575 if (LHS == RHS)
1576 return true;
1577 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1578 return false;
1580 }
1581};
1582
1583#define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>;
1584#include "llvm/IR/Metadata.def"
1585
1586/// Single metadata attachment, forms linked list ended by index 0.
1588 unsigned Next = 0;
1589 unsigned MDKind;
1591};
1592
1594public:
1595 /// OwnedModules - The set of modules instantiated in this context, and which
1596 /// will be automatically deleted if this context is deleted.
1598
1599 /// MachineFunctionNums - Keep the next available unique number available for
1600 /// a MachineFunction in given module. Module must in OwnedModules.
1602
1603 /// The main remark streamer used by all the other streamers (e.g. IR, MIR,
1604 /// frontends, etc.). This should only be used by the specific streamers, and
1605 /// never directly.
1606 std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer;
1607
1608 std::unique_ptr<DiagnosticHandler> DiagHandler;
1611 /// The minimum hotness value a diagnostic needs in order to be included in
1612 /// optimization diagnostics.
1613 ///
1614 /// The threshold is an Optional value, which maps to one of the 3 states:
1615 /// 1). 0 => threshold disabled. All emarks will be printed.
1616 /// 2). positive int => manual threshold by user. Remarks with hotness exceed
1617 /// threshold will be printed.
1618 /// 3). None => 'auto' threshold by user. The actual value is not
1619 /// available at command line, but will be synced with
1620 /// hotness threhold from profile summary during
1621 /// compilation.
1622 ///
1623 /// State 1 and 2 are considered as terminal states. State transition is
1624 /// only allowed from 3 to 2, when the threshold is first synced with profile
1625 /// summary. This ensures that the threshold is set only once and stays
1626 /// constant.
1627 ///
1628 /// If threshold option is not specified, it is disabled (0) by default.
1629 std::optional<uint64_t> DiagnosticsHotnessThreshold = 0;
1630
1631 /// The percentage of difference between profiling branch weights and
1632 /// llvm.expect branch weights to tolerate when emiting MisExpect diagnostics
1633 std::optional<uint32_t> DiagnosticsMisExpectTolerance = 0;
1635
1636 /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
1637 std::unique_ptr<LLVMRemarkStreamer> LLVMRS;
1638
1640 void *YieldOpaqueHandle = nullptr;
1641
1643
1647 DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantInt>>
1649
1653 DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantByte>>
1655
1657 DenseMap<std::pair<ElementCount, APFloat>, std::unique_ptr<ConstantFP>>
1659
1663
1668
1669#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
1670 DenseSet<CLASS *, CLASS##Info> CLASS##s;
1671#include "llvm/IR/Metadata.def"
1672
1673 // Optional map for looking up composite types by identifier.
1674 std::optional<DenseMap<const MDString *, DICompositeType *>> DITypeMap;
1675
1676 // MDNodes may be uniqued or not uniqued. When they're not uniqued, they
1677 // aren't in the MDNodeSet, but they're still shared between objects, so no
1678 // one object can destroy them. Keep track of them here so we can delete
1679 // them on context teardown.
1680 std::vector<MDNode *> DistinctMDNodes;
1681
1682 // ConstantRangeListAttributeImpl is a TrailingObjects/ArrayRef of
1683 // ConstantRange. Since this is a dynamically sized class, it's not
1684 // possible to use SpecificBumpPtrAllocator. Instead, we use normal Alloc
1685 // for allocation and record all allocated pointers in this vector. In the
1686 // LLVMContext destructor, call the destuctors of everything in the vector.
1687 std::vector<ConstantRangeListAttributeImpl *> ConstantRangeListAttributes;
1688
1690
1693
1696
1699
1701
1703
1705
1707
1709
1711
1713
1715
1717
1719
1721
1724
1727
1728 // Basic type instances.
1734
1735 std::unique_ptr<ConstantTokenNone> TheNoneToken;
1736
1741
1744
1751
1754
1757 PointerType *AS0PointerType = nullptr; // AddrSpace = 0
1760
1761 /// ValueHandles - This map keeps track of all of the value handles that are
1762 /// watching a Value*. The Value::HasValueHandle bit is used to know
1763 /// whether or not a value has an entry in this map.
1766
1767 /// CustomMDKindNames - Map to hold the metadata string to ID mapping.
1769
1770 /// Collection of metadata attachments in this context.
1772 /// Index of first free Metadatas entry, linked list via MDAttachment::Next.
1774 /// Number of currently unused metadata entries. Only used/updated in debug
1775 /// builds to ensure that all metadata attachments are properly freed.
1777
1778 /// Map DIAssignID -> Instructions with that attachment.
1779 /// Managed by Instruction via Instruction::updateDIAssignIDMapping.
1780 /// Query using the at:: functions defined in DebugInfo.h.
1782
1783 /// Collection of per-GlobalObject sections used in this context.
1785
1786 /// Collection of per-GlobalValue partitions used in this context.
1788
1791
1792 /// DiscriminatorTable - This table maps file:line locations to an
1793 /// integer representing the next DWARF path discriminator to assign to
1794 /// instructions in different blocks at the same location.
1796
1797 /// A set of interned tags for operand bundles. The StringMap maps
1798 /// bundle tags to their IDs.
1799 ///
1800 /// \see LLVMContext::getOperandBundleTagID
1802
1806
1807 /// A set of interned synchronization scopes. The StringMap maps
1808 /// synchronization scope names to their respective synchronization scope IDs.
1810
1811 /// getOrInsertSyncScopeID - Maps synchronization scope name to
1812 /// synchronization scope ID. Every synchronization scope registered with
1813 /// LLVMContext has unique ID except pre-defined ones.
1815
1816 /// getSyncScopeNames - Populates client supplied SmallVector with
1817 /// synchronization scope names registered with LLVMContext. Synchronization
1818 /// scope names are ordered by increasing synchronization scope IDs.
1820
1821 /// getSyncScopeName - Returns the name of a SyncScope::ID
1822 /// registered with LLVMContext, if any.
1823 std::optional<StringRef> getSyncScopeName(SyncScope::ID Id) const;
1824
1825 /// Maintain the GC name for each function.
1826 ///
1827 /// This saves allocating an additional word in Function for programs which
1828 /// do not use GC (i.e., most programs) at the cost of increased overhead for
1829 /// clients which do use GC.
1831
1832 /// Flag to indicate if Value (other than GlobalValue) retains their name or
1833 /// not.
1834 bool DiscardValueNames = false;
1835
1838
1839 mutable OptPassGate *OPG = nullptr;
1840
1841 /// Access the object which can disable optional passes and individual
1842 /// optimizations at compile time.
1843 OptPassGate &getOptPassGate() const;
1844
1845 /// Set the object which can disable optional passes and individual
1846 /// optimizations at compile time.
1847 ///
1848 /// The lifetime of the object must be guaranteed to extend as long as the
1849 /// LLVMContext is used by compilation.
1851
1852 /// Mapping of blocks to collections of "trailing" DbgVariableRecords. As part
1853 /// of the "RemoveDIs" project, debug-info variable location records are going
1854 /// to cease being instructions... which raises the problem of where should
1855 /// they be recorded when we remove the terminator of a blocks, such as:
1856 ///
1857 /// %foo = add i32 0, 0
1858 /// br label %bar
1859 ///
1860 /// If the branch is removed, a legitimate transient state while editing a
1861 /// block, any debug-records between those two instructions will not have a
1862 /// location. Each block thus records any DbgVariableRecord records that
1863 /// "trail" in such a way. These are stored in LLVMContext because typically
1864 /// LLVM only edits a small number of blocks at a time, so there's no need to
1865 /// bloat BasicBlock with such a data structure.
1867
1868 // Set, get and delete operations for TrailingDbgRecords.
1873
1877
1879
1880 std::string DefaultTargetCPU;
1882
1883 /// The next available source atom group number. The front end is responsible
1884 /// for assigning source atom numbers, but certain optimisations need to
1885 /// assign new group numbers to a set of instructions. Most often code
1886 /// duplication optimisations like loop unroll. Tracking a global maximum
1887 /// value means we can know (cheaply) we're never using a group number that's
1888 /// already used within this function.
1889 ///
1890 /// Start a 1 because 0 means the source location isn't part of an atom group.
1892};
1893
1894} // end namespace llvm
1895
1896#endif // LLVM_LIB_IR_LLVMCONTEXTIMPL_H
static std::optional< unsigned > getTag(const TargetRegisterInfo *TRI, const MachineInstr &MI, const LoadInfo &LI)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
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")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
dxil translate DXIL Translate Metadata
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.
This file defines a hash set that can be used to remove duplication of nodes in a graph.
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file contains the declarations for metadata subclasses.
#define P(N)
static StringRef getName(Value *V)
This file contains some templates that are useful if you are working with the STL at all.
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static uint32_t getFlags(const Symbol *Sym)
Definition TapiFile.cpp:26
Value * RHS
Value * LHS
static const fltSemantics & Bogus()
A Pseudo fltsemantic used to construct APFloats that cannot conflict with anything real.
Definition APFloat.h:323
Class for arbitrary precision integers.
Definition APInt.h:78
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Class to represent array types.
This class represents a single, uniqued attribute.
This class represents a set of attributes that apply to the function, return type,...
This class represents a group of attributes that apply to one element: function, return type,...
LLVM Basic Block Representation.
Definition BasicBlock.h:62
Class to represent byte types.
Constant * getValue() const
Definition Metadata.h:545
Class for constant bytes.
Definition Constants.h:281
This is the shared class of boolean and integer constants.
Definition Constants.h:87
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:174
List of ValueAsMetadata, to be used as an argument to a dbg.value intrinsic.
Basic type, like 'int' or 'float'.
Debug common block.
Enumeration value.
DWARF expression.
A pair of DIGlobalVariable and DIExpression.
An imported module (C++ using directive or similar).
Debug lexical block.
Represents a module in the programming language, for example, a Clang module, or a Fortran module.
Debug lexical block.
String type, Fortran CHARACTER(n)
Subprogram description. Uses SubclassData1.
Array subrange.
Type array for a subprogram.
Per-instruction record of debug-info.
Implements a dense probed hash-table based set.
Definition DenseSet.h:279
FoldingSet - This template class is used to instantiate a specialized implementation of the folding s...
Definition FoldingSet.h:536
Class to represent function types.
Generic tagged DWARF-like metadata node.
Class to represent integer types.
DenseMap< const GlobalValue *, StringRef > GlobalValuePartitions
Collection of per-GlobalValue partitions used in this context.
DenseMap< const GlobalValue *, GlobalValue::SanitizerMetadata > GlobalValueSanitizerMetadata
DenseMap< unsigned, std::unique_ptr< ConstantInt > > IntOneConstants
void getSyncScopeNames(SmallVectorImpl< StringRef > &SSNs) const
getSyncScopeNames - Populates client supplied SmallVector with synchronization scope names registered...
DenseMap< unsigned, std::unique_ptr< ConstantInt > > IntZeroConstants
DenseMap< Metadata *, MetadataAsValue * > MetadataAsValues
DenseMap< unsigned, ByteType * > ByteTypes
ConstantUniqueMap< ConstantArray > ArrayConstantsTy
SmallVector< MDAttachment, 0 > Metadatas
Collection of metadata attachments in this context.
DenseMap< std::pair< ElementCount, APInt >, std::unique_ptr< ConstantByte > > ByteSplatConstants
DenseMap< APFloat, std::unique_ptr< ConstantFP > > FPConstants
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
DenseSet< FunctionType *, FunctionTypeKeyInfo > FunctionTypeSet
TargetExtTypeSet TargetExtTypes
DenseMap< DIAssignID *, SmallVector< Instruction *, 1 > > AssignmentIDToInstrs
Map DIAssignID -> Instructions with that attachment.
DenseMap< Type *, std::unique_ptr< PoisonValue > > PVConstants
DenseMap< APInt, std::unique_ptr< ConstantInt > > IntConstants
DenseMap< Value *, ValueHandleBase * > ValueHandlesTy
ValueHandles - This map keeps track of all of the value handles that are watching a Value*.
ConstantByte * TheFalseByteVal
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
SyncScope::ID getOrInsertSyncScopeID(StringRef SSN)
getOrInsertSyncScopeID - Maps synchronization scope name to synchronization scope ID.
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< const BasicBlock *, BlockAddress * > BlockAddresses
ConstantByte * TheTrueByteVal
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
std::string DefaultTargetFeatures
DenseMap< Module *, unsigned > MachineFunctionNums
MachineFunctionNums - Keep the next available unique number available for a MachineFunction in given ...
StringMap< unsigned > CustomMDKindNames
CustomMDKindNames - Map to hold the metadata string to ID mapping.
ConstantUniqueMap< ConstantStruct > StructConstantsTy
StringMapEntry< uint32_t > * getOrInsertBundleTag(StringRef Tag)
std::unique_ptr< DiagnosticHandler > DiagHandler
StringMap< uint32_t > BundleTagCache
A set of interned tags for operand bundles.
DbgMarker * getTrailingDbgRecords(BasicBlock *B)
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
DenseSet< TargetExtType *, TargetExtTypeKeyInfo > TargetExtTypeSet
void deleteTrailingDbgRecords(BasicBlock *B)
FoldingSet< AttributeSetNode > AttrsSetNodes
FoldingSet< AttributeListImpl > AttrsLists
ConstantUniqueMap< ConstantPtrAuth > ConstantPtrAuths
DenseMap< TargetExtType *, std::unique_ptr< ConstantTargetNone > > CTNConstants
SpecificBumpPtrAllocator< ConstantRangeAttributeImpl > ConstantRangeAttributeAlloc
std::optional< uint64_t > DiagnosticsHotnessThreshold
The minimum hotness value a diagnostic needs in order to be included in optimization diagnostics.
ConstantUniqueMap< ConstantVector > VectorConstantsTy
ConstantUniqueMap< ConstantExpr > ExprConstants
uint32_t getOperandBundleTagID(StringRef Tag) const
StringMap< SyncScope::ID > SSC
A set of interned synchronization scopes.
DenseMap< unsigned, PointerType * > PointerTypes
void setTrailingDbgRecords(BasicBlock *B, DbgMarker *M)
DenseSet< StructType *, AnonStructTypeKeyInfo > StructTypeSet
DenseMap< std::pair< ElementCount, APInt >, std::unique_ptr< ConstantInt > > IntSplatConstants
UniqueStringSaver Saver
unsigned MetadataRecycleHead
Index of first free Metadatas entry, linked list via MDAttachment::Next.
LLVMContext::YieldCallbackTy YieldCallback
DenseMap< unsigned, std::unique_ptr< ConstantByte > > ByteOneConstants
DenseMap< unsigned, IntegerType * > IntegerTypes
StringMap< StructType * > NamedStructTypes
std::vector< ConstantRangeListAttributeImpl * > ConstantRangeListAttributes
DenseSet< DIArgList *, DIArgListInfo > DIArgLists
ValueHandlesTy ValueHandles
std::optional< StringRef > getSyncScopeName(SyncScope::ID Id) const
getSyncScopeName - Returns the name of a SyncScope::ID registered with LLVMContext,...
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...
uint64_t NextAtomGroup
The next available source atom group number.
LLVMContextImpl(LLVMContext &C)
DenseMap< const GlobalValue *, DSOLocalEquivalent * > DSOLocalEquivalents
DenseMap< unsigned, std::unique_ptr< ConstantByte > > ByteZeroConstants
DenseMap< APInt, std::unique_ptr< ConstantByte > > ByteConstants
SmallDenseMap< BasicBlock *, DbgMarker * > TrailingDbgRecords
Mapping of blocks to collections of "trailing" DbgVariableRecords.
FunctionTypeSet FunctionTypes
std::optional< DenseMap< const MDString *, DICompositeType * > > DITypeMap
DenseMap< std::pair< ElementCount, APFloat >, std::unique_ptr< ConstantFP > > FPSplatConstants
unsigned MetadataRecycleSize
Number of currently unused metadata entries.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
void(*)(LLVMContext *Context, void *OpaqueHandle) YieldCallbackTy
Defines the type of a yield callback.
Streamer for LLVM remarks which has logic for dealing with DiagnosticInfo objects.
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:1080
A single uniqued string.
Definition Metadata.h:722
Tuple of metadata.
Definition Metadata.h:1500
Root of the metadata hierarchy.
Definition Metadata.h:64
Extensions to this class implement mechanisms to disable passes and individual optimizations at compi...
Definition OptBisect.h:26
Class to represent pointers.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
Definition Allocator.h:390
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:133
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
Class to represent struct types.
Class to represent target extensions types, which are generally unintrospectable from target-independ...
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
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:45
This is the common base class of value handles.
Definition ValueHandle.h:30
Base class of all SIMD vector types.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:557
TypedTrackingMDRef< MDNode > TrackingMDNodeRef
hash_code hash_value(const FixedPointSemantics &Val)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool isa_and_nonnull(const Y &Val)
Definition Casting.h:676
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1916
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition Hashing.h:592
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
Definition Hashing.h:466
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
#define N
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)
DenseMapInfo for DIArgList.
static unsigned getHashValue(const KeyTy &Key)
static DIArgList * getEmptyKey()
static unsigned getHashValue(const DIArgList *N)
static bool isEqual(const DIArgList *LHS, const DIArgList *RHS)
DIArgListKeyInfo KeyTy
static DIArgList * getTombstoneKey()
static bool isEqual(const KeyTy &LHS, const DIArgList *RHS)
ArrayRef< ValueAsMetadata * > Args
DIArgListKeyInfo(const DIArgList *N)
DIArgListKeyInfo(ArrayRef< ValueAsMetadata * > Args)
unsigned getHashValue() const
bool isKeyOf(const DIArgList *RHS) const
A single checksum, represented by a Kind and a Value (a string).
static bool isEqual(const APFloat &LHS, const APFloat &RHS)
static unsigned getHashValue(const APFloat &Key)
An information struct used to provide DenseMap with the various necessary components for a given valu...
This is the base class for diagnostic handling in LLVM.
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()
Single metadata attachment, forms linked list ended by index 0.
TrackingMDNodeRef Node
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)
MDNodeSubsetEqualImpl< NodeTy > SubsetEqualTy
MDNodeKeyImpl< NodeTy > KeyTy
static NodeTy * getTombstoneKey()
static NodeTy * getEmptyKey()
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned LineNo, Metadata *Scope, Metadata *SizeInBits, uint32_t AlignInBits, unsigned Encoding, uint32_t NumExtraInhabitants, uint32_t DataSizeInBits, unsigned Flags)
bool isKeyOf(const DIBasicType *RHS) const
bool isKeyOf(const DICommonBlock *RHS) const
MDNodeKeyImpl(Metadata *Scope, Metadata *Decl, MDString *Name, Metadata *File, unsigned LineNo)
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits, uint32_t AlignInBits, Metadata *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, Metadata *Specification, uint32_t NumExtraInhabitants, Metadata *BitStride)
MDNodeKeyImpl(const DICompositeType *N)
bool isKeyOf(const DICompositeType *RHS) const
MDNodeKeyImpl(APInt Value, bool IsUnsigned, MDString *Name)
MDNodeKeyImpl(int64_t Value, bool IsUnsigned, MDString *Name)
bool isKeyOf(const DIEnumerator *RHS) const
bool isKeyOf(const DIExpression *RHS) const
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)
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned LineNo, Metadata *Scope, Metadata *SizeInBits, uint32_t AlignInBits, unsigned Encoding, unsigned Flags, unsigned Kind, int Factor, APInt Numerator, APInt Denominator)
MDNodeKeyImpl(const DIFixedPointType *N)
bool isKeyOf(const DIFixedPointType *RHS) const
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
std::optional< unsigned > CoroSuspendIdx
MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line, unsigned Column, bool IsArtificial, std::optional< unsigned > CoroSuspendIdx)
MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator)
MDNodeKeyImpl(const DILexicalBlockFile *N)
bool isKeyOf(const DILexicalBlockFile *RHS) const
bool isKeyOf(const DILexicalBlock *RHS) const
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, uint16_t Column, Metadata *Scope, Metadata *InlinedAt, bool ImplicitCode, uint64_t AtomGroup, uint8_t AtomRank)
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(Metadata *Scope, MDString *Name, bool ExportSymbols)
bool isKeyOf(const DINamespace *RHS) const
bool isKeyOf(const DIObjCProperty *RHS) const
MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line, MDString *GetterName, MDString *SetterName, unsigned Attributes, Metadata *Type)
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *StringLength, Metadata *StringLengthExp, Metadata *StringLocationExp, Metadata *SizeInBits, uint32_t AlignInBits, unsigned Encoding)
bool isKeyOf(const DIStringType *RHS) const
MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *SizeInBits, uint32_t AlignInBits, unsigned Flags, Metadata *BaseType, Metadata *LowerBound, Metadata *UpperBound, Metadata *Stride, Metadata *Bias)
bool isKeyOf(const DISubrangeType *RHS) const
MDNodeKeyImpl(const DISubrangeType *N)
MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound, Metadata *Stride)
bool isKeyOf(const DISubrange *RHS) const
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)
MDNodeKeyImpl< NodeTy > KeyTy
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()