//===- Module.cpp - Implement the Module class ----------------------------===//
//
// 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 implements the Module class for the IR library.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/Module.h"
#include "SymbolTableListTraitsImpl.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Comdat.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GVMaterializer.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalIFunc.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/ModuleSummaryIndex.h"
#include "llvm/IR/SymbolTableListTraits.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/TypeFinder.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/RandomNumberGenerator.h"
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/VersionTuple.h"
#include <cassert>
#include <cstdint>
#include <memory>
#include <optional>
#include <utility>
#include <vector>

using namespace llvm;

//===----------------------------------------------------------------------===//
// Methods to implement the globals and functions lists.
//

// Explicit instantiations of SymbolTableListTraits since some of the methods
// are not in the public header file.
template class LLVM_EXPORT_TEMPLATE llvm::SymbolTableListTraits<Function>;
template class LLVM_EXPORT_TEMPLATE llvm::SymbolTableListTraits<GlobalVariable>;
template class LLVM_EXPORT_TEMPLATE llvm::SymbolTableListTraits<GlobalAlias>;
template class LLVM_EXPORT_TEMPLATE llvm::SymbolTableListTraits<GlobalIFunc>;

//===----------------------------------------------------------------------===//
// Primitive Module methods.
//

Module::Module(StringRef MID, LLVMContext &C)
    : Context(C), ValSymTab(std::make_unique<ValueSymbolTable>(-1)),
      ModuleID(std::string(MID)), SourceFileName(std::string(MID)) {
  Context.addModule(this);
}

Module &Module::operator=(Module &&Other) {
  assert(&Context == &Other.Context && "Module must be in the same Context");

  dropAllReferences();

  ModuleID = std::move(Other.ModuleID);
  SourceFileName = std::move(Other.SourceFileName);

  GlobalList.clear();
  GlobalList.splice(GlobalList.begin(), Other.GlobalList);

  FunctionList.clear();
  FunctionList.splice(FunctionList.begin(), Other.FunctionList);

  AliasList.clear();
  AliasList.splice(AliasList.begin(), Other.AliasList);

  IFuncList.clear();
  IFuncList.splice(IFuncList.begin(), Other.IFuncList);

  NamedMDList.clear();
  NamedMDList.splice(NamedMDList.begin(), Other.NamedMDList);
  for (NamedMDNode &NMD : NamedMDList)
    NMD.setParent(this);

  NamedMDSymTab = std::move(Other.NamedMDSymTab);
  ComdatSymTab = std::move(Other.ComdatSymTab);
  GlobalScopeAsm = std::move(Other.GlobalScopeAsm);
  OwnedMemoryBuffer = std::move(Other.OwnedMemoryBuffer);
  Materializer = std::move(Other.Materializer);
  TargetTriple = std::move(Other.TargetTriple);
  DL = std::move(Other.DL);
  CurrentIntrinsicIds = std::move(Other.CurrentIntrinsicIds);
  UniquedIntrinsicNames = std::move(Other.UniquedIntrinsicNames);
  ModuleFlags = std::move(Other.ModuleFlags);
  Context.addModule(this);
  return *this;
}

Module::~Module() {
  Context.removeModule(this);
  dropAllReferences();
  GlobalList.clear();
  FunctionList.clear();
  AliasList.clear();
  IFuncList.clear();
}

void Module::removeDebugIntrinsicDeclarations() {
  if (auto *DeclareIntrinsicFn =
          Intrinsic::getDeclarationIfExists(this, Intrinsic::dbg_declare)) {
    assert((!isMaterialized() || DeclareIntrinsicFn->hasZeroLiveUses()) &&
           "Debug declare intrinsic should have had uses removed.");
    DeclareIntrinsicFn->eraseFromParent();
  }
  if (auto *ValueIntrinsicFn =
          Intrinsic::getDeclarationIfExists(this, Intrinsic::dbg_value)) {
    assert((!isMaterialized() || ValueIntrinsicFn->hasZeroLiveUses()) &&
           "Debug value intrinsic should have had uses removed.");
    ValueIntrinsicFn->eraseFromParent();
  }
  if (auto *AssignIntrinsicFn =
          Intrinsic::getDeclarationIfExists(this, Intrinsic::dbg_assign)) {
    assert((!isMaterialized() || AssignIntrinsicFn->hasZeroLiveUses()) &&
           "Debug assign intrinsic should have had uses removed.");
    AssignIntrinsicFn->eraseFromParent();
  }
  if (auto *LabelntrinsicFn =
          Intrinsic::getDeclarationIfExists(this, Intrinsic::dbg_label)) {
    assert((!isMaterialized() || LabelntrinsicFn->hasZeroLiveUses()) &&
           "Debug label intrinsic should have had uses removed.");
    LabelntrinsicFn->eraseFromParent();
  }
}

std::unique_ptr<RandomNumberGenerator>
Module::createRNG(const StringRef Name) const {
  SmallString<32> Salt(Name);

  // This RNG is guaranteed to produce the same random stream only
  // when the Module ID and thus the input filename is the same. This
  // might be problematic if the input filename extension changes
  // (e.g. from .c to .bc or .ll).
  //
  // We could store this salt in NamedMetadata, but this would make
  // the parameter non-const. This would unfortunately make this
  // interface unusable by any Machine passes, since they only have a
  // const reference to their IR Module. Alternatively we can always
  // store salt metadata from the Module constructor.
  Salt += sys::path::filename(getModuleIdentifier());

  return std::unique_ptr<RandomNumberGenerator>(
      new RandomNumberGenerator(Salt));
}

/// getNamedValue - Return the first global value in the module with
/// the specified name, of arbitrary type.  This method returns null
/// if a global with the specified name is not found.
GlobalValue *Module::getNamedValue(StringRef Name) const {
  return cast_or_null<GlobalValue>(getValueSymbolTable().lookup(Name));
}

unsigned Module::getNumNamedValues() const {
  return getValueSymbolTable().size();
}

/// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
/// This ID is uniqued across modules in the current LLVMContext.
unsigned Module::getMDKindID(StringRef Name) const {
  return Context.getMDKindID(Name);
}

/// getMDKindNames - Populate client supplied SmallVector with the name for
/// custom metadata IDs registered in this LLVMContext.   ID #0 is not used,
/// so it is filled in as an empty string.
void Module::getMDKindNames(SmallVectorImpl<StringRef> &Result) const {
  return Context.getMDKindNames(Result);
}

void Module::getOperandBundleTags(SmallVectorImpl<StringRef> &Result) const {
  return Context.getOperandBundleTags(Result);
}

//===----------------------------------------------------------------------===//
// Methods for easy access to the functions in the module.
//

// getOrInsertFunction - Look up the specified function in the module symbol
// table.  If it does not exist, add a prototype for the function and return
// it.  This is nice because it allows most passes to get away with not handling
// the symbol table directly for this common task.
//
FunctionCallee Module::getOrInsertFunction(StringRef Name, FunctionType *Ty,
                                           AttributeList AttributeList) {
  // See if we have a definition for the specified function already.
  GlobalValue *F = getNamedValue(Name);
  if (!F) {
    // Nope, add it
    Function *New = Function::Create(Ty, GlobalVariable::ExternalLinkage,
                                     DL.getProgramAddressSpace(), Name, this);
    if (!New->isIntrinsic())       // Intrinsics get attrs set on construction
      New->setAttributes(AttributeList);
    return {Ty, New}; // Return the new prototype.
  }

  // Otherwise, we just found the existing function or a prototype.
  return {Ty, F};
}

FunctionCallee Module::getOrInsertFunction(StringRef Name, FunctionType *Ty) {
  return getOrInsertFunction(Name, Ty, AttributeList());
}

// getFunction - Look up the specified function in the module symbol table.
// If it does not exist, return null.
//
Function *Module::getFunction(StringRef Name) const {
  return dyn_cast_or_null<Function>(getNamedValue(Name));
}

//===----------------------------------------------------------------------===//
// Methods for easy access to the global variables in the module.
//

/// getGlobalVariable - Look up the specified global variable in the module
/// symbol table.  If it does not exist, return null.  The type argument
/// should be the underlying type of the global, i.e., it should not have
/// the top-level PointerType, which represents the address of the global.
/// If AllowLocal is set to true, this function will return types that
/// have an local. By default, these types are not returned.
///
GlobalVariable *Module::getGlobalVariable(StringRef Name,
                                          bool AllowLocal) const {
  if (GlobalVariable *Result =
      dyn_cast_or_null<GlobalVariable>(getNamedValue(Name)))
    if (AllowLocal || !Result->hasLocalLinkage())
      return Result;
  return nullptr;
}

/// getOrInsertGlobal - Look up the specified global in the module symbol table.
/// If it does not exist, add a declaration of the global and return it.
/// Otherwise, return the existing global.
GlobalVariable *Module::getOrInsertGlobal(
    StringRef Name, Type *Ty,
    function_ref<GlobalVariable *()> CreateGlobalCallback) {
  // See if we have a definition for the specified global already.
  GlobalVariable *GV = dyn_cast_or_null<GlobalVariable>(getNamedValue(Name));
  if (!GV)
    GV = CreateGlobalCallback();
  assert(GV && "The CreateGlobalCallback is expected to create a global");

  // Otherwise, we just found the existing function or a prototype.
  return GV;
}

// Overload to construct a global variable using its constructor's defaults.
GlobalVariable *Module::getOrInsertGlobal(StringRef Name, Type *Ty) {
  return getOrInsertGlobal(Name, Ty, [&] {
    return new GlobalVariable(*this, Ty, false, GlobalVariable::ExternalLinkage,
                              nullptr, Name);
  });
}

//===----------------------------------------------------------------------===//
// Methods for easy access to the global variables in the module.
//

// getNamedAlias - Look up the specified global in the module symbol table.
// If it does not exist, return null.
//
GlobalAlias *Module::getNamedAlias(StringRef Name) const {
  return dyn_cast_or_null<GlobalAlias>(getNamedValue(Name));
}

GlobalIFunc *Module::getNamedIFunc(StringRef Name) const {
  return dyn_cast_or_null<GlobalIFunc>(getNamedValue(Name));
}

/// getNamedMetadata - Return the first NamedMDNode in the module with the
/// specified name. This method returns null if a NamedMDNode with the
/// specified name is not found.
NamedMDNode *Module::getNamedMetadata(StringRef Name) const {
  return NamedMDSymTab.lookup(Name);
}

/// getOrInsertNamedMetadata - Return the first named MDNode in the module
/// with the specified name. This method returns a new NamedMDNode if a
/// NamedMDNode with the specified name is not found.
NamedMDNode *Module::getOrInsertNamedMetadata(StringRef Name) {
  NamedMDNode *&NMD = NamedMDSymTab[Name];
  if (!NMD) {
    NMD = new NamedMDNode(Name);
    NMD->setParent(this);
    insertNamedMDNode(NMD);
    if (Name == "llvm.module.flags")
      ModuleFlags = NMD;
  }
  return NMD;
}

/// eraseNamedMetadata - Remove the given NamedMDNode from this module and
/// delete it.
void Module::eraseNamedMetadata(NamedMDNode *NMD) {
  NamedMDSymTab.erase(NMD->getName());
  if (NMD == ModuleFlags)
    ModuleFlags = nullptr;
  eraseNamedMDNode(NMD);
}

bool Module::isValidModFlagBehavior(Metadata *MD, ModFlagBehavior &MFB) {
  if (ConstantInt *Behavior = mdconst::dyn_extract_or_null<ConstantInt>(MD)) {
    uint64_t Val = Behavior->getLimitedValue();
    if (Val >= ModFlagBehaviorFirstVal && Val <= ModFlagBehaviorLastVal) {
      MFB = static_cast<ModFlagBehavior>(Val);
      return true;
    }
  }
  return false;
}

/// getModuleFlagsMetadata - Returns the module flags in the provided vector.
void Module::
getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const {
  const NamedMDNode *ModFlags = getModuleFlagsMetadata();
  if (!ModFlags) return;

  for (const MDNode *Flag : ModFlags->operands()) {
    // The verifier will catch errors, so no need to check them here.
    auto *MFBConstant = mdconst::extract<ConstantInt>(Flag->getOperand(0));
    auto MFB = static_cast<ModFlagBehavior>(MFBConstant->getLimitedValue());
    MDString *Key = cast<MDString>(Flag->getOperand(1));
    Metadata *Val = Flag->getOperand(2);
    Flags.push_back(ModuleFlagEntry(MFB, Key, Val));
  }
}

/// Return the corresponding value if Key appears in module flags, otherwise
/// return null.
Metadata *Module::getModuleFlag(StringRef Key) const {
  const NamedMDNode *ModFlags = getModuleFlagsMetadata();
  if (!ModFlags)
    return nullptr;
  for (const MDNode *Flag : ModFlags->operands()) {
    if (Key == cast<MDString>(Flag->getOperand(1))->getString())
      return Flag->getOperand(2);
  }
  return nullptr;
}

/// getOrInsertModuleFlagsMetadata - Returns the NamedMDNode in the module that
/// represents module-level flags. If module-level flags aren't found, it
/// creates the named metadata that contains them.
NamedMDNode *Module::getOrInsertModuleFlagsMetadata() {
  if (ModuleFlags)
    return ModuleFlags;
  return getOrInsertNamedMetadata("llvm.module.flags");
}

/// addModuleFlag - Add a module-level flag to the module-level flags
/// metadata. It will create the module-level flags named metadata if it doesn't
/// already exist.
void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key,
                           Metadata *Val) {
  Type *Int32Ty = Type::getInt32Ty(Context);
  Metadata *Ops[3] = {
      ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Behavior)),
      MDString::get(Context, Key), Val};
  getOrInsertModuleFlagsMetadata()->addOperand(MDNode::get(Context, Ops));
}
void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key,
                           Constant *Val) {
  addModuleFlag(Behavior, Key, ConstantAsMetadata::get(Val));
}
void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key,
                           uint64_t Val) {
  Type *Int64Ty = Type::getInt64Ty(Context);
  addModuleFlag(Behavior, Key, ConstantInt::get(Int64Ty, Val));
}
void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key,
                           uint32_t Val) {
  Type *Int32Ty = Type::getInt32Ty(Context);
  addModuleFlag(Behavior, Key, ConstantInt::get(Int32Ty, Val));
}
void Module::addModuleFlag(MDNode *Node) {
  assert(Node->getNumOperands() == 3 &&
         "Invalid number of operands for module flag!");
  assert(mdconst::hasa<ConstantInt>(Node->getOperand(0)) &&
         isa<MDString>(Node->getOperand(1)) &&
         "Invalid operand types for module flag!");
  getOrInsertModuleFlagsMetadata()->addOperand(Node);
}

void Module::setModuleFlag(ModFlagBehavior Behavior, StringRef Key,
                           Metadata *Val) {
  NamedMDNode *ModFlags = getOrInsertModuleFlagsMetadata();
  // Replace the flag if it already exists.
  for (unsigned i = 0; i < ModFlags->getNumOperands(); ++i) {
    MDNode *Flag = ModFlags->getOperand(i);
    if (cast<MDString>(Flag->getOperand(1))->getString() == Key) {
      Type *Int32Ty = Type::getInt32Ty(Context);
      Metadata *Ops[3] = {
          ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Behavior)),
          MDString::get(Context, Key), Val};
      ModFlags->setOperand(i, MDNode::get(Context, Ops));
      return;
    }
  }
  addModuleFlag(Behavior, Key, Val);
}
void Module::setModuleFlag(ModFlagBehavior Behavior, StringRef Key,
                           Constant *Val) {
  setModuleFlag(Behavior, Key, ConstantAsMetadata::get(Val));
}
void Module::setModuleFlag(ModFlagBehavior Behavior, StringRef Key,
                           uint64_t Val) {
  Type *Int64Ty = Type::getInt64Ty(Context);
  setModuleFlag(Behavior, Key, ConstantInt::get(Int64Ty, Val));
}
void Module::setModuleFlag(ModFlagBehavior Behavior, StringRef Key,
                           uint32_t Val) {
  Type *Int32Ty = Type::getInt32Ty(Context);
  setModuleFlag(Behavior, Key, ConstantInt::get(Int32Ty, Val));
}

void Module::setDataLayout(StringRef Desc) { DL = DataLayout(Desc); }

void Module::setDataLayout(const DataLayout &Other) { DL = Other; }

DICompileUnit *Module::debug_compile_units_iterator::operator*() const {
  return cast<DICompileUnit>(CUs->getOperand(Idx));
}
DICompileUnit *Module::debug_compile_units_iterator::operator->() const {
  return cast<DICompileUnit>(CUs->getOperand(Idx));
}

void Module::debug_compile_units_iterator::SkipNoDebugCUs() {
  while (CUs && (Idx < CUs->getNumOperands()) &&
         ((*this)->getEmissionKind() == DICompileUnit::NoDebug))
    ++Idx;
}

iterator_range<Module::global_object_iterator> Module::global_objects() {
  return concat<GlobalObject>(functions(), globals());
}
iterator_range<Module::const_global_object_iterator>
Module::global_objects() const {
  return concat<const GlobalObject>(functions(), globals());
}

iterator_range<Module::global_value_iterator> Module::global_values() {
  return concat<GlobalValue>(functions(), globals(), aliases(), ifuncs());
}
iterator_range<Module::const_global_value_iterator>
Module::global_values() const {
  return concat<const GlobalValue>(functions(), globals(), aliases(), ifuncs());
}

//===----------------------------------------------------------------------===//
// Methods to control the materialization of GlobalValues in the Module.
//
void Module::setMaterializer(GVMaterializer *GVM) {
  assert(!Materializer &&
         "Module already has a GVMaterializer.  Call materializeAll"
         " to clear it out before setting another one.");
  Materializer.reset(GVM);
}

Error Module::materialize(GlobalValue *GV) {
  if (!Materializer)
    return Error::success();

  return Materializer->materialize(GV);
}

Error Module::materializeAll() {
  if (!Materializer)
    return Error::success();
  std::unique_ptr<GVMaterializer> M = std::move(Materializer);
  return M->materializeModule();
}

Error Module::materializeMetadata() {
  llvm::TimeTraceScope timeScope("Materialize metadata");
  if (!Materializer)
    return Error::success();
  return Materializer->materializeMetadata();
}

//===----------------------------------------------------------------------===//
// Other module related stuff.
//

std::vector<StructType *> Module::getIdentifiedStructTypes() const {
  // If we have a materializer, it is possible that some unread function
  // uses a type that is currently not visible to a TypeFinder, so ask
  // the materializer which types it created.
  if (Materializer)
    return Materializer->getIdentifiedStructTypes();

  std::vector<StructType *> Ret;
  TypeFinder SrcStructTypes;
  SrcStructTypes.run(*this, true);
  Ret.assign(SrcStructTypes.begin(), SrcStructTypes.end());
  return Ret;
}

std::string Module::getUniqueIntrinsicName(StringRef BaseName, Intrinsic::ID Id,
                                           const FunctionType *Proto) {
  auto Encode = [&BaseName](unsigned Suffix) {
    return (Twine(BaseName) + "." + Twine(Suffix)).str();
  };

  {
    // fast path - the prototype is already known
    auto UinItInserted = UniquedIntrinsicNames.insert({{Id, Proto}, 0});
    if (!UinItInserted.second)
      return Encode(UinItInserted.first->second);
  }

  // Not known yet. A new entry was created with index 0. Check if there already
  // exists a matching declaration, or select a new entry.

  // Start looking for names with the current known maximum count (or 0).
  auto NiidItInserted = CurrentIntrinsicIds.insert({BaseName, 0});
  unsigned Count = NiidItInserted.first->second;

  // This might be slow if a whole population of intrinsics already existed, but
  // we cache the values for later usage.
  std::string NewName;
  while (true) {
    NewName = Encode(Count);
    GlobalValue *F = getNamedValue(NewName);
    if (!F) {
      // Reserve this entry for the new proto
      UniquedIntrinsicNames[{Id, Proto}] = Count;
      break;
    }

    // A declaration with this name already exists. Remember it.
    FunctionType *FT = dyn_cast<FunctionType>(F->getValueType());
    auto UinItInserted = UniquedIntrinsicNames.insert({{Id, FT}, Count});
    if (FT == Proto) {
      // It was a declaration for our prototype. This entry was allocated in the
      // beginning. Update the count to match the existing declaration.
      UinItInserted.first->second = Count;
      break;
    }

    ++Count;
  }

  NiidItInserted.first->second = Count + 1;

  return NewName;
}

// dropAllReferences() - This function causes all the subelements to "let go"
// of all references that they are maintaining.  This allows one to 'delete' a
// whole module at a time, even though there may be circular references... first
// all references are dropped, and all use counts go to zero.  Then everything
// is deleted for real.  Note that no operations are valid on an object that
// has "dropped all references", except operator delete.
//
void Module::dropAllReferences() {
  for (Function &F : *this)
    F.dropAllReferences();

  for (GlobalVariable &GV : globals())
    GV.dropAllReferences();

  for (GlobalAlias &GA : aliases())
    GA.dropAllReferences();

  for (GlobalIFunc &GIF : ifuncs())
    GIF.dropAllReferences();
}

unsigned Module::getNumberRegisterParameters() const {
  auto *Val =
      cast_or_null<ConstantAsMetadata>(getModuleFlag("NumRegisterParameters"));
  if (!Val)
    return 0;
  return cast<ConstantInt>(Val->getValue())->getZExtValue();
}

unsigned Module::getDwarfVersion() const {
  auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("Dwarf Version"));
  if (!Val)
    return 0;
  return cast<ConstantInt>(Val->getValue())->getZExtValue();
}

bool Module::isDwarf64() const {
  auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("DWARF64"));
  return Val && cast<ConstantInt>(Val->getValue())->isOne();
}

unsigned Module::getCodeViewFlag() const {
  auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("CodeView"));
  if (!Val)
    return 0;
  return cast<ConstantInt>(Val->getValue())->getZExtValue();
}

unsigned Module::getInstructionCount() const {
  unsigned NumInstrs = 0;
  for (const Function &F : FunctionList)
    NumInstrs += F.getInstructionCount();
  return NumInstrs;
}

Comdat *Module::getOrInsertComdat(StringRef Name) {
  auto &Entry = *ComdatSymTab.insert(std::make_pair(Name, Comdat())).first;
  Entry.second.Name = &Entry;
  return &Entry.second;
}

PICLevel::Level Module::getPICLevel() const {
  auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("PIC Level"));

  if (!Val)
    return PICLevel::NotPIC;

  return static_cast<PICLevel::Level>(
      cast<ConstantInt>(Val->getValue())->getZExtValue());
}

void Module::setPICLevel(PICLevel::Level PL) {
  // The merge result of a non-PIC object and a PIC object can only be reliably
  // used as a non-PIC object, so use the Min merge behavior.
  addModuleFlag(ModFlagBehavior::Min, "PIC Level", PL);
}

PIELevel::Level Module::getPIELevel() const {
  auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("PIE Level"));

  if (!Val)
    return PIELevel::Default;

  return static_cast<PIELevel::Level>(
      cast<ConstantInt>(Val->getValue())->getZExtValue());
}

void Module::setPIELevel(PIELevel::Level PL) {
  addModuleFlag(ModFlagBehavior::Max, "PIE Level", PL);
}

std::optional<CodeModel::Model> Module::getCodeModel() const {
  auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("Code Model"));

  if (!Val)
    return std::nullopt;

  return static_cast<CodeModel::Model>(
      cast<ConstantInt>(Val->getValue())->getZExtValue());
}

void Module::setCodeModel(CodeModel::Model CL) {
  // Linking object files with different code models is undefined behavior
  // because the compiler would have to generate additional code (to span
  // longer jumps) if a larger code model is used with a smaller one.
  // Therefore we will treat attempts to mix code models as an error.
  addModuleFlag(ModFlagBehavior::Error, "Code Model", CL);
}

LongDoubleFormat Module::getLongDoubleFormat() const {
  if (auto *Val =
          dyn_cast_or_null<MDString>(getModuleFlag("long-double-type"))) {
    if (std::optional<LongDoubleFormat> Format =
            parseLongDoubleFormat(Val->getString()))
      return *Format;
  }

  return getTargetTriple().getDefaultLongDoubleFormat();
}

void Module::setLongDoubleFormat(LongDoubleFormat Format) {
  addModuleFlag(ModFlagBehavior::Error, "long-double-type",
                MDString::get(getContext(), getLongDoubleFormatName(Format)));
}

FloatABI::ABIType Module::getFloatABI() const {
  if (auto *Val = dyn_cast_or_null<MDString>(getModuleFlag("float-abi")))
    return *FloatABI::parseABIType(Val->getString());
  // Without an explicit flag, fall back to the ABI implied by the target
  // triple.
  return getTargetTriple().getDefaultFloatABI();
}

std::optional<uint64_t> Module::getLargeDataThreshold() const {
  auto *Val =
      cast_or_null<ConstantAsMetadata>(getModuleFlag("Large Data Threshold"));

  if (!Val)
    return std::nullopt;

  return cast<ConstantInt>(Val->getValue())->getZExtValue();
}

void Module::setLargeDataThreshold(uint64_t Threshold) {
  // Since the large data threshold goes along with the code model, the merge
  // behavior is the same.
  addModuleFlag(ModFlagBehavior::Error, "Large Data Threshold",
                ConstantInt::get(Type::getInt64Ty(Context), Threshold));
}

void Module::setProfileSummary(Metadata *M, ProfileSummary::Kind Kind) {
  if (Kind == ProfileSummary::PSK_CSInstr)
    setModuleFlag(ModFlagBehavior::Error, "CSProfileSummary", M);
  else
    setModuleFlag(ModFlagBehavior::Error, "ProfileSummary", M);
}

Metadata *Module::getProfileSummary(bool IsCS) const {
  return (IsCS ? getModuleFlag("CSProfileSummary")
               : getModuleFlag("ProfileSummary"));
}

bool Module::getSemanticInterposition() const {
  Metadata *MF = getModuleFlag("SemanticInterposition");

  auto *Val = cast_or_null<ConstantAsMetadata>(MF);
  if (!Val)
    return false;

  return cast<ConstantInt>(Val->getValue())->getZExtValue();
}

void Module::setSemanticInterposition(bool SI) {
  addModuleFlag(ModFlagBehavior::Error, "SemanticInterposition", SI);
}

void Module::setOwnedMemoryBuffer(std::unique_ptr<MemoryBuffer> MB) {
  OwnedMemoryBuffer = std::move(MB);
}

bool Module::getRtLibUseGOT() const {
  auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("RtLibUseGOT"));
  return Val && (cast<ConstantInt>(Val->getValue())->getZExtValue() > 0);
}

void Module::setRtLibUseGOT() {
  addModuleFlag(ModFlagBehavior::Max, "RtLibUseGOT", 1);
}

bool Module::getDirectAccessExternalData() const {
  auto *Val = cast_or_null<ConstantAsMetadata>(
      getModuleFlag("direct-access-external-data"));
  if (Val)
    return cast<ConstantInt>(Val->getValue())->getZExtValue() > 0;
  return getPICLevel() == PICLevel::NotPIC;
}

void Module::setDirectAccessExternalData(bool Value) {
  addModuleFlag(ModFlagBehavior::Max, "direct-access-external-data", Value);
}

UWTableKind Module::getUwtable() const {
  if (auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("uwtable")))
    return UWTableKind(cast<ConstantInt>(Val->getValue())->getZExtValue());
  return UWTableKind::None;
}

void Module::setUwtable(UWTableKind Kind) {
  addModuleFlag(ModFlagBehavior::Max, "uwtable", uint32_t(Kind));
}

FramePointerKind Module::getFramePointer() const {
  auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("frame-pointer"));
  return static_cast<FramePointerKind>(
      Val ? cast<ConstantInt>(Val->getValue())->getZExtValue() : 0);
}

void Module::setFramePointer(FramePointerKind Kind) {
  addModuleFlag(ModFlagBehavior::Max, "frame-pointer", static_cast<int>(Kind));
}

bool Module::hasStackProtectorGuardRecord() const {
  auto *Val = cast_or_null<ConstantAsMetadata>(
      getModuleFlag("stack-protector-guard-record"));
  return Val && cast<ConstantInt>(Val->getValue())->isOne();
}

void Module::setStackProtectorGuardRecord(bool Flag) {
  addModuleFlag(ModFlagBehavior::Max, "stack-protector-guard-record",
                Flag ? 1 : 0);
}

StringRef Module::getStackProtectorGuard() const {
  Metadata *MD = getModuleFlag("stack-protector-guard");
  if (auto *MDS = dyn_cast_or_null<MDString>(MD))
    return MDS->getString();
  return {};
}

void Module::setStackProtectorGuard(StringRef Kind) {
  MDString *ID = MDString::get(getContext(), Kind);
  addModuleFlag(ModFlagBehavior::Error, "stack-protector-guard", ID);
}

StringRef Module::getStackProtectorGuardReg() const {
  Metadata *MD = getModuleFlag("stack-protector-guard-reg");
  if (auto *MDS = dyn_cast_or_null<MDString>(MD))
    return MDS->getString();
  return {};
}

void Module::setStackProtectorGuardReg(StringRef Reg) {
  MDString *ID = MDString::get(getContext(), Reg);
  addModuleFlag(ModFlagBehavior::Error, "stack-protector-guard-reg", ID);
}

StringRef Module::getStackProtectorGuardSymbol() const {
  Metadata *MD = getModuleFlag("stack-protector-guard-symbol");
  if (auto *MDS = dyn_cast_or_null<MDString>(MD))
    return MDS->getString();
  return {};
}

void Module::setStackProtectorGuardSymbol(StringRef Symbol) {
  MDString *ID = MDString::get(getContext(), Symbol);
  addModuleFlag(ModFlagBehavior::Error, "stack-protector-guard-symbol", ID);
}

int Module::getStackProtectorGuardOffset() const {
  Metadata *MD = getModuleFlag("stack-protector-guard-offset");
  if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD))
    return CI->getSExtValue();
  return INT_MAX;
}

void Module::setStackProtectorGuardOffset(int Offset) {
  addModuleFlag(ModFlagBehavior::Error, "stack-protector-guard-offset", Offset);
}

std::optional<unsigned> Module::getStackProtectorGuardValueWidth() const {
  Metadata *MD = getModuleFlag("stack-protector-guard-value-width");
  if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD))
    return CI->getZExtValue();
  return std::nullopt;
}

void Module::setStackProtectorGuardValueWidth(unsigned Width) {
  addModuleFlag(ModFlagBehavior::Error, "stack-protector-guard-value-width",
                Width);
}

unsigned Module::getOverrideStackAlignment() const {
  Metadata *MD = getModuleFlag("override-stack-alignment");
  if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD))
    return CI->getZExtValue();
  return 0;
}

unsigned Module::getMaxTLSAlignment() const {
  Metadata *MD = getModuleFlag("MaxTLSAlign");
  if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD))
    return CI->getZExtValue();
  return 0;
}

void Module::setOverrideStackAlignment(unsigned Align) {
  addModuleFlag(ModFlagBehavior::Error, "override-stack-alignment", Align);
}

static void addSDKVersionMD(const VersionTuple &V, Module &M, StringRef Name) {
  SmallVector<unsigned, 3> Entries;
  Entries.push_back(V.getMajor());
  if (auto Minor = V.getMinor()) {
    Entries.push_back(*Minor);
    if (auto Subminor = V.getSubminor())
      Entries.push_back(*Subminor);
    // Ignore the 'build' component as it can't be represented in the object
    // file.
  }
  M.addModuleFlag(Module::ModFlagBehavior::Warning, Name,
                  ConstantDataArray::get(M.getContext(), Entries));
}

void Module::setSDKVersion(const VersionTuple &V) {
  addSDKVersionMD(V, *this, "SDK Version");
}

static VersionTuple getSDKVersionMD(Metadata *MD) {
  auto *CM = dyn_cast_or_null<ConstantAsMetadata>(MD);
  if (!CM)
    return {};
  auto *Arr = dyn_cast_or_null<ConstantDataArray>(CM->getValue());
  if (!Arr)
    return {};
  auto getVersionComponent = [&](unsigned Index) -> std::optional<unsigned> {
    if (Index >= Arr->getNumElements())
      return std::nullopt;
    return (unsigned)Arr->getElementAsInteger(Index);
  };
  auto Major = getVersionComponent(0);
  if (!Major)
    return {};
  VersionTuple Result = VersionTuple(*Major);
  if (auto Minor = getVersionComponent(1)) {
    Result = VersionTuple(*Major, *Minor);
    if (auto Subminor = getVersionComponent(2)) {
      Result = VersionTuple(*Major, *Minor, *Subminor);
    }
  }
  return Result;
}

VersionTuple Module::getSDKVersion() const {
  return getSDKVersionMD(getModuleFlag("SDK Version"));
}

GlobalVariable *llvm::collectUsedGlobalVariables(
    const Module &M, SmallVectorImpl<GlobalValue *> &Vec, bool CompilerUsed) {
  const char *Name = CompilerUsed ? "llvm.compiler.used" : "llvm.used";
  GlobalVariable *GV = M.getGlobalVariable(Name);
  if (!GV || !GV->hasInitializer())
    return GV;

  const ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
  for (Value *Op : Init->operands()) {
    GlobalValue *G = cast<GlobalValue>(Op->stripPointerCasts());
    Vec.push_back(G);
  }
  return GV;
}

void Module::setPartialSampleProfileRatio(const ModuleSummaryIndex &Index) {
  if (auto *SummaryMD = getProfileSummary(/*IsCS*/ false)) {
    std::unique_ptr<ProfileSummary> ProfileSummary(
        ProfileSummary::getFromMD(SummaryMD));
    if (ProfileSummary) {
      if (ProfileSummary->getKind() != ProfileSummary::PSK_Sample ||
          !ProfileSummary->isPartialProfile())
        return;
      uint64_t BlockCount = Index.getBlockCount();
      uint32_t NumCounts = ProfileSummary->getNumCounts();
      if (!NumCounts)
        return;
      double Ratio = (double)BlockCount / NumCounts;
      ProfileSummary->setPartialProfileRatio(Ratio);
      setProfileSummary(ProfileSummary->getMD(getContext()),
                        ProfileSummary::PSK_Sample);
    }
  }
}

StringRef Module::getDarwinTargetVariantTriple() const {
  if (const auto *MD = getModuleFlag("darwin.target_variant.triple"))
    return cast<MDString>(MD)->getString();
  return "";
}

void Module::setDarwinTargetVariantTriple(StringRef T) {
  addModuleFlag(ModFlagBehavior::Warning, "darwin.target_variant.triple",
                MDString::get(getContext(), T));
}

VersionTuple Module::getDarwinTargetVariantSDKVersion() const {
  return getSDKVersionMD(getModuleFlag("darwin.target_variant.SDK Version"));
}

void Module::setDarwinTargetVariantSDKVersion(VersionTuple Version) {
  addSDKVersionMD(Version, *this, "darwin.target_variant.SDK Version");
}

StringRef Module::getTargetABIFromMD() {
  StringRef TargetABI;
  if (auto *TargetABIMD =
          dyn_cast_or_null<MDString>(getModuleFlag("target-abi")))
    TargetABI = TargetABIMD->getString();
  return TargetABI;
}

WinX64EHUnwindMode Module::getWinX64EHUnwindMode() const {
  // Check the new unified flag first.
  if (Metadata *MD = getModuleFlag("winx64-eh-unwind")) {
    if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD))
      return static_cast<WinX64EHUnwindMode>(CI->getZExtValue());
  }
  // Fall back to the legacy V2 flag.
  if (Metadata *MD = getModuleFlag("winx64-eh-unwindv2")) {
    if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD))
      return static_cast<WinX64EHUnwindMode>(CI->getZExtValue());
  }
  return WinX64EHUnwindMode::V1;
}

ControlFlowGuardMode Module::getControlFlowGuardMode() const {
  Metadata *MD = getModuleFlag("cfguard");
  if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD))
    return static_cast<ControlFlowGuardMode>(CI->getZExtValue());
  return ControlFlowGuardMode::Disabled;
}

bool Module::GlobalAsmProperties::set(StringRef Name, std::string Value) {
  if (Name == "target_features")
    TargetFeatures = std::move(Value);
  else if (Name == "target_cpu")
    TargetCPU = std::move(Value);
  else
    return false;
  return true;
}

SmallVector<std::pair<StringRef, StringRef>>
Module::GlobalAsmProperties::getAsStrings() const {
  SmallVector<std::pair<StringRef, StringRef>> Props;
  if (!TargetFeatures.empty())
    Props.emplace_back("target_features", TargetFeatures);
  if (!TargetCPU.empty())
    Props.emplace_back("target_cpu", TargetCPU);
  return Props;
}
