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"
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"
43#include <algorithm>
44#include <cassert>
45#include <cstddef>
46#include <cstdint>
47#include <memory>
48#include <optional>
49#include <string>
50#include <utility>
51#include <vector>
52
53namespace llvm {
54
55class AttributeImpl;
56class AttributeListImpl;
57class AttributeSetNode;
58class BasicBlock;
59class ConstantRangeAttributeImpl;
60class ConstantRangeListAttributeImpl;
61struct DiagnosticHandler;
62class DbgMarker;
63class ElementCount;
64class Function;
65class GlobalObject;
66class GlobalValue;
67class InlineAsm;
68class LLVMRemarkStreamer;
69class OptPassGate;
70namespace remarks {
71class RemarkStreamer;
72}
73template <typename T> class StringMapEntry;
74class StringRef;
75class TypedPointerType;
76class ValueHandleBase;
77
78template <> struct DenseMapInfo<APFloat> {
79 static unsigned getHashValue(const APFloat &Key) {
80 return static_cast<unsigned>(hash_value(Arg: Key));
81 }
82
83 static bool isEqual(const APFloat &LHS, const APFloat &RHS) {
84 return LHS.bitwiseIsEqual(RHS);
85 }
86};
87
88struct AnonStructTypeKeyInfo {
89 struct KeyTy {
90 ArrayRef<Type *> ETypes;
91 bool isPacked;
92
93 KeyTy(const ArrayRef<Type *> &E, bool P) : ETypes(E), isPacked(P) {}
94
95 KeyTy(const StructType *ST)
96 : ETypes(ST->elements()), isPacked(ST->isPacked()) {}
97
98 bool operator==(const KeyTy &that) const {
99 if (isPacked != that.isPacked)
100 return false;
101 if (ETypes != that.ETypes)
102 return false;
103 return true;
104 }
105 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
106 };
107
108 static unsigned getHashValue(const KeyTy &Key) {
109 return hash_combine(args: hash_combine_range(R: Key.ETypes), args: Key.isPacked);
110 }
111
112 static unsigned getHashValue(const StructType *ST) {
113 return getHashValue(Key: KeyTy(ST));
114 }
115
116 static bool isEqual(const KeyTy &LHS, const StructType *RHS) {
117 return LHS == KeyTy(RHS);
118 }
119
120 static bool isEqual(const StructType *LHS, const StructType *RHS) {
121 return LHS == RHS;
122 }
123};
124
125struct FunctionTypeKeyInfo {
126 struct KeyTy {
127 const Type *ReturnType;
128 ArrayRef<Type *> Params;
129 bool isVarArg;
130
131 KeyTy(const Type *R, const ArrayRef<Type *> &P, bool V)
132 : ReturnType(R), Params(P), isVarArg(V) {}
133 KeyTy(const FunctionType *FT)
134 : ReturnType(FT->getReturnType()), Params(FT->params()),
135 isVarArg(FT->isVarArg()) {}
136
137 bool operator==(const KeyTy &that) const {
138 if (ReturnType != that.ReturnType)
139 return false;
140 if (isVarArg != that.isVarArg)
141 return false;
142 if (Params != that.Params)
143 return false;
144 return true;
145 }
146 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
147 };
148
149 static unsigned getHashValue(const KeyTy &Key) {
150 return hash_combine(args: Key.ReturnType, args: hash_combine_range(R: Key.Params),
151 args: Key.isVarArg);
152 }
153
154 static unsigned getHashValue(const FunctionType *FT) {
155 return getHashValue(Key: KeyTy(FT));
156 }
157
158 static bool isEqual(const KeyTy &LHS, const FunctionType *RHS) {
159 return LHS == KeyTy(RHS);
160 }
161
162 static bool isEqual(const FunctionType *LHS, const FunctionType *RHS) {
163 return LHS == RHS;
164 }
165};
166
167struct TargetExtTypeKeyInfo {
168 struct KeyTy {
169 StringRef Name;
170 ArrayRef<Type *> TypeParams;
171 ArrayRef<unsigned> IntParams;
172
173 KeyTy(StringRef N, const ArrayRef<Type *> &TP, const ArrayRef<unsigned> &IP)
174 : Name(N), TypeParams(TP), IntParams(IP) {}
175 KeyTy(const TargetExtType *TT)
176 : Name(TT->getName()), TypeParams(TT->type_params()),
177 IntParams(TT->int_params()) {}
178
179 bool operator==(const KeyTy &that) const {
180 return Name == that.Name && TypeParams == that.TypeParams &&
181 IntParams == that.IntParams;
182 }
183 bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
184 };
185
186 static unsigned getHashValue(const KeyTy &Key) {
187 return hash_combine(args: Key.Name, args: hash_combine_range(R: Key.TypeParams),
188 args: hash_combine_range(R: Key.IntParams));
189 }
190
191 static unsigned getHashValue(const TargetExtType *FT) {
192 return getHashValue(Key: KeyTy(FT));
193 }
194
195 static bool isEqual(const KeyTy &LHS, const TargetExtType *RHS) {
196 return LHS == KeyTy(RHS);
197 }
198
199 static bool isEqual(const TargetExtType *LHS, const TargetExtType *RHS) {
200 return LHS == RHS;
201 }
202};
203
204/// Structure for hashing arbitrary MDNode operands.
205class MDNodeOpsKey {
206 ArrayRef<Metadata *> RawOps;
207 ArrayRef<MDOperand> Ops;
208 unsigned Hash;
209
210protected:
211 MDNodeOpsKey(ArrayRef<Metadata *> Ops)
212 : RawOps(Ops), Hash(calculateHash(Ops)) {}
213
214 template <class NodeTy>
215 MDNodeOpsKey(const NodeTy *N, unsigned Offset = 0)
216 : Ops(N->op_begin() + Offset, N->op_end()), Hash(N->getHash()) {}
217
218 template <class NodeTy>
219 bool compareOps(const NodeTy *RHS, unsigned Offset = 0) const {
220 if (getHash() != RHS->getHash())
221 return false;
222
223 assert((RawOps.empty() || Ops.empty()) && "Two sets of operands?");
224 return RawOps.empty() ? compareOps(Ops, RHS, Offset)
225 : compareOps(RawOps, RHS, Offset);
226 }
227
228 static unsigned calculateHash(MDNode *N, unsigned Offset = 0);
229
230private:
231 template <class T>
232 static bool compareOps(ArrayRef<T> Ops, const MDNode *RHS, unsigned Offset) {
233 if (Ops.size() != RHS->getNumOperands() - Offset)
234 return false;
235 return std::equal(Ops.begin(), Ops.end(), RHS->op_begin() + Offset);
236 }
237
238 static unsigned calculateHash(ArrayRef<Metadata *> Ops);
239
240public:
241 unsigned getHash() const { return Hash; }
242};
243
244template <class NodeTy> struct MDNodeKeyImpl;
245
246/// Configuration point for MDNodeInfo::isEqual().
247template <class NodeTy> struct MDNodeSubsetEqualImpl {
248 using KeyTy = MDNodeKeyImpl<NodeTy>;
249
250 static bool isSubsetEqual(const KeyTy &LHS, const NodeTy *RHS) {
251 return false;
252 }
253
254 static bool isSubsetEqual(const NodeTy *LHS, const NodeTy *RHS) {
255 return false;
256 }
257};
258
259/// DenseMapInfo for MDTuple.
260///
261/// Note that we don't need the is-function-local bit, since that's implicit in
262/// the operands.
263template <> struct MDNodeKeyImpl<MDTuple> : MDNodeOpsKey {
264 MDNodeKeyImpl(ArrayRef<Metadata *> Ops) : MDNodeOpsKey(Ops) {}
265 MDNodeKeyImpl(const MDTuple *N) : MDNodeOpsKey(N) {}
266
267 bool isKeyOf(const MDTuple *RHS) const { return compareOps(RHS); }
268
269 unsigned getHashValue() const { return getHash(); }
270
271 static unsigned calculateHash(MDTuple *N) {
272 return MDNodeOpsKey::calculateHash(N);
273 }
274};
275
276/// DenseMapInfo for DILocation.
277template <> struct MDNodeKeyImpl<DILocation> {
278 Metadata *Scope;
279 Metadata *InlinedAt;
280 uint64_t AtomGroup : 61;
281 uint64_t AtomRank : 3;
282 unsigned Line;
283 uint16_t Column;
284 bool ImplicitCode;
285
286 MDNodeKeyImpl(unsigned Line, uint16_t Column, Metadata *Scope,
287 Metadata *InlinedAt, bool ImplicitCode, uint64_t AtomGroup,
288 uint8_t AtomRank)
289 : Scope(Scope), InlinedAt(InlinedAt), AtomGroup(AtomGroup),
290 AtomRank(AtomRank), Line(Line), Column(Column),
291 ImplicitCode(ImplicitCode) {}
292
293 MDNodeKeyImpl(const DILocation *L)
294 : Scope(L->getRawScope()), InlinedAt(L->getRawInlinedAt()),
295 AtomGroup(L->getAtomGroup()), AtomRank(L->getAtomRank()),
296 Line(L->getLine()), Column(L->getColumn()),
297 ImplicitCode(L->isImplicitCode()) {}
298
299 bool isKeyOf(const DILocation *RHS) const {
300 return Line == RHS->getLine() && Column == RHS->getColumn() &&
301 Scope == RHS->getRawScope() && InlinedAt == RHS->getRawInlinedAt() &&
302 ImplicitCode == RHS->isImplicitCode() &&
303 AtomGroup == RHS->getAtomGroup() && AtomRank == RHS->getAtomRank();
304 }
305
306 unsigned getHashValue() const {
307 uint64_t LineColumnAndImplicitCode =
308 Line | (uint64_t(Column) << 32) | (uint64_t(ImplicitCode) << 48);
309 // Hashing AtomGroup and AtomRank substantially impacts performance whether
310 // Key Instructions is enabled or not. We can't detect whether it's enabled
311 // here cheaply; avoiding hashing zero values is a good approximation. This
312 // affects Key Instruction builds too, but any potential costs incurred by
313 // messing with the hash distribution* appear to still be massively
314 // outweighed by the overall compile time savings by performing this check.
315 // * (hash_combine(x) != hash_combine(x, 0))
316 if (AtomGroup || AtomRank)
317 return hash_combine(args: LineColumnAndImplicitCode, args: Scope, args: InlinedAt,
318 args: AtomGroup | (uint64_t(AtomRank) << 61));
319 return hash_combine(args: LineColumnAndImplicitCode, args: Scope, args: InlinedAt);
320 }
321};
322
323/// DenseMapInfo for GenericDINode.
324template <> struct MDNodeKeyImpl<GenericDINode> : MDNodeOpsKey {
325 unsigned Tag;
326 MDString *Header;
327
328 MDNodeKeyImpl(unsigned Tag, MDString *Header, ArrayRef<Metadata *> DwarfOps)
329 : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {}
330 MDNodeKeyImpl(const GenericDINode *N)
331 : MDNodeOpsKey(N, 1), Tag(N->getTag()), Header(N->getRawHeader()) {}
332
333 bool isKeyOf(const GenericDINode *RHS) const {
334 return Tag == RHS->getTag() && Header == RHS->getRawHeader() &&
335 compareOps(RHS, Offset: 1);
336 }
337
338 unsigned getHashValue() const { return hash_combine(args: getHash(), args: Tag, args: Header); }
339
340 static unsigned calculateHash(GenericDINode *N) {
341 return MDNodeOpsKey::calculateHash(N, Offset: 1);
342 }
343};
344
345template <> struct MDNodeKeyImpl<DISubrange> {
346 Metadata *CountNode;
347 Metadata *LowerBound;
348 Metadata *UpperBound;
349 Metadata *Stride;
350
351 MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound,
352 Metadata *Stride)
353 : CountNode(CountNode), LowerBound(LowerBound), UpperBound(UpperBound),
354 Stride(Stride) {}
355 MDNodeKeyImpl(const DISubrange *N)
356 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
357 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
358
359 bool isKeyOf(const DISubrange *RHS) const {
360 auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool {
361 if (Node1 == Node2)
362 return true;
363
364 ConstantAsMetadata *MD1 = dyn_cast_or_null<ConstantAsMetadata>(Val: Node1);
365 ConstantAsMetadata *MD2 = dyn_cast_or_null<ConstantAsMetadata>(Val: Node2);
366 if (MD1 && MD2) {
367 ConstantInt *CV1 = cast<ConstantInt>(Val: MD1->getValue());
368 ConstantInt *CV2 = cast<ConstantInt>(Val: MD2->getValue());
369 if (CV1->getSExtValue() == CV2->getSExtValue())
370 return true;
371 }
372 return false;
373 };
374
375 return BoundsEqual(CountNode, RHS->getRawCountNode()) &&
376 BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
377 BoundsEqual(UpperBound, RHS->getRawUpperBound()) &&
378 BoundsEqual(Stride, RHS->getRawStride());
379 }
380
381 unsigned getHashValue() const {
382 if (CountNode)
383 if (auto *MD = dyn_cast<ConstantAsMetadata>(Val: CountNode))
384 return hash_combine(args: cast<ConstantInt>(Val: MD->getValue())->getSExtValue(),
385 args: LowerBound, args: UpperBound, args: Stride);
386 return hash_combine(args: CountNode, args: LowerBound, args: UpperBound, args: Stride);
387 }
388};
389
390template <> struct MDNodeKeyImpl<DIGenericSubrange> {
391 Metadata *CountNode;
392 Metadata *LowerBound;
393 Metadata *UpperBound;
394 Metadata *Stride;
395
396 MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound,
397 Metadata *Stride)
398 : CountNode(CountNode), LowerBound(LowerBound), UpperBound(UpperBound),
399 Stride(Stride) {}
400 MDNodeKeyImpl(const DIGenericSubrange *N)
401 : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
402 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}
403
404 bool isKeyOf(const DIGenericSubrange *RHS) const {
405 return (CountNode == RHS->getRawCountNode()) &&
406 (LowerBound == RHS->getRawLowerBound()) &&
407 (UpperBound == RHS->getRawUpperBound()) &&
408 (Stride == RHS->getRawStride());
409 }
410
411 unsigned getHashValue() const {
412 auto *MD = dyn_cast_or_null<ConstantAsMetadata>(Val: CountNode);
413 if (CountNode && MD)
414 return hash_combine(args: cast<ConstantInt>(Val: MD->getValue())->getSExtValue(),
415 args: LowerBound, args: UpperBound, args: Stride);
416 return hash_combine(args: CountNode, args: LowerBound, args: UpperBound, args: Stride);
417 }
418};
419
420template <> struct MDNodeKeyImpl<DIEnumerator> {
421 APInt Value;
422 MDString *Name;
423 bool IsUnsigned;
424
425 MDNodeKeyImpl(APInt Value, bool IsUnsigned, MDString *Name)
426 : Value(std::move(Value)), Name(Name), IsUnsigned(IsUnsigned) {}
427 MDNodeKeyImpl(int64_t Value, bool IsUnsigned, MDString *Name)
428 : Value(APInt(64, Value, !IsUnsigned)), Name(Name),
429 IsUnsigned(IsUnsigned) {}
430 MDNodeKeyImpl(const DIEnumerator *N)
431 : Value(N->getValue()), Name(N->getRawName()),
432 IsUnsigned(N->isUnsigned()) {}
433
434 bool isKeyOf(const DIEnumerator *RHS) const {
435 return Value.getBitWidth() == RHS->getValue().getBitWidth() &&
436 Value == RHS->getValue() && IsUnsigned == RHS->isUnsigned() &&
437 Name == RHS->getRawName();
438 }
439
440 unsigned getHashValue() const { return hash_combine(args: Value, args: Name); }
441};
442
443template <> struct MDNodeKeyImpl<DIBasicType> {
444 unsigned Tag;
445 MDString *Name;
446 Metadata *File;
447 unsigned LineNo;
448 Metadata *Scope;
449 Metadata *SizeInBits;
450 uint32_t AlignInBits;
451 unsigned Encoding;
452 uint32_t NumExtraInhabitants;
453 uint32_t DataSizeInBits;
454 unsigned Flags;
455
456 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned LineNo,
457 Metadata *Scope, Metadata *SizeInBits, uint32_t AlignInBits,
458 unsigned Encoding, uint32_t NumExtraInhabitants,
459 uint32_t DataSizeInBits, unsigned Flags)
460 : Tag(Tag), Name(Name), File(File), LineNo(LineNo), Scope(Scope),
461 SizeInBits(SizeInBits), AlignInBits(AlignInBits), Encoding(Encoding),
462 NumExtraInhabitants(NumExtraInhabitants),
463 DataSizeInBits(DataSizeInBits), Flags(Flags) {}
464 MDNodeKeyImpl(const DIBasicType *N)
465 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
466 LineNo(N->getLine()), Scope(N->getRawScope()),
467 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
468 Encoding(N->getEncoding()),
469 NumExtraInhabitants(N->getNumExtraInhabitants()),
470 DataSizeInBits(N->getDataSizeInBits()), Flags(N->getFlags()) {}
471
472 bool isKeyOf(const DIBasicType *RHS) const {
473 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
474 File == RHS->getRawFile() && LineNo == RHS->getLine() &&
475 Scope == RHS->getRawScope() &&
476 SizeInBits == RHS->getRawSizeInBits() &&
477 AlignInBits == RHS->getAlignInBits() &&
478 Encoding == RHS->getEncoding() &&
479 NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
480 DataSizeInBits == RHS->getDataSizeInBits() &&
481 Flags == RHS->getFlags();
482 }
483
484 unsigned getHashValue() const {
485 return hash_combine(args: Tag, args: Name, args: File, args: LineNo, args: Scope, args: SizeInBits, args: AlignInBits,
486 args: Encoding);
487 }
488};
489
490template <> struct MDNodeKeyImpl<DIFixedPointType> {
491 unsigned Tag;
492 MDString *Name;
493 Metadata *File;
494 unsigned LineNo;
495 Metadata *Scope;
496 Metadata *SizeInBits;
497 uint32_t AlignInBits;
498 unsigned Encoding;
499 unsigned Flags;
500 unsigned Kind;
501 int Factor;
502 APInt Numerator;
503 APInt Denominator;
504
505 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned LineNo,
506 Metadata *Scope, Metadata *SizeInBits, uint32_t AlignInBits,
507 unsigned Encoding, unsigned Flags, unsigned Kind, int Factor,
508 APInt Numerator, APInt Denominator)
509 : Tag(Tag), Name(Name), File(File), LineNo(LineNo), Scope(Scope),
510 SizeInBits(SizeInBits), AlignInBits(AlignInBits), Encoding(Encoding),
511 Flags(Flags), Kind(Kind), Factor(Factor), Numerator(Numerator),
512 Denominator(Denominator) {}
513 MDNodeKeyImpl(const DIFixedPointType *N)
514 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
515 LineNo(N->getLine()), Scope(N->getRawScope()),
516 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
517 Encoding(N->getEncoding()), Flags(N->getFlags()), Kind(N->getKind()),
518 Factor(N->getFactorRaw()), Numerator(N->getNumeratorRaw()),
519 Denominator(N->getDenominatorRaw()) {}
520
521 bool isKeyOf(const DIFixedPointType *RHS) const {
522 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
523 LineNo == RHS->getLine() && Scope == RHS->getRawScope() &&
524 SizeInBits == RHS->getRawSizeInBits() &&
525 AlignInBits == RHS->getAlignInBits() && Kind == RHS->getKind() &&
526 (RHS->isRational() ? (Numerator == RHS->getNumerator() &&
527 Denominator == RHS->getDenominator())
528 : Factor == RHS->getFactor());
529 }
530
531 unsigned getHashValue() const {
532 return hash_combine(args: Name, args: File, args: LineNo, args: Scope, args: Flags, args: Kind, args: Factor,
533 args: Numerator, args: Denominator);
534 }
535};
536
537template <> struct MDNodeKeyImpl<DIStringType> {
538 unsigned Tag;
539 MDString *Name;
540 Metadata *StringLength;
541 Metadata *StringLengthExp;
542 Metadata *StringLocationExp;
543 Metadata *SizeInBits;
544 uint32_t AlignInBits;
545 unsigned Encoding;
546
547 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *StringLength,
548 Metadata *StringLengthExp, Metadata *StringLocationExp,
549 Metadata *SizeInBits, uint32_t AlignInBits, unsigned Encoding)
550 : Tag(Tag), Name(Name), StringLength(StringLength),
551 StringLengthExp(StringLengthExp), StringLocationExp(StringLocationExp),
552 SizeInBits(SizeInBits), AlignInBits(AlignInBits), Encoding(Encoding) {}
553 MDNodeKeyImpl(const DIStringType *N)
554 : Tag(N->getTag()), Name(N->getRawName()),
555 StringLength(N->getRawStringLength()),
556 StringLengthExp(N->getRawStringLengthExp()),
557 StringLocationExp(N->getRawStringLocationExp()),
558 SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
559 Encoding(N->getEncoding()) {}
560
561 bool isKeyOf(const DIStringType *RHS) const {
562 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
563 StringLength == RHS->getRawStringLength() &&
564 StringLengthExp == RHS->getRawStringLengthExp() &&
565 StringLocationExp == RHS->getRawStringLocationExp() &&
566 SizeInBits == RHS->getRawSizeInBits() &&
567 AlignInBits == RHS->getAlignInBits() &&
568 Encoding == RHS->getEncoding();
569 }
570 unsigned getHashValue() const {
571 // Intentionally computes the hash on a subset of the operands for
572 // performance reason. The subset has to be significant enough to avoid
573 // collision "most of the time". There is no correctness issue in case of
574 // collision because of the full check above.
575 return hash_combine(args: Tag, args: Name, args: StringLength, args: Encoding);
576 }
577};
578
579template <> struct MDNodeKeyImpl<DIDerivedType> {
580 unsigned Tag;
581 MDString *Name;
582 Metadata *File;
583 unsigned Line;
584 Metadata *Scope;
585 Metadata *BaseType;
586 Metadata *SizeInBits;
587 Metadata *OffsetInBits;
588 uint32_t AlignInBits;
589 std::optional<unsigned> DWARFAddressSpace;
590 std::optional<DIDerivedType::PtrAuthData> PtrAuthData;
591 unsigned Flags;
592 Metadata *ExtraData;
593 Metadata *Annotations;
594
595 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
596 Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
597 uint32_t AlignInBits, Metadata *OffsetInBits,
598 std::optional<unsigned> DWARFAddressSpace,
599 std::optional<DIDerivedType::PtrAuthData> PtrAuthData,
600 unsigned Flags, Metadata *ExtraData, Metadata *Annotations)
601 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
602 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
603 AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace),
604 PtrAuthData(PtrAuthData), Flags(Flags), ExtraData(ExtraData),
605 Annotations(Annotations) {}
606 MDNodeKeyImpl(const DIDerivedType *N)
607 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
608 Line(N->getLine()), Scope(N->getRawScope()),
609 BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
610 OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
611 DWARFAddressSpace(N->getDWARFAddressSpace()),
612 PtrAuthData(N->getPtrAuthData()), Flags(N->getFlags()),
613 ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {}
614
615 bool isKeyOf(const DIDerivedType *RHS) const {
616 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
617 File == RHS->getRawFile() && Line == RHS->getLine() &&
618 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
619 SizeInBits == RHS->getRawSizeInBits() &&
620 AlignInBits == RHS->getAlignInBits() &&
621 OffsetInBits == RHS->getRawOffsetInBits() &&
622 DWARFAddressSpace == RHS->getDWARFAddressSpace() &&
623 PtrAuthData == RHS->getPtrAuthData() && Flags == RHS->getFlags() &&
624 ExtraData == RHS->getRawExtraData() &&
625 Annotations == RHS->getRawAnnotations();
626 }
627
628 unsigned getHashValue() const {
629 // If this is a member inside an ODR type, only hash the type and the name.
630 // Otherwise the hash will be stronger than
631 // MDNodeSubsetEqualImpl::isODRMember().
632 if (Tag == dwarf::DW_TAG_member && Name)
633 if (auto *CT = dyn_cast_or_null<DICompositeType>(Val: Scope))
634 if (CT->getRawIdentifier())
635 return hash_combine(args: Name, args: Scope);
636
637 // Intentionally computes the hash on a subset of the operands for
638 // performance reason. The subset has to be significant enough to avoid
639 // collision "most of the time". There is no correctness issue in case of
640 // collision because of the full check above.
641 return hash_combine(args: Tag, args: Name, args: File, args: Line, args: Scope, args: BaseType, args: Flags);
642 }
643};
644
645template <> struct MDNodeKeyImpl<DISubrangeType> {
646 MDString *Name;
647 Metadata *File;
648 unsigned Line;
649 Metadata *Scope;
650 Metadata *SizeInBits;
651 uint32_t AlignInBits;
652 unsigned Flags;
653 Metadata *BaseType;
654 Metadata *LowerBound;
655 Metadata *UpperBound;
656 Metadata *Stride;
657 Metadata *Bias;
658
659 MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
660 Metadata *SizeInBits, uint32_t AlignInBits, unsigned Flags,
661 Metadata *BaseType, Metadata *LowerBound, Metadata *UpperBound,
662 Metadata *Stride, Metadata *Bias)
663 : Name(Name), File(File), Line(Line), Scope(Scope),
664 SizeInBits(SizeInBits), AlignInBits(AlignInBits), Flags(Flags),
665 BaseType(BaseType), LowerBound(LowerBound), UpperBound(UpperBound),
666 Stride(Stride), Bias(Bias) {}
667 MDNodeKeyImpl(const DISubrangeType *N)
668 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
669 Scope(N->getRawScope()), SizeInBits(N->getRawSizeInBits()),
670 AlignInBits(N->getAlignInBits()), Flags(N->getFlags()),
671 BaseType(N->getRawBaseType()), LowerBound(N->getRawLowerBound()),
672 UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()),
673 Bias(N->getRawBias()) {}
674
675 bool isKeyOf(const DISubrangeType *RHS) const {
676 auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool {
677 if (Node1 == Node2)
678 return true;
679
680 ConstantAsMetadata *MD1 = dyn_cast_or_null<ConstantAsMetadata>(Val: Node1);
681 ConstantAsMetadata *MD2 = dyn_cast_or_null<ConstantAsMetadata>(Val: Node2);
682 if (MD1 && MD2) {
683 ConstantInt *CV1 = cast<ConstantInt>(Val: MD1->getValue());
684 ConstantInt *CV2 = cast<ConstantInt>(Val: MD2->getValue());
685 if (CV1->getSExtValue() == CV2->getSExtValue())
686 return true;
687 }
688 return false;
689 };
690
691 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
692 Line == RHS->getLine() && Scope == RHS->getRawScope() &&
693 SizeInBits == RHS->getRawSizeInBits() &&
694 AlignInBits == RHS->getAlignInBits() && Flags == RHS->getFlags() &&
695 BaseType == RHS->getRawBaseType() &&
696 BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
697 BoundsEqual(UpperBound, RHS->getRawUpperBound()) &&
698 BoundsEqual(Stride, RHS->getRawStride()) &&
699 BoundsEqual(Bias, RHS->getRawBias());
700 }
701
702 unsigned getHashValue() const {
703 unsigned val = 0;
704 auto HashBound = [&](Metadata *Node) -> void {
705 ConstantAsMetadata *MD = dyn_cast_or_null<ConstantAsMetadata>(Val: Node);
706 if (MD) {
707 ConstantInt *CV = cast<ConstantInt>(Val: MD->getValue());
708 val = hash_combine(args: val, args: CV->getSExtValue());
709 } else {
710 val = hash_combine(args: val, args: Node);
711 }
712 };
713
714 HashBound(LowerBound);
715 HashBound(UpperBound);
716 HashBound(Stride);
717 HashBound(Bias);
718
719 return hash_combine(args: val, args: Name, args: File, args: Line, args: Scope, args: BaseType, args: Flags);
720 }
721};
722
723template <> struct MDNodeSubsetEqualImpl<DIDerivedType> {
724 using KeyTy = MDNodeKeyImpl<DIDerivedType>;
725
726 static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) {
727 return isODRMember(Tag: LHS.Tag, Scope: LHS.Scope, Name: LHS.Name, RHS);
728 }
729
730 static bool isSubsetEqual(const DIDerivedType *LHS,
731 const DIDerivedType *RHS) {
732 return isODRMember(Tag: LHS->getTag(), Scope: LHS->getRawScope(), Name: LHS->getRawName(),
733 RHS);
734 }
735
736 /// Subprograms compare equal if they declare the same function in an ODR
737 /// type.
738 static bool isODRMember(unsigned Tag, const Metadata *Scope,
739 const MDString *Name, const DIDerivedType *RHS) {
740 // Check whether the LHS is eligible.
741 if (Tag != dwarf::DW_TAG_member || !Name)
742 return false;
743
744 auto *CT = dyn_cast_or_null<DICompositeType>(Val: Scope);
745 if (!CT || !CT->getRawIdentifier())
746 return false;
747
748 // Compare to the RHS.
749 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
750 Scope == RHS->getRawScope();
751 }
752};
753
754template <> struct MDNodeKeyImpl<DICompositeType> {
755 unsigned Tag;
756 MDString *Name;
757 Metadata *File;
758 unsigned Line;
759 Metadata *Scope;
760 Metadata *BaseType;
761 Metadata *SizeInBits;
762 Metadata *OffsetInBits;
763 uint32_t AlignInBits;
764 unsigned Flags;
765 Metadata *Elements;
766 unsigned RuntimeLang;
767 Metadata *VTableHolder;
768 Metadata *TemplateParams;
769 MDString *Identifier;
770 Metadata *Discriminator;
771 Metadata *DataLocation;
772 Metadata *Associated;
773 Metadata *Allocated;
774 Metadata *Rank;
775 Metadata *Annotations;
776 Metadata *Specification;
777 uint32_t NumExtraInhabitants;
778 Metadata *BitStride;
779
780 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
781 Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
782 uint32_t AlignInBits, Metadata *OffsetInBits, unsigned Flags,
783 Metadata *Elements, unsigned RuntimeLang,
784 Metadata *VTableHolder, Metadata *TemplateParams,
785 MDString *Identifier, Metadata *Discriminator,
786 Metadata *DataLocation, Metadata *Associated,
787 Metadata *Allocated, Metadata *Rank, Metadata *Annotations,
788 Metadata *Specification, uint32_t NumExtraInhabitants,
789 Metadata *BitStride)
790 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
791 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
792 AlignInBits(AlignInBits), Flags(Flags), Elements(Elements),
793 RuntimeLang(RuntimeLang), VTableHolder(VTableHolder),
794 TemplateParams(TemplateParams), Identifier(Identifier),
795 Discriminator(Discriminator), DataLocation(DataLocation),
796 Associated(Associated), Allocated(Allocated), Rank(Rank),
797 Annotations(Annotations), Specification(Specification),
798 NumExtraInhabitants(NumExtraInhabitants), BitStride(BitStride) {}
799 MDNodeKeyImpl(const DICompositeType *N)
800 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
801 Line(N->getLine()), Scope(N->getRawScope()),
802 BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
803 OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
804 Flags(N->getFlags()), Elements(N->getRawElements()),
805 RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()),
806 TemplateParams(N->getRawTemplateParams()),
807 Identifier(N->getRawIdentifier()),
808 Discriminator(N->getRawDiscriminator()),
809 DataLocation(N->getRawDataLocation()),
810 Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()),
811 Rank(N->getRawRank()), Annotations(N->getRawAnnotations()),
812 Specification(N->getSpecification()),
813 NumExtraInhabitants(N->getNumExtraInhabitants()),
814 BitStride(N->getRawBitStride()) {}
815
816 bool isKeyOf(const DICompositeType *RHS) const {
817 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
818 File == RHS->getRawFile() && Line == RHS->getLine() &&
819 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
820 SizeInBits == RHS->getRawSizeInBits() &&
821 AlignInBits == RHS->getAlignInBits() &&
822 OffsetInBits == RHS->getRawOffsetInBits() &&
823 Flags == RHS->getFlags() && Elements == RHS->getRawElements() &&
824 RuntimeLang == RHS->getRuntimeLang() &&
825 VTableHolder == RHS->getRawVTableHolder() &&
826 TemplateParams == RHS->getRawTemplateParams() &&
827 Identifier == RHS->getRawIdentifier() &&
828 Discriminator == RHS->getRawDiscriminator() &&
829 DataLocation == RHS->getRawDataLocation() &&
830 Associated == RHS->getRawAssociated() &&
831 Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() &&
832 Annotations == RHS->getRawAnnotations() &&
833 Specification == RHS->getSpecification() &&
834 NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
835 BitStride == RHS->getRawBitStride();
836 }
837
838 unsigned getHashValue() const {
839 // Intentionally computes the hash on a subset of the operands for
840 // performance reason. The subset has to be significant enough to avoid
841 // collision "most of the time". There is no correctness issue in case of
842 // collision because of the full check above.
843 return hash_combine(args: Name, args: File, args: Line, args: BaseType, args: Scope, args: Elements,
844 args: TemplateParams, args: Annotations);
845 }
846};
847
848template <> struct MDNodeKeyImpl<DISubroutineType> {
849 unsigned Flags;
850 uint8_t CC;
851 Metadata *TypeArray;
852
853 MDNodeKeyImpl(unsigned Flags, uint8_t CC, Metadata *TypeArray)
854 : Flags(Flags), CC(CC), TypeArray(TypeArray) {}
855 MDNodeKeyImpl(const DISubroutineType *N)
856 : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()) {}
857
858 bool isKeyOf(const DISubroutineType *RHS) const {
859 return Flags == RHS->getFlags() && CC == RHS->getCC() &&
860 TypeArray == RHS->getRawTypeArray();
861 }
862
863 unsigned getHashValue() const { return hash_combine(args: Flags, args: CC, args: TypeArray); }
864};
865
866template <> struct MDNodeKeyImpl<DIFile> {
867 MDString *Filename;
868 MDString *Directory;
869 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum;
870 MDString *Source;
871
872 MDNodeKeyImpl(MDString *Filename, MDString *Directory,
873 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum,
874 MDString *Source)
875 : Filename(Filename), Directory(Directory), Checksum(Checksum),
876 Source(Source) {}
877 MDNodeKeyImpl(const DIFile *N)
878 : Filename(N->getRawFilename()), Directory(N->getRawDirectory()),
879 Checksum(N->getRawChecksum()), Source(N->getRawSource()) {}
880
881 bool isKeyOf(const DIFile *RHS) const {
882 return Filename == RHS->getRawFilename() &&
883 Directory == RHS->getRawDirectory() &&
884 Checksum == RHS->getRawChecksum() && Source == RHS->getRawSource();
885 }
886
887 unsigned getHashValue() const {
888 return hash_combine(args: Filename, args: Directory, args: Checksum ? Checksum->Kind : 0,
889 args: Checksum ? Checksum->Value : nullptr, args: Source);
890 }
891};
892
893template <> struct MDNodeKeyImpl<DISubprogram> {
894 Metadata *Scope;
895 MDString *Name;
896 MDString *LinkageName;
897 Metadata *File;
898 unsigned Line;
899 unsigned ScopeLine;
900 Metadata *Type;
901 Metadata *ContainingType;
902 unsigned VirtualIndex;
903 int ThisAdjustment;
904 unsigned Flags;
905 unsigned SPFlags;
906 Metadata *Unit;
907 Metadata *TemplateParams;
908 Metadata *Declaration;
909 Metadata *RetainedNodes;
910 Metadata *ThrownTypes;
911 Metadata *Annotations;
912 MDString *TargetFuncName;
913 bool UsesKeyInstructions;
914
915 MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
916 Metadata *File, unsigned Line, Metadata *Type,
917 unsigned ScopeLine, Metadata *ContainingType,
918 unsigned VirtualIndex, int ThisAdjustment, unsigned Flags,
919 unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams,
920 Metadata *Declaration, Metadata *RetainedNodes,
921 Metadata *ThrownTypes, Metadata *Annotations,
922 MDString *TargetFuncName, bool UsesKeyInstructions)
923 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
924 Line(Line), ScopeLine(ScopeLine), Type(Type),
925 ContainingType(ContainingType), VirtualIndex(VirtualIndex),
926 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags),
927 Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration),
928 RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes),
929 Annotations(Annotations), TargetFuncName(TargetFuncName),
930 UsesKeyInstructions(UsesKeyInstructions) {}
931 MDNodeKeyImpl(const DISubprogram *N)
932 : Scope(N->getRawScope()), Name(N->getRawName()),
933 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
934 Line(N->getLine()), ScopeLine(N->getScopeLine()), Type(N->getRawType()),
935 ContainingType(N->getRawContainingType()),
936 VirtualIndex(N->getVirtualIndex()),
937 ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()),
938 SPFlags(N->getSPFlags()), Unit(N->getRawUnit()),
939 TemplateParams(N->getRawTemplateParams()),
940 Declaration(N->getRawDeclaration()),
941 RetainedNodes(N->getRawRetainedNodes()),
942 ThrownTypes(N->getRawThrownTypes()),
943 Annotations(N->getRawAnnotations()),
944 TargetFuncName(N->getRawTargetFuncName()),
945 UsesKeyInstructions(N->getKeyInstructionsEnabled()) {}
946
947 bool isKeyOf(const DISubprogram *RHS) const {
948 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
949 LinkageName == RHS->getRawLinkageName() &&
950 File == RHS->getRawFile() && Line == RHS->getLine() &&
951 Type == RHS->getRawType() && ScopeLine == RHS->getScopeLine() &&
952 ContainingType == RHS->getRawContainingType() &&
953 VirtualIndex == RHS->getVirtualIndex() &&
954 ThisAdjustment == RHS->getThisAdjustment() &&
955 Flags == RHS->getFlags() && SPFlags == RHS->getSPFlags() &&
956 Unit == RHS->getUnit() &&
957 TemplateParams == RHS->getRawTemplateParams() &&
958 Declaration == RHS->getRawDeclaration() &&
959 RetainedNodes == RHS->getRawRetainedNodes() &&
960 ThrownTypes == RHS->getRawThrownTypes() &&
961 Annotations == RHS->getRawAnnotations() &&
962 TargetFuncName == RHS->getRawTargetFuncName() &&
963 UsesKeyInstructions == RHS->getKeyInstructionsEnabled();
964 }
965
966 bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; }
967
968 unsigned getHashValue() const {
969 // Use the Scope's linkage name instead of using the scope directly, as the
970 // scope may be a temporary one which can replaced, which would produce a
971 // different hash for the same DISubprogram.
972 llvm::StringRef ScopeLinkageName;
973 if (auto *CT = dyn_cast_or_null<DICompositeType>(Val: Scope))
974 if (auto *ID = CT->getRawIdentifier())
975 ScopeLinkageName = ID->getString();
976
977 // If this is a declaration inside an ODR type, only hash the type and the
978 // name. Otherwise the hash will be stronger than
979 // MDNodeSubsetEqualImpl::isDeclarationOfODRMember().
980 if (!isDefinition() && LinkageName &&
981 isa_and_nonnull<DICompositeType>(Val: Scope))
982 return hash_combine(args: LinkageName, args: ScopeLinkageName);
983
984 // Intentionally computes the hash on a subset of the operands for
985 // performance reason. The subset has to be significant enough to avoid
986 // collision "most of the time". There is no correctness issue in case of
987 // collision because of the full check above.
988 return hash_combine(args: Name, args: ScopeLinkageName, args: File, args: Type, args: Line);
989 }
990};
991
992template <> struct MDNodeSubsetEqualImpl<DISubprogram> {
993 using KeyTy = MDNodeKeyImpl<DISubprogram>;
994
995 static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) {
996 return isDeclarationOfODRMember(IsDefinition: LHS.isDefinition(), Scope: LHS.Scope,
997 LinkageName: LHS.LinkageName, TemplateParams: LHS.TemplateParams, RHS);
998 }
999
1000 static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) {
1001 return isDeclarationOfODRMember(IsDefinition: LHS->isDefinition(), Scope: LHS->getRawScope(),
1002 LinkageName: LHS->getRawLinkageName(),
1003 TemplateParams: LHS->getRawTemplateParams(), RHS);
1004 }
1005
1006 /// Subprograms compare equal if they declare the same function in an ODR
1007 /// type.
1008 static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope,
1009 const MDString *LinkageName,
1010 const Metadata *TemplateParams,
1011 const DISubprogram *RHS) {
1012 // Check whether the LHS is eligible.
1013 if (IsDefinition || !Scope || !LinkageName)
1014 return false;
1015
1016 auto *CT = dyn_cast_or_null<DICompositeType>(Val: Scope);
1017 if (!CT || !CT->getRawIdentifier())
1018 return false;
1019
1020 // Compare to the RHS.
1021 // FIXME: We need to compare template parameters here to avoid incorrect
1022 // collisions in mapMetadata when RF_ReuseAndMutateDistinctMDs and a
1023 // ODR-DISubprogram has a non-ODR template parameter (i.e., a
1024 // DICompositeType that does not have an identifier). Eventually we should
1025 // decouple ODR logic from uniquing logic.
1026 return IsDefinition == RHS->isDefinition() && Scope == RHS->getRawScope() &&
1027 LinkageName == RHS->getRawLinkageName() &&
1028 TemplateParams == RHS->getRawTemplateParams();
1029 }
1030};
1031
1032template <> struct MDNodeKeyImpl<DILexicalBlock> {
1033 Metadata *Scope;
1034 Metadata *File;
1035 unsigned Line;
1036 unsigned Column;
1037
1038 MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Line, unsigned Column)
1039 : Scope(Scope), File(File), Line(Line), Column(Column) {}
1040 MDNodeKeyImpl(const DILexicalBlock *N)
1041 : Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()),
1042 Column(N->getColumn()) {}
1043
1044 bool isKeyOf(const DILexicalBlock *RHS) const {
1045 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
1046 Line == RHS->getLine() && Column == RHS->getColumn();
1047 }
1048
1049 unsigned getHashValue() const {
1050 return hash_combine(args: Scope, args: File, args: Line, args: Column);
1051 }
1052};
1053
1054template <> struct MDNodeKeyImpl<DILexicalBlockFile> {
1055 Metadata *Scope;
1056 Metadata *File;
1057 unsigned Discriminator;
1058
1059 MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator)
1060 : Scope(Scope), File(File), Discriminator(Discriminator) {}
1061 MDNodeKeyImpl(const DILexicalBlockFile *N)
1062 : Scope(N->getRawScope()), File(N->getRawFile()),
1063 Discriminator(N->getDiscriminator()) {}
1064
1065 bool isKeyOf(const DILexicalBlockFile *RHS) const {
1066 return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
1067 Discriminator == RHS->getDiscriminator();
1068 }
1069
1070 unsigned getHashValue() const {
1071 return hash_combine(args: Scope, args: File, args: Discriminator);
1072 }
1073};
1074
1075template <> struct MDNodeKeyImpl<DINamespace> {
1076 Metadata *Scope;
1077 MDString *Name;
1078 bool ExportSymbols;
1079
1080 MDNodeKeyImpl(Metadata *Scope, MDString *Name, bool ExportSymbols)
1081 : Scope(Scope), Name(Name), ExportSymbols(ExportSymbols) {}
1082 MDNodeKeyImpl(const DINamespace *N)
1083 : Scope(N->getRawScope()), Name(N->getRawName()),
1084 ExportSymbols(N->getExportSymbols()) {}
1085
1086 bool isKeyOf(const DINamespace *RHS) const {
1087 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1088 ExportSymbols == RHS->getExportSymbols();
1089 }
1090
1091 unsigned getHashValue() const { return hash_combine(args: Scope, args: Name); }
1092};
1093
1094template <> struct MDNodeKeyImpl<DICommonBlock> {
1095 Metadata *Scope;
1096 Metadata *Decl;
1097 MDString *Name;
1098 Metadata *File;
1099 unsigned LineNo;
1100
1101 MDNodeKeyImpl(Metadata *Scope, Metadata *Decl, MDString *Name, Metadata *File,
1102 unsigned LineNo)
1103 : Scope(Scope), Decl(Decl), Name(Name), File(File), LineNo(LineNo) {}
1104 MDNodeKeyImpl(const DICommonBlock *N)
1105 : Scope(N->getRawScope()), Decl(N->getRawDecl()), Name(N->getRawName()),
1106 File(N->getRawFile()), LineNo(N->getLineNo()) {}
1107
1108 bool isKeyOf(const DICommonBlock *RHS) const {
1109 return Scope == RHS->getRawScope() && Decl == RHS->getRawDecl() &&
1110 Name == RHS->getRawName() && File == RHS->getRawFile() &&
1111 LineNo == RHS->getLineNo();
1112 }
1113
1114 unsigned getHashValue() const {
1115 return hash_combine(args: Scope, args: Decl, args: Name, args: File, args: LineNo);
1116 }
1117};
1118
1119template <> struct MDNodeKeyImpl<DIModule> {
1120 Metadata *File;
1121 Metadata *Scope;
1122 MDString *Name;
1123 MDString *ConfigurationMacros;
1124 MDString *IncludePath;
1125 MDString *APINotesFile;
1126 unsigned LineNo;
1127 bool IsDecl;
1128
1129 MDNodeKeyImpl(Metadata *File, Metadata *Scope, MDString *Name,
1130 MDString *ConfigurationMacros, MDString *IncludePath,
1131 MDString *APINotesFile, unsigned LineNo, bool IsDecl)
1132 : File(File), Scope(Scope), Name(Name),
1133 ConfigurationMacros(ConfigurationMacros), IncludePath(IncludePath),
1134 APINotesFile(APINotesFile), LineNo(LineNo), IsDecl(IsDecl) {}
1135 MDNodeKeyImpl(const DIModule *N)
1136 : File(N->getRawFile()), Scope(N->getRawScope()), Name(N->getRawName()),
1137 ConfigurationMacros(N->getRawConfigurationMacros()),
1138 IncludePath(N->getRawIncludePath()),
1139 APINotesFile(N->getRawAPINotesFile()), LineNo(N->getLineNo()),
1140 IsDecl(N->getIsDecl()) {}
1141
1142 bool isKeyOf(const DIModule *RHS) const {
1143 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1144 ConfigurationMacros == RHS->getRawConfigurationMacros() &&
1145 IncludePath == RHS->getRawIncludePath() &&
1146 APINotesFile == RHS->getRawAPINotesFile() &&
1147 File == RHS->getRawFile() && LineNo == RHS->getLineNo() &&
1148 IsDecl == RHS->getIsDecl();
1149 }
1150
1151 unsigned getHashValue() const {
1152 return hash_combine(args: Scope, args: Name, args: ConfigurationMacros, args: IncludePath);
1153 }
1154};
1155
1156template <> struct MDNodeKeyImpl<DITemplateTypeParameter> {
1157 MDString *Name;
1158 Metadata *Type;
1159 bool IsDefault;
1160
1161 MDNodeKeyImpl(MDString *Name, Metadata *Type, bool IsDefault)
1162 : Name(Name), Type(Type), IsDefault(IsDefault) {}
1163 MDNodeKeyImpl(const DITemplateTypeParameter *N)
1164 : Name(N->getRawName()), Type(N->getRawType()),
1165 IsDefault(N->isDefault()) {}
1166
1167 bool isKeyOf(const DITemplateTypeParameter *RHS) const {
1168 return Name == RHS->getRawName() && Type == RHS->getRawType() &&
1169 IsDefault == RHS->isDefault();
1170 }
1171
1172 unsigned getHashValue() const { return hash_combine(args: Name, args: Type, args: IsDefault); }
1173};
1174
1175template <> struct MDNodeKeyImpl<DITemplateValueParameter> {
1176 unsigned Tag;
1177 MDString *Name;
1178 Metadata *Type;
1179 bool IsDefault;
1180 Metadata *Value;
1181
1182 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *Type, bool IsDefault,
1183 Metadata *Value)
1184 : Tag(Tag), Name(Name), Type(Type), IsDefault(IsDefault), Value(Value) {}
1185 MDNodeKeyImpl(const DITemplateValueParameter *N)
1186 : Tag(N->getTag()), Name(N->getRawName()), Type(N->getRawType()),
1187 IsDefault(N->isDefault()), Value(N->getValue()) {}
1188
1189 bool isKeyOf(const DITemplateValueParameter *RHS) const {
1190 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
1191 Type == RHS->getRawType() && IsDefault == RHS->isDefault() &&
1192 Value == RHS->getValue();
1193 }
1194
1195 unsigned getHashValue() const {
1196 return hash_combine(args: Tag, args: Name, args: Type, args: IsDefault, args: Value);
1197 }
1198};
1199
1200template <> struct MDNodeKeyImpl<DIGlobalVariable> {
1201 Metadata *Scope;
1202 MDString *Name;
1203 MDString *LinkageName;
1204 Metadata *File;
1205 unsigned Line;
1206 Metadata *Type;
1207 bool IsLocalToUnit;
1208 bool IsDefinition;
1209 Metadata *StaticDataMemberDeclaration;
1210 Metadata *TemplateParams;
1211 uint32_t AlignInBits;
1212 Metadata *Annotations;
1213
1214 MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
1215 Metadata *File, unsigned Line, Metadata *Type,
1216 bool IsLocalToUnit, bool IsDefinition,
1217 Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
1218 uint32_t AlignInBits, Metadata *Annotations)
1219 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
1220 Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit),
1221 IsDefinition(IsDefinition),
1222 StaticDataMemberDeclaration(StaticDataMemberDeclaration),
1223 TemplateParams(TemplateParams), AlignInBits(AlignInBits),
1224 Annotations(Annotations) {}
1225 MDNodeKeyImpl(const DIGlobalVariable *N)
1226 : Scope(N->getRawScope()), Name(N->getRawName()),
1227 LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
1228 Line(N->getLine()), Type(N->getRawType()),
1229 IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
1230 StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()),
1231 TemplateParams(N->getRawTemplateParams()),
1232 AlignInBits(N->getAlignInBits()), Annotations(N->getRawAnnotations()) {}
1233
1234 bool isKeyOf(const DIGlobalVariable *RHS) const {
1235 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1236 LinkageName == RHS->getRawLinkageName() &&
1237 File == RHS->getRawFile() && Line == RHS->getLine() &&
1238 Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() &&
1239 IsDefinition == RHS->isDefinition() &&
1240 StaticDataMemberDeclaration ==
1241 RHS->getRawStaticDataMemberDeclaration() &&
1242 TemplateParams == RHS->getRawTemplateParams() &&
1243 AlignInBits == RHS->getAlignInBits() &&
1244 Annotations == RHS->getRawAnnotations();
1245 }
1246
1247 unsigned getHashValue() const {
1248 // We do not use AlignInBits in hashing function here on purpose:
1249 // in most cases this param for local variable is zero (for function param
1250 // it is always zero). This leads to lots of hash collisions and errors on
1251 // cases with lots of similar variables.
1252 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1253 // generated IR is random for each run and test fails with Align included.
1254 // TODO: make hashing work fine with such situations
1255 return hash_combine(args: Scope, args: Name, args: LinkageName, args: File, args: Line, args: Type,
1256 args: IsLocalToUnit, args: IsDefinition, /* AlignInBits, */
1257 args: StaticDataMemberDeclaration, args: Annotations);
1258 }
1259};
1260
1261template <> struct MDNodeKeyImpl<DILocalVariable> {
1262 Metadata *Scope;
1263 MDString *Name;
1264 Metadata *File;
1265 unsigned Line;
1266 Metadata *Type;
1267 unsigned Arg;
1268 unsigned Flags;
1269 uint32_t AlignInBits;
1270 Metadata *Annotations;
1271
1272 MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line,
1273 Metadata *Type, unsigned Arg, unsigned Flags,
1274 uint32_t AlignInBits, Metadata *Annotations)
1275 : Scope(Scope), Name(Name), File(File), Line(Line), Type(Type), Arg(Arg),
1276 Flags(Flags), AlignInBits(AlignInBits), Annotations(Annotations) {}
1277 MDNodeKeyImpl(const DILocalVariable *N)
1278 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1279 Line(N->getLine()), Type(N->getRawType()), Arg(N->getArg()),
1280 Flags(N->getFlags()), AlignInBits(N->getAlignInBits()),
1281 Annotations(N->getRawAnnotations()) {}
1282
1283 bool isKeyOf(const DILocalVariable *RHS) const {
1284 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1285 File == RHS->getRawFile() && Line == RHS->getLine() &&
1286 Type == RHS->getRawType() && Arg == RHS->getArg() &&
1287 Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits() &&
1288 Annotations == RHS->getRawAnnotations();
1289 }
1290
1291 unsigned getHashValue() const {
1292 // We do not use AlignInBits in hashing function here on purpose:
1293 // in most cases this param for local variable is zero (for function param
1294 // it is always zero). This leads to lots of hash collisions and errors on
1295 // cases with lots of similar variables.
1296 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
1297 // generated IR is random for each run and test fails with Align included.
1298 // TODO: make hashing work fine with such situations
1299 return hash_combine(args: Scope, args: Name, args: File, args: Line, args: Type, args: Arg, args: Flags, args: Annotations);
1300 }
1301};
1302
1303template <> struct MDNodeKeyImpl<DILabel> {
1304 Metadata *Scope;
1305 MDString *Name;
1306 Metadata *File;
1307 unsigned Line;
1308 unsigned Column;
1309 bool IsArtificial;
1310 std::optional<unsigned> CoroSuspendIdx;
1311
1312 MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line,
1313 unsigned Column, bool IsArtificial,
1314 std::optional<unsigned> CoroSuspendIdx)
1315 : Scope(Scope), Name(Name), File(File), Line(Line), Column(Column),
1316 IsArtificial(IsArtificial), CoroSuspendIdx(CoroSuspendIdx) {}
1317 MDNodeKeyImpl(const DILabel *N)
1318 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
1319 Line(N->getLine()), Column(N->getColumn()),
1320 IsArtificial(N->isArtificial()),
1321 CoroSuspendIdx(N->getCoroSuspendIdx()) {}
1322
1323 bool isKeyOf(const DILabel *RHS) const {
1324 return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
1325 File == RHS->getRawFile() && Line == RHS->getLine() &&
1326 Column == RHS->getColumn() && IsArtificial == RHS->isArtificial() &&
1327 CoroSuspendIdx == RHS->getCoroSuspendIdx();
1328 }
1329
1330 /// Using name and line to get hash value. It should already be mostly unique.
1331 unsigned getHashValue() const {
1332 return hash_combine(args: Scope, args: Name, args: Line, args: Column, args: IsArtificial,
1333 args: CoroSuspendIdx);
1334 }
1335};
1336
1337template <> struct MDNodeKeyImpl<DIExpression> {
1338 ArrayRef<uint64_t> Elements;
1339
1340 MDNodeKeyImpl(ArrayRef<uint64_t> Elements) : Elements(Elements) {}
1341 MDNodeKeyImpl(const DIExpression *N) : Elements(N->getElements()) {}
1342
1343 bool isKeyOf(const DIExpression *RHS) const {
1344 return Elements == RHS->getElements();
1345 }
1346
1347 unsigned getHashValue() const { return hash_combine_range(R: Elements); }
1348};
1349
1350template <> struct MDNodeKeyImpl<DIGlobalVariableExpression> {
1351 Metadata *Variable;
1352 Metadata *Expression;
1353
1354 MDNodeKeyImpl(Metadata *Variable, Metadata *Expression)
1355 : Variable(Variable), Expression(Expression) {}
1356 MDNodeKeyImpl(const DIGlobalVariableExpression *N)
1357 : Variable(N->getRawVariable()), Expression(N->getRawExpression()) {}
1358
1359 bool isKeyOf(const DIGlobalVariableExpression *RHS) const {
1360 return Variable == RHS->getRawVariable() &&
1361 Expression == RHS->getRawExpression();
1362 }
1363
1364 unsigned getHashValue() const { return hash_combine(args: Variable, args: Expression); }
1365};
1366
1367template <> struct MDNodeKeyImpl<DIObjCProperty> {
1368 MDString *Name;
1369 Metadata *File;
1370 unsigned Line;
1371 MDString *GetterName;
1372 MDString *SetterName;
1373 unsigned Attributes;
1374 Metadata *Type;
1375
1376 MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line,
1377 MDString *GetterName, MDString *SetterName, unsigned Attributes,
1378 Metadata *Type)
1379 : Name(Name), File(File), Line(Line), GetterName(GetterName),
1380 SetterName(SetterName), Attributes(Attributes), Type(Type) {}
1381 MDNodeKeyImpl(const DIObjCProperty *N)
1382 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
1383 GetterName(N->getRawGetterName()), SetterName(N->getRawSetterName()),
1384 Attributes(N->getAttributes()), Type(N->getRawType()) {}
1385
1386 bool isKeyOf(const DIObjCProperty *RHS) const {
1387 return Name == RHS->getRawName() && File == RHS->getRawFile() &&
1388 Line == RHS->getLine() && GetterName == RHS->getRawGetterName() &&
1389 SetterName == RHS->getRawSetterName() &&
1390 Attributes == RHS->getAttributes() && Type == RHS->getRawType();
1391 }
1392
1393 unsigned getHashValue() const {
1394 return hash_combine(args: Name, args: File, args: Line, args: GetterName, args: SetterName, args: Attributes,
1395 args: Type);
1396 }
1397};
1398
1399template <> struct MDNodeKeyImpl<DIImportedEntity> {
1400 unsigned Tag;
1401 Metadata *Scope;
1402 Metadata *Entity;
1403 Metadata *File;
1404 unsigned Line;
1405 MDString *Name;
1406 Metadata *Elements;
1407
1408 MDNodeKeyImpl(unsigned Tag, Metadata *Scope, Metadata *Entity, Metadata *File,
1409 unsigned Line, MDString *Name, Metadata *Elements)
1410 : Tag(Tag), Scope(Scope), Entity(Entity), File(File), Line(Line),
1411 Name(Name), Elements(Elements) {}
1412 MDNodeKeyImpl(const DIImportedEntity *N)
1413 : Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()),
1414 File(N->getRawFile()), Line(N->getLine()), Name(N->getRawName()),
1415 Elements(N->getRawElements()) {}
1416
1417 bool isKeyOf(const DIImportedEntity *RHS) const {
1418 return Tag == RHS->getTag() && Scope == RHS->getRawScope() &&
1419 Entity == RHS->getRawEntity() && File == RHS->getFile() &&
1420 Line == RHS->getLine() && Name == RHS->getRawName() &&
1421 Elements == RHS->getRawElements();
1422 }
1423
1424 unsigned getHashValue() const {
1425 return hash_combine(args: Tag, args: Scope, args: Entity, args: File, args: Line, args: Name, args: Elements);
1426 }
1427};
1428
1429template <> struct MDNodeKeyImpl<DIMacro> {
1430 unsigned MIType;
1431 unsigned Line;
1432 MDString *Name;
1433 MDString *Value;
1434
1435 MDNodeKeyImpl(unsigned MIType, unsigned Line, MDString *Name, MDString *Value)
1436 : MIType(MIType), Line(Line), Name(Name), Value(Value) {}
1437 MDNodeKeyImpl(const DIMacro *N)
1438 : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getRawName()),
1439 Value(N->getRawValue()) {}
1440
1441 bool isKeyOf(const DIMacro *RHS) const {
1442 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1443 Name == RHS->getRawName() && Value == RHS->getRawValue();
1444 }
1445
1446 unsigned getHashValue() const {
1447 return hash_combine(args: MIType, args: Line, args: Name, args: Value);
1448 }
1449};
1450
1451template <> struct MDNodeKeyImpl<DIMacroFile> {
1452 unsigned MIType;
1453 unsigned Line;
1454 Metadata *File;
1455 Metadata *Elements;
1456
1457 MDNodeKeyImpl(unsigned MIType, unsigned Line, Metadata *File,
1458 Metadata *Elements)
1459 : MIType(MIType), Line(Line), File(File), Elements(Elements) {}
1460 MDNodeKeyImpl(const DIMacroFile *N)
1461 : MIType(N->getMacinfoType()), Line(N->getLine()), File(N->getRawFile()),
1462 Elements(N->getRawElements()) {}
1463
1464 bool isKeyOf(const DIMacroFile *RHS) const {
1465 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
1466 File == RHS->getRawFile() && Elements == RHS->getRawElements();
1467 }
1468
1469 unsigned getHashValue() const {
1470 return hash_combine(args: MIType, args: Line, args: File, args: Elements);
1471 }
1472};
1473
1474// DIArgLists are not MDNodes, but we still want to unique them in a DenseSet
1475// based on a hash of their arguments.
1476struct DIArgListKeyInfo {
1477 ArrayRef<ValueAsMetadata *> Args;
1478
1479 DIArgListKeyInfo(ArrayRef<ValueAsMetadata *> Args) : Args(Args) {}
1480 DIArgListKeyInfo(const DIArgList *N) : Args(N->getArgs()) {}
1481
1482 bool isKeyOf(const DIArgList *RHS) const { return Args == RHS->getArgs(); }
1483
1484 unsigned getHashValue() const { return hash_combine_range(R: Args); }
1485};
1486
1487/// DenseMapInfo for DIArgList.
1488struct DIArgListInfo {
1489 using KeyTy = DIArgListKeyInfo;
1490
1491 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1492
1493 static unsigned getHashValue(const DIArgList *N) {
1494 return KeyTy(N).getHashValue();
1495 }
1496
1497 static bool isEqual(const KeyTy &LHS, const DIArgList *RHS) {
1498 return LHS.isKeyOf(RHS);
1499 }
1500
1501 static bool isEqual(const DIArgList *LHS, const DIArgList *RHS) {
1502 return LHS == RHS;
1503 }
1504};
1505
1506/// DenseMapInfo for MDNode subclasses.
1507template <class NodeTy> struct MDNodeInfo {
1508 using KeyTy = MDNodeKeyImpl<NodeTy>;
1509 using SubsetEqualTy = MDNodeSubsetEqualImpl<NodeTy>;
1510
1511 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
1512
1513 static unsigned getHashValue(const NodeTy *N) {
1514 return KeyTy(N).getHashValue();
1515 }
1516
1517 static bool isEqual(const KeyTy &LHS, const NodeTy *RHS) {
1518 return SubsetEqualTy::isSubsetEqual(LHS, RHS) || LHS.isKeyOf(RHS);
1519 }
1520
1521 static bool isEqual(const NodeTy *LHS, const NodeTy *RHS) {
1522 if (LHS == RHS)
1523 return true;
1524 return SubsetEqualTy::isSubsetEqual(LHS, RHS);
1525 }
1526};
1527
1528#define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>;
1529#include "llvm/IR/Metadata.def"
1530
1531/// Single metadata attachment, forms linked list ended by index 0.
1532struct MDAttachment {
1533 unsigned Next = 0;
1534 unsigned MDKind;
1535 TrackingMDNodeRef Node;
1536};
1537
1538class LLVMContextImpl {
1539public:
1540 /// OwnedModules - The set of modules instantiated in this context, and which
1541 /// will be automatically deleted if this context is deleted.
1542 SmallPtrSet<Module *, 4> OwnedModules;
1543
1544 /// MachineFunctionNums - Keep the next available unique number available for
1545 /// a MachineFunction in given module. Module must in OwnedModules.
1546 DenseMap<Module *, unsigned> MachineFunctionNums;
1547
1548 /// The main remark streamer used by all the other streamers (e.g. IR, MIR,
1549 /// frontends, etc.). This should only be used by the specific streamers, and
1550 /// never directly.
1551 std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer;
1552
1553 std::unique_ptr<DiagnosticHandler> DiagHandler;
1554 bool RespectDiagnosticFilters = false;
1555 bool DiagnosticsHotnessRequested = false;
1556 /// The minimum hotness value a diagnostic needs in order to be included in
1557 /// optimization diagnostics.
1558 ///
1559 /// The threshold is an Optional value, which maps to one of the 3 states:
1560 /// 1). 0 => threshold disabled. All emarks will be printed.
1561 /// 2). positive int => manual threshold by user. Remarks with hotness exceed
1562 /// threshold will be printed.
1563 /// 3). None => 'auto' threshold by user. The actual value is not
1564 /// available at command line, but will be synced with
1565 /// hotness threhold from profile summary during
1566 /// compilation.
1567 ///
1568 /// State 1 and 2 are considered as terminal states. State transition is
1569 /// only allowed from 3 to 2, when the threshold is first synced with profile
1570 /// summary. This ensures that the threshold is set only once and stays
1571 /// constant.
1572 ///
1573 /// If threshold option is not specified, it is disabled (0) by default.
1574 std::optional<uint64_t> DiagnosticsHotnessThreshold = 0;
1575
1576 /// The percentage of difference between profiling branch weights and
1577 /// llvm.expect branch weights to tolerate when emiting MisExpect diagnostics
1578 std::optional<uint32_t> DiagnosticsMisExpectTolerance = 0;
1579 bool MisExpectWarningRequested = false;
1580
1581 /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
1582 std::unique_ptr<LLVMRemarkStreamer> LLVMRS;
1583
1584 LLVMContext::YieldCallbackTy YieldCallback = nullptr;
1585 void *YieldOpaqueHandle = nullptr;
1586
1587 DenseMap<const Value *, ValueName *> ValueNames;
1588
1589 DenseMap<unsigned, std::unique_ptr<ConstantInt>> IntZeroConstants;
1590 DenseMap<unsigned, std::unique_ptr<ConstantInt>> IntOneConstants;
1591 DenseMap<APInt, std::unique_ptr<ConstantInt>> IntConstants;
1592 DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantInt>>
1593 IntSplatConstants;
1594
1595 DenseMap<unsigned, std::unique_ptr<ConstantByte>> ByteZeroConstants;
1596 DenseMap<unsigned, std::unique_ptr<ConstantByte>> ByteOneConstants;
1597 DenseMap<APInt, std::unique_ptr<ConstantByte>> ByteConstants;
1598 DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantByte>>
1599 ByteSplatConstants;
1600
1601 DenseMap<APFloat, std::unique_ptr<ConstantFP>> FPConstants;
1602 DenseMap<std::pair<ElementCount, APFloat>, std::unique_ptr<ConstantFP>>
1603 FPSplatConstants;
1604
1605 FoldingSet<AttributeImpl> AttrsSet;
1606 FoldingSet<AttributeListImpl> AttrsLists;
1607 FoldingSet<AttributeSetNode> AttrsSetNodes;
1608
1609 StringMap<MDString, BumpPtrAllocator> MDStringCache;
1610 DenseMap<Value *, ValueAsMetadata *> ValuesAsMetadata;
1611 DenseMap<Metadata *, MetadataAsValue *> MetadataAsValues;
1612 DenseSet<DIArgList *, DIArgListInfo> DIArgLists;
1613
1614#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
1615 DenseSet<CLASS *, CLASS##Info> CLASS##s;
1616#include "llvm/IR/Metadata.def"
1617
1618 // Optional map for looking up composite types by identifier.
1619 std::optional<DenseMap<const MDString *, DICompositeType *>> DITypeMap;
1620
1621 // MDNodes may be uniqued or not uniqued. When they're not uniqued, they
1622 // aren't in the MDNodeSet, but they're still shared between objects, so no
1623 // one object can destroy them. Keep track of them here so we can delete
1624 // them on context teardown.
1625 std::vector<MDNode *> DistinctMDNodes;
1626
1627 // ConstantRangeListAttributeImpl is a TrailingObjects/ArrayRef of
1628 // ConstantRange. Since this is a dynamically sized class, it's not
1629 // possible to use SpecificBumpPtrAllocator. Instead, we use normal Alloc
1630 // for allocation and record all allocated pointers in this vector. In the
1631 // LLVMContext destructor, call the destuctors of everything in the vector.
1632 std::vector<ConstantRangeListAttributeImpl *> ConstantRangeListAttributes;
1633
1634 DenseMap<Type *, std::unique_ptr<ConstantAggregateZero>> CAZConstants;
1635
1636 using ArrayConstantsTy = ConstantUniqueMap<ConstantArray>;
1637 ArrayConstantsTy ArrayConstants;
1638
1639 using StructConstantsTy = ConstantUniqueMap<ConstantStruct>;
1640 StructConstantsTy StructConstants;
1641
1642 using VectorConstantsTy = ConstantUniqueMap<ConstantVector>;
1643 VectorConstantsTy VectorConstants;
1644
1645 DenseMap<Type *, std::unique_ptr<ConstantPointerNull>> CPNConstants;
1646
1647 DenseMap<TargetExtType *, std::unique_ptr<ConstantTargetNone>> CTNConstants;
1648
1649 DenseMap<Type *, std::unique_ptr<UndefValue>> UVConstants;
1650
1651 DenseMap<Type *, std::unique_ptr<PoisonValue>> PVConstants;
1652
1653 StringMap<std::unique_ptr<ConstantDataSequential>> CDSConstants;
1654
1655 DenseMap<const BasicBlock *, BlockAddress *> BlockAddresses;
1656
1657 DenseMap<const GlobalValue *, DSOLocalEquivalent *> DSOLocalEquivalents;
1658
1659 DenseMap<const GlobalValue *, NoCFIValue *> NoCFIValues;
1660
1661 ConstantUniqueMap<ConstantPtrAuth> ConstantPtrAuths;
1662
1663 ConstantUniqueMap<ConstantExpr> ExprConstants;
1664
1665 ConstantUniqueMap<InlineAsm> InlineAsms;
1666
1667 ConstantInt *TheTrueVal = nullptr;
1668 ConstantInt *TheFalseVal = nullptr;
1669
1670 ConstantByte *TheTrueByteVal = nullptr;
1671 ConstantByte *TheFalseByteVal = nullptr;
1672
1673 // Basic type instances.
1674 Type VoidTy, LabelTy, HalfTy, BFloatTy, FloatTy, DoubleTy, MetadataTy,
1675 TokenTy;
1676 Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_AMXTy;
1677 IntegerType Int1Ty, Int8Ty, Int16Ty, Int32Ty, Int64Ty, Int128Ty;
1678 ByteType Byte1Ty, Byte8Ty, Byte16Ty, Byte32Ty, Byte64Ty, Byte128Ty;
1679
1680 std::unique_ptr<ConstantTokenNone> TheNoneToken;
1681
1682 BumpPtrAllocator Alloc;
1683 UniqueStringSaver Saver{Alloc};
1684 SpecificBumpPtrAllocator<ConstantRangeAttributeImpl>
1685 ConstantRangeAttributeAlloc;
1686
1687 DenseMap<unsigned, ByteType *> ByteTypes;
1688 DenseMap<unsigned, IntegerType *> IntegerTypes;
1689
1690 using FunctionTypeSet = DenseSet<FunctionType *, FunctionTypeKeyInfo>;
1691 FunctionTypeSet FunctionTypes;
1692 using StructTypeSet = DenseSet<StructType *, AnonStructTypeKeyInfo>;
1693 StructTypeSet AnonStructTypes;
1694 StringMap<StructType *> NamedStructTypes;
1695 unsigned NamedStructTypesUniqueID = 0;
1696
1697 using TargetExtTypeSet = DenseSet<TargetExtType *, TargetExtTypeKeyInfo>;
1698 TargetExtTypeSet TargetExtTypes;
1699
1700 DenseMap<std::pair<Type *, uint64_t>, ArrayType *> ArrayTypes;
1701 DenseMap<std::pair<Type *, ElementCount>, VectorType *> VectorTypes;
1702 PointerType *AS0PointerType = nullptr; // AddrSpace = 0
1703 DenseMap<unsigned, PointerType *> PointerTypes;
1704 DenseMap<std::pair<Type *, unsigned>, TypedPointerType *> ASTypedPointerTypes;
1705
1706 /// ValueHandles - This map keeps track of all of the value handles that are
1707 /// watching a Value*. The Value::HasValueHandle bit is used to know
1708 /// whether or not a value has an entry in this map.
1709 using ValueHandlesTy = DenseMap<Value *, ValueHandleBase *>;
1710 ValueHandlesTy ValueHandles;
1711
1712 /// CustomMDKindNames - Map to hold the metadata string to ID mapping.
1713 StringMap<unsigned> CustomMDKindNames;
1714
1715 /// Collection of metadata attachments in this context.
1716 SmallVector<MDAttachment, 0> Metadatas;
1717 /// Index of first free Metadatas entry, linked list via MDAttachment::Next.
1718 unsigned MetadataRecycleHead = 0;
1719 /// Number of currently unused metadata entries. Only used/updated in debug
1720 /// builds to ensure that all metadata attachments are properly freed.
1721 unsigned MetadataRecycleSize = 0;
1722
1723 /// Map DIAssignID -> Instructions with that attachment.
1724 /// Managed by Instruction via Instruction::updateDIAssignIDMapping.
1725 /// Query using the at:: functions defined in DebugInfo.h.
1726 DenseMap<DIAssignID *, SmallVector<Instruction *, 1>> AssignmentIDToInstrs;
1727
1728 /// Collection of per-GlobalObject sections used in this context.
1729 DenseMap<const GlobalObject *, StringRef> GlobalObjectSections;
1730
1731 /// Collection of per-GlobalValue partitions used in this context.
1732 DenseMap<const GlobalValue *, StringRef> GlobalValuePartitions;
1733
1734 DenseMap<const GlobalValue *, GlobalValue::SanitizerMetadata>
1735 GlobalValueSanitizerMetadata;
1736
1737 /// DiscriminatorTable - This table maps file:line locations to an
1738 /// integer representing the next DWARF path discriminator to assign to
1739 /// instructions in different blocks at the same location.
1740 DenseMap<std::pair<const char *, unsigned>, unsigned> DiscriminatorTable;
1741
1742 /// A set of interned tags for operand bundles. The StringMap maps
1743 /// bundle tags to their IDs.
1744 ///
1745 /// \see LLVMContext::getOperandBundleTagID
1746 StringMap<uint32_t> BundleTagCache;
1747
1748 StringMapEntry<uint32_t> *getOrInsertBundleTag(StringRef Tag);
1749 void getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const;
1750 uint32_t getOperandBundleTagID(StringRef Tag) const;
1751
1752 /// A set of interned synchronization scopes. The StringMap maps
1753 /// synchronization scope names to their respective synchronization scope IDs.
1754 StringMap<SyncScope::ID> SSC;
1755
1756 /// getOrInsertSyncScopeID - Maps synchronization scope name to
1757 /// synchronization scope ID. Every synchronization scope registered with
1758 /// LLVMContext has unique ID except pre-defined ones.
1759 SyncScope::ID getOrInsertSyncScopeID(StringRef SSN);
1760
1761 /// getSyncScopeNames - Populates client supplied SmallVector with
1762 /// synchronization scope names registered with LLVMContext. Synchronization
1763 /// scope names are ordered by increasing synchronization scope IDs.
1764 void getSyncScopeNames(SmallVectorImpl<StringRef> &SSNs) const;
1765
1766 /// getSyncScopeName - Returns the name of a SyncScope::ID
1767 /// registered with LLVMContext, if any.
1768 std::optional<StringRef> getSyncScopeName(SyncScope::ID Id) const;
1769
1770 /// Maintain the GC name for each function.
1771 ///
1772 /// This saves allocating an additional word in Function for programs which
1773 /// do not use GC (i.e., most programs) at the cost of increased overhead for
1774 /// clients which do use GC.
1775 DenseMap<const Function *, std::string> GCNames;
1776
1777 /// Flag to indicate if Value (other than GlobalValue) retains their name or
1778 /// not.
1779 bool DiscardValueNames = false;
1780
1781 LLVMContextImpl(LLVMContext &C);
1782 ~LLVMContextImpl();
1783
1784 mutable OptPassGate *OPG = nullptr;
1785
1786 /// Access the object which can disable optional passes and individual
1787 /// optimizations at compile time.
1788 OptPassGate &getOptPassGate() const;
1789
1790 /// Set the object which can disable optional passes and individual
1791 /// optimizations at compile time.
1792 ///
1793 /// The lifetime of the object must be guaranteed to extend as long as the
1794 /// LLVMContext is used by compilation.
1795 void setOptPassGate(OptPassGate &);
1796
1797 /// Mapping of blocks to collections of "trailing" DbgVariableRecords. As part
1798 /// of the "RemoveDIs" project, debug-info variable location records are going
1799 /// to cease being instructions... which raises the problem of where should
1800 /// they be recorded when we remove the terminator of a blocks, such as:
1801 ///
1802 /// %foo = add i32 0, 0
1803 /// br label %bar
1804 ///
1805 /// If the branch is removed, a legitimate transient state while editing a
1806 /// block, any debug-records between those two instructions will not have a
1807 /// location. Each block thus records any DbgVariableRecord records that
1808 /// "trail" in such a way. These are stored in LLVMContext because typically
1809 /// LLVM only edits a small number of blocks at a time, so there's no need to
1810 /// bloat BasicBlock with such a data structure.
1811 SmallDenseMap<BasicBlock *, DbgMarker *> TrailingDbgRecords;
1812
1813 // Set, get and delete operations for TrailingDbgRecords.
1814 void setTrailingDbgRecords(BasicBlock *B, DbgMarker *M) {
1815 assert(!TrailingDbgRecords.count(B));
1816 TrailingDbgRecords[B] = M;
1817 }
1818
1819 DbgMarker *getTrailingDbgRecords(BasicBlock *B) {
1820 return TrailingDbgRecords.lookup(Val: B);
1821 }
1822
1823 void deleteTrailingDbgRecords(BasicBlock *B) { TrailingDbgRecords.erase(Val: B); }
1824
1825 std::string DefaultTargetCPU;
1826 std::string DefaultTargetFeatures;
1827
1828 /// The next available source atom group number. The front end is responsible
1829 /// for assigning source atom numbers, but certain optimisations need to
1830 /// assign new group numbers to a set of instructions. Most often code
1831 /// duplication optimisations like loop unroll. Tracking a global maximum
1832 /// value means we can know (cheaply) we're never using a group number that's
1833 /// already used within this function.
1834 ///
1835 /// Start a 1 because 0 means the source location isn't part of an atom group.
1836 uint64_t NextAtomGroup = 1;
1837};
1838
1839} // end namespace llvm
1840
1841#endif // LLVM_LIB_IR_LLVMCONTEXTIMPL_H
1842