LLVM 20.0.0git
LLVMContextImpl.h
Go to the documentation of this file.
1//===- LLVMContextImpl.h - The LLVMContextImpl opaque class -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file declares LLVMContextImpl, the opaque implementation
10// of LLVMContext.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_IR_LLVMCONTEXTIMPL_H
15#define LLVM_LIB_IR_LLVMCONTEXTIMPL_H
16
17#include "ConstantsContext.h"
18#include "llvm/ADT/APFloat.h"
19#include "llvm/ADT/APInt.h"
20#include "llvm/ADT/ArrayRef.h"
21#include "llvm/ADT/DenseMap.h"
23#include "llvm/ADT/DenseSet.h"
24#include "llvm/ADT/FoldingSet.h"
25#include "llvm/ADT/Hashing.h"
26#include "llvm/ADT/STLExtras.h"
29#include "llvm/ADT/StringMap.h"
31#include "llvm/IR/Constants.h"
34#include "llvm/IR/LLVMContext.h"
35#include "llvm/IR/Metadata.h"
36#include "llvm/IR/Module.h"
38#include "llvm/IR/Type.h"
39#include "llvm/IR/Value.h"
43#include <algorithm>
44#include <cassert>
45#include <cstddef>
46#include <cstdint>
47#include <memory>
48#include <optional>
49#include <string>
50#include <utility>
51#include <vector>
52
53namespace llvm {
54
55class AttributeImpl;
56class AttributeListImpl;
57class AttributeSetNode;
58class BasicBlock;
59class ConstantRangeAttributeImpl;
60class ConstantRangeListAttributeImpl;
61struct DiagnosticHandler;
62class DbgMarker;
63class ElementCount;
64class Function;
65class GlobalObject;
66class GlobalValue;
67class InlineAsm;
68class LLVMRemarkStreamer;
69class OptPassGate;
70namespace remarks {
71class RemarkStreamer;
72}
73template <typename T> class StringMapEntry;
74class StringRef;
75class TypedPointerType;
76class ValueHandleBase;
77
78template <> struct DenseMapInfo<APFloat> {
79 static inline APFloat getEmptyKey() { return APFloat(APFloat::Bogus(), 1); }
80 static inline APFloat getTombstoneKey() {
81 return APFloat(APFloat::Bogus(), 2);
82 }
83
84 static unsigned getHashValue(const APFloat &Key) {
85 return static_cast<unsigned>(hash_value(Key));
86 }
87
88 static bool isEqual(const APFloat &LHS, const APFloat &RHS) {
89 return LHS.bitwiseIsEqual(RHS);
90 }
91};
92
94 struct KeyTy {
97
98 KeyTy(const ArrayRef<Type *> &E, bool P) : ETypes(E), isPacked(P) {}
99
100 KeyTy(const StructType *ST)
101 : ETypes(ST->elements()), isPacked(ST->isPacked()) {}
102
103 bool operator==(const KeyTy &that) const {
104 if (isPacked != that.isPacked)
105 return false;
106 if (ETypes != that.ETypes)
107 return false;
108 return true;
109 }
110 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
111 };
112
113 static inline StructType *getEmptyKey() {
115 }
116
117 static inline StructType *getTombstoneKey() {
119 }
120
121 static unsigned getHashValue(const KeyTy &Key) {
122 return hash_combine(
123 hash_combine_range(Key.ETypes.begin(), Key.ETypes.end()), Key.isPacked);
124 }
125
126 static unsigned getHashValue(const StructType *ST) {
127 return getHashValue(KeyTy(ST));
128 }
129
130 static bool isEqual(const KeyTy &LHS, const StructType *RHS) {
131 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
132 return false;
133 return LHS == KeyTy(RHS);
134 }
135
136 static bool isEqual(const StructType *LHS, const StructType *RHS) {
137 return LHS == RHS;
138 }
139};
140
142 struct KeyTy {
146
147 KeyTy(const Type *R, const ArrayRef<Type *> &P, bool V)
148 : ReturnType(R), Params(P), isVarArg(V) {}
150 : ReturnType(FT->getReturnType()), Params(FT->params()),
151 isVarArg(FT->isVarArg()) {}
152
153 bool operator==(const KeyTy &that) const {
154 if (ReturnType != that.ReturnType)
155 return false;
156 if (isVarArg != that.isVarArg)
157 return false;
158 if (Params != that.Params)
159 return false;
160 return true;
161 }
162 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
163 };
164
165 static inline FunctionType *getEmptyKey() {
167 }
168
169 static inline FunctionType *getTombstoneKey() {
171 }
172
173 static unsigned getHashValue(const KeyTy &Key) {
174 return hash_combine(
175 Key.ReturnType,
176 hash_combine_range(Key.Params.begin(), Key.Params.end()), Key.isVarArg);
177 }
178
179 static unsigned getHashValue(const FunctionType *FT) {
180 return getHashValue(KeyTy(FT));
181 }
182
183 static bool isEqual(const KeyTy &LHS, const FunctionType *RHS) {
184 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
185 return false;
186 return LHS == KeyTy(RHS);
187 }
188
189 static bool isEqual(const FunctionType *LHS, const FunctionType *RHS) {
190 return LHS == RHS;
191 }
192};
193
195 struct KeyTy {
199
201 : Name(N), TypeParams(TP), IntParams(IP) {}
203 : Name(TT->getName()), TypeParams(TT->type_params()),
204 IntParams(TT->int_params()) {}
205
206 bool operator==(const KeyTy &that) const {
207 return Name == that.Name && TypeParams == that.TypeParams &&
208 IntParams == that.IntParams;
209 }
210 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
211 };
212
213 static inline TargetExtType *getEmptyKey() {
215 }
216
219 }
220
221 static unsigned getHashValue(const KeyTy &Key) {
222 return hash_combine(
223 Key.Name,
224 hash_combine_range(Key.TypeParams.begin(), Key.TypeParams.end()),
225 hash_combine_range(Key.IntParams.begin(), Key.IntParams.end()));
226 }
227
228 static unsigned getHashValue(const TargetExtType *FT) {
229 return getHashValue(KeyTy(FT));
230 }
231
232 static bool isEqual(const KeyTy &LHS, const TargetExtType *RHS) {
233 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
234 return false;
235 return LHS == KeyTy(RHS);
236 }
237
238 static bool isEqual(const TargetExtType *LHS, const TargetExtType *RHS) {
239 return LHS == RHS;
240 }
241};
242
243/// Structure for hashing arbitrary MDNode operands.
247 unsigned Hash;
248
249protected:
251 : RawOps(Ops), Hash(calculateHash(Ops)) {}
252
253 template <class NodeTy>
254 MDNodeOpsKey(const NodeTy *N, unsigned Offset = 0)
255 : Ops(N->op_begin() + Offset, N->op_end()), Hash(N->getHash()) {}
256
257 template <class NodeTy>
258 bool compareOps(const NodeTy *RHS, unsigned Offset = 0) const {
259 if (getHash() != RHS->getHash())
260 return false;
261
262 assert((RawOps.empty() || Ops.empty()) && "Two sets of operands?");
263 return RawOps.empty() ? compareOps(Ops, RHS, Offset)
264 : compareOps(RawOps, RHS, Offset);
265 }
266
267 static unsigned calculateHash(MDNode *N, unsigned Offset = 0);
268
269private:
270 template <class T>
271 static bool compareOps(ArrayRef<T> Ops, const MDNode *RHS, unsigned Offset) {
272 if (Ops.size() != RHS->getNumOperands() - Offset)
273 return false;
274 return std::equal(Ops.begin(), Ops.end(), RHS->op_begin() + Offset);
275 }
276
277 static unsigned calculateHash(ArrayRef<Metadata *> Ops);
278
279public:
280 unsigned getHash() const { return Hash; }
281};
282
283template <class NodeTy> struct MDNodeKeyImpl;
284
285/// Configuration point for MDNodeInfo::isEqual().
286template <class NodeTy> struct MDNodeSubsetEqualImpl {
288
289 static bool isSubsetEqual(const KeyTy &LHS, const NodeTy *RHS) {
290 return false;
291 }
292
293 static bool isSubsetEqual(const NodeTy *LHS, const NodeTy *RHS) {
294 return false;
295 }
296};
297
298/// DenseMapInfo for MDTuple.
299///
300/// Note that we don't need the is-function-local bit, since that's implicit in
301/// the operands.
302template <> struct MDNodeKeyImpl<MDTuple> : MDNodeOpsKey {
305
306 bool isKeyOf(const MDTuple *RHS) const { return compareOps(RHS); }
307
308 unsigned getHashValue() const { return getHash(); }
309
310 static unsigned calculateHash(MDTuple *N) {
312 }
313};
314
315/// DenseMapInfo for DILocation.
316template <> struct MDNodeKeyImpl<DILocation> {
317 unsigned Line;
318 unsigned Column;
322
323 MDNodeKeyImpl(unsigned Line, unsigned Column, Metadata *Scope,
324 Metadata *InlinedAt, bool ImplicitCode)
325 : Line(Line), Column(Column), Scope(Scope), InlinedAt(InlinedAt),
326 ImplicitCode(ImplicitCode) {}
328 : Line(L->getLine()), Column(L->getColumn()), Scope(L->getRawScope()),
329 InlinedAt(L->getRawInlinedAt()), ImplicitCode(L->isImplicitCode()) {}
330
331 bool isKeyOf(const DILocation *RHS) const {
332 return Line == RHS->getLine() && Column == RHS->getColumn() &&
333 Scope == RHS->getRawScope() && InlinedAt == RHS->getRawInlinedAt() &&
334 ImplicitCode == RHS->isImplicitCode();
335 }
336
337 unsigned getHashValue() const {
338 return hash_combine(Line, Column, Scope, InlinedAt, ImplicitCode);
339 }
340};
341
342/// DenseMapInfo for GenericDINode.
344 unsigned Tag;
346
347 MDNodeKeyImpl(unsigned Tag, MDString *Header, ArrayRef<Metadata *> DwarfOps)
348 : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {}
350 : MDNodeOpsKey(N, 1), Tag(N->getTag()), Header(N->getRawHeader()) {}
351
352 bool isKeyOf(const GenericDINode *RHS) const {
353 return Tag == RHS->getTag() && Header == RHS->getRawHeader() &&
354 compareOps(RHS, 1);
355 }
356
357 unsigned getHashValue() const { return hash_combine(getHash(), Tag, Header); }
358
359 static unsigned calculateHash(GenericDINode *N) {
361 }
362};
363
364template <> struct MDNodeKeyImpl<DISubrange> {
369
370 MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound,
371 Metadata *Stride)
372 : CountNode(CountNode), LowerBound(LowerBound), UpperBound(UpperBound),
373 Stride(Stride) {}
375 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
376 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
377
378 bool isKeyOf(const DISubrange *RHS) const {
379 auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool {
380 if (Node1 == Node2)
381 return true;
382
383 ConstantAsMetadata *MD1 = dyn_cast_or_null<ConstantAsMetadata>(Node1);
384 ConstantAsMetadata *MD2 = dyn_cast_or_null<ConstantAsMetadata>(Node2);
385 if (MD1 && MD2) {
386 ConstantInt *CV1 = cast<ConstantInt>(MD1->getValue());
387 ConstantInt *CV2 = cast<ConstantInt>(MD2->getValue());
388 if (CV1->getSExtValue() == CV2->getSExtValue())
389 return true;
390 }
391 return false;
392 };
393
394 return BoundsEqual(CountNode, RHS->getRawCountNode()) &&
395 BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
396 BoundsEqual(UpperBound, RHS->getRawUpperBound()) &&
397 BoundsEqual(Stride, RHS->getRawStride());
398 }
399
400 unsigned getHashValue() const {
401 if (CountNode)
402 if (auto *MD = dyn_cast<ConstantAsMetadata>(CountNode))
403 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
404 LowerBound, UpperBound, Stride);
405 return hash_combine(CountNode, LowerBound, UpperBound, Stride);
406 }
407};
408
409template <> struct MDNodeKeyImpl<DIGenericSubrange> {
414
415 MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound,
416 Metadata *Stride)
417 : CountNode(CountNode), LowerBound(LowerBound), UpperBound(UpperBound),
418 Stride(Stride) {}
420 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
421 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
422
423 bool isKeyOf(const DIGenericSubrange *RHS) const {
424 return (CountNode == RHS->getRawCountNode()) &&
425 (LowerBound == RHS->getRawLowerBound()) &&
426 (UpperBound == RHS->getRawUpperBound()) &&
427 (Stride == RHS->getRawStride());
428 }
429
430 unsigned getHashValue() const {
431 auto *MD = dyn_cast_or_null<ConstantAsMetadata>(CountNode);
432 if (CountNode && MD)
433 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
434 LowerBound, UpperBound, Stride);
435 return hash_combine(CountNode, LowerBound, UpperBound, Stride);
436 }
437};
438
439template <> struct MDNodeKeyImpl<DIEnumerator> {
443
445 : Value(std::move(Value)), Name(Name), IsUnsigned(IsUnsigned) {}
446 MDNodeKeyImpl(int64_t Value, bool IsUnsigned, MDString *Name)
447 : Value(APInt(64, Value, !IsUnsigned)), Name(Name),
448 IsUnsigned(IsUnsigned) {}
450 : Value(N->getValue()), Name(N->getRawName()),
451 IsUnsigned(N->isUnsigned()) {}
452
453 bool isKeyOf(const DIEnumerator *RHS) const {
454 return Value.getBitWidth() == RHS->getValue().getBitWidth() &&
455 Value == RHS->getValue() && IsUnsigned == RHS->isUnsigned() &&
456 Name == RHS->getRawName();
457 }
458
459 unsigned getHashValue() const { return hash_combine(Value, Name); }
460};
461
462template <> struct MDNodeKeyImpl<DIBasicType> {
463 unsigned Tag;
467 unsigned Encoding;
469 unsigned Flags;
470
471 MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits,
472 uint32_t AlignInBits, unsigned Encoding,
473 uint32_t NumExtraInhabitants, unsigned Flags)
474 : Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits),
475 Encoding(Encoding), NumExtraInhabitants(NumExtraInhabitants),
476 Flags(Flags) {}
478 : Tag(N->getTag()), Name(N->getRawName()), SizeInBits(N->getSizeInBits()),
479 AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()),
480 NumExtraInhabitants(N->getNumExtraInhabitants()), Flags(N->getFlags()) {
481 }
482
483 bool isKeyOf(const DIBasicType *RHS) const {
484 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
485 SizeInBits == RHS->getSizeInBits() &&
486 AlignInBits == RHS->getAlignInBits() &&
487 Encoding == RHS->getEncoding() &&
488 NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
489 Flags == RHS->getFlags();
490 }
491
492 unsigned getHashValue() const {
493 return hash_combine(Tag, Name, SizeInBits, AlignInBits, Encoding);
494 }
495};
496
497template <> struct MDNodeKeyImpl<DIStringType> {
498 unsigned Tag;
505 unsigned Encoding;
506
507 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *StringLength,
508 Metadata *StringLengthExp, Metadata *StringLocationExp,
509 uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding)
510 : Tag(Tag), Name(Name), StringLength(StringLength),
511 StringLengthExp(StringLengthExp), StringLocationExp(StringLocationExp),
512 SizeInBits(SizeInBits), AlignInBits(AlignInBits), Encoding(Encoding) {}
514 : Tag(N->getTag()), Name(N->getRawName()),
515 StringLength(N->getRawStringLength()),
516 StringLengthExp(N->getRawStringLengthExp()),
517 StringLocationExp(N->getRawStringLocationExp()),
518 SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()),
519 Encoding(N->getEncoding()) {}
520
521 bool isKeyOf(const DIStringType *RHS) const {
522 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
523 StringLength == RHS->getRawStringLength() &&
524 StringLengthExp == RHS->getRawStringLengthExp() &&
525 StringLocationExp == RHS->getRawStringLocationExp() &&
526 SizeInBits == RHS->getSizeInBits() &&
527 AlignInBits == RHS->getAlignInBits() &&
528 Encoding == RHS->getEncoding();
529 }
530 unsigned getHashValue() const {
531 // Intentionally computes the hash on a subset of the operands for
532 // performance reason. The subset has to be significant enough to avoid
533 // collision "most of the time". There is no correctness issue in case of
534 // collision because of the full check above.
535 return hash_combine(Tag, Name, StringLength, Encoding);
536 }
537};
538
539template <> struct MDNodeKeyImpl<DIDerivedType> {
540 unsigned Tag;
543 unsigned Line;
549 std::optional<unsigned> DWARFAddressSpace;
550 std::optional<DIDerivedType::PtrAuthData> PtrAuthData;
551 unsigned Flags;
554
555 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
556 Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
557 uint32_t AlignInBits, uint64_t OffsetInBits,
558 std::optional<unsigned> DWARFAddressSpace,
559 std::optional<DIDerivedType::PtrAuthData> PtrAuthData,
560 unsigned Flags, Metadata *ExtraData, Metadata *Annotations)
561 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
562 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
563 AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace),
564 PtrAuthData(PtrAuthData), Flags(Flags), ExtraData(ExtraData),
567 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
568 Line(N->getLine()), Scope(N->getRawScope()),
569 BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
570 OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()),
571 DWARFAddressSpace(N->getDWARFAddressSpace()),
572 PtrAuthData(N->getPtrAuthData()), Flags(N->getFlags()),
573 ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {}
574
575 bool isKeyOf(const DIDerivedType *RHS) const {
576 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
577 File == RHS->getRawFile() && Line == RHS->getLine() &&
578 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
579 SizeInBits == RHS->getSizeInBits() &&
580 AlignInBits == RHS->getAlignInBits() &&
581 OffsetInBits == RHS->getOffsetInBits() &&
582 DWARFAddressSpace == RHS->getDWARFAddressSpace() &&
583 PtrAuthData == RHS->getPtrAuthData() && Flags == RHS->getFlags() &&
584 ExtraData == RHS->getRawExtraData() &&
585 Annotations == RHS->getRawAnnotations();
586 }
587
588 unsigned getHashValue() const {
589 // If this is a member inside an ODR type, only hash the type and the name.
590 // Otherwise the hash will be stronger than
591 // MDNodeSubsetEqualImpl::isODRMember().
592 if (Tag == dwarf::DW_TAG_member && Name)
593 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
594 if (CT->getRawIdentifier())
595 return hash_combine(Name, Scope);
596
597 // Intentionally computes the hash on a subset of the operands for
598 // performance reason. The subset has to be significant enough to avoid
599 // collision "most of the time". There is no correctness issue in case of
600 // collision because of the full check above.
601 return hash_combine(Tag, Name, File, Line, Scope, BaseType, Flags);
602 }
603};
604
607
608 static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) {
609 return isODRMember(LHS.Tag, LHS.Scope, LHS.Name, RHS);
610 }
611
612 static bool isSubsetEqual(const DIDerivedType *LHS,
613 const DIDerivedType *RHS) {
614 return isODRMember(LHS->getTag(), LHS->getRawScope(), LHS->getRawName(),
615 RHS);
616 }
617
618 /// Subprograms compare equal if they declare the same function in an ODR
619 /// type.
620 static bool isODRMember(unsigned Tag, const Metadata *Scope,
621 const MDString *Name, const DIDerivedType *RHS) {
622 // Check whether the LHS is eligible.
623 if (Tag != dwarf::DW_TAG_member || !Name)
624 return false;
625
626 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
627 if (!CT || !CT->getRawIdentifier())
628 return false;
629
630 // Compare to the RHS.
631 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
632 Scope == RHS->getRawScope();
633 }
634};
635
636template <> struct MDNodeKeyImpl<DICompositeType> {
637 unsigned Tag;
640 unsigned Line;
646 unsigned Flags;
648 unsigned RuntimeLang;
660
661 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
662 Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
663 uint32_t AlignInBits, uint64_t OffsetInBits, unsigned Flags,
664 Metadata *Elements, unsigned RuntimeLang,
665 Metadata *VTableHolder, Metadata *TemplateParams,
666 MDString *Identifier, Metadata *Discriminator,
667 Metadata *DataLocation, Metadata *Associated,
668 Metadata *Allocated, Metadata *Rank, Metadata *Annotations,
669 Metadata *Specification, uint32_t NumExtraInhabitants)
670 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
671 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
672 AlignInBits(AlignInBits), Flags(Flags), Elements(Elements),
673 RuntimeLang(RuntimeLang), VTableHolder(VTableHolder),
674 TemplateParams(TemplateParams), Identifier(Identifier),
675 Discriminator(Discriminator), DataLocation(DataLocation),
676 Associated(Associated), Allocated(Allocated), Rank(Rank),
677 Annotations(Annotations), Specification(Specification),
678 NumExtraInhabitants(NumExtraInhabitants) {}
680 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
681 Line(N->getLine()), Scope(N->getRawScope()),
682 BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
683 OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()),
684 Flags(N->getFlags()), Elements(N->getRawElements()),
685 RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()),
686 TemplateParams(N->getRawTemplateParams()),
687 Identifier(N->getRawIdentifier()),
688 Discriminator(N->getRawDiscriminator()),
689 DataLocation(N->getRawDataLocation()),
690 Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()),
691 Rank(N->getRawRank()), Annotations(N->getRawAnnotations()),
692 Specification(N->getSpecification()),
693 NumExtraInhabitants(N->getNumExtraInhabitants()) {}
694
695 bool isKeyOf(const DICompositeType *RHS) const {
696 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
697 File == RHS->getRawFile() && Line == RHS->getLine() &&
698 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
699 SizeInBits == RHS->getSizeInBits() &&
700 AlignInBits == RHS->getAlignInBits() &&
701 OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() &&
702 Elements == RHS->getRawElements() &&
703 RuntimeLang == RHS->getRuntimeLang() &&
704 VTableHolder == RHS->getRawVTableHolder() &&
705 TemplateParams == RHS->getRawTemplateParams() &&
706 Identifier == RHS->getRawIdentifier() &&
707 Discriminator == RHS->getRawDiscriminator() &&
708 DataLocation == RHS->getRawDataLocation() &&
709 Associated == RHS->getRawAssociated() &&
710 Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() &&
711 Annotations == RHS->getRawAnnotations() &&
712 Specification == RHS->getSpecification() &&
713 NumExtraInhabitants == RHS->getNumExtraInhabitants();
714 }
715
716 unsigned getHashValue() const {
717 // Intentionally computes the hash on a subset of the operands for
718 // performance reason. The subset has to be significant enough to avoid
719 // collision "most of the time". There is no correctness issue in case of
720 // collision because of the full check above.
721 return hash_combine(Name, File, Line, BaseType, Scope, Elements,
722 TemplateParams, Annotations);
723 }
724};
725
726template <> struct MDNodeKeyImpl<DISubroutineType> {
727 unsigned Flags;
730
731 MDNodeKeyImpl(unsigned Flags, uint8_t CC, Metadata *TypeArray)
732 : Flags(Flags), CC(CC), TypeArray(TypeArray) {}
734 : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()) {}
735
736 bool isKeyOf(const DISubroutineType *RHS) const {
737 return Flags == RHS->getFlags() && CC == RHS->getCC() &&
738 TypeArray == RHS->getRawTypeArray();
739 }
740
741 unsigned getHashValue() const { return hash_combine(Flags, CC, TypeArray); }
742};
743
744template <> struct MDNodeKeyImpl<DIFile> {
747 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum;
749
750 MDNodeKeyImpl(MDString *Filename, MDString *Directory,
751 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum,
752 MDString *Source)
753 : Filename(Filename), Directory(Directory), Checksum(Checksum),
754 Source(Source) {}
756 : Filename(N->getRawFilename()), Directory(N->getRawDirectory()),
757 Checksum(N->getRawChecksum()), Source(N->getRawSource()) {}
758
759 bool isKeyOf(const DIFile *RHS) const {
760 return Filename == RHS->getRawFilename() &&
761 Directory == RHS->getRawDirectory() &&
762 Checksum == RHS->getRawChecksum() && Source == RHS->getRawSource();
763 }
764
765 unsigned getHashValue() const {
766 return hash_combine(Filename, Directory, Checksum ? Checksum->Kind : 0,
767 Checksum ? Checksum->Value : nullptr, Source);
768 }
769};
770
771template <> struct MDNodeKeyImpl<DISubprogram> {
776 unsigned Line;
778 unsigned ScopeLine;
780 unsigned VirtualIndex;
782 unsigned Flags;
783 unsigned SPFlags;
791
793 Metadata *File, unsigned Line, Metadata *Type,
794 unsigned ScopeLine, Metadata *ContainingType,
795 unsigned VirtualIndex, int ThisAdjustment, unsigned Flags,
796 unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams,
797 Metadata *Declaration, Metadata *RetainedNodes,
798 Metadata *ThrownTypes, Metadata *Annotations,
799 MDString *TargetFuncName)
800 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
801 Line(Line), Type(Type), ScopeLine(ScopeLine),
802 ContainingType(ContainingType), VirtualIndex(VirtualIndex),
803 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags),
804 Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration),
805 RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes),
806 Annotations(Annotations), TargetFuncName(TargetFuncName) {}
808 : Scope(N->getRawScope()), Name(N->getRawName()),
809 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
810 Line(N->getLine()), Type(N->getRawType()), ScopeLine(N->getScopeLine()),
811 ContainingType(N->getRawContainingType()),
812 VirtualIndex(N->getVirtualIndex()),
813 ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()),
814 SPFlags(N->getSPFlags()), Unit(N->getRawUnit()),
815 TemplateParams(N->getRawTemplateParams()),
816 Declaration(N->getRawDeclaration()),
817 RetainedNodes(N->getRawRetainedNodes()),
818 ThrownTypes(N->getRawThrownTypes()),
819 Annotations(N->getRawAnnotations()),
820 TargetFuncName(N->getRawTargetFuncName()) {}
821
822 bool isKeyOf(const DISubprogram *RHS) const {
823 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
824 LinkageName == RHS->getRawLinkageName() &&
825 File == RHS->getRawFile() && Line == RHS->getLine() &&
826 Type == RHS->getRawType() && ScopeLine == RHS->getScopeLine() &&
827 ContainingType == RHS->getRawContainingType() &&
828 VirtualIndex == RHS->getVirtualIndex() &&
829 ThisAdjustment == RHS->getThisAdjustment() &&
830 Flags == RHS->getFlags() && SPFlags == RHS->getSPFlags() &&
831 Unit == RHS->getUnit() &&
832 TemplateParams == RHS->getRawTemplateParams() &&
833 Declaration == RHS->getRawDeclaration() &&
834 RetainedNodes == RHS->getRawRetainedNodes() &&
835 ThrownTypes == RHS->getRawThrownTypes() &&
836 Annotations == RHS->getRawAnnotations() &&
837 TargetFuncName == RHS->getRawTargetFuncName();
838 }
839
840 bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; }
841
842 unsigned getHashValue() const {
843 // Use the Scope's linkage name instead of using the scope directly, as the
844 // scope may be a temporary one which can replaced, which would produce a
845 // different hash for the same DISubprogram.
846 llvm::StringRef ScopeLinkageName;
847 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
848 if (auto *ID = CT->getRawIdentifier())
849 ScopeLinkageName = ID->getString();
850
851 // If this is a declaration inside an ODR type, only hash the type and the
852 // name. Otherwise the hash will be stronger than
853 // MDNodeSubsetEqualImpl::isDeclarationOfODRMember().
854 if (!isDefinition() && LinkageName &&
855 isa_and_nonnull<DICompositeType>(Scope))
856 return hash_combine(LinkageName, ScopeLinkageName);
857
858 // Intentionally computes the hash on a subset of the operands for
859 // performance reason. The subset has to be significant enough to avoid
860 // collision "most of the time". There is no correctness issue in case of
861 // collision because of the full check above.
862 return hash_combine(Name, ScopeLinkageName, File, Type, Line);
863 }
864};
865
868
869 static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) {
870 return isDeclarationOfODRMember(LHS.isDefinition(), LHS.Scope,
871 LHS.LinkageName, LHS.TemplateParams, RHS);
872 }
873
874 static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) {
875 return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(),
876 LHS->getRawLinkageName(),
877 LHS->getRawTemplateParams(), RHS);
878 }
879
880 /// Subprograms compare equal if they declare the same function in an ODR
881 /// type.
882 static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope,
883 const MDString *LinkageName,
884 const Metadata *TemplateParams,
885 const DISubprogram *RHS) {
886 // Check whether the LHS is eligible.
887 if (IsDefinition || !Scope || !LinkageName)
888 return false;
889
890 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
891 if (!CT || !CT->getRawIdentifier())
892 return false;
893
894 // Compare to the RHS.
895 // FIXME: We need to compare template parameters here to avoid incorrect
896 // collisions in mapMetadata when RF_ReuseAndMutateDistinctMDs and a
897 // ODR-DISubprogram has a non-ODR template parameter (i.e., a
898 // DICompositeType that does not have an identifier). Eventually we should
899 // decouple ODR logic from uniquing logic.
900 return IsDefinition == RHS->isDefinition() && Scope == RHS->getRawScope() &&
901 LinkageName == RHS->getRawLinkageName() &&
902 TemplateParams == RHS->getRawTemplateParams();
903 }
904};
905
906template <> struct MDNodeKeyImpl<DILexicalBlock> {
909 unsigned Line;
910 unsigned Column;
911
912 MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Line, unsigned Column)
913 : Scope(Scope), File(File), Line(Line), Column(Column) {}
915 : Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()),
916 Column(N->getColumn()) {}
917
918 bool isKeyOf(const DILexicalBlock *RHS) const {
919 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
920 Line == RHS->getLine() && Column == RHS->getColumn();
921 }
922
923 unsigned getHashValue() const {
924 return hash_combine(Scope, File, Line, Column);
925 }
926};
927
932
933 MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator)
934 : Scope(Scope), File(File), Discriminator(Discriminator) {}
936 : Scope(N->getRawScope()), File(N->getRawFile()),
937 Discriminator(N->getDiscriminator()) {}
938
939 bool isKeyOf(const DILexicalBlockFile *RHS) const {
940 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
941 Discriminator == RHS->getDiscriminator();
942 }
943
944 unsigned getHashValue() const {
945 return hash_combine(Scope, File, Discriminator);
946 }
947};
948
949template <> struct MDNodeKeyImpl<DINamespace> {
953
954 MDNodeKeyImpl(Metadata *Scope, MDString *Name, bool ExportSymbols)
955 : Scope(Scope), Name(Name), ExportSymbols(ExportSymbols) {}
957 : Scope(N->getRawScope()), Name(N->getRawName()),
958 ExportSymbols(N->getExportSymbols()) {}
959
960 bool isKeyOf(const DINamespace *RHS) const {
961 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
962 ExportSymbols == RHS->getExportSymbols();
963 }
964
965 unsigned getHashValue() const { return hash_combine(Scope, Name); }
966};
967
968template <> struct MDNodeKeyImpl<DICommonBlock> {
973 unsigned LineNo;
974
976 unsigned LineNo)
977 : Scope(Scope), Decl(Decl), Name(Name), File(File), LineNo(LineNo) {}
979 : Scope(N->getRawScope()), Decl(N->getRawDecl()), Name(N->getRawName()),
980 File(N->getRawFile()), LineNo(N->getLineNo()) {}
981
982 bool isKeyOf(const DICommonBlock *RHS) const {
983 return Scope == RHS->getRawScope() && Decl == RHS->getRawDecl() &&
984 Name == RHS->getRawName() && File == RHS->getRawFile() &&
985 LineNo == RHS->getLineNo();
986 }
987
988 unsigned getHashValue() const {
989 return hash_combine(Scope, Decl, Name, File, LineNo);
990 }
991};
992
993template <> struct MDNodeKeyImpl<DIModule> {
1000 unsigned LineNo;
1002
1004 MDString *ConfigurationMacros, MDString *IncludePath,
1005 MDString *APINotesFile, unsigned LineNo, bool IsDecl)
1006 : File(File), Scope(Scope), Name(Name),
1007 ConfigurationMacros(ConfigurationMacros), IncludePath(IncludePath),
1008 APINotesFile(APINotesFile), LineNo(LineNo), IsDecl(IsDecl) {}
1010 : File(N->getRawFile()), Scope(N->getRawScope()), Name(N->getRawName()),
1011 ConfigurationMacros(N->getRawConfigurationMacros()),
1012 IncludePath(N->getRawIncludePath()),
1013 APINotesFile(N->getRawAPINotesFile()), LineNo(N->getLineNo()),
1014 IsDecl(N->getIsDecl()) {}
1015
1016 bool isKeyOf(const DIModule *RHS) const {
1017 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1018 ConfigurationMacros == RHS->getRawConfigurationMacros() &&
1019 IncludePath == RHS->getRawIncludePath() &&
1020 APINotesFile == RHS->getRawAPINotesFile() &&
1021 File == RHS->getRawFile() && LineNo == RHS->getLineNo() &&
1022 IsDecl == RHS->getIsDecl();
1023 }
1024
1025 unsigned getHashValue() const {
1026 return hash_combine(Scope, Name, ConfigurationMacros, IncludePath);
1027 }
1028};
1029
1034
1036 : Name(Name), Type(Type), IsDefault(IsDefault) {}
1038 : Name(N->getRawName()), Type(N->getRawType()),
1039 IsDefault(N->isDefault()) {}
1040
1042 return Name == RHS->getRawName() && Type == RHS->getRawType() &&
1043 IsDefault == RHS->isDefault();
1044 }
1045
1046 unsigned getHashValue() const { return hash_combine(Name, Type, IsDefault); }
1047};
1048
1050 unsigned Tag;
1055
1056 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *Type, bool IsDefault,
1057 Metadata *Value)
1058 : Tag(Tag), Name(Name), Type(Type), IsDefault(IsDefault), Value(Value) {}
1060 : Tag(N->getTag()), Name(N->getRawName()), Type(N->getRawType()),
1061 IsDefault(N->isDefault()), Value(N->getValue()) {}
1062
1064 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
1065 Type == RHS->getRawType() && IsDefault == RHS->isDefault() &&
1066 Value == RHS->getValue();
1067 }
1068
1069 unsigned getHashValue() const {
1070 return hash_combine(Tag, Name, Type, IsDefault, Value);
1071 }
1072};
1073
1074template <> struct MDNodeKeyImpl<DIGlobalVariable> {
1079 unsigned Line;
1087
1089 Metadata *File, unsigned Line, Metadata *Type,
1090 bool IsLocalToUnit, bool IsDefinition,
1091 Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
1092 uint32_t AlignInBits, Metadata *Annotations)
1093 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
1094 Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit),
1095 IsDefinition(IsDefinition),
1096 StaticDataMemberDeclaration(StaticDataMemberDeclaration),
1097 TemplateParams(TemplateParams), AlignInBits(AlignInBits),
1100 : Scope(N->getRawScope()), Name(N->getRawName()),
1101 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
1102 Line(N->getLine()), Type(N->getRawType()),
1103 IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
1104 StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()),
1105 TemplateParams(N->getRawTemplateParams()),
1106 AlignInBits(N->getAlignInBits()), Annotations(N->getRawAnnotations()) {}
1107
1108 bool isKeyOf(const DIGlobalVariable *RHS) const {
1109 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1110 LinkageName == RHS->getRawLinkageName() &&
1111 File == RHS->getRawFile() && Line == RHS->getLine() &&
1112 Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() &&
1113 IsDefinition == RHS->isDefinition() &&
1114 StaticDataMemberDeclaration ==
1115 RHS->getRawStaticDataMemberDeclaration() &&
1116 TemplateParams == RHS->getRawTemplateParams() &&
1117 AlignInBits == RHS->getAlignInBits() &&
1118 Annotations == RHS->getRawAnnotations();
1119 }
1120
1121 unsigned getHashValue() const {
1122 // We do not use AlignInBits in hashing function here on purpose:
1123 // in most cases this param for local variable is zero (for function param
1124 // it is always zero). This leads to lots of hash collisions and errors on
1125 // cases with lots of similar variables.
1126 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1127 // generated IR is random for each run and test fails with Align included.
1128 // TODO: make hashing work fine with such situations
1129 return hash_combine(Scope, Name, LinkageName, File, Line, Type,
1130 IsLocalToUnit, IsDefinition, /* AlignInBits, */
1131 StaticDataMemberDeclaration, Annotations);
1132 }
1133};
1134
1135template <> struct MDNodeKeyImpl<DILocalVariable> {
1139 unsigned Line;
1141 unsigned Arg;
1142 unsigned Flags;
1145
1146 MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line,
1147 Metadata *Type, unsigned Arg, unsigned Flags,
1148 uint32_t AlignInBits, Metadata *Annotations)
1149 : Scope(Scope), Name(Name), File(File), Line(Line), Type(Type), Arg(Arg),
1150 Flags(Flags), AlignInBits(AlignInBits), Annotations(Annotations) {}
1152 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1153 Line(N->getLine()), Type(N->getRawType()), Arg(N->getArg()),
1154 Flags(N->getFlags()), AlignInBits(N->getAlignInBits()),
1155 Annotations(N->getRawAnnotations()) {}
1156
1157 bool isKeyOf(const DILocalVariable *RHS) const {
1158 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1159 File == RHS->getRawFile() && Line == RHS->getLine() &&
1160 Type == RHS->getRawType() && Arg == RHS->getArg() &&
1161 Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits() &&
1162 Annotations == RHS->getRawAnnotations();
1163 }
1164
1165 unsigned getHashValue() const {
1166 // We do not use AlignInBits in hashing function here on purpose:
1167 // in most cases this param for local variable is zero (for function param
1168 // it is always zero). This leads to lots of hash collisions and errors on
1169 // cases with lots of similar variables.
1170 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1171 // generated IR is random for each run and test fails with Align included.
1172 // TODO: make hashing work fine with such situations
1173 return hash_combine(Scope, Name, File, Line, Type, Arg, Flags, Annotations);
1174 }
1175};
1176
1177template <> struct MDNodeKeyImpl<DILabel> {
1181 unsigned Line;
1182
1183 MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line)
1184 : Scope(Scope), Name(Name), File(File), Line(Line) {}
1186 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1187 Line(N->getLine()) {}
1188
1189 bool isKeyOf(const DILabel *RHS) const {
1190 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1191 File == RHS->getRawFile() && Line == RHS->getLine();
1192 }
1193
1194 /// Using name and line to get hash value. It should already be mostly unique.
1195 unsigned getHashValue() const { return hash_combine(Scope, Name, Line); }
1196};
1197
1198template <> struct MDNodeKeyImpl<DIExpression> {
1200
1201 MDNodeKeyImpl(ArrayRef<uint64_t> Elements) : Elements(Elements) {}
1202 MDNodeKeyImpl(const DIExpression *N) : Elements(N->getElements()) {}
1203
1204 bool isKeyOf(const DIExpression *RHS) const {
1205 return Elements == RHS->getElements();
1206 }
1207
1208 unsigned getHashValue() const {
1209 return hash_combine_range(Elements.begin(), Elements.end());
1210 }
1211};
1212
1216
1218 : Variable(Variable), Expression(Expression) {}
1220 : Variable(N->getRawVariable()), Expression(N->getRawExpression()) {}
1221
1223 return Variable == RHS->getRawVariable() &&
1224 Expression == RHS->getRawExpression();
1225 }
1226
1227 unsigned getHashValue() const { return hash_combine(Variable, Expression); }
1228};
1229
1230template <> struct MDNodeKeyImpl<DIObjCProperty> {
1233 unsigned Line;
1236 unsigned Attributes;
1238
1239 MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line,
1240 MDString *GetterName, MDString *SetterName, unsigned Attributes,
1241 Metadata *Type)
1242 : Name(Name), File(File), Line(Line), GetterName(GetterName),
1243 SetterName(SetterName), Attributes(Attributes), Type(Type) {}
1245 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
1246 GetterName(N->getRawGetterName()), SetterName(N->getRawSetterName()),
1247 Attributes(N->getAttributes()), Type(N->getRawType()) {}
1248
1249 bool isKeyOf(const DIObjCProperty *RHS) const {
1250 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
1251 Line == RHS->getLine() && GetterName == RHS->getRawGetterName() &&
1252 SetterName == RHS->getRawSetterName() &&
1253 Attributes == RHS->getAttributes() && Type == RHS->getRawType();
1254 }
1255
1256 unsigned getHashValue() const {
1257 return hash_combine(Name, File, Line, GetterName, SetterName, Attributes,
1258 Type);
1259 }
1260};
1261
1262template <> struct MDNodeKeyImpl<DIImportedEntity> {
1263 unsigned Tag;
1267 unsigned Line;
1270
1271 MDNodeKeyImpl(unsigned Tag, Metadata *Scope, Metadata *Entity, Metadata *File,
1272 unsigned Line, MDString *Name, Metadata *Elements)
1273 : Tag(Tag), Scope(Scope), Entity(Entity), File(File), Line(Line),
1274 Name(Name), Elements(Elements) {}
1276 : Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()),
1277 File(N->getRawFile()), Line(N->getLine()), Name(N->getRawName()),
1278 Elements(N->getRawElements()) {}
1279
1280 bool isKeyOf(const DIImportedEntity *RHS) const {
1281 return Tag == RHS->getTag() && Scope == RHS->getRawScope() &&
1282 Entity == RHS->getRawEntity() && File == RHS->getFile() &&
1283 Line == RHS->getLine() && Name == RHS->getRawName() &&
1284 Elements == RHS->getRawElements();
1285 }
1286
1287 unsigned getHashValue() const {
1288 return hash_combine(Tag, Scope, Entity, File, Line, Name, Elements);
1289 }
1290};
1291
1292template <> struct MDNodeKeyImpl<DIMacro> {
1293 unsigned MIType;
1294 unsigned Line;
1297
1298 MDNodeKeyImpl(unsigned MIType, unsigned Line, MDString *Name, MDString *Value)
1299 : MIType(MIType), Line(Line), Name(Name), Value(Value) {}
1301 : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getRawName()),
1302 Value(N->getRawValue()) {}
1303
1304 bool isKeyOf(const DIMacro *RHS) const {
1305 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1306 Name == RHS->getRawName() && Value == RHS->getRawValue();
1307 }
1308
1309 unsigned getHashValue() const {
1310 return hash_combine(MIType, Line, Name, Value);
1311 }
1312};
1313
1314template <> struct MDNodeKeyImpl<DIMacroFile> {
1315 unsigned MIType;
1316 unsigned Line;
1319
1320 MDNodeKeyImpl(unsigned MIType, unsigned Line, Metadata *File,
1321 Metadata *Elements)
1322 : MIType(MIType), Line(Line), File(File), Elements(Elements) {}
1324 : MIType(N->getMacinfoType()), Line(N->getLine()), File(N->getRawFile()),
1325 Elements(N->getRawElements()) {}
1326
1327 bool isKeyOf(const DIMacroFile *RHS) const {
1328 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1329 File == RHS->getRawFile() && Elements == RHS->getRawElements();
1330 }
1331
1332 unsigned getHashValue() const {
1333 return hash_combine(MIType, Line, File, Elements);
1334 }
1335};
1336
1337// DIArgLists are not MDNodes, but we still want to unique them in a DenseSet
1338// based on a hash of their arguments.
1341
1343 DIArgListKeyInfo(const DIArgList *N) : Args(N->getArgs()) {}
1344
1345 bool isKeyOf(const DIArgList *RHS) const { return Args == RHS->getArgs(); }
1346
1347 unsigned getHashValue() const {
1348 return hash_combine_range(Args.begin(), Args.end());
1349 }
1350};
1351
1352/// DenseMapInfo for DIArgList.
1355
1356 static inline DIArgList *getEmptyKey() {
1358 }
1359
1360 static inline DIArgList *getTombstoneKey() {
1362 }
1363
1364 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1365
1366 static unsigned getHashValue(const DIArgList *N) {
1367 return KeyTy(N).getHashValue();
1368 }
1369
1370 static bool isEqual(const KeyTy &LHS, const DIArgList *RHS) {
1371 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1372 return false;
1373 return LHS.isKeyOf(RHS);
1374 }
1375
1376 static bool isEqual(const DIArgList *LHS, const DIArgList *RHS) {
1377 return LHS == RHS;
1378 }
1379};
1380
1381/// DenseMapInfo for MDNode subclasses.
1382template <class NodeTy> struct MDNodeInfo {
1385
1386 static inline NodeTy *getEmptyKey() {
1388 }
1389
1390 static inline NodeTy *getTombstoneKey() {
1392 }
1393
1394 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1395
1396 static unsigned getHashValue(const NodeTy *N) {
1397 return KeyTy(N).getHashValue();
1398 }
1399
1400 static bool isEqual(const KeyTy &LHS, const NodeTy *RHS) {
1401 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1402 return false;
1403 return SubsetEqualTy::isSubsetEqual(LHS, RHS) || LHS.isKeyOf(RHS);
1404 }
1405
1406 static bool isEqual(const NodeTy *LHS, const NodeTy *RHS) {
1407 if (LHS == RHS)
1408 return true;
1409 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1410 return false;
1412 }
1413};
1414
1415#define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>;
1416#include "llvm/IR/Metadata.def"
1417
1418/// Multimap-like storage for metadata attachments.
1420public:
1421 struct Attachment {
1422 unsigned MDKind;
1424 };
1425
1426private:
1427 SmallVector<Attachment, 1> Attachments;
1428
1429public:
1430 bool empty() const { return Attachments.empty(); }
1431 size_t size() const { return Attachments.size(); }
1432
1433 /// Returns the first attachment with the given ID or nullptr if no such
1434 /// attachment exists.
1435 MDNode *lookup(unsigned ID) const;
1436
1437 /// Appends all attachments with the given ID to \c Result in insertion order.
1438 /// If the global has no attachments with the given ID, or if ID is invalid,
1439 /// leaves Result unchanged.
1440 void get(unsigned ID, SmallVectorImpl<MDNode *> &Result) const;
1441
1442 /// Appends all attachments for the global to \c Result, sorting by attachment
1443 /// ID. Attachments with the same ID appear in insertion order. This function
1444 /// does \em not clear \c Result.
1445 void getAll(SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const;
1446
1447 /// Set an attachment to a particular node.
1448 ///
1449 /// Set the \c ID attachment to \c MD, replacing the current attachments at \c
1450 /// ID (if anyway).
1451 void set(unsigned ID, MDNode *MD);
1452
1453 /// Adds an attachment to a particular node.
1454 void insert(unsigned ID, MDNode &MD);
1455
1456 /// Remove attachments with the given ID.
1457 ///
1458 /// Remove the attachments at \c ID, if any.
1459 bool erase(unsigned ID);
1460
1461 /// Erase matching attachments.
1462 ///
1463 /// Erases all attachments matching the \c shouldRemove predicate.
1464 template <class PredTy> void remove_if(PredTy shouldRemove) {
1465 llvm::erase_if(Attachments, shouldRemove);
1466 }
1467};
1468
1470public:
1471 /// OwnedModules - The set of modules instantiated in this context, and which
1472 /// will be automatically deleted if this context is deleted.
1474
1475 /// MachineFunctionNums - Keep the next available unique number available for
1476 /// a MachineFunction in given module. Module must in OwnedModules.
1478
1479 /// The main remark streamer used by all the other streamers (e.g. IR, MIR,
1480 /// frontends, etc.). This should only be used by the specific streamers, and
1481 /// never directly.
1482 std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer;
1483
1484 std::unique_ptr<DiagnosticHandler> DiagHandler;
1487 /// The minimum hotness value a diagnostic needs in order to be included in
1488 /// optimization diagnostics.
1489 ///
1490 /// The threshold is an Optional value, which maps to one of the 3 states:
1491 /// 1). 0 => threshold disabled. All emarks will be printed.
1492 /// 2). positive int => manual threshold by user. Remarks with hotness exceed
1493 /// threshold will be printed.
1494 /// 3). None => 'auto' threshold by user. The actual value is not
1495 /// available at command line, but will be synced with
1496 /// hotness threhold from profile summary during
1497 /// compilation.
1498 ///
1499 /// State 1 and 2 are considered as terminal states. State transition is
1500 /// only allowed from 3 to 2, when the threshold is first synced with profile
1501 /// summary. This ensures that the threshold is set only once and stays
1502 /// constant.
1503 ///
1504 /// If threshold option is not specified, it is disabled (0) by default.
1505 std::optional<uint64_t> DiagnosticsHotnessThreshold = 0;
1506
1507 /// The percentage of difference between profiling branch weights and
1508 /// llvm.expect branch weights to tolerate when emiting MisExpect diagnostics
1509 std::optional<uint32_t> DiagnosticsMisExpectTolerance = 0;
1511
1512 /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
1513 std::unique_ptr<LLVMRemarkStreamer> LLVMRS;
1514
1516 void *YieldOpaqueHandle = nullptr;
1517
1519
1523 DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantInt>>
1525
1527 DenseMap<std::pair<ElementCount, APFloat>, std::unique_ptr<ConstantFP>>
1529
1533
1538
1539#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
1540 DenseSet<CLASS *, CLASS##Info> CLASS##s;
1541#include "llvm/IR/Metadata.def"
1542
1543 // Optional map for looking up composite types by identifier.
1544 std::optional<DenseMap<const MDString *, DICompositeType *>> DITypeMap;
1545
1546 // MDNodes may be uniqued or not uniqued. When they're not uniqued, they
1547 // aren't in the MDNodeSet, but they're still shared between objects, so no
1548 // one object can destroy them. Keep track of them here so we can delete
1549 // them on context teardown.
1550 std::vector<MDNode *> DistinctMDNodes;
1551
1552 // ConstantRangeListAttributeImpl is a TrailingObjects/ArrayRef of
1553 // ConstantRange. Since this is a dynamically sized class, it's not
1554 // possible to use SpecificBumpPtrAllocator. Instead, we use normal Alloc
1555 // for allocation and record all allocated pointers in this vector. In the
1556 // LLVMContext destructor, call the destuctors of everything in the vector.
1557 std::vector<ConstantRangeListAttributeImpl *> ConstantRangeListAttributes;
1558
1560
1563
1566
1569
1571
1573
1575
1577
1579
1582
1584
1586
1588
1590
1592
1595
1596 // Basic type instances.
1601
1602 std::unique_ptr<ConstantTokenNone> TheNoneToken;
1603
1608
1610
1617
1620
1623 PointerType *AS0PointerType = nullptr; // AddrSpace = 0
1626
1627 /// ValueHandles - This map keeps track of all of the value handles that are
1628 /// watching a Value*. The Value::HasValueHandle bit is used to know
1629 /// whether or not a value has an entry in this map.
1632
1633 /// CustomMDKindNames - Map to hold the metadata string to ID mapping.
1635
1636 /// Collection of metadata used in this context.
1638
1639 /// Map DIAssignID -> Instructions with that attachment.
1640 /// Managed by Instruction via Instruction::updateDIAssignIDMapping.
1641 /// Query using the at:: functions defined in DebugInfo.h.
1643
1644 /// Collection of per-GlobalObject sections used in this context.
1646
1647 /// Collection of per-GlobalValue partitions used in this context.
1649
1652
1653 /// DiscriminatorTable - This table maps file:line locations to an
1654 /// integer representing the next DWARF path discriminator to assign to
1655 /// instructions in different blocks at the same location.
1657
1658 /// A set of interned tags for operand bundles. The StringMap maps
1659 /// bundle tags to their IDs.
1660 ///
1661 /// \see LLVMContext::getOperandBundleTagID
1663
1667
1668 /// A set of interned synchronization scopes. The StringMap maps
1669 /// synchronization scope names to their respective synchronization scope IDs.
1671
1672 /// getOrInsertSyncScopeID - Maps synchronization scope name to
1673 /// synchronization scope ID. Every synchronization scope registered with
1674 /// LLVMContext has unique ID except pre-defined ones.
1676
1677 /// getSyncScopeNames - Populates client supplied SmallVector with
1678 /// synchronization scope names registered with LLVMContext. Synchronization
1679 /// scope names are ordered by increasing synchronization scope IDs.
1681
1682 /// getSyncScopeName - Returns the name of a SyncScope::ID
1683 /// registered with LLVMContext, if any.
1684 std::optional<StringRef> getSyncScopeName(SyncScope::ID Id) const;
1685
1686 /// Maintain the GC name for each function.
1687 ///
1688 /// This saves allocating an additional word in Function for programs which
1689 /// do not use GC (i.e., most programs) at the cost of increased overhead for
1690 /// clients which do use GC.
1692
1693 /// Flag to indicate if Value (other than GlobalValue) retains their name or
1694 /// not.
1695 bool DiscardValueNames = false;
1696
1699
1700 /// Destroy the ConstantArrays if they are not used.
1702
1703 mutable OptPassGate *OPG = nullptr;
1704
1705 /// Access the object which can disable optional passes and individual
1706 /// optimizations at compile time.
1707 OptPassGate &getOptPassGate() const;
1708
1709 /// Set the object which can disable optional passes and individual
1710 /// optimizations at compile time.
1711 ///
1712 /// The lifetime of the object must be guaranteed to extend as long as the
1713 /// LLVMContext is used by compilation.
1715
1716 /// Mapping of blocks to collections of "trailing" DbgVariableRecords. As part
1717 /// of the "RemoveDIs" project, debug-info variable location records are going
1718 /// to cease being instructions... which raises the problem of where should
1719 /// they be recorded when we remove the terminator of a blocks, such as:
1720 ///
1721 /// %foo = add i32 0, 0
1722 /// br label %bar
1723 ///
1724 /// If the branch is removed, a legitimate transient state while editing a
1725 /// block, any debug-records between those two instructions will not have a
1726 /// location. Each block thus records any DbgVariableRecord records that
1727 /// "trail" in such a way. These are stored in LLVMContext because typically
1728 /// LLVM only edits a small number of blocks at a time, so there's no need to
1729 /// bloat BasicBlock with such a data structure.
1731
1732 // Set, get and delete operations for TrailingDbgRecords.
1734 assert(!TrailingDbgRecords.count(B));
1735 TrailingDbgRecords[B] = M;
1736 }
1737
1739 return TrailingDbgRecords.lookup(B);
1740 }
1741
1743
1744 std::string DefaultTargetCPU;
1746};
1747
1748} // end namespace llvm
1749
1750#endif // LLVM_LIB_IR_LLVMCONTEXTIMPL_H
static std::optional< unsigned > getTag(const TargetRegisterInfo *TRI, const MachineInstr &MI, const LoadInfo &LI)
This file defines the StringMap class.
AMDGPU Kernel Attributes
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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.
std::string Name
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.
This file contains the declarations for metadata subclasses.
#define P(N)
static StringRef getName(Value *V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
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
Annotations lets you mark points and ranges inside source code, for tests:
Definition: Annotations.h:53
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
iterator end() const
Definition: ArrayRef.h:157
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:168
iterator begin() const
Definition: ArrayRef.h:156
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:163
Class to represent array types.
Definition: DerivedTypes.h:395
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
The address of a basic block.
Definition: Constants.h:893
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:66
Constant * getValue() const
Definition: Metadata.h:536
This is the shared class of boolean and integer constants.
Definition: Constants.h:83
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:163
List of ValueAsMetadata, to be used as an argument to a dbg.value intrinsic.
Basic type, like 'int' or 'float'.
Debug common block.
Enumeration value.
DWARF expression.
A pair of DIGlobalVariable and DIExpression.
An imported module (C++ using directive or similar).
Debug lexical block.
Debug location.
Represents a module in the programming language, for example, a Clang module, or a Fortran module.
Debug lexical block.
String type, Fortran CHARACTER(n)
Subprogram description.
Array subrange.
Type array for a subprogram.
Per-instruction record of debug-info.
Implements a dense probed hash-table based set.
Definition: DenseSet.h:278
Class representing an expression and its matching format.
FoldingSet - This template class is used to instantiate a specialized implementation of the folding s...
Definition: FoldingSet.h:536
Class to represent function types.
Definition: DerivedTypes.h:105
Generic tagged DWARF-like metadata node.
Class to represent integer types.
Definition: DerivedTypes.h:42
DenseMap< const GlobalValue *, StringRef > GlobalValuePartitions
Collection of per-GlobalValue partitions used in this context.
DenseMap< const GlobalValue *, GlobalValue::SanitizerMetadata > GlobalValueSanitizerMetadata
DenseMap< unsigned, std::unique_ptr< ConstantInt > > IntOneConstants
void getSyncScopeNames(SmallVectorImpl< StringRef > &SSNs) const
getSyncScopeNames - Populates client supplied SmallVector with synchronization scope names registered...
DenseMap< unsigned, std::unique_ptr< ConstantInt > > IntZeroConstants
DenseMap< Metadata *, MetadataAsValue * > MetadataAsValues
DenseMap< 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< PointerType *, std::unique_ptr< ConstantPointerNull > > CPNConstants
DenseMap< Type *, std::unique_ptr< ConstantAggregateZero > > CAZConstants
StringMap< MDString, BumpPtrAllocator > MDStringCache
TargetExtTypeSet TargetExtTypes
DenseMap< DIAssignID *, SmallVector< Instruction *, 1 > > AssignmentIDToInstrs
Map DIAssignID -> Instructions with that attachment.
DenseMap< Type *, std::unique_ptr< PoisonValue > > PVConstants
DenseMap< std::pair< const Function *, const BasicBlock * >, BlockAddress * > BlockAddresses
DenseMap< APInt, std::unique_ptr< ConstantInt > > IntConstants
std::vector< MDNode * > DistinctMDNodes
std::optional< uint32_t > DiagnosticsMisExpectTolerance
The percentage of difference between profiling branch weights and llvm.expect branch weights to toler...
FoldingSet< AttributeImpl > AttrsSet
StructTypeSet AnonStructTypes
std::unique_ptr< ConstantTokenNone > TheNoneToken
DenseMap< const Value *, ValueName * > ValueNames
SyncScope::ID getOrInsertSyncScopeID(StringRef SSN)
getOrInsertSyncScopeID - Maps synchronization scope name to synchronization scope ID.
void dropTriviallyDeadConstantArrays()
Destroy the ConstantArrays if they are not used.
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< 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< const Value *, MDAttachments > ValueMetadata
Collection of metadata used in this context.
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.
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)
BumpPtrAllocator Alloc
DenseMap< const GlobalObject *, StringRef > GlobalObjectSections
Collection of per-GlobalObject sections used in this context.
StringMap< std::unique_ptr< ConstantDataSequential > > CDSConstants
StructConstantsTy StructConstants
DenseMap< std::pair< Type *, ElementCount >, VectorType * > VectorTypes
std::unique_ptr< remarks::RemarkStreamer > MainRemarkStreamer
The main remark streamer used by all the other streamers (e.g.
void getOperandBundleTags(SmallVectorImpl< StringRef > &Tags) const
void deleteTrailingDbgRecords(BasicBlock *B)
FoldingSet< AttributeSetNode > AttrsSetNodes
FoldingSet< AttributeListImpl > AttrsLists
ConstantUniqueMap< ConstantPtrAuth > ConstantPtrAuths
DenseMap< TargetExtType *, std::unique_ptr< ConstantTargetNone > > CTNConstants
SpecificBumpPtrAllocator< ConstantRangeAttributeImpl > ConstantRangeAttributeAlloc
std::optional< uint64_t > DiagnosticsHotnessThreshold
The minimum hotness value a diagnostic needs in order to be included in optimization diagnostics.
ConstantUniqueMap< 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)
DenseMap< std::pair< ElementCount, APInt >, std::unique_ptr< ConstantInt > > IntSplatConstants
UniqueStringSaver Saver
LLVMContext::YieldCallbackTy YieldCallback
DenseMap< unsigned, IntegerType * > IntegerTypes
StringMap< StructType * > NamedStructTypes
std::vector< ConstantRangeListAttributeImpl * > ConstantRangeListAttributes
PointerType * AS0PointerType
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...
DenseMap< const GlobalValue *, DSOLocalEquivalent * > DSOLocalEquivalents
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
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
void(*)(LLVMContext *Context, void *OpaqueHandle) YieldCallbackTy
Defines the type of a yield callback.
Definition: LLVMContext.h:168
Multimap-like storage for metadata attachments.
void insert(unsigned ID, MDNode &MD)
Adds an attachment to a particular node.
Definition: Metadata.cpp:1478
void remove_if(PredTy shouldRemove)
Erase matching attachments.
void get(unsigned ID, SmallVectorImpl< MDNode * > &Result) const
Appends all attachments with the given ID to Result in insertion order.
Definition: Metadata.cpp:1455
void getAll(SmallVectorImpl< std::pair< unsigned, MDNode * > > &Result) const
Appends all attachments for the global to Result, sorting by attachment ID.
Definition: Metadata.cpp:1461
void set(unsigned ID, MDNode *MD)
Set an attachment to a particular node.
Definition: Metadata.cpp:1472
MDNode * lookup(unsigned ID) const
Returns the first attachment with the given ID or nullptr if no such attachment exists.
Definition: Metadata.cpp:1448
bool erase(unsigned ID)
Remove attachments with the given ID.
Definition: Metadata.cpp:1482
Structure for hashing arbitrary MDNode operands.
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:1069
A single uniqued string.
Definition: Metadata.h:720
Tuple of metadata.
Definition: Metadata.h:1473
Root of the metadata hierarchy.
Definition: Metadata.h:62
Extensions to this class implement mechanisms to disable passes and individual optimizations at compi...
Definition: OptBisect.h:24
Class to represent pointers.
Definition: DerivedTypes.h:670
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:519
bool empty() const
Definition: SmallVector.h:81
size_t size() const
Definition: SmallVector.h:78
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
Definition: Allocator.h:389
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:128
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
Class to represent struct types.
Definition: DerivedTypes.h:218
Class to represent target extensions types, which are generally unintrospectable from target-independ...
Definition: DerivedTypes.h:744
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
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:44
LLVM Value Representation.
Definition: Value.h:74
Base class of all SIMD vector types.
Definition: DerivedTypes.h:427
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ BasicBlock
Various leaf nodes.
Definition: ISDOpcodes.h:71
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
hash_code hash_value(const FixedPointSemantics &Val)
Definition: APFixedPoint.h:136
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:1873
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition: STLExtras.h:2099
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition: Hashing.h:590
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
Definition: Hashing.h:468
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
#define N
static const fltSemantics & Bogus() LLVM_READNONE
A Pseudo fltsemantic used to construct APFloats that cannot conflict with anything real.
Definition: APFloat.cpp:291
KeyTy(const ArrayRef< Type * > &E, bool P)
bool operator==(const KeyTy &that) const
bool operator!=(const KeyTy &that) const
static StructType * getEmptyKey()
static bool isEqual(const StructType *LHS, const StructType *RHS)
static unsigned getHashValue(const StructType *ST)
static unsigned getHashValue(const KeyTy &Key)
static StructType * getTombstoneKey()
static bool isEqual(const KeyTy &LHS, const StructType *RHS)
DenseMapInfo for DIArgList.
static unsigned getHashValue(const KeyTy &Key)
static DIArgList * getEmptyKey()
static unsigned getHashValue(const DIArgList *N)
static bool isEqual(const DIArgList *LHS, const DIArgList *RHS)
DIArgListKeyInfo KeyTy
static DIArgList * getTombstoneKey()
static bool isEqual(const KeyTy &LHS, const DIArgList *RHS)
ArrayRef< ValueAsMetadata * > Args
DIArgListKeyInfo(const DIArgList *N)
DIArgListKeyInfo(ArrayRef< ValueAsMetadata * > Args)
unsigned getHashValue() const
bool isKeyOf(const DIArgList *RHS) const
A single checksum, represented by a Kind and a Value (a string).
static bool isEqual(const APFloat &LHS, const APFloat &RHS)
static APFloat getTombstoneKey()
static unsigned getHashValue(const APFloat &Key)
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:52
bool operator==(const KeyTy &that) const
bool operator!=(const KeyTy &that) const
KeyTy(const Type *R, const ArrayRef< Type * > &P, bool V)
KeyTy(const FunctionType *FT)
static unsigned getHashValue(const FunctionType *FT)
static FunctionType * getTombstoneKey()
static bool isEqual(const KeyTy &LHS, const FunctionType *RHS)
static unsigned getHashValue(const KeyTy &Key)
static bool isEqual(const FunctionType *LHS, const FunctionType *RHS)
static FunctionType * getEmptyKey()
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)
MDNodeKeyImpl< NodeTy > KeyTy
static NodeTy * getTombstoneKey()
static NodeTy * getEmptyKey()
bool isKeyOf(const DIBasicType *RHS) const
MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, uint32_t NumExtraInhabitants, unsigned Flags)
MDNodeKeyImpl(const DIBasicType *N)
bool isKeyOf(const DICommonBlock *RHS) const
MDNodeKeyImpl(const DICommonBlock *N)
MDNodeKeyImpl(Metadata *Scope, Metadata *Decl, MDString *Name, Metadata *File, unsigned LineNo)
MDNodeKeyImpl(const DICompositeType *N)
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t 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)
bool isKeyOf(const DICompositeType *RHS) const
std::optional< DIDerivedType::PtrAuthData > PtrAuthData
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, std::optional< unsigned > DWARFAddressSpace, std::optional< DIDerivedType::PtrAuthData > PtrAuthData, unsigned Flags, Metadata *ExtraData, Metadata *Annotations)
MDNodeKeyImpl(const DIDerivedType *N)
bool isKeyOf(const DIDerivedType *RHS) const
std::optional< unsigned > DWARFAddressSpace
MDNodeKeyImpl(APInt Value, bool IsUnsigned, MDString *Name)
MDNodeKeyImpl(int64_t Value, bool IsUnsigned, MDString *Name)
bool isKeyOf(const DIEnumerator *RHS) const
MDNodeKeyImpl(const DIEnumerator *N)
bool isKeyOf(const DIExpression *RHS) const
MDNodeKeyImpl(const DIExpression *N)
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)
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
MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line)
MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator)
MDNodeKeyImpl(const DILexicalBlockFile *N)
bool isKeyOf(const DILexicalBlockFile *RHS) const
bool isKeyOf(const DILexicalBlock *RHS) const
MDNodeKeyImpl(const DILexicalBlock *N)
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, unsigned Column, Metadata *Scope, Metadata *InlinedAt, bool ImplicitCode)
MDNodeKeyImpl(const DILocation *L)
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(const DINamespace *N)
MDNodeKeyImpl(Metadata *Scope, MDString *Name, bool ExportSymbols)
bool isKeyOf(const DINamespace *RHS) const
MDNodeKeyImpl(const DIObjCProperty *N)
bool isKeyOf(const DIObjCProperty *RHS) const
MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line, MDString *GetterName, MDString *SetterName, unsigned Attributes, Metadata *Type)
MDNodeKeyImpl(const DIStringType *N)
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *StringLength, Metadata *StringLengthExp, Metadata *StringLocationExp, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding)
bool isKeyOf(const DIStringType *RHS) const
MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex, int ThisAdjustment, unsigned Flags, unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes, Metadata *ThrownTypes, Metadata *Annotations, MDString *TargetFuncName)
bool isKeyOf(const DISubprogram *RHS) const
MDNodeKeyImpl(const DISubprogram *N)
MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound, Metadata *Stride)
bool isKeyOf(const DISubrange *RHS) const
MDNodeKeyImpl(const DISubrange *N)
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)
static bool isSubsetEqual(const NodeTy *LHS, const NodeTy *RHS)
KeyTy(StringRef N, const ArrayRef< Type * > &TP, const ArrayRef< unsigned > &IP)
bool operator==(const KeyTy &that) const
KeyTy(const TargetExtType *TT)
bool operator!=(const KeyTy &that) const
static unsigned getHashValue(const TargetExtType *FT)
static bool isEqual(const TargetExtType *LHS, const TargetExtType *RHS)
static bool isEqual(const KeyTy &LHS, const TargetExtType *RHS)
static unsigned getHashValue(const KeyTy &Key)
static TargetExtType * getTombstoneKey()
static TargetExtType * getEmptyKey()