//===- 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/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);
  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,
                           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 (MDNode *Flag : ModFlags->operands()) {
    if (cast<MDString>(Flag->getOperand(1))->getString() == Key) {
      Flag->replaceOperandWith(2, Val);
      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,
                           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() {
  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);
}

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));
}

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);
}

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;
}

WinX64EHUnwindV2Mode Module::getWinX64EHUnwindV2Mode() const {
  Metadata *MD = getModuleFlag("winx64-eh-unwindv2");
  if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD))
    return static_cast<WinX64EHUnwindV2Mode>(CI->getZExtValue());
  return WinX64EHUnwindV2Mode::Disabled;
}
