//===- LLVMContextImpl.h - The LLVMContextImpl opaque class -----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file declares LLVMContextImpl, the opaque implementation
//  of LLVMContext.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_IR_LLVMCONTEXTIMPL_H
#define LLVM_LIB_IR_LLVMCONTEXTIMPL_H

#include "ConstantsContext.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/TrackingMDRef.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/StringSaver.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

namespace llvm {

class AttributeImpl;
class AttributeListImpl;
class AttributeSetNode;
class BasicBlock;
class ConstantRangeAttributeImpl;
class ConstantRangeListAttributeImpl;
struct DiagnosticHandler;
class DbgMarker;
class ElementCount;
class Function;
class GlobalObject;
class GlobalValue;
class InlineAsm;
class LLVMRemarkStreamer;
class OptPassGate;
namespace remarks {
class RemarkStreamer;
}
template <typename T> class StringMapEntry;
class StringRef;
class TypedPointerType;
class ValueHandleBase;

template <> struct DenseMapInfo<APFloat> {
  static inline APFloat getEmptyKey() { return APFloat(APFloat::Bogus(), 1); }
  static inline APFloat getTombstoneKey() {
    return APFloat(APFloat::Bogus(), 2);
  }

  static unsigned getHashValue(const APFloat &Key) {
    return static_cast<unsigned>(hash_value(Key));
  }

  static bool isEqual(const APFloat &LHS, const APFloat &RHS) {
    return LHS.bitwiseIsEqual(RHS);
  }
};

struct AnonStructTypeKeyInfo {
  struct KeyTy {
    ArrayRef<Type *> ETypes;
    bool isPacked;

    KeyTy(const ArrayRef<Type *> &E, bool P) : ETypes(E), isPacked(P) {}

    KeyTy(const StructType *ST)
        : ETypes(ST->elements()), isPacked(ST->isPacked()) {}

    bool operator==(const KeyTy &that) const {
      if (isPacked != that.isPacked)
        return false;
      if (ETypes != that.ETypes)
        return false;
      return true;
    }
    bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
  };

  static inline StructType *getEmptyKey() {
    return DenseMapInfo<StructType *>::getEmptyKey();
  }

  static inline StructType *getTombstoneKey() {
    return DenseMapInfo<StructType *>::getTombstoneKey();
  }

  static unsigned getHashValue(const KeyTy &Key) {
    return hash_combine(hash_combine_range(Key.ETypes), Key.isPacked);
  }

  static unsigned getHashValue(const StructType *ST) {
    return getHashValue(KeyTy(ST));
  }

  static bool isEqual(const KeyTy &LHS, const StructType *RHS) {
    if (RHS == getEmptyKey() || RHS == getTombstoneKey())
      return false;
    return LHS == KeyTy(RHS);
  }

  static bool isEqual(const StructType *LHS, const StructType *RHS) {
    return LHS == RHS;
  }
};

struct FunctionTypeKeyInfo {
  struct KeyTy {
    const Type *ReturnType;
    ArrayRef<Type *> Params;
    bool isVarArg;

    KeyTy(const Type *R, const ArrayRef<Type *> &P, bool V)
        : ReturnType(R), Params(P), isVarArg(V) {}
    KeyTy(const FunctionType *FT)
        : ReturnType(FT->getReturnType()), Params(FT->params()),
          isVarArg(FT->isVarArg()) {}

    bool operator==(const KeyTy &that) const {
      if (ReturnType != that.ReturnType)
        return false;
      if (isVarArg != that.isVarArg)
        return false;
      if (Params != that.Params)
        return false;
      return true;
    }
    bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
  };

  static inline FunctionType *getEmptyKey() {
    return DenseMapInfo<FunctionType *>::getEmptyKey();
  }

  static inline FunctionType *getTombstoneKey() {
    return DenseMapInfo<FunctionType *>::getTombstoneKey();
  }

  static unsigned getHashValue(const KeyTy &Key) {
    return hash_combine(Key.ReturnType, hash_combine_range(Key.Params),
                        Key.isVarArg);
  }

  static unsigned getHashValue(const FunctionType *FT) {
    return getHashValue(KeyTy(FT));
  }

  static bool isEqual(const KeyTy &LHS, const FunctionType *RHS) {
    if (RHS == getEmptyKey() || RHS == getTombstoneKey())
      return false;
    return LHS == KeyTy(RHS);
  }

  static bool isEqual(const FunctionType *LHS, const FunctionType *RHS) {
    return LHS == RHS;
  }
};

struct TargetExtTypeKeyInfo {
  struct KeyTy {
    StringRef Name;
    ArrayRef<Type *> TypeParams;
    ArrayRef<unsigned> IntParams;

    KeyTy(StringRef N, const ArrayRef<Type *> &TP, const ArrayRef<unsigned> &IP)
        : Name(N), TypeParams(TP), IntParams(IP) {}
    KeyTy(const TargetExtType *TT)
        : Name(TT->getName()), TypeParams(TT->type_params()),
          IntParams(TT->int_params()) {}

    bool operator==(const KeyTy &that) const {
      return Name == that.Name && TypeParams == that.TypeParams &&
             IntParams == that.IntParams;
    }
    bool operator!=(const KeyTy &that) const { return !this->operator==(that); }
  };

  static inline TargetExtType *getEmptyKey() {
    return DenseMapInfo<TargetExtType *>::getEmptyKey();
  }

  static inline TargetExtType *getTombstoneKey() {
    return DenseMapInfo<TargetExtType *>::getTombstoneKey();
  }

  static unsigned getHashValue(const KeyTy &Key) {
    return hash_combine(Key.Name, hash_combine_range(Key.TypeParams),
                        hash_combine_range(Key.IntParams));
  }

  static unsigned getHashValue(const TargetExtType *FT) {
    return getHashValue(KeyTy(FT));
  }

  static bool isEqual(const KeyTy &LHS, const TargetExtType *RHS) {
    if (RHS == getEmptyKey() || RHS == getTombstoneKey())
      return false;
    return LHS == KeyTy(RHS);
  }

  static bool isEqual(const TargetExtType *LHS, const TargetExtType *RHS) {
    return LHS == RHS;
  }
};

/// Structure for hashing arbitrary MDNode operands.
class MDNodeOpsKey {
  ArrayRef<Metadata *> RawOps;
  ArrayRef<MDOperand> Ops;
  unsigned Hash;

protected:
  MDNodeOpsKey(ArrayRef<Metadata *> Ops)
      : RawOps(Ops), Hash(calculateHash(Ops)) {}

  template <class NodeTy>
  MDNodeOpsKey(const NodeTy *N, unsigned Offset = 0)
      : Ops(N->op_begin() + Offset, N->op_end()), Hash(N->getHash()) {}

  template <class NodeTy>
  bool compareOps(const NodeTy *RHS, unsigned Offset = 0) const {
    if (getHash() != RHS->getHash())
      return false;

    assert((RawOps.empty() || Ops.empty()) && "Two sets of operands?");
    return RawOps.empty() ? compareOps(Ops, RHS, Offset)
                          : compareOps(RawOps, RHS, Offset);
  }

  static unsigned calculateHash(MDNode *N, unsigned Offset = 0);

private:
  template <class T>
  static bool compareOps(ArrayRef<T> Ops, const MDNode *RHS, unsigned Offset) {
    if (Ops.size() != RHS->getNumOperands() - Offset)
      return false;
    return std::equal(Ops.begin(), Ops.end(), RHS->op_begin() + Offset);
  }

  static unsigned calculateHash(ArrayRef<Metadata *> Ops);

public:
  unsigned getHash() const { return Hash; }
};

template <class NodeTy> struct MDNodeKeyImpl;

/// Configuration point for MDNodeInfo::isEqual().
template <class NodeTy> struct MDNodeSubsetEqualImpl {
  using KeyTy = MDNodeKeyImpl<NodeTy>;

  static bool isSubsetEqual(const KeyTy &LHS, const NodeTy *RHS) {
    return false;
  }

  static bool isSubsetEqual(const NodeTy *LHS, const NodeTy *RHS) {
    return false;
  }
};

/// DenseMapInfo for MDTuple.
///
/// Note that we don't need the is-function-local bit, since that's implicit in
/// the operands.
template <> struct MDNodeKeyImpl<MDTuple> : MDNodeOpsKey {
  MDNodeKeyImpl(ArrayRef<Metadata *> Ops) : MDNodeOpsKey(Ops) {}
  MDNodeKeyImpl(const MDTuple *N) : MDNodeOpsKey(N) {}

  bool isKeyOf(const MDTuple *RHS) const { return compareOps(RHS); }

  unsigned getHashValue() const { return getHash(); }

  static unsigned calculateHash(MDTuple *N) {
    return MDNodeOpsKey::calculateHash(N);
  }
};

/// DenseMapInfo for DILocation.
template <> struct MDNodeKeyImpl<DILocation> {
  Metadata *Scope;
  Metadata *InlinedAt;
#ifdef EXPERIMENTAL_KEY_INSTRUCTIONS
  uint64_t AtomGroup : 61;
  uint64_t AtomRank : 3;
#endif
  unsigned Line;
  uint16_t Column;
  bool ImplicitCode;

  MDNodeKeyImpl(unsigned Line, uint16_t Column, Metadata *Scope,
                Metadata *InlinedAt, bool ImplicitCode, uint64_t AtomGroup,
                uint8_t AtomRank)
      : Scope(Scope), InlinedAt(InlinedAt),
#ifdef EXPERIMENTAL_KEY_INSTRUCTIONS
        AtomGroup(AtomGroup), AtomRank(AtomRank),
#endif
        Line(Line), Column(Column), ImplicitCode(ImplicitCode) {
  }

  MDNodeKeyImpl(const DILocation *L)
      : Scope(L->getRawScope()), InlinedAt(L->getRawInlinedAt()),
#ifdef EXPERIMENTAL_KEY_INSTRUCTIONS
        AtomGroup(L->getAtomGroup()), AtomRank(L->getAtomRank()),
#endif
        Line(L->getLine()), Column(L->getColumn()),
        ImplicitCode(L->isImplicitCode()) {
  }

  bool isKeyOf(const DILocation *RHS) const {
    return Line == RHS->getLine() && Column == RHS->getColumn() &&
           Scope == RHS->getRawScope() && InlinedAt == RHS->getRawInlinedAt() &&
           ImplicitCode == RHS->isImplicitCode()
#ifdef EXPERIMENTAL_KEY_INSTRUCTIONS
           && AtomGroup == RHS->getAtomGroup() &&
           AtomRank == RHS->getAtomRank();
#else
        ;
#endif
  }

  unsigned getHashValue() const {
#ifdef EXPERIMENTAL_KEY_INSTRUCTIONS
    // Hashing AtomGroup and AtomRank substantially impacts performance whether
    // Key Instructions is enabled or not. We can't detect whether it's enabled
    // here cheaply; avoiding hashing zero values is a good approximation. This
    // affects Key Instruction builds too, but any potential costs incurred by
    // messing with the hash distribution* appear to still be massively
    // outweighed by the overall compile time savings by performing this check.
    // * (hash_combine(x) != hash_combine(x, 0))
    if (AtomGroup || AtomRank)
      return hash_combine(Line, Column, Scope, InlinedAt, ImplicitCode,
                          AtomGroup, (uint8_t)AtomRank);
#endif
    return hash_combine(Line, Column, Scope, InlinedAt, ImplicitCode);
  }
};

/// DenseMapInfo for GenericDINode.
template <> struct MDNodeKeyImpl<GenericDINode> : MDNodeOpsKey {
  unsigned Tag;
  MDString *Header;

  MDNodeKeyImpl(unsigned Tag, MDString *Header, ArrayRef<Metadata *> DwarfOps)
      : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {}
  MDNodeKeyImpl(const GenericDINode *N)
      : MDNodeOpsKey(N, 1), Tag(N->getTag()), Header(N->getRawHeader()) {}

  bool isKeyOf(const GenericDINode *RHS) const {
    return Tag == RHS->getTag() && Header == RHS->getRawHeader() &&
           compareOps(RHS, 1);
  }

  unsigned getHashValue() const { return hash_combine(getHash(), Tag, Header); }

  static unsigned calculateHash(GenericDINode *N) {
    return MDNodeOpsKey::calculateHash(N, 1);
  }
};

template <> struct MDNodeKeyImpl<DISubrange> {
  Metadata *CountNode;
  Metadata *LowerBound;
  Metadata *UpperBound;
  Metadata *Stride;

  MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound,
                Metadata *Stride)
      : CountNode(CountNode), LowerBound(LowerBound), UpperBound(UpperBound),
        Stride(Stride) {}
  MDNodeKeyImpl(const DISubrange *N)
      : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
        UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}

  bool isKeyOf(const DISubrange *RHS) const {
    auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool {
      if (Node1 == Node2)
        return true;

      ConstantAsMetadata *MD1 = dyn_cast_or_null<ConstantAsMetadata>(Node1);
      ConstantAsMetadata *MD2 = dyn_cast_or_null<ConstantAsMetadata>(Node2);
      if (MD1 && MD2) {
        ConstantInt *CV1 = cast<ConstantInt>(MD1->getValue());
        ConstantInt *CV2 = cast<ConstantInt>(MD2->getValue());
        if (CV1->getSExtValue() == CV2->getSExtValue())
          return true;
      }
      return false;
    };

    return BoundsEqual(CountNode, RHS->getRawCountNode()) &&
           BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
           BoundsEqual(UpperBound, RHS->getRawUpperBound()) &&
           BoundsEqual(Stride, RHS->getRawStride());
  }

  unsigned getHashValue() const {
    if (CountNode)
      if (auto *MD = dyn_cast<ConstantAsMetadata>(CountNode))
        return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
                            LowerBound, UpperBound, Stride);
    return hash_combine(CountNode, LowerBound, UpperBound, Stride);
  }
};

template <> struct MDNodeKeyImpl<DIGenericSubrange> {
  Metadata *CountNode;
  Metadata *LowerBound;
  Metadata *UpperBound;
  Metadata *Stride;

  MDNodeKeyImpl(Metadata *CountNode, Metadata *LowerBound, Metadata *UpperBound,
                Metadata *Stride)
      : CountNode(CountNode), LowerBound(LowerBound), UpperBound(UpperBound),
        Stride(Stride) {}
  MDNodeKeyImpl(const DIGenericSubrange *N)
      : CountNode(N->getRawCountNode()), LowerBound(N->getRawLowerBound()),
        UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()) {}

  bool isKeyOf(const DIGenericSubrange *RHS) const {
    return (CountNode == RHS->getRawCountNode()) &&
           (LowerBound == RHS->getRawLowerBound()) &&
           (UpperBound == RHS->getRawUpperBound()) &&
           (Stride == RHS->getRawStride());
  }

  unsigned getHashValue() const {
    auto *MD = dyn_cast_or_null<ConstantAsMetadata>(CountNode);
    if (CountNode && MD)
      return hash_combine(cast<ConstantInt>(MD->getValue())->getSExtValue(),
                          LowerBound, UpperBound, Stride);
    return hash_combine(CountNode, LowerBound, UpperBound, Stride);
  }
};

template <> struct MDNodeKeyImpl<DIEnumerator> {
  APInt Value;
  MDString *Name;
  bool IsUnsigned;

  MDNodeKeyImpl(APInt Value, bool IsUnsigned, MDString *Name)
      : Value(std::move(Value)), Name(Name), IsUnsigned(IsUnsigned) {}
  MDNodeKeyImpl(int64_t Value, bool IsUnsigned, MDString *Name)
      : Value(APInt(64, Value, !IsUnsigned)), Name(Name),
        IsUnsigned(IsUnsigned) {}
  MDNodeKeyImpl(const DIEnumerator *N)
      : Value(N->getValue()), Name(N->getRawName()),
        IsUnsigned(N->isUnsigned()) {}

  bool isKeyOf(const DIEnumerator *RHS) const {
    return Value.getBitWidth() == RHS->getValue().getBitWidth() &&
           Value == RHS->getValue() && IsUnsigned == RHS->isUnsigned() &&
           Name == RHS->getRawName();
  }

  unsigned getHashValue() const { return hash_combine(Value, Name); }
};

template <> struct MDNodeKeyImpl<DIBasicType> {
  unsigned Tag;
  MDString *Name;
  Metadata *SizeInBits;
  uint32_t AlignInBits;
  unsigned Encoding;
  uint32_t NumExtraInhabitants;
  unsigned Flags;

  MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *SizeInBits,
                uint32_t AlignInBits, unsigned Encoding,
                uint32_t NumExtraInhabitants, unsigned Flags)
      : Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits),
        Encoding(Encoding), NumExtraInhabitants(NumExtraInhabitants),
        Flags(Flags) {}
  MDNodeKeyImpl(const DIBasicType *N)
      : Tag(N->getTag()), Name(N->getRawName()),
        SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
        Encoding(N->getEncoding()),
        NumExtraInhabitants(N->getNumExtraInhabitants()), Flags(N->getFlags()) {
  }

  bool isKeyOf(const DIBasicType *RHS) const {
    return Tag == RHS->getTag() && Name == RHS->getRawName() &&
           SizeInBits == RHS->getRawSizeInBits() &&
           AlignInBits == RHS->getAlignInBits() &&
           Encoding == RHS->getEncoding() &&
           NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
           Flags == RHS->getFlags();
  }

  unsigned getHashValue() const {
    return hash_combine(Tag, Name, SizeInBits, AlignInBits, Encoding);
  }
};

template <> struct MDNodeKeyImpl<DIFixedPointType> {
  unsigned Tag;
  MDString *Name;
  Metadata *SizeInBits;
  uint32_t AlignInBits;
  unsigned Encoding;
  unsigned Flags;
  unsigned Kind;
  int Factor;
  APInt Numerator;
  APInt Denominator;

  MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *SizeInBits,
                uint32_t AlignInBits, unsigned Encoding, unsigned Flags,
                unsigned Kind, int Factor, APInt Numerator, APInt Denominator)
      : Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits),
        Encoding(Encoding), Flags(Flags), Kind(Kind), Factor(Factor),
        Numerator(Numerator), Denominator(Denominator) {}
  MDNodeKeyImpl(const DIFixedPointType *N)
      : Tag(N->getTag()), Name(N->getRawName()),
        SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
        Encoding(N->getEncoding()), Flags(N->getFlags()), Kind(N->getKind()),
        Factor(N->getFactorRaw()), Numerator(N->getNumeratorRaw()),
        Denominator(N->getDenominatorRaw()) {}

  bool isKeyOf(const DIFixedPointType *RHS) const {
    return Name == RHS->getRawName() && SizeInBits == RHS->getRawSizeInBits() &&
           AlignInBits == RHS->getAlignInBits() && Kind == RHS->getKind() &&
           (RHS->isRational() ? (Numerator == RHS->getNumerator() &&
                                 Denominator == RHS->getDenominator())
                              : Factor == RHS->getFactor());
  }

  unsigned getHashValue() const {
    return hash_combine(Name, Flags, Kind, Factor, Numerator, Denominator);
  }
};

template <> struct MDNodeKeyImpl<DIStringType> {
  unsigned Tag;
  MDString *Name;
  Metadata *StringLength;
  Metadata *StringLengthExp;
  Metadata *StringLocationExp;
  Metadata *SizeInBits;
  uint32_t AlignInBits;
  unsigned Encoding;

  MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *StringLength,
                Metadata *StringLengthExp, Metadata *StringLocationExp,
                Metadata *SizeInBits, uint32_t AlignInBits, unsigned Encoding)
      : Tag(Tag), Name(Name), StringLength(StringLength),
        StringLengthExp(StringLengthExp), StringLocationExp(StringLocationExp),
        SizeInBits(SizeInBits), AlignInBits(AlignInBits), Encoding(Encoding) {}
  MDNodeKeyImpl(const DIStringType *N)
      : Tag(N->getTag()), Name(N->getRawName()),
        StringLength(N->getRawStringLength()),
        StringLengthExp(N->getRawStringLengthExp()),
        StringLocationExp(N->getRawStringLocationExp()),
        SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
        Encoding(N->getEncoding()) {}

  bool isKeyOf(const DIStringType *RHS) const {
    return Tag == RHS->getTag() && Name == RHS->getRawName() &&
           StringLength == RHS->getRawStringLength() &&
           StringLengthExp == RHS->getRawStringLengthExp() &&
           StringLocationExp == RHS->getRawStringLocationExp() &&
           SizeInBits == RHS->getRawSizeInBits() &&
           AlignInBits == RHS->getAlignInBits() &&
           Encoding == RHS->getEncoding();
  }
  unsigned getHashValue() const {
    // Intentionally computes the hash on a subset of the operands for
    // performance reason. The subset has to be significant enough to avoid
    // collision "most of the time". There is no correctness issue in case of
    // collision because of the full check above.
    return hash_combine(Tag, Name, StringLength, Encoding);
  }
};

template <> struct MDNodeKeyImpl<DIDerivedType> {
  unsigned Tag;
  MDString *Name;
  Metadata *File;
  unsigned Line;
  Metadata *Scope;
  Metadata *BaseType;
  Metadata *SizeInBits;
  Metadata *OffsetInBits;
  uint32_t AlignInBits;
  std::optional<unsigned> DWARFAddressSpace;
  std::optional<DIDerivedType::PtrAuthData> PtrAuthData;
  unsigned Flags;
  Metadata *ExtraData;
  Metadata *Annotations;

  MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
                Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
                uint32_t AlignInBits, Metadata *OffsetInBits,
                std::optional<unsigned> DWARFAddressSpace,
                std::optional<DIDerivedType::PtrAuthData> PtrAuthData,
                unsigned Flags, Metadata *ExtraData, Metadata *Annotations)
      : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
        BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
        AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace),
        PtrAuthData(PtrAuthData), Flags(Flags), ExtraData(ExtraData),
        Annotations(Annotations) {}
  MDNodeKeyImpl(const DIDerivedType *N)
      : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
        Line(N->getLine()), Scope(N->getRawScope()),
        BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
        OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
        DWARFAddressSpace(N->getDWARFAddressSpace()),
        PtrAuthData(N->getPtrAuthData()), Flags(N->getFlags()),
        ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {}

  bool isKeyOf(const DIDerivedType *RHS) const {
    return Tag == RHS->getTag() && Name == RHS->getRawName() &&
           File == RHS->getRawFile() && Line == RHS->getLine() &&
           Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
           SizeInBits == RHS->getRawSizeInBits() &&
           AlignInBits == RHS->getAlignInBits() &&
           OffsetInBits == RHS->getRawOffsetInBits() &&
           DWARFAddressSpace == RHS->getDWARFAddressSpace() &&
           PtrAuthData == RHS->getPtrAuthData() && Flags == RHS->getFlags() &&
           ExtraData == RHS->getRawExtraData() &&
           Annotations == RHS->getRawAnnotations();
  }

  unsigned getHashValue() const {
    // If this is a member inside an ODR type, only hash the type and the name.
    // Otherwise the hash will be stronger than
    // MDNodeSubsetEqualImpl::isODRMember().
    if (Tag == dwarf::DW_TAG_member && Name)
      if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
        if (CT->getRawIdentifier())
          return hash_combine(Name, Scope);

    // Intentionally computes the hash on a subset of the operands for
    // performance reason. The subset has to be significant enough to avoid
    // collision "most of the time". There is no correctness issue in case of
    // collision because of the full check above.
    return hash_combine(Tag, Name, File, Line, Scope, BaseType, Flags);
  }
};

template <> struct MDNodeKeyImpl<DISubrangeType> {
  MDString *Name;
  Metadata *File;
  unsigned Line;
  Metadata *Scope;
  Metadata *SizeInBits;
  uint32_t AlignInBits;
  unsigned Flags;
  Metadata *BaseType;
  Metadata *LowerBound;
  Metadata *UpperBound;
  Metadata *Stride;
  Metadata *Bias;

  MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
                Metadata *SizeInBits, uint32_t AlignInBits, unsigned Flags,
                Metadata *BaseType, Metadata *LowerBound, Metadata *UpperBound,
                Metadata *Stride, Metadata *Bias)
      : Name(Name), File(File), Line(Line), Scope(Scope),
        SizeInBits(SizeInBits), AlignInBits(AlignInBits), Flags(Flags),
        BaseType(BaseType), LowerBound(LowerBound), UpperBound(UpperBound),
        Stride(Stride), Bias(Bias) {}
  MDNodeKeyImpl(const DISubrangeType *N)
      : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
        Scope(N->getRawScope()), SizeInBits(N->getRawSizeInBits()),
        AlignInBits(N->getAlignInBits()), Flags(N->getFlags()),
        BaseType(N->getRawBaseType()), LowerBound(N->getRawLowerBound()),
        UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()),
        Bias(N->getRawBias()) {}

  bool isKeyOf(const DISubrangeType *RHS) const {
    auto BoundsEqual = [=](Metadata *Node1, Metadata *Node2) -> bool {
      if (Node1 == Node2)
        return true;

      ConstantAsMetadata *MD1 = dyn_cast_or_null<ConstantAsMetadata>(Node1);
      ConstantAsMetadata *MD2 = dyn_cast_or_null<ConstantAsMetadata>(Node2);
      if (MD1 && MD2) {
        ConstantInt *CV1 = cast<ConstantInt>(MD1->getValue());
        ConstantInt *CV2 = cast<ConstantInt>(MD2->getValue());
        if (CV1->getSExtValue() == CV2->getSExtValue())
          return true;
      }
      return false;
    };

    return Name == RHS->getRawName() && File == RHS->getRawFile() &&
           Line == RHS->getLine() && Scope == RHS->getRawScope() &&
           SizeInBits == RHS->getRawSizeInBits() &&
           AlignInBits == RHS->getAlignInBits() && Flags == RHS->getFlags() &&
           BaseType == RHS->getRawBaseType() &&
           BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
           BoundsEqual(UpperBound, RHS->getRawUpperBound()) &&
           BoundsEqual(Stride, RHS->getRawStride()) &&
           BoundsEqual(Bias, RHS->getRawBias());
  }

  unsigned getHashValue() const {
    unsigned val = 0;
    auto HashBound = [&](Metadata *Node) -> void {
      ConstantAsMetadata *MD = dyn_cast_or_null<ConstantAsMetadata>(Node);
      if (MD) {
        ConstantInt *CV = cast<ConstantInt>(MD->getValue());
        val = hash_combine(val, CV->getSExtValue());
      } else {
        val = hash_combine(val, Node);
      }
    };

    HashBound(LowerBound);
    HashBound(UpperBound);
    HashBound(Stride);
    HashBound(Bias);

    return hash_combine(val, Name, File, Line, Scope, BaseType, Flags);
  }
};

template <> struct MDNodeSubsetEqualImpl<DIDerivedType> {
  using KeyTy = MDNodeKeyImpl<DIDerivedType>;

  static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) {
    return isODRMember(LHS.Tag, LHS.Scope, LHS.Name, RHS);
  }

  static bool isSubsetEqual(const DIDerivedType *LHS,
                            const DIDerivedType *RHS) {
    return isODRMember(LHS->getTag(), LHS->getRawScope(), LHS->getRawName(),
                       RHS);
  }

  /// Subprograms compare equal if they declare the same function in an ODR
  /// type.
  static bool isODRMember(unsigned Tag, const Metadata *Scope,
                          const MDString *Name, const DIDerivedType *RHS) {
    // Check whether the LHS is eligible.
    if (Tag != dwarf::DW_TAG_member || !Name)
      return false;

    auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
    if (!CT || !CT->getRawIdentifier())
      return false;

    // Compare to the RHS.
    return Tag == RHS->getTag() && Name == RHS->getRawName() &&
           Scope == RHS->getRawScope();
  }
};

template <> struct MDNodeKeyImpl<DICompositeType> {
  unsigned Tag;
  MDString *Name;
  Metadata *File;
  unsigned Line;
  Metadata *Scope;
  Metadata *BaseType;
  Metadata *SizeInBits;
  Metadata *OffsetInBits;
  uint32_t AlignInBits;
  unsigned Flags;
  Metadata *Elements;
  unsigned RuntimeLang;
  Metadata *VTableHolder;
  Metadata *TemplateParams;
  MDString *Identifier;
  Metadata *Discriminator;
  Metadata *DataLocation;
  Metadata *Associated;
  Metadata *Allocated;
  Metadata *Rank;
  Metadata *Annotations;
  Metadata *Specification;
  uint32_t NumExtraInhabitants;
  Metadata *BitStride;

  MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
                Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
                uint32_t AlignInBits, Metadata *OffsetInBits, unsigned Flags,
                Metadata *Elements, unsigned RuntimeLang,
                Metadata *VTableHolder, Metadata *TemplateParams,
                MDString *Identifier, Metadata *Discriminator,
                Metadata *DataLocation, Metadata *Associated,
                Metadata *Allocated, Metadata *Rank, Metadata *Annotations,
                Metadata *Specification, uint32_t NumExtraInhabitants,
                Metadata *BitStride)
      : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
        BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
        AlignInBits(AlignInBits), Flags(Flags), Elements(Elements),
        RuntimeLang(RuntimeLang), VTableHolder(VTableHolder),
        TemplateParams(TemplateParams), Identifier(Identifier),
        Discriminator(Discriminator), DataLocation(DataLocation),
        Associated(Associated), Allocated(Allocated), Rank(Rank),
        Annotations(Annotations), Specification(Specification),
        NumExtraInhabitants(NumExtraInhabitants), BitStride(BitStride) {}
  MDNodeKeyImpl(const DICompositeType *N)
      : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
        Line(N->getLine()), Scope(N->getRawScope()),
        BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
        OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
        Flags(N->getFlags()), Elements(N->getRawElements()),
        RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()),
        TemplateParams(N->getRawTemplateParams()),
        Identifier(N->getRawIdentifier()),
        Discriminator(N->getRawDiscriminator()),
        DataLocation(N->getRawDataLocation()),
        Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()),
        Rank(N->getRawRank()), Annotations(N->getRawAnnotations()),
        Specification(N->getSpecification()),
        NumExtraInhabitants(N->getNumExtraInhabitants()),
        BitStride(N->getRawBitStride()) {}

  bool isKeyOf(const DICompositeType *RHS) const {
    return Tag == RHS->getTag() && Name == RHS->getRawName() &&
           File == RHS->getRawFile() && Line == RHS->getLine() &&
           Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
           SizeInBits == RHS->getRawSizeInBits() &&
           AlignInBits == RHS->getAlignInBits() &&
           OffsetInBits == RHS->getRawOffsetInBits() &&
           Flags == RHS->getFlags() && Elements == RHS->getRawElements() &&
           RuntimeLang == RHS->getRuntimeLang() &&
           VTableHolder == RHS->getRawVTableHolder() &&
           TemplateParams == RHS->getRawTemplateParams() &&
           Identifier == RHS->getRawIdentifier() &&
           Discriminator == RHS->getRawDiscriminator() &&
           DataLocation == RHS->getRawDataLocation() &&
           Associated == RHS->getRawAssociated() &&
           Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() &&
           Annotations == RHS->getRawAnnotations() &&
           Specification == RHS->getSpecification() &&
           NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
           BitStride == RHS->getRawBitStride();
  }

  unsigned getHashValue() const {
    // Intentionally computes the hash on a subset of the operands for
    // performance reason. The subset has to be significant enough to avoid
    // collision "most of the time". There is no correctness issue in case of
    // collision because of the full check above.
    return hash_combine(Name, File, Line, BaseType, Scope, Elements,
                        TemplateParams, Annotations);
  }
};

template <> struct MDNodeKeyImpl<DISubroutineType> {
  unsigned Flags;
  uint8_t CC;
  Metadata *TypeArray;

  MDNodeKeyImpl(unsigned Flags, uint8_t CC, Metadata *TypeArray)
      : Flags(Flags), CC(CC), TypeArray(TypeArray) {}
  MDNodeKeyImpl(const DISubroutineType *N)
      : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()) {}

  bool isKeyOf(const DISubroutineType *RHS) const {
    return Flags == RHS->getFlags() && CC == RHS->getCC() &&
           TypeArray == RHS->getRawTypeArray();
  }

  unsigned getHashValue() const { return hash_combine(Flags, CC, TypeArray); }
};

template <> struct MDNodeKeyImpl<DIFile> {
  MDString *Filename;
  MDString *Directory;
  std::optional<DIFile::ChecksumInfo<MDString *>> Checksum;
  MDString *Source;

  MDNodeKeyImpl(MDString *Filename, MDString *Directory,
                std::optional<DIFile::ChecksumInfo<MDString *>> Checksum,
                MDString *Source)
      : Filename(Filename), Directory(Directory), Checksum(Checksum),
        Source(Source) {}
  MDNodeKeyImpl(const DIFile *N)
      : Filename(N->getRawFilename()), Directory(N->getRawDirectory()),
        Checksum(N->getRawChecksum()), Source(N->getRawSource()) {}

  bool isKeyOf(const DIFile *RHS) const {
    return Filename == RHS->getRawFilename() &&
           Directory == RHS->getRawDirectory() &&
           Checksum == RHS->getRawChecksum() && Source == RHS->getRawSource();
  }

  unsigned getHashValue() const {
    return hash_combine(Filename, Directory, Checksum ? Checksum->Kind : 0,
                        Checksum ? Checksum->Value : nullptr, Source);
  }
};

template <> struct MDNodeKeyImpl<DISubprogram> {
  Metadata *Scope;
  MDString *Name;
  MDString *LinkageName;
  Metadata *File;
  unsigned Line;
  unsigned ScopeLine;
  Metadata *Type;
  Metadata *ContainingType;
  unsigned VirtualIndex;
  int ThisAdjustment;
  unsigned Flags;
  unsigned SPFlags;
  Metadata *Unit;
  Metadata *TemplateParams;
  Metadata *Declaration;
  Metadata *RetainedNodes;
  Metadata *ThrownTypes;
  Metadata *Annotations;
  MDString *TargetFuncName;
  bool UsesKeyInstructions;

  MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
                Metadata *File, unsigned Line, Metadata *Type,
                unsigned ScopeLine, Metadata *ContainingType,
                unsigned VirtualIndex, int ThisAdjustment, unsigned Flags,
                unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams,
                Metadata *Declaration, Metadata *RetainedNodes,
                Metadata *ThrownTypes, Metadata *Annotations,
                MDString *TargetFuncName, bool UsesKeyInstructions)
      : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
        Line(Line), ScopeLine(ScopeLine), Type(Type),
        ContainingType(ContainingType), VirtualIndex(VirtualIndex),
        ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags),
        Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration),
        RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes),
        Annotations(Annotations), TargetFuncName(TargetFuncName),
        UsesKeyInstructions(UsesKeyInstructions) {}
  MDNodeKeyImpl(const DISubprogram *N)
      : Scope(N->getRawScope()), Name(N->getRawName()),
        LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
        Line(N->getLine()), ScopeLine(N->getScopeLine()), Type(N->getRawType()),
        ContainingType(N->getRawContainingType()),
        VirtualIndex(N->getVirtualIndex()),
        ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()),
        SPFlags(N->getSPFlags()), Unit(N->getRawUnit()),
        TemplateParams(N->getRawTemplateParams()),
        Declaration(N->getRawDeclaration()),
        RetainedNodes(N->getRawRetainedNodes()),
        ThrownTypes(N->getRawThrownTypes()),
        Annotations(N->getRawAnnotations()),
        TargetFuncName(N->getRawTargetFuncName()),
        UsesKeyInstructions(N->getKeyInstructionsEnabled()) {}

  bool isKeyOf(const DISubprogram *RHS) const {
    return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
           LinkageName == RHS->getRawLinkageName() &&
           File == RHS->getRawFile() && Line == RHS->getLine() &&
           Type == RHS->getRawType() && ScopeLine == RHS->getScopeLine() &&
           ContainingType == RHS->getRawContainingType() &&
           VirtualIndex == RHS->getVirtualIndex() &&
           ThisAdjustment == RHS->getThisAdjustment() &&
           Flags == RHS->getFlags() && SPFlags == RHS->getSPFlags() &&
           Unit == RHS->getUnit() &&
           TemplateParams == RHS->getRawTemplateParams() &&
           Declaration == RHS->getRawDeclaration() &&
           RetainedNodes == RHS->getRawRetainedNodes() &&
           ThrownTypes == RHS->getRawThrownTypes() &&
           Annotations == RHS->getRawAnnotations() &&
           TargetFuncName == RHS->getRawTargetFuncName() &&
           UsesKeyInstructions == RHS->getKeyInstructionsEnabled();
  }

  bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; }

  unsigned getHashValue() const {
    // Use the Scope's linkage name instead of using the scope directly, as the
    // scope may be a temporary one which can replaced, which would produce a
    // different hash for the same DISubprogram.
    llvm::StringRef ScopeLinkageName;
    if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope))
      if (auto *ID = CT->getRawIdentifier())
        ScopeLinkageName = ID->getString();

    // If this is a declaration inside an ODR type, only hash the type and the
    // name.  Otherwise the hash will be stronger than
    // MDNodeSubsetEqualImpl::isDeclarationOfODRMember().
    if (!isDefinition() && LinkageName &&
        isa_and_nonnull<DICompositeType>(Scope))
      return hash_combine(LinkageName, ScopeLinkageName);

    // Intentionally computes the hash on a subset of the operands for
    // performance reason. The subset has to be significant enough to avoid
    // collision "most of the time". There is no correctness issue in case of
    // collision because of the full check above.
    return hash_combine(Name, ScopeLinkageName, File, Type, Line);
  }
};

template <> struct MDNodeSubsetEqualImpl<DISubprogram> {
  using KeyTy = MDNodeKeyImpl<DISubprogram>;

  static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) {
    return isDeclarationOfODRMember(LHS.isDefinition(), LHS.Scope,
                                    LHS.LinkageName, LHS.TemplateParams, RHS);
  }

  static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) {
    return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(),
                                    LHS->getRawLinkageName(),
                                    LHS->getRawTemplateParams(), RHS);
  }

  /// Subprograms compare equal if they declare the same function in an ODR
  /// type.
  static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope,
                                       const MDString *LinkageName,
                                       const Metadata *TemplateParams,
                                       const DISubprogram *RHS) {
    // Check whether the LHS is eligible.
    if (IsDefinition || !Scope || !LinkageName)
      return false;

    auto *CT = dyn_cast_or_null<DICompositeType>(Scope);
    if (!CT || !CT->getRawIdentifier())
      return false;

    // Compare to the RHS.
    // FIXME: We need to compare template parameters here to avoid incorrect
    // collisions in mapMetadata when RF_ReuseAndMutateDistinctMDs and a
    // ODR-DISubprogram has a non-ODR template parameter (i.e., a
    // DICompositeType that does not have an identifier). Eventually we should
    // decouple ODR logic from uniquing logic.
    return IsDefinition == RHS->isDefinition() && Scope == RHS->getRawScope() &&
           LinkageName == RHS->getRawLinkageName() &&
           TemplateParams == RHS->getRawTemplateParams();
  }
};

template <> struct MDNodeKeyImpl<DILexicalBlock> {
  Metadata *Scope;
  Metadata *File;
  unsigned Line;
  unsigned Column;

  MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Line, unsigned Column)
      : Scope(Scope), File(File), Line(Line), Column(Column) {}
  MDNodeKeyImpl(const DILexicalBlock *N)
      : Scope(N->getRawScope()), File(N->getRawFile()), Line(N->getLine()),
        Column(N->getColumn()) {}

  bool isKeyOf(const DILexicalBlock *RHS) const {
    return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
           Line == RHS->getLine() && Column == RHS->getColumn();
  }

  unsigned getHashValue() const {
    return hash_combine(Scope, File, Line, Column);
  }
};

template <> struct MDNodeKeyImpl<DILexicalBlockFile> {
  Metadata *Scope;
  Metadata *File;
  unsigned Discriminator;

  MDNodeKeyImpl(Metadata *Scope, Metadata *File, unsigned Discriminator)
      : Scope(Scope), File(File), Discriminator(Discriminator) {}
  MDNodeKeyImpl(const DILexicalBlockFile *N)
      : Scope(N->getRawScope()), File(N->getRawFile()),
        Discriminator(N->getDiscriminator()) {}

  bool isKeyOf(const DILexicalBlockFile *RHS) const {
    return Scope == RHS->getRawScope() && File == RHS->getRawFile() &&
           Discriminator == RHS->getDiscriminator();
  }

  unsigned getHashValue() const {
    return hash_combine(Scope, File, Discriminator);
  }
};

template <> struct MDNodeKeyImpl<DINamespace> {
  Metadata *Scope;
  MDString *Name;
  bool ExportSymbols;

  MDNodeKeyImpl(Metadata *Scope, MDString *Name, bool ExportSymbols)
      : Scope(Scope), Name(Name), ExportSymbols(ExportSymbols) {}
  MDNodeKeyImpl(const DINamespace *N)
      : Scope(N->getRawScope()), Name(N->getRawName()),
        ExportSymbols(N->getExportSymbols()) {}

  bool isKeyOf(const DINamespace *RHS) const {
    return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
           ExportSymbols == RHS->getExportSymbols();
  }

  unsigned getHashValue() const { return hash_combine(Scope, Name); }
};

template <> struct MDNodeKeyImpl<DICommonBlock> {
  Metadata *Scope;
  Metadata *Decl;
  MDString *Name;
  Metadata *File;
  unsigned LineNo;

  MDNodeKeyImpl(Metadata *Scope, Metadata *Decl, MDString *Name, Metadata *File,
                unsigned LineNo)
      : Scope(Scope), Decl(Decl), Name(Name), File(File), LineNo(LineNo) {}
  MDNodeKeyImpl(const DICommonBlock *N)
      : Scope(N->getRawScope()), Decl(N->getRawDecl()), Name(N->getRawName()),
        File(N->getRawFile()), LineNo(N->getLineNo()) {}

  bool isKeyOf(const DICommonBlock *RHS) const {
    return Scope == RHS->getRawScope() && Decl == RHS->getRawDecl() &&
           Name == RHS->getRawName() && File == RHS->getRawFile() &&
           LineNo == RHS->getLineNo();
  }

  unsigned getHashValue() const {
    return hash_combine(Scope, Decl, Name, File, LineNo);
  }
};

template <> struct MDNodeKeyImpl<DIModule> {
  Metadata *File;
  Metadata *Scope;
  MDString *Name;
  MDString *ConfigurationMacros;
  MDString *IncludePath;
  MDString *APINotesFile;
  unsigned LineNo;
  bool IsDecl;

  MDNodeKeyImpl(Metadata *File, Metadata *Scope, MDString *Name,
                MDString *ConfigurationMacros, MDString *IncludePath,
                MDString *APINotesFile, unsigned LineNo, bool IsDecl)
      : File(File), Scope(Scope), Name(Name),
        ConfigurationMacros(ConfigurationMacros), IncludePath(IncludePath),
        APINotesFile(APINotesFile), LineNo(LineNo), IsDecl(IsDecl) {}
  MDNodeKeyImpl(const DIModule *N)
      : File(N->getRawFile()), Scope(N->getRawScope()), Name(N->getRawName()),
        ConfigurationMacros(N->getRawConfigurationMacros()),
        IncludePath(N->getRawIncludePath()),
        APINotesFile(N->getRawAPINotesFile()), LineNo(N->getLineNo()),
        IsDecl(N->getIsDecl()) {}

  bool isKeyOf(const DIModule *RHS) const {
    return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
           ConfigurationMacros == RHS->getRawConfigurationMacros() &&
           IncludePath == RHS->getRawIncludePath() &&
           APINotesFile == RHS->getRawAPINotesFile() &&
           File == RHS->getRawFile() && LineNo == RHS->getLineNo() &&
           IsDecl == RHS->getIsDecl();
  }

  unsigned getHashValue() const {
    return hash_combine(Scope, Name, ConfigurationMacros, IncludePath);
  }
};

template <> struct MDNodeKeyImpl<DITemplateTypeParameter> {
  MDString *Name;
  Metadata *Type;
  bool IsDefault;

  MDNodeKeyImpl(MDString *Name, Metadata *Type, bool IsDefault)
      : Name(Name), Type(Type), IsDefault(IsDefault) {}
  MDNodeKeyImpl(const DITemplateTypeParameter *N)
      : Name(N->getRawName()), Type(N->getRawType()),
        IsDefault(N->isDefault()) {}

  bool isKeyOf(const DITemplateTypeParameter *RHS) const {
    return Name == RHS->getRawName() && Type == RHS->getRawType() &&
           IsDefault == RHS->isDefault();
  }

  unsigned getHashValue() const { return hash_combine(Name, Type, IsDefault); }
};

template <> struct MDNodeKeyImpl<DITemplateValueParameter> {
  unsigned Tag;
  MDString *Name;
  Metadata *Type;
  bool IsDefault;
  Metadata *Value;

  MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *Type, bool IsDefault,
                Metadata *Value)
      : Tag(Tag), Name(Name), Type(Type), IsDefault(IsDefault), Value(Value) {}
  MDNodeKeyImpl(const DITemplateValueParameter *N)
      : Tag(N->getTag()), Name(N->getRawName()), Type(N->getRawType()),
        IsDefault(N->isDefault()), Value(N->getValue()) {}

  bool isKeyOf(const DITemplateValueParameter *RHS) const {
    return Tag == RHS->getTag() && Name == RHS->getRawName() &&
           Type == RHS->getRawType() && IsDefault == RHS->isDefault() &&
           Value == RHS->getValue();
  }

  unsigned getHashValue() const {
    return hash_combine(Tag, Name, Type, IsDefault, Value);
  }
};

template <> struct MDNodeKeyImpl<DIGlobalVariable> {
  Metadata *Scope;
  MDString *Name;
  MDString *LinkageName;
  Metadata *File;
  unsigned Line;
  Metadata *Type;
  bool IsLocalToUnit;
  bool IsDefinition;
  Metadata *StaticDataMemberDeclaration;
  Metadata *TemplateParams;
  uint32_t AlignInBits;
  Metadata *Annotations;

  MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
                Metadata *File, unsigned Line, Metadata *Type,
                bool IsLocalToUnit, bool IsDefinition,
                Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
                uint32_t AlignInBits, Metadata *Annotations)
      : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
        Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit),
        IsDefinition(IsDefinition),
        StaticDataMemberDeclaration(StaticDataMemberDeclaration),
        TemplateParams(TemplateParams), AlignInBits(AlignInBits),
        Annotations(Annotations) {}
  MDNodeKeyImpl(const DIGlobalVariable *N)
      : Scope(N->getRawScope()), Name(N->getRawName()),
        LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
        Line(N->getLine()), Type(N->getRawType()),
        IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
        StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()),
        TemplateParams(N->getRawTemplateParams()),
        AlignInBits(N->getAlignInBits()), Annotations(N->getRawAnnotations()) {}

  bool isKeyOf(const DIGlobalVariable *RHS) const {
    return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
           LinkageName == RHS->getRawLinkageName() &&
           File == RHS->getRawFile() && Line == RHS->getLine() &&
           Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() &&
           IsDefinition == RHS->isDefinition() &&
           StaticDataMemberDeclaration ==
               RHS->getRawStaticDataMemberDeclaration() &&
           TemplateParams == RHS->getRawTemplateParams() &&
           AlignInBits == RHS->getAlignInBits() &&
           Annotations == RHS->getRawAnnotations();
  }

  unsigned getHashValue() const {
    // We do not use AlignInBits in hashing function here on purpose:
    // in most cases this param for local variable is zero (for function param
    // it is always zero). This leads to lots of hash collisions and errors on
    // cases with lots of similar variables.
    // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
    // generated IR is random for each run and test fails with Align included.
    // TODO: make hashing work fine with such situations
    return hash_combine(Scope, Name, LinkageName, File, Line, Type,
                        IsLocalToUnit, IsDefinition, /* AlignInBits, */
                        StaticDataMemberDeclaration, Annotations);
  }
};

template <> struct MDNodeKeyImpl<DILocalVariable> {
  Metadata *Scope;
  MDString *Name;
  Metadata *File;
  unsigned Line;
  Metadata *Type;
  unsigned Arg;
  unsigned Flags;
  uint32_t AlignInBits;
  Metadata *Annotations;

  MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line,
                Metadata *Type, unsigned Arg, unsigned Flags,
                uint32_t AlignInBits, Metadata *Annotations)
      : Scope(Scope), Name(Name), File(File), Line(Line), Type(Type), Arg(Arg),
        Flags(Flags), AlignInBits(AlignInBits), Annotations(Annotations) {}
  MDNodeKeyImpl(const DILocalVariable *N)
      : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
        Line(N->getLine()), Type(N->getRawType()), Arg(N->getArg()),
        Flags(N->getFlags()), AlignInBits(N->getAlignInBits()),
        Annotations(N->getRawAnnotations()) {}

  bool isKeyOf(const DILocalVariable *RHS) const {
    return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
           File == RHS->getRawFile() && Line == RHS->getLine() &&
           Type == RHS->getRawType() && Arg == RHS->getArg() &&
           Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits() &&
           Annotations == RHS->getRawAnnotations();
  }

  unsigned getHashValue() const {
    // We do not use AlignInBits in hashing function here on purpose:
    // in most cases this param for local variable is zero (for function param
    // it is always zero). This leads to lots of hash collisions and errors on
    // cases with lots of similar variables.
    // clang/test/CodeGen/debug-info-257-args.c is an example of this problem,
    // generated IR is random for each run and test fails with Align included.
    // TODO: make hashing work fine with such situations
    return hash_combine(Scope, Name, File, Line, Type, Arg, Flags, Annotations);
  }
};

template <> struct MDNodeKeyImpl<DILabel> {
  Metadata *Scope;
  MDString *Name;
  Metadata *File;
  unsigned Line;
  unsigned Column;
  bool IsArtificial;
  std::optional<unsigned> CoroSuspendIdx;

  MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line,
                unsigned Column, bool IsArtificial,
                std::optional<unsigned> CoroSuspendIdx)
      : Scope(Scope), Name(Name), File(File), Line(Line), Column(Column),
        IsArtificial(IsArtificial), CoroSuspendIdx(CoroSuspendIdx) {}
  MDNodeKeyImpl(const DILabel *N)
      : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()),
        Line(N->getLine()), Column(N->getColumn()),
        IsArtificial(N->isArtificial()),
        CoroSuspendIdx(N->getCoroSuspendIdx()) {}

  bool isKeyOf(const DILabel *RHS) const {
    return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
           File == RHS->getRawFile() && Line == RHS->getLine() &&
           Column == RHS->getColumn() && IsArtificial == RHS->isArtificial() &&
           CoroSuspendIdx == RHS->getCoroSuspendIdx();
  }

  /// Using name and line to get hash value. It should already be mostly unique.
  unsigned getHashValue() const {
    return hash_combine(Scope, Name, Line, Column, IsArtificial,
                        CoroSuspendIdx);
  }
};

template <> struct MDNodeKeyImpl<DIExpression> {
  ArrayRef<uint64_t> Elements;

  MDNodeKeyImpl(ArrayRef<uint64_t> Elements) : Elements(Elements) {}
  MDNodeKeyImpl(const DIExpression *N) : Elements(N->getElements()) {}

  bool isKeyOf(const DIExpression *RHS) const {
    return Elements == RHS->getElements();
  }

  unsigned getHashValue() const { return hash_combine_range(Elements); }
};

template <> struct MDNodeKeyImpl<DIGlobalVariableExpression> {
  Metadata *Variable;
  Metadata *Expression;

  MDNodeKeyImpl(Metadata *Variable, Metadata *Expression)
      : Variable(Variable), Expression(Expression) {}
  MDNodeKeyImpl(const DIGlobalVariableExpression *N)
      : Variable(N->getRawVariable()), Expression(N->getRawExpression()) {}

  bool isKeyOf(const DIGlobalVariableExpression *RHS) const {
    return Variable == RHS->getRawVariable() &&
           Expression == RHS->getRawExpression();
  }

  unsigned getHashValue() const { return hash_combine(Variable, Expression); }
};

template <> struct MDNodeKeyImpl<DIObjCProperty> {
  MDString *Name;
  Metadata *File;
  unsigned Line;
  MDString *GetterName;
  MDString *SetterName;
  unsigned Attributes;
  Metadata *Type;

  MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line,
                MDString *GetterName, MDString *SetterName, unsigned Attributes,
                Metadata *Type)
      : Name(Name), File(File), Line(Line), GetterName(GetterName),
        SetterName(SetterName), Attributes(Attributes), Type(Type) {}
  MDNodeKeyImpl(const DIObjCProperty *N)
      : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
        GetterName(N->getRawGetterName()), SetterName(N->getRawSetterName()),
        Attributes(N->getAttributes()), Type(N->getRawType()) {}

  bool isKeyOf(const DIObjCProperty *RHS) const {
    return Name == RHS->getRawName() && File == RHS->getRawFile() &&
           Line == RHS->getLine() && GetterName == RHS->getRawGetterName() &&
           SetterName == RHS->getRawSetterName() &&
           Attributes == RHS->getAttributes() && Type == RHS->getRawType();
  }

  unsigned getHashValue() const {
    return hash_combine(Name, File, Line, GetterName, SetterName, Attributes,
                        Type);
  }
};

template <> struct MDNodeKeyImpl<DIImportedEntity> {
  unsigned Tag;
  Metadata *Scope;
  Metadata *Entity;
  Metadata *File;
  unsigned Line;
  MDString *Name;
  Metadata *Elements;

  MDNodeKeyImpl(unsigned Tag, Metadata *Scope, Metadata *Entity, Metadata *File,
                unsigned Line, MDString *Name, Metadata *Elements)
      : Tag(Tag), Scope(Scope), Entity(Entity), File(File), Line(Line),
        Name(Name), Elements(Elements) {}
  MDNodeKeyImpl(const DIImportedEntity *N)
      : Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()),
        File(N->getRawFile()), Line(N->getLine()), Name(N->getRawName()),
        Elements(N->getRawElements()) {}

  bool isKeyOf(const DIImportedEntity *RHS) const {
    return Tag == RHS->getTag() && Scope == RHS->getRawScope() &&
           Entity == RHS->getRawEntity() && File == RHS->getFile() &&
           Line == RHS->getLine() && Name == RHS->getRawName() &&
           Elements == RHS->getRawElements();
  }

  unsigned getHashValue() const {
    return hash_combine(Tag, Scope, Entity, File, Line, Name, Elements);
  }
};

template <> struct MDNodeKeyImpl<DIMacro> {
  unsigned MIType;
  unsigned Line;
  MDString *Name;
  MDString *Value;

  MDNodeKeyImpl(unsigned MIType, unsigned Line, MDString *Name, MDString *Value)
      : MIType(MIType), Line(Line), Name(Name), Value(Value) {}
  MDNodeKeyImpl(const DIMacro *N)
      : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getRawName()),
        Value(N->getRawValue()) {}

  bool isKeyOf(const DIMacro *RHS) const {
    return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
           Name == RHS->getRawName() && Value == RHS->getRawValue();
  }

  unsigned getHashValue() const {
    return hash_combine(MIType, Line, Name, Value);
  }
};

template <> struct MDNodeKeyImpl<DIMacroFile> {
  unsigned MIType;
  unsigned Line;
  Metadata *File;
  Metadata *Elements;

  MDNodeKeyImpl(unsigned MIType, unsigned Line, Metadata *File,
                Metadata *Elements)
      : MIType(MIType), Line(Line), File(File), Elements(Elements) {}
  MDNodeKeyImpl(const DIMacroFile *N)
      : MIType(N->getMacinfoType()), Line(N->getLine()), File(N->getRawFile()),
        Elements(N->getRawElements()) {}

  bool isKeyOf(const DIMacroFile *RHS) const {
    return MIType == RHS->getMacinfoType() && Line == RHS->getLine() &&
           File == RHS->getRawFile() && Elements == RHS->getRawElements();
  }

  unsigned getHashValue() const {
    return hash_combine(MIType, Line, File, Elements);
  }
};

// DIArgLists are not MDNodes, but we still want to unique them in a DenseSet
// based on a hash of their arguments.
struct DIArgListKeyInfo {
  ArrayRef<ValueAsMetadata *> Args;

  DIArgListKeyInfo(ArrayRef<ValueAsMetadata *> Args) : Args(Args) {}
  DIArgListKeyInfo(const DIArgList *N) : Args(N->getArgs()) {}

  bool isKeyOf(const DIArgList *RHS) const { return Args == RHS->getArgs(); }

  unsigned getHashValue() const { return hash_combine_range(Args); }
};

/// DenseMapInfo for DIArgList.
struct DIArgListInfo {
  using KeyTy = DIArgListKeyInfo;

  static inline DIArgList *getEmptyKey() {
    return DenseMapInfo<DIArgList *>::getEmptyKey();
  }

  static inline DIArgList *getTombstoneKey() {
    return DenseMapInfo<DIArgList *>::getTombstoneKey();
  }

  static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }

  static unsigned getHashValue(const DIArgList *N) {
    return KeyTy(N).getHashValue();
  }

  static bool isEqual(const KeyTy &LHS, const DIArgList *RHS) {
    if (RHS == getEmptyKey() || RHS == getTombstoneKey())
      return false;
    return LHS.isKeyOf(RHS);
  }

  static bool isEqual(const DIArgList *LHS, const DIArgList *RHS) {
    return LHS == RHS;
  }
};

/// DenseMapInfo for MDNode subclasses.
template <class NodeTy> struct MDNodeInfo {
  using KeyTy = MDNodeKeyImpl<NodeTy>;
  using SubsetEqualTy = MDNodeSubsetEqualImpl<NodeTy>;

  static inline NodeTy *getEmptyKey() {
    return DenseMapInfo<NodeTy *>::getEmptyKey();
  }

  static inline NodeTy *getTombstoneKey() {
    return DenseMapInfo<NodeTy *>::getTombstoneKey();
  }

  static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }

  static unsigned getHashValue(const NodeTy *N) {
    return KeyTy(N).getHashValue();
  }

  static bool isEqual(const KeyTy &LHS, const NodeTy *RHS) {
    if (RHS == getEmptyKey() || RHS == getTombstoneKey())
      return false;
    return SubsetEqualTy::isSubsetEqual(LHS, RHS) || LHS.isKeyOf(RHS);
  }

  static bool isEqual(const NodeTy *LHS, const NodeTy *RHS) {
    if (LHS == RHS)
      return true;
    if (RHS == getEmptyKey() || RHS == getTombstoneKey())
      return false;
    return SubsetEqualTy::isSubsetEqual(LHS, RHS);
  }
};

#define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>;
#include "llvm/IR/Metadata.def"

/// Multimap-like storage for metadata attachments.
class MDAttachments {
public:
  struct Attachment {
    unsigned MDKind;
    TrackingMDNodeRef Node;
  };

private:
  SmallVector<Attachment, 1> Attachments;

public:
  bool empty() const { return Attachments.empty(); }
  size_t size() const { return Attachments.size(); }

  /// Returns the first attachment with the given ID or nullptr if no such
  /// attachment exists.
  MDNode *lookup(unsigned ID) const;

  /// Appends all attachments with the given ID to \c Result in insertion order.
  /// If the global has no attachments with the given ID, or if ID is invalid,
  /// leaves Result unchanged.
  void get(unsigned ID, SmallVectorImpl<MDNode *> &Result) const;

  /// Appends all attachments for the global to \c Result, sorting by attachment
  /// ID. Attachments with the same ID appear in insertion order. This function
  /// does \em not clear \c Result.
  void getAll(SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const;

  /// Set an attachment to a particular node.
  ///
  /// Set the \c ID attachment to \c MD, replacing the current attachments at \c
  /// ID (if anyway).
  void set(unsigned ID, MDNode *MD);

  /// Adds an attachment to a particular node.
  void insert(unsigned ID, MDNode &MD);

  /// Remove attachments with the given ID.
  ///
  /// Remove the attachments at \c ID, if any.
  bool erase(unsigned ID);

  /// Erase matching attachments.
  ///
  /// Erases all attachments matching the \c shouldRemove predicate.
  template <class PredTy> void remove_if(PredTy shouldRemove) {
    llvm::erase_if(Attachments, shouldRemove);
  }
};

class LLVMContextImpl {
public:
  /// OwnedModules - The set of modules instantiated in this context, and which
  /// will be automatically deleted if this context is deleted.
  SmallPtrSet<Module *, 4> OwnedModules;

  /// MachineFunctionNums - Keep the next available unique number available for
  /// a MachineFunction in given module. Module must in OwnedModules.
  DenseMap<Module *, unsigned> MachineFunctionNums;

  /// The main remark streamer used by all the other streamers (e.g. IR, MIR,
  /// frontends, etc.). This should only be used by the specific streamers, and
  /// never directly.
  std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer;

  std::unique_ptr<DiagnosticHandler> DiagHandler;
  bool RespectDiagnosticFilters = false;
  bool DiagnosticsHotnessRequested = false;
  /// The minimum hotness value a diagnostic needs in order to be included in
  /// optimization diagnostics.
  ///
  /// The threshold is an Optional value, which maps to one of the 3 states:
  /// 1). 0            => threshold disabled. All emarks will be printed.
  /// 2). positive int => manual threshold by user. Remarks with hotness exceed
  ///                     threshold will be printed.
  /// 3). None         => 'auto' threshold by user. The actual value is not
  ///                     available at command line, but will be synced with
  ///                     hotness threhold from profile summary during
  ///                     compilation.
  ///
  /// State 1 and 2 are considered as terminal states. State transition is
  /// only allowed from 3 to 2, when the threshold is first synced with profile
  /// summary. This ensures that the threshold is set only once and stays
  /// constant.
  ///
  /// If threshold option is not specified, it is disabled (0) by default.
  std::optional<uint64_t> DiagnosticsHotnessThreshold = 0;

  /// The percentage of difference between profiling branch weights and
  /// llvm.expect branch weights to tolerate when emiting MisExpect diagnostics
  std::optional<uint32_t> DiagnosticsMisExpectTolerance = 0;
  bool MisExpectWarningRequested = false;

  /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
  std::unique_ptr<LLVMRemarkStreamer> LLVMRS;

  LLVMContext::YieldCallbackTy YieldCallback = nullptr;
  void *YieldOpaqueHandle = nullptr;

  DenseMap<const Value *, ValueName *> ValueNames;

  DenseMap<unsigned, std::unique_ptr<ConstantInt>> IntZeroConstants;
  DenseMap<unsigned, std::unique_ptr<ConstantInt>> IntOneConstants;
  DenseMap<APInt, std::unique_ptr<ConstantInt>> IntConstants;
  DenseMap<std::pair<ElementCount, APInt>, std::unique_ptr<ConstantInt>>
      IntSplatConstants;

  DenseMap<APFloat, std::unique_ptr<ConstantFP>> FPConstants;
  DenseMap<std::pair<ElementCount, APFloat>, std::unique_ptr<ConstantFP>>
      FPSplatConstants;

  FoldingSet<AttributeImpl> AttrsSet;
  FoldingSet<AttributeListImpl> AttrsLists;
  FoldingSet<AttributeSetNode> AttrsSetNodes;

  StringMap<MDString, BumpPtrAllocator> MDStringCache;
  DenseMap<Value *, ValueAsMetadata *> ValuesAsMetadata;
  DenseMap<Metadata *, MetadataAsValue *> MetadataAsValues;
  DenseSet<DIArgList *, DIArgListInfo> DIArgLists;

#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS)                                    \
  DenseSet<CLASS *, CLASS##Info> CLASS##s;
#include "llvm/IR/Metadata.def"

  // Optional map for looking up composite types by identifier.
  std::optional<DenseMap<const MDString *, DICompositeType *>> DITypeMap;

  // MDNodes may be uniqued or not uniqued.  When they're not uniqued, they
  // aren't in the MDNodeSet, but they're still shared between objects, so no
  // one object can destroy them.  Keep track of them here so we can delete
  // them on context teardown.
  std::vector<MDNode *> DistinctMDNodes;

  // ConstantRangeListAttributeImpl is a TrailingObjects/ArrayRef of
  // ConstantRange. Since this is a dynamically sized class, it's not
  // possible to use SpecificBumpPtrAllocator. Instead, we use normal Alloc
  // for allocation and record all allocated pointers in this vector. In the
  // LLVMContext destructor, call the destuctors of everything in the vector.
  std::vector<ConstantRangeListAttributeImpl *> ConstantRangeListAttributes;

  DenseMap<Type *, std::unique_ptr<ConstantAggregateZero>> CAZConstants;

  using ArrayConstantsTy = ConstantUniqueMap<ConstantArray>;
  ArrayConstantsTy ArrayConstants;

  using StructConstantsTy = ConstantUniqueMap<ConstantStruct>;
  StructConstantsTy StructConstants;

  using VectorConstantsTy = ConstantUniqueMap<ConstantVector>;
  VectorConstantsTy VectorConstants;

  DenseMap<PointerType *, std::unique_ptr<ConstantPointerNull>> CPNConstants;

  DenseMap<TargetExtType *, std::unique_ptr<ConstantTargetNone>> CTNConstants;

  DenseMap<Type *, std::unique_ptr<UndefValue>> UVConstants;

  DenseMap<Type *, std::unique_ptr<PoisonValue>> PVConstants;

  StringMap<std::unique_ptr<ConstantDataSequential>> CDSConstants;

  DenseMap<const BasicBlock *, BlockAddress *> BlockAddresses;

  DenseMap<const GlobalValue *, DSOLocalEquivalent *> DSOLocalEquivalents;

  DenseMap<const GlobalValue *, NoCFIValue *> NoCFIValues;

  ConstantUniqueMap<ConstantPtrAuth> ConstantPtrAuths;

  ConstantUniqueMap<ConstantExpr> ExprConstants;

  ConstantUniqueMap<InlineAsm> InlineAsms;

  ConstantInt *TheTrueVal = nullptr;
  ConstantInt *TheFalseVal = nullptr;

  // Basic type instances.
  Type VoidTy, LabelTy, HalfTy, BFloatTy, FloatTy, DoubleTy, MetadataTy,
      TokenTy;
  Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_AMXTy;
  IntegerType Int1Ty, Int8Ty, Int16Ty, Int32Ty, Int64Ty, Int128Ty;

  std::unique_ptr<ConstantTokenNone> TheNoneToken;

  BumpPtrAllocator Alloc;
  UniqueStringSaver Saver{Alloc};
  SpecificBumpPtrAllocator<ConstantRangeAttributeImpl>
      ConstantRangeAttributeAlloc;

  DenseMap<unsigned, IntegerType *> IntegerTypes;

  using FunctionTypeSet = DenseSet<FunctionType *, FunctionTypeKeyInfo>;
  FunctionTypeSet FunctionTypes;
  using StructTypeSet = DenseSet<StructType *, AnonStructTypeKeyInfo>;
  StructTypeSet AnonStructTypes;
  StringMap<StructType *> NamedStructTypes;
  unsigned NamedStructTypesUniqueID = 0;

  using TargetExtTypeSet = DenseSet<TargetExtType *, TargetExtTypeKeyInfo>;
  TargetExtTypeSet TargetExtTypes;

  DenseMap<std::pair<Type *, uint64_t>, ArrayType *> ArrayTypes;
  DenseMap<std::pair<Type *, ElementCount>, VectorType *> VectorTypes;
  PointerType *AS0PointerType = nullptr; // AddrSpace = 0
  DenseMap<unsigned, PointerType *> PointerTypes;
  DenseMap<std::pair<Type *, unsigned>, TypedPointerType *> ASTypedPointerTypes;

  /// ValueHandles - This map keeps track of all of the value handles that are
  /// watching a Value*.  The Value::HasValueHandle bit is used to know
  /// whether or not a value has an entry in this map.
  using ValueHandlesTy = DenseMap<Value *, ValueHandleBase *>;
  ValueHandlesTy ValueHandles;

  /// CustomMDKindNames - Map to hold the metadata string to ID mapping.
  StringMap<unsigned> CustomMDKindNames;

  /// Collection of metadata used in this context.
  DenseMap<const Value *, MDAttachments> ValueMetadata;

  /// Map DIAssignID -> Instructions with that attachment.
  /// Managed by Instruction via Instruction::updateDIAssignIDMapping.
  /// Query using the at:: functions defined in DebugInfo.h.
  DenseMap<DIAssignID *, SmallVector<Instruction *, 1>> AssignmentIDToInstrs;

  /// Collection of per-GlobalObject sections used in this context.
  DenseMap<const GlobalObject *, StringRef> GlobalObjectSections;

  /// Collection of per-GlobalValue partitions used in this context.
  DenseMap<const GlobalValue *, StringRef> GlobalValuePartitions;

  DenseMap<const GlobalValue *, GlobalValue::SanitizerMetadata>
      GlobalValueSanitizerMetadata;

  /// DiscriminatorTable - This table maps file:line locations to an
  /// integer representing the next DWARF path discriminator to assign to
  /// instructions in different blocks at the same location.
  DenseMap<std::pair<const char *, unsigned>, unsigned> DiscriminatorTable;

  /// A set of interned tags for operand bundles.  The StringMap maps
  /// bundle tags to their IDs.
  ///
  /// \see LLVMContext::getOperandBundleTagID
  StringMap<uint32_t> BundleTagCache;

  StringMapEntry<uint32_t> *getOrInsertBundleTag(StringRef Tag);
  void getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const;
  uint32_t getOperandBundleTagID(StringRef Tag) const;

  /// A set of interned synchronization scopes.  The StringMap maps
  /// synchronization scope names to their respective synchronization scope IDs.
  StringMap<SyncScope::ID> SSC;

  /// getOrInsertSyncScopeID - Maps synchronization scope name to
  /// synchronization scope ID.  Every synchronization scope registered with
  /// LLVMContext has unique ID except pre-defined ones.
  SyncScope::ID getOrInsertSyncScopeID(StringRef SSN);

  /// getSyncScopeNames - Populates client supplied SmallVector with
  /// synchronization scope names registered with LLVMContext.  Synchronization
  /// scope names are ordered by increasing synchronization scope IDs.
  void getSyncScopeNames(SmallVectorImpl<StringRef> &SSNs) const;

  /// getSyncScopeName - Returns the name of a SyncScope::ID
  /// registered with LLVMContext, if any.
  std::optional<StringRef> getSyncScopeName(SyncScope::ID Id) const;

  /// Maintain the GC name for each function.
  ///
  /// This saves allocating an additional word in Function for programs which
  /// do not use GC (i.e., most programs) at the cost of increased overhead for
  /// clients which do use GC.
  DenseMap<const Function *, std::string> GCNames;

  /// Flag to indicate if Value (other than GlobalValue) retains their name or
  /// not.
  bool DiscardValueNames = false;

  LLVMContextImpl(LLVMContext &C);
  ~LLVMContextImpl();

  mutable OptPassGate *OPG = nullptr;

  /// Access the object which can disable optional passes and individual
  /// optimizations at compile time.
  OptPassGate &getOptPassGate() const;

  /// Set the object which can disable optional passes and individual
  /// optimizations at compile time.
  ///
  /// The lifetime of the object must be guaranteed to extend as long as the
  /// LLVMContext is used by compilation.
  void setOptPassGate(OptPassGate &);

  /// Mapping of blocks to collections of "trailing" DbgVariableRecords. As part
  /// of the "RemoveDIs" project, debug-info variable location records are going
  /// to cease being instructions... which raises the problem of where should
  /// they be recorded when we remove the terminator of a blocks, such as:
  ///
  ///    %foo = add i32 0, 0
  ///    br label %bar
  ///
  /// If the branch is removed, a legitimate transient state while editing a
  /// block, any debug-records between those two instructions will not have a
  /// location. Each block thus records any DbgVariableRecord records that
  /// "trail" in such a way. These are stored in LLVMContext because typically
  /// LLVM only edits a small number of blocks at a time, so there's no need to
  /// bloat BasicBlock with such a data structure.
  SmallDenseMap<BasicBlock *, DbgMarker *> TrailingDbgRecords;

  // Set, get and delete operations for TrailingDbgRecords.
  void setTrailingDbgRecords(BasicBlock *B, DbgMarker *M) {
    assert(!TrailingDbgRecords.count(B));
    TrailingDbgRecords[B] = M;
  }

  DbgMarker *getTrailingDbgRecords(BasicBlock *B) {
    return TrailingDbgRecords.lookup(B);
  }

  void deleteTrailingDbgRecords(BasicBlock *B) { TrailingDbgRecords.erase(B); }

  std::string DefaultTargetCPU;
  std::string DefaultTargetFeatures;

  /// The next available source atom group number. The front end is responsible
  /// for assigning source atom numbers, but certain optimisations need to
  /// assign new group numbers to a set of instructions. Most often code
  /// duplication optimisations like loop unroll. Tracking a global maximum
  /// value means we can know (cheaply) we're never using a group number that's
  /// already used within this function.
  ///
  /// Start a 1 because 0 means the source location isn't part of an atom group.
  uint64_t NextAtomGroup = 1;
};

} // end namespace llvm

#endif // LLVM_LIB_IR_LLVMCONTEXTIMPL_H
