109467b48Spatrick //===- LLVMContextImpl.h - The LLVMContextImpl opaque class -----*- C++ -*-===// 209467b48Spatrick // 309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information. 509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 609467b48Spatrick // 709467b48Spatrick //===----------------------------------------------------------------------===// 809467b48Spatrick // 909467b48Spatrick // This file declares LLVMContextImpl, the opaque implementation 1009467b48Spatrick // of LLVMContext. 1109467b48Spatrick // 1209467b48Spatrick //===----------------------------------------------------------------------===// 1309467b48Spatrick 1409467b48Spatrick #ifndef LLVM_LIB_IR_LLVMCONTEXTIMPL_H 1509467b48Spatrick #define LLVM_LIB_IR_LLVMCONTEXTIMPL_H 1609467b48Spatrick 1709467b48Spatrick #include "ConstantsContext.h" 1809467b48Spatrick #include "llvm/ADT/APFloat.h" 1909467b48Spatrick #include "llvm/ADT/APInt.h" 2009467b48Spatrick #include "llvm/ADT/ArrayRef.h" 2109467b48Spatrick #include "llvm/ADT/DenseMap.h" 2209467b48Spatrick #include "llvm/ADT/DenseMapInfo.h" 2309467b48Spatrick #include "llvm/ADT/DenseSet.h" 2409467b48Spatrick #include "llvm/ADT/FoldingSet.h" 2509467b48Spatrick #include "llvm/ADT/Hashing.h" 2609467b48Spatrick #include "llvm/ADT/STLExtras.h" 2709467b48Spatrick #include "llvm/ADT/SmallPtrSet.h" 2809467b48Spatrick #include "llvm/ADT/SmallVector.h" 2909467b48Spatrick #include "llvm/ADT/StringMap.h" 3009467b48Spatrick #include "llvm/BinaryFormat/Dwarf.h" 3109467b48Spatrick #include "llvm/IR/Constants.h" 3209467b48Spatrick #include "llvm/IR/DebugInfoMetadata.h" 3309467b48Spatrick #include "llvm/IR/DerivedTypes.h" 3409467b48Spatrick #include "llvm/IR/LLVMContext.h" 3509467b48Spatrick #include "llvm/IR/Metadata.h" 36*d415bd75Srobert #include "llvm/IR/Module.h" 3709467b48Spatrick #include "llvm/IR/TrackingMDRef.h" 38*d415bd75Srobert #include "llvm/IR/Type.h" 39*d415bd75Srobert #include "llvm/IR/Value.h" 4009467b48Spatrick #include "llvm/Support/Allocator.h" 4109467b48Spatrick #include "llvm/Support/Casting.h" 4209467b48Spatrick #include "llvm/Support/StringSaver.h" 4309467b48Spatrick #include <algorithm> 4409467b48Spatrick #include <cassert> 4509467b48Spatrick #include <cstddef> 4609467b48Spatrick #include <cstdint> 4709467b48Spatrick #include <memory> 48*d415bd75Srobert #include <optional> 4909467b48Spatrick #include <string> 5009467b48Spatrick #include <utility> 5109467b48Spatrick #include <vector> 5209467b48Spatrick 5309467b48Spatrick namespace llvm { 5409467b48Spatrick 55*d415bd75Srobert class AttributeImpl; 56*d415bd75Srobert class AttributeListImpl; 57*d415bd75Srobert class AttributeSetNode; 58*d415bd75Srobert class BasicBlock; 59*d415bd75Srobert struct DiagnosticHandler; 60*d415bd75Srobert class ElementCount; 61*d415bd75Srobert class Function; 62*d415bd75Srobert class GlobalObject; 63*d415bd75Srobert class GlobalValue; 64*d415bd75Srobert class InlineAsm; 65*d415bd75Srobert class LLVMRemarkStreamer; 66*d415bd75Srobert class OptPassGate; 67*d415bd75Srobert namespace remarks { 68*d415bd75Srobert class RemarkStreamer; 69*d415bd75Srobert } 70*d415bd75Srobert template <typename T> class StringMapEntry; 71097a140dSpatrick class StringRef; 72*d415bd75Srobert class TypedPointerType; 7309467b48Spatrick class ValueHandleBase; 7409467b48Spatrick 7573471bf0Spatrick using DenseMapAPIntKeyInfo = DenseMapInfo<APInt>; 7609467b48Spatrick 7709467b48Spatrick struct DenseMapAPFloatKeyInfo { getEmptyKeyDenseMapAPFloatKeyInfo7809467b48Spatrick static inline APFloat getEmptyKey() { return APFloat(APFloat::Bogus(), 1); } getTombstoneKeyDenseMapAPFloatKeyInfo79*d415bd75Srobert static inline APFloat getTombstoneKey() { 80*d415bd75Srobert return APFloat(APFloat::Bogus(), 2); 81*d415bd75Srobert } 8209467b48Spatrick getHashValueDenseMapAPFloatKeyInfo8309467b48Spatrick static unsigned getHashValue(const APFloat &Key) { 8409467b48Spatrick return static_cast<unsigned>(hash_value(Key)); 8509467b48Spatrick } 8609467b48Spatrick isEqualDenseMapAPFloatKeyInfo8709467b48Spatrick static bool isEqual(const APFloat &LHS, const APFloat &RHS) { 8809467b48Spatrick return LHS.bitwiseIsEqual(RHS); 8909467b48Spatrick } 9009467b48Spatrick }; 9109467b48Spatrick 9209467b48Spatrick struct AnonStructTypeKeyInfo { 9309467b48Spatrick struct KeyTy { 9409467b48Spatrick ArrayRef<Type *> ETypes; 9509467b48Spatrick bool isPacked; 9609467b48Spatrick KeyTyAnonStructTypeKeyInfo::KeyTy97*d415bd75Srobert KeyTy(const ArrayRef<Type *> &E, bool P) : ETypes(E), isPacked(P) {} 9809467b48Spatrick KeyTyAnonStructTypeKeyInfo::KeyTy9909467b48Spatrick KeyTy(const StructType *ST) 10009467b48Spatrick : ETypes(ST->elements()), isPacked(ST->isPacked()) {} 10109467b48Spatrick 10209467b48Spatrick bool operator==(const KeyTy &that) const { 10309467b48Spatrick if (isPacked != that.isPacked) 10409467b48Spatrick return false; 10509467b48Spatrick if (ETypes != that.ETypes) 10609467b48Spatrick return false; 10709467b48Spatrick return true; 10809467b48Spatrick } 109*d415bd75Srobert bool operator!=(const KeyTy &that) const { return !this->operator==(that); } 11009467b48Spatrick }; 11109467b48Spatrick getEmptyKeyAnonStructTypeKeyInfo11209467b48Spatrick static inline StructType *getEmptyKey() { 11309467b48Spatrick return DenseMapInfo<StructType *>::getEmptyKey(); 11409467b48Spatrick } 11509467b48Spatrick getTombstoneKeyAnonStructTypeKeyInfo11609467b48Spatrick static inline StructType *getTombstoneKey() { 11709467b48Spatrick return DenseMapInfo<StructType *>::getTombstoneKey(); 11809467b48Spatrick } 11909467b48Spatrick getHashValueAnonStructTypeKeyInfo12009467b48Spatrick static unsigned getHashValue(const KeyTy &Key) { 121*d415bd75Srobert return hash_combine( 122*d415bd75Srobert hash_combine_range(Key.ETypes.begin(), Key.ETypes.end()), Key.isPacked); 12309467b48Spatrick } 12409467b48Spatrick getHashValueAnonStructTypeKeyInfo12509467b48Spatrick static unsigned getHashValue(const StructType *ST) { 12609467b48Spatrick return getHashValue(KeyTy(ST)); 12709467b48Spatrick } 12809467b48Spatrick isEqualAnonStructTypeKeyInfo12909467b48Spatrick static bool isEqual(const KeyTy &LHS, const StructType *RHS) { 13009467b48Spatrick if (RHS == getEmptyKey() || RHS == getTombstoneKey()) 13109467b48Spatrick return false; 13209467b48Spatrick return LHS == KeyTy(RHS); 13309467b48Spatrick } 13409467b48Spatrick isEqualAnonStructTypeKeyInfo13509467b48Spatrick static bool isEqual(const StructType *LHS, const StructType *RHS) { 13609467b48Spatrick return LHS == RHS; 13709467b48Spatrick } 13809467b48Spatrick }; 13909467b48Spatrick 14009467b48Spatrick struct FunctionTypeKeyInfo { 14109467b48Spatrick struct KeyTy { 14209467b48Spatrick const Type *ReturnType; 14309467b48Spatrick ArrayRef<Type *> Params; 14409467b48Spatrick bool isVarArg; 14509467b48Spatrick KeyTyFunctionTypeKeyInfo::KeyTy146*d415bd75Srobert KeyTy(const Type *R, const ArrayRef<Type *> &P, bool V) 147*d415bd75Srobert : ReturnType(R), Params(P), isVarArg(V) {} KeyTyFunctionTypeKeyInfo::KeyTy14809467b48Spatrick KeyTy(const FunctionType *FT) 14909467b48Spatrick : ReturnType(FT->getReturnType()), Params(FT->params()), 15009467b48Spatrick isVarArg(FT->isVarArg()) {} 15109467b48Spatrick 15209467b48Spatrick bool operator==(const KeyTy &that) const { 15309467b48Spatrick if (ReturnType != that.ReturnType) 15409467b48Spatrick return false; 15509467b48Spatrick if (isVarArg != that.isVarArg) 15609467b48Spatrick return false; 15709467b48Spatrick if (Params != that.Params) 15809467b48Spatrick return false; 15909467b48Spatrick return true; 16009467b48Spatrick } 161*d415bd75Srobert bool operator!=(const KeyTy &that) const { return !this->operator==(that); } 16209467b48Spatrick }; 16309467b48Spatrick getEmptyKeyFunctionTypeKeyInfo16409467b48Spatrick static inline FunctionType *getEmptyKey() { 16509467b48Spatrick return DenseMapInfo<FunctionType *>::getEmptyKey(); 16609467b48Spatrick } 16709467b48Spatrick getTombstoneKeyFunctionTypeKeyInfo16809467b48Spatrick static inline FunctionType *getTombstoneKey() { 16909467b48Spatrick return DenseMapInfo<FunctionType *>::getTombstoneKey(); 17009467b48Spatrick } 17109467b48Spatrick getHashValueFunctionTypeKeyInfo17209467b48Spatrick static unsigned getHashValue(const KeyTy &Key) { 173*d415bd75Srobert return hash_combine( 174*d415bd75Srobert Key.ReturnType, 175*d415bd75Srobert hash_combine_range(Key.Params.begin(), Key.Params.end()), Key.isVarArg); 17609467b48Spatrick } 17709467b48Spatrick getHashValueFunctionTypeKeyInfo17809467b48Spatrick static unsigned getHashValue(const FunctionType *FT) { 17909467b48Spatrick return getHashValue(KeyTy(FT)); 18009467b48Spatrick } 18109467b48Spatrick isEqualFunctionTypeKeyInfo18209467b48Spatrick static bool isEqual(const KeyTy &LHS, const FunctionType *RHS) { 18309467b48Spatrick if (RHS == getEmptyKey() || RHS == getTombstoneKey()) 18409467b48Spatrick return false; 18509467b48Spatrick return LHS == KeyTy(RHS); 18609467b48Spatrick } 18709467b48Spatrick isEqualFunctionTypeKeyInfo18809467b48Spatrick static bool isEqual(const FunctionType *LHS, const FunctionType *RHS) { 18909467b48Spatrick return LHS == RHS; 19009467b48Spatrick } 19109467b48Spatrick }; 19209467b48Spatrick 193*d415bd75Srobert struct TargetExtTypeKeyInfo { 194*d415bd75Srobert struct KeyTy { 195*d415bd75Srobert StringRef Name; 196*d415bd75Srobert ArrayRef<Type *> TypeParams; 197*d415bd75Srobert ArrayRef<unsigned> IntParams; 198*d415bd75Srobert KeyTyTargetExtTypeKeyInfo::KeyTy199*d415bd75Srobert KeyTy(StringRef N, const ArrayRef<Type *> &TP, const ArrayRef<unsigned> &IP) 200*d415bd75Srobert : Name(N), TypeParams(TP), IntParams(IP) {} KeyTyTargetExtTypeKeyInfo::KeyTy201*d415bd75Srobert KeyTy(const TargetExtType *TT) 202*d415bd75Srobert : Name(TT->getName()), TypeParams(TT->type_params()), 203*d415bd75Srobert IntParams(TT->int_params()) {} 204*d415bd75Srobert 205*d415bd75Srobert bool operator==(const KeyTy &that) const { 206*d415bd75Srobert return Name == that.Name && TypeParams == that.TypeParams && 207*d415bd75Srobert IntParams == that.IntParams; 208*d415bd75Srobert } 209*d415bd75Srobert bool operator!=(const KeyTy &that) const { return !this->operator==(that); } 210*d415bd75Srobert }; 211*d415bd75Srobert getEmptyKeyTargetExtTypeKeyInfo212*d415bd75Srobert static inline TargetExtType *getEmptyKey() { 213*d415bd75Srobert return DenseMapInfo<TargetExtType *>::getEmptyKey(); 214*d415bd75Srobert } 215*d415bd75Srobert getTombstoneKeyTargetExtTypeKeyInfo216*d415bd75Srobert static inline TargetExtType *getTombstoneKey() { 217*d415bd75Srobert return DenseMapInfo<TargetExtType *>::getTombstoneKey(); 218*d415bd75Srobert } 219*d415bd75Srobert getHashValueTargetExtTypeKeyInfo220*d415bd75Srobert static unsigned getHashValue(const KeyTy &Key) { 221*d415bd75Srobert return hash_combine( 222*d415bd75Srobert Key.Name, 223*d415bd75Srobert hash_combine_range(Key.TypeParams.begin(), Key.TypeParams.end()), 224*d415bd75Srobert hash_combine_range(Key.IntParams.begin(), Key.IntParams.end())); 225*d415bd75Srobert } 226*d415bd75Srobert getHashValueTargetExtTypeKeyInfo227*d415bd75Srobert static unsigned getHashValue(const TargetExtType *FT) { 228*d415bd75Srobert return getHashValue(KeyTy(FT)); 229*d415bd75Srobert } 230*d415bd75Srobert isEqualTargetExtTypeKeyInfo231*d415bd75Srobert static bool isEqual(const KeyTy &LHS, const TargetExtType *RHS) { 232*d415bd75Srobert if (RHS == getEmptyKey() || RHS == getTombstoneKey()) 233*d415bd75Srobert return false; 234*d415bd75Srobert return LHS == KeyTy(RHS); 235*d415bd75Srobert } 236*d415bd75Srobert isEqualTargetExtTypeKeyInfo237*d415bd75Srobert static bool isEqual(const TargetExtType *LHS, const TargetExtType *RHS) { 238*d415bd75Srobert return LHS == RHS; 239*d415bd75Srobert } 240*d415bd75Srobert }; 241*d415bd75Srobert 24209467b48Spatrick /// Structure for hashing arbitrary MDNode operands. 24309467b48Spatrick class MDNodeOpsKey { 24409467b48Spatrick ArrayRef<Metadata *> RawOps; 24509467b48Spatrick ArrayRef<MDOperand> Ops; 24609467b48Spatrick unsigned Hash; 24709467b48Spatrick 24809467b48Spatrick protected: MDNodeOpsKey(ArrayRef<Metadata * > Ops)24909467b48Spatrick MDNodeOpsKey(ArrayRef<Metadata *> Ops) 25009467b48Spatrick : RawOps(Ops), Hash(calculateHash(Ops)) {} 25109467b48Spatrick 25209467b48Spatrick template <class NodeTy> 25309467b48Spatrick MDNodeOpsKey(const NodeTy *N, unsigned Offset = 0) 25409467b48Spatrick : Ops(N->op_begin() + Offset, N->op_end()), Hash(N->getHash()) {} 25509467b48Spatrick 25609467b48Spatrick template <class NodeTy> 25709467b48Spatrick bool compareOps(const NodeTy *RHS, unsigned Offset = 0) const { 25809467b48Spatrick if (getHash() != RHS->getHash()) 25909467b48Spatrick return false; 26009467b48Spatrick 26109467b48Spatrick assert((RawOps.empty() || Ops.empty()) && "Two sets of operands?"); 26209467b48Spatrick return RawOps.empty() ? compareOps(Ops, RHS, Offset) 26309467b48Spatrick : compareOps(RawOps, RHS, Offset); 26409467b48Spatrick } 26509467b48Spatrick 26609467b48Spatrick static unsigned calculateHash(MDNode *N, unsigned Offset = 0); 26709467b48Spatrick 26809467b48Spatrick private: 26909467b48Spatrick template <class T> compareOps(ArrayRef<T> Ops,const MDNode * RHS,unsigned Offset)27009467b48Spatrick static bool compareOps(ArrayRef<T> Ops, const MDNode *RHS, unsigned Offset) { 27109467b48Spatrick if (Ops.size() != RHS->getNumOperands() - Offset) 27209467b48Spatrick return false; 27309467b48Spatrick return std::equal(Ops.begin(), Ops.end(), RHS->op_begin() + Offset); 27409467b48Spatrick } 27509467b48Spatrick 27609467b48Spatrick static unsigned calculateHash(ArrayRef<Metadata *> Ops); 27709467b48Spatrick 27809467b48Spatrick public: getHash()27909467b48Spatrick unsigned getHash() const { return Hash; } 28009467b48Spatrick }; 28109467b48Spatrick 28209467b48Spatrick template <class NodeTy> struct MDNodeKeyImpl; 28309467b48Spatrick 28409467b48Spatrick /// Configuration point for MDNodeInfo::isEqual(). 28509467b48Spatrick template <class NodeTy> struct MDNodeSubsetEqualImpl { 28609467b48Spatrick using KeyTy = MDNodeKeyImpl<NodeTy>; 28709467b48Spatrick isSubsetEqualMDNodeSubsetEqualImpl28809467b48Spatrick static bool isSubsetEqual(const KeyTy &LHS, const NodeTy *RHS) { 28909467b48Spatrick return false; 29009467b48Spatrick } 29109467b48Spatrick isSubsetEqualMDNodeSubsetEqualImpl29209467b48Spatrick static bool isSubsetEqual(const NodeTy *LHS, const NodeTy *RHS) { 29309467b48Spatrick return false; 29409467b48Spatrick } 29509467b48Spatrick }; 29609467b48Spatrick 29709467b48Spatrick /// DenseMapInfo for MDTuple. 29809467b48Spatrick /// 29909467b48Spatrick /// Note that we don't need the is-function-local bit, since that's implicit in 30009467b48Spatrick /// the operands. 30109467b48Spatrick template <> struct MDNodeKeyImpl<MDTuple> : MDNodeOpsKey { 30209467b48Spatrick MDNodeKeyImpl(ArrayRef<Metadata *> Ops) : MDNodeOpsKey(Ops) {} 30309467b48Spatrick MDNodeKeyImpl(const MDTuple *N) : MDNodeOpsKey(N) {} 30409467b48Spatrick 30509467b48Spatrick bool isKeyOf(const MDTuple *RHS) const { return compareOps(RHS); } 30609467b48Spatrick 30709467b48Spatrick unsigned getHashValue() const { return getHash(); } 30809467b48Spatrick 30909467b48Spatrick static unsigned calculateHash(MDTuple *N) { 31009467b48Spatrick return MDNodeOpsKey::calculateHash(N); 31109467b48Spatrick } 31209467b48Spatrick }; 31309467b48Spatrick 31409467b48Spatrick /// DenseMapInfo for DILocation. 31509467b48Spatrick template <> struct MDNodeKeyImpl<DILocation> { 31609467b48Spatrick unsigned Line; 31709467b48Spatrick unsigned Column; 31809467b48Spatrick Metadata *Scope; 31909467b48Spatrick Metadata *InlinedAt; 32009467b48Spatrick bool ImplicitCode; 32109467b48Spatrick 32209467b48Spatrick MDNodeKeyImpl(unsigned Line, unsigned Column, Metadata *Scope, 32309467b48Spatrick Metadata *InlinedAt, bool ImplicitCode) 32409467b48Spatrick : Line(Line), Column(Column), Scope(Scope), InlinedAt(InlinedAt), 32509467b48Spatrick ImplicitCode(ImplicitCode) {} 32609467b48Spatrick MDNodeKeyImpl(const DILocation *L) 32709467b48Spatrick : Line(L->getLine()), Column(L->getColumn()), Scope(L->getRawScope()), 32809467b48Spatrick InlinedAt(L->getRawInlinedAt()), ImplicitCode(L->isImplicitCode()) {} 32909467b48Spatrick 33009467b48Spatrick bool isKeyOf(const DILocation *RHS) const { 33109467b48Spatrick return Line == RHS->getLine() && Column == RHS->getColumn() && 33209467b48Spatrick Scope == RHS->getRawScope() && InlinedAt == RHS->getRawInlinedAt() && 33309467b48Spatrick ImplicitCode == RHS->isImplicitCode(); 33409467b48Spatrick } 33509467b48Spatrick 33609467b48Spatrick unsigned getHashValue() const { 33709467b48Spatrick return hash_combine(Line, Column, Scope, InlinedAt, ImplicitCode); 33809467b48Spatrick } 33909467b48Spatrick }; 34009467b48Spatrick 34109467b48Spatrick /// DenseMapInfo for GenericDINode. 34209467b48Spatrick template <> struct MDNodeKeyImpl<GenericDINode> : MDNodeOpsKey { 34309467b48Spatrick unsigned Tag; 34409467b48Spatrick MDString *Header; 34509467b48Spatrick 34609467b48Spatrick MDNodeKeyImpl(unsigned Tag, MDString *Header, ArrayRef<Metadata *> DwarfOps) 34709467b48Spatrick : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {} 34809467b48Spatrick MDNodeKeyImpl(const GenericDINode *N) 34909467b48Spatrick : MDNodeOpsKey(N, 1), Tag(N->getTag()), Header(N->getRawHeader()) {} 35009467b48Spatrick 35109467b48Spatrick bool isKeyOf(const GenericDINode *RHS) const { 35209467b48Spatrick return Tag == RHS->getTag() && Header == RHS->getRawHeader() && 35309467b48Spatrick compareOps(RHS, 1); 35409467b48Spatrick } 35509467b48Spatrick 35609467b48Spatrick unsigned getHashValue() const { return hash_combine(getHash(), Tag, Header); } 35709467b48Spatrick 35809467b48Spatrick static unsigned calculateHash(GenericDINode *N) { 35909467b48Spatrick return MDNodeOpsKey::calculateHash(N, 1); 36009467b48Spatrick } 36109467b48Spatrick }; 36209467b48Spatrick 36309467b48Spatrick template <> struct MDNodeKeyImpl<DISubrange> { 36409467b48Spatrick Metadata *CountNode; 365097a140dSpatrick Metadata *LowerBound; 366097a140dSpatrick Metadata *UpperBound; 367097a140dSpatrick Metadata *Stride; 36809467b48Spatrick 369097a140dSpatrick MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound, 370097a140dSpatrick Metadata *Stride) 371097a140dSpatrick : CountNode(CountNode), LowerBound(LowerBound), UpperBound(UpperBound), 372097a140dSpatrick Stride(Stride) {} 37309467b48Spatrick MDNodeKeyImpl(const DISubrange *N) 374097a140dSpatrick : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()), 375097a140dSpatrick UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {} 37609467b48Spatrick 37709467b48Spatrick bool isKeyOf(const DISubrange *RHS) const { 378097a140dSpatrick auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool { 379097a140dSpatrick if (Node1 == Node2) 38009467b48Spatrick return true; 38109467b48Spatrick 382097a140dSpatrick ConstantAsMetadata *MD1 = dyn_cast_or_null<ConstantAsMetadata>(Node1); 383097a140dSpatrick ConstantAsMetadata *MD2 = dyn_cast_or_null<ConstantAsMetadata>(Node2); 384097a140dSpatrick if (MD1 && MD2) { 385097a140dSpatrick ConstantInt *CV1 = cast<ConstantInt>(MD1->getValue()); 386097a140dSpatrick ConstantInt *CV2 = cast<ConstantInt>(MD2->getValue()); 387097a140dSpatrick if (CV1->getSExtValue() == CV2->getSExtValue()) 388097a140dSpatrick return true; 389097a140dSpatrick } 390097a140dSpatrick return false; 391097a140dSpatrick }; 392097a140dSpatrick 393097a140dSpatrick return BoundsEqual(CountNode, RHS->getRawCountNode()) && 394097a140dSpatrick BoundsEqual(LowerBound, RHS->getRawLowerBound()) && 395097a140dSpatrick BoundsEqual(UpperBound, RHS->getRawUpperBound()) && 396097a140dSpatrick BoundsEqual(Stride, RHS->getRawStride()); 39709467b48Spatrick } 39809467b48Spatrick 39909467b48Spatrick unsigned getHashValue() const { 400097a140dSpatrick if (CountNode) 40109467b48Spatrick if (auto *MD = dyn_cast<ConstantAsMetadata>(CountNode)) 40209467b48Spatrick return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(), 403097a140dSpatrick LowerBound, UpperBound, Stride); 404097a140dSpatrick return hash_combine(CountNode, LowerBound, UpperBound, Stride); 40509467b48Spatrick } 40609467b48Spatrick }; 40709467b48Spatrick 40873471bf0Spatrick template <> struct MDNodeKeyImpl<DIGenericSubrange> { 40973471bf0Spatrick Metadata *CountNode; 41073471bf0Spatrick Metadata *LowerBound; 41173471bf0Spatrick Metadata *UpperBound; 41273471bf0Spatrick Metadata *Stride; 41373471bf0Spatrick 41473471bf0Spatrick MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound, 41573471bf0Spatrick Metadata *Stride) 41673471bf0Spatrick : CountNode(CountNode), LowerBound(LowerBound), UpperBound(UpperBound), 41773471bf0Spatrick Stride(Stride) {} 41873471bf0Spatrick MDNodeKeyImpl(const DIGenericSubrange *N) 41973471bf0Spatrick : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()), 42073471bf0Spatrick UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {} 42173471bf0Spatrick 42273471bf0Spatrick bool isKeyOf(const DIGenericSubrange *RHS) const { 42373471bf0Spatrick return (CountNode == RHS->getRawCountNode()) && 42473471bf0Spatrick (LowerBound == RHS->getRawLowerBound()) && 42573471bf0Spatrick (UpperBound == RHS->getRawUpperBound()) && 42673471bf0Spatrick (Stride == RHS->getRawStride()); 42773471bf0Spatrick } 42873471bf0Spatrick 42973471bf0Spatrick unsigned getHashValue() const { 43073471bf0Spatrick auto *MD = dyn_cast_or_null<ConstantAsMetadata>(CountNode); 43173471bf0Spatrick if (CountNode && MD) 43273471bf0Spatrick return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(), 43373471bf0Spatrick LowerBound, UpperBound, Stride); 43473471bf0Spatrick return hash_combine(CountNode, LowerBound, UpperBound, Stride); 43573471bf0Spatrick } 43673471bf0Spatrick }; 43773471bf0Spatrick 43809467b48Spatrick template <> struct MDNodeKeyImpl<DIEnumerator> { 439097a140dSpatrick APInt Value; 44009467b48Spatrick MDString *Name; 44109467b48Spatrick bool IsUnsigned; 44209467b48Spatrick 443097a140dSpatrick MDNodeKeyImpl(APInt Value, bool IsUnsigned, MDString *Name) 44409467b48Spatrick : Value(Value), Name(Name), IsUnsigned(IsUnsigned) {} 445097a140dSpatrick MDNodeKeyImpl(int64_t Value, bool IsUnsigned, MDString *Name) 446097a140dSpatrick : Value(APInt(64, Value, !IsUnsigned)), Name(Name), 447097a140dSpatrick IsUnsigned(IsUnsigned) {} 44809467b48Spatrick MDNodeKeyImpl(const DIEnumerator *N) 44909467b48Spatrick : Value(N->getValue()), Name(N->getRawName()), 45009467b48Spatrick IsUnsigned(N->isUnsigned()) {} 45109467b48Spatrick 45209467b48Spatrick bool isKeyOf(const DIEnumerator *RHS) const { 453*d415bd75Srobert return Value.getBitWidth() == RHS->getValue().getBitWidth() && 454*d415bd75Srobert Value == RHS->getValue() && IsUnsigned == RHS->isUnsigned() && 455*d415bd75Srobert Name == RHS->getRawName(); 45609467b48Spatrick } 45709467b48Spatrick 45809467b48Spatrick unsigned getHashValue() const { return hash_combine(Value, Name); } 45909467b48Spatrick }; 46009467b48Spatrick 46109467b48Spatrick template <> struct MDNodeKeyImpl<DIBasicType> { 46209467b48Spatrick unsigned Tag; 46309467b48Spatrick MDString *Name; 46409467b48Spatrick uint64_t SizeInBits; 46509467b48Spatrick uint32_t AlignInBits; 46609467b48Spatrick unsigned Encoding; 46709467b48Spatrick unsigned Flags; 46809467b48Spatrick 46909467b48Spatrick MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits, 47009467b48Spatrick uint32_t AlignInBits, unsigned Encoding, unsigned Flags) 47109467b48Spatrick : Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits), 47209467b48Spatrick Encoding(Encoding), Flags(Flags) {} 47309467b48Spatrick MDNodeKeyImpl(const DIBasicType *N) 47409467b48Spatrick : Tag(N->getTag()), Name(N->getRawName()), SizeInBits(N->getSizeInBits()), 475*d415bd75Srobert AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()), 476*d415bd75Srobert Flags(N->getFlags()) {} 47709467b48Spatrick 47809467b48Spatrick bool isKeyOf(const DIBasicType *RHS) const { 47909467b48Spatrick return Tag == RHS->getTag() && Name == RHS->getRawName() && 48009467b48Spatrick SizeInBits == RHS->getSizeInBits() && 48109467b48Spatrick AlignInBits == RHS->getAlignInBits() && 482*d415bd75Srobert Encoding == RHS->getEncoding() && Flags == RHS->getFlags(); 48309467b48Spatrick } 48409467b48Spatrick 48509467b48Spatrick unsigned getHashValue() const { 48609467b48Spatrick return hash_combine(Tag, Name, SizeInBits, AlignInBits, Encoding); 48709467b48Spatrick } 48809467b48Spatrick }; 48909467b48Spatrick 49073471bf0Spatrick template <> struct MDNodeKeyImpl<DIStringType> { 49173471bf0Spatrick unsigned Tag; 49273471bf0Spatrick MDString *Name; 49373471bf0Spatrick Metadata *StringLength; 49473471bf0Spatrick Metadata *StringLengthExp; 495*d415bd75Srobert Metadata *StringLocationExp; 49673471bf0Spatrick uint64_t SizeInBits; 49773471bf0Spatrick uint32_t AlignInBits; 49873471bf0Spatrick unsigned Encoding; 49973471bf0Spatrick 50073471bf0Spatrick MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *StringLength, 501*d415bd75Srobert Metadata *StringLengthExp, Metadata *StringLocationExp, 502*d415bd75Srobert uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding) 50373471bf0Spatrick : Tag(Tag), Name(Name), StringLength(StringLength), 504*d415bd75Srobert StringLengthExp(StringLengthExp), StringLocationExp(StringLocationExp), 505*d415bd75Srobert SizeInBits(SizeInBits), AlignInBits(AlignInBits), Encoding(Encoding) {} 50673471bf0Spatrick MDNodeKeyImpl(const DIStringType *N) 50773471bf0Spatrick : Tag(N->getTag()), Name(N->getRawName()), 50873471bf0Spatrick StringLength(N->getRawStringLength()), 50973471bf0Spatrick StringLengthExp(N->getRawStringLengthExp()), 510*d415bd75Srobert StringLocationExp(N->getRawStringLocationExp()), 51173471bf0Spatrick SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()), 51273471bf0Spatrick Encoding(N->getEncoding()) {} 51373471bf0Spatrick 51473471bf0Spatrick bool isKeyOf(const DIStringType *RHS) const { 51573471bf0Spatrick return Tag == RHS->getTag() && Name == RHS->getRawName() && 51673471bf0Spatrick SizeInBits == RHS->getSizeInBits() && 51773471bf0Spatrick AlignInBits == RHS->getAlignInBits() && 51873471bf0Spatrick Encoding == RHS->getEncoding(); 51973471bf0Spatrick } 52073471bf0Spatrick unsigned getHashValue() const { return hash_combine(Tag, Name, Encoding); } 52173471bf0Spatrick }; 52273471bf0Spatrick 52309467b48Spatrick template <> struct MDNodeKeyImpl<DIDerivedType> { 52409467b48Spatrick unsigned Tag; 52509467b48Spatrick MDString *Name; 52609467b48Spatrick Metadata *File; 52709467b48Spatrick unsigned Line; 52809467b48Spatrick Metadata *Scope; 52909467b48Spatrick Metadata *BaseType; 53009467b48Spatrick uint64_t SizeInBits; 53109467b48Spatrick uint64_t OffsetInBits; 53209467b48Spatrick uint32_t AlignInBits; 533*d415bd75Srobert std::optional<unsigned> DWARFAddressSpace; 53409467b48Spatrick unsigned Flags; 53509467b48Spatrick Metadata *ExtraData; 536*d415bd75Srobert Metadata *Annotations; 53709467b48Spatrick 53809467b48Spatrick MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, 53909467b48Spatrick Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, 54009467b48Spatrick uint32_t AlignInBits, uint64_t OffsetInBits, 541*d415bd75Srobert std::optional<unsigned> DWARFAddressSpace, unsigned Flags, 542*d415bd75Srobert Metadata *ExtraData, Metadata *Annotations) 54309467b48Spatrick : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope), 54409467b48Spatrick BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits), 54509467b48Spatrick AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace), 546*d415bd75Srobert Flags(Flags), ExtraData(ExtraData), Annotations(Annotations) {} 54709467b48Spatrick MDNodeKeyImpl(const DIDerivedType *N) 54809467b48Spatrick : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()), 54909467b48Spatrick Line(N->getLine()), Scope(N->getRawScope()), 55009467b48Spatrick BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()), 55109467b48Spatrick OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()), 55209467b48Spatrick DWARFAddressSpace(N->getDWARFAddressSpace()), Flags(N->getFlags()), 553*d415bd75Srobert ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {} 55409467b48Spatrick 55509467b48Spatrick bool isKeyOf(const DIDerivedType *RHS) const { 55609467b48Spatrick return Tag == RHS->getTag() && Name == RHS->getRawName() && 55709467b48Spatrick File == RHS->getRawFile() && Line == RHS->getLine() && 55809467b48Spatrick Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() && 55909467b48Spatrick SizeInBits == RHS->getSizeInBits() && 56009467b48Spatrick AlignInBits == RHS->getAlignInBits() && 56109467b48Spatrick OffsetInBits == RHS->getOffsetInBits() && 56209467b48Spatrick DWARFAddressSpace == RHS->getDWARFAddressSpace() && 563*d415bd75Srobert Flags == RHS->getFlags() && ExtraData == RHS->getRawExtraData() && 564*d415bd75Srobert Annotations == RHS->getRawAnnotations(); 56509467b48Spatrick } 56609467b48Spatrick 56709467b48Spatrick unsigned getHashValue() const { 56809467b48Spatrick // If this is a member inside an ODR type, only hash the type and the name. 56909467b48Spatrick // Otherwise the hash will be stronger than 57009467b48Spatrick // MDNodeSubsetEqualImpl::isODRMember(). 57109467b48Spatrick if (Tag == dwarf::DW_TAG_member && Name) 57209467b48Spatrick if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope)) 57309467b48Spatrick if (CT->getRawIdentifier()) 57409467b48Spatrick return hash_combine(Name, Scope); 57509467b48Spatrick 57609467b48Spatrick // Intentionally computes the hash on a subset of the operands for 57709467b48Spatrick // performance reason. The subset has to be significant enough to avoid 57809467b48Spatrick // collision "most of the time". There is no correctness issue in case of 57909467b48Spatrick // collision because of the full check above. 58009467b48Spatrick return hash_combine(Tag, Name, File, Line, Scope, BaseType, Flags); 58109467b48Spatrick } 58209467b48Spatrick }; 58309467b48Spatrick 58409467b48Spatrick template <> struct MDNodeSubsetEqualImpl<DIDerivedType> { 58509467b48Spatrick using KeyTy = MDNodeKeyImpl<DIDerivedType>; 58609467b48Spatrick 58709467b48Spatrick static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) { 58809467b48Spatrick return isODRMember(LHS.Tag, LHS.Scope, LHS.Name, RHS); 58909467b48Spatrick } 59009467b48Spatrick 591*d415bd75Srobert static bool isSubsetEqual(const DIDerivedType *LHS, 592*d415bd75Srobert const DIDerivedType *RHS) { 59309467b48Spatrick return isODRMember(LHS->getTag(), LHS->getRawScope(), LHS->getRawName(), 59409467b48Spatrick RHS); 59509467b48Spatrick } 59609467b48Spatrick 59709467b48Spatrick /// Subprograms compare equal if they declare the same function in an ODR 59809467b48Spatrick /// type. 59909467b48Spatrick static bool isODRMember(unsigned Tag, const Metadata *Scope, 60009467b48Spatrick const MDString *Name, const DIDerivedType *RHS) { 60109467b48Spatrick // Check whether the LHS is eligible. 60209467b48Spatrick if (Tag != dwarf::DW_TAG_member || !Name) 60309467b48Spatrick return false; 60409467b48Spatrick 60509467b48Spatrick auto *CT = dyn_cast_or_null<DICompositeType>(Scope); 60609467b48Spatrick if (!CT || !CT->getRawIdentifier()) 60709467b48Spatrick return false; 60809467b48Spatrick 60909467b48Spatrick // Compare to the RHS. 61009467b48Spatrick return Tag == RHS->getTag() && Name == RHS->getRawName() && 61109467b48Spatrick Scope == RHS->getRawScope(); 61209467b48Spatrick } 61309467b48Spatrick }; 61409467b48Spatrick 61509467b48Spatrick template <> struct MDNodeKeyImpl<DICompositeType> { 61609467b48Spatrick unsigned Tag; 61709467b48Spatrick MDString *Name; 61809467b48Spatrick Metadata *File; 61909467b48Spatrick unsigned Line; 62009467b48Spatrick Metadata *Scope; 62109467b48Spatrick Metadata *BaseType; 62209467b48Spatrick uint64_t SizeInBits; 62309467b48Spatrick uint64_t OffsetInBits; 62409467b48Spatrick uint32_t AlignInBits; 62509467b48Spatrick unsigned Flags; 62609467b48Spatrick Metadata *Elements; 62709467b48Spatrick unsigned RuntimeLang; 62809467b48Spatrick Metadata *VTableHolder; 62909467b48Spatrick Metadata *TemplateParams; 63009467b48Spatrick MDString *Identifier; 63109467b48Spatrick Metadata *Discriminator; 632097a140dSpatrick Metadata *DataLocation; 63373471bf0Spatrick Metadata *Associated; 63473471bf0Spatrick Metadata *Allocated; 63573471bf0Spatrick Metadata *Rank; 636*d415bd75Srobert Metadata *Annotations; 63709467b48Spatrick 63809467b48Spatrick MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, 63909467b48Spatrick Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, 64009467b48Spatrick uint32_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, 64109467b48Spatrick Metadata *Elements, unsigned RuntimeLang, 64209467b48Spatrick Metadata *VTableHolder, Metadata *TemplateParams, 643097a140dSpatrick MDString *Identifier, Metadata *Discriminator, 64473471bf0Spatrick Metadata *DataLocation, Metadata *Associated, 645*d415bd75Srobert Metadata *Allocated, Metadata *Rank, Metadata *Annotations) 64609467b48Spatrick : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope), 64709467b48Spatrick BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits), 64809467b48Spatrick AlignInBits(AlignInBits), Flags(Flags), Elements(Elements), 64909467b48Spatrick RuntimeLang(RuntimeLang), VTableHolder(VTableHolder), 65009467b48Spatrick TemplateParams(TemplateParams), Identifier(Identifier), 65173471bf0Spatrick Discriminator(Discriminator), DataLocation(DataLocation), 652*d415bd75Srobert Associated(Associated), Allocated(Allocated), Rank(Rank), 653*d415bd75Srobert Annotations(Annotations) {} 65409467b48Spatrick MDNodeKeyImpl(const DICompositeType *N) 65509467b48Spatrick : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()), 65609467b48Spatrick Line(N->getLine()), Scope(N->getRawScope()), 65709467b48Spatrick BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()), 65809467b48Spatrick OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()), 65909467b48Spatrick Flags(N->getFlags()), Elements(N->getRawElements()), 66009467b48Spatrick RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()), 66109467b48Spatrick TemplateParams(N->getRawTemplateParams()), 66209467b48Spatrick Identifier(N->getRawIdentifier()), 663097a140dSpatrick Discriminator(N->getRawDiscriminator()), 66473471bf0Spatrick DataLocation(N->getRawDataLocation()), 66573471bf0Spatrick Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()), 666*d415bd75Srobert Rank(N->getRawRank()), Annotations(N->getRawAnnotations()) {} 66709467b48Spatrick 66809467b48Spatrick bool isKeyOf(const DICompositeType *RHS) const { 66909467b48Spatrick return Tag == RHS->getTag() && Name == RHS->getRawName() && 67009467b48Spatrick File == RHS->getRawFile() && Line == RHS->getLine() && 67109467b48Spatrick Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() && 67209467b48Spatrick SizeInBits == RHS->getSizeInBits() && 67309467b48Spatrick AlignInBits == RHS->getAlignInBits() && 67409467b48Spatrick OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() && 67509467b48Spatrick Elements == RHS->getRawElements() && 67609467b48Spatrick RuntimeLang == RHS->getRuntimeLang() && 67709467b48Spatrick VTableHolder == RHS->getRawVTableHolder() && 67809467b48Spatrick TemplateParams == RHS->getRawTemplateParams() && 67909467b48Spatrick Identifier == RHS->getRawIdentifier() && 680097a140dSpatrick Discriminator == RHS->getRawDiscriminator() && 68173471bf0Spatrick DataLocation == RHS->getRawDataLocation() && 68273471bf0Spatrick Associated == RHS->getRawAssociated() && 683*d415bd75Srobert Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() && 684*d415bd75Srobert Annotations == RHS->getRawAnnotations(); 68509467b48Spatrick } 68609467b48Spatrick 68709467b48Spatrick unsigned getHashValue() const { 68809467b48Spatrick // Intentionally computes the hash on a subset of the operands for 68909467b48Spatrick // performance reason. The subset has to be significant enough to avoid 69009467b48Spatrick // collision "most of the time". There is no correctness issue in case of 69109467b48Spatrick // collision because of the full check above. 69209467b48Spatrick return hash_combine(Name, File, Line, BaseType, Scope, Elements, 693*d415bd75Srobert TemplateParams, Annotations); 69409467b48Spatrick } 69509467b48Spatrick }; 69609467b48Spatrick 69709467b48Spatrick template <> struct MDNodeKeyImpl<DISubroutineType> { 69809467b48Spatrick unsigned Flags; 69909467b48Spatrick uint8_t CC; 70009467b48Spatrick Metadata *TypeArray; 70109467b48Spatrick 70209467b48Spatrick MDNodeKeyImpl(unsigned Flags, uint8_t CC, Metadata *TypeArray) 70309467b48Spatrick : Flags(Flags), CC(CC), TypeArray(TypeArray) {} 70409467b48Spatrick MDNodeKeyImpl(const DISubroutineType *N) 70509467b48Spatrick : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()) {} 70609467b48Spatrick 70709467b48Spatrick bool isKeyOf(const DISubroutineType *RHS) const { 70809467b48Spatrick return Flags == RHS->getFlags() && CC == RHS->getCC() && 70909467b48Spatrick TypeArray == RHS->getRawTypeArray(); 71009467b48Spatrick } 71109467b48Spatrick 71209467b48Spatrick unsigned getHashValue() const { return hash_combine(Flags, CC, TypeArray); } 71309467b48Spatrick }; 71409467b48Spatrick 71509467b48Spatrick template <> struct MDNodeKeyImpl<DIFile> { 71609467b48Spatrick MDString *Filename; 71709467b48Spatrick MDString *Directory; 718*d415bd75Srobert std::optional<DIFile::ChecksumInfo<MDString *>> Checksum; 719*d415bd75Srobert MDString *Source; 72009467b48Spatrick 72109467b48Spatrick MDNodeKeyImpl(MDString *Filename, MDString *Directory, 722*d415bd75Srobert std::optional<DIFile::ChecksumInfo<MDString *>> Checksum, 723*d415bd75Srobert MDString *Source) 72409467b48Spatrick : Filename(Filename), Directory(Directory), Checksum(Checksum), 72509467b48Spatrick Source(Source) {} 72609467b48Spatrick MDNodeKeyImpl(const DIFile *N) 72709467b48Spatrick : Filename(N->getRawFilename()), Directory(N->getRawDirectory()), 72809467b48Spatrick Checksum(N->getRawChecksum()), Source(N->getRawSource()) {} 72909467b48Spatrick 73009467b48Spatrick bool isKeyOf(const DIFile *RHS) const { 73109467b48Spatrick return Filename == RHS->getRawFilename() && 73209467b48Spatrick Directory == RHS->getRawDirectory() && 733*d415bd75Srobert Checksum == RHS->getRawChecksum() && Source == RHS->getRawSource(); 73409467b48Spatrick } 73509467b48Spatrick 73609467b48Spatrick unsigned getHashValue() const { 737*d415bd75Srobert return hash_combine(Filename, Directory, Checksum ? Checksum->Kind : 0, 738*d415bd75Srobert Checksum ? Checksum->Value : nullptr, Source); 73909467b48Spatrick } 74009467b48Spatrick }; 74109467b48Spatrick 74209467b48Spatrick template <> struct MDNodeKeyImpl<DISubprogram> { 74309467b48Spatrick Metadata *Scope; 74409467b48Spatrick MDString *Name; 74509467b48Spatrick MDString *LinkageName; 74609467b48Spatrick Metadata *File; 74709467b48Spatrick unsigned Line; 74809467b48Spatrick Metadata *Type; 74909467b48Spatrick unsigned ScopeLine; 75009467b48Spatrick Metadata *ContainingType; 75109467b48Spatrick unsigned VirtualIndex; 75209467b48Spatrick int ThisAdjustment; 75309467b48Spatrick unsigned Flags; 75409467b48Spatrick unsigned SPFlags; 75509467b48Spatrick Metadata *Unit; 75609467b48Spatrick Metadata *TemplateParams; 75709467b48Spatrick Metadata *Declaration; 75809467b48Spatrick Metadata *RetainedNodes; 75909467b48Spatrick Metadata *ThrownTypes; 760*d415bd75Srobert Metadata *Annotations; 761*d415bd75Srobert MDString *TargetFuncName; 76209467b48Spatrick 76309467b48Spatrick MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName, 76409467b48Spatrick Metadata *File, unsigned Line, Metadata *Type, 76509467b48Spatrick unsigned ScopeLine, Metadata *ContainingType, 76609467b48Spatrick unsigned VirtualIndex, int ThisAdjustment, unsigned Flags, 76709467b48Spatrick unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams, 76809467b48Spatrick Metadata *Declaration, Metadata *RetainedNodes, 769*d415bd75Srobert Metadata *ThrownTypes, Metadata *Annotations, 770*d415bd75Srobert MDString *TargetFuncName) 77109467b48Spatrick : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File), 77209467b48Spatrick Line(Line), Type(Type), ScopeLine(ScopeLine), 77309467b48Spatrick ContainingType(ContainingType), VirtualIndex(VirtualIndex), 77409467b48Spatrick ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags), 77509467b48Spatrick Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration), 776*d415bd75Srobert RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes), 777*d415bd75Srobert Annotations(Annotations), TargetFuncName(TargetFuncName) {} 77809467b48Spatrick MDNodeKeyImpl(const DISubprogram *N) 77909467b48Spatrick : Scope(N->getRawScope()), Name(N->getRawName()), 78009467b48Spatrick LinkageName(N->getRawLinkageName()), File(N->getRawFile()), 78109467b48Spatrick Line(N->getLine()), Type(N->getRawType()), ScopeLine(N->getScopeLine()), 78209467b48Spatrick ContainingType(N->getRawContainingType()), 78309467b48Spatrick VirtualIndex(N->getVirtualIndex()), 78409467b48Spatrick ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()), 78509467b48Spatrick SPFlags(N->getSPFlags()), Unit(N->getRawUnit()), 78609467b48Spatrick TemplateParams(N->getRawTemplateParams()), 78709467b48Spatrick Declaration(N->getRawDeclaration()), 78809467b48Spatrick RetainedNodes(N->getRawRetainedNodes()), 789*d415bd75Srobert ThrownTypes(N->getRawThrownTypes()), 790*d415bd75Srobert Annotations(N->getRawAnnotations()), 791*d415bd75Srobert TargetFuncName(N->getRawTargetFuncName()) {} 79209467b48Spatrick 79309467b48Spatrick bool isKeyOf(const DISubprogram *RHS) const { 79409467b48Spatrick return Scope == RHS->getRawScope() && Name == RHS->getRawName() && 79509467b48Spatrick LinkageName == RHS->getRawLinkageName() && 79609467b48Spatrick File == RHS->getRawFile() && Line == RHS->getLine() && 79709467b48Spatrick Type == RHS->getRawType() && ScopeLine == RHS->getScopeLine() && 79809467b48Spatrick ContainingType == RHS->getRawContainingType() && 79909467b48Spatrick VirtualIndex == RHS->getVirtualIndex() && 80009467b48Spatrick ThisAdjustment == RHS->getThisAdjustment() && 80109467b48Spatrick Flags == RHS->getFlags() && SPFlags == RHS->getSPFlags() && 80209467b48Spatrick Unit == RHS->getUnit() && 80309467b48Spatrick TemplateParams == RHS->getRawTemplateParams() && 80409467b48Spatrick Declaration == RHS->getRawDeclaration() && 80509467b48Spatrick RetainedNodes == RHS->getRawRetainedNodes() && 806*d415bd75Srobert ThrownTypes == RHS->getRawThrownTypes() && 807*d415bd75Srobert Annotations == RHS->getRawAnnotations() && 808*d415bd75Srobert TargetFuncName == RHS->getRawTargetFuncName(); 80909467b48Spatrick } 81009467b48Spatrick 81109467b48Spatrick bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; } 81209467b48Spatrick 81309467b48Spatrick unsigned getHashValue() const { 81409467b48Spatrick // If this is a declaration inside an ODR type, only hash the type and the 81509467b48Spatrick // name. Otherwise the hash will be stronger than 81609467b48Spatrick // MDNodeSubsetEqualImpl::isDeclarationOfODRMember(). 81709467b48Spatrick if (!isDefinition() && LinkageName) 81809467b48Spatrick if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope)) 81909467b48Spatrick if (CT->getRawIdentifier()) 82009467b48Spatrick return hash_combine(LinkageName, Scope); 82109467b48Spatrick 82209467b48Spatrick // Intentionally computes the hash on a subset of the operands for 82309467b48Spatrick // performance reason. The subset has to be significant enough to avoid 82409467b48Spatrick // collision "most of the time". There is no correctness issue in case of 82509467b48Spatrick // collision because of the full check above. 82609467b48Spatrick return hash_combine(Name, Scope, File, Type, Line); 82709467b48Spatrick } 82809467b48Spatrick }; 82909467b48Spatrick 83009467b48Spatrick template <> struct MDNodeSubsetEqualImpl<DISubprogram> { 83109467b48Spatrick using KeyTy = MDNodeKeyImpl<DISubprogram>; 83209467b48Spatrick 83309467b48Spatrick static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) { 83409467b48Spatrick return isDeclarationOfODRMember(LHS.isDefinition(), LHS.Scope, 83509467b48Spatrick LHS.LinkageName, LHS.TemplateParams, RHS); 83609467b48Spatrick } 83709467b48Spatrick 83809467b48Spatrick static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) { 83909467b48Spatrick return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(), 84009467b48Spatrick LHS->getRawLinkageName(), 84109467b48Spatrick LHS->getRawTemplateParams(), RHS); 84209467b48Spatrick } 84309467b48Spatrick 84409467b48Spatrick /// Subprograms compare equal if they declare the same function in an ODR 84509467b48Spatrick /// type. 84609467b48Spatrick static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope, 84709467b48Spatrick const MDString *LinkageName, 84809467b48Spatrick const Metadata *TemplateParams, 84909467b48Spatrick const DISubprogram *RHS) { 85009467b48Spatrick // Check whether the LHS is eligible. 85109467b48Spatrick if (IsDefinition || !Scope || !LinkageName) 85209467b48Spatrick return false; 85309467b48Spatrick 85409467b48Spatrick auto *CT = dyn_cast_or_null<DICompositeType>(Scope); 85509467b48Spatrick if (!CT || !CT->getRawIdentifier()) 85609467b48Spatrick return false; 85709467b48Spatrick 85809467b48Spatrick // Compare to the RHS. 85909467b48Spatrick // FIXME: We need to compare template parameters here to avoid incorrect 86073471bf0Spatrick // collisions in mapMetadata when RF_ReuseAndMutateDistinctMDs and a 86173471bf0Spatrick // ODR-DISubprogram has a non-ODR template parameter (i.e., a 86273471bf0Spatrick // DICompositeType that does not have an identifier). Eventually we should 86373471bf0Spatrick // decouple ODR logic from uniquing logic. 86409467b48Spatrick return IsDefinition == RHS->isDefinition() && Scope == RHS->getRawScope() && 86509467b48Spatrick LinkageName == RHS->getRawLinkageName() && 86609467b48Spatrick TemplateParams == RHS->getRawTemplateParams(); 86709467b48Spatrick } 86809467b48Spatrick }; 86909467b48Spatrick 87009467b48Spatrick template <> struct MDNodeKeyImpl<DILexicalBlock> { 87109467b48Spatrick Metadata *Scope; 87209467b48Spatrick Metadata *File; 87309467b48Spatrick unsigned Line; 87409467b48Spatrick unsigned Column; 87509467b48Spatrick 87609467b48Spatrick MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Line, unsigned Column) 87709467b48Spatrick : Scope(Scope), File(File), Line(Line), Column(Column) {} 87809467b48Spatrick MDNodeKeyImpl(const DILexicalBlock *N) 87909467b48Spatrick : Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()), 88009467b48Spatrick Column(N->getColumn()) {} 88109467b48Spatrick 88209467b48Spatrick bool isKeyOf(const DILexicalBlock *RHS) const { 88309467b48Spatrick return Scope == RHS->getRawScope() && File == RHS->getRawFile() && 88409467b48Spatrick Line == RHS->getLine() && Column == RHS->getColumn(); 88509467b48Spatrick } 88609467b48Spatrick 88709467b48Spatrick unsigned getHashValue() const { 88809467b48Spatrick return hash_combine(Scope, File, Line, Column); 88909467b48Spatrick } 89009467b48Spatrick }; 89109467b48Spatrick 89209467b48Spatrick template <> struct MDNodeKeyImpl<DILexicalBlockFile> { 89309467b48Spatrick Metadata *Scope; 89409467b48Spatrick Metadata *File; 89509467b48Spatrick unsigned Discriminator; 89609467b48Spatrick 89709467b48Spatrick MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator) 89809467b48Spatrick : Scope(Scope), File(File), Discriminator(Discriminator) {} 89909467b48Spatrick MDNodeKeyImpl(const DILexicalBlockFile *N) 90009467b48Spatrick : Scope(N->getRawScope()), File(N->getRawFile()), 90109467b48Spatrick Discriminator(N->getDiscriminator()) {} 90209467b48Spatrick 90309467b48Spatrick bool isKeyOf(const DILexicalBlockFile *RHS) const { 90409467b48Spatrick return Scope == RHS->getRawScope() && File == RHS->getRawFile() && 90509467b48Spatrick Discriminator == RHS->getDiscriminator(); 90609467b48Spatrick } 90709467b48Spatrick 90809467b48Spatrick unsigned getHashValue() const { 90909467b48Spatrick return hash_combine(Scope, File, Discriminator); 91009467b48Spatrick } 91109467b48Spatrick }; 91209467b48Spatrick 91309467b48Spatrick template <> struct MDNodeKeyImpl<DINamespace> { 91409467b48Spatrick Metadata *Scope; 91509467b48Spatrick MDString *Name; 91609467b48Spatrick bool ExportSymbols; 91709467b48Spatrick 91809467b48Spatrick MDNodeKeyImpl(Metadata *Scope, MDString *Name, bool ExportSymbols) 91909467b48Spatrick : Scope(Scope), Name(Name), ExportSymbols(ExportSymbols) {} 92009467b48Spatrick MDNodeKeyImpl(const DINamespace *N) 92109467b48Spatrick : Scope(N->getRawScope()), Name(N->getRawName()), 92209467b48Spatrick ExportSymbols(N->getExportSymbols()) {} 92309467b48Spatrick 92409467b48Spatrick bool isKeyOf(const DINamespace *RHS) const { 92509467b48Spatrick return Scope == RHS->getRawScope() && Name == RHS->getRawName() && 92609467b48Spatrick ExportSymbols == RHS->getExportSymbols(); 92709467b48Spatrick } 92809467b48Spatrick 929*d415bd75Srobert unsigned getHashValue() const { return hash_combine(Scope, Name); } 93009467b48Spatrick }; 93109467b48Spatrick 93209467b48Spatrick template <> struct MDNodeKeyImpl<DICommonBlock> { 93309467b48Spatrick Metadata *Scope; 93409467b48Spatrick Metadata *Decl; 93509467b48Spatrick MDString *Name; 93609467b48Spatrick Metadata *File; 93709467b48Spatrick unsigned LineNo; 93809467b48Spatrick 939*d415bd75Srobert MDNodeKeyImpl(Metadata *Scope, Metadata *Decl, MDString *Name, Metadata *File, 940*d415bd75Srobert unsigned LineNo) 94109467b48Spatrick : Scope(Scope), Decl(Decl), Name(Name), File(File), LineNo(LineNo) {} 94209467b48Spatrick MDNodeKeyImpl(const DICommonBlock *N) 94309467b48Spatrick : Scope(N->getRawScope()), Decl(N->getRawDecl()), Name(N->getRawName()), 94409467b48Spatrick File(N->getRawFile()), LineNo(N->getLineNo()) {} 94509467b48Spatrick 94609467b48Spatrick bool isKeyOf(const DICommonBlock *RHS) const { 94709467b48Spatrick return Scope == RHS->getRawScope() && Decl == RHS->getRawDecl() && 94809467b48Spatrick Name == RHS->getRawName() && File == RHS->getRawFile() && 94909467b48Spatrick LineNo == RHS->getLineNo(); 95009467b48Spatrick } 95109467b48Spatrick 95209467b48Spatrick unsigned getHashValue() const { 95309467b48Spatrick return hash_combine(Scope, Decl, Name, File, LineNo); 95409467b48Spatrick } 95509467b48Spatrick }; 95609467b48Spatrick 95709467b48Spatrick template <> struct MDNodeKeyImpl<DIModule> { 958097a140dSpatrick Metadata *File; 95909467b48Spatrick Metadata *Scope; 96009467b48Spatrick MDString *Name; 96109467b48Spatrick MDString *ConfigurationMacros; 96209467b48Spatrick MDString *IncludePath; 963097a140dSpatrick MDString *APINotesFile; 964097a140dSpatrick unsigned LineNo; 96573471bf0Spatrick bool IsDecl; 96609467b48Spatrick 967097a140dSpatrick MDNodeKeyImpl(Metadata *File, Metadata *Scope, MDString *Name, 968097a140dSpatrick MDString *ConfigurationMacros, MDString *IncludePath, 96973471bf0Spatrick MDString *APINotesFile, unsigned LineNo, bool IsDecl) 970097a140dSpatrick : File(File), Scope(Scope), Name(Name), 971097a140dSpatrick ConfigurationMacros(ConfigurationMacros), IncludePath(IncludePath), 97273471bf0Spatrick APINotesFile(APINotesFile), LineNo(LineNo), IsDecl(IsDecl) {} 97309467b48Spatrick MDNodeKeyImpl(const DIModule *N) 974097a140dSpatrick : File(N->getRawFile()), Scope(N->getRawScope()), Name(N->getRawName()), 97509467b48Spatrick ConfigurationMacros(N->getRawConfigurationMacros()), 976097a140dSpatrick IncludePath(N->getRawIncludePath()), 97773471bf0Spatrick APINotesFile(N->getRawAPINotesFile()), LineNo(N->getLineNo()), 97873471bf0Spatrick IsDecl(N->getIsDecl()) {} 97909467b48Spatrick 98009467b48Spatrick bool isKeyOf(const DIModule *RHS) const { 98109467b48Spatrick return Scope == RHS->getRawScope() && Name == RHS->getRawName() && 98209467b48Spatrick ConfigurationMacros == RHS->getRawConfigurationMacros() && 98309467b48Spatrick IncludePath == RHS->getRawIncludePath() && 984097a140dSpatrick APINotesFile == RHS->getRawAPINotesFile() && 98573471bf0Spatrick File == RHS->getRawFile() && LineNo == RHS->getLineNo() && 98673471bf0Spatrick IsDecl == RHS->getIsDecl(); 98709467b48Spatrick } 98809467b48Spatrick 98909467b48Spatrick unsigned getHashValue() const { 990097a140dSpatrick return hash_combine(Scope, Name, ConfigurationMacros, IncludePath); 99109467b48Spatrick } 99209467b48Spatrick }; 99309467b48Spatrick 99409467b48Spatrick template <> struct MDNodeKeyImpl<DITemplateTypeParameter> { 99509467b48Spatrick MDString *Name; 99609467b48Spatrick Metadata *Type; 997097a140dSpatrick bool IsDefault; 99809467b48Spatrick 999097a140dSpatrick MDNodeKeyImpl(MDString *Name, Metadata *Type, bool IsDefault) 1000097a140dSpatrick : Name(Name), Type(Type), IsDefault(IsDefault) {} 100109467b48Spatrick MDNodeKeyImpl(const DITemplateTypeParameter *N) 1002097a140dSpatrick : Name(N->getRawName()), Type(N->getRawType()), 1003097a140dSpatrick IsDefault(N->isDefault()) {} 100409467b48Spatrick 100509467b48Spatrick bool isKeyOf(const DITemplateTypeParameter *RHS) const { 1006097a140dSpatrick return Name == RHS->getRawName() && Type == RHS->getRawType() && 1007097a140dSpatrick IsDefault == RHS->isDefault(); 100809467b48Spatrick } 100909467b48Spatrick 1010097a140dSpatrick unsigned getHashValue() const { return hash_combine(Name, Type, IsDefault); } 101109467b48Spatrick }; 101209467b48Spatrick 101309467b48Spatrick template <> struct MDNodeKeyImpl<DITemplateValueParameter> { 101409467b48Spatrick unsigned Tag; 101509467b48Spatrick MDString *Name; 101609467b48Spatrick Metadata *Type; 1017097a140dSpatrick bool IsDefault; 101809467b48Spatrick Metadata *Value; 101909467b48Spatrick 1020097a140dSpatrick MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *Type, bool IsDefault, 1021097a140dSpatrick Metadata *Value) 1022097a140dSpatrick : Tag(Tag), Name(Name), Type(Type), IsDefault(IsDefault), Value(Value) {} 102309467b48Spatrick MDNodeKeyImpl(const DITemplateValueParameter *N) 102409467b48Spatrick : Tag(N->getTag()), Name(N->getRawName()), Type(N->getRawType()), 1025097a140dSpatrick IsDefault(N->isDefault()), Value(N->getValue()) {} 102609467b48Spatrick 102709467b48Spatrick bool isKeyOf(const DITemplateValueParameter *RHS) const { 102809467b48Spatrick return Tag == RHS->getTag() && Name == RHS->getRawName() && 1029097a140dSpatrick Type == RHS->getRawType() && IsDefault == RHS->isDefault() && 1030097a140dSpatrick Value == RHS->getValue(); 103109467b48Spatrick } 103209467b48Spatrick 1033097a140dSpatrick unsigned getHashValue() const { 1034097a140dSpatrick return hash_combine(Tag, Name, Type, IsDefault, Value); 1035097a140dSpatrick } 103609467b48Spatrick }; 103709467b48Spatrick 103809467b48Spatrick template <> struct MDNodeKeyImpl<DIGlobalVariable> { 103909467b48Spatrick Metadata *Scope; 104009467b48Spatrick MDString *Name; 104109467b48Spatrick MDString *LinkageName; 104209467b48Spatrick Metadata *File; 104309467b48Spatrick unsigned Line; 104409467b48Spatrick Metadata *Type; 104509467b48Spatrick bool IsLocalToUnit; 104609467b48Spatrick bool IsDefinition; 104709467b48Spatrick Metadata *StaticDataMemberDeclaration; 104809467b48Spatrick Metadata *TemplateParams; 104909467b48Spatrick uint32_t AlignInBits; 1050*d415bd75Srobert Metadata *Annotations; 105109467b48Spatrick 105209467b48Spatrick MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName, 105309467b48Spatrick Metadata *File, unsigned Line, Metadata *Type, 105409467b48Spatrick bool IsLocalToUnit, bool IsDefinition, 105509467b48Spatrick Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, 1056*d415bd75Srobert uint32_t AlignInBits, Metadata *Annotations) 105709467b48Spatrick : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File), 105809467b48Spatrick Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit), 105909467b48Spatrick IsDefinition(IsDefinition), 106009467b48Spatrick StaticDataMemberDeclaration(StaticDataMemberDeclaration), 1061*d415bd75Srobert TemplateParams(TemplateParams), AlignInBits(AlignInBits), 1062*d415bd75Srobert Annotations(Annotations) {} 106309467b48Spatrick MDNodeKeyImpl(const DIGlobalVariable *N) 106409467b48Spatrick : Scope(N->getRawScope()), Name(N->getRawName()), 106509467b48Spatrick LinkageName(N->getRawLinkageName()), File(N->getRawFile()), 106609467b48Spatrick Line(N->getLine()), Type(N->getRawType()), 106709467b48Spatrick IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()), 106809467b48Spatrick StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()), 106909467b48Spatrick TemplateParams(N->getRawTemplateParams()), 1070*d415bd75Srobert AlignInBits(N->getAlignInBits()), Annotations(N->getRawAnnotations()) {} 107109467b48Spatrick 107209467b48Spatrick bool isKeyOf(const DIGlobalVariable *RHS) const { 107309467b48Spatrick return Scope == RHS->getRawScope() && Name == RHS->getRawName() && 107409467b48Spatrick LinkageName == RHS->getRawLinkageName() && 107509467b48Spatrick File == RHS->getRawFile() && Line == RHS->getLine() && 107609467b48Spatrick Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() && 107709467b48Spatrick IsDefinition == RHS->isDefinition() && 107809467b48Spatrick StaticDataMemberDeclaration == 107909467b48Spatrick RHS->getRawStaticDataMemberDeclaration() && 108009467b48Spatrick TemplateParams == RHS->getRawTemplateParams() && 1081*d415bd75Srobert AlignInBits == RHS->getAlignInBits() && 1082*d415bd75Srobert Annotations == RHS->getRawAnnotations(); 108309467b48Spatrick } 108409467b48Spatrick 108509467b48Spatrick unsigned getHashValue() const { 108609467b48Spatrick // We do not use AlignInBits in hashing function here on purpose: 108709467b48Spatrick // in most cases this param for local variable is zero (for function param 108809467b48Spatrick // it is always zero). This leads to lots of hash collisions and errors on 108909467b48Spatrick // cases with lots of similar variables. 109009467b48Spatrick // clang/test/CodeGen/debug-info-257-args.c is an example of this problem, 109109467b48Spatrick // generated IR is random for each run and test fails with Align included. 109209467b48Spatrick // TODO: make hashing work fine with such situations 109309467b48Spatrick return hash_combine(Scope, Name, LinkageName, File, Line, Type, 109409467b48Spatrick IsLocalToUnit, IsDefinition, /* AlignInBits, */ 1095*d415bd75Srobert StaticDataMemberDeclaration, Annotations); 109609467b48Spatrick } 109709467b48Spatrick }; 109809467b48Spatrick 109909467b48Spatrick template <> struct MDNodeKeyImpl<DILocalVariable> { 110009467b48Spatrick Metadata *Scope; 110109467b48Spatrick MDString *Name; 110209467b48Spatrick Metadata *File; 110309467b48Spatrick unsigned Line; 110409467b48Spatrick Metadata *Type; 110509467b48Spatrick unsigned Arg; 110609467b48Spatrick unsigned Flags; 110709467b48Spatrick uint32_t AlignInBits; 1108*d415bd75Srobert Metadata *Annotations; 110909467b48Spatrick 111009467b48Spatrick MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line, 111109467b48Spatrick Metadata *Type, unsigned Arg, unsigned Flags, 1112*d415bd75Srobert uint32_t AlignInBits, Metadata *Annotations) 111309467b48Spatrick : Scope(Scope), Name(Name), File(File), Line(Line), Type(Type), Arg(Arg), 1114*d415bd75Srobert Flags(Flags), AlignInBits(AlignInBits), Annotations(Annotations) {} 111509467b48Spatrick MDNodeKeyImpl(const DILocalVariable *N) 111609467b48Spatrick : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()), 111709467b48Spatrick Line(N->getLine()), Type(N->getRawType()), Arg(N->getArg()), 1118*d415bd75Srobert Flags(N->getFlags()), AlignInBits(N->getAlignInBits()), 1119*d415bd75Srobert Annotations(N->getRawAnnotations()) {} 112009467b48Spatrick 112109467b48Spatrick bool isKeyOf(const DILocalVariable *RHS) const { 112209467b48Spatrick return Scope == RHS->getRawScope() && Name == RHS->getRawName() && 112309467b48Spatrick File == RHS->getRawFile() && Line == RHS->getLine() && 112409467b48Spatrick Type == RHS->getRawType() && Arg == RHS->getArg() && 1125*d415bd75Srobert Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits() && 1126*d415bd75Srobert Annotations == RHS->getRawAnnotations(); 112709467b48Spatrick } 112809467b48Spatrick 112909467b48Spatrick unsigned getHashValue() const { 113009467b48Spatrick // We do not use AlignInBits in hashing function here on purpose: 113109467b48Spatrick // in most cases this param for local variable is zero (for function param 113209467b48Spatrick // it is always zero). This leads to lots of hash collisions and errors on 113309467b48Spatrick // cases with lots of similar variables. 113409467b48Spatrick // clang/test/CodeGen/debug-info-257-args.c is an example of this problem, 113509467b48Spatrick // generated IR is random for each run and test fails with Align included. 113609467b48Spatrick // TODO: make hashing work fine with such situations 1137*d415bd75Srobert return hash_combine(Scope, Name, File, Line, Type, Arg, Flags, Annotations); 113809467b48Spatrick } 113909467b48Spatrick }; 114009467b48Spatrick 114109467b48Spatrick template <> struct MDNodeKeyImpl<DILabel> { 114209467b48Spatrick Metadata *Scope; 114309467b48Spatrick MDString *Name; 114409467b48Spatrick Metadata *File; 114509467b48Spatrick unsigned Line; 114609467b48Spatrick 114709467b48Spatrick MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line) 114809467b48Spatrick : Scope(Scope), Name(Name), File(File), Line(Line) {} 114909467b48Spatrick MDNodeKeyImpl(const DILabel *N) 115009467b48Spatrick : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()), 115109467b48Spatrick Line(N->getLine()) {} 115209467b48Spatrick 115309467b48Spatrick bool isKeyOf(const DILabel *RHS) const { 115409467b48Spatrick return Scope == RHS->getRawScope() && Name == RHS->getRawName() && 115509467b48Spatrick File == RHS->getRawFile() && Line == RHS->getLine(); 115609467b48Spatrick } 115709467b48Spatrick 115809467b48Spatrick /// Using name and line to get hash value. It should already be mostly unique. 1159*d415bd75Srobert unsigned getHashValue() const { return hash_combine(Scope, Name, Line); } 116009467b48Spatrick }; 116109467b48Spatrick 116209467b48Spatrick template <> struct MDNodeKeyImpl<DIExpression> { 116309467b48Spatrick ArrayRef<uint64_t> Elements; 116409467b48Spatrick 116509467b48Spatrick MDNodeKeyImpl(ArrayRef<uint64_t> Elements) : Elements(Elements) {} 116609467b48Spatrick MDNodeKeyImpl(const DIExpression *N) : Elements(N->getElements()) {} 116709467b48Spatrick 116809467b48Spatrick bool isKeyOf(const DIExpression *RHS) const { 116909467b48Spatrick return Elements == RHS->getElements(); 117009467b48Spatrick } 117109467b48Spatrick 117209467b48Spatrick unsigned getHashValue() const { 117309467b48Spatrick return hash_combine_range(Elements.begin(), Elements.end()); 117409467b48Spatrick } 117509467b48Spatrick }; 117609467b48Spatrick 117709467b48Spatrick template <> struct MDNodeKeyImpl<DIGlobalVariableExpression> { 117809467b48Spatrick Metadata *Variable; 117909467b48Spatrick Metadata *Expression; 118009467b48Spatrick 118109467b48Spatrick MDNodeKeyImpl(Metadata *Variable, Metadata *Expression) 118209467b48Spatrick : Variable(Variable), Expression(Expression) {} 118309467b48Spatrick MDNodeKeyImpl(const DIGlobalVariableExpression *N) 118409467b48Spatrick : Variable(N->getRawVariable()), Expression(N->getRawExpression()) {} 118509467b48Spatrick 118609467b48Spatrick bool isKeyOf(const DIGlobalVariableExpression *RHS) const { 118709467b48Spatrick return Variable == RHS->getRawVariable() && 118809467b48Spatrick Expression == RHS->getRawExpression(); 118909467b48Spatrick } 119009467b48Spatrick 119109467b48Spatrick unsigned getHashValue() const { return hash_combine(Variable, Expression); } 119209467b48Spatrick }; 119309467b48Spatrick 119409467b48Spatrick template <> struct MDNodeKeyImpl<DIObjCProperty> { 119509467b48Spatrick MDString *Name; 119609467b48Spatrick Metadata *File; 119709467b48Spatrick unsigned Line; 119809467b48Spatrick MDString *GetterName; 119909467b48Spatrick MDString *SetterName; 120009467b48Spatrick unsigned Attributes; 120109467b48Spatrick Metadata *Type; 120209467b48Spatrick 120309467b48Spatrick MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line, 120409467b48Spatrick MDString *GetterName, MDString *SetterName, unsigned Attributes, 120509467b48Spatrick Metadata *Type) 120609467b48Spatrick : Name(Name), File(File), Line(Line), GetterName(GetterName), 120709467b48Spatrick SetterName(SetterName), Attributes(Attributes), Type(Type) {} 120809467b48Spatrick MDNodeKeyImpl(const DIObjCProperty *N) 120909467b48Spatrick : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()), 121009467b48Spatrick GetterName(N->getRawGetterName()), SetterName(N->getRawSetterName()), 121109467b48Spatrick Attributes(N->getAttributes()), Type(N->getRawType()) {} 121209467b48Spatrick 121309467b48Spatrick bool isKeyOf(const DIObjCProperty *RHS) const { 121409467b48Spatrick return Name == RHS->getRawName() && File == RHS->getRawFile() && 121509467b48Spatrick Line == RHS->getLine() && GetterName == RHS->getRawGetterName() && 121609467b48Spatrick SetterName == RHS->getRawSetterName() && 121709467b48Spatrick Attributes == RHS->getAttributes() && Type == RHS->getRawType(); 121809467b48Spatrick } 121909467b48Spatrick 122009467b48Spatrick unsigned getHashValue() const { 122109467b48Spatrick return hash_combine(Name, File, Line, GetterName, SetterName, Attributes, 122209467b48Spatrick Type); 122309467b48Spatrick } 122409467b48Spatrick }; 122509467b48Spatrick 122609467b48Spatrick template <> struct MDNodeKeyImpl<DIImportedEntity> { 122709467b48Spatrick unsigned Tag; 122809467b48Spatrick Metadata *Scope; 122909467b48Spatrick Metadata *Entity; 123009467b48Spatrick Metadata *File; 123109467b48Spatrick unsigned Line; 123209467b48Spatrick MDString *Name; 1233*d415bd75Srobert Metadata *Elements; 123409467b48Spatrick 123509467b48Spatrick MDNodeKeyImpl(unsigned Tag, Metadata *Scope, Metadata *Entity, Metadata *File, 1236*d415bd75Srobert unsigned Line, MDString *Name, Metadata *Elements) 123709467b48Spatrick : Tag(Tag), Scope(Scope), Entity(Entity), File(File), Line(Line), 1238*d415bd75Srobert Name(Name), Elements(Elements) {} 123909467b48Spatrick MDNodeKeyImpl(const DIImportedEntity *N) 124009467b48Spatrick : Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()), 1241*d415bd75Srobert File(N->getRawFile()), Line(N->getLine()), Name(N->getRawName()), 1242*d415bd75Srobert Elements(N->getRawElements()) {} 124309467b48Spatrick 124409467b48Spatrick bool isKeyOf(const DIImportedEntity *RHS) const { 124509467b48Spatrick return Tag == RHS->getTag() && Scope == RHS->getRawScope() && 124609467b48Spatrick Entity == RHS->getRawEntity() && File == RHS->getFile() && 1247*d415bd75Srobert Line == RHS->getLine() && Name == RHS->getRawName() && 1248*d415bd75Srobert Elements == RHS->getRawElements(); 124909467b48Spatrick } 125009467b48Spatrick 125109467b48Spatrick unsigned getHashValue() const { 1252*d415bd75Srobert return hash_combine(Tag, Scope, Entity, File, Line, Name, Elements); 125309467b48Spatrick } 125409467b48Spatrick }; 125509467b48Spatrick 125609467b48Spatrick template <> struct MDNodeKeyImpl<DIMacro> { 125709467b48Spatrick unsigned MIType; 125809467b48Spatrick unsigned Line; 125909467b48Spatrick MDString *Name; 126009467b48Spatrick MDString *Value; 126109467b48Spatrick 126209467b48Spatrick MDNodeKeyImpl(unsigned MIType, unsigned Line, MDString *Name, MDString *Value) 126309467b48Spatrick : MIType(MIType), Line(Line), Name(Name), Value(Value) {} 126409467b48Spatrick MDNodeKeyImpl(const DIMacro *N) 126509467b48Spatrick : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getRawName()), 126609467b48Spatrick Value(N->getRawValue()) {} 126709467b48Spatrick 126809467b48Spatrick bool isKeyOf(const DIMacro *RHS) const { 126909467b48Spatrick return MIType == RHS->getMacinfoType() && Line == RHS->getLine() && 127009467b48Spatrick Name == RHS->getRawName() && Value == RHS->getRawValue(); 127109467b48Spatrick } 127209467b48Spatrick 127309467b48Spatrick unsigned getHashValue() const { 127409467b48Spatrick return hash_combine(MIType, Line, Name, Value); 127509467b48Spatrick } 127609467b48Spatrick }; 127709467b48Spatrick 127809467b48Spatrick template <> struct MDNodeKeyImpl<DIMacroFile> { 127909467b48Spatrick unsigned MIType; 128009467b48Spatrick unsigned Line; 128109467b48Spatrick Metadata *File; 128209467b48Spatrick Metadata *Elements; 128309467b48Spatrick 128409467b48Spatrick MDNodeKeyImpl(unsigned MIType, unsigned Line, Metadata *File, 128509467b48Spatrick Metadata *Elements) 128609467b48Spatrick : MIType(MIType), Line(Line), File(File), Elements(Elements) {} 128709467b48Spatrick MDNodeKeyImpl(const DIMacroFile *N) 128809467b48Spatrick : MIType(N->getMacinfoType()), Line(N->getLine()), File(N->getRawFile()), 128909467b48Spatrick Elements(N->getRawElements()) {} 129009467b48Spatrick 129109467b48Spatrick bool isKeyOf(const DIMacroFile *RHS) const { 129209467b48Spatrick return MIType == RHS->getMacinfoType() && Line == RHS->getLine() && 129309467b48Spatrick File == RHS->getRawFile() && Elements == RHS->getRawElements(); 129409467b48Spatrick } 129509467b48Spatrick 129609467b48Spatrick unsigned getHashValue() const { 129709467b48Spatrick return hash_combine(MIType, Line, File, Elements); 129809467b48Spatrick } 129909467b48Spatrick }; 130009467b48Spatrick 130173471bf0Spatrick template <> struct MDNodeKeyImpl<DIArgList> { 130273471bf0Spatrick ArrayRef<ValueAsMetadata *> Args; 130373471bf0Spatrick 130473471bf0Spatrick MDNodeKeyImpl(ArrayRef<ValueAsMetadata *> Args) : Args(Args) {} 130573471bf0Spatrick MDNodeKeyImpl(const DIArgList *N) : Args(N->getArgs()) {} 130673471bf0Spatrick 130773471bf0Spatrick bool isKeyOf(const DIArgList *RHS) const { return Args == RHS->getArgs(); } 130873471bf0Spatrick 130973471bf0Spatrick unsigned getHashValue() const { 131073471bf0Spatrick return hash_combine_range(Args.begin(), Args.end()); 131173471bf0Spatrick } 131273471bf0Spatrick }; 131373471bf0Spatrick 131409467b48Spatrick /// DenseMapInfo for MDNode subclasses. 131509467b48Spatrick template <class NodeTy> struct MDNodeInfo { 131609467b48Spatrick using KeyTy = MDNodeKeyImpl<NodeTy>; 131709467b48Spatrick using SubsetEqualTy = MDNodeSubsetEqualImpl<NodeTy>; 131809467b48Spatrick 131909467b48Spatrick static inline NodeTy *getEmptyKey() { 132009467b48Spatrick return DenseMapInfo<NodeTy *>::getEmptyKey(); 132109467b48Spatrick } 132209467b48Spatrick 132309467b48Spatrick static inline NodeTy *getTombstoneKey() { 132409467b48Spatrick return DenseMapInfo<NodeTy *>::getTombstoneKey(); 132509467b48Spatrick } 132609467b48Spatrick 132709467b48Spatrick static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); } 132809467b48Spatrick 132909467b48Spatrick static unsigned getHashValue(const NodeTy *N) { 133009467b48Spatrick return KeyTy(N).getHashValue(); 133109467b48Spatrick } 133209467b48Spatrick 133309467b48Spatrick static bool isEqual(const KeyTy &LHS, const NodeTy *RHS) { 133409467b48Spatrick if (RHS == getEmptyKey() || RHS == getTombstoneKey()) 133509467b48Spatrick return false; 133609467b48Spatrick return SubsetEqualTy::isSubsetEqual(LHS, RHS) || LHS.isKeyOf(RHS); 133709467b48Spatrick } 133809467b48Spatrick 133909467b48Spatrick static bool isEqual(const NodeTy *LHS, const NodeTy *RHS) { 134009467b48Spatrick if (LHS == RHS) 134109467b48Spatrick return true; 134209467b48Spatrick if (RHS == getEmptyKey() || RHS == getTombstoneKey()) 134309467b48Spatrick return false; 134409467b48Spatrick return SubsetEqualTy::isSubsetEqual(LHS, RHS); 134509467b48Spatrick } 134609467b48Spatrick }; 134709467b48Spatrick 134809467b48Spatrick #define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>; 134909467b48Spatrick #include "llvm/IR/Metadata.def" 135009467b48Spatrick 135173471bf0Spatrick /// Multimap-like storage for metadata attachments. 135273471bf0Spatrick class MDAttachments { 135373471bf0Spatrick public: 135473471bf0Spatrick struct Attachment { 135573471bf0Spatrick unsigned MDKind; 135673471bf0Spatrick TrackingMDNodeRef Node; 135773471bf0Spatrick }; 135873471bf0Spatrick 135973471bf0Spatrick private: 136073471bf0Spatrick SmallVector<Attachment, 1> Attachments; 136109467b48Spatrick 136209467b48Spatrick public: 136309467b48Spatrick bool empty() const { return Attachments.empty(); } 136409467b48Spatrick size_t size() const { return Attachments.size(); } 136509467b48Spatrick 136673471bf0Spatrick /// Returns the first attachment with the given ID or nullptr if no such 136773471bf0Spatrick /// attachment exists. 136809467b48Spatrick MDNode *lookup(unsigned ID) const; 136909467b48Spatrick 137009467b48Spatrick /// Appends all attachments with the given ID to \c Result in insertion order. 137109467b48Spatrick /// If the global has no attachments with the given ID, or if ID is invalid, 137209467b48Spatrick /// leaves Result unchanged. 137309467b48Spatrick void get(unsigned ID, SmallVectorImpl<MDNode *> &Result) const; 137409467b48Spatrick 137509467b48Spatrick /// Appends all attachments for the global to \c Result, sorting by attachment 137609467b48Spatrick /// ID. Attachments with the same ID appear in insertion order. This function 137709467b48Spatrick /// does \em not clear \c Result. 137809467b48Spatrick void getAll(SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const; 137973471bf0Spatrick 138073471bf0Spatrick /// Set an attachment to a particular node. 138173471bf0Spatrick /// 138273471bf0Spatrick /// Set the \c ID attachment to \c MD, replacing the current attachments at \c 138373471bf0Spatrick /// ID (if anyway). 138473471bf0Spatrick void set(unsigned ID, MDNode *MD); 138573471bf0Spatrick 138673471bf0Spatrick /// Adds an attachment to a particular node. 138773471bf0Spatrick void insert(unsigned ID, MDNode &MD); 138873471bf0Spatrick 138973471bf0Spatrick /// Remove attachments with the given ID. 139073471bf0Spatrick /// 139173471bf0Spatrick /// Remove the attachments at \c ID, if any. 139273471bf0Spatrick bool erase(unsigned ID); 139373471bf0Spatrick 139473471bf0Spatrick /// Erase matching attachments. 139573471bf0Spatrick /// 139673471bf0Spatrick /// Erases all attachments matching the \c shouldRemove predicate. 139773471bf0Spatrick template <class PredTy> void remove_if(PredTy shouldRemove) { 139873471bf0Spatrick llvm::erase_if(Attachments, shouldRemove); 139973471bf0Spatrick } 140009467b48Spatrick }; 140109467b48Spatrick 140209467b48Spatrick class LLVMContextImpl { 140309467b48Spatrick public: 140409467b48Spatrick /// OwnedModules - The set of modules instantiated in this context, and which 140509467b48Spatrick /// will be automatically deleted if this context is deleted. 140609467b48Spatrick SmallPtrSet<Module *, 4> OwnedModules; 140709467b48Spatrick 1408097a140dSpatrick /// The main remark streamer used by all the other streamers (e.g. IR, MIR, 1409097a140dSpatrick /// frontends, etc.). This should only be used by the specific streamers, and 1410097a140dSpatrick /// never directly. 1411097a140dSpatrick std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer; 1412097a140dSpatrick 141309467b48Spatrick std::unique_ptr<DiagnosticHandler> DiagHandler; 141409467b48Spatrick bool RespectDiagnosticFilters = false; 141509467b48Spatrick bool DiagnosticsHotnessRequested = false; 141673471bf0Spatrick /// The minimum hotness value a diagnostic needs in order to be included in 141773471bf0Spatrick /// optimization diagnostics. 141873471bf0Spatrick /// 141973471bf0Spatrick /// The threshold is an Optional value, which maps to one of the 3 states: 142073471bf0Spatrick /// 1). 0 => threshold disabled. All emarks will be printed. 142173471bf0Spatrick /// 2). positive int => manual threshold by user. Remarks with hotness exceed 142273471bf0Spatrick /// threshold will be printed. 142373471bf0Spatrick /// 3). None => 'auto' threshold by user. The actual value is not 142473471bf0Spatrick /// available at command line, but will be synced with 142573471bf0Spatrick /// hotness threhold from profile summary during 142673471bf0Spatrick /// compilation. 142773471bf0Spatrick /// 142873471bf0Spatrick /// State 1 and 2 are considered as terminal states. State transition is 142973471bf0Spatrick /// only allowed from 3 to 2, when the threshold is first synced with profile 143073471bf0Spatrick /// summary. This ensures that the threshold is set only once and stays 143173471bf0Spatrick /// constant. 143273471bf0Spatrick /// 143373471bf0Spatrick /// If threshold option is not specified, it is disabled (0) by default. 1434*d415bd75Srobert std::optional<uint64_t> DiagnosticsHotnessThreshold = 0; 1435*d415bd75Srobert 1436*d415bd75Srobert /// The percentage of difference between profiling branch weights and 1437*d415bd75Srobert /// llvm.expect branch weights to tolerate when emiting MisExpect diagnostics 1438*d415bd75Srobert std::optional<uint32_t> DiagnosticsMisExpectTolerance = 0; 1439*d415bd75Srobert bool MisExpectWarningRequested = false; 144073471bf0Spatrick 1441097a140dSpatrick /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter. 1442097a140dSpatrick std::unique_ptr<LLVMRemarkStreamer> LLVMRS; 144309467b48Spatrick 144409467b48Spatrick LLVMContext::YieldCallbackTy YieldCallback = nullptr; 144509467b48Spatrick void *YieldOpaqueHandle = nullptr; 144609467b48Spatrick 1447*d415bd75Srobert DenseMap<const Value *, ValueName *> ValueNames; 1448*d415bd75Srobert 144909467b48Spatrick using IntMapTy = 145009467b48Spatrick DenseMap<APInt, std::unique_ptr<ConstantInt>, DenseMapAPIntKeyInfo>; 145109467b48Spatrick IntMapTy IntConstants; 145209467b48Spatrick 145309467b48Spatrick using FPMapTy = 145409467b48Spatrick DenseMap<APFloat, std::unique_ptr<ConstantFP>, DenseMapAPFloatKeyInfo>; 145509467b48Spatrick FPMapTy FPConstants; 145609467b48Spatrick 145709467b48Spatrick FoldingSet<AttributeImpl> AttrsSet; 145809467b48Spatrick FoldingSet<AttributeListImpl> AttrsLists; 145909467b48Spatrick FoldingSet<AttributeSetNode> AttrsSetNodes; 146009467b48Spatrick 146109467b48Spatrick StringMap<MDString, BumpPtrAllocator> MDStringCache; 146209467b48Spatrick DenseMap<Value *, ValueAsMetadata *> ValuesAsMetadata; 146309467b48Spatrick DenseMap<Metadata *, MetadataAsValue *> MetadataAsValues; 146409467b48Spatrick 146509467b48Spatrick #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \ 146609467b48Spatrick DenseSet<CLASS *, CLASS##Info> CLASS##s; 146709467b48Spatrick #include "llvm/IR/Metadata.def" 146809467b48Spatrick 146909467b48Spatrick // Optional map for looking up composite types by identifier. 1470*d415bd75Srobert std::optional<DenseMap<const MDString *, DICompositeType *>> DITypeMap; 147109467b48Spatrick 147209467b48Spatrick // MDNodes may be uniqued or not uniqued. When they're not uniqued, they 147309467b48Spatrick // aren't in the MDNodeSet, but they're still shared between objects, so no 147409467b48Spatrick // one object can destroy them. Keep track of them here so we can delete 147509467b48Spatrick // them on context teardown. 147609467b48Spatrick std::vector<MDNode *> DistinctMDNodes; 147709467b48Spatrick 147809467b48Spatrick DenseMap<Type *, std::unique_ptr<ConstantAggregateZero>> CAZConstants; 147909467b48Spatrick 148009467b48Spatrick using ArrayConstantsTy = ConstantUniqueMap<ConstantArray>; 148109467b48Spatrick ArrayConstantsTy ArrayConstants; 148209467b48Spatrick 148309467b48Spatrick using StructConstantsTy = ConstantUniqueMap<ConstantStruct>; 148409467b48Spatrick StructConstantsTy StructConstants; 148509467b48Spatrick 148609467b48Spatrick using VectorConstantsTy = ConstantUniqueMap<ConstantVector>; 148709467b48Spatrick VectorConstantsTy VectorConstants; 148809467b48Spatrick 148909467b48Spatrick DenseMap<PointerType *, std::unique_ptr<ConstantPointerNull>> CPNConstants; 149009467b48Spatrick 1491*d415bd75Srobert DenseMap<TargetExtType *, std::unique_ptr<ConstantTargetNone>> CTNConstants; 1492*d415bd75Srobert 149309467b48Spatrick DenseMap<Type *, std::unique_ptr<UndefValue>> UVConstants; 149409467b48Spatrick 149573471bf0Spatrick DenseMap<Type *, std::unique_ptr<PoisonValue>> PVConstants; 149673471bf0Spatrick 149773471bf0Spatrick StringMap<std::unique_ptr<ConstantDataSequential>> CDSConstants; 149809467b48Spatrick 149909467b48Spatrick DenseMap<std::pair<const Function *, const BasicBlock *>, BlockAddress *> 150009467b48Spatrick BlockAddresses; 150173471bf0Spatrick 150273471bf0Spatrick DenseMap<const GlobalValue *, DSOLocalEquivalent *> DSOLocalEquivalents; 150373471bf0Spatrick 1504*d415bd75Srobert DenseMap<const GlobalValue *, NoCFIValue *> NoCFIValues; 1505*d415bd75Srobert 150609467b48Spatrick ConstantUniqueMap<ConstantExpr> ExprConstants; 150709467b48Spatrick 150809467b48Spatrick ConstantUniqueMap<InlineAsm> InlineAsms; 150909467b48Spatrick 151009467b48Spatrick ConstantInt *TheTrueVal = nullptr; 151109467b48Spatrick ConstantInt *TheFalseVal = nullptr; 151209467b48Spatrick 151309467b48Spatrick // Basic type instances. 1514097a140dSpatrick Type VoidTy, LabelTy, HalfTy, BFloatTy, FloatTy, DoubleTy, MetadataTy, 1515097a140dSpatrick TokenTy; 151673471bf0Spatrick Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy, X86_AMXTy; 151709467b48Spatrick IntegerType Int1Ty, Int8Ty, Int16Ty, Int32Ty, Int64Ty, Int128Ty; 151809467b48Spatrick 1519*d415bd75Srobert std::unique_ptr<ConstantTokenNone> TheNoneToken; 1520*d415bd75Srobert 152109467b48Spatrick BumpPtrAllocator Alloc; 152209467b48Spatrick UniqueStringSaver Saver{Alloc}; 152309467b48Spatrick 152409467b48Spatrick DenseMap<unsigned, IntegerType *> IntegerTypes; 152509467b48Spatrick 152609467b48Spatrick using FunctionTypeSet = DenseSet<FunctionType *, FunctionTypeKeyInfo>; 152709467b48Spatrick FunctionTypeSet FunctionTypes; 152809467b48Spatrick using StructTypeSet = DenseSet<StructType *, AnonStructTypeKeyInfo>; 152909467b48Spatrick StructTypeSet AnonStructTypes; 153009467b48Spatrick StringMap<StructType *> NamedStructTypes; 153109467b48Spatrick unsigned NamedStructTypesUniqueID = 0; 153209467b48Spatrick 1533*d415bd75Srobert using TargetExtTypeSet = DenseSet<TargetExtType *, TargetExtTypeKeyInfo>; 1534*d415bd75Srobert TargetExtTypeSet TargetExtTypes; 1535*d415bd75Srobert 153609467b48Spatrick DenseMap<std::pair<Type *, uint64_t>, ArrayType *> ArrayTypes; 153709467b48Spatrick DenseMap<std::pair<Type *, ElementCount>, VectorType *> VectorTypes; 153809467b48Spatrick DenseMap<Type *, PointerType *> PointerTypes; // Pointers in AddrSpace = 0 153909467b48Spatrick DenseMap<std::pair<Type *, unsigned>, PointerType *> ASPointerTypes; 1540*d415bd75Srobert DenseMap<std::pair<Type *, unsigned>, TypedPointerType *> ASTypedPointerTypes; 154109467b48Spatrick 154209467b48Spatrick /// ValueHandles - This map keeps track of all of the value handles that are 154309467b48Spatrick /// watching a Value*. The Value::HasValueHandle bit is used to know 154409467b48Spatrick /// whether or not a value has an entry in this map. 154509467b48Spatrick using ValueHandlesTy = DenseMap<Value *, ValueHandleBase *>; 154609467b48Spatrick ValueHandlesTy ValueHandles; 154709467b48Spatrick 154809467b48Spatrick /// CustomMDKindNames - Map to hold the metadata string to ID mapping. 154909467b48Spatrick StringMap<unsigned> CustomMDKindNames; 155009467b48Spatrick 155173471bf0Spatrick /// Collection of metadata used in this context. 155273471bf0Spatrick DenseMap<const Value *, MDAttachments> ValueMetadata; 155309467b48Spatrick 1554*d415bd75Srobert /// Map DIAssignID -> Instructions with that attachment. 1555*d415bd75Srobert /// Managed by Instruction via Instruction::updateDIAssignIDMapping. 1556*d415bd75Srobert /// Query using the at:: functions defined in DebugInfo.h. 1557*d415bd75Srobert DenseMap<DIAssignID *, SmallVector<Instruction *, 1>> AssignmentIDToInstrs; 1558*d415bd75Srobert 155909467b48Spatrick /// Collection of per-GlobalObject sections used in this context. 156009467b48Spatrick DenseMap<const GlobalObject *, StringRef> GlobalObjectSections; 156109467b48Spatrick 156209467b48Spatrick /// Collection of per-GlobalValue partitions used in this context. 156309467b48Spatrick DenseMap<const GlobalValue *, StringRef> GlobalValuePartitions; 156409467b48Spatrick 1565*d415bd75Srobert DenseMap<const GlobalValue *, GlobalValue::SanitizerMetadata> 1566*d415bd75Srobert GlobalValueSanitizerMetadata; 1567*d415bd75Srobert 156809467b48Spatrick /// DiscriminatorTable - This table maps file:line locations to an 156909467b48Spatrick /// integer representing the next DWARF path discriminator to assign to 157009467b48Spatrick /// instructions in different blocks at the same location. 157109467b48Spatrick DenseMap<std::pair<const char *, unsigned>, unsigned> DiscriminatorTable; 157209467b48Spatrick 157309467b48Spatrick /// A set of interned tags for operand bundles. The StringMap maps 157409467b48Spatrick /// bundle tags to their IDs. 157509467b48Spatrick /// 157609467b48Spatrick /// \see LLVMContext::getOperandBundleTagID 157709467b48Spatrick StringMap<uint32_t> BundleTagCache; 157809467b48Spatrick 157909467b48Spatrick StringMapEntry<uint32_t> *getOrInsertBundleTag(StringRef Tag); 158009467b48Spatrick void getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const; 158109467b48Spatrick uint32_t getOperandBundleTagID(StringRef Tag) const; 158209467b48Spatrick 158309467b48Spatrick /// A set of interned synchronization scopes. The StringMap maps 158409467b48Spatrick /// synchronization scope names to their respective synchronization scope IDs. 158509467b48Spatrick StringMap<SyncScope::ID> SSC; 158609467b48Spatrick 158709467b48Spatrick /// getOrInsertSyncScopeID - Maps synchronization scope name to 158809467b48Spatrick /// synchronization scope ID. Every synchronization scope registered with 158909467b48Spatrick /// LLVMContext has unique ID except pre-defined ones. 159009467b48Spatrick SyncScope::ID getOrInsertSyncScopeID(StringRef SSN); 159109467b48Spatrick 159209467b48Spatrick /// getSyncScopeNames - Populates client supplied SmallVector with 159309467b48Spatrick /// synchronization scope names registered with LLVMContext. Synchronization 159409467b48Spatrick /// scope names are ordered by increasing synchronization scope IDs. 159509467b48Spatrick void getSyncScopeNames(SmallVectorImpl<StringRef> &SSNs) const; 159609467b48Spatrick 159709467b48Spatrick /// Maintain the GC name for each function. 159809467b48Spatrick /// 159909467b48Spatrick /// This saves allocating an additional word in Function for programs which 160009467b48Spatrick /// do not use GC (i.e., most programs) at the cost of increased overhead for 160109467b48Spatrick /// clients which do use GC. 160209467b48Spatrick DenseMap<const Function *, std::string> GCNames; 160309467b48Spatrick 160409467b48Spatrick /// Flag to indicate if Value (other than GlobalValue) retains their name or 160509467b48Spatrick /// not. 160609467b48Spatrick bool DiscardValueNames = false; 160709467b48Spatrick 160809467b48Spatrick LLVMContextImpl(LLVMContext &C); 160909467b48Spatrick ~LLVMContextImpl(); 161009467b48Spatrick 161109467b48Spatrick /// Destroy the ConstantArrays if they are not used. 161209467b48Spatrick void dropTriviallyDeadConstantArrays(); 161309467b48Spatrick 161409467b48Spatrick mutable OptPassGate *OPG = nullptr; 161509467b48Spatrick 161609467b48Spatrick /// Access the object which can disable optional passes and individual 161709467b48Spatrick /// optimizations at compile time. 161809467b48Spatrick OptPassGate &getOptPassGate() const; 161909467b48Spatrick 162009467b48Spatrick /// Set the object which can disable optional passes and individual 162109467b48Spatrick /// optimizations at compile time. 162209467b48Spatrick /// 162309467b48Spatrick /// The lifetime of the object must be guaranteed to extend as long as the 162409467b48Spatrick /// LLVMContext is used by compilation. 162509467b48Spatrick void setOptPassGate(OptPassGate &); 1626*d415bd75Srobert 1627*d415bd75Srobert // TODO: clean up the following after we no longer support non-opaque pointer 1628*d415bd75Srobert // types. 1629*d415bd75Srobert bool getOpaquePointers(); 1630*d415bd75Srobert void setOpaquePointers(bool OP); 1631*d415bd75Srobert 1632*d415bd75Srobert private: 1633*d415bd75Srobert std::optional<bool> OpaquePointers; 163409467b48Spatrick }; 163509467b48Spatrick 163609467b48Spatrick } // end namespace llvm 163709467b48Spatrick 163809467b48Spatrick #endif // LLVM_LIB_IR_LLVMCONTEXTIMPL_H 1639