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"
44#include <algorithm>
45#include <cassert>
46#include <cstddef>
47#include <cstdint>
48#include <memory>
49#include <optional>
50#include <string>
51#include <utility>
52#include <vector>
53
54namespace llvm {
55
56class BasicBlock;
58class DbgMarker;
59class ElementCount;
60class Function;
61class GlobalObject;
62class GlobalValue;
63class InlineAsm;
65class OptPassGate;
66namespace remarks {
67class RemarkStreamer;
68}
69template <typename T> class StringMapEntry;
70class StringRef;
72class ValueHandleBase;
73
74template <> struct DenseMapInfo<APFloat> {
75 static unsigned getHashValue(const APFloat &Key) {
76 return static_cast<unsigned>(hash_value(Key));
77 }
78
79 static bool isEqual(const APFloat &LHS, const APFloat &RHS) {
80 return LHS.bitwiseIsEqual(RHS);
81 }
82};
83
85 struct KeyTy {
88
89 KeyTy(const ArrayRef<Type *> &E, bool P) : ETypes(E), isPacked(P) {}
90
91 KeyTy(const StructType *ST)
92 : ETypes(ST->elements()), isPacked(ST->isPacked()) {}
93
94 bool operator==(const KeyTy &that) const {
95 if (isPacked != that.isPacked)
96 return false;
97 if (ETypes != that.ETypes)
98 return false;
99 return true;
100 }
101 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
102 };
103
104 static unsigned getHashValue(const KeyTy &Key) {
105 return hash_combine(hash_combine_range(Key.ETypes), Key.isPacked);
106 }
107
108 static unsigned getHashValue(const StructType *ST) {
109 return getHashValue(KeyTy(ST));
110 }
111
112 static bool isEqual(const KeyTy &LHS, const StructType *RHS) {
113 return LHS == KeyTy(RHS);
114 }
115
116 static bool isEqual(const StructType *LHS, const StructType *RHS) {
117 return LHS == RHS;
118 }
119};
120
122 struct KeyTy {
126
127 KeyTy(const Type *R, const ArrayRef<Type *> &P, bool V)
128 : ReturnType(R), Params(P), isVarArg(V) {}
130 : ReturnType(FT->getReturnType()), Params(FT->params()),
131 isVarArg(FT->isVarArg()) {}
132
133 bool operator==(const KeyTy &that) const {
134 if (ReturnType != that.ReturnType)
135 return false;
136 if (isVarArg != that.isVarArg)
137 return false;
138 if (Params != that.Params)
139 return false;
140 return true;
141 }
142 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
143 };
144
145 static unsigned getHashValue(const KeyTy &Key) {
146 return hash_combine(Key.ReturnType, hash_combine_range(Key.Params),
147 Key.isVarArg);
148 }
149
150 static unsigned getHashValue(const FunctionType *FT) {
151 return getHashValue(KeyTy(FT));
152 }
153
154 static bool isEqual(const KeyTy &LHS, const FunctionType *RHS) {
155 return LHS == KeyTy(RHS);
156 }
157
158 static bool isEqual(const FunctionType *LHS, const FunctionType *RHS) {
159 return LHS == RHS;
160 }
161};
162
164 struct KeyTy {
168
170 : Name(N), TypeParams(TP), IntParams(IP) {}
172 : Name(TT->getName()), TypeParams(TT->type_params()),
173 IntParams(TT->int_params()) {}
174
175 bool operator==(const KeyTy &that) const {
176 return Name == that.Name && TypeParams == that.TypeParams &&
177 IntParams == that.IntParams;
178 }
179 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
180 };
181
182 static unsigned getHashValue(const KeyTy &Key) {
183 return hash_combine(Key.Name, hash_combine_range(Key.TypeParams),
184 hash_combine_range(Key.IntParams));
185 }
186
187 static unsigned getHashValue(const TargetExtType *FT) {
188 return getHashValue(KeyTy(FT));
189 }
190
191 static bool isEqual(const KeyTy &LHS, const TargetExtType *RHS) {
192 return LHS == KeyTy(RHS);
193 }
194
195 static bool isEqual(const TargetExtType *LHS, const TargetExtType *RHS) {
196 return LHS == RHS;
197 }
198};
199
200/// Structure for hashing arbitrary MDNode operands.
204 unsigned Hash;
205
206protected:
208 : RawOps(Ops), Hash(calculateHash(Ops)) {}
209
210 template <class NodeTy>
211 MDNodeOpsKey(const NodeTy *N, unsigned Offset = 0)
212 : Ops(N->op_begin() + Offset, N->op_end()), Hash(N->getHash()) {}
213
214 template <class NodeTy>
215 bool compareOps(const NodeTy *RHS, unsigned Offset = 0) const {
216 if (getHash() != RHS->getHash())
217 return false;
218
219 assert((RawOps.empty() || Ops.empty()) && "Two sets of operands?");
220 return RawOps.empty() ? compareOps(Ops, RHS, Offset)
221 : compareOps(RawOps, RHS, Offset);
222 }
223
224 static unsigned calculateHash(MDNode *N, unsigned Offset = 0);
225
226private:
227 template <class T>
228 static bool compareOps(ArrayRef<T> Ops, const MDNode *RHS, unsigned Offset) {
229 if (Ops.size() != RHS->getNumOperands() - Offset)
230 return false;
231 return std::equal(Ops.begin(), Ops.end(), RHS->op_begin() + Offset);
232 }
233
234 static unsigned calculateHash(ArrayRef<Metadata *> Ops);
235
236public:
237 unsigned getHash() const { return Hash; }
238};
239
240template <class NodeTy> struct MDNodeKeyImpl;
241
242/// Configuration point for MDNodeInfo::isEqual().
243template <class NodeTy> struct MDNodeSubsetEqualImpl {
245
246 static bool isSubsetEqual(const KeyTy &LHS, const NodeTy *RHS) {
247 return false;
248 }
249
250 static bool isSubsetEqual(const NodeTy *LHS, const NodeTy *RHS) {
251 return false;
252 }
253};
254
255/// DenseMapInfo for MDTuple.
256///
257/// Note that we don't need the is-function-local bit, since that's implicit in
258/// the operands.
259template <> struct MDNodeKeyImpl<MDTuple> : MDNodeOpsKey {
262
263 bool isKeyOf(const MDTuple *RHS) const { return compareOps(RHS); }
264
265 unsigned getHashValue() const { return getHash(); }
266
267 static unsigned calculateHash(MDTuple *N) {
269 }
270};
271
272/// DenseMapInfo for DILocation.
273template <> struct MDNodeKeyImpl<DILocation> {
279 unsigned Line;
282
289
291 : Scope(L->getRawScope()), InlinedAt(L->getRawInlinedAt()),
292 IRLayers(L->getRawIRLayers()), AtomGroup(L->getAtomGroup()),
293 AtomRank(L->getAtomRank()), Line(L->getLine()), Column(L->getColumn()),
294 ImplicitCode(L->isImplicitCode()) {}
295
296 bool isKeyOf(const DILocation *RHS) const {
297 return Line == RHS->getLine() && Column == RHS->getColumn() &&
298 Scope == RHS->getRawScope() && InlinedAt == RHS->getRawInlinedAt() &&
299 ImplicitCode == RHS->isImplicitCode() &&
300 AtomGroup == RHS->getAtomGroup() && AtomRank == RHS->getAtomRank() &&
301 IRLayers == RHS->getRawIRLayers();
302 }
303
304 unsigned getHashValue() const {
305 uint64_t LineColumnAndImplicitCode =
306 Line | (uint64_t(Column) << 32) | (uint64_t(ImplicitCode) << 48);
307 // Hashing AtomGroup and AtomRank substantially impacts performance whether
308 // Key Instructions is enabled or not. We can't detect whether it's enabled
309 // here cheaply; avoiding hashing zero values is a good approximation. This
310 // affects Key Instruction builds too, but any potential costs incurred by
311 // messing with the hash distribution* appear to still be massively
312 // outweighed by the overall compile time savings by performing this check.
313 // * (hash_combine(x) != hash_combine(x, 0))
314 // irlayers is likewise rare, so it is only mixed in when present to keep
315 // the common no-layers hashes unchanged.
316 if (AtomGroup || AtomRank) {
317 if (IRLayers)
318 return hash_combine(LineColumnAndImplicitCode, Scope, InlinedAt,
319 AtomGroup | (uint64_t(AtomRank) << 61), IRLayers);
320 return hash_combine(LineColumnAndImplicitCode, Scope, InlinedAt,
321 AtomGroup | (uint64_t(AtomRank) << 61));
322 }
323 if (IRLayers)
324 return hash_combine(LineColumnAndImplicitCode, Scope, InlinedAt,
325 IRLayers);
326 return hash_combine(LineColumnAndImplicitCode, Scope, InlinedAt);
327 }
328};
329
330/// DenseMapInfo for DILayerLoc.
331template <> struct MDNodeKeyImpl<DILayerLoc> {
334 unsigned Line;
336
340 : Kind(N->getRawKind()), File(N->getRawFile()), Line(N->getLine()),
341 Column(N->getColumn()) {}
342
343 bool isKeyOf(const DILayerLoc *RHS) const {
344 return Kind == RHS->getRawKind() && File == RHS->getRawFile() &&
345 Line == RHS->getLine() && Column == RHS->getColumn();
346 }
347
348 unsigned getHashValue() const {
349 return hash_combine(Kind, File, Line, Column);
350 }
351};
352
353/// DenseMapInfo for DILayerLocList.
357
358 bool isKeyOf(const DILayerLocList *RHS) const { return compareOps(RHS); }
359
360 unsigned getHashValue() const { return getHash(); }
361
362 static unsigned calculateHash(DILayerLocList *N) {
364 }
365};
366
367/// DenseMapInfo for GenericDINode.
369 unsigned Tag;
371
373 : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {}
375 : MDNodeOpsKey(N, 1), Tag(N->getTag()), Header(N->getRawHeader()) {}
376
377 bool isKeyOf(const GenericDINode *RHS) const {
378 return Tag == RHS->getTag() && Header == RHS->getRawHeader() &&
379 compareOps(RHS, 1);
380 }
381
382 unsigned getHashValue() const { return hash_combine(getHash(), Tag, Header); }
383
384 static unsigned calculateHash(GenericDINode *N) {
386 }
387};
388
389template <> struct MDNodeKeyImpl<DISubrange> {
394
400 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
401 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
402
403 bool isKeyOf(const DISubrange *RHS) const {
404 auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool {
405 if (Node1 == Node2)
406 return true;
407
410 if (MD1 && MD2) {
413 if (CV1->getSExtValue() == CV2->getSExtValue())
414 return true;
415 }
416 return false;
417 };
418
419 return BoundsEqual(CountNode, RHS->getRawCountNode()) &&
420 BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
421 BoundsEqual(UpperBound, RHS->getRawUpperBound()) &&
422 BoundsEqual(Stride, RHS->getRawStride());
423 }
424
425 unsigned getHashValue() const {
426 if (CountNode)
428 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
431 }
432};
433
434template <> struct MDNodeKeyImpl<DIGenericSubrange> {
439
445 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
446 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
447
448 bool isKeyOf(const DIGenericSubrange *RHS) const {
449 return (CountNode == RHS->getRawCountNode()) &&
450 (LowerBound == RHS->getRawLowerBound()) &&
451 (UpperBound == RHS->getRawUpperBound()) &&
452 (Stride == RHS->getRawStride());
453 }
454
455 unsigned getHashValue() const {
457 if (CountNode && MD)
458 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
461 }
462};
463
464template <> struct MDNodeKeyImpl<DIEnumerator> {
468
475 : Value(N->getValue()), Name(N->getRawName()),
476 IsUnsigned(N->isUnsigned()) {}
477
478 bool isKeyOf(const DIEnumerator *RHS) const {
479 return Value.getBitWidth() == RHS->getValue().getBitWidth() &&
480 Value == RHS->getValue() && IsUnsigned == RHS->isUnsigned() &&
481 Name == RHS->getRawName();
482 }
483
484 unsigned getHashValue() const { return hash_combine(Value, Name); }
485};
486
487template <> struct MDNodeKeyImpl<DIBasicType> {
488 unsigned Tag;
491 unsigned LineNo;
495 unsigned Encoding;
498 unsigned Flags;
499
509 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
510 LineNo(N->getLine()), Scope(N->getRawScope()),
511 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
512 Encoding(N->getEncoding()),
513 NumExtraInhabitants(N->getNumExtraInhabitants()),
514 DataSizeInBits(N->getDataSizeInBits()), Flags(N->getFlags()) {}
515
516 bool isKeyOf(const DIBasicType *RHS) const {
517 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
518 File == RHS->getRawFile() && LineNo == RHS->getLine() &&
519 Scope == RHS->getRawScope() &&
520 SizeInBits == RHS->getRawSizeInBits() &&
521 AlignInBits == RHS->getAlignInBits() &&
522 Encoding == RHS->getEncoding() &&
523 NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
524 DataSizeInBits == RHS->getDataSizeInBits() &&
525 Flags == RHS->getFlags();
526 }
527
528 unsigned getHashValue() const {
530 Encoding);
531 }
532};
533
534template <> struct MDNodeKeyImpl<DIFixedPointType> {
535 unsigned Tag;
538 unsigned LineNo;
542 unsigned Encoding;
543 unsigned Flags;
544 unsigned Kind;
548
558 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
559 LineNo(N->getLine()), Scope(N->getRawScope()),
560 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
561 Encoding(N->getEncoding()), Flags(N->getFlags()), Kind(N->getKind()),
562 Factor(N->getFactorRaw()), Numerator(N->getNumeratorRaw()),
563 Denominator(N->getDenominatorRaw()) {}
564
565 bool isKeyOf(const DIFixedPointType *RHS) const {
566 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
567 LineNo == RHS->getLine() && Scope == RHS->getRawScope() &&
568 SizeInBits == RHS->getRawSizeInBits() &&
569 AlignInBits == RHS->getAlignInBits() && Kind == RHS->getKind() &&
570 (RHS->isRational() ? (Numerator == RHS->getNumerator() &&
571 Denominator == RHS->getDenominator())
572 : Factor == RHS->getFactor());
573 }
574
575 unsigned getHashValue() const {
578 }
579};
580
581template <> struct MDNodeKeyImpl<DIStringType> {
582 unsigned Tag;
589 unsigned Encoding;
591
601 : Tag(N->getTag()), Name(N->getRawName()),
602 StringLength(N->getRawStringLength()),
603 StringLengthExp(N->getRawStringLengthExp()),
604 StringLocationExp(N->getRawStringLocationExp()),
605 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
606 Encoding(N->getEncoding()), CharType(N->getRawCharType()) {}
607
608 bool isKeyOf(const DIStringType *RHS) const {
609 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
610 StringLength == RHS->getRawStringLength() &&
611 StringLengthExp == RHS->getRawStringLengthExp() &&
612 StringLocationExp == RHS->getRawStringLocationExp() &&
613 SizeInBits == RHS->getRawSizeInBits() &&
614 AlignInBits == RHS->getAlignInBits() &&
615 Encoding == RHS->getEncoding() && CharType == RHS->getRawCharType();
616 }
617 unsigned getHashValue() const {
618 // Intentionally computes the hash on a subset of the operands for
619 // performance reason. The subset has to be significant enough to avoid
620 // collision "most of the time". There is no correctness issue in case of
621 // collision because of the full check above.
623 }
624};
625
626template <> struct MDNodeKeyImpl<DIDerivedType> {
627 unsigned Tag;
628 MDString *Name;
629 Metadata *File;
630 unsigned Line;
631 Metadata *Scope;
633 Metadata *SizeInBits;
634 Metadata *OffsetInBits;
635 uint32_t AlignInBits;
636 std::optional<unsigned> DWARFAddressSpace;
637 std::optional<DIDerivedType::PtrAuthData> PtrAuthData;
638 unsigned Flags;
640 Metadata *Annotations;
641
642 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
643 Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
644 uint32_t AlignInBits, Metadata *OffsetInBits,
645 std::optional<unsigned> DWARFAddressSpace,
646 std::optional<DIDerivedType::PtrAuthData> PtrAuthData,
647 unsigned Flags, Metadata *ExtraData, Metadata *Annotations)
648 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
649 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
650 AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace),
651 PtrAuthData(PtrAuthData), Flags(Flags), ExtraData(ExtraData),
652 Annotations(Annotations) {}
653 MDNodeKeyImpl(const DIDerivedType *N)
654 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
655 Line(N->getLine()), Scope(N->getRawScope()),
656 BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
657 OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
658 DWARFAddressSpace(N->getDWARFAddressSpace()),
659 PtrAuthData(N->getPtrAuthData()), Flags(N->getFlags()),
660 ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {}
661
662 bool isKeyOf(const DIDerivedType *RHS) const {
663 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
664 File == RHS->getRawFile() && Line == RHS->getLine() &&
665 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
666 SizeInBits == RHS->getRawSizeInBits() &&
667 AlignInBits == RHS->getAlignInBits() &&
668 OffsetInBits == RHS->getRawOffsetInBits() &&
669 DWARFAddressSpace == RHS->getDWARFAddressSpace() &&
670 PtrAuthData == RHS->getPtrAuthData() && Flags == RHS->getFlags() &&
671 ExtraData == RHS->getRawExtraData() &&
672 Annotations == RHS->getRawAnnotations();
673 }
674
675 unsigned getHashValue() const {
676 // If this is a member inside an ODR type, only hash the type and the name.
677 // Otherwise the hash will be stronger than
678 // MDNodeSubsetEqualImpl::isODRMember().
679 if (Tag == dwarf::DW_TAG_member && Name)
680 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
681 if (CT->getRawIdentifier())
682 return hash_combine(Name, Scope);
683
684 // Intentionally computes the hash on a subset of the operands for
685 // performance reason. The subset has to be significant enough to avoid
686 // collision "most of the time". There is no correctness issue in case of
687 // collision because of the full check above.
688 return hash_combine(Tag, Name, File, Line, Scope, BaseType, Flags);
689 }
690};
691
692template <> struct MDNodeKeyImpl<DISubrangeType> {
695 unsigned Line;
699 unsigned Flags;
705
715 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
716 Scope(N->getRawScope()), SizeInBits(N->getRawSizeInBits()),
717 AlignInBits(N->getAlignInBits()), Flags(N->getFlags()),
718 BaseType(N->getRawBaseType()), LowerBound(N->getRawLowerBound()),
719 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()),
720 Bias(N->getRawBias()) {}
721
722 bool isKeyOf(const DISubrangeType *RHS) const {
723 auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool {
724 if (Node1 == Node2)
725 return true;
726
729 if (MD1 && MD2) {
732 if (CV1->getSExtValue() == CV2->getSExtValue())
733 return true;
734 }
735 return false;
736 };
737
738 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
739 Line == RHS->getLine() && Scope == RHS->getRawScope() &&
740 SizeInBits == RHS->getRawSizeInBits() &&
741 AlignInBits == RHS->getAlignInBits() && Flags == RHS->getFlags() &&
742 BaseType == RHS->getRawBaseType() &&
743 BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
744 BoundsEqual(UpperBound, RHS->getRawUpperBound()) &&
745 BoundsEqual(Stride, RHS->getRawStride()) &&
746 BoundsEqual(Bias, RHS->getRawBias());
747 }
748
749 unsigned getHashValue() const {
750 unsigned val = 0;
751 auto HashBound = [&](Metadata *Node) -> void {
753 if (MD) {
755 val = hash_combine(val, CV->getSExtValue());
756 } else {
757 val = hash_combine(val, Node);
758 }
759 };
760
761 HashBound(LowerBound);
762 HashBound(UpperBound);
763 HashBound(Stride);
764 HashBound(Bias);
765
766 return hash_combine(val, Name, File, Line, Scope, BaseType, Flags);
767 }
768};
769
772
773 static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) {
774 return isODRMember(LHS.Tag, LHS.Scope, LHS.Name, RHS);
775 }
776
777 static bool isSubsetEqual(const DIDerivedType *LHS,
778 const DIDerivedType *RHS) {
779 return isODRMember(LHS->getTag(), LHS->getRawScope(), LHS->getRawName(),
780 RHS);
781 }
782
783 /// Subprograms compare equal if they declare the same function in an ODR
784 /// type.
785 static bool isODRMember(unsigned Tag, const Metadata *Scope,
786 const MDString *Name, const DIDerivedType *RHS) {
787 // Check whether the LHS is eligible.
788 if (Tag != dwarf::DW_TAG_member || !Name)
789 return false;
790
791 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
792 if (!CT || !CT->getRawIdentifier())
793 return false;
794
795 // Compare to the RHS.
796 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
797 Scope == RHS->getRawScope();
798 }
799};
800
801template <> struct MDNodeKeyImpl<DICompositeType> {
802 unsigned Tag;
805 unsigned Line;
811 unsigned Flags;
813 unsigned RuntimeLang;
826
847 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
848 Line(N->getLine()), Scope(N->getRawScope()),
849 BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
850 OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
851 Flags(N->getFlags()), Elements(N->getRawElements()),
852 RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()),
853 TemplateParams(N->getRawTemplateParams()),
854 Identifier(N->getRawIdentifier()),
855 Discriminator(N->getRawDiscriminator()),
856 DataLocation(N->getRawDataLocation()),
857 Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()),
858 Rank(N->getRawRank()), Annotations(N->getRawAnnotations()),
859 Specification(N->getSpecification()),
860 NumExtraInhabitants(N->getNumExtraInhabitants()),
861 BitStride(N->getRawBitStride()) {}
862
863 bool isKeyOf(const DICompositeType *RHS) const {
864 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
865 File == RHS->getRawFile() && Line == RHS->getLine() &&
866 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
867 SizeInBits == RHS->getRawSizeInBits() &&
868 AlignInBits == RHS->getAlignInBits() &&
869 OffsetInBits == RHS->getRawOffsetInBits() &&
870 Flags == RHS->getFlags() && Elements == RHS->getRawElements() &&
871 RuntimeLang == RHS->getRuntimeLang() &&
872 VTableHolder == RHS->getRawVTableHolder() &&
873 TemplateParams == RHS->getRawTemplateParams() &&
874 Identifier == RHS->getRawIdentifier() &&
875 Discriminator == RHS->getRawDiscriminator() &&
876 DataLocation == RHS->getRawDataLocation() &&
877 Associated == RHS->getRawAssociated() &&
878 Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() &&
879 Annotations == RHS->getRawAnnotations() &&
880 Specification == RHS->getSpecification() &&
881 NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
882 BitStride == RHS->getRawBitStride();
883 }
884
885 unsigned getHashValue() const {
886 // Intentionally computes the hash on a subset of the operands for
887 // performance reason. The subset has to be significant enough to avoid
888 // collision "most of the time". There is no correctness issue in case of
889 // collision because of the full check above.
892 }
893};
894
895template <> struct MDNodeKeyImpl<DISubroutineType> {
896 unsigned Flags;
899
903 : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()) {}
904
905 bool isKeyOf(const DISubroutineType *RHS) const {
906 return Flags == RHS->getFlags() && CC == RHS->getCC() &&
907 TypeArray == RHS->getRawTypeArray();
908 }
909
910 unsigned getHashValue() const { return hash_combine(Flags, CC, TypeArray); }
911};
912
913template <> struct MDNodeKeyImpl<DIFile> {
916 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum;
918
925 : Filename(N->getRawFilename()), Directory(N->getRawDirectory()),
926 Checksum(N->getRawChecksum()), Source(N->getRawSource()) {}
927
928 bool isKeyOf(const DIFile *RHS) const {
929 return Filename == RHS->getRawFilename() &&
930 Directory == RHS->getRawDirectory() &&
931 Checksum == RHS->getRawChecksum() && Source == RHS->getRawSource();
932 }
933
934 unsigned getHashValue() const {
935 return hash_combine(Filename, Directory, Checksum ? Checksum->Kind : 0,
936 Checksum ? Checksum->Value : nullptr, Source);
937 }
938};
939
940template <> struct MDNodeKeyImpl<DISubprogram> {
941 Metadata *Scope;
942 MDString *Name;
943 MDString *LinkageName;
944 Metadata *File;
945 unsigned Line;
946 unsigned ScopeLine;
947 Metadata *Type;
948 Metadata *ContainingType;
949 unsigned VirtualIndex;
950 int ThisAdjustment;
951 unsigned Flags;
952 unsigned SPFlags;
953 Metadata *Unit;
954 Metadata *TemplateParams;
955 Metadata *Declaration;
956 Metadata *RetainedNodes;
957 Metadata *ThrownTypes;
958 Metadata *Annotations;
959 MDString *TargetFuncName;
960 bool UsesKeyInstructions;
961
962 MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
963 Metadata *File, unsigned Line, Metadata *Type,
964 unsigned ScopeLine, Metadata *ContainingType,
965 unsigned VirtualIndex, int ThisAdjustment, unsigned Flags,
966 unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams,
967 Metadata *Declaration, Metadata *RetainedNodes,
968 Metadata *ThrownTypes, Metadata *Annotations,
969 MDString *TargetFuncName, bool UsesKeyInstructions)
970 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
971 Line(Line), ScopeLine(ScopeLine), Type(Type),
972 ContainingType(ContainingType), VirtualIndex(VirtualIndex),
973 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags),
974 Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration),
975 RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes),
976 Annotations(Annotations), TargetFuncName(TargetFuncName),
977 UsesKeyInstructions(UsesKeyInstructions) {}
978 MDNodeKeyImpl(const DISubprogram *N)
979 : Scope(N->getRawScope()), Name(N->getRawName()),
980 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
981 Line(N->getLine()), ScopeLine(N->getScopeLine()), Type(N->getRawType()),
982 ContainingType(N->getRawContainingType()),
983 VirtualIndex(N->getVirtualIndex()),
984 ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()),
985 SPFlags(N->getSPFlags()), Unit(N->getRawUnit()),
986 TemplateParams(N->getRawTemplateParams()),
987 Declaration(N->getRawDeclaration()),
988 RetainedNodes(N->getRawRetainedNodes()),
989 ThrownTypes(N->getRawThrownTypes()),
990 Annotations(N->getRawAnnotations()),
991 TargetFuncName(N->getRawTargetFuncName()),
992 UsesKeyInstructions(N->getKeyInstructionsEnabled()) {}
993
994 bool isKeyOf(const DISubprogram *RHS) const {
995 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
996 LinkageName == RHS->getRawLinkageName() &&
997 File == RHS->getRawFile() && Line == RHS->getLine() &&
998 Type == RHS->getRawType() && ScopeLine == RHS->getScopeLine() &&
999 ContainingType == RHS->getRawContainingType() &&
1000 VirtualIndex == RHS->getVirtualIndex() &&
1001 ThisAdjustment == RHS->getThisAdjustment() &&
1002 Flags == RHS->getFlags() && SPFlags == RHS->getSPFlags() &&
1003 Unit == RHS->getUnit() &&
1004 TemplateParams == RHS->getRawTemplateParams() &&
1005 Declaration == RHS->getRawDeclaration() &&
1006 RetainedNodes == RHS->getRawRetainedNodes() &&
1007 ThrownTypes == RHS->getRawThrownTypes() &&
1008 Annotations == RHS->getRawAnnotations() &&
1009 TargetFuncName == RHS->getRawTargetFuncName() &&
1010 UsesKeyInstructions == RHS->getKeyInstructionsEnabled();
1011 }
1012
1013 bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; }
1014
1015 unsigned getHashValue() const {
1016 // Use the Scope's linkage name instead of using the scope directly, as the
1017 // scope may be a temporary one which can replaced, which would produce a
1018 // different hash for the same DISubprogram.
1019 llvm::StringRef ScopeLinkageName;
1020 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
1021 if (auto *ID = CT->getRawIdentifier())
1022 ScopeLinkageName = ID->getString();
1023
1024 // If this is a declaration inside an ODR type, only hash the type and the
1025 // name. Otherwise the hash will be stronger than
1026 // MDNodeSubsetEqualImpl::isDeclarationOfODRMember().
1027 if (!isDefinition() && LinkageName &&
1029 return hash_combine(LinkageName, ScopeLinkageName);
1030
1031 // Intentionally computes the hash on a subset of the operands for
1032 // performance reason. The subset has to be significant enough to avoid
1033 // collision "most of the time". There is no correctness issue in case of
1034 // collision because of the full check above.
1035 return hash_combine(Name, ScopeLinkageName, File, Type, Line);
1036 }
1037};
1038
1041
1042 static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) {
1043 return isDeclarationOfODRMember(LHS.isDefinition(), LHS.Scope,
1044 LHS.LinkageName, LHS.TemplateParams, RHS);
1045 }
1046
1047 static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) {
1048 return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(),
1049 LHS->getRawLinkageName(),
1050 LHS->getRawTemplateParams(), RHS);
1051 }
1052
1053 /// Subprograms compare equal if they declare the same function in an ODR
1054 /// type.
1055 static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope,
1056 const MDString *LinkageName,
1057 const Metadata *TemplateParams,
1058 const DISubprogram *RHS) {
1059 // Check whether the LHS is eligible.
1060 if (IsDefinition || !Scope || !LinkageName)
1061 return false;
1062
1063 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
1064 if (!CT || !CT->getRawIdentifier())
1065 return false;
1066
1067 // Compare to the RHS.
1068 // FIXME: We need to compare template parameters here to avoid incorrect
1069 // collisions in mapMetadata when RF_ReuseAndMutateDistinctMDs and a
1070 // ODR-DISubprogram has a non-ODR template parameter (i.e., a
1071 // DICompositeType that does not have an identifier). Eventually we should
1072 // decouple ODR logic from uniquing logic.
1073 return IsDefinition == RHS->isDefinition() && Scope == RHS->getRawScope() &&
1074 LinkageName == RHS->getRawLinkageName() &&
1075 TemplateParams == RHS->getRawTemplateParams();
1076 }
1077};
1078
1079template <> struct MDNodeKeyImpl<DILexicalBlock> {
1082 unsigned Line;
1083 unsigned Column;
1084
1088 : Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()),
1089 Column(N->getColumn()) {}
1090
1091 bool isKeyOf(const DILexicalBlock *RHS) const {
1092 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
1093 Line == RHS->getLine() && Column == RHS->getColumn();
1094 }
1095
1096 unsigned getHashValue() const {
1097 return hash_combine(Scope, File, Line, Column);
1098 }
1099};
1100
1105
1109 : Scope(N->getRawScope()), File(N->getRawFile()),
1110 Discriminator(N->getDiscriminator()) {}
1111
1112 bool isKeyOf(const DILexicalBlockFile *RHS) const {
1113 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
1114 Discriminator == RHS->getDiscriminator();
1115 }
1116
1117 unsigned getHashValue() const {
1119 }
1120};
1121
1122template <> struct MDNodeKeyImpl<DINamespace> {
1126
1130 : Scope(N->getRawScope()), Name(N->getRawName()),
1131 ExportSymbols(N->getExportSymbols()) {}
1132
1133 bool isKeyOf(const DINamespace *RHS) const {
1134 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1135 ExportSymbols == RHS->getExportSymbols();
1136 }
1137
1138 unsigned getHashValue() const { return hash_combine(Scope, Name); }
1139};
1140
1141template <> struct MDNodeKeyImpl<DICommonBlock> {
1146 unsigned LineNo;
1147
1152 : Scope(N->getRawScope()), Decl(N->getRawDecl()), Name(N->getRawName()),
1153 File(N->getRawFile()), LineNo(N->getLineNo()) {}
1154
1155 bool isKeyOf(const DICommonBlock *RHS) const {
1156 return Scope == RHS->getRawScope() && Decl == RHS->getRawDecl() &&
1157 Name == RHS->getRawName() && File == RHS->getRawFile() &&
1158 LineNo == RHS->getLineNo();
1159 }
1160
1161 unsigned getHashValue() const {
1162 return hash_combine(Scope, Decl, Name, File, LineNo);
1163 }
1164};
1165
1166template <> struct MDNodeKeyImpl<DIModule> {
1173 unsigned LineNo;
1175
1183 : File(N->getRawFile()), Scope(N->getRawScope()), Name(N->getRawName()),
1184 ConfigurationMacros(N->getRawConfigurationMacros()),
1185 IncludePath(N->getRawIncludePath()),
1186 APINotesFile(N->getRawAPINotesFile()), LineNo(N->getLineNo()),
1187 IsDecl(N->getIsDecl()) {}
1188
1189 bool isKeyOf(const DIModule *RHS) const {
1190 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1191 ConfigurationMacros == RHS->getRawConfigurationMacros() &&
1192 IncludePath == RHS->getRawIncludePath() &&
1193 APINotesFile == RHS->getRawAPINotesFile() &&
1194 File == RHS->getRawFile() && LineNo == RHS->getLineNo() &&
1195 IsDecl == RHS->getIsDecl();
1196 }
1197
1198 unsigned getHashValue() const {
1200 }
1201};
1202
1207
1211 : Name(N->getRawName()), Type(N->getRawType()),
1212 IsDefault(N->isDefault()) {}
1213
1215 return Name == RHS->getRawName() && Type == RHS->getRawType() &&
1216 IsDefault == RHS->isDefault();
1217 }
1218
1219 unsigned getHashValue() const { return hash_combine(Name, Type, IsDefault); }
1220};
1221
1223 unsigned Tag;
1228
1233 : Tag(N->getTag()), Name(N->getRawName()), Type(N->getRawType()),
1234 IsDefault(N->isDefault()), Value(N->getValue()) {}
1235
1237 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
1238 Type == RHS->getRawType() && IsDefault == RHS->isDefault() &&
1239 Value == RHS->getValue();
1240 }
1241
1242 unsigned getHashValue() const {
1244 }
1245};
1246
1247template <> struct MDNodeKeyImpl<DIGlobalVariable> {
1252 unsigned Line;
1260
1273 : Scope(N->getRawScope()), Name(N->getRawName()),
1274 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
1275 Line(N->getLine()), Type(N->getRawType()),
1276 IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
1277 StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()),
1278 TemplateParams(N->getRawTemplateParams()),
1279 AlignInBits(N->getAlignInBits()), Annotations(N->getRawAnnotations()) {}
1280
1281 bool isKeyOf(const DIGlobalVariable *RHS) const {
1282 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1283 LinkageName == RHS->getRawLinkageName() &&
1284 File == RHS->getRawFile() && Line == RHS->getLine() &&
1285 Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() &&
1286 IsDefinition == RHS->isDefinition() &&
1288 RHS->getRawStaticDataMemberDeclaration() &&
1289 TemplateParams == RHS->getRawTemplateParams() &&
1290 AlignInBits == RHS->getAlignInBits() &&
1291 Annotations == RHS->getRawAnnotations();
1292 }
1293
1294 unsigned getHashValue() const {
1295 // We do not use AlignInBits in hashing function here on purpose:
1296 // in most cases this param for local variable is zero (for function param
1297 // it is always zero). This leads to lots of hash collisions and errors on
1298 // cases with lots of similar variables.
1299 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1300 // generated IR is random for each run and test fails with Align included.
1301 // TODO: make hashing work fine with such situations
1303 IsLocalToUnit, IsDefinition, /* AlignInBits, */
1305 }
1306};
1307
1308template <> struct MDNodeKeyImpl<DILocalVariable> {
1312 unsigned Line;
1314 unsigned Arg;
1315 unsigned Flags;
1318
1325 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1326 Line(N->getLine()), Type(N->getRawType()), Arg(N->getArg()),
1327 Flags(N->getFlags()), AlignInBits(N->getAlignInBits()),
1328 Annotations(N->getRawAnnotations()) {}
1329
1330 bool isKeyOf(const DILocalVariable *RHS) const {
1331 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1332 File == RHS->getRawFile() && Line == RHS->getLine() &&
1333 Type == RHS->getRawType() && Arg == RHS->getArg() &&
1334 Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits() &&
1335 Annotations == RHS->getRawAnnotations();
1336 }
1337
1338 unsigned getHashValue() const {
1339 // We do not use AlignInBits in hashing function here on purpose:
1340 // in most cases this param for local variable is zero (for function param
1341 // it is always zero). This leads to lots of hash collisions and errors on
1342 // cases with lots of similar variables.
1343 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1344 // generated IR is random for each run and test fails with Align included.
1345 // TODO: make hashing work fine with such situations
1347 }
1348};
1349
1350template <> struct MDNodeKeyImpl<DILabel> {
1354 unsigned Line;
1355 unsigned Column;
1357 std::optional<unsigned> CoroSuspendIdx;
1358
1365 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1366 Line(N->getLine()), Column(N->getColumn()),
1367 IsArtificial(N->isArtificial()),
1368 CoroSuspendIdx(N->getCoroSuspendIdx()) {}
1369
1370 bool isKeyOf(const DILabel *RHS) const {
1371 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1372 File == RHS->getRawFile() && Line == RHS->getLine() &&
1373 Column == RHS->getColumn() && IsArtificial == RHS->isArtificial() &&
1374 CoroSuspendIdx == RHS->getCoroSuspendIdx();
1375 }
1376
1377 /// Using name and line to get hash value. It should already be mostly unique.
1378 unsigned getHashValue() const {
1381 }
1382};
1383
1384template <> struct MDNodeKeyImpl<DIExpression> {
1386
1388 MDNodeKeyImpl(const DIExpression *N) : Elements(N->getElements()) {}
1389
1390 bool isKeyOf(const DIExpression *RHS) const {
1391 return Elements == RHS->getElements();
1392 }
1393
1394 unsigned getHashValue() const { return hash_combine_range(Elements); }
1395};
1396
1400
1404 : Variable(N->getRawVariable()), Expression(N->getRawExpression()) {}
1405
1407 return Variable == RHS->getRawVariable() &&
1408 Expression == RHS->getRawExpression();
1409 }
1410
1411 unsigned getHashValue() const { return hash_combine(Variable, Expression); }
1412};
1413
1414template <> struct MDNodeKeyImpl<DIObjCProperty> {
1417 unsigned Line;
1420 unsigned Attributes;
1422
1429 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
1430 GetterName(N->getRawGetterName()), SetterName(N->getRawSetterName()),
1431 Attributes(N->getAttributes()), Type(N->getRawType()) {}
1432
1433 bool isKeyOf(const DIObjCProperty *RHS) const {
1434 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
1435 Line == RHS->getLine() && GetterName == RHS->getRawGetterName() &&
1436 SetterName == RHS->getRawSetterName() &&
1437 Attributes == RHS->getAttributes() && Type == RHS->getRawType();
1438 }
1439
1440 unsigned getHashValue() const {
1442 Type);
1443 }
1444};
1445
1446template <> struct MDNodeKeyImpl<DIProperty> {
1449 unsigned Line;
1452
1458 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
1459 Type(N->getRawType()), BackingStorage(N->getRawBackingStorage()) {}
1460
1461 bool isKeyOf(const DIProperty *RHS) const {
1462 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
1463 Line == RHS->getLine() && Type == RHS->getRawType() &&
1464 BackingStorage == RHS->getRawBackingStorage();
1465 }
1466
1467 unsigned getHashValue() const {
1469 }
1470};
1471
1472template <> struct MDNodeKeyImpl<DIImportedEntity> {
1473 unsigned Tag;
1477 unsigned Line;
1480
1486 : Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()),
1487 File(N->getRawFile()), Line(N->getLine()), Name(N->getRawName()),
1488 Elements(N->getRawElements()) {}
1489
1490 bool isKeyOf(const DIImportedEntity *RHS) const {
1491 return Tag == RHS->getTag() && Scope == RHS->getRawScope() &&
1492 Entity == RHS->getRawEntity() && File == RHS->getFile() &&
1493 Line == RHS->getLine() && Name == RHS->getRawName() &&
1494 Elements == RHS->getRawElements();
1495 }
1496
1497 unsigned getHashValue() const {
1499 }
1500};
1501
1502template <> struct MDNodeKeyImpl<DIMacro> {
1503 unsigned MIType;
1504 unsigned Line;
1507
1511 : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getRawName()),
1512 Value(N->getRawValue()) {}
1513
1514 bool isKeyOf(const DIMacro *RHS) const {
1515 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1516 Name == RHS->getRawName() && Value == RHS->getRawValue();
1517 }
1518
1519 unsigned getHashValue() const {
1520 return hash_combine(MIType, Line, Name, Value);
1521 }
1522};
1523
1524template <> struct MDNodeKeyImpl<DIMacroFile> {
1525 unsigned MIType;
1526 unsigned Line;
1529
1534 : MIType(N->getMacinfoType()), Line(N->getLine()), File(N->getRawFile()),
1535 Elements(N->getRawElements()) {}
1536
1537 bool isKeyOf(const DIMacroFile *RHS) const {
1538 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1539 File == RHS->getRawFile() && Elements == RHS->getRawElements();
1540 }
1541
1542 unsigned getHashValue() const {
1544 }
1545};
1546
1547// DIArgLists are not MDNodes, but we still want to unique them in a DenseSet
1548// based on a hash of their arguments.
1551
1553 DIArgListKeyInfo(const DIArgList *N) : Args(N->getArgs()) {}
1554
1555 bool isKeyOf(const DIArgList *RHS) const { return Args == RHS->getArgs(); }
1556
1557 unsigned getHashValue() const { return hash_combine_range(Args); }
1558};
1559
1560/// DenseMapInfo for DIArgList.
1563
1564 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1565
1566 static unsigned getHashValue(const DIArgList *N) {
1567 return KeyTy(N).getHashValue();
1568 }
1569
1570 static bool isEqual(const KeyTy &LHS, const DIArgList *RHS) {
1571 return LHS.isKeyOf(RHS);
1572 }
1573
1574 static bool isEqual(const DIArgList *LHS, const DIArgList *RHS) {
1575 return LHS == RHS;
1576 }
1577};
1578
1579/// DenseMapInfo for MDNode subclasses.
1580template <class NodeTy> struct MDNodeInfo {
1583
1584 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1585
1586 static unsigned getHashValue(const NodeTy *N) {
1587 return KeyTy(N).getHashValue();
1588 }
1589
1590 static bool isEqual(const KeyTy &LHS, const NodeTy *RHS) {
1591 return SubsetEqualTy::isSubsetEqual(LHS, RHS) || LHS.isKeyOf(RHS);
1592 }
1593
1594 static bool isEqual(const NodeTy *LHS, const NodeTy *RHS) {
1595 if (LHS == RHS)
1596 return true;
1598 }
1599};
1600
1601#define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>;
1602#include "llvm/IR/Metadata.def"
1603
1604/// Single metadata attachment, forms linked list ended by index 0.
1606 unsigned Next = 0;
1607 unsigned MDKind;
1609};
1610
1611/// Head pointer for a Value's ValueHandleBase doubly-linked list, stored in
1612/// LLVMContextImpl::ValueHandles. The first node's PrevPtr points to Head, so
1613/// relocating the bucket refreshes PrevPtr to the new Head address.
1615 // Tag Head with true via PointerIntPair so RemoveFromUseList can
1616 // distinguish ValueHandleHead::Head from an untagged ValueHandleBase::Next
1617 // when accessed through *PrevPtr.
1619
1620 ValueHandleBase *Head =
1621 static_cast<ValueHandleBase *>(TaggedPtr(nullptr, true).getOpaqueValue());
1622
1623public:
1626 }
1627
1628 ValueHandleBase **getAddress() { return &Head; }
1629
1630 // Replace the pointer in *Slot with NewPtr while preserving its tag bit,
1631 // and return the old TaggedPtr.
1632 static TaggedPtr exchange(ValueHandleBase **Slot, ValueHandleBase *NewPtr) {
1633 TaggedPtr Old = TaggedPtr::getFromOpaqueValue(*Slot);
1634 TaggedPtr Updated = Old;
1635 Updated.setPointer(NewPtr);
1636 *Slot = static_cast<ValueHandleBase *>(Updated.getOpaqueValue());
1637 return Old;
1638 }
1639
1640 ValueHandleHead() = default;
1645};
1646
1648public:
1649 /// OwnedModules - The set of modules instantiated in this context, and which
1650 /// will be automatically deleted if this context is deleted.
1652
1653 /// MachineFunctionNums - Keep the next available unique number available for
1654 /// a MachineFunction in given module. Module must in OwnedModules.
1656
1657 /// The main remark streamer used by all the other streamers (e.g. IR, MIR,
1658 /// frontends, etc.). This should only be used by the specific streamers, and
1659 /// never directly.
1660 std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer;
1661
1662 std::unique_ptr<DiagnosticHandler> DiagHandler;
1665 /// The minimum hotness value a diagnostic needs in order to be included in
1666 /// optimization diagnostics.
1667 ///
1668 /// The threshold is an Optional value, which maps to one of the 3 states:
1669 /// 1). 0 => threshold disabled. All emarks will be printed.
1670 /// 2). positive int => manual threshold by user. Remarks with hotness exceed
1671 /// threshold will be printed.
1672 /// 3). None => 'auto' threshold by user. The actual value is not
1673 /// available at command line, but will be synced with
1674 /// hotness threhold from profile summary during
1675 /// compilation.
1676 ///
1677 /// State 1 and 2 are considered as terminal states. State transition is
1678 /// only allowed from 3 to 2, when the threshold is first synced with profile
1679 /// summary. This ensures that the threshold is set only once and stays
1680 /// constant.
1681 ///
1682 /// If threshold option is not specified, it is disabled (0) by default.
1683 std::optional<uint64_t> DiagnosticsHotnessThreshold = 0;
1684
1685 /// The percentage of difference between profiling branch weights and
1686 /// llvm.expect branch weights to tolerate when emiting MisExpect diagnostics
1687 std::optional<uint32_t> DiagnosticsMisExpectTolerance = 0;
1689
1690 /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
1691 std::unique_ptr<LLVMRemarkStreamer> LLVMRS;
1692
1694 void *YieldOpaqueHandle = nullptr;
1695
1697
1701 DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantInt>>
1703
1707 DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantByte>>
1709
1711 DenseMap<std::pair<ElementCount, APFloat>, std::unique_ptr<ConstantFP>>
1713
1721
1726
1728
1730
1732
1734 return N->getHeader().MetadataPrintID;
1735 }
1736
1738 N->getHeader().MetadataPrintID = ID;
1739 }
1740
1741#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
1742 DenseSet<CLASS *, CLASS##Info> CLASS##s;
1743#include "llvm/IR/Metadata.def"
1744
1745 // Optional map for looking up composite types by identifier.
1746 std::optional<DenseMap<const MDString *, DICompositeType *>> DITypeMap;
1747
1748 // MDNodes may be uniqued or not uniqued. When they're not uniqued, they
1749 // aren't in the MDNodeSet, but they're still shared between objects, so no
1750 // one object can destroy them. Keep track of them here so we can delete
1751 // them on context teardown.
1752 std::vector<MDNode *> DistinctMDNodes;
1753
1754 // Temporary nodes are caller-owned, but track live ones for persistent
1755 // metadata print IDs.
1757
1758 // ConstantRangeListAttributeImpl is a TrailingObjects/ArrayRef of
1759 // ConstantRange. Since this is a dynamically sized class, it's not
1760 // possible to use SpecificBumpPtrAllocator. Instead, we use normal Alloc
1761 // for allocation and record all allocated pointers in this vector. In the
1762 // LLVMContext destructor, call the destuctors of everything in the vector.
1763 std::vector<ConstantRangeListAttributeImpl *> ConstantRangeListAttributes;
1764
1766
1769
1772
1775
1777
1779
1781
1783
1785
1787
1789
1791
1793
1795
1797
1800
1803
1804 // Basic type instances.
1810
1811 std::unique_ptr<ConstantTokenNone> TheNoneToken;
1812
1817
1820
1827
1830
1833 PointerType *AS0PointerType = nullptr; // AddrSpace = 0
1836
1837 /// ValueHandles - This map keeps track of all of the value handles that are
1838 /// watching a Value*. The Value::HasValueHandle bit is used to know
1839 /// whether or not a value has an entry in this map.
1842
1843 /// CustomMDKindNames - Map to hold the metadata string to ID mapping.
1845
1846 /// Collection of metadata attachments in this context.
1848 /// Index of first free Metadatas entry, linked list via MDAttachment::Next.
1850 /// Number of currently unused metadata entries. Only used/updated in debug
1851 /// builds to ensure that all metadata attachments are properly freed.
1853
1854 /// Collection of per-GlobalObject sections used in this context.
1856
1857 /// Collection of per-GlobalValue partitions used in this context.
1859
1862
1863 /// DiscriminatorTable - This table maps file:line locations to an
1864 /// integer representing the next DWARF path discriminator to assign to
1865 /// instructions in different blocks at the same location.
1867
1868 /// A set of interned tags for operand bundles. The StringMap maps
1869 /// bundle tags to their IDs.
1870 ///
1871 /// \see LLVMContext::getOperandBundleTagID
1873
1877
1878 /// A set of interned synchronization scopes. The StringMap maps
1879 /// synchronization scope names to their respective synchronization scope IDs.
1881
1882 /// getOrInsertSyncScopeID - Maps synchronization scope name to
1883 /// synchronization scope ID. Every synchronization scope registered with
1884 /// LLVMContext has unique ID except pre-defined ones.
1886
1887 /// getSyncScopeNames - Populates client supplied SmallVector with
1888 /// synchronization scope names registered with LLVMContext. Synchronization
1889 /// scope names are ordered by increasing synchronization scope IDs.
1891
1892 /// getSyncScopeName - Returns the name of a SyncScope::ID
1893 /// registered with LLVMContext, if any.
1894 std::optional<StringRef> getSyncScopeName(SyncScope::ID Id) const;
1895
1896 /// Maintain the GC name for each function.
1897 ///
1898 /// This saves allocating an additional word in Function for programs which
1899 /// do not use GC (i.e., most programs) at the cost of increased overhead for
1900 /// clients which do use GC.
1902
1903 /// Flag to indicate if Value (other than GlobalValue) retains their name or
1904 /// not.
1905 bool DiscardValueNames = false;
1906
1909
1910 mutable OptPassGate *OPG = nullptr;
1911
1912 /// Access the object which can disable optional passes and individual
1913 /// optimizations at compile time.
1914 OptPassGate &getOptPassGate() const;
1915
1916 /// Set the object which can disable optional passes and individual
1917 /// optimizations at compile time.
1918 ///
1919 /// The lifetime of the object must be guaranteed to extend as long as the
1920 /// LLVMContext is used by compilation.
1922
1923 /// Mapping of blocks to collections of "trailing" DbgVariableRecords. As part
1924 /// of the "RemoveDIs" project, debug-info variable location records are going
1925 /// to cease being instructions... which raises the problem of where should
1926 /// they be recorded when we remove the terminator of a blocks, such as:
1927 ///
1928 /// %foo = add i32 0, 0
1929 /// br label %bar
1930 ///
1931 /// If the branch is removed, a legitimate transient state while editing a
1932 /// block, any debug-records between those two instructions will not have a
1933 /// location. Each block thus records any DbgVariableRecord records that
1934 /// "trail" in such a way. These are stored in LLVMContext because typically
1935 /// LLVM only edits a small number of blocks at a time, so there's no need to
1936 /// bloat BasicBlock with such a data structure.
1938
1939 // Set, get and delete operations for TrailingDbgRecords.
1944
1948
1950
1951 std::string DefaultTargetCPU;
1953
1954 /// The next available source atom group number. The front end is responsible
1955 /// for assigning source atom numbers, but certain optimisations need to
1956 /// assign new group numbers to a set of instructions. Most often code
1957 /// duplication optimisations like loop unroll. Tracking a global maximum
1958 /// value means we can know (cheaply) we're never using a group number that's
1959 /// already used within this function.
1960 ///
1961 /// Start a 1 because 0 means the source location isn't part of an atom group.
1963};
1964
1965} // end namespace llvm
1966
1967#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
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:68
void(*)(LLVMContext *Context, void *OpaqueHandle) YieldCallbackTy
Defines the type of a yield callback.
Streamer for LLVM remarks which has logic for dealing with DiagnosticInfo objects.
MDNodeOpsKey(const NodeTy *N, unsigned Offset=0)
bool compareOps(const NodeTy *RHS, unsigned Offset=0) const
unsigned getHash() const
MDNodeOpsKey(ArrayRef< Metadata * > Ops)
static unsigned calculateHash(MDNode *N, unsigned Offset=0)
Metadata node.
Definition Metadata.h: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)