10b57cec5SDimitry Andric //===- Module.cpp - Implement the Module class ----------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the Module class for the IR library.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "llvm/IR/Module.h"
140b57cec5SDimitry Andric #include "SymbolTableListTraitsImpl.h"
150b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
160b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
170b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h"
180b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
190b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
200b57cec5SDimitry Andric #include "llvm/IR/Attributes.h"
210b57cec5SDimitry Andric #include "llvm/IR/Comdat.h"
220b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
230b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
240b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
250b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h"
260b57cec5SDimitry Andric #include "llvm/IR/Function.h"
270b57cec5SDimitry Andric #include "llvm/IR/GVMaterializer.h"
280b57cec5SDimitry Andric #include "llvm/IR/GlobalAlias.h"
290b57cec5SDimitry Andric #include "llvm/IR/GlobalIFunc.h"
300b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h"
310b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h"
320b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h"
330b57cec5SDimitry Andric #include "llvm/IR/Metadata.h"
345ffd83dbSDimitry Andric #include "llvm/IR/ModuleSummaryIndex.h"
350b57cec5SDimitry Andric #include "llvm/IR/SymbolTableListTraits.h"
360b57cec5SDimitry Andric #include "llvm/IR/Type.h"
370b57cec5SDimitry Andric #include "llvm/IR/TypeFinder.h"
380b57cec5SDimitry Andric #include "llvm/IR/Value.h"
390b57cec5SDimitry Andric #include "llvm/IR/ValueSymbolTable.h"
400b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
410b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h"
420b57cec5SDimitry Andric #include "llvm/Support/Error.h"
430b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
440b57cec5SDimitry Andric #include "llvm/Support/Path.h"
450b57cec5SDimitry Andric #include "llvm/Support/RandomNumberGenerator.h"
460b57cec5SDimitry Andric #include "llvm/Support/VersionTuple.h"
470b57cec5SDimitry Andric #include <algorithm>
480b57cec5SDimitry Andric #include <cassert>
490b57cec5SDimitry Andric #include <cstdint>
500b57cec5SDimitry Andric #include <memory>
51bdd1243dSDimitry Andric #include <optional>
520b57cec5SDimitry Andric #include <utility>
530b57cec5SDimitry Andric #include <vector>
540b57cec5SDimitry Andric
550b57cec5SDimitry Andric using namespace llvm;
560b57cec5SDimitry Andric
57*0fca6ea1SDimitry Andric extern cl::opt<bool> UseNewDbgInfoFormat;
58*0fca6ea1SDimitry Andric
590b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
600b57cec5SDimitry Andric // Methods to implement the globals and functions lists.
610b57cec5SDimitry Andric //
620b57cec5SDimitry Andric
630b57cec5SDimitry Andric // Explicit instantiations of SymbolTableListTraits since some of the methods
640b57cec5SDimitry Andric // are not in the public header file.
650b57cec5SDimitry Andric template class llvm::SymbolTableListTraits<Function>;
660b57cec5SDimitry Andric template class llvm::SymbolTableListTraits<GlobalVariable>;
670b57cec5SDimitry Andric template class llvm::SymbolTableListTraits<GlobalAlias>;
680b57cec5SDimitry Andric template class llvm::SymbolTableListTraits<GlobalIFunc>;
690b57cec5SDimitry Andric
700b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
710b57cec5SDimitry Andric // Primitive Module methods.
720b57cec5SDimitry Andric //
730b57cec5SDimitry Andric
Module(StringRef MID,LLVMContext & C)740b57cec5SDimitry Andric Module::Module(StringRef MID, LLVMContext &C)
75fe6060f1SDimitry Andric : Context(C), ValSymTab(std::make_unique<ValueSymbolTable>(-1)),
765f757f3fSDimitry Andric ModuleID(std::string(MID)), SourceFileName(std::string(MID)), DL(""),
77*0fca6ea1SDimitry Andric IsNewDbgInfoFormat(UseNewDbgInfoFormat) {
780b57cec5SDimitry Andric Context.addModule(this);
790b57cec5SDimitry Andric }
800b57cec5SDimitry Andric
~Module()810b57cec5SDimitry Andric Module::~Module() {
820b57cec5SDimitry Andric Context.removeModule(this);
830b57cec5SDimitry Andric dropAllReferences();
840b57cec5SDimitry Andric GlobalList.clear();
850b57cec5SDimitry Andric FunctionList.clear();
860b57cec5SDimitry Andric AliasList.clear();
870b57cec5SDimitry Andric IFuncList.clear();
880b57cec5SDimitry Andric }
890b57cec5SDimitry Andric
removeDebugIntrinsicDeclarations()90*0fca6ea1SDimitry Andric void Module::removeDebugIntrinsicDeclarations() {
91*0fca6ea1SDimitry Andric auto *DeclareIntrinsicFn =
92*0fca6ea1SDimitry Andric Intrinsic::getDeclaration(this, Intrinsic::dbg_declare);
93*0fca6ea1SDimitry Andric assert((!isMaterialized() || DeclareIntrinsicFn->hasZeroLiveUses()) &&
94*0fca6ea1SDimitry Andric "Debug declare intrinsic should have had uses removed.");
95*0fca6ea1SDimitry Andric DeclareIntrinsicFn->eraseFromParent();
96*0fca6ea1SDimitry Andric auto *ValueIntrinsicFn =
97*0fca6ea1SDimitry Andric Intrinsic::getDeclaration(this, Intrinsic::dbg_value);
98*0fca6ea1SDimitry Andric assert((!isMaterialized() || ValueIntrinsicFn->hasZeroLiveUses()) &&
99*0fca6ea1SDimitry Andric "Debug value intrinsic should have had uses removed.");
100*0fca6ea1SDimitry Andric ValueIntrinsicFn->eraseFromParent();
101*0fca6ea1SDimitry Andric auto *AssignIntrinsicFn =
102*0fca6ea1SDimitry Andric Intrinsic::getDeclaration(this, Intrinsic::dbg_assign);
103*0fca6ea1SDimitry Andric assert((!isMaterialized() || AssignIntrinsicFn->hasZeroLiveUses()) &&
104*0fca6ea1SDimitry Andric "Debug assign intrinsic should have had uses removed.");
105*0fca6ea1SDimitry Andric AssignIntrinsicFn->eraseFromParent();
106*0fca6ea1SDimitry Andric auto *LabelntrinsicFn = Intrinsic::getDeclaration(this, Intrinsic::dbg_label);
107*0fca6ea1SDimitry Andric assert((!isMaterialized() || LabelntrinsicFn->hasZeroLiveUses()) &&
108*0fca6ea1SDimitry Andric "Debug label intrinsic should have had uses removed.");
109*0fca6ea1SDimitry Andric LabelntrinsicFn->eraseFromParent();
110*0fca6ea1SDimitry Andric }
111*0fca6ea1SDimitry Andric
1125ffd83dbSDimitry Andric std::unique_ptr<RandomNumberGenerator>
createRNG(const StringRef Name) const1135ffd83dbSDimitry Andric Module::createRNG(const StringRef Name) const {
1145ffd83dbSDimitry Andric SmallString<32> Salt(Name);
1150b57cec5SDimitry Andric
1160b57cec5SDimitry Andric // This RNG is guaranteed to produce the same random stream only
1170b57cec5SDimitry Andric // when the Module ID and thus the input filename is the same. This
1180b57cec5SDimitry Andric // might be problematic if the input filename extension changes
1190b57cec5SDimitry Andric // (e.g. from .c to .bc or .ll).
1200b57cec5SDimitry Andric //
1210b57cec5SDimitry Andric // We could store this salt in NamedMetadata, but this would make
1220b57cec5SDimitry Andric // the parameter non-const. This would unfortunately make this
1230b57cec5SDimitry Andric // interface unusable by any Machine passes, since they only have a
1240b57cec5SDimitry Andric // const reference to their IR Module. Alternatively we can always
1250b57cec5SDimitry Andric // store salt metadata from the Module constructor.
1260b57cec5SDimitry Andric Salt += sys::path::filename(getModuleIdentifier());
1270b57cec5SDimitry Andric
1285ffd83dbSDimitry Andric return std::unique_ptr<RandomNumberGenerator>(
1295ffd83dbSDimitry Andric new RandomNumberGenerator(Salt));
1300b57cec5SDimitry Andric }
1310b57cec5SDimitry Andric
1320b57cec5SDimitry Andric /// getNamedValue - Return the first global value in the module with
1330b57cec5SDimitry Andric /// the specified name, of arbitrary type. This method returns null
1340b57cec5SDimitry Andric /// if a global with the specified name is not found.
getNamedValue(StringRef Name) const1350b57cec5SDimitry Andric GlobalValue *Module::getNamedValue(StringRef Name) const {
1360b57cec5SDimitry Andric return cast_or_null<GlobalValue>(getValueSymbolTable().lookup(Name));
1370b57cec5SDimitry Andric }
1380b57cec5SDimitry Andric
getNumNamedValues() const1396e75b2fbSDimitry Andric unsigned Module::getNumNamedValues() const {
1406e75b2fbSDimitry Andric return getValueSymbolTable().size();
1416e75b2fbSDimitry Andric }
1426e75b2fbSDimitry Andric
1430b57cec5SDimitry Andric /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
1440b57cec5SDimitry Andric /// This ID is uniqued across modules in the current LLVMContext.
getMDKindID(StringRef Name) const1450b57cec5SDimitry Andric unsigned Module::getMDKindID(StringRef Name) const {
1460b57cec5SDimitry Andric return Context.getMDKindID(Name);
1470b57cec5SDimitry Andric }
1480b57cec5SDimitry Andric
1490b57cec5SDimitry Andric /// getMDKindNames - Populate client supplied SmallVector with the name for
1500b57cec5SDimitry Andric /// custom metadata IDs registered in this LLVMContext. ID #0 is not used,
1510b57cec5SDimitry Andric /// so it is filled in as an empty string.
getMDKindNames(SmallVectorImpl<StringRef> & Result) const1520b57cec5SDimitry Andric void Module::getMDKindNames(SmallVectorImpl<StringRef> &Result) const {
1530b57cec5SDimitry Andric return Context.getMDKindNames(Result);
1540b57cec5SDimitry Andric }
1550b57cec5SDimitry Andric
getOperandBundleTags(SmallVectorImpl<StringRef> & Result) const1560b57cec5SDimitry Andric void Module::getOperandBundleTags(SmallVectorImpl<StringRef> &Result) const {
1570b57cec5SDimitry Andric return Context.getOperandBundleTags(Result);
1580b57cec5SDimitry Andric }
1590b57cec5SDimitry Andric
1600b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1610b57cec5SDimitry Andric // Methods for easy access to the functions in the module.
1620b57cec5SDimitry Andric //
1630b57cec5SDimitry Andric
1640b57cec5SDimitry Andric // getOrInsertFunction - Look up the specified function in the module symbol
1650b57cec5SDimitry Andric // table. If it does not exist, add a prototype for the function and return
1660b57cec5SDimitry Andric // it. This is nice because it allows most passes to get away with not handling
1670b57cec5SDimitry Andric // the symbol table directly for this common task.
1680b57cec5SDimitry Andric //
getOrInsertFunction(StringRef Name,FunctionType * Ty,AttributeList AttributeList)1690b57cec5SDimitry Andric FunctionCallee Module::getOrInsertFunction(StringRef Name, FunctionType *Ty,
1700b57cec5SDimitry Andric AttributeList AttributeList) {
1710b57cec5SDimitry Andric // See if we have a definition for the specified function already.
1720b57cec5SDimitry Andric GlobalValue *F = getNamedValue(Name);
1730b57cec5SDimitry Andric if (!F) {
1740b57cec5SDimitry Andric // Nope, add it
1750b57cec5SDimitry Andric Function *New = Function::Create(Ty, GlobalVariable::ExternalLinkage,
176*0fca6ea1SDimitry Andric DL.getProgramAddressSpace(), Name, this);
1770b57cec5SDimitry Andric if (!New->isIntrinsic()) // Intrinsics get attrs set on construction
1780b57cec5SDimitry Andric New->setAttributes(AttributeList);
1790b57cec5SDimitry Andric return {Ty, New}; // Return the new prototype.
1800b57cec5SDimitry Andric }
1810b57cec5SDimitry Andric
1820b57cec5SDimitry Andric // Otherwise, we just found the existing function or a prototype.
1830b57cec5SDimitry Andric return {Ty, F};
1840b57cec5SDimitry Andric }
1850b57cec5SDimitry Andric
getOrInsertFunction(StringRef Name,FunctionType * Ty)1860b57cec5SDimitry Andric FunctionCallee Module::getOrInsertFunction(StringRef Name, FunctionType *Ty) {
1870b57cec5SDimitry Andric return getOrInsertFunction(Name, Ty, AttributeList());
1880b57cec5SDimitry Andric }
1890b57cec5SDimitry Andric
1900b57cec5SDimitry Andric // getFunction - Look up the specified function in the module symbol table.
1910b57cec5SDimitry Andric // If it does not exist, return null.
1920b57cec5SDimitry Andric //
getFunction(StringRef Name) const1930b57cec5SDimitry Andric Function *Module::getFunction(StringRef Name) const {
1940b57cec5SDimitry Andric return dyn_cast_or_null<Function>(getNamedValue(Name));
1950b57cec5SDimitry Andric }
1960b57cec5SDimitry Andric
1970b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1980b57cec5SDimitry Andric // Methods for easy access to the global variables in the module.
1990b57cec5SDimitry Andric //
2000b57cec5SDimitry Andric
2010b57cec5SDimitry Andric /// getGlobalVariable - Look up the specified global variable in the module
2020b57cec5SDimitry Andric /// symbol table. If it does not exist, return null. The type argument
2030b57cec5SDimitry Andric /// should be the underlying type of the global, i.e., it should not have
2040b57cec5SDimitry Andric /// the top-level PointerType, which represents the address of the global.
2050b57cec5SDimitry Andric /// If AllowLocal is set to true, this function will return types that
2060b57cec5SDimitry Andric /// have an local. By default, these types are not returned.
2070b57cec5SDimitry Andric ///
getGlobalVariable(StringRef Name,bool AllowLocal) const2080b57cec5SDimitry Andric GlobalVariable *Module::getGlobalVariable(StringRef Name,
2090b57cec5SDimitry Andric bool AllowLocal) const {
2100b57cec5SDimitry Andric if (GlobalVariable *Result =
2110b57cec5SDimitry Andric dyn_cast_or_null<GlobalVariable>(getNamedValue(Name)))
2120b57cec5SDimitry Andric if (AllowLocal || !Result->hasLocalLinkage())
2130b57cec5SDimitry Andric return Result;
2140b57cec5SDimitry Andric return nullptr;
2150b57cec5SDimitry Andric }
2160b57cec5SDimitry Andric
2170b57cec5SDimitry Andric /// getOrInsertGlobal - Look up the specified global in the module symbol table.
2180b57cec5SDimitry Andric /// 1. If it does not exist, add a declaration of the global and return it.
2190b57cec5SDimitry Andric /// 2. Else, the global exists but has the wrong type: return the function
2200b57cec5SDimitry Andric /// with a constantexpr cast to the right type.
2210b57cec5SDimitry Andric /// 3. Finally, if the existing global is the correct declaration, return the
2220b57cec5SDimitry Andric /// existing global.
getOrInsertGlobal(StringRef Name,Type * Ty,function_ref<GlobalVariable * ()> CreateGlobalCallback)2230b57cec5SDimitry Andric Constant *Module::getOrInsertGlobal(
2240b57cec5SDimitry Andric StringRef Name, Type *Ty,
2250b57cec5SDimitry Andric function_ref<GlobalVariable *()> CreateGlobalCallback) {
2260b57cec5SDimitry Andric // See if we have a definition for the specified global already.
2270b57cec5SDimitry Andric GlobalVariable *GV = dyn_cast_or_null<GlobalVariable>(getNamedValue(Name));
2280b57cec5SDimitry Andric if (!GV)
2290b57cec5SDimitry Andric GV = CreateGlobalCallback();
2300b57cec5SDimitry Andric assert(GV && "The CreateGlobalCallback is expected to create a global");
2310b57cec5SDimitry Andric
2320b57cec5SDimitry Andric // Otherwise, we just found the existing function or a prototype.
2330b57cec5SDimitry Andric return GV;
2340b57cec5SDimitry Andric }
2350b57cec5SDimitry Andric
2360b57cec5SDimitry Andric // Overload to construct a global variable using its constructor's defaults.
getOrInsertGlobal(StringRef Name,Type * Ty)2370b57cec5SDimitry Andric Constant *Module::getOrInsertGlobal(StringRef Name, Type *Ty) {
2380b57cec5SDimitry Andric return getOrInsertGlobal(Name, Ty, [&] {
2390b57cec5SDimitry Andric return new GlobalVariable(*this, Ty, false, GlobalVariable::ExternalLinkage,
2400b57cec5SDimitry Andric nullptr, Name);
2410b57cec5SDimitry Andric });
2420b57cec5SDimitry Andric }
2430b57cec5SDimitry Andric
2440b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2450b57cec5SDimitry Andric // Methods for easy access to the global variables in the module.
2460b57cec5SDimitry Andric //
2470b57cec5SDimitry Andric
2480b57cec5SDimitry Andric // getNamedAlias - Look up the specified global in the module symbol table.
2490b57cec5SDimitry Andric // If it does not exist, return null.
2500b57cec5SDimitry Andric //
getNamedAlias(StringRef Name) const2510b57cec5SDimitry Andric GlobalAlias *Module::getNamedAlias(StringRef Name) const {
2520b57cec5SDimitry Andric return dyn_cast_or_null<GlobalAlias>(getNamedValue(Name));
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric
getNamedIFunc(StringRef Name) const2550b57cec5SDimitry Andric GlobalIFunc *Module::getNamedIFunc(StringRef Name) const {
2560b57cec5SDimitry Andric return dyn_cast_or_null<GlobalIFunc>(getNamedValue(Name));
2570b57cec5SDimitry Andric }
2580b57cec5SDimitry Andric
2590b57cec5SDimitry Andric /// getNamedMetadata - Return the first NamedMDNode in the module with the
2600b57cec5SDimitry Andric /// specified name. This method returns null if a NamedMDNode with the
2610b57cec5SDimitry Andric /// specified name is not found.
getNamedMetadata(const Twine & Name) const2620b57cec5SDimitry Andric NamedMDNode *Module::getNamedMetadata(const Twine &Name) const {
2630b57cec5SDimitry Andric SmallString<256> NameData;
2640b57cec5SDimitry Andric StringRef NameRef = Name.toStringRef(NameData);
2655ffd83dbSDimitry Andric return NamedMDSymTab.lookup(NameRef);
2660b57cec5SDimitry Andric }
2670b57cec5SDimitry Andric
2680b57cec5SDimitry Andric /// getOrInsertNamedMetadata - Return the first named MDNode in the module
2690b57cec5SDimitry Andric /// with the specified name. This method returns a new NamedMDNode if a
2700b57cec5SDimitry Andric /// NamedMDNode with the specified name is not found.
getOrInsertNamedMetadata(StringRef Name)2710b57cec5SDimitry Andric NamedMDNode *Module::getOrInsertNamedMetadata(StringRef Name) {
2725ffd83dbSDimitry Andric NamedMDNode *&NMD = NamedMDSymTab[Name];
2730b57cec5SDimitry Andric if (!NMD) {
2740b57cec5SDimitry Andric NMD = new NamedMDNode(Name);
2750b57cec5SDimitry Andric NMD->setParent(this);
27606c3fb27SDimitry Andric insertNamedMDNode(NMD);
2770b57cec5SDimitry Andric }
2780b57cec5SDimitry Andric return NMD;
2790b57cec5SDimitry Andric }
2800b57cec5SDimitry Andric
2810b57cec5SDimitry Andric /// eraseNamedMetadata - Remove the given NamedMDNode from this module and
2820b57cec5SDimitry Andric /// delete it.
eraseNamedMetadata(NamedMDNode * NMD)2830b57cec5SDimitry Andric void Module::eraseNamedMetadata(NamedMDNode *NMD) {
2845ffd83dbSDimitry Andric NamedMDSymTab.erase(NMD->getName());
28506c3fb27SDimitry Andric eraseNamedMDNode(NMD);
2860b57cec5SDimitry Andric }
2870b57cec5SDimitry Andric
isValidModFlagBehavior(Metadata * MD,ModFlagBehavior & MFB)2880b57cec5SDimitry Andric bool Module::isValidModFlagBehavior(Metadata *MD, ModFlagBehavior &MFB) {
2890b57cec5SDimitry Andric if (ConstantInt *Behavior = mdconst::dyn_extract_or_null<ConstantInt>(MD)) {
2900b57cec5SDimitry Andric uint64_t Val = Behavior->getLimitedValue();
2910b57cec5SDimitry Andric if (Val >= ModFlagBehaviorFirstVal && Val <= ModFlagBehaviorLastVal) {
2920b57cec5SDimitry Andric MFB = static_cast<ModFlagBehavior>(Val);
2930b57cec5SDimitry Andric return true;
2940b57cec5SDimitry Andric }
2950b57cec5SDimitry Andric }
2960b57cec5SDimitry Andric return false;
2970b57cec5SDimitry Andric }
2980b57cec5SDimitry Andric
isValidModuleFlag(const MDNode & ModFlag,ModFlagBehavior & MFB,MDString * & Key,Metadata * & Val)2995ffd83dbSDimitry Andric bool Module::isValidModuleFlag(const MDNode &ModFlag, ModFlagBehavior &MFB,
3005ffd83dbSDimitry Andric MDString *&Key, Metadata *&Val) {
3015ffd83dbSDimitry Andric if (ModFlag.getNumOperands() < 3)
3025ffd83dbSDimitry Andric return false;
3035ffd83dbSDimitry Andric if (!isValidModFlagBehavior(ModFlag.getOperand(0), MFB))
3045ffd83dbSDimitry Andric return false;
3055ffd83dbSDimitry Andric MDString *K = dyn_cast_or_null<MDString>(ModFlag.getOperand(1));
3065ffd83dbSDimitry Andric if (!K)
3075ffd83dbSDimitry Andric return false;
3085ffd83dbSDimitry Andric Key = K;
3095ffd83dbSDimitry Andric Val = ModFlag.getOperand(2);
3105ffd83dbSDimitry Andric return true;
3115ffd83dbSDimitry Andric }
3125ffd83dbSDimitry Andric
3130b57cec5SDimitry Andric /// getModuleFlagsMetadata - Returns the module flags in the provided vector.
3140b57cec5SDimitry Andric void Module::
getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> & Flags) const3150b57cec5SDimitry Andric getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const {
3160b57cec5SDimitry Andric const NamedMDNode *ModFlags = getModuleFlagsMetadata();
3170b57cec5SDimitry Andric if (!ModFlags) return;
3180b57cec5SDimitry Andric
3190b57cec5SDimitry Andric for (const MDNode *Flag : ModFlags->operands()) {
3200b57cec5SDimitry Andric ModFlagBehavior MFB;
3215ffd83dbSDimitry Andric MDString *Key = nullptr;
3225ffd83dbSDimitry Andric Metadata *Val = nullptr;
3235ffd83dbSDimitry Andric if (isValidModuleFlag(*Flag, MFB, Key, Val)) {
3240b57cec5SDimitry Andric // Check the operands of the MDNode before accessing the operands.
3250b57cec5SDimitry Andric // The verifier will actually catch these failures.
3260b57cec5SDimitry Andric Flags.push_back(ModuleFlagEntry(MFB, Key, Val));
3270b57cec5SDimitry Andric }
3280b57cec5SDimitry Andric }
3290b57cec5SDimitry Andric }
3300b57cec5SDimitry Andric
3310b57cec5SDimitry Andric /// Return the corresponding value if Key appears in module flags, otherwise
3320b57cec5SDimitry Andric /// return null.
getModuleFlag(StringRef Key) const3330b57cec5SDimitry Andric Metadata *Module::getModuleFlag(StringRef Key) const {
3340b57cec5SDimitry Andric SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
3350b57cec5SDimitry Andric getModuleFlagsMetadata(ModuleFlags);
3360b57cec5SDimitry Andric for (const ModuleFlagEntry &MFE : ModuleFlags) {
3370b57cec5SDimitry Andric if (Key == MFE.Key->getString())
3380b57cec5SDimitry Andric return MFE.Val;
3390b57cec5SDimitry Andric }
3400b57cec5SDimitry Andric return nullptr;
3410b57cec5SDimitry Andric }
3420b57cec5SDimitry Andric
3430b57cec5SDimitry Andric /// getModuleFlagsMetadata - Returns the NamedMDNode in the module that
3440b57cec5SDimitry Andric /// represents module-level flags. This method returns null if there are no
3450b57cec5SDimitry Andric /// module-level flags.
getModuleFlagsMetadata() const3460b57cec5SDimitry Andric NamedMDNode *Module::getModuleFlagsMetadata() const {
3470b57cec5SDimitry Andric return getNamedMetadata("llvm.module.flags");
3480b57cec5SDimitry Andric }
3490b57cec5SDimitry Andric
3500b57cec5SDimitry Andric /// getOrInsertModuleFlagsMetadata - Returns the NamedMDNode in the module that
3510b57cec5SDimitry Andric /// represents module-level flags. If module-level flags aren't found, it
3520b57cec5SDimitry Andric /// creates the named metadata that contains them.
getOrInsertModuleFlagsMetadata()3530b57cec5SDimitry Andric NamedMDNode *Module::getOrInsertModuleFlagsMetadata() {
3540b57cec5SDimitry Andric return getOrInsertNamedMetadata("llvm.module.flags");
3550b57cec5SDimitry Andric }
3560b57cec5SDimitry Andric
3570b57cec5SDimitry Andric /// addModuleFlag - Add a module-level flag to the module-level flags
3580b57cec5SDimitry Andric /// metadata. It will create the module-level flags named metadata if it doesn't
3590b57cec5SDimitry Andric /// already exist.
addModuleFlag(ModFlagBehavior Behavior,StringRef Key,Metadata * Val)3600b57cec5SDimitry Andric void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key,
3610b57cec5SDimitry Andric Metadata *Val) {
3620b57cec5SDimitry Andric Type *Int32Ty = Type::getInt32Ty(Context);
3630b57cec5SDimitry Andric Metadata *Ops[3] = {
3640b57cec5SDimitry Andric ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Behavior)),
3650b57cec5SDimitry Andric MDString::get(Context, Key), Val};
3660b57cec5SDimitry Andric getOrInsertModuleFlagsMetadata()->addOperand(MDNode::get(Context, Ops));
3670b57cec5SDimitry Andric }
addModuleFlag(ModFlagBehavior Behavior,StringRef Key,Constant * Val)3680b57cec5SDimitry Andric void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key,
3690b57cec5SDimitry Andric Constant *Val) {
3700b57cec5SDimitry Andric addModuleFlag(Behavior, Key, ConstantAsMetadata::get(Val));
3710b57cec5SDimitry Andric }
addModuleFlag(ModFlagBehavior Behavior,StringRef Key,uint32_t Val)3720b57cec5SDimitry Andric void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key,
3730b57cec5SDimitry Andric uint32_t Val) {
3740b57cec5SDimitry Andric Type *Int32Ty = Type::getInt32Ty(Context);
3750b57cec5SDimitry Andric addModuleFlag(Behavior, Key, ConstantInt::get(Int32Ty, Val));
3760b57cec5SDimitry Andric }
addModuleFlag(MDNode * Node)3770b57cec5SDimitry Andric void Module::addModuleFlag(MDNode *Node) {
3780b57cec5SDimitry Andric assert(Node->getNumOperands() == 3 &&
3790b57cec5SDimitry Andric "Invalid number of operands for module flag!");
3800b57cec5SDimitry Andric assert(mdconst::hasa<ConstantInt>(Node->getOperand(0)) &&
3810b57cec5SDimitry Andric isa<MDString>(Node->getOperand(1)) &&
3820b57cec5SDimitry Andric "Invalid operand types for module flag!");
3830b57cec5SDimitry Andric getOrInsertModuleFlagsMetadata()->addOperand(Node);
3840b57cec5SDimitry Andric }
3850b57cec5SDimitry Andric
setModuleFlag(ModFlagBehavior Behavior,StringRef Key,Metadata * Val)3865ffd83dbSDimitry Andric void Module::setModuleFlag(ModFlagBehavior Behavior, StringRef Key,
3875ffd83dbSDimitry Andric Metadata *Val) {
3885ffd83dbSDimitry Andric NamedMDNode *ModFlags = getOrInsertModuleFlagsMetadata();
3895ffd83dbSDimitry Andric // Replace the flag if it already exists.
390*0fca6ea1SDimitry Andric for (MDNode *Flag : ModFlags->operands()) {
3915ffd83dbSDimitry Andric ModFlagBehavior MFB;
3925ffd83dbSDimitry Andric MDString *K = nullptr;
3935ffd83dbSDimitry Andric Metadata *V = nullptr;
3945ffd83dbSDimitry Andric if (isValidModuleFlag(*Flag, MFB, K, V) && K->getString() == Key) {
3955ffd83dbSDimitry Andric Flag->replaceOperandWith(2, Val);
3965ffd83dbSDimitry Andric return;
3975ffd83dbSDimitry Andric }
3985ffd83dbSDimitry Andric }
3995ffd83dbSDimitry Andric addModuleFlag(Behavior, Key, Val);
4005ffd83dbSDimitry Andric }
setModuleFlag(ModFlagBehavior Behavior,StringRef Key,Constant * Val)401*0fca6ea1SDimitry Andric void Module::setModuleFlag(ModFlagBehavior Behavior, StringRef Key,
402*0fca6ea1SDimitry Andric Constant *Val) {
403*0fca6ea1SDimitry Andric setModuleFlag(Behavior, Key, ConstantAsMetadata::get(Val));
404*0fca6ea1SDimitry Andric }
setModuleFlag(ModFlagBehavior Behavior,StringRef Key,uint32_t Val)405*0fca6ea1SDimitry Andric void Module::setModuleFlag(ModFlagBehavior Behavior, StringRef Key,
406*0fca6ea1SDimitry Andric uint32_t Val) {
407*0fca6ea1SDimitry Andric Type *Int32Ty = Type::getInt32Ty(Context);
408*0fca6ea1SDimitry Andric setModuleFlag(Behavior, Key, ConstantInt::get(Int32Ty, Val));
409*0fca6ea1SDimitry Andric }
4105ffd83dbSDimitry Andric
setDataLayout(StringRef Desc)4110b57cec5SDimitry Andric void Module::setDataLayout(StringRef Desc) {
4120b57cec5SDimitry Andric DL.reset(Desc);
4130b57cec5SDimitry Andric }
4140b57cec5SDimitry Andric
setDataLayout(const DataLayout & Other)4150b57cec5SDimitry Andric void Module::setDataLayout(const DataLayout &Other) { DL = Other; }
4160b57cec5SDimitry Andric
operator *() const4170b57cec5SDimitry Andric DICompileUnit *Module::debug_compile_units_iterator::operator*() const {
4180b57cec5SDimitry Andric return cast<DICompileUnit>(CUs->getOperand(Idx));
4190b57cec5SDimitry Andric }
operator ->() const4200b57cec5SDimitry Andric DICompileUnit *Module::debug_compile_units_iterator::operator->() const {
4210b57cec5SDimitry Andric return cast<DICompileUnit>(CUs->getOperand(Idx));
4220b57cec5SDimitry Andric }
4230b57cec5SDimitry Andric
SkipNoDebugCUs()4240b57cec5SDimitry Andric void Module::debug_compile_units_iterator::SkipNoDebugCUs() {
4250b57cec5SDimitry Andric while (CUs && (Idx < CUs->getNumOperands()) &&
4260b57cec5SDimitry Andric ((*this)->getEmissionKind() == DICompileUnit::NoDebug))
4270b57cec5SDimitry Andric ++Idx;
4280b57cec5SDimitry Andric }
4290b57cec5SDimitry Andric
global_objects()430480093f4SDimitry Andric iterator_range<Module::global_object_iterator> Module::global_objects() {
431480093f4SDimitry Andric return concat<GlobalObject>(functions(), globals());
432480093f4SDimitry Andric }
433480093f4SDimitry Andric iterator_range<Module::const_global_object_iterator>
global_objects() const434480093f4SDimitry Andric Module::global_objects() const {
435480093f4SDimitry Andric return concat<const GlobalObject>(functions(), globals());
436480093f4SDimitry Andric }
437480093f4SDimitry Andric
global_values()438480093f4SDimitry Andric iterator_range<Module::global_value_iterator> Module::global_values() {
439480093f4SDimitry Andric return concat<GlobalValue>(functions(), globals(), aliases(), ifuncs());
440480093f4SDimitry Andric }
441480093f4SDimitry Andric iterator_range<Module::const_global_value_iterator>
global_values() const442480093f4SDimitry Andric Module::global_values() const {
443480093f4SDimitry Andric return concat<const GlobalValue>(functions(), globals(), aliases(), ifuncs());
444480093f4SDimitry Andric }
445480093f4SDimitry Andric
4460b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4470b57cec5SDimitry Andric // Methods to control the materialization of GlobalValues in the Module.
4480b57cec5SDimitry Andric //
setMaterializer(GVMaterializer * GVM)4490b57cec5SDimitry Andric void Module::setMaterializer(GVMaterializer *GVM) {
4500b57cec5SDimitry Andric assert(!Materializer &&
4510b57cec5SDimitry Andric "Module already has a GVMaterializer. Call materializeAll"
4520b57cec5SDimitry Andric " to clear it out before setting another one.");
4530b57cec5SDimitry Andric Materializer.reset(GVM);
4540b57cec5SDimitry Andric }
4550b57cec5SDimitry Andric
materialize(GlobalValue * GV)4560b57cec5SDimitry Andric Error Module::materialize(GlobalValue *GV) {
4570b57cec5SDimitry Andric if (!Materializer)
4580b57cec5SDimitry Andric return Error::success();
4590b57cec5SDimitry Andric
4600b57cec5SDimitry Andric return Materializer->materialize(GV);
4610b57cec5SDimitry Andric }
4620b57cec5SDimitry Andric
materializeAll()4630b57cec5SDimitry Andric Error Module::materializeAll() {
4640b57cec5SDimitry Andric if (!Materializer)
4650b57cec5SDimitry Andric return Error::success();
4660b57cec5SDimitry Andric std::unique_ptr<GVMaterializer> M = std::move(Materializer);
4670b57cec5SDimitry Andric return M->materializeModule();
4680b57cec5SDimitry Andric }
4690b57cec5SDimitry Andric
materializeMetadata()4700b57cec5SDimitry Andric Error Module::materializeMetadata() {
4710b57cec5SDimitry Andric if (!Materializer)
4720b57cec5SDimitry Andric return Error::success();
4730b57cec5SDimitry Andric return Materializer->materializeMetadata();
4740b57cec5SDimitry Andric }
4750b57cec5SDimitry Andric
4760b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4770b57cec5SDimitry Andric // Other module related stuff.
4780b57cec5SDimitry Andric //
4790b57cec5SDimitry Andric
getIdentifiedStructTypes() const4800b57cec5SDimitry Andric std::vector<StructType *> Module::getIdentifiedStructTypes() const {
4810b57cec5SDimitry Andric // If we have a materializer, it is possible that some unread function
4820b57cec5SDimitry Andric // uses a type that is currently not visible to a TypeFinder, so ask
4830b57cec5SDimitry Andric // the materializer which types it created.
4840b57cec5SDimitry Andric if (Materializer)
4850b57cec5SDimitry Andric return Materializer->getIdentifiedStructTypes();
4860b57cec5SDimitry Andric
4870b57cec5SDimitry Andric std::vector<StructType *> Ret;
4880b57cec5SDimitry Andric TypeFinder SrcStructTypes;
4890b57cec5SDimitry Andric SrcStructTypes.run(*this, true);
4900b57cec5SDimitry Andric Ret.assign(SrcStructTypes.begin(), SrcStructTypes.end());
4910b57cec5SDimitry Andric return Ret;
4920b57cec5SDimitry Andric }
4930b57cec5SDimitry Andric
getUniqueIntrinsicName(StringRef BaseName,Intrinsic::ID Id,const FunctionType * Proto)494fe6060f1SDimitry Andric std::string Module::getUniqueIntrinsicName(StringRef BaseName, Intrinsic::ID Id,
495fe6060f1SDimitry Andric const FunctionType *Proto) {
496fe6060f1SDimitry Andric auto Encode = [&BaseName](unsigned Suffix) {
497fe6060f1SDimitry Andric return (Twine(BaseName) + "." + Twine(Suffix)).str();
498fe6060f1SDimitry Andric };
499fe6060f1SDimitry Andric
500fe6060f1SDimitry Andric {
501fe6060f1SDimitry Andric // fast path - the prototype is already known
502fe6060f1SDimitry Andric auto UinItInserted = UniquedIntrinsicNames.insert({{Id, Proto}, 0});
503fe6060f1SDimitry Andric if (!UinItInserted.second)
504fe6060f1SDimitry Andric return Encode(UinItInserted.first->second);
505fe6060f1SDimitry Andric }
506fe6060f1SDimitry Andric
507fe6060f1SDimitry Andric // Not known yet. A new entry was created with index 0. Check if there already
508fe6060f1SDimitry Andric // exists a matching declaration, or select a new entry.
509fe6060f1SDimitry Andric
510fe6060f1SDimitry Andric // Start looking for names with the current known maximum count (or 0).
511fe6060f1SDimitry Andric auto NiidItInserted = CurrentIntrinsicIds.insert({BaseName, 0});
512fe6060f1SDimitry Andric unsigned Count = NiidItInserted.first->second;
513fe6060f1SDimitry Andric
514fe6060f1SDimitry Andric // This might be slow if a whole population of intrinsics already existed, but
515fe6060f1SDimitry Andric // we cache the values for later usage.
516fe6060f1SDimitry Andric std::string NewName;
517fe6060f1SDimitry Andric while (true) {
518fe6060f1SDimitry Andric NewName = Encode(Count);
519fe6060f1SDimitry Andric GlobalValue *F = getNamedValue(NewName);
520fe6060f1SDimitry Andric if (!F) {
521fe6060f1SDimitry Andric // Reserve this entry for the new proto
522fe6060f1SDimitry Andric UniquedIntrinsicNames[{Id, Proto}] = Count;
523fe6060f1SDimitry Andric break;
524fe6060f1SDimitry Andric }
525fe6060f1SDimitry Andric
526fe6060f1SDimitry Andric // A declaration with this name already exists. Remember it.
527fe6060f1SDimitry Andric FunctionType *FT = dyn_cast<FunctionType>(F->getValueType());
528fe6060f1SDimitry Andric auto UinItInserted = UniquedIntrinsicNames.insert({{Id, FT}, Count});
529fe6060f1SDimitry Andric if (FT == Proto) {
530fe6060f1SDimitry Andric // It was a declaration for our prototype. This entry was allocated in the
531fe6060f1SDimitry Andric // beginning. Update the count to match the existing declaration.
532fe6060f1SDimitry Andric UinItInserted.first->second = Count;
533fe6060f1SDimitry Andric break;
534fe6060f1SDimitry Andric }
535fe6060f1SDimitry Andric
536fe6060f1SDimitry Andric ++Count;
537fe6060f1SDimitry Andric }
538fe6060f1SDimitry Andric
539fe6060f1SDimitry Andric NiidItInserted.first->second = Count + 1;
540fe6060f1SDimitry Andric
541fe6060f1SDimitry Andric return NewName;
542fe6060f1SDimitry Andric }
543fe6060f1SDimitry Andric
5440b57cec5SDimitry Andric // dropAllReferences() - This function causes all the subelements to "let go"
5450b57cec5SDimitry Andric // of all references that they are maintaining. This allows one to 'delete' a
5460b57cec5SDimitry Andric // whole module at a time, even though there may be circular references... first
5470b57cec5SDimitry Andric // all references are dropped, and all use counts go to zero. Then everything
5480b57cec5SDimitry Andric // is deleted for real. Note that no operations are valid on an object that
5490b57cec5SDimitry Andric // has "dropped all references", except operator delete.
5500b57cec5SDimitry Andric //
dropAllReferences()5510b57cec5SDimitry Andric void Module::dropAllReferences() {
5520b57cec5SDimitry Andric for (Function &F : *this)
5530b57cec5SDimitry Andric F.dropAllReferences();
5540b57cec5SDimitry Andric
5550b57cec5SDimitry Andric for (GlobalVariable &GV : globals())
5560b57cec5SDimitry Andric GV.dropAllReferences();
5570b57cec5SDimitry Andric
5580b57cec5SDimitry Andric for (GlobalAlias &GA : aliases())
5590b57cec5SDimitry Andric GA.dropAllReferences();
5600b57cec5SDimitry Andric
5610b57cec5SDimitry Andric for (GlobalIFunc &GIF : ifuncs())
5620b57cec5SDimitry Andric GIF.dropAllReferences();
5630b57cec5SDimitry Andric }
5640b57cec5SDimitry Andric
getNumberRegisterParameters() const5650b57cec5SDimitry Andric unsigned Module::getNumberRegisterParameters() const {
5660b57cec5SDimitry Andric auto *Val =
5670b57cec5SDimitry Andric cast_or_null<ConstantAsMetadata>(getModuleFlag("NumRegisterParameters"));
5680b57cec5SDimitry Andric if (!Val)
5690b57cec5SDimitry Andric return 0;
5700b57cec5SDimitry Andric return cast<ConstantInt>(Val->getValue())->getZExtValue();
5710b57cec5SDimitry Andric }
5720b57cec5SDimitry Andric
getDwarfVersion() const5730b57cec5SDimitry Andric unsigned Module::getDwarfVersion() const {
5740b57cec5SDimitry Andric auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("Dwarf Version"));
5750b57cec5SDimitry Andric if (!Val)
5760b57cec5SDimitry Andric return 0;
5770b57cec5SDimitry Andric return cast<ConstantInt>(Val->getValue())->getZExtValue();
5780b57cec5SDimitry Andric }
5790b57cec5SDimitry Andric
isDwarf64() const580fe6060f1SDimitry Andric bool Module::isDwarf64() const {
581fe6060f1SDimitry Andric auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("DWARF64"));
582fe6060f1SDimitry Andric return Val && cast<ConstantInt>(Val->getValue())->isOne();
583fe6060f1SDimitry Andric }
584fe6060f1SDimitry Andric
getCodeViewFlag() const5850b57cec5SDimitry Andric unsigned Module::getCodeViewFlag() const {
5860b57cec5SDimitry Andric auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("CodeView"));
5870b57cec5SDimitry Andric if (!Val)
5880b57cec5SDimitry Andric return 0;
5890b57cec5SDimitry Andric return cast<ConstantInt>(Val->getValue())->getZExtValue();
5900b57cec5SDimitry Andric }
5910b57cec5SDimitry Andric
getInstructionCount() const592fe6060f1SDimitry Andric unsigned Module::getInstructionCount() const {
5930b57cec5SDimitry Andric unsigned NumInstrs = 0;
594fe6060f1SDimitry Andric for (const Function &F : FunctionList)
5950b57cec5SDimitry Andric NumInstrs += F.getInstructionCount();
5960b57cec5SDimitry Andric return NumInstrs;
5970b57cec5SDimitry Andric }
5980b57cec5SDimitry Andric
getOrInsertComdat(StringRef Name)5990b57cec5SDimitry Andric Comdat *Module::getOrInsertComdat(StringRef Name) {
6000b57cec5SDimitry Andric auto &Entry = *ComdatSymTab.insert(std::make_pair(Name, Comdat())).first;
6010b57cec5SDimitry Andric Entry.second.Name = &Entry;
6020b57cec5SDimitry Andric return &Entry.second;
6030b57cec5SDimitry Andric }
6040b57cec5SDimitry Andric
getPICLevel() const6050b57cec5SDimitry Andric PICLevel::Level Module::getPICLevel() const {
6060b57cec5SDimitry Andric auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("PIC Level"));
6070b57cec5SDimitry Andric
6080b57cec5SDimitry Andric if (!Val)
6090b57cec5SDimitry Andric return PICLevel::NotPIC;
6100b57cec5SDimitry Andric
6110b57cec5SDimitry Andric return static_cast<PICLevel::Level>(
6120b57cec5SDimitry Andric cast<ConstantInt>(Val->getValue())->getZExtValue());
6130b57cec5SDimitry Andric }
6140b57cec5SDimitry Andric
setPICLevel(PICLevel::Level PL)6150b57cec5SDimitry Andric void Module::setPICLevel(PICLevel::Level PL) {
616bdd1243dSDimitry Andric // The merge result of a non-PIC object and a PIC object can only be reliably
617bdd1243dSDimitry Andric // used as a non-PIC object, so use the Min merge behavior.
618bdd1243dSDimitry Andric addModuleFlag(ModFlagBehavior::Min, "PIC Level", PL);
6190b57cec5SDimitry Andric }
6200b57cec5SDimitry Andric
getPIELevel() const6210b57cec5SDimitry Andric PIELevel::Level Module::getPIELevel() const {
6220b57cec5SDimitry Andric auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("PIE Level"));
6230b57cec5SDimitry Andric
6240b57cec5SDimitry Andric if (!Val)
6250b57cec5SDimitry Andric return PIELevel::Default;
6260b57cec5SDimitry Andric
6270b57cec5SDimitry Andric return static_cast<PIELevel::Level>(
6280b57cec5SDimitry Andric cast<ConstantInt>(Val->getValue())->getZExtValue());
6290b57cec5SDimitry Andric }
6300b57cec5SDimitry Andric
setPIELevel(PIELevel::Level PL)6310b57cec5SDimitry Andric void Module::setPIELevel(PIELevel::Level PL) {
6320b57cec5SDimitry Andric addModuleFlag(ModFlagBehavior::Max, "PIE Level", PL);
6330b57cec5SDimitry Andric }
6340b57cec5SDimitry Andric
getCodeModel() const635bdd1243dSDimitry Andric std::optional<CodeModel::Model> Module::getCodeModel() const {
6360b57cec5SDimitry Andric auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("Code Model"));
6370b57cec5SDimitry Andric
6380b57cec5SDimitry Andric if (!Val)
639bdd1243dSDimitry Andric return std::nullopt;
6400b57cec5SDimitry Andric
6410b57cec5SDimitry Andric return static_cast<CodeModel::Model>(
6420b57cec5SDimitry Andric cast<ConstantInt>(Val->getValue())->getZExtValue());
6430b57cec5SDimitry Andric }
6440b57cec5SDimitry Andric
setCodeModel(CodeModel::Model CL)6450b57cec5SDimitry Andric void Module::setCodeModel(CodeModel::Model CL) {
6460b57cec5SDimitry Andric // Linking object files with different code models is undefined behavior
6470b57cec5SDimitry Andric // because the compiler would have to generate additional code (to span
6480b57cec5SDimitry Andric // longer jumps) if a larger code model is used with a smaller one.
6490b57cec5SDimitry Andric // Therefore we will treat attempts to mix code models as an error.
6500b57cec5SDimitry Andric addModuleFlag(ModFlagBehavior::Error, "Code Model", CL);
6510b57cec5SDimitry Andric }
6520b57cec5SDimitry Andric
getLargeDataThreshold() const6535f757f3fSDimitry Andric std::optional<uint64_t> Module::getLargeDataThreshold() const {
6545f757f3fSDimitry Andric auto *Val =
6555f757f3fSDimitry Andric cast_or_null<ConstantAsMetadata>(getModuleFlag("Large Data Threshold"));
6565f757f3fSDimitry Andric
6575f757f3fSDimitry Andric if (!Val)
6585f757f3fSDimitry Andric return std::nullopt;
6595f757f3fSDimitry Andric
6605f757f3fSDimitry Andric return cast<ConstantInt>(Val->getValue())->getZExtValue();
6615f757f3fSDimitry Andric }
6625f757f3fSDimitry Andric
setLargeDataThreshold(uint64_t Threshold)6635f757f3fSDimitry Andric void Module::setLargeDataThreshold(uint64_t Threshold) {
6645f757f3fSDimitry Andric // Since the large data threshold goes along with the code model, the merge
6655f757f3fSDimitry Andric // behavior is the same.
6665f757f3fSDimitry Andric addModuleFlag(ModFlagBehavior::Error, "Large Data Threshold",
6675f757f3fSDimitry Andric ConstantInt::get(Type::getInt64Ty(Context), Threshold));
6685f757f3fSDimitry Andric }
6695f757f3fSDimitry Andric
setProfileSummary(Metadata * M,ProfileSummary::Kind Kind)6700b57cec5SDimitry Andric void Module::setProfileSummary(Metadata *M, ProfileSummary::Kind Kind) {
6710b57cec5SDimitry Andric if (Kind == ProfileSummary::PSK_CSInstr)
6725ffd83dbSDimitry Andric setModuleFlag(ModFlagBehavior::Error, "CSProfileSummary", M);
6730b57cec5SDimitry Andric else
6745ffd83dbSDimitry Andric setModuleFlag(ModFlagBehavior::Error, "ProfileSummary", M);
6750b57cec5SDimitry Andric }
6760b57cec5SDimitry Andric
getProfileSummary(bool IsCS) const677e8d8bef9SDimitry Andric Metadata *Module::getProfileSummary(bool IsCS) const {
6780b57cec5SDimitry Andric return (IsCS ? getModuleFlag("CSProfileSummary")
6790b57cec5SDimitry Andric : getModuleFlag("ProfileSummary"));
6800b57cec5SDimitry Andric }
6810b57cec5SDimitry Andric
getSemanticInterposition() const6825ffd83dbSDimitry Andric bool Module::getSemanticInterposition() const {
6835ffd83dbSDimitry Andric Metadata *MF = getModuleFlag("SemanticInterposition");
6845ffd83dbSDimitry Andric
6855ffd83dbSDimitry Andric auto *Val = cast_or_null<ConstantAsMetadata>(MF);
6865ffd83dbSDimitry Andric if (!Val)
6875ffd83dbSDimitry Andric return false;
6885ffd83dbSDimitry Andric
6895ffd83dbSDimitry Andric return cast<ConstantInt>(Val->getValue())->getZExtValue();
6905ffd83dbSDimitry Andric }
6915ffd83dbSDimitry Andric
setSemanticInterposition(bool SI)6925ffd83dbSDimitry Andric void Module::setSemanticInterposition(bool SI) {
6935ffd83dbSDimitry Andric addModuleFlag(ModFlagBehavior::Error, "SemanticInterposition", SI);
6945ffd83dbSDimitry Andric }
6955ffd83dbSDimitry Andric
setOwnedMemoryBuffer(std::unique_ptr<MemoryBuffer> MB)6960b57cec5SDimitry Andric void Module::setOwnedMemoryBuffer(std::unique_ptr<MemoryBuffer> MB) {
6970b57cec5SDimitry Andric OwnedMemoryBuffer = std::move(MB);
6980b57cec5SDimitry Andric }
6990b57cec5SDimitry Andric
getRtLibUseGOT() const7000b57cec5SDimitry Andric bool Module::getRtLibUseGOT() const {
7010b57cec5SDimitry Andric auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("RtLibUseGOT"));
7020b57cec5SDimitry Andric return Val && (cast<ConstantInt>(Val->getValue())->getZExtValue() > 0);
7030b57cec5SDimitry Andric }
7040b57cec5SDimitry Andric
setRtLibUseGOT()7050b57cec5SDimitry Andric void Module::setRtLibUseGOT() {
7060b57cec5SDimitry Andric addModuleFlag(ModFlagBehavior::Max, "RtLibUseGOT", 1);
7070b57cec5SDimitry Andric }
7080b57cec5SDimitry Andric
getDirectAccessExternalData() const70906c3fb27SDimitry Andric bool Module::getDirectAccessExternalData() const {
71006c3fb27SDimitry Andric auto *Val = cast_or_null<ConstantAsMetadata>(
71106c3fb27SDimitry Andric getModuleFlag("direct-access-external-data"));
71206c3fb27SDimitry Andric if (Val)
71306c3fb27SDimitry Andric return cast<ConstantInt>(Val->getValue())->getZExtValue() > 0;
71406c3fb27SDimitry Andric return getPICLevel() == PICLevel::NotPIC;
71506c3fb27SDimitry Andric }
71606c3fb27SDimitry Andric
setDirectAccessExternalData(bool Value)71706c3fb27SDimitry Andric void Module::setDirectAccessExternalData(bool Value) {
71806c3fb27SDimitry Andric addModuleFlag(ModFlagBehavior::Max, "direct-access-external-data", Value);
71906c3fb27SDimitry Andric }
72006c3fb27SDimitry Andric
getUwtable() const72181ad6265SDimitry Andric UWTableKind Module::getUwtable() const {
72281ad6265SDimitry Andric if (auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("uwtable")))
72381ad6265SDimitry Andric return UWTableKind(cast<ConstantInt>(Val->getValue())->getZExtValue());
72481ad6265SDimitry Andric return UWTableKind::None;
725fe6060f1SDimitry Andric }
726fe6060f1SDimitry Andric
setUwtable(UWTableKind Kind)72781ad6265SDimitry Andric void Module::setUwtable(UWTableKind Kind) {
72881ad6265SDimitry Andric addModuleFlag(ModFlagBehavior::Max, "uwtable", uint32_t(Kind));
72981ad6265SDimitry Andric }
730fe6060f1SDimitry Andric
getFramePointer() const731fe6060f1SDimitry Andric FramePointerKind Module::getFramePointer() const {
732fe6060f1SDimitry Andric auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("frame-pointer"));
733fe6060f1SDimitry Andric return static_cast<FramePointerKind>(
734fe6060f1SDimitry Andric Val ? cast<ConstantInt>(Val->getValue())->getZExtValue() : 0);
735fe6060f1SDimitry Andric }
736fe6060f1SDimitry Andric
setFramePointer(FramePointerKind Kind)737fe6060f1SDimitry Andric void Module::setFramePointer(FramePointerKind Kind) {
738fe6060f1SDimitry Andric addModuleFlag(ModFlagBehavior::Max, "frame-pointer", static_cast<int>(Kind));
739fe6060f1SDimitry Andric }
740fe6060f1SDimitry Andric
getStackProtectorGuard() const741fe6060f1SDimitry Andric StringRef Module::getStackProtectorGuard() const {
742fe6060f1SDimitry Andric Metadata *MD = getModuleFlag("stack-protector-guard");
743fe6060f1SDimitry Andric if (auto *MDS = dyn_cast_or_null<MDString>(MD))
744fe6060f1SDimitry Andric return MDS->getString();
745fe6060f1SDimitry Andric return {};
746fe6060f1SDimitry Andric }
747fe6060f1SDimitry Andric
setStackProtectorGuard(StringRef Kind)748fe6060f1SDimitry Andric void Module::setStackProtectorGuard(StringRef Kind) {
749fe6060f1SDimitry Andric MDString *ID = MDString::get(getContext(), Kind);
750fe6060f1SDimitry Andric addModuleFlag(ModFlagBehavior::Error, "stack-protector-guard", ID);
751fe6060f1SDimitry Andric }
752fe6060f1SDimitry Andric
getStackProtectorGuardReg() const753fe6060f1SDimitry Andric StringRef Module::getStackProtectorGuardReg() const {
754fe6060f1SDimitry Andric Metadata *MD = getModuleFlag("stack-protector-guard-reg");
755fe6060f1SDimitry Andric if (auto *MDS = dyn_cast_or_null<MDString>(MD))
756fe6060f1SDimitry Andric return MDS->getString();
757fe6060f1SDimitry Andric return {};
758fe6060f1SDimitry Andric }
759fe6060f1SDimitry Andric
setStackProtectorGuardReg(StringRef Reg)760fe6060f1SDimitry Andric void Module::setStackProtectorGuardReg(StringRef Reg) {
761fe6060f1SDimitry Andric MDString *ID = MDString::get(getContext(), Reg);
762fe6060f1SDimitry Andric addModuleFlag(ModFlagBehavior::Error, "stack-protector-guard-reg", ID);
763fe6060f1SDimitry Andric }
764fe6060f1SDimitry Andric
getStackProtectorGuardSymbol() const765753f127fSDimitry Andric StringRef Module::getStackProtectorGuardSymbol() const {
766753f127fSDimitry Andric Metadata *MD = getModuleFlag("stack-protector-guard-symbol");
767753f127fSDimitry Andric if (auto *MDS = dyn_cast_or_null<MDString>(MD))
768753f127fSDimitry Andric return MDS->getString();
769753f127fSDimitry Andric return {};
770753f127fSDimitry Andric }
771753f127fSDimitry Andric
setStackProtectorGuardSymbol(StringRef Symbol)772753f127fSDimitry Andric void Module::setStackProtectorGuardSymbol(StringRef Symbol) {
773753f127fSDimitry Andric MDString *ID = MDString::get(getContext(), Symbol);
774753f127fSDimitry Andric addModuleFlag(ModFlagBehavior::Error, "stack-protector-guard-symbol", ID);
775753f127fSDimitry Andric }
776753f127fSDimitry Andric
getStackProtectorGuardOffset() const777fe6060f1SDimitry Andric int Module::getStackProtectorGuardOffset() const {
778fe6060f1SDimitry Andric Metadata *MD = getModuleFlag("stack-protector-guard-offset");
779fe6060f1SDimitry Andric if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD))
780fe6060f1SDimitry Andric return CI->getSExtValue();
781fe6060f1SDimitry Andric return INT_MAX;
782fe6060f1SDimitry Andric }
783fe6060f1SDimitry Andric
setStackProtectorGuardOffset(int Offset)784fe6060f1SDimitry Andric void Module::setStackProtectorGuardOffset(int Offset) {
785fe6060f1SDimitry Andric addModuleFlag(ModFlagBehavior::Error, "stack-protector-guard-offset", Offset);
786fe6060f1SDimitry Andric }
787fe6060f1SDimitry Andric
getOverrideStackAlignment() const788fe6060f1SDimitry Andric unsigned Module::getOverrideStackAlignment() const {
789fe6060f1SDimitry Andric Metadata *MD = getModuleFlag("override-stack-alignment");
790fe6060f1SDimitry Andric if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD))
791fe6060f1SDimitry Andric return CI->getZExtValue();
792fe6060f1SDimitry Andric return 0;
793fe6060f1SDimitry Andric }
794fe6060f1SDimitry Andric
getMaxTLSAlignment() const79506c3fb27SDimitry Andric unsigned Module::getMaxTLSAlignment() const {
79606c3fb27SDimitry Andric Metadata *MD = getModuleFlag("MaxTLSAlign");
79706c3fb27SDimitry Andric if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD))
79806c3fb27SDimitry Andric return CI->getZExtValue();
79906c3fb27SDimitry Andric return 0;
80006c3fb27SDimitry Andric }
80106c3fb27SDimitry Andric
setOverrideStackAlignment(unsigned Align)802fe6060f1SDimitry Andric void Module::setOverrideStackAlignment(unsigned Align) {
803fe6060f1SDimitry Andric addModuleFlag(ModFlagBehavior::Error, "override-stack-alignment", Align);
804fe6060f1SDimitry Andric }
805fe6060f1SDimitry Andric
addSDKVersionMD(const VersionTuple & V,Module & M,StringRef Name)80681ad6265SDimitry Andric static void addSDKVersionMD(const VersionTuple &V, Module &M, StringRef Name) {
8070b57cec5SDimitry Andric SmallVector<unsigned, 3> Entries;
8080b57cec5SDimitry Andric Entries.push_back(V.getMajor());
8090b57cec5SDimitry Andric if (auto Minor = V.getMinor()) {
8100b57cec5SDimitry Andric Entries.push_back(*Minor);
8110b57cec5SDimitry Andric if (auto Subminor = V.getSubminor())
8120b57cec5SDimitry Andric Entries.push_back(*Subminor);
8130b57cec5SDimitry Andric // Ignore the 'build' component as it can't be represented in the object
8140b57cec5SDimitry Andric // file.
8150b57cec5SDimitry Andric }
81681ad6265SDimitry Andric M.addModuleFlag(Module::ModFlagBehavior::Warning, Name,
81781ad6265SDimitry Andric ConstantDataArray::get(M.getContext(), Entries));
81881ad6265SDimitry Andric }
81981ad6265SDimitry Andric
setSDKVersion(const VersionTuple & V)82081ad6265SDimitry Andric void Module::setSDKVersion(const VersionTuple &V) {
82181ad6265SDimitry Andric addSDKVersionMD(V, *this, "SDK Version");
8220b57cec5SDimitry Andric }
8230b57cec5SDimitry Andric
getSDKVersionMD(Metadata * MD)8240eae32dcSDimitry Andric static VersionTuple getSDKVersionMD(Metadata *MD) {
8250eae32dcSDimitry Andric auto *CM = dyn_cast_or_null<ConstantAsMetadata>(MD);
8260b57cec5SDimitry Andric if (!CM)
8270b57cec5SDimitry Andric return {};
8280b57cec5SDimitry Andric auto *Arr = dyn_cast_or_null<ConstantDataArray>(CM->getValue());
8290b57cec5SDimitry Andric if (!Arr)
8300b57cec5SDimitry Andric return {};
831bdd1243dSDimitry Andric auto getVersionComponent = [&](unsigned Index) -> std::optional<unsigned> {
8320b57cec5SDimitry Andric if (Index >= Arr->getNumElements())
833bdd1243dSDimitry Andric return std::nullopt;
8340b57cec5SDimitry Andric return (unsigned)Arr->getElementAsInteger(Index);
8350b57cec5SDimitry Andric };
8360b57cec5SDimitry Andric auto Major = getVersionComponent(0);
8370b57cec5SDimitry Andric if (!Major)
8380b57cec5SDimitry Andric return {};
8390b57cec5SDimitry Andric VersionTuple Result = VersionTuple(*Major);
8400b57cec5SDimitry Andric if (auto Minor = getVersionComponent(1)) {
8410b57cec5SDimitry Andric Result = VersionTuple(*Major, *Minor);
8420b57cec5SDimitry Andric if (auto Subminor = getVersionComponent(2)) {
8430b57cec5SDimitry Andric Result = VersionTuple(*Major, *Minor, *Subminor);
8440b57cec5SDimitry Andric }
8450b57cec5SDimitry Andric }
8460b57cec5SDimitry Andric return Result;
8470b57cec5SDimitry Andric }
8480b57cec5SDimitry Andric
getSDKVersion() const8490eae32dcSDimitry Andric VersionTuple Module::getSDKVersion() const {
8500eae32dcSDimitry Andric return getSDKVersionMD(getModuleFlag("SDK Version"));
8510eae32dcSDimitry Andric }
8520eae32dcSDimitry Andric
collectUsedGlobalVariables(const Module & M,SmallVectorImpl<GlobalValue * > & Vec,bool CompilerUsed)8530b57cec5SDimitry Andric GlobalVariable *llvm::collectUsedGlobalVariables(
854fe6060f1SDimitry Andric const Module &M, SmallVectorImpl<GlobalValue *> &Vec, bool CompilerUsed) {
8550b57cec5SDimitry Andric const char *Name = CompilerUsed ? "llvm.compiler.used" : "llvm.used";
8560b57cec5SDimitry Andric GlobalVariable *GV = M.getGlobalVariable(Name);
8570b57cec5SDimitry Andric if (!GV || !GV->hasInitializer())
8580b57cec5SDimitry Andric return GV;
8590b57cec5SDimitry Andric
8600b57cec5SDimitry Andric const ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
8610b57cec5SDimitry Andric for (Value *Op : Init->operands()) {
8628bcb0991SDimitry Andric GlobalValue *G = cast<GlobalValue>(Op->stripPointerCasts());
863fe6060f1SDimitry Andric Vec.push_back(G);
8640b57cec5SDimitry Andric }
8650b57cec5SDimitry Andric return GV;
8660b57cec5SDimitry Andric }
8675ffd83dbSDimitry Andric
setPartialSampleProfileRatio(const ModuleSummaryIndex & Index)8685ffd83dbSDimitry Andric void Module::setPartialSampleProfileRatio(const ModuleSummaryIndex &Index) {
8695ffd83dbSDimitry Andric if (auto *SummaryMD = getProfileSummary(/*IsCS*/ false)) {
8705ffd83dbSDimitry Andric std::unique_ptr<ProfileSummary> ProfileSummary(
8715ffd83dbSDimitry Andric ProfileSummary::getFromMD(SummaryMD));
8725ffd83dbSDimitry Andric if (ProfileSummary) {
8735ffd83dbSDimitry Andric if (ProfileSummary->getKind() != ProfileSummary::PSK_Sample ||
8745ffd83dbSDimitry Andric !ProfileSummary->isPartialProfile())
8755ffd83dbSDimitry Andric return;
8765ffd83dbSDimitry Andric uint64_t BlockCount = Index.getBlockCount();
8775ffd83dbSDimitry Andric uint32_t NumCounts = ProfileSummary->getNumCounts();
8785ffd83dbSDimitry Andric if (!NumCounts)
8795ffd83dbSDimitry Andric return;
8805ffd83dbSDimitry Andric double Ratio = (double)BlockCount / NumCounts;
8815ffd83dbSDimitry Andric ProfileSummary->setPartialProfileRatio(Ratio);
8825ffd83dbSDimitry Andric setProfileSummary(ProfileSummary->getMD(getContext()),
8835ffd83dbSDimitry Andric ProfileSummary::PSK_Sample);
8845ffd83dbSDimitry Andric }
8855ffd83dbSDimitry Andric }
8865ffd83dbSDimitry Andric }
8870eae32dcSDimitry Andric
getDarwinTargetVariantTriple() const8880eae32dcSDimitry Andric StringRef Module::getDarwinTargetVariantTriple() const {
8890eae32dcSDimitry Andric if (const auto *MD = getModuleFlag("darwin.target_variant.triple"))
8900eae32dcSDimitry Andric return cast<MDString>(MD)->getString();
8910eae32dcSDimitry Andric return "";
8920eae32dcSDimitry Andric }
8930eae32dcSDimitry Andric
setDarwinTargetVariantTriple(StringRef T)89481ad6265SDimitry Andric void Module::setDarwinTargetVariantTriple(StringRef T) {
895*0fca6ea1SDimitry Andric addModuleFlag(ModFlagBehavior::Warning, "darwin.target_variant.triple",
89681ad6265SDimitry Andric MDString::get(getContext(), T));
89781ad6265SDimitry Andric }
89881ad6265SDimitry Andric
getDarwinTargetVariantSDKVersion() const8990eae32dcSDimitry Andric VersionTuple Module::getDarwinTargetVariantSDKVersion() const {
9000eae32dcSDimitry Andric return getSDKVersionMD(getModuleFlag("darwin.target_variant.SDK Version"));
9010eae32dcSDimitry Andric }
90281ad6265SDimitry Andric
setDarwinTargetVariantSDKVersion(VersionTuple Version)90381ad6265SDimitry Andric void Module::setDarwinTargetVariantSDKVersion(VersionTuple Version) {
90481ad6265SDimitry Andric addSDKVersionMD(Version, *this, "darwin.target_variant.SDK Version");
90581ad6265SDimitry Andric }
906