//===- Attributes.cpp - Implement AttributesList --------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// \file
// This file implements the Attribute, AttributeImpl, AttrBuilder,
// AttributeListImpl, and AttributeList classes.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/Attributes.h"
#include "AttributeImpl.h"
#include "LLVMContextImpl.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/AttributeMask.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/ConstantRangeList.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ModRef.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <limits>
#include <optional>
#include <string>
#include <tuple>
#include <utility>

using namespace llvm;

//===----------------------------------------------------------------------===//
// Attribute Construction Methods
//===----------------------------------------------------------------------===//

// allocsize has two integer arguments, but because they're both 32 bits, we can
// pack them into one 64-bit value, at the cost of making said value
// nonsensical.
//
// In order to do this, we need to reserve one value of the second (optional)
// allocsize argument to signify "not present."
static const unsigned AllocSizeNumElemsNotPresent = -1;

static uint64_t packAllocSizeArgs(unsigned ElemSizeArg,
                                  const std::optional<unsigned> &NumElemsArg) {
  assert((!NumElemsArg || *NumElemsArg != AllocSizeNumElemsNotPresent) &&
         "Attempting to pack a reserved value");

  return uint64_t(ElemSizeArg) << 32 |
         NumElemsArg.value_or(AllocSizeNumElemsNotPresent);
}

static std::pair<unsigned, std::optional<unsigned>>
unpackAllocSizeArgs(uint64_t Num) {
  unsigned NumElems = Num & std::numeric_limits<unsigned>::max();
  unsigned ElemSizeArg = Num >> 32;

  std::optional<unsigned> NumElemsArg;
  if (NumElems != AllocSizeNumElemsNotPresent)
    NumElemsArg = NumElems;
  return std::make_pair(ElemSizeArg, NumElemsArg);
}

static uint64_t packVScaleRangeArgs(unsigned MinValue,
                                    std::optional<unsigned> MaxValue) {
  return uint64_t(MinValue) << 32 | MaxValue.value_or(0);
}

static std::pair<unsigned, std::optional<unsigned>>
unpackVScaleRangeArgs(uint64_t Value) {
  unsigned MaxValue = Value & std::numeric_limits<unsigned>::max();
  unsigned MinValue = Value >> 32;

  return std::make_pair(MinValue,
                        MaxValue > 0 ? MaxValue : std::optional<unsigned>());
}

Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
                         uint64_t Val) {
  bool IsIntAttr = Attribute::isIntAttrKind(Kind);
  assert((IsIntAttr || Attribute::isEnumAttrKind(Kind)) &&
         "Not an enum or int attribute");

  LLVMContextImpl *pImpl = Context.pImpl;
  FoldingSetNodeID ID;
  ID.AddInteger(Kind);
  if (IsIntAttr)
    ID.AddInteger(Val);
  else
    assert(Val == 0 && "Value must be zero for enum attributes");

  void *InsertPoint;
  AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);

  if (!PA) {
    // If we didn't find any existing attributes of the same shape then create a
    // new one and insert it.
    if (!IsIntAttr)
      PA = new (pImpl->Alloc) EnumAttributeImpl(Kind);
    else
      PA = new (pImpl->Alloc) IntAttributeImpl(Kind, Val);
    pImpl->AttrsSet.InsertNode(PA, InsertPoint);
  }

  // Return the Attribute that we found or created.
  return Attribute(PA);
}

Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) {
  LLVMContextImpl *pImpl = Context.pImpl;
  FoldingSetNodeID ID;
  ID.AddString(Kind);
  if (!Val.empty()) ID.AddString(Val);

  void *InsertPoint;
  AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);

  if (!PA) {
    // If we didn't find any existing attributes of the same shape then create a
    // new one and insert it.
    void *Mem =
        pImpl->Alloc.Allocate(StringAttributeImpl::totalSizeToAlloc(Kind, Val),
                              alignof(StringAttributeImpl));
    PA = new (Mem) StringAttributeImpl(Kind, Val);
    pImpl->AttrsSet.InsertNode(PA, InsertPoint);
  }

  // Return the Attribute that we found or created.
  return Attribute(PA);
}

Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
                         Type *Ty) {
  assert(Attribute::isTypeAttrKind(Kind) && "Not a type attribute");
  LLVMContextImpl *pImpl = Context.pImpl;
  FoldingSetNodeID ID;
  ID.AddInteger(Kind);
  ID.AddPointer(Ty);

  void *InsertPoint;
  AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);

  if (!PA) {
    // If we didn't find any existing attributes of the same shape then create a
    // new one and insert it.
    PA = new (pImpl->Alloc) TypeAttributeImpl(Kind, Ty);
    pImpl->AttrsSet.InsertNode(PA, InsertPoint);
  }

  // Return the Attribute that we found or created.
  return Attribute(PA);
}

Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
                         const ConstantRange &CR) {
  assert(Attribute::isConstantRangeAttrKind(Kind) &&
         "Not a ConstantRange attribute");
  assert(!CR.isFullSet() && "ConstantRange attribute must not be full");
  LLVMContextImpl *pImpl = Context.pImpl;
  FoldingSetNodeID ID;
  ID.AddInteger(Kind);
  CR.getLower().Profile(ID);
  CR.getUpper().Profile(ID);

  void *InsertPoint;
  AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);

  if (!PA) {
    // If we didn't find any existing attributes of the same shape then create a
    // new one and insert it.
    PA = new (pImpl->ConstantRangeAttributeAlloc.Allocate())
        ConstantRangeAttributeImpl(Kind, CR);
    pImpl->AttrsSet.InsertNode(PA, InsertPoint);
  }

  // Return the Attribute that we found or created.
  return Attribute(PA);
}

Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
                         ArrayRef<ConstantRange> Val) {
  assert(Attribute::isConstantRangeListAttrKind(Kind) &&
         "Not a ConstantRangeList attribute");
  LLVMContextImpl *pImpl = Context.pImpl;
  FoldingSetNodeID ID;
  ID.AddInteger(Kind);
  ID.AddInteger(Val.size());
  for (auto &CR : Val) {
    CR.getLower().Profile(ID);
    CR.getUpper().Profile(ID);
  }

  void *InsertPoint;
  AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);

  if (!PA) {
    // If we didn't find any existing attributes of the same shape then create a
    // new one and insert it.
    // ConstantRangeListAttributeImpl is a dynamically sized class and cannot
    // use SpecificBumpPtrAllocator. Instead, we use normal Alloc for
    // allocation and record the allocated pointer in
    // `ConstantRangeListAttributes`. LLVMContext destructor will call the
    // destructor of the allocated pointer explicitly.
    void *Mem = pImpl->Alloc.Allocate(
        ConstantRangeListAttributeImpl::totalSizeToAlloc(Val),
        alignof(ConstantRangeListAttributeImpl));
    PA = new (Mem) ConstantRangeListAttributeImpl(Kind, Val);
    pImpl->AttrsSet.InsertNode(PA, InsertPoint);
    pImpl->ConstantRangeListAttributes.push_back(
        reinterpret_cast<ConstantRangeListAttributeImpl *>(PA));
  }

  // Return the Attribute that we found or created.
  return Attribute(PA);
}

Attribute Attribute::getWithAlignment(LLVMContext &Context, Align A) {
  assert(A <= llvm::Value::MaximumAlignment && "Alignment too large.");
  return get(Context, Alignment, A.value());
}

Attribute Attribute::getWithStackAlignment(LLVMContext &Context, Align A) {
  assert(A <= 0x100 && "Alignment too large.");
  return get(Context, StackAlignment, A.value());
}

Attribute Attribute::getWithDereferenceableBytes(LLVMContext &Context,
                                                uint64_t Bytes) {
  assert(Bytes && "Bytes must be non-zero.");
  return get(Context, Dereferenceable, Bytes);
}

Attribute Attribute::getWithDereferenceableOrNullBytes(LLVMContext &Context,
                                                       uint64_t Bytes) {
  assert(Bytes && "Bytes must be non-zero.");
  return get(Context, DereferenceableOrNull, Bytes);
}

Attribute Attribute::getWithByValType(LLVMContext &Context, Type *Ty) {
  return get(Context, ByVal, Ty);
}

Attribute Attribute::getWithStructRetType(LLVMContext &Context, Type *Ty) {
  return get(Context, StructRet, Ty);
}

Attribute Attribute::getWithByRefType(LLVMContext &Context, Type *Ty) {
  return get(Context, ByRef, Ty);
}

Attribute Attribute::getWithPreallocatedType(LLVMContext &Context, Type *Ty) {
  return get(Context, Preallocated, Ty);
}

Attribute Attribute::getWithInAllocaType(LLVMContext &Context, Type *Ty) {
  return get(Context, InAlloca, Ty);
}

Attribute Attribute::getWithUWTableKind(LLVMContext &Context,
                                        UWTableKind Kind) {
  return get(Context, UWTable, uint64_t(Kind));
}

Attribute Attribute::getWithMemoryEffects(LLVMContext &Context,
                                          MemoryEffects ME) {
  return get(Context, Memory, ME.toIntValue());
}

Attribute Attribute::getWithNoFPClass(LLVMContext &Context,
                                      FPClassTest ClassMask) {
  return get(Context, NoFPClass, ClassMask);
}

Attribute Attribute::getWithDeadOnReturnInfo(LLVMContext &Context,
                                             DeadOnReturnInfo DI) {
  return get(Context, DeadOnReturn, DI.toIntValue());
}

Attribute Attribute::getWithCaptureInfo(LLVMContext &Context, CaptureInfo CI) {
  return get(Context, Captures, CI.toIntValue());
}

Attribute
Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg,
                                const std::optional<unsigned> &NumElemsArg) {
  assert(!(ElemSizeArg == 0 && NumElemsArg == 0) &&
         "Invalid allocsize arguments -- given allocsize(0, 0)");
  return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
}

Attribute Attribute::getWithAllocKind(LLVMContext &Context, AllocFnKind Kind) {
  return get(Context, AllocKind, static_cast<uint64_t>(Kind));
}

Attribute Attribute::getWithVScaleRangeArgs(LLVMContext &Context,
                                            unsigned MinValue,
                                            unsigned MaxValue) {
  return get(Context, VScaleRange, packVScaleRangeArgs(MinValue, MaxValue));
}

Attribute::AttrKind Attribute::getAttrKindFromName(StringRef AttrName) {
  return StringSwitch<Attribute::AttrKind>(AttrName)
#define GET_ATTR_NAMES
#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME)                                \
  .Case(#DISPLAY_NAME, Attribute::ENUM_NAME)
#include "llvm/IR/Attributes.inc"
      .Default(Attribute::None);
}

StringRef Attribute::getNameFromAttrKind(Attribute::AttrKind AttrKind) {
  switch (AttrKind) {
#define GET_ATTR_NAMES
#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME)                                \
  case Attribute::ENUM_NAME:                                                   \
    return #DISPLAY_NAME;
#include "llvm/IR/Attributes.inc"
  case Attribute::None:
    return "none";
  default:
    llvm_unreachable("invalid Kind");
  }
}

bool Attribute::isExistingAttribute(StringRef Name) {
  return StringSwitch<bool>(Name)
#define GET_ATTR_NAMES
#define ATTRIBUTE_ALL(ENUM_NAME, DISPLAY_NAME) .Case(#DISPLAY_NAME, true)
#include "llvm/IR/Attributes.inc"
      .Default(false);
}

//===----------------------------------------------------------------------===//
// Attribute Accessor Methods
//===----------------------------------------------------------------------===//

bool Attribute::isEnumAttribute() const {
  return pImpl && pImpl->isEnumAttribute();
}

bool Attribute::isIntAttribute() const {
  return pImpl && pImpl->isIntAttribute();
}

bool Attribute::isStringAttribute() const {
  return pImpl && pImpl->isStringAttribute();
}

bool Attribute::isTypeAttribute() const {
  return pImpl && pImpl->isTypeAttribute();
}

bool Attribute::isConstantRangeAttribute() const {
  return pImpl && pImpl->isConstantRangeAttribute();
}

bool Attribute::isConstantRangeListAttribute() const {
  return pImpl && pImpl->isConstantRangeListAttribute();
}

Attribute::AttrKind Attribute::getKindAsEnum() const {
  if (!pImpl) return None;
  assert(hasKindAsEnum() &&
         "Invalid attribute type to get the kind as an enum!");
  return pImpl->getKindAsEnum();
}

uint64_t Attribute::getValueAsInt() const {
  if (!pImpl) return 0;
  assert(isIntAttribute() &&
         "Expected the attribute to be an integer attribute!");
  return pImpl->getValueAsInt();
}

bool Attribute::getValueAsBool() const {
  if (!pImpl) return false;
  assert(isStringAttribute() &&
         "Expected the attribute to be a string attribute!");
  return pImpl->getValueAsBool();
}

StringRef Attribute::getKindAsString() const {
  if (!pImpl) return {};
  assert(isStringAttribute() &&
         "Invalid attribute type to get the kind as a string!");
  return pImpl->getKindAsString();
}

StringRef Attribute::getValueAsString() const {
  if (!pImpl) return {};
  assert(isStringAttribute() &&
         "Invalid attribute type to get the value as a string!");
  return pImpl->getValueAsString();
}

Type *Attribute::getValueAsType() const {
  if (!pImpl) return {};
  assert(isTypeAttribute() &&
         "Invalid attribute type to get the value as a type!");
  return pImpl->getValueAsType();
}

const ConstantRange &Attribute::getValueAsConstantRange() const {
  assert(isConstantRangeAttribute() &&
         "Invalid attribute type to get the value as a ConstantRange!");
  return pImpl->getValueAsConstantRange();
}

ArrayRef<ConstantRange> Attribute::getValueAsConstantRangeList() const {
  assert(isConstantRangeListAttribute() &&
         "Invalid attribute type to get the value as a ConstantRangeList!");
  return pImpl->getValueAsConstantRangeList();
}

bool Attribute::hasAttribute(AttrKind Kind) const {
  return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
}

bool Attribute::hasAttribute(StringRef Kind) const {
  if (!isStringAttribute()) return false;
  return pImpl && pImpl->hasAttribute(Kind);
}

MaybeAlign Attribute::getAlignment() const {
  assert(hasAttribute(Attribute::Alignment) &&
         "Trying to get alignment from non-alignment attribute!");
  return MaybeAlign(pImpl->getValueAsInt());
}

MaybeAlign Attribute::getStackAlignment() const {
  assert(hasAttribute(Attribute::StackAlignment) &&
         "Trying to get alignment from non-alignment attribute!");
  return MaybeAlign(pImpl->getValueAsInt());
}

uint64_t Attribute::getDereferenceableBytes() const {
  assert(hasAttribute(Attribute::Dereferenceable) &&
         "Trying to get dereferenceable bytes from "
         "non-dereferenceable attribute!");
  return pImpl->getValueAsInt();
}

DeadOnReturnInfo Attribute::getDeadOnReturnInfo() const {
  assert(hasAttribute(Attribute::DeadOnReturn) &&
         "Trying to get dead_on_return bytes from"
         "a parameter without such an attribute!");
  return DeadOnReturnInfo::createFromIntValue(pImpl->getValueAsInt());
}

uint64_t Attribute::getDereferenceableOrNullBytes() const {
  assert(hasAttribute(Attribute::DereferenceableOrNull) &&
         "Trying to get dereferenceable bytes from "
         "non-dereferenceable attribute!");
  return pImpl->getValueAsInt();
}

std::pair<unsigned, std::optional<unsigned>>
Attribute::getAllocSizeArgs() const {
  assert(hasAttribute(Attribute::AllocSize) &&
         "Trying to get allocsize args from non-allocsize attribute");
  return unpackAllocSizeArgs(pImpl->getValueAsInt());
}

unsigned Attribute::getVScaleRangeMin() const {
  assert(hasAttribute(Attribute::VScaleRange) &&
         "Trying to get vscale args from non-vscale attribute");
  return unpackVScaleRangeArgs(pImpl->getValueAsInt()).first;
}

std::optional<unsigned> Attribute::getVScaleRangeMax() const {
  assert(hasAttribute(Attribute::VScaleRange) &&
         "Trying to get vscale args from non-vscale attribute");
  return unpackVScaleRangeArgs(pImpl->getValueAsInt()).second;
}

UWTableKind Attribute::getUWTableKind() const {
  assert(hasAttribute(Attribute::UWTable) &&
         "Trying to get unwind table kind from non-uwtable attribute");
  return UWTableKind(pImpl->getValueAsInt());
}

AllocFnKind Attribute::getAllocKind() const {
  assert(hasAttribute(Attribute::AllocKind) &&
         "Trying to get allockind value from non-allockind attribute");
  return AllocFnKind(pImpl->getValueAsInt());
}

MemoryEffects Attribute::getMemoryEffects() const {
  assert(hasAttribute(Attribute::Memory) &&
         "Can only call getMemoryEffects() on memory attribute");
  return MemoryEffects::createFromIntValue(pImpl->getValueAsInt());
}

CaptureInfo Attribute::getCaptureInfo() const {
  assert(hasAttribute(Attribute::Captures) &&
         "Can only call getCaptureInfo() on captures attribute");
  return CaptureInfo::createFromIntValue(pImpl->getValueAsInt());
}

DenormalFPEnv Attribute::getDenormalFPEnv() const {
  return DenormalFPEnv::createFromIntValue(pImpl->getValueAsInt());
}

FPClassTest Attribute::getNoFPClass() const {
  assert(hasAttribute(Attribute::NoFPClass) &&
         "Can only call getNoFPClass() on nofpclass attribute");
  return static_cast<FPClassTest>(pImpl->getValueAsInt());
}

const ConstantRange &Attribute::getRange() const {
  assert(hasAttribute(Attribute::Range) &&
         "Trying to get range args from non-range attribute");
  return pImpl->getValueAsConstantRange();
}

ArrayRef<ConstantRange> Attribute::getInitializes() const {
  assert(hasAttribute(Attribute::Initializes) &&
         "Trying to get initializes attr from non-ConstantRangeList attribute");
  return pImpl->getValueAsConstantRangeList();
}

static const char *getModRefStr(ModRefInfo MR) {
  switch (MR) {
  case ModRefInfo::NoModRef:
    return "none";
  case ModRefInfo::Ref:
    return "read";
  case ModRefInfo::Mod:
    return "write";
  case ModRefInfo::ModRef:
    return "readwrite";
  }
  llvm_unreachable("Invalid ModRefInfo");
}

std::string Attribute::getAsString(bool InAttrGrp) const {
  if (!pImpl) return {};

  if (isEnumAttribute())
    return getNameFromAttrKind(getKindAsEnum()).str();

  if (isTypeAttribute()) {
    std::string Result = getNameFromAttrKind(getKindAsEnum()).str();
    Result += '(';
    raw_string_ostream OS(Result);
    getValueAsType()->print(OS, false, true);
    Result += ')';
    return Result;
  }

  // FIXME: These should be output like this:
  //
  //   align=4
  //   alignstack=8
  //
  if (hasAttribute(Attribute::Alignment))
    return (InAttrGrp ? "align=" + Twine(getValueAsInt())
                      : "align " + Twine(getValueAsInt()))
        .str();

  auto AttrWithBytesToString = [&](const char *Name) {
    return (InAttrGrp ? Name + ("=" + Twine(getValueAsInt()))
                      : Name + ("(" + Twine(getValueAsInt())) + ")")
        .str();
  };

  if (hasAttribute(Attribute::StackAlignment))
    return AttrWithBytesToString("alignstack");

  if (hasAttribute(Attribute::Dereferenceable))
    return AttrWithBytesToString("dereferenceable");

  if (hasAttribute(Attribute::DereferenceableOrNull))
    return AttrWithBytesToString("dereferenceable_or_null");

  if (hasAttribute(Attribute::DeadOnReturn)) {
    uint64_t DeadBytes = getValueAsInt();
    if (DeadBytes == std::numeric_limits<uint64_t>::max())
      return "dead_on_return";
    return AttrWithBytesToString("dead_on_return");
  }

  if (hasAttribute(Attribute::AllocSize)) {
    unsigned ElemSize;
    std::optional<unsigned> NumElems;
    std::tie(ElemSize, NumElems) = getAllocSizeArgs();

    return (NumElems
                ? "allocsize(" + Twine(ElemSize) + "," + Twine(*NumElems) + ")"
                : "allocsize(" + Twine(ElemSize) + ")")
        .str();
  }

  if (hasAttribute(Attribute::VScaleRange)) {
    unsigned MinValue = getVScaleRangeMin();
    std::optional<unsigned> MaxValue = getVScaleRangeMax();
    return ("vscale_range(" + Twine(MinValue) + "," +
            Twine(MaxValue.value_or(0)) + ")")
        .str();
  }

  if (hasAttribute(Attribute::UWTable)) {
    UWTableKind Kind = getUWTableKind();
    assert(Kind != UWTableKind::None && "uwtable attribute should not be none");
    return Kind == UWTableKind::Default ? "uwtable" : "uwtable(sync)";
  }

  if (hasAttribute(Attribute::AllocKind)) {
    AllocFnKind Kind = getAllocKind();
    SmallVector<StringRef> parts;
    if ((Kind & AllocFnKind::Alloc) != AllocFnKind::Unknown)
      parts.push_back("alloc");
    if ((Kind & AllocFnKind::Realloc) != AllocFnKind::Unknown)
      parts.push_back("realloc");
    if ((Kind & AllocFnKind::Free) != AllocFnKind::Unknown)
      parts.push_back("free");
    if ((Kind & AllocFnKind::Uninitialized) != AllocFnKind::Unknown)
      parts.push_back("uninitialized");
    if ((Kind & AllocFnKind::Zeroed) != AllocFnKind::Unknown)
      parts.push_back("zeroed");
    if ((Kind & AllocFnKind::Aligned) != AllocFnKind::Unknown)
      parts.push_back("aligned");
    return ("allockind(\"" +
            Twine(llvm::join(parts.begin(), parts.end(), ",")) + "\")")
        .str();
  }

  if (hasAttribute(Attribute::Memory)) {
    std::string Result;
    raw_string_ostream OS(Result);
    bool First = true;
    OS << "memory(";

    MemoryEffects ME = getMemoryEffects();

    // Print access kind for "other" as the default access kind. This way it
    // will apply to any new location kinds that get split out of "other".
    ModRefInfo OtherMR = ME.getModRef(IRMemLocation::Other);
    if (OtherMR != ModRefInfo::NoModRef || ME.getModRef() == OtherMR) {
      First = false;
      OS << getModRefStr(OtherMR);
    }

    for (auto Loc : MemoryEffects::locations()) {
      ModRefInfo MR = ME.getModRef(Loc);
      if (MR == OtherMR)
        continue;

      if (!First)
        OS << ", ";
      First = false;

      switch (Loc) {
      case IRMemLocation::ArgMem:
        OS << "argmem: ";
        break;
      case IRMemLocation::InaccessibleMem:
        OS << "inaccessiblemem: ";
        break;
      case IRMemLocation::ErrnoMem:
        OS << "errnomem: ";
        break;
      case IRMemLocation::Other:
        llvm_unreachable("This is represented as the default access kind");
      case IRMemLocation::TargetMem0:
        OS << "target_mem0: ";
        break;
      case IRMemLocation::TargetMem1:
        OS << "target_mem1: ";
        break;
      }
      OS << getModRefStr(MR);
    }
    OS << ")";
    return Result;
  }

  if (hasAttribute(Attribute::Captures)) {
    std::string Result;
    raw_string_ostream(Result) << getCaptureInfo();
    return Result;
  }

  if (hasAttribute(Attribute::DenormalFPEnv)) {
    std::string Result = "denormal_fpenv(";
    raw_string_ostream OS(Result);

    struct DenormalFPEnv FPEnv = getDenormalFPEnv();
    FPEnv.print(OS, /*OmitIfSame=*/true);

    OS << ')';
    return Result;
  }

  if (hasAttribute(Attribute::NoFPClass)) {
    std::string Result = "nofpclass";
    raw_string_ostream(Result) << getNoFPClass();
    return Result;
  }

  if (hasAttribute(Attribute::Range)) {
    std::string Result;
    raw_string_ostream OS(Result);
    const ConstantRange &CR = getValueAsConstantRange();
    OS << "range(";
    OS << "i" << CR.getBitWidth() << " ";
    OS << CR.getLower() << ", " << CR.getUpper();
    OS << ")";
    return Result;
  }

  if (hasAttribute(Attribute::Initializes)) {
    std::string Result;
    raw_string_ostream OS(Result);
    ConstantRangeList CRL = getInitializes();
    OS << "initializes(";
    CRL.print(OS);
    OS << ")";
    return Result;
  }

  // Convert target-dependent attributes to strings of the form:
  //
  //   "kind"
  //   "kind" = "value"
  //
  if (isStringAttribute()) {
    std::string Result;
    {
      raw_string_ostream OS(Result);
      OS << '"' << getKindAsString() << '"';

      // Since some attribute strings contain special characters that cannot be
      // printable, those have to be escaped to make the attribute value
      // printable as is.  e.g. "\01__gnu_mcount_nc"
      const auto &AttrVal = pImpl->getValueAsString();
      if (!AttrVal.empty()) {
        OS << "=\"";
        printEscapedString(AttrVal, OS);
        OS << "\"";
      }
    }
    return Result;
  }

  llvm_unreachable("Unknown attribute");
}

bool Attribute::hasParentContext(LLVMContext &C) const {
  assert(isValid() && "invalid Attribute doesn't refer to any context");
  FoldingSetNodeID ID;
  pImpl->Profile(ID);
  void *Unused;
  return C.pImpl->AttrsSet.FindNodeOrInsertPos(ID, Unused) == pImpl;
}

int Attribute::cmpKind(Attribute A) const {
  if (!pImpl && !A.pImpl)
    return 0;
  if (!pImpl)
    return 1;
  if (!A.pImpl)
    return -1;
  return pImpl->cmp(*A.pImpl, /*KindOnly=*/true);
}

bool Attribute::operator<(Attribute A) const {
  if (!pImpl && !A.pImpl) return false;
  if (!pImpl) return true;
  if (!A.pImpl) return false;
  return *pImpl < *A.pImpl;
}

void Attribute::Profile(FoldingSetNodeID &ID) const {
  ID.AddPointer(pImpl);
}

enum AttributeProperty {
  FnAttr = (1 << 0),
  ParamAttr = (1 << 1),
  RetAttr = (1 << 2),
  IntersectPreserve = (0 << 3),
  IntersectAnd = (1 << 3),
  IntersectMin = (2 << 3),
  IntersectCustom = (3 << 3),
  IntersectPropertyMask = (3 << 3),
};

#define GET_ATTR_PROP_TABLE
#include "llvm/IR/Attributes.inc"

static unsigned getAttributeProperties(Attribute::AttrKind Kind) {
  unsigned Index = Kind - 1;
  assert(Index < std::size(AttrPropTable) && "Invalid attribute kind");
  return AttrPropTable[Index];
}

static bool hasAttributeProperty(Attribute::AttrKind Kind,
                                 AttributeProperty Prop) {
  return getAttributeProperties(Kind) & Prop;
}

bool Attribute::canUseAsFnAttr(AttrKind Kind) {
  return hasAttributeProperty(Kind, AttributeProperty::FnAttr);
}

bool Attribute::canUseAsParamAttr(AttrKind Kind) {
  return hasAttributeProperty(Kind, AttributeProperty::ParamAttr);
}

bool Attribute::canUseAsRetAttr(AttrKind Kind) {
  return hasAttributeProperty(Kind, AttributeProperty::RetAttr);
}

static bool hasIntersectProperty(Attribute::AttrKind Kind,
                                 AttributeProperty Prop) {
  assert((Prop == AttributeProperty::IntersectPreserve ||
          Prop == AttributeProperty::IntersectAnd ||
          Prop == AttributeProperty::IntersectMin ||
          Prop == AttributeProperty::IntersectCustom) &&
         "Unknown intersect property");
  return (getAttributeProperties(Kind) &
          AttributeProperty::IntersectPropertyMask) == Prop;
}

bool Attribute::intersectMustPreserve(AttrKind Kind) {
  return hasIntersectProperty(Kind, AttributeProperty::IntersectPreserve);
}
bool Attribute::intersectWithAnd(AttrKind Kind) {
  return hasIntersectProperty(Kind, AttributeProperty::IntersectAnd);
}
bool Attribute::intersectWithMin(AttrKind Kind) {
  return hasIntersectProperty(Kind, AttributeProperty::IntersectMin);
}
bool Attribute::intersectWithCustom(AttrKind Kind) {
  return hasIntersectProperty(Kind, AttributeProperty::IntersectCustom);
}

//===----------------------------------------------------------------------===//
// AttributeImpl Definition
//===----------------------------------------------------------------------===//

bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
  if (isStringAttribute()) return false;
  return getKindAsEnum() == A;
}

bool AttributeImpl::hasAttribute(StringRef Kind) const {
  if (!isStringAttribute()) return false;
  return getKindAsString() == Kind;
}

Attribute::AttrKind AttributeImpl::getKindAsEnum() const {
  assert(isEnumAttribute() || isIntAttribute() || isTypeAttribute() ||
         isConstantRangeAttribute() || isConstantRangeListAttribute());
  return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
}

uint64_t AttributeImpl::getValueAsInt() const {
  assert(isIntAttribute());
  return static_cast<const IntAttributeImpl *>(this)->getValue();
}

bool AttributeImpl::getValueAsBool() const {
  assert(getValueAsString().empty() || getValueAsString() == "false" || getValueAsString() == "true");
  return getValueAsString() == "true";
}

StringRef AttributeImpl::getKindAsString() const {
  assert(isStringAttribute());
  return static_cast<const StringAttributeImpl *>(this)->getStringKind();
}

StringRef AttributeImpl::getValueAsString() const {
  assert(isStringAttribute());
  return static_cast<const StringAttributeImpl *>(this)->getStringValue();
}

Type *AttributeImpl::getValueAsType() const {
  assert(isTypeAttribute());
  return static_cast<const TypeAttributeImpl *>(this)->getTypeValue();
}

const ConstantRange &AttributeImpl::getValueAsConstantRange() const {
  assert(isConstantRangeAttribute());
  return static_cast<const ConstantRangeAttributeImpl *>(this)
      ->getConstantRangeValue();
}

ArrayRef<ConstantRange> AttributeImpl::getValueAsConstantRangeList() const {
  assert(isConstantRangeListAttribute());
  return static_cast<const ConstantRangeListAttributeImpl *>(this)
      ->getConstantRangeListValue();
}

int AttributeImpl::cmp(const AttributeImpl &AI, bool KindOnly) const {
  if (this == &AI)
    return 0;

  // This sorts the attributes with Attribute::AttrKinds coming first (sorted
  // relative to their enum value) and then strings.
  if (!isStringAttribute()) {
    if (AI.isStringAttribute())
      return -1;

    if (getKindAsEnum() != AI.getKindAsEnum())
      return getKindAsEnum() < AI.getKindAsEnum() ? -1 : 1;
    else if (KindOnly)
      return 0;

    assert(!AI.isEnumAttribute() && "Non-unique attribute");
    assert(!AI.isTypeAttribute() && "Comparison of types would be unstable");
    assert(!AI.isConstantRangeAttribute() && "Unclear how to compare ranges");
    assert(!AI.isConstantRangeListAttribute() &&
           "Unclear how to compare range list");
    // TODO: Is this actually needed?
    assert(AI.isIntAttribute() && "Only possibility left");
    if (getValueAsInt() < AI.getValueAsInt())
      return -1;
    return getValueAsInt() == AI.getValueAsInt() ? 0 : 1;
  }
  if (!AI.isStringAttribute())
    return 1;
  if (KindOnly)
    return getKindAsString().compare(AI.getKindAsString());
  if (getKindAsString() == AI.getKindAsString())
    return getValueAsString().compare(AI.getValueAsString());
  return getKindAsString().compare(AI.getKindAsString());
}

bool AttributeImpl::operator<(const AttributeImpl &AI) const {
  return cmp(AI, /*KindOnly=*/false) < 0;
}

//===----------------------------------------------------------------------===//
// AttributeSet Definition
//===----------------------------------------------------------------------===//

AttributeSet AttributeSet::get(LLVMContext &C, const AttrBuilder &B) {
  return AttributeSet(AttributeSetNode::get(C, B));
}

AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<Attribute> Attrs) {
  return AttributeSet(AttributeSetNode::get(C, Attrs));
}

AttributeSet AttributeSet::addAttribute(LLVMContext &C,
                                        Attribute::AttrKind Kind) const {
  if (hasAttribute(Kind)) return *this;
  AttrBuilder B(C);
  B.addAttribute(Kind);
  return addAttributes(C, AttributeSet::get(C, B));
}

AttributeSet AttributeSet::addAttribute(LLVMContext &C, StringRef Kind,
                                        StringRef Value) const {
  AttrBuilder B(C);
  B.addAttribute(Kind, Value);
  return addAttributes(C, AttributeSet::get(C, B));
}

AttributeSet AttributeSet::addAttributes(LLVMContext &C,
                                         const AttributeSet AS) const {
  if (!hasAttributes())
    return AS;

  if (!AS.hasAttributes())
    return *this;

  AttrBuilder B(C, *this);
  B.merge(AttrBuilder(C, AS));
  return get(C, B);
}

AttributeSet AttributeSet::addAttributes(LLVMContext &C,
                                         const AttrBuilder &B) const {
  if (!hasAttributes())
    return get(C, B);

  if (!B.hasAttributes())
    return *this;

  AttrBuilder Merged(C, *this);
  Merged.merge(B);
  return get(C, Merged);
}

AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
                                             Attribute::AttrKind Kind) const {
  if (!hasAttribute(Kind)) return *this;
  AttrBuilder B(C, *this);
  B.removeAttribute(Kind);
  return get(C, B);
}

AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
                                             StringRef Kind) const {
  if (!hasAttribute(Kind)) return *this;
  AttrBuilder B(C, *this);
  B.removeAttribute(Kind);
  return get(C, B);
}

AttributeSet AttributeSet::removeAttributes(LLVMContext &C,
                                            const AttributeMask &Attrs) const {
  AttrBuilder B(C, *this);
  // If there is nothing to remove, directly return the original set.
  if (!B.overlaps(Attrs))
    return *this;

  B.remove(Attrs);
  return get(C, B);
}

std::optional<AttributeSet>
AttributeSet::intersectWith(LLVMContext &C, AttributeSet Other) const {
  if (*this == Other)
    return *this;

  AttrBuilder Intersected(C);
  // Iterate over both attr sets at once.
  auto ItBegin0 = begin();
  auto ItEnd0 = end();
  auto ItBegin1 = Other.begin();
  auto ItEnd1 = Other.end();

  while (ItBegin0 != ItEnd0 || ItBegin1 != ItEnd1) {
    // Loop through all attributes in both this and Other in sorted order. If
    // the attribute is only present in one of the sets, it will be set in
    // Attr0. If it is present in both sets both Attr0 and Attr1 will be set.
    Attribute Attr0, Attr1;
    if (ItBegin1 == ItEnd1)
      Attr0 = *ItBegin0++;
    else if (ItBegin0 == ItEnd0)
      Attr0 = *ItBegin1++;
    else {
      int Cmp = ItBegin0->cmpKind(*ItBegin1);
      if (Cmp == 0) {
        Attr0 = *ItBegin0++;
        Attr1 = *ItBegin1++;
      } else if (Cmp < 0)
        Attr0 = *ItBegin0++;
      else
        Attr0 = *ItBegin1++;
    }
    assert(Attr0.isValid() && "Iteration should always yield a valid attr");

    auto IntersectEq = [&]() {
      if (!Attr1.isValid())
        return false;
      if (Attr0 != Attr1)
        return false;
      Intersected.addAttribute(Attr0);
      return true;
    };

    // Non-enum assume we must preserve. Handle early so we can unconditionally
    // use Kind below.
    if (!Attr0.hasKindAsEnum()) {
      if (!IntersectEq())
        return std::nullopt;
      continue;
    }

    Attribute::AttrKind Kind = Attr0.getKindAsEnum();
    // If we don't have both attributes, then fail if the attribute is
    // must-preserve or drop it otherwise.
    if (!Attr1.isValid()) {
      if (Attribute::intersectMustPreserve(Kind))
        return std::nullopt;
      continue;
    }

    // We have both attributes so apply the intersection rule.
    assert(Attr1.hasKindAsEnum() && Kind == Attr1.getKindAsEnum() &&
           "Iterator picked up two different attributes in the same iteration");

    // Attribute we can intersect with "and"
    if (Attribute::intersectWithAnd(Kind)) {
      assert(Attribute::isEnumAttrKind(Kind) &&
             "Invalid attr type of intersectAnd");
      Intersected.addAttribute(Kind);
      continue;
    }

    // Attribute we can intersect with "min"
    if (Attribute::intersectWithMin(Kind)) {
      assert(Attribute::isIntAttrKind(Kind) &&
             "Invalid attr type of intersectMin");
      uint64_t NewVal = std::min(Attr0.getValueAsInt(), Attr1.getValueAsInt());
      Intersected.addRawIntAttr(Kind, NewVal);
      continue;
    }
    // Attribute we can intersect but need a custom rule for.
    if (Attribute::intersectWithCustom(Kind)) {
      switch (Kind) {
      case Attribute::Alignment:
        // If `byval` is present, alignment become must-preserve. This is
        // handled below if we have `byval`.
        Intersected.addAlignmentAttr(
            std::min(Attr0.getAlignment().valueOrOne(),
                     Attr1.getAlignment().valueOrOne()));
        break;
      case Attribute::Memory:
        Intersected.addMemoryAttr(Attr0.getMemoryEffects() |
                                  Attr1.getMemoryEffects());
        break;
      case Attribute::Captures:
        Intersected.addCapturesAttr(Attr0.getCaptureInfo() |
                                    Attr1.getCaptureInfo());
        break;
      case Attribute::NoFPClass:
        Intersected.addNoFPClassAttr(Attr0.getNoFPClass() &
                                     Attr1.getNoFPClass());
        break;
      case Attribute::Range: {
        ConstantRange Range0 = Attr0.getRange();
        ConstantRange Range1 = Attr1.getRange();
        ConstantRange NewRange = Range0.unionWith(Range1);
        if (!NewRange.isFullSet())
          Intersected.addRangeAttr(NewRange);
      } break;
      default:
        llvm_unreachable("Unknown attribute with custom intersection rule");
      }
      continue;
    }

    // Attributes with no intersection rule. Only intersect if they are equal.
    // Otherwise fail.
    if (!IntersectEq())
      return std::nullopt;

    // Special handling of `byval`. `byval` essentially turns align attr into
    // must-preserve
    if (Kind == Attribute::ByVal &&
        getAttribute(Attribute::Alignment) !=
            Other.getAttribute(Attribute::Alignment))
      return std::nullopt;
  }

  return get(C, Intersected);
}

unsigned AttributeSet::getNumAttributes() const {
  return SetNode ? SetNode->getNumAttributes() : 0;
}

bool AttributeSet::hasAttribute(Attribute::AttrKind Kind) const {
  return SetNode ? SetNode->hasAttribute(Kind) : false;
}

bool AttributeSet::hasAttribute(StringRef Kind) const {
  return SetNode ? SetNode->hasAttribute(Kind) : false;
}

Attribute AttributeSet::getAttribute(Attribute::AttrKind Kind) const {
  return SetNode ? SetNode->getAttribute(Kind) : Attribute();
}

Attribute AttributeSet::getAttribute(StringRef Kind) const {
  return SetNode ? SetNode->getAttribute(Kind) : Attribute();
}

MaybeAlign AttributeSet::getAlignment() const {
  return SetNode ? SetNode->getAlignment() : std::nullopt;
}

MaybeAlign AttributeSet::getStackAlignment() const {
  return SetNode ? SetNode->getStackAlignment() : std::nullopt;
}

uint64_t AttributeSet::getDereferenceableBytes() const {
  return SetNode ? SetNode->getDereferenceableBytes() : 0;
}

DeadOnReturnInfo AttributeSet::getDeadOnReturnInfo() const {
  return SetNode ? SetNode->getDeadOnReturnInfo() : DeadOnReturnInfo(0);
}

uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
  return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
}

Type *AttributeSet::getByRefType() const {
  return SetNode ? SetNode->getAttributeType(Attribute::ByRef) : nullptr;
}

Type *AttributeSet::getByValType() const {
  return SetNode ? SetNode->getAttributeType(Attribute::ByVal) : nullptr;
}

Type *AttributeSet::getStructRetType() const {
  return SetNode ? SetNode->getAttributeType(Attribute::StructRet) : nullptr;
}

Type *AttributeSet::getPreallocatedType() const {
  return SetNode ? SetNode->getAttributeType(Attribute::Preallocated) : nullptr;
}

Type *AttributeSet::getInAllocaType() const {
  return SetNode ? SetNode->getAttributeType(Attribute::InAlloca) : nullptr;
}

Type *AttributeSet::getElementType() const {
  return SetNode ? SetNode->getAttributeType(Attribute::ElementType) : nullptr;
}

std::optional<std::pair<unsigned, std::optional<unsigned>>>
AttributeSet::getAllocSizeArgs() const {
  if (SetNode)
    return SetNode->getAllocSizeArgs();
  return std::nullopt;
}

unsigned AttributeSet::getVScaleRangeMin() const {
  return SetNode ? SetNode->getVScaleRangeMin() : 1;
}

std::optional<unsigned> AttributeSet::getVScaleRangeMax() const {
  return SetNode ? SetNode->getVScaleRangeMax() : std::nullopt;
}

UWTableKind AttributeSet::getUWTableKind() const {
  return SetNode ? SetNode->getUWTableKind() : UWTableKind::None;
}

AllocFnKind AttributeSet::getAllocKind() const {
  return SetNode ? SetNode->getAllocKind() : AllocFnKind::Unknown;
}

MemoryEffects AttributeSet::getMemoryEffects() const {
  return SetNode ? SetNode->getMemoryEffects() : MemoryEffects::unknown();
}

CaptureInfo AttributeSet::getCaptureInfo() const {
  return SetNode ? SetNode->getCaptureInfo() : CaptureInfo::all();
}

FPClassTest AttributeSet::getNoFPClass() const {
  return SetNode ? SetNode->getNoFPClass() : fcNone;
}

std::string AttributeSet::getAsString(bool InAttrGrp) const {
  return SetNode ? SetNode->getAsString(InAttrGrp) : "";
}

bool AttributeSet::hasParentContext(LLVMContext &C) const {
  assert(hasAttributes() && "empty AttributeSet doesn't refer to any context");
  FoldingSetNodeID ID;
  SetNode->Profile(ID);
  void *Unused;
  return C.pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, Unused) == SetNode;
}

AttributeSet::iterator AttributeSet::begin() const {
  return SetNode ? SetNode->begin() : nullptr;
}

AttributeSet::iterator AttributeSet::end() const {
  return SetNode ? SetNode->end() : nullptr;
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void AttributeSet::dump() const {
  dbgs() << "AS =\n";
    dbgs() << "  { ";
    dbgs() << getAsString(true) << " }\n";
}
#endif

//===----------------------------------------------------------------------===//
// AttributeSetNode Definition
//===----------------------------------------------------------------------===//

AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
    : NumAttrs(Attrs.size()) {
  // There's memory after the node where we can store the entries in.
  llvm::copy(Attrs, getTrailingObjects());

  for (const auto &I : *this) {
    if (I.isStringAttribute())
      StringAttrs.insert({ I.getKindAsString(), I });
    else
      AvailableAttrs.addAttribute(I.getKindAsEnum());
  }
}

AttributeSetNode *AttributeSetNode::get(LLVMContext &C,
                                        ArrayRef<Attribute> Attrs) {
  SmallVector<Attribute, 8> SortedAttrs(Attrs);
  llvm::sort(SortedAttrs);
  return getSorted(C, SortedAttrs);
}

AttributeSetNode *AttributeSetNode::getSorted(LLVMContext &C,
                                              ArrayRef<Attribute> SortedAttrs) {
  if (SortedAttrs.empty())
    return nullptr;

  // Build a key to look up the existing attributes.
  LLVMContextImpl *pImpl = C.pImpl;
  FoldingSetNodeID ID;

  assert(llvm::is_sorted(SortedAttrs) && "Expected sorted attributes!");
  for (const auto &Attr : SortedAttrs)
    Attr.Profile(ID);

  void *InsertPoint;
  AttributeSetNode *PA =
    pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);

  // If we didn't find any existing attributes of the same shape then create a
  // new one and insert it.
  if (!PA) {
    // Coallocate entries after the AttributeSetNode itself.
    void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
    PA = new (Mem) AttributeSetNode(SortedAttrs);
    pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
  }

  // Return the AttributeSetNode that we found or created.
  return PA;
}

AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) {
  return getSorted(C, B.attrs());
}

bool AttributeSetNode::hasAttribute(StringRef Kind) const {
  return StringAttrs.count(Kind);
}

std::optional<Attribute>
AttributeSetNode::findEnumAttribute(Attribute::AttrKind Kind) const {
  // Do a quick presence check.
  if (!hasAttribute(Kind))
    return std::nullopt;

  // Attributes in a set are sorted by enum value, followed by string
  // attributes. Binary search the one we want.
  const Attribute *I =
      std::lower_bound(begin(), end() - StringAttrs.size(), Kind,
                       [](Attribute A, Attribute::AttrKind Kind) {
                         return A.getKindAsEnum() < Kind;
                       });
  assert(I != end() && I->hasAttribute(Kind) && "Presence check failed?");
  return *I;
}

Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
  if (auto A = findEnumAttribute(Kind))
    return *A;
  return {};
}

Attribute AttributeSetNode::getAttribute(StringRef Kind) const {
  return StringAttrs.lookup(Kind);
}

MaybeAlign AttributeSetNode::getAlignment() const {
  if (auto A = findEnumAttribute(Attribute::Alignment))
    return A->getAlignment();
  return std::nullopt;
}

MaybeAlign AttributeSetNode::getStackAlignment() const {
  if (auto A = findEnumAttribute(Attribute::StackAlignment))
    return A->getStackAlignment();
  return std::nullopt;
}

Type *AttributeSetNode::getAttributeType(Attribute::AttrKind Kind) const {
  if (auto A = findEnumAttribute(Kind))
    return A->getValueAsType();
  return nullptr;
}

uint64_t AttributeSetNode::getDereferenceableBytes() const {
  if (auto A = findEnumAttribute(Attribute::Dereferenceable))
    return A->getDereferenceableBytes();
  return 0;
}

DeadOnReturnInfo AttributeSetNode::getDeadOnReturnInfo() const {
  if (auto A = findEnumAttribute(Attribute::DeadOnReturn))
    return A->getDeadOnReturnInfo();
  return 0;
}

uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
  if (auto A = findEnumAttribute(Attribute::DereferenceableOrNull))
    return A->getDereferenceableOrNullBytes();
  return 0;
}

std::optional<std::pair<unsigned, std::optional<unsigned>>>
AttributeSetNode::getAllocSizeArgs() const {
  if (auto A = findEnumAttribute(Attribute::AllocSize))
    return A->getAllocSizeArgs();
  return std::nullopt;
}

unsigned AttributeSetNode::getVScaleRangeMin() const {
  if (auto A = findEnumAttribute(Attribute::VScaleRange))
    return A->getVScaleRangeMin();
  return 1;
}

std::optional<unsigned> AttributeSetNode::getVScaleRangeMax() const {
  if (auto A = findEnumAttribute(Attribute::VScaleRange))
    return A->getVScaleRangeMax();
  return std::nullopt;
}

UWTableKind AttributeSetNode::getUWTableKind() const {
  if (auto A = findEnumAttribute(Attribute::UWTable))
    return A->getUWTableKind();
  return UWTableKind::None;
}

AllocFnKind AttributeSetNode::getAllocKind() const {
  if (auto A = findEnumAttribute(Attribute::AllocKind))
    return A->getAllocKind();
  return AllocFnKind::Unknown;
}

MemoryEffects AttributeSetNode::getMemoryEffects() const {
  if (auto A = findEnumAttribute(Attribute::Memory))
    return A->getMemoryEffects();
  return MemoryEffects::unknown();
}

CaptureInfo AttributeSetNode::getCaptureInfo() const {
  if (auto A = findEnumAttribute(Attribute::Captures))
    return A->getCaptureInfo();
  return CaptureInfo::all();
}

FPClassTest AttributeSetNode::getNoFPClass() const {
  if (auto A = findEnumAttribute(Attribute::NoFPClass))
    return A->getNoFPClass();
  return fcNone;
}

std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
  std::string Str;
  for (iterator I = begin(), E = end(); I != E; ++I) {
    if (I != begin())
      Str += ' ';
    Str += I->getAsString(InAttrGrp);
  }
  return Str;
}

//===----------------------------------------------------------------------===//
// AttributeListImpl Definition
//===----------------------------------------------------------------------===//

/// Map from AttributeList index to the internal array index. Adding one happens
/// to work, because -1 wraps around to 0.
static unsigned attrIdxToArrayIdx(unsigned Index) {
  return Index + 1;
}

AttributeListImpl::AttributeListImpl(ArrayRef<AttributeSet> Sets)
    : NumAttrSets(Sets.size()) {
  assert(!Sets.empty() && "pointless AttributeListImpl");

  // There's memory after the node where we can store the entries in.
  llvm::copy(Sets, getTrailingObjects());

  // Initialize AvailableFunctionAttrs and AvailableSomewhereAttrs
  // summary bitsets.
  for (const auto &I : Sets[attrIdxToArrayIdx(AttributeList::FunctionIndex)])
    if (!I.isStringAttribute())
      AvailableFunctionAttrs.addAttribute(I.getKindAsEnum());

  for (const auto &Set : Sets)
    for (const auto &I : Set)
      if (!I.isStringAttribute())
        AvailableSomewhereAttrs.addAttribute(I.getKindAsEnum());
}

void AttributeListImpl::Profile(FoldingSetNodeID &ID) const {
  Profile(ID, ArrayRef(begin(), end()));
}

void AttributeListImpl::Profile(FoldingSetNodeID &ID,
                                ArrayRef<AttributeSet> Sets) {
  for (const auto &Set : Sets)
    ID.AddPointer(Set.SetNode);
}

bool AttributeListImpl::hasAttrSomewhere(Attribute::AttrKind Kind,
                                        unsigned *Index) const {
  if (!AvailableSomewhereAttrs.hasAttribute(Kind))
    return false;

  if (Index) {
    for (unsigned I = 0, E = NumAttrSets; I != E; ++I) {
      if (begin()[I].hasAttribute(Kind)) {
        *Index = I - 1;
        break;
      }
    }
  }

  return true;
}


#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void AttributeListImpl::dump() const {
  AttributeList(const_cast<AttributeListImpl *>(this)).dump();
}
#endif

//===----------------------------------------------------------------------===//
// AttributeList Construction and Mutation Methods
//===----------------------------------------------------------------------===//

AttributeList AttributeList::getImpl(LLVMContext &C,
                                     ArrayRef<AttributeSet> AttrSets) {
  assert(!AttrSets.empty() && "pointless AttributeListImpl");

  LLVMContextImpl *pImpl = C.pImpl;
  FoldingSetNodeID ID;
  AttributeListImpl::Profile(ID, AttrSets);

  void *InsertPoint;
  AttributeListImpl *PA =
      pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);

  // If we didn't find any existing attributes of the same shape then
  // create a new one and insert it.
  if (!PA) {
    // Coallocate entries after the AttributeListImpl itself.
    void *Mem = pImpl->Alloc.Allocate(
        AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()),
        alignof(AttributeListImpl));
    PA = new (Mem) AttributeListImpl(AttrSets);
    pImpl->AttrsLists.InsertNode(PA, InsertPoint);
  }

  // Return the AttributesList that we found or created.
  return AttributeList(PA);
}

AttributeList
AttributeList::get(LLVMContext &C,
                   ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
  // If there are no attributes then return a null AttributesList pointer.
  if (Attrs.empty())
    return {};

  assert(llvm::is_sorted(Attrs, llvm::less_first()) &&
         "Misordered Attributes list!");
  assert(llvm::all_of(Attrs,
                      [](const std::pair<unsigned, Attribute> &Pair) {
                        return Pair.second.isValid();
                      }) &&
         "Pointless attribute!");

  // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
  // list.
  SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairVec;
  for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
         E = Attrs.end(); I != E; ) {
    unsigned Index = I->first;
    SmallVector<Attribute, 4> AttrVec;
    while (I != E && I->first == Index) {
      AttrVec.push_back(I->second);
      ++I;
    }

    AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
  }

  return get(C, AttrPairVec);
}

AttributeList
AttributeList::get(LLVMContext &C,
                   ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
  // If there are no attributes then return a null AttributesList pointer.
  if (Attrs.empty())
    return {};

  assert(llvm::is_sorted(Attrs, llvm::less_first()) &&
         "Misordered Attributes list!");
  assert(llvm::none_of(Attrs,
                       [](const std::pair<unsigned, AttributeSet> &Pair) {
                         return !Pair.second.hasAttributes();
                       }) &&
         "Pointless attribute!");

  unsigned MaxIndex = Attrs.back().first;
  // If the MaxIndex is FunctionIndex and there are other indices in front
  // of it, we need to use the largest of those to get the right size.
  if (MaxIndex == FunctionIndex && Attrs.size() > 1)
    MaxIndex = Attrs[Attrs.size() - 2].first;

  SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1);
  for (const auto &Pair : Attrs)
    AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second;

  return getImpl(C, AttrVec);
}

AttributeList AttributeList::get(LLVMContext &C, AttributeSet FnAttrs,
                                 AttributeSet RetAttrs,
                                 ArrayRef<AttributeSet> ArgAttrs) {
  // Scan from the end to find the last argument with attributes.  Most
  // arguments don't have attributes, so it's nice if we can have fewer unique
  // AttributeListImpls by dropping empty attribute sets at the end of the list.
  unsigned NumSets = 0;
  for (size_t I = ArgAttrs.size(); I != 0; --I) {
    if (ArgAttrs[I - 1].hasAttributes()) {
      NumSets = I + 2;
      break;
    }
  }
  if (NumSets == 0) {
    // Check function and return attributes if we didn't have argument
    // attributes.
    if (RetAttrs.hasAttributes())
      NumSets = 2;
    else if (FnAttrs.hasAttributes())
      NumSets = 1;
  }

  // If all attribute sets were empty, we can use the empty attribute list.
  if (NumSets == 0)
    return {};

  SmallVector<AttributeSet, 8> AttrSets;
  AttrSets.reserve(NumSets);
  // If we have any attributes, we always have function attributes.
  AttrSets.push_back(FnAttrs);
  if (NumSets > 1)
    AttrSets.push_back(RetAttrs);
  if (NumSets > 2) {
    // Drop the empty argument attribute sets at the end.
    ArgAttrs = ArgAttrs.take_front(NumSets - 2);
    llvm::append_range(AttrSets, ArgAttrs);
  }

  return getImpl(C, AttrSets);
}

AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
                                 AttributeSet Attrs) {
  if (!Attrs.hasAttributes())
    return {};
  Index = attrIdxToArrayIdx(Index);
  SmallVector<AttributeSet, 8> AttrSets(Index + 1);
  AttrSets[Index] = Attrs;
  return getImpl(C, AttrSets);
}

AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
                                 const AttrBuilder &B) {
  return get(C, Index, AttributeSet::get(C, B));
}

AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
                                 ArrayRef<Attribute::AttrKind> Kinds) {
  SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
  for (const auto K : Kinds)
    Attrs.emplace_back(Index, Attribute::get(C, K));
  return get(C, Attrs);
}

AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
                                 ArrayRef<Attribute::AttrKind> Kinds,
                                 ArrayRef<uint64_t> Values) {
  assert(Kinds.size() == Values.size() && "Mismatched attribute values.");
  SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
  auto VI = Values.begin();
  for (const auto K : Kinds)
    Attrs.emplace_back(Index, Attribute::get(C, K, *VI++));
  return get(C, Attrs);
}

AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
                                 ArrayRef<StringRef> Kinds) {
  SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
  for (const auto &K : Kinds)
    Attrs.emplace_back(Index, Attribute::get(C, K));
  return get(C, Attrs);
}

AttributeList AttributeList::get(LLVMContext &C,
                                 ArrayRef<AttributeList> Attrs) {
  if (Attrs.empty())
    return {};
  if (Attrs.size() == 1)
    return Attrs[0];

  unsigned MaxSize = 0;
  for (const auto &List : Attrs)
    MaxSize = std::max(MaxSize, List.getNumAttrSets());

  // If every list was empty, there is no point in merging the lists.
  if (MaxSize == 0)
    return {};

  SmallVector<AttributeSet, 8> NewAttrSets(MaxSize);
  for (unsigned I = 0; I < MaxSize; ++I) {
    AttrBuilder CurBuilder(C);
    for (const auto &List : Attrs)
      CurBuilder.merge(AttrBuilder(C, List.getAttributes(I - 1)));
    NewAttrSets[I] = AttributeSet::get(C, CurBuilder);
  }

  return getImpl(C, NewAttrSets);
}

AttributeList
AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index,
                                   Attribute::AttrKind Kind) const {
  AttributeSet Attrs = getAttributes(Index);
  if (Attrs.hasAttribute(Kind))
    return *this;
  // TODO: Insert at correct position and avoid sort.
  SmallVector<Attribute, 8> NewAttrs(Attrs.begin(), Attrs.end());
  NewAttrs.push_back(Attribute::get(C, Kind));
  return setAttributesAtIndex(C, Index, AttributeSet::get(C, NewAttrs));
}

AttributeList AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index,
                                                 StringRef Kind,
                                                 StringRef Value) const {
  AttrBuilder B(C);
  B.addAttribute(Kind, Value);
  return addAttributesAtIndex(C, Index, B);
}

AttributeList AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index,
                                                 Attribute A) const {
  AttrBuilder B(C);
  B.addAttribute(A);
  return addAttributesAtIndex(C, Index, B);
}

AttributeList AttributeList::setAttributesAtIndex(LLVMContext &C,
                                                  unsigned Index,
                                                  AttributeSet Attrs) const {
  Index = attrIdxToArrayIdx(Index);
  SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
  if (Index >= AttrSets.size())
    AttrSets.resize(Index + 1);
  AttrSets[Index] = Attrs;

  // Remove trailing empty attribute sets.
  while (!AttrSets.empty() && !AttrSets.back().hasAttributes())
    AttrSets.pop_back();
  if (AttrSets.empty())
    return {};
  return AttributeList::getImpl(C, AttrSets);
}

AttributeList AttributeList::addAttributesAtIndex(LLVMContext &C,
                                                  unsigned Index,
                                                  const AttrBuilder &B) const {
  if (!B.hasAttributes())
    return *this;

  if (!pImpl)
    return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}});

  AttrBuilder Merged(C, getAttributes(Index));
  Merged.merge(B);
  return setAttributesAtIndex(C, Index, AttributeSet::get(C, Merged));
}

AttributeList AttributeList::addParamAttribute(LLVMContext &C,
                                               ArrayRef<unsigned> ArgNos,
                                               Attribute A) const {
  assert(llvm::is_sorted(ArgNos));

  SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
  unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex);
  if (MaxIndex >= AttrSets.size())
    AttrSets.resize(MaxIndex + 1);

  for (unsigned ArgNo : ArgNos) {
    unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex);
    AttrBuilder B(C, AttrSets[Index]);
    B.addAttribute(A);
    AttrSets[Index] = AttributeSet::get(C, B);
  }

  return getImpl(C, AttrSets);
}

AttributeList
AttributeList::removeAttributeAtIndex(LLVMContext &C, unsigned Index,
                                      Attribute::AttrKind Kind) const {
  AttributeSet Attrs = getAttributes(Index);
  AttributeSet NewAttrs = Attrs.removeAttribute(C, Kind);
  if (Attrs == NewAttrs)
    return *this;
  return setAttributesAtIndex(C, Index, NewAttrs);
}

AttributeList AttributeList::removeAttributeAtIndex(LLVMContext &C,
                                                    unsigned Index,
                                                    StringRef Kind) const {
  AttributeSet Attrs = getAttributes(Index);
  AttributeSet NewAttrs = Attrs.removeAttribute(C, Kind);
  if (Attrs == NewAttrs)
    return *this;
  return setAttributesAtIndex(C, Index, NewAttrs);
}

AttributeList AttributeList::removeAttributesAtIndex(
    LLVMContext &C, unsigned Index, const AttributeMask &AttrsToRemove) const {
  AttributeSet Attrs = getAttributes(Index);
  AttributeSet NewAttrs = Attrs.removeAttributes(C, AttrsToRemove);
  // If nothing was removed, return the original list.
  if (Attrs == NewAttrs)
    return *this;
  return setAttributesAtIndex(C, Index, NewAttrs);
}

AttributeList
AttributeList::removeAttributesAtIndex(LLVMContext &C,
                                       unsigned WithoutIndex) const {
  if (!pImpl)
    return {};
  if (attrIdxToArrayIdx(WithoutIndex) >= getNumAttrSets())
    return *this;
  return setAttributesAtIndex(C, WithoutIndex, AttributeSet());
}

AttributeList AttributeList::addDereferenceableRetAttr(LLVMContext &C,
                                                       uint64_t Bytes) const {
  AttrBuilder B(C);
  B.addDereferenceableAttr(Bytes);
  return addRetAttributes(C, B);
}

AttributeList AttributeList::addDereferenceableParamAttr(LLVMContext &C,
                                                         unsigned Index,
                                                         uint64_t Bytes) const {
  AttrBuilder B(C);
  B.addDereferenceableAttr(Bytes);
  return addParamAttributes(C, Index, B);
}

AttributeList
AttributeList::addDereferenceableOrNullParamAttr(LLVMContext &C, unsigned Index,
                                                 uint64_t Bytes) const {
  AttrBuilder B(C);
  B.addDereferenceableOrNullAttr(Bytes);
  return addParamAttributes(C, Index, B);
}

AttributeList AttributeList::addRangeRetAttr(LLVMContext &C,
                                             const ConstantRange &CR) const {
  AttrBuilder B(C);
  B.addRangeAttr(CR);
  return addRetAttributes(C, B);
}

AttributeList AttributeList::addAllocSizeParamAttr(
    LLVMContext &C, unsigned Index, unsigned ElemSizeArg,
    const std::optional<unsigned> &NumElemsArg) const {
  AttrBuilder B(C);
  B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
  return addParamAttributes(C, Index, B);
}

std::optional<AttributeList>
AttributeList::intersectWith(LLVMContext &C, AttributeList Other) const {
  // Trivial case, the two lists are equal.
  if (*this == Other)
    return *this;

  SmallVector<std::pair<unsigned, AttributeSet>> IntersectedAttrs;
  auto IndexIt =
      index_iterator(std::max(getNumAttrSets(), Other.getNumAttrSets()));
  for (unsigned Idx : IndexIt) {
    auto IntersectedAS =
        getAttributes(Idx).intersectWith(C, Other.getAttributes(Idx));
    // If any index fails to intersect, fail.
    if (!IntersectedAS)
      return std::nullopt;
    if (!IntersectedAS->hasAttributes())
      continue;
    IntersectedAttrs.push_back(std::make_pair(Idx, *IntersectedAS));
  }

  llvm::sort(IntersectedAttrs, llvm::less_first());
  return AttributeList::get(C, IntersectedAttrs);
}

//===----------------------------------------------------------------------===//
// AttributeList Accessor Methods
//===----------------------------------------------------------------------===//

AttributeSet AttributeList::getParamAttrs(unsigned ArgNo) const {
  return getAttributes(ArgNo + FirstArgIndex);
}

AttributeSet AttributeList::getRetAttrs() const {
  return getAttributes(ReturnIndex);
}

AttributeSet AttributeList::getFnAttrs() const {
  return getAttributes(FunctionIndex);
}

bool AttributeList::hasAttributeAtIndex(unsigned Index,
                                        Attribute::AttrKind Kind) const {
  return getAttributes(Index).hasAttribute(Kind);
}

bool AttributeList::hasAttributeAtIndex(unsigned Index, StringRef Kind) const {
  return getAttributes(Index).hasAttribute(Kind);
}

bool AttributeList::hasAttributesAtIndex(unsigned Index) const {
  return getAttributes(Index).hasAttributes();
}

bool AttributeList::hasFnAttr(Attribute::AttrKind Kind) const {
  return pImpl && pImpl->hasFnAttribute(Kind);
}

bool AttributeList::hasFnAttr(StringRef Kind) const {
  return hasAttributeAtIndex(AttributeList::FunctionIndex, Kind);
}

bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr,
                                     unsigned *Index) const {
  return pImpl && pImpl->hasAttrSomewhere(Attr, Index);
}

Attribute AttributeList::getAttributeAtIndex(unsigned Index,
                                             Attribute::AttrKind Kind) const {
  return getAttributes(Index).getAttribute(Kind);
}

Attribute AttributeList::getAttributeAtIndex(unsigned Index,
                                             StringRef Kind) const {
  return getAttributes(Index).getAttribute(Kind);
}

MaybeAlign AttributeList::getRetAlignment() const {
  return getAttributes(ReturnIndex).getAlignment();
}

MaybeAlign AttributeList::getParamAlignment(unsigned ArgNo) const {
  return getAttributes(ArgNo + FirstArgIndex).getAlignment();
}

MaybeAlign AttributeList::getParamStackAlignment(unsigned ArgNo) const {
  return getAttributes(ArgNo + FirstArgIndex).getStackAlignment();
}

Type *AttributeList::getParamByValType(unsigned Index) const {
  return getAttributes(Index+FirstArgIndex).getByValType();
}

Type *AttributeList::getParamStructRetType(unsigned Index) const {
  return getAttributes(Index + FirstArgIndex).getStructRetType();
}

Type *AttributeList::getParamByRefType(unsigned Index) const {
  return getAttributes(Index + FirstArgIndex).getByRefType();
}

Type *AttributeList::getParamPreallocatedType(unsigned Index) const {
  return getAttributes(Index + FirstArgIndex).getPreallocatedType();
}

Type *AttributeList::getParamInAllocaType(unsigned Index) const {
  return getAttributes(Index + FirstArgIndex).getInAllocaType();
}

Type *AttributeList::getParamElementType(unsigned Index) const {
  return getAttributes(Index + FirstArgIndex).getElementType();
}

MaybeAlign AttributeList::getFnStackAlignment() const {
  return getFnAttrs().getStackAlignment();
}

MaybeAlign AttributeList::getRetStackAlignment() const {
  return getRetAttrs().getStackAlignment();
}

uint64_t AttributeList::getRetDereferenceableBytes() const {
  return getRetAttrs().getDereferenceableBytes();
}

uint64_t AttributeList::getParamDereferenceableBytes(unsigned Index) const {
  return getParamAttrs(Index).getDereferenceableBytes();
}

uint64_t AttributeList::getRetDereferenceableOrNullBytes() const {
  return getRetAttrs().getDereferenceableOrNullBytes();
}

DeadOnReturnInfo AttributeList::getDeadOnReturnInfo(unsigned Index) const {
  return getParamAttrs(Index).getDeadOnReturnInfo();
}

uint64_t
AttributeList::getParamDereferenceableOrNullBytes(unsigned Index) const {
  return getParamAttrs(Index).getDereferenceableOrNullBytes();
}

std::optional<ConstantRange>
AttributeList::getParamRange(unsigned ArgNo) const {
  auto RangeAttr = getParamAttrs(ArgNo).getAttribute(Attribute::Range);
  if (RangeAttr.isValid())
    return RangeAttr.getRange();
  return std::nullopt;
}

FPClassTest AttributeList::getRetNoFPClass() const {
  return getRetAttrs().getNoFPClass();
}

FPClassTest AttributeList::getParamNoFPClass(unsigned Index) const {
  return getParamAttrs(Index).getNoFPClass();
}

UWTableKind AttributeList::getUWTableKind() const {
  return getFnAttrs().getUWTableKind();
}

AllocFnKind AttributeList::getAllocKind() const {
  return getFnAttrs().getAllocKind();
}

MemoryEffects AttributeList::getMemoryEffects() const {
  return getFnAttrs().getMemoryEffects();
}

std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
  return getAttributes(Index).getAsString(InAttrGrp);
}

AttributeSet AttributeList::getAttributes(unsigned Index) const {
  Index = attrIdxToArrayIdx(Index);
  if (!pImpl || Index >= getNumAttrSets())
    return {};
  return pImpl->begin()[Index];
}

bool AttributeList::hasParentContext(LLVMContext &C) const {
  assert(!isEmpty() && "an empty attribute list has no parent context");
  FoldingSetNodeID ID;
  pImpl->Profile(ID);
  void *Unused;
  return C.pImpl->AttrsLists.FindNodeOrInsertPos(ID, Unused) == pImpl;
}

AttributeList::iterator AttributeList::begin() const {
  return pImpl ? pImpl->begin() : nullptr;
}

AttributeList::iterator AttributeList::end() const {
  return pImpl ? pImpl->end() : nullptr;
}

//===----------------------------------------------------------------------===//
// AttributeList Introspection Methods
//===----------------------------------------------------------------------===//

unsigned AttributeList::getNumAttrSets() const {
  return pImpl ? pImpl->NumAttrSets : 0;
}

void AttributeList::print(raw_ostream &O) const {
  O << "AttributeList[\n";

  for (unsigned i : indexes()) {
    if (!getAttributes(i).hasAttributes())
      continue;
    O << "  { ";
    switch (i) {
    case AttrIndex::ReturnIndex:
      O << "return";
      break;
    case AttrIndex::FunctionIndex:
      O << "function";
      break;
    default:
      O << "arg(" << i - AttrIndex::FirstArgIndex << ")";
    }
    O << " => " << getAsString(i) << " }\n";
  }

  O << "]\n";
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void AttributeList::dump() const { print(dbgs()); }
#endif

//===----------------------------------------------------------------------===//
// AttrBuilder Method Implementations
//===----------------------------------------------------------------------===//

AttrBuilder::AttrBuilder(LLVMContext &Ctx, AttributeSet AS) : Ctx(Ctx) {
  append_range(Attrs, AS);
  assert(is_sorted(Attrs) && "AttributeSet should be sorted");
}

void AttrBuilder::clear() { Attrs.clear(); }

/// Attribute comparator that only compares attribute keys. Enum attributes are
/// sorted before string attributes.
struct AttributeComparator {
  bool operator()(Attribute A0, Attribute A1) const {
    bool A0IsString = A0.isStringAttribute();
    bool A1IsString = A1.isStringAttribute();
    if (A0IsString) {
      if (A1IsString)
        return A0.getKindAsString() < A1.getKindAsString();
      else
        return false;
    }
    if (A1IsString)
      return true;
    return A0.getKindAsEnum() < A1.getKindAsEnum();
  }
  bool operator()(Attribute A0, Attribute::AttrKind Kind) const {
    if (A0.isStringAttribute())
      return false;
    return A0.getKindAsEnum() < Kind;
  }
  bool operator()(Attribute A0, StringRef Kind) const {
    if (A0.isStringAttribute())
      return A0.getKindAsString() < Kind;
    return true;
  }
};

template <typename K>
static void addAttributeImpl(SmallVectorImpl<Attribute> &Attrs, K Kind,
                             Attribute Attr) {
  auto It = lower_bound(Attrs, Kind, AttributeComparator());
  if (It != Attrs.end() && It->hasAttribute(Kind))
    std::swap(*It, Attr);
  else
    Attrs.insert(It, Attr);
}

AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
  if (Attr.isStringAttribute())
    addAttributeImpl(Attrs, Attr.getKindAsString(), Attr);
  else
    addAttributeImpl(Attrs, Attr.getKindAsEnum(), Attr);
  return *this;
}

AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Kind) {
  addAttributeImpl(Attrs, Kind, Attribute::get(Ctx, Kind));
  return *this;
}

AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) {
  addAttributeImpl(Attrs, A, Attribute::get(Ctx, A, V));
  return *this;
}

AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
  assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
  auto It = lower_bound(Attrs, Val, AttributeComparator());
  if (It != Attrs.end() && It->hasAttribute(Val))
    Attrs.erase(It);
  return *this;
}

AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
  auto It = lower_bound(Attrs, A, AttributeComparator());
  if (It != Attrs.end() && It->hasAttribute(A))
    Attrs.erase(It);
  return *this;
}

std::optional<uint64_t>
AttrBuilder::getRawIntAttr(Attribute::AttrKind Kind) const {
  assert(Attribute::isIntAttrKind(Kind) && "Not an int attribute");
  Attribute A = getAttribute(Kind);
  if (A.isValid())
    return A.getValueAsInt();
  return std::nullopt;
}

AttrBuilder &AttrBuilder::addRawIntAttr(Attribute::AttrKind Kind,
                                        uint64_t Value) {
  return addAttribute(Attribute::get(Ctx, Kind, Value));
}

std::optional<std::pair<unsigned, std::optional<unsigned>>>
AttrBuilder::getAllocSizeArgs() const {
  Attribute A = getAttribute(Attribute::AllocSize);
  if (A.isValid())
    return A.getAllocSizeArgs();
  return std::nullopt;
}

AttrBuilder &AttrBuilder::addAlignmentAttr(MaybeAlign Align) {
  if (!Align)
    return *this;

  assert(*Align <= llvm::Value::MaximumAlignment && "Alignment too large.");
  return addRawIntAttr(Attribute::Alignment, Align->value());
}

AttrBuilder &AttrBuilder::addStackAlignmentAttr(MaybeAlign Align) {
  // Default alignment, allow the target to define how to align it.
  if (!Align)
    return *this;

  assert(*Align <= 0x100 && "Alignment too large.");
  return addRawIntAttr(Attribute::StackAlignment, Align->value());
}

AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
  if (Bytes == 0) return *this;

  return addRawIntAttr(Attribute::Dereferenceable, Bytes);
}

AttrBuilder &AttrBuilder::addDeadOnReturnAttr(DeadOnReturnInfo Info) {
  if (Info.isZeroSized())
    return *this;

  return addRawIntAttr(Attribute::DeadOnReturn, Info.toIntValue());
}

AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
  if (Bytes == 0)
    return *this;

  return addRawIntAttr(Attribute::DereferenceableOrNull, Bytes);
}

AttrBuilder &
AttrBuilder::addAllocSizeAttr(unsigned ElemSize,
                              const std::optional<unsigned> &NumElems) {
  return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
}

AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) {
  // (0, 0) is our "not present" value, so we need to check for it here.
  assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
  return addRawIntAttr(Attribute::AllocSize, RawArgs);
}

AttrBuilder &AttrBuilder::addVScaleRangeAttr(unsigned MinValue,
                                             std::optional<unsigned> MaxValue) {
  return addVScaleRangeAttrFromRawRepr(packVScaleRangeArgs(MinValue, MaxValue));
}

AttrBuilder &AttrBuilder::addVScaleRangeAttrFromRawRepr(uint64_t RawArgs) {
  // (0, 0) is not present hence ignore this case
  if (RawArgs == 0)
    return *this;

  return addRawIntAttr(Attribute::VScaleRange, RawArgs);
}

AttrBuilder &AttrBuilder::addUWTableAttr(UWTableKind Kind) {
  if (Kind == UWTableKind::None)
    return *this;
  return addRawIntAttr(Attribute::UWTable, uint64_t(Kind));
}

AttrBuilder &AttrBuilder::addMemoryAttr(MemoryEffects ME) {
  return addRawIntAttr(Attribute::Memory, ME.toIntValue());
}

AttrBuilder &AttrBuilder::addCapturesAttr(CaptureInfo CI) {
  return addRawIntAttr(Attribute::Captures, CI.toIntValue());
}

AttrBuilder &AttrBuilder::addDenormalFPEnvAttr(DenormalFPEnv FPEnv) {
  return addRawIntAttr(Attribute::DenormalFPEnv, FPEnv.toIntValue());
}

AttrBuilder &AttrBuilder::addNoFPClassAttr(FPClassTest Mask) {
  if (Mask == fcNone)
    return *this;

  return addRawIntAttr(Attribute::NoFPClass, Mask);
}

AttrBuilder &AttrBuilder::addAllocKindAttr(AllocFnKind Kind) {
  return addRawIntAttr(Attribute::AllocKind, static_cast<uint64_t>(Kind));
}

Type *AttrBuilder::getTypeAttr(Attribute::AttrKind Kind) const {
  assert(Attribute::isTypeAttrKind(Kind) && "Not a type attribute");
  Attribute A = getAttribute(Kind);
  return A.isValid() ? A.getValueAsType() : nullptr;
}

AttrBuilder &AttrBuilder::addTypeAttr(Attribute::AttrKind Kind, Type *Ty) {
  return addAttribute(Attribute::get(Ctx, Kind, Ty));
}

AttrBuilder &AttrBuilder::addByValAttr(Type *Ty) {
  return addTypeAttr(Attribute::ByVal, Ty);
}

AttrBuilder &AttrBuilder::addStructRetAttr(Type *Ty) {
  return addTypeAttr(Attribute::StructRet, Ty);
}

AttrBuilder &AttrBuilder::addByRefAttr(Type *Ty) {
  return addTypeAttr(Attribute::ByRef, Ty);
}

AttrBuilder &AttrBuilder::addPreallocatedAttr(Type *Ty) {
  return addTypeAttr(Attribute::Preallocated, Ty);
}

AttrBuilder &AttrBuilder::addInAllocaAttr(Type *Ty) {
  return addTypeAttr(Attribute::InAlloca, Ty);
}

AttrBuilder &AttrBuilder::addConstantRangeAttr(Attribute::AttrKind Kind,
                                               const ConstantRange &CR) {
  if (CR.isFullSet())
    return *this;

  return addAttribute(Attribute::get(Ctx, Kind, CR));
}

AttrBuilder &AttrBuilder::addRangeAttr(const ConstantRange &CR) {
  return addConstantRangeAttr(Attribute::Range, CR);
}

AttrBuilder &
AttrBuilder::addConstantRangeListAttr(Attribute::AttrKind Kind,
                                      ArrayRef<ConstantRange> Val) {
  return addAttribute(Attribute::get(Ctx, Kind, Val));
}

AttrBuilder &AttrBuilder::addInitializesAttr(const ConstantRangeList &CRL) {
  return addConstantRangeListAttr(Attribute::Initializes, CRL.rangesRef());
}

AttrBuilder &AttrBuilder::addFromEquivalentMetadata(const Instruction &I) {
  if (I.hasMetadata(LLVMContext::MD_nonnull))
    addAttribute(Attribute::NonNull);

  if (I.hasMetadata(LLVMContext::MD_noundef))
    addAttribute(Attribute::NoUndef);

  if (const MDNode *Align = I.getMetadata(LLVMContext::MD_align)) {
    ConstantInt *CI = mdconst::extract<ConstantInt>(Align->getOperand(0));
    addAlignmentAttr(CI->getZExtValue());
  }

  if (const MDNode *Dereferenceable =
          I.getMetadata(LLVMContext::MD_dereferenceable)) {
    ConstantInt *CI =
        mdconst::extract<ConstantInt>(Dereferenceable->getOperand(0));
    addDereferenceableAttr(CI->getZExtValue());
  }

  if (const MDNode *DereferenceableOrNull =
          I.getMetadata(LLVMContext::MD_dereferenceable_or_null)) {
    ConstantInt *CI =
        mdconst::extract<ConstantInt>(DereferenceableOrNull->getOperand(0));
    addDereferenceableAttr(CI->getZExtValue());
  }

  if (const MDNode *Range = I.getMetadata(LLVMContext::MD_range))
    addRangeAttr(getConstantRangeFromMetadata(*Range));

  if (const MDNode *NoFPClass = I.getMetadata(LLVMContext::MD_nofpclass)) {
    ConstantInt *CI = mdconst::extract<ConstantInt>(NoFPClass->getOperand(0));
    addNoFPClassAttr(static_cast<FPClassTest>(CI->getZExtValue()));
  }

  return *this;
}

AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
  // TODO: Could make this O(n) as we're merging two sorted lists.
  for (const auto &I : B.attrs())
    addAttribute(I);

  return *this;
}

AttrBuilder &AttrBuilder::remove(const AttributeMask &AM) {
  erase_if(Attrs, [&](Attribute A) { return AM.contains(A); });
  return *this;
}

bool AttrBuilder::overlaps(const AttributeMask &AM) const {
  return any_of(Attrs, [&](Attribute A) { return AM.contains(A); });
}

Attribute AttrBuilder::getAttribute(Attribute::AttrKind A) const {
  assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range!");
  auto It = lower_bound(Attrs, A, AttributeComparator());
  if (It != Attrs.end() && It->hasAttribute(A))
    return *It;
  return {};
}

Attribute AttrBuilder::getAttribute(StringRef A) const {
  auto It = lower_bound(Attrs, A, AttributeComparator());
  if (It != Attrs.end() && It->hasAttribute(A))
    return *It;
  return {};
}

std::optional<ConstantRange> AttrBuilder::getRange() const {
  const Attribute RangeAttr = getAttribute(Attribute::Range);
  if (RangeAttr.isValid())
    return RangeAttr.getRange();
  return std::nullopt;
}

bool AttrBuilder::contains(Attribute::AttrKind A) const {
  return getAttribute(A).isValid();
}

bool AttrBuilder::contains(StringRef A) const {
  return getAttribute(A).isValid();
}

bool AttrBuilder::operator==(const AttrBuilder &B) const {
  return Attrs == B.Attrs;
}

//===----------------------------------------------------------------------===//
// AttributeFuncs Function Defintions
//===----------------------------------------------------------------------===//

/// Returns true if this is a type legal for the 'nofpclass' attribute. This
/// follows the same type rules as FPMathOperator.
bool AttributeFuncs::isNoFPClassCompatibleType(Type *Ty) {
  return FPMathOperator::isSupportedFloatingPointType(Ty);
}

/// Which attributes cannot be applied to a type.
AttributeMask AttributeFuncs::typeIncompatible(Type *Ty, AttributeSet AS,
                                               AttributeSafetyKind ASK) {
  AttributeMask Incompatible;

  if (!Ty->isIntegerTy()) {
    // Attributes that only apply to integers.
    if (ASK & ASK_SAFE_TO_DROP)
      Incompatible.addAttribute(Attribute::AllocAlign);
    if (ASK & ASK_UNSAFE_TO_DROP)
      Incompatible.addAttribute(Attribute::SExt).addAttribute(Attribute::ZExt);
  }

  if (!Ty->isIntOrIntVectorTy()) {
    // Attributes that only apply to integers or vector of integers.
    if (ASK & ASK_SAFE_TO_DROP)
      Incompatible.addAttribute(Attribute::Range);
  } else {
    Attribute RangeAttr = AS.getAttribute(Attribute::Range);
    if (RangeAttr.isValid() &&
        RangeAttr.getRange().getBitWidth() != Ty->getScalarSizeInBits())
      Incompatible.addAttribute(Attribute::Range);
  }

  if (!Ty->isPointerTy()) {
    // Attributes that only apply to pointers.
    if (ASK & ASK_SAFE_TO_DROP)
      Incompatible.addAttribute(Attribute::NoAlias)
          .addAttribute(Attribute::NonNull)
          .addAttribute(Attribute::ReadNone)
          .addAttribute(Attribute::ReadOnly)
          .addAttribute(Attribute::Dereferenceable)
          .addAttribute(Attribute::DereferenceableOrNull)
          .addAttribute(Attribute::Writable)
          .addAttribute(Attribute::DeadOnUnwind)
          .addAttribute(Attribute::Initializes)
          .addAttribute(Attribute::Captures)
          .addAttribute(Attribute::DeadOnReturn);
    if (ASK & ASK_UNSAFE_TO_DROP)
      Incompatible.addAttribute(Attribute::Nest)
          .addAttribute(Attribute::SwiftError)
          .addAttribute(Attribute::Preallocated)
          .addAttribute(Attribute::InAlloca)
          .addAttribute(Attribute::ByVal)
          .addAttribute(Attribute::StructRet)
          .addAttribute(Attribute::ByRef)
          .addAttribute(Attribute::ElementType)
          .addAttribute(Attribute::AllocatedPointer);
  }

    // Attributes that only apply to pointers or vectors of pointers.
  if (!Ty->isPtrOrPtrVectorTy()) {
    if (ASK & ASK_SAFE_TO_DROP)
      Incompatible.addAttribute(Attribute::Alignment);
  }

  if (ASK & ASK_SAFE_TO_DROP) {
    if (!isNoFPClassCompatibleType(Ty))
      Incompatible.addAttribute(Attribute::NoFPClass);
  }

  // Some attributes can apply to all "values" but there are no `void` values.
  if (Ty->isVoidTy()) {
    if (ASK & ASK_SAFE_TO_DROP)
      Incompatible.addAttribute(Attribute::NoUndef);
  }

  return Incompatible;
}

AttributeMask AttributeFuncs::getUBImplyingAttributes() {
  AttributeMask AM;
  AM.addAttribute(Attribute::NoUndef);
  AM.addAttribute(Attribute::Dereferenceable);
  AM.addAttribute(Attribute::DereferenceableOrNull);
  return AM;
}

/// Callees with dynamic denormal modes are compatible with any caller mode.
static bool denormModeCompatible(DenormalMode CallerMode,
                                 DenormalMode CalleeMode) {
  if (CallerMode == CalleeMode || CalleeMode == DenormalMode::getDynamic())
    return true;

  // If they don't exactly match, it's OK if the mismatched component is
  // dynamic.
  if (CalleeMode.Input == CallerMode.Input &&
      CalleeMode.Output == DenormalMode::Dynamic)
    return true;

  if (CalleeMode.Output == CallerMode.Output &&
      CalleeMode.Input == DenormalMode::Dynamic)
    return true;
  return false;
}

static bool checkDenormMode(const Function &Caller, const Function &Callee) {
  DenormalFPEnv CallerEnv = Caller.getDenormalFPEnv();
  DenormalFPEnv CalleeEnv = Callee.getDenormalFPEnv();

  if (denormModeCompatible(CallerEnv.DefaultMode, CalleeEnv.DefaultMode)) {
    DenormalMode CallerModeF32 = CallerEnv.F32Mode;
    DenormalMode CalleeModeF32 = CalleeEnv.F32Mode;
    if (CallerModeF32 == DenormalMode::getInvalid())
      CallerModeF32 = CallerEnv.DefaultMode;
    if (CalleeModeF32 == DenormalMode::getInvalid())
      CalleeModeF32 = CalleeEnv.DefaultMode;
    return denormModeCompatible(CallerModeF32, CalleeModeF32);
  }

  return false;
}

static bool checkStrictFP(const Function &Caller, const Function &Callee) {
  // Do not inline strictfp function into non-strictfp one. It would require
  // conversion of all FP operations in host function to constrained intrinsics.
  return !Callee.getAttributes().hasFnAttr(Attribute::StrictFP) ||
         Caller.getAttributes().hasFnAttr(Attribute::StrictFP);
}

template<typename AttrClass>
static bool isEqual(const Function &Caller, const Function &Callee) {
  return Caller.getFnAttribute(AttrClass::getKind()) ==
         Callee.getFnAttribute(AttrClass::getKind());
}

static bool isEqual(const Function &Caller, const Function &Callee,
                    const StringRef &AttrName) {
  return Caller.getFnAttribute(AttrName) == Callee.getFnAttribute(AttrName);
}

/// Compute the logical AND of the attributes of the caller and the
/// callee.
///
/// This function sets the caller's attribute to false if the callee's attribute
/// is false.
template<typename AttrClass>
static void setAND(Function &Caller, const Function &Callee) {
  if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
      !AttrClass::isSet(Callee, AttrClass::getKind()))
    AttrClass::set(Caller, AttrClass::getKind(), false);
}

/// Compute the logical OR of the attributes of the caller and the
/// callee.
///
/// This function sets the caller's attribute to true if the callee's attribute
/// is true.
template<typename AttrClass>
static void setOR(Function &Caller, const Function &Callee) {
  if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
      AttrClass::isSet(Callee, AttrClass::getKind()))
    AttrClass::set(Caller, AttrClass::getKind(), true);
}

/// If the inlined function had a higher stack protection level than the
/// calling function, then bump up the caller's stack protection level.
static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
  // If the calling function has *no* stack protection level (e.g. it was built
  // with Clang's -fno-stack-protector or no_stack_protector attribute), don't
  // change it as that could change the program's semantics.
  if (!Caller.hasStackProtectorFnAttr())
    return;

  // If upgrading the SSP attribute, clear out the old SSP Attributes first.
  // Having multiple SSP attributes doesn't actually hurt, but it adds useless
  // clutter to the IR.
  AttributeMask OldSSPAttr;
  OldSSPAttr.addAttribute(Attribute::StackProtect)
      .addAttribute(Attribute::StackProtectStrong)
      .addAttribute(Attribute::StackProtectReq);

  if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
    Caller.removeFnAttrs(OldSSPAttr);
    Caller.addFnAttr(Attribute::StackProtectReq);
  } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
             !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
    Caller.removeFnAttrs(OldSSPAttr);
    Caller.addFnAttr(Attribute::StackProtectStrong);
  } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
             !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
             !Caller.hasFnAttribute(Attribute::StackProtectStrong))
    Caller.addFnAttr(Attribute::StackProtect);
}

/// If the inlined function required stack probes, then ensure that
/// the calling function has those too.
static void adjustCallerStackProbes(Function &Caller, const Function &Callee) {
  if (!Caller.hasFnAttribute("probe-stack") &&
      Callee.hasFnAttribute("probe-stack")) {
    Caller.addFnAttr(Callee.getFnAttribute("probe-stack"));
  }
}

/// If the inlined function defines the size of guard region
/// on the stack, then ensure that the calling function defines a guard region
/// that is no larger.
static void
adjustCallerStackProbeSize(Function &Caller, const Function &Callee) {
  Attribute CalleeAttr = Callee.getFnAttribute("stack-probe-size");
  if (CalleeAttr.isValid()) {
    Attribute CallerAttr = Caller.getFnAttribute("stack-probe-size");
    if (CallerAttr.isValid()) {
      uint64_t CallerStackProbeSize, CalleeStackProbeSize;
      CallerAttr.getValueAsString().getAsInteger(0, CallerStackProbeSize);
      CalleeAttr.getValueAsString().getAsInteger(0, CalleeStackProbeSize);

      if (CallerStackProbeSize > CalleeStackProbeSize) {
        Caller.addFnAttr(CalleeAttr);
      }
    } else {
      Caller.addFnAttr(CalleeAttr);
    }
  }
}

/// If the inlined function defines a min legal vector width, then ensure
/// the calling function has the same or larger min legal vector width. If the
/// caller has the attribute, but the callee doesn't, we need to remove the
/// attribute from the caller since we can't make any guarantees about the
/// caller's requirements.
/// This function is called after the inlining decision has been made so we have
/// to merge the attribute this way. Heuristics that would use
/// min-legal-vector-width to determine inline compatibility would need to be
/// handled as part of inline cost analysis.
static void
adjustMinLegalVectorWidth(Function &Caller, const Function &Callee) {
  Attribute CallerAttr = Caller.getFnAttribute("min-legal-vector-width");
  if (CallerAttr.isValid()) {
    Attribute CalleeAttr = Callee.getFnAttribute("min-legal-vector-width");
    if (CalleeAttr.isValid()) {
      uint64_t CallerVectorWidth, CalleeVectorWidth;
      CallerAttr.getValueAsString().getAsInteger(0, CallerVectorWidth);
      CalleeAttr.getValueAsString().getAsInteger(0, CalleeVectorWidth);
      if (CallerVectorWidth < CalleeVectorWidth)
        Caller.addFnAttr(CalleeAttr);
    } else {
      // If the callee doesn't have the attribute then we don't know anything
      // and must drop the attribute from the caller.
      Caller.removeFnAttr("min-legal-vector-width");
    }
  }
}

/// If the inlined function has null_pointer_is_valid attribute,
/// set this attribute in the caller post inlining.
static void
adjustNullPointerValidAttr(Function &Caller, const Function &Callee) {
  if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
    Caller.addFnAttr(Attribute::NullPointerIsValid);
  }
}

struct EnumAttr {
  static bool isSet(const Function &Fn,
                    Attribute::AttrKind Kind) {
    return Fn.hasFnAttribute(Kind);
  }

  static void set(Function &Fn,
                  Attribute::AttrKind Kind, bool Val) {
    if (Val)
      Fn.addFnAttr(Kind);
    else
      Fn.removeFnAttr(Kind);
  }
};

struct StrBoolAttr {
  static bool isSet(const Function &Fn,
                    StringRef Kind) {
    auto A = Fn.getFnAttribute(Kind);
    return A.getValueAsString() == "true";
  }

  static void set(Function &Fn,
                  StringRef Kind, bool Val) {
    Fn.addFnAttr(Kind, Val ? "true" : "false");
  }
};

#define GET_ATTR_NAMES
#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME)                                \
  struct ENUM_NAME##Attr : EnumAttr {                                          \
    static enum Attribute::AttrKind getKind() {                                \
      return llvm::Attribute::ENUM_NAME;                                       \
    }                                                                          \
  };
#define ATTRIBUTE_STRBOOL(ENUM_NAME, DISPLAY_NAME)                             \
  struct ENUM_NAME##Attr : StrBoolAttr {                                       \
    static StringRef getKind() { return #DISPLAY_NAME; }                       \
  };
#include "llvm/IR/Attributes.inc"

#define GET_ATTR_COMPAT_FUNC
#include "llvm/IR/Attributes.inc"

bool AttributeFuncs::areInlineCompatible(const Function &Caller,
                                         const Function &Callee) {
  return hasCompatibleFnAttrs(Caller, Callee);
}

bool AttributeFuncs::areOutlineCompatible(const Function &A,
                                          const Function &B) {
  return hasCompatibleFnAttrs(A, B);
}

void AttributeFuncs::mergeAttributesForInlining(Function &Caller,
                                                const Function &Callee) {
  mergeFnAttrs(Caller, Callee);
}

void AttributeFuncs::mergeAttributesForOutlining(Function &Base,
                                                const Function &ToMerge) {

  // We merge functions so that they meet the most general case.
  // For example, if the NoNansFPMathAttr is set in one function, but not in
  // the other, in the merged function we can say that the NoNansFPMathAttr
  // is not set.
  // However if we have the SpeculativeLoadHardeningAttr set true in one
  // function, but not the other, we make sure that the function retains
  // that aspect in the merged function.
  mergeFnAttrs(Base, ToMerge);
}

void AttributeFuncs::updateMinLegalVectorWidthAttr(Function &Fn,
                                                   uint64_t Width) {
  Attribute Attr = Fn.getFnAttribute("min-legal-vector-width");
  if (Attr.isValid()) {
    uint64_t OldWidth;
    Attr.getValueAsString().getAsInteger(0, OldWidth);
    if (Width > OldWidth)
      Fn.addFnAttr("min-legal-vector-width", llvm::utostr(Width));
  }
}
