LLVM 24.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 "AttributeImpl.h"
18#include "ConstantsContext.h"
19#include "llvm/ADT/APFloat.h"
20#include "llvm/ADT/APInt.h"
21#include "llvm/ADT/ArrayRef.h"
22#include "llvm/ADT/DenseMap.h"
24#include "llvm/ADT/DenseSet.h"
25#include "llvm/ADT/FoldingSet.h"
26#include "llvm/ADT/Hashing.h"
27#include "llvm/ADT/STLExtras.h"
30#include "llvm/ADT/StringMap.h"
32#include "llvm/IR/Constants.h"
35#include "llvm/IR/LLVMContext.h"
36#include "llvm/IR/Metadata.h"
37#include "llvm/IR/Module.h"
39#include "llvm/IR/Type.h"
40#include "llvm/IR/Value.h"
45#include <algorithm>
46#include <cassert>
47#include <cstddef>
48#include <cstdint>
49#include <memory>
50#include <optional>
51#include <string>
52#include <utility>
53#include <vector>
54
55namespace llvm {
56
57class BasicBlock;
59class DbgMarker;
60class ElementCount;
61class Function;
62class GlobalObject;
63class GlobalValue;
64class InlineAsm;
66class OptPassGate;
67namespace remarks {
68class RemarkStreamer;
69}
70template <typename T> class StringMapEntry;
71class StringRef;
73class ValueHandleBase;
74
75template <> struct DenseMapInfo<APFloat> {
76 static unsigned getHashValue(const APFloat &Key) {
77 return static_cast<unsigned>(hash_value(Key));
78 }
79
80 static bool isEqual(const APFloat &LHS, const APFloat &RHS) {
81 return LHS.bitwiseIsEqual(RHS);
82 }
83};
84
86 struct KeyTy {
89
90 KeyTy(const ArrayRef<Type *> &E, bool P) : ETypes(E), isPacked(P) {}
91
92 KeyTy(const StructType *ST)
93 : ETypes(ST->elements()), isPacked(ST->isPacked()) {}
94
95 bool operator==(const KeyTy &that) const {
96 if (isPacked != that.isPacked)
97 return false;
98 if (ETypes != that.ETypes)
99 return false;
100 return true;
101 }
102 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
103 };
104
105 static unsigned getHashValue(const KeyTy &Key) {
106 return hash_combine(hash_combine_range(Key.ETypes), Key.isPacked);
107 }
108
109 static unsigned getHashValue(const StructType *ST) {
110 return getHashValue(KeyTy(ST));
111 }
112
113 static bool isEqual(const KeyTy &LHS, const StructType *RHS) {
114 return LHS == KeyTy(RHS);
115 }
116
117 static bool isEqual(const StructType *LHS, const StructType *RHS) {
118 return LHS == RHS;
119 }
120};
121
123 struct KeyTy {
127
128 KeyTy(const Type *R, const ArrayRef<Type *> &P, bool V)
129 : ReturnType(R), Params(P), isVarArg(V) {}
131 : ReturnType(FT->getReturnType()), Params(FT->params()),
132 isVarArg(FT->isVarArg()) {}
133
134 bool operator==(const KeyTy &that) const {
135 if (ReturnType != that.ReturnType)
136 return false;
137 if (isVarArg != that.isVarArg)
138 return false;
139 if (Params != that.Params)
140 return false;
141 return true;
142 }
143 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
144 };
145
146 static unsigned getHashValue(const KeyTy &Key) {
147 return hash_combine(Key.ReturnType, hash_combine_range(Key.Params),
148 Key.isVarArg);
149 }
150
151 static unsigned getHashValue(const FunctionType *FT) {
152 return getHashValue(KeyTy(FT));
153 }
154
155 static bool isEqual(const KeyTy &LHS, const FunctionType *RHS) {
156 return LHS == KeyTy(RHS);
157 }
158
159 static bool isEqual(const FunctionType *LHS, const FunctionType *RHS) {
160 return LHS == RHS;
161 }
162};
163
165 struct KeyTy {
169
171 : Name(N), TypeParams(TP), IntParams(IP) {}
173 : Name(TT->getName()), TypeParams(TT->type_params()),
174 IntParams(TT->int_params()) {}
175
176 bool operator==(const KeyTy &that) const {
177 return Name == that.Name && TypeParams == that.TypeParams &&
178 IntParams == that.IntParams;
179 }
180 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
181 };
182
183 static unsigned getHashValue(const KeyTy &Key) {
184 return hash_combine(Key.Name, hash_combine_range(Key.TypeParams),
185 hash_combine_range(Key.IntParams));
186 }
187
188 static unsigned getHashValue(const TargetExtType *FT) {
189 return getHashValue(KeyTy(FT));
190 }
191
192 static bool isEqual(const KeyTy &LHS, const TargetExtType *RHS) {
193 return LHS == KeyTy(RHS);
194 }
195
196 static bool isEqual(const TargetExtType *LHS, const TargetExtType *RHS) {
197 return LHS == RHS;
198 }
199};
200
201/// Structure for hashing arbitrary MDNode operands.
205 unsigned Hash;
206
207protected:
209 : RawOps(Ops), Hash(calculateHash(Ops)) {}
210
211 template <class NodeTy>
212 MDNodeOpsKey(const NodeTy *N, unsigned Offset = 0)
213 : Ops(N->op_begin() + Offset, N->op_end()), Hash(N->getHash()) {}
214
215 template <class NodeTy>
216 bool compareOps(const NodeTy *RHS, unsigned Offset = 0) const {
217 if (getHash() != RHS->getHash())
218 return false;
219
220 assert((RawOps.empty() || Ops.empty()) && "Two sets of operands?");
221 return RawOps.empty() ? compareOps(Ops, RHS, Offset)
222 : compareOps(RawOps, RHS, Offset);
223 }
224
225 static unsigned calculateHash(MDNode *N, unsigned Offset = 0);
226
227private:
228 template <class T>
229 static bool compareOps(ArrayRef<T> Ops, const MDNode *RHS, unsigned Offset) {
230 if (Ops.size() != RHS->getNumOperands() - Offset)
231 return false;
232 return std::equal(Ops.begin(), Ops.end(), RHS->op_begin() + Offset);
233 }
234
235 static unsigned calculateHash(ArrayRef<Metadata *> Ops);
236
237public:
238 unsigned getHash() const { return Hash; }
239};
240
241template <class NodeTy> struct MDNodeKeyImpl;
242
243/// Configuration point for MDNodeInfo::isEqual().
244template <class NodeTy> struct MDNodeSubsetEqualImpl {
246
247 static bool isSubsetEqual(const KeyTy &LHS, const NodeTy *RHS) {
248 return false;
249 }
250
251 static bool isSubsetEqual(const NodeTy *LHS, const NodeTy *RHS) {
252 return false;
253 }
254};
255
256/// DenseMapInfo for MDTuple.
257///
258/// Note that we don't need the is-function-local bit, since that's implicit in
259/// the operands.
260template <> struct MDNodeKeyImpl<MDTuple> : MDNodeOpsKey {
263
264 bool isKeyOf(const MDTuple *RHS) const { return compareOps(RHS); }
265
266 unsigned getHashValue() const { return getHash(); }
267
268 static unsigned calculateHash(MDTuple *N) {
270 }
271};
272
273/// DenseMapInfo for DILocation.
274template <> struct MDNodeKeyImpl<DILocation> {
280 unsigned Line;
283
290
292 : Scope(L->getRawScope()), InlinedAt(L->getRawInlinedAt()),
293 IRLayers(L->getRawIRLayers()), AtomGroup(L->getAtomGroup()),
294 AtomRank(L->getAtomRank()), Line(L->getLine()), Column(L->getColumn()),
295 ImplicitCode(L->isImplicitCode()) {}
296
297 bool isKeyOf(const DILocation *RHS) const {
298 return Line == RHS->getLine() && Column == RHS->getColumn() &&
299 Scope == RHS->getRawScope() && InlinedAt == RHS->getRawInlinedAt() &&
300 ImplicitCode == RHS->isImplicitCode() &&
301 AtomGroup == RHS->getAtomGroup() && AtomRank == RHS->getAtomRank() &&
302 IRLayers == RHS->getRawIRLayers();
303 }
304
305 unsigned getHashValue() const {
306 uint64_t LineColumnAndImplicitCode =
307 Line | (uint64_t(Column) << 32) | (uint64_t(ImplicitCode) << 48);
308 // Hashing AtomGroup and AtomRank substantially impacts performance whether
309 // Key Instructions is enabled or not. We can't detect whether it's enabled
310 // here cheaply; avoiding hashing zero values is a good approximation. This
311 // affects Key Instruction builds too, but any potential costs incurred by
312 // messing with the hash distribution* appear to still be massively
313 // outweighed by the overall compile time savings by performing this check.
314 // * (hash_combine(x) != hash_combine(x, 0))
315 // irlayers is likewise rare, so it is only mixed in when present to keep
316 // the common no-layers hashes unchanged.
317 if (AtomGroup || AtomRank) {
318 if (IRLayers)
319 return hash_combine(LineColumnAndImplicitCode, Scope, InlinedAt,
320 AtomGroup | (uint64_t(AtomRank) << 61), IRLayers);
321 return hash_combine(LineColumnAndImplicitCode, Scope, InlinedAt,
322 AtomGroup | (uint64_t(AtomRank) << 61));
323 }
324 if (IRLayers)
325 return hash_combine(LineColumnAndImplicitCode, Scope, InlinedAt,
326 IRLayers);
327 return hash_combine(LineColumnAndImplicitCode, Scope, InlinedAt);
328 }
329};
330
331/// DenseMapInfo for DILayerLoc.
332template <> struct MDNodeKeyImpl<DILayerLoc> {
335 unsigned Line;
337
341 : Kind(N->getRawKind()), File(N->getRawFile()), Line(N->getLine()),
342 Column(N->getColumn()) {}
343
344 bool isKeyOf(const DILayerLoc *RHS) const {
345 return Kind == RHS->getRawKind() && File == RHS->getRawFile() &&
346 Line == RHS->getLine() && Column == RHS->getColumn();
347 }
348
349 unsigned getHashValue() const {
350 return hash_combine(Kind, File, Line, Column);
351 }
352};
353
354/// DenseMapInfo for DILayerLocList.
358
359 bool isKeyOf(const DILayerLocList *RHS) const { return compareOps(RHS); }
360
361 unsigned getHashValue() const { return getHash(); }
362
363 static unsigned calculateHash(DILayerLocList *N) {
365 }
366};
367
368/// DenseMapInfo for GenericDINode.
370 unsigned Tag;
372
374 : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {}
376 : MDNodeOpsKey(N, 1), Tag(N->getTag()), Header(N->getRawHeader()) {}
377
378 bool isKeyOf(const GenericDINode *RHS) const {
379 return Tag == RHS->getTag() && Header == RHS->getRawHeader() &&
380 compareOps(RHS, 1);
381 }
382
383 unsigned getHashValue() const { return hash_combine(getHash(), Tag, Header); }
384
385 static unsigned calculateHash(GenericDINode *N) {
387 }
388};
389
390template <> struct MDNodeKeyImpl<DISubrange> {
395
401 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
402 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
403
404 bool isKeyOf(const DISubrange *RHS) const {
405 auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool {
406 if (Node1 == Node2)
407 return true;
408
411 if (MD1 && MD2) {
414 if (CV1->getSExtValue() == CV2->getSExtValue())
415 return true;
416 }
417 return false;
418 };
419
420 return BoundsEqual(CountNode, RHS->getRawCountNode()) &&
421 BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
422 BoundsEqual(UpperBound, RHS->getRawUpperBound()) &&
423 BoundsEqual(Stride, RHS->getRawStride());
424 }
425
426 unsigned getHashValue() const {
427 if (CountNode)
429 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
432 }
433};
434
435template <> struct MDNodeKeyImpl<DIGenericSubrange> {
440
446 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
447 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
448
449 bool isKeyOf(const DIGenericSubrange *RHS) const {
450 return (CountNode == RHS->getRawCountNode()) &&
451 (LowerBound == RHS->getRawLowerBound()) &&
452 (UpperBound == RHS->getRawUpperBound()) &&
453 (Stride == RHS->getRawStride());
454 }
455
456 unsigned getHashValue() const {
458 if (CountNode && MD)
459 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
462 }
463};
464
465template <> struct MDNodeKeyImpl<DIEnumerator> {
469
476 : Value(N->getValue()), Name(N->getRawName()),
477 IsUnsigned(N->isUnsigned()) {}
478
479 bool isKeyOf(const DIEnumerator *RHS) const {
480 return Value.getBitWidth() == RHS->getValue().getBitWidth() &&
481 Value == RHS->getValue() && IsUnsigned == RHS->isUnsigned() &&
482 Name == RHS->getRawName();
483 }
484
485 unsigned getHashValue() const { return hash_combine(Value, Name); }
486};
487
488template <> struct MDNodeKeyImpl<DIBasicType> {
489 unsigned Tag;
492 unsigned LineNo;
496 unsigned Encoding;
499 unsigned Flags;
500
510 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
511 LineNo(N->getLine()), Scope(N->getRawScope()),
512 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
513 Encoding(N->getEncoding()),
514 NumExtraInhabitants(N->getNumExtraInhabitants()),
515 DataSizeInBits(N->getDataSizeInBits()), Flags(N->getFlags()) {}
516
517 bool isKeyOf(const DIBasicType *RHS) const {
518 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
519 File == RHS->getRawFile() && LineNo == RHS->getLine() &&
520 Scope == RHS->getRawScope() &&
521 SizeInBits == RHS->getRawSizeInBits() &&
522 AlignInBits == RHS->getAlignInBits() &&
523 Encoding == RHS->getEncoding() &&
524 NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
525 DataSizeInBits == RHS->getDataSizeInBits() &&
526 Flags == RHS->getFlags();
527 }
528
529 unsigned getHashValue() const {
531 Encoding);
532 }
533};
534
535template <> struct MDNodeKeyImpl<DIFixedPointType> {
536 unsigned Tag;
539 unsigned LineNo;
543 unsigned Encoding;
544 unsigned Flags;
545 unsigned Kind;
549
559 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
560 LineNo(N->getLine()), Scope(N->getRawScope()),
561 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
562 Encoding(N->getEncoding()), Flags(N->getFlags()), Kind(N->getKind()),
563 Factor(N->getFactorRaw()), Numerator(N->getNumeratorRaw()),
564 Denominator(N->getDenominatorRaw()) {}
565
566 bool isKeyOf(const DIFixedPointType *RHS) const {
567 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
568 LineNo == RHS->getLine() && Scope == RHS->getRawScope() &&
569 SizeInBits == RHS->getRawSizeInBits() &&
570 AlignInBits == RHS->getAlignInBits() && Kind == RHS->getKind() &&
571 (RHS->isRational() ? (Numerator == RHS->getNumerator() &&
572 Denominator == RHS->getDenominator())
573 : Factor == RHS->getFactor());
574 }
575
576 unsigned getHashValue() const {
579 }
580};
581
582template <> struct MDNodeKeyImpl<DIStringType> {
583 unsigned Tag;
590 unsigned Encoding;
592
602 : Tag(N->getTag()), Name(N->getRawName()),
603 StringLength(N->getRawStringLength()),
604 StringLengthExp(N->getRawStringLengthExp()),
605 StringLocationExp(N->getRawStringLocationExp()),
606 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
607 Encoding(N->getEncoding()), CharType(N->getRawCharType()) {}
608
609 bool isKeyOf(const DIStringType *RHS) const {
610 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
611 StringLength == RHS->getRawStringLength() &&
612 StringLengthExp == RHS->getRawStringLengthExp() &&
613 StringLocationExp == RHS->getRawStringLocationExp() &&
614 SizeInBits == RHS->getRawSizeInBits() &&
615 AlignInBits == RHS->getAlignInBits() &&
616 Encoding == RHS->getEncoding() && CharType == RHS->getRawCharType();
617 }
618 unsigned getHashValue() const {
619 // Intentionally computes the hash on a subset of the operands for
620 // performance reason. The subset has to be significant enough to avoid
621 // collision "most of the time". There is no correctness issue in case of
622 // collision because of the full check above.
624 }
625};
626
627template <> struct MDNodeKeyImpl<DIDerivedType> {
628 unsigned Tag;
629 MDString *Name;
630 Metadata *File;
631 unsigned Line;
632 Metadata *Scope;
634 Metadata *SizeInBits;
635 Metadata *OffsetInBits;
636 uint32_t AlignInBits;
637 std::optional<unsigned> DWARFAddressSpace;
638 std::optional<DIDerivedType::PtrAuthData> PtrAuthData;
639 unsigned Flags;
641 Metadata *Annotations;
642
643 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
644 Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
645 uint32_t AlignInBits, Metadata *OffsetInBits,
646 std::optional<unsigned> DWARFAddressSpace,
647 std::optional<DIDerivedType::PtrAuthData> PtrAuthData,
648 unsigned Flags, Metadata *ExtraData, Metadata *Annotations)
649 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
650 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
651 AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace),
652 PtrAuthData(PtrAuthData), Flags(Flags), ExtraData(ExtraData),
653 Annotations(Annotations) {}
654 MDNodeKeyImpl(const DIDerivedType *N)
655 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
656 Line(N->getLine()), Scope(N->getRawScope()),
657 BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
658 OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
659 DWARFAddressSpace(N->getDWARFAddressSpace()),
660 PtrAuthData(N->getPtrAuthData()), Flags(N->getFlags()),
661 ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {}
662
663 bool isKeyOf(const DIDerivedType *RHS) const {
664 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
665 File == RHS->getRawFile() && Line == RHS->getLine() &&
666 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
667 SizeInBits == RHS->getRawSizeInBits() &&
668 AlignInBits == RHS->getAlignInBits() &&
669 OffsetInBits == RHS->getRawOffsetInBits() &&
670 DWARFAddressSpace == RHS->getDWARFAddressSpace() &&
671 PtrAuthData == RHS->getPtrAuthData() && Flags == RHS->getFlags() &&
672 ExtraData == RHS->getRawExtraData() &&
673 Annotations == RHS->getRawAnnotations();
674 }
675
676 unsigned getHashValue() const {
677 // If this is a member inside an ODR type, only hash the type and the name.
678 // Otherwise the hash will be stronger than
679 // MDNodeSubsetEqualImpl::isODRMember().
680 if (Tag == dwarf::DW_TAG_member && Name)
681 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
682 if (CT->getRawIdentifier())
683 return hash_combine(Name, Scope);
684
685 // Intentionally computes the hash on a subset of the operands for
686 // performance reason. The subset has to be significant enough to avoid
687 // collision "most of the time". There is no correctness issue in case of
688 // collision because of the full check above.
689 return hash_combine(Tag, Name, File, Line, Scope, BaseType, Flags);
690 }
691};
692
693template <> struct MDNodeKeyImpl<DISubrangeType> {
696 unsigned Line;
700 unsigned Flags;
706
716 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
717 Scope(N->getRawScope()), SizeInBits(N->getRawSizeInBits()),
718 AlignInBits(N->getAlignInBits()), Flags(N->getFlags()),
719 BaseType(N->getRawBaseType()), LowerBound(N->getRawLowerBound()),
720 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()),
721 Bias(N->getRawBias()) {}
722
723 bool isKeyOf(const DISubrangeType *RHS) const {
724 auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool {
725 if (Node1 == Node2)
726 return true;
727
730 if (MD1 && MD2) {
733 if (CV1->getSExtValue() == CV2->getSExtValue())
734 return true;
735 }
736 return false;
737 };
738
739 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
740 Line == RHS->getLine() && Scope == RHS->getRawScope() &&
741 SizeInBits == RHS->getRawSizeInBits() &&
742 AlignInBits == RHS->getAlignInBits() && Flags == RHS->getFlags() &&
743 BaseType == RHS->getRawBaseType() &&
744 BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
745 BoundsEqual(UpperBound, RHS->getRawUpperBound()) &&
746 BoundsEqual(Stride, RHS->getRawStride()) &&
747 BoundsEqual(Bias, RHS->getRawBias());
748 }
749
750 unsigned getHashValue() const {
751 unsigned val = 0;
752 auto HashBound = [&](Metadata *Node) -> void {
754 if (MD) {
756 val = hash_combine(val, CV->getSExtValue());
757 } else {
758 val = hash_combine(val, Node);
759 }
760 };
761
762 HashBound(LowerBound);
763 HashBound(UpperBound);
764 HashBound(Stride);
765 HashBound(Bias);
766
767 return hash_combine(val, Name, File, Line, Scope, BaseType, Flags);
768 }
769};
770
773
774 static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) {
775 return isODRMember(LHS.Tag, LHS.Scope, LHS.Name, RHS);
776 }
777
778 static bool isSubsetEqual(const DIDerivedType *LHS,
779 const DIDerivedType *RHS) {
780 return isODRMember(LHS->getTag(), LHS->getRawScope(), LHS->getRawName(),
781 RHS);
782 }
783
784 /// Subprograms compare equal if they declare the same function in an ODR
785 /// type.
786 static bool isODRMember(unsigned Tag, const Metadata *Scope,
787 const MDString *Name, const DIDerivedType *RHS) {
788 // Check whether the LHS is eligible.
789 if (Tag != dwarf::DW_TAG_member || !Name)
790 return false;
791
792 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
793 if (!CT || !CT->getRawIdentifier())
794 return false;
795
796 // Compare to the RHS.
797 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
798 Scope == RHS->getRawScope();
799 }
800};
801
802template <> struct MDNodeKeyImpl<DICompositeType> {
803 unsigned Tag;
806 unsigned Line;
812 unsigned Flags;
814 unsigned RuntimeLang;
827
848 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
849 Line(N->getLine()), Scope(N->getRawScope()),
850 BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
851 OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
852 Flags(N->getFlags()), Elements(N->getRawElements()),
853 RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()),
854 TemplateParams(N->getRawTemplateParams()),
855 Identifier(N->getRawIdentifier()),
856 Discriminator(N->getRawDiscriminator()),
857 DataLocation(N->getRawDataLocation()),
858 Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()),
859 Rank(N->getRawRank()), Annotations(N->getRawAnnotations()),
860 Specification(N->getSpecification()),
861 NumExtraInhabitants(N->getNumExtraInhabitants()),
862 BitStride(N->getRawBitStride()) {}
863
864 bool isKeyOf(const DICompositeType *RHS) const {
865 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
866 File == RHS->getRawFile() && Line == RHS->getLine() &&
867 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
868 SizeInBits == RHS->getRawSizeInBits() &&
869 AlignInBits == RHS->getAlignInBits() &&
870 OffsetInBits == RHS->getRawOffsetInBits() &&
871 Flags == RHS->getFlags() && Elements == RHS->getRawElements() &&
872 RuntimeLang == RHS->getRuntimeLang() &&
873 VTableHolder == RHS->getRawVTableHolder() &&
874 TemplateParams == RHS->getRawTemplateParams() &&
875 Identifier == RHS->getRawIdentifier() &&
876 Discriminator == RHS->getRawDiscriminator() &&
877 DataLocation == RHS->getRawDataLocation() &&
878 Associated == RHS->getRawAssociated() &&
879 Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() &&
880 Annotations == RHS->getRawAnnotations() &&
881 Specification == RHS->getSpecification() &&
882 NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
883 BitStride == RHS->getRawBitStride();
884 }
885
886 unsigned getHashValue() const {
887 // Intentionally computes the hash on a subset of the operands for
888 // performance reason. The subset has to be significant enough to avoid
889 // collision "most of the time". There is no correctness issue in case of
890 // collision because of the full check above.
893 }
894};
895
896template <> struct MDNodeKeyImpl<DISubroutineType> {
897 unsigned Flags;
900
904 : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()) {}
905
906 bool isKeyOf(const DISubroutineType *RHS) const {
907 return Flags == RHS->getFlags() && CC == RHS->getCC() &&
908 TypeArray == RHS->getRawTypeArray();
909 }
910
911 unsigned getHashValue() const { return hash_combine(Flags, CC, TypeArray); }
912};
913
914template <> struct MDNodeKeyImpl<DIFile> {
917 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum;
919
926 : Filename(N->getRawFilename()), Directory(N->getRawDirectory()),
927 Checksum(N->getRawChecksum()), Source(N->getRawSource()) {}
928
929 bool isKeyOf(const DIFile *RHS) const {
930 return Filename == RHS->getRawFilename() &&
931 Directory == RHS->getRawDirectory() &&
932 Checksum == RHS->getRawChecksum() && Source == RHS->getRawSource();
933 }
934
935 unsigned getHashValue() const {
936 return hash_combine(Filename, Directory, Checksum ? Checksum->Kind : 0,
937 Checksum ? Checksum->Value : nullptr, Source);
938 }
939};
940
941template <> struct MDNodeKeyImpl<DISubprogram> {
942 Metadata *Scope;
943 MDString *Name;
944 MDString *LinkageName;
945 Metadata *File;
946 unsigned Line;
947 unsigned ScopeLine;
948 Metadata *Type;
949 Metadata *ContainingType;
950 unsigned VirtualIndex;
951 int ThisAdjustment;
952 unsigned Flags;
953 unsigned SPFlags;
954 Metadata *Unit;
955 Metadata *TemplateParams;
956 Metadata *Declaration;
957 Metadata *RetainedNodes;
958 Metadata *ThrownTypes;
959 Metadata *Annotations;
960 MDString *TargetFuncName;
961 bool UsesKeyInstructions;
962
963 MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
964 Metadata *File, unsigned Line, Metadata *Type,
965 unsigned ScopeLine, Metadata *ContainingType,
966 unsigned VirtualIndex, int ThisAdjustment, unsigned Flags,
967 unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams,
968 Metadata *Declaration, Metadata *RetainedNodes,
969 Metadata *ThrownTypes, Metadata *Annotations,
970 MDString *TargetFuncName, bool UsesKeyInstructions)
971 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
972 Line(Line), ScopeLine(ScopeLine), Type(Type),
973 ContainingType(ContainingType), VirtualIndex(VirtualIndex),
974 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags),
975 Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration),
976 RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes),
977 Annotations(Annotations), TargetFuncName(TargetFuncName),
978 UsesKeyInstructions(UsesKeyInstructions) {}
979 MDNodeKeyImpl(const DISubprogram *N)
980 : Scope(N->getRawScope()), Name(N->getRawName()),
981 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
982 Line(N->getLine()), ScopeLine(N->getScopeLine()), Type(N->getRawType()),
983 ContainingType(N->getRawContainingType()),
984 VirtualIndex(N->getVirtualIndex()),
985 ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()),
986 SPFlags(N->getSPFlags()), Unit(N->getRawUnit()),
987 TemplateParams(N->getRawTemplateParams()),
988 Declaration(N->getRawDeclaration()),
989 RetainedNodes(N->getRawRetainedNodes()),
990 ThrownTypes(N->getRawThrownTypes()),
991 Annotations(N->getRawAnnotations()),
992 TargetFuncName(N->getRawTargetFuncName()),
993 UsesKeyInstructions(N->getKeyInstructionsEnabled()) {}
994
995 bool isKeyOf(const DISubprogram *RHS) const {
996 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
997 LinkageName == RHS->getRawLinkageName() &&
998 File == RHS->getRawFile() && Line == RHS->getLine() &&
999 Type == RHS->getRawType() && ScopeLine == RHS->getScopeLine() &&
1000 ContainingType == RHS->getRawContainingType() &&
1001 VirtualIndex == RHS->getVirtualIndex() &&
1002 ThisAdjustment == RHS->getThisAdjustment() &&
1003 Flags == RHS->getFlags() && SPFlags == RHS->getSPFlags() &&
1004 Unit == RHS->getUnit() &&
1005 TemplateParams == RHS->getRawTemplateParams() &&
1006 Declaration == RHS->getRawDeclaration() &&
1007 RetainedNodes == RHS->getRawRetainedNodes() &&
1008 ThrownTypes == RHS->getRawThrownTypes() &&
1009 Annotations == RHS->getRawAnnotations() &&
1010 TargetFuncName == RHS->getRawTargetFuncName() &&
1011 UsesKeyInstructions == RHS->getKeyInstructionsEnabled();
1012 }
1013
1014 bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; }
1015
1016 unsigned getHashValue() const {
1017 // Use the Scope's linkage name instead of using the scope directly, as the
1018 // scope may be a temporary one which can replaced, which would produce a
1019 // different hash for the same DISubprogram.
1020 llvm::StringRef ScopeLinkageName;
1021 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
1022 if (auto *ID = CT->getRawIdentifier())
1023 ScopeLinkageName = ID->getString();
1024
1025 // If this is a declaration inside an ODR type, only hash the type and the
1026 // name. Otherwise the hash will be stronger than
1027 // MDNodeSubsetEqualImpl::isDeclarationOfODRMember().
1028 if (!isDefinition() && LinkageName &&
1030 return hash_combine(LinkageName, ScopeLinkageName);
1031
1032 // Intentionally computes the hash on a subset of the operands for
1033 // performance reason. The subset has to be significant enough to avoid
1034 // collision "most of the time". There is no correctness issue in case of
1035 // collision because of the full check above.
1036 return hash_combine(Name, ScopeLinkageName, File, Type, Line);
1037 }
1038};
1039
1042
1043 static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) {
1044 return isDeclarationOfODRMember(LHS.isDefinition(), LHS.Scope,
1045 LHS.LinkageName, LHS.TemplateParams, RHS);
1046 }
1047
1048 static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) {
1049 return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(),
1050 LHS->getRawLinkageName(),
1051 LHS->getRawTemplateParams(), RHS);
1052 }
1053
1054 /// Subprograms compare equal if they declare the same function in an ODR
1055 /// type.
1056 static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope,
1057 const MDString *LinkageName,
1058 const Metadata *TemplateParams,
1059 const DISubprogram *RHS) {
1060 // Check whether the LHS is eligible.
1061 if (IsDefinition || !Scope || !LinkageName)
1062 return false;
1063
1064 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
1065 if (!CT || !CT->getRawIdentifier())
1066 return false;
1067
1068 // Compare to the RHS.
1069 // FIXME: We need to compare template parameters here to avoid incorrect
1070 // collisions in mapMetadata when RF_ReuseAndMutateDistinctMDs and a
1071 // ODR-DISubprogram has a non-ODR template parameter (i.e., a
1072 // DICompositeType that does not have an identifier). Eventually we should
1073 // decouple ODR logic from uniquing logic.
1074 return IsDefinition == RHS->isDefinition() && Scope == RHS->getRawScope() &&
1075 LinkageName == RHS->getRawLinkageName() &&
1076 TemplateParams == RHS->getRawTemplateParams();
1077 }
1078};
1079
1080template <> struct MDNodeKeyImpl<DILexicalBlock> {
1083 unsigned Line;
1084 unsigned Column;
1085
1089 : Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()),
1090 Column(N->getColumn()) {}
1091
1092 bool isKeyOf(const DILexicalBlock *RHS) const {
1093 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
1094 Line == RHS->getLine() && Column == RHS->getColumn();
1095 }
1096
1097 unsigned getHashValue() const {
1098 return hash_combine(Scope, File, Line, Column);
1099 }
1100};
1101
1106
1110 : Scope(N->getRawScope()), File(N->getRawFile()),
1111 Discriminator(N->getDiscriminator()) {}
1112
1113 bool isKeyOf(const DILexicalBlockFile *RHS) const {
1114 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
1115 Discriminator == RHS->getDiscriminator();
1116 }
1117
1118 unsigned getHashValue() const {
1120 }
1121};
1122
1123template <> struct MDNodeKeyImpl<DINamespace> {
1127
1131 : Scope(N->getRawScope()), Name(N->getRawName()),
1132 ExportSymbols(N->getExportSymbols()) {}
1133
1134 bool isKeyOf(const DINamespace *RHS) const {
1135 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1136 ExportSymbols == RHS->getExportSymbols();
1137 }
1138
1139 unsigned getHashValue() const { return hash_combine(Scope, Name); }
1140};
1141
1142template <> struct MDNodeKeyImpl<DICommonBlock> {
1147 unsigned LineNo;
1148
1153 : Scope(N->getRawScope()), Decl(N->getRawDecl()), Name(N->getRawName()),
1154 File(N->getRawFile()), LineNo(N->getLineNo()) {}
1155
1156 bool isKeyOf(const DICommonBlock *RHS) const {
1157 return Scope == RHS->getRawScope() && Decl == RHS->getRawDecl() &&
1158 Name == RHS->getRawName() && File == RHS->getRawFile() &&
1159 LineNo == RHS->getLineNo();
1160 }
1161
1162 unsigned getHashValue() const {
1163 return hash_combine(Scope, Decl, Name, File, LineNo);
1164 }
1165};
1166
1167template <> struct MDNodeKeyImpl<DIModule> {
1174 unsigned LineNo;
1176
1184 : File(N->getRawFile()), Scope(N->getRawScope()), Name(N->getRawName()),
1185 ConfigurationMacros(N->getRawConfigurationMacros()),
1186 IncludePath(N->getRawIncludePath()),
1187 APINotesFile(N->getRawAPINotesFile()), LineNo(N->getLineNo()),
1188 IsDecl(N->getIsDecl()) {}
1189
1190 bool isKeyOf(const DIModule *RHS) const {
1191 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1192 ConfigurationMacros == RHS->getRawConfigurationMacros() &&
1193 IncludePath == RHS->getRawIncludePath() &&
1194 APINotesFile == RHS->getRawAPINotesFile() &&
1195 File == RHS->getRawFile() && LineNo == RHS->getLineNo() &&
1196 IsDecl == RHS->getIsDecl();
1197 }
1198
1199 unsigned getHashValue() const {
1201 }
1202};
1203
1208
1212 : Name(N->getRawName()), Type(N->getRawType()),
1213 IsDefault(N->isDefault()) {}
1214
1216 return Name == RHS->getRawName() && Type == RHS->getRawType() &&
1217 IsDefault == RHS->isDefault();
1218 }
1219
1220 unsigned getHashValue() const { return hash_combine(Name, Type, IsDefault); }
1221};
1222
1224 unsigned Tag;
1229
1234 : Tag(N->getTag()), Name(N->getRawName()), Type(N->getRawType()),
1235 IsDefault(N->isDefault()), Value(N->getValue()) {}
1236
1238 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
1239 Type == RHS->getRawType() && IsDefault == RHS->isDefault() &&
1240 Value == RHS->getValue();
1241 }
1242
1243 unsigned getHashValue() const {
1245 }
1246};
1247
1248template <> struct MDNodeKeyImpl<DIGlobalVariable> {
1253 unsigned Line;
1261
1274 : Scope(N->getRawScope()), Name(N->getRawName()),
1275 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
1276 Line(N->getLine()), Type(N->getRawType()),
1277 IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
1278 StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()),
1279 TemplateParams(N->getRawTemplateParams()),
1280 AlignInBits(N->getAlignInBits()), Annotations(N->getRawAnnotations()) {}
1281
1282 bool isKeyOf(const DIGlobalVariable *RHS) const {
1283 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1284 LinkageName == RHS->getRawLinkageName() &&
1285 File == RHS->getRawFile() && Line == RHS->getLine() &&
1286 Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() &&
1287 IsDefinition == RHS->isDefinition() &&
1289 RHS->getRawStaticDataMemberDeclaration() &&
1290 TemplateParams == RHS->getRawTemplateParams() &&
1291 AlignInBits == RHS->getAlignInBits() &&
1292 Annotations == RHS->getRawAnnotations();
1293 }
1294
1295 unsigned getHashValue() const {
1296 // We do not use AlignInBits in hashing function here on purpose:
1297 // in most cases this param for local variable is zero (for function param
1298 // it is always zero). This leads to lots of hash collisions and errors on
1299 // cases with lots of similar variables.
1300 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1301 // generated IR is random for each run and test fails with Align included.
1302 // TODO: make hashing work fine with such situations
1304 IsLocalToUnit, IsDefinition, /* AlignInBits, */
1306 }
1307};
1308
1309template <> struct MDNodeKeyImpl<DILocalVariable> {
1313 unsigned Line;
1315 unsigned Arg;
1316 unsigned Flags;
1319
1326 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1327 Line(N->getLine()), Type(N->getRawType()), Arg(N->getArg()),
1328 Flags(N->getFlags()), AlignInBits(N->getAlignInBits()),
1329 Annotations(N->getRawAnnotations()) {}
1330
1331 bool isKeyOf(const DILocalVariable *RHS) const {
1332 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1333 File == RHS->getRawFile() && Line == RHS->getLine() &&
1334 Type == RHS->getRawType() && Arg == RHS->getArg() &&
1335 Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits() &&
1336 Annotations == RHS->getRawAnnotations();
1337 }
1338
1339 unsigned getHashValue() const {
1340 // We do not use AlignInBits in hashing function here on purpose:
1341 // in most cases this param for local variable is zero (for function param
1342 // it is always zero). This leads to lots of hash collisions and errors on
1343 // cases with lots of similar variables.
1344 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1345 // generated IR is random for each run and test fails with Align included.
1346 // TODO: make hashing work fine with such situations
1348 }
1349};
1350
1351template <> struct MDNodeKeyImpl<DILabel> {
1355 unsigned Line;
1356 unsigned Column;
1358 std::optional<unsigned> CoroSuspendIdx;
1359
1366 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1367 Line(N->getLine()), Column(N->getColumn()),
1368 IsArtificial(N->isArtificial()),
1369 CoroSuspendIdx(N->getCoroSuspendIdx()) {}
1370
1371 bool isKeyOf(const DILabel *RHS) const {
1372 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1373 File == RHS->getRawFile() && Line == RHS->getLine() &&
1374 Column == RHS->getColumn() && IsArtificial == RHS->isArtificial() &&
1375 CoroSuspendIdx == RHS->getCoroSuspendIdx();
1376 }
1377
1378 /// Using name and line to get hash value. It should already be mostly unique.
1379 unsigned getHashValue() const {
1382 }
1383};
1384
1385template <> struct MDNodeKeyImpl<DIExpression> {
1387
1389 MDNodeKeyImpl(const DIExpression *N) : Elements(N->getElements()) {}
1390
1391 bool isKeyOf(const DIExpression *RHS) const {
1392 return Elements == RHS->getElements();
1393 }
1394
1395 unsigned getHashValue() const { return hash_combine_range(Elements); }
1396};
1397
1401
1405 : Variable(N->getRawVariable()), Expression(N->getRawExpression()) {}
1406
1408 return Variable == RHS->getRawVariable() &&
1409 Expression == RHS->getRawExpression();
1410 }
1411
1412 unsigned getHashValue() const { return hash_combine(Variable, Expression); }
1413};
1414
1415template <> struct MDNodeKeyImpl<DIObjCProperty> {
1418 unsigned Line;
1421 unsigned Attributes;
1423
1430 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
1431 GetterName(N->getRawGetterName()), SetterName(N->getRawSetterName()),
1432 Attributes(N->getAttributes()), Type(N->getRawType()) {}
1433
1434 bool isKeyOf(const DIObjCProperty *RHS) const {
1435 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
1436 Line == RHS->getLine() && GetterName == RHS->getRawGetterName() &&
1437 SetterName == RHS->getRawSetterName() &&
1438 Attributes == RHS->getAttributes() && Type == RHS->getRawType();
1439 }
1440
1441 unsigned getHashValue() const {
1443 Type);
1444 }
1445};
1446
1447template <> struct MDNodeKeyImpl<DIProperty> {
1450 unsigned Line;
1453
1459 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
1460 Type(N->getRawType()), BackingStorage(N->getRawBackingStorage()) {}
1461
1462 bool isKeyOf(const DIProperty *RHS) const {
1463 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
1464 Line == RHS->getLine() && Type == RHS->getRawType() &&
1465 BackingStorage == RHS->getRawBackingStorage();
1466 }
1467
1468 unsigned getHashValue() const {
1470 }
1471};
1472
1473template <> struct MDNodeKeyImpl<DIImportedEntity> {
1474 unsigned Tag;
1478 unsigned Line;
1481
1487 : Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()),
1488 File(N->getRawFile()), Line(N->getLine()), Name(N->getRawName()),
1489 Elements(N->getRawElements()) {}
1490
1491 bool isKeyOf(const DIImportedEntity *RHS) const {
1492 return Tag == RHS->getTag() && Scope == RHS->getRawScope() &&
1493 Entity == RHS->getRawEntity() && File == RHS->getFile() &&
1494 Line == RHS->getLine() && Name == RHS->getRawName() &&
1495 Elements == RHS->getRawElements();
1496 }
1497
1498 unsigned getHashValue() const {
1500 }
1501};
1502
1503template <> struct MDNodeKeyImpl<DIMacro> {
1504 unsigned MIType;
1505 unsigned Line;
1508
1512 : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getRawName()),
1513 Value(N->getRawValue()) {}
1514
1515 bool isKeyOf(const DIMacro *RHS) const {
1516 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1517 Name == RHS->getRawName() && Value == RHS->getRawValue();
1518 }
1519
1520 unsigned getHashValue() const {
1521 return hash_combine(MIType, Line, Name, Value);
1522 }
1523};
1524
1525template <> struct MDNodeKeyImpl<DIMacroFile> {
1526 unsigned MIType;
1527 unsigned Line;
1530
1535 : MIType(N->getMacinfoType()), Line(N->getLine()), File(N->getRawFile()),
1536 Elements(N->getRawElements()) {}
1537
1538 bool isKeyOf(const DIMacroFile *RHS) const {
1539 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1540 File == RHS->getRawFile() && Elements == RHS->getRawElements();
1541 }
1542
1543 unsigned getHashValue() const {
1545 }
1546};
1547
1548// DIArgLists are not MDNodes, but we still want to unique them in a DenseSet
1549// based on a hash of their arguments.
1552
1554 DIArgListKeyInfo(const DIArgList *N) : Args(N->getArgs()) {}
1555
1556 bool isKeyOf(const DIArgList *RHS) const { return Args == RHS->getArgs(); }
1557
1558 unsigned getHashValue() const { return hash_combine_range(Args); }
1559};
1560
1561/// DenseMapInfo for DIArgList.
1564
1565 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1566
1567 static unsigned getHashValue(const DIArgList *N) {
1568 return KeyTy(N).getHashValue();
1569 }
1570
1571 static bool isEqual(const KeyTy &LHS, const DIArgList *RHS) {
1572 return LHS.isKeyOf(RHS);
1573 }
1574
1575 static bool isEqual(const DIArgList *LHS, const DIArgList *RHS) {
1576 return LHS == RHS;
1577 }
1578};
1579
1580/// DenseMapInfo for MDNode subclasses.
1581template <class NodeTy> struct MDNodeInfo {
1584
1585 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1586
1587 static unsigned getHashValue(const NodeTy *N) {
1588 return KeyTy(N).getHashValue();
1589 }
1590
1591 static bool isEqual(const KeyTy &LHS, const NodeTy *RHS) {
1592 return SubsetEqualTy::isSubsetEqual(LHS, RHS) || LHS.isKeyOf(RHS);
1593 }
1594
1595 static bool isEqual(const NodeTy *LHS, const NodeTy *RHS) {
1596 if (LHS == RHS)
1597 return true;
1599 }
1600};
1601
1602#define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>;
1603#include "llvm/IR/Metadata.def"
1604
1605/// Single metadata attachment, forms linked list ended by index 0.
1607 unsigned Next = 0;
1608 unsigned MDKind;
1610};
1611
1612/// Head pointer for a Value's ValueHandleBase doubly-linked list, stored in
1613/// LLVMContextImpl::ValueHandles. The first node's PrevPtr points to Head, so
1614/// relocating the bucket refreshes PrevPtr to the new Head address.
1616 // Tag Head with true via PointerIntPair so RemoveFromUseList can
1617 // distinguish ValueHandleHead::Head from an untagged ValueHandleBase::Next
1618 // when accessed through *PrevPtr.
1620
1621 ValueHandleBase *Head =
1622 static_cast<ValueHandleBase *>(TaggedPtr(nullptr, true).getOpaqueValue());
1623
1624public:
1627 }
1628
1629 ValueHandleBase **getAddress() { return &Head; }
1630
1631 // Replace the pointer in *Slot with NewPtr while preserving its tag bit,
1632 // and return the old TaggedPtr.
1633 static TaggedPtr exchange(ValueHandleBase **Slot, ValueHandleBase *NewPtr) {
1634 TaggedPtr Old = TaggedPtr::getFromOpaqueValue(*Slot);
1635 TaggedPtr Updated = Old;
1636 Updated.setPointer(NewPtr);
1637 *Slot = static_cast<ValueHandleBase *>(Updated.getOpaqueValue());
1638 return Old;
1639 }
1640
1641 ValueHandleHead() = default;
1646};
1647
1649public:
1650 /// OwnedModules - The set of modules instantiated in this context, and which
1651 /// will be automatically deleted if this context is deleted.
1653
1654 /// MachineFunctionNums - Keep the next available unique number available for
1655 /// a MachineFunction in given module. Module must in OwnedModules.
1657
1658 /// The main remark streamer used by all the other streamers (e.g. IR, MIR,
1659 /// frontends, etc.). This should only be used by the specific streamers, and
1660 /// never directly.
1661 std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer;
1662
1663 std::unique_ptr<DiagnosticHandler> DiagHandler;
1666 /// The minimum hotness value a diagnostic needs in order to be included in
1667 /// optimization diagnostics.
1668 ///
1669 /// The threshold is an Optional value, which maps to one of the 3 states:
1670 /// 1). 0 => threshold disabled. All emarks will be printed.
1671 /// 2). positive int => manual threshold by user. Remarks with hotness exceed
1672 /// threshold will be printed.
1673 /// 3). None => 'auto' threshold by user. The actual value is not
1674 /// available at command line, but will be synced with
1675 /// hotness threhold from profile summary during
1676 /// compilation.
1677 ///
1678 /// State 1 and 2 are considered as terminal states. State transition is
1679 /// only allowed from 3 to 2, when the threshold is first synced with profile
1680 /// summary. This ensures that the threshold is set only once and stays
1681 /// constant.
1682 ///
1683 /// If threshold option is not specified, it is disabled (0) by default.
1684 std::optional<uint64_t> DiagnosticsHotnessThreshold = 0;
1685
1686 /// The percentage of difference between profiling branch weights and
1687 /// llvm.expect branch weights to tolerate when emiting MisExpect diagnostics
1688 std::optional<uint32_t> DiagnosticsMisExpectTolerance = 0;
1690
1691 /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
1692 std::unique_ptr<LLVMRemarkStreamer> LLVMRS;
1693
1695 void *YieldOpaqueHandle = nullptr;
1696
1698
1702 DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantInt>>
1704
1708 DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantByte>>
1710
1712 DenseMap<std::pair<ElementCount, APFloat>, std::unique_ptr<ConstantFP>>
1714
1722
1727
1729
1731
1733
1735 return N->getHeader().MetadataPrintID;
1736 }
1737
1739 N->getHeader().MetadataPrintID = ID;
1740 }
1741
1742#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
1743 DenseSet<CLASS *, CLASS##Info> CLASS##s;
1744#include "llvm/IR/Metadata.def"
1745
1746 // Optional map for looking up composite types by identifier.
1747 std::optional<DenseMap<const MDString *, DICompositeType *>> DITypeMap;
1748
1749 // MDNodes may be uniqued or not uniqued. When they're not uniqued, they
1750 // aren't in the MDNodeSet, but they're still shared between objects, so no
1751 // one object can destroy them. Keep track of them here so we can delete
1752 // them on context teardown.
1753 std::vector<MDNode *> DistinctMDNodes;
1754
1755 // Temporary nodes are caller-owned, but track live ones for persistent
1756 // metadata print IDs.
1758
1759 // ConstantRangeListAttributeImpl is a TrailingObjects/ArrayRef of
1760 // ConstantRange. Since this is a dynamically sized class, it's not
1761 // possible to use SpecificBumpPtrAllocator. Instead, we use normal Alloc
1762 // for allocation and record all allocated pointers in this vector. In the
1763 // LLVMContext destructor, call the destuctors of everything in the vector.
1764 std::vector<ConstantRangeListAttributeImpl *> ConstantRangeListAttributes;
1765
1767
1770
1773
1776
1778
1780
1782
1784
1786
1788
1790
1792
1794
1796
1798
1801
1804
1805 // Basic type instances.
1811
1812 std::unique_ptr<ConstantTokenNone> TheNoneToken;
1813
1818
1821
1828
1831
1834 PointerType *AS0PointerType = nullptr; // AddrSpace = 0
1837
1838 /// ValueHandles - This map keeps track of all of the value handles that are
1839 /// watching a Value*. The Value::HasValueHandle bit is used to know
1840 /// whether or not a value has an entry in this map.
1843
1844 /// CustomMDKindNames - Map to hold the metadata string to ID mapping.
1846
1847 /// Collection of metadata attachments in this context.
1849 /// Index of first free Metadatas entry, linked list via MDAttachment::Next.
1851 /// Number of currently unused metadata entries. Only used/updated in debug
1852 /// builds to ensure that all metadata attachments are properly freed.
1854
1855 /// Collection of per-GlobalObject sections used in this context.
1857
1858 /// Collection of per-GlobalValue partitions used in this context.
1860
1863
1864 /// DiscriminatorTable - This table maps file:line locations to an
1865 /// integer representing the next DWARF path discriminator to assign to
1866 /// instructions in different blocks at the same location.
1868
1869 /// A set of interned tags for operand bundles. The StringMap maps
1870 /// bundle tags to their IDs.
1871 ///
1872 /// \see LLVMContext::getOperandBundleTagID
1874
1878
1879 /// A set of interned synchronization scopes. The StringMap maps
1880 /// synchronization scope names to their respective synchronization scope IDs.
1882
1883 /// getOrInsertSyncScopeID - Maps synchronization scope name to
1884 /// synchronization scope ID. Every synchronization scope registered with
1885 /// LLVMContext has unique ID except pre-defined ones.
1887
1888 /// getSyncScopeNames - Populates client supplied SmallVector with
1889 /// synchronization scope names registered with LLVMContext. Synchronization
1890 /// scope names are ordered by increasing synchronization scope IDs.
1892
1893 /// getSyncScopeName - Returns the name of a SyncScope::ID
1894 /// registered with LLVMContext, if any.
1895 std::optional<StringRef> getSyncScopeName(SyncScope::ID Id) const;
1896
1897 /// Maintain the GC name for each function.
1898 ///
1899 /// This saves allocating an additional word in Function for programs which
1900 /// do not use GC (i.e., most programs) at the cost of increased overhead for
1901 /// clients which do use GC.
1903
1904 /// Flag to indicate if Value (other than GlobalValue) retains their name or
1905 /// not.
1906 bool DiscardValueNames = false;
1907
1910
1911 mutable OptPassGate *OPG = nullptr;
1912
1913 /// Access the object which can disable optional passes and individual
1914 /// optimizations at compile time.
1915 OptPassGate &getOptPassGate() const;
1916
1917 /// Set the object which can disable optional passes and individual
1918 /// optimizations at compile time.
1919 ///
1920 /// The lifetime of the object must be guaranteed to extend as long as the
1921 /// LLVMContext is used by compilation.
1923
1924 /// Mapping of blocks to collections of "trailing" DbgVariableRecords. As part
1925 /// of the "RemoveDIs" project, debug-info variable location records are going
1926 /// to cease being instructions... which raises the problem of where should
1927 /// they be recorded when we remove the terminator of a blocks, such as:
1928 ///
1929 /// %foo = add i32 0, 0
1930 /// br label %bar
1931 ///
1932 /// If the branch is removed, a legitimate transient state while editing a
1933 /// block, any debug-records between those two instructions will not have a
1934 /// location. Each block thus records any DbgVariableRecord records that
1935 /// "trail" in such a way. These are stored in LLVMContext because typically
1936 /// LLVM only edits a small number of blocks at a time, so there's no need to
1937 /// bloat BasicBlock with such a data structure.
1939
1940 // Set, get and delete operations for TrailingDbgRecords.
1945
1949
1951
1952 std::string DefaultTargetCPU;
1954
1956
1957 /// The next available source atom group number. The front end is responsible
1958 /// for assigning source atom numbers, but certain optimisations need to
1959 /// assign new group numbers to a set of instructions. Most often code
1960 /// duplication optimisations like loop unroll. Tracking a global maximum
1961 /// value means we can know (cheaply) we're never using a group number that's
1962 /// already used within this function.
1963 ///
1964 /// Start a 1 because 0 means the source location isn't part of an atom group.
1966};
1967
1968} // end namespace llvm
1969
1970#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.
unsigned uint64_t
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.
This file defines various helper methods and classes used by LLVMContextImpl for creating and managin...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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
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.
static const unsigned NumEnumAttrKinds
Definition Attributes.h:135
LLVM Basic Block Representation.
Definition BasicBlock.h:62
Class to represent byte types.
Constant * getValue() const
Definition Metadata.h:556
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).
A sequence of DILayerLoc entries.
A single intermediate-IR layer location.
Debug lexical block.
Represents a module in the programming language, for example, a Clang module, or a Fortran module.
Debug lexical block.
A property of a class or structure.
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:281
A set of classes that contain the value of the attribute object.
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
UniquingSet< TypeAttributeImpl > TypeAttrs
DenseMap< Metadata *, MetadataAsValue * > MetadataAsValues
DenseMap< unsigned, ByteType * > ByteTypes
ConstantUniqueMap< ConstantArray > ArrayConstantsTy
EnumAttributeImpl * EnumAttrs[Attribute::NumEnumAttrKinds]
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
void setMetadataPrintID(MDNode *N, uint32_t ID)
DenseMap< Type *, std::unique_ptr< PoisonValue > > PVConstants
DenseMap< APInt, std::unique_ptr< ConstantInt > > IntConstants
ConstantByte * TheFalseByteVal
std::vector< MDNode * > DistinctMDNodes
UniquingSet< IntAttributeImpl > IntAttrs
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
UniquingSet< AttributeSetNode > AttrsSetNodes
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 getAllMetadataNodes(SmallVectorImpl< MDNode * > &Nodes) const
cl::LibraryOptionsContext LibraryOptions
void deleteTrailingDbgRecords(BasicBlock *B)
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
uint32_t getMetadataPrintID(const MDNode *N) const
StringMap< StructType * > NamedStructTypes
UniquingSet< StringAttributeImpl > StringAttrs
DenseMap< Value *, ValueHandleHead > ValueHandlesTy
ValueHandles - This map keeps track of all of the value handles that are watching a Value*.
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...
DenseSet< MDNode * > TemporaryMDNodes
uint64_t NextAtomGroup
The next available source atom group number.
LLVMContextImpl(LLVMContext &C)
DenseMap< const GlobalValue *, DSOLocalEquivalent * > DSOLocalEquivalents
UniquingSet< AttributeListImpl > AttrsLists
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:71
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:1081
A single uniqued string.
Definition Metadata.h:733
Tuple of metadata.
Definition Metadata.h:1496
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
PointerIntPair - This class implements a pair of a pointer and small integer.
void setPointer(PointerTy PtrVal) &
void * getOpaqueValue() const
static PointerIntPair getFromOpaqueValue(void *V)
PointerTy getPointer() const
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:398
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:129
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
A uniquing set that compares nodes against a typed key rather than a serialized FoldingSetNodeID.
Definition FoldingSet.h:696
This is the common base class of value handles.
Definition ValueHandle.h:30
ValueHandleBase ** getAddress()
ValueHandleHead & operator=(const ValueHandleHead &)=delete
static TaggedPtr exchange(ValueHandleBase **Slot, ValueHandleBase *NewPtr)
ValueHandleBase * get() const
ValueHandleHead(const ValueHandleHead &)=delete
ValueHandleHead & operator=(ValueHandleHead &&)=delete
Base class of all SIMD vector types.
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
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
@ Other
Any other memory.
Definition ModRef.h:68
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:1933
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:307
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:391
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
Definition Hashing.h:287
FoldingSetImpl< T, Trait > FoldingSet
This template class is used to instantiate a specialized implementation of the folding set to the nod...
Definition FoldingSet.h:558
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
#define N
KeyTy(const ArrayRef< Type * > &E, bool P)
bool operator==(const KeyTy &that) const
bool operator!=(const KeyTy &that) const
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 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)
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
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)
static unsigned calculateHash(DILayerLocList *N)
MDNodeKeyImpl(ArrayRef< Metadata * > Ops)
MDNodeKeyImpl(const DILayerLocList *N)
bool isKeyOf(const DILayerLocList *RHS) const
bool isKeyOf(const DILayerLoc *RHS) const
MDNodeKeyImpl(Metadata *Kind, Metadata *File, unsigned Line, uint16_t Column)
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, Metadata *IRLayers)
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(MDString *Name, Metadata *File, unsigned Line, Metadata *Type, Metadata *BackingStorage)
bool isKeyOf(const DIProperty *RHS) const
bool isKeyOf(const DIStringType *RHS) const
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *StringLength, Metadata *StringLengthExp, Metadata *StringLocationExp, Metadata *SizeInBits, uint32_t AlignInBits, unsigned Encoding, Metadata *CharType)
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)