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
;
65 class LLVMRemarkStreamer
;
70 template <typename T
> class StringMapEntry
;
72 class TypedPointerType
;
73 class ValueHandleBase
;
75 using DenseMapAPIntKeyInfo
= DenseMapInfo
<APInt
>;
77 struct DenseMapAPFloatKeyInfo
{
78 static inline APFloat
getEmptyKey() { return APFloat(APFloat::Bogus(), 1); }
79 static inline APFloat
getTombstoneKey() {
80 return APFloat(APFloat::Bogus(), 2);
83 static unsigned getHashValue(const APFloat
&Key
) {
84 return static_cast<unsigned>(hash_value(Key
));
87 static bool isEqual(const APFloat
&LHS
, const APFloat
&RHS
) {
88 return LHS
.bitwiseIsEqual(RHS
);
92 struct AnonStructTypeKeyInfo
{
94 ArrayRef
<Type
*> ETypes
;
97 KeyTy(const ArrayRef
<Type
*> &E
, bool P
) : ETypes(E
), isPacked(P
) {}
99 KeyTy(const StructType
*ST
)
100 : ETypes(ST
->elements()), isPacked(ST
->isPacked()) {}
102 bool operator==(const KeyTy
&that
) const {
103 if (isPacked
!= that
.isPacked
)
105 if (ETypes
!= that
.ETypes
)
109 bool operator!=(const KeyTy
&that
) const { return !this->operator==(that
); }
112 static inline StructType
*getEmptyKey() {
113 return DenseMapInfo
<StructType
*>::getEmptyKey();
116 static inline StructType
*getTombstoneKey() {
117 return DenseMapInfo
<StructType
*>::getTombstoneKey();
120 static unsigned getHashValue(const KeyTy
&Key
) {
122 hash_combine_range(Key
.ETypes
.begin(), Key
.ETypes
.end()), Key
.isPacked
);
125 static unsigned getHashValue(const StructType
*ST
) {
126 return getHashValue(KeyTy(ST
));
129 static bool isEqual(const KeyTy
&LHS
, const StructType
*RHS
) {
130 if (RHS
== getEmptyKey() || RHS
== getTombstoneKey())
132 return LHS
== KeyTy(RHS
);
135 static bool isEqual(const StructType
*LHS
, const StructType
*RHS
) {
140 struct FunctionTypeKeyInfo
{
142 const Type
*ReturnType
;
143 ArrayRef
<Type
*> Params
;
146 KeyTy(const Type
*R
, const ArrayRef
<Type
*> &P
, bool V
)
147 : ReturnType(R
), Params(P
), isVarArg(V
) {}
148 KeyTy(const FunctionType
*FT
)
149 : ReturnType(FT
->getReturnType()), Params(FT
->params()),
150 isVarArg(FT
->isVarArg()) {}
152 bool operator==(const KeyTy
&that
) const {
153 if (ReturnType
!= that
.ReturnType
)
155 if (isVarArg
!= that
.isVarArg
)
157 if (Params
!= that
.Params
)
161 bool operator!=(const KeyTy
&that
) const { return !this->operator==(that
); }
164 static inline FunctionType
*getEmptyKey() {
165 return DenseMapInfo
<FunctionType
*>::getEmptyKey();
168 static inline FunctionType
*getTombstoneKey() {
169 return DenseMapInfo
<FunctionType
*>::getTombstoneKey();
172 static unsigned getHashValue(const KeyTy
&Key
) {
175 hash_combine_range(Key
.Params
.begin(), Key
.Params
.end()), Key
.isVarArg
);
178 static unsigned getHashValue(const FunctionType
*FT
) {
179 return getHashValue(KeyTy(FT
));
182 static bool isEqual(const KeyTy
&LHS
, const FunctionType
*RHS
) {
183 if (RHS
== getEmptyKey() || RHS
== getTombstoneKey())
185 return LHS
== KeyTy(RHS
);
188 static bool isEqual(const FunctionType
*LHS
, const FunctionType
*RHS
) {
193 struct TargetExtTypeKeyInfo
{
196 ArrayRef
<Type
*> TypeParams
;
197 ArrayRef
<unsigned> IntParams
;
199 KeyTy(StringRef N
, const ArrayRef
<Type
*> &TP
, const ArrayRef
<unsigned> &IP
)
200 : Name(N
), TypeParams(TP
), IntParams(IP
) {}
201 KeyTy(const TargetExtType
*TT
)
202 : Name(TT
->getName()), TypeParams(TT
->type_params()),
203 IntParams(TT
->int_params()) {}
205 bool operator==(const KeyTy
&that
) const {
206 return Name
== that
.Name
&& TypeParams
== that
.TypeParams
&&
207 IntParams
== that
.IntParams
;
209 bool operator!=(const KeyTy
&that
) const { return !this->operator==(that
); }
212 static inline TargetExtType
*getEmptyKey() {
213 return DenseMapInfo
<TargetExtType
*>::getEmptyKey();
216 static inline TargetExtType
*getTombstoneKey() {
217 return DenseMapInfo
<TargetExtType
*>::getTombstoneKey();
220 static unsigned getHashValue(const KeyTy
&Key
) {
223 hash_combine_range(Key
.TypeParams
.begin(), Key
.TypeParams
.end()),
224 hash_combine_range(Key
.IntParams
.begin(), Key
.IntParams
.end()));
227 static unsigned getHashValue(const TargetExtType
*FT
) {
228 return getHashValue(KeyTy(FT
));
231 static bool isEqual(const KeyTy
&LHS
, const TargetExtType
*RHS
) {
232 if (RHS
== getEmptyKey() || RHS
== getTombstoneKey())
234 return LHS
== KeyTy(RHS
);
237 static bool isEqual(const TargetExtType
*LHS
, const TargetExtType
*RHS
) {
242 /// Structure for hashing arbitrary MDNode operands.
244 ArrayRef
<Metadata
*> RawOps
;
245 ArrayRef
<MDOperand
> Ops
;
249 MDNodeOpsKey(ArrayRef
<Metadata
*> Ops
)
250 : RawOps(Ops
), Hash(calculateHash(Ops
)) {}
252 template <class NodeTy
>
253 MDNodeOpsKey(const NodeTy
*N
, unsigned Offset
= 0)
254 : Ops(N
->op_begin() + Offset
, N
->op_end()), Hash(N
->getHash()) {}
256 template <class NodeTy
>
257 bool compareOps(const NodeTy
*RHS
, unsigned Offset
= 0) const {
258 if (getHash() != RHS
->getHash())
261 assert((RawOps
.empty() || Ops
.empty()) && "Two sets of operands?");
262 return RawOps
.empty() ? compareOps(Ops
, RHS
, Offset
)
263 : compareOps(RawOps
, RHS
, Offset
);
266 static unsigned calculateHash(MDNode
*N
, unsigned Offset
= 0);
270 static bool compareOps(ArrayRef
<T
> Ops
, const MDNode
*RHS
, unsigned Offset
) {
271 if (Ops
.size() != RHS
->getNumOperands() - Offset
)
273 return std::equal(Ops
.begin(), Ops
.end(), RHS
->op_begin() + Offset
);
276 static unsigned calculateHash(ArrayRef
<Metadata
*> Ops
);
279 unsigned getHash() const { return Hash
; }
282 template <class NodeTy
> struct MDNodeKeyImpl
;
284 /// Configuration point for MDNodeInfo::isEqual().
285 template <class NodeTy
> struct MDNodeSubsetEqualImpl
{
286 using KeyTy
= MDNodeKeyImpl
<NodeTy
>;
288 static bool isSubsetEqual(const KeyTy
&LHS
, const NodeTy
*RHS
) {
292 static bool isSubsetEqual(const NodeTy
*LHS
, const NodeTy
*RHS
) {
297 /// DenseMapInfo for MDTuple.
299 /// Note that we don't need the is-function-local bit, since that's implicit in
301 template <> struct MDNodeKeyImpl
<MDTuple
> : MDNodeOpsKey
{
302 MDNodeKeyImpl(ArrayRef
<Metadata
*> Ops
) : MDNodeOpsKey(Ops
) {}
303 MDNodeKeyImpl(const MDTuple
*N
) : MDNodeOpsKey(N
) {}
305 bool isKeyOf(const MDTuple
*RHS
) const { return compareOps(RHS
); }
307 unsigned getHashValue() const { return getHash(); }
309 static unsigned calculateHash(MDTuple
*N
) {
310 return MDNodeOpsKey::calculateHash(N
);
314 /// DenseMapInfo for DILocation.
315 template <> struct MDNodeKeyImpl
<DILocation
> {
322 MDNodeKeyImpl(unsigned Line
, unsigned Column
, Metadata
*Scope
,
323 Metadata
*InlinedAt
, bool ImplicitCode
)
324 : Line(Line
), Column(Column
), Scope(Scope
), InlinedAt(InlinedAt
),
325 ImplicitCode(ImplicitCode
) {}
326 MDNodeKeyImpl(const DILocation
*L
)
327 : Line(L
->getLine()), Column(L
->getColumn()), Scope(L
->getRawScope()),
328 InlinedAt(L
->getRawInlinedAt()), ImplicitCode(L
->isImplicitCode()) {}
330 bool isKeyOf(const DILocation
*RHS
) const {
331 return Line
== RHS
->getLine() && Column
== RHS
->getColumn() &&
332 Scope
== RHS
->getRawScope() && InlinedAt
== RHS
->getRawInlinedAt() &&
333 ImplicitCode
== RHS
->isImplicitCode();
336 unsigned getHashValue() const {
337 return hash_combine(Line
, Column
, Scope
, InlinedAt
, ImplicitCode
);
341 /// DenseMapInfo for GenericDINode.
342 template <> struct MDNodeKeyImpl
<GenericDINode
> : MDNodeOpsKey
{
346 MDNodeKeyImpl(unsigned Tag
, MDString
*Header
, ArrayRef
<Metadata
*> DwarfOps
)
347 : MDNodeOpsKey(DwarfOps
), Tag(Tag
), Header(Header
) {}
348 MDNodeKeyImpl(const GenericDINode
*N
)
349 : MDNodeOpsKey(N
, 1), Tag(N
->getTag()), Header(N
->getRawHeader()) {}
351 bool isKeyOf(const GenericDINode
*RHS
) const {
352 return Tag
== RHS
->getTag() && Header
== RHS
->getRawHeader() &&
356 unsigned getHashValue() const { return hash_combine(getHash(), Tag
, Header
); }
358 static unsigned calculateHash(GenericDINode
*N
) {
359 return MDNodeOpsKey::calculateHash(N
, 1);
363 template <> struct MDNodeKeyImpl
<DISubrange
> {
365 Metadata
*LowerBound
;
366 Metadata
*UpperBound
;
369 MDNodeKeyImpl(Metadata
*CountNode
, Metadata
*LowerBound
, Metadata
*UpperBound
,
371 : CountNode(CountNode
), LowerBound(LowerBound
), UpperBound(UpperBound
),
373 MDNodeKeyImpl(const DISubrange
*N
)
374 : CountNode(N
->getRawCountNode()), LowerBound(N
->getRawLowerBound()),
375 UpperBound(N
->getRawUpperBound()), Stride(N
->getRawStride()) {}
377 bool isKeyOf(const DISubrange
*RHS
) const {
378 auto BoundsEqual
= [=](Metadata
*Node1
, Metadata
*Node2
) -> bool {
382 ConstantAsMetadata
*MD1
= dyn_cast_or_null
<ConstantAsMetadata
>(Node1
);
383 ConstantAsMetadata
*MD2
= dyn_cast_or_null
<ConstantAsMetadata
>(Node2
);
385 ConstantInt
*CV1
= cast
<ConstantInt
>(MD1
->getValue());
386 ConstantInt
*CV2
= cast
<ConstantInt
>(MD2
->getValue());
387 if (CV1
->getSExtValue() == CV2
->getSExtValue())
393 return BoundsEqual(CountNode
, RHS
->getRawCountNode()) &&
394 BoundsEqual(LowerBound
, RHS
->getRawLowerBound()) &&
395 BoundsEqual(UpperBound
, RHS
->getRawUpperBound()) &&
396 BoundsEqual(Stride
, RHS
->getRawStride());
399 unsigned getHashValue() const {
401 if (auto *MD
= dyn_cast
<ConstantAsMetadata
>(CountNode
))
402 return hash_combine(cast
<ConstantInt
>(MD
->getValue())->getSExtValue(),
403 LowerBound
, UpperBound
, Stride
);
404 return hash_combine(CountNode
, LowerBound
, UpperBound
, Stride
);
408 template <> struct MDNodeKeyImpl
<DIGenericSubrange
> {
410 Metadata
*LowerBound
;
411 Metadata
*UpperBound
;
414 MDNodeKeyImpl(Metadata
*CountNode
, Metadata
*LowerBound
, Metadata
*UpperBound
,
416 : CountNode(CountNode
), LowerBound(LowerBound
), UpperBound(UpperBound
),
418 MDNodeKeyImpl(const DIGenericSubrange
*N
)
419 : CountNode(N
->getRawCountNode()), LowerBound(N
->getRawLowerBound()),
420 UpperBound(N
->getRawUpperBound()), Stride(N
->getRawStride()) {}
422 bool isKeyOf(const DIGenericSubrange
*RHS
) const {
423 return (CountNode
== RHS
->getRawCountNode()) &&
424 (LowerBound
== RHS
->getRawLowerBound()) &&
425 (UpperBound
== RHS
->getRawUpperBound()) &&
426 (Stride
== RHS
->getRawStride());
429 unsigned getHashValue() const {
430 auto *MD
= dyn_cast_or_null
<ConstantAsMetadata
>(CountNode
);
432 return hash_combine(cast
<ConstantInt
>(MD
->getValue())->getSExtValue(),
433 LowerBound
, UpperBound
, Stride
);
434 return hash_combine(CountNode
, LowerBound
, UpperBound
, Stride
);
438 template <> struct MDNodeKeyImpl
<DIEnumerator
> {
443 MDNodeKeyImpl(APInt Value
, bool IsUnsigned
, MDString
*Name
)
444 : Value(Value
), Name(Name
), IsUnsigned(IsUnsigned
) {}
445 MDNodeKeyImpl(int64_t Value
, bool IsUnsigned
, MDString
*Name
)
446 : Value(APInt(64, Value
, !IsUnsigned
)), Name(Name
),
447 IsUnsigned(IsUnsigned
) {}
448 MDNodeKeyImpl(const DIEnumerator
*N
)
449 : Value(N
->getValue()), Name(N
->getRawName()),
450 IsUnsigned(N
->isUnsigned()) {}
452 bool isKeyOf(const DIEnumerator
*RHS
) const {
453 return Value
.getBitWidth() == RHS
->getValue().getBitWidth() &&
454 Value
== RHS
->getValue() && IsUnsigned
== RHS
->isUnsigned() &&
455 Name
== RHS
->getRawName();
458 unsigned getHashValue() const { return hash_combine(Value
, Name
); }
461 template <> struct MDNodeKeyImpl
<DIBasicType
> {
465 uint32_t AlignInBits
;
469 MDNodeKeyImpl(unsigned Tag
, MDString
*Name
, uint64_t SizeInBits
,
470 uint32_t AlignInBits
, unsigned Encoding
, unsigned Flags
)
471 : Tag(Tag
), Name(Name
), SizeInBits(SizeInBits
), AlignInBits(AlignInBits
),
472 Encoding(Encoding
), Flags(Flags
) {}
473 MDNodeKeyImpl(const DIBasicType
*N
)
474 : Tag(N
->getTag()), Name(N
->getRawName()), SizeInBits(N
->getSizeInBits()),
475 AlignInBits(N
->getAlignInBits()), Encoding(N
->getEncoding()),
476 Flags(N
->getFlags()) {}
478 bool isKeyOf(const DIBasicType
*RHS
) const {
479 return Tag
== RHS
->getTag() && Name
== RHS
->getRawName() &&
480 SizeInBits
== RHS
->getSizeInBits() &&
481 AlignInBits
== RHS
->getAlignInBits() &&
482 Encoding
== RHS
->getEncoding() && Flags
== RHS
->getFlags();
485 unsigned getHashValue() const {
486 return hash_combine(Tag
, Name
, SizeInBits
, AlignInBits
, Encoding
);
490 template <> struct MDNodeKeyImpl
<DIStringType
> {
493 Metadata
*StringLength
;
494 Metadata
*StringLengthExp
;
495 Metadata
*StringLocationExp
;
497 uint32_t AlignInBits
;
500 MDNodeKeyImpl(unsigned Tag
, MDString
*Name
, Metadata
*StringLength
,
501 Metadata
*StringLengthExp
, Metadata
*StringLocationExp
,
502 uint64_t SizeInBits
, uint32_t AlignInBits
, unsigned Encoding
)
503 : Tag(Tag
), Name(Name
), StringLength(StringLength
),
504 StringLengthExp(StringLengthExp
), StringLocationExp(StringLocationExp
),
505 SizeInBits(SizeInBits
), AlignInBits(AlignInBits
), Encoding(Encoding
) {}
506 MDNodeKeyImpl(const DIStringType
*N
)
507 : Tag(N
->getTag()), Name(N
->getRawName()),
508 StringLength(N
->getRawStringLength()),
509 StringLengthExp(N
->getRawStringLengthExp()),
510 StringLocationExp(N
->getRawStringLocationExp()),
511 SizeInBits(N
->getSizeInBits()), AlignInBits(N
->getAlignInBits()),
512 Encoding(N
->getEncoding()) {}
514 bool isKeyOf(const DIStringType
*RHS
) const {
515 return Tag
== RHS
->getTag() && Name
== RHS
->getRawName() &&
516 StringLength
== RHS
->getRawStringLength() &&
517 StringLengthExp
== RHS
->getRawStringLengthExp() &&
518 StringLocationExp
== RHS
->getRawStringLocationExp() &&
519 SizeInBits
== RHS
->getSizeInBits() &&
520 AlignInBits
== RHS
->getAlignInBits() &&
521 Encoding
== RHS
->getEncoding();
523 unsigned getHashValue() const {
524 // Intentionally computes the hash on a subset of the operands for
525 // performance reason. The subset has to be significant enough to avoid
526 // collision "most of the time". There is no correctness issue in case of
527 // collision because of the full check above.
528 return hash_combine(Tag
, Name
, StringLength
, Encoding
);
532 template <> struct MDNodeKeyImpl
<DIDerivedType
> {
540 uint64_t OffsetInBits
;
541 uint32_t AlignInBits
;
542 std::optional
<unsigned> DWARFAddressSpace
;
545 Metadata
*Annotations
;
547 MDNodeKeyImpl(unsigned Tag
, MDString
*Name
, Metadata
*File
, unsigned Line
,
548 Metadata
*Scope
, Metadata
*BaseType
, uint64_t SizeInBits
,
549 uint32_t AlignInBits
, uint64_t OffsetInBits
,
550 std::optional
<unsigned> DWARFAddressSpace
, unsigned Flags
,
551 Metadata
*ExtraData
, Metadata
*Annotations
)
552 : Tag(Tag
), Name(Name
), File(File
), Line(Line
), Scope(Scope
),
553 BaseType(BaseType
), SizeInBits(SizeInBits
), OffsetInBits(OffsetInBits
),
554 AlignInBits(AlignInBits
), DWARFAddressSpace(DWARFAddressSpace
),
555 Flags(Flags
), ExtraData(ExtraData
), Annotations(Annotations
) {}
556 MDNodeKeyImpl(const DIDerivedType
*N
)
557 : Tag(N
->getTag()), Name(N
->getRawName()), File(N
->getRawFile()),
558 Line(N
->getLine()), Scope(N
->getRawScope()),
559 BaseType(N
->getRawBaseType()), SizeInBits(N
->getSizeInBits()),
560 OffsetInBits(N
->getOffsetInBits()), AlignInBits(N
->getAlignInBits()),
561 DWARFAddressSpace(N
->getDWARFAddressSpace()), Flags(N
->getFlags()),
562 ExtraData(N
->getRawExtraData()), Annotations(N
->getRawAnnotations()) {}
564 bool isKeyOf(const DIDerivedType
*RHS
) const {
565 return Tag
== RHS
->getTag() && Name
== RHS
->getRawName() &&
566 File
== RHS
->getRawFile() && Line
== RHS
->getLine() &&
567 Scope
== RHS
->getRawScope() && BaseType
== RHS
->getRawBaseType() &&
568 SizeInBits
== RHS
->getSizeInBits() &&
569 AlignInBits
== RHS
->getAlignInBits() &&
570 OffsetInBits
== RHS
->getOffsetInBits() &&
571 DWARFAddressSpace
== RHS
->getDWARFAddressSpace() &&
572 Flags
== RHS
->getFlags() && ExtraData
== RHS
->getRawExtraData() &&
573 Annotations
== RHS
->getRawAnnotations();
576 unsigned getHashValue() const {
577 // If this is a member inside an ODR type, only hash the type and the name.
578 // Otherwise the hash will be stronger than
579 // MDNodeSubsetEqualImpl::isODRMember().
580 if (Tag
== dwarf::DW_TAG_member
&& Name
)
581 if (auto *CT
= dyn_cast_or_null
<DICompositeType
>(Scope
))
582 if (CT
->getRawIdentifier())
583 return hash_combine(Name
, Scope
);
585 // Intentionally computes the hash on a subset of the operands for
586 // performance reason. The subset has to be significant enough to avoid
587 // collision "most of the time". There is no correctness issue in case of
588 // collision because of the full check above.
589 return hash_combine(Tag
, Name
, File
, Line
, Scope
, BaseType
, Flags
);
593 template <> struct MDNodeSubsetEqualImpl
<DIDerivedType
> {
594 using KeyTy
= MDNodeKeyImpl
<DIDerivedType
>;
596 static bool isSubsetEqual(const KeyTy
&LHS
, const DIDerivedType
*RHS
) {
597 return isODRMember(LHS
.Tag
, LHS
.Scope
, LHS
.Name
, RHS
);
600 static bool isSubsetEqual(const DIDerivedType
*LHS
,
601 const DIDerivedType
*RHS
) {
602 return isODRMember(LHS
->getTag(), LHS
->getRawScope(), LHS
->getRawName(),
606 /// Subprograms compare equal if they declare the same function in an ODR
608 static bool isODRMember(unsigned Tag
, const Metadata
*Scope
,
609 const MDString
*Name
, const DIDerivedType
*RHS
) {
610 // Check whether the LHS is eligible.
611 if (Tag
!= dwarf::DW_TAG_member
|| !Name
)
614 auto *CT
= dyn_cast_or_null
<DICompositeType
>(Scope
);
615 if (!CT
|| !CT
->getRawIdentifier())
618 // Compare to the RHS.
619 return Tag
== RHS
->getTag() && Name
== RHS
->getRawName() &&
620 Scope
== RHS
->getRawScope();
624 template <> struct MDNodeKeyImpl
<DICompositeType
> {
632 uint64_t OffsetInBits
;
633 uint32_t AlignInBits
;
636 unsigned RuntimeLang
;
637 Metadata
*VTableHolder
;
638 Metadata
*TemplateParams
;
639 MDString
*Identifier
;
640 Metadata
*Discriminator
;
641 Metadata
*DataLocation
;
642 Metadata
*Associated
;
645 Metadata
*Annotations
;
647 MDNodeKeyImpl(unsigned Tag
, MDString
*Name
, Metadata
*File
, unsigned Line
,
648 Metadata
*Scope
, Metadata
*BaseType
, uint64_t SizeInBits
,
649 uint32_t AlignInBits
, uint64_t OffsetInBits
, unsigned Flags
,
650 Metadata
*Elements
, unsigned RuntimeLang
,
651 Metadata
*VTableHolder
, Metadata
*TemplateParams
,
652 MDString
*Identifier
, Metadata
*Discriminator
,
653 Metadata
*DataLocation
, Metadata
*Associated
,
654 Metadata
*Allocated
, Metadata
*Rank
, Metadata
*Annotations
)
655 : Tag(Tag
), Name(Name
), File(File
), Line(Line
), Scope(Scope
),
656 BaseType(BaseType
), SizeInBits(SizeInBits
), OffsetInBits(OffsetInBits
),
657 AlignInBits(AlignInBits
), Flags(Flags
), Elements(Elements
),
658 RuntimeLang(RuntimeLang
), VTableHolder(VTableHolder
),
659 TemplateParams(TemplateParams
), Identifier(Identifier
),
660 Discriminator(Discriminator
), DataLocation(DataLocation
),
661 Associated(Associated
), Allocated(Allocated
), Rank(Rank
),
662 Annotations(Annotations
) {}
663 MDNodeKeyImpl(const DICompositeType
*N
)
664 : Tag(N
->getTag()), Name(N
->getRawName()), File(N
->getRawFile()),
665 Line(N
->getLine()), Scope(N
->getRawScope()),
666 BaseType(N
->getRawBaseType()), SizeInBits(N
->getSizeInBits()),
667 OffsetInBits(N
->getOffsetInBits()), AlignInBits(N
->getAlignInBits()),
668 Flags(N
->getFlags()), Elements(N
->getRawElements()),
669 RuntimeLang(N
->getRuntimeLang()), VTableHolder(N
->getRawVTableHolder()),
670 TemplateParams(N
->getRawTemplateParams()),
671 Identifier(N
->getRawIdentifier()),
672 Discriminator(N
->getRawDiscriminator()),
673 DataLocation(N
->getRawDataLocation()),
674 Associated(N
->getRawAssociated()), Allocated(N
->getRawAllocated()),
675 Rank(N
->getRawRank()), Annotations(N
->getRawAnnotations()) {}
677 bool isKeyOf(const DICompositeType
*RHS
) const {
678 return Tag
== RHS
->getTag() && Name
== RHS
->getRawName() &&
679 File
== RHS
->getRawFile() && Line
== RHS
->getLine() &&
680 Scope
== RHS
->getRawScope() && BaseType
== RHS
->getRawBaseType() &&
681 SizeInBits
== RHS
->getSizeInBits() &&
682 AlignInBits
== RHS
->getAlignInBits() &&
683 OffsetInBits
== RHS
->getOffsetInBits() && Flags
== RHS
->getFlags() &&
684 Elements
== RHS
->getRawElements() &&
685 RuntimeLang
== RHS
->getRuntimeLang() &&
686 VTableHolder
== RHS
->getRawVTableHolder() &&
687 TemplateParams
== RHS
->getRawTemplateParams() &&
688 Identifier
== RHS
->getRawIdentifier() &&
689 Discriminator
== RHS
->getRawDiscriminator() &&
690 DataLocation
== RHS
->getRawDataLocation() &&
691 Associated
== RHS
->getRawAssociated() &&
692 Allocated
== RHS
->getRawAllocated() && Rank
== RHS
->getRawRank() &&
693 Annotations
== RHS
->getRawAnnotations();
696 unsigned getHashValue() const {
697 // Intentionally computes the hash on a subset of the operands for
698 // performance reason. The subset has to be significant enough to avoid
699 // collision "most of the time". There is no correctness issue in case of
700 // collision because of the full check above.
701 return hash_combine(Name
, File
, Line
, BaseType
, Scope
, Elements
,
702 TemplateParams
, Annotations
);
706 template <> struct MDNodeKeyImpl
<DISubroutineType
> {
711 MDNodeKeyImpl(unsigned Flags
, uint8_t CC
, Metadata
*TypeArray
)
712 : Flags(Flags
), CC(CC
), TypeArray(TypeArray
) {}
713 MDNodeKeyImpl(const DISubroutineType
*N
)
714 : Flags(N
->getFlags()), CC(N
->getCC()), TypeArray(N
->getRawTypeArray()) {}
716 bool isKeyOf(const DISubroutineType
*RHS
) const {
717 return Flags
== RHS
->getFlags() && CC
== RHS
->getCC() &&
718 TypeArray
== RHS
->getRawTypeArray();
721 unsigned getHashValue() const { return hash_combine(Flags
, CC
, TypeArray
); }
724 template <> struct MDNodeKeyImpl
<DIFile
> {
727 std::optional
<DIFile::ChecksumInfo
<MDString
*>> Checksum
;
730 MDNodeKeyImpl(MDString
*Filename
, MDString
*Directory
,
731 std::optional
<DIFile::ChecksumInfo
<MDString
*>> Checksum
,
733 : Filename(Filename
), Directory(Directory
), Checksum(Checksum
),
735 MDNodeKeyImpl(const DIFile
*N
)
736 : Filename(N
->getRawFilename()), Directory(N
->getRawDirectory()),
737 Checksum(N
->getRawChecksum()), Source(N
->getRawSource()) {}
739 bool isKeyOf(const DIFile
*RHS
) const {
740 return Filename
== RHS
->getRawFilename() &&
741 Directory
== RHS
->getRawDirectory() &&
742 Checksum
== RHS
->getRawChecksum() && Source
== RHS
->getRawSource();
745 unsigned getHashValue() const {
746 return hash_combine(Filename
, Directory
, Checksum
? Checksum
->Kind
: 0,
747 Checksum
? Checksum
->Value
: nullptr, Source
);
751 template <> struct MDNodeKeyImpl
<DISubprogram
> {
754 MDString
*LinkageName
;
759 Metadata
*ContainingType
;
760 unsigned VirtualIndex
;
765 Metadata
*TemplateParams
;
766 Metadata
*Declaration
;
767 Metadata
*RetainedNodes
;
768 Metadata
*ThrownTypes
;
769 Metadata
*Annotations
;
770 MDString
*TargetFuncName
;
772 MDNodeKeyImpl(Metadata
*Scope
, MDString
*Name
, MDString
*LinkageName
,
773 Metadata
*File
, unsigned Line
, Metadata
*Type
,
774 unsigned ScopeLine
, Metadata
*ContainingType
,
775 unsigned VirtualIndex
, int ThisAdjustment
, unsigned Flags
,
776 unsigned SPFlags
, Metadata
*Unit
, Metadata
*TemplateParams
,
777 Metadata
*Declaration
, Metadata
*RetainedNodes
,
778 Metadata
*ThrownTypes
, Metadata
*Annotations
,
779 MDString
*TargetFuncName
)
780 : Scope(Scope
), Name(Name
), LinkageName(LinkageName
), File(File
),
781 Line(Line
), Type(Type
), ScopeLine(ScopeLine
),
782 ContainingType(ContainingType
), VirtualIndex(VirtualIndex
),
783 ThisAdjustment(ThisAdjustment
), Flags(Flags
), SPFlags(SPFlags
),
784 Unit(Unit
), TemplateParams(TemplateParams
), Declaration(Declaration
),
785 RetainedNodes(RetainedNodes
), ThrownTypes(ThrownTypes
),
786 Annotations(Annotations
), TargetFuncName(TargetFuncName
) {}
787 MDNodeKeyImpl(const DISubprogram
*N
)
788 : Scope(N
->getRawScope()), Name(N
->getRawName()),
789 LinkageName(N
->getRawLinkageName()), File(N
->getRawFile()),
790 Line(N
->getLine()), Type(N
->getRawType()), ScopeLine(N
->getScopeLine()),
791 ContainingType(N
->getRawContainingType()),
792 VirtualIndex(N
->getVirtualIndex()),
793 ThisAdjustment(N
->getThisAdjustment()), Flags(N
->getFlags()),
794 SPFlags(N
->getSPFlags()), Unit(N
->getRawUnit()),
795 TemplateParams(N
->getRawTemplateParams()),
796 Declaration(N
->getRawDeclaration()),
797 RetainedNodes(N
->getRawRetainedNodes()),
798 ThrownTypes(N
->getRawThrownTypes()),
799 Annotations(N
->getRawAnnotations()),
800 TargetFuncName(N
->getRawTargetFuncName()) {}
802 bool isKeyOf(const DISubprogram
*RHS
) const {
803 return Scope
== RHS
->getRawScope() && Name
== RHS
->getRawName() &&
804 LinkageName
== RHS
->getRawLinkageName() &&
805 File
== RHS
->getRawFile() && Line
== RHS
->getLine() &&
806 Type
== RHS
->getRawType() && ScopeLine
== RHS
->getScopeLine() &&
807 ContainingType
== RHS
->getRawContainingType() &&
808 VirtualIndex
== RHS
->getVirtualIndex() &&
809 ThisAdjustment
== RHS
->getThisAdjustment() &&
810 Flags
== RHS
->getFlags() && SPFlags
== RHS
->getSPFlags() &&
811 Unit
== RHS
->getUnit() &&
812 TemplateParams
== RHS
->getRawTemplateParams() &&
813 Declaration
== RHS
->getRawDeclaration() &&
814 RetainedNodes
== RHS
->getRawRetainedNodes() &&
815 ThrownTypes
== RHS
->getRawThrownTypes() &&
816 Annotations
== RHS
->getRawAnnotations() &&
817 TargetFuncName
== RHS
->getRawTargetFuncName();
820 bool isDefinition() const { return SPFlags
& DISubprogram::SPFlagDefinition
; }
822 unsigned getHashValue() const {
823 // If this is a declaration inside an ODR type, only hash the type and the
824 // name. Otherwise the hash will be stronger than
825 // MDNodeSubsetEqualImpl::isDeclarationOfODRMember().
826 if (!isDefinition() && LinkageName
)
827 if (auto *CT
= dyn_cast_or_null
<DICompositeType
>(Scope
))
828 if (CT
->getRawIdentifier())
829 return hash_combine(LinkageName
, Scope
);
831 // Intentionally computes the hash on a subset of the operands for
832 // performance reason. The subset has to be significant enough to avoid
833 // collision "most of the time". There is no correctness issue in case of
834 // collision because of the full check above.
835 return hash_combine(Name
, Scope
, File
, Type
, Line
);
839 template <> struct MDNodeSubsetEqualImpl
<DISubprogram
> {
840 using KeyTy
= MDNodeKeyImpl
<DISubprogram
>;
842 static bool isSubsetEqual(const KeyTy
&LHS
, const DISubprogram
*RHS
) {
843 return isDeclarationOfODRMember(LHS
.isDefinition(), LHS
.Scope
,
844 LHS
.LinkageName
, LHS
.TemplateParams
, RHS
);
847 static bool isSubsetEqual(const DISubprogram
*LHS
, const DISubprogram
*RHS
) {
848 return isDeclarationOfODRMember(LHS
->isDefinition(), LHS
->getRawScope(),
849 LHS
->getRawLinkageName(),
850 LHS
->getRawTemplateParams(), RHS
);
853 /// Subprograms compare equal if they declare the same function in an ODR
855 static bool isDeclarationOfODRMember(bool IsDefinition
, const Metadata
*Scope
,
856 const MDString
*LinkageName
,
857 const Metadata
*TemplateParams
,
858 const DISubprogram
*RHS
) {
859 // Check whether the LHS is eligible.
860 if (IsDefinition
|| !Scope
|| !LinkageName
)
863 auto *CT
= dyn_cast_or_null
<DICompositeType
>(Scope
);
864 if (!CT
|| !CT
->getRawIdentifier())
867 // Compare to the RHS.
868 // FIXME: We need to compare template parameters here to avoid incorrect
869 // collisions in mapMetadata when RF_ReuseAndMutateDistinctMDs and a
870 // ODR-DISubprogram has a non-ODR template parameter (i.e., a
871 // DICompositeType that does not have an identifier). Eventually we should
872 // decouple ODR logic from uniquing logic.
873 return IsDefinition
== RHS
->isDefinition() && Scope
== RHS
->getRawScope() &&
874 LinkageName
== RHS
->getRawLinkageName() &&
875 TemplateParams
== RHS
->getRawTemplateParams();
879 template <> struct MDNodeKeyImpl
<DILexicalBlock
> {
885 MDNodeKeyImpl(Metadata
*Scope
, Metadata
*File
, unsigned Line
, unsigned Column
)
886 : Scope(Scope
), File(File
), Line(Line
), Column(Column
) {}
887 MDNodeKeyImpl(const DILexicalBlock
*N
)
888 : Scope(N
->getRawScope()), File(N
->getRawFile()), Line(N
->getLine()),
889 Column(N
->getColumn()) {}
891 bool isKeyOf(const DILexicalBlock
*RHS
) const {
892 return Scope
== RHS
->getRawScope() && File
== RHS
->getRawFile() &&
893 Line
== RHS
->getLine() && Column
== RHS
->getColumn();
896 unsigned getHashValue() const {
897 return hash_combine(Scope
, File
, Line
, Column
);
901 template <> struct MDNodeKeyImpl
<DILexicalBlockFile
> {
904 unsigned Discriminator
;
906 MDNodeKeyImpl(Metadata
*Scope
, Metadata
*File
, unsigned Discriminator
)
907 : Scope(Scope
), File(File
), Discriminator(Discriminator
) {}
908 MDNodeKeyImpl(const DILexicalBlockFile
*N
)
909 : Scope(N
->getRawScope()), File(N
->getRawFile()),
910 Discriminator(N
->getDiscriminator()) {}
912 bool isKeyOf(const DILexicalBlockFile
*RHS
) const {
913 return Scope
== RHS
->getRawScope() && File
== RHS
->getRawFile() &&
914 Discriminator
== RHS
->getDiscriminator();
917 unsigned getHashValue() const {
918 return hash_combine(Scope
, File
, Discriminator
);
922 template <> struct MDNodeKeyImpl
<DINamespace
> {
927 MDNodeKeyImpl(Metadata
*Scope
, MDString
*Name
, bool ExportSymbols
)
928 : Scope(Scope
), Name(Name
), ExportSymbols(ExportSymbols
) {}
929 MDNodeKeyImpl(const DINamespace
*N
)
930 : Scope(N
->getRawScope()), Name(N
->getRawName()),
931 ExportSymbols(N
->getExportSymbols()) {}
933 bool isKeyOf(const DINamespace
*RHS
) const {
934 return Scope
== RHS
->getRawScope() && Name
== RHS
->getRawName() &&
935 ExportSymbols
== RHS
->getExportSymbols();
938 unsigned getHashValue() const { return hash_combine(Scope
, Name
); }
941 template <> struct MDNodeKeyImpl
<DICommonBlock
> {
948 MDNodeKeyImpl(Metadata
*Scope
, Metadata
*Decl
, MDString
*Name
, Metadata
*File
,
950 : Scope(Scope
), Decl(Decl
), Name(Name
), File(File
), LineNo(LineNo
) {}
951 MDNodeKeyImpl(const DICommonBlock
*N
)
952 : Scope(N
->getRawScope()), Decl(N
->getRawDecl()), Name(N
->getRawName()),
953 File(N
->getRawFile()), LineNo(N
->getLineNo()) {}
955 bool isKeyOf(const DICommonBlock
*RHS
) const {
956 return Scope
== RHS
->getRawScope() && Decl
== RHS
->getRawDecl() &&
957 Name
== RHS
->getRawName() && File
== RHS
->getRawFile() &&
958 LineNo
== RHS
->getLineNo();
961 unsigned getHashValue() const {
962 return hash_combine(Scope
, Decl
, Name
, File
, LineNo
);
966 template <> struct MDNodeKeyImpl
<DIModule
> {
970 MDString
*ConfigurationMacros
;
971 MDString
*IncludePath
;
972 MDString
*APINotesFile
;
976 MDNodeKeyImpl(Metadata
*File
, Metadata
*Scope
, MDString
*Name
,
977 MDString
*ConfigurationMacros
, MDString
*IncludePath
,
978 MDString
*APINotesFile
, unsigned LineNo
, bool IsDecl
)
979 : File(File
), Scope(Scope
), Name(Name
),
980 ConfigurationMacros(ConfigurationMacros
), IncludePath(IncludePath
),
981 APINotesFile(APINotesFile
), LineNo(LineNo
), IsDecl(IsDecl
) {}
982 MDNodeKeyImpl(const DIModule
*N
)
983 : File(N
->getRawFile()), Scope(N
->getRawScope()), Name(N
->getRawName()),
984 ConfigurationMacros(N
->getRawConfigurationMacros()),
985 IncludePath(N
->getRawIncludePath()),
986 APINotesFile(N
->getRawAPINotesFile()), LineNo(N
->getLineNo()),
987 IsDecl(N
->getIsDecl()) {}
989 bool isKeyOf(const DIModule
*RHS
) const {
990 return Scope
== RHS
->getRawScope() && Name
== RHS
->getRawName() &&
991 ConfigurationMacros
== RHS
->getRawConfigurationMacros() &&
992 IncludePath
== RHS
->getRawIncludePath() &&
993 APINotesFile
== RHS
->getRawAPINotesFile() &&
994 File
== RHS
->getRawFile() && LineNo
== RHS
->getLineNo() &&
995 IsDecl
== RHS
->getIsDecl();
998 unsigned getHashValue() const {
999 return hash_combine(Scope
, Name
, ConfigurationMacros
, IncludePath
);
1003 template <> struct MDNodeKeyImpl
<DITemplateTypeParameter
> {
1008 MDNodeKeyImpl(MDString
*Name
, Metadata
*Type
, bool IsDefault
)
1009 : Name(Name
), Type(Type
), IsDefault(IsDefault
) {}
1010 MDNodeKeyImpl(const DITemplateTypeParameter
*N
)
1011 : Name(N
->getRawName()), Type(N
->getRawType()),
1012 IsDefault(N
->isDefault()) {}
1014 bool isKeyOf(const DITemplateTypeParameter
*RHS
) const {
1015 return Name
== RHS
->getRawName() && Type
== RHS
->getRawType() &&
1016 IsDefault
== RHS
->isDefault();
1019 unsigned getHashValue() const { return hash_combine(Name
, Type
, IsDefault
); }
1022 template <> struct MDNodeKeyImpl
<DITemplateValueParameter
> {
1029 MDNodeKeyImpl(unsigned Tag
, MDString
*Name
, Metadata
*Type
, bool IsDefault
,
1031 : Tag(Tag
), Name(Name
), Type(Type
), IsDefault(IsDefault
), Value(Value
) {}
1032 MDNodeKeyImpl(const DITemplateValueParameter
*N
)
1033 : Tag(N
->getTag()), Name(N
->getRawName()), Type(N
->getRawType()),
1034 IsDefault(N
->isDefault()), Value(N
->getValue()) {}
1036 bool isKeyOf(const DITemplateValueParameter
*RHS
) const {
1037 return Tag
== RHS
->getTag() && Name
== RHS
->getRawName() &&
1038 Type
== RHS
->getRawType() && IsDefault
== RHS
->isDefault() &&
1039 Value
== RHS
->getValue();
1042 unsigned getHashValue() const {
1043 return hash_combine(Tag
, Name
, Type
, IsDefault
, Value
);
1047 template <> struct MDNodeKeyImpl
<DIGlobalVariable
> {
1050 MDString
*LinkageName
;
1056 Metadata
*StaticDataMemberDeclaration
;
1057 Metadata
*TemplateParams
;
1058 uint32_t AlignInBits
;
1059 Metadata
*Annotations
;
1061 MDNodeKeyImpl(Metadata
*Scope
, MDString
*Name
, MDString
*LinkageName
,
1062 Metadata
*File
, unsigned Line
, Metadata
*Type
,
1063 bool IsLocalToUnit
, bool IsDefinition
,
1064 Metadata
*StaticDataMemberDeclaration
, Metadata
*TemplateParams
,
1065 uint32_t AlignInBits
, Metadata
*Annotations
)
1066 : Scope(Scope
), Name(Name
), LinkageName(LinkageName
), File(File
),
1067 Line(Line
), Type(Type
), IsLocalToUnit(IsLocalToUnit
),
1068 IsDefinition(IsDefinition
),
1069 StaticDataMemberDeclaration(StaticDataMemberDeclaration
),
1070 TemplateParams(TemplateParams
), AlignInBits(AlignInBits
),
1071 Annotations(Annotations
) {}
1072 MDNodeKeyImpl(const DIGlobalVariable
*N
)
1073 : Scope(N
->getRawScope()), Name(N
->getRawName()),
1074 LinkageName(N
->getRawLinkageName()), File(N
->getRawFile()),
1075 Line(N
->getLine()), Type(N
->getRawType()),
1076 IsLocalToUnit(N
->isLocalToUnit()), IsDefinition(N
->isDefinition()),
1077 StaticDataMemberDeclaration(N
->getRawStaticDataMemberDeclaration()),
1078 TemplateParams(N
->getRawTemplateParams()),
1079 AlignInBits(N
->getAlignInBits()), Annotations(N
->getRawAnnotations()) {}
1081 bool isKeyOf(const DIGlobalVariable
*RHS
) const {
1082 return Scope
== RHS
->getRawScope() && Name
== RHS
->getRawName() &&
1083 LinkageName
== RHS
->getRawLinkageName() &&
1084 File
== RHS
->getRawFile() && Line
== RHS
->getLine() &&
1085 Type
== RHS
->getRawType() && IsLocalToUnit
== RHS
->isLocalToUnit() &&
1086 IsDefinition
== RHS
->isDefinition() &&
1087 StaticDataMemberDeclaration
==
1088 RHS
->getRawStaticDataMemberDeclaration() &&
1089 TemplateParams
== RHS
->getRawTemplateParams() &&
1090 AlignInBits
== RHS
->getAlignInBits() &&
1091 Annotations
== RHS
->getRawAnnotations();
1094 unsigned getHashValue() const {
1095 // We do not use AlignInBits in hashing function here on purpose:
1096 // in most cases this param for local variable is zero (for function param
1097 // it is always zero). This leads to lots of hash collisions and errors on
1098 // cases with lots of similar variables.
1099 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1100 // generated IR is random for each run and test fails with Align included.
1101 // TODO: make hashing work fine with such situations
1102 return hash_combine(Scope
, Name
, LinkageName
, File
, Line
, Type
,
1103 IsLocalToUnit
, IsDefinition
, /* AlignInBits, */
1104 StaticDataMemberDeclaration
, Annotations
);
1108 template <> struct MDNodeKeyImpl
<DILocalVariable
> {
1116 uint32_t AlignInBits
;
1117 Metadata
*Annotations
;
1119 MDNodeKeyImpl(Metadata
*Scope
, MDString
*Name
, Metadata
*File
, unsigned Line
,
1120 Metadata
*Type
, unsigned Arg
, unsigned Flags
,
1121 uint32_t AlignInBits
, Metadata
*Annotations
)
1122 : Scope(Scope
), Name(Name
), File(File
), Line(Line
), Type(Type
), Arg(Arg
),
1123 Flags(Flags
), AlignInBits(AlignInBits
), Annotations(Annotations
) {}
1124 MDNodeKeyImpl(const DILocalVariable
*N
)
1125 : Scope(N
->getRawScope()), Name(N
->getRawName()), File(N
->getRawFile()),
1126 Line(N
->getLine()), Type(N
->getRawType()), Arg(N
->getArg()),
1127 Flags(N
->getFlags()), AlignInBits(N
->getAlignInBits()),
1128 Annotations(N
->getRawAnnotations()) {}
1130 bool isKeyOf(const DILocalVariable
*RHS
) const {
1131 return Scope
== RHS
->getRawScope() && Name
== RHS
->getRawName() &&
1132 File
== RHS
->getRawFile() && Line
== RHS
->getLine() &&
1133 Type
== RHS
->getRawType() && Arg
== RHS
->getArg() &&
1134 Flags
== RHS
->getFlags() && AlignInBits
== RHS
->getAlignInBits() &&
1135 Annotations
== RHS
->getRawAnnotations();
1138 unsigned getHashValue() const {
1139 // We do not use AlignInBits in hashing function here on purpose:
1140 // in most cases this param for local variable is zero (for function param
1141 // it is always zero). This leads to lots of hash collisions and errors on
1142 // cases with lots of similar variables.
1143 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1144 // generated IR is random for each run and test fails with Align included.
1145 // TODO: make hashing work fine with such situations
1146 return hash_combine(Scope
, Name
, File
, Line
, Type
, Arg
, Flags
, Annotations
);
1150 template <> struct MDNodeKeyImpl
<DILabel
> {
1156 MDNodeKeyImpl(Metadata
*Scope
, MDString
*Name
, Metadata
*File
, unsigned Line
)
1157 : Scope(Scope
), Name(Name
), File(File
), Line(Line
) {}
1158 MDNodeKeyImpl(const DILabel
*N
)
1159 : Scope(N
->getRawScope()), Name(N
->getRawName()), File(N
->getRawFile()),
1160 Line(N
->getLine()) {}
1162 bool isKeyOf(const DILabel
*RHS
) const {
1163 return Scope
== RHS
->getRawScope() && Name
== RHS
->getRawName() &&
1164 File
== RHS
->getRawFile() && Line
== RHS
->getLine();
1167 /// Using name and line to get hash value. It should already be mostly unique.
1168 unsigned getHashValue() const { return hash_combine(Scope
, Name
, Line
); }
1171 template <> struct MDNodeKeyImpl
<DIExpression
> {
1172 ArrayRef
<uint64_t> Elements
;
1174 MDNodeKeyImpl(ArrayRef
<uint64_t> Elements
) : Elements(Elements
) {}
1175 MDNodeKeyImpl(const DIExpression
*N
) : Elements(N
->getElements()) {}
1177 bool isKeyOf(const DIExpression
*RHS
) const {
1178 return Elements
== RHS
->getElements();
1181 unsigned getHashValue() const {
1182 return hash_combine_range(Elements
.begin(), Elements
.end());
1186 template <> struct MDNodeKeyImpl
<DIGlobalVariableExpression
> {
1188 Metadata
*Expression
;
1190 MDNodeKeyImpl(Metadata
*Variable
, Metadata
*Expression
)
1191 : Variable(Variable
), Expression(Expression
) {}
1192 MDNodeKeyImpl(const DIGlobalVariableExpression
*N
)
1193 : Variable(N
->getRawVariable()), Expression(N
->getRawExpression()) {}
1195 bool isKeyOf(const DIGlobalVariableExpression
*RHS
) const {
1196 return Variable
== RHS
->getRawVariable() &&
1197 Expression
== RHS
->getRawExpression();
1200 unsigned getHashValue() const { return hash_combine(Variable
, Expression
); }
1203 template <> struct MDNodeKeyImpl
<DIObjCProperty
> {
1207 MDString
*GetterName
;
1208 MDString
*SetterName
;
1209 unsigned Attributes
;
1212 MDNodeKeyImpl(MDString
*Name
, Metadata
*File
, unsigned Line
,
1213 MDString
*GetterName
, MDString
*SetterName
, unsigned Attributes
,
1215 : Name(Name
), File(File
), Line(Line
), GetterName(GetterName
),
1216 SetterName(SetterName
), Attributes(Attributes
), Type(Type
) {}
1217 MDNodeKeyImpl(const DIObjCProperty
*N
)
1218 : Name(N
->getRawName()), File(N
->getRawFile()), Line(N
->getLine()),
1219 GetterName(N
->getRawGetterName()), SetterName(N
->getRawSetterName()),
1220 Attributes(N
->getAttributes()), Type(N
->getRawType()) {}
1222 bool isKeyOf(const DIObjCProperty
*RHS
) const {
1223 return Name
== RHS
->getRawName() && File
== RHS
->getRawFile() &&
1224 Line
== RHS
->getLine() && GetterName
== RHS
->getRawGetterName() &&
1225 SetterName
== RHS
->getRawSetterName() &&
1226 Attributes
== RHS
->getAttributes() && Type
== RHS
->getRawType();
1229 unsigned getHashValue() const {
1230 return hash_combine(Name
, File
, Line
, GetterName
, SetterName
, Attributes
,
1235 template <> struct MDNodeKeyImpl
<DIImportedEntity
> {
1244 MDNodeKeyImpl(unsigned Tag
, Metadata
*Scope
, Metadata
*Entity
, Metadata
*File
,
1245 unsigned Line
, MDString
*Name
, Metadata
*Elements
)
1246 : Tag(Tag
), Scope(Scope
), Entity(Entity
), File(File
), Line(Line
),
1247 Name(Name
), Elements(Elements
) {}
1248 MDNodeKeyImpl(const DIImportedEntity
*N
)
1249 : Tag(N
->getTag()), Scope(N
->getRawScope()), Entity(N
->getRawEntity()),
1250 File(N
->getRawFile()), Line(N
->getLine()), Name(N
->getRawName()),
1251 Elements(N
->getRawElements()) {}
1253 bool isKeyOf(const DIImportedEntity
*RHS
) const {
1254 return Tag
== RHS
->getTag() && Scope
== RHS
->getRawScope() &&
1255 Entity
== RHS
->getRawEntity() && File
== RHS
->getFile() &&
1256 Line
== RHS
->getLine() && Name
== RHS
->getRawName() &&
1257 Elements
== RHS
->getRawElements();
1260 unsigned getHashValue() const {
1261 return hash_combine(Tag
, Scope
, Entity
, File
, Line
, Name
, Elements
);
1265 template <> struct MDNodeKeyImpl
<DIMacro
> {
1271 MDNodeKeyImpl(unsigned MIType
, unsigned Line
, MDString
*Name
, MDString
*Value
)
1272 : MIType(MIType
), Line(Line
), Name(Name
), Value(Value
) {}
1273 MDNodeKeyImpl(const DIMacro
*N
)
1274 : MIType(N
->getMacinfoType()), Line(N
->getLine()), Name(N
->getRawName()),
1275 Value(N
->getRawValue()) {}
1277 bool isKeyOf(const DIMacro
*RHS
) const {
1278 return MIType
== RHS
->getMacinfoType() && Line
== RHS
->getLine() &&
1279 Name
== RHS
->getRawName() && Value
== RHS
->getRawValue();
1282 unsigned getHashValue() const {
1283 return hash_combine(MIType
, Line
, Name
, Value
);
1287 template <> struct MDNodeKeyImpl
<DIMacroFile
> {
1293 MDNodeKeyImpl(unsigned MIType
, unsigned Line
, Metadata
*File
,
1295 : MIType(MIType
), Line(Line
), File(File
), Elements(Elements
) {}
1296 MDNodeKeyImpl(const DIMacroFile
*N
)
1297 : MIType(N
->getMacinfoType()), Line(N
->getLine()), File(N
->getRawFile()),
1298 Elements(N
->getRawElements()) {}
1300 bool isKeyOf(const DIMacroFile
*RHS
) const {
1301 return MIType
== RHS
->getMacinfoType() && Line
== RHS
->getLine() &&
1302 File
== RHS
->getRawFile() && Elements
== RHS
->getRawElements();
1305 unsigned getHashValue() const {
1306 return hash_combine(MIType
, Line
, File
, Elements
);
1310 template <> struct MDNodeKeyImpl
<DIArgList
> {
1311 ArrayRef
<ValueAsMetadata
*> Args
;
1313 MDNodeKeyImpl(ArrayRef
<ValueAsMetadata
*> Args
) : Args(Args
) {}
1314 MDNodeKeyImpl(const DIArgList
*N
) : Args(N
->getArgs()) {}
1316 bool isKeyOf(const DIArgList
*RHS
) const { return Args
== RHS
->getArgs(); }
1318 unsigned getHashValue() const {
1319 return hash_combine_range(Args
.begin(), Args
.end());
1323 /// DenseMapInfo for MDNode subclasses.
1324 template <class NodeTy
> struct MDNodeInfo
{
1325 using KeyTy
= MDNodeKeyImpl
<NodeTy
>;
1326 using SubsetEqualTy
= MDNodeSubsetEqualImpl
<NodeTy
>;
1328 static inline NodeTy
*getEmptyKey() {
1329 return DenseMapInfo
<NodeTy
*>::getEmptyKey();
1332 static inline NodeTy
*getTombstoneKey() {
1333 return DenseMapInfo
<NodeTy
*>::getTombstoneKey();
1336 static unsigned getHashValue(const KeyTy
&Key
) { return Key
.getHashValue(); }
1338 static unsigned getHashValue(const NodeTy
*N
) {
1339 return KeyTy(N
).getHashValue();
1342 static bool isEqual(const KeyTy
&LHS
, const NodeTy
*RHS
) {
1343 if (RHS
== getEmptyKey() || RHS
== getTombstoneKey())
1345 return SubsetEqualTy::isSubsetEqual(LHS
, RHS
) || LHS
.isKeyOf(RHS
);
1348 static bool isEqual(const NodeTy
*LHS
, const NodeTy
*RHS
) {
1351 if (RHS
== getEmptyKey() || RHS
== getTombstoneKey())
1353 return SubsetEqualTy::isSubsetEqual(LHS
, RHS
);
1357 #define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>;
1358 #include "llvm/IR/Metadata.def"
1360 /// Multimap-like storage for metadata attachments.
1361 class MDAttachments
{
1365 TrackingMDNodeRef Node
;
1369 SmallVector
<Attachment
, 1> Attachments
;
1372 bool empty() const { return Attachments
.empty(); }
1373 size_t size() const { return Attachments
.size(); }
1375 /// Returns the first attachment with the given ID or nullptr if no such
1376 /// attachment exists.
1377 MDNode
*lookup(unsigned ID
) const;
1379 /// Appends all attachments with the given ID to \c Result in insertion order.
1380 /// If the global has no attachments with the given ID, or if ID is invalid,
1381 /// leaves Result unchanged.
1382 void get(unsigned ID
, SmallVectorImpl
<MDNode
*> &Result
) const;
1384 /// Appends all attachments for the global to \c Result, sorting by attachment
1385 /// ID. Attachments with the same ID appear in insertion order. This function
1386 /// does \em not clear \c Result.
1387 void getAll(SmallVectorImpl
<std::pair
<unsigned, MDNode
*>> &Result
) const;
1389 /// Set an attachment to a particular node.
1391 /// Set the \c ID attachment to \c MD, replacing the current attachments at \c
1393 void set(unsigned ID
, MDNode
*MD
);
1395 /// Adds an attachment to a particular node.
1396 void insert(unsigned ID
, MDNode
&MD
);
1398 /// Remove attachments with the given ID.
1400 /// Remove the attachments at \c ID, if any.
1401 bool erase(unsigned ID
);
1403 /// Erase matching attachments.
1405 /// Erases all attachments matching the \c shouldRemove predicate.
1406 template <class PredTy
> void remove_if(PredTy shouldRemove
) {
1407 llvm::erase_if(Attachments
, shouldRemove
);
1411 class LLVMContextImpl
{
1413 /// OwnedModules - The set of modules instantiated in this context, and which
1414 /// will be automatically deleted if this context is deleted.
1415 SmallPtrSet
<Module
*, 4> OwnedModules
;
1417 /// The main remark streamer used by all the other streamers (e.g. IR, MIR,
1418 /// frontends, etc.). This should only be used by the specific streamers, and
1420 std::unique_ptr
<remarks::RemarkStreamer
> MainRemarkStreamer
;
1422 std::unique_ptr
<DiagnosticHandler
> DiagHandler
;
1423 bool RespectDiagnosticFilters
= false;
1424 bool DiagnosticsHotnessRequested
= false;
1425 /// The minimum hotness value a diagnostic needs in order to be included in
1426 /// optimization diagnostics.
1428 /// The threshold is an Optional value, which maps to one of the 3 states:
1429 /// 1). 0 => threshold disabled. All emarks will be printed.
1430 /// 2). positive int => manual threshold by user. Remarks with hotness exceed
1431 /// threshold will be printed.
1432 /// 3). None => 'auto' threshold by user. The actual value is not
1433 /// available at command line, but will be synced with
1434 /// hotness threhold from profile summary during
1437 /// State 1 and 2 are considered as terminal states. State transition is
1438 /// only allowed from 3 to 2, when the threshold is first synced with profile
1439 /// summary. This ensures that the threshold is set only once and stays
1442 /// If threshold option is not specified, it is disabled (0) by default.
1443 std::optional
<uint64_t> DiagnosticsHotnessThreshold
= 0;
1445 /// The percentage of difference between profiling branch weights and
1446 /// llvm.expect branch weights to tolerate when emiting MisExpect diagnostics
1447 std::optional
<uint32_t> DiagnosticsMisExpectTolerance
= 0;
1448 bool MisExpectWarningRequested
= false;
1450 /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
1451 std::unique_ptr
<LLVMRemarkStreamer
> LLVMRS
;
1453 LLVMContext::YieldCallbackTy YieldCallback
= nullptr;
1454 void *YieldOpaqueHandle
= nullptr;
1456 DenseMap
<const Value
*, ValueName
*> ValueNames
;
1458 DenseMap
<unsigned, std::unique_ptr
<ConstantInt
>> IntZeroConstants
;
1459 DenseMap
<unsigned, std::unique_ptr
<ConstantInt
>> IntOneConstants
;
1460 DenseMap
<APInt
, std::unique_ptr
<ConstantInt
>, DenseMapAPIntKeyInfo
>
1463 DenseMap
<APFloat
, std::unique_ptr
<ConstantFP
>, DenseMapAPFloatKeyInfo
>
1466 FoldingSet
<AttributeImpl
> AttrsSet
;
1467 FoldingSet
<AttributeListImpl
> AttrsLists
;
1468 FoldingSet
<AttributeSetNode
> AttrsSetNodes
;
1470 StringMap
<MDString
, BumpPtrAllocator
> MDStringCache
;
1471 DenseMap
<Value
*, ValueAsMetadata
*> ValuesAsMetadata
;
1472 DenseMap
<Metadata
*, MetadataAsValue
*> MetadataAsValues
;
1474 #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
1475 DenseSet<CLASS *, CLASS##Info> CLASS##s;
1476 #include "llvm/IR/Metadata.def"
1478 // Optional map for looking up composite types by identifier.
1479 std::optional
<DenseMap
<const MDString
*, DICompositeType
*>> DITypeMap
;
1481 // MDNodes may be uniqued or not uniqued. When they're not uniqued, they
1482 // aren't in the MDNodeSet, but they're still shared between objects, so no
1483 // one object can destroy them. Keep track of them here so we can delete
1484 // them on context teardown.
1485 std::vector
<MDNode
*> DistinctMDNodes
;
1487 DenseMap
<Type
*, std::unique_ptr
<ConstantAggregateZero
>> CAZConstants
;
1489 using ArrayConstantsTy
= ConstantUniqueMap
<ConstantArray
>;
1490 ArrayConstantsTy ArrayConstants
;
1492 using StructConstantsTy
= ConstantUniqueMap
<ConstantStruct
>;
1493 StructConstantsTy StructConstants
;
1495 using VectorConstantsTy
= ConstantUniqueMap
<ConstantVector
>;
1496 VectorConstantsTy VectorConstants
;
1498 DenseMap
<PointerType
*, std::unique_ptr
<ConstantPointerNull
>> CPNConstants
;
1500 DenseMap
<TargetExtType
*, std::unique_ptr
<ConstantTargetNone
>> CTNConstants
;
1502 DenseMap
<Type
*, std::unique_ptr
<UndefValue
>> UVConstants
;
1504 DenseMap
<Type
*, std::unique_ptr
<PoisonValue
>> PVConstants
;
1506 StringMap
<std::unique_ptr
<ConstantDataSequential
>> CDSConstants
;
1508 DenseMap
<std::pair
<const Function
*, const BasicBlock
*>, BlockAddress
*>
1511 DenseMap
<const GlobalValue
*, DSOLocalEquivalent
*> DSOLocalEquivalents
;
1513 DenseMap
<const GlobalValue
*, NoCFIValue
*> NoCFIValues
;
1515 ConstantUniqueMap
<ConstantExpr
> ExprConstants
;
1517 ConstantUniqueMap
<InlineAsm
> InlineAsms
;
1519 ConstantInt
*TheTrueVal
= nullptr;
1520 ConstantInt
*TheFalseVal
= nullptr;
1522 // Basic type instances.
1523 Type VoidTy
, LabelTy
, HalfTy
, BFloatTy
, FloatTy
, DoubleTy
, MetadataTy
,
1525 Type X86_FP80Ty
, FP128Ty
, PPC_FP128Ty
, X86_MMXTy
, X86_AMXTy
;
1526 IntegerType Int1Ty
, Int8Ty
, Int16Ty
, Int32Ty
, Int64Ty
, Int128Ty
;
1528 std::unique_ptr
<ConstantTokenNone
> TheNoneToken
;
1530 BumpPtrAllocator Alloc
;
1531 UniqueStringSaver Saver
{Alloc
};
1533 DenseMap
<unsigned, IntegerType
*> IntegerTypes
;
1535 using FunctionTypeSet
= DenseSet
<FunctionType
*, FunctionTypeKeyInfo
>;
1536 FunctionTypeSet FunctionTypes
;
1537 using StructTypeSet
= DenseSet
<StructType
*, AnonStructTypeKeyInfo
>;
1538 StructTypeSet AnonStructTypes
;
1539 StringMap
<StructType
*> NamedStructTypes
;
1540 unsigned NamedStructTypesUniqueID
= 0;
1542 using TargetExtTypeSet
= DenseSet
<TargetExtType
*, TargetExtTypeKeyInfo
>;
1543 TargetExtTypeSet TargetExtTypes
;
1545 DenseMap
<std::pair
<Type
*, uint64_t>, ArrayType
*> ArrayTypes
;
1546 DenseMap
<std::pair
<Type
*, ElementCount
>, VectorType
*> VectorTypes
;
1547 PointerType
*AS0PointerType
= nullptr; // AddrSpace = 0
1548 DenseMap
<unsigned, PointerType
*> PointerTypes
;
1549 DenseMap
<std::pair
<Type
*, unsigned>, PointerType
*> LegacyPointerTypes
;
1550 DenseMap
<std::pair
<Type
*, unsigned>, TypedPointerType
*> ASTypedPointerTypes
;
1552 /// ValueHandles - This map keeps track of all of the value handles that are
1553 /// watching a Value*. The Value::HasValueHandle bit is used to know
1554 /// whether or not a value has an entry in this map.
1555 using ValueHandlesTy
= DenseMap
<Value
*, ValueHandleBase
*>;
1556 ValueHandlesTy ValueHandles
;
1558 /// CustomMDKindNames - Map to hold the metadata string to ID mapping.
1559 StringMap
<unsigned> CustomMDKindNames
;
1561 /// Collection of metadata used in this context.
1562 DenseMap
<const Value
*, MDAttachments
> ValueMetadata
;
1564 /// Map DIAssignID -> Instructions with that attachment.
1565 /// Managed by Instruction via Instruction::updateDIAssignIDMapping.
1566 /// Query using the at:: functions defined in DebugInfo.h.
1567 DenseMap
<DIAssignID
*, SmallVector
<Instruction
*, 1>> AssignmentIDToInstrs
;
1569 /// Collection of per-GlobalObject sections used in this context.
1570 DenseMap
<const GlobalObject
*, StringRef
> GlobalObjectSections
;
1572 /// Collection of per-GlobalValue partitions used in this context.
1573 DenseMap
<const GlobalValue
*, StringRef
> GlobalValuePartitions
;
1575 DenseMap
<const GlobalValue
*, GlobalValue::SanitizerMetadata
>
1576 GlobalValueSanitizerMetadata
;
1578 /// DiscriminatorTable - This table maps file:line locations to an
1579 /// integer representing the next DWARF path discriminator to assign to
1580 /// instructions in different blocks at the same location.
1581 DenseMap
<std::pair
<const char *, unsigned>, unsigned> DiscriminatorTable
;
1583 /// A set of interned tags for operand bundles. The StringMap maps
1584 /// bundle tags to their IDs.
1586 /// \see LLVMContext::getOperandBundleTagID
1587 StringMap
<uint32_t> BundleTagCache
;
1589 StringMapEntry
<uint32_t> *getOrInsertBundleTag(StringRef Tag
);
1590 void getOperandBundleTags(SmallVectorImpl
<StringRef
> &Tags
) const;
1591 uint32_t getOperandBundleTagID(StringRef Tag
) const;
1593 /// A set of interned synchronization scopes. The StringMap maps
1594 /// synchronization scope names to their respective synchronization scope IDs.
1595 StringMap
<SyncScope::ID
> SSC
;
1597 /// getOrInsertSyncScopeID - Maps synchronization scope name to
1598 /// synchronization scope ID. Every synchronization scope registered with
1599 /// LLVMContext has unique ID except pre-defined ones.
1600 SyncScope::ID
getOrInsertSyncScopeID(StringRef SSN
);
1602 /// getSyncScopeNames - Populates client supplied SmallVector with
1603 /// synchronization scope names registered with LLVMContext. Synchronization
1604 /// scope names are ordered by increasing synchronization scope IDs.
1605 void getSyncScopeNames(SmallVectorImpl
<StringRef
> &SSNs
) const;
1607 /// Maintain the GC name for each function.
1609 /// This saves allocating an additional word in Function for programs which
1610 /// do not use GC (i.e., most programs) at the cost of increased overhead for
1611 /// clients which do use GC.
1612 DenseMap
<const Function
*, std::string
> GCNames
;
1614 /// Flag to indicate if Value (other than GlobalValue) retains their name or
1616 bool DiscardValueNames
= false;
1618 LLVMContextImpl(LLVMContext
&C
);
1621 /// Destroy the ConstantArrays if they are not used.
1622 void dropTriviallyDeadConstantArrays();
1624 mutable OptPassGate
*OPG
= nullptr;
1626 /// Access the object which can disable optional passes and individual
1627 /// optimizations at compile time.
1628 OptPassGate
&getOptPassGate() const;
1630 /// Set the object which can disable optional passes and individual
1631 /// optimizations at compile time.
1633 /// The lifetime of the object must be guaranteed to extend as long as the
1634 /// LLVMContext is used by compilation.
1635 void setOptPassGate(OptPassGate
&);
1638 } // end namespace llvm
1640 #endif // LLVM_LIB_IR_LLVMCONTEXTIMPL_H