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 53 namespace llvm { 54 55 class AttributeImpl; 56 class AttributeListImpl; 57 class AttributeSetNode; 58 class BasicBlock; 59 struct DiagnosticHandler; 60 class ElementCount; 61 class Function; 62 class GlobalObject; 63 class GlobalValue; 64 class InlineAsm; 65 class LLVMRemarkStreamer; 66 class OptPassGate; 67 namespace remarks { 68 class RemarkStreamer; 69 } 70 template <typename T> class StringMapEntry; 71 class StringRef; 72 class TypedPointerType; 73 class ValueHandleBase; 74 75 using DenseMapAPIntKeyInfo = DenseMapInfo<APInt>; 76 77 struct DenseMapAPFloatKeyInfo { 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 92 struct AnonStructTypeKeyInfo { 93 struct KeyTy { 94 ArrayRef<Type *> ETypes; 95 bool isPacked; 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() { 113 return DenseMapInfo<StructType *>::getEmptyKey(); 114 } 115 116 static inline StructType *getTombstoneKey() { 117 return DenseMapInfo<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 140 struct FunctionTypeKeyInfo { 141 struct KeyTy { 142 const Type *ReturnType; 143 ArrayRef<Type *> Params; 144 bool isVarArg; 145 146 KeyTy(const Type *R, const ArrayRef<Type *> &P, bool V) 147 : ReturnType(R), Params(P), isVarArg(V) {} 148 KeyTy(const FunctionType *FT) 149 : ReturnType(FT->getReturnType()), Params(FT->params()), 150 isVarArg(FT->isVarArg()) {} 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() { 165 return DenseMapInfo<FunctionType *>::getEmptyKey(); 166 } 167 168 static inline FunctionType *getTombstoneKey() { 169 return DenseMapInfo<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 193 struct TargetExtTypeKeyInfo { 194 struct KeyTy { 195 StringRef Name; 196 ArrayRef<Type *> TypeParams; 197 ArrayRef<unsigned> IntParams; 198 199 KeyTy(StringRef N, const ArrayRef<Type *> &TP, const ArrayRef<unsigned> &IP) 200 : Name(N), TypeParams(TP), IntParams(IP) {} 201 KeyTy(const TargetExtType *TT) 202 : Name(TT->getName()), TypeParams(TT->type_params()), 203 IntParams(TT->int_params()) {} 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() { 213 return DenseMapInfo<TargetExtType *>::getEmptyKey(); 214 } 215 216 static inline TargetExtType *getTombstoneKey() { 217 return DenseMapInfo<TargetExtType *>::getTombstoneKey(); 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. 243 class MDNodeOpsKey { 244 ArrayRef<Metadata *> RawOps; 245 ArrayRef<MDOperand> Ops; 246 unsigned Hash; 247 248 protected: 249 MDNodeOpsKey(ArrayRef<Metadata *> Ops) 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 268 private: 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 278 public: 279 unsigned getHash() const { return Hash; } 280 }; 281 282 template <class NodeTy> struct MDNodeKeyImpl; 283 284 /// Configuration point for MDNodeInfo::isEqual(). 285 template <class NodeTy> struct MDNodeSubsetEqualImpl { 286 using KeyTy = MDNodeKeyImpl<NodeTy>; 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. 301 template <> struct MDNodeKeyImpl<MDTuple> : MDNodeOpsKey { 302 MDNodeKeyImpl(ArrayRef<Metadata *> Ops) : MDNodeOpsKey(Ops) {} 303 MDNodeKeyImpl(const MDTuple *N) : MDNodeOpsKey(N) {} 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) { 310 return MDNodeOpsKey::calculateHash(N); 311 } 312 }; 313 314 /// DenseMapInfo for DILocation. 315 template <> struct MDNodeKeyImpl<DILocation> { 316 unsigned Line; 317 unsigned Column; 318 Metadata *Scope; 319 Metadata *InlinedAt; 320 bool ImplicitCode; 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) {} 326 MDNodeKeyImpl(const DILocation *L) 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. 342 template <> struct MDNodeKeyImpl<GenericDINode> : MDNodeOpsKey { 343 unsigned Tag; 344 MDString *Header; 345 346 MDNodeKeyImpl(unsigned Tag, MDString *Header, ArrayRef<Metadata *> DwarfOps) 347 : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {} 348 MDNodeKeyImpl(const GenericDINode *N) 349 : MDNodeOpsKey(N, 1), Tag(N->getTag()), Header(N->getRawHeader()) {} 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) { 359 return MDNodeOpsKey::calculateHash(N, 1); 360 } 361 }; 362 363 template <> struct MDNodeKeyImpl<DISubrange> { 364 Metadata *CountNode; 365 Metadata *LowerBound; 366 Metadata *UpperBound; 367 Metadata *Stride; 368 369 MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound, 370 Metadata *Stride) 371 : CountNode(CountNode), LowerBound(LowerBound), UpperBound(UpperBound), 372 Stride(Stride) {} 373 MDNodeKeyImpl(const DISubrange *N) 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 408 template <> struct MDNodeKeyImpl<DIGenericSubrange> { 409 Metadata *CountNode; 410 Metadata *LowerBound; 411 Metadata *UpperBound; 412 Metadata *Stride; 413 414 MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound, 415 Metadata *Stride) 416 : CountNode(CountNode), LowerBound(LowerBound), UpperBound(UpperBound), 417 Stride(Stride) {} 418 MDNodeKeyImpl(const DIGenericSubrange *N) 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 438 template <> struct MDNodeKeyImpl<DIEnumerator> { 439 APInt Value; 440 MDString *Name; 441 bool IsUnsigned; 442 443 MDNodeKeyImpl(APInt Value, bool IsUnsigned, MDString *Name) 444 : Value(Value), Name(Name), IsUnsigned(IsUnsigned) {} 445 MDNodeKeyImpl(int64_t Value, bool IsUnsigned, MDString *Name) 446 : Value(APInt(64, Value, !IsUnsigned)), Name(Name), 447 IsUnsigned(IsUnsigned) {} 448 MDNodeKeyImpl(const DIEnumerator *N) 449 : Value(N->getValue()), Name(N->getRawName()), 450 IsUnsigned(N->isUnsigned()) {} 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 461 template <> struct MDNodeKeyImpl<DIBasicType> { 462 unsigned Tag; 463 MDString *Name; 464 uint64_t SizeInBits; 465 uint32_t AlignInBits; 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) {} 473 MDNodeKeyImpl(const DIBasicType *N) 474 : Tag(N->getTag()), Name(N->getRawName()), SizeInBits(N->getSizeInBits()), 475 AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()), 476 Flags(N->getFlags()) {} 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 490 template <> struct MDNodeKeyImpl<DIStringType> { 491 unsigned Tag; 492 MDString *Name; 493 Metadata *StringLength; 494 Metadata *StringLengthExp; 495 Metadata *StringLocationExp; 496 uint64_t SizeInBits; 497 uint32_t AlignInBits; 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) {} 506 MDNodeKeyImpl(const DIStringType *N) 507 : Tag(N->getTag()), Name(N->getRawName()), 508 StringLength(N->getRawStringLength()), 509 StringLengthExp(N->getRawStringLengthExp()), 510 StringLocationExp(N->getRawStringLocationExp()), 511 SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()), 512 Encoding(N->getEncoding()) {} 513 514 bool isKeyOf(const DIStringType *RHS) const { 515 return Tag == RHS->getTag() && Name == RHS->getRawName() && 516 SizeInBits == RHS->getSizeInBits() && 517 AlignInBits == RHS->getAlignInBits() && 518 Encoding == RHS->getEncoding(); 519 } 520 unsigned getHashValue() const { return hash_combine(Tag, Name, Encoding); } 521 }; 522 523 template <> struct MDNodeKeyImpl<DIDerivedType> { 524 unsigned Tag; 525 MDString *Name; 526 Metadata *File; 527 unsigned Line; 528 Metadata *Scope; 529 Metadata *BaseType; 530 uint64_t SizeInBits; 531 uint64_t OffsetInBits; 532 uint32_t AlignInBits; 533 std::optional<unsigned> DWARFAddressSpace; 534 unsigned Flags; 535 Metadata *ExtraData; 536 Metadata *Annotations; 537 538 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, 539 Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, 540 uint32_t AlignInBits, uint64_t OffsetInBits, 541 std::optional<unsigned> DWARFAddressSpace, unsigned Flags, 542 Metadata *ExtraData, Metadata *Annotations) 543 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope), 544 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits), 545 AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace), 546 Flags(Flags), ExtraData(ExtraData), Annotations(Annotations) {} 547 MDNodeKeyImpl(const DIDerivedType *N) 548 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()), 549 Line(N->getLine()), Scope(N->getRawScope()), 550 BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()), 551 OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()), 552 DWARFAddressSpace(N->getDWARFAddressSpace()), Flags(N->getFlags()), 553 ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {} 554 555 bool isKeyOf(const DIDerivedType *RHS) const { 556 return Tag == RHS->getTag() && Name == RHS->getRawName() && 557 File == RHS->getRawFile() && Line == RHS->getLine() && 558 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() && 559 SizeInBits == RHS->getSizeInBits() && 560 AlignInBits == RHS->getAlignInBits() && 561 OffsetInBits == RHS->getOffsetInBits() && 562 DWARFAddressSpace == RHS->getDWARFAddressSpace() && 563 Flags == RHS->getFlags() && ExtraData == RHS->getRawExtraData() && 564 Annotations == RHS->getRawAnnotations(); 565 } 566 567 unsigned getHashValue() const { 568 // If this is a member inside an ODR type, only hash the type and the name. 569 // Otherwise the hash will be stronger than 570 // MDNodeSubsetEqualImpl::isODRMember(). 571 if (Tag == dwarf::DW_TAG_member && Name) 572 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope)) 573 if (CT->getRawIdentifier()) 574 return hash_combine(Name, Scope); 575 576 // Intentionally computes the hash on a subset of the operands for 577 // performance reason. The subset has to be significant enough to avoid 578 // collision "most of the time". There is no correctness issue in case of 579 // collision because of the full check above. 580 return hash_combine(Tag, Name, File, Line, Scope, BaseType, Flags); 581 } 582 }; 583 584 template <> struct MDNodeSubsetEqualImpl<DIDerivedType> { 585 using KeyTy = MDNodeKeyImpl<DIDerivedType>; 586 587 static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) { 588 return isODRMember(LHS.Tag, LHS.Scope, LHS.Name, RHS); 589 } 590 591 static bool isSubsetEqual(const DIDerivedType *LHS, 592 const DIDerivedType *RHS) { 593 return isODRMember(LHS->getTag(), LHS->getRawScope(), LHS->getRawName(), 594 RHS); 595 } 596 597 /// Subprograms compare equal if they declare the same function in an ODR 598 /// type. 599 static bool isODRMember(unsigned Tag, const Metadata *Scope, 600 const MDString *Name, const DIDerivedType *RHS) { 601 // Check whether the LHS is eligible. 602 if (Tag != dwarf::DW_TAG_member || !Name) 603 return false; 604 605 auto *CT = dyn_cast_or_null<DICompositeType>(Scope); 606 if (!CT || !CT->getRawIdentifier()) 607 return false; 608 609 // Compare to the RHS. 610 return Tag == RHS->getTag() && Name == RHS->getRawName() && 611 Scope == RHS->getRawScope(); 612 } 613 }; 614 615 template <> struct MDNodeKeyImpl<DICompositeType> { 616 unsigned Tag; 617 MDString *Name; 618 Metadata *File; 619 unsigned Line; 620 Metadata *Scope; 621 Metadata *BaseType; 622 uint64_t SizeInBits; 623 uint64_t OffsetInBits; 624 uint32_t AlignInBits; 625 unsigned Flags; 626 Metadata *Elements; 627 unsigned RuntimeLang; 628 Metadata *VTableHolder; 629 Metadata *TemplateParams; 630 MDString *Identifier; 631 Metadata *Discriminator; 632 Metadata *DataLocation; 633 Metadata *Associated; 634 Metadata *Allocated; 635 Metadata *Rank; 636 Metadata *Annotations; 637 638 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, 639 Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, 640 uint32_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, 641 Metadata *Elements, unsigned RuntimeLang, 642 Metadata *VTableHolder, Metadata *TemplateParams, 643 MDString *Identifier, Metadata *Discriminator, 644 Metadata *DataLocation, Metadata *Associated, 645 Metadata *Allocated, Metadata *Rank, Metadata *Annotations) 646 : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope), 647 BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits), 648 AlignInBits(AlignInBits), Flags(Flags), Elements(Elements), 649 RuntimeLang(RuntimeLang), VTableHolder(VTableHolder), 650 TemplateParams(TemplateParams), Identifier(Identifier), 651 Discriminator(Discriminator), DataLocation(DataLocation), 652 Associated(Associated), Allocated(Allocated), Rank(Rank), 653 Annotations(Annotations) {} 654 MDNodeKeyImpl(const DICompositeType *N) 655 : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()), 656 Line(N->getLine()), Scope(N->getRawScope()), 657 BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()), 658 OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()), 659 Flags(N->getFlags()), Elements(N->getRawElements()), 660 RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()), 661 TemplateParams(N->getRawTemplateParams()), 662 Identifier(N->getRawIdentifier()), 663 Discriminator(N->getRawDiscriminator()), 664 DataLocation(N->getRawDataLocation()), 665 Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()), 666 Rank(N->getRawRank()), Annotations(N->getRawAnnotations()) {} 667 668 bool isKeyOf(const DICompositeType *RHS) const { 669 return Tag == RHS->getTag() && Name == RHS->getRawName() && 670 File == RHS->getRawFile() && Line == RHS->getLine() && 671 Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() && 672 SizeInBits == RHS->getSizeInBits() && 673 AlignInBits == RHS->getAlignInBits() && 674 OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() && 675 Elements == RHS->getRawElements() && 676 RuntimeLang == RHS->getRuntimeLang() && 677 VTableHolder == RHS->getRawVTableHolder() && 678 TemplateParams == RHS->getRawTemplateParams() && 679 Identifier == RHS->getRawIdentifier() && 680 Discriminator == RHS->getRawDiscriminator() && 681 DataLocation == RHS->getRawDataLocation() && 682 Associated == RHS->getRawAssociated() && 683 Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() && 684 Annotations == RHS->getRawAnnotations(); 685 } 686 687 unsigned getHashValue() const { 688 // Intentionally computes the hash on a subset of the operands for 689 // performance reason. The subset has to be significant enough to avoid 690 // collision "most of the time". There is no correctness issue in case of 691 // collision because of the full check above. 692 return hash_combine(Name, File, Line, BaseType, Scope, Elements, 693 TemplateParams, Annotations); 694 } 695 }; 696 697 template <> struct MDNodeKeyImpl<DISubroutineType> { 698 unsigned Flags; 699 uint8_t CC; 700 Metadata *TypeArray; 701 702 MDNodeKeyImpl(unsigned Flags, uint8_t CC, Metadata *TypeArray) 703 : Flags(Flags), CC(CC), TypeArray(TypeArray) {} 704 MDNodeKeyImpl(const DISubroutineType *N) 705 : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()) {} 706 707 bool isKeyOf(const DISubroutineType *RHS) const { 708 return Flags == RHS->getFlags() && CC == RHS->getCC() && 709 TypeArray == RHS->getRawTypeArray(); 710 } 711 712 unsigned getHashValue() const { return hash_combine(Flags, CC, TypeArray); } 713 }; 714 715 template <> struct MDNodeKeyImpl<DIFile> { 716 MDString *Filename; 717 MDString *Directory; 718 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum; 719 MDString *Source; 720 721 MDNodeKeyImpl(MDString *Filename, MDString *Directory, 722 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum, 723 MDString *Source) 724 : Filename(Filename), Directory(Directory), Checksum(Checksum), 725 Source(Source) {} 726 MDNodeKeyImpl(const DIFile *N) 727 : Filename(N->getRawFilename()), Directory(N->getRawDirectory()), 728 Checksum(N->getRawChecksum()), Source(N->getRawSource()) {} 729 730 bool isKeyOf(const DIFile *RHS) const { 731 return Filename == RHS->getRawFilename() && 732 Directory == RHS->getRawDirectory() && 733 Checksum == RHS->getRawChecksum() && Source == RHS->getRawSource(); 734 } 735 736 unsigned getHashValue() const { 737 return hash_combine(Filename, Directory, Checksum ? Checksum->Kind : 0, 738 Checksum ? Checksum->Value : nullptr, Source); 739 } 740 }; 741 742 template <> struct MDNodeKeyImpl<DISubprogram> { 743 Metadata *Scope; 744 MDString *Name; 745 MDString *LinkageName; 746 Metadata *File; 747 unsigned Line; 748 Metadata *Type; 749 unsigned ScopeLine; 750 Metadata *ContainingType; 751 unsigned VirtualIndex; 752 int ThisAdjustment; 753 unsigned Flags; 754 unsigned SPFlags; 755 Metadata *Unit; 756 Metadata *TemplateParams; 757 Metadata *Declaration; 758 Metadata *RetainedNodes; 759 Metadata *ThrownTypes; 760 Metadata *Annotations; 761 MDString *TargetFuncName; 762 763 MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName, 764 Metadata *File, unsigned Line, Metadata *Type, 765 unsigned ScopeLine, Metadata *ContainingType, 766 unsigned VirtualIndex, int ThisAdjustment, unsigned Flags, 767 unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams, 768 Metadata *Declaration, Metadata *RetainedNodes, 769 Metadata *ThrownTypes, Metadata *Annotations, 770 MDString *TargetFuncName) 771 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File), 772 Line(Line), Type(Type), ScopeLine(ScopeLine), 773 ContainingType(ContainingType), VirtualIndex(VirtualIndex), 774 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags), 775 Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration), 776 RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes), 777 Annotations(Annotations), TargetFuncName(TargetFuncName) {} 778 MDNodeKeyImpl(const DISubprogram *N) 779 : Scope(N->getRawScope()), Name(N->getRawName()), 780 LinkageName(N->getRawLinkageName()), File(N->getRawFile()), 781 Line(N->getLine()), Type(N->getRawType()), ScopeLine(N->getScopeLine()), 782 ContainingType(N->getRawContainingType()), 783 VirtualIndex(N->getVirtualIndex()), 784 ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()), 785 SPFlags(N->getSPFlags()), Unit(N->getRawUnit()), 786 TemplateParams(N->getRawTemplateParams()), 787 Declaration(N->getRawDeclaration()), 788 RetainedNodes(N->getRawRetainedNodes()), 789 ThrownTypes(N->getRawThrownTypes()), 790 Annotations(N->getRawAnnotations()), 791 TargetFuncName(N->getRawTargetFuncName()) {} 792 793 bool isKeyOf(const DISubprogram *RHS) const { 794 return Scope == RHS->getRawScope() && Name == RHS->getRawName() && 795 LinkageName == RHS->getRawLinkageName() && 796 File == RHS->getRawFile() && Line == RHS->getLine() && 797 Type == RHS->getRawType() && ScopeLine == RHS->getScopeLine() && 798 ContainingType == RHS->getRawContainingType() && 799 VirtualIndex == RHS->getVirtualIndex() && 800 ThisAdjustment == RHS->getThisAdjustment() && 801 Flags == RHS->getFlags() && SPFlags == RHS->getSPFlags() && 802 Unit == RHS->getUnit() && 803 TemplateParams == RHS->getRawTemplateParams() && 804 Declaration == RHS->getRawDeclaration() && 805 RetainedNodes == RHS->getRawRetainedNodes() && 806 ThrownTypes == RHS->getRawThrownTypes() && 807 Annotations == RHS->getRawAnnotations() && 808 TargetFuncName == RHS->getRawTargetFuncName(); 809 } 810 811 bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; } 812 813 unsigned getHashValue() const { 814 // If this is a declaration inside an ODR type, only hash the type and the 815 // name. Otherwise the hash will be stronger than 816 // MDNodeSubsetEqualImpl::isDeclarationOfODRMember(). 817 if (!isDefinition() && LinkageName) 818 if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope)) 819 if (CT->getRawIdentifier()) 820 return hash_combine(LinkageName, Scope); 821 822 // Intentionally computes the hash on a subset of the operands for 823 // performance reason. The subset has to be significant enough to avoid 824 // collision "most of the time". There is no correctness issue in case of 825 // collision because of the full check above. 826 return hash_combine(Name, Scope, File, Type, Line); 827 } 828 }; 829 830 template <> struct MDNodeSubsetEqualImpl<DISubprogram> { 831 using KeyTy = MDNodeKeyImpl<DISubprogram>; 832 833 static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) { 834 return isDeclarationOfODRMember(LHS.isDefinition(), LHS.Scope, 835 LHS.LinkageName, LHS.TemplateParams, RHS); 836 } 837 838 static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) { 839 return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(), 840 LHS->getRawLinkageName(), 841 LHS->getRawTemplateParams(), RHS); 842 } 843 844 /// Subprograms compare equal if they declare the same function in an ODR 845 /// type. 846 static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope, 847 const MDString *LinkageName, 848 const Metadata *TemplateParams, 849 const DISubprogram *RHS) { 850 // Check whether the LHS is eligible. 851 if (IsDefinition || !Scope || !LinkageName) 852 return false; 853 854 auto *CT = dyn_cast_or_null<DICompositeType>(Scope); 855 if (!CT || !CT->getRawIdentifier()) 856 return false; 857 858 // Compare to the RHS. 859 // FIXME: We need to compare template parameters here to avoid incorrect 860 // collisions in mapMetadata when RF_ReuseAndMutateDistinctMDs and a 861 // ODR-DISubprogram has a non-ODR template parameter (i.e., a 862 // DICompositeType that does not have an identifier). Eventually we should 863 // decouple ODR logic from uniquing logic. 864 return IsDefinition == RHS->isDefinition() && Scope == RHS->getRawScope() && 865 LinkageName == RHS->getRawLinkageName() && 866 TemplateParams == RHS->getRawTemplateParams(); 867 } 868 }; 869 870 template <> struct MDNodeKeyImpl<DILexicalBlock> { 871 Metadata *Scope; 872 Metadata *File; 873 unsigned Line; 874 unsigned Column; 875 876 MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Line, unsigned Column) 877 : Scope(Scope), File(File), Line(Line), Column(Column) {} 878 MDNodeKeyImpl(const DILexicalBlock *N) 879 : Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()), 880 Column(N->getColumn()) {} 881 882 bool isKeyOf(const DILexicalBlock *RHS) const { 883 return Scope == RHS->getRawScope() && File == RHS->getRawFile() && 884 Line == RHS->getLine() && Column == RHS->getColumn(); 885 } 886 887 unsigned getHashValue() const { 888 return hash_combine(Scope, File, Line, Column); 889 } 890 }; 891 892 template <> struct MDNodeKeyImpl<DILexicalBlockFile> { 893 Metadata *Scope; 894 Metadata *File; 895 unsigned Discriminator; 896 897 MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator) 898 : Scope(Scope), File(File), Discriminator(Discriminator) {} 899 MDNodeKeyImpl(const DILexicalBlockFile *N) 900 : Scope(N->getRawScope()), File(N->getRawFile()), 901 Discriminator(N->getDiscriminator()) {} 902 903 bool isKeyOf(const DILexicalBlockFile *RHS) const { 904 return Scope == RHS->getRawScope() && File == RHS->getRawFile() && 905 Discriminator == RHS->getDiscriminator(); 906 } 907 908 unsigned getHashValue() const { 909 return hash_combine(Scope, File, Discriminator); 910 } 911 }; 912 913 template <> struct MDNodeKeyImpl<DINamespace> { 914 Metadata *Scope; 915 MDString *Name; 916 bool ExportSymbols; 917 918 MDNodeKeyImpl(Metadata *Scope, MDString *Name, bool ExportSymbols) 919 : Scope(Scope), Name(Name), ExportSymbols(ExportSymbols) {} 920 MDNodeKeyImpl(const DINamespace *N) 921 : Scope(N->getRawScope()), Name(N->getRawName()), 922 ExportSymbols(N->getExportSymbols()) {} 923 924 bool isKeyOf(const DINamespace *RHS) const { 925 return Scope == RHS->getRawScope() && Name == RHS->getRawName() && 926 ExportSymbols == RHS->getExportSymbols(); 927 } 928 929 unsigned getHashValue() const { return hash_combine(Scope, Name); } 930 }; 931 932 template <> struct MDNodeKeyImpl<DICommonBlock> { 933 Metadata *Scope; 934 Metadata *Decl; 935 MDString *Name; 936 Metadata *File; 937 unsigned LineNo; 938 939 MDNodeKeyImpl(Metadata *Scope, Metadata *Decl, MDString *Name, Metadata *File, 940 unsigned LineNo) 941 : Scope(Scope), Decl(Decl), Name(Name), File(File), LineNo(LineNo) {} 942 MDNodeKeyImpl(const DICommonBlock *N) 943 : Scope(N->getRawScope()), Decl(N->getRawDecl()), Name(N->getRawName()), 944 File(N->getRawFile()), LineNo(N->getLineNo()) {} 945 946 bool isKeyOf(const DICommonBlock *RHS) const { 947 return Scope == RHS->getRawScope() && Decl == RHS->getRawDecl() && 948 Name == RHS->getRawName() && File == RHS->getRawFile() && 949 LineNo == RHS->getLineNo(); 950 } 951 952 unsigned getHashValue() const { 953 return hash_combine(Scope, Decl, Name, File, LineNo); 954 } 955 }; 956 957 template <> struct MDNodeKeyImpl<DIModule> { 958 Metadata *File; 959 Metadata *Scope; 960 MDString *Name; 961 MDString *ConfigurationMacros; 962 MDString *IncludePath; 963 MDString *APINotesFile; 964 unsigned LineNo; 965 bool IsDecl; 966 967 MDNodeKeyImpl(Metadata *File, Metadata *Scope, MDString *Name, 968 MDString *ConfigurationMacros, MDString *IncludePath, 969 MDString *APINotesFile, unsigned LineNo, bool IsDecl) 970 : File(File), Scope(Scope), Name(Name), 971 ConfigurationMacros(ConfigurationMacros), IncludePath(IncludePath), 972 APINotesFile(APINotesFile), LineNo(LineNo), IsDecl(IsDecl) {} 973 MDNodeKeyImpl(const DIModule *N) 974 : File(N->getRawFile()), Scope(N->getRawScope()), Name(N->getRawName()), 975 ConfigurationMacros(N->getRawConfigurationMacros()), 976 IncludePath(N->getRawIncludePath()), 977 APINotesFile(N->getRawAPINotesFile()), LineNo(N->getLineNo()), 978 IsDecl(N->getIsDecl()) {} 979 980 bool isKeyOf(const DIModule *RHS) const { 981 return Scope == RHS->getRawScope() && Name == RHS->getRawName() && 982 ConfigurationMacros == RHS->getRawConfigurationMacros() && 983 IncludePath == RHS->getRawIncludePath() && 984 APINotesFile == RHS->getRawAPINotesFile() && 985 File == RHS->getRawFile() && LineNo == RHS->getLineNo() && 986 IsDecl == RHS->getIsDecl(); 987 } 988 989 unsigned getHashValue() const { 990 return hash_combine(Scope, Name, ConfigurationMacros, IncludePath); 991 } 992 }; 993 994 template <> struct MDNodeKeyImpl<DITemplateTypeParameter> { 995 MDString *Name; 996 Metadata *Type; 997 bool IsDefault; 998 999 MDNodeKeyImpl(MDString *Name, Metadata *Type, bool IsDefault) 1000 : Name(Name), Type(Type), IsDefault(IsDefault) {} 1001 MDNodeKeyImpl(const DITemplateTypeParameter *N) 1002 : Name(N->getRawName()), Type(N->getRawType()), 1003 IsDefault(N->isDefault()) {} 1004 1005 bool isKeyOf(const DITemplateTypeParameter *RHS) const { 1006 return Name == RHS->getRawName() && Type == RHS->getRawType() && 1007 IsDefault == RHS->isDefault(); 1008 } 1009 1010 unsigned getHashValue() const { return hash_combine(Name, Type, IsDefault); } 1011 }; 1012 1013 template <> struct MDNodeKeyImpl<DITemplateValueParameter> { 1014 unsigned Tag; 1015 MDString *Name; 1016 Metadata *Type; 1017 bool IsDefault; 1018 Metadata *Value; 1019 1020 MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *Type, bool IsDefault, 1021 Metadata *Value) 1022 : Tag(Tag), Name(Name), Type(Type), IsDefault(IsDefault), Value(Value) {} 1023 MDNodeKeyImpl(const DITemplateValueParameter *N) 1024 : Tag(N->getTag()), Name(N->getRawName()), Type(N->getRawType()), 1025 IsDefault(N->isDefault()), Value(N->getValue()) {} 1026 1027 bool isKeyOf(const DITemplateValueParameter *RHS) const { 1028 return Tag == RHS->getTag() && Name == RHS->getRawName() && 1029 Type == RHS->getRawType() && IsDefault == RHS->isDefault() && 1030 Value == RHS->getValue(); 1031 } 1032 1033 unsigned getHashValue() const { 1034 return hash_combine(Tag, Name, Type, IsDefault, Value); 1035 } 1036 }; 1037 1038 template <> struct MDNodeKeyImpl<DIGlobalVariable> { 1039 Metadata *Scope; 1040 MDString *Name; 1041 MDString *LinkageName; 1042 Metadata *File; 1043 unsigned Line; 1044 Metadata *Type; 1045 bool IsLocalToUnit; 1046 bool IsDefinition; 1047 Metadata *StaticDataMemberDeclaration; 1048 Metadata *TemplateParams; 1049 uint32_t AlignInBits; 1050 Metadata *Annotations; 1051 1052 MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName, 1053 Metadata *File, unsigned Line, Metadata *Type, 1054 bool IsLocalToUnit, bool IsDefinition, 1055 Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, 1056 uint32_t AlignInBits, Metadata *Annotations) 1057 : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File), 1058 Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit), 1059 IsDefinition(IsDefinition), 1060 StaticDataMemberDeclaration(StaticDataMemberDeclaration), 1061 TemplateParams(TemplateParams), AlignInBits(AlignInBits), 1062 Annotations(Annotations) {} 1063 MDNodeKeyImpl(const DIGlobalVariable *N) 1064 : Scope(N->getRawScope()), Name(N->getRawName()), 1065 LinkageName(N->getRawLinkageName()), File(N->getRawFile()), 1066 Line(N->getLine()), Type(N->getRawType()), 1067 IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()), 1068 StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()), 1069 TemplateParams(N->getRawTemplateParams()), 1070 AlignInBits(N->getAlignInBits()), Annotations(N->getRawAnnotations()) {} 1071 1072 bool isKeyOf(const DIGlobalVariable *RHS) const { 1073 return Scope == RHS->getRawScope() && Name == RHS->getRawName() && 1074 LinkageName == RHS->getRawLinkageName() && 1075 File == RHS->getRawFile() && Line == RHS->getLine() && 1076 Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() && 1077 IsDefinition == RHS->isDefinition() && 1078 StaticDataMemberDeclaration == 1079 RHS->getRawStaticDataMemberDeclaration() && 1080 TemplateParams == RHS->getRawTemplateParams() && 1081 AlignInBits == RHS->getAlignInBits() && 1082 Annotations == RHS->getRawAnnotations(); 1083 } 1084 1085 unsigned getHashValue() const { 1086 // We do not use AlignInBits in hashing function here on purpose: 1087 // in most cases this param for local variable is zero (for function param 1088 // it is always zero). This leads to lots of hash collisions and errors on 1089 // cases with lots of similar variables. 1090 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem, 1091 // generated IR is random for each run and test fails with Align included. 1092 // TODO: make hashing work fine with such situations 1093 return hash_combine(Scope, Name, LinkageName, File, Line, Type, 1094 IsLocalToUnit, IsDefinition, /* AlignInBits, */ 1095 StaticDataMemberDeclaration, Annotations); 1096 } 1097 }; 1098 1099 template <> struct MDNodeKeyImpl<DILocalVariable> { 1100 Metadata *Scope; 1101 MDString *Name; 1102 Metadata *File; 1103 unsigned Line; 1104 Metadata *Type; 1105 unsigned Arg; 1106 unsigned Flags; 1107 uint32_t AlignInBits; 1108 Metadata *Annotations; 1109 1110 MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line, 1111 Metadata *Type, unsigned Arg, unsigned Flags, 1112 uint32_t AlignInBits, Metadata *Annotations) 1113 : Scope(Scope), Name(Name), File(File), Line(Line), Type(Type), Arg(Arg), 1114 Flags(Flags), AlignInBits(AlignInBits), Annotations(Annotations) {} 1115 MDNodeKeyImpl(const DILocalVariable *N) 1116 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()), 1117 Line(N->getLine()), Type(N->getRawType()), Arg(N->getArg()), 1118 Flags(N->getFlags()), AlignInBits(N->getAlignInBits()), 1119 Annotations(N->getRawAnnotations()) {} 1120 1121 bool isKeyOf(const DILocalVariable *RHS) const { 1122 return Scope == RHS->getRawScope() && Name == RHS->getRawName() && 1123 File == RHS->getRawFile() && Line == RHS->getLine() && 1124 Type == RHS->getRawType() && Arg == RHS->getArg() && 1125 Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits() && 1126 Annotations == RHS->getRawAnnotations(); 1127 } 1128 1129 unsigned getHashValue() const { 1130 // We do not use AlignInBits in hashing function here on purpose: 1131 // in most cases this param for local variable is zero (for function param 1132 // it is always zero). This leads to lots of hash collisions and errors on 1133 // cases with lots of similar variables. 1134 // clang/test/CodeGen/debug-info-257-args.c is an example of this problem, 1135 // generated IR is random for each run and test fails with Align included. 1136 // TODO: make hashing work fine with such situations 1137 return hash_combine(Scope, Name, File, Line, Type, Arg, Flags, Annotations); 1138 } 1139 }; 1140 1141 template <> struct MDNodeKeyImpl<DILabel> { 1142 Metadata *Scope; 1143 MDString *Name; 1144 Metadata *File; 1145 unsigned Line; 1146 1147 MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line) 1148 : Scope(Scope), Name(Name), File(File), Line(Line) {} 1149 MDNodeKeyImpl(const DILabel *N) 1150 : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()), 1151 Line(N->getLine()) {} 1152 1153 bool isKeyOf(const DILabel *RHS) const { 1154 return Scope == RHS->getRawScope() && Name == RHS->getRawName() && 1155 File == RHS->getRawFile() && Line == RHS->getLine(); 1156 } 1157 1158 /// Using name and line to get hash value. It should already be mostly unique. 1159 unsigned getHashValue() const { return hash_combine(Scope, Name, Line); } 1160 }; 1161 1162 template <> struct MDNodeKeyImpl<DIExpression> { 1163 ArrayRef<uint64_t> Elements; 1164 1165 MDNodeKeyImpl(ArrayRef<uint64_t> Elements) : Elements(Elements) {} 1166 MDNodeKeyImpl(const DIExpression *N) : Elements(N->getElements()) {} 1167 1168 bool isKeyOf(const DIExpression *RHS) const { 1169 return Elements == RHS->getElements(); 1170 } 1171 1172 unsigned getHashValue() const { 1173 return hash_combine_range(Elements.begin(), Elements.end()); 1174 } 1175 }; 1176 1177 template <> struct MDNodeKeyImpl<DIGlobalVariableExpression> { 1178 Metadata *Variable; 1179 Metadata *Expression; 1180 1181 MDNodeKeyImpl(Metadata *Variable, Metadata *Expression) 1182 : Variable(Variable), Expression(Expression) {} 1183 MDNodeKeyImpl(const DIGlobalVariableExpression *N) 1184 : Variable(N->getRawVariable()), Expression(N->getRawExpression()) {} 1185 1186 bool isKeyOf(const DIGlobalVariableExpression *RHS) const { 1187 return Variable == RHS->getRawVariable() && 1188 Expression == RHS->getRawExpression(); 1189 } 1190 1191 unsigned getHashValue() const { return hash_combine(Variable, Expression); } 1192 }; 1193 1194 template <> struct MDNodeKeyImpl<DIObjCProperty> { 1195 MDString *Name; 1196 Metadata *File; 1197 unsigned Line; 1198 MDString *GetterName; 1199 MDString *SetterName; 1200 unsigned Attributes; 1201 Metadata *Type; 1202 1203 MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line, 1204 MDString *GetterName, MDString *SetterName, unsigned Attributes, 1205 Metadata *Type) 1206 : Name(Name), File(File), Line(Line), GetterName(GetterName), 1207 SetterName(SetterName), Attributes(Attributes), Type(Type) {} 1208 MDNodeKeyImpl(const DIObjCProperty *N) 1209 : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()), 1210 GetterName(N->getRawGetterName()), SetterName(N->getRawSetterName()), 1211 Attributes(N->getAttributes()), Type(N->getRawType()) {} 1212 1213 bool isKeyOf(const DIObjCProperty *RHS) const { 1214 return Name == RHS->getRawName() && File == RHS->getRawFile() && 1215 Line == RHS->getLine() && GetterName == RHS->getRawGetterName() && 1216 SetterName == RHS->getRawSetterName() && 1217 Attributes == RHS->getAttributes() && Type == RHS->getRawType(); 1218 } 1219 1220 unsigned getHashValue() const { 1221 return hash_combine(Name, File, Line, GetterName, SetterName, Attributes, 1222 Type); 1223 } 1224 }; 1225 1226 template <> struct MDNodeKeyImpl<DIImportedEntity> { 1227 unsigned Tag; 1228 Metadata *Scope; 1229 Metadata *Entity; 1230 Metadata *File; 1231 unsigned Line; 1232 MDString *Name; 1233 Metadata *Elements; 1234 1235 MDNodeKeyImpl(unsigned Tag, Metadata *Scope, Metadata *Entity, Metadata *File, 1236 unsigned Line, MDString *Name, Metadata *Elements) 1237 : Tag(Tag), Scope(Scope), Entity(Entity), File(File), Line(Line), 1238 Name(Name), Elements(Elements) {} 1239 MDNodeKeyImpl(const DIImportedEntity *N) 1240 : Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()), 1241 File(N->getRawFile()), Line(N->getLine()), Name(N->getRawName()), 1242 Elements(N->getRawElements()) {} 1243 1244 bool isKeyOf(const DIImportedEntity *RHS) const { 1245 return Tag == RHS->getTag() && Scope == RHS->getRawScope() && 1246 Entity == RHS->getRawEntity() && File == RHS->getFile() && 1247 Line == RHS->getLine() && Name == RHS->getRawName() && 1248 Elements == RHS->getRawElements(); 1249 } 1250 1251 unsigned getHashValue() const { 1252 return hash_combine(Tag, Scope, Entity, File, Line, Name, Elements); 1253 } 1254 }; 1255 1256 template <> struct MDNodeKeyImpl<DIMacro> { 1257 unsigned MIType; 1258 unsigned Line; 1259 MDString *Name; 1260 MDString *Value; 1261 1262 MDNodeKeyImpl(unsigned MIType, unsigned Line, MDString *Name, MDString *Value) 1263 : MIType(MIType), Line(Line), Name(Name), Value(Value) {} 1264 MDNodeKeyImpl(const DIMacro *N) 1265 : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getRawName()), 1266 Value(N->getRawValue()) {} 1267 1268 bool isKeyOf(const DIMacro *RHS) const { 1269 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() && 1270 Name == RHS->getRawName() && Value == RHS->getRawValue(); 1271 } 1272 1273 unsigned getHashValue() const { 1274 return hash_combine(MIType, Line, Name, Value); 1275 } 1276 }; 1277 1278 template <> struct MDNodeKeyImpl<DIMacroFile> { 1279 unsigned MIType; 1280 unsigned Line; 1281 Metadata *File; 1282 Metadata *Elements; 1283 1284 MDNodeKeyImpl(unsigned MIType, unsigned Line, Metadata *File, 1285 Metadata *Elements) 1286 : MIType(MIType), Line(Line), File(File), Elements(Elements) {} 1287 MDNodeKeyImpl(const DIMacroFile *N) 1288 : MIType(N->getMacinfoType()), Line(N->getLine()), File(N->getRawFile()), 1289 Elements(N->getRawElements()) {} 1290 1291 bool isKeyOf(const DIMacroFile *RHS) const { 1292 return MIType == RHS->getMacinfoType() && Line == RHS->getLine() && 1293 File == RHS->getRawFile() && Elements == RHS->getRawElements(); 1294 } 1295 1296 unsigned getHashValue() const { 1297 return hash_combine(MIType, Line, File, Elements); 1298 } 1299 }; 1300 1301 template <> struct MDNodeKeyImpl<DIArgList> { 1302 ArrayRef<ValueAsMetadata *> Args; 1303 1304 MDNodeKeyImpl(ArrayRef<ValueAsMetadata *> Args) : Args(Args) {} 1305 MDNodeKeyImpl(const DIArgList *N) : Args(N->getArgs()) {} 1306 1307 bool isKeyOf(const DIArgList *RHS) const { return Args == RHS->getArgs(); } 1308 1309 unsigned getHashValue() const { 1310 return hash_combine_range(Args.begin(), Args.end()); 1311 } 1312 }; 1313 1314 /// DenseMapInfo for MDNode subclasses. 1315 template <class NodeTy> struct MDNodeInfo { 1316 using KeyTy = MDNodeKeyImpl<NodeTy>; 1317 using SubsetEqualTy = MDNodeSubsetEqualImpl<NodeTy>; 1318 1319 static inline NodeTy *getEmptyKey() { 1320 return DenseMapInfo<NodeTy *>::getEmptyKey(); 1321 } 1322 1323 static inline NodeTy *getTombstoneKey() { 1324 return DenseMapInfo<NodeTy *>::getTombstoneKey(); 1325 } 1326 1327 static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); } 1328 1329 static unsigned getHashValue(const NodeTy *N) { 1330 return KeyTy(N).getHashValue(); 1331 } 1332 1333 static bool isEqual(const KeyTy &LHS, const NodeTy *RHS) { 1334 if (RHS == getEmptyKey() || RHS == getTombstoneKey()) 1335 return false; 1336 return SubsetEqualTy::isSubsetEqual(LHS, RHS) || LHS.isKeyOf(RHS); 1337 } 1338 1339 static bool isEqual(const NodeTy *LHS, const NodeTy *RHS) { 1340 if (LHS == RHS) 1341 return true; 1342 if (RHS == getEmptyKey() || RHS == getTombstoneKey()) 1343 return false; 1344 return SubsetEqualTy::isSubsetEqual(LHS, RHS); 1345 } 1346 }; 1347 1348 #define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>; 1349 #include "llvm/IR/Metadata.def" 1350 1351 /// Multimap-like storage for metadata attachments. 1352 class MDAttachments { 1353 public: 1354 struct Attachment { 1355 unsigned MDKind; 1356 TrackingMDNodeRef Node; 1357 }; 1358 1359 private: 1360 SmallVector<Attachment, 1> Attachments; 1361 1362 public: 1363 bool empty() const { return Attachments.empty(); } 1364 size_t size() const { return Attachments.size(); } 1365 1366 /// Returns the first attachment with the given ID or nullptr if no such 1367 /// attachment exists. 1368 MDNode *lookup(unsigned ID) const; 1369 1370 /// Appends all attachments with the given ID to \c Result in insertion order. 1371 /// If the global has no attachments with the given ID, or if ID is invalid, 1372 /// leaves Result unchanged. 1373 void get(unsigned ID, SmallVectorImpl<MDNode *> &Result) const; 1374 1375 /// Appends all attachments for the global to \c Result, sorting by attachment 1376 /// ID. Attachments with the same ID appear in insertion order. This function 1377 /// does \em not clear \c Result. 1378 void getAll(SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const; 1379 1380 /// Set an attachment to a particular node. 1381 /// 1382 /// Set the \c ID attachment to \c MD, replacing the current attachments at \c 1383 /// ID (if anyway). 1384 void set(unsigned ID, MDNode *MD); 1385 1386 /// Adds an attachment to a particular node. 1387 void insert(unsigned ID, MDNode &MD); 1388 1389 /// Remove attachments with the given ID. 1390 /// 1391 /// Remove the attachments at \c ID, if any. 1392 bool erase(unsigned ID); 1393 1394 /// Erase matching attachments. 1395 /// 1396 /// Erases all attachments matching the \c shouldRemove predicate. 1397 template <class PredTy> void remove_if(PredTy shouldRemove) { 1398 llvm::erase_if(Attachments, shouldRemove); 1399 } 1400 }; 1401 1402 class LLVMContextImpl { 1403 public: 1404 /// OwnedModules - The set of modules instantiated in this context, and which 1405 /// will be automatically deleted if this context is deleted. 1406 SmallPtrSet<Module *, 4> OwnedModules; 1407 1408 /// The main remark streamer used by all the other streamers (e.g. IR, MIR, 1409 /// frontends, etc.). This should only be used by the specific streamers, and 1410 /// never directly. 1411 std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer; 1412 1413 std::unique_ptr<DiagnosticHandler> DiagHandler; 1414 bool RespectDiagnosticFilters = false; 1415 bool DiagnosticsHotnessRequested = false; 1416 /// The minimum hotness value a diagnostic needs in order to be included in 1417 /// optimization diagnostics. 1418 /// 1419 /// The threshold is an Optional value, which maps to one of the 3 states: 1420 /// 1). 0 => threshold disabled. All emarks will be printed. 1421 /// 2). positive int => manual threshold by user. Remarks with hotness exceed 1422 /// threshold will be printed. 1423 /// 3). None => 'auto' threshold by user. The actual value is not 1424 /// available at command line, but will be synced with 1425 /// hotness threhold from profile summary during 1426 /// compilation. 1427 /// 1428 /// State 1 and 2 are considered as terminal states. State transition is 1429 /// only allowed from 3 to 2, when the threshold is first synced with profile 1430 /// summary. This ensures that the threshold is set only once and stays 1431 /// constant. 1432 /// 1433 /// If threshold option is not specified, it is disabled (0) by default. 1434 std::optional<uint64_t> DiagnosticsHotnessThreshold = 0; 1435 1436 /// The percentage of difference between profiling branch weights and 1437 /// llvm.expect branch weights to tolerate when emiting MisExpect diagnostics 1438 std::optional<uint32_t> DiagnosticsMisExpectTolerance = 0; 1439 bool MisExpectWarningRequested = false; 1440 1441 /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter. 1442 std::unique_ptr<LLVMRemarkStreamer> LLVMRS; 1443 1444 LLVMContext::YieldCallbackTy YieldCallback = nullptr; 1445 void *YieldOpaqueHandle = nullptr; 1446 1447 DenseMap<const Value *, ValueName *> ValueNames; 1448 1449 using IntMapTy = 1450 DenseMap<APInt, std::unique_ptr<ConstantInt>, DenseMapAPIntKeyInfo>; 1451 IntMapTy IntConstants; 1452 1453 using FPMapTy = 1454 DenseMap<APFloat, std::unique_ptr<ConstantFP>, DenseMapAPFloatKeyInfo>; 1455 FPMapTy FPConstants; 1456 1457 FoldingSet<AttributeImpl> AttrsSet; 1458 FoldingSet<AttributeListImpl> AttrsLists; 1459 FoldingSet<AttributeSetNode> AttrsSetNodes; 1460 1461 StringMap<MDString, BumpPtrAllocator> MDStringCache; 1462 DenseMap<Value *, ValueAsMetadata *> ValuesAsMetadata; 1463 DenseMap<Metadata *, MetadataAsValue *> MetadataAsValues; 1464 1465 #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \ 1466 DenseSet<CLASS *, CLASS##Info> CLASS##s; 1467 #include "llvm/IR/Metadata.def" 1468 1469 // Optional map for looking up composite types by identifier. 1470 std::optional<DenseMap<const MDString *, DICompositeType *>> DITypeMap; 1471 1472 // MDNodes may be uniqued or not uniqued. When they're not uniqued, they 1473 // aren't in the MDNodeSet, but they're still shared between objects, so no 1474 // one object can destroy them. Keep track of them here so we can delete 1475 // them on context teardown. 1476 std::vector<MDNode *> DistinctMDNodes; 1477 1478 DenseMap<Type *, std::unique_ptr<ConstantAggregateZero>> CAZConstants; 1479 1480 using ArrayConstantsTy = ConstantUniqueMap<ConstantArray>; 1481 ArrayConstantsTy ArrayConstants; 1482 1483 using StructConstantsTy = ConstantUniqueMap<ConstantStruct>; 1484 StructConstantsTy StructConstants; 1485 1486 using VectorConstantsTy = ConstantUniqueMap<ConstantVector>; 1487 VectorConstantsTy VectorConstants; 1488 1489 DenseMap<PointerType *, std::unique_ptr<ConstantPointerNull>> CPNConstants; 1490 1491 DenseMap<TargetExtType *, std::unique_ptr<ConstantTargetNone>> CTNConstants; 1492 1493 DenseMap<Type *, std::unique_ptr<UndefValue>> UVConstants; 1494 1495 DenseMap<Type *, std::unique_ptr<PoisonValue>> PVConstants; 1496 1497 StringMap<std::unique_ptr<ConstantDataSequential>> CDSConstants; 1498 1499 DenseMap<std::pair<const Function *, const BasicBlock *>, BlockAddress *> 1500 BlockAddresses; 1501 1502 DenseMap<const GlobalValue *, DSOLocalEquivalent *> DSOLocalEquivalents; 1503 1504 DenseMap<const GlobalValue *, NoCFIValue *> NoCFIValues; 1505 1506 ConstantUniqueMap<ConstantExpr> ExprConstants; 1507 1508 ConstantUniqueMap<InlineAsm> InlineAsms; 1509 1510 ConstantInt *TheTrueVal = nullptr; 1511 ConstantInt *TheFalseVal = nullptr; 1512 1513 // Basic type instances. 1514 Type VoidTy, LabelTy, HalfTy, BFloatTy, FloatTy, DoubleTy, MetadataTy, 1515 TokenTy; 1516 Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy, X86_AMXTy; 1517 IntegerType Int1Ty, Int8Ty, Int16Ty, Int32Ty, Int64Ty, Int128Ty; 1518 1519 std::unique_ptr<ConstantTokenNone> TheNoneToken; 1520 1521 BumpPtrAllocator Alloc; 1522 UniqueStringSaver Saver{Alloc}; 1523 1524 DenseMap<unsigned, IntegerType *> IntegerTypes; 1525 1526 using FunctionTypeSet = DenseSet<FunctionType *, FunctionTypeKeyInfo>; 1527 FunctionTypeSet FunctionTypes; 1528 using StructTypeSet = DenseSet<StructType *, AnonStructTypeKeyInfo>; 1529 StructTypeSet AnonStructTypes; 1530 StringMap<StructType *> NamedStructTypes; 1531 unsigned NamedStructTypesUniqueID = 0; 1532 1533 using TargetExtTypeSet = DenseSet<TargetExtType *, TargetExtTypeKeyInfo>; 1534 TargetExtTypeSet TargetExtTypes; 1535 1536 DenseMap<std::pair<Type *, uint64_t>, ArrayType *> ArrayTypes; 1537 DenseMap<std::pair<Type *, ElementCount>, VectorType *> VectorTypes; 1538 DenseMap<Type *, PointerType *> PointerTypes; // Pointers in AddrSpace = 0 1539 DenseMap<std::pair<Type *, unsigned>, PointerType *> ASPointerTypes; 1540 DenseMap<std::pair<Type *, unsigned>, TypedPointerType *> ASTypedPointerTypes; 1541 1542 /// ValueHandles - This map keeps track of all of the value handles that are 1543 /// watching a Value*. The Value::HasValueHandle bit is used to know 1544 /// whether or not a value has an entry in this map. 1545 using ValueHandlesTy = DenseMap<Value *, ValueHandleBase *>; 1546 ValueHandlesTy ValueHandles; 1547 1548 /// CustomMDKindNames - Map to hold the metadata string to ID mapping. 1549 StringMap<unsigned> CustomMDKindNames; 1550 1551 /// Collection of metadata used in this context. 1552 DenseMap<const Value *, MDAttachments> ValueMetadata; 1553 1554 /// Map DIAssignID -> Instructions with that attachment. 1555 /// Managed by Instruction via Instruction::updateDIAssignIDMapping. 1556 /// Query using the at:: functions defined in DebugInfo.h. 1557 DenseMap<DIAssignID *, SmallVector<Instruction *, 1>> AssignmentIDToInstrs; 1558 1559 /// Collection of per-GlobalObject sections used in this context. 1560 DenseMap<const GlobalObject *, StringRef> GlobalObjectSections; 1561 1562 /// Collection of per-GlobalValue partitions used in this context. 1563 DenseMap<const GlobalValue *, StringRef> GlobalValuePartitions; 1564 1565 DenseMap<const GlobalValue *, GlobalValue::SanitizerMetadata> 1566 GlobalValueSanitizerMetadata; 1567 1568 /// DiscriminatorTable - This table maps file:line locations to an 1569 /// integer representing the next DWARF path discriminator to assign to 1570 /// instructions in different blocks at the same location. 1571 DenseMap<std::pair<const char *, unsigned>, unsigned> DiscriminatorTable; 1572 1573 /// A set of interned tags for operand bundles. The StringMap maps 1574 /// bundle tags to their IDs. 1575 /// 1576 /// \see LLVMContext::getOperandBundleTagID 1577 StringMap<uint32_t> BundleTagCache; 1578 1579 StringMapEntry<uint32_t> *getOrInsertBundleTag(StringRef Tag); 1580 void getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const; 1581 uint32_t getOperandBundleTagID(StringRef Tag) const; 1582 1583 /// A set of interned synchronization scopes. The StringMap maps 1584 /// synchronization scope names to their respective synchronization scope IDs. 1585 StringMap<SyncScope::ID> SSC; 1586 1587 /// getOrInsertSyncScopeID - Maps synchronization scope name to 1588 /// synchronization scope ID. Every synchronization scope registered with 1589 /// LLVMContext has unique ID except pre-defined ones. 1590 SyncScope::ID getOrInsertSyncScopeID(StringRef SSN); 1591 1592 /// getSyncScopeNames - Populates client supplied SmallVector with 1593 /// synchronization scope names registered with LLVMContext. Synchronization 1594 /// scope names are ordered by increasing synchronization scope IDs. 1595 void getSyncScopeNames(SmallVectorImpl<StringRef> &SSNs) const; 1596 1597 /// Maintain the GC name for each function. 1598 /// 1599 /// This saves allocating an additional word in Function for programs which 1600 /// do not use GC (i.e., most programs) at the cost of increased overhead for 1601 /// clients which do use GC. 1602 DenseMap<const Function *, std::string> GCNames; 1603 1604 /// Flag to indicate if Value (other than GlobalValue) retains their name or 1605 /// not. 1606 bool DiscardValueNames = false; 1607 1608 LLVMContextImpl(LLVMContext &C); 1609 ~LLVMContextImpl(); 1610 1611 /// Destroy the ConstantArrays if they are not used. 1612 void dropTriviallyDeadConstantArrays(); 1613 1614 mutable OptPassGate *OPG = nullptr; 1615 1616 /// Access the object which can disable optional passes and individual 1617 /// optimizations at compile time. 1618 OptPassGate &getOptPassGate() const; 1619 1620 /// Set the object which can disable optional passes and individual 1621 /// optimizations at compile time. 1622 /// 1623 /// The lifetime of the object must be guaranteed to extend as long as the 1624 /// LLVMContext is used by compilation. 1625 void setOptPassGate(OptPassGate &); 1626 1627 // TODO: clean up the following after we no longer support non-opaque pointer 1628 // types. 1629 bool getOpaquePointers(); 1630 void setOpaquePointers(bool OP); 1631 1632 private: 1633 std::optional<bool> OpaquePointers; 1634 }; 1635 1636 } // end namespace llvm 1637 1638 #endif // LLVM_LIB_IR_LLVMCONTEXTIMPL_H 1639