//===- DataLayout.cpp - Data size & alignment routines ---------------------==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines layout properties related to datatype size/offset/alignment
// information.
//
// This structure should be created once, filled in if the defaults are not
// correct and then passed around by const&.  None of the members functions
// require modification to the object.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/DataLayout.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemAlloc.h"
#include "llvm/Support/TypeSize.h"
#include "llvm/TargetParser/Triple.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstdlib>
#include <new>
#include <utility>

using namespace llvm;

//===----------------------------------------------------------------------===//
// Support for StructLayout
//===----------------------------------------------------------------------===//

StructLayout::StructLayout(StructType *ST, const DataLayout &DL)
    : StructSize(TypeSize::getFixed(0)) {
  assert(!ST->isOpaque() && "Cannot get layout of opaque structs");
  IsPadded = false;
  NumElements = ST->getNumElements();

  // Loop over each of the elements, placing them in memory.
  for (unsigned i = 0, e = NumElements; i != e; ++i) {
    Type *Ty = ST->getElementType(i);
    if (i == 0 && Ty->isScalableTy())
      StructSize = TypeSize::getScalable(0);

    const Align TyAlign = ST->isPacked() ? Align(1) : DL.getABITypeAlign(Ty);

    // Add padding if necessary to align the data element properly.
    // Currently the only structure with scalable size will be the homogeneous
    // scalable vector types. Homogeneous scalable vector types have members of
    // the same data type so no alignment issue will happen. The condition here
    // assumes so and needs to be adjusted if this assumption changes (e.g. we
    // support structures with arbitrary scalable data type, or structure that
    // contains both fixed size and scalable size data type members).
    if (!StructSize.isScalable() && !isAligned(TyAlign, StructSize)) {
      IsPadded = true;
      StructSize = TypeSize::getFixed(alignTo(StructSize, TyAlign));
    }

    // Keep track of maximum alignment constraint.
    StructAlignment = std::max(TyAlign, StructAlignment);

    getMemberOffsets()[i] = StructSize;
    // Consume space for this data item
    StructSize += DL.getTypeAllocSize(Ty);
  }

  // Add padding to the end of the struct so that it could be put in an array
  // and all array elements would be aligned correctly.
  if (!StructSize.isScalable() && !isAligned(StructAlignment, StructSize)) {
    IsPadded = true;
    StructSize = TypeSize::getFixed(alignTo(StructSize, StructAlignment));
  }
}

/// getElementContainingOffset - Given a valid offset into the structure,
/// return the structure index that contains it.
unsigned StructLayout::getElementContainingOffset(uint64_t FixedOffset) const {
  assert(!StructSize.isScalable() &&
         "Cannot get element at offset for structure containing scalable "
         "vector types");
  TypeSize Offset = TypeSize::getFixed(FixedOffset);
  ArrayRef<TypeSize> MemberOffsets = getMemberOffsets();

  const auto *SI = llvm::upper_bound(MemberOffsets, Offset,
                                     [](TypeSize LHS, TypeSize RHS) -> bool {
                                       return TypeSize::isKnownLT(LHS, RHS);
                                     });
  assert(SI != MemberOffsets.begin() && "Offset not in structure type!");
  --SI;
  assert(TypeSize::isKnownLE(*SI, Offset) && "upper_bound didn't work");
  assert(
      (SI == MemberOffsets.begin() || TypeSize::isKnownLE(*(SI - 1), Offset)) &&
      (SI + 1 == MemberOffsets.end() ||
       TypeSize::isKnownGT(*(SI + 1), Offset)) &&
      "Upper bound didn't work!");

  // Multiple fields can have the same offset if any of them are zero sized.
  // For example, in { i32, [0 x i32], i32 }, searching for offset 4 will stop
  // at the i32 element, because it is the last element at that offset.  This is
  // the right one to return, because anything after it will have a higher
  // offset, implying that this element is non-empty.
  return SI - MemberOffsets.begin();
}

namespace {

class StructLayoutMap {
  using LayoutInfoTy = DenseMap<StructType *, StructLayout *>;
  LayoutInfoTy LayoutInfo;

public:
  ~StructLayoutMap() {
    // Remove any layouts.
    for (const auto &I : LayoutInfo) {
      StructLayout *Value = I.second;
      Value->~StructLayout();
      free(Value);
    }
  }

  StructLayout *&operator[](StructType *STy) { return LayoutInfo[STy]; }
};

} // end anonymous namespace

//===----------------------------------------------------------------------===//
//                       DataLayout Class Implementation
//===----------------------------------------------------------------------===//

bool DataLayout::PrimitiveSpec::operator==(const PrimitiveSpec &Other) const {
  return BitWidth == Other.BitWidth && ABIAlign == Other.ABIAlign &&
         PrefAlign == Other.PrefAlign;
}

bool DataLayout::PointerSpec::operator==(const PointerSpec &Other) const {
  return AddrSpace == Other.AddrSpace && BitWidth == Other.BitWidth &&
         ABIAlign == Other.ABIAlign && PrefAlign == Other.PrefAlign &&
         IndexBitWidth == Other.IndexBitWidth &&
         HasUnstableRepresentation == Other.HasUnstableRepresentation &&
         HasExternalState == Other.HasExternalState &&
         NullPtrValue == Other.NullPtrValue &&
         AddrSpaceName == Other.AddrSpaceName;
}

namespace {
/// Predicate to sort primitive specs by bit width.
struct LessPrimitiveBitWidth {
  bool operator()(const DataLayout::PrimitiveSpec &LHS,
                  unsigned RHSBitWidth) const {
    return LHS.BitWidth < RHSBitWidth;
  }
};

/// Predicate to sort pointer specs by address space number.
struct LessPointerAddrSpace {
  bool operator()(const DataLayout::PointerSpec &LHS,
                  unsigned RHSAddrSpace) const {
    return LHS.AddrSpace < RHSAddrSpace;
  }
};
} // namespace

// Default primitive type specifications.
// NOTE: These arrays must be sorted by type bit width.
constexpr DataLayout::PrimitiveSpec DefaultIntSpecs[] = {
    {8, Align::Constant<1>(), Align::Constant<1>()},  // i8:8:8
    {16, Align::Constant<2>(), Align::Constant<2>()}, // i16:16:16
    {32, Align::Constant<4>(), Align::Constant<4>()}, // i32:32:32
    {64, Align::Constant<4>(), Align::Constant<8>()}, // i64:32:64
};
constexpr DataLayout::PrimitiveSpec DefaultFloatSpecs[] = {
    {16, Align::Constant<2>(), Align::Constant<2>()},    // f16:16:16
    {32, Align::Constant<4>(), Align::Constant<4>()},    // f32:32:32
    {64, Align::Constant<8>(), Align::Constant<8>()},    // f64:64:64
    {128, Align::Constant<16>(), Align::Constant<16>()}, // f128:128:128
};

DataLayout::DataLayout()
    : IntSpecs(ArrayRef(DefaultIntSpecs)),
      FloatSpecs(ArrayRef(DefaultFloatSpecs)) {
  // Default pointer type specifications.
  setPointerSpec(0, 64, Align::Constant<8>(), Align::Constant<8>(), 64, false,
                 false, "", APInt::getZero(64));
}

DataLayout::DataLayout(StringRef LayoutString) : DataLayout() {
  if (Error Err = parseLayoutString(LayoutString))
    report_fatal_error(std::move(Err));
}

DataLayout &DataLayout::operator=(const DataLayout &Other) {
  delete static_cast<StructLayoutMap *>(LayoutMap);
  LayoutMap = nullptr;
  StringRepresentation = Other.StringRepresentation;
  BigEndian = Other.BigEndian;
  VectorsAreElementAligned = Other.VectorsAreElementAligned;
  AllocaAddrSpace = Other.AllocaAddrSpace;
  ProgramAddrSpace = Other.ProgramAddrSpace;
  DefaultGlobalsAddrSpace = Other.DefaultGlobalsAddrSpace;
  StackNaturalAlign = Other.StackNaturalAlign;
  FunctionPtrAlign = Other.FunctionPtrAlign;
  TheFunctionPtrAlignType = Other.TheFunctionPtrAlignType;
  ManglingMode = Other.ManglingMode;
  LegalIntWidths = Other.LegalIntWidths;
  IntSpecs = Other.IntSpecs;
  FloatSpecs = Other.FloatSpecs;
  VectorSpecs = Other.VectorSpecs;
  PointerSpecs = Other.PointerSpecs;
  StructABIAlignment = Other.StructABIAlignment;
  StructPrefAlignment = Other.StructPrefAlignment;
  return *this;
}

bool DataLayout::operator==(const DataLayout &Other) const {
  // NOTE: StringRepresentation might differ, it is not canonicalized.
  return BigEndian == Other.BigEndian &&
         VectorsAreElementAligned == Other.VectorsAreElementAligned &&
         AllocaAddrSpace == Other.AllocaAddrSpace &&
         ProgramAddrSpace == Other.ProgramAddrSpace &&
         DefaultGlobalsAddrSpace == Other.DefaultGlobalsAddrSpace &&
         StackNaturalAlign == Other.StackNaturalAlign &&
         FunctionPtrAlign == Other.FunctionPtrAlign &&
         TheFunctionPtrAlignType == Other.TheFunctionPtrAlignType &&
         ManglingMode == Other.ManglingMode &&
         LegalIntWidths == Other.LegalIntWidths && IntSpecs == Other.IntSpecs &&
         FloatSpecs == Other.FloatSpecs && VectorSpecs == Other.VectorSpecs &&
         PointerSpecs == Other.PointerSpecs &&
         StructABIAlignment == Other.StructABIAlignment &&
         StructPrefAlignment == Other.StructPrefAlignment;
}

Expected<DataLayout> DataLayout::parse(StringRef LayoutString) {
  DataLayout Layout;
  if (Error Err = Layout.parseLayoutString(LayoutString))
    return std::move(Err);
  return Layout;
}

static Error createSpecFormatError(Twine Format) {
  return createStringError("malformed specification, must be of the form \"" +
                           Format + "\"");
}

/// Attempts to parse an address space component of a specification.
static Error parseAddrSpace(StringRef Str, unsigned &AddrSpace) {
  if (Str.empty())
    return createStringError("address space component cannot be empty");

  if (!to_integer(Str, AddrSpace, 10) || !isUInt<24>(AddrSpace))
    return createStringError("address space must be a 24-bit integer");

  return Error::success();
}

/// Attempts to parse an address space component of a specification allowing
/// name to be specified as well. The input is expected to be of the form
/// <number> '(' name ' )', with the name otional and the number is optional as
/// well.
static Error parseAddrSpaceAndName(StringRef Str, unsigned &AddrSpace,
                                   StringRef &AddrSpaceName) {
  if (Str.empty())
    return createStringError("address space component cannot be empty");

  if (isDigit(Str.front())) {
    if (Str.consumeInteger(10, AddrSpace) || !isUInt<24>(AddrSpace))
      return createStringError("address space must be a 24-bit integer");
  }

  if (Str.empty())
    return Error::success();

  if (Str.front() != '(')
    return createStringError("address space must be a 24-bit integer");

  // Expect atleast one character in between the ( and ).
  if (Str.back() != ')' || Str.size() == 2)
    return createStringError("Expected `( address space name )`");

  AddrSpaceName = Str.drop_front().drop_back();
  // TODO: Do we need any additional verification for address space name? Like
  // should be a valid identifier of some sort? Its not strictly needed.

  // LLVM's assembly parser used names "P", "G" and "A" to represent the
  // program, default global, and alloca address space. This mapping is not 1:1
  // in the sense that all of them can map to the same numberic address space.
  // Diallow using these predefined symbolic address space names as address
  // space names specified in the data layout.
  if (AddrSpaceName.size() == 1) {
    char C = AddrSpaceName.front();
    if (C == 'P' || C == 'G' || C == 'A')
      return createStringError(
          "Cannot use predefined address space names P/G/A in data layout");
  }
  return Error::success();
}

/// Attempts to parse a size component of a specification.
static Error parseSize(StringRef Str, unsigned &BitWidth,
                       StringRef Name = "size") {
  if (Str.empty())
    return createStringError(Name + " component cannot be empty");

  if (!to_integer(Str, BitWidth, 10) || BitWidth == 0 || !isUInt<24>(BitWidth))
    return createStringError(Name + " must be a non-zero 24-bit integer");

  return Error::success();
}

/// Attempts to parse an alignment component of a specification.
///
/// On success, returns the value converted to byte amount in \p Alignment.
/// If the value is zero and \p AllowZero is true, \p Alignment is set to one.
///
/// Return an error in a number of cases:
/// - \p Str is empty or contains characters other than decimal digits;
/// - the value is zero and \p AllowZero is false;
/// - the value is too large;
/// - the value is not a multiple of the byte width;
/// - the value converted to byte amount is not not a power of two.
static Error parseAlignment(StringRef Str, Align &Alignment, StringRef Name,
                            bool AllowZero = false) {
  if (Str.empty())
    return createStringError(Name + " alignment component cannot be empty");

  unsigned Value;
  if (!to_integer(Str, Value, 10) || !isUInt<16>(Value))
    return createStringError(Name + " alignment must be a 16-bit integer");

  if (Value == 0) {
    if (!AllowZero)
      return createStringError(Name + " alignment must be non-zero");
    Alignment = Align(1);
    return Error::success();
  }

  constexpr unsigned ByteWidth = 8;
  if (Value % ByteWidth || !isPowerOf2_32(Value / ByteWidth))
    return createStringError(
        Name + " alignment must be a power of two times the byte width");

  Alignment = Align(Value / ByteWidth);
  return Error::success();
}

Error DataLayout::parsePrimitiveSpec(StringRef Spec) {
  // [ifv]<size>:<abi>[:<pref>]
  SmallVector<StringRef, 3> Components;
  char Specifier = Spec.front();
  assert(Specifier == 'i' || Specifier == 'f' || Specifier == 'v');
  Spec.drop_front().split(Components, ':');

  if (Components.size() < 2 || Components.size() > 3)
    return createSpecFormatError(Twine(Specifier) + "<size>:<abi>[:<pref>]");

  // Size. Required, cannot be zero.
  unsigned BitWidth;
  if (Error Err = parseSize(Components[0], BitWidth))
    return Err;

  // ABI alignment.
  Align ABIAlign;
  if (Error Err = parseAlignment(Components[1], ABIAlign, "ABI"))
    return Err;

  if (Specifier == 'i' && BitWidth == 8 && ABIAlign != 1)
    return createStringError("i8 must be 8-bit aligned");

  // Preferred alignment. Optional, defaults to the ABI alignment.
  Align PrefAlign = ABIAlign;
  if (Components.size() > 2)
    if (Error Err = parseAlignment(Components[2], PrefAlign, "preferred"))
      return Err;

  if (PrefAlign < ABIAlign)
    return createStringError(
        "preferred alignment cannot be less than the ABI alignment");

  setPrimitiveSpec(Specifier, BitWidth, ABIAlign, PrefAlign);
  return Error::success();
}

Error DataLayout::parseAggregateSpec(StringRef Spec) {
  // a<size>:<abi>[:<pref>]
  SmallVector<StringRef, 3> Components;
  assert(Spec.front() == 'a');
  Spec.drop_front().split(Components, ':');

  if (Components.size() < 2 || Components.size() > 3)
    return createSpecFormatError("a:<abi>[:<pref>]");

  // According to LangRef, <size> component must be absent altogether.
  // For backward compatibility, allow it to be specified, but require
  // it to be zero.
  if (!Components[0].empty()) {
    unsigned BitWidth;
    if (!to_integer(Components[0], BitWidth, 10) || BitWidth != 0)
      return createStringError("size must be zero");
  }

  // ABI alignment. Required. Can be zero, meaning use one byte alignment.
  Align ABIAlign;
  if (Error Err =
          parseAlignment(Components[1], ABIAlign, "ABI", /*AllowZero=*/true))
    return Err;

  // Preferred alignment. Optional, defaults to the ABI alignment.
  Align PrefAlign = ABIAlign;
  if (Components.size() > 2)
    if (Error Err = parseAlignment(Components[2], PrefAlign, "preferred"))
      return Err;

  if (PrefAlign < ABIAlign)
    return createStringError(
        "preferred alignment cannot be less than the ABI alignment");

  StructABIAlignment = ABIAlign;
  StructPrefAlignment = PrefAlign;
  return Error::success();
}

Error DataLayout::parsePointerSpec(
    StringRef Spec, SmallDenseSet<StringRef, 8> &AddrSpaceNames) {
  // p[<n>]:<size>:<abi>[:<pref>[:<idx>]]
  SmallVector<StringRef, 5> Components;
  assert(Spec.front() == 'p');
  Spec.drop_front().split(Components, ':');

  if (Components.size() < 3 || Components.size() > 5)
    return createSpecFormatError("p[<n>]:<size>:<abi>[:<pref>[:<idx>]]");

  // Address space. Optional, defaults to 0.
  unsigned AddrSpace = 0;
  bool ExternalState = false;
  bool UnstableRepr = false;
  // Null pointer value flags: default, z = all-zeros, o = all-ones.
  enum class NullPtrKind { Default, Zero, AllOnes };
  NullPtrKind NullPtrFlag = NullPtrKind::Default;
  StringRef AddrSpaceName;
  StringRef AddrSpaceStr = Components[0];
  while (!AddrSpaceStr.empty()) {
    char C = AddrSpaceStr.front();
    if (C == 'e') {
      ExternalState = true;
    } else if (C == 'u') {
      UnstableRepr = true;
    } else if (C == 'z') {
      if (NullPtrFlag != NullPtrKind::Default)
        return createStringError("only one of 'z' or 'o' may be specified");
      NullPtrFlag = NullPtrKind::Zero;
    } else if (C == 'o') {
      if (NullPtrFlag != NullPtrKind::Default)
        return createStringError("only one of 'z' or 'o' may be specified");
      NullPtrFlag = NullPtrKind::AllOnes;
    } else if (isAlpha(C)) {
      return createStringError("'%c' is not a valid pointer specification flag",
                               C);
    } else {
      break; // not a valid flag, remaining must be the address space number.
    }
    AddrSpaceStr = AddrSpaceStr.drop_front(1);
  }
  if (!AddrSpaceStr.empty())
    if (Error Err =
            parseAddrSpaceAndName(AddrSpaceStr, AddrSpace, AddrSpaceName))
      return Err; // Failed to parse the remaining characters as a number
  if (AddrSpace == 0 && (ExternalState || UnstableRepr))
    return createStringError(
        "address space 0 cannot be unstable or have external state");

  // Check for duplicate address space names.
  if (!AddrSpaceName.empty() && !AddrSpaceNames.insert(AddrSpaceName).second)
    return createStringError("address space name `" + AddrSpaceName +
                             "` already used");

  // Size. Required, cannot be zero.
  unsigned BitWidth;
  if (Error Err = parseSize(Components[1], BitWidth, "pointer size"))
    return Err;

  // ABI alignment. Required, cannot be zero.
  Align ABIAlign;
  if (Error Err = parseAlignment(Components[2], ABIAlign, "ABI"))
    return Err;

  // Preferred alignment. Optional, defaults to the ABI alignment.
  // Cannot be zero.
  Align PrefAlign = ABIAlign;
  if (Components.size() > 3)
    if (Error Err = parseAlignment(Components[3], PrefAlign, "preferred"))
      return Err;

  if (PrefAlign < ABIAlign)
    return createStringError(
        "preferred alignment cannot be less than the ABI alignment");

  // Index size. Optional, defaults to pointer size. Cannot be zero.
  unsigned IndexBitWidth = BitWidth;
  if (Components.size() > 4)
    if (Error Err = parseSize(Components[4], IndexBitWidth, "index size"))
      return Err;

  if (IndexBitWidth > BitWidth)
    return createStringError(
        "index size cannot be larger than the pointer size");

  APInt NullPtrValue = NullPtrFlag == NullPtrKind::AllOnes
                           ? APInt::getAllOnes(BitWidth)
                           : APInt::getZero(BitWidth);

  setPointerSpec(AddrSpace, BitWidth, ABIAlign, PrefAlign, IndexBitWidth,
                 UnstableRepr, ExternalState, AddrSpaceName, NullPtrValue);
  return Error::success();
}

Error DataLayout::parseSpecification(
    StringRef Spec, SmallVectorImpl<unsigned> &NonIntegralAddressSpaces,
    SmallDenseSet<StringRef, 8> &AddrSpaceNames) {
  // The "ni" specifier is the only two-character specifier. Handle it first.
  if (Spec.starts_with("ni")) {
    // ni:<address space>[:<address space>]...
    StringRef Rest = Spec.drop_front(2);

    // Drop the first ':', then split the rest of the string the usual way.
    if (!Rest.consume_front(":"))
      return createSpecFormatError("ni:<address space>[:<address space>]...");

    for (StringRef Str : split(Rest, ':')) {
      unsigned AddrSpace;
      if (Error Err = parseAddrSpace(Str, AddrSpace))
        return Err;
      if (AddrSpace == 0)
        return createStringError("address space 0 cannot be non-integral");
      NonIntegralAddressSpaces.push_back(AddrSpace);
    }
    return Error::success();
  }

  if (Spec == "ve") {
    VectorsAreElementAligned = true;
    return Error::success();
  }

  // The rest of the specifiers are single-character.
  assert(!Spec.empty() && "Empty specification is handled by the caller");
  char Specifier = Spec.front();

  if (Specifier == 'i' || Specifier == 'f' || Specifier == 'v')
    return parsePrimitiveSpec(Spec);

  if (Specifier == 'a')
    return parseAggregateSpec(Spec);

  if (Specifier == 'p')
    return parsePointerSpec(Spec, AddrSpaceNames);

  StringRef Rest = Spec.drop_front();
  switch (Specifier) {
  case 's':
    // Deprecated, but ignoring here to preserve loading older textual llvm
    // ASM file
    break;
  case 'e':
  case 'E':
    if (!Rest.empty())
      return createStringError(
          "malformed specification, must be just 'e' or 'E'");
    BigEndian = Specifier == 'E';
    break;
  case 'n': // Native integer types.
    // n<size>[:<size>]...
    for (StringRef Str : split(Rest, ':')) {
      unsigned BitWidth;
      if (Error Err = parseSize(Str, BitWidth))
        return Err;
      LegalIntWidths.push_back(BitWidth);
    }
    break;
  case 'S': { // Stack natural alignment.
    // S<size>
    if (Rest.empty())
      return createSpecFormatError("S<size>");
    Align Alignment;
    if (Error Err = parseAlignment(Rest, Alignment, "stack natural"))
      return Err;
    StackNaturalAlign = Alignment;
    break;
  }
  case 'F': {
    // F<type><abi>
    if (Rest.empty())
      return createSpecFormatError("F<type><abi>");
    char Type = Rest.front();
    Rest = Rest.drop_front();
    switch (Type) {
    case 'i':
      TheFunctionPtrAlignType = FunctionPtrAlignType::Independent;
      break;
    case 'n':
      TheFunctionPtrAlignType = FunctionPtrAlignType::MultipleOfFunctionAlign;
      break;
    default:
      return createStringError("unknown function pointer alignment type '" +
                               Twine(Type) + "'");
    }
    Align Alignment;
    if (Error Err = parseAlignment(Rest, Alignment, "ABI"))
      return Err;
    FunctionPtrAlign = Alignment;
    break;
  }
  case 'P': { // Function address space.
    if (Rest.empty())
      return createSpecFormatError("P<address space>");
    if (Error Err = parseAddrSpace(Rest, ProgramAddrSpace))
      return Err;
    break;
  }
  case 'A': { // Default stack/alloca address space.
    if (Rest.empty())
      return createSpecFormatError("A<address space>");
    if (Error Err = parseAddrSpace(Rest, AllocaAddrSpace))
      return Err;
    break;
  }
  case 'G': { // Default address space for global variables.
    if (Rest.empty())
      return createSpecFormatError("G<address space>");
    if (Error Err = parseAddrSpace(Rest, DefaultGlobalsAddrSpace))
      return Err;
    break;
  }
  case 'm':
    if (!Rest.consume_front(":") || Rest.empty())
      return createSpecFormatError("m:<mangling>");
    if (Rest.size() > 1)
      return createStringError("unknown mangling mode");
    switch (Rest[0]) {
    default:
      return createStringError("unknown mangling mode");
    case 'e':
      ManglingMode = MM_ELF;
      break;
    case 'l':
      ManglingMode = MM_GOFF;
      break;
    case 'o':
      ManglingMode = MM_MachO;
      break;
    case 'm':
      ManglingMode = MM_Mips;
      break;
    case 'w':
      ManglingMode = MM_WinCOFF;
      break;
    case 'x':
      ManglingMode = MM_WinCOFFX86;
      break;
    case 'a':
      ManglingMode = MM_XCOFF;
      break;
    }
    break;
  default:
    return createStringError("unknown specifier '" + Twine(Specifier) + "'");
  }

  return Error::success();
}

Error DataLayout::parseLayoutString(StringRef LayoutString) {
  StringRepresentation = LayoutString.str();

  if (LayoutString.empty())
    return Error::success();

  // Split the data layout string into specifications separated by '-' and
  // parse each specification individually, updating internal data structures.
  SmallVector<unsigned, 8> NonIntegralAddressSpaces;
  SmallDenseSet<StringRef, 8> AddessSpaceNames;
  for (StringRef Spec : split(StringRepresentation, '-')) {
    if (Spec.empty())
      return createStringError("empty specification is not allowed");
    if (Error Err = parseSpecification(Spec, NonIntegralAddressSpaces,
                                       AddessSpaceNames))
      return Err;
  }
  // Mark all address spaces that were qualified as non-integral now. This has
  // to be done later since the non-integral property is not part of the data
  // layout pointer specification.
  for (unsigned AS : NonIntegralAddressSpaces) {
    // If there is no special spec for a given AS, getPointerSpec(AS) returns
    // the spec for AS0, and we then update that to mark it non-integral.
    const PointerSpec &PS = getPointerSpec(AS);
    setPointerSpec(AS, PS.BitWidth, PS.ABIAlign, PS.PrefAlign, PS.IndexBitWidth,
                   /*HasUnstableRepr=*/true, /*HasExternalState=*/false,
                   getAddressSpaceName(AS), PS.NullPtrValue);
  }

  return Error::success();
}

void DataLayout::setPrimitiveSpec(char Specifier, uint32_t BitWidth,
                                  Align ABIAlign, Align PrefAlign) {
  SmallVectorImpl<PrimitiveSpec> *Specs;
  switch (Specifier) {
  default:
    llvm_unreachable("Unexpected specifier");
  case 'i':
    Specs = &IntSpecs;
    break;
  case 'f':
    Specs = &FloatSpecs;
    break;
  case 'v':
    Specs = &VectorSpecs;
    break;
  }

  auto I = lower_bound(*Specs, BitWidth, LessPrimitiveBitWidth());
  if (I != Specs->end() && I->BitWidth == BitWidth) {
    // Update the abi, preferred alignments.
    I->ABIAlign = ABIAlign;
    I->PrefAlign = PrefAlign;
  } else {
    // Insert before I to keep the vector sorted.
    Specs->insert(I, PrimitiveSpec{BitWidth, ABIAlign, PrefAlign});
  }
}

const DataLayout::PointerSpec &
DataLayout::getPointerSpec(uint32_t AddrSpace) const {
  if (AddrSpace != 0) {
    auto I = lower_bound(PointerSpecs, AddrSpace, LessPointerAddrSpace());
    if (I != PointerSpecs.end() && I->AddrSpace == AddrSpace)
      return *I;
  }

  assert(PointerSpecs[0].AddrSpace == 0);
  return PointerSpecs[0];
}

void DataLayout::setPointerSpec(uint32_t AddrSpace, uint32_t BitWidth,
                                Align ABIAlign, Align PrefAlign,
                                uint32_t IndexBitWidth, bool HasUnstableRepr,
                                bool HasExternalState, StringRef AddrSpaceName,
                                APInt NullPtrValue) {
  auto I = lower_bound(PointerSpecs, AddrSpace, LessPointerAddrSpace());
  if (I == PointerSpecs.end() || I->AddrSpace != AddrSpace) {
    PointerSpecs.insert(I, PointerSpec{AddrSpace, BitWidth, ABIAlign, PrefAlign,
                                       IndexBitWidth, HasUnstableRepr,
                                       HasExternalState, AddrSpaceName.str(),
                                       std::move(NullPtrValue)});
  } else {
    I->BitWidth = BitWidth;
    I->ABIAlign = ABIAlign;
    I->PrefAlign = PrefAlign;
    I->IndexBitWidth = IndexBitWidth;
    I->HasUnstableRepresentation = HasUnstableRepr;
    I->HasExternalState = HasExternalState;
    I->AddrSpaceName = AddrSpaceName.str();
    I->NullPtrValue = std::move(NullPtrValue);
  }
}

Align DataLayout::getIntegerAlignment(uint32_t BitWidth,
                                      bool abi_or_pref) const {
  auto I = IntSpecs.begin();
  for (; I != IntSpecs.end(); ++I) {
    if (I->BitWidth >= BitWidth)
      break;
  }

  // If we don't have an exact match, use alignment of next larger integer
  // type. If there is none, use alignment of largest integer type by going
  // back one element.
  if (I == IntSpecs.end())
    --I;
  return abi_or_pref ? I->ABIAlign : I->PrefAlign;
}

DataLayout::~DataLayout() { delete static_cast<StructLayoutMap *>(LayoutMap); }

const StructLayout *DataLayout::getStructLayout(StructType *Ty) const {
  if (!LayoutMap)
    LayoutMap = new StructLayoutMap();

  StructLayoutMap *STM = static_cast<StructLayoutMap*>(LayoutMap);
  StructLayout *&SL = (*STM)[Ty];
  if (SL) return SL;

  // Otherwise, create the struct layout.  Because it is variable length, we
  // malloc it, then use placement new.
  StructLayout *L = (StructLayout *)safe_malloc(
      StructLayout::totalSizeToAlloc<TypeSize>(Ty->getNumElements()));

  // Set SL before calling StructLayout's ctor.  The ctor could cause other
  // entries to be added to TheMap, invalidating our reference.
  SL = L;

  new (L) StructLayout(Ty, *this);

  return L;
}

Align DataLayout::getPointerABIAlignment(unsigned AS) const {
  return getPointerSpec(AS).ABIAlign;
}

StringRef DataLayout::getAddressSpaceName(unsigned AS) const {
  return getPointerSpec(AS).AddrSpaceName;
}

std::optional<unsigned> DataLayout::getNamedAddressSpace(StringRef Name) const {
  auto II = llvm::find_if(PointerSpecs, [Name](const PointerSpec &PS) {
    return PS.AddrSpaceName == Name;
  });
  if (II != PointerSpecs.end())
    return II->AddrSpace;
  return std::nullopt;
}

Align DataLayout::getPointerPrefAlignment(unsigned AS) const {
  return getPointerSpec(AS).PrefAlign;
}

unsigned DataLayout::getPointerSize(unsigned AS) const {
  return divideCeil(getPointerSpec(AS).BitWidth, 8);
}

unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const {
  assert(Ty->isPtrOrPtrVectorTy() &&
         "This should only be called with a pointer or pointer vector type");
  Ty = Ty->getScalarType();
  return getPointerSizeInBits(cast<PointerType>(Ty)->getAddressSpace());
}

unsigned DataLayout::getIndexSize(unsigned AS) const {
  return divideCeil(getPointerSpec(AS).IndexBitWidth, 8);
}

unsigned DataLayout::getIndexTypeSizeInBits(Type *Ty) const {
  assert(Ty->isPtrOrPtrVectorTy() &&
         "This should only be called with a pointer or pointer vector type");
  Ty = Ty->getScalarType();
  return getIndexSizeInBits(cast<PointerType>(Ty)->getAddressSpace());
}

/*!
  \param abi_or_pref Flag that determines which alignment is returned. true
  returns the ABI alignment, false returns the preferred alignment.
  \param Ty The underlying type for which alignment is determined.

  Get the ABI (\a abi_or_pref == true) or preferred alignment (\a abi_or_pref
  == false) for the requested type \a Ty.
 */
Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
  assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
  switch (Ty->getTypeID()) {
  // Early escape for the non-numeric types.
  case Type::LabelTyID:
    return abi_or_pref ? getPointerABIAlignment(0) : getPointerPrefAlignment(0);
  case Type::PointerTyID: {
    unsigned AS = cast<PointerType>(Ty)->getAddressSpace();
    return abi_or_pref ? getPointerABIAlignment(AS)
                       : getPointerPrefAlignment(AS);
    }
  case Type::ArrayTyID:
    return getAlignment(cast<ArrayType>(Ty)->getElementType(), abi_or_pref);

  case Type::StructTyID: {
    // Packed structure types always have an ABI alignment of one.
    if (cast<StructType>(Ty)->isPacked() && abi_or_pref)
      return Align(1);

    // Get the layout annotation... which is lazily created on demand.
    const StructLayout *Layout = getStructLayout(cast<StructType>(Ty));
    const Align Align = abi_or_pref ? StructABIAlignment : StructPrefAlignment;
    return std::max(Align, Layout->getAlignment());
  }
  case Type::ByteTyID:
    // The byte type has the same alignment as the equally sized integer type.
    return getIntegerAlignment(Ty->getByteBitWidth(), abi_or_pref);
  case Type::IntegerTyID:
    return getIntegerAlignment(Ty->getIntegerBitWidth(), abi_or_pref);
  case Type::HalfTyID:
  case Type::BFloatTyID:
  case Type::FloatTyID:
  case Type::DoubleTyID:
  // PPC_FP128TyID and FP128TyID have different data contents, but the
  // same size and alignment, so they look the same here.
  case Type::PPC_FP128TyID:
  case Type::FP128TyID:
  case Type::X86_FP80TyID: {
    unsigned BitWidth = getTypeSizeInBits(Ty).getFixedValue();
    auto I = lower_bound(FloatSpecs, BitWidth, LessPrimitiveBitWidth());
    if (I != FloatSpecs.end() && I->BitWidth == BitWidth)
      return abi_or_pref ? I->ABIAlign : I->PrefAlign;

    // If we still couldn't find a reasonable default alignment, fall back
    // to a simple heuristic that the alignment is the first power of two
    // greater-or-equal to the store size of the type.  This is a reasonable
    // approximation of reality, and if the user wanted something less
    // less conservative, they should have specified it explicitly in the data
    // layout.
    return Align(PowerOf2Ceil(BitWidth / 8));
  }
  case Type::FixedVectorTyID:
  case Type::ScalableVectorTyID: {
    unsigned BitWidth = getTypeSizeInBits(Ty).getKnownMinValue();
    auto I = lower_bound(VectorSpecs, BitWidth, LessPrimitiveBitWidth());
    if (I != VectorSpecs.end() && I->BitWidth == BitWidth)
      return abi_or_pref ? I->ABIAlign : I->PrefAlign;

    if (vectorsAreElementAligned())
      return getAlignment(cast<VectorType>(Ty)->getElementType(), abi_or_pref);

    // By default, use natural alignment for vector types. This is consistent
    // with what clang and llvm-gcc do.
    //
    // We're only calculating a natural alignment, so it doesn't have to be
    // based on the full size for scalable vectors. Using the minimum element
    // count should be enough here.
    return Align(PowerOf2Ceil(getTypeStoreSize(Ty).getKnownMinValue()));
  }
  case Type::X86_AMXTyID:
    return Align(64);
  case Type::TargetExtTyID: {
    Type *LayoutTy = cast<TargetExtType>(Ty)->getLayoutType();
    return getAlignment(LayoutTy, abi_or_pref);
  }
  default:
    llvm_unreachable("Bad type for getAlignment!!!");
  }
}

TypeSize DataLayout::getTypeAllocSize(Type *Ty) const {
  switch (Ty->getTypeID()) {
  case Type::ArrayTyID: {
    // The alignment of the array is the alignment of the element, so there
    // is no need for further adjustment.
    auto *ATy = cast<ArrayType>(Ty);
    return ATy->getNumElements() * getTypeAllocSize(ATy->getElementType());
  }
  case Type::StructTyID: {
    const StructLayout *Layout = getStructLayout(cast<StructType>(Ty));
    TypeSize Size = Layout->getSizeInBytes();

    if (cast<StructType>(Ty)->isPacked())
      return Size;

    Align A = std::max(StructABIAlignment, Layout->getAlignment());
    return alignTo(Size, A.value());
  }
  case Type::IntegerTyID: {
    unsigned BitWidth = Ty->getIntegerBitWidth();
    TypeSize Size = TypeSize::getFixed(divideCeil(BitWidth, 8));
    Align A = getIntegerAlignment(BitWidth, /*ABI=*/true);
    return alignTo(Size, A.value());
  }
  case Type::PointerTyID: {
    unsigned AS = Ty->getPointerAddressSpace();
    TypeSize Size = TypeSize::getFixed(getPointerSize(AS));
    return alignTo(Size, getPointerABIAlignment(AS).value());
  }
  case Type::TargetExtTyID: {
    Type *LayoutTy = cast<TargetExtType>(Ty)->getLayoutType();
    return getTypeAllocSize(LayoutTy);
  }
  default:
    return alignTo(getTypeStoreSize(Ty), getABITypeAlign(Ty).value());
  }
}

Align DataLayout::getABITypeAlign(Type *Ty) const {
  return getAlignment(Ty, true);
}

Align DataLayout::getPrefTypeAlign(Type *Ty) const {
  return getAlignment(Ty, false);
}

IntegerType *DataLayout::getIntPtrType(LLVMContext &C,
                                       unsigned AddressSpace) const {
  return IntegerType::get(C, getPointerSizeInBits(AddressSpace));
}

Type *DataLayout::getIntPtrType(Type *Ty) const {
  assert(Ty->isPtrOrPtrVectorTy() &&
         "Expected a pointer or pointer vector type.");
  unsigned NumBits = getPointerTypeSizeInBits(Ty);
  IntegerType *IntTy = IntegerType::get(Ty->getContext(), NumBits);
  if (VectorType *VecTy = dyn_cast<VectorType>(Ty))
    return VectorType::get(IntTy, VecTy);
  return IntTy;
}

ByteType *DataLayout::getBytePtrType(LLVMContext &C,
                                     unsigned AddressSpace) const {
  return ByteType::get(C, getPointerSizeInBits(AddressSpace));
}

Type *DataLayout::getBytePtrType(Type *Ty) const {
  assert(Ty->isPtrOrPtrVectorTy() &&
         "Expected a pointer or pointer vector type.");
  unsigned NumBits = getPointerTypeSizeInBits(Ty);
  ByteType *ByteTy = ByteType::get(Ty->getContext(), NumBits);
  if (VectorType *VecTy = dyn_cast<VectorType>(Ty))
    return VectorType::get(ByteTy, VecTy);
  return ByteTy;
}

Type *DataLayout::getSmallestLegalIntType(LLVMContext &C, unsigned Width) const {
  for (unsigned LegalIntWidth : LegalIntWidths)
    if (Width <= LegalIntWidth)
      return Type::getIntNTy(C, LegalIntWidth);
  return nullptr;
}

unsigned DataLayout::getLargestLegalIntTypeSizeInBits() const {
  auto Max = llvm::max_element(LegalIntWidths);
  return Max != LegalIntWidths.end() ? *Max : 0;
}

IntegerType *DataLayout::getIndexType(LLVMContext &C,
                                      unsigned AddressSpace) const {
  return IntegerType::get(C, getIndexSizeInBits(AddressSpace));
}

Type *DataLayout::getIndexType(Type *Ty) const {
  assert(Ty->isPtrOrPtrVectorTy() &&
         "Expected a pointer or pointer vector type.");
  unsigned NumBits = getIndexTypeSizeInBits(Ty);
  IntegerType *IntTy = IntegerType::get(Ty->getContext(), NumBits);
  if (VectorType *VecTy = dyn_cast<VectorType>(Ty))
    return VectorType::get(IntTy, VecTy);
  return IntTy;
}

int64_t DataLayout::getIndexedOffsetInType(Type *ElemTy,
                                           ArrayRef<Value *> Indices) const {
  int64_t Result = 0;

  generic_gep_type_iterator<Value* const*>
    GTI = gep_type_begin(ElemTy, Indices),
    GTE = gep_type_end(ElemTy, Indices);
  for (; GTI != GTE; ++GTI) {
    Value *Idx = GTI.getOperand();
    if (StructType *STy = GTI.getStructTypeOrNull()) {
      assert(Idx->getType()->isIntegerTy(32) && "Illegal struct idx");
      unsigned FieldNo = cast<ConstantInt>(Idx)->getZExtValue();

      // Get structure layout information...
      const StructLayout *Layout = getStructLayout(STy);

      // Add in the offset, as calculated by the structure layout info...
      Result += Layout->getElementOffset(FieldNo);
    } else {
      if (int64_t ArrayIdx = cast<ConstantInt>(Idx)->getSExtValue())
        Result += ArrayIdx * GTI.getSequentialElementStride(*this);
    }
  }

  return Result;
}

static APInt getElementIndex(TypeSize ElemSize, APInt &Offset) {
  // Skip over scalable or zero size elements. Also skip element sizes larger
  // than the positive index space, because the arithmetic below may not be
  // correct in that case.
  unsigned BitWidth = Offset.getBitWidth();
  if (ElemSize.isScalable() || ElemSize == 0 ||
      !isUIntN(BitWidth - 1, ElemSize)) {
    return APInt::getZero(BitWidth);
  }

  uint64_t FixedElemSize = ElemSize.getFixedValue();
  APInt Index = Offset.sdiv(FixedElemSize);
  Offset -= Index * FixedElemSize;
  if (Offset.isNegative()) {
    // Prefer a positive remaining offset to allow struct indexing.
    --Index;
    Offset += FixedElemSize;
    assert(Offset.isNonNegative() && "Remaining offset shouldn't be negative");
  }
  return Index;
}

std::optional<APInt> DataLayout::getGEPIndexForOffset(Type *&ElemTy,
                                                      APInt &Offset) const {
  if (auto *ArrTy = dyn_cast<ArrayType>(ElemTy)) {
    ElemTy = ArrTy->getElementType();
    return getElementIndex(getTypeAllocSize(ElemTy), Offset);
  }

  if (isa<VectorType>(ElemTy)) {
    // Vector GEPs are partially broken (e.g. for overaligned element types),
    // and may be forbidden in the future, so avoid generating GEPs into
    // vectors. See https://discourse.llvm.org/t/67497
    return std::nullopt;
  }

  if (auto *STy = dyn_cast<StructType>(ElemTy)) {
    const StructLayout *SL = getStructLayout(STy);
    uint64_t IntOffset = Offset.getZExtValue();
    if (IntOffset >= SL->getSizeInBytes())
      return std::nullopt;

    unsigned Index = SL->getElementContainingOffset(IntOffset);
    Offset -= SL->getElementOffset(Index);
    ElemTy = STy->getElementType(Index);
    return APInt(32, Index);
  }

  // Non-aggregate type.
  return std::nullopt;
}

SmallVector<APInt> DataLayout::getGEPIndicesForOffset(Type *&ElemTy,
                                                      APInt &Offset) const {
  assert(ElemTy->isSized() && "Element type must be sized");
  SmallVector<APInt> Indices;
  Indices.push_back(getElementIndex(getTypeAllocSize(ElemTy), Offset));
  while (Offset != 0) {
    std::optional<APInt> Index = getGEPIndexForOffset(ElemTy, Offset);
    if (!Index)
      break;
    Indices.push_back(*Index);
  }

  return Indices;
}

/// getPreferredAlign - Return the preferred alignment of the specified global.
/// This includes an explicitly requested alignment (if the global has one).
Align DataLayout::getPreferredAlign(const GlobalVariable *GV) const {
  MaybeAlign GVAlignment = GV->getAlign();
  // If a section is specified, always precisely honor explicit alignment,
  // so we don't insert padding into a section we don't control.
  if (GVAlignment && GV->hasSection())
    return *GVAlignment;

  // If no explicit alignment is specified, compute the alignment based on
  // the IR type. If an alignment is specified, increase it to match the ABI
  // alignment of the IR type.
  //
  // FIXME: Not sure it makes sense to use the alignment of the type if
  // there's already an explicit alignment specification.
  Type *ElemType = GV->getValueType();
  Align Alignment = getPrefTypeAlign(ElemType);
  if (GVAlignment) {
    if (*GVAlignment >= Alignment)
      Alignment = *GVAlignment;
    else
      Alignment = std::max(*GVAlignment, getABITypeAlign(ElemType));
  }

  // If no explicit alignment is specified, and the global is large, increase
  // the alignment to 16.
  // FIXME: Why 16, specifically?
  if (GV->hasInitializer() && !GVAlignment) {
    if (Alignment < Align(16)) {
      // If the global is not external, see if it is large.  If so, give it a
      // larger alignment.
      if (getTypeSizeInBits(ElemType) > 128)
        Alignment = Align(16); // 16-byte alignment.
    }
  }
  return Alignment;
}
