LLVM 19.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;
60struct DiagnosticHandler;
61class DbgMarker;
62class ElementCount;
63class Function;
64class GlobalObject;
65class GlobalValue;
66class InlineAsm;
67class LLVMRemarkStreamer;
68class OptPassGate;
69namespace remarks {
70class RemarkStreamer;
71}
72template <typename T> class StringMapEntry;
73class StringRef;
74class TypedPointerType;
75class ValueHandleBase;
76
77template <> struct DenseMapInfo<APFloat> {
78 static inline APFloat getEmptyKey() { return APFloat(APFloat::Bogus(), 1); }
79 static inline APFloat getTombstoneKey() {
80 return APFloat(APFloat::Bogus(), 2);
81 }
82
83 static unsigned getHashValue(const APFloat &Key) {
84 return static_cast<unsigned>(hash_value(Key));
85 }
86
87 static bool isEqual(const APFloat &LHS, const APFloat &RHS) {
88 return LHS.bitwiseIsEqual(RHS);
89 }
90};
91
93 struct KeyTy {
96
97 KeyTy(const ArrayRef<Type *> &E, bool P) : ETypes(E), isPacked(P) {}
98
99 KeyTy(const StructType *ST)
100 : ETypes(ST->elements()), isPacked(ST->isPacked()) {}
101
102 bool operator==(const KeyTy &that) const {
103 if (isPacked != that.isPacked)
104 return false;
105 if (ETypes != that.ETypes)
106 return false;
107 return true;
108 }
109 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
110 };
111
112 static inline StructType *getEmptyKey() {
114 }
115
116 static inline StructType *getTombstoneKey() {
118 }
119
120 static unsigned getHashValue(const KeyTy &Key) {
121 return hash_combine(
122 hash_combine_range(Key.ETypes.begin(), Key.ETypes.end()), Key.isPacked);
123 }
124
125 static unsigned getHashValue(const StructType *ST) {
126 return getHashValue(KeyTy(ST));
127 }
128
129 static bool isEqual(const KeyTy &LHS, const StructType *RHS) {
130 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
131 return false;
132 return LHS == KeyTy(RHS);
133 }
134
135 static bool isEqual(const StructType *LHS, const StructType *RHS) {
136 return LHS == RHS;
137 }
138};
139
141 struct KeyTy {
145
146 KeyTy(const Type *R, const ArrayRef<Type *> &P, bool V)
147 : ReturnType(R), Params(P), isVarArg(V) {}
149 : ReturnType(FT->getReturnType()), Params(FT->params()),
150 isVarArg(FT->isVarArg()) {}
151
152 bool operator==(const KeyTy &that) const {
153 if (ReturnType != that.ReturnType)
154 return false;
155 if (isVarArg != that.isVarArg)
156 return false;
157 if (Params != that.Params)
158 return false;
159 return true;
160 }
161 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
162 };
163
164 static inline FunctionType *getEmptyKey() {
166 }
167
168 static inline FunctionType *getTombstoneKey() {
170 }
171
172 static unsigned getHashValue(const KeyTy &Key) {
173 return hash_combine(
174 Key.ReturnType,
175 hash_combine_range(Key.Params.begin(), Key.Params.end()), Key.isVarArg);
176 }
177
178 static unsigned getHashValue(const FunctionType *FT) {
179 return getHashValue(KeyTy(FT));
180 }
181
182 static bool isEqual(const KeyTy &LHS, const FunctionType *RHS) {
183 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
184 return false;
185 return LHS == KeyTy(RHS);
186 }
187
188 static bool isEqual(const FunctionType *LHS, const FunctionType *RHS) {
189 return LHS == RHS;
190 }
191};
192
194 struct KeyTy {
198
200 : Name(N), TypeParams(TP), IntParams(IP) {}
202 : Name(TT->getName()), TypeParams(TT->type_params()),
203 IntParams(TT->int_params()) {}
204
205 bool operator==(const KeyTy &that) const {
206 return Name == that.Name && TypeParams == that.TypeParams &&
207 IntParams == that.IntParams;
208 }
209 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
210 };
211
212 static inline TargetExtType *getEmptyKey() {
214 }
215
218 }
219
220 static unsigned getHashValue(const KeyTy &Key) {
221 return hash_combine(
222 Key.Name,
223 hash_combine_range(Key.TypeParams.begin(), Key.TypeParams.end()),
224 hash_combine_range(Key.IntParams.begin(), Key.IntParams.end()));
225 }
226
227 static unsigned getHashValue(const TargetExtType *FT) {
228 return getHashValue(KeyTy(FT));
229 }
230
231 static bool isEqual(const KeyTy &LHS, const TargetExtType *RHS) {
232 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
233 return false;
234 return LHS == KeyTy(RHS);
235 }
236
237 static bool isEqual(const TargetExtType *LHS, const TargetExtType *RHS) {
238 return LHS == RHS;
239 }
240};
241
242/// Structure for hashing arbitrary MDNode operands.
246 unsigned Hash;
247
248protected:
250 : RawOps(Ops), Hash(calculateHash(Ops)) {}
251
252 template <class NodeTy>
253 MDNodeOpsKey(const NodeTy *N, unsigned Offset = 0)
254 : Ops(N->op_begin() + Offset, N->op_end()), Hash(N->getHash()) {}
255
256 template <class NodeTy>
257 bool compareOps(const NodeTy *RHS, unsigned Offset = 0) const {
258 if (getHash() != RHS->getHash())
259 return false;
260
261 assert((RawOps.empty() || Ops.empty()) && "Two sets of operands?");
262 return RawOps.empty() ? compareOps(Ops, RHS, Offset)
263 : compareOps(RawOps, RHS, Offset);
264 }
265
266 static unsigned calculateHash(MDNode *N, unsigned Offset = 0);
267
268private:
269 template <class T>
270 static bool compareOps(ArrayRef<T> Ops, const MDNode *RHS, unsigned Offset) {
271 if (Ops.size() != RHS->getNumOperands() - Offset)
272 return false;
273 return std::equal(Ops.begin(), Ops.end(), RHS->op_begin() + Offset);
274 }
275
276 static unsigned calculateHash(ArrayRef<Metadata *> Ops);
277
278public:
279 unsigned getHash() const { return Hash; }
280};
281
282template <class NodeTy> struct MDNodeKeyImpl;
283
284/// Configuration point for MDNodeInfo::isEqual().
285template <class NodeTy> struct MDNodeSubsetEqualImpl {
287
288 static bool isSubsetEqual(const KeyTy &LHS, const NodeTy *RHS) {
289 return false;
290 }
291
292 static bool isSubsetEqual(const NodeTy *LHS, const NodeTy *RHS) {
293 return false;
294 }
295};
296
297/// DenseMapInfo for MDTuple.
298///
299/// Note that we don't need the is-function-local bit, since that's implicit in
300/// the operands.
301template <> struct MDNodeKeyImpl<MDTuple> : MDNodeOpsKey {
304
305 bool isKeyOf(const MDTuple *RHS) const { return compareOps(RHS); }
306
307 unsigned getHashValue() const { return getHash(); }
308
309 static unsigned calculateHash(MDTuple *N) {
311 }
312};
313
314/// DenseMapInfo for DILocation.
315template <> struct MDNodeKeyImpl<DILocation> {
316 unsigned Line;
317 unsigned Column;
321
322 MDNodeKeyImpl(unsigned Line, unsigned Column, Metadata *Scope,
323 Metadata *InlinedAt, bool ImplicitCode)
324 : Line(Line), Column(Column), Scope(Scope), InlinedAt(InlinedAt),
325 ImplicitCode(ImplicitCode) {}
327 : Line(L->getLine()), Column(L->getColumn()), Scope(L->getRawScope()),
328 InlinedAt(L->getRawInlinedAt()), ImplicitCode(L->isImplicitCode()) {}
329
330 bool isKeyOf(const DILocation *RHS) const {
331 return Line == RHS->getLine() && Column == RHS->getColumn() &&
332 Scope == RHS->getRawScope() && InlinedAt == RHS->getRawInlinedAt() &&
333 ImplicitCode == RHS->isImplicitCode();
334 }
335
336 unsigned getHashValue() const {
337 return hash_combine(Line, Column, Scope, InlinedAt, ImplicitCode);
338 }
339};
340
341/// DenseMapInfo for GenericDINode.
343 unsigned Tag;
345
346 MDNodeKeyImpl(unsigned Tag, MDString *Header, ArrayRef<Metadata *> DwarfOps)
347 : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {}
349 : MDNodeOpsKey(N, 1), Tag(N->getTag()), Header(N->getRawHeader()) {}
350
351 bool isKeyOf(const GenericDINode *RHS) const {
352 return Tag == RHS->getTag() && Header == RHS->getRawHeader() &&
353 compareOps(RHS, 1);
354 }
355
356 unsigned getHashValue() const { return hash_combine(getHash(), Tag, Header); }
357
358 static unsigned calculateHash(GenericDINode *N) {
360 }
361};
362
363template <> struct MDNodeKeyImpl<DISubrange> {
368
369 MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound,
370 Metadata *Stride)
371 : CountNode(CountNode), LowerBound(LowerBound), UpperBound(UpperBound),
372 Stride(Stride) {}
374 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
375 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
376
377 bool isKeyOf(const DISubrange *RHS) const {
378 auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool {
379 if (Node1 == Node2)
380 return true;
381
382 ConstantAsMetadata *MD1 = dyn_cast_or_null<ConstantAsMetadata>(Node1);
383 ConstantAsMetadata *MD2 = dyn_cast_or_null<ConstantAsMetadata>(Node2);
384 if (MD1 && MD2) {
385 ConstantInt *CV1 = cast<ConstantInt>(MD1->getValue());
386 ConstantInt *CV2 = cast<ConstantInt>(MD2->getValue());
387 if (CV1->getSExtValue() == CV2->getSExtValue())
388 return true;
389 }
390 return false;
391 };
392
393 return BoundsEqual(CountNode, RHS->getRawCountNode()) &&
394 BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
395 BoundsEqual(UpperBound, RHS->getRawUpperBound()) &&
396 BoundsEqual(Stride, RHS->getRawStride());
397 }
398
399 unsigned getHashValue() const {
400 if (CountNode)
401 if (auto *MD = dyn_cast<ConstantAsMetadata>(CountNode))
402 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
403 LowerBound, UpperBound, Stride);
404 return hash_combine(CountNode, LowerBound, UpperBound, Stride);
405 }
406};
407
408template <> struct MDNodeKeyImpl<DIGenericSubrange> {
413
414 MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound,
415 Metadata *Stride)
416 : CountNode(CountNode), LowerBound(LowerBound), UpperBound(UpperBound),
417 Stride(Stride) {}
419 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
420 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
421
422 bool isKeyOf(const DIGenericSubrange *RHS) const {
423 return (CountNode == RHS->getRawCountNode()) &&
424 (LowerBound == RHS->getRawLowerBound()) &&
425 (UpperBound == RHS->getRawUpperBound()) &&
426 (Stride == RHS->getRawStride());
427 }
428
429 unsigned getHashValue() const {
430 auto *MD = dyn_cast_or_null<ConstantAsMetadata>(CountNode);
431 if (CountNode && MD)
432 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
433 LowerBound, UpperBound, Stride);
434 return hash_combine(CountNode, LowerBound, UpperBound, Stride);
435 }
436};
437
438template <> struct MDNodeKeyImpl<DIEnumerator> {
442
444 : Value(std::move(Value)), Name(Name), IsUnsigned(IsUnsigned) {}
445 MDNodeKeyImpl(int64_t Value, bool IsUnsigned, MDString *Name)
446 : Value(APInt(64, Value, !IsUnsigned)), Name(Name),
447 IsUnsigned(IsUnsigned) {}
449 : Value(N->getValue()), Name(N->getRawName()),
450 IsUnsigned(N->isUnsigned()) {}
451
452 bool isKeyOf(const DIEnumerator *RHS) const {
453 return Value.getBitWidth() == RHS->getValue().getBitWidth() &&
454 Value == RHS->getValue() && IsUnsigned == RHS->isUnsigned() &&
455 Name == RHS->getRawName();
456 }
457
458 unsigned getHashValue() const { return hash_combine(Value, Name); }
459};
460
461template <> struct MDNodeKeyImpl<DIBasicType> {
462 unsigned Tag;
466 unsigned Encoding;
467 unsigned Flags;
468
469 MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits,
470 uint32_t AlignInBits, unsigned Encoding, unsigned Flags)
471 : Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits),
472 Encoding(Encoding), Flags(Flags) {}
474 : Tag(N->getTag()), Name(N->getRawName()), SizeInBits(N->getSizeInBits()),
475 AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()),
476 Flags(N->getFlags()) {}
477
478 bool isKeyOf(const DIBasicType *RHS) const {
479 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
480 SizeInBits == RHS->getSizeInBits() &&
481 AlignInBits == RHS->getAlignInBits() &&
482 Encoding == RHS->getEncoding() && Flags == RHS->getFlags();
483 }
484
485 unsigned getHashValue() const {
486 return hash_combine(Tag, Name, SizeInBits, AlignInBits, Encoding);
487 }
488};
489
490template <> struct MDNodeKeyImpl<DIStringType> {
491 unsigned Tag;
498 unsigned Encoding;
499
500 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *StringLength,
501 Metadata *StringLengthExp, Metadata *StringLocationExp,
502 uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding)
503 : Tag(Tag), Name(Name), StringLength(StringLength),
504 StringLengthExp(StringLengthExp), StringLocationExp(StringLocationExp),
505 SizeInBits(SizeInBits), AlignInBits(AlignInBits), Encoding(Encoding) {}
507 : Tag(N->getTag()), Name(N->getRawName()),
508 StringLength(N->getRawStringLength()),
509 StringLengthExp(N->getRawStringLengthExp()),
510 StringLocationExp(N->getRawStringLocationExp()),
511 SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()),
512 Encoding(N->getEncoding()) {}
513
514 bool isKeyOf(const DIStringType *RHS) const {
515 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
516 StringLength == RHS->getRawStringLength() &&
517 StringLengthExp == RHS->getRawStringLengthExp() &&
518 StringLocationExp == RHS->getRawStringLocationExp() &&
519 SizeInBits == RHS->getSizeInBits() &&
520 AlignInBits == RHS->getAlignInBits() &&
521 Encoding == RHS->getEncoding();
522 }
523 unsigned getHashValue() const {
524 // Intentionally computes the hash on a subset of the operands for
525 // performance reason. The subset has to be significant enough to avoid
526 // collision "most of the time". There is no correctness issue in case of
527 // collision because of the full check above.
528 return hash_combine(Tag, Name, StringLength, Encoding);
529 }
530};
531
532template <> struct MDNodeKeyImpl<DIDerivedType> {
533 unsigned Tag;
536 unsigned Line;
542 std::optional<unsigned> DWARFAddressSpace;
543 std::optional<DIDerivedType::PtrAuthData> PtrAuthData;
544 unsigned Flags;
547
548 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
549 Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
550 uint32_t AlignInBits, uint64_t OffsetInBits,
551 std::optional<unsigned> DWARFAddressSpace,
552 std::optional<DIDerivedType::PtrAuthData> PtrAuthData,
553 unsigned Flags, Metadata *ExtraData, Metadata *Annotations)
554 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
555 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
556 AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace),
557 PtrAuthData(PtrAuthData), Flags(Flags), ExtraData(ExtraData),
560 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
561 Line(N->getLine()), Scope(N->getRawScope()),
562 BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
563 OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()),
564 DWARFAddressSpace(N->getDWARFAddressSpace()),
565 PtrAuthData(N->getPtrAuthData()), Flags(N->getFlags()),
566 ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {}
567
568 bool isKeyOf(const DIDerivedType *RHS) const {
569 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
570 File == RHS->getRawFile() && Line == RHS->getLine() &&
571 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
572 SizeInBits == RHS->getSizeInBits() &&
573 AlignInBits == RHS->getAlignInBits() &&
574 OffsetInBits == RHS->getOffsetInBits() &&
575 DWARFAddressSpace == RHS->getDWARFAddressSpace() &&
576 PtrAuthData == RHS->getPtrAuthData() && Flags == RHS->getFlags() &&
577 ExtraData == RHS->getRawExtraData() &&
578 Annotations == RHS->getRawAnnotations();
579 }
580
581 unsigned getHashValue() const {
582 // If this is a member inside an ODR type, only hash the type and the name.
583 // Otherwise the hash will be stronger than
584 // MDNodeSubsetEqualImpl::isODRMember().
585 if (Tag == dwarf::DW_TAG_member && Name)
586 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
587 if (CT->getRawIdentifier())
588 return hash_combine(Name, Scope);
589
590 // Intentionally computes the hash on a subset of the operands for
591 // performance reason. The subset has to be significant enough to avoid
592 // collision "most of the time". There is no correctness issue in case of
593 // collision because of the full check above.
594 return hash_combine(Tag, Name, File, Line, Scope, BaseType, Flags);
595 }
596};
597
600
601 static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) {
602 return isODRMember(LHS.Tag, LHS.Scope, LHS.Name, RHS);
603 }
604
605 static bool isSubsetEqual(const DIDerivedType *LHS,
606 const DIDerivedType *RHS) {
607 return isODRMember(LHS->getTag(), LHS->getRawScope(), LHS->getRawName(),
608 RHS);
609 }
610
611 /// Subprograms compare equal if they declare the same function in an ODR
612 /// type.
613 static bool isODRMember(unsigned Tag, const Metadata *Scope,
614 const MDString *Name, const DIDerivedType *RHS) {
615 // Check whether the LHS is eligible.
616 if (Tag != dwarf::DW_TAG_member || !Name)
617 return false;
618
619 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
620 if (!CT || !CT->getRawIdentifier())
621 return false;
622
623 // Compare to the RHS.
624 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
625 Scope == RHS->getRawScope();
626 }
627};
628
629template <> struct MDNodeKeyImpl<DICompositeType> {
630 unsigned Tag;
633 unsigned Line;
639 unsigned Flags;
641 unsigned RuntimeLang;
651
652 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
653 Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
654 uint32_t AlignInBits, uint64_t OffsetInBits, unsigned Flags,
655 Metadata *Elements, unsigned RuntimeLang,
656 Metadata *VTableHolder, Metadata *TemplateParams,
657 MDString *Identifier, Metadata *Discriminator,
658 Metadata *DataLocation, Metadata *Associated,
659 Metadata *Allocated, Metadata *Rank, Metadata *Annotations)
660 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
661 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
662 AlignInBits(AlignInBits), Flags(Flags), Elements(Elements),
663 RuntimeLang(RuntimeLang), VTableHolder(VTableHolder),
664 TemplateParams(TemplateParams), Identifier(Identifier),
665 Discriminator(Discriminator), DataLocation(DataLocation),
666 Associated(Associated), Allocated(Allocated), Rank(Rank),
669 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
670 Line(N->getLine()), Scope(N->getRawScope()),
671 BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
672 OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()),
673 Flags(N->getFlags()), Elements(N->getRawElements()),
674 RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()),
675 TemplateParams(N->getRawTemplateParams()),
676 Identifier(N->getRawIdentifier()),
677 Discriminator(N->getRawDiscriminator()),
678 DataLocation(N->getRawDataLocation()),
679 Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()),
680 Rank(N->getRawRank()), Annotations(N->getRawAnnotations()) {}
681
682 bool isKeyOf(const DICompositeType *RHS) const {
683 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
684 File == RHS->getRawFile() && Line == RHS->getLine() &&
685 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
686 SizeInBits == RHS->getSizeInBits() &&
687 AlignInBits == RHS->getAlignInBits() &&
688 OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() &&
689 Elements == RHS->getRawElements() &&
690 RuntimeLang == RHS->getRuntimeLang() &&
691 VTableHolder == RHS->getRawVTableHolder() &&
692 TemplateParams == RHS->getRawTemplateParams() &&
693 Identifier == RHS->getRawIdentifier() &&
694 Discriminator == RHS->getRawDiscriminator() &&
695 DataLocation == RHS->getRawDataLocation() &&
696 Associated == RHS->getRawAssociated() &&
697 Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() &&
698 Annotations == RHS->getRawAnnotations();
699 }
700
701 unsigned getHashValue() const {
702 // Intentionally computes the hash on a subset of the operands for
703 // performance reason. The subset has to be significant enough to avoid
704 // collision "most of the time". There is no correctness issue in case of
705 // collision because of the full check above.
706 return hash_combine(Name, File, Line, BaseType, Scope, Elements,
707 TemplateParams, Annotations);
708 }
709};
710
711template <> struct MDNodeKeyImpl<DISubroutineType> {
712 unsigned Flags;
713 uint8_t CC;
715
716 MDNodeKeyImpl(unsigned Flags, uint8_t CC, Metadata *TypeArray)
717 : Flags(Flags), CC(CC), TypeArray(TypeArray) {}
719 : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()) {}
720
721 bool isKeyOf(const DISubroutineType *RHS) const {
722 return Flags == RHS->getFlags() && CC == RHS->getCC() &&
723 TypeArray == RHS->getRawTypeArray();
724 }
725
726 unsigned getHashValue() const { return hash_combine(Flags, CC, TypeArray); }
727};
728
729template <> struct MDNodeKeyImpl<DIFile> {
732 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum;
734
735 MDNodeKeyImpl(MDString *Filename, MDString *Directory,
736 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum,
737 MDString *Source)
738 : Filename(Filename), Directory(Directory), Checksum(Checksum),
739 Source(Source) {}
741 : Filename(N->getRawFilename()), Directory(N->getRawDirectory()),
742 Checksum(N->getRawChecksum()), Source(N->getRawSource()) {}
743
744 bool isKeyOf(const DIFile *RHS) const {
745 return Filename == RHS->getRawFilename() &&
746 Directory == RHS->getRawDirectory() &&
747 Checksum == RHS->getRawChecksum() && Source == RHS->getRawSource();
748 }
749
750 unsigned getHashValue() const {
751 return hash_combine(Filename, Directory, Checksum ? Checksum->Kind : 0,
752 Checksum ? Checksum->Value : nullptr, Source);
753 }
754};
755
756template <> struct MDNodeKeyImpl<DISubprogram> {
761 unsigned Line;
763 unsigned ScopeLine;
765 unsigned VirtualIndex;
767 unsigned Flags;
768 unsigned SPFlags;
776
778 Metadata *File, unsigned Line, Metadata *Type,
779 unsigned ScopeLine, Metadata *ContainingType,
780 unsigned VirtualIndex, int ThisAdjustment, unsigned Flags,
781 unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams,
782 Metadata *Declaration, Metadata *RetainedNodes,
783 Metadata *ThrownTypes, Metadata *Annotations,
784 MDString *TargetFuncName)
785 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
786 Line(Line), Type(Type), ScopeLine(ScopeLine),
787 ContainingType(ContainingType), VirtualIndex(VirtualIndex),
788 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags),
789 Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration),
790 RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes),
791 Annotations(Annotations), TargetFuncName(TargetFuncName) {}
793 : Scope(N->getRawScope()), Name(N->getRawName()),
794 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
795 Line(N->getLine()), Type(N->getRawType()), ScopeLine(N->getScopeLine()),
796 ContainingType(N->getRawContainingType()),
797 VirtualIndex(N->getVirtualIndex()),
798 ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()),
799 SPFlags(N->getSPFlags()), Unit(N->getRawUnit()),
800 TemplateParams(N->getRawTemplateParams()),
801 Declaration(N->getRawDeclaration()),
802 RetainedNodes(N->getRawRetainedNodes()),
803 ThrownTypes(N->getRawThrownTypes()),
804 Annotations(N->getRawAnnotations()),
805 TargetFuncName(N->getRawTargetFuncName()) {}
806
807 bool isKeyOf(const DISubprogram *RHS) const {
808 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
809 LinkageName == RHS->getRawLinkageName() &&
810 File == RHS->getRawFile() && Line == RHS->getLine() &&
811 Type == RHS->getRawType() && ScopeLine == RHS->getScopeLine() &&
812 ContainingType == RHS->getRawContainingType() &&
813 VirtualIndex == RHS->getVirtualIndex() &&
814 ThisAdjustment == RHS->getThisAdjustment() &&
815 Flags == RHS->getFlags() && SPFlags == RHS->getSPFlags() &&
816 Unit == RHS->getUnit() &&
817 TemplateParams == RHS->getRawTemplateParams() &&
818 Declaration == RHS->getRawDeclaration() &&
819 RetainedNodes == RHS->getRawRetainedNodes() &&
820 ThrownTypes == RHS->getRawThrownTypes() &&
821 Annotations == RHS->getRawAnnotations() &&
822 TargetFuncName == RHS->getRawTargetFuncName();
823 }
824
825 bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; }
826
827 unsigned getHashValue() const {
828 // Use the Scope's linkage name instead of using the scope directly, as the
829 // scope may be a temporary one which can replaced, which would produce a
830 // different hash for the same DISubprogram.
831 llvm::StringRef ScopeLinkageName;
832 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
833 if (auto *ID = CT->getRawIdentifier())
834 ScopeLinkageName = ID->getString();
835
836 // If this is a declaration inside an ODR type, only hash the type and the
837 // name. Otherwise the hash will be stronger than
838 // MDNodeSubsetEqualImpl::isDeclarationOfODRMember().
839 if (!isDefinition() && LinkageName &&
840 isa_and_nonnull<DICompositeType>(Scope))
841 return hash_combine(LinkageName, ScopeLinkageName);
842
843 // Intentionally computes the hash on a subset of the operands for
844 // performance reason. The subset has to be significant enough to avoid
845 // collision "most of the time". There is no correctness issue in case of
846 // collision because of the full check above.
847 return hash_combine(Name, ScopeLinkageName, File, Type, Line);
848 }
849};
850
853
854 static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) {
855 return isDeclarationOfODRMember(LHS.isDefinition(), LHS.Scope,
856 LHS.LinkageName, LHS.TemplateParams, RHS);
857 }
858
859 static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) {
860 return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(),
861 LHS->getRawLinkageName(),
862 LHS->getRawTemplateParams(), RHS);
863 }
864
865 /// Subprograms compare equal if they declare the same function in an ODR
866 /// type.
867 static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope,
868 const MDString *LinkageName,
869 const Metadata *TemplateParams,
870 const DISubprogram *RHS) {
871 // Check whether the LHS is eligible.
872 if (IsDefinition || !Scope || !LinkageName)
873 return false;
874
875 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
876 if (!CT || !CT->getRawIdentifier())
877 return false;
878
879 // Compare to the RHS.
880 // FIXME: We need to compare template parameters here to avoid incorrect
881 // collisions in mapMetadata when RF_ReuseAndMutateDistinctMDs and a
882 // ODR-DISubprogram has a non-ODR template parameter (i.e., a
883 // DICompositeType that does not have an identifier). Eventually we should
884 // decouple ODR logic from uniquing logic.
885 return IsDefinition == RHS->isDefinition() && Scope == RHS->getRawScope() &&
886 LinkageName == RHS->getRawLinkageName() &&
887 TemplateParams == RHS->getRawTemplateParams();
888 }
889};
890
891template <> struct MDNodeKeyImpl<DILexicalBlock> {
894 unsigned Line;
895 unsigned Column;
896
897 MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Line, unsigned Column)
898 : Scope(Scope), File(File), Line(Line), Column(Column) {}
900 : Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()),
901 Column(N->getColumn()) {}
902
903 bool isKeyOf(const DILexicalBlock *RHS) const {
904 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
905 Line == RHS->getLine() && Column == RHS->getColumn();
906 }
907
908 unsigned getHashValue() const {
909 return hash_combine(Scope, File, Line, Column);
910 }
911};
912
917
918 MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator)
919 : Scope(Scope), File(File), Discriminator(Discriminator) {}
921 : Scope(N->getRawScope()), File(N->getRawFile()),
922 Discriminator(N->getDiscriminator()) {}
923
924 bool isKeyOf(const DILexicalBlockFile *RHS) const {
925 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
926 Discriminator == RHS->getDiscriminator();
927 }
928
929 unsigned getHashValue() const {
930 return hash_combine(Scope, File, Discriminator);
931 }
932};
933
934template <> struct MDNodeKeyImpl<DINamespace> {
938
939 MDNodeKeyImpl(Metadata *Scope, MDString *Name, bool ExportSymbols)
940 : Scope(Scope), Name(Name), ExportSymbols(ExportSymbols) {}
942 : Scope(N->getRawScope()), Name(N->getRawName()),
943 ExportSymbols(N->getExportSymbols()) {}
944
945 bool isKeyOf(const DINamespace *RHS) const {
946 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
947 ExportSymbols == RHS->getExportSymbols();
948 }
949
950 unsigned getHashValue() const { return hash_combine(Scope, Name); }
951};
952
953template <> struct MDNodeKeyImpl<DICommonBlock> {
958 unsigned LineNo;
959
961 unsigned LineNo)
962 : Scope(Scope), Decl(Decl), Name(Name), File(File), LineNo(LineNo) {}
964 : Scope(N->getRawScope()), Decl(N->getRawDecl()), Name(N->getRawName()),
965 File(N->getRawFile()), LineNo(N->getLineNo()) {}
966
967 bool isKeyOf(const DICommonBlock *RHS) const {
968 return Scope == RHS->getRawScope() && Decl == RHS->getRawDecl() &&
969 Name == RHS->getRawName() && File == RHS->getRawFile() &&
970 LineNo == RHS->getLineNo();
971 }
972
973 unsigned getHashValue() const {
974 return hash_combine(Scope, Decl, Name, File, LineNo);
975 }
976};
977
978template <> struct MDNodeKeyImpl<DIModule> {
985 unsigned LineNo;
986 bool IsDecl;
987
989 MDString *ConfigurationMacros, MDString *IncludePath,
990 MDString *APINotesFile, unsigned LineNo, bool IsDecl)
991 : File(File), Scope(Scope), Name(Name),
992 ConfigurationMacros(ConfigurationMacros), IncludePath(IncludePath),
993 APINotesFile(APINotesFile), LineNo(LineNo), IsDecl(IsDecl) {}
995 : File(N->getRawFile()), Scope(N->getRawScope()), Name(N->getRawName()),
996 ConfigurationMacros(N->getRawConfigurationMacros()),
997 IncludePath(N->getRawIncludePath()),
998 APINotesFile(N->getRawAPINotesFile()), LineNo(N->getLineNo()),
999 IsDecl(N->getIsDecl()) {}
1000
1001 bool isKeyOf(const DIModule *RHS) const {
1002 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1003 ConfigurationMacros == RHS->getRawConfigurationMacros() &&
1004 IncludePath == RHS->getRawIncludePath() &&
1005 APINotesFile == RHS->getRawAPINotesFile() &&
1006 File == RHS->getRawFile() && LineNo == RHS->getLineNo() &&
1007 IsDecl == RHS->getIsDecl();
1008 }
1009
1010 unsigned getHashValue() const {
1011 return hash_combine(Scope, Name, ConfigurationMacros, IncludePath);
1012 }
1013};
1014
1019
1021 : Name(Name), Type(Type), IsDefault(IsDefault) {}
1023 : Name(N->getRawName()), Type(N->getRawType()),
1024 IsDefault(N->isDefault()) {}
1025
1027 return Name == RHS->getRawName() && Type == RHS->getRawType() &&
1028 IsDefault == RHS->isDefault();
1029 }
1030
1031 unsigned getHashValue() const { return hash_combine(Name, Type, IsDefault); }
1032};
1033
1035 unsigned Tag;
1040
1041 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *Type, bool IsDefault,
1042 Metadata *Value)
1043 : Tag(Tag), Name(Name), Type(Type), IsDefault(IsDefault), Value(Value) {}
1045 : Tag(N->getTag()), Name(N->getRawName()), Type(N->getRawType()),
1046 IsDefault(N->isDefault()), Value(N->getValue()) {}
1047
1049 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
1050 Type == RHS->getRawType() && IsDefault == RHS->isDefault() &&
1051 Value == RHS->getValue();
1052 }
1053
1054 unsigned getHashValue() const {
1055 return hash_combine(Tag, Name, Type, IsDefault, Value);
1056 }
1057};
1058
1059template <> struct MDNodeKeyImpl<DIGlobalVariable> {
1064 unsigned Line;
1072
1074 Metadata *File, unsigned Line, Metadata *Type,
1075 bool IsLocalToUnit, bool IsDefinition,
1076 Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
1077 uint32_t AlignInBits, Metadata *Annotations)
1078 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
1079 Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit),
1080 IsDefinition(IsDefinition),
1081 StaticDataMemberDeclaration(StaticDataMemberDeclaration),
1082 TemplateParams(TemplateParams), AlignInBits(AlignInBits),
1085 : Scope(N->getRawScope()), Name(N->getRawName()),
1086 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
1087 Line(N->getLine()), Type(N->getRawType()),
1088 IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
1089 StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()),
1090 TemplateParams(N->getRawTemplateParams()),
1091 AlignInBits(N->getAlignInBits()), Annotations(N->getRawAnnotations()) {}
1092
1093 bool isKeyOf(const DIGlobalVariable *RHS) const {
1094 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1095 LinkageName == RHS->getRawLinkageName() &&
1096 File == RHS->getRawFile() && Line == RHS->getLine() &&
1097 Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() &&
1098 IsDefinition == RHS->isDefinition() &&
1099 StaticDataMemberDeclaration ==
1100 RHS->getRawStaticDataMemberDeclaration() &&
1101 TemplateParams == RHS->getRawTemplateParams() &&
1102 AlignInBits == RHS->getAlignInBits() &&
1103 Annotations == RHS->getRawAnnotations();
1104 }
1105
1106 unsigned getHashValue() const {
1107 // We do not use AlignInBits in hashing function here on purpose:
1108 // in most cases this param for local variable is zero (for function param
1109 // it is always zero). This leads to lots of hash collisions and errors on
1110 // cases with lots of similar variables.
1111 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1112 // generated IR is random for each run and test fails with Align included.
1113 // TODO: make hashing work fine with such situations
1114 return hash_combine(Scope, Name, LinkageName, File, Line, Type,
1115 IsLocalToUnit, IsDefinition, /* AlignInBits, */
1116 StaticDataMemberDeclaration, Annotations);
1117 }
1118};
1119
1120template <> struct MDNodeKeyImpl<DILocalVariable> {
1124 unsigned Line;
1126 unsigned Arg;
1127 unsigned Flags;
1130
1131 MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line,
1132 Metadata *Type, unsigned Arg, unsigned Flags,
1133 uint32_t AlignInBits, Metadata *Annotations)
1134 : Scope(Scope), Name(Name), File(File), Line(Line), Type(Type), Arg(Arg),
1135 Flags(Flags), AlignInBits(AlignInBits), Annotations(Annotations) {}
1137 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1138 Line(N->getLine()), Type(N->getRawType()), Arg(N->getArg()),
1139 Flags(N->getFlags()), AlignInBits(N->getAlignInBits()),
1140 Annotations(N->getRawAnnotations()) {}
1141
1142 bool isKeyOf(const DILocalVariable *RHS) const {
1143 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1144 File == RHS->getRawFile() && Line == RHS->getLine() &&
1145 Type == RHS->getRawType() && Arg == RHS->getArg() &&
1146 Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits() &&
1147 Annotations == RHS->getRawAnnotations();
1148 }
1149
1150 unsigned getHashValue() const {
1151 // We do not use AlignInBits in hashing function here on purpose:
1152 // in most cases this param for local variable is zero (for function param
1153 // it is always zero). This leads to lots of hash collisions and errors on
1154 // cases with lots of similar variables.
1155 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1156 // generated IR is random for each run and test fails with Align included.
1157 // TODO: make hashing work fine with such situations
1158 return hash_combine(Scope, Name, File, Line, Type, Arg, Flags, Annotations);
1159 }
1160};
1161
1162template <> struct MDNodeKeyImpl<DILabel> {
1166 unsigned Line;
1167
1168 MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line)
1169 : Scope(Scope), Name(Name), File(File), Line(Line) {}
1171 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1172 Line(N->getLine()) {}
1173
1174 bool isKeyOf(const DILabel *RHS) const {
1175 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1176 File == RHS->getRawFile() && Line == RHS->getLine();
1177 }
1178
1179 /// Using name and line to get hash value. It should already be mostly unique.
1180 unsigned getHashValue() const { return hash_combine(Scope, Name, Line); }
1181};
1182
1183template <> struct MDNodeKeyImpl<DIExpression> {
1185
1186 MDNodeKeyImpl(ArrayRef<uint64_t> Elements) : Elements(Elements) {}
1187 MDNodeKeyImpl(const DIExpression *N) : Elements(N->getElements()) {}
1188
1189 bool isKeyOf(const DIExpression *RHS) const {
1190 return Elements == RHS->getElements();
1191 }
1192
1193 unsigned getHashValue() const {
1194 return hash_combine_range(Elements.begin(), Elements.end());
1195 }
1196};
1197
1201
1203 : Variable(Variable), Expression(Expression) {}
1205 : Variable(N->getRawVariable()), Expression(N->getRawExpression()) {}
1206
1208 return Variable == RHS->getRawVariable() &&
1209 Expression == RHS->getRawExpression();
1210 }
1211
1212 unsigned getHashValue() const { return hash_combine(Variable, Expression); }
1213};
1214
1215template <> struct MDNodeKeyImpl<DIObjCProperty> {
1218 unsigned Line;
1221 unsigned Attributes;
1223
1224 MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line,
1225 MDString *GetterName, MDString *SetterName, unsigned Attributes,
1226 Metadata *Type)
1227 : Name(Name), File(File), Line(Line), GetterName(GetterName),
1228 SetterName(SetterName), Attributes(Attributes), Type(Type) {}
1230 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
1231 GetterName(N->getRawGetterName()), SetterName(N->getRawSetterName()),
1232 Attributes(N->getAttributes()), Type(N->getRawType()) {}
1233
1234 bool isKeyOf(const DIObjCProperty *RHS) const {
1235 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
1236 Line == RHS->getLine() && GetterName == RHS->getRawGetterName() &&
1237 SetterName == RHS->getRawSetterName() &&
1238 Attributes == RHS->getAttributes() && Type == RHS->getRawType();
1239 }
1240
1241 unsigned getHashValue() const {
1242 return hash_combine(Name, File, Line, GetterName, SetterName, Attributes,
1243 Type);
1244 }
1245};
1246
1247template <> struct MDNodeKeyImpl<DIImportedEntity> {
1248 unsigned Tag;
1252 unsigned Line;
1255
1256 MDNodeKeyImpl(unsigned Tag, Metadata *Scope, Metadata *Entity, Metadata *File,
1257 unsigned Line, MDString *Name, Metadata *Elements)
1258 : Tag(Tag), Scope(Scope), Entity(Entity), File(File), Line(Line),
1259 Name(Name), Elements(Elements) {}
1261 : Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()),
1262 File(N->getRawFile()), Line(N->getLine()), Name(N->getRawName()),
1263 Elements(N->getRawElements()) {}
1264
1265 bool isKeyOf(const DIImportedEntity *RHS) const {
1266 return Tag == RHS->getTag() && Scope == RHS->getRawScope() &&
1267 Entity == RHS->getRawEntity() && File == RHS->getFile() &&
1268 Line == RHS->getLine() && Name == RHS->getRawName() &&
1269 Elements == RHS->getRawElements();
1270 }
1271
1272 unsigned getHashValue() const {
1273 return hash_combine(Tag, Scope, Entity, File, Line, Name, Elements);
1274 }
1275};
1276
1277template <> struct MDNodeKeyImpl<DIMacro> {
1278 unsigned MIType;
1279 unsigned Line;
1282
1283 MDNodeKeyImpl(unsigned MIType, unsigned Line, MDString *Name, MDString *Value)
1284 : MIType(MIType), Line(Line), Name(Name), Value(Value) {}
1286 : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getRawName()),
1287 Value(N->getRawValue()) {}
1288
1289 bool isKeyOf(const DIMacro *RHS) const {
1290 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1291 Name == RHS->getRawName() && Value == RHS->getRawValue();
1292 }
1293
1294 unsigned getHashValue() const {
1295 return hash_combine(MIType, Line, Name, Value);
1296 }
1297};
1298
1299template <> struct MDNodeKeyImpl<DIMacroFile> {
1300 unsigned MIType;
1301 unsigned Line;
1304
1305 MDNodeKeyImpl(unsigned MIType, unsigned Line, Metadata *File,
1306 Metadata *Elements)
1307 : MIType(MIType), Line(Line), File(File), Elements(Elements) {}
1309 : MIType(N->getMacinfoType()), Line(N->getLine()), File(N->getRawFile()),
1310 Elements(N->getRawElements()) {}
1311
1312 bool isKeyOf(const DIMacroFile *RHS) const {
1313 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1314 File == RHS->getRawFile() && Elements == RHS->getRawElements();
1315 }
1316
1317 unsigned getHashValue() const {
1318 return hash_combine(MIType, Line, File, Elements);
1319 }
1320};
1321
1322// DIArgLists are not MDNodes, but we still want to unique them in a DenseSet
1323// based on a hash of their arguments.
1326
1328 DIArgListKeyInfo(const DIArgList *N) : Args(N->getArgs()) {}
1329
1330 bool isKeyOf(const DIArgList *RHS) const { return Args == RHS->getArgs(); }
1331
1332 unsigned getHashValue() const {
1333 return hash_combine_range(Args.begin(), Args.end());
1334 }
1335};
1336
1337/// DenseMapInfo for DIArgList.
1340
1341 static inline DIArgList *getEmptyKey() {
1343 }
1344
1345 static inline DIArgList *getTombstoneKey() {
1347 }
1348
1349 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1350
1351 static unsigned getHashValue(const DIArgList *N) {
1352 return KeyTy(N).getHashValue();
1353 }
1354
1355 static bool isEqual(const KeyTy &LHS, const DIArgList *RHS) {
1356 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1357 return false;
1358 return LHS.isKeyOf(RHS);
1359 }
1360
1361 static bool isEqual(const DIArgList *LHS, const DIArgList *RHS) {
1362 return LHS == RHS;
1363 }
1364};
1365
1366/// DenseMapInfo for MDNode subclasses.
1367template <class NodeTy> struct MDNodeInfo {
1370
1371 static inline NodeTy *getEmptyKey() {
1373 }
1374
1375 static inline NodeTy *getTombstoneKey() {
1377 }
1378
1379 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1380
1381 static unsigned getHashValue(const NodeTy *N) {
1382 return KeyTy(N).getHashValue();
1383 }
1384
1385 static bool isEqual(const KeyTy &LHS, const NodeTy *RHS) {
1386 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1387 return false;
1388 return SubsetEqualTy::isSubsetEqual(LHS, RHS) || LHS.isKeyOf(RHS);
1389 }
1390
1391 static bool isEqual(const NodeTy *LHS, const NodeTy *RHS) {
1392 if (LHS == RHS)
1393 return true;
1394 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1395 return false;
1397 }
1398};
1399
1400#define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>;
1401#include "llvm/IR/Metadata.def"
1402
1403/// Multimap-like storage for metadata attachments.
1405public:
1406 struct Attachment {
1407 unsigned MDKind;
1409 };
1410
1411private:
1412 SmallVector<Attachment, 1> Attachments;
1413
1414public:
1415 bool empty() const { return Attachments.empty(); }
1416 size_t size() const { return Attachments.size(); }
1417
1418 /// Returns the first attachment with the given ID or nullptr if no such
1419 /// attachment exists.
1420 MDNode *lookup(unsigned ID) const;
1421
1422 /// Appends all attachments with the given ID to \c Result in insertion order.
1423 /// If the global has no attachments with the given ID, or if ID is invalid,
1424 /// leaves Result unchanged.
1425 void get(unsigned ID, SmallVectorImpl<MDNode *> &Result) const;
1426
1427 /// Appends all attachments for the global to \c Result, sorting by attachment
1428 /// ID. Attachments with the same ID appear in insertion order. This function
1429 /// does \em not clear \c Result.
1430 void getAll(SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const;
1431
1432 /// Set an attachment to a particular node.
1433 ///
1434 /// Set the \c ID attachment to \c MD, replacing the current attachments at \c
1435 /// ID (if anyway).
1436 void set(unsigned ID, MDNode *MD);
1437
1438 /// Adds an attachment to a particular node.
1439 void insert(unsigned ID, MDNode &MD);
1440
1441 /// Remove attachments with the given ID.
1442 ///
1443 /// Remove the attachments at \c ID, if any.
1444 bool erase(unsigned ID);
1445
1446 /// Erase matching attachments.
1447 ///
1448 /// Erases all attachments matching the \c shouldRemove predicate.
1449 template <class PredTy> void remove_if(PredTy shouldRemove) {
1450 llvm::erase_if(Attachments, shouldRemove);
1451 }
1452};
1453
1455public:
1456 /// OwnedModules - The set of modules instantiated in this context, and which
1457 /// will be automatically deleted if this context is deleted.
1459
1460 /// MachineFunctionNums - Keep the next available unique number available for
1461 /// a MachineFunction in given module. Module must in OwnedModules.
1463
1464 /// The main remark streamer used by all the other streamers (e.g. IR, MIR,
1465 /// frontends, etc.). This should only be used by the specific streamers, and
1466 /// never directly.
1467 std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer;
1468
1469 std::unique_ptr<DiagnosticHandler> DiagHandler;
1472 /// The minimum hotness value a diagnostic needs in order to be included in
1473 /// optimization diagnostics.
1474 ///
1475 /// The threshold is an Optional value, which maps to one of the 3 states:
1476 /// 1). 0 => threshold disabled. All emarks will be printed.
1477 /// 2). positive int => manual threshold by user. Remarks with hotness exceed
1478 /// threshold will be printed.
1479 /// 3). None => 'auto' threshold by user. The actual value is not
1480 /// available at command line, but will be synced with
1481 /// hotness threhold from profile summary during
1482 /// compilation.
1483 ///
1484 /// State 1 and 2 are considered as terminal states. State transition is
1485 /// only allowed from 3 to 2, when the threshold is first synced with profile
1486 /// summary. This ensures that the threshold is set only once and stays
1487 /// constant.
1488 ///
1489 /// If threshold option is not specified, it is disabled (0) by default.
1490 std::optional<uint64_t> DiagnosticsHotnessThreshold = 0;
1491
1492 /// The percentage of difference between profiling branch weights and
1493 /// llvm.expect branch weights to tolerate when emiting MisExpect diagnostics
1494 std::optional<uint32_t> DiagnosticsMisExpectTolerance = 0;
1496
1497 /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
1498 std::unique_ptr<LLVMRemarkStreamer> LLVMRS;
1499
1501 void *YieldOpaqueHandle = nullptr;
1502
1504
1508 DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantInt>>
1510
1512 DenseMap<std::pair<ElementCount, APFloat>, std::unique_ptr<ConstantFP>>
1514
1518
1523
1524#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
1525 DenseSet<CLASS *, CLASS##Info> CLASS##s;
1526#include "llvm/IR/Metadata.def"
1527
1528 // Optional map for looking up composite types by identifier.
1529 std::optional<DenseMap<const MDString *, DICompositeType *>> DITypeMap;
1530
1531 // MDNodes may be uniqued or not uniqued. When they're not uniqued, they
1532 // aren't in the MDNodeSet, but they're still shared between objects, so no
1533 // one object can destroy them. Keep track of them here so we can delete
1534 // them on context teardown.
1535 std::vector<MDNode *> DistinctMDNodes;
1536
1538
1541
1544
1547
1549
1551
1553
1555
1557
1560
1562
1564
1566
1568
1571
1572 // Basic type instances.
1577
1578 std::unique_ptr<ConstantTokenNone> TheNoneToken;
1579
1584
1586
1593
1596
1599 PointerType *AS0PointerType = nullptr; // AddrSpace = 0
1603
1604 /// ValueHandles - This map keeps track of all of the value handles that are
1605 /// watching a Value*. The Value::HasValueHandle bit is used to know
1606 /// whether or not a value has an entry in this map.
1609
1610 /// CustomMDKindNames - Map to hold the metadata string to ID mapping.
1612
1613 /// Collection of metadata used in this context.
1615
1616 /// Map DIAssignID -> Instructions with that attachment.
1617 /// Managed by Instruction via Instruction::updateDIAssignIDMapping.
1618 /// Query using the at:: functions defined in DebugInfo.h.
1620
1621 /// Collection of per-GlobalObject sections used in this context.
1623
1624 /// Collection of per-GlobalValue partitions used in this context.
1626
1629
1630 /// DiscriminatorTable - This table maps file:line locations to an
1631 /// integer representing the next DWARF path discriminator to assign to
1632 /// instructions in different blocks at the same location.
1634
1635 /// A set of interned tags for operand bundles. The StringMap maps
1636 /// bundle tags to their IDs.
1637 ///
1638 /// \see LLVMContext::getOperandBundleTagID
1640
1644
1645 /// A set of interned synchronization scopes. The StringMap maps
1646 /// synchronization scope names to their respective synchronization scope IDs.
1648
1649 /// getOrInsertSyncScopeID - Maps synchronization scope name to
1650 /// synchronization scope ID. Every synchronization scope registered with
1651 /// LLVMContext has unique ID except pre-defined ones.
1653
1654 /// getSyncScopeNames - Populates client supplied SmallVector with
1655 /// synchronization scope names registered with LLVMContext. Synchronization
1656 /// scope names are ordered by increasing synchronization scope IDs.
1658
1659 /// Maintain the GC name for each function.
1660 ///
1661 /// This saves allocating an additional word in Function for programs which
1662 /// do not use GC (i.e., most programs) at the cost of increased overhead for
1663 /// clients which do use GC.
1665
1666 /// Flag to indicate if Value (other than GlobalValue) retains their name or
1667 /// not.
1668 bool DiscardValueNames = false;
1669
1672
1673 /// Destroy the ConstantArrays if they are not used.
1675
1676 mutable OptPassGate *OPG = nullptr;
1677
1678 /// Access the object which can disable optional passes and individual
1679 /// optimizations at compile time.
1680 OptPassGate &getOptPassGate() const;
1681
1682 /// Set the object which can disable optional passes and individual
1683 /// optimizations at compile time.
1684 ///
1685 /// The lifetime of the object must be guaranteed to extend as long as the
1686 /// LLVMContext is used by compilation.
1688
1689 /// Mapping of blocks to collections of "trailing" DbgVariableRecords. As part
1690 /// of the "RemoveDIs" project, debug-info variable location records are going
1691 /// to cease being instructions... which raises the problem of where should
1692 /// they be recorded when we remove the terminator of a blocks, such as:
1693 ///
1694 /// %foo = add i32 0, 0
1695 /// br label %bar
1696 ///
1697 /// If the branch is removed, a legitimate transient state while editing a
1698 /// block, any debug-records between those two instructions will not have a
1699 /// location. Each block thus records any DbgVariableRecord records that
1700 /// "trail" in such a way. These are stored in LLVMContext because typically
1701 /// LLVM only edits a small number of blocks at a time, so there's no need to
1702 /// bloat BasicBlock with such a data structure.
1704
1705 // Set, get and delete operations for TrailingDbgRecords.
1707 assert(!TrailingDbgRecords.count(B));
1708 TrailingDbgRecords[B] = M;
1709 }
1710
1712 return TrailingDbgRecords.lookup(B);
1713 }
1714
1716};
1717
1718} // end namespace llvm
1719
1720#endif // LLVM_LIB_IR_LLVMCONTEXTIMPL_H
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.
This file contains the declarations for metadata subclasses.
Module.h This file contains the declarations for the Module class.
#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:27
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition: APInt.h:76
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:154
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
iterator begin() const
Definition: ArrayRef.h:153
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:160
Class to represent array types.
Definition: DerivedTypes.h:371
LLVM Basic Block Representation.
Definition: BasicBlock.h:60
The address of a basic block.
Definition: Constants.h:889
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:80
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:160
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:271
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:521
Class to represent function types.
Definition: DerivedTypes.h:103
Generic tagged DWARF-like metadata node.
Class to represent integer types.
Definition: DerivedTypes.h:40
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
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
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
DenseMap< std::pair< Type *, unsigned >, PointerType * > LegacyPointerTypes
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
PointerType * AS0PointerType
DenseSet< DIArgList *, DIArgListInfo > DIArgLists
ValueHandlesTy ValueHandles
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:164
Multimap-like storage for metadata attachments.
void insert(unsigned ID, MDNode &MD)
Adds an attachment to a particular node.
Definition: Metadata.cpp:1434
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:1411
void getAll(SmallVectorImpl< std::pair< unsigned, MDNode * > > &Result) const
Appends all attachments for the global to Result, sorting by attachment ID.
Definition: Metadata.cpp:1417
void set(unsigned ID, MDNode *MD)
Set an attachment to a particular node.
Definition: Metadata.cpp:1428
MDNode * lookup(unsigned ID) const
Returns the first attachment with the given ID or nullptr if no such attachment exists.
Definition: Metadata.cpp:1404
bool erase(unsigned ID)
Remove attachments with the given ID.
Definition: Metadata.cpp:1438
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:1067
A single uniqued string.
Definition: Metadata.h:720
Tuple of metadata.
Definition: Metadata.h:1470
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:646
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:427
bool empty() const
Definition: SmallVector.h:94
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
Definition: Allocator.h:387
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:127
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Class to represent struct types.
Definition: DerivedTypes.h:216
Class to represent target extensions types, which are generally unintrospectable from target-independ...
Definition: DerivedTypes.h:720
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:403
unsigned getTag(StringRef TagString)
Definition: Dwarf.cpp:32
@ 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:456
hash_code hash_value(const FixedPointSemantics &Val)
Definition: APFixedPoint.h:128
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:1849
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:2051
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition: Hashing.h:613
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
Definition: Hashing.h:491
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:266
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:50
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(const DIBasicType *N)
MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, unsigned Flags)
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)
bool isKeyOf(const DICompositeType *RHS) const
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)
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()