LLVM 22.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;
481 unsigned Encoding;
484 unsigned Flags;
485
494 : Tag(N->getTag()), Name(N->getRawName()),
495 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
496 Encoding(N->getEncoding()),
497 NumExtraInhabitants(N->getNumExtraInhabitants()),
498 DataSizeInBits(N->getDataSizeInBits()), Flags(N->getFlags()) {}
499
500 bool isKeyOf(const DIBasicType *RHS) const {
501 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
502 SizeInBits == RHS->getRawSizeInBits() &&
503 AlignInBits == RHS->getAlignInBits() &&
504 Encoding == RHS->getEncoding() &&
505 NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
506 DataSizeInBits == RHS->getDataSizeInBits() &&
507 Flags == RHS->getFlags();
508 }
509
510 unsigned getHashValue() const {
512 }
513};
514
515template <> struct MDNodeKeyImpl<DIFixedPointType> {
516 unsigned Tag;
520 unsigned Encoding;
521 unsigned Flags;
522 unsigned Kind;
526
534 : Tag(N->getTag()), Name(N->getRawName()),
535 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
536 Encoding(N->getEncoding()), Flags(N->getFlags()), Kind(N->getKind()),
537 Factor(N->getFactorRaw()), Numerator(N->getNumeratorRaw()),
538 Denominator(N->getDenominatorRaw()) {}
539
540 bool isKeyOf(const DIFixedPointType *RHS) const {
541 return Name == RHS->getRawName() && SizeInBits == RHS->getRawSizeInBits() &&
542 AlignInBits == RHS->getAlignInBits() && Kind == RHS->getKind() &&
543 (RHS->isRational() ? (Numerator == RHS->getNumerator() &&
544 Denominator == RHS->getDenominator())
545 : Factor == RHS->getFactor());
546 }
547
548 unsigned getHashValue() const {
550 }
551};
552
553template <> struct MDNodeKeyImpl<DIStringType> {
554 unsigned Tag;
561 unsigned Encoding;
562
570 : Tag(N->getTag()), Name(N->getRawName()),
571 StringLength(N->getRawStringLength()),
572 StringLengthExp(N->getRawStringLengthExp()),
573 StringLocationExp(N->getRawStringLocationExp()),
574 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
575 Encoding(N->getEncoding()) {}
576
577 bool isKeyOf(const DIStringType *RHS) const {
578 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
579 StringLength == RHS->getRawStringLength() &&
580 StringLengthExp == RHS->getRawStringLengthExp() &&
581 StringLocationExp == RHS->getRawStringLocationExp() &&
582 SizeInBits == RHS->getRawSizeInBits() &&
583 AlignInBits == RHS->getAlignInBits() &&
584 Encoding == RHS->getEncoding();
585 }
586 unsigned getHashValue() const {
587 // Intentionally computes the hash on a subset of the operands for
588 // performance reason. The subset has to be significant enough to avoid
589 // collision "most of the time". There is no correctness issue in case of
590 // collision because of the full check above.
592 }
593};
594
595template <> struct MDNodeKeyImpl<DIDerivedType> {
596 unsigned Tag;
597 MDString *Name;
598 Metadata *File;
599 unsigned Line;
600 Metadata *Scope;
602 Metadata *SizeInBits;
603 Metadata *OffsetInBits;
604 uint32_t AlignInBits;
605 std::optional<unsigned> DWARFAddressSpace;
606 std::optional<DIDerivedType::PtrAuthData> PtrAuthData;
607 unsigned Flags;
609 Metadata *Annotations;
610
611 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
612 Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
613 uint32_t AlignInBits, Metadata *OffsetInBits,
614 std::optional<unsigned> DWARFAddressSpace,
615 std::optional<DIDerivedType::PtrAuthData> PtrAuthData,
616 unsigned Flags, Metadata *ExtraData, Metadata *Annotations)
617 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
618 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
619 AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace),
620 PtrAuthData(PtrAuthData), Flags(Flags), ExtraData(ExtraData),
621 Annotations(Annotations) {}
622 MDNodeKeyImpl(const DIDerivedType *N)
623 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
624 Line(N->getLine()), Scope(N->getRawScope()),
625 BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
626 OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
627 DWARFAddressSpace(N->getDWARFAddressSpace()),
628 PtrAuthData(N->getPtrAuthData()), Flags(N->getFlags()),
629 ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {}
630
631 bool isKeyOf(const DIDerivedType *RHS) const {
632 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
633 File == RHS->getRawFile() && Line == RHS->getLine() &&
634 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
635 SizeInBits == RHS->getRawSizeInBits() &&
636 AlignInBits == RHS->getAlignInBits() &&
637 OffsetInBits == RHS->getRawOffsetInBits() &&
638 DWARFAddressSpace == RHS->getDWARFAddressSpace() &&
639 PtrAuthData == RHS->getPtrAuthData() && Flags == RHS->getFlags() &&
640 ExtraData == RHS->getRawExtraData() &&
641 Annotations == RHS->getRawAnnotations();
642 }
643
644 unsigned getHashValue() const {
645 // If this is a member inside an ODR type, only hash the type and the name.
646 // Otherwise the hash will be stronger than
647 // MDNodeSubsetEqualImpl::isODRMember().
648 if (Tag == dwarf::DW_TAG_member && Name)
649 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
650 if (CT->getRawIdentifier())
651 return hash_combine(Name, Scope);
652
653 // Intentionally computes the hash on a subset of the operands for
654 // performance reason. The subset has to be significant enough to avoid
655 // collision "most of the time". There is no correctness issue in case of
656 // collision because of the full check above.
657 return hash_combine(Tag, Name, File, Line, Scope, BaseType, Flags);
658 }
659};
660
661template <> struct MDNodeKeyImpl<DISubrangeType> {
664 unsigned Line;
668 unsigned Flags;
674
684 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
685 Scope(N->getRawScope()), SizeInBits(N->getRawSizeInBits()),
686 AlignInBits(N->getAlignInBits()), Flags(N->getFlags()),
687 BaseType(N->getRawBaseType()), LowerBound(N->getRawLowerBound()),
688 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()),
689 Bias(N->getRawBias()) {}
690
691 bool isKeyOf(const DISubrangeType *RHS) const {
692 auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool {
693 if (Node1 == Node2)
694 return true;
695
698 if (MD1 && MD2) {
701 if (CV1->getSExtValue() == CV2->getSExtValue())
702 return true;
703 }
704 return false;
705 };
706
707 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
708 Line == RHS->getLine() && Scope == RHS->getRawScope() &&
709 SizeInBits == RHS->getRawSizeInBits() &&
710 AlignInBits == RHS->getAlignInBits() && Flags == RHS->getFlags() &&
711 BaseType == RHS->getRawBaseType() &&
712 BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
713 BoundsEqual(UpperBound, RHS->getRawUpperBound()) &&
714 BoundsEqual(Stride, RHS->getRawStride()) &&
715 BoundsEqual(Bias, RHS->getRawBias());
716 }
717
718 unsigned getHashValue() const {
719 unsigned val = 0;
720 auto HashBound = [&](Metadata *Node) -> void {
722 if (MD) {
724 val = hash_combine(val, CV->getSExtValue());
725 } else {
726 val = hash_combine(val, Node);
727 }
728 };
729
730 HashBound(LowerBound);
731 HashBound(UpperBound);
732 HashBound(Stride);
733 HashBound(Bias);
734
735 return hash_combine(val, Name, File, Line, Scope, BaseType, Flags);
736 }
737};
738
741
742 static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) {
743 return isODRMember(LHS.Tag, LHS.Scope, LHS.Name, RHS);
744 }
745
746 static bool isSubsetEqual(const DIDerivedType *LHS,
747 const DIDerivedType *RHS) {
748 return isODRMember(LHS->getTag(), LHS->getRawScope(), LHS->getRawName(),
749 RHS);
750 }
751
752 /// Subprograms compare equal if they declare the same function in an ODR
753 /// type.
754 static bool isODRMember(unsigned Tag, const Metadata *Scope,
755 const MDString *Name, const DIDerivedType *RHS) {
756 // Check whether the LHS is eligible.
757 if (Tag != dwarf::DW_TAG_member || !Name)
758 return false;
759
760 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
761 if (!CT || !CT->getRawIdentifier())
762 return false;
763
764 // Compare to the RHS.
765 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
766 Scope == RHS->getRawScope();
767 }
768};
769
770template <> struct MDNodeKeyImpl<DICompositeType> {
771 unsigned Tag;
774 unsigned Line;
780 unsigned Flags;
782 unsigned RuntimeLang;
795
816 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
817 Line(N->getLine()), Scope(N->getRawScope()),
818 BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
819 OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
820 Flags(N->getFlags()), Elements(N->getRawElements()),
821 RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()),
822 TemplateParams(N->getRawTemplateParams()),
823 Identifier(N->getRawIdentifier()),
824 Discriminator(N->getRawDiscriminator()),
825 DataLocation(N->getRawDataLocation()),
826 Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()),
827 Rank(N->getRawRank()), Annotations(N->getRawAnnotations()),
828 Specification(N->getSpecification()),
829 NumExtraInhabitants(N->getNumExtraInhabitants()),
830 BitStride(N->getRawBitStride()) {}
831
832 bool isKeyOf(const DICompositeType *RHS) const {
833 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
834 File == RHS->getRawFile() && Line == RHS->getLine() &&
835 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
836 SizeInBits == RHS->getRawSizeInBits() &&
837 AlignInBits == RHS->getAlignInBits() &&
838 OffsetInBits == RHS->getRawOffsetInBits() &&
839 Flags == RHS->getFlags() && Elements == RHS->getRawElements() &&
840 RuntimeLang == RHS->getRuntimeLang() &&
841 VTableHolder == RHS->getRawVTableHolder() &&
842 TemplateParams == RHS->getRawTemplateParams() &&
843 Identifier == RHS->getRawIdentifier() &&
844 Discriminator == RHS->getRawDiscriminator() &&
845 DataLocation == RHS->getRawDataLocation() &&
846 Associated == RHS->getRawAssociated() &&
847 Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() &&
848 Annotations == RHS->getRawAnnotations() &&
849 Specification == RHS->getSpecification() &&
850 NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
851 BitStride == RHS->getRawBitStride();
852 }
853
854 unsigned getHashValue() const {
855 // Intentionally computes the hash on a subset of the operands for
856 // performance reason. The subset has to be significant enough to avoid
857 // collision "most of the time". There is no correctness issue in case of
858 // collision because of the full check above.
861 }
862};
863
864template <> struct MDNodeKeyImpl<DISubroutineType> {
865 unsigned Flags;
868
872 : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()) {}
873
874 bool isKeyOf(const DISubroutineType *RHS) const {
875 return Flags == RHS->getFlags() && CC == RHS->getCC() &&
876 TypeArray == RHS->getRawTypeArray();
877 }
878
879 unsigned getHashValue() const { return hash_combine(Flags, CC, TypeArray); }
880};
881
882template <> struct MDNodeKeyImpl<DIFile> {
885 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum;
887
894 : Filename(N->getRawFilename()), Directory(N->getRawDirectory()),
895 Checksum(N->getRawChecksum()), Source(N->getRawSource()) {}
896
897 bool isKeyOf(const DIFile *RHS) const {
898 return Filename == RHS->getRawFilename() &&
899 Directory == RHS->getRawDirectory() &&
900 Checksum == RHS->getRawChecksum() && Source == RHS->getRawSource();
901 }
902
903 unsigned getHashValue() const {
904 return hash_combine(Filename, Directory, Checksum ? Checksum->Kind : 0,
905 Checksum ? Checksum->Value : nullptr, Source);
906 }
907};
908
909template <> struct MDNodeKeyImpl<DISubprogram> {
910 Metadata *Scope;
911 MDString *Name;
912 MDString *LinkageName;
913 Metadata *File;
914 unsigned Line;
915 unsigned ScopeLine;
916 Metadata *Type;
917 Metadata *ContainingType;
918 unsigned VirtualIndex;
919 int ThisAdjustment;
920 unsigned Flags;
921 unsigned SPFlags;
922 Metadata *Unit;
923 Metadata *TemplateParams;
924 Metadata *Declaration;
925 Metadata *RetainedNodes;
926 Metadata *ThrownTypes;
927 Metadata *Annotations;
928 MDString *TargetFuncName;
929 bool UsesKeyInstructions;
930
931 MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
932 Metadata *File, unsigned Line, Metadata *Type,
933 unsigned ScopeLine, Metadata *ContainingType,
934 unsigned VirtualIndex, int ThisAdjustment, unsigned Flags,
935 unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams,
936 Metadata *Declaration, Metadata *RetainedNodes,
937 Metadata *ThrownTypes, Metadata *Annotations,
938 MDString *TargetFuncName, bool UsesKeyInstructions)
939 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
940 Line(Line), ScopeLine(ScopeLine), Type(Type),
941 ContainingType(ContainingType), VirtualIndex(VirtualIndex),
942 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags),
943 Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration),
944 RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes),
945 Annotations(Annotations), TargetFuncName(TargetFuncName),
946 UsesKeyInstructions(UsesKeyInstructions) {}
947 MDNodeKeyImpl(const DISubprogram *N)
948 : Scope(N->getRawScope()), Name(N->getRawName()),
949 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
950 Line(N->getLine()), ScopeLine(N->getScopeLine()), Type(N->getRawType()),
951 ContainingType(N->getRawContainingType()),
952 VirtualIndex(N->getVirtualIndex()),
953 ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()),
954 SPFlags(N->getSPFlags()), Unit(N->getRawUnit()),
955 TemplateParams(N->getRawTemplateParams()),
956 Declaration(N->getRawDeclaration()),
957 RetainedNodes(N->getRawRetainedNodes()),
958 ThrownTypes(N->getRawThrownTypes()),
959 Annotations(N->getRawAnnotations()),
960 TargetFuncName(N->getRawTargetFuncName()),
961 UsesKeyInstructions(N->getKeyInstructionsEnabled()) {}
962
963 bool isKeyOf(const DISubprogram *RHS) const {
964 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
965 LinkageName == RHS->getRawLinkageName() &&
966 File == RHS->getRawFile() && Line == RHS->getLine() &&
967 Type == RHS->getRawType() && ScopeLine == RHS->getScopeLine() &&
968 ContainingType == RHS->getRawContainingType() &&
969 VirtualIndex == RHS->getVirtualIndex() &&
970 ThisAdjustment == RHS->getThisAdjustment() &&
971 Flags == RHS->getFlags() && SPFlags == RHS->getSPFlags() &&
972 Unit == RHS->getUnit() &&
973 TemplateParams == RHS->getRawTemplateParams() &&
974 Declaration == RHS->getRawDeclaration() &&
975 RetainedNodes == RHS->getRawRetainedNodes() &&
976 ThrownTypes == RHS->getRawThrownTypes() &&
977 Annotations == RHS->getRawAnnotations() &&
978 TargetFuncName == RHS->getRawTargetFuncName() &&
979 UsesKeyInstructions == RHS->getKeyInstructionsEnabled();
980 }
981
982 bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; }
983
984 unsigned getHashValue() const {
985 // Use the Scope's linkage name instead of using the scope directly, as the
986 // scope may be a temporary one which can replaced, which would produce a
987 // different hash for the same DISubprogram.
988 llvm::StringRef ScopeLinkageName;
989 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
990 if (auto *ID = CT->getRawIdentifier())
991 ScopeLinkageName = ID->getString();
992
993 // If this is a declaration inside an ODR type, only hash the type and the
994 // name. Otherwise the hash will be stronger than
995 // MDNodeSubsetEqualImpl::isDeclarationOfODRMember().
996 if (!isDefinition() && LinkageName &&
998 return hash_combine(LinkageName, ScopeLinkageName);
999
1000 // Intentionally computes the hash on a subset of the operands for
1001 // performance reason. The subset has to be significant enough to avoid
1002 // collision "most of the time". There is no correctness issue in case of
1003 // collision because of the full check above.
1004 return hash_combine(Name, ScopeLinkageName, File, Type, Line);
1005 }
1006};
1007
1010
1011 static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) {
1012 return isDeclarationOfODRMember(LHS.isDefinition(), LHS.Scope,
1013 LHS.LinkageName, LHS.TemplateParams, RHS);
1014 }
1015
1016 static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) {
1017 return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(),
1018 LHS->getRawLinkageName(),
1019 LHS->getRawTemplateParams(), RHS);
1020 }
1021
1022 /// Subprograms compare equal if they declare the same function in an ODR
1023 /// type.
1024 static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope,
1025 const MDString *LinkageName,
1026 const Metadata *TemplateParams,
1027 const DISubprogram *RHS) {
1028 // Check whether the LHS is eligible.
1029 if (IsDefinition || !Scope || !LinkageName)
1030 return false;
1031
1032 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
1033 if (!CT || !CT->getRawIdentifier())
1034 return false;
1035
1036 // Compare to the RHS.
1037 // FIXME: We need to compare template parameters here to avoid incorrect
1038 // collisions in mapMetadata when RF_ReuseAndMutateDistinctMDs and a
1039 // ODR-DISubprogram has a non-ODR template parameter (i.e., a
1040 // DICompositeType that does not have an identifier). Eventually we should
1041 // decouple ODR logic from uniquing logic.
1042 return IsDefinition == RHS->isDefinition() && Scope == RHS->getRawScope() &&
1043 LinkageName == RHS->getRawLinkageName() &&
1044 TemplateParams == RHS->getRawTemplateParams();
1045 }
1046};
1047
1048template <> struct MDNodeKeyImpl<DILexicalBlock> {
1051 unsigned Line;
1052 unsigned Column;
1053
1057 : Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()),
1058 Column(N->getColumn()) {}
1059
1060 bool isKeyOf(const DILexicalBlock *RHS) const {
1061 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
1062 Line == RHS->getLine() && Column == RHS->getColumn();
1063 }
1064
1065 unsigned getHashValue() const {
1066 return hash_combine(Scope, File, Line, Column);
1067 }
1068};
1069
1074
1078 : Scope(N->getRawScope()), File(N->getRawFile()),
1079 Discriminator(N->getDiscriminator()) {}
1080
1081 bool isKeyOf(const DILexicalBlockFile *RHS) const {
1082 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
1083 Discriminator == RHS->getDiscriminator();
1084 }
1085
1086 unsigned getHashValue() const {
1088 }
1089};
1090
1091template <> struct MDNodeKeyImpl<DINamespace> {
1095
1099 : Scope(N->getRawScope()), Name(N->getRawName()),
1100 ExportSymbols(N->getExportSymbols()) {}
1101
1102 bool isKeyOf(const DINamespace *RHS) const {
1103 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1104 ExportSymbols == RHS->getExportSymbols();
1105 }
1106
1107 unsigned getHashValue() const { return hash_combine(Scope, Name); }
1108};
1109
1110template <> struct MDNodeKeyImpl<DICommonBlock> {
1115 unsigned LineNo;
1116
1121 : Scope(N->getRawScope()), Decl(N->getRawDecl()), Name(N->getRawName()),
1122 File(N->getRawFile()), LineNo(N->getLineNo()) {}
1123
1124 bool isKeyOf(const DICommonBlock *RHS) const {
1125 return Scope == RHS->getRawScope() && Decl == RHS->getRawDecl() &&
1126 Name == RHS->getRawName() && File == RHS->getRawFile() &&
1127 LineNo == RHS->getLineNo();
1128 }
1129
1130 unsigned getHashValue() const {
1131 return hash_combine(Scope, Decl, Name, File, LineNo);
1132 }
1133};
1134
1135template <> struct MDNodeKeyImpl<DIModule> {
1142 unsigned LineNo;
1144
1152 : File(N->getRawFile()), Scope(N->getRawScope()), Name(N->getRawName()),
1153 ConfigurationMacros(N->getRawConfigurationMacros()),
1154 IncludePath(N->getRawIncludePath()),
1155 APINotesFile(N->getRawAPINotesFile()), LineNo(N->getLineNo()),
1156 IsDecl(N->getIsDecl()) {}
1157
1158 bool isKeyOf(const DIModule *RHS) const {
1159 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1160 ConfigurationMacros == RHS->getRawConfigurationMacros() &&
1161 IncludePath == RHS->getRawIncludePath() &&
1162 APINotesFile == RHS->getRawAPINotesFile() &&
1163 File == RHS->getRawFile() && LineNo == RHS->getLineNo() &&
1164 IsDecl == RHS->getIsDecl();
1165 }
1166
1167 unsigned getHashValue() const {
1169 }
1170};
1171
1176
1180 : Name(N->getRawName()), Type(N->getRawType()),
1181 IsDefault(N->isDefault()) {}
1182
1184 return Name == RHS->getRawName() && Type == RHS->getRawType() &&
1185 IsDefault == RHS->isDefault();
1186 }
1187
1188 unsigned getHashValue() const { return hash_combine(Name, Type, IsDefault); }
1189};
1190
1192 unsigned Tag;
1197
1202 : Tag(N->getTag()), Name(N->getRawName()), Type(N->getRawType()),
1203 IsDefault(N->isDefault()), Value(N->getValue()) {}
1204
1206 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
1207 Type == RHS->getRawType() && IsDefault == RHS->isDefault() &&
1208 Value == RHS->getValue();
1209 }
1210
1211 unsigned getHashValue() const {
1213 }
1214};
1215
1216template <> struct MDNodeKeyImpl<DIGlobalVariable> {
1221 unsigned Line;
1229
1242 : Scope(N->getRawScope()), Name(N->getRawName()),
1243 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
1244 Line(N->getLine()), Type(N->getRawType()),
1245 IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
1246 StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()),
1247 TemplateParams(N->getRawTemplateParams()),
1248 AlignInBits(N->getAlignInBits()), Annotations(N->getRawAnnotations()) {}
1249
1250 bool isKeyOf(const DIGlobalVariable *RHS) const {
1251 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1252 LinkageName == RHS->getRawLinkageName() &&
1253 File == RHS->getRawFile() && Line == RHS->getLine() &&
1254 Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() &&
1255 IsDefinition == RHS->isDefinition() &&
1257 RHS->getRawStaticDataMemberDeclaration() &&
1258 TemplateParams == RHS->getRawTemplateParams() &&
1259 AlignInBits == RHS->getAlignInBits() &&
1260 Annotations == RHS->getRawAnnotations();
1261 }
1262
1263 unsigned getHashValue() const {
1264 // We do not use AlignInBits in hashing function here on purpose:
1265 // in most cases this param for local variable is zero (for function param
1266 // it is always zero). This leads to lots of hash collisions and errors on
1267 // cases with lots of similar variables.
1268 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1269 // generated IR is random for each run and test fails with Align included.
1270 // TODO: make hashing work fine with such situations
1272 IsLocalToUnit, IsDefinition, /* AlignInBits, */
1274 }
1275};
1276
1277template <> struct MDNodeKeyImpl<DILocalVariable> {
1281 unsigned Line;
1283 unsigned Arg;
1284 unsigned Flags;
1287
1294 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1295 Line(N->getLine()), Type(N->getRawType()), Arg(N->getArg()),
1296 Flags(N->getFlags()), AlignInBits(N->getAlignInBits()),
1297 Annotations(N->getRawAnnotations()) {}
1298
1299 bool isKeyOf(const DILocalVariable *RHS) const {
1300 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1301 File == RHS->getRawFile() && Line == RHS->getLine() &&
1302 Type == RHS->getRawType() && Arg == RHS->getArg() &&
1303 Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits() &&
1304 Annotations == RHS->getRawAnnotations();
1305 }
1306
1307 unsigned getHashValue() const {
1308 // We do not use AlignInBits in hashing function here on purpose:
1309 // in most cases this param for local variable is zero (for function param
1310 // it is always zero). This leads to lots of hash collisions and errors on
1311 // cases with lots of similar variables.
1312 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1313 // generated IR is random for each run and test fails with Align included.
1314 // TODO: make hashing work fine with such situations
1316 }
1317};
1318
1319template <> struct MDNodeKeyImpl<DILabel> {
1323 unsigned Line;
1324 unsigned Column;
1326 std::optional<unsigned> CoroSuspendIdx;
1327
1334 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1335 Line(N->getLine()), Column(N->getColumn()),
1336 IsArtificial(N->isArtificial()),
1337 CoroSuspendIdx(N->getCoroSuspendIdx()) {}
1338
1339 bool isKeyOf(const DILabel *RHS) const {
1340 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1341 File == RHS->getRawFile() && Line == RHS->getLine() &&
1342 Column == RHS->getColumn() && IsArtificial == RHS->isArtificial() &&
1343 CoroSuspendIdx == RHS->getCoroSuspendIdx();
1344 }
1345
1346 /// Using name and line to get hash value. It should already be mostly unique.
1347 unsigned getHashValue() const {
1350 }
1351};
1352
1353template <> struct MDNodeKeyImpl<DIExpression> {
1355
1357 MDNodeKeyImpl(const DIExpression *N) : Elements(N->getElements()) {}
1358
1359 bool isKeyOf(const DIExpression *RHS) const {
1360 return Elements == RHS->getElements();
1361 }
1362
1363 unsigned getHashValue() const { return hash_combine_range(Elements); }
1364};
1365
1369
1373 : Variable(N->getRawVariable()), Expression(N->getRawExpression()) {}
1374
1376 return Variable == RHS->getRawVariable() &&
1377 Expression == RHS->getRawExpression();
1378 }
1379
1380 unsigned getHashValue() const { return hash_combine(Variable, Expression); }
1381};
1382
1383template <> struct MDNodeKeyImpl<DIObjCProperty> {
1386 unsigned Line;
1389 unsigned Attributes;
1391
1398 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
1399 GetterName(N->getRawGetterName()), SetterName(N->getRawSetterName()),
1400 Attributes(N->getAttributes()), Type(N->getRawType()) {}
1401
1402 bool isKeyOf(const DIObjCProperty *RHS) const {
1403 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
1404 Line == RHS->getLine() && GetterName == RHS->getRawGetterName() &&
1405 SetterName == RHS->getRawSetterName() &&
1406 Attributes == RHS->getAttributes() && Type == RHS->getRawType();
1407 }
1408
1409 unsigned getHashValue() const {
1411 Type);
1412 }
1413};
1414
1415template <> struct MDNodeKeyImpl<DIImportedEntity> {
1416 unsigned Tag;
1420 unsigned Line;
1423
1429 : Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()),
1430 File(N->getRawFile()), Line(N->getLine()), Name(N->getRawName()),
1431 Elements(N->getRawElements()) {}
1432
1433 bool isKeyOf(const DIImportedEntity *RHS) const {
1434 return Tag == RHS->getTag() && Scope == RHS->getRawScope() &&
1435 Entity == RHS->getRawEntity() && File == RHS->getFile() &&
1436 Line == RHS->getLine() && Name == RHS->getRawName() &&
1437 Elements == RHS->getRawElements();
1438 }
1439
1440 unsigned getHashValue() const {
1442 }
1443};
1444
1445template <> struct MDNodeKeyImpl<DIMacro> {
1446 unsigned MIType;
1447 unsigned Line;
1450
1454 : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getRawName()),
1455 Value(N->getRawValue()) {}
1456
1457 bool isKeyOf(const DIMacro *RHS) const {
1458 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1459 Name == RHS->getRawName() && Value == RHS->getRawValue();
1460 }
1461
1462 unsigned getHashValue() const {
1463 return hash_combine(MIType, Line, Name, Value);
1464 }
1465};
1466
1467template <> struct MDNodeKeyImpl<DIMacroFile> {
1468 unsigned MIType;
1469 unsigned Line;
1472
1477 : MIType(N->getMacinfoType()), Line(N->getLine()), File(N->getRawFile()),
1478 Elements(N->getRawElements()) {}
1479
1480 bool isKeyOf(const DIMacroFile *RHS) const {
1481 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1482 File == RHS->getRawFile() && Elements == RHS->getRawElements();
1483 }
1484
1485 unsigned getHashValue() const {
1487 }
1488};
1489
1490// DIArgLists are not MDNodes, but we still want to unique them in a DenseSet
1491// based on a hash of their arguments.
1494
1496 DIArgListKeyInfo(const DIArgList *N) : Args(N->getArgs()) {}
1497
1498 bool isKeyOf(const DIArgList *RHS) const { return Args == RHS->getArgs(); }
1499
1500 unsigned getHashValue() const { return hash_combine_range(Args); }
1501};
1502
1503/// DenseMapInfo for DIArgList.
1506
1507 static inline DIArgList *getEmptyKey() {
1509 }
1510
1514
1515 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1516
1517 static unsigned getHashValue(const DIArgList *N) {
1518 return KeyTy(N).getHashValue();
1519 }
1520
1521 static bool isEqual(const KeyTy &LHS, const DIArgList *RHS) {
1522 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1523 return false;
1524 return LHS.isKeyOf(RHS);
1525 }
1526
1527 static bool isEqual(const DIArgList *LHS, const DIArgList *RHS) {
1528 return LHS == RHS;
1529 }
1530};
1531
1532/// DenseMapInfo for MDNode subclasses.
1533template <class NodeTy> struct MDNodeInfo {
1536
1537 static inline NodeTy *getEmptyKey() {
1539 }
1540
1541 static inline NodeTy *getTombstoneKey() {
1543 }
1544
1545 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1546
1547 static unsigned getHashValue(const NodeTy *N) {
1548 return KeyTy(N).getHashValue();
1549 }
1550
1551 static bool isEqual(const KeyTy &LHS, const NodeTy *RHS) {
1552 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1553 return false;
1554 return SubsetEqualTy::isSubsetEqual(LHS, RHS) || LHS.isKeyOf(RHS);
1555 }
1556
1557 static bool isEqual(const NodeTy *LHS, const NodeTy *RHS) {
1558 if (LHS == RHS)
1559 return true;
1560 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1561 return false;
1563 }
1564};
1565
1566#define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>;
1567#include "llvm/IR/Metadata.def"
1568
1569/// Multimap-like storage for metadata attachments.
1571public:
1576
1577private:
1578 SmallVector<Attachment, 1> Attachments;
1579
1580public:
1581 bool empty() const { return Attachments.empty(); }
1582 size_t size() const { return Attachments.size(); }
1583
1584 /// Returns the first attachment with the given ID or nullptr if no such
1585 /// attachment exists.
1586 MDNode *lookup(unsigned ID) const;
1587
1588 /// Appends all attachments with the given ID to \c Result in insertion order.
1589 /// If the global has no attachments with the given ID, or if ID is invalid,
1590 /// leaves Result unchanged.
1591 void get(unsigned ID, SmallVectorImpl<MDNode *> &Result) const;
1592
1593 /// Appends all attachments for the global to \c Result, sorting by attachment
1594 /// ID. Attachments with the same ID appear in insertion order. This function
1595 /// does \em not clear \c Result.
1596 void getAll(SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const;
1597
1598 /// Set an attachment to a particular node.
1599 ///
1600 /// Set the \c ID attachment to \c MD, replacing the current attachments at \c
1601 /// ID (if anyway).
1602 void set(unsigned ID, MDNode *MD);
1603
1604 /// Adds an attachment to a particular node.
1605 void insert(unsigned ID, MDNode &MD);
1606
1607 /// Remove attachments with the given ID.
1608 ///
1609 /// Remove the attachments at \c ID, if any.
1610 bool erase(unsigned ID);
1611
1612 /// Erase matching attachments.
1613 ///
1614 /// Erases all attachments matching the \c shouldRemove predicate.
1615 template <class PredTy> void remove_if(PredTy shouldRemove) {
1616 llvm::erase_if(Attachments, shouldRemove);
1617 }
1618};
1619
1621public:
1622 /// OwnedModules - The set of modules instantiated in this context, and which
1623 /// will be automatically deleted if this context is deleted.
1625
1626 /// MachineFunctionNums - Keep the next available unique number available for
1627 /// a MachineFunction in given module. Module must in OwnedModules.
1629
1630 /// The main remark streamer used by all the other streamers (e.g. IR, MIR,
1631 /// frontends, etc.). This should only be used by the specific streamers, and
1632 /// never directly.
1633 std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer;
1634
1635 std::unique_ptr<DiagnosticHandler> DiagHandler;
1638 /// The minimum hotness value a diagnostic needs in order to be included in
1639 /// optimization diagnostics.
1640 ///
1641 /// The threshold is an Optional value, which maps to one of the 3 states:
1642 /// 1). 0 => threshold disabled. All emarks will be printed.
1643 /// 2). positive int => manual threshold by user. Remarks with hotness exceed
1644 /// threshold will be printed.
1645 /// 3). None => 'auto' threshold by user. The actual value is not
1646 /// available at command line, but will be synced with
1647 /// hotness threhold from profile summary during
1648 /// compilation.
1649 ///
1650 /// State 1 and 2 are considered as terminal states. State transition is
1651 /// only allowed from 3 to 2, when the threshold is first synced with profile
1652 /// summary. This ensures that the threshold is set only once and stays
1653 /// constant.
1654 ///
1655 /// If threshold option is not specified, it is disabled (0) by default.
1656 std::optional<uint64_t> DiagnosticsHotnessThreshold = 0;
1657
1658 /// The percentage of difference between profiling branch weights and
1659 /// llvm.expect branch weights to tolerate when emiting MisExpect diagnostics
1660 std::optional<uint32_t> DiagnosticsMisExpectTolerance = 0;
1662
1663 /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
1664 std::unique_ptr<LLVMRemarkStreamer> LLVMRS;
1665
1667 void *YieldOpaqueHandle = nullptr;
1668
1670
1674 DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantInt>>
1676
1678 DenseMap<std::pair<ElementCount, APFloat>, std::unique_ptr<ConstantFP>>
1680
1684
1689
1690#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
1691 DenseSet<CLASS *, CLASS##Info> CLASS##s;
1692#include "llvm/IR/Metadata.def"
1693
1694 // Optional map for looking up composite types by identifier.
1695 std::optional<DenseMap<const MDString *, DICompositeType *>> DITypeMap;
1696
1697 // MDNodes may be uniqued or not uniqued. When they're not uniqued, they
1698 // aren't in the MDNodeSet, but they're still shared between objects, so no
1699 // one object can destroy them. Keep track of them here so we can delete
1700 // them on context teardown.
1701 std::vector<MDNode *> DistinctMDNodes;
1702
1703 // ConstantRangeListAttributeImpl is a TrailingObjects/ArrayRef of
1704 // ConstantRange. Since this is a dynamically sized class, it's not
1705 // possible to use SpecificBumpPtrAllocator. Instead, we use normal Alloc
1706 // for allocation and record all allocated pointers in this vector. In the
1707 // LLVMContext destructor, call the destuctors of everything in the vector.
1708 std::vector<ConstantRangeListAttributeImpl *> ConstantRangeListAttributes;
1709
1711
1714
1717
1720
1722
1724
1726
1728
1730
1732
1734
1736
1738
1740
1742
1745
1746 // Basic type instances.
1751
1752 std::unique_ptr<ConstantTokenNone> TheNoneToken;
1753
1758
1760
1767
1770
1773 PointerType *AS0PointerType = nullptr; // AddrSpace = 0
1776
1777 /// ValueHandles - This map keeps track of all of the value handles that are
1778 /// watching a Value*. The Value::HasValueHandle bit is used to know
1779 /// whether or not a value has an entry in this map.
1782
1783 /// CustomMDKindNames - Map to hold the metadata string to ID mapping.
1785
1786 /// Collection of metadata used in this context.
1788
1789 /// Map DIAssignID -> Instructions with that attachment.
1790 /// Managed by Instruction via Instruction::updateDIAssignIDMapping.
1791 /// Query using the at:: functions defined in DebugInfo.h.
1793
1794 /// Collection of per-GlobalObject sections used in this context.
1796
1797 /// Collection of per-GlobalValue partitions used in this context.
1799
1802
1803 /// DiscriminatorTable - This table maps file:line locations to an
1804 /// integer representing the next DWARF path discriminator to assign to
1805 /// instructions in different blocks at the same location.
1807
1808 /// A set of interned tags for operand bundles. The StringMap maps
1809 /// bundle tags to their IDs.
1810 ///
1811 /// \see LLVMContext::getOperandBundleTagID
1813
1817
1818 /// A set of interned synchronization scopes. The StringMap maps
1819 /// synchronization scope names to their respective synchronization scope IDs.
1821
1822 /// getOrInsertSyncScopeID - Maps synchronization scope name to
1823 /// synchronization scope ID. Every synchronization scope registered with
1824 /// LLVMContext has unique ID except pre-defined ones.
1826
1827 /// getSyncScopeNames - Populates client supplied SmallVector with
1828 /// synchronization scope names registered with LLVMContext. Synchronization
1829 /// scope names are ordered by increasing synchronization scope IDs.
1831
1832 /// getSyncScopeName - Returns the name of a SyncScope::ID
1833 /// registered with LLVMContext, if any.
1834 std::optional<StringRef> getSyncScopeName(SyncScope::ID Id) const;
1835
1836 /// Maintain the GC name for each function.
1837 ///
1838 /// This saves allocating an additional word in Function for programs which
1839 /// do not use GC (i.e., most programs) at the cost of increased overhead for
1840 /// clients which do use GC.
1842
1843 /// Flag to indicate if Value (other than GlobalValue) retains their name or
1844 /// not.
1845 bool DiscardValueNames = false;
1846
1849
1850 mutable OptPassGate *OPG = nullptr;
1851
1852 /// Access the object which can disable optional passes and individual
1853 /// optimizations at compile time.
1854 OptPassGate &getOptPassGate() const;
1855
1856 /// Set the object which can disable optional passes and individual
1857 /// optimizations at compile time.
1858 ///
1859 /// The lifetime of the object must be guaranteed to extend as long as the
1860 /// LLVMContext is used by compilation.
1862
1863 /// Mapping of blocks to collections of "trailing" DbgVariableRecords. As part
1864 /// of the "RemoveDIs" project, debug-info variable location records are going
1865 /// to cease being instructions... which raises the problem of where should
1866 /// they be recorded when we remove the terminator of a blocks, such as:
1867 ///
1868 /// %foo = add i32 0, 0
1869 /// br label %bar
1870 ///
1871 /// If the branch is removed, a legitimate transient state while editing a
1872 /// block, any debug-records between those two instructions will not have a
1873 /// location. Each block thus records any DbgVariableRecord records that
1874 /// "trail" in such a way. These are stored in LLVMContext because typically
1875 /// LLVM only edits a small number of blocks at a time, so there's no need to
1876 /// bloat BasicBlock with such a data structure.
1878
1879 // Set, get and delete operations for TrailingDbgRecords.
1884
1888
1890
1891 std::string DefaultTargetCPU;
1893
1894 /// The next available source atom group number. The front end is responsible
1895 /// for assigning source atom numbers, but certain optimisations need to
1896 /// assign new group numbers to a set of instructions. Most often code
1897 /// duplication optimisations like loop unroll. Tracking a global maximum
1898 /// value means we can know (cheaply) we're never using a group number that's
1899 /// already used within this function.
1900 ///
1901 /// Start a 1 because 0 means the source location isn't part of an atom group.
1903};
1904
1905} // end namespace llvm
1906
1907#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:41
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
Constant * getValue() const
Definition Metadata.h:544
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:169
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:535
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
ConstantUniqueMap< ConstantArray > ArrayConstantsTy
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*.
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
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< const Value *, MDAttachments > ValueMetadata
Collection of metadata used in this context.
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
LLVMContext::YieldCallbackTy YieldCallback
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
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
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.
Multimap-like storage for metadata attachments.
void insert(unsigned ID, MDNode &MD)
Adds an attachment to a particular node.
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.
void getAll(SmallVectorImpl< std::pair< unsigned, MDNode * > > &Result) const
Appends all attachments for the global to Result, sorting by attachment ID.
void set(unsigned ID, MDNode *MD)
Set an attachment to a particular node.
MDNode * lookup(unsigned ID) const
Returns the first attachment with the given ID or nullptr if no such attachment exists.
bool erase(unsigned ID)
Remove attachments with the given ID.
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:1078
A single uniqued string.
Definition Metadata.h:721
Tuple of metadata.
Definition Metadata.h:1497
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: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: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:477
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
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383
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:1867
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
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:2120
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition Hashing.h:592
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:867
#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()
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()
bool isKeyOf(const DIBasicType *RHS) const
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *SizeInBits, uint32_t AlignInBits, unsigned Encoding, uint32_t NumExtraInhabitants, uint32_t DataSizeInBits, unsigned Flags)
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 *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()