//===- 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/Optional.h"
#include "llvm/ADT/SmallPtrSet.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/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CodeGen.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 <algorithm>
#include <cassert>
#include <cstdint>
#include <memory>
#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::SymbolTableListTraits<Function>;
template class llvm::SymbolTableListTraits<GlobalVariable>;
template class llvm::SymbolTableListTraits<GlobalAlias>;
template class llvm::SymbolTableListTraits<GlobalIFunc>;

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

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

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

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);
    if (!New->isIntrinsic())       // Intrinsics get attrs set on construction
      New->setAttributes(AttributeList);
    FunctionList.push_back(New);
    return {Ty, New}; // Return the new prototype.
  }

  // If the function exists but has the wrong type, return a bitcast to the
  // right type.
  auto *PTy = PointerType::get(Ty, F->getAddressSpace());
  if (F->getType() != PTy)
    return {Ty, ConstantExpr::getBitCast(F, PTy)};

  // 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.
///   1. If it does not exist, add a declaration of the global and return it.
///   2. Else, the global exists but has the wrong type: return the function
///      with a constantexpr cast to the right type.
///   3. Finally, if the existing global is the correct declaration, return the
///      existing global.
Constant *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");

  // If the variable exists but has the wrong type, return a bitcast to the
  // right type.
  Type *GVTy = GV->getType();
  PointerType *PTy = PointerType::get(Ty, GVTy->getPointerAddressSpace());
  if (GVTy != PTy)
    return ConstantExpr::getBitCast(GV, PTy);

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

// Overload to construct a global variable using its constructor's defaults.
Constant *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(const Twine &Name) const {
  SmallString<256> NameData;
  StringRef NameRef = Name.toStringRef(NameData);
  return NamedMDSymTab.lookup(NameRef);
}

/// 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);
    NamedMDList.push_back(NMD);
  }
  return NMD;
}

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

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

bool Module::isValidModuleFlag(const MDNode &ModFlag, ModFlagBehavior &MFB,
                               MDString *&Key, Metadata *&Val) {
  if (ModFlag.getNumOperands() < 3)
    return false;
  if (!isValidModFlagBehavior(ModFlag.getOperand(0), MFB))
    return false;
  MDString *K = dyn_cast_or_null<MDString>(ModFlag.getOperand(1));
  if (!K)
    return false;
  Key = K;
  Val = ModFlag.getOperand(2);
  return true;
}

/// 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()) {
    ModFlagBehavior MFB;
    MDString *Key = nullptr;
    Metadata *Val = nullptr;
    if (isValidModuleFlag(*Flag, MFB, Key, Val)) {
      // Check the operands of the MDNode before accessing the operands.
      // The verifier will actually catch these failures.
      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 {
  SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
  getModuleFlagsMetadata(ModuleFlags);
  for (const ModuleFlagEntry &MFE : ModuleFlags) {
    if (Key == MFE.Key->getString())
      return MFE.Val;
  }
  return nullptr;
}

/// getModuleFlagsMetadata - Returns the NamedMDNode in the module that
/// represents module-level flags. This method returns null if there are no
/// module-level flags.
NamedMDNode *Module::getModuleFlagsMetadata() const {
  return getNamedMetadata("llvm.module.flags");
}

/// 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() {
  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 (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) {
    MDNode *Flag = ModFlags->getOperand(I);
    ModFlagBehavior MFB;
    MDString *K = nullptr;
    Metadata *V = nullptr;
    if (isValidModuleFlag(*Flag, MFB, K, V) && K->getString() == Key) {
      Flag->replaceOperandWith(2, Val);
      return;
    }
  }
  addModuleFlag(Behavior, Key, Val);
}

void Module::setDataLayout(StringRef Desc) {
  DL.reset(Desc);
}

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

const DataLayout &Module::getDataLayout() const { return DL; }

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) {
  addModuleFlag(ModFlagBehavior::Max, "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);
}

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

  if (!Val)
    return None;

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

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::getUwtable() const {
  auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("uwtable"));
  return Val && (cast<ConstantInt>(Val->getValue())->getZExtValue() > 0);
}

void Module::setUwtable() { addModuleFlag(ModFlagBehavior::Max, "uwtable", 1); }

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

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

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

void Module::setSDKVersion(const VersionTuple &V) {
  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.
  }
  addModuleFlag(ModFlagBehavior::Warning, "SDK Version",
                ConstantDataArray::get(Context, Entries));
}

VersionTuple Module::getSDKVersion() const {
  auto *CM = dyn_cast_or_null<ConstantAsMetadata>(getModuleFlag("SDK Version"));
  if (!CM)
    return {};
  auto *Arr = dyn_cast_or_null<ConstantDataArray>(CM->getValue());
  if (!Arr)
    return {};
  auto getVersionComponent = [&](unsigned Index) -> Optional<unsigned> {
    if (Index >= Arr->getNumElements())
      return None;
    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;
}

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