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
81 static unsigned getHashValue(const APFloat &Key) {
82 return static_cast<unsigned>(hash_value(Key));
83 }
84
85 static bool isEqual(const APFloat &LHS, const APFloat &RHS) {
86 return LHS.bitwiseIsEqual(RHS);
87 }
88};
89
91 struct KeyTy {
94
95 KeyTy(const ArrayRef<Type *> &E, bool P) : ETypes(E), isPacked(P) {}
96
97 KeyTy(const StructType *ST)
98 : ETypes(ST->elements()), isPacked(ST->isPacked()) {}
99
100 bool operator==(const KeyTy &that) const {
101 if (isPacked != that.isPacked)
102 return false;
103 if (ETypes != that.ETypes)
104 return false;
105 return true;
106 }
107 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
108 };
109
110 static inline StructType *getEmptyKey() {
112 }
113
114 static unsigned getHashValue(const KeyTy &Key) {
115 return hash_combine(hash_combine_range(Key.ETypes), Key.isPacked);
116 }
117
118 static unsigned getHashValue(const StructType *ST) {
119 return getHashValue(KeyTy(ST));
120 }
121
122 static bool isEqual(const KeyTy &LHS, const StructType *RHS) {
123 if (RHS == getEmptyKey())
124 return false;
125 return LHS == KeyTy(RHS);
126 }
127
128 static bool isEqual(const StructType *LHS, const StructType *RHS) {
129 return LHS == RHS;
130 }
131};
132
134 struct KeyTy {
138
139 KeyTy(const Type *R, const ArrayRef<Type *> &P, bool V)
140 : ReturnType(R), Params(P), isVarArg(V) {}
142 : ReturnType(FT->getReturnType()), Params(FT->params()),
143 isVarArg(FT->isVarArg()) {}
144
145 bool operator==(const KeyTy &that) const {
146 if (ReturnType != that.ReturnType)
147 return false;
148 if (isVarArg != that.isVarArg)
149 return false;
150 if (Params != that.Params)
151 return false;
152 return true;
153 }
154 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
155 };
156
160
161 static unsigned getHashValue(const KeyTy &Key) {
162 return hash_combine(Key.ReturnType, hash_combine_range(Key.Params),
163 Key.isVarArg);
164 }
165
166 static unsigned getHashValue(const FunctionType *FT) {
167 return getHashValue(KeyTy(FT));
168 }
169
170 static bool isEqual(const KeyTy &LHS, const FunctionType *RHS) {
171 if (RHS == getEmptyKey())
172 return false;
173 return LHS == KeyTy(RHS);
174 }
175
176 static bool isEqual(const FunctionType *LHS, const FunctionType *RHS) {
177 return LHS == RHS;
178 }
179};
180
182 struct KeyTy {
186
188 : Name(N), TypeParams(TP), IntParams(IP) {}
190 : Name(TT->getName()), TypeParams(TT->type_params()),
191 IntParams(TT->int_params()) {}
192
193 bool operator==(const KeyTy &that) const {
194 return Name == that.Name && TypeParams == that.TypeParams &&
195 IntParams == that.IntParams;
196 }
197 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
198 };
199
203
204 static unsigned getHashValue(const KeyTy &Key) {
205 return hash_combine(Key.Name, hash_combine_range(Key.TypeParams),
206 hash_combine_range(Key.IntParams));
207 }
208
209 static unsigned getHashValue(const TargetExtType *FT) {
210 return getHashValue(KeyTy(FT));
211 }
212
213 static bool isEqual(const KeyTy &LHS, const TargetExtType *RHS) {
214 if (RHS == getEmptyKey())
215 return false;
216 return LHS == KeyTy(RHS);
217 }
218
219 static bool isEqual(const TargetExtType *LHS, const TargetExtType *RHS) {
220 return LHS == RHS;
221 }
222};
223
224/// Structure for hashing arbitrary MDNode operands.
228 unsigned Hash;
229
230protected:
232 : RawOps(Ops), Hash(calculateHash(Ops)) {}
233
234 template <class NodeTy>
235 MDNodeOpsKey(const NodeTy *N, unsigned Offset = 0)
236 : Ops(N->op_begin() + Offset, N->op_end()), Hash(N->getHash()) {}
237
238 template <class NodeTy>
239 bool compareOps(const NodeTy *RHS, unsigned Offset = 0) const {
240 if (getHash() != RHS->getHash())
241 return false;
242
243 assert((RawOps.empty() || Ops.empty()) && "Two sets of operands?");
244 return RawOps.empty() ? compareOps(Ops, RHS, Offset)
245 : compareOps(RawOps, RHS, Offset);
246 }
247
248 static unsigned calculateHash(MDNode *N, unsigned Offset = 0);
249
250private:
251 template <class T>
252 static bool compareOps(ArrayRef<T> Ops, const MDNode *RHS, unsigned Offset) {
253 if (Ops.size() != RHS->getNumOperands() - Offset)
254 return false;
255 return std::equal(Ops.begin(), Ops.end(), RHS->op_begin() + Offset);
256 }
257
258 static unsigned calculateHash(ArrayRef<Metadata *> Ops);
259
260public:
261 unsigned getHash() const { return Hash; }
262};
263
264template <class NodeTy> struct MDNodeKeyImpl;
265
266/// Configuration point for MDNodeInfo::isEqual().
267template <class NodeTy> struct MDNodeSubsetEqualImpl {
269
270 static bool isSubsetEqual(const KeyTy &LHS, const NodeTy *RHS) {
271 return false;
272 }
273
274 static bool isSubsetEqual(const NodeTy *LHS, const NodeTy *RHS) {
275 return false;
276 }
277};
278
279/// DenseMapInfo for MDTuple.
280///
281/// Note that we don't need the is-function-local bit, since that's implicit in
282/// the operands.
283template <> struct MDNodeKeyImpl<MDTuple> : MDNodeOpsKey {
286
287 bool isKeyOf(const MDTuple *RHS) const { return compareOps(RHS); }
288
289 unsigned getHashValue() const { return getHash(); }
290
291 static unsigned calculateHash(MDTuple *N) {
293 }
294};
295
296/// DenseMapInfo for DILocation.
297template <> struct MDNodeKeyImpl<DILocation> {
302 unsigned Line;
305
312
314 : Scope(L->getRawScope()), InlinedAt(L->getRawInlinedAt()),
315 AtomGroup(L->getAtomGroup()), AtomRank(L->getAtomRank()),
316 Line(L->getLine()), Column(L->getColumn()),
317 ImplicitCode(L->isImplicitCode()) {}
318
319 bool isKeyOf(const DILocation *RHS) const {
320 return Line == RHS->getLine() && Column == RHS->getColumn() &&
321 Scope == RHS->getRawScope() && InlinedAt == RHS->getRawInlinedAt() &&
322 ImplicitCode == RHS->isImplicitCode() &&
323 AtomGroup == RHS->getAtomGroup() && AtomRank == RHS->getAtomRank();
324 }
325
326 unsigned getHashValue() const {
327 uint64_t LineColumnAndImplicitCode =
328 Line | (uint64_t(Column) << 32) | (uint64_t(ImplicitCode) << 48);
329 // Hashing AtomGroup and AtomRank substantially impacts performance whether
330 // Key Instructions is enabled or not. We can't detect whether it's enabled
331 // here cheaply; avoiding hashing zero values is a good approximation. This
332 // affects Key Instruction builds too, but any potential costs incurred by
333 // messing with the hash distribution* appear to still be massively
334 // outweighed by the overall compile time savings by performing this check.
335 // * (hash_combine(x) != hash_combine(x, 0))
336 if (AtomGroup || AtomRank)
337 return hash_combine(LineColumnAndImplicitCode, Scope, InlinedAt,
338 AtomGroup | (uint64_t(AtomRank) << 61));
339 return hash_combine(LineColumnAndImplicitCode, Scope, InlinedAt);
340 }
341};
342
343/// DenseMapInfo for GenericDINode.
345 unsigned Tag;
347
349 : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {}
351 : MDNodeOpsKey(N, 1), Tag(N->getTag()), Header(N->getRawHeader()) {}
352
353 bool isKeyOf(const GenericDINode *RHS) const {
354 return Tag == RHS->getTag() && Header == RHS->getRawHeader() &&
355 compareOps(RHS, 1);
356 }
357
358 unsigned getHashValue() const { return hash_combine(getHash(), Tag, Header); }
359
360 static unsigned calculateHash(GenericDINode *N) {
362 }
363};
364
365template <> struct MDNodeKeyImpl<DISubrange> {
370
376 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
377 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
378
379 bool isKeyOf(const DISubrange *RHS) const {
380 auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool {
381 if (Node1 == Node2)
382 return true;
383
386 if (MD1 && MD2) {
389 if (CV1->getSExtValue() == CV2->getSExtValue())
390 return true;
391 }
392 return false;
393 };
394
395 return BoundsEqual(CountNode, RHS->getRawCountNode()) &&
396 BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
397 BoundsEqual(UpperBound, RHS->getRawUpperBound()) &&
398 BoundsEqual(Stride, RHS->getRawStride());
399 }
400
401 unsigned getHashValue() const {
402 if (CountNode)
404 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
407 }
408};
409
410template <> struct MDNodeKeyImpl<DIGenericSubrange> {
415
421 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
422 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
423
424 bool isKeyOf(const DIGenericSubrange *RHS) const {
425 return (CountNode == RHS->getRawCountNode()) &&
426 (LowerBound == RHS->getRawLowerBound()) &&
427 (UpperBound == RHS->getRawUpperBound()) &&
428 (Stride == RHS->getRawStride());
429 }
430
431 unsigned getHashValue() const {
433 if (CountNode && MD)
434 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
437 }
438};
439
440template <> struct MDNodeKeyImpl<DIEnumerator> {
444
451 : Value(N->getValue()), Name(N->getRawName()),
452 IsUnsigned(N->isUnsigned()) {}
453
454 bool isKeyOf(const DIEnumerator *RHS) const {
455 return Value.getBitWidth() == RHS->getValue().getBitWidth() &&
456 Value == RHS->getValue() && IsUnsigned == RHS->isUnsigned() &&
457 Name == RHS->getRawName();
458 }
459
460 unsigned getHashValue() const { return hash_combine(Value, Name); }
461};
462
463template <> struct MDNodeKeyImpl<DIBasicType> {
464 unsigned Tag;
467 unsigned LineNo;
471 unsigned Encoding;
474 unsigned Flags;
475
485 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
486 LineNo(N->getLine()), Scope(N->getRawScope()),
487 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
488 Encoding(N->getEncoding()),
489 NumExtraInhabitants(N->getNumExtraInhabitants()),
490 DataSizeInBits(N->getDataSizeInBits()), Flags(N->getFlags()) {}
491
492 bool isKeyOf(const DIBasicType *RHS) const {
493 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
494 File == RHS->getRawFile() && LineNo == RHS->getLine() &&
495 Scope == RHS->getRawScope() &&
496 SizeInBits == RHS->getRawSizeInBits() &&
497 AlignInBits == RHS->getAlignInBits() &&
498 Encoding == RHS->getEncoding() &&
499 NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
500 DataSizeInBits == RHS->getDataSizeInBits() &&
501 Flags == RHS->getFlags();
502 }
503
504 unsigned getHashValue() const {
506 Encoding);
507 }
508};
509
510template <> struct MDNodeKeyImpl<DIFixedPointType> {
511 unsigned Tag;
514 unsigned LineNo;
518 unsigned Encoding;
519 unsigned Flags;
520 unsigned Kind;
524
534 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
535 LineNo(N->getLine()), Scope(N->getRawScope()),
536 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
537 Encoding(N->getEncoding()), Flags(N->getFlags()), Kind(N->getKind()),
538 Factor(N->getFactorRaw()), Numerator(N->getNumeratorRaw()),
539 Denominator(N->getDenominatorRaw()) {}
540
541 bool isKeyOf(const DIFixedPointType *RHS) const {
542 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
543 LineNo == RHS->getLine() && Scope == RHS->getRawScope() &&
544 SizeInBits == RHS->getRawSizeInBits() &&
545 AlignInBits == RHS->getAlignInBits() && Kind == RHS->getKind() &&
546 (RHS->isRational() ? (Numerator == RHS->getNumerator() &&
547 Denominator == RHS->getDenominator())
548 : Factor == RHS->getFactor());
549 }
550
551 unsigned getHashValue() const {
554 }
555};
556
557template <> struct MDNodeKeyImpl<DIStringType> {
558 unsigned Tag;
565 unsigned Encoding;
566
574 : Tag(N->getTag()), Name(N->getRawName()),
575 StringLength(N->getRawStringLength()),
576 StringLengthExp(N->getRawStringLengthExp()),
577 StringLocationExp(N->getRawStringLocationExp()),
578 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
579 Encoding(N->getEncoding()) {}
580
581 bool isKeyOf(const DIStringType *RHS) const {
582 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
583 StringLength == RHS->getRawStringLength() &&
584 StringLengthExp == RHS->getRawStringLengthExp() &&
585 StringLocationExp == RHS->getRawStringLocationExp() &&
586 SizeInBits == RHS->getRawSizeInBits() &&
587 AlignInBits == RHS->getAlignInBits() &&
588 Encoding == RHS->getEncoding();
589 }
590 unsigned getHashValue() const {
591 // Intentionally computes the hash on a subset of the operands for
592 // performance reason. The subset has to be significant enough to avoid
593 // collision "most of the time". There is no correctness issue in case of
594 // collision because of the full check above.
596 }
597};
598
599template <> struct MDNodeKeyImpl<DIDerivedType> {
600 unsigned Tag;
601 MDString *Name;
602 Metadata *File;
603 unsigned Line;
604 Metadata *Scope;
606 Metadata *SizeInBits;
607 Metadata *OffsetInBits;
608 uint32_t AlignInBits;
609 std::optional<unsigned> DWARFAddressSpace;
610 std::optional<DIDerivedType::PtrAuthData> PtrAuthData;
611 unsigned Flags;
613 Metadata *Annotations;
614
615 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
616 Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
617 uint32_t AlignInBits, Metadata *OffsetInBits,
618 std::optional<unsigned> DWARFAddressSpace,
619 std::optional<DIDerivedType::PtrAuthData> PtrAuthData,
620 unsigned Flags, Metadata *ExtraData, Metadata *Annotations)
621 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
622 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
623 AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace),
624 PtrAuthData(PtrAuthData), Flags(Flags), ExtraData(ExtraData),
625 Annotations(Annotations) {}
626 MDNodeKeyImpl(const DIDerivedType *N)
627 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
628 Line(N->getLine()), Scope(N->getRawScope()),
629 BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
630 OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
631 DWARFAddressSpace(N->getDWARFAddressSpace()),
632 PtrAuthData(N->getPtrAuthData()), Flags(N->getFlags()),
633 ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {}
634
635 bool isKeyOf(const DIDerivedType *RHS) const {
636 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
637 File == RHS->getRawFile() && Line == RHS->getLine() &&
638 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
639 SizeInBits == RHS->getRawSizeInBits() &&
640 AlignInBits == RHS->getAlignInBits() &&
641 OffsetInBits == RHS->getRawOffsetInBits() &&
642 DWARFAddressSpace == RHS->getDWARFAddressSpace() &&
643 PtrAuthData == RHS->getPtrAuthData() && Flags == RHS->getFlags() &&
644 ExtraData == RHS->getRawExtraData() &&
645 Annotations == RHS->getRawAnnotations();
646 }
647
648 unsigned getHashValue() const {
649 // If this is a member inside an ODR type, only hash the type and the name.
650 // Otherwise the hash will be stronger than
651 // MDNodeSubsetEqualImpl::isODRMember().
652 if (Tag == dwarf::DW_TAG_member && Name)
653 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
654 if (CT->getRawIdentifier())
655 return hash_combine(Name, Scope);
656
657 // Intentionally computes the hash on a subset of the operands for
658 // performance reason. The subset has to be significant enough to avoid
659 // collision "most of the time". There is no correctness issue in case of
660 // collision because of the full check above.
661 return hash_combine(Tag, Name, File, Line, Scope, BaseType, Flags);
662 }
663};
664
665template <> struct MDNodeKeyImpl<DISubrangeType> {
668 unsigned Line;
672 unsigned Flags;
678
688 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
689 Scope(N->getRawScope()), SizeInBits(N->getRawSizeInBits()),
690 AlignInBits(N->getAlignInBits()), Flags(N->getFlags()),
691 BaseType(N->getRawBaseType()), LowerBound(N->getRawLowerBound()),
692 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()),
693 Bias(N->getRawBias()) {}
694
695 bool isKeyOf(const DISubrangeType *RHS) const {
696 auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool {
697 if (Node1 == Node2)
698 return true;
699
702 if (MD1 && MD2) {
705 if (CV1->getSExtValue() == CV2->getSExtValue())
706 return true;
707 }
708 return false;
709 };
710
711 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
712 Line == RHS->getLine() && Scope == RHS->getRawScope() &&
713 SizeInBits == RHS->getRawSizeInBits() &&
714 AlignInBits == RHS->getAlignInBits() && Flags == RHS->getFlags() &&
715 BaseType == RHS->getRawBaseType() &&
716 BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
717 BoundsEqual(UpperBound, RHS->getRawUpperBound()) &&
718 BoundsEqual(Stride, RHS->getRawStride()) &&
719 BoundsEqual(Bias, RHS->getRawBias());
720 }
721
722 unsigned getHashValue() const {
723 unsigned val = 0;
724 auto HashBound = [&](Metadata *Node) -> void {
726 if (MD) {
728 val = hash_combine(val, CV->getSExtValue());
729 } else {
730 val = hash_combine(val, Node);
731 }
732 };
733
734 HashBound(LowerBound);
735 HashBound(UpperBound);
736 HashBound(Stride);
737 HashBound(Bias);
738
739 return hash_combine(val, Name, File, Line, Scope, BaseType, Flags);
740 }
741};
742
745
746 static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) {
747 return isODRMember(LHS.Tag, LHS.Scope, LHS.Name, RHS);
748 }
749
750 static bool isSubsetEqual(const DIDerivedType *LHS,
751 const DIDerivedType *RHS) {
752 return isODRMember(LHS->getTag(), LHS->getRawScope(), LHS->getRawName(),
753 RHS);
754 }
755
756 /// Subprograms compare equal if they declare the same function in an ODR
757 /// type.
758 static bool isODRMember(unsigned Tag, const Metadata *Scope,
759 const MDString *Name, const DIDerivedType *RHS) {
760 // Check whether the LHS is eligible.
761 if (Tag != dwarf::DW_TAG_member || !Name)
762 return false;
763
764 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
765 if (!CT || !CT->getRawIdentifier())
766 return false;
767
768 // Compare to the RHS.
769 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
770 Scope == RHS->getRawScope();
771 }
772};
773
774template <> struct MDNodeKeyImpl<DICompositeType> {
775 unsigned Tag;
778 unsigned Line;
784 unsigned Flags;
786 unsigned RuntimeLang;
799
820 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
821 Line(N->getLine()), Scope(N->getRawScope()),
822 BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
823 OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
824 Flags(N->getFlags()), Elements(N->getRawElements()),
825 RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()),
826 TemplateParams(N->getRawTemplateParams()),
827 Identifier(N->getRawIdentifier()),
828 Discriminator(N->getRawDiscriminator()),
829 DataLocation(N->getRawDataLocation()),
830 Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()),
831 Rank(N->getRawRank()), Annotations(N->getRawAnnotations()),
832 Specification(N->getSpecification()),
833 NumExtraInhabitants(N->getNumExtraInhabitants()),
834 BitStride(N->getRawBitStride()) {}
835
836 bool isKeyOf(const DICompositeType *RHS) const {
837 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
838 File == RHS->getRawFile() && Line == RHS->getLine() &&
839 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
840 SizeInBits == RHS->getRawSizeInBits() &&
841 AlignInBits == RHS->getAlignInBits() &&
842 OffsetInBits == RHS->getRawOffsetInBits() &&
843 Flags == RHS->getFlags() && Elements == RHS->getRawElements() &&
844 RuntimeLang == RHS->getRuntimeLang() &&
845 VTableHolder == RHS->getRawVTableHolder() &&
846 TemplateParams == RHS->getRawTemplateParams() &&
847 Identifier == RHS->getRawIdentifier() &&
848 Discriminator == RHS->getRawDiscriminator() &&
849 DataLocation == RHS->getRawDataLocation() &&
850 Associated == RHS->getRawAssociated() &&
851 Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() &&
852 Annotations == RHS->getRawAnnotations() &&
853 Specification == RHS->getSpecification() &&
854 NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
855 BitStride == RHS->getRawBitStride();
856 }
857
858 unsigned getHashValue() const {
859 // Intentionally computes the hash on a subset of the operands for
860 // performance reason. The subset has to be significant enough to avoid
861 // collision "most of the time". There is no correctness issue in case of
862 // collision because of the full check above.
865 }
866};
867
868template <> struct MDNodeKeyImpl<DISubroutineType> {
869 unsigned Flags;
872
876 : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()) {}
877
878 bool isKeyOf(const DISubroutineType *RHS) const {
879 return Flags == RHS->getFlags() && CC == RHS->getCC() &&
880 TypeArray == RHS->getRawTypeArray();
881 }
882
883 unsigned getHashValue() const { return hash_combine(Flags, CC, TypeArray); }
884};
885
886template <> struct MDNodeKeyImpl<DIFile> {
889 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum;
891
898 : Filename(N->getRawFilename()), Directory(N->getRawDirectory()),
899 Checksum(N->getRawChecksum()), Source(N->getRawSource()) {}
900
901 bool isKeyOf(const DIFile *RHS) const {
902 return Filename == RHS->getRawFilename() &&
903 Directory == RHS->getRawDirectory() &&
904 Checksum == RHS->getRawChecksum() && Source == RHS->getRawSource();
905 }
906
907 unsigned getHashValue() const {
908 return hash_combine(Filename, Directory, Checksum ? Checksum->Kind : 0,
909 Checksum ? Checksum->Value : nullptr, Source);
910 }
911};
912
913template <> struct MDNodeKeyImpl<DISubprogram> {
914 Metadata *Scope;
915 MDString *Name;
916 MDString *LinkageName;
917 Metadata *File;
918 unsigned Line;
919 unsigned ScopeLine;
920 Metadata *Type;
921 Metadata *ContainingType;
922 unsigned VirtualIndex;
923 int ThisAdjustment;
924 unsigned Flags;
925 unsigned SPFlags;
926 Metadata *Unit;
927 Metadata *TemplateParams;
928 Metadata *Declaration;
929 Metadata *RetainedNodes;
930 Metadata *ThrownTypes;
931 Metadata *Annotations;
932 MDString *TargetFuncName;
933 bool UsesKeyInstructions;
934
935 MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
936 Metadata *File, unsigned Line, Metadata *Type,
937 unsigned ScopeLine, Metadata *ContainingType,
938 unsigned VirtualIndex, int ThisAdjustment, unsigned Flags,
939 unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams,
940 Metadata *Declaration, Metadata *RetainedNodes,
941 Metadata *ThrownTypes, Metadata *Annotations,
942 MDString *TargetFuncName, bool UsesKeyInstructions)
943 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
944 Line(Line), ScopeLine(ScopeLine), Type(Type),
945 ContainingType(ContainingType), VirtualIndex(VirtualIndex),
946 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags),
947 Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration),
948 RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes),
949 Annotations(Annotations), TargetFuncName(TargetFuncName),
950 UsesKeyInstructions(UsesKeyInstructions) {}
951 MDNodeKeyImpl(const DISubprogram *N)
952 : Scope(N->getRawScope()), Name(N->getRawName()),
953 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
954 Line(N->getLine()), ScopeLine(N->getScopeLine()), Type(N->getRawType()),
955 ContainingType(N->getRawContainingType()),
956 VirtualIndex(N->getVirtualIndex()),
957 ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()),
958 SPFlags(N->getSPFlags()), Unit(N->getRawUnit()),
959 TemplateParams(N->getRawTemplateParams()),
960 Declaration(N->getRawDeclaration()),
961 RetainedNodes(N->getRawRetainedNodes()),
962 ThrownTypes(N->getRawThrownTypes()),
963 Annotations(N->getRawAnnotations()),
964 TargetFuncName(N->getRawTargetFuncName()),
965 UsesKeyInstructions(N->getKeyInstructionsEnabled()) {}
966
967 bool isKeyOf(const DISubprogram *RHS) const {
968 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
969 LinkageName == RHS->getRawLinkageName() &&
970 File == RHS->getRawFile() && Line == RHS->getLine() &&
971 Type == RHS->getRawType() && ScopeLine == RHS->getScopeLine() &&
972 ContainingType == RHS->getRawContainingType() &&
973 VirtualIndex == RHS->getVirtualIndex() &&
974 ThisAdjustment == RHS->getThisAdjustment() &&
975 Flags == RHS->getFlags() && SPFlags == RHS->getSPFlags() &&
976 Unit == RHS->getUnit() &&
977 TemplateParams == RHS->getRawTemplateParams() &&
978 Declaration == RHS->getRawDeclaration() &&
979 RetainedNodes == RHS->getRawRetainedNodes() &&
980 ThrownTypes == RHS->getRawThrownTypes() &&
981 Annotations == RHS->getRawAnnotations() &&
982 TargetFuncName == RHS->getRawTargetFuncName() &&
983 UsesKeyInstructions == RHS->getKeyInstructionsEnabled();
984 }
985
986 bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; }
987
988 unsigned getHashValue() const {
989 // Use the Scope's linkage name instead of using the scope directly, as the
990 // scope may be a temporary one which can replaced, which would produce a
991 // different hash for the same DISubprogram.
992 llvm::StringRef ScopeLinkageName;
993 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
994 if (auto *ID = CT->getRawIdentifier())
995 ScopeLinkageName = ID->getString();
996
997 // If this is a declaration inside an ODR type, only hash the type and the
998 // name. Otherwise the hash will be stronger than
999 // MDNodeSubsetEqualImpl::isDeclarationOfODRMember().
1000 if (!isDefinition() && LinkageName &&
1002 return hash_combine(LinkageName, ScopeLinkageName);
1003
1004 // Intentionally computes the hash on a subset of the operands for
1005 // performance reason. The subset has to be significant enough to avoid
1006 // collision "most of the time". There is no correctness issue in case of
1007 // collision because of the full check above.
1008 return hash_combine(Name, ScopeLinkageName, File, Type, Line);
1009 }
1010};
1011
1014
1015 static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) {
1016 return isDeclarationOfODRMember(LHS.isDefinition(), LHS.Scope,
1017 LHS.LinkageName, LHS.TemplateParams, RHS);
1018 }
1019
1020 static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) {
1021 return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(),
1022 LHS->getRawLinkageName(),
1023 LHS->getRawTemplateParams(), RHS);
1024 }
1025
1026 /// Subprograms compare equal if they declare the same function in an ODR
1027 /// type.
1028 static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope,
1029 const MDString *LinkageName,
1030 const Metadata *TemplateParams,
1031 const DISubprogram *RHS) {
1032 // Check whether the LHS is eligible.
1033 if (IsDefinition || !Scope || !LinkageName)
1034 return false;
1035
1036 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
1037 if (!CT || !CT->getRawIdentifier())
1038 return false;
1039
1040 // Compare to the RHS.
1041 // FIXME: We need to compare template parameters here to avoid incorrect
1042 // collisions in mapMetadata when RF_ReuseAndMutateDistinctMDs and a
1043 // ODR-DISubprogram has a non-ODR template parameter (i.e., a
1044 // DICompositeType that does not have an identifier). Eventually we should
1045 // decouple ODR logic from uniquing logic.
1046 return IsDefinition == RHS->isDefinition() && Scope == RHS->getRawScope() &&
1047 LinkageName == RHS->getRawLinkageName() &&
1048 TemplateParams == RHS->getRawTemplateParams();
1049 }
1050};
1051
1052template <> struct MDNodeKeyImpl<DILexicalBlock> {
1055 unsigned Line;
1056 unsigned Column;
1057
1061 : Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()),
1062 Column(N->getColumn()) {}
1063
1064 bool isKeyOf(const DILexicalBlock *RHS) const {
1065 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
1066 Line == RHS->getLine() && Column == RHS->getColumn();
1067 }
1068
1069 unsigned getHashValue() const {
1070 return hash_combine(Scope, File, Line, Column);
1071 }
1072};
1073
1078
1082 : Scope(N->getRawScope()), File(N->getRawFile()),
1083 Discriminator(N->getDiscriminator()) {}
1084
1085 bool isKeyOf(const DILexicalBlockFile *RHS) const {
1086 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
1087 Discriminator == RHS->getDiscriminator();
1088 }
1089
1090 unsigned getHashValue() const {
1092 }
1093};
1094
1095template <> struct MDNodeKeyImpl<DINamespace> {
1099
1103 : Scope(N->getRawScope()), Name(N->getRawName()),
1104 ExportSymbols(N->getExportSymbols()) {}
1105
1106 bool isKeyOf(const DINamespace *RHS) const {
1107 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1108 ExportSymbols == RHS->getExportSymbols();
1109 }
1110
1111 unsigned getHashValue() const { return hash_combine(Scope, Name); }
1112};
1113
1114template <> struct MDNodeKeyImpl<DICommonBlock> {
1119 unsigned LineNo;
1120
1125 : Scope(N->getRawScope()), Decl(N->getRawDecl()), Name(N->getRawName()),
1126 File(N->getRawFile()), LineNo(N->getLineNo()) {}
1127
1128 bool isKeyOf(const DICommonBlock *RHS) const {
1129 return Scope == RHS->getRawScope() && Decl == RHS->getRawDecl() &&
1130 Name == RHS->getRawName() && File == RHS->getRawFile() &&
1131 LineNo == RHS->getLineNo();
1132 }
1133
1134 unsigned getHashValue() const {
1135 return hash_combine(Scope, Decl, Name, File, LineNo);
1136 }
1137};
1138
1139template <> struct MDNodeKeyImpl<DIModule> {
1146 unsigned LineNo;
1148
1156 : File(N->getRawFile()), Scope(N->getRawScope()), Name(N->getRawName()),
1157 ConfigurationMacros(N->getRawConfigurationMacros()),
1158 IncludePath(N->getRawIncludePath()),
1159 APINotesFile(N->getRawAPINotesFile()), LineNo(N->getLineNo()),
1160 IsDecl(N->getIsDecl()) {}
1161
1162 bool isKeyOf(const DIModule *RHS) const {
1163 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1164 ConfigurationMacros == RHS->getRawConfigurationMacros() &&
1165 IncludePath == RHS->getRawIncludePath() &&
1166 APINotesFile == RHS->getRawAPINotesFile() &&
1167 File == RHS->getRawFile() && LineNo == RHS->getLineNo() &&
1168 IsDecl == RHS->getIsDecl();
1169 }
1170
1171 unsigned getHashValue() const {
1173 }
1174};
1175
1180
1184 : Name(N->getRawName()), Type(N->getRawType()),
1185 IsDefault(N->isDefault()) {}
1186
1188 return Name == RHS->getRawName() && Type == RHS->getRawType() &&
1189 IsDefault == RHS->isDefault();
1190 }
1191
1192 unsigned getHashValue() const { return hash_combine(Name, Type, IsDefault); }
1193};
1194
1196 unsigned Tag;
1201
1206 : Tag(N->getTag()), Name(N->getRawName()), Type(N->getRawType()),
1207 IsDefault(N->isDefault()), Value(N->getValue()) {}
1208
1210 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
1211 Type == RHS->getRawType() && IsDefault == RHS->isDefault() &&
1212 Value == RHS->getValue();
1213 }
1214
1215 unsigned getHashValue() const {
1217 }
1218};
1219
1220template <> struct MDNodeKeyImpl<DIGlobalVariable> {
1225 unsigned Line;
1233
1246 : Scope(N->getRawScope()), Name(N->getRawName()),
1247 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
1248 Line(N->getLine()), Type(N->getRawType()),
1249 IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
1250 StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()),
1251 TemplateParams(N->getRawTemplateParams()),
1252 AlignInBits(N->getAlignInBits()), Annotations(N->getRawAnnotations()) {}
1253
1254 bool isKeyOf(const DIGlobalVariable *RHS) const {
1255 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1256 LinkageName == RHS->getRawLinkageName() &&
1257 File == RHS->getRawFile() && Line == RHS->getLine() &&
1258 Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() &&
1259 IsDefinition == RHS->isDefinition() &&
1261 RHS->getRawStaticDataMemberDeclaration() &&
1262 TemplateParams == RHS->getRawTemplateParams() &&
1263 AlignInBits == RHS->getAlignInBits() &&
1264 Annotations == RHS->getRawAnnotations();
1265 }
1266
1267 unsigned getHashValue() const {
1268 // We do not use AlignInBits in hashing function here on purpose:
1269 // in most cases this param for local variable is zero (for function param
1270 // it is always zero). This leads to lots of hash collisions and errors on
1271 // cases with lots of similar variables.
1272 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1273 // generated IR is random for each run and test fails with Align included.
1274 // TODO: make hashing work fine with such situations
1276 IsLocalToUnit, IsDefinition, /* AlignInBits, */
1278 }
1279};
1280
1281template <> struct MDNodeKeyImpl<DILocalVariable> {
1285 unsigned Line;
1287 unsigned Arg;
1288 unsigned Flags;
1291
1298 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1299 Line(N->getLine()), Type(N->getRawType()), Arg(N->getArg()),
1300 Flags(N->getFlags()), AlignInBits(N->getAlignInBits()),
1301 Annotations(N->getRawAnnotations()) {}
1302
1303 bool isKeyOf(const DILocalVariable *RHS) const {
1304 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1305 File == RHS->getRawFile() && Line == RHS->getLine() &&
1306 Type == RHS->getRawType() && Arg == RHS->getArg() &&
1307 Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits() &&
1308 Annotations == RHS->getRawAnnotations();
1309 }
1310
1311 unsigned getHashValue() const {
1312 // We do not use AlignInBits in hashing function here on purpose:
1313 // in most cases this param for local variable is zero (for function param
1314 // it is always zero). This leads to lots of hash collisions and errors on
1315 // cases with lots of similar variables.
1316 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1317 // generated IR is random for each run and test fails with Align included.
1318 // TODO: make hashing work fine with such situations
1320 }
1321};
1322
1323template <> struct MDNodeKeyImpl<DILabel> {
1327 unsigned Line;
1328 unsigned Column;
1330 std::optional<unsigned> CoroSuspendIdx;
1331
1338 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1339 Line(N->getLine()), Column(N->getColumn()),
1340 IsArtificial(N->isArtificial()),
1341 CoroSuspendIdx(N->getCoroSuspendIdx()) {}
1342
1343 bool isKeyOf(const DILabel *RHS) const {
1344 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1345 File == RHS->getRawFile() && Line == RHS->getLine() &&
1346 Column == RHS->getColumn() && IsArtificial == RHS->isArtificial() &&
1347 CoroSuspendIdx == RHS->getCoroSuspendIdx();
1348 }
1349
1350 /// Using name and line to get hash value. It should already be mostly unique.
1351 unsigned getHashValue() const {
1354 }
1355};
1356
1357template <> struct MDNodeKeyImpl<DIExpression> {
1359
1361 MDNodeKeyImpl(const DIExpression *N) : Elements(N->getElements()) {}
1362
1363 bool isKeyOf(const DIExpression *RHS) const {
1364 return Elements == RHS->getElements();
1365 }
1366
1367 unsigned getHashValue() const { return hash_combine_range(Elements); }
1368};
1369
1373
1377 : Variable(N->getRawVariable()), Expression(N->getRawExpression()) {}
1378
1380 return Variable == RHS->getRawVariable() &&
1381 Expression == RHS->getRawExpression();
1382 }
1383
1384 unsigned getHashValue() const { return hash_combine(Variable, Expression); }
1385};
1386
1387template <> struct MDNodeKeyImpl<DIObjCProperty> {
1390 unsigned Line;
1393 unsigned Attributes;
1395
1402 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
1403 GetterName(N->getRawGetterName()), SetterName(N->getRawSetterName()),
1404 Attributes(N->getAttributes()), Type(N->getRawType()) {}
1405
1406 bool isKeyOf(const DIObjCProperty *RHS) const {
1407 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
1408 Line == RHS->getLine() && GetterName == RHS->getRawGetterName() &&
1409 SetterName == RHS->getRawSetterName() &&
1410 Attributes == RHS->getAttributes() && Type == RHS->getRawType();
1411 }
1412
1413 unsigned getHashValue() const {
1415 Type);
1416 }
1417};
1418
1419template <> struct MDNodeKeyImpl<DIImportedEntity> {
1420 unsigned Tag;
1424 unsigned Line;
1427
1433 : Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()),
1434 File(N->getRawFile()), Line(N->getLine()), Name(N->getRawName()),
1435 Elements(N->getRawElements()) {}
1436
1437 bool isKeyOf(const DIImportedEntity *RHS) const {
1438 return Tag == RHS->getTag() && Scope == RHS->getRawScope() &&
1439 Entity == RHS->getRawEntity() && File == RHS->getFile() &&
1440 Line == RHS->getLine() && Name == RHS->getRawName() &&
1441 Elements == RHS->getRawElements();
1442 }
1443
1444 unsigned getHashValue() const {
1446 }
1447};
1448
1449template <> struct MDNodeKeyImpl<DIMacro> {
1450 unsigned MIType;
1451 unsigned Line;
1454
1458 : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getRawName()),
1459 Value(N->getRawValue()) {}
1460
1461 bool isKeyOf(const DIMacro *RHS) const {
1462 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1463 Name == RHS->getRawName() && Value == RHS->getRawValue();
1464 }
1465
1466 unsigned getHashValue() const {
1467 return hash_combine(MIType, Line, Name, Value);
1468 }
1469};
1470
1471template <> struct MDNodeKeyImpl<DIMacroFile> {
1472 unsigned MIType;
1473 unsigned Line;
1476
1481 : MIType(N->getMacinfoType()), Line(N->getLine()), File(N->getRawFile()),
1482 Elements(N->getRawElements()) {}
1483
1484 bool isKeyOf(const DIMacroFile *RHS) const {
1485 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1486 File == RHS->getRawFile() && Elements == RHS->getRawElements();
1487 }
1488
1489 unsigned getHashValue() const {
1491 }
1492};
1493
1494// DIArgLists are not MDNodes, but we still want to unique them in a DenseSet
1495// based on a hash of their arguments.
1498
1500 DIArgListKeyInfo(const DIArgList *N) : Args(N->getArgs()) {}
1501
1502 bool isKeyOf(const DIArgList *RHS) const { return Args == RHS->getArgs(); }
1503
1504 unsigned getHashValue() const { return hash_combine_range(Args); }
1505};
1506
1507/// DenseMapInfo for DIArgList.
1510
1511 static inline DIArgList *getEmptyKey() {
1513 }
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())
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 unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1542
1543 static unsigned getHashValue(const NodeTy *N) {
1544 return KeyTy(N).getHashValue();
1545 }
1546
1547 static bool isEqual(const KeyTy &LHS, const NodeTy *RHS) {
1548 if (RHS == getEmptyKey())
1549 return false;
1550 return SubsetEqualTy::isSubsetEqual(LHS, RHS) || LHS.isKeyOf(RHS);
1551 }
1552
1553 static bool isEqual(const NodeTy *LHS, const NodeTy *RHS) {
1554 if (LHS == RHS)
1555 return true;
1556 if (RHS == getEmptyKey())
1557 return false;
1559 }
1560};
1561
1562#define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>;
1563#include "llvm/IR/Metadata.def"
1564
1565/// Single metadata attachment, forms linked list ended by index 0.
1567 unsigned Next = 0;
1568 unsigned MDKind;
1570};
1571
1573public:
1574 /// OwnedModules - The set of modules instantiated in this context, and which
1575 /// will be automatically deleted if this context is deleted.
1577
1578 /// MachineFunctionNums - Keep the next available unique number available for
1579 /// a MachineFunction in given module. Module must in OwnedModules.
1581
1582 /// The main remark streamer used by all the other streamers (e.g. IR, MIR,
1583 /// frontends, etc.). This should only be used by the specific streamers, and
1584 /// never directly.
1585 std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer;
1586
1587 std::unique_ptr<DiagnosticHandler> DiagHandler;
1590 /// The minimum hotness value a diagnostic needs in order to be included in
1591 /// optimization diagnostics.
1592 ///
1593 /// The threshold is an Optional value, which maps to one of the 3 states:
1594 /// 1). 0 => threshold disabled. All emarks will be printed.
1595 /// 2). positive int => manual threshold by user. Remarks with hotness exceed
1596 /// threshold will be printed.
1597 /// 3). None => 'auto' threshold by user. The actual value is not
1598 /// available at command line, but will be synced with
1599 /// hotness threhold from profile summary during
1600 /// compilation.
1601 ///
1602 /// State 1 and 2 are considered as terminal states. State transition is
1603 /// only allowed from 3 to 2, when the threshold is first synced with profile
1604 /// summary. This ensures that the threshold is set only once and stays
1605 /// constant.
1606 ///
1607 /// If threshold option is not specified, it is disabled (0) by default.
1608 std::optional<uint64_t> DiagnosticsHotnessThreshold = 0;
1609
1610 /// The percentage of difference between profiling branch weights and
1611 /// llvm.expect branch weights to tolerate when emiting MisExpect diagnostics
1612 std::optional<uint32_t> DiagnosticsMisExpectTolerance = 0;
1614
1615 /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
1616 std::unique_ptr<LLVMRemarkStreamer> LLVMRS;
1617
1619 void *YieldOpaqueHandle = nullptr;
1620
1622
1626 DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantInt>>
1628
1632 DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantByte>>
1634
1636 DenseMap<std::pair<ElementCount, APFloat>, std::unique_ptr<ConstantFP>>
1638
1642
1647
1648#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
1649 DenseSet<CLASS *, CLASS##Info> CLASS##s;
1650#include "llvm/IR/Metadata.def"
1651
1652 // Optional map for looking up composite types by identifier.
1653 std::optional<DenseMap<const MDString *, DICompositeType *>> DITypeMap;
1654
1655 // MDNodes may be uniqued or not uniqued. When they're not uniqued, they
1656 // aren't in the MDNodeSet, but they're still shared between objects, so no
1657 // one object can destroy them. Keep track of them here so we can delete
1658 // them on context teardown.
1659 std::vector<MDNode *> DistinctMDNodes;
1660
1661 // ConstantRangeListAttributeImpl is a TrailingObjects/ArrayRef of
1662 // ConstantRange. Since this is a dynamically sized class, it's not
1663 // possible to use SpecificBumpPtrAllocator. Instead, we use normal Alloc
1664 // for allocation and record all allocated pointers in this vector. In the
1665 // LLVMContext destructor, call the destuctors of everything in the vector.
1666 std::vector<ConstantRangeListAttributeImpl *> ConstantRangeListAttributes;
1667
1669
1672
1675
1678
1680
1682
1684
1686
1688
1690
1692
1694
1696
1698
1700
1703
1706
1707 // Basic type instances.
1713
1714 std::unique_ptr<ConstantTokenNone> TheNoneToken;
1715
1720
1723
1730
1733
1736 PointerType *AS0PointerType = nullptr; // AddrSpace = 0
1739
1740 /// ValueHandles - This map keeps track of all of the value handles that are
1741 /// watching a Value*. The Value::HasValueHandle bit is used to know
1742 /// whether or not a value has an entry in this map.
1745
1746 /// CustomMDKindNames - Map to hold the metadata string to ID mapping.
1748
1749 /// Collection of metadata attachments in this context.
1751 /// Index of first free Metadatas entry, linked list via MDAttachment::Next.
1753 /// Number of currently unused metadata entries. Only used/updated in debug
1754 /// builds to ensure that all metadata attachments are properly freed.
1756
1757 /// Map DIAssignID -> Instructions with that attachment.
1758 /// Managed by Instruction via Instruction::updateDIAssignIDMapping.
1759 /// Query using the at:: functions defined in DebugInfo.h.
1761
1762 /// Collection of per-GlobalObject sections used in this context.
1764
1765 /// Collection of per-GlobalValue partitions used in this context.
1767
1770
1771 /// DiscriminatorTable - This table maps file:line locations to an
1772 /// integer representing the next DWARF path discriminator to assign to
1773 /// instructions in different blocks at the same location.
1775
1776 /// A set of interned tags for operand bundles. The StringMap maps
1777 /// bundle tags to their IDs.
1778 ///
1779 /// \see LLVMContext::getOperandBundleTagID
1781
1785
1786 /// A set of interned synchronization scopes. The StringMap maps
1787 /// synchronization scope names to their respective synchronization scope IDs.
1789
1790 /// getOrInsertSyncScopeID - Maps synchronization scope name to
1791 /// synchronization scope ID. Every synchronization scope registered with
1792 /// LLVMContext has unique ID except pre-defined ones.
1794
1795 /// getSyncScopeNames - Populates client supplied SmallVector with
1796 /// synchronization scope names registered with LLVMContext. Synchronization
1797 /// scope names are ordered by increasing synchronization scope IDs.
1799
1800 /// getSyncScopeName - Returns the name of a SyncScope::ID
1801 /// registered with LLVMContext, if any.
1802 std::optional<StringRef> getSyncScopeName(SyncScope::ID Id) const;
1803
1804 /// Maintain the GC name for each function.
1805 ///
1806 /// This saves allocating an additional word in Function for programs which
1807 /// do not use GC (i.e., most programs) at the cost of increased overhead for
1808 /// clients which do use GC.
1810
1811 /// Flag to indicate if Value (other than GlobalValue) retains their name or
1812 /// not.
1813 bool DiscardValueNames = false;
1814
1817
1818 mutable OptPassGate *OPG = nullptr;
1819
1820 /// Access the object which can disable optional passes and individual
1821 /// optimizations at compile time.
1822 OptPassGate &getOptPassGate() const;
1823
1824 /// Set the object which can disable optional passes and individual
1825 /// optimizations at compile time.
1826 ///
1827 /// The lifetime of the object must be guaranteed to extend as long as the
1828 /// LLVMContext is used by compilation.
1830
1831 /// Mapping of blocks to collections of "trailing" DbgVariableRecords. As part
1832 /// of the "RemoveDIs" project, debug-info variable location records are going
1833 /// to cease being instructions... which raises the problem of where should
1834 /// they be recorded when we remove the terminator of a blocks, such as:
1835 ///
1836 /// %foo = add i32 0, 0
1837 /// br label %bar
1838 ///
1839 /// If the branch is removed, a legitimate transient state while editing a
1840 /// block, any debug-records between those two instructions will not have a
1841 /// location. Each block thus records any DbgVariableRecord records that
1842 /// "trail" in such a way. These are stored in LLVMContext because typically
1843 /// LLVM only edits a small number of blocks at a time, so there's no need to
1844 /// bloat BasicBlock with such a data structure.
1846
1847 // Set, get and delete operations for TrailingDbgRecords.
1852
1856
1858
1859 std::string DefaultTargetCPU;
1861
1862 /// The next available source atom group number. The front end is responsible
1863 /// for assigning source atom numbers, but certain optimisations need to
1864 /// assign new group numbers to a set of instructions. Most often code
1865 /// duplication optimisations like loop unroll. Tracking a global maximum
1866 /// value means we can know (cheaply) we're never using a group number that's
1867 /// already used within this function.
1868 ///
1869 /// Start a 1 because 0 means the source location isn't part of an atom group.
1871};
1872
1873} // end namespace llvm
1874
1875#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.
static constexpr Value * getValue(Ty &ValueOrUse)
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:289
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:1075
A single uniqued string.
Definition Metadata.h:722
Tuple of metadata.
Definition Metadata.h:1495
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:558
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:861
#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 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 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 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 * 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 * getEmptyKey()