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 uint64_t LineColumnAndImplicitCode =
343 Line | (uint64_t(Column) << 32) | (uint64_t(ImplicitCode) << 48);
344 // Hashing AtomGroup and AtomRank substantially impacts performance whether
345 // Key Instructions is enabled or not. We can't detect whether it's enabled
346 // here cheaply; avoiding hashing zero values is a good approximation. This
347 // affects Key Instruction builds too, but any potential costs incurred by
348 // messing with the hash distribution* appear to still be massively
349 // outweighed by the overall compile time savings by performing this check.
350 // * (hash_combine(x) != hash_combine(x, 0))
351 if (AtomGroup || AtomRank)
352 return hash_combine(LineColumnAndImplicitCode, Scope, InlinedAt,
353 AtomGroup | (uint64_t(AtomRank) << 61));
354 return hash_combine(LineColumnAndImplicitCode, Scope, InlinedAt);
355 }
356};
357
358/// DenseMapInfo for GenericDINode.
360 unsigned Tag;
362
364 : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {}
366 : MDNodeOpsKey(N, 1), Tag(N->getTag()), Header(N->getRawHeader()) {}
367
368 bool isKeyOf(const GenericDINode *RHS) const {
369 return Tag == RHS->getTag() && Header == RHS->getRawHeader() &&
370 compareOps(RHS, 1);
371 }
372
373 unsigned getHashValue() const { return hash_combine(getHash(), Tag, Header); }
374
375 static unsigned calculateHash(GenericDINode *N) {
377 }
378};
379
380template <> struct MDNodeKeyImpl<DISubrange> {
385
391 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
392 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
393
394 bool isKeyOf(const DISubrange *RHS) const {
395 auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool {
396 if (Node1 == Node2)
397 return true;
398
401 if (MD1 && MD2) {
404 if (CV1->getSExtValue() == CV2->getSExtValue())
405 return true;
406 }
407 return false;
408 };
409
410 return BoundsEqual(CountNode, RHS->getRawCountNode()) &&
411 BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
412 BoundsEqual(UpperBound, RHS->getRawUpperBound()) &&
413 BoundsEqual(Stride, RHS->getRawStride());
414 }
415
416 unsigned getHashValue() const {
417 if (CountNode)
419 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
422 }
423};
424
425template <> struct MDNodeKeyImpl<DIGenericSubrange> {
430
436 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
437 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
438
439 bool isKeyOf(const DIGenericSubrange *RHS) const {
440 return (CountNode == RHS->getRawCountNode()) &&
441 (LowerBound == RHS->getRawLowerBound()) &&
442 (UpperBound == RHS->getRawUpperBound()) &&
443 (Stride == RHS->getRawStride());
444 }
445
446 unsigned getHashValue() const {
448 if (CountNode && MD)
449 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
452 }
453};
454
455template <> struct MDNodeKeyImpl<DIEnumerator> {
459
466 : Value(N->getValue()), Name(N->getRawName()),
467 IsUnsigned(N->isUnsigned()) {}
468
469 bool isKeyOf(const DIEnumerator *RHS) const {
470 return Value.getBitWidth() == RHS->getValue().getBitWidth() &&
471 Value == RHS->getValue() && IsUnsigned == RHS->isUnsigned() &&
472 Name == RHS->getRawName();
473 }
474
475 unsigned getHashValue() const { return hash_combine(Value, Name); }
476};
477
478template <> struct MDNodeKeyImpl<DIBasicType> {
479 unsigned Tag;
482 unsigned LineNo;
486 unsigned Encoding;
489 unsigned Flags;
490
500 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
501 LineNo(N->getLine()), Scope(N->getRawScope()),
502 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
503 Encoding(N->getEncoding()),
504 NumExtraInhabitants(N->getNumExtraInhabitants()),
505 DataSizeInBits(N->getDataSizeInBits()), Flags(N->getFlags()) {}
506
507 bool isKeyOf(const DIBasicType *RHS) const {
508 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
509 File == RHS->getRawFile() && LineNo == RHS->getLine() &&
510 Scope == RHS->getRawScope() &&
511 SizeInBits == RHS->getRawSizeInBits() &&
512 AlignInBits == RHS->getAlignInBits() &&
513 Encoding == RHS->getEncoding() &&
514 NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
515 DataSizeInBits == RHS->getDataSizeInBits() &&
516 Flags == RHS->getFlags();
517 }
518
519 unsigned getHashValue() const {
521 Encoding);
522 }
523};
524
525template <> struct MDNodeKeyImpl<DIFixedPointType> {
526 unsigned Tag;
529 unsigned LineNo;
533 unsigned Encoding;
534 unsigned Flags;
535 unsigned Kind;
539
549 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
550 LineNo(N->getLine()), Scope(N->getRawScope()),
551 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
552 Encoding(N->getEncoding()), Flags(N->getFlags()), Kind(N->getKind()),
553 Factor(N->getFactorRaw()), Numerator(N->getNumeratorRaw()),
554 Denominator(N->getDenominatorRaw()) {}
555
556 bool isKeyOf(const DIFixedPointType *RHS) const {
557 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
558 LineNo == RHS->getLine() && Scope == RHS->getRawScope() &&
559 SizeInBits == RHS->getRawSizeInBits() &&
560 AlignInBits == RHS->getAlignInBits() && Kind == RHS->getKind() &&
561 (RHS->isRational() ? (Numerator == RHS->getNumerator() &&
562 Denominator == RHS->getDenominator())
563 : Factor == RHS->getFactor());
564 }
565
566 unsigned getHashValue() const {
569 }
570};
571
572template <> struct MDNodeKeyImpl<DIStringType> {
573 unsigned Tag;
580 unsigned Encoding;
581
589 : Tag(N->getTag()), Name(N->getRawName()),
590 StringLength(N->getRawStringLength()),
591 StringLengthExp(N->getRawStringLengthExp()),
592 StringLocationExp(N->getRawStringLocationExp()),
593 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
594 Encoding(N->getEncoding()) {}
595
596 bool isKeyOf(const DIStringType *RHS) const {
597 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
598 StringLength == RHS->getRawStringLength() &&
599 StringLengthExp == RHS->getRawStringLengthExp() &&
600 StringLocationExp == RHS->getRawStringLocationExp() &&
601 SizeInBits == RHS->getRawSizeInBits() &&
602 AlignInBits == RHS->getAlignInBits() &&
603 Encoding == RHS->getEncoding();
604 }
605 unsigned getHashValue() const {
606 // Intentionally computes the hash on a subset of the operands for
607 // performance reason. The subset has to be significant enough to avoid
608 // collision "most of the time". There is no correctness issue in case of
609 // collision because of the full check above.
611 }
612};
613
614template <> struct MDNodeKeyImpl<DIDerivedType> {
615 unsigned Tag;
616 MDString *Name;
617 Metadata *File;
618 unsigned Line;
619 Metadata *Scope;
621 Metadata *SizeInBits;
622 Metadata *OffsetInBits;
623 uint32_t AlignInBits;
624 std::optional<unsigned> DWARFAddressSpace;
625 std::optional<DIDerivedType::PtrAuthData> PtrAuthData;
626 unsigned Flags;
628 Metadata *Annotations;
629
630 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
631 Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
632 uint32_t AlignInBits, Metadata *OffsetInBits,
633 std::optional<unsigned> DWARFAddressSpace,
634 std::optional<DIDerivedType::PtrAuthData> PtrAuthData,
635 unsigned Flags, Metadata *ExtraData, Metadata *Annotations)
636 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
637 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
638 AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace),
639 PtrAuthData(PtrAuthData), Flags(Flags), ExtraData(ExtraData),
640 Annotations(Annotations) {}
641 MDNodeKeyImpl(const DIDerivedType *N)
642 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
643 Line(N->getLine()), Scope(N->getRawScope()),
644 BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
645 OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
646 DWARFAddressSpace(N->getDWARFAddressSpace()),
647 PtrAuthData(N->getPtrAuthData()), Flags(N->getFlags()),
648 ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {}
649
650 bool isKeyOf(const DIDerivedType *RHS) const {
651 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
652 File == RHS->getRawFile() && Line == RHS->getLine() &&
653 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
654 SizeInBits == RHS->getRawSizeInBits() &&
655 AlignInBits == RHS->getAlignInBits() &&
656 OffsetInBits == RHS->getRawOffsetInBits() &&
657 DWARFAddressSpace == RHS->getDWARFAddressSpace() &&
658 PtrAuthData == RHS->getPtrAuthData() && Flags == RHS->getFlags() &&
659 ExtraData == RHS->getRawExtraData() &&
660 Annotations == RHS->getRawAnnotations();
661 }
662
663 unsigned getHashValue() const {
664 // If this is a member inside an ODR type, only hash the type and the name.
665 // Otherwise the hash will be stronger than
666 // MDNodeSubsetEqualImpl::isODRMember().
667 if (Tag == dwarf::DW_TAG_member && Name)
668 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
669 if (CT->getRawIdentifier())
670 return hash_combine(Name, Scope);
671
672 // Intentionally computes the hash on a subset of the operands for
673 // performance reason. The subset has to be significant enough to avoid
674 // collision "most of the time". There is no correctness issue in case of
675 // collision because of the full check above.
676 return hash_combine(Tag, Name, File, Line, Scope, BaseType, Flags);
677 }
678};
679
680template <> struct MDNodeKeyImpl<DISubrangeType> {
683 unsigned Line;
687 unsigned Flags;
693
703 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
704 Scope(N->getRawScope()), SizeInBits(N->getRawSizeInBits()),
705 AlignInBits(N->getAlignInBits()), Flags(N->getFlags()),
706 BaseType(N->getRawBaseType()), LowerBound(N->getRawLowerBound()),
707 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()),
708 Bias(N->getRawBias()) {}
709
710 bool isKeyOf(const DISubrangeType *RHS) const {
711 auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool {
712 if (Node1 == Node2)
713 return true;
714
717 if (MD1 && MD2) {
720 if (CV1->getSExtValue() == CV2->getSExtValue())
721 return true;
722 }
723 return false;
724 };
725
726 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
727 Line == RHS->getLine() && Scope == RHS->getRawScope() &&
728 SizeInBits == RHS->getRawSizeInBits() &&
729 AlignInBits == RHS->getAlignInBits() && Flags == RHS->getFlags() &&
730 BaseType == RHS->getRawBaseType() &&
731 BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
732 BoundsEqual(UpperBound, RHS->getRawUpperBound()) &&
733 BoundsEqual(Stride, RHS->getRawStride()) &&
734 BoundsEqual(Bias, RHS->getRawBias());
735 }
736
737 unsigned getHashValue() const {
738 unsigned val = 0;
739 auto HashBound = [&](Metadata *Node) -> void {
741 if (MD) {
743 val = hash_combine(val, CV->getSExtValue());
744 } else {
745 val = hash_combine(val, Node);
746 }
747 };
748
749 HashBound(LowerBound);
750 HashBound(UpperBound);
751 HashBound(Stride);
752 HashBound(Bias);
753
754 return hash_combine(val, Name, File, Line, Scope, BaseType, Flags);
755 }
756};
757
760
761 static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) {
762 return isODRMember(LHS.Tag, LHS.Scope, LHS.Name, RHS);
763 }
764
765 static bool isSubsetEqual(const DIDerivedType *LHS,
766 const DIDerivedType *RHS) {
767 return isODRMember(LHS->getTag(), LHS->getRawScope(), LHS->getRawName(),
768 RHS);
769 }
770
771 /// Subprograms compare equal if they declare the same function in an ODR
772 /// type.
773 static bool isODRMember(unsigned Tag, const Metadata *Scope,
774 const MDString *Name, const DIDerivedType *RHS) {
775 // Check whether the LHS is eligible.
776 if (Tag != dwarf::DW_TAG_member || !Name)
777 return false;
778
779 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
780 if (!CT || !CT->getRawIdentifier())
781 return false;
782
783 // Compare to the RHS.
784 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
785 Scope == RHS->getRawScope();
786 }
787};
788
789template <> struct MDNodeKeyImpl<DICompositeType> {
790 unsigned Tag;
793 unsigned Line;
799 unsigned Flags;
801 unsigned RuntimeLang;
814
835 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
836 Line(N->getLine()), Scope(N->getRawScope()),
837 BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
838 OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
839 Flags(N->getFlags()), Elements(N->getRawElements()),
840 RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()),
841 TemplateParams(N->getRawTemplateParams()),
842 Identifier(N->getRawIdentifier()),
843 Discriminator(N->getRawDiscriminator()),
844 DataLocation(N->getRawDataLocation()),
845 Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()),
846 Rank(N->getRawRank()), Annotations(N->getRawAnnotations()),
847 Specification(N->getSpecification()),
848 NumExtraInhabitants(N->getNumExtraInhabitants()),
849 BitStride(N->getRawBitStride()) {}
850
851 bool isKeyOf(const DICompositeType *RHS) const {
852 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
853 File == RHS->getRawFile() && Line == RHS->getLine() &&
854 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
855 SizeInBits == RHS->getRawSizeInBits() &&
856 AlignInBits == RHS->getAlignInBits() &&
857 OffsetInBits == RHS->getRawOffsetInBits() &&
858 Flags == RHS->getFlags() && Elements == RHS->getRawElements() &&
859 RuntimeLang == RHS->getRuntimeLang() &&
860 VTableHolder == RHS->getRawVTableHolder() &&
861 TemplateParams == RHS->getRawTemplateParams() &&
862 Identifier == RHS->getRawIdentifier() &&
863 Discriminator == RHS->getRawDiscriminator() &&
864 DataLocation == RHS->getRawDataLocation() &&
865 Associated == RHS->getRawAssociated() &&
866 Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() &&
867 Annotations == RHS->getRawAnnotations() &&
868 Specification == RHS->getSpecification() &&
869 NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
870 BitStride == RHS->getRawBitStride();
871 }
872
873 unsigned getHashValue() const {
874 // Intentionally computes the hash on a subset of the operands for
875 // performance reason. The subset has to be significant enough to avoid
876 // collision "most of the time". There is no correctness issue in case of
877 // collision because of the full check above.
880 }
881};
882
883template <> struct MDNodeKeyImpl<DISubroutineType> {
884 unsigned Flags;
887
891 : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()) {}
892
893 bool isKeyOf(const DISubroutineType *RHS) const {
894 return Flags == RHS->getFlags() && CC == RHS->getCC() &&
895 TypeArray == RHS->getRawTypeArray();
896 }
897
898 unsigned getHashValue() const { return hash_combine(Flags, CC, TypeArray); }
899};
900
901template <> struct MDNodeKeyImpl<DIFile> {
904 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum;
906
913 : Filename(N->getRawFilename()), Directory(N->getRawDirectory()),
914 Checksum(N->getRawChecksum()), Source(N->getRawSource()) {}
915
916 bool isKeyOf(const DIFile *RHS) const {
917 return Filename == RHS->getRawFilename() &&
918 Directory == RHS->getRawDirectory() &&
919 Checksum == RHS->getRawChecksum() && Source == RHS->getRawSource();
920 }
921
922 unsigned getHashValue() const {
923 return hash_combine(Filename, Directory, Checksum ? Checksum->Kind : 0,
924 Checksum ? Checksum->Value : nullptr, Source);
925 }
926};
927
928template <> struct MDNodeKeyImpl<DISubprogram> {
929 Metadata *Scope;
930 MDString *Name;
931 MDString *LinkageName;
932 Metadata *File;
933 unsigned Line;
934 unsigned ScopeLine;
935 Metadata *Type;
936 Metadata *ContainingType;
937 unsigned VirtualIndex;
938 int ThisAdjustment;
939 unsigned Flags;
940 unsigned SPFlags;
941 Metadata *Unit;
942 Metadata *TemplateParams;
943 Metadata *Declaration;
944 Metadata *RetainedNodes;
945 Metadata *ThrownTypes;
946 Metadata *Annotations;
947 MDString *TargetFuncName;
948 bool UsesKeyInstructions;
949
950 MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
951 Metadata *File, unsigned Line, Metadata *Type,
952 unsigned ScopeLine, Metadata *ContainingType,
953 unsigned VirtualIndex, int ThisAdjustment, unsigned Flags,
954 unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams,
955 Metadata *Declaration, Metadata *RetainedNodes,
956 Metadata *ThrownTypes, Metadata *Annotations,
957 MDString *TargetFuncName, bool UsesKeyInstructions)
958 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
959 Line(Line), ScopeLine(ScopeLine), Type(Type),
960 ContainingType(ContainingType), VirtualIndex(VirtualIndex),
961 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags),
962 Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration),
963 RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes),
964 Annotations(Annotations), TargetFuncName(TargetFuncName),
965 UsesKeyInstructions(UsesKeyInstructions) {}
966 MDNodeKeyImpl(const DISubprogram *N)
967 : Scope(N->getRawScope()), Name(N->getRawName()),
968 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
969 Line(N->getLine()), ScopeLine(N->getScopeLine()), Type(N->getRawType()),
970 ContainingType(N->getRawContainingType()),
971 VirtualIndex(N->getVirtualIndex()),
972 ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()),
973 SPFlags(N->getSPFlags()), Unit(N->getRawUnit()),
974 TemplateParams(N->getRawTemplateParams()),
975 Declaration(N->getRawDeclaration()),
976 RetainedNodes(N->getRawRetainedNodes()),
977 ThrownTypes(N->getRawThrownTypes()),
978 Annotations(N->getRawAnnotations()),
979 TargetFuncName(N->getRawTargetFuncName()),
980 UsesKeyInstructions(N->getKeyInstructionsEnabled()) {}
981
982 bool isKeyOf(const DISubprogram *RHS) const {
983 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
984 LinkageName == RHS->getRawLinkageName() &&
985 File == RHS->getRawFile() && Line == RHS->getLine() &&
986 Type == RHS->getRawType() && ScopeLine == RHS->getScopeLine() &&
987 ContainingType == RHS->getRawContainingType() &&
988 VirtualIndex == RHS->getVirtualIndex() &&
989 ThisAdjustment == RHS->getThisAdjustment() &&
990 Flags == RHS->getFlags() && SPFlags == RHS->getSPFlags() &&
991 Unit == RHS->getUnit() &&
992 TemplateParams == RHS->getRawTemplateParams() &&
993 Declaration == RHS->getRawDeclaration() &&
994 RetainedNodes == RHS->getRawRetainedNodes() &&
995 ThrownTypes == RHS->getRawThrownTypes() &&
996 Annotations == RHS->getRawAnnotations() &&
997 TargetFuncName == RHS->getRawTargetFuncName() &&
998 UsesKeyInstructions == RHS->getKeyInstructionsEnabled();
999 }
1000
1001 bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; }
1002
1003 unsigned getHashValue() const {
1004 // Use the Scope's linkage name instead of using the scope directly, as the
1005 // scope may be a temporary one which can replaced, which would produce a
1006 // different hash for the same DISubprogram.
1007 llvm::StringRef ScopeLinkageName;
1008 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
1009 if (auto *ID = CT->getRawIdentifier())
1010 ScopeLinkageName = ID->getString();
1011
1012 // If this is a declaration inside an ODR type, only hash the type and the
1013 // name. Otherwise the hash will be stronger than
1014 // MDNodeSubsetEqualImpl::isDeclarationOfODRMember().
1015 if (!isDefinition() && LinkageName &&
1017 return hash_combine(LinkageName, ScopeLinkageName);
1018
1019 // Intentionally computes the hash on a subset of the operands for
1020 // performance reason. The subset has to be significant enough to avoid
1021 // collision "most of the time". There is no correctness issue in case of
1022 // collision because of the full check above.
1023 return hash_combine(Name, ScopeLinkageName, File, Type, Line);
1024 }
1025};
1026
1029
1030 static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) {
1031 return isDeclarationOfODRMember(LHS.isDefinition(), LHS.Scope,
1032 LHS.LinkageName, LHS.TemplateParams, RHS);
1033 }
1034
1035 static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) {
1036 return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(),
1037 LHS->getRawLinkageName(),
1038 LHS->getRawTemplateParams(), RHS);
1039 }
1040
1041 /// Subprograms compare equal if they declare the same function in an ODR
1042 /// type.
1043 static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope,
1044 const MDString *LinkageName,
1045 const Metadata *TemplateParams,
1046 const DISubprogram *RHS) {
1047 // Check whether the LHS is eligible.
1048 if (IsDefinition || !Scope || !LinkageName)
1049 return false;
1050
1051 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
1052 if (!CT || !CT->getRawIdentifier())
1053 return false;
1054
1055 // Compare to the RHS.
1056 // FIXME: We need to compare template parameters here to avoid incorrect
1057 // collisions in mapMetadata when RF_ReuseAndMutateDistinctMDs and a
1058 // ODR-DISubprogram has a non-ODR template parameter (i.e., a
1059 // DICompositeType that does not have an identifier). Eventually we should
1060 // decouple ODR logic from uniquing logic.
1061 return IsDefinition == RHS->isDefinition() && Scope == RHS->getRawScope() &&
1062 LinkageName == RHS->getRawLinkageName() &&
1063 TemplateParams == RHS->getRawTemplateParams();
1064 }
1065};
1066
1067template <> struct MDNodeKeyImpl<DILexicalBlock> {
1070 unsigned Line;
1071 unsigned Column;
1072
1076 : Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()),
1077 Column(N->getColumn()) {}
1078
1079 bool isKeyOf(const DILexicalBlock *RHS) const {
1080 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
1081 Line == RHS->getLine() && Column == RHS->getColumn();
1082 }
1083
1084 unsigned getHashValue() const {
1085 return hash_combine(Scope, File, Line, Column);
1086 }
1087};
1088
1093
1097 : Scope(N->getRawScope()), File(N->getRawFile()),
1098 Discriminator(N->getDiscriminator()) {}
1099
1100 bool isKeyOf(const DILexicalBlockFile *RHS) const {
1101 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
1102 Discriminator == RHS->getDiscriminator();
1103 }
1104
1105 unsigned getHashValue() const {
1107 }
1108};
1109
1110template <> struct MDNodeKeyImpl<DINamespace> {
1114
1118 : Scope(N->getRawScope()), Name(N->getRawName()),
1119 ExportSymbols(N->getExportSymbols()) {}
1120
1121 bool isKeyOf(const DINamespace *RHS) const {
1122 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1123 ExportSymbols == RHS->getExportSymbols();
1124 }
1125
1126 unsigned getHashValue() const { return hash_combine(Scope, Name); }
1127};
1128
1129template <> struct MDNodeKeyImpl<DICommonBlock> {
1134 unsigned LineNo;
1135
1140 : Scope(N->getRawScope()), Decl(N->getRawDecl()), Name(N->getRawName()),
1141 File(N->getRawFile()), LineNo(N->getLineNo()) {}
1142
1143 bool isKeyOf(const DICommonBlock *RHS) const {
1144 return Scope == RHS->getRawScope() && Decl == RHS->getRawDecl() &&
1145 Name == RHS->getRawName() && File == RHS->getRawFile() &&
1146 LineNo == RHS->getLineNo();
1147 }
1148
1149 unsigned getHashValue() const {
1150 return hash_combine(Scope, Decl, Name, File, LineNo);
1151 }
1152};
1153
1154template <> struct MDNodeKeyImpl<DIModule> {
1161 unsigned LineNo;
1163
1171 : File(N->getRawFile()), Scope(N->getRawScope()), Name(N->getRawName()),
1172 ConfigurationMacros(N->getRawConfigurationMacros()),
1173 IncludePath(N->getRawIncludePath()),
1174 APINotesFile(N->getRawAPINotesFile()), LineNo(N->getLineNo()),
1175 IsDecl(N->getIsDecl()) {}
1176
1177 bool isKeyOf(const DIModule *RHS) const {
1178 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1179 ConfigurationMacros == RHS->getRawConfigurationMacros() &&
1180 IncludePath == RHS->getRawIncludePath() &&
1181 APINotesFile == RHS->getRawAPINotesFile() &&
1182 File == RHS->getRawFile() && LineNo == RHS->getLineNo() &&
1183 IsDecl == RHS->getIsDecl();
1184 }
1185
1186 unsigned getHashValue() const {
1188 }
1189};
1190
1195
1199 : Name(N->getRawName()), Type(N->getRawType()),
1200 IsDefault(N->isDefault()) {}
1201
1203 return Name == RHS->getRawName() && Type == RHS->getRawType() &&
1204 IsDefault == RHS->isDefault();
1205 }
1206
1207 unsigned getHashValue() const { return hash_combine(Name, Type, IsDefault); }
1208};
1209
1211 unsigned Tag;
1216
1221 : Tag(N->getTag()), Name(N->getRawName()), Type(N->getRawType()),
1222 IsDefault(N->isDefault()), Value(N->getValue()) {}
1223
1225 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
1226 Type == RHS->getRawType() && IsDefault == RHS->isDefault() &&
1227 Value == RHS->getValue();
1228 }
1229
1230 unsigned getHashValue() const {
1232 }
1233};
1234
1235template <> struct MDNodeKeyImpl<DIGlobalVariable> {
1240 unsigned Line;
1248
1261 : Scope(N->getRawScope()), Name(N->getRawName()),
1262 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
1263 Line(N->getLine()), Type(N->getRawType()),
1264 IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
1265 StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()),
1266 TemplateParams(N->getRawTemplateParams()),
1267 AlignInBits(N->getAlignInBits()), Annotations(N->getRawAnnotations()) {}
1268
1269 bool isKeyOf(const DIGlobalVariable *RHS) const {
1270 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1271 LinkageName == RHS->getRawLinkageName() &&
1272 File == RHS->getRawFile() && Line == RHS->getLine() &&
1273 Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() &&
1274 IsDefinition == RHS->isDefinition() &&
1276 RHS->getRawStaticDataMemberDeclaration() &&
1277 TemplateParams == RHS->getRawTemplateParams() &&
1278 AlignInBits == RHS->getAlignInBits() &&
1279 Annotations == RHS->getRawAnnotations();
1280 }
1281
1282 unsigned getHashValue() const {
1283 // We do not use AlignInBits in hashing function here on purpose:
1284 // in most cases this param for local variable is zero (for function param
1285 // it is always zero). This leads to lots of hash collisions and errors on
1286 // cases with lots of similar variables.
1287 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1288 // generated IR is random for each run and test fails with Align included.
1289 // TODO: make hashing work fine with such situations
1291 IsLocalToUnit, IsDefinition, /* AlignInBits, */
1293 }
1294};
1295
1296template <> struct MDNodeKeyImpl<DILocalVariable> {
1300 unsigned Line;
1302 unsigned Arg;
1303 unsigned Flags;
1306
1313 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1314 Line(N->getLine()), Type(N->getRawType()), Arg(N->getArg()),
1315 Flags(N->getFlags()), AlignInBits(N->getAlignInBits()),
1316 Annotations(N->getRawAnnotations()) {}
1317
1318 bool isKeyOf(const DILocalVariable *RHS) const {
1319 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1320 File == RHS->getRawFile() && Line == RHS->getLine() &&
1321 Type == RHS->getRawType() && Arg == RHS->getArg() &&
1322 Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits() &&
1323 Annotations == RHS->getRawAnnotations();
1324 }
1325
1326 unsigned getHashValue() const {
1327 // We do not use AlignInBits in hashing function here on purpose:
1328 // in most cases this param for local variable is zero (for function param
1329 // it is always zero). This leads to lots of hash collisions and errors on
1330 // cases with lots of similar variables.
1331 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1332 // generated IR is random for each run and test fails with Align included.
1333 // TODO: make hashing work fine with such situations
1335 }
1336};
1337
1338template <> struct MDNodeKeyImpl<DILabel> {
1342 unsigned Line;
1343 unsigned Column;
1345 std::optional<unsigned> CoroSuspendIdx;
1346
1353 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1354 Line(N->getLine()), Column(N->getColumn()),
1355 IsArtificial(N->isArtificial()),
1356 CoroSuspendIdx(N->getCoroSuspendIdx()) {}
1357
1358 bool isKeyOf(const DILabel *RHS) const {
1359 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1360 File == RHS->getRawFile() && Line == RHS->getLine() &&
1361 Column == RHS->getColumn() && IsArtificial == RHS->isArtificial() &&
1362 CoroSuspendIdx == RHS->getCoroSuspendIdx();
1363 }
1364
1365 /// Using name and line to get hash value. It should already be mostly unique.
1366 unsigned getHashValue() const {
1369 }
1370};
1371
1372template <> struct MDNodeKeyImpl<DIExpression> {
1374
1376 MDNodeKeyImpl(const DIExpression *N) : Elements(N->getElements()) {}
1377
1378 bool isKeyOf(const DIExpression *RHS) const {
1379 return Elements == RHS->getElements();
1380 }
1381
1382 unsigned getHashValue() const { return hash_combine_range(Elements); }
1383};
1384
1388
1392 : Variable(N->getRawVariable()), Expression(N->getRawExpression()) {}
1393
1395 return Variable == RHS->getRawVariable() &&
1396 Expression == RHS->getRawExpression();
1397 }
1398
1399 unsigned getHashValue() const { return hash_combine(Variable, Expression); }
1400};
1401
1402template <> struct MDNodeKeyImpl<DIObjCProperty> {
1405 unsigned Line;
1408 unsigned Attributes;
1410
1417 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
1418 GetterName(N->getRawGetterName()), SetterName(N->getRawSetterName()),
1419 Attributes(N->getAttributes()), Type(N->getRawType()) {}
1420
1421 bool isKeyOf(const DIObjCProperty *RHS) const {
1422 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
1423 Line == RHS->getLine() && GetterName == RHS->getRawGetterName() &&
1424 SetterName == RHS->getRawSetterName() &&
1425 Attributes == RHS->getAttributes() && Type == RHS->getRawType();
1426 }
1427
1428 unsigned getHashValue() const {
1430 Type);
1431 }
1432};
1433
1434template <> struct MDNodeKeyImpl<DIImportedEntity> {
1435 unsigned Tag;
1439 unsigned Line;
1442
1448 : Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()),
1449 File(N->getRawFile()), Line(N->getLine()), Name(N->getRawName()),
1450 Elements(N->getRawElements()) {}
1451
1452 bool isKeyOf(const DIImportedEntity *RHS) const {
1453 return Tag == RHS->getTag() && Scope == RHS->getRawScope() &&
1454 Entity == RHS->getRawEntity() && File == RHS->getFile() &&
1455 Line == RHS->getLine() && Name == RHS->getRawName() &&
1456 Elements == RHS->getRawElements();
1457 }
1458
1459 unsigned getHashValue() const {
1461 }
1462};
1463
1464template <> struct MDNodeKeyImpl<DIMacro> {
1465 unsigned MIType;
1466 unsigned Line;
1469
1473 : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getRawName()),
1474 Value(N->getRawValue()) {}
1475
1476 bool isKeyOf(const DIMacro *RHS) const {
1477 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1478 Name == RHS->getRawName() && Value == RHS->getRawValue();
1479 }
1480
1481 unsigned getHashValue() const {
1482 return hash_combine(MIType, Line, Name, Value);
1483 }
1484};
1485
1486template <> struct MDNodeKeyImpl<DIMacroFile> {
1487 unsigned MIType;
1488 unsigned Line;
1491
1496 : MIType(N->getMacinfoType()), Line(N->getLine()), File(N->getRawFile()),
1497 Elements(N->getRawElements()) {}
1498
1499 bool isKeyOf(const DIMacroFile *RHS) const {
1500 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1501 File == RHS->getRawFile() && Elements == RHS->getRawElements();
1502 }
1503
1504 unsigned getHashValue() const {
1506 }
1507};
1508
1509// DIArgLists are not MDNodes, but we still want to unique them in a DenseSet
1510// based on a hash of their arguments.
1513
1515 DIArgListKeyInfo(const DIArgList *N) : Args(N->getArgs()) {}
1516
1517 bool isKeyOf(const DIArgList *RHS) const { return Args == RHS->getArgs(); }
1518
1519 unsigned getHashValue() const { return hash_combine_range(Args); }
1520};
1521
1522/// DenseMapInfo for DIArgList.
1525
1526 static inline DIArgList *getEmptyKey() {
1528 }
1529
1533
1534 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1535
1536 static unsigned getHashValue(const DIArgList *N) {
1537 return KeyTy(N).getHashValue();
1538 }
1539
1540 static bool isEqual(const KeyTy &LHS, const DIArgList *RHS) {
1541 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1542 return false;
1543 return LHS.isKeyOf(RHS);
1544 }
1545
1546 static bool isEqual(const DIArgList *LHS, const DIArgList *RHS) {
1547 return LHS == RHS;
1548 }
1549};
1550
1551/// DenseMapInfo for MDNode subclasses.
1552template <class NodeTy> struct MDNodeInfo {
1555
1556 static inline NodeTy *getEmptyKey() {
1558 }
1559
1560 static inline NodeTy *getTombstoneKey() {
1562 }
1563
1564 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1565
1566 static unsigned getHashValue(const NodeTy *N) {
1567 return KeyTy(N).getHashValue();
1568 }
1569
1570 static bool isEqual(const KeyTy &LHS, const NodeTy *RHS) {
1571 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1572 return false;
1573 return SubsetEqualTy::isSubsetEqual(LHS, RHS) || LHS.isKeyOf(RHS);
1574 }
1575
1576 static bool isEqual(const NodeTy *LHS, const NodeTy *RHS) {
1577 if (LHS == RHS)
1578 return true;
1579 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1580 return false;
1582 }
1583};
1584
1585#define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>;
1586#include "llvm/IR/Metadata.def"
1587
1588/// Single metadata attachment, forms linked list ended by index 0.
1590 unsigned Next = 0;
1591 unsigned MDKind;
1593};
1594
1596public:
1597 /// OwnedModules - The set of modules instantiated in this context, and which
1598 /// will be automatically deleted if this context is deleted.
1600
1601 /// MachineFunctionNums - Keep the next available unique number available for
1602 /// a MachineFunction in given module. Module must in OwnedModules.
1604
1605 /// The main remark streamer used by all the other streamers (e.g. IR, MIR,
1606 /// frontends, etc.). This should only be used by the specific streamers, and
1607 /// never directly.
1608 std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer;
1609
1610 std::unique_ptr<DiagnosticHandler> DiagHandler;
1613 /// The minimum hotness value a diagnostic needs in order to be included in
1614 /// optimization diagnostics.
1615 ///
1616 /// The threshold is an Optional value, which maps to one of the 3 states:
1617 /// 1). 0 => threshold disabled. All emarks will be printed.
1618 /// 2). positive int => manual threshold by user. Remarks with hotness exceed
1619 /// threshold will be printed.
1620 /// 3). None => 'auto' threshold by user. The actual value is not
1621 /// available at command line, but will be synced with
1622 /// hotness threhold from profile summary during
1623 /// compilation.
1624 ///
1625 /// State 1 and 2 are considered as terminal states. State transition is
1626 /// only allowed from 3 to 2, when the threshold is first synced with profile
1627 /// summary. This ensures that the threshold is set only once and stays
1628 /// constant.
1629 ///
1630 /// If threshold option is not specified, it is disabled (0) by default.
1631 std::optional<uint64_t> DiagnosticsHotnessThreshold = 0;
1632
1633 /// The percentage of difference between profiling branch weights and
1634 /// llvm.expect branch weights to tolerate when emiting MisExpect diagnostics
1635 std::optional<uint32_t> DiagnosticsMisExpectTolerance = 0;
1637
1638 /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
1639 std::unique_ptr<LLVMRemarkStreamer> LLVMRS;
1640
1642 void *YieldOpaqueHandle = nullptr;
1643
1645
1649 DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantInt>>
1651
1655 DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantByte>>
1657
1659 DenseMap<std::pair<ElementCount, APFloat>, std::unique_ptr<ConstantFP>>
1661
1665
1670
1671#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
1672 DenseSet<CLASS *, CLASS##Info> CLASS##s;
1673#include "llvm/IR/Metadata.def"
1674
1675 // Optional map for looking up composite types by identifier.
1676 std::optional<DenseMap<const MDString *, DICompositeType *>> DITypeMap;
1677
1678 // MDNodes may be uniqued or not uniqued. When they're not uniqued, they
1679 // aren't in the MDNodeSet, but they're still shared between objects, so no
1680 // one object can destroy them. Keep track of them here so we can delete
1681 // them on context teardown.
1682 std::vector<MDNode *> DistinctMDNodes;
1683
1684 // ConstantRangeListAttributeImpl is a TrailingObjects/ArrayRef of
1685 // ConstantRange. Since this is a dynamically sized class, it's not
1686 // possible to use SpecificBumpPtrAllocator. Instead, we use normal Alloc
1687 // for allocation and record all allocated pointers in this vector. In the
1688 // LLVMContext destructor, call the destuctors of everything in the vector.
1689 std::vector<ConstantRangeListAttributeImpl *> ConstantRangeListAttributes;
1690
1692
1695
1698
1701
1703
1705
1707
1709
1711
1713
1715
1717
1719
1721
1723
1726
1729
1730 // Basic type instances.
1736
1737 std::unique_ptr<ConstantTokenNone> TheNoneToken;
1738
1743
1746
1753
1756
1759 PointerType *AS0PointerType = nullptr; // AddrSpace = 0
1762
1763 /// ValueHandles - This map keeps track of all of the value handles that are
1764 /// watching a Value*. The Value::HasValueHandle bit is used to know
1765 /// whether or not a value has an entry in this map.
1768
1769 /// CustomMDKindNames - Map to hold the metadata string to ID mapping.
1771
1772 /// Collection of metadata attachments in this context.
1774 /// Index of first free Metadatas entry, linked list via MDAttachment::Next.
1776 /// Number of currently unused metadata entries. Only used/updated in debug
1777 /// builds to ensure that all metadata attachments are properly freed.
1779
1780 /// Map DIAssignID -> Instructions with that attachment.
1781 /// Managed by Instruction via Instruction::updateDIAssignIDMapping.
1782 /// Query using the at:: functions defined in DebugInfo.h.
1784
1785 /// Collection of per-GlobalObject sections used in this context.
1787
1788 /// Collection of per-GlobalValue partitions used in this context.
1790
1793
1794 /// DiscriminatorTable - This table maps file:line locations to an
1795 /// integer representing the next DWARF path discriminator to assign to
1796 /// instructions in different blocks at the same location.
1798
1799 /// A set of interned tags for operand bundles. The StringMap maps
1800 /// bundle tags to their IDs.
1801 ///
1802 /// \see LLVMContext::getOperandBundleTagID
1804
1808
1809 /// A set of interned synchronization scopes. The StringMap maps
1810 /// synchronization scope names to their respective synchronization scope IDs.
1812
1813 /// getOrInsertSyncScopeID - Maps synchronization scope name to
1814 /// synchronization scope ID. Every synchronization scope registered with
1815 /// LLVMContext has unique ID except pre-defined ones.
1817
1818 /// getSyncScopeNames - Populates client supplied SmallVector with
1819 /// synchronization scope names registered with LLVMContext. Synchronization
1820 /// scope names are ordered by increasing synchronization scope IDs.
1822
1823 /// getSyncScopeName - Returns the name of a SyncScope::ID
1824 /// registered with LLVMContext, if any.
1825 std::optional<StringRef> getSyncScopeName(SyncScope::ID Id) const;
1826
1827 /// Maintain the GC name for each function.
1828 ///
1829 /// This saves allocating an additional word in Function for programs which
1830 /// do not use GC (i.e., most programs) at the cost of increased overhead for
1831 /// clients which do use GC.
1833
1834 /// Flag to indicate if Value (other than GlobalValue) retains their name or
1835 /// not.
1836 bool DiscardValueNames = false;
1837
1840
1841 mutable OptPassGate *OPG = nullptr;
1842
1843 /// Access the object which can disable optional passes and individual
1844 /// optimizations at compile time.
1845 OptPassGate &getOptPassGate() const;
1846
1847 /// Set the object which can disable optional passes and individual
1848 /// optimizations at compile time.
1849 ///
1850 /// The lifetime of the object must be guaranteed to extend as long as the
1851 /// LLVMContext is used by compilation.
1853
1854 /// Mapping of blocks to collections of "trailing" DbgVariableRecords. As part
1855 /// of the "RemoveDIs" project, debug-info variable location records are going
1856 /// to cease being instructions... which raises the problem of where should
1857 /// they be recorded when we remove the terminator of a blocks, such as:
1858 ///
1859 /// %foo = add i32 0, 0
1860 /// br label %bar
1861 ///
1862 /// If the branch is removed, a legitimate transient state while editing a
1863 /// block, any debug-records between those two instructions will not have a
1864 /// location. Each block thus records any DbgVariableRecord records that
1865 /// "trail" in such a way. These are stored in LLVMContext because typically
1866 /// LLVM only edits a small number of blocks at a time, so there's no need to
1867 /// bloat BasicBlock with such a data structure.
1869
1870 // Set, get and delete operations for TrailingDbgRecords.
1875
1879
1881
1882 std::string DefaultTargetCPU;
1884
1885 /// The next available source atom group number. The front end is responsible
1886 /// for assigning source atom numbers, but certain optimisations need to
1887 /// assign new group numbers to a set of instructions. Most often code
1888 /// duplication optimisations like loop unroll. Tracking a global maximum
1889 /// value means we can know (cheaply) we're never using a group number that's
1890 /// already used within this function.
1891 ///
1892 /// Start a 1 because 0 means the source location isn't part of an atom group.
1894};
1895
1896} // end namespace llvm
1897
1898#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
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
This template class is used to instantiate a specialized implementation of the folding set to the nod...
Definition FoldingSet.h:529
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< Type *, std::unique_ptr< ConstantPointerNull > > CPNConstants
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< 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
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
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:325
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:305
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:874
#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()