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"
46#include <algorithm>
47#include <cassert>
48#include <cstddef>
49#include <cstdint>
50#include <memory>
51#include <optional>
52#include <string>
53#include <utility>
54#include <vector>
55
56namespace llvm {
57
58class BasicBlock;
60class DbgMarker;
61class ElementCount;
62class Function;
63class GlobalObject;
64class GlobalValue;
65class InlineAsm;
67class OptPassGate;
68namespace remarks {
69class RemarkStreamer;
70}
71template <typename T> class StringMapEntry;
72class StringRef;
74class ValueHandleBase;
75
76template <> struct DenseMapInfo<APFloat> {
77 static unsigned getHashValue(const APFloat &Key) {
78 return static_cast<unsigned>(hash_value(Key));
79 }
80
81 static bool isEqual(const APFloat &LHS, const APFloat &RHS) {
82 return LHS.bitwiseIsEqual(RHS);
83 }
84};
85
87 struct KeyTy {
90
91 KeyTy(const ArrayRef<Type *> &E, bool P) : ETypes(E), isPacked(P) {}
92
93 KeyTy(const StructType *ST)
94 : ETypes(ST->elements()), isPacked(ST->isPacked()) {}
95
96 bool operator==(const KeyTy &that) const {
97 if (isPacked != that.isPacked)
98 return false;
99 if (ETypes != that.ETypes)
100 return false;
101 return true;
102 }
103 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
104 };
105
106 static unsigned getHashValue(const KeyTy &Key) {
107 return hash_combine(hash_combine_range(Key.ETypes), Key.isPacked);
108 }
109
110 static unsigned getHashValue(const StructType *ST) {
111 return getHashValue(KeyTy(ST));
112 }
113
114 static bool isEqual(const KeyTy &LHS, const StructType *RHS) {
115 return LHS == KeyTy(RHS);
116 }
117
118 static bool isEqual(const StructType *LHS, const StructType *RHS) {
119 return LHS == RHS;
120 }
121};
122
124 struct KeyTy {
128
129 KeyTy(const Type *R, const ArrayRef<Type *> &P, bool V)
130 : ReturnType(R), Params(P), isVarArg(V) {}
132 : ReturnType(FT->getReturnType()), Params(FT->params()),
133 isVarArg(FT->isVarArg()) {}
134
135 bool operator==(const KeyTy &that) const {
136 if (ReturnType != that.ReturnType)
137 return false;
138 if (isVarArg != that.isVarArg)
139 return false;
140 if (Params != that.Params)
141 return false;
142 return true;
143 }
144 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
145 };
146
147 static unsigned getHashValue(const KeyTy &Key) {
148 return hash_combine(Key.ReturnType, hash_combine_range(Key.Params),
149 Key.isVarArg);
150 }
151
152 static unsigned getHashValue(const FunctionType *FT) {
153 return getHashValue(KeyTy(FT));
154 }
155
156 static bool isEqual(const KeyTy &LHS, const FunctionType *RHS) {
157 return LHS == KeyTy(RHS);
158 }
159
160 static bool isEqual(const FunctionType *LHS, const FunctionType *RHS) {
161 return LHS == RHS;
162 }
163};
164
166 struct KeyTy {
170
172 : Name(N), TypeParams(TP), IntParams(IP) {}
174 : Name(TT->getName()), TypeParams(TT->type_params()),
175 IntParams(TT->int_params()) {}
176
177 bool operator==(const KeyTy &that) const {
178 return Name == that.Name && TypeParams == that.TypeParams &&
179 IntParams == that.IntParams;
180 }
181 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
182 };
183
184 static unsigned getHashValue(const KeyTy &Key) {
185 return hash_combine(Key.Name, hash_combine_range(Key.TypeParams),
186 hash_combine_range(Key.IntParams));
187 }
188
189 static unsigned getHashValue(const TargetExtType *FT) {
190 return getHashValue(KeyTy(FT));
191 }
192
193 static bool isEqual(const KeyTy &LHS, const TargetExtType *RHS) {
194 return LHS == KeyTy(RHS);
195 }
196
197 static bool isEqual(const TargetExtType *LHS, const TargetExtType *RHS) {
198 return LHS == RHS;
199 }
200};
201
202/// Structure for hashing arbitrary MDNode operands.
206 unsigned Hash;
207
208protected:
210 : RawOps(Ops), Hash(calculateHash(Ops)) {}
211
212 template <class NodeTy>
213 MDNodeOpsKey(const NodeTy *N, unsigned Offset = 0)
214 : Ops(N->op_begin() + Offset, N->op_end()), Hash(N->getHash()) {}
215
216 template <class NodeTy>
217 bool compareOps(const NodeTy *RHS, unsigned Offset = 0) const {
218 if (getHash() != RHS->getHash())
219 return false;
220
221 assert((RawOps.empty() || Ops.empty()) && "Two sets of operands?");
222 return RawOps.empty() ? compareOps(Ops, RHS, Offset)
223 : compareOps(RawOps, RHS, Offset);
224 }
225
226 static unsigned calculateHash(MDNode *N, unsigned Offset = 0);
227
228private:
229 template <class T>
230 static bool compareOps(ArrayRef<T> Ops, const MDNode *RHS, unsigned Offset) {
231 if (Ops.size() != RHS->getNumOperands() - Offset)
232 return false;
233 return std::equal(Ops.begin(), Ops.end(), RHS->op_begin() + Offset);
234 }
235
236 static unsigned calculateHash(ArrayRef<Metadata *> Ops);
237
238public:
239 unsigned getHash() const { return Hash; }
240};
241
242template <class NodeTy> struct MDNodeKeyImpl;
243
244/// Configuration point for MDNodeInfo::isEqual().
245template <class NodeTy> struct MDNodeSubsetEqualImpl {
247
248 static bool isSubsetEqual(const KeyTy &LHS, const NodeTy *RHS) {
249 return false;
250 }
251
252 static bool isSubsetEqual(const NodeTy *LHS, const NodeTy *RHS) {
253 return false;
254 }
255};
256
257/// DenseMapInfo for MDTuple.
258///
259/// Note that we don't need the is-function-local bit, since that's implicit in
260/// the operands.
261template <> struct MDNodeKeyImpl<MDTuple> : MDNodeOpsKey {
264
265 bool isKeyOf(const MDTuple *RHS) const { return compareOps(RHS); }
266
267 unsigned getHashValue() const { return getHash(); }
268
269 static unsigned calculateHash(MDTuple *N) {
271 }
272};
273
274/// DenseMapInfo for DILocation.
275template <> struct MDNodeKeyImpl<DILocation> {
281 unsigned Line;
284
291
293 : Scope(L->getRawScope()), InlinedAt(L->getRawInlinedAt()),
294 IRLayers(L->getRawIRLayers()), AtomGroup(L->getAtomGroup()),
295 AtomRank(L->getAtomRank()), Line(L->getLine()), Column(L->getColumn()),
296 ImplicitCode(L->isImplicitCode()) {}
297
298 bool isKeyOf(const DILocation *RHS) const {
299 return Line == RHS->getLine() && Column == RHS->getColumn() &&
300 Scope == RHS->getRawScope() && InlinedAt == RHS->getRawInlinedAt() &&
301 ImplicitCode == RHS->isImplicitCode() &&
302 AtomGroup == RHS->getAtomGroup() && AtomRank == RHS->getAtomRank() &&
303 IRLayers == RHS->getRawIRLayers();
304 }
305
306 unsigned getHashValue() const {
307 uint64_t LineColumnAndImplicitCode =
308 Line | (uint64_t(Column) << 32) | (uint64_t(ImplicitCode) << 48);
309 // Hashing AtomGroup and AtomRank substantially impacts performance whether
310 // Key Instructions is enabled or not. We can't detect whether it's enabled
311 // here cheaply; avoiding hashing zero values is a good approximation. This
312 // affects Key Instruction builds too, but any potential costs incurred by
313 // messing with the hash distribution* appear to still be massively
314 // outweighed by the overall compile time savings by performing this check.
315 // * (hash_combine(x) != hash_combine(x, 0))
316 // irlayers is likewise rare, so it is only mixed in when present to keep
317 // the common no-layers hashes unchanged.
318 if (AtomGroup || AtomRank) {
319 if (IRLayers)
320 return hash_combine(LineColumnAndImplicitCode, Scope, InlinedAt,
321 AtomGroup | (uint64_t(AtomRank) << 61), IRLayers);
322 return hash_combine(LineColumnAndImplicitCode, Scope, InlinedAt,
323 AtomGroup | (uint64_t(AtomRank) << 61));
324 }
325 if (IRLayers)
326 return hash_combine(LineColumnAndImplicitCode, Scope, InlinedAt,
327 IRLayers);
328 return hash_combine(LineColumnAndImplicitCode, Scope, InlinedAt);
329 }
330};
331
332/// DenseMapInfo for DILayerLoc.
333template <> struct MDNodeKeyImpl<DILayerLoc> {
336 unsigned Line;
338
342 : Kind(N->getRawKind()), File(N->getRawFile()), Line(N->getLine()),
343 Column(N->getColumn()) {}
344
345 bool isKeyOf(const DILayerLoc *RHS) const {
346 return Kind == RHS->getRawKind() && File == RHS->getRawFile() &&
347 Line == RHS->getLine() && Column == RHS->getColumn();
348 }
349
350 unsigned getHashValue() const {
351 return hash_combine(Kind, File, Line, Column);
352 }
353};
354
355/// DenseMapInfo for DILayerLocList.
359
360 bool isKeyOf(const DILayerLocList *RHS) const { return compareOps(RHS); }
361
362 unsigned getHashValue() const { return getHash(); }
363
364 static unsigned calculateHash(DILayerLocList *N) {
366 }
367};
368
369/// DenseMapInfo for GenericDINode.
371 unsigned Tag;
373
375 : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {}
377 : MDNodeOpsKey(N, 1), Tag(N->getTag()), Header(N->getRawHeader()) {}
378
379 bool isKeyOf(const GenericDINode *RHS) const {
380 return Tag == RHS->getTag() && Header == RHS->getRawHeader() &&
381 compareOps(RHS, 1);
382 }
383
384 unsigned getHashValue() const { return hash_combine(getHash(), Tag, Header); }
385
386 static unsigned calculateHash(GenericDINode *N) {
388 }
389};
390
391template <> struct MDNodeKeyImpl<DISubrange> {
396
402 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
403 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
404
405 bool isKeyOf(const DISubrange *RHS) const {
406 auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool {
407 if (Node1 == Node2)
408 return true;
409
412 if (MD1 && MD2) {
415 if (CV1->getSExtValue() == CV2->getSExtValue())
416 return true;
417 }
418 return false;
419 };
420
421 return BoundsEqual(CountNode, RHS->getRawCountNode()) &&
422 BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
423 BoundsEqual(UpperBound, RHS->getRawUpperBound()) &&
424 BoundsEqual(Stride, RHS->getRawStride());
425 }
426
427 unsigned getHashValue() const {
428 if (CountNode)
430 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
433 }
434};
435
436template <> struct MDNodeKeyImpl<DIGenericSubrange> {
441
447 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
448 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
449
450 bool isKeyOf(const DIGenericSubrange *RHS) const {
451 return (CountNode == RHS->getRawCountNode()) &&
452 (LowerBound == RHS->getRawLowerBound()) &&
453 (UpperBound == RHS->getRawUpperBound()) &&
454 (Stride == RHS->getRawStride());
455 }
456
457 unsigned getHashValue() const {
459 if (CountNode && MD)
460 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
463 }
464};
465
466template <> struct MDNodeKeyImpl<DIEnumerator> {
470
477 : Value(N->getValue()), Name(N->getRawName()),
478 IsUnsigned(N->isUnsigned()) {}
479
480 bool isKeyOf(const DIEnumerator *RHS) const {
481 return Value.getBitWidth() == RHS->getValue().getBitWidth() &&
482 Value == RHS->getValue() && IsUnsigned == RHS->isUnsigned() &&
483 Name == RHS->getRawName();
484 }
485
486 unsigned getHashValue() const { return hash_combine(Value, Name); }
487};
488
489template <> struct MDNodeKeyImpl<DIBasicType> {
490 unsigned Tag;
493 unsigned LineNo;
497 unsigned Encoding;
500 unsigned Flags;
501
511 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
512 LineNo(N->getLine()), Scope(N->getRawScope()),
513 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
514 Encoding(N->getEncoding()),
515 NumExtraInhabitants(N->getNumExtraInhabitants()),
516 DataSizeInBits(N->getDataSizeInBits()), Flags(N->getFlags()) {}
517
518 bool isKeyOf(const DIBasicType *RHS) const {
519 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
520 File == RHS->getRawFile() && LineNo == RHS->getLine() &&
521 Scope == RHS->getRawScope() &&
522 SizeInBits == RHS->getRawSizeInBits() &&
523 AlignInBits == RHS->getAlignInBits() &&
524 Encoding == RHS->getEncoding() &&
525 NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
526 DataSizeInBits == RHS->getDataSizeInBits() &&
527 Flags == RHS->getFlags();
528 }
529
530 unsigned getHashValue() const {
532 Encoding);
533 }
534};
535
536template <> struct MDNodeKeyImpl<DIFixedPointType> {
537 unsigned Tag;
540 unsigned LineNo;
544 unsigned Encoding;
545 unsigned Flags;
546 unsigned Kind;
550
560 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
561 LineNo(N->getLine()), Scope(N->getRawScope()),
562 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
563 Encoding(N->getEncoding()), Flags(N->getFlags()), Kind(N->getKind()),
564 Factor(N->getFactorRaw()), Numerator(N->getNumeratorRaw()),
565 Denominator(N->getDenominatorRaw()) {}
566
567 bool isKeyOf(const DIFixedPointType *RHS) const {
568 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
569 LineNo == RHS->getLine() && Scope == RHS->getRawScope() &&
570 SizeInBits == RHS->getRawSizeInBits() &&
571 AlignInBits == RHS->getAlignInBits() && Kind == RHS->getKind() &&
572 (RHS->isRational() ? (Numerator == RHS->getNumerator() &&
573 Denominator == RHS->getDenominator())
574 : Factor == RHS->getFactor());
575 }
576
577 unsigned getHashValue() const {
580 }
581};
582
583template <> struct MDNodeKeyImpl<DIStringType> {
584 unsigned Tag;
591 unsigned Encoding;
593
603 : Tag(N->getTag()), Name(N->getRawName()),
604 StringLength(N->getRawStringLength()),
605 StringLengthExp(N->getRawStringLengthExp()),
606 StringLocationExp(N->getRawStringLocationExp()),
607 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
608 Encoding(N->getEncoding()), CharType(N->getRawCharType()) {}
609
610 bool isKeyOf(const DIStringType *RHS) const {
611 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
612 StringLength == RHS->getRawStringLength() &&
613 StringLengthExp == RHS->getRawStringLengthExp() &&
614 StringLocationExp == RHS->getRawStringLocationExp() &&
615 SizeInBits == RHS->getRawSizeInBits() &&
616 AlignInBits == RHS->getAlignInBits() &&
617 Encoding == RHS->getEncoding() && CharType == RHS->getRawCharType();
618 }
619 unsigned getHashValue() const {
620 // Intentionally computes the hash on a subset of the operands for
621 // performance reason. The subset has to be significant enough to avoid
622 // collision "most of the time". There is no correctness issue in case of
623 // collision because of the full check above.
625 }
626};
627
628template <> struct MDNodeKeyImpl<DIDerivedType> {
629 unsigned Tag;
630 MDString *Name;
631 Metadata *File;
632 unsigned Line;
633 Metadata *Scope;
635 Metadata *SizeInBits;
636 Metadata *OffsetInBits;
637 uint32_t AlignInBits;
638 std::optional<unsigned> DWARFAddressSpace;
639 std::optional<DIDerivedType::PtrAuthData> PtrAuthData;
640 unsigned Flags;
642 Metadata *Annotations;
643
644 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
645 Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
646 uint32_t AlignInBits, Metadata *OffsetInBits,
647 std::optional<unsigned> DWARFAddressSpace,
648 std::optional<DIDerivedType::PtrAuthData> PtrAuthData,
649 unsigned Flags, Metadata *ExtraData, Metadata *Annotations)
650 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
651 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
652 AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace),
653 PtrAuthData(PtrAuthData), Flags(Flags), ExtraData(ExtraData),
654 Annotations(Annotations) {}
655 MDNodeKeyImpl(const DIDerivedType *N)
656 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
657 Line(N->getLine()), Scope(N->getRawScope()),
658 BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
659 OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
660 DWARFAddressSpace(N->getDWARFAddressSpace()),
661 PtrAuthData(N->getPtrAuthData()), Flags(N->getFlags()),
662 ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {}
663
664 bool isKeyOf(const DIDerivedType *RHS) const {
665 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
666 File == RHS->getRawFile() && Line == RHS->getLine() &&
667 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
668 SizeInBits == RHS->getRawSizeInBits() &&
669 AlignInBits == RHS->getAlignInBits() &&
670 OffsetInBits == RHS->getRawOffsetInBits() &&
671 DWARFAddressSpace == RHS->getDWARFAddressSpace() &&
672 PtrAuthData == RHS->getPtrAuthData() && Flags == RHS->getFlags() &&
673 ExtraData == RHS->getRawExtraData() &&
674 Annotations == RHS->getRawAnnotations();
675 }
676
677 unsigned getHashValue() const {
678 // If this is a member inside an ODR type, only hash the type and the name.
679 // Otherwise the hash will be stronger than
680 // MDNodeSubsetEqualImpl::isODRMember().
681 if (Tag == dwarf::DW_TAG_member && Name)
682 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
683 if (CT->getRawIdentifier())
684 return hash_combine(Name, Scope);
685
686 // Intentionally computes the hash on a subset of the operands for
687 // performance reason. The subset has to be significant enough to avoid
688 // collision "most of the time". There is no correctness issue in case of
689 // collision because of the full check above.
690 return hash_combine(Tag, Name, File, Line, Scope, BaseType, Flags);
691 }
692};
693
694template <> struct MDNodeKeyImpl<DISubrangeType> {
697 unsigned Line;
701 unsigned Flags;
707
717 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
718 Scope(N->getRawScope()), SizeInBits(N->getRawSizeInBits()),
719 AlignInBits(N->getAlignInBits()), Flags(N->getFlags()),
720 BaseType(N->getRawBaseType()), LowerBound(N->getRawLowerBound()),
721 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()),
722 Bias(N->getRawBias()) {}
723
724 bool isKeyOf(const DISubrangeType *RHS) const {
725 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
726 Line == RHS->getLine() && Scope == RHS->getRawScope() &&
727 SizeInBits == RHS->getRawSizeInBits() &&
728 AlignInBits == RHS->getAlignInBits() && Flags == RHS->getFlags() &&
729 BaseType == RHS->getRawBaseType() &&
730 LowerBound == RHS->getRawLowerBound() &&
731 UpperBound == RHS->getRawUpperBound() &&
732 Stride == RHS->getRawStride() && Bias == RHS->getRawBias();
733 }
734
735 unsigned getHashValue() const {
738 }
739};
740
743
744 static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) {
745 return isODRMember(LHS.Tag, LHS.Scope, LHS.Name, RHS);
746 }
747
748 static bool isSubsetEqual(const DIDerivedType *LHS,
749 const DIDerivedType *RHS) {
750 return isODRMember(LHS->getTag(), LHS->getRawScope(), LHS->getRawName(),
751 RHS);
752 }
753
754 /// Subprograms compare equal if they declare the same function in an ODR
755 /// type.
756 static bool isODRMember(unsigned Tag, const Metadata *Scope,
757 const MDString *Name, const DIDerivedType *RHS) {
758 // Check whether the LHS is eligible.
759 if (Tag != dwarf::DW_TAG_member || !Name)
760 return false;
761
762 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
763 if (!CT || !CT->getRawIdentifier())
764 return false;
765
766 // Compare to the RHS.
767 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
768 Scope == RHS->getRawScope();
769 }
770};
771
772template <> struct MDNodeKeyImpl<DICompositeType> {
773 unsigned Tag;
776 unsigned Line;
782 unsigned Flags;
784 unsigned RuntimeLang;
797
818 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
819 Line(N->getLine()), Scope(N->getRawScope()),
820 BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
821 OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
822 Flags(N->getFlags()), Elements(N->getRawElements()),
823 RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()),
824 TemplateParams(N->getRawTemplateParams()),
825 Identifier(N->getRawIdentifier()),
826 Discriminator(N->getRawDiscriminator()),
827 DataLocation(N->getRawDataLocation()),
828 Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()),
829 Rank(N->getRawRank()), Annotations(N->getRawAnnotations()),
830 Specification(N->getSpecification()),
831 NumExtraInhabitants(N->getNumExtraInhabitants()),
832 BitStride(N->getRawBitStride()) {}
833
834 bool isKeyOf(const DICompositeType *RHS) const {
835 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
836 File == RHS->getRawFile() && Line == RHS->getLine() &&
837 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
838 SizeInBits == RHS->getRawSizeInBits() &&
839 AlignInBits == RHS->getAlignInBits() &&
840 OffsetInBits == RHS->getRawOffsetInBits() &&
841 Flags == RHS->getFlags() && Elements == RHS->getRawElements() &&
842 RuntimeLang == RHS->getRuntimeLang() &&
843 VTableHolder == RHS->getRawVTableHolder() &&
844 TemplateParams == RHS->getRawTemplateParams() &&
845 Identifier == RHS->getRawIdentifier() &&
846 Discriminator == RHS->getRawDiscriminator() &&
847 DataLocation == RHS->getRawDataLocation() &&
848 Associated == RHS->getRawAssociated() &&
849 Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() &&
850 Annotations == RHS->getRawAnnotations() &&
851 Specification == RHS->getSpecification() &&
852 NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
853 BitStride == RHS->getRawBitStride();
854 }
855
856 unsigned getHashValue() const {
857 // Intentionally computes the hash on a subset of the operands for
858 // performance reason. The subset has to be significant enough to avoid
859 // collision "most of the time". There is no correctness issue in case of
860 // collision because of the full check above.
863 }
864};
865
866template <> struct MDNodeKeyImpl<DISubroutineType> {
867 unsigned Flags;
870
874 : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()) {}
875
876 bool isKeyOf(const DISubroutineType *RHS) const {
877 return Flags == RHS->getFlags() && CC == RHS->getCC() &&
878 TypeArray == RHS->getRawTypeArray();
879 }
880
881 unsigned getHashValue() const { return hash_combine(Flags, CC, TypeArray); }
882};
883
884template <> struct MDNodeKeyImpl<DIFile> {
887 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum;
889
896 : Filename(N->getRawFilename()), Directory(N->getRawDirectory()),
897 Checksum(N->getRawChecksum()), Source(N->getRawSource()) {}
898
899 bool isKeyOf(const DIFile *RHS) const {
900 return Filename == RHS->getRawFilename() &&
901 Directory == RHS->getRawDirectory() &&
902 Checksum == RHS->getRawChecksum() && Source == RHS->getRawSource();
903 }
904
905 unsigned getHashValue() const {
906 return hash_combine(Filename, Directory, Checksum ? Checksum->Kind : 0,
907 Checksum ? Checksum->Value : nullptr, Source);
908 }
909};
910
911template <> struct MDNodeKeyImpl<DISubprogram> {
912 Metadata *Scope;
913 MDString *Name;
914 MDString *LinkageName;
915 Metadata *File;
916 unsigned Line;
917 unsigned ScopeLine;
918 Metadata *Type;
919 Metadata *ContainingType;
920 unsigned VirtualIndex;
921 int ThisAdjustment;
922 unsigned Flags;
923 unsigned SPFlags;
924 Metadata *Unit;
925 Metadata *TemplateParams;
926 Metadata *Declaration;
927 Metadata *RetainedNodes;
928 Metadata *ThrownTypes;
929 Metadata *Annotations;
930 MDString *TargetFuncName;
931 bool UsesKeyInstructions;
932
933 MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
934 Metadata *File, unsigned Line, Metadata *Type,
935 unsigned ScopeLine, Metadata *ContainingType,
936 unsigned VirtualIndex, int ThisAdjustment, unsigned Flags,
937 unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams,
938 Metadata *Declaration, Metadata *RetainedNodes,
939 Metadata *ThrownTypes, Metadata *Annotations,
940 MDString *TargetFuncName, bool UsesKeyInstructions)
941 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
942 Line(Line), ScopeLine(ScopeLine), Type(Type),
943 ContainingType(ContainingType), VirtualIndex(VirtualIndex),
944 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags),
945 Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration),
946 RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes),
947 Annotations(Annotations), TargetFuncName(TargetFuncName),
948 UsesKeyInstructions(UsesKeyInstructions) {}
949 MDNodeKeyImpl(const DISubprogram *N)
950 : Scope(N->getRawScope()), Name(N->getRawName()),
951 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
952 Line(N->getLine()), ScopeLine(N->getScopeLine()), Type(N->getRawType()),
953 ContainingType(N->getRawContainingType()),
954 VirtualIndex(N->getVirtualIndex()),
955 ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()),
956 SPFlags(N->getSPFlags()), Unit(N->getRawUnit()),
957 TemplateParams(N->getRawTemplateParams()),
958 Declaration(N->getRawDeclaration()),
959 RetainedNodes(N->getRawRetainedNodes()),
960 ThrownTypes(N->getRawThrownTypes()),
961 Annotations(N->getRawAnnotations()),
962 TargetFuncName(N->getRawTargetFuncName()),
963 UsesKeyInstructions(N->getKeyInstructionsEnabled()) {}
964
965 bool isKeyOf(const DISubprogram *RHS) const {
966 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
967 LinkageName == RHS->getRawLinkageName() &&
968 File == RHS->getRawFile() && Line == RHS->getLine() &&
969 Type == RHS->getRawType() && ScopeLine == RHS->getScopeLine() &&
970 ContainingType == RHS->getRawContainingType() &&
971 VirtualIndex == RHS->getVirtualIndex() &&
972 ThisAdjustment == RHS->getThisAdjustment() &&
973 Flags == RHS->getFlags() && SPFlags == RHS->getSPFlags() &&
974 Unit == RHS->getUnit() &&
975 TemplateParams == RHS->getRawTemplateParams() &&
976 Declaration == RHS->getRawDeclaration() &&
977 RetainedNodes == RHS->getRawRetainedNodes() &&
978 ThrownTypes == RHS->getRawThrownTypes() &&
979 Annotations == RHS->getRawAnnotations() &&
980 TargetFuncName == RHS->getRawTargetFuncName() &&
981 UsesKeyInstructions == RHS->getKeyInstructionsEnabled();
982 }
983
984 bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; }
985
986 unsigned getHashValue() const {
987 // Use the Scope's linkage name instead of using the scope directly, as the
988 // scope may be a temporary one which can replaced, which would produce a
989 // different hash for the same DISubprogram.
990 llvm::StringRef ScopeLinkageName;
991 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
992 if (auto *ID = CT->getRawIdentifier())
993 ScopeLinkageName = ID->getString();
994
995 // If this is a declaration inside an ODR type, only hash the type and the
996 // name. Otherwise the hash will be stronger than
997 // MDNodeSubsetEqualImpl::isDeclarationOfODRMember().
998 if (!isDefinition() && LinkageName &&
1000 return hash_combine(LinkageName, ScopeLinkageName);
1001
1002 // Intentionally computes the hash on a subset of the operands for
1003 // performance reason. The subset has to be significant enough to avoid
1004 // collision "most of the time". There is no correctness issue in case of
1005 // collision because of the full check above.
1006 return hash_combine(Name, ScopeLinkageName, File, Type, Line);
1007 }
1008};
1009
1012
1013 static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) {
1014 return isDeclarationOfODRMember(LHS.isDefinition(), LHS.Scope,
1015 LHS.LinkageName, LHS.TemplateParams, RHS);
1016 }
1017
1018 static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) {
1019 return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(),
1020 LHS->getRawLinkageName(),
1021 LHS->getRawTemplateParams(), RHS);
1022 }
1023
1024 /// Subprograms compare equal if they declare the same function in an ODR
1025 /// type.
1026 static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope,
1027 const MDString *LinkageName,
1028 const Metadata *TemplateParams,
1029 const DISubprogram *RHS) {
1030 // Check whether the LHS is eligible.
1031 if (IsDefinition || !Scope || !LinkageName)
1032 return false;
1033
1034 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
1035 if (!CT || !CT->getRawIdentifier())
1036 return false;
1037
1038 // Compare to the RHS.
1039 // FIXME: We need to compare template parameters here to avoid incorrect
1040 // collisions in mapMetadata when RF_ReuseAndMutateDistinctMDs and a
1041 // ODR-DISubprogram has a non-ODR template parameter (i.e., a
1042 // DICompositeType that does not have an identifier). Eventually we should
1043 // decouple ODR logic from uniquing logic.
1044 return IsDefinition == RHS->isDefinition() && Scope == RHS->getRawScope() &&
1045 LinkageName == RHS->getRawLinkageName() &&
1046 TemplateParams == RHS->getRawTemplateParams();
1047 }
1048};
1049
1050template <> struct MDNodeKeyImpl<DILexicalBlock> {
1053 unsigned Line;
1054 unsigned Column;
1055
1059 : Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()),
1060 Column(N->getColumn()) {}
1061
1062 bool isKeyOf(const DILexicalBlock *RHS) const {
1063 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
1064 Line == RHS->getLine() && Column == RHS->getColumn();
1065 }
1066
1067 unsigned getHashValue() const {
1068 return hash_combine(Scope, File, Line, Column);
1069 }
1070};
1071
1076
1080 : Scope(N->getRawScope()), File(N->getRawFile()),
1081 Discriminator(N->getDiscriminator()) {}
1082
1083 bool isKeyOf(const DILexicalBlockFile *RHS) const {
1084 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
1085 Discriminator == RHS->getDiscriminator();
1086 }
1087
1088 unsigned getHashValue() const {
1090 }
1091};
1092
1093template <> struct MDNodeKeyImpl<DINamespace> {
1097
1101 : Scope(N->getRawScope()), Name(N->getRawName()),
1102 ExportSymbols(N->getExportSymbols()) {}
1103
1104 bool isKeyOf(const DINamespace *RHS) const {
1105 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1106 ExportSymbols == RHS->getExportSymbols();
1107 }
1108
1109 unsigned getHashValue() const { return hash_combine(Scope, Name); }
1110};
1111
1112template <> struct MDNodeKeyImpl<DICommonBlock> {
1117 unsigned LineNo;
1118
1123 : Scope(N->getRawScope()), Decl(N->getRawDecl()), Name(N->getRawName()),
1124 File(N->getRawFile()), LineNo(N->getLineNo()) {}
1125
1126 bool isKeyOf(const DICommonBlock *RHS) const {
1127 return Scope == RHS->getRawScope() && Decl == RHS->getRawDecl() &&
1128 Name == RHS->getRawName() && File == RHS->getRawFile() &&
1129 LineNo == RHS->getLineNo();
1130 }
1131
1132 unsigned getHashValue() const {
1133 return hash_combine(Scope, Decl, Name, File, LineNo);
1134 }
1135};
1136
1137template <> struct MDNodeKeyImpl<DIModule> {
1144 unsigned LineNo;
1146
1154 : File(N->getRawFile()), Scope(N->getRawScope()), Name(N->getRawName()),
1155 ConfigurationMacros(N->getRawConfigurationMacros()),
1156 IncludePath(N->getRawIncludePath()),
1157 APINotesFile(N->getRawAPINotesFile()), LineNo(N->getLineNo()),
1158 IsDecl(N->getIsDecl()) {}
1159
1160 bool isKeyOf(const DIModule *RHS) const {
1161 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1162 ConfigurationMacros == RHS->getRawConfigurationMacros() &&
1163 IncludePath == RHS->getRawIncludePath() &&
1164 APINotesFile == RHS->getRawAPINotesFile() &&
1165 File == RHS->getRawFile() && LineNo == RHS->getLineNo() &&
1166 IsDecl == RHS->getIsDecl();
1167 }
1168
1169 unsigned getHashValue() const {
1171 }
1172};
1173
1178
1182 : Name(N->getRawName()), Type(N->getRawType()),
1183 IsDefault(N->isDefault()) {}
1184
1186 return Name == RHS->getRawName() && Type == RHS->getRawType() &&
1187 IsDefault == RHS->isDefault();
1188 }
1189
1190 unsigned getHashValue() const { return hash_combine(Name, Type, IsDefault); }
1191};
1192
1194 unsigned Tag;
1199
1204 : Tag(N->getTag()), Name(N->getRawName()), Type(N->getRawType()),
1205 IsDefault(N->isDefault()), Value(N->getValue()) {}
1206
1208 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
1209 Type == RHS->getRawType() && IsDefault == RHS->isDefault() &&
1210 Value == RHS->getValue();
1211 }
1212
1213 unsigned getHashValue() const {
1215 }
1216};
1217
1218template <> struct MDNodeKeyImpl<DIGlobalVariable> {
1223 unsigned Line;
1231
1244 : Scope(N->getRawScope()), Name(N->getRawName()),
1245 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
1246 Line(N->getLine()), Type(N->getRawType()),
1247 IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
1248 StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()),
1249 TemplateParams(N->getRawTemplateParams()),
1250 AlignInBits(N->getAlignInBits()), Annotations(N->getRawAnnotations()) {}
1251
1252 bool isKeyOf(const DIGlobalVariable *RHS) const {
1253 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1254 LinkageName == RHS->getRawLinkageName() &&
1255 File == RHS->getRawFile() && Line == RHS->getLine() &&
1256 Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() &&
1257 IsDefinition == RHS->isDefinition() &&
1259 RHS->getRawStaticDataMemberDeclaration() &&
1260 TemplateParams == RHS->getRawTemplateParams() &&
1261 AlignInBits == RHS->getAlignInBits() &&
1262 Annotations == RHS->getRawAnnotations();
1263 }
1264
1265 unsigned getHashValue() const {
1266 // We do not use AlignInBits in hashing function here on purpose:
1267 // in most cases this param for local variable is zero (for function param
1268 // it is always zero). This leads to lots of hash collisions and errors on
1269 // cases with lots of similar variables.
1270 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1271 // generated IR is random for each run and test fails with Align included.
1272 // TODO: make hashing work fine with such situations
1274 IsLocalToUnit, IsDefinition, /* AlignInBits, */
1276 }
1277};
1278
1279template <> struct MDNodeKeyImpl<DILocalVariable> {
1283 unsigned Line;
1285 unsigned Arg;
1286 unsigned Flags;
1289
1296 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1297 Line(N->getLine()), Type(N->getRawType()), Arg(N->getArg()),
1298 Flags(N->getFlags()), AlignInBits(N->getAlignInBits()),
1299 Annotations(N->getRawAnnotations()) {}
1300
1301 bool isKeyOf(const DILocalVariable *RHS) const {
1302 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1303 File == RHS->getRawFile() && Line == RHS->getLine() &&
1304 Type == RHS->getRawType() && Arg == RHS->getArg() &&
1305 Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits() &&
1306 Annotations == RHS->getRawAnnotations();
1307 }
1308
1309 unsigned getHashValue() const {
1310 // We do not use AlignInBits in hashing function here on purpose:
1311 // in most cases this param for local variable is zero (for function param
1312 // it is always zero). This leads to lots of hash collisions and errors on
1313 // cases with lots of similar variables.
1314 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1315 // generated IR is random for each run and test fails with Align included.
1316 // TODO: make hashing work fine with such situations
1318 }
1319};
1320
1321template <> struct MDNodeKeyImpl<DILabel> {
1325 unsigned Line;
1326 unsigned Column;
1328 std::optional<unsigned> CoroSuspendIdx;
1329
1336 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1337 Line(N->getLine()), Column(N->getColumn()),
1338 IsArtificial(N->isArtificial()),
1339 CoroSuspendIdx(N->getCoroSuspendIdx()) {}
1340
1341 bool isKeyOf(const DILabel *RHS) const {
1342 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1343 File == RHS->getRawFile() && Line == RHS->getLine() &&
1344 Column == RHS->getColumn() && IsArtificial == RHS->isArtificial() &&
1345 CoroSuspendIdx == RHS->getCoroSuspendIdx();
1346 }
1347
1348 /// Using name and line to get hash value. It should already be mostly unique.
1349 unsigned getHashValue() const {
1352 }
1353};
1354
1355template <> struct MDNodeKeyImpl<DIExpression> {
1357
1359 MDNodeKeyImpl(const DIExpression *N) : Elements(N->getElements()) {}
1360
1361 bool isKeyOf(const DIExpression *RHS) const {
1362 return Elements == RHS->getElements();
1363 }
1364
1365 unsigned getHashValue() const { return hash_combine_range(Elements); }
1366};
1367
1371
1375 : Variable(N->getRawVariable()), Expression(N->getRawExpression()) {}
1376
1378 return Variable == RHS->getRawVariable() &&
1379 Expression == RHS->getRawExpression();
1380 }
1381
1382 unsigned getHashValue() const { return hash_combine(Variable, Expression); }
1383};
1384
1385template <> struct MDNodeKeyImpl<DIObjCProperty> {
1388 unsigned Line;
1391 unsigned Attributes;
1393
1400 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
1401 GetterName(N->getRawGetterName()), SetterName(N->getRawSetterName()),
1402 Attributes(N->getAttributes()), Type(N->getRawType()) {}
1403
1404 bool isKeyOf(const DIObjCProperty *RHS) const {
1405 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
1406 Line == RHS->getLine() && GetterName == RHS->getRawGetterName() &&
1407 SetterName == RHS->getRawSetterName() &&
1408 Attributes == RHS->getAttributes() && Type == RHS->getRawType();
1409 }
1410
1411 unsigned getHashValue() const {
1413 Type);
1414 }
1415};
1416
1417template <> struct MDNodeKeyImpl<DIProperty> {
1420 unsigned Line;
1423
1429 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
1430 Type(N->getRawType()), BackingStorage(N->getRawBackingStorage()) {}
1431
1432 bool isKeyOf(const DIProperty *RHS) const {
1433 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
1434 Line == RHS->getLine() && Type == RHS->getRawType() &&
1435 BackingStorage == RHS->getRawBackingStorage();
1436 }
1437
1438 unsigned getHashValue() const {
1440 }
1441};
1442
1443template <> struct MDNodeKeyImpl<DIImportedEntity> {
1444 unsigned Tag;
1448 unsigned Line;
1451
1457 : Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()),
1458 File(N->getRawFile()), Line(N->getLine()), Name(N->getRawName()),
1459 Elements(N->getRawElements()) {}
1460
1461 bool isKeyOf(const DIImportedEntity *RHS) const {
1462 return Tag == RHS->getTag() && Scope == RHS->getRawScope() &&
1463 Entity == RHS->getRawEntity() && File == RHS->getFile() &&
1464 Line == RHS->getLine() && Name == RHS->getRawName() &&
1465 Elements == RHS->getRawElements();
1466 }
1467
1468 unsigned getHashValue() const {
1470 }
1471};
1472
1473template <> struct MDNodeKeyImpl<DIMacro> {
1474 unsigned MIType;
1475 unsigned Line;
1478
1482 : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getRawName()),
1483 Value(N->getRawValue()) {}
1484
1485 bool isKeyOf(const DIMacro *RHS) const {
1486 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1487 Name == RHS->getRawName() && Value == RHS->getRawValue();
1488 }
1489
1490 unsigned getHashValue() const {
1491 return hash_combine(MIType, Line, Name, Value);
1492 }
1493};
1494
1495template <> struct MDNodeKeyImpl<DIMacroFile> {
1496 unsigned MIType;
1497 unsigned Line;
1500
1505 : MIType(N->getMacinfoType()), Line(N->getLine()), File(N->getRawFile()),
1506 Elements(N->getRawElements()) {}
1507
1508 bool isKeyOf(const DIMacroFile *RHS) const {
1509 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1510 File == RHS->getRawFile() && Elements == RHS->getRawElements();
1511 }
1512
1513 unsigned getHashValue() const {
1515 }
1516};
1517
1518// DIArgLists are not MDNodes, but we still want to unique them in a DenseSet
1519// based on a hash of their arguments.
1522
1524 DIArgListKeyInfo(const DIArgList *N) : Args(N->getArgs()) {}
1525
1526 bool isKeyOf(const DIArgList *RHS) const { return Args == RHS->getArgs(); }
1527
1528 unsigned getHashValue() const { return hash_combine_range(Args); }
1529};
1530
1531/// DenseMapInfo for DIArgList.
1534
1535 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1536
1537 static unsigned getHashValue(const DIArgList *N) {
1538 return KeyTy(N).getHashValue();
1539 }
1540
1541 static bool isEqual(const KeyTy &LHS, const DIArgList *RHS) {
1542 return LHS.isKeyOf(RHS);
1543 }
1544
1545 static bool isEqual(const DIArgList *LHS, const DIArgList *RHS) {
1546 return LHS == RHS;
1547 }
1548};
1549
1550/// DenseMapInfo for MDNode subclasses.
1551template <class NodeTy> struct MDNodeInfo {
1554
1555 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1556
1557 static unsigned getHashValue(const NodeTy *N) {
1558 return KeyTy(N).getHashValue();
1559 }
1560
1561 static bool isEqual(const KeyTy &LHS, const NodeTy *RHS) {
1562 return SubsetEqualTy::isSubsetEqual(LHS, RHS) || LHS.isKeyOf(RHS);
1563 }
1564
1565 static bool isEqual(const NodeTy *LHS, const NodeTy *RHS) {
1566 if (LHS == RHS)
1567 return true;
1569 }
1570};
1571
1572#define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>;
1573#include "llvm/IR/Metadata.def"
1574
1575/// Single metadata attachment, forms linked list ended by index 0.
1577 unsigned Next = 0;
1578 unsigned MDKind;
1580};
1581
1582/// Head pointer for a Value's ValueHandleBase doubly-linked list, stored in
1583/// LLVMContextImpl::ValueHandles. The first node's PrevPtr points to Head, so
1584/// relocating the bucket refreshes PrevPtr to the new Head address.
1586 // Tag Head with true via PointerIntPair so RemoveFromUseList can
1587 // distinguish ValueHandleHead::Head from an untagged ValueHandleBase::Next
1588 // when accessed through *PrevPtr.
1590
1591 ValueHandleBase *Head =
1592 static_cast<ValueHandleBase *>(TaggedPtr(nullptr, true).getOpaqueValue());
1593
1594public:
1597 }
1598
1599 ValueHandleBase **getAddress() { return &Head; }
1600
1601 // Replace the pointer in *Slot with NewPtr while preserving its tag bit,
1602 // and return the old TaggedPtr.
1603 static TaggedPtr exchange(ValueHandleBase **Slot, ValueHandleBase *NewPtr) {
1604 TaggedPtr Old = TaggedPtr::getFromOpaqueValue(*Slot);
1605 TaggedPtr Updated = Old;
1606 Updated.setPointer(NewPtr);
1607 *Slot = static_cast<ValueHandleBase *>(Updated.getOpaqueValue());
1608 return Old;
1609 }
1610
1611 ValueHandleHead() = default;
1616};
1617
1619public:
1620 /// OwnedModules - The set of modules instantiated in this context, and which
1621 /// will be automatically deleted if this context is deleted.
1623
1624 /// MachineFunctionNums - Keep the next available unique number available for
1625 /// a MachineFunction in given module. Module must in OwnedModules.
1627
1628 /// The main remark streamer used by all the other streamers (e.g. IR, MIR,
1629 /// frontends, etc.). This should only be used by the specific streamers, and
1630 /// never directly.
1631 std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer;
1632
1633 /// The virtual file system used for inputs.
1635
1636 std::unique_ptr<DiagnosticHandler> DiagHandler;
1639 /// The minimum hotness value a diagnostic needs in order to be included in
1640 /// optimization diagnostics.
1641 ///
1642 /// The threshold is an Optional value, which maps to one of the 3 states:
1643 /// 1). 0 => threshold disabled. All emarks will be printed.
1644 /// 2). positive int => manual threshold by user. Remarks with hotness exceed
1645 /// threshold will be printed.
1646 /// 3). None => 'auto' threshold by user. The actual value is not
1647 /// available at command line, but will be synced with
1648 /// hotness threhold from profile summary during
1649 /// compilation.
1650 ///
1651 /// State 1 and 2 are considered as terminal states. State transition is
1652 /// only allowed from 3 to 2, when the threshold is first synced with profile
1653 /// summary. This ensures that the threshold is set only once and stays
1654 /// constant.
1655 ///
1656 /// If threshold option is not specified, it is disabled (0) by default.
1657 std::optional<uint64_t> DiagnosticsHotnessThreshold = 0;
1658
1659 /// The percentage of difference between profiling branch weights and
1660 /// llvm.expect branch weights to tolerate when emiting MisExpect diagnostics
1661 std::optional<uint32_t> DiagnosticsMisExpectTolerance = 0;
1663
1664 /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
1665 std::unique_ptr<LLVMRemarkStreamer> LLVMRS;
1666
1668 void *YieldOpaqueHandle = nullptr;
1669
1671
1675 DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantInt>>
1677
1681 DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantByte>>
1683
1685 DenseMap<std::pair<ElementCount, APFloat>, std::unique_ptr<ConstantFP>>
1687
1695
1700
1702
1704
1706
1708 return N->getHeader().MetadataPrintID;
1709 }
1710
1712 N->getHeader().MetadataPrintID = ID;
1713 }
1714
1715#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
1716 DenseSet<CLASS *, CLASS##Info> CLASS##s;
1717#include "llvm/IR/Metadata.def"
1718
1719 // Optional map for looking up composite types by identifier.
1720 std::optional<DenseMap<const MDString *, DICompositeType *>> DITypeMap;
1721
1722 // MDNodes may be uniqued or not uniqued. When they're not uniqued, they
1723 // aren't in the MDNodeSet, but they're still shared between objects, so no
1724 // one object can destroy them. Keep track of them here so we can delete
1725 // them on context teardown.
1726 std::vector<MDNode *> DistinctMDNodes;
1727
1728 // Temporary nodes are caller-owned, but track live ones for persistent
1729 // metadata print IDs.
1731
1732 // ConstantRangeListAttributeImpl is a TrailingObjects/ArrayRef of
1733 // ConstantRange. Since this is a dynamically sized class, it's not
1734 // possible to use SpecificBumpPtrAllocator. Instead, we use normal Alloc
1735 // for allocation and record all allocated pointers in this vector. In the
1736 // LLVMContext destructor, call the destuctors of everything in the vector.
1737 std::vector<ConstantRangeListAttributeImpl *> ConstantRangeListAttributes;
1738
1740
1743
1746
1749
1751
1753
1755
1757
1759
1761
1763
1765
1767
1769
1771
1774
1777
1778 // Basic type instances.
1784
1785 std::unique_ptr<ConstantTokenNone> TheNoneToken;
1786
1791
1794
1801
1804
1807 PointerType *AS0PointerType = nullptr; // AddrSpace = 0
1810
1811 /// ValueHandles - This map keeps track of all of the value handles that are
1812 /// watching a Value*. The Value::HasValueHandle bit is used to know
1813 /// whether or not a value has an entry in this map.
1816
1817 /// CustomMDKindNames - Map to hold the metadata string to ID mapping.
1819
1820 /// Collection of metadata attachments in this context.
1822 /// Index of first free Metadatas entry, linked list via MDAttachment::Next.
1824 /// Number of currently unused metadata entries. Only used/updated in debug
1825 /// builds to ensure that all metadata attachments are properly freed.
1827
1828 /// Collection of per-GlobalObject sections used in this context.
1830
1831 /// Collection of per-GlobalValue partitions used in this context.
1833
1836
1837 /// A set of interned tags for operand bundles. The StringMap maps
1838 /// bundle tags to their IDs.
1839 ///
1840 /// \see LLVMContext::getOperandBundleTagID
1842
1846
1847 /// A set of interned synchronization scopes. The StringMap maps
1848 /// synchronization scope names to their respective synchronization scope IDs.
1850
1851 /// getOrInsertSyncScopeID - Maps synchronization scope name to
1852 /// synchronization scope ID. Every synchronization scope registered with
1853 /// LLVMContext has unique ID except pre-defined ones.
1855
1856 /// getSyncScopeNames - Populates client supplied SmallVector with
1857 /// synchronization scope names registered with LLVMContext. Synchronization
1858 /// scope names are ordered by increasing synchronization scope IDs.
1860
1861 /// getSyncScopeName - Returns the name of a SyncScope::ID
1862 /// registered with LLVMContext, if any.
1863 std::optional<StringRef> getSyncScopeName(SyncScope::ID Id) const;
1864
1865 /// Maintain the GC name for each function.
1866 ///
1867 /// This saves allocating an additional word in Function for programs which
1868 /// do not use GC (i.e., most programs) at the cost of increased overhead for
1869 /// clients which do use GC.
1871
1872 /// Flag to indicate if Value (other than GlobalValue) retains their name or
1873 /// not.
1874 bool DiscardValueNames = false;
1875
1878
1879 mutable OptPassGate *OPG = nullptr;
1880
1881 /// Access the object which can disable optional passes and individual
1882 /// optimizations at compile time.
1883 OptPassGate &getOptPassGate() const;
1884
1885 /// Set the object which can disable optional passes and individual
1886 /// optimizations at compile time.
1887 ///
1888 /// The lifetime of the object must be guaranteed to extend as long as the
1889 /// LLVMContext is used by compilation.
1891
1892 /// Mapping of blocks to collections of "trailing" DbgVariableRecords. As part
1893 /// of the "RemoveDIs" project, debug-info variable location records are going
1894 /// to cease being instructions... which raises the problem of where should
1895 /// they be recorded when we remove the terminator of a blocks, such as:
1896 ///
1897 /// %foo = add i32 0, 0
1898 /// br label %bar
1899 ///
1900 /// If the branch is removed, a legitimate transient state while editing a
1901 /// block, any debug-records between those two instructions will not have a
1902 /// location. Each block thus records any DbgVariableRecord records that
1903 /// "trail" in such a way. These are stored in LLVMContext because typically
1904 /// LLVM only edits a small number of blocks at a time, so there's no need to
1905 /// bloat BasicBlock with such a data structure.
1907
1908 // Set, get and delete operations for TrailingDbgRecords.
1913
1917
1919
1920 std::string DefaultTargetCPU;
1922
1924
1925 /// The next available source atom group number. The front end is responsible
1926 /// for assigning source atom numbers, but certain optimisations need to
1927 /// assign new group numbers to a set of instructions. Most often code
1928 /// duplication optimisations like loop unroll. Tracking a global maximum
1929 /// value means we can know (cheaply) we're never using a group number that's
1930 /// already used within this function.
1931 ///
1932 /// Start a 1 because 0 means the source location isn't part of an atom group.
1934};
1935
1936} // end namespace llvm
1937
1938#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.
uint64_t 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
Defines the virtual file system interface vfs::FileSystem.
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.
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
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
IntrusiveRefCntPtr< vfs::FileSystem > FS
The virtual file system used for inputs.
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
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:76
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)