LLVM 19.0.0git
LLVMContextImpl.h
Go to the documentation of this file.
1//===- LLVMContextImpl.h - The LLVMContextImpl opaque class -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file declares LLVMContextImpl, the opaque implementation
10// of LLVMContext.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_IR_LLVMCONTEXTIMPL_H
15#define LLVM_LIB_IR_LLVMCONTEXTIMPL_H
16
17#include "ConstantsContext.h"
18#include "llvm/ADT/APFloat.h"
19#include "llvm/ADT/APInt.h"
20#include "llvm/ADT/ArrayRef.h"
21#include "llvm/ADT/DenseMap.h"
23#include "llvm/ADT/DenseSet.h"
24#include "llvm/ADT/FoldingSet.h"
25#include "llvm/ADT/Hashing.h"
26#include "llvm/ADT/STLExtras.h"
29#include "llvm/ADT/StringMap.h"
31#include "llvm/IR/Constants.h"
34#include "llvm/IR/LLVMContext.h"
35#include "llvm/IR/Metadata.h"
36#include "llvm/IR/Module.h"
38#include "llvm/IR/Type.h"
39#include "llvm/IR/Value.h"
43#include <algorithm>
44#include <cassert>
45#include <cstddef>
46#include <cstdint>
47#include <memory>
48#include <optional>
49#include <string>
50#include <utility>
51#include <vector>
52
53namespace llvm {
54
55class AttributeImpl;
56class AttributeListImpl;
57class AttributeSetNode;
58class BasicBlock;
59class ConstantRangeAttributeImpl;
60struct DiagnosticHandler;
61class DPMarker;
62class ElementCount;
63class Function;
64class GlobalObject;
65class GlobalValue;
66class InlineAsm;
67class LLVMRemarkStreamer;
68class OptPassGate;
69namespace remarks {
70class RemarkStreamer;
71}
72template <typename T> class StringMapEntry;
73class StringRef;
74class TypedPointerType;
75class ValueHandleBase;
76
77template <> struct DenseMapInfo<APFloat> {
78 static inline APFloat getEmptyKey() { return APFloat(APFloat::Bogus(), 1); }
79 static inline APFloat getTombstoneKey() {
80 return APFloat(APFloat::Bogus(), 2);
81 }
82
83 static unsigned getHashValue(const APFloat &Key) {
84 return static_cast<unsigned>(hash_value(Key));
85 }
86
87 static bool isEqual(const APFloat &LHS, const APFloat &RHS) {
88 return LHS.bitwiseIsEqual(RHS);
89 }
90};
91
93 struct KeyTy {
96
97 KeyTy(const ArrayRef<Type *> &E, bool P) : ETypes(E), isPacked(P) {}
98
99 KeyTy(const StructType *ST)
100 : ETypes(ST->elements()), isPacked(ST->isPacked()) {}
101
102 bool operator==(const KeyTy &that) const {
103 if (isPacked != that.isPacked)
104 return false;
105 if (ETypes != that.ETypes)
106 return false;
107 return true;
108 }
109 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
110 };
111
112 static inline StructType *getEmptyKey() {
114 }
115
116 static inline StructType *getTombstoneKey() {
118 }
119
120 static unsigned getHashValue(const KeyTy &Key) {
121 return hash_combine(
122 hash_combine_range(Key.ETypes.begin(), Key.ETypes.end()), Key.isPacked);
123 }
124
125 static unsigned getHashValue(const StructType *ST) {
126 return getHashValue(KeyTy(ST));
127 }
128
129 static bool isEqual(const KeyTy &LHS, const StructType *RHS) {
130 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
131 return false;
132 return LHS == KeyTy(RHS);
133 }
134
135 static bool isEqual(const StructType *LHS, const StructType *RHS) {
136 return LHS == RHS;
137 }
138};
139
141 struct KeyTy {
145
146 KeyTy(const Type *R, const ArrayRef<Type *> &P, bool V)
147 : ReturnType(R), Params(P), isVarArg(V) {}
149 : ReturnType(FT->getReturnType()), Params(FT->params()),
150 isVarArg(FT->isVarArg()) {}
151
152 bool operator==(const KeyTy &that) const {
153 if (ReturnType != that.ReturnType)
154 return false;
155 if (isVarArg != that.isVarArg)
156 return false;
157 if (Params != that.Params)
158 return false;
159 return true;
160 }
161 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
162 };
163
164 static inline FunctionType *getEmptyKey() {
166 }
167
168 static inline FunctionType *getTombstoneKey() {
170 }
171
172 static unsigned getHashValue(const KeyTy &Key) {
173 return hash_combine(
174 Key.ReturnType,
175 hash_combine_range(Key.Params.begin(), Key.Params.end()), Key.isVarArg);
176 }
177
178 static unsigned getHashValue(const FunctionType *FT) {
179 return getHashValue(KeyTy(FT));
180 }
181
182 static bool isEqual(const KeyTy &LHS, const FunctionType *RHS) {
183 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
184 return false;
185 return LHS == KeyTy(RHS);
186 }
187
188 static bool isEqual(const FunctionType *LHS, const FunctionType *RHS) {
189 return LHS == RHS;
190 }
191};
192
194 struct KeyTy {
198
200 : Name(N), TypeParams(TP), IntParams(IP) {}
202 : Name(TT->getName()), TypeParams(TT->type_params()),
203 IntParams(TT->int_params()) {}
204
205 bool operator==(const KeyTy &that) const {
206 return Name == that.Name && TypeParams == that.TypeParams &&
207 IntParams == that.IntParams;
208 }
209 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
210 };
211
212 static inline TargetExtType *getEmptyKey() {
214 }
215
218 }
219
220 static unsigned getHashValue(const KeyTy &Key) {
221 return hash_combine(
222 Key.Name,
223 hash_combine_range(Key.TypeParams.begin(), Key.TypeParams.end()),
224 hash_combine_range(Key.IntParams.begin(), Key.IntParams.end()));
225 }
226
227 static unsigned getHashValue(const TargetExtType *FT) {
228 return getHashValue(KeyTy(FT));
229 }
230
231 static bool isEqual(const KeyTy &LHS, const TargetExtType *RHS) {
232 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
233 return false;
234 return LHS == KeyTy(RHS);
235 }
236
237 static bool isEqual(const TargetExtType *LHS, const TargetExtType *RHS) {
238 return LHS == RHS;
239 }
240};
241
242/// Structure for hashing arbitrary MDNode operands.
246 unsigned Hash;
247
248protected:
250 : RawOps(Ops), Hash(calculateHash(Ops)) {}
251
252 template <class NodeTy>
253 MDNodeOpsKey(const NodeTy *N, unsigned Offset = 0)
254 : Ops(N->op_begin() + Offset, N->op_end()), Hash(N->getHash()) {}
255
256 template <class NodeTy>
257 bool compareOps(const NodeTy *RHS, unsigned Offset = 0) const {
258 if (getHash() != RHS->getHash())
259 return false;
260
261 assert((RawOps.empty() || Ops.empty()) && "Two sets of operands?");
262 return RawOps.empty() ? compareOps(Ops, RHS, Offset)
263 : compareOps(RawOps, RHS, Offset);
264 }
265
266 static unsigned calculateHash(MDNode *N, unsigned Offset = 0);
267
268private:
269 template <class T>
270 static bool compareOps(ArrayRef<T> Ops, const MDNode *RHS, unsigned Offset) {
271 if (Ops.size() != RHS->getNumOperands() - Offset)
272 return false;
273 return std::equal(Ops.begin(), Ops.end(), RHS->op_begin() + Offset);
274 }
275
276 static unsigned calculateHash(ArrayRef<Metadata *> Ops);
277
278public:
279 unsigned getHash() const { return Hash; }
280};
281
282template <class NodeTy> struct MDNodeKeyImpl;
283
284/// Configuration point for MDNodeInfo::isEqual().
285template <class NodeTy> struct MDNodeSubsetEqualImpl {
287
288 static bool isSubsetEqual(const KeyTy &LHS, const NodeTy *RHS) {
289 return false;
290 }
291
292 static bool isSubsetEqual(const NodeTy *LHS, const NodeTy *RHS) {
293 return false;
294 }
295};
296
297/// DenseMapInfo for MDTuple.
298///
299/// Note that we don't need the is-function-local bit, since that's implicit in
300/// the operands.
301template <> struct MDNodeKeyImpl<MDTuple> : MDNodeOpsKey {
304
305 bool isKeyOf(const MDTuple *RHS) const { return compareOps(RHS); }
306
307 unsigned getHashValue() const { return getHash(); }
308
309 static unsigned calculateHash(MDTuple *N) {
311 }
312};
313
314/// DenseMapInfo for DILocation.
315template <> struct MDNodeKeyImpl<DILocation> {
316 unsigned Line;
317 unsigned Column;
321
322 MDNodeKeyImpl(unsigned Line, unsigned Column, Metadata *Scope,
323 Metadata *InlinedAt, bool ImplicitCode)
324 : Line(Line), Column(Column), Scope(Scope), InlinedAt(InlinedAt),
325 ImplicitCode(ImplicitCode) {}
327 : Line(L->getLine()), Column(L->getColumn()), Scope(L->getRawScope()),
328 InlinedAt(L->getRawInlinedAt()), ImplicitCode(L->isImplicitCode()) {}
329
330 bool isKeyOf(const DILocation *RHS) const {
331 return Line == RHS->getLine() && Column == RHS->getColumn() &&
332 Scope == RHS->getRawScope() && InlinedAt == RHS->getRawInlinedAt() &&
333 ImplicitCode == RHS->isImplicitCode();
334 }
335
336 unsigned getHashValue() const {
337 return hash_combine(Line, Column, Scope, InlinedAt, ImplicitCode);
338 }
339};
340
341/// DenseMapInfo for GenericDINode.
343 unsigned Tag;
345
346 MDNodeKeyImpl(unsigned Tag, MDString *Header, ArrayRef<Metadata *> DwarfOps)
347 : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {}
349 : MDNodeOpsKey(N, 1), Tag(N->getTag()), Header(N->getRawHeader()) {}
350
351 bool isKeyOf(const GenericDINode *RHS) const {
352 return Tag == RHS->getTag() && Header == RHS->getRawHeader() &&
353 compareOps(RHS, 1);
354 }
355
356 unsigned getHashValue() const { return hash_combine(getHash(), Tag, Header); }
357
358 static unsigned calculateHash(GenericDINode *N) {
360 }
361};
362
363template <> struct MDNodeKeyImpl<DISubrange> {
368
369 MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound,
370 Metadata *Stride)
371 : CountNode(CountNode), LowerBound(LowerBound), UpperBound(UpperBound),
372 Stride(Stride) {}
374 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
375 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
376
377 bool isKeyOf(const DISubrange *RHS) const {
378 auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool {
379 if (Node1 == Node2)
380 return true;
381
382 ConstantAsMetadata *MD1 = dyn_cast_or_null<ConstantAsMetadata>(Node1);
383 ConstantAsMetadata *MD2 = dyn_cast_or_null<ConstantAsMetadata>(Node2);
384 if (MD1 && MD2) {
385 ConstantInt *CV1 = cast<ConstantInt>(MD1->getValue());
386 ConstantInt *CV2 = cast<ConstantInt>(MD2->getValue());
387 if (CV1->getSExtValue() == CV2->getSExtValue())
388 return true;
389 }
390 return false;
391 };
392
393 return BoundsEqual(CountNode, RHS->getRawCountNode()) &&
394 BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
395 BoundsEqual(UpperBound, RHS->getRawUpperBound()) &&
396 BoundsEqual(Stride, RHS->getRawStride());
397 }
398
399 unsigned getHashValue() const {
400 if (CountNode)
401 if (auto *MD = dyn_cast<ConstantAsMetadata>(CountNode))
402 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
403 LowerBound, UpperBound, Stride);
404 return hash_combine(CountNode, LowerBound, UpperBound, Stride);
405 }
406};
407
408template <> struct MDNodeKeyImpl<DIGenericSubrange> {
413
414 MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound,
415 Metadata *Stride)
416 : CountNode(CountNode), LowerBound(LowerBound), UpperBound(UpperBound),
417 Stride(Stride) {}
419 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
420 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
421
422 bool isKeyOf(const DIGenericSubrange *RHS) const {
423 return (CountNode == RHS->getRawCountNode()) &&
424 (LowerBound == RHS->getRawLowerBound()) &&
425 (UpperBound == RHS->getRawUpperBound()) &&
426 (Stride == RHS->getRawStride());
427 }
428
429 unsigned getHashValue() const {
430 auto *MD = dyn_cast_or_null<ConstantAsMetadata>(CountNode);
431 if (CountNode && MD)
432 return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
433 LowerBound, UpperBound, Stride);
434 return hash_combine(CountNode, LowerBound, UpperBound, Stride);
435 }
436};
437
438template <> struct MDNodeKeyImpl<DIEnumerator> {
442
444 : Value(Value), Name(Name), IsUnsigned(IsUnsigned) {}
445 MDNodeKeyImpl(int64_t Value, bool IsUnsigned, MDString *Name)
446 : Value(APInt(64, Value, !IsUnsigned)), Name(Name),
447 IsUnsigned(IsUnsigned) {}
449 : Value(N->getValue()), Name(N->getRawName()),
450 IsUnsigned(N->isUnsigned()) {}
451
452 bool isKeyOf(const DIEnumerator *RHS) const {
453 return Value.getBitWidth() == RHS->getValue().getBitWidth() &&
454 Value == RHS->getValue() && IsUnsigned == RHS->isUnsigned() &&
455 Name == RHS->getRawName();
456 }
457
458 unsigned getHashValue() const { return hash_combine(Value, Name); }
459};
460
461template <> struct MDNodeKeyImpl<DIBasicType> {
462 unsigned Tag;
466 unsigned Encoding;
467 unsigned Flags;
468
469 MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits,
470 uint32_t AlignInBits, unsigned Encoding, unsigned Flags)
471 : Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits),
472 Encoding(Encoding), Flags(Flags) {}
474 : Tag(N->getTag()), Name(N->getRawName()), SizeInBits(N->getSizeInBits()),
475 AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()),
476 Flags(N->getFlags()) {}
477
478 bool isKeyOf(const DIBasicType *RHS) const {
479 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
480 SizeInBits == RHS->getSizeInBits() &&
481 AlignInBits == RHS->getAlignInBits() &&
482 Encoding == RHS->getEncoding() && Flags == RHS->getFlags();
483 }
484
485 unsigned getHashValue() const {
486 return hash_combine(Tag, Name, SizeInBits, AlignInBits, Encoding);
487 }
488};
489
490template <> struct MDNodeKeyImpl<DIStringType> {
491 unsigned Tag;
498 unsigned Encoding;
499
500 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *StringLength,
501 Metadata *StringLengthExp, Metadata *StringLocationExp,
502 uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding)
503 : Tag(Tag), Name(Name), StringLength(StringLength),
504 StringLengthExp(StringLengthExp), StringLocationExp(StringLocationExp),
505 SizeInBits(SizeInBits), AlignInBits(AlignInBits), Encoding(Encoding) {}
507 : Tag(N->getTag()), Name(N->getRawName()),
508 StringLength(N->getRawStringLength()),
509 StringLengthExp(N->getRawStringLengthExp()),
510 StringLocationExp(N->getRawStringLocationExp()),
511 SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()),
512 Encoding(N->getEncoding()) {}
513
514 bool isKeyOf(const DIStringType *RHS) const {
515 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
516 StringLength == RHS->getRawStringLength() &&
517 StringLengthExp == RHS->getRawStringLengthExp() &&
518 StringLocationExp == RHS->getRawStringLocationExp() &&
519 SizeInBits == RHS->getSizeInBits() &&
520 AlignInBits == RHS->getAlignInBits() &&
521 Encoding == RHS->getEncoding();
522 }
523 unsigned getHashValue() const {
524 // Intentionally computes the hash on a subset of the operands for
525 // performance reason. The subset has to be significant enough to avoid
526 // collision "most of the time". There is no correctness issue in case of
527 // collision because of the full check above.
528 return hash_combine(Tag, Name, StringLength, Encoding);
529 }
530};
531
532template <> struct MDNodeKeyImpl<DIDerivedType> {
533 unsigned Tag;
536 unsigned Line;
542 std::optional<unsigned> DWARFAddressSpace;
543 unsigned Flags;
546
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) {}
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()) {}
563
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();
574 }
575
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);
584
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);
590 }
591};
592
595
596 static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) {
597 return isODRMember(LHS.Tag, LHS.Scope, LHS.Name, RHS);
598 }
599
600 static bool isSubsetEqual(const DIDerivedType *LHS,
601 const DIDerivedType *RHS) {
602 return isODRMember(LHS->getTag(), LHS->getRawScope(), LHS->getRawName(),
603 RHS);
604 }
605
606 /// Subprograms compare equal if they declare the same function in an ODR
607 /// type.
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)
612 return false;
613
614 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
615 if (!CT || !CT->getRawIdentifier())
616 return false;
617
618 // Compare to the RHS.
619 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
620 Scope == RHS->getRawScope();
621 }
622};
623
624template <> struct MDNodeKeyImpl<DICompositeType> {
625 unsigned Tag;
628 unsigned Line;
634 unsigned Flags;
636 unsigned RuntimeLang;
646
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),
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()) {}
676
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();
694 }
695
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);
703 }
704};
705
706template <> struct MDNodeKeyImpl<DISubroutineType> {
707 unsigned Flags;
708 uint8_t CC;
710
711 MDNodeKeyImpl(unsigned Flags, uint8_t CC, Metadata *TypeArray)
712 : Flags(Flags), CC(CC), TypeArray(TypeArray) {}
714 : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()) {}
715
716 bool isKeyOf(const DISubroutineType *RHS) const {
717 return Flags == RHS->getFlags() && CC == RHS->getCC() &&
718 TypeArray == RHS->getRawTypeArray();
719 }
720
721 unsigned getHashValue() const { return hash_combine(Flags, CC, TypeArray); }
722};
723
724template <> struct MDNodeKeyImpl<DIFile> {
727 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum;
729
730 MDNodeKeyImpl(MDString *Filename, MDString *Directory,
731 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum,
732 MDString *Source)
733 : Filename(Filename), Directory(Directory), Checksum(Checksum),
734 Source(Source) {}
736 : Filename(N->getRawFilename()), Directory(N->getRawDirectory()),
737 Checksum(N->getRawChecksum()), Source(N->getRawSource()) {}
738
739 bool isKeyOf(const DIFile *RHS) const {
740 return Filename == RHS->getRawFilename() &&
741 Directory == RHS->getRawDirectory() &&
742 Checksum == RHS->getRawChecksum() && Source == RHS->getRawSource();
743 }
744
745 unsigned getHashValue() const {
746 return hash_combine(Filename, Directory, Checksum ? Checksum->Kind : 0,
747 Checksum ? Checksum->Value : nullptr, Source);
748 }
749};
750
751template <> struct MDNodeKeyImpl<DISubprogram> {
756 unsigned Line;
758 unsigned ScopeLine;
760 unsigned VirtualIndex;
762 unsigned Flags;
763 unsigned SPFlags;
771
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) {}
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()) {}
801
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();
818 }
819
820 bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; }
821
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);
830
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);
836 }
837};
838
841
842 static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) {
843 return isDeclarationOfODRMember(LHS.isDefinition(), LHS.Scope,
844 LHS.LinkageName, LHS.TemplateParams, RHS);
845 }
846
847 static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) {
848 return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(),
849 LHS->getRawLinkageName(),
850 LHS->getRawTemplateParams(), RHS);
851 }
852
853 /// Subprograms compare equal if they declare the same function in an ODR
854 /// type.
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)
861 return false;
862
863 auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
864 if (!CT || !CT->getRawIdentifier())
865 return false;
866
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();
876 }
877};
878
879template <> struct MDNodeKeyImpl<DILexicalBlock> {
882 unsigned Line;
883 unsigned Column;
884
885 MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Line, unsigned Column)
886 : Scope(Scope), File(File), Line(Line), Column(Column) {}
888 : Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()),
889 Column(N->getColumn()) {}
890
891 bool isKeyOf(const DILexicalBlock *RHS) const {
892 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
893 Line == RHS->getLine() && Column == RHS->getColumn();
894 }
895
896 unsigned getHashValue() const {
897 return hash_combine(Scope, File, Line, Column);
898 }
899};
900
905
906 MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator)
907 : Scope(Scope), File(File), Discriminator(Discriminator) {}
909 : Scope(N->getRawScope()), File(N->getRawFile()),
910 Discriminator(N->getDiscriminator()) {}
911
912 bool isKeyOf(const DILexicalBlockFile *RHS) const {
913 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
914 Discriminator == RHS->getDiscriminator();
915 }
916
917 unsigned getHashValue() const {
918 return hash_combine(Scope, File, Discriminator);
919 }
920};
921
922template <> struct MDNodeKeyImpl<DINamespace> {
926
927 MDNodeKeyImpl(Metadata *Scope, MDString *Name, bool ExportSymbols)
928 : Scope(Scope), Name(Name), ExportSymbols(ExportSymbols) {}
930 : Scope(N->getRawScope()), Name(N->getRawName()),
931 ExportSymbols(N->getExportSymbols()) {}
932
933 bool isKeyOf(const DINamespace *RHS) const {
934 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
935 ExportSymbols == RHS->getExportSymbols();
936 }
937
938 unsigned getHashValue() const { return hash_combine(Scope, Name); }
939};
940
941template <> struct MDNodeKeyImpl<DICommonBlock> {
946 unsigned LineNo;
947
949 unsigned LineNo)
950 : Scope(Scope), Decl(Decl), Name(Name), File(File), LineNo(LineNo) {}
952 : Scope(N->getRawScope()), Decl(N->getRawDecl()), Name(N->getRawName()),
953 File(N->getRawFile()), LineNo(N->getLineNo()) {}
954
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();
959 }
960
961 unsigned getHashValue() const {
962 return hash_combine(Scope, Decl, Name, File, LineNo);
963 }
964};
965
966template <> struct MDNodeKeyImpl<DIModule> {
973 unsigned LineNo;
974 bool IsDecl;
975
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) {}
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()) {}
988
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();
996 }
997
998 unsigned getHashValue() const {
999 return hash_combine(Scope, Name, ConfigurationMacros, IncludePath);
1000 }
1001};
1002
1007
1009 : Name(Name), Type(Type), IsDefault(IsDefault) {}
1011 : Name(N->getRawName()), Type(N->getRawType()),
1012 IsDefault(N->isDefault()) {}
1013
1015 return Name == RHS->getRawName() && Type == RHS->getRawType() &&
1016 IsDefault == RHS->isDefault();
1017 }
1018
1019 unsigned getHashValue() const { return hash_combine(Name, Type, IsDefault); }
1020};
1021
1023 unsigned Tag;
1028
1029 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *Type, bool IsDefault,
1030 Metadata *Value)
1031 : Tag(Tag), Name(Name), Type(Type), IsDefault(IsDefault), Value(Value) {}
1033 : Tag(N->getTag()), Name(N->getRawName()), Type(N->getRawType()),
1034 IsDefault(N->isDefault()), Value(N->getValue()) {}
1035
1037 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
1038 Type == RHS->getRawType() && IsDefault == RHS->isDefault() &&
1039 Value == RHS->getValue();
1040 }
1041
1042 unsigned getHashValue() const {
1043 return hash_combine(Tag, Name, Type, IsDefault, Value);
1044 }
1045};
1046
1047template <> struct MDNodeKeyImpl<DIGlobalVariable> {
1052 unsigned Line;
1060
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),
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()) {}
1080
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();
1092 }
1093
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);
1105 }
1106};
1107
1108template <> struct MDNodeKeyImpl<DILocalVariable> {
1112 unsigned Line;
1114 unsigned Arg;
1115 unsigned Flags;
1118
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) {}
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()) {}
1129
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();
1136 }
1137
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);
1147 }
1148};
1149
1150template <> struct MDNodeKeyImpl<DILabel> {
1154 unsigned Line;
1155
1156 MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line)
1157 : Scope(Scope), Name(Name), File(File), Line(Line) {}
1159 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1160 Line(N->getLine()) {}
1161
1162 bool isKeyOf(const DILabel *RHS) const {
1163 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1164 File == RHS->getRawFile() && Line == RHS->getLine();
1165 }
1166
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); }
1169};
1170
1171template <> struct MDNodeKeyImpl<DIExpression> {
1173
1174 MDNodeKeyImpl(ArrayRef<uint64_t> Elements) : Elements(Elements) {}
1175 MDNodeKeyImpl(const DIExpression *N) : Elements(N->getElements()) {}
1176
1177 bool isKeyOf(const DIExpression *RHS) const {
1178 return Elements == RHS->getElements();
1179 }
1180
1181 unsigned getHashValue() const {
1182 return hash_combine_range(Elements.begin(), Elements.end());
1183 }
1184};
1185
1189
1191 : Variable(Variable), Expression(Expression) {}
1193 : Variable(N->getRawVariable()), Expression(N->getRawExpression()) {}
1194
1196 return Variable == RHS->getRawVariable() &&
1197 Expression == RHS->getRawExpression();
1198 }
1199
1200 unsigned getHashValue() const { return hash_combine(Variable, Expression); }
1201};
1202
1203template <> struct MDNodeKeyImpl<DIObjCProperty> {
1206 unsigned Line;
1209 unsigned Attributes;
1211
1212 MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line,
1213 MDString *GetterName, MDString *SetterName, unsigned Attributes,
1214 Metadata *Type)
1215 : Name(Name), File(File), Line(Line), GetterName(GetterName),
1216 SetterName(SetterName), Attributes(Attributes), Type(Type) {}
1218 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
1219 GetterName(N->getRawGetterName()), SetterName(N->getRawSetterName()),
1220 Attributes(N->getAttributes()), Type(N->getRawType()) {}
1221
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();
1227 }
1228
1229 unsigned getHashValue() const {
1230 return hash_combine(Name, File, Line, GetterName, SetterName, Attributes,
1231 Type);
1232 }
1233};
1234
1235template <> struct MDNodeKeyImpl<DIImportedEntity> {
1236 unsigned Tag;
1240 unsigned Line;
1243
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) {}
1249 : Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()),
1250 File(N->getRawFile()), Line(N->getLine()), Name(N->getRawName()),
1251 Elements(N->getRawElements()) {}
1252
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();
1258 }
1259
1260 unsigned getHashValue() const {
1261 return hash_combine(Tag, Scope, Entity, File, Line, Name, Elements);
1262 }
1263};
1264
1265template <> struct MDNodeKeyImpl<DIMacro> {
1266 unsigned MIType;
1267 unsigned Line;
1270
1271 MDNodeKeyImpl(unsigned MIType, unsigned Line, MDString *Name, MDString *Value)
1272 : MIType(MIType), Line(Line), Name(Name), Value(Value) {}
1274 : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getRawName()),
1275 Value(N->getRawValue()) {}
1276
1277 bool isKeyOf(const DIMacro *RHS) const {
1278 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1279 Name == RHS->getRawName() && Value == RHS->getRawValue();
1280 }
1281
1282 unsigned getHashValue() const {
1283 return hash_combine(MIType, Line, Name, Value);
1284 }
1285};
1286
1287template <> struct MDNodeKeyImpl<DIMacroFile> {
1288 unsigned MIType;
1289 unsigned Line;
1292
1293 MDNodeKeyImpl(unsigned MIType, unsigned Line, Metadata *File,
1294 Metadata *Elements)
1295 : MIType(MIType), Line(Line), File(File), Elements(Elements) {}
1297 : MIType(N->getMacinfoType()), Line(N->getLine()), File(N->getRawFile()),
1298 Elements(N->getRawElements()) {}
1299
1300 bool isKeyOf(const DIMacroFile *RHS) const {
1301 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1302 File == RHS->getRawFile() && Elements == RHS->getRawElements();
1303 }
1304
1305 unsigned getHashValue() const {
1306 return hash_combine(MIType, Line, File, Elements);
1307 }
1308};
1309
1310// DIArgLists are not MDNodes, but we still want to unique them in a DenseSet
1311// based on a hash of their arguments.
1314
1316 DIArgListKeyInfo(const DIArgList *N) : Args(N->getArgs()) {}
1317
1318 bool isKeyOf(const DIArgList *RHS) const { return Args == RHS->getArgs(); }
1319
1320 unsigned getHashValue() const {
1321 return hash_combine_range(Args.begin(), Args.end());
1322 }
1323};
1324
1325/// DenseMapInfo for DIArgList.
1328
1329 static inline DIArgList *getEmptyKey() {
1331 }
1332
1333 static inline DIArgList *getTombstoneKey() {
1335 }
1336
1337 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1338
1339 static unsigned getHashValue(const DIArgList *N) {
1340 return KeyTy(N).getHashValue();
1341 }
1342
1343 static bool isEqual(const KeyTy &LHS, const DIArgList *RHS) {
1344 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1345 return false;
1346 return LHS.isKeyOf(RHS);
1347 }
1348
1349 static bool isEqual(const DIArgList *LHS, const DIArgList *RHS) {
1350 return LHS == RHS;
1351 }
1352};
1353
1354/// DenseMapInfo for MDNode subclasses.
1355template <class NodeTy> struct MDNodeInfo {
1358
1359 static inline NodeTy *getEmptyKey() {
1361 }
1362
1363 static inline NodeTy *getTombstoneKey() {
1365 }
1366
1367 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1368
1369 static unsigned getHashValue(const NodeTy *N) {
1370 return KeyTy(N).getHashValue();
1371 }
1372
1373 static bool isEqual(const KeyTy &LHS, const NodeTy *RHS) {
1374 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1375 return false;
1376 return SubsetEqualTy::isSubsetEqual(LHS, RHS) || LHS.isKeyOf(RHS);
1377 }
1378
1379 static bool isEqual(const NodeTy *LHS, const NodeTy *RHS) {
1380 if (LHS == RHS)
1381 return true;
1382 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
1383 return false;
1385 }
1386};
1387
1388#define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>;
1389#include "llvm/IR/Metadata.def"
1390
1391/// Multimap-like storage for metadata attachments.
1393public:
1394 struct Attachment {
1395 unsigned MDKind;
1397 };
1398
1399private:
1400 SmallVector<Attachment, 1> Attachments;
1401
1402public:
1403 bool empty() const { return Attachments.empty(); }
1404 size_t size() const { return Attachments.size(); }
1405
1406 /// Returns the first attachment with the given ID or nullptr if no such
1407 /// attachment exists.
1408 MDNode *lookup(unsigned ID) const;
1409
1410 /// Appends all attachments with the given ID to \c Result in insertion order.
1411 /// If the global has no attachments with the given ID, or if ID is invalid,
1412 /// leaves Result unchanged.
1413 void get(unsigned ID, SmallVectorImpl<MDNode *> &Result) const;
1414
1415 /// Appends all attachments for the global to \c Result, sorting by attachment
1416 /// ID. Attachments with the same ID appear in insertion order. This function
1417 /// does \em not clear \c Result.
1418 void getAll(SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const;
1419
1420 /// Set an attachment to a particular node.
1421 ///
1422 /// Set the \c ID attachment to \c MD, replacing the current attachments at \c
1423 /// ID (if anyway).
1424 void set(unsigned ID, MDNode *MD);
1425
1426 /// Adds an attachment to a particular node.
1427 void insert(unsigned ID, MDNode &MD);
1428
1429 /// Remove attachments with the given ID.
1430 ///
1431 /// Remove the attachments at \c ID, if any.
1432 bool erase(unsigned ID);
1433
1434 /// Erase matching attachments.
1435 ///
1436 /// Erases all attachments matching the \c shouldRemove predicate.
1437 template <class PredTy> void remove_if(PredTy shouldRemove) {
1438 llvm::erase_if(Attachments, shouldRemove);
1439 }
1440};
1441
1443public:
1444 /// OwnedModules - The set of modules instantiated in this context, and which
1445 /// will be automatically deleted if this context is deleted.
1447
1448 /// The main remark streamer used by all the other streamers (e.g. IR, MIR,
1449 /// frontends, etc.). This should only be used by the specific streamers, and
1450 /// never directly.
1451 std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer;
1452
1453 std::unique_ptr<DiagnosticHandler> DiagHandler;
1456 /// The minimum hotness value a diagnostic needs in order to be included in
1457 /// optimization diagnostics.
1458 ///
1459 /// The threshold is an Optional value, which maps to one of the 3 states:
1460 /// 1). 0 => threshold disabled. All emarks will be printed.
1461 /// 2). positive int => manual threshold by user. Remarks with hotness exceed
1462 /// threshold will be printed.
1463 /// 3). None => 'auto' threshold by user. The actual value is not
1464 /// available at command line, but will be synced with
1465 /// hotness threhold from profile summary during
1466 /// compilation.
1467 ///
1468 /// State 1 and 2 are considered as terminal states. State transition is
1469 /// only allowed from 3 to 2, when the threshold is first synced with profile
1470 /// summary. This ensures that the threshold is set only once and stays
1471 /// constant.
1472 ///
1473 /// If threshold option is not specified, it is disabled (0) by default.
1474 std::optional<uint64_t> DiagnosticsHotnessThreshold = 0;
1475
1476 /// The percentage of difference between profiling branch weights and
1477 /// llvm.expect branch weights to tolerate when emiting MisExpect diagnostics
1478 std::optional<uint32_t> DiagnosticsMisExpectTolerance = 0;
1480
1481 /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
1482 std::unique_ptr<LLVMRemarkStreamer> LLVMRS;
1483
1485 void *YieldOpaqueHandle = nullptr;
1486
1488
1492 DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantInt>>
1494
1496 DenseMap<std::pair<ElementCount, APFloat>, std::unique_ptr<ConstantFP>>
1498
1502
1507
1508#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
1509 DenseSet<CLASS *, CLASS##Info> CLASS##s;
1510#include "llvm/IR/Metadata.def"
1511
1512 // Optional map for looking up composite types by identifier.
1513 std::optional<DenseMap<const MDString *, DICompositeType *>> DITypeMap;
1514
1515 // MDNodes may be uniqued or not uniqued. When they're not uniqued, they
1516 // aren't in the MDNodeSet, but they're still shared between objects, so no
1517 // one object can destroy them. Keep track of them here so we can delete
1518 // them on context teardown.
1519 std::vector<MDNode *> DistinctMDNodes;
1520
1522
1525
1528
1531
1533
1535
1537
1539
1541
1544
1546
1548
1550
1552
1555
1556 // Basic type instances.
1561
1562 std::unique_ptr<ConstantTokenNone> TheNoneToken;
1563
1568
1570
1577
1580
1583 PointerType *AS0PointerType = nullptr; // AddrSpace = 0
1587
1588 /// ValueHandles - This map keeps track of all of the value handles that are
1589 /// watching a Value*. The Value::HasValueHandle bit is used to know
1590 /// whether or not a value has an entry in this map.
1593
1594 /// CustomMDKindNames - Map to hold the metadata string to ID mapping.
1596
1597 /// Collection of metadata used in this context.
1599
1600 /// Map DIAssignID -> Instructions with that attachment.
1601 /// Managed by Instruction via Instruction::updateDIAssignIDMapping.
1602 /// Query using the at:: functions defined in DebugInfo.h.
1604
1605 /// Collection of per-GlobalObject sections used in this context.
1607
1608 /// Collection of per-GlobalValue partitions used in this context.
1610
1613
1614 /// DiscriminatorTable - This table maps file:line locations to an
1615 /// integer representing the next DWARF path discriminator to assign to
1616 /// instructions in different blocks at the same location.
1618
1619 /// A set of interned tags for operand bundles. The StringMap maps
1620 /// bundle tags to their IDs.
1621 ///
1622 /// \see LLVMContext::getOperandBundleTagID
1624
1628
1629 /// A set of interned synchronization scopes. The StringMap maps
1630 /// synchronization scope names to their respective synchronization scope IDs.
1632
1633 /// getOrInsertSyncScopeID - Maps synchronization scope name to
1634 /// synchronization scope ID. Every synchronization scope registered with
1635 /// LLVMContext has unique ID except pre-defined ones.
1637
1638 /// getSyncScopeNames - Populates client supplied SmallVector with
1639 /// synchronization scope names registered with LLVMContext. Synchronization
1640 /// scope names are ordered by increasing synchronization scope IDs.
1642
1643 /// Maintain the GC name for each function.
1644 ///
1645 /// This saves allocating an additional word in Function for programs which
1646 /// do not use GC (i.e., most programs) at the cost of increased overhead for
1647 /// clients which do use GC.
1649
1650 /// Flag to indicate if Value (other than GlobalValue) retains their name or
1651 /// not.
1652 bool DiscardValueNames = false;
1653
1656
1657 /// Destroy the ConstantArrays if they are not used.
1659
1660 mutable OptPassGate *OPG = nullptr;
1661
1662 /// Access the object which can disable optional passes and individual
1663 /// optimizations at compile time.
1664 OptPassGate &getOptPassGate() const;
1665
1666 /// Set the object which can disable optional passes and individual
1667 /// optimizations at compile time.
1668 ///
1669 /// The lifetime of the object must be guaranteed to extend as long as the
1670 /// LLVMContext is used by compilation.
1672
1673 /// Mapping of blocks to collections of "trailing" DPValues. As part of the
1674 /// "RemoveDIs" project, debug-info variable location records are going to
1675 /// cease being instructions... which raises the problem of where should they
1676 /// be recorded when we remove the terminator of a blocks, such as:
1677 ///
1678 /// %foo = add i32 0, 0
1679 /// br label %bar
1680 ///
1681 /// If the branch is removed, a legitimate transient state while editing a
1682 /// block, any debug-records between those two instructions will not have a
1683 /// location. Each block thus records any DPValue records that "trail" in
1684 /// such a way. These are stored in LLVMContext because typically LLVM only
1685 /// edits a small number of blocks at a time, so there's no need to bloat
1686 /// BasicBlock with such a data structure.
1688
1689 // Set, get and delete operations for TrailingDbgRecords.
1691 assert(!TrailingDbgRecords.count(B));
1692 TrailingDbgRecords[B] = M;
1693 }
1694
1696 return TrailingDbgRecords.lookup(B);
1697 }
1698
1700};
1701
1702} // end namespace llvm
1703
1704#endif // LLVM_LIB_IR_LLVMCONTEXTIMPL_H
This file defines the StringMap class.
AMDGPU Kernel Attributes
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines DenseMapInfo traits for DenseMap.
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
This file contains constants used for implementing Dwarf debug support.
std::string Name
This file defines a hash set that can be used to remove duplication of nodes in a graph.
This file contains the declarations for metadata subclasses.
Module.h This file contains the declarations for the Module class.
#define P(N)
static StringRef getName(Value *V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static uint32_t getFlags(const Symbol *Sym)
Definition: TapiFile.cpp:27
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition: APInt.h:76
Annotations lets you mark points and ranges inside source code, for tests:
Definition: Annotations.h:53
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
iterator end() const
Definition: ArrayRef.h:154
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
iterator begin() const
Definition: ArrayRef.h:153
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:160
Class to represent array types.
Definition: DerivedTypes.h:371
LLVM Basic Block Representation.
Definition: BasicBlock.h:60
The address of a basic block.
Definition: Constants.h:888
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:66
Constant * getValue() const
Definition: Metadata.h:536
This is the shared class of boolean and integer constants.
Definition: Constants.h:79
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
Definition: Constants.h:159
List of ValueAsMetadata, to be used as an argument to a dbg.value intrinsic.
Basic type, like 'int' or 'float'.
Debug common block.
Enumeration value.
DWARF expression.
A pair of DIGlobalVariable and DIExpression.
An imported module (C++ using directive or similar).
Debug lexical block.
Debug location.
Represents a module in the programming language, for example, a Clang module, or a Fortran module.
Debug lexical block.
String type, Fortran CHARACTER(n)
Subprogram description.
Array subrange.
Type array for a subprogram.
Per-instruction record of debug-info.
Implements a dense probed hash-table based set.
Definition: DenseSet.h:271
Class representing an expression and its matching format.
FoldingSet - This template class is used to instantiate a specialized implementation of the folding s...
Definition: FoldingSet.h:528
Class to represent function types.
Definition: DerivedTypes.h:103
Generic tagged DWARF-like metadata node.
Class to represent integer types.
Definition: DerivedTypes.h:40
DenseMap< const GlobalValue *, StringRef > GlobalValuePartitions
Collection of per-GlobalValue partitions used in this context.
DenseMap< const GlobalValue *, GlobalValue::SanitizerMetadata > GlobalValueSanitizerMetadata
DenseMap< unsigned, std::unique_ptr< ConstantInt > > IntOneConstants
void getSyncScopeNames(SmallVectorImpl< StringRef > &SSNs) const
getSyncScopeNames - Populates client supplied SmallVector with synchronization scope names registered...
DenseMap< unsigned, std::unique_ptr< ConstantInt > > IntZeroConstants
DenseMap< Metadata *, MetadataAsValue * > MetadataAsValues
DPMarker * getTrailingDbgRecords(BasicBlock *B)
DenseMap< APFloat, std::unique_ptr< ConstantFP > > FPConstants
SmallPtrSet< Module *, 4 > OwnedModules
OwnedModules - The set of modules instantiated in this context, and which will be automatically delet...
DenseMap< PointerType *, std::unique_ptr< ConstantPointerNull > > CPNConstants
DenseMap< Type *, std::unique_ptr< ConstantAggregateZero > > CAZConstants
StringMap< MDString, BumpPtrAllocator > MDStringCache
TargetExtTypeSet TargetExtTypes
DenseMap< DIAssignID *, SmallVector< Instruction *, 1 > > AssignmentIDToInstrs
Map DIAssignID -> Instructions with that attachment.
DenseMap< Type *, std::unique_ptr< PoisonValue > > PVConstants
DenseMap< std::pair< const Function *, const BasicBlock * >, BlockAddress * > BlockAddresses
DenseMap< APInt, std::unique_ptr< ConstantInt > > IntConstants
std::vector< MDNode * > DistinctMDNodes
std::optional< uint32_t > DiagnosticsMisExpectTolerance
The percentage of difference between profiling branch weights and llvm.expect branch weights to toler...
FoldingSet< AttributeImpl > AttrsSet
StructTypeSet AnonStructTypes
std::unique_ptr< ConstantTokenNone > TheNoneToken
DenseMap< const Value *, ValueName * > ValueNames
SyncScope::ID getOrInsertSyncScopeID(StringRef SSN)
getOrInsertSyncScopeID - Maps synchronization scope name to synchronization scope ID.
void dropTriviallyDeadConstantArrays()
Destroy the ConstantArrays if they are not used.
void setOptPassGate(OptPassGate &)
Set the object which can disable optional passes and individual optimizations at compile time.
VectorConstantsTy VectorConstants
std::unique_ptr< LLVMRemarkStreamer > LLVMRS
The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
bool DiscardValueNames
Flag to indicate if Value (other than GlobalValue) retains their name or not.
DenseMap< const GlobalValue *, NoCFIValue * > NoCFIValues
DenseMap< const Function *, std::string > GCNames
Maintain the GC name for each function.
DenseMap< Type *, std::unique_ptr< UndefValue > > UVConstants
OptPassGate & getOptPassGate() const
Access the object which can disable optional passes and individual optimizations at compile time.
DenseMap< std::pair< Type *, unsigned >, TypedPointerType * > ASTypedPointerTypes
DenseMap< std::pair< Type *, uint64_t >, ArrayType * > ArrayTypes
DenseMap< const Value *, MDAttachments > ValueMetadata
Collection of metadata used in this context.
StringMap< unsigned > CustomMDKindNames
CustomMDKindNames - Map to hold the metadata string to ID mapping.
StringMapEntry< uint32_t > * getOrInsertBundleTag(StringRef Tag)
std::unique_ptr< DiagnosticHandler > DiagHandler
StringMap< uint32_t > BundleTagCache
A set of interned tags for operand bundles.
BumpPtrAllocator Alloc
DenseMap< const GlobalObject *, StringRef > GlobalObjectSections
Collection of per-GlobalObject sections used in this context.
StringMap< std::unique_ptr< ConstantDataSequential > > CDSConstants
StructConstantsTy StructConstants
DenseMap< std::pair< Type *, ElementCount >, VectorType * > VectorTypes
std::unique_ptr< remarks::RemarkStreamer > MainRemarkStreamer
The main remark streamer used by all the other streamers (e.g.
void getOperandBundleTags(SmallVectorImpl< StringRef > &Tags) const
void deleteTrailingDbgRecords(BasicBlock *B)
FoldingSet< AttributeSetNode > AttrsSetNodes
FoldingSet< AttributeListImpl > AttrsLists
void setTrailingDbgRecords(BasicBlock *B, DPMarker *M)
DenseMap< TargetExtType *, std::unique_ptr< ConstantTargetNone > > CTNConstants
SpecificBumpPtrAllocator< ConstantRangeAttributeImpl > ConstantRangeAttributeAlloc
std::optional< uint64_t > DiagnosticsHotnessThreshold
The minimum hotness value a diagnostic needs in order to be included in optimization diagnostics.
ConstantUniqueMap< ConstantExpr > ExprConstants
uint32_t getOperandBundleTagID(StringRef Tag) const
DenseMap< std::pair< Type *, unsigned >, PointerType * > LegacyPointerTypes
StringMap< SyncScope::ID > SSC
A set of interned synchronization scopes.
DenseMap< unsigned, PointerType * > PointerTypes
DenseMap< std::pair< ElementCount, APInt >, std::unique_ptr< ConstantInt > > IntSplatConstants
UniqueStringSaver Saver
LLVMContext::YieldCallbackTy YieldCallback
DenseMap< unsigned, IntegerType * > IntegerTypes
StringMap< StructType * > NamedStructTypes
PointerType * AS0PointerType
DenseSet< DIArgList *, DIArgListInfo > DIArgLists
ValueHandlesTy ValueHandles
ArrayConstantsTy ArrayConstants
DenseMap< Value *, ValueAsMetadata * > ValuesAsMetadata
SmallDenseMap< BasicBlock *, DPMarker * > TrailingDbgRecords
Mapping of blocks to collections of "trailing" DPValues.
ConstantUniqueMap< InlineAsm > InlineAsms
DenseMap< std::pair< const char *, unsigned >, unsigned > DiscriminatorTable
DiscriminatorTable - This table maps file:line locations to an integer representing the next DWARF pa...
DenseMap< const GlobalValue *, DSOLocalEquivalent * > DSOLocalEquivalents
FunctionTypeSet FunctionTypes
std::optional< DenseMap< const MDString *, DICompositeType * > > DITypeMap
DenseMap< std::pair< ElementCount, APFloat >, std::unique_ptr< ConstantFP > > FPSplatConstants
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
void(*)(LLVMContext *Context, void *OpaqueHandle) YieldCallbackTy
Defines the type of a yield callback.
Definition: LLVMContext.h:160
Multimap-like storage for metadata attachments.
void insert(unsigned ID, MDNode &MD)
Adds an attachment to a particular node.
Definition: Metadata.cpp:1432
void remove_if(PredTy shouldRemove)
Erase matching attachments.
void get(unsigned ID, SmallVectorImpl< MDNode * > &Result) const
Appends all attachments with the given ID to Result in insertion order.
Definition: Metadata.cpp:1409
void getAll(SmallVectorImpl< std::pair< unsigned, MDNode * > > &Result) const
Appends all attachments for the global to Result, sorting by attachment ID.
Definition: Metadata.cpp:1415
void set(unsigned ID, MDNode *MD)
Set an attachment to a particular node.
Definition: Metadata.cpp:1426
MDNode * lookup(unsigned ID) const
Returns the first attachment with the given ID or nullptr if no such attachment exists.
Definition: Metadata.cpp:1402
bool erase(unsigned ID)
Remove attachments with the given ID.
Definition: Metadata.cpp:1436
Structure for hashing arbitrary MDNode operands.
MDNodeOpsKey(const NodeTy *N, unsigned Offset=0)
bool compareOps(const NodeTy *RHS, unsigned Offset=0) const
unsigned getHash() const
MDNodeOpsKey(ArrayRef< Metadata * > Ops)
static unsigned calculateHash(MDNode *N, unsigned Offset=0)
Metadata node.
Definition: Metadata.h:1067
A single uniqued string.
Definition: Metadata.h:720
Tuple of metadata.
Definition: Metadata.h:1470
Root of the metadata hierarchy.
Definition: Metadata.h:62
Extensions to this class implement mechanisms to disable passes and individual optimizations at compi...
Definition: OptBisect.h:24
Class to represent pointers.
Definition: DerivedTypes.h:646
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:427
bool empty() const
Definition: SmallVector.h:94
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
Definition: Allocator.h:382
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:128
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Class to represent struct types.
Definition: DerivedTypes.h:216
Class to represent target extensions types, which are generally unintrospectable from target-independ...
Definition: DerivedTypes.h:720
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
A few GPU targets, such as DXIL and SPIR-V, have typed pointers.
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
Definition: StringSaver.h:44
LLVM Value Representation.
Definition: Value.h:74
Base class of all SIMD vector types.
Definition: DerivedTypes.h:403
unsigned getTag(StringRef TagString)
Definition: Dwarf.cpp:32
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ BasicBlock
Various leaf nodes.
Definition: ISDOpcodes.h:71
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
hash_code hash_value(const FixedPointSemantics &Val)
Definition: APFixedPoint.h:128
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition: STLExtras.h:2060
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition: Hashing.h:613
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
Definition: Hashing.h:491
#define N
static const fltSemantics & Bogus() LLVM_READNONE
A Pseudo fltsemantic used to construct APFloats that cannot conflict with anything real.
Definition: APFloat.cpp:266
KeyTy(const ArrayRef< Type * > &E, bool P)
bool operator==(const KeyTy &that) const
bool operator!=(const KeyTy &that) const
static StructType * getEmptyKey()
static bool isEqual(const StructType *LHS, const StructType *RHS)
static unsigned getHashValue(const StructType *ST)
static unsigned getHashValue(const KeyTy &Key)
static StructType * getTombstoneKey()
static bool isEqual(const KeyTy &LHS, const StructType *RHS)
DenseMapInfo for DIArgList.
static unsigned getHashValue(const KeyTy &Key)
static DIArgList * getEmptyKey()
static unsigned getHashValue(const DIArgList *N)
static bool isEqual(const DIArgList *LHS, const DIArgList *RHS)
DIArgListKeyInfo KeyTy
static DIArgList * getTombstoneKey()
static bool isEqual(const KeyTy &LHS, const DIArgList *RHS)
ArrayRef< ValueAsMetadata * > Args
DIArgListKeyInfo(const DIArgList *N)
DIArgListKeyInfo(ArrayRef< ValueAsMetadata * > Args)
unsigned getHashValue() const
bool isKeyOf(const DIArgList *RHS) const
A single checksum, represented by a Kind and a Value (a string).
static bool isEqual(const APFloat &LHS, const APFloat &RHS)
static APFloat getTombstoneKey()
static unsigned getHashValue(const APFloat &Key)
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:50
bool operator==(const KeyTy &that) const
bool operator!=(const KeyTy &that) const
KeyTy(const Type *R, const ArrayRef< Type * > &P, bool V)
KeyTy(const FunctionType *FT)
static unsigned getHashValue(const FunctionType *FT)
static FunctionType * getTombstoneKey()
static bool isEqual(const KeyTy &LHS, const FunctionType *RHS)
static unsigned getHashValue(const KeyTy &Key)
static bool isEqual(const FunctionType *LHS, const FunctionType *RHS)
static FunctionType * getEmptyKey()
DenseMapInfo for MDNode subclasses.
static unsigned getHashValue(const KeyTy &Key)
static bool isEqual(const NodeTy *LHS, const NodeTy *RHS)
static bool isEqual(const KeyTy &LHS, const NodeTy *RHS)
static unsigned getHashValue(const NodeTy *N)
MDNodeKeyImpl< NodeTy > KeyTy
static NodeTy * getTombstoneKey()
static NodeTy * getEmptyKey()
bool isKeyOf(const DIBasicType *RHS) const
MDNodeKeyImpl(const DIBasicType *N)
MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, unsigned Flags)
bool isKeyOf(const DICommonBlock *RHS) const
MDNodeKeyImpl(const DICommonBlock *N)
MDNodeKeyImpl(Metadata *Scope, Metadata *Decl, MDString *Name, Metadata *File, unsigned LineNo)
MDNodeKeyImpl(const DICompositeType *N)
bool isKeyOf(const DICompositeType *RHS) const
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, Metadata *Rank, Metadata *Annotations)
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, std::optional< unsigned > DWARFAddressSpace, unsigned Flags, Metadata *ExtraData, Metadata *Annotations)
MDNodeKeyImpl(const DIDerivedType *N)
bool isKeyOf(const DIDerivedType *RHS) const
std::optional< unsigned > DWARFAddressSpace
MDNodeKeyImpl(APInt Value, bool IsUnsigned, MDString *Name)
MDNodeKeyImpl(int64_t Value, bool IsUnsigned, MDString *Name)
bool isKeyOf(const DIEnumerator *RHS) const
MDNodeKeyImpl(const DIEnumerator *N)
bool isKeyOf(const DIExpression *RHS) const
MDNodeKeyImpl(const DIExpression *N)
MDNodeKeyImpl(ArrayRef< uint64_t > Elements)
std::optional< DIFile::ChecksumInfo< MDString * > > Checksum
bool isKeyOf(const DIFile *RHS) const
MDNodeKeyImpl(MDString *Filename, MDString *Directory, std::optional< DIFile::ChecksumInfo< MDString * > > Checksum, MDString *Source)
bool isKeyOf(const DIGenericSubrange *RHS) const
MDNodeKeyImpl(const DIGenericSubrange *N)
MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound, Metadata *Stride)
MDNodeKeyImpl(Metadata *Variable, Metadata *Expression)
bool isKeyOf(const DIGlobalVariableExpression *RHS) const
MDNodeKeyImpl(const DIGlobalVariableExpression *N)
bool isKeyOf(const DIGlobalVariable *RHS) const
MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, uint32_t AlignInBits, Metadata *Annotations)
MDNodeKeyImpl(const DIGlobalVariable *N)
bool isKeyOf(const DIImportedEntity *RHS) const
MDNodeKeyImpl(unsigned Tag, Metadata *Scope, Metadata *Entity, Metadata *File, unsigned Line, MDString *Name, Metadata *Elements)
MDNodeKeyImpl(const DIImportedEntity *N)
unsigned getHashValue() const
Using name and line to get hash value. It should already be mostly unique.
bool isKeyOf(const DILabel *RHS) const
MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line)
MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator)
MDNodeKeyImpl(const DILexicalBlockFile *N)
bool isKeyOf(const DILexicalBlockFile *RHS) const
bool isKeyOf(const DILexicalBlock *RHS) const
MDNodeKeyImpl(const DILexicalBlock *N)
MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Line, unsigned Column)
bool isKeyOf(const DILocalVariable *RHS) const
MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line, Metadata *Type, unsigned Arg, unsigned Flags, uint32_t AlignInBits, Metadata *Annotations)
MDNodeKeyImpl(const DILocalVariable *N)
MDNodeKeyImpl(unsigned Line, unsigned Column, Metadata *Scope, Metadata *InlinedAt, bool ImplicitCode)
MDNodeKeyImpl(const DILocation *L)
bool isKeyOf(const DILocation *RHS) const
MDNodeKeyImpl(unsigned MIType, unsigned Line, Metadata *File, Metadata *Elements)
bool isKeyOf(const DIMacroFile *RHS) const
MDNodeKeyImpl(unsigned MIType, unsigned Line, MDString *Name, MDString *Value)
bool isKeyOf(const DIMacro *RHS) const
MDNodeKeyImpl(Metadata *File, Metadata *Scope, MDString *Name, MDString *ConfigurationMacros, MDString *IncludePath, MDString *APINotesFile, unsigned LineNo, bool IsDecl)
bool isKeyOf(const DIModule *RHS) const
MDNodeKeyImpl(const DINamespace *N)
MDNodeKeyImpl(Metadata *Scope, MDString *Name, bool ExportSymbols)
bool isKeyOf(const DINamespace *RHS) const
MDNodeKeyImpl(const DIObjCProperty *N)
bool isKeyOf(const DIObjCProperty *RHS) const
MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line, MDString *GetterName, MDString *SetterName, unsigned Attributes, Metadata *Type)
MDNodeKeyImpl(const DIStringType *N)
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *StringLength, Metadata *StringLengthExp, Metadata *StringLocationExp, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding)
bool isKeyOf(const DIStringType *RHS) const
MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex, int ThisAdjustment, unsigned Flags, unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes, Metadata *ThrownTypes, Metadata *Annotations, MDString *TargetFuncName)
bool isKeyOf(const DISubprogram *RHS) const
MDNodeKeyImpl(const DISubprogram *N)
MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound, Metadata *Stride)
bool isKeyOf(const DISubrange *RHS) const
MDNodeKeyImpl(const DISubrange *N)
bool isKeyOf(const DISubroutineType *RHS) const
MDNodeKeyImpl(unsigned Flags, uint8_t CC, Metadata *TypeArray)
MDNodeKeyImpl(const DISubroutineType *N)
MDNodeKeyImpl(const DITemplateTypeParameter *N)
bool isKeyOf(const DITemplateTypeParameter *RHS) const
MDNodeKeyImpl(MDString *Name, Metadata *Type, bool IsDefault)
MDNodeKeyImpl(const DITemplateValueParameter *N)
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *Type, bool IsDefault, Metadata *Value)
bool isKeyOf(const DITemplateValueParameter *RHS) const
static unsigned calculateHash(GenericDINode *N)
MDNodeKeyImpl(const GenericDINode *N)
MDNodeKeyImpl(unsigned Tag, MDString *Header, ArrayRef< Metadata * > DwarfOps)
bool isKeyOf(const GenericDINode *RHS) const
bool isKeyOf(const MDTuple *RHS) const
MDNodeKeyImpl(ArrayRef< Metadata * > Ops)
static unsigned calculateHash(MDTuple *N)
static bool isSubsetEqual(const DIDerivedType *LHS, const DIDerivedType *RHS)
static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS)
static bool isODRMember(unsigned Tag, const Metadata *Scope, const MDString *Name, const DIDerivedType *RHS)
Subprograms compare equal if they declare the same function in an ODR type.
static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS)
static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS)
static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope, const MDString *LinkageName, const Metadata *TemplateParams, const DISubprogram *RHS)
Subprograms compare equal if they declare the same function in an ODR type.
Configuration point for MDNodeInfo::isEqual().
static bool isSubsetEqual(const KeyTy &LHS, const NodeTy *RHS)
static bool isSubsetEqual(const NodeTy *LHS, const NodeTy *RHS)
KeyTy(StringRef N, const ArrayRef< Type * > &TP, const ArrayRef< unsigned > &IP)
bool operator==(const KeyTy &that) const
KeyTy(const TargetExtType *TT)
bool operator!=(const KeyTy &that) const
static unsigned getHashValue(const TargetExtType *FT)
static bool isEqual(const TargetExtType *LHS, const TargetExtType *RHS)
static bool isEqual(const KeyTy &LHS, const TargetExtType *RHS)
static unsigned getHashValue(const KeyTy &Key)
static TargetExtType * getTombstoneKey()
static TargetExtType * getEmptyKey()