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;
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;
468 unsigned Flags;
469
470 MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits,
471 uint32_t AlignInBits, unsigned Encoding, unsigned Flags)
472 : Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits),
473 Encoding(Encoding), Flags(Flags) {}
475 : Tag(N->getTag()), Name(N->getRawName()), SizeInBits(N->getSizeInBits()),
476 AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()),
477 Flags(N->getFlags()) {}
478
479 bool isKeyOf(const DIBasicType *RHS) const {
480 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
481 SizeInBits == RHS->getSizeInBits() &&
482 AlignInBits == RHS->getAlignInBits() &&
483 Encoding == RHS->getEncoding() && Flags == RHS->getFlags();
484 }
485
486 unsigned getHashValue() const {
487 return hash_combine(Tag, Name, SizeInBits, AlignInBits, Encoding);
488 }
489};
490
491template <> struct MDNodeKeyImpl<DIStringType> {
492 unsigned Tag;
499 unsigned Encoding;
500
501 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *StringLength,
502 Metadata *StringLengthExp, Metadata *StringLocationExp,
503 uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding)
504 : Tag(Tag), Name(Name), StringLength(StringLength),
505 StringLengthExp(StringLengthExp), StringLocationExp(StringLocationExp),
506 SizeInBits(SizeInBits), AlignInBits(AlignInBits), Encoding(Encoding) {}
508 : Tag(N->getTag()), Name(N->getRawName()),
509 StringLength(N->getRawStringLength()),
510 StringLengthExp(N->getRawStringLengthExp()),
511 StringLocationExp(N->getRawStringLocationExp()),
512 SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()),
513 Encoding(N->getEncoding()) {}
514
515 bool isKeyOf(const DIStringType *RHS) const {
516 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
517 StringLength == RHS->getRawStringLength() &&
518 StringLengthExp == RHS->getRawStringLengthExp() &&
519 StringLocationExp == RHS->getRawStringLocationExp() &&
520 SizeInBits == RHS->getSizeInBits() &&
521 AlignInBits == RHS->getAlignInBits() &&
522 Encoding == RHS->getEncoding();
523 }
524 unsigned getHashValue() const {
525 // Intentionally computes the hash on a subset of the operands for
526 // performance reason. The subset has to be significant enough to avoid
527 // collision "most of the time". There is no correctness issue in case of
528 // collision because of the full check above.
529 return hash_combine(Tag, Name, StringLength, Encoding);
530 }
531};
532
533template <> struct MDNodeKeyImpl<DIDerivedType> {
534 unsigned Tag;
537 unsigned Line;
543 std::optional<unsigned> DWARFAddressSpace;
544 std::optional<DIDerivedType::PtrAuthData> PtrAuthData;
545 unsigned Flags;
548
549 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
550 Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
551 uint32_t AlignInBits, uint64_t OffsetInBits,
552 std::optional<unsigned> DWARFAddressSpace,
553 std::optional<DIDerivedType::PtrAuthData> PtrAuthData,
554 unsigned Flags, Metadata *ExtraData, Metadata *Annotations)
555 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
556 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
557 AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace),
558 PtrAuthData(PtrAuthData), Flags(Flags), ExtraData(ExtraData),
561 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
562 Line(N->getLine()), Scope(N->getRawScope()),
563 BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
564 OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()),
565 DWARFAddressSpace(N->getDWARFAddressSpace()),
566 PtrAuthData(N->getPtrAuthData()), Flags(N->getFlags()),
567 ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {}
568
569 bool isKeyOf(const DIDerivedType *RHS) const {
570 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
571 File == RHS->getRawFile() && Line == RHS->getLine() &&
572 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
573 SizeInBits == RHS->getSizeInBits() &&
574 AlignInBits == RHS->getAlignInBits() &&
575 OffsetInBits == RHS->getOffsetInBits() &&
576 DWARFAddressSpace == RHS->getDWARFAddressSpace() &&
577 PtrAuthData == RHS->getPtrAuthData() && Flags == RHS->getFlags() &&
578 ExtraData == RHS->getRawExtraData() &&
579 Annotations == RHS->getRawAnnotations();
580 }
581
582 unsigned getHashValue() const {
583 // If this is a member inside an ODR type, only hash the type and the name.
584 // Otherwise the hash will be stronger than
585 // MDNodeSubsetEqualImpl::isODRMember().
586 if (Tag == dwarf::DW_TAG_member && Name)
587 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
588 if (CT->getRawIdentifier())
589 return hash_combine(Name, Scope);
590
591 // Intentionally computes the hash on a subset of the operands for
592 // performance reason. The subset has to be significant enough to avoid
593 // collision "most of the time". There is no correctness issue in case of
594 // collision because of the full check above.
595 return hash_combine(Tag, Name, File, Line, Scope, BaseType, Flags);
596 }
597};
598
601
602 static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) {
603 return isODRMember(LHS.Tag, LHS.Scope, LHS.Name, RHS);
604 }
605
606 static bool isSubsetEqual(const DIDerivedType *LHS,
607 const DIDerivedType *RHS) {
608 return isODRMember(LHS->getTag(), LHS->getRawScope(), LHS->getRawName(),
609 RHS);
610 }
611
612 /// Subprograms compare equal if they declare the same function in an ODR
613 /// type.
614 static bool isODRMember(unsigned Tag, const Metadata *Scope,
615 const MDString *Name, const DIDerivedType *RHS) {
616 // Check whether the LHS is eligible.
617 if (Tag != dwarf::DW_TAG_member || !Name)
618 return false;
619
620 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
621 if (!CT || !CT->getRawIdentifier())
622 return false;
623
624 // Compare to the RHS.
625 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
626 Scope == RHS->getRawScope();
627 }
628};
629
630template <> struct MDNodeKeyImpl<DICompositeType> {
631 unsigned Tag;
634 unsigned Line;
640 unsigned Flags;
642 unsigned RuntimeLang;
652
653 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
654 Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
655 uint32_t AlignInBits, uint64_t OffsetInBits, unsigned Flags,
656 Metadata *Elements, unsigned RuntimeLang,
657 Metadata *VTableHolder, Metadata *TemplateParams,
658 MDString *Identifier, Metadata *Discriminator,
659 Metadata *DataLocation, Metadata *Associated,
660 Metadata *Allocated, Metadata *Rank, Metadata *Annotations)
661 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
662 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
663 AlignInBits(AlignInBits), Flags(Flags), Elements(Elements),
664 RuntimeLang(RuntimeLang), VTableHolder(VTableHolder),
665 TemplateParams(TemplateParams), Identifier(Identifier),
666 Discriminator(Discriminator), DataLocation(DataLocation),
667 Associated(Associated), Allocated(Allocated), Rank(Rank),
670 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
671 Line(N->getLine()), Scope(N->getRawScope()),
672 BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
673 OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()),
674 Flags(N->getFlags()), Elements(N->getRawElements()),
675 RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()),
676 TemplateParams(N->getRawTemplateParams()),
677 Identifier(N->getRawIdentifier()),
678 Discriminator(N->getRawDiscriminator()),
679 DataLocation(N->getRawDataLocation()),
680 Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()),
681 Rank(N->getRawRank()), Annotations(N->getRawAnnotations()) {}
682
683 bool isKeyOf(const DICompositeType *RHS) const {
684 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
685 File == RHS->getRawFile() && Line == RHS->getLine() &&
686 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
687 SizeInBits == RHS->getSizeInBits() &&
688 AlignInBits == RHS->getAlignInBits() &&
689 OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() &&
690 Elements == RHS->getRawElements() &&
691 RuntimeLang == RHS->getRuntimeLang() &&
692 VTableHolder == RHS->getRawVTableHolder() &&
693 TemplateParams == RHS->getRawTemplateParams() &&
694 Identifier == RHS->getRawIdentifier() &&
695 Discriminator == RHS->getRawDiscriminator() &&
696 DataLocation == RHS->getRawDataLocation() &&
697 Associated == RHS->getRawAssociated() &&
698 Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() &&
699 Annotations == RHS->getRawAnnotations();
700 }
701
702 unsigned getHashValue() const {
703 // Intentionally computes the hash on a subset of the operands for
704 // performance reason. The subset has to be significant enough to avoid
705 // collision "most of the time". There is no correctness issue in case of
706 // collision because of the full check above.
707 return hash_combine(Name, File, Line, BaseType, Scope, Elements,
708 TemplateParams, Annotations);
709 }
710};
711
712template <> struct MDNodeKeyImpl<DISubroutineType> {
713 unsigned Flags;
714 uint8_t CC;
716
717 MDNodeKeyImpl(unsigned Flags, uint8_t CC, Metadata *TypeArray)
718 : Flags(Flags), CC(CC), TypeArray(TypeArray) {}
720 : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()) {}
721
722 bool isKeyOf(const DISubroutineType *RHS) const {
723 return Flags == RHS->getFlags() && CC == RHS->getCC() &&
724 TypeArray == RHS->getRawTypeArray();
725 }
726
727 unsigned getHashValue() const { return hash_combine(Flags, CC, TypeArray); }
728};
729
730template <> struct MDNodeKeyImpl<DIFile> {
733 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum;
735
736 MDNodeKeyImpl(MDString *Filename, MDString *Directory,
737 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum,
738 MDString *Source)
739 : Filename(Filename), Directory(Directory), Checksum(Checksum),
740 Source(Source) {}
742 : Filename(N->getRawFilename()), Directory(N->getRawDirectory()),
743 Checksum(N->getRawChecksum()), Source(N->getRawSource()) {}
744
745 bool isKeyOf(const DIFile *RHS) const {
746 return Filename == RHS->getRawFilename() &&
747 Directory == RHS->getRawDirectory() &&
748 Checksum == RHS->getRawChecksum() && Source == RHS->getRawSource();
749 }
750
751 unsigned getHashValue() const {
752 return hash_combine(Filename, Directory, Checksum ? Checksum->Kind : 0,
753 Checksum ? Checksum->Value : nullptr, Source);
754 }
755};
756
757template <> struct MDNodeKeyImpl<DISubprogram> {
762 unsigned Line;
764 unsigned ScopeLine;
766 unsigned VirtualIndex;
768 unsigned Flags;
769 unsigned SPFlags;
777
779 Metadata *File, unsigned Line, Metadata *Type,
780 unsigned ScopeLine, Metadata *ContainingType,
781 unsigned VirtualIndex, int ThisAdjustment, unsigned Flags,
782 unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams,
783 Metadata *Declaration, Metadata *RetainedNodes,
784 Metadata *ThrownTypes, Metadata *Annotations,
785 MDString *TargetFuncName)
786 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
787 Line(Line), Type(Type), ScopeLine(ScopeLine),
788 ContainingType(ContainingType), VirtualIndex(VirtualIndex),
789 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags),
790 Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration),
791 RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes),
792 Annotations(Annotations), TargetFuncName(TargetFuncName) {}
794 : Scope(N->getRawScope()), Name(N->getRawName()),
795 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
796 Line(N->getLine()), Type(N->getRawType()), ScopeLine(N->getScopeLine()),
797 ContainingType(N->getRawContainingType()),
798 VirtualIndex(N->getVirtualIndex()),
799 ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()),
800 SPFlags(N->getSPFlags()), Unit(N->getRawUnit()),
801 TemplateParams(N->getRawTemplateParams()),
802 Declaration(N->getRawDeclaration()),
803 RetainedNodes(N->getRawRetainedNodes()),
804 ThrownTypes(N->getRawThrownTypes()),
805 Annotations(N->getRawAnnotations()),
806 TargetFuncName(N->getRawTargetFuncName()) {}
807
808 bool isKeyOf(const DISubprogram *RHS) const {
809 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
810 LinkageName == RHS->getRawLinkageName() &&
811 File == RHS->getRawFile() && Line == RHS->getLine() &&
812 Type == RHS->getRawType() && ScopeLine == RHS->getScopeLine() &&
813 ContainingType == RHS->getRawContainingType() &&
814 VirtualIndex == RHS->getVirtualIndex() &&
815 ThisAdjustment == RHS->getThisAdjustment() &&
816 Flags == RHS->getFlags() && SPFlags == RHS->getSPFlags() &&
817 Unit == RHS->getUnit() &&
818 TemplateParams == RHS->getRawTemplateParams() &&
819 Declaration == RHS->getRawDeclaration() &&
820 RetainedNodes == RHS->getRawRetainedNodes() &&
821 ThrownTypes == RHS->getRawThrownTypes() &&
822 Annotations == RHS->getRawAnnotations() &&
823 TargetFuncName == RHS->getRawTargetFuncName();
824 }
825
826 bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; }
827
828 unsigned getHashValue() const {
829 // Use the Scope's linkage name instead of using the scope directly, as the
830 // scope may be a temporary one which can replaced, which would produce a
831 // different hash for the same DISubprogram.
832 llvm::StringRef ScopeLinkageName;
833 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
834 if (auto *ID = CT->getRawIdentifier())
835 ScopeLinkageName = ID->getString();
836
837 // If this is a declaration inside an ODR type, only hash the type and the
838 // name. Otherwise the hash will be stronger than
839 // MDNodeSubsetEqualImpl::isDeclarationOfODRMember().
840 if (!isDefinition() && LinkageName &&
841 isa_and_nonnull<DICompositeType>(Scope))
842 return hash_combine(LinkageName, ScopeLinkageName);
843
844 // Intentionally computes the hash on a subset of the operands for
845 // performance reason. The subset has to be significant enough to avoid
846 // collision "most of the time". There is no correctness issue in case of
847 // collision because of the full check above.
848 return hash_combine(Name, ScopeLinkageName, File, Type, Line);
849 }
850};
851
854
855 static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) {
856 return isDeclarationOfODRMember(LHS.isDefinition(), LHS.Scope,
857 LHS.LinkageName, LHS.TemplateParams, RHS);
858 }
859
860 static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) {
861 return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(),
862 LHS->getRawLinkageName(),
863 LHS->getRawTemplateParams(), RHS);
864 }
865
866 /// Subprograms compare equal if they declare the same function in an ODR
867 /// type.
868 static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope,
869 const MDString *LinkageName,
870 const Metadata *TemplateParams,
871 const DISubprogram *RHS) {
872 // Check whether the LHS is eligible.
873 if (IsDefinition || !Scope || !LinkageName)
874 return false;
875
876 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
877 if (!CT || !CT->getRawIdentifier())
878 return false;
879
880 // Compare to the RHS.
881 // FIXME: We need to compare template parameters here to avoid incorrect
882 // collisions in mapMetadata when RF_ReuseAndMutateDistinctMDs and a
883 // ODR-DISubprogram has a non-ODR template parameter (i.e., a
884 // DICompositeType that does not have an identifier). Eventually we should
885 // decouple ODR logic from uniquing logic.
886 return IsDefinition == RHS->isDefinition() && Scope == RHS->getRawScope() &&
887 LinkageName == RHS->getRawLinkageName() &&
888 TemplateParams == RHS->getRawTemplateParams();
889 }
890};
891
892template <> struct MDNodeKeyImpl<DILexicalBlock> {
895 unsigned Line;
896 unsigned Column;
897
898 MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Line, unsigned Column)
899 : Scope(Scope), File(File), Line(Line), Column(Column) {}
901 : Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()),
902 Column(N->getColumn()) {}
903
904 bool isKeyOf(const DILexicalBlock *RHS) const {
905 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
906 Line == RHS->getLine() && Column == RHS->getColumn();
907 }
908
909 unsigned getHashValue() const {
910 return hash_combine(Scope, File, Line, Column);
911 }
912};
913
918
919 MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator)
920 : Scope(Scope), File(File), Discriminator(Discriminator) {}
922 : Scope(N->getRawScope()), File(N->getRawFile()),
923 Discriminator(N->getDiscriminator()) {}
924
925 bool isKeyOf(const DILexicalBlockFile *RHS) const {
926 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
927 Discriminator == RHS->getDiscriminator();
928 }
929
930 unsigned getHashValue() const {
931 return hash_combine(Scope, File, Discriminator);
932 }
933};
934
935template <> struct MDNodeKeyImpl<DINamespace> {
939
940 MDNodeKeyImpl(Metadata *Scope, MDString *Name, bool ExportSymbols)
941 : Scope(Scope), Name(Name), ExportSymbols(ExportSymbols) {}
943 : Scope(N->getRawScope()), Name(N->getRawName()),
944 ExportSymbols(N->getExportSymbols()) {}
945
946 bool isKeyOf(const DINamespace *RHS) const {
947 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
948 ExportSymbols == RHS->getExportSymbols();
949 }
950
951 unsigned getHashValue() const { return hash_combine(Scope, Name); }
952};
953
954template <> struct MDNodeKeyImpl<DICommonBlock> {
959 unsigned LineNo;
960
962 unsigned LineNo)
963 : Scope(Scope), Decl(Decl), Name(Name), File(File), LineNo(LineNo) {}
965 : Scope(N->getRawScope()), Decl(N->getRawDecl()), Name(N->getRawName()),
966 File(N->getRawFile()), LineNo(N->getLineNo()) {}
967
968 bool isKeyOf(const DICommonBlock *RHS) const {
969 return Scope == RHS->getRawScope() && Decl == RHS->getRawDecl() &&
970 Name == RHS->getRawName() && File == RHS->getRawFile() &&
971 LineNo == RHS->getLineNo();
972 }
973
974 unsigned getHashValue() const {
975 return hash_combine(Scope, Decl, Name, File, LineNo);
976 }
977};
978
979template <> struct MDNodeKeyImpl<DIModule> {
986 unsigned LineNo;
987 bool IsDecl;
988
990 MDString *ConfigurationMacros, MDString *IncludePath,
991 MDString *APINotesFile, unsigned LineNo, bool IsDecl)
992 : File(File), Scope(Scope), Name(Name),
993 ConfigurationMacros(ConfigurationMacros), IncludePath(IncludePath),
994 APINotesFile(APINotesFile), LineNo(LineNo), IsDecl(IsDecl) {}
996 : File(N->getRawFile()), Scope(N->getRawScope()), Name(N->getRawName()),
997 ConfigurationMacros(N->getRawConfigurationMacros()),
998 IncludePath(N->getRawIncludePath()),
999 APINotesFile(N->getRawAPINotesFile()), LineNo(N->getLineNo()),
1000 IsDecl(N->getIsDecl()) {}
1001
1002 bool isKeyOf(const DIModule *RHS) const {
1003 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1004 ConfigurationMacros == RHS->getRawConfigurationMacros() &&
1005 IncludePath == RHS->getRawIncludePath() &&
1006 APINotesFile == RHS->getRawAPINotesFile() &&
1007 File == RHS->getRawFile() && LineNo == RHS->getLineNo() &&
1008 IsDecl == RHS->getIsDecl();
1009 }
1010
1011 unsigned getHashValue() const {
1012 return hash_combine(Scope, Name, ConfigurationMacros, IncludePath);
1013 }
1014};
1015
1020
1022 : Name(Name), Type(Type), IsDefault(IsDefault) {}
1024 : Name(N->getRawName()), Type(N->getRawType()),
1025 IsDefault(N->isDefault()) {}
1026
1028 return Name == RHS->getRawName() && Type == RHS->getRawType() &&
1029 IsDefault == RHS->isDefault();
1030 }
1031
1032 unsigned getHashValue() const { return hash_combine(Name, Type, IsDefault); }
1033};
1034
1036 unsigned Tag;
1041
1042 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *Type, bool IsDefault,
1043 Metadata *Value)
1044 : Tag(Tag), Name(Name), Type(Type), IsDefault(IsDefault), Value(Value) {}
1046 : Tag(N->getTag()), Name(N->getRawName()), Type(N->getRawType()),
1047 IsDefault(N->isDefault()), Value(N->getValue()) {}
1048
1050 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
1051 Type == RHS->getRawType() && IsDefault == RHS->isDefault() &&
1052 Value == RHS->getValue();
1053 }
1054
1055 unsigned getHashValue() const {
1056 return hash_combine(Tag, Name, Type, IsDefault, Value);
1057 }
1058};
1059
1060template <> struct MDNodeKeyImpl<DIGlobalVariable> {
1065 unsigned Line;
1073
1075 Metadata *File, unsigned Line, Metadata *Type,
1076 bool IsLocalToUnit, bool IsDefinition,
1077 Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
1078 uint32_t AlignInBits, Metadata *Annotations)
1079 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
1080 Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit),
1081 IsDefinition(IsDefinition),
1082 StaticDataMemberDeclaration(StaticDataMemberDeclaration),
1083 TemplateParams(TemplateParams), AlignInBits(AlignInBits),
1086 : Scope(N->getRawScope()), Name(N->getRawName()),
1087 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
1088 Line(N->getLine()), Type(N->getRawType()),
1089 IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
1090 StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()),
1091 TemplateParams(N->getRawTemplateParams()),
1092 AlignInBits(N->getAlignInBits()), Annotations(N->getRawAnnotations()) {}
1093
1094 bool isKeyOf(const DIGlobalVariable *RHS) const {
1095 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1096 LinkageName == RHS->getRawLinkageName() &&
1097 File == RHS->getRawFile() && Line == RHS->getLine() &&
1098 Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() &&
1099 IsDefinition == RHS->isDefinition() &&
1100 StaticDataMemberDeclaration ==
1101 RHS->getRawStaticDataMemberDeclaration() &&
1102 TemplateParams == RHS->getRawTemplateParams() &&
1103 AlignInBits == RHS->getAlignInBits() &&
1104 Annotations == RHS->getRawAnnotations();
1105 }
1106
1107 unsigned getHashValue() const {
1108 // We do not use AlignInBits in hashing function here on purpose:
1109 // in most cases this param for local variable is zero (for function param
1110 // it is always zero). This leads to lots of hash collisions and errors on
1111 // cases with lots of similar variables.
1112 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1113 // generated IR is random for each run and test fails with Align included.
1114 // TODO: make hashing work fine with such situations
1115 return hash_combine(Scope, Name, LinkageName, File, Line, Type,
1116 IsLocalToUnit, IsDefinition, /* AlignInBits, */
1117 StaticDataMemberDeclaration, Annotations);
1118 }
1119};
1120
1121template <> struct MDNodeKeyImpl<DILocalVariable> {
1125 unsigned Line;
1127 unsigned Arg;
1128 unsigned Flags;
1131
1132 MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line,
1133 Metadata *Type, unsigned Arg, unsigned Flags,
1134 uint32_t AlignInBits, Metadata *Annotations)
1135 : Scope(Scope), Name(Name), File(File), Line(Line), Type(Type), Arg(Arg),
1136 Flags(Flags), AlignInBits(AlignInBits), Annotations(Annotations) {}
1138 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1139 Line(N->getLine()), Type(N->getRawType()), Arg(N->getArg()),
1140 Flags(N->getFlags()), AlignInBits(N->getAlignInBits()),
1141 Annotations(N->getRawAnnotations()) {}
1142
1143 bool isKeyOf(const DILocalVariable *RHS) const {
1144 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1145 File == RHS->getRawFile() && Line == RHS->getLine() &&
1146 Type == RHS->getRawType() && Arg == RHS->getArg() &&
1147 Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits() &&
1148 Annotations == RHS->getRawAnnotations();
1149 }
1150
1151 unsigned getHashValue() const {
1152 // We do not use AlignInBits in hashing function here on purpose:
1153 // in most cases this param for local variable is zero (for function param
1154 // it is always zero). This leads to lots of hash collisions and errors on
1155 // cases with lots of similar variables.
1156 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1157 // generated IR is random for each run and test fails with Align included.
1158 // TODO: make hashing work fine with such situations
1159 return hash_combine(Scope, Name, File, Line, Type, Arg, Flags, Annotations);
1160 }
1161};
1162
1163template <> struct MDNodeKeyImpl<DILabel> {
1167 unsigned Line;
1168
1169 MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line)
1170 : Scope(Scope), Name(Name), File(File), Line(Line) {}
1172 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1173 Line(N->getLine()) {}
1174
1175 bool isKeyOf(const DILabel *RHS) const {
1176 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1177 File == RHS->getRawFile() && Line == RHS->getLine();
1178 }
1179
1180 /// Using name and line to get hash value. It should already be mostly unique.
1181 unsigned getHashValue() const { return hash_combine(Scope, Name, Line); }
1182};
1183
1184template <> struct MDNodeKeyImpl<DIExpression> {
1186
1187 MDNodeKeyImpl(ArrayRef<uint64_t> Elements) : Elements(Elements) {}
1188 MDNodeKeyImpl(const DIExpression *N) : Elements(N->getElements()) {}
1189
1190 bool isKeyOf(const DIExpression *RHS) const {
1191 return Elements == RHS->getElements();
1192 }
1193
1194 unsigned getHashValue() const {
1195 return hash_combine_range(Elements.begin(), Elements.end());
1196 }
1197};
1198
1202
1204 : Variable(Variable), Expression(Expression) {}
1206 : Variable(N->getRawVariable()), Expression(N->getRawExpression()) {}
1207
1209 return Variable == RHS->getRawVariable() &&
1210 Expression == RHS->getRawExpression();
1211 }
1212
1213 unsigned getHashValue() const { return hash_combine(Variable, Expression); }
1214};
1215
1216template <> struct MDNodeKeyImpl<DIObjCProperty> {
1219 unsigned Line;
1222 unsigned Attributes;
1224
1225 MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line,
1226 MDString *GetterName, MDString *SetterName, unsigned Attributes,
1227 Metadata *Type)
1228 : Name(Name), File(File), Line(Line), GetterName(GetterName),
1229 SetterName(SetterName), Attributes(Attributes), Type(Type) {}
1231 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
1232 GetterName(N->getRawGetterName()), SetterName(N->getRawSetterName()),
1233 Attributes(N->getAttributes()), Type(N->getRawType()) {}
1234
1235 bool isKeyOf(const DIObjCProperty *RHS) const {
1236 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
1237 Line == RHS->getLine() && GetterName == RHS->getRawGetterName() &&
1238 SetterName == RHS->getRawSetterName() &&
1239 Attributes == RHS->getAttributes() && Type == RHS->getRawType();
1240 }
1241
1242 unsigned getHashValue() const {
1243 return hash_combine(Name, File, Line, GetterName, SetterName, Attributes,
1244 Type);
1245 }
1246};
1247
1248template <> struct MDNodeKeyImpl<DIImportedEntity> {
1249 unsigned Tag;
1253 unsigned Line;
1256
1257 MDNodeKeyImpl(unsigned Tag, Metadata *Scope, Metadata *Entity, Metadata *File,
1258 unsigned Line, MDString *Name, Metadata *Elements)
1259 : Tag(Tag), Scope(Scope), Entity(Entity), File(File), Line(Line),
1260 Name(Name), Elements(Elements) {}
1262 : Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()),
1263 File(N->getRawFile()), Line(N->getLine()), Name(N->getRawName()),
1264 Elements(N->getRawElements()) {}
1265
1266 bool isKeyOf(const DIImportedEntity *RHS) const {
1267 return Tag == RHS->getTag() && Scope == RHS->getRawScope() &&
1268 Entity == RHS->getRawEntity() && File == RHS->getFile() &&
1269 Line == RHS->getLine() && Name == RHS->getRawName() &&
1270 Elements == RHS->getRawElements();
1271 }
1272
1273 unsigned getHashValue() const {
1274 return hash_combine(Tag, Scope, Entity, File, Line, Name, Elements);
1275 }
1276};
1277
1278template <> struct MDNodeKeyImpl<DIMacro> {
1279 unsigned MIType;
1280 unsigned Line;
1283
1284 MDNodeKeyImpl(unsigned MIType, unsigned Line, MDString *Name, MDString *Value)
1285 : MIType(MIType), Line(Line), Name(Name), Value(Value) {}
1287 : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getRawName()),
1288 Value(N->getRawValue()) {}
1289
1290 bool isKeyOf(const DIMacro *RHS) const {
1291 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1292 Name == RHS->getRawName() && Value == RHS->getRawValue();
1293 }
1294
1295 unsigned getHashValue() const {
1296 return hash_combine(MIType, Line, Name, Value);
1297 }
1298};
1299
1300template <> struct MDNodeKeyImpl<DIMacroFile> {
1301 unsigned MIType;
1302 unsigned Line;
1305
1306 MDNodeKeyImpl(unsigned MIType, unsigned Line, Metadata *File,
1307 Metadata *Elements)
1308 : MIType(MIType), Line(Line), File(File), Elements(Elements) {}
1310 : MIType(N->getMacinfoType()), Line(N->getLine()), File(N->getRawFile()),
1311 Elements(N->getRawElements()) {}
1312
1313 bool isKeyOf(const DIMacroFile *RHS) const {
1314 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1315 File == RHS->getRawFile() && Elements == RHS->getRawElements();
1316 }
1317
1318 unsigned getHashValue() const {
1319 return hash_combine(MIType, Line, File, Elements);
1320 }
1321};
1322
1323// DIArgLists are not MDNodes, but we still want to unique them in a DenseSet
1324// based on a hash of their arguments.
1327
1329 DIArgListKeyInfo(const DIArgList *N) : Args(N->getArgs()) {}
1330
1331 bool isKeyOf(const DIArgList *RHS) const { return Args == RHS->getArgs(); }
1332
1333 unsigned getHashValue() const {
1334 return hash_combine_range(Args.begin(), Args.end());
1335 }
1336};
1337
1338/// DenseMapInfo for DIArgList.
1341
1342 static inline DIArgList *getEmptyKey() {
1344 }
1345
1346 static inline DIArgList *getTombstoneKey() {
1348 }
1349
1350 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1351
1352 static unsigned getHashValue(const DIArgList *N) {
1353 return KeyTy(N).getHashValue();
1354 }
1355
1356 static bool isEqual(const KeyTy &LHS, const DIArgList *RHS) {
1357 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1358 return false;
1359 return LHS.isKeyOf(RHS);
1360 }
1361
1362 static bool isEqual(const DIArgList *LHS, const DIArgList *RHS) {
1363 return LHS == RHS;
1364 }
1365};
1366
1367/// DenseMapInfo for MDNode subclasses.
1368template <class NodeTy> struct MDNodeInfo {
1371
1372 static inline NodeTy *getEmptyKey() {
1374 }
1375
1376 static inline NodeTy *getTombstoneKey() {
1378 }
1379
1380 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1381
1382 static unsigned getHashValue(const NodeTy *N) {
1383 return KeyTy(N).getHashValue();
1384 }
1385
1386 static bool isEqual(const KeyTy &LHS, const NodeTy *RHS) {
1387 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1388 return false;
1389 return SubsetEqualTy::isSubsetEqual(LHS, RHS) || LHS.isKeyOf(RHS);
1390 }
1391
1392 static bool isEqual(const NodeTy *LHS, const NodeTy *RHS) {
1393 if (LHS == RHS)
1394 return true;
1395 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1396 return false;
1398 }
1399};
1400
1401#define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>;
1402#include "llvm/IR/Metadata.def"
1403
1404/// Multimap-like storage for metadata attachments.
1406public:
1407 struct Attachment {
1408 unsigned MDKind;
1410 };
1411
1412private:
1413 SmallVector<Attachment, 1> Attachments;
1414
1415public:
1416 bool empty() const { return Attachments.empty(); }
1417 size_t size() const { return Attachments.size(); }
1418
1419 /// Returns the first attachment with the given ID or nullptr if no such
1420 /// attachment exists.
1421 MDNode *lookup(unsigned ID) const;
1422
1423 /// Appends all attachments with the given ID to \c Result in insertion order.
1424 /// If the global has no attachments with the given ID, or if ID is invalid,
1425 /// leaves Result unchanged.
1426 void get(unsigned ID, SmallVectorImpl<MDNode *> &Result) const;
1427
1428 /// Appends all attachments for the global to \c Result, sorting by attachment
1429 /// ID. Attachments with the same ID appear in insertion order. This function
1430 /// does \em not clear \c Result.
1431 void getAll(SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const;
1432
1433 /// Set an attachment to a particular node.
1434 ///
1435 /// Set the \c ID attachment to \c MD, replacing the current attachments at \c
1436 /// ID (if anyway).
1437 void set(unsigned ID, MDNode *MD);
1438
1439 /// Adds an attachment to a particular node.
1440 void insert(unsigned ID, MDNode &MD);
1441
1442 /// Remove attachments with the given ID.
1443 ///
1444 /// Remove the attachments at \c ID, if any.
1445 bool erase(unsigned ID);
1446
1447 /// Erase matching attachments.
1448 ///
1449 /// Erases all attachments matching the \c shouldRemove predicate.
1450 template <class PredTy> void remove_if(PredTy shouldRemove) {
1451 llvm::erase_if(Attachments, shouldRemove);
1452 }
1453};
1454
1456public:
1457 /// OwnedModules - The set of modules instantiated in this context, and which
1458 /// will be automatically deleted if this context is deleted.
1460
1461 /// MachineFunctionNums - Keep the next available unique number available for
1462 /// a MachineFunction in given module. Module must in OwnedModules.
1464
1465 /// The main remark streamer used by all the other streamers (e.g. IR, MIR,
1466 /// frontends, etc.). This should only be used by the specific streamers, and
1467 /// never directly.
1468 std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer;
1469
1470 std::unique_ptr<DiagnosticHandler> DiagHandler;
1473 /// The minimum hotness value a diagnostic needs in order to be included in
1474 /// optimization diagnostics.
1475 ///
1476 /// The threshold is an Optional value, which maps to one of the 3 states:
1477 /// 1). 0 => threshold disabled. All emarks will be printed.
1478 /// 2). positive int => manual threshold by user. Remarks with hotness exceed
1479 /// threshold will be printed.
1480 /// 3). None => 'auto' threshold by user. The actual value is not
1481 /// available at command line, but will be synced with
1482 /// hotness threhold from profile summary during
1483 /// compilation.
1484 ///
1485 /// State 1 and 2 are considered as terminal states. State transition is
1486 /// only allowed from 3 to 2, when the threshold is first synced with profile
1487 /// summary. This ensures that the threshold is set only once and stays
1488 /// constant.
1489 ///
1490 /// If threshold option is not specified, it is disabled (0) by default.
1491 std::optional<uint64_t> DiagnosticsHotnessThreshold = 0;
1492
1493 /// The percentage of difference between profiling branch weights and
1494 /// llvm.expect branch weights to tolerate when emiting MisExpect diagnostics
1495 std::optional<uint32_t> DiagnosticsMisExpectTolerance = 0;
1497
1498 /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
1499 std::unique_ptr<LLVMRemarkStreamer> LLVMRS;
1500
1502 void *YieldOpaqueHandle = nullptr;
1503
1505
1509 DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantInt>>
1511
1513 DenseMap<std::pair<ElementCount, APFloat>, std::unique_ptr<ConstantFP>>
1515
1519
1524
1525#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
1526 DenseSet<CLASS *, CLASS##Info> CLASS##s;
1527#include "llvm/IR/Metadata.def"
1528
1529 // Optional map for looking up composite types by identifier.
1530 std::optional<DenseMap<const MDString *, DICompositeType *>> DITypeMap;
1531
1532 // MDNodes may be uniqued or not uniqued. When they're not uniqued, they
1533 // aren't in the MDNodeSet, but they're still shared between objects, so no
1534 // one object can destroy them. Keep track of them here so we can delete
1535 // them on context teardown.
1536 std::vector<MDNode *> DistinctMDNodes;
1537
1538 // ConstantRangeListAttributeImpl is a TrailingObjects/ArrayRef of
1539 // ConstantRange. Since this is a dynamically sized class, it's not
1540 // possible to use SpecificBumpPtrAllocator. Instead, we use normal Alloc
1541 // for allocation and record all allocated pointers in this vector. In the
1542 // LLVMContext destructor, call the destuctors of everything in the vector.
1543 std::vector<ConstantRangeListAttributeImpl *> ConstantRangeListAttributes;
1544
1546
1549
1552
1555
1557
1559
1561
1563
1565
1568
1570
1572
1574
1576
1578
1581
1582 // Basic type instances.
1587
1588 std::unique_ptr<ConstantTokenNone> TheNoneToken;
1589
1594
1596
1603
1606
1609 PointerType *AS0PointerType = nullptr; // AddrSpace = 0
1613
1614 /// ValueHandles - This map keeps track of all of the value handles that are
1615 /// watching a Value*. The Value::HasValueHandle bit is used to know
1616 /// whether or not a value has an entry in this map.
1619
1620 /// CustomMDKindNames - Map to hold the metadata string to ID mapping.
1622
1623 /// Collection of metadata used in this context.
1625
1626 /// Map DIAssignID -> Instructions with that attachment.
1627 /// Managed by Instruction via Instruction::updateDIAssignIDMapping.
1628 /// Query using the at:: functions defined in DebugInfo.h.
1630
1631 /// Collection of per-GlobalObject sections used in this context.
1633
1634 /// Collection of per-GlobalValue partitions used in this context.
1636
1639
1640 /// DiscriminatorTable - This table maps file:line locations to an
1641 /// integer representing the next DWARF path discriminator to assign to
1642 /// instructions in different blocks at the same location.
1644
1645 /// A set of interned tags for operand bundles. The StringMap maps
1646 /// bundle tags to their IDs.
1647 ///
1648 /// \see LLVMContext::getOperandBundleTagID
1650
1654
1655 /// A set of interned synchronization scopes. The StringMap maps
1656 /// synchronization scope names to their respective synchronization scope IDs.
1658
1659 /// getOrInsertSyncScopeID - Maps synchronization scope name to
1660 /// synchronization scope ID. Every synchronization scope registered with
1661 /// LLVMContext has unique ID except pre-defined ones.
1663
1664 /// getSyncScopeNames - Populates client supplied SmallVector with
1665 /// synchronization scope names registered with LLVMContext. Synchronization
1666 /// scope names are ordered by increasing synchronization scope IDs.
1668
1669 /// Maintain the GC name for each function.
1670 ///
1671 /// This saves allocating an additional word in Function for programs which
1672 /// do not use GC (i.e., most programs) at the cost of increased overhead for
1673 /// clients which do use GC.
1675
1676 /// Flag to indicate if Value (other than GlobalValue) retains their name or
1677 /// not.
1678 bool DiscardValueNames = false;
1679
1682
1683 /// Destroy the ConstantArrays if they are not used.
1685
1686 mutable OptPassGate *OPG = nullptr;
1687
1688 /// Access the object which can disable optional passes and individual
1689 /// optimizations at compile time.
1690 OptPassGate &getOptPassGate() const;
1691
1692 /// Set the object which can disable optional passes and individual
1693 /// optimizations at compile time.
1694 ///
1695 /// The lifetime of the object must be guaranteed to extend as long as the
1696 /// LLVMContext is used by compilation.
1698
1699 /// Mapping of blocks to collections of "trailing" DbgVariableRecords. As part
1700 /// of the "RemoveDIs" project, debug-info variable location records are going
1701 /// to cease being instructions... which raises the problem of where should
1702 /// they be recorded when we remove the terminator of a blocks, such as:
1703 ///
1704 /// %foo = add i32 0, 0
1705 /// br label %bar
1706 ///
1707 /// If the branch is removed, a legitimate transient state while editing a
1708 /// block, any debug-records between those two instructions will not have a
1709 /// location. Each block thus records any DbgVariableRecord records that
1710 /// "trail" in such a way. These are stored in LLVMContext because typically
1711 /// LLVM only edits a small number of blocks at a time, so there's no need to
1712 /// bloat BasicBlock with such a data structure.
1714
1715 // Set, get and delete operations for TrailingDbgRecords.
1717 assert(!TrailingDbgRecords.count(B));
1718 TrailingDbgRecords[B] = M;
1719 }
1720
1722 return TrailingDbgRecords.lookup(B);
1723 }
1724
1726};
1727
1728} // end namespace llvm
1729
1730#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:77
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:890
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:81
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:161
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:536
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
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
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
std::vector< ConstantRangeListAttributeImpl * > ConstantRangeListAttributes
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:128
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: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(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()