1 //===- LLVMContextImpl.h - The LLVMContextImpl opaque class -----*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file declares LLVMContextImpl, the opaque implementation
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_LIB_IR_LLVMCONTEXTIMPL_H
15 #define LLVM_LIB_IR_LLVMCONTEXTIMPL_H
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"
22 #include "llvm/ADT/DenseMapInfo.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"
27 #include "llvm/ADT/SmallPtrSet.h"
28 #include "llvm/ADT/SmallVector.h"
29 #include "llvm/ADT/StringMap.h"
30 #include "llvm/BinaryFormat/Dwarf.h"
31 #include "llvm/IR/Constants.h"
32 #include "llvm/IR/DebugInfoMetadata.h"
33 #include "llvm/IR/DerivedTypes.h"
34 #include "llvm/IR/LLVMContext.h"
35 #include "llvm/IR/Metadata.h"
36 #include "llvm/IR/Module.h"
37 #include "llvm/IR/TrackingMDRef.h"
38 #include "llvm/IR/Type.h"
39 #include "llvm/IR/Value.h"
40 #include "llvm/Support/Allocator.h"
41 #include "llvm/Support/Casting.h"
42 #include "llvm/Support/StringSaver.h"
56 class AttributeListImpl
;
57 class AttributeSetNode
;
59 struct DiagnosticHandler
;
66 class LLVMRemarkStreamer
;
71 template <typename T
> class StringMapEntry
;
73 class TypedPointerType
;
74 class ValueHandleBase
;
76 template <> struct DenseMapInfo
<APFloat
> {
77 static inline APFloat
getEmptyKey() { return APFloat(APFloat::Bogus(), 1); }
78 static inline APFloat
getTombstoneKey() {
79 return APFloat(APFloat::Bogus(), 2);
82 static unsigned getHashValue(const APFloat
&Key
) {
83 return static_cast<unsigned>(hash_value(Key
));
86 static bool isEqual(const APFloat
&LHS
, const APFloat
&RHS
) {
87 return LHS
.bitwiseIsEqual(RHS
);
91 struct AnonStructTypeKeyInfo
{
93 ArrayRef
<Type
*> ETypes
;
96 KeyTy(const ArrayRef
<Type
*> &E
, bool P
) : ETypes(E
), isPacked(P
) {}
98 KeyTy(const StructType
*ST
)
99 : ETypes(ST
->elements()), isPacked(ST
->isPacked()) {}
101 bool operator==(const KeyTy
&that
) const {
102 if (isPacked
!= that
.isPacked
)
104 if (ETypes
!= that
.ETypes
)
108 bool operator!=(const KeyTy
&that
) const { return !this->operator==(that
); }
111 static inline StructType
*getEmptyKey() {
112 return DenseMapInfo
<StructType
*>::getEmptyKey();
115 static inline StructType
*getTombstoneKey() {
116 return DenseMapInfo
<StructType
*>::getTombstoneKey();
119 static unsigned getHashValue(const KeyTy
&Key
) {
121 hash_combine_range(Key
.ETypes
.begin(), Key
.ETypes
.end()), Key
.isPacked
);
124 static unsigned getHashValue(const StructType
*ST
) {
125 return getHashValue(KeyTy(ST
));
128 static bool isEqual(const KeyTy
&LHS
, const StructType
*RHS
) {
129 if (RHS
== getEmptyKey() || RHS
== getTombstoneKey())
131 return LHS
== KeyTy(RHS
);
134 static bool isEqual(const StructType
*LHS
, const StructType
*RHS
) {
139 struct FunctionTypeKeyInfo
{
141 const Type
*ReturnType
;
142 ArrayRef
<Type
*> Params
;
145 KeyTy(const Type
*R
, const ArrayRef
<Type
*> &P
, bool V
)
146 : ReturnType(R
), Params(P
), isVarArg(V
) {}
147 KeyTy(const FunctionType
*FT
)
148 : ReturnType(FT
->getReturnType()), Params(FT
->params()),
149 isVarArg(FT
->isVarArg()) {}
151 bool operator==(const KeyTy
&that
) const {
152 if (ReturnType
!= that
.ReturnType
)
154 if (isVarArg
!= that
.isVarArg
)
156 if (Params
!= that
.Params
)
160 bool operator!=(const KeyTy
&that
) const { return !this->operator==(that
); }
163 static inline FunctionType
*getEmptyKey() {
164 return DenseMapInfo
<FunctionType
*>::getEmptyKey();
167 static inline FunctionType
*getTombstoneKey() {
168 return DenseMapInfo
<FunctionType
*>::getTombstoneKey();
171 static unsigned getHashValue(const KeyTy
&Key
) {
174 hash_combine_range(Key
.Params
.begin(), Key
.Params
.end()), Key
.isVarArg
);
177 static unsigned getHashValue(const FunctionType
*FT
) {
178 return getHashValue(KeyTy(FT
));
181 static bool isEqual(const KeyTy
&LHS
, const FunctionType
*RHS
) {
182 if (RHS
== getEmptyKey() || RHS
== getTombstoneKey())
184 return LHS
== KeyTy(RHS
);
187 static bool isEqual(const FunctionType
*LHS
, const FunctionType
*RHS
) {
192 struct TargetExtTypeKeyInfo
{
195 ArrayRef
<Type
*> TypeParams
;
196 ArrayRef
<unsigned> IntParams
;
198 KeyTy(StringRef N
, const ArrayRef
<Type
*> &TP
, const ArrayRef
<unsigned> &IP
)
199 : Name(N
), TypeParams(TP
), IntParams(IP
) {}
200 KeyTy(const TargetExtType
*TT
)
201 : Name(TT
->getName()), TypeParams(TT
->type_params()),
202 IntParams(TT
->int_params()) {}
204 bool operator==(const KeyTy
&that
) const {
205 return Name
== that
.Name
&& TypeParams
== that
.TypeParams
&&
206 IntParams
== that
.IntParams
;
208 bool operator!=(const KeyTy
&that
) const { return !this->operator==(that
); }
211 static inline TargetExtType
*getEmptyKey() {
212 return DenseMapInfo
<TargetExtType
*>::getEmptyKey();
215 static inline TargetExtType
*getTombstoneKey() {
216 return DenseMapInfo
<TargetExtType
*>::getTombstoneKey();
219 static unsigned getHashValue(const KeyTy
&Key
) {
222 hash_combine_range(Key
.TypeParams
.begin(), Key
.TypeParams
.end()),
223 hash_combine_range(Key
.IntParams
.begin(), Key
.IntParams
.end()));
226 static unsigned getHashValue(const TargetExtType
*FT
) {
227 return getHashValue(KeyTy(FT
));
230 static bool isEqual(const KeyTy
&LHS
, const TargetExtType
*RHS
) {
231 if (RHS
== getEmptyKey() || RHS
== getTombstoneKey())
233 return LHS
== KeyTy(RHS
);
236 static bool isEqual(const TargetExtType
*LHS
, const TargetExtType
*RHS
) {
241 /// Structure for hashing arbitrary MDNode operands.
243 ArrayRef
<Metadata
*> RawOps
;
244 ArrayRef
<MDOperand
> Ops
;
248 MDNodeOpsKey(ArrayRef
<Metadata
*> Ops
)
249 : RawOps(Ops
), Hash(calculateHash(Ops
)) {}
251 template <class NodeTy
>
252 MDNodeOpsKey(const NodeTy
*N
, unsigned Offset
= 0)
253 : Ops(N
->op_begin() + Offset
, N
->op_end()), Hash(N
->getHash()) {}
255 template <class NodeTy
>
256 bool compareOps(const NodeTy
*RHS
, unsigned Offset
= 0) const {
257 if (getHash() != RHS
->getHash())
260 assert((RawOps
.empty() || Ops
.empty()) && "Two sets of operands?");
261 return RawOps
.empty() ? compareOps(Ops
, RHS
, Offset
)
262 : compareOps(RawOps
, RHS
, Offset
);
265 static unsigned calculateHash(MDNode
*N
, unsigned Offset
= 0);
269 static bool compareOps(ArrayRef
<T
> Ops
, const MDNode
*RHS
, unsigned Offset
) {
270 if (Ops
.size() != RHS
->getNumOperands() - Offset
)
272 return std::equal(Ops
.begin(), Ops
.end(), RHS
->op_begin() + Offset
);
275 static unsigned calculateHash(ArrayRef
<Metadata
*> Ops
);
278 unsigned getHash() const { return Hash
; }
281 template <class NodeTy
> struct MDNodeKeyImpl
;
283 /// Configuration point for MDNodeInfo::isEqual().
284 template <class NodeTy
> struct MDNodeSubsetEqualImpl
{
285 using KeyTy
= MDNodeKeyImpl
<NodeTy
>;
287 static bool isSubsetEqual(const KeyTy
&LHS
, const NodeTy
*RHS
) {
291 static bool isSubsetEqual(const NodeTy
*LHS
, const NodeTy
*RHS
) {
296 /// DenseMapInfo for MDTuple.
298 /// Note that we don't need the is-function-local bit, since that's implicit in
300 template <> struct MDNodeKeyImpl
<MDTuple
> : MDNodeOpsKey
{
301 MDNodeKeyImpl(ArrayRef
<Metadata
*> Ops
) : MDNodeOpsKey(Ops
) {}
302 MDNodeKeyImpl(const MDTuple
*N
) : MDNodeOpsKey(N
) {}
304 bool isKeyOf(const MDTuple
*RHS
) const { return compareOps(RHS
); }
306 unsigned getHashValue() const { return getHash(); }
308 static unsigned calculateHash(MDTuple
*N
) {
309 return MDNodeOpsKey::calculateHash(N
);
313 /// DenseMapInfo for DILocation.
314 template <> struct MDNodeKeyImpl
<DILocation
> {
321 MDNodeKeyImpl(unsigned Line
, unsigned Column
, Metadata
*Scope
,
322 Metadata
*InlinedAt
, bool ImplicitCode
)
323 : Line(Line
), Column(Column
), Scope(Scope
), InlinedAt(InlinedAt
),
324 ImplicitCode(ImplicitCode
) {}
325 MDNodeKeyImpl(const DILocation
*L
)
326 : Line(L
->getLine()), Column(L
->getColumn()), Scope(L
->getRawScope()),
327 InlinedAt(L
->getRawInlinedAt()), ImplicitCode(L
->isImplicitCode()) {}
329 bool isKeyOf(const DILocation
*RHS
) const {
330 return Line
== RHS
->getLine() && Column
== RHS
->getColumn() &&
331 Scope
== RHS
->getRawScope() && InlinedAt
== RHS
->getRawInlinedAt() &&
332 ImplicitCode
== RHS
->isImplicitCode();
335 unsigned getHashValue() const {
336 return hash_combine(Line
, Column
, Scope
, InlinedAt
, ImplicitCode
);
340 /// DenseMapInfo for GenericDINode.
341 template <> struct MDNodeKeyImpl
<GenericDINode
> : MDNodeOpsKey
{
345 MDNodeKeyImpl(unsigned Tag
, MDString
*Header
, ArrayRef
<Metadata
*> DwarfOps
)
346 : MDNodeOpsKey(DwarfOps
), Tag(Tag
), Header(Header
) {}
347 MDNodeKeyImpl(const GenericDINode
*N
)
348 : MDNodeOpsKey(N
, 1), Tag(N
->getTag()), Header(N
->getRawHeader()) {}
350 bool isKeyOf(const GenericDINode
*RHS
) const {
351 return Tag
== RHS
->getTag() && Header
== RHS
->getRawHeader() &&
355 unsigned getHashValue() const { return hash_combine(getHash(), Tag
, Header
); }
357 static unsigned calculateHash(GenericDINode
*N
) {
358 return MDNodeOpsKey::calculateHash(N
, 1);
362 template <> struct MDNodeKeyImpl
<DISubrange
> {
364 Metadata
*LowerBound
;
365 Metadata
*UpperBound
;
368 MDNodeKeyImpl(Metadata
*CountNode
, Metadata
*LowerBound
, Metadata
*UpperBound
,
370 : CountNode(CountNode
), LowerBound(LowerBound
), UpperBound(UpperBound
),
372 MDNodeKeyImpl(const DISubrange
*N
)
373 : CountNode(N
->getRawCountNode()), LowerBound(N
->getRawLowerBound()),
374 UpperBound(N
->getRawUpperBound()), Stride(N
->getRawStride()) {}
376 bool isKeyOf(const DISubrange
*RHS
) const {
377 auto BoundsEqual
= [=](Metadata
*Node1
, Metadata
*Node2
) -> bool {
381 ConstantAsMetadata
*MD1
= dyn_cast_or_null
<ConstantAsMetadata
>(Node1
);
382 ConstantAsMetadata
*MD2
= dyn_cast_or_null
<ConstantAsMetadata
>(Node2
);
384 ConstantInt
*CV1
= cast
<ConstantInt
>(MD1
->getValue());
385 ConstantInt
*CV2
= cast
<ConstantInt
>(MD2
->getValue());
386 if (CV1
->getSExtValue() == CV2
->getSExtValue())
392 return BoundsEqual(CountNode
, RHS
->getRawCountNode()) &&
393 BoundsEqual(LowerBound
, RHS
->getRawLowerBound()) &&
394 BoundsEqual(UpperBound
, RHS
->getRawUpperBound()) &&
395 BoundsEqual(Stride
, RHS
->getRawStride());
398 unsigned getHashValue() const {
400 if (auto *MD
= dyn_cast
<ConstantAsMetadata
>(CountNode
))
401 return hash_combine(cast
<ConstantInt
>(MD
->getValue())->getSExtValue(),
402 LowerBound
, UpperBound
, Stride
);
403 return hash_combine(CountNode
, LowerBound
, UpperBound
, Stride
);
407 template <> struct MDNodeKeyImpl
<DIGenericSubrange
> {
409 Metadata
*LowerBound
;
410 Metadata
*UpperBound
;
413 MDNodeKeyImpl(Metadata
*CountNode
, Metadata
*LowerBound
, Metadata
*UpperBound
,
415 : CountNode(CountNode
), LowerBound(LowerBound
), UpperBound(UpperBound
),
417 MDNodeKeyImpl(const DIGenericSubrange
*N
)
418 : CountNode(N
->getRawCountNode()), LowerBound(N
->getRawLowerBound()),
419 UpperBound(N
->getRawUpperBound()), Stride(N
->getRawStride()) {}
421 bool isKeyOf(const DIGenericSubrange
*RHS
) const {
422 return (CountNode
== RHS
->getRawCountNode()) &&
423 (LowerBound
== RHS
->getRawLowerBound()) &&
424 (UpperBound
== RHS
->getRawUpperBound()) &&
425 (Stride
== RHS
->getRawStride());
428 unsigned getHashValue() const {
429 auto *MD
= dyn_cast_or_null
<ConstantAsMetadata
>(CountNode
);
431 return hash_combine(cast
<ConstantInt
>(MD
->getValue())->getSExtValue(),
432 LowerBound
, UpperBound
, Stride
);
433 return hash_combine(CountNode
, LowerBound
, UpperBound
, Stride
);
437 template <> struct MDNodeKeyImpl
<DIEnumerator
> {
442 MDNodeKeyImpl(APInt Value
, bool IsUnsigned
, MDString
*Name
)
443 : Value(Value
), Name(Name
), IsUnsigned(IsUnsigned
) {}
444 MDNodeKeyImpl(int64_t Value
, bool IsUnsigned
, MDString
*Name
)
445 : Value(APInt(64, Value
, !IsUnsigned
)), Name(Name
),
446 IsUnsigned(IsUnsigned
) {}
447 MDNodeKeyImpl(const DIEnumerator
*N
)
448 : Value(N
->getValue()), Name(N
->getRawName()),
449 IsUnsigned(N
->isUnsigned()) {}
451 bool isKeyOf(const DIEnumerator
*RHS
) const {
452 return Value
.getBitWidth() == RHS
->getValue().getBitWidth() &&
453 Value
== RHS
->getValue() && IsUnsigned
== RHS
->isUnsigned() &&
454 Name
== RHS
->getRawName();
457 unsigned getHashValue() const { return hash_combine(Value
, Name
); }
460 template <> struct MDNodeKeyImpl
<DIBasicType
> {
464 uint32_t AlignInBits
;
468 MDNodeKeyImpl(unsigned Tag
, MDString
*Name
, uint64_t SizeInBits
,
469 uint32_t AlignInBits
, unsigned Encoding
, unsigned Flags
)
470 : Tag(Tag
), Name(Name
), SizeInBits(SizeInBits
), AlignInBits(AlignInBits
),
471 Encoding(Encoding
), Flags(Flags
) {}
472 MDNodeKeyImpl(const DIBasicType
*N
)
473 : Tag(N
->getTag()), Name(N
->getRawName()), SizeInBits(N
->getSizeInBits()),
474 AlignInBits(N
->getAlignInBits()), Encoding(N
->getEncoding()),
475 Flags(N
->getFlags()) {}
477 bool isKeyOf(const DIBasicType
*RHS
) const {
478 return Tag
== RHS
->getTag() && Name
== RHS
->getRawName() &&
479 SizeInBits
== RHS
->getSizeInBits() &&
480 AlignInBits
== RHS
->getAlignInBits() &&
481 Encoding
== RHS
->getEncoding() && Flags
== RHS
->getFlags();
484 unsigned getHashValue() const {
485 return hash_combine(Tag
, Name
, SizeInBits
, AlignInBits
, Encoding
);
489 template <> struct MDNodeKeyImpl
<DIStringType
> {
492 Metadata
*StringLength
;
493 Metadata
*StringLengthExp
;
494 Metadata
*StringLocationExp
;
496 uint32_t AlignInBits
;
499 MDNodeKeyImpl(unsigned Tag
, MDString
*Name
, Metadata
*StringLength
,
500 Metadata
*StringLengthExp
, Metadata
*StringLocationExp
,
501 uint64_t SizeInBits
, uint32_t AlignInBits
, unsigned Encoding
)
502 : Tag(Tag
), Name(Name
), StringLength(StringLength
),
503 StringLengthExp(StringLengthExp
), StringLocationExp(StringLocationExp
),
504 SizeInBits(SizeInBits
), AlignInBits(AlignInBits
), Encoding(Encoding
) {}
505 MDNodeKeyImpl(const DIStringType
*N
)
506 : Tag(N
->getTag()), Name(N
->getRawName()),
507 StringLength(N
->getRawStringLength()),
508 StringLengthExp(N
->getRawStringLengthExp()),
509 StringLocationExp(N
->getRawStringLocationExp()),
510 SizeInBits(N
->getSizeInBits()), AlignInBits(N
->getAlignInBits()),
511 Encoding(N
->getEncoding()) {}
513 bool isKeyOf(const DIStringType
*RHS
) const {
514 return Tag
== RHS
->getTag() && Name
== RHS
->getRawName() &&
515 StringLength
== RHS
->getRawStringLength() &&
516 StringLengthExp
== RHS
->getRawStringLengthExp() &&
517 StringLocationExp
== RHS
->getRawStringLocationExp() &&
518 SizeInBits
== RHS
->getSizeInBits() &&
519 AlignInBits
== RHS
->getAlignInBits() &&
520 Encoding
== RHS
->getEncoding();
522 unsigned getHashValue() const {
523 // Intentionally computes the hash on a subset of the operands for
524 // performance reason. The subset has to be significant enough to avoid
525 // collision "most of the time". There is no correctness issue in case of
526 // collision because of the full check above.
527 return hash_combine(Tag
, Name
, StringLength
, Encoding
);
531 template <> struct MDNodeKeyImpl
<DIDerivedType
> {
539 uint64_t OffsetInBits
;
540 uint32_t AlignInBits
;
541 std::optional
<unsigned> DWARFAddressSpace
;
544 Metadata
*Annotations
;
546 MDNodeKeyImpl(unsigned Tag
, MDString
*Name
, Metadata
*File
, unsigned Line
,
547 Metadata
*Scope
, Metadata
*BaseType
, uint64_t SizeInBits
,
548 uint32_t AlignInBits
, uint64_t OffsetInBits
,
549 std::optional
<unsigned> DWARFAddressSpace
, unsigned Flags
,
550 Metadata
*ExtraData
, Metadata
*Annotations
)
551 : Tag(Tag
), Name(Name
), File(File
), Line(Line
), Scope(Scope
),
552 BaseType(BaseType
), SizeInBits(SizeInBits
), OffsetInBits(OffsetInBits
),
553 AlignInBits(AlignInBits
), DWARFAddressSpace(DWARFAddressSpace
),
554 Flags(Flags
), ExtraData(ExtraData
), Annotations(Annotations
) {}
555 MDNodeKeyImpl(const DIDerivedType
*N
)
556 : Tag(N
->getTag()), Name(N
->getRawName()), File(N
->getRawFile()),
557 Line(N
->getLine()), Scope(N
->getRawScope()),
558 BaseType(N
->getRawBaseType()), SizeInBits(N
->getSizeInBits()),
559 OffsetInBits(N
->getOffsetInBits()), AlignInBits(N
->getAlignInBits()),
560 DWARFAddressSpace(N
->getDWARFAddressSpace()), Flags(N
->getFlags()),
561 ExtraData(N
->getRawExtraData()), Annotations(N
->getRawAnnotations()) {}
563 bool isKeyOf(const DIDerivedType
*RHS
) const {
564 return Tag
== RHS
->getTag() && Name
== RHS
->getRawName() &&
565 File
== RHS
->getRawFile() && Line
== RHS
->getLine() &&
566 Scope
== RHS
->getRawScope() && BaseType
== RHS
->getRawBaseType() &&
567 SizeInBits
== RHS
->getSizeInBits() &&
568 AlignInBits
== RHS
->getAlignInBits() &&
569 OffsetInBits
== RHS
->getOffsetInBits() &&
570 DWARFAddressSpace
== RHS
->getDWARFAddressSpace() &&
571 Flags
== RHS
->getFlags() && ExtraData
== RHS
->getRawExtraData() &&
572 Annotations
== RHS
->getRawAnnotations();
575 unsigned getHashValue() const {
576 // If this is a member inside an ODR type, only hash the type and the name.
577 // Otherwise the hash will be stronger than
578 // MDNodeSubsetEqualImpl::isODRMember().
579 if (Tag
== dwarf::DW_TAG_member
&& Name
)
580 if (auto *CT
= dyn_cast_or_null
<DICompositeType
>(Scope
))
581 if (CT
->getRawIdentifier())
582 return hash_combine(Name
, Scope
);
584 // Intentionally computes the hash on a subset of the operands for
585 // performance reason. The subset has to be significant enough to avoid
586 // collision "most of the time". There is no correctness issue in case of
587 // collision because of the full check above.
588 return hash_combine(Tag
, Name
, File
, Line
, Scope
, BaseType
, Flags
);
592 template <> struct MDNodeSubsetEqualImpl
<DIDerivedType
> {
593 using KeyTy
= MDNodeKeyImpl
<DIDerivedType
>;
595 static bool isSubsetEqual(const KeyTy
&LHS
, const DIDerivedType
*RHS
) {
596 return isODRMember(LHS
.Tag
, LHS
.Scope
, LHS
.Name
, RHS
);
599 static bool isSubsetEqual(const DIDerivedType
*LHS
,
600 const DIDerivedType
*RHS
) {
601 return isODRMember(LHS
->getTag(), LHS
->getRawScope(), LHS
->getRawName(),
605 /// Subprograms compare equal if they declare the same function in an ODR
607 static bool isODRMember(unsigned Tag
, const Metadata
*Scope
,
608 const MDString
*Name
, const DIDerivedType
*RHS
) {
609 // Check whether the LHS is eligible.
610 if (Tag
!= dwarf::DW_TAG_member
|| !Name
)
613 auto *CT
= dyn_cast_or_null
<DICompositeType
>(Scope
);
614 if (!CT
|| !CT
->getRawIdentifier())
617 // Compare to the RHS.
618 return Tag
== RHS
->getTag() && Name
== RHS
->getRawName() &&
619 Scope
== RHS
->getRawScope();
623 template <> struct MDNodeKeyImpl
<DICompositeType
> {
631 uint64_t OffsetInBits
;
632 uint32_t AlignInBits
;
635 unsigned RuntimeLang
;
636 Metadata
*VTableHolder
;
637 Metadata
*TemplateParams
;
638 MDString
*Identifier
;
639 Metadata
*Discriminator
;
640 Metadata
*DataLocation
;
641 Metadata
*Associated
;
644 Metadata
*Annotations
;
646 MDNodeKeyImpl(unsigned Tag
, MDString
*Name
, Metadata
*File
, unsigned Line
,
647 Metadata
*Scope
, Metadata
*BaseType
, uint64_t SizeInBits
,
648 uint32_t AlignInBits
, uint64_t OffsetInBits
, unsigned Flags
,
649 Metadata
*Elements
, unsigned RuntimeLang
,
650 Metadata
*VTableHolder
, Metadata
*TemplateParams
,
651 MDString
*Identifier
, Metadata
*Discriminator
,
652 Metadata
*DataLocation
, Metadata
*Associated
,
653 Metadata
*Allocated
, Metadata
*Rank
, Metadata
*Annotations
)
654 : Tag(Tag
), Name(Name
), File(File
), Line(Line
), Scope(Scope
),
655 BaseType(BaseType
), SizeInBits(SizeInBits
), OffsetInBits(OffsetInBits
),
656 AlignInBits(AlignInBits
), Flags(Flags
), Elements(Elements
),
657 RuntimeLang(RuntimeLang
), VTableHolder(VTableHolder
),
658 TemplateParams(TemplateParams
), Identifier(Identifier
),
659 Discriminator(Discriminator
), DataLocation(DataLocation
),
660 Associated(Associated
), Allocated(Allocated
), Rank(Rank
),
661 Annotations(Annotations
) {}
662 MDNodeKeyImpl(const DICompositeType
*N
)
663 : Tag(N
->getTag()), Name(N
->getRawName()), File(N
->getRawFile()),
664 Line(N
->getLine()), Scope(N
->getRawScope()),
665 BaseType(N
->getRawBaseType()), SizeInBits(N
->getSizeInBits()),
666 OffsetInBits(N
->getOffsetInBits()), AlignInBits(N
->getAlignInBits()),
667 Flags(N
->getFlags()), Elements(N
->getRawElements()),
668 RuntimeLang(N
->getRuntimeLang()), VTableHolder(N
->getRawVTableHolder()),
669 TemplateParams(N
->getRawTemplateParams()),
670 Identifier(N
->getRawIdentifier()),
671 Discriminator(N
->getRawDiscriminator()),
672 DataLocation(N
->getRawDataLocation()),
673 Associated(N
->getRawAssociated()), Allocated(N
->getRawAllocated()),
674 Rank(N
->getRawRank()), Annotations(N
->getRawAnnotations()) {}
676 bool isKeyOf(const DICompositeType
*RHS
) const {
677 return Tag
== RHS
->getTag() && Name
== RHS
->getRawName() &&
678 File
== RHS
->getRawFile() && Line
== RHS
->getLine() &&
679 Scope
== RHS
->getRawScope() && BaseType
== RHS
->getRawBaseType() &&
680 SizeInBits
== RHS
->getSizeInBits() &&
681 AlignInBits
== RHS
->getAlignInBits() &&
682 OffsetInBits
== RHS
->getOffsetInBits() && Flags
== RHS
->getFlags() &&
683 Elements
== RHS
->getRawElements() &&
684 RuntimeLang
== RHS
->getRuntimeLang() &&
685 VTableHolder
== RHS
->getRawVTableHolder() &&
686 TemplateParams
== RHS
->getRawTemplateParams() &&
687 Identifier
== RHS
->getRawIdentifier() &&
688 Discriminator
== RHS
->getRawDiscriminator() &&
689 DataLocation
== RHS
->getRawDataLocation() &&
690 Associated
== RHS
->getRawAssociated() &&
691 Allocated
== RHS
->getRawAllocated() && Rank
== RHS
->getRawRank() &&
692 Annotations
== RHS
->getRawAnnotations();
695 unsigned getHashValue() const {
696 // Intentionally computes the hash on a subset of the operands for
697 // performance reason. The subset has to be significant enough to avoid
698 // collision "most of the time". There is no correctness issue in case of
699 // collision because of the full check above.
700 return hash_combine(Name
, File
, Line
, BaseType
, Scope
, Elements
,
701 TemplateParams
, Annotations
);
705 template <> struct MDNodeKeyImpl
<DISubroutineType
> {
710 MDNodeKeyImpl(unsigned Flags
, uint8_t CC
, Metadata
*TypeArray
)
711 : Flags(Flags
), CC(CC
), TypeArray(TypeArray
) {}
712 MDNodeKeyImpl(const DISubroutineType
*N
)
713 : Flags(N
->getFlags()), CC(N
->getCC()), TypeArray(N
->getRawTypeArray()) {}
715 bool isKeyOf(const DISubroutineType
*RHS
) const {
716 return Flags
== RHS
->getFlags() && CC
== RHS
->getCC() &&
717 TypeArray
== RHS
->getRawTypeArray();
720 unsigned getHashValue() const { return hash_combine(Flags
, CC
, TypeArray
); }
723 template <> struct MDNodeKeyImpl
<DIFile
> {
726 std::optional
<DIFile::ChecksumInfo
<MDString
*>> Checksum
;
729 MDNodeKeyImpl(MDString
*Filename
, MDString
*Directory
,
730 std::optional
<DIFile::ChecksumInfo
<MDString
*>> Checksum
,
732 : Filename(Filename
), Directory(Directory
), Checksum(Checksum
),
734 MDNodeKeyImpl(const DIFile
*N
)
735 : Filename(N
->getRawFilename()), Directory(N
->getRawDirectory()),
736 Checksum(N
->getRawChecksum()), Source(N
->getRawSource()) {}
738 bool isKeyOf(const DIFile
*RHS
) const {
739 return Filename
== RHS
->getRawFilename() &&
740 Directory
== RHS
->getRawDirectory() &&
741 Checksum
== RHS
->getRawChecksum() && Source
== RHS
->getRawSource();
744 unsigned getHashValue() const {
745 return hash_combine(Filename
, Directory
, Checksum
? Checksum
->Kind
: 0,
746 Checksum
? Checksum
->Value
: nullptr, Source
);
750 template <> struct MDNodeKeyImpl
<DISubprogram
> {
753 MDString
*LinkageName
;
758 Metadata
*ContainingType
;
759 unsigned VirtualIndex
;
764 Metadata
*TemplateParams
;
765 Metadata
*Declaration
;
766 Metadata
*RetainedNodes
;
767 Metadata
*ThrownTypes
;
768 Metadata
*Annotations
;
769 MDString
*TargetFuncName
;
771 MDNodeKeyImpl(Metadata
*Scope
, MDString
*Name
, MDString
*LinkageName
,
772 Metadata
*File
, unsigned Line
, Metadata
*Type
,
773 unsigned ScopeLine
, Metadata
*ContainingType
,
774 unsigned VirtualIndex
, int ThisAdjustment
, unsigned Flags
,
775 unsigned SPFlags
, Metadata
*Unit
, Metadata
*TemplateParams
,
776 Metadata
*Declaration
, Metadata
*RetainedNodes
,
777 Metadata
*ThrownTypes
, Metadata
*Annotations
,
778 MDString
*TargetFuncName
)
779 : Scope(Scope
), Name(Name
), LinkageName(LinkageName
), File(File
),
780 Line(Line
), Type(Type
), ScopeLine(ScopeLine
),
781 ContainingType(ContainingType
), VirtualIndex(VirtualIndex
),
782 ThisAdjustment(ThisAdjustment
), Flags(Flags
), SPFlags(SPFlags
),
783 Unit(Unit
), TemplateParams(TemplateParams
), Declaration(Declaration
),
784 RetainedNodes(RetainedNodes
), ThrownTypes(ThrownTypes
),
785 Annotations(Annotations
), TargetFuncName(TargetFuncName
) {}
786 MDNodeKeyImpl(const DISubprogram
*N
)
787 : Scope(N
->getRawScope()), Name(N
->getRawName()),
788 LinkageName(N
->getRawLinkageName()), File(N
->getRawFile()),
789 Line(N
->getLine()), Type(N
->getRawType()), ScopeLine(N
->getScopeLine()),
790 ContainingType(N
->getRawContainingType()),
791 VirtualIndex(N
->getVirtualIndex()),
792 ThisAdjustment(N
->getThisAdjustment()), Flags(N
->getFlags()),
793 SPFlags(N
->getSPFlags()), Unit(N
->getRawUnit()),
794 TemplateParams(N
->getRawTemplateParams()),
795 Declaration(N
->getRawDeclaration()),
796 RetainedNodes(N
->getRawRetainedNodes()),
797 ThrownTypes(N
->getRawThrownTypes()),
798 Annotations(N
->getRawAnnotations()),
799 TargetFuncName(N
->getRawTargetFuncName()) {}
801 bool isKeyOf(const DISubprogram
*RHS
) const {
802 return Scope
== RHS
->getRawScope() && Name
== RHS
->getRawName() &&
803 LinkageName
== RHS
->getRawLinkageName() &&
804 File
== RHS
->getRawFile() && Line
== RHS
->getLine() &&
805 Type
== RHS
->getRawType() && ScopeLine
== RHS
->getScopeLine() &&
806 ContainingType
== RHS
->getRawContainingType() &&
807 VirtualIndex
== RHS
->getVirtualIndex() &&
808 ThisAdjustment
== RHS
->getThisAdjustment() &&
809 Flags
== RHS
->getFlags() && SPFlags
== RHS
->getSPFlags() &&
810 Unit
== RHS
->getUnit() &&
811 TemplateParams
== RHS
->getRawTemplateParams() &&
812 Declaration
== RHS
->getRawDeclaration() &&
813 RetainedNodes
== RHS
->getRawRetainedNodes() &&
814 ThrownTypes
== RHS
->getRawThrownTypes() &&
815 Annotations
== RHS
->getRawAnnotations() &&
816 TargetFuncName
== RHS
->getRawTargetFuncName();
819 bool isDefinition() const { return SPFlags
& DISubprogram::SPFlagDefinition
; }
821 unsigned getHashValue() const {
822 // If this is a declaration inside an ODR type, only hash the type and the
823 // name. Otherwise the hash will be stronger than
824 // MDNodeSubsetEqualImpl::isDeclarationOfODRMember().
825 if (!isDefinition() && LinkageName
)
826 if (auto *CT
= dyn_cast_or_null
<DICompositeType
>(Scope
))
827 if (CT
->getRawIdentifier())
828 return hash_combine(LinkageName
, Scope
);
830 // Intentionally computes the hash on a subset of the operands for
831 // performance reason. The subset has to be significant enough to avoid
832 // collision "most of the time". There is no correctness issue in case of
833 // collision because of the full check above.
834 return hash_combine(Name
, Scope
, File
, Type
, Line
);
838 template <> struct MDNodeSubsetEqualImpl
<DISubprogram
> {
839 using KeyTy
= MDNodeKeyImpl
<DISubprogram
>;
841 static bool isSubsetEqual(const KeyTy
&LHS
, const DISubprogram
*RHS
) {
842 return isDeclarationOfODRMember(LHS
.isDefinition(), LHS
.Scope
,
843 LHS
.LinkageName
, LHS
.TemplateParams
, RHS
);
846 static bool isSubsetEqual(const DISubprogram
*LHS
, const DISubprogram
*RHS
) {
847 return isDeclarationOfODRMember(LHS
->isDefinition(), LHS
->getRawScope(),
848 LHS
->getRawLinkageName(),
849 LHS
->getRawTemplateParams(), RHS
);
852 /// Subprograms compare equal if they declare the same function in an ODR
854 static bool isDeclarationOfODRMember(bool IsDefinition
, const Metadata
*Scope
,
855 const MDString
*LinkageName
,
856 const Metadata
*TemplateParams
,
857 const DISubprogram
*RHS
) {
858 // Check whether the LHS is eligible.
859 if (IsDefinition
|| !Scope
|| !LinkageName
)
862 auto *CT
= dyn_cast_or_null
<DICompositeType
>(Scope
);
863 if (!CT
|| !CT
->getRawIdentifier())
866 // Compare to the RHS.
867 // FIXME: We need to compare template parameters here to avoid incorrect
868 // collisions in mapMetadata when RF_ReuseAndMutateDistinctMDs and a
869 // ODR-DISubprogram has a non-ODR template parameter (i.e., a
870 // DICompositeType that does not have an identifier). Eventually we should
871 // decouple ODR logic from uniquing logic.
872 return IsDefinition
== RHS
->isDefinition() && Scope
== RHS
->getRawScope() &&
873 LinkageName
== RHS
->getRawLinkageName() &&
874 TemplateParams
== RHS
->getRawTemplateParams();
878 template <> struct MDNodeKeyImpl
<DILexicalBlock
> {
884 MDNodeKeyImpl(Metadata
*Scope
, Metadata
*File
, unsigned Line
, unsigned Column
)
885 : Scope(Scope
), File(File
), Line(Line
), Column(Column
) {}
886 MDNodeKeyImpl(const DILexicalBlock
*N
)
887 : Scope(N
->getRawScope()), File(N
->getRawFile()), Line(N
->getLine()),
888 Column(N
->getColumn()) {}
890 bool isKeyOf(const DILexicalBlock
*RHS
) const {
891 return Scope
== RHS
->getRawScope() && File
== RHS
->getRawFile() &&
892 Line
== RHS
->getLine() && Column
== RHS
->getColumn();
895 unsigned getHashValue() const {
896 return hash_combine(Scope
, File
, Line
, Column
);
900 template <> struct MDNodeKeyImpl
<DILexicalBlockFile
> {
903 unsigned Discriminator
;
905 MDNodeKeyImpl(Metadata
*Scope
, Metadata
*File
, unsigned Discriminator
)
906 : Scope(Scope
), File(File
), Discriminator(Discriminator
) {}
907 MDNodeKeyImpl(const DILexicalBlockFile
*N
)
908 : Scope(N
->getRawScope()), File(N
->getRawFile()),
909 Discriminator(N
->getDiscriminator()) {}
911 bool isKeyOf(const DILexicalBlockFile
*RHS
) const {
912 return Scope
== RHS
->getRawScope() && File
== RHS
->getRawFile() &&
913 Discriminator
== RHS
->getDiscriminator();
916 unsigned getHashValue() const {
917 return hash_combine(Scope
, File
, Discriminator
);
921 template <> struct MDNodeKeyImpl
<DINamespace
> {
926 MDNodeKeyImpl(Metadata
*Scope
, MDString
*Name
, bool ExportSymbols
)
927 : Scope(Scope
), Name(Name
), ExportSymbols(ExportSymbols
) {}
928 MDNodeKeyImpl(const DINamespace
*N
)
929 : Scope(N
->getRawScope()), Name(N
->getRawName()),
930 ExportSymbols(N
->getExportSymbols()) {}
932 bool isKeyOf(const DINamespace
*RHS
) const {
933 return Scope
== RHS
->getRawScope() && Name
== RHS
->getRawName() &&
934 ExportSymbols
== RHS
->getExportSymbols();
937 unsigned getHashValue() const { return hash_combine(Scope
, Name
); }
940 template <> struct MDNodeKeyImpl
<DICommonBlock
> {
947 MDNodeKeyImpl(Metadata
*Scope
, Metadata
*Decl
, MDString
*Name
, Metadata
*File
,
949 : Scope(Scope
), Decl(Decl
), Name(Name
), File(File
), LineNo(LineNo
) {}
950 MDNodeKeyImpl(const DICommonBlock
*N
)
951 : Scope(N
->getRawScope()), Decl(N
->getRawDecl()), Name(N
->getRawName()),
952 File(N
->getRawFile()), LineNo(N
->getLineNo()) {}
954 bool isKeyOf(const DICommonBlock
*RHS
) const {
955 return Scope
== RHS
->getRawScope() && Decl
== RHS
->getRawDecl() &&
956 Name
== RHS
->getRawName() && File
== RHS
->getRawFile() &&
957 LineNo
== RHS
->getLineNo();
960 unsigned getHashValue() const {
961 return hash_combine(Scope
, Decl
, Name
, File
, LineNo
);
965 template <> struct MDNodeKeyImpl
<DIModule
> {
969 MDString
*ConfigurationMacros
;
970 MDString
*IncludePath
;
971 MDString
*APINotesFile
;
975 MDNodeKeyImpl(Metadata
*File
, Metadata
*Scope
, MDString
*Name
,
976 MDString
*ConfigurationMacros
, MDString
*IncludePath
,
977 MDString
*APINotesFile
, unsigned LineNo
, bool IsDecl
)
978 : File(File
), Scope(Scope
), Name(Name
),
979 ConfigurationMacros(ConfigurationMacros
), IncludePath(IncludePath
),
980 APINotesFile(APINotesFile
), LineNo(LineNo
), IsDecl(IsDecl
) {}
981 MDNodeKeyImpl(const DIModule
*N
)
982 : File(N
->getRawFile()), Scope(N
->getRawScope()), Name(N
->getRawName()),
983 ConfigurationMacros(N
->getRawConfigurationMacros()),
984 IncludePath(N
->getRawIncludePath()),
985 APINotesFile(N
->getRawAPINotesFile()), LineNo(N
->getLineNo()),
986 IsDecl(N
->getIsDecl()) {}
988 bool isKeyOf(const DIModule
*RHS
) const {
989 return Scope
== RHS
->getRawScope() && Name
== RHS
->getRawName() &&
990 ConfigurationMacros
== RHS
->getRawConfigurationMacros() &&
991 IncludePath
== RHS
->getRawIncludePath() &&
992 APINotesFile
== RHS
->getRawAPINotesFile() &&
993 File
== RHS
->getRawFile() && LineNo
== RHS
->getLineNo() &&
994 IsDecl
== RHS
->getIsDecl();
997 unsigned getHashValue() const {
998 return hash_combine(Scope
, Name
, ConfigurationMacros
, IncludePath
);
1002 template <> struct MDNodeKeyImpl
<DITemplateTypeParameter
> {
1007 MDNodeKeyImpl(MDString
*Name
, Metadata
*Type
, bool IsDefault
)
1008 : Name(Name
), Type(Type
), IsDefault(IsDefault
) {}
1009 MDNodeKeyImpl(const DITemplateTypeParameter
*N
)
1010 : Name(N
->getRawName()), Type(N
->getRawType()),
1011 IsDefault(N
->isDefault()) {}
1013 bool isKeyOf(const DITemplateTypeParameter
*RHS
) const {
1014 return Name
== RHS
->getRawName() && Type
== RHS
->getRawType() &&
1015 IsDefault
== RHS
->isDefault();
1018 unsigned getHashValue() const { return hash_combine(Name
, Type
, IsDefault
); }
1021 template <> struct MDNodeKeyImpl
<DITemplateValueParameter
> {
1028 MDNodeKeyImpl(unsigned Tag
, MDString
*Name
, Metadata
*Type
, bool IsDefault
,
1030 : Tag(Tag
), Name(Name
), Type(Type
), IsDefault(IsDefault
), Value(Value
) {}
1031 MDNodeKeyImpl(const DITemplateValueParameter
*N
)
1032 : Tag(N
->getTag()), Name(N
->getRawName()), Type(N
->getRawType()),
1033 IsDefault(N
->isDefault()), Value(N
->getValue()) {}
1035 bool isKeyOf(const DITemplateValueParameter
*RHS
) const {
1036 return Tag
== RHS
->getTag() && Name
== RHS
->getRawName() &&
1037 Type
== RHS
->getRawType() && IsDefault
== RHS
->isDefault() &&
1038 Value
== RHS
->getValue();
1041 unsigned getHashValue() const {
1042 return hash_combine(Tag
, Name
, Type
, IsDefault
, Value
);
1046 template <> struct MDNodeKeyImpl
<DIGlobalVariable
> {
1049 MDString
*LinkageName
;
1055 Metadata
*StaticDataMemberDeclaration
;
1056 Metadata
*TemplateParams
;
1057 uint32_t AlignInBits
;
1058 Metadata
*Annotations
;
1060 MDNodeKeyImpl(Metadata
*Scope
, MDString
*Name
, MDString
*LinkageName
,
1061 Metadata
*File
, unsigned Line
, Metadata
*Type
,
1062 bool IsLocalToUnit
, bool IsDefinition
,
1063 Metadata
*StaticDataMemberDeclaration
, Metadata
*TemplateParams
,
1064 uint32_t AlignInBits
, Metadata
*Annotations
)
1065 : Scope(Scope
), Name(Name
), LinkageName(LinkageName
), File(File
),
1066 Line(Line
), Type(Type
), IsLocalToUnit(IsLocalToUnit
),
1067 IsDefinition(IsDefinition
),
1068 StaticDataMemberDeclaration(StaticDataMemberDeclaration
),
1069 TemplateParams(TemplateParams
), AlignInBits(AlignInBits
),
1070 Annotations(Annotations
) {}
1071 MDNodeKeyImpl(const DIGlobalVariable
*N
)
1072 : Scope(N
->getRawScope()), Name(N
->getRawName()),
1073 LinkageName(N
->getRawLinkageName()), File(N
->getRawFile()),
1074 Line(N
->getLine()), Type(N
->getRawType()),
1075 IsLocalToUnit(N
->isLocalToUnit()), IsDefinition(N
->isDefinition()),
1076 StaticDataMemberDeclaration(N
->getRawStaticDataMemberDeclaration()),
1077 TemplateParams(N
->getRawTemplateParams()),
1078 AlignInBits(N
->getAlignInBits()), Annotations(N
->getRawAnnotations()) {}
1080 bool isKeyOf(const DIGlobalVariable
*RHS
) const {
1081 return Scope
== RHS
->getRawScope() && Name
== RHS
->getRawName() &&
1082 LinkageName
== RHS
->getRawLinkageName() &&
1083 File
== RHS
->getRawFile() && Line
== RHS
->getLine() &&
1084 Type
== RHS
->getRawType() && IsLocalToUnit
== RHS
->isLocalToUnit() &&
1085 IsDefinition
== RHS
->isDefinition() &&
1086 StaticDataMemberDeclaration
==
1087 RHS
->getRawStaticDataMemberDeclaration() &&
1088 TemplateParams
== RHS
->getRawTemplateParams() &&
1089 AlignInBits
== RHS
->getAlignInBits() &&
1090 Annotations
== RHS
->getRawAnnotations();
1093 unsigned getHashValue() const {
1094 // We do not use AlignInBits in hashing function here on purpose:
1095 // in most cases this param for local variable is zero (for function param
1096 // it is always zero). This leads to lots of hash collisions and errors on
1097 // cases with lots of similar variables.
1098 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1099 // generated IR is random for each run and test fails with Align included.
1100 // TODO: make hashing work fine with such situations
1101 return hash_combine(Scope
, Name
, LinkageName
, File
, Line
, Type
,
1102 IsLocalToUnit
, IsDefinition
, /* AlignInBits, */
1103 StaticDataMemberDeclaration
, Annotations
);
1107 template <> struct MDNodeKeyImpl
<DILocalVariable
> {
1115 uint32_t AlignInBits
;
1116 Metadata
*Annotations
;
1118 MDNodeKeyImpl(Metadata
*Scope
, MDString
*Name
, Metadata
*File
, unsigned Line
,
1119 Metadata
*Type
, unsigned Arg
, unsigned Flags
,
1120 uint32_t AlignInBits
, Metadata
*Annotations
)
1121 : Scope(Scope
), Name(Name
), File(File
), Line(Line
), Type(Type
), Arg(Arg
),
1122 Flags(Flags
), AlignInBits(AlignInBits
), Annotations(Annotations
) {}
1123 MDNodeKeyImpl(const DILocalVariable
*N
)
1124 : Scope(N
->getRawScope()), Name(N
->getRawName()), File(N
->getRawFile()),
1125 Line(N
->getLine()), Type(N
->getRawType()), Arg(N
->getArg()),
1126 Flags(N
->getFlags()), AlignInBits(N
->getAlignInBits()),
1127 Annotations(N
->getRawAnnotations()) {}
1129 bool isKeyOf(const DILocalVariable
*RHS
) const {
1130 return Scope
== RHS
->getRawScope() && Name
== RHS
->getRawName() &&
1131 File
== RHS
->getRawFile() && Line
== RHS
->getLine() &&
1132 Type
== RHS
->getRawType() && Arg
== RHS
->getArg() &&
1133 Flags
== RHS
->getFlags() && AlignInBits
== RHS
->getAlignInBits() &&
1134 Annotations
== RHS
->getRawAnnotations();
1137 unsigned getHashValue() const {
1138 // We do not use AlignInBits in hashing function here on purpose:
1139 // in most cases this param for local variable is zero (for function param
1140 // it is always zero). This leads to lots of hash collisions and errors on
1141 // cases with lots of similar variables.
1142 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1143 // generated IR is random for each run and test fails with Align included.
1144 // TODO: make hashing work fine with such situations
1145 return hash_combine(Scope
, Name
, File
, Line
, Type
, Arg
, Flags
, Annotations
);
1149 template <> struct MDNodeKeyImpl
<DILabel
> {
1155 MDNodeKeyImpl(Metadata
*Scope
, MDString
*Name
, Metadata
*File
, unsigned Line
)
1156 : Scope(Scope
), Name(Name
), File(File
), Line(Line
) {}
1157 MDNodeKeyImpl(const DILabel
*N
)
1158 : Scope(N
->getRawScope()), Name(N
->getRawName()), File(N
->getRawFile()),
1159 Line(N
->getLine()) {}
1161 bool isKeyOf(const DILabel
*RHS
) const {
1162 return Scope
== RHS
->getRawScope() && Name
== RHS
->getRawName() &&
1163 File
== RHS
->getRawFile() && Line
== RHS
->getLine();
1166 /// Using name and line to get hash value. It should already be mostly unique.
1167 unsigned getHashValue() const { return hash_combine(Scope
, Name
, Line
); }
1170 template <> struct MDNodeKeyImpl
<DIExpression
> {
1171 ArrayRef
<uint64_t> Elements
;
1173 MDNodeKeyImpl(ArrayRef
<uint64_t> Elements
) : Elements(Elements
) {}
1174 MDNodeKeyImpl(const DIExpression
*N
) : Elements(N
->getElements()) {}
1176 bool isKeyOf(const DIExpression
*RHS
) const {
1177 return Elements
== RHS
->getElements();
1180 unsigned getHashValue() const {
1181 return hash_combine_range(Elements
.begin(), Elements
.end());
1185 template <> struct MDNodeKeyImpl
<DIGlobalVariableExpression
> {
1187 Metadata
*Expression
;
1189 MDNodeKeyImpl(Metadata
*Variable
, Metadata
*Expression
)
1190 : Variable(Variable
), Expression(Expression
) {}
1191 MDNodeKeyImpl(const DIGlobalVariableExpression
*N
)
1192 : Variable(N
->getRawVariable()), Expression(N
->getRawExpression()) {}
1194 bool isKeyOf(const DIGlobalVariableExpression
*RHS
) const {
1195 return Variable
== RHS
->getRawVariable() &&
1196 Expression
== RHS
->getRawExpression();
1199 unsigned getHashValue() const { return hash_combine(Variable
, Expression
); }
1202 template <> struct MDNodeKeyImpl
<DIObjCProperty
> {
1206 MDString
*GetterName
;
1207 MDString
*SetterName
;
1208 unsigned Attributes
;
1211 MDNodeKeyImpl(MDString
*Name
, Metadata
*File
, unsigned Line
,
1212 MDString
*GetterName
, MDString
*SetterName
, unsigned Attributes
,
1214 : Name(Name
), File(File
), Line(Line
), GetterName(GetterName
),
1215 SetterName(SetterName
), Attributes(Attributes
), Type(Type
) {}
1216 MDNodeKeyImpl(const DIObjCProperty
*N
)
1217 : Name(N
->getRawName()), File(N
->getRawFile()), Line(N
->getLine()),
1218 GetterName(N
->getRawGetterName()), SetterName(N
->getRawSetterName()),
1219 Attributes(N
->getAttributes()), Type(N
->getRawType()) {}
1221 bool isKeyOf(const DIObjCProperty
*RHS
) const {
1222 return Name
== RHS
->getRawName() && File
== RHS
->getRawFile() &&
1223 Line
== RHS
->getLine() && GetterName
== RHS
->getRawGetterName() &&
1224 SetterName
== RHS
->getRawSetterName() &&
1225 Attributes
== RHS
->getAttributes() && Type
== RHS
->getRawType();
1228 unsigned getHashValue() const {
1229 return hash_combine(Name
, File
, Line
, GetterName
, SetterName
, Attributes
,
1234 template <> struct MDNodeKeyImpl
<DIImportedEntity
> {
1243 MDNodeKeyImpl(unsigned Tag
, Metadata
*Scope
, Metadata
*Entity
, Metadata
*File
,
1244 unsigned Line
, MDString
*Name
, Metadata
*Elements
)
1245 : Tag(Tag
), Scope(Scope
), Entity(Entity
), File(File
), Line(Line
),
1246 Name(Name
), Elements(Elements
) {}
1247 MDNodeKeyImpl(const DIImportedEntity
*N
)
1248 : Tag(N
->getTag()), Scope(N
->getRawScope()), Entity(N
->getRawEntity()),
1249 File(N
->getRawFile()), Line(N
->getLine()), Name(N
->getRawName()),
1250 Elements(N
->getRawElements()) {}
1252 bool isKeyOf(const DIImportedEntity
*RHS
) const {
1253 return Tag
== RHS
->getTag() && Scope
== RHS
->getRawScope() &&
1254 Entity
== RHS
->getRawEntity() && File
== RHS
->getFile() &&
1255 Line
== RHS
->getLine() && Name
== RHS
->getRawName() &&
1256 Elements
== RHS
->getRawElements();
1259 unsigned getHashValue() const {
1260 return hash_combine(Tag
, Scope
, Entity
, File
, Line
, Name
, Elements
);
1264 template <> struct MDNodeKeyImpl
<DIMacro
> {
1270 MDNodeKeyImpl(unsigned MIType
, unsigned Line
, MDString
*Name
, MDString
*Value
)
1271 : MIType(MIType
), Line(Line
), Name(Name
), Value(Value
) {}
1272 MDNodeKeyImpl(const DIMacro
*N
)
1273 : MIType(N
->getMacinfoType()), Line(N
->getLine()), Name(N
->getRawName()),
1274 Value(N
->getRawValue()) {}
1276 bool isKeyOf(const DIMacro
*RHS
) const {
1277 return MIType
== RHS
->getMacinfoType() && Line
== RHS
->getLine() &&
1278 Name
== RHS
->getRawName() && Value
== RHS
->getRawValue();
1281 unsigned getHashValue() const {
1282 return hash_combine(MIType
, Line
, Name
, Value
);
1286 template <> struct MDNodeKeyImpl
<DIMacroFile
> {
1292 MDNodeKeyImpl(unsigned MIType
, unsigned Line
, Metadata
*File
,
1294 : MIType(MIType
), Line(Line
), File(File
), Elements(Elements
) {}
1295 MDNodeKeyImpl(const DIMacroFile
*N
)
1296 : MIType(N
->getMacinfoType()), Line(N
->getLine()), File(N
->getRawFile()),
1297 Elements(N
->getRawElements()) {}
1299 bool isKeyOf(const DIMacroFile
*RHS
) const {
1300 return MIType
== RHS
->getMacinfoType() && Line
== RHS
->getLine() &&
1301 File
== RHS
->getRawFile() && Elements
== RHS
->getRawElements();
1304 unsigned getHashValue() const {
1305 return hash_combine(MIType
, Line
, File
, Elements
);
1309 // DIArgLists are not MDNodes, but we still want to unique them in a DenseSet
1310 // based on a hash of their arguments.
1311 struct DIArgListKeyInfo
{
1312 ArrayRef
<ValueAsMetadata
*> Args
;
1314 DIArgListKeyInfo(ArrayRef
<ValueAsMetadata
*> Args
) : Args(Args
) {}
1315 DIArgListKeyInfo(const DIArgList
*N
) : Args(N
->getArgs()) {}
1317 bool isKeyOf(const DIArgList
*RHS
) const { return Args
== RHS
->getArgs(); }
1319 unsigned getHashValue() const {
1320 return hash_combine_range(Args
.begin(), Args
.end());
1324 /// DenseMapInfo for DIArgList.
1325 struct DIArgListInfo
{
1326 using KeyTy
= DIArgListKeyInfo
;
1328 static inline DIArgList
*getEmptyKey() {
1329 return DenseMapInfo
<DIArgList
*>::getEmptyKey();
1332 static inline DIArgList
*getTombstoneKey() {
1333 return DenseMapInfo
<DIArgList
*>::getTombstoneKey();
1336 static unsigned getHashValue(const KeyTy
&Key
) { return Key
.getHashValue(); }
1338 static unsigned getHashValue(const DIArgList
*N
) {
1339 return KeyTy(N
).getHashValue();
1342 static bool isEqual(const KeyTy
&LHS
, const DIArgList
*RHS
) {
1343 if (RHS
== getEmptyKey() || RHS
== getTombstoneKey())
1345 return LHS
.isKeyOf(RHS
);
1348 static bool isEqual(const DIArgList
*LHS
, const DIArgList
*RHS
) {
1353 /// DenseMapInfo for MDNode subclasses.
1354 template <class NodeTy
> struct MDNodeInfo
{
1355 using KeyTy
= MDNodeKeyImpl
<NodeTy
>;
1356 using SubsetEqualTy
= MDNodeSubsetEqualImpl
<NodeTy
>;
1358 static inline NodeTy
*getEmptyKey() {
1359 return DenseMapInfo
<NodeTy
*>::getEmptyKey();
1362 static inline NodeTy
*getTombstoneKey() {
1363 return DenseMapInfo
<NodeTy
*>::getTombstoneKey();
1366 static unsigned getHashValue(const KeyTy
&Key
) { return Key
.getHashValue(); }
1368 static unsigned getHashValue(const NodeTy
*N
) {
1369 return KeyTy(N
).getHashValue();
1372 static bool isEqual(const KeyTy
&LHS
, const NodeTy
*RHS
) {
1373 if (RHS
== getEmptyKey() || RHS
== getTombstoneKey())
1375 return SubsetEqualTy::isSubsetEqual(LHS
, RHS
) || LHS
.isKeyOf(RHS
);
1378 static bool isEqual(const NodeTy
*LHS
, const NodeTy
*RHS
) {
1381 if (RHS
== getEmptyKey() || RHS
== getTombstoneKey())
1383 return SubsetEqualTy::isSubsetEqual(LHS
, RHS
);
1387 #define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>;
1388 #include "llvm/IR/Metadata.def"
1390 /// Multimap-like storage for metadata attachments.
1391 class MDAttachments
{
1395 TrackingMDNodeRef Node
;
1399 SmallVector
<Attachment
, 1> Attachments
;
1402 bool empty() const { return Attachments
.empty(); }
1403 size_t size() const { return Attachments
.size(); }
1405 /// Returns the first attachment with the given ID or nullptr if no such
1406 /// attachment exists.
1407 MDNode
*lookup(unsigned ID
) const;
1409 /// Appends all attachments with the given ID to \c Result in insertion order.
1410 /// If the global has no attachments with the given ID, or if ID is invalid,
1411 /// leaves Result unchanged.
1412 void get(unsigned ID
, SmallVectorImpl
<MDNode
*> &Result
) const;
1414 /// Appends all attachments for the global to \c Result, sorting by attachment
1415 /// ID. Attachments with the same ID appear in insertion order. This function
1416 /// does \em not clear \c Result.
1417 void getAll(SmallVectorImpl
<std::pair
<unsigned, MDNode
*>> &Result
) const;
1419 /// Set an attachment to a particular node.
1421 /// Set the \c ID attachment to \c MD, replacing the current attachments at \c
1423 void set(unsigned ID
, MDNode
*MD
);
1425 /// Adds an attachment to a particular node.
1426 void insert(unsigned ID
, MDNode
&MD
);
1428 /// Remove attachments with the given ID.
1430 /// Remove the attachments at \c ID, if any.
1431 bool erase(unsigned ID
);
1433 /// Erase matching attachments.
1435 /// Erases all attachments matching the \c shouldRemove predicate.
1436 template <class PredTy
> void remove_if(PredTy shouldRemove
) {
1437 llvm::erase_if(Attachments
, shouldRemove
);
1441 class LLVMContextImpl
{
1443 /// OwnedModules - The set of modules instantiated in this context, and which
1444 /// will be automatically deleted if this context is deleted.
1445 SmallPtrSet
<Module
*, 4> OwnedModules
;
1447 /// The main remark streamer used by all the other streamers (e.g. IR, MIR,
1448 /// frontends, etc.). This should only be used by the specific streamers, and
1450 std::unique_ptr
<remarks::RemarkStreamer
> MainRemarkStreamer
;
1452 std::unique_ptr
<DiagnosticHandler
> DiagHandler
;
1453 bool RespectDiagnosticFilters
= false;
1454 bool DiagnosticsHotnessRequested
= false;
1455 /// The minimum hotness value a diagnostic needs in order to be included in
1456 /// optimization diagnostics.
1458 /// The threshold is an Optional value, which maps to one of the 3 states:
1459 /// 1). 0 => threshold disabled. All emarks will be printed.
1460 /// 2). positive int => manual threshold by user. Remarks with hotness exceed
1461 /// threshold will be printed.
1462 /// 3). None => 'auto' threshold by user. The actual value is not
1463 /// available at command line, but will be synced with
1464 /// hotness threhold from profile summary during
1467 /// State 1 and 2 are considered as terminal states. State transition is
1468 /// only allowed from 3 to 2, when the threshold is first synced with profile
1469 /// summary. This ensures that the threshold is set only once and stays
1472 /// If threshold option is not specified, it is disabled (0) by default.
1473 std::optional
<uint64_t> DiagnosticsHotnessThreshold
= 0;
1475 /// The percentage of difference between profiling branch weights and
1476 /// llvm.expect branch weights to tolerate when emiting MisExpect diagnostics
1477 std::optional
<uint32_t> DiagnosticsMisExpectTolerance
= 0;
1478 bool MisExpectWarningRequested
= false;
1480 /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
1481 std::unique_ptr
<LLVMRemarkStreamer
> LLVMRS
;
1483 LLVMContext::YieldCallbackTy YieldCallback
= nullptr;
1484 void *YieldOpaqueHandle
= nullptr;
1486 DenseMap
<const Value
*, ValueName
*> ValueNames
;
1488 DenseMap
<unsigned, std::unique_ptr
<ConstantInt
>> IntZeroConstants
;
1489 DenseMap
<unsigned, std::unique_ptr
<ConstantInt
>> IntOneConstants
;
1490 DenseMap
<APInt
, std::unique_ptr
<ConstantInt
>> IntConstants
;
1492 DenseMap
<APFloat
, std::unique_ptr
<ConstantFP
>> FPConstants
;
1494 FoldingSet
<AttributeImpl
> AttrsSet
;
1495 FoldingSet
<AttributeListImpl
> AttrsLists
;
1496 FoldingSet
<AttributeSetNode
> AttrsSetNodes
;
1498 StringMap
<MDString
, BumpPtrAllocator
> MDStringCache
;
1499 DenseMap
<Value
*, ValueAsMetadata
*> ValuesAsMetadata
;
1500 DenseMap
<Metadata
*, MetadataAsValue
*> MetadataAsValues
;
1501 DenseSet
<DIArgList
*, DIArgListInfo
> DIArgLists
;
1503 #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
1504 DenseSet<CLASS *, CLASS##Info> CLASS##s;
1505 #include "llvm/IR/Metadata.def"
1507 // Optional map for looking up composite types by identifier.
1508 std::optional
<DenseMap
<const MDString
*, DICompositeType
*>> DITypeMap
;
1510 // MDNodes may be uniqued or not uniqued. When they're not uniqued, they
1511 // aren't in the MDNodeSet, but they're still shared between objects, so no
1512 // one object can destroy them. Keep track of them here so we can delete
1513 // them on context teardown.
1514 std::vector
<MDNode
*> DistinctMDNodes
;
1516 DenseMap
<Type
*, std::unique_ptr
<ConstantAggregateZero
>> CAZConstants
;
1518 using ArrayConstantsTy
= ConstantUniqueMap
<ConstantArray
>;
1519 ArrayConstantsTy ArrayConstants
;
1521 using StructConstantsTy
= ConstantUniqueMap
<ConstantStruct
>;
1522 StructConstantsTy StructConstants
;
1524 using VectorConstantsTy
= ConstantUniqueMap
<ConstantVector
>;
1525 VectorConstantsTy VectorConstants
;
1527 DenseMap
<PointerType
*, std::unique_ptr
<ConstantPointerNull
>> CPNConstants
;
1529 DenseMap
<TargetExtType
*, std::unique_ptr
<ConstantTargetNone
>> CTNConstants
;
1531 DenseMap
<Type
*, std::unique_ptr
<UndefValue
>> UVConstants
;
1533 DenseMap
<Type
*, std::unique_ptr
<PoisonValue
>> PVConstants
;
1535 StringMap
<std::unique_ptr
<ConstantDataSequential
>> CDSConstants
;
1537 DenseMap
<std::pair
<const Function
*, const BasicBlock
*>, BlockAddress
*>
1540 DenseMap
<const GlobalValue
*, DSOLocalEquivalent
*> DSOLocalEquivalents
;
1542 DenseMap
<const GlobalValue
*, NoCFIValue
*> NoCFIValues
;
1544 ConstantUniqueMap
<ConstantExpr
> ExprConstants
;
1546 ConstantUniqueMap
<InlineAsm
> InlineAsms
;
1548 ConstantInt
*TheTrueVal
= nullptr;
1549 ConstantInt
*TheFalseVal
= nullptr;
1551 // Basic type instances.
1552 Type VoidTy
, LabelTy
, HalfTy
, BFloatTy
, FloatTy
, DoubleTy
, MetadataTy
,
1554 Type X86_FP80Ty
, FP128Ty
, PPC_FP128Ty
, X86_MMXTy
, X86_AMXTy
;
1555 IntegerType Int1Ty
, Int8Ty
, Int16Ty
, Int32Ty
, Int64Ty
, Int128Ty
;
1557 std::unique_ptr
<ConstantTokenNone
> TheNoneToken
;
1559 BumpPtrAllocator Alloc
;
1560 UniqueStringSaver Saver
{Alloc
};
1562 DenseMap
<unsigned, IntegerType
*> IntegerTypes
;
1564 using FunctionTypeSet
= DenseSet
<FunctionType
*, FunctionTypeKeyInfo
>;
1565 FunctionTypeSet FunctionTypes
;
1566 using StructTypeSet
= DenseSet
<StructType
*, AnonStructTypeKeyInfo
>;
1567 StructTypeSet AnonStructTypes
;
1568 StringMap
<StructType
*> NamedStructTypes
;
1569 unsigned NamedStructTypesUniqueID
= 0;
1571 using TargetExtTypeSet
= DenseSet
<TargetExtType
*, TargetExtTypeKeyInfo
>;
1572 TargetExtTypeSet TargetExtTypes
;
1574 DenseMap
<std::pair
<Type
*, uint64_t>, ArrayType
*> ArrayTypes
;
1575 DenseMap
<std::pair
<Type
*, ElementCount
>, VectorType
*> VectorTypes
;
1576 PointerType
*AS0PointerType
= nullptr; // AddrSpace = 0
1577 DenseMap
<unsigned, PointerType
*> PointerTypes
;
1578 DenseMap
<std::pair
<Type
*, unsigned>, PointerType
*> LegacyPointerTypes
;
1579 DenseMap
<std::pair
<Type
*, unsigned>, TypedPointerType
*> ASTypedPointerTypes
;
1581 /// ValueHandles - This map keeps track of all of the value handles that are
1582 /// watching a Value*. The Value::HasValueHandle bit is used to know
1583 /// whether or not a value has an entry in this map.
1584 using ValueHandlesTy
= DenseMap
<Value
*, ValueHandleBase
*>;
1585 ValueHandlesTy ValueHandles
;
1587 /// CustomMDKindNames - Map to hold the metadata string to ID mapping.
1588 StringMap
<unsigned> CustomMDKindNames
;
1590 /// Collection of metadata used in this context.
1591 DenseMap
<const Value
*, MDAttachments
> ValueMetadata
;
1593 /// Map DIAssignID -> Instructions with that attachment.
1594 /// Managed by Instruction via Instruction::updateDIAssignIDMapping.
1595 /// Query using the at:: functions defined in DebugInfo.h.
1596 DenseMap
<DIAssignID
*, SmallVector
<Instruction
*, 1>> AssignmentIDToInstrs
;
1598 /// Collection of per-GlobalObject sections used in this context.
1599 DenseMap
<const GlobalObject
*, StringRef
> GlobalObjectSections
;
1601 /// Collection of per-GlobalValue partitions used in this context.
1602 DenseMap
<const GlobalValue
*, StringRef
> GlobalValuePartitions
;
1604 DenseMap
<const GlobalValue
*, GlobalValue::SanitizerMetadata
>
1605 GlobalValueSanitizerMetadata
;
1607 /// DiscriminatorTable - This table maps file:line locations to an
1608 /// integer representing the next DWARF path discriminator to assign to
1609 /// instructions in different blocks at the same location.
1610 DenseMap
<std::pair
<const char *, unsigned>, unsigned> DiscriminatorTable
;
1612 /// A set of interned tags for operand bundles. The StringMap maps
1613 /// bundle tags to their IDs.
1615 /// \see LLVMContext::getOperandBundleTagID
1616 StringMap
<uint32_t> BundleTagCache
;
1618 StringMapEntry
<uint32_t> *getOrInsertBundleTag(StringRef Tag
);
1619 void getOperandBundleTags(SmallVectorImpl
<StringRef
> &Tags
) const;
1620 uint32_t getOperandBundleTagID(StringRef Tag
) const;
1622 /// A set of interned synchronization scopes. The StringMap maps
1623 /// synchronization scope names to their respective synchronization scope IDs.
1624 StringMap
<SyncScope::ID
> SSC
;
1626 /// getOrInsertSyncScopeID - Maps synchronization scope name to
1627 /// synchronization scope ID. Every synchronization scope registered with
1628 /// LLVMContext has unique ID except pre-defined ones.
1629 SyncScope::ID
getOrInsertSyncScopeID(StringRef SSN
);
1631 /// getSyncScopeNames - Populates client supplied SmallVector with
1632 /// synchronization scope names registered with LLVMContext. Synchronization
1633 /// scope names are ordered by increasing synchronization scope IDs.
1634 void getSyncScopeNames(SmallVectorImpl
<StringRef
> &SSNs
) const;
1636 /// Maintain the GC name for each function.
1638 /// This saves allocating an additional word in Function for programs which
1639 /// do not use GC (i.e., most programs) at the cost of increased overhead for
1640 /// clients which do use GC.
1641 DenseMap
<const Function
*, std::string
> GCNames
;
1643 /// Flag to indicate if Value (other than GlobalValue) retains their name or
1645 bool DiscardValueNames
= false;
1647 LLVMContextImpl(LLVMContext
&C
);
1650 /// Destroy the ConstantArrays if they are not used.
1651 void dropTriviallyDeadConstantArrays();
1653 mutable OptPassGate
*OPG
= nullptr;
1655 /// Access the object which can disable optional passes and individual
1656 /// optimizations at compile time.
1657 OptPassGate
&getOptPassGate() const;
1659 /// Set the object which can disable optional passes and individual
1660 /// optimizations at compile time.
1662 /// The lifetime of the object must be guaranteed to extend as long as the
1663 /// LLVMContext is used by compilation.
1664 void setOptPassGate(OptPassGate
&);
1666 /// Mapping of blocks to collections of "trailing" DPValues. As part of the
1667 /// "RemoveDIs" project, debug-info variable location records are going to
1668 /// cease being instructions... which raises the problem of where should they
1669 /// be recorded when we remove the terminator of a blocks, such as:
1671 /// %foo = add i32 0, 0
1674 /// If the branch is removed, a legitimate transient state while editing a
1675 /// block, any debug-records between those two instructions will not have a
1676 /// location. Each block thus records any DPValue records that "trail" in
1677 /// such a way. These are stored in LLVMContext because typically LLVM only
1678 /// edits a small number of blocks at a time, so there's no need to bloat
1679 /// BasicBlock with such a data structure.
1680 SmallDenseMap
<BasicBlock
*, DPMarker
*> TrailingDPValues
;
1682 // Set, get and delete operations for TrailingDPValues.
1683 void setTrailingDPValues(BasicBlock
*B
, DPMarker
*M
) {
1684 assert(!TrailingDPValues
.count(B
));
1685 TrailingDPValues
[B
] = M
;
1688 DPMarker
*getTrailingDPValues(BasicBlock
*B
) {
1689 return TrailingDPValues
.lookup(B
);
1692 void deleteTrailingDPValues(BasicBlock
*B
) {
1693 TrailingDPValues
.erase(B
);
1697 } // end namespace llvm
1699 #endif // LLVM_LIB_IR_LLVMCONTEXTIMPL_H