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/Optional.h" 160b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 170b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 180b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 190b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h" 200b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 210b57cec5SDimitry Andric #include "llvm/ADT/Twine.h" 220b57cec5SDimitry Andric #include "llvm/IR/Attributes.h" 230b57cec5SDimitry Andric #include "llvm/IR/Comdat.h" 240b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 250b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 260b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 270b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h" 280b57cec5SDimitry Andric #include "llvm/IR/Function.h" 290b57cec5SDimitry Andric #include "llvm/IR/GVMaterializer.h" 300b57cec5SDimitry Andric #include "llvm/IR/GlobalAlias.h" 310b57cec5SDimitry Andric #include "llvm/IR/GlobalIFunc.h" 320b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h" 330b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h" 340b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h" 350b57cec5SDimitry Andric #include "llvm/IR/Metadata.h" 365ffd83dbSDimitry Andric #include "llvm/IR/ModuleSummaryIndex.h" 370b57cec5SDimitry Andric #include "llvm/IR/SymbolTableListTraits.h" 380b57cec5SDimitry Andric #include "llvm/IR/Type.h" 390b57cec5SDimitry Andric #include "llvm/IR/TypeFinder.h" 400b57cec5SDimitry Andric #include "llvm/IR/Value.h" 410b57cec5SDimitry Andric #include "llvm/IR/ValueSymbolTable.h" 420b57cec5SDimitry Andric #include "llvm/Pass.h" 430b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 440b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h" 450b57cec5SDimitry Andric #include "llvm/Support/Error.h" 460b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 470b57cec5SDimitry Andric #include "llvm/Support/Path.h" 480b57cec5SDimitry Andric #include "llvm/Support/RandomNumberGenerator.h" 490b57cec5SDimitry Andric #include "llvm/Support/VersionTuple.h" 500b57cec5SDimitry Andric #include <algorithm> 510b57cec5SDimitry Andric #include <cassert> 520b57cec5SDimitry Andric #include <cstdint> 530b57cec5SDimitry Andric #include <memory> 540b57cec5SDimitry Andric #include <utility> 550b57cec5SDimitry Andric #include <vector> 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric using namespace llvm; 580b57cec5SDimitry 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 740b57cec5SDimitry Andric Module::Module(StringRef MID, LLVMContext &C) 755ffd83dbSDimitry Andric : Context(C), ValSymTab(std::make_unique<ValueSymbolTable>()), 765ffd83dbSDimitry Andric Materializer(), ModuleID(std::string(MID)), 775ffd83dbSDimitry Andric SourceFileName(std::string(MID)), DL("") { 780b57cec5SDimitry Andric Context.addModule(this); 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric 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 905ffd83dbSDimitry Andric std::unique_ptr<RandomNumberGenerator> 915ffd83dbSDimitry Andric Module::createRNG(const StringRef Name) const { 925ffd83dbSDimitry Andric SmallString<32> Salt(Name); 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric // This RNG is guaranteed to produce the same random stream only 950b57cec5SDimitry Andric // when the Module ID and thus the input filename is the same. This 960b57cec5SDimitry Andric // might be problematic if the input filename extension changes 970b57cec5SDimitry Andric // (e.g. from .c to .bc or .ll). 980b57cec5SDimitry Andric // 990b57cec5SDimitry Andric // We could store this salt in NamedMetadata, but this would make 1000b57cec5SDimitry Andric // the parameter non-const. This would unfortunately make this 1010b57cec5SDimitry Andric // interface unusable by any Machine passes, since they only have a 1020b57cec5SDimitry Andric // const reference to their IR Module. Alternatively we can always 1030b57cec5SDimitry Andric // store salt metadata from the Module constructor. 1040b57cec5SDimitry Andric Salt += sys::path::filename(getModuleIdentifier()); 1050b57cec5SDimitry Andric 1065ffd83dbSDimitry Andric return std::unique_ptr<RandomNumberGenerator>( 1075ffd83dbSDimitry Andric new RandomNumberGenerator(Salt)); 1080b57cec5SDimitry Andric } 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric /// getNamedValue - Return the first global value in the module with 1110b57cec5SDimitry Andric /// the specified name, of arbitrary type. This method returns null 1120b57cec5SDimitry Andric /// if a global with the specified name is not found. 1130b57cec5SDimitry Andric GlobalValue *Module::getNamedValue(StringRef Name) const { 1140b57cec5SDimitry Andric return cast_or_null<GlobalValue>(getValueSymbolTable().lookup(Name)); 1150b57cec5SDimitry Andric } 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric /// getMDKindID - Return a unique non-zero ID for the specified metadata kind. 1180b57cec5SDimitry Andric /// This ID is uniqued across modules in the current LLVMContext. 1190b57cec5SDimitry Andric unsigned Module::getMDKindID(StringRef Name) const { 1200b57cec5SDimitry Andric return Context.getMDKindID(Name); 1210b57cec5SDimitry Andric } 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric /// getMDKindNames - Populate client supplied SmallVector with the name for 1240b57cec5SDimitry Andric /// custom metadata IDs registered in this LLVMContext. ID #0 is not used, 1250b57cec5SDimitry Andric /// so it is filled in as an empty string. 1260b57cec5SDimitry Andric void Module::getMDKindNames(SmallVectorImpl<StringRef> &Result) const { 1270b57cec5SDimitry Andric return Context.getMDKindNames(Result); 1280b57cec5SDimitry Andric } 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric void Module::getOperandBundleTags(SmallVectorImpl<StringRef> &Result) const { 1310b57cec5SDimitry Andric return Context.getOperandBundleTags(Result); 1320b57cec5SDimitry Andric } 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1350b57cec5SDimitry Andric // Methods for easy access to the functions in the module. 1360b57cec5SDimitry Andric // 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric // getOrInsertFunction - Look up the specified function in the module symbol 1390b57cec5SDimitry Andric // table. If it does not exist, add a prototype for the function and return 1400b57cec5SDimitry Andric // it. This is nice because it allows most passes to get away with not handling 1410b57cec5SDimitry Andric // the symbol table directly for this common task. 1420b57cec5SDimitry Andric // 1430b57cec5SDimitry Andric FunctionCallee Module::getOrInsertFunction(StringRef Name, FunctionType *Ty, 1440b57cec5SDimitry Andric AttributeList AttributeList) { 1450b57cec5SDimitry Andric // See if we have a definition for the specified function already. 1460b57cec5SDimitry Andric GlobalValue *F = getNamedValue(Name); 1470b57cec5SDimitry Andric if (!F) { 1480b57cec5SDimitry Andric // Nope, add it 1490b57cec5SDimitry Andric Function *New = Function::Create(Ty, GlobalVariable::ExternalLinkage, 1500b57cec5SDimitry Andric DL.getProgramAddressSpace(), Name); 1510b57cec5SDimitry Andric if (!New->isIntrinsic()) // Intrinsics get attrs set on construction 1520b57cec5SDimitry Andric New->setAttributes(AttributeList); 1530b57cec5SDimitry Andric FunctionList.push_back(New); 1540b57cec5SDimitry Andric return {Ty, New}; // Return the new prototype. 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric // If the function exists but has the wrong type, return a bitcast to the 1580b57cec5SDimitry Andric // right type. 1590b57cec5SDimitry Andric auto *PTy = PointerType::get(Ty, F->getAddressSpace()); 1600b57cec5SDimitry Andric if (F->getType() != PTy) 1610b57cec5SDimitry Andric return {Ty, ConstantExpr::getBitCast(F, PTy)}; 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric // Otherwise, we just found the existing function or a prototype. 1640b57cec5SDimitry Andric return {Ty, F}; 1650b57cec5SDimitry Andric } 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric FunctionCallee Module::getOrInsertFunction(StringRef Name, FunctionType *Ty) { 1680b57cec5SDimitry Andric return getOrInsertFunction(Name, Ty, AttributeList()); 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric // getFunction - Look up the specified function in the module symbol table. 1720b57cec5SDimitry Andric // If it does not exist, return null. 1730b57cec5SDimitry Andric // 1740b57cec5SDimitry Andric Function *Module::getFunction(StringRef Name) const { 1750b57cec5SDimitry Andric return dyn_cast_or_null<Function>(getNamedValue(Name)); 1760b57cec5SDimitry Andric } 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1790b57cec5SDimitry Andric // Methods for easy access to the global variables in the module. 1800b57cec5SDimitry Andric // 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric /// getGlobalVariable - Look up the specified global variable in the module 1830b57cec5SDimitry Andric /// symbol table. If it does not exist, return null. The type argument 1840b57cec5SDimitry Andric /// should be the underlying type of the global, i.e., it should not have 1850b57cec5SDimitry Andric /// the top-level PointerType, which represents the address of the global. 1860b57cec5SDimitry Andric /// If AllowLocal is set to true, this function will return types that 1870b57cec5SDimitry Andric /// have an local. By default, these types are not returned. 1880b57cec5SDimitry Andric /// 1890b57cec5SDimitry Andric GlobalVariable *Module::getGlobalVariable(StringRef Name, 1900b57cec5SDimitry Andric bool AllowLocal) const { 1910b57cec5SDimitry Andric if (GlobalVariable *Result = 1920b57cec5SDimitry Andric dyn_cast_or_null<GlobalVariable>(getNamedValue(Name))) 1930b57cec5SDimitry Andric if (AllowLocal || !Result->hasLocalLinkage()) 1940b57cec5SDimitry Andric return Result; 1950b57cec5SDimitry Andric return nullptr; 1960b57cec5SDimitry Andric } 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric /// getOrInsertGlobal - Look up the specified global in the module symbol table. 1990b57cec5SDimitry Andric /// 1. If it does not exist, add a declaration of the global and return it. 2000b57cec5SDimitry Andric /// 2. Else, the global exists but has the wrong type: return the function 2010b57cec5SDimitry Andric /// with a constantexpr cast to the right type. 2020b57cec5SDimitry Andric /// 3. Finally, if the existing global is the correct declaration, return the 2030b57cec5SDimitry Andric /// existing global. 2040b57cec5SDimitry Andric Constant *Module::getOrInsertGlobal( 2050b57cec5SDimitry Andric StringRef Name, Type *Ty, 2060b57cec5SDimitry Andric function_ref<GlobalVariable *()> CreateGlobalCallback) { 2070b57cec5SDimitry Andric // See if we have a definition for the specified global already. 2080b57cec5SDimitry Andric GlobalVariable *GV = dyn_cast_or_null<GlobalVariable>(getNamedValue(Name)); 2090b57cec5SDimitry Andric if (!GV) 2100b57cec5SDimitry Andric GV = CreateGlobalCallback(); 2110b57cec5SDimitry Andric assert(GV && "The CreateGlobalCallback is expected to create a global"); 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric // If the variable exists but has the wrong type, return a bitcast to the 2140b57cec5SDimitry Andric // right type. 2150b57cec5SDimitry Andric Type *GVTy = GV->getType(); 2160b57cec5SDimitry Andric PointerType *PTy = PointerType::get(Ty, GVTy->getPointerAddressSpace()); 2170b57cec5SDimitry Andric if (GVTy != PTy) 2180b57cec5SDimitry Andric return ConstantExpr::getBitCast(GV, PTy); 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric // Otherwise, we just found the existing function or a prototype. 2210b57cec5SDimitry Andric return GV; 2220b57cec5SDimitry Andric } 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric // Overload to construct a global variable using its constructor's defaults. 2250b57cec5SDimitry Andric Constant *Module::getOrInsertGlobal(StringRef Name, Type *Ty) { 2260b57cec5SDimitry Andric return getOrInsertGlobal(Name, Ty, [&] { 2270b57cec5SDimitry Andric return new GlobalVariable(*this, Ty, false, GlobalVariable::ExternalLinkage, 2280b57cec5SDimitry Andric nullptr, Name); 2290b57cec5SDimitry Andric }); 2300b57cec5SDimitry Andric } 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2330b57cec5SDimitry Andric // Methods for easy access to the global variables in the module. 2340b57cec5SDimitry Andric // 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric // getNamedAlias - Look up the specified global in the module symbol table. 2370b57cec5SDimitry Andric // If it does not exist, return null. 2380b57cec5SDimitry Andric // 2390b57cec5SDimitry Andric GlobalAlias *Module::getNamedAlias(StringRef Name) const { 2400b57cec5SDimitry Andric return dyn_cast_or_null<GlobalAlias>(getNamedValue(Name)); 2410b57cec5SDimitry Andric } 2420b57cec5SDimitry Andric 2430b57cec5SDimitry Andric GlobalIFunc *Module::getNamedIFunc(StringRef Name) const { 2440b57cec5SDimitry Andric return dyn_cast_or_null<GlobalIFunc>(getNamedValue(Name)); 2450b57cec5SDimitry Andric } 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric /// getNamedMetadata - Return the first NamedMDNode in the module with the 2480b57cec5SDimitry Andric /// specified name. This method returns null if a NamedMDNode with the 2490b57cec5SDimitry Andric /// specified name is not found. 2500b57cec5SDimitry Andric NamedMDNode *Module::getNamedMetadata(const Twine &Name) const { 2510b57cec5SDimitry Andric SmallString<256> NameData; 2520b57cec5SDimitry Andric StringRef NameRef = Name.toStringRef(NameData); 2535ffd83dbSDimitry Andric return NamedMDSymTab.lookup(NameRef); 2540b57cec5SDimitry Andric } 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric /// getOrInsertNamedMetadata - Return the first named MDNode in the module 2570b57cec5SDimitry Andric /// with the specified name. This method returns a new NamedMDNode if a 2580b57cec5SDimitry Andric /// NamedMDNode with the specified name is not found. 2590b57cec5SDimitry Andric NamedMDNode *Module::getOrInsertNamedMetadata(StringRef Name) { 2605ffd83dbSDimitry Andric NamedMDNode *&NMD = NamedMDSymTab[Name]; 2610b57cec5SDimitry Andric if (!NMD) { 2620b57cec5SDimitry Andric NMD = new NamedMDNode(Name); 2630b57cec5SDimitry Andric NMD->setParent(this); 2640b57cec5SDimitry Andric NamedMDList.push_back(NMD); 2650b57cec5SDimitry Andric } 2660b57cec5SDimitry Andric return NMD; 2670b57cec5SDimitry Andric } 2680b57cec5SDimitry Andric 2690b57cec5SDimitry Andric /// eraseNamedMetadata - Remove the given NamedMDNode from this module and 2700b57cec5SDimitry Andric /// delete it. 2710b57cec5SDimitry Andric void Module::eraseNamedMetadata(NamedMDNode *NMD) { 2725ffd83dbSDimitry Andric NamedMDSymTab.erase(NMD->getName()); 2730b57cec5SDimitry Andric NamedMDList.erase(NMD->getIterator()); 2740b57cec5SDimitry Andric } 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric bool Module::isValidModFlagBehavior(Metadata *MD, ModFlagBehavior &MFB) { 2770b57cec5SDimitry Andric if (ConstantInt *Behavior = mdconst::dyn_extract_or_null<ConstantInt>(MD)) { 2780b57cec5SDimitry Andric uint64_t Val = Behavior->getLimitedValue(); 2790b57cec5SDimitry Andric if (Val >= ModFlagBehaviorFirstVal && Val <= ModFlagBehaviorLastVal) { 2800b57cec5SDimitry Andric MFB = static_cast<ModFlagBehavior>(Val); 2810b57cec5SDimitry Andric return true; 2820b57cec5SDimitry Andric } 2830b57cec5SDimitry Andric } 2840b57cec5SDimitry Andric return false; 2850b57cec5SDimitry Andric } 2860b57cec5SDimitry Andric 2875ffd83dbSDimitry Andric bool Module::isValidModuleFlag(const MDNode &ModFlag, ModFlagBehavior &MFB, 2885ffd83dbSDimitry Andric MDString *&Key, Metadata *&Val) { 2895ffd83dbSDimitry Andric if (ModFlag.getNumOperands() < 3) 2905ffd83dbSDimitry Andric return false; 2915ffd83dbSDimitry Andric if (!isValidModFlagBehavior(ModFlag.getOperand(0), MFB)) 2925ffd83dbSDimitry Andric return false; 2935ffd83dbSDimitry Andric MDString *K = dyn_cast_or_null<MDString>(ModFlag.getOperand(1)); 2945ffd83dbSDimitry Andric if (!K) 2955ffd83dbSDimitry Andric return false; 2965ffd83dbSDimitry Andric Key = K; 2975ffd83dbSDimitry Andric Val = ModFlag.getOperand(2); 2985ffd83dbSDimitry Andric return true; 2995ffd83dbSDimitry Andric } 3005ffd83dbSDimitry Andric 3010b57cec5SDimitry Andric /// getModuleFlagsMetadata - Returns the module flags in the provided vector. 3020b57cec5SDimitry Andric void Module:: 3030b57cec5SDimitry Andric getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const { 3040b57cec5SDimitry Andric const NamedMDNode *ModFlags = getModuleFlagsMetadata(); 3050b57cec5SDimitry Andric if (!ModFlags) return; 3060b57cec5SDimitry Andric 3070b57cec5SDimitry Andric for (const MDNode *Flag : ModFlags->operands()) { 3080b57cec5SDimitry Andric ModFlagBehavior MFB; 3095ffd83dbSDimitry Andric MDString *Key = nullptr; 3105ffd83dbSDimitry Andric Metadata *Val = nullptr; 3115ffd83dbSDimitry Andric if (isValidModuleFlag(*Flag, MFB, Key, Val)) { 3120b57cec5SDimitry Andric // Check the operands of the MDNode before accessing the operands. 3130b57cec5SDimitry Andric // The verifier will actually catch these failures. 3140b57cec5SDimitry Andric Flags.push_back(ModuleFlagEntry(MFB, Key, Val)); 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric } 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric /// Return the corresponding value if Key appears in module flags, otherwise 3200b57cec5SDimitry Andric /// return null. 3210b57cec5SDimitry Andric Metadata *Module::getModuleFlag(StringRef Key) const { 3220b57cec5SDimitry Andric SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags; 3230b57cec5SDimitry Andric getModuleFlagsMetadata(ModuleFlags); 3240b57cec5SDimitry Andric for (const ModuleFlagEntry &MFE : ModuleFlags) { 3250b57cec5SDimitry Andric if (Key == MFE.Key->getString()) 3260b57cec5SDimitry Andric return MFE.Val; 3270b57cec5SDimitry Andric } 3280b57cec5SDimitry Andric return nullptr; 3290b57cec5SDimitry Andric } 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric /// getModuleFlagsMetadata - Returns the NamedMDNode in the module that 3320b57cec5SDimitry Andric /// represents module-level flags. This method returns null if there are no 3330b57cec5SDimitry Andric /// module-level flags. 3340b57cec5SDimitry Andric NamedMDNode *Module::getModuleFlagsMetadata() const { 3350b57cec5SDimitry Andric return getNamedMetadata("llvm.module.flags"); 3360b57cec5SDimitry Andric } 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric /// getOrInsertModuleFlagsMetadata - Returns the NamedMDNode in the module that 3390b57cec5SDimitry Andric /// represents module-level flags. If module-level flags aren't found, it 3400b57cec5SDimitry Andric /// creates the named metadata that contains them. 3410b57cec5SDimitry Andric NamedMDNode *Module::getOrInsertModuleFlagsMetadata() { 3420b57cec5SDimitry Andric return getOrInsertNamedMetadata("llvm.module.flags"); 3430b57cec5SDimitry Andric } 3440b57cec5SDimitry Andric 3450b57cec5SDimitry Andric /// addModuleFlag - Add a module-level flag to the module-level flags 3460b57cec5SDimitry Andric /// metadata. It will create the module-level flags named metadata if it doesn't 3470b57cec5SDimitry Andric /// already exist. 3480b57cec5SDimitry Andric void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key, 3490b57cec5SDimitry Andric Metadata *Val) { 3500b57cec5SDimitry Andric Type *Int32Ty = Type::getInt32Ty(Context); 3510b57cec5SDimitry Andric Metadata *Ops[3] = { 3520b57cec5SDimitry Andric ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Behavior)), 3530b57cec5SDimitry Andric MDString::get(Context, Key), Val}; 3540b57cec5SDimitry Andric getOrInsertModuleFlagsMetadata()->addOperand(MDNode::get(Context, Ops)); 3550b57cec5SDimitry Andric } 3560b57cec5SDimitry Andric void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key, 3570b57cec5SDimitry Andric Constant *Val) { 3580b57cec5SDimitry Andric addModuleFlag(Behavior, Key, ConstantAsMetadata::get(Val)); 3590b57cec5SDimitry Andric } 3600b57cec5SDimitry Andric void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key, 3610b57cec5SDimitry Andric uint32_t Val) { 3620b57cec5SDimitry Andric Type *Int32Ty = Type::getInt32Ty(Context); 3630b57cec5SDimitry Andric addModuleFlag(Behavior, Key, ConstantInt::get(Int32Ty, Val)); 3640b57cec5SDimitry Andric } 3650b57cec5SDimitry Andric void Module::addModuleFlag(MDNode *Node) { 3660b57cec5SDimitry Andric assert(Node->getNumOperands() == 3 && 3670b57cec5SDimitry Andric "Invalid number of operands for module flag!"); 3680b57cec5SDimitry Andric assert(mdconst::hasa<ConstantInt>(Node->getOperand(0)) && 3690b57cec5SDimitry Andric isa<MDString>(Node->getOperand(1)) && 3700b57cec5SDimitry Andric "Invalid operand types for module flag!"); 3710b57cec5SDimitry Andric getOrInsertModuleFlagsMetadata()->addOperand(Node); 3720b57cec5SDimitry Andric } 3730b57cec5SDimitry Andric 3745ffd83dbSDimitry Andric void Module::setModuleFlag(ModFlagBehavior Behavior, StringRef Key, 3755ffd83dbSDimitry Andric Metadata *Val) { 3765ffd83dbSDimitry Andric NamedMDNode *ModFlags = getOrInsertModuleFlagsMetadata(); 3775ffd83dbSDimitry Andric // Replace the flag if it already exists. 3785ffd83dbSDimitry Andric for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) { 3795ffd83dbSDimitry Andric MDNode *Flag = ModFlags->getOperand(I); 3805ffd83dbSDimitry Andric ModFlagBehavior MFB; 3815ffd83dbSDimitry Andric MDString *K = nullptr; 3825ffd83dbSDimitry Andric Metadata *V = nullptr; 3835ffd83dbSDimitry Andric if (isValidModuleFlag(*Flag, MFB, K, V) && K->getString() == Key) { 3845ffd83dbSDimitry Andric Flag->replaceOperandWith(2, Val); 3855ffd83dbSDimitry Andric return; 3865ffd83dbSDimitry Andric } 3875ffd83dbSDimitry Andric } 3885ffd83dbSDimitry Andric addModuleFlag(Behavior, Key, Val); 3895ffd83dbSDimitry Andric } 3905ffd83dbSDimitry Andric 3910b57cec5SDimitry Andric void Module::setDataLayout(StringRef Desc) { 3920b57cec5SDimitry Andric DL.reset(Desc); 3930b57cec5SDimitry Andric } 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric void Module::setDataLayout(const DataLayout &Other) { DL = Other; } 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric const DataLayout &Module::getDataLayout() const { return DL; } 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andric DICompileUnit *Module::debug_compile_units_iterator::operator*() const { 4000b57cec5SDimitry Andric return cast<DICompileUnit>(CUs->getOperand(Idx)); 4010b57cec5SDimitry Andric } 4020b57cec5SDimitry Andric DICompileUnit *Module::debug_compile_units_iterator::operator->() const { 4030b57cec5SDimitry Andric return cast<DICompileUnit>(CUs->getOperand(Idx)); 4040b57cec5SDimitry Andric } 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andric void Module::debug_compile_units_iterator::SkipNoDebugCUs() { 4070b57cec5SDimitry Andric while (CUs && (Idx < CUs->getNumOperands()) && 4080b57cec5SDimitry Andric ((*this)->getEmissionKind() == DICompileUnit::NoDebug)) 4090b57cec5SDimitry Andric ++Idx; 4100b57cec5SDimitry Andric } 4110b57cec5SDimitry Andric 412480093f4SDimitry Andric iterator_range<Module::global_object_iterator> Module::global_objects() { 413480093f4SDimitry Andric return concat<GlobalObject>(functions(), globals()); 414480093f4SDimitry Andric } 415480093f4SDimitry Andric iterator_range<Module::const_global_object_iterator> 416480093f4SDimitry Andric Module::global_objects() const { 417480093f4SDimitry Andric return concat<const GlobalObject>(functions(), globals()); 418480093f4SDimitry Andric } 419480093f4SDimitry Andric 420480093f4SDimitry Andric iterator_range<Module::global_value_iterator> Module::global_values() { 421480093f4SDimitry Andric return concat<GlobalValue>(functions(), globals(), aliases(), ifuncs()); 422480093f4SDimitry Andric } 423480093f4SDimitry Andric iterator_range<Module::const_global_value_iterator> 424480093f4SDimitry Andric Module::global_values() const { 425480093f4SDimitry Andric return concat<const GlobalValue>(functions(), globals(), aliases(), ifuncs()); 426480093f4SDimitry Andric } 427480093f4SDimitry Andric 4280b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4290b57cec5SDimitry Andric // Methods to control the materialization of GlobalValues in the Module. 4300b57cec5SDimitry Andric // 4310b57cec5SDimitry Andric void Module::setMaterializer(GVMaterializer *GVM) { 4320b57cec5SDimitry Andric assert(!Materializer && 4330b57cec5SDimitry Andric "Module already has a GVMaterializer. Call materializeAll" 4340b57cec5SDimitry Andric " to clear it out before setting another one."); 4350b57cec5SDimitry Andric Materializer.reset(GVM); 4360b57cec5SDimitry Andric } 4370b57cec5SDimitry Andric 4380b57cec5SDimitry Andric Error Module::materialize(GlobalValue *GV) { 4390b57cec5SDimitry Andric if (!Materializer) 4400b57cec5SDimitry Andric return Error::success(); 4410b57cec5SDimitry Andric 4420b57cec5SDimitry Andric return Materializer->materialize(GV); 4430b57cec5SDimitry Andric } 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric Error Module::materializeAll() { 4460b57cec5SDimitry Andric if (!Materializer) 4470b57cec5SDimitry Andric return Error::success(); 4480b57cec5SDimitry Andric std::unique_ptr<GVMaterializer> M = std::move(Materializer); 4490b57cec5SDimitry Andric return M->materializeModule(); 4500b57cec5SDimitry Andric } 4510b57cec5SDimitry Andric 4520b57cec5SDimitry Andric Error Module::materializeMetadata() { 4530b57cec5SDimitry Andric if (!Materializer) 4540b57cec5SDimitry Andric return Error::success(); 4550b57cec5SDimitry Andric return Materializer->materializeMetadata(); 4560b57cec5SDimitry Andric } 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4590b57cec5SDimitry Andric // Other module related stuff. 4600b57cec5SDimitry Andric // 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andric std::vector<StructType *> Module::getIdentifiedStructTypes() const { 4630b57cec5SDimitry Andric // If we have a materializer, it is possible that some unread function 4640b57cec5SDimitry Andric // uses a type that is currently not visible to a TypeFinder, so ask 4650b57cec5SDimitry Andric // the materializer which types it created. 4660b57cec5SDimitry Andric if (Materializer) 4670b57cec5SDimitry Andric return Materializer->getIdentifiedStructTypes(); 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric std::vector<StructType *> Ret; 4700b57cec5SDimitry Andric TypeFinder SrcStructTypes; 4710b57cec5SDimitry Andric SrcStructTypes.run(*this, true); 4720b57cec5SDimitry Andric Ret.assign(SrcStructTypes.begin(), SrcStructTypes.end()); 4730b57cec5SDimitry Andric return Ret; 4740b57cec5SDimitry Andric } 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric // dropAllReferences() - This function causes all the subelements to "let go" 4770b57cec5SDimitry Andric // of all references that they are maintaining. This allows one to 'delete' a 4780b57cec5SDimitry Andric // whole module at a time, even though there may be circular references... first 4790b57cec5SDimitry Andric // all references are dropped, and all use counts go to zero. Then everything 4800b57cec5SDimitry Andric // is deleted for real. Note that no operations are valid on an object that 4810b57cec5SDimitry Andric // has "dropped all references", except operator delete. 4820b57cec5SDimitry Andric // 4830b57cec5SDimitry Andric void Module::dropAllReferences() { 4840b57cec5SDimitry Andric for (Function &F : *this) 4850b57cec5SDimitry Andric F.dropAllReferences(); 4860b57cec5SDimitry Andric 4870b57cec5SDimitry Andric for (GlobalVariable &GV : globals()) 4880b57cec5SDimitry Andric GV.dropAllReferences(); 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andric for (GlobalAlias &GA : aliases()) 4910b57cec5SDimitry Andric GA.dropAllReferences(); 4920b57cec5SDimitry Andric 4930b57cec5SDimitry Andric for (GlobalIFunc &GIF : ifuncs()) 4940b57cec5SDimitry Andric GIF.dropAllReferences(); 4950b57cec5SDimitry Andric } 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric unsigned Module::getNumberRegisterParameters() const { 4980b57cec5SDimitry Andric auto *Val = 4990b57cec5SDimitry Andric cast_or_null<ConstantAsMetadata>(getModuleFlag("NumRegisterParameters")); 5000b57cec5SDimitry Andric if (!Val) 5010b57cec5SDimitry Andric return 0; 5020b57cec5SDimitry Andric return cast<ConstantInt>(Val->getValue())->getZExtValue(); 5030b57cec5SDimitry Andric } 5040b57cec5SDimitry Andric 5050b57cec5SDimitry Andric unsigned Module::getDwarfVersion() const { 5060b57cec5SDimitry Andric auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("Dwarf Version")); 5070b57cec5SDimitry Andric if (!Val) 5080b57cec5SDimitry Andric return 0; 5090b57cec5SDimitry Andric return cast<ConstantInt>(Val->getValue())->getZExtValue(); 5100b57cec5SDimitry Andric } 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andric unsigned Module::getCodeViewFlag() const { 5130b57cec5SDimitry Andric auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("CodeView")); 5140b57cec5SDimitry Andric if (!Val) 5150b57cec5SDimitry Andric return 0; 5160b57cec5SDimitry Andric return cast<ConstantInt>(Val->getValue())->getZExtValue(); 5170b57cec5SDimitry Andric } 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andric unsigned Module::getInstructionCount() { 5200b57cec5SDimitry Andric unsigned NumInstrs = 0; 5210b57cec5SDimitry Andric for (Function &F : FunctionList) 5220b57cec5SDimitry Andric NumInstrs += F.getInstructionCount(); 5230b57cec5SDimitry Andric return NumInstrs; 5240b57cec5SDimitry Andric } 5250b57cec5SDimitry Andric 5260b57cec5SDimitry Andric Comdat *Module::getOrInsertComdat(StringRef Name) { 5270b57cec5SDimitry Andric auto &Entry = *ComdatSymTab.insert(std::make_pair(Name, Comdat())).first; 5280b57cec5SDimitry Andric Entry.second.Name = &Entry; 5290b57cec5SDimitry Andric return &Entry.second; 5300b57cec5SDimitry Andric } 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric PICLevel::Level Module::getPICLevel() const { 5330b57cec5SDimitry Andric auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("PIC Level")); 5340b57cec5SDimitry Andric 5350b57cec5SDimitry Andric if (!Val) 5360b57cec5SDimitry Andric return PICLevel::NotPIC; 5370b57cec5SDimitry Andric 5380b57cec5SDimitry Andric return static_cast<PICLevel::Level>( 5390b57cec5SDimitry Andric cast<ConstantInt>(Val->getValue())->getZExtValue()); 5400b57cec5SDimitry Andric } 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andric void Module::setPICLevel(PICLevel::Level PL) { 5430b57cec5SDimitry Andric addModuleFlag(ModFlagBehavior::Max, "PIC Level", PL); 5440b57cec5SDimitry Andric } 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric PIELevel::Level Module::getPIELevel() const { 5470b57cec5SDimitry Andric auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("PIE Level")); 5480b57cec5SDimitry Andric 5490b57cec5SDimitry Andric if (!Val) 5500b57cec5SDimitry Andric return PIELevel::Default; 5510b57cec5SDimitry Andric 5520b57cec5SDimitry Andric return static_cast<PIELevel::Level>( 5530b57cec5SDimitry Andric cast<ConstantInt>(Val->getValue())->getZExtValue()); 5540b57cec5SDimitry Andric } 5550b57cec5SDimitry Andric 5560b57cec5SDimitry Andric void Module::setPIELevel(PIELevel::Level PL) { 5570b57cec5SDimitry Andric addModuleFlag(ModFlagBehavior::Max, "PIE Level", PL); 5580b57cec5SDimitry Andric } 5590b57cec5SDimitry Andric 5600b57cec5SDimitry Andric Optional<CodeModel::Model> Module::getCodeModel() const { 5610b57cec5SDimitry Andric auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("Code Model")); 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andric if (!Val) 5640b57cec5SDimitry Andric return None; 5650b57cec5SDimitry Andric 5660b57cec5SDimitry Andric return static_cast<CodeModel::Model>( 5670b57cec5SDimitry Andric cast<ConstantInt>(Val->getValue())->getZExtValue()); 5680b57cec5SDimitry Andric } 5690b57cec5SDimitry Andric 5700b57cec5SDimitry Andric void Module::setCodeModel(CodeModel::Model CL) { 5710b57cec5SDimitry Andric // Linking object files with different code models is undefined behavior 5720b57cec5SDimitry Andric // because the compiler would have to generate additional code (to span 5730b57cec5SDimitry Andric // longer jumps) if a larger code model is used with a smaller one. 5740b57cec5SDimitry Andric // Therefore we will treat attempts to mix code models as an error. 5750b57cec5SDimitry Andric addModuleFlag(ModFlagBehavior::Error, "Code Model", CL); 5760b57cec5SDimitry Andric } 5770b57cec5SDimitry Andric 5780b57cec5SDimitry Andric void Module::setProfileSummary(Metadata *M, ProfileSummary::Kind Kind) { 5790b57cec5SDimitry Andric if (Kind == ProfileSummary::PSK_CSInstr) 5805ffd83dbSDimitry Andric setModuleFlag(ModFlagBehavior::Error, "CSProfileSummary", M); 5810b57cec5SDimitry Andric else 5825ffd83dbSDimitry Andric setModuleFlag(ModFlagBehavior::Error, "ProfileSummary", M); 5830b57cec5SDimitry Andric } 5840b57cec5SDimitry Andric 585e8d8bef9SDimitry Andric Metadata *Module::getProfileSummary(bool IsCS) const { 5860b57cec5SDimitry Andric return (IsCS ? getModuleFlag("CSProfileSummary") 5870b57cec5SDimitry Andric : getModuleFlag("ProfileSummary")); 5880b57cec5SDimitry Andric } 5890b57cec5SDimitry Andric 5905ffd83dbSDimitry Andric bool Module::getSemanticInterposition() const { 5915ffd83dbSDimitry Andric Metadata *MF = getModuleFlag("SemanticInterposition"); 5925ffd83dbSDimitry Andric 5935ffd83dbSDimitry Andric auto *Val = cast_or_null<ConstantAsMetadata>(MF); 5945ffd83dbSDimitry Andric if (!Val) 5955ffd83dbSDimitry Andric return false; 5965ffd83dbSDimitry Andric 5975ffd83dbSDimitry Andric return cast<ConstantInt>(Val->getValue())->getZExtValue(); 5985ffd83dbSDimitry Andric } 5995ffd83dbSDimitry Andric 6005ffd83dbSDimitry Andric void Module::setSemanticInterposition(bool SI) { 6015ffd83dbSDimitry Andric addModuleFlag(ModFlagBehavior::Error, "SemanticInterposition", SI); 6025ffd83dbSDimitry Andric } 6035ffd83dbSDimitry Andric 6040b57cec5SDimitry Andric void Module::setOwnedMemoryBuffer(std::unique_ptr<MemoryBuffer> MB) { 6050b57cec5SDimitry Andric OwnedMemoryBuffer = std::move(MB); 6060b57cec5SDimitry Andric } 6070b57cec5SDimitry Andric 6080b57cec5SDimitry Andric bool Module::getRtLibUseGOT() const { 6090b57cec5SDimitry Andric auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("RtLibUseGOT")); 6100b57cec5SDimitry Andric return Val && (cast<ConstantInt>(Val->getValue())->getZExtValue() > 0); 6110b57cec5SDimitry Andric } 6120b57cec5SDimitry Andric 6130b57cec5SDimitry Andric void Module::setRtLibUseGOT() { 6140b57cec5SDimitry Andric addModuleFlag(ModFlagBehavior::Max, "RtLibUseGOT", 1); 6150b57cec5SDimitry Andric } 6160b57cec5SDimitry Andric 6170b57cec5SDimitry Andric void Module::setSDKVersion(const VersionTuple &V) { 6180b57cec5SDimitry Andric SmallVector<unsigned, 3> Entries; 6190b57cec5SDimitry Andric Entries.push_back(V.getMajor()); 6200b57cec5SDimitry Andric if (auto Minor = V.getMinor()) { 6210b57cec5SDimitry Andric Entries.push_back(*Minor); 6220b57cec5SDimitry Andric if (auto Subminor = V.getSubminor()) 6230b57cec5SDimitry Andric Entries.push_back(*Subminor); 6240b57cec5SDimitry Andric // Ignore the 'build' component as it can't be represented in the object 6250b57cec5SDimitry Andric // file. 6260b57cec5SDimitry Andric } 6270b57cec5SDimitry Andric addModuleFlag(ModFlagBehavior::Warning, "SDK Version", 6280b57cec5SDimitry Andric ConstantDataArray::get(Context, Entries)); 6290b57cec5SDimitry Andric } 6300b57cec5SDimitry Andric 6310b57cec5SDimitry Andric VersionTuple Module::getSDKVersion() const { 6320b57cec5SDimitry Andric auto *CM = dyn_cast_or_null<ConstantAsMetadata>(getModuleFlag("SDK Version")); 6330b57cec5SDimitry Andric if (!CM) 6340b57cec5SDimitry Andric return {}; 6350b57cec5SDimitry Andric auto *Arr = dyn_cast_or_null<ConstantDataArray>(CM->getValue()); 6360b57cec5SDimitry Andric if (!Arr) 6370b57cec5SDimitry Andric return {}; 6380b57cec5SDimitry Andric auto getVersionComponent = [&](unsigned Index) -> Optional<unsigned> { 6390b57cec5SDimitry Andric if (Index >= Arr->getNumElements()) 6400b57cec5SDimitry Andric return None; 6410b57cec5SDimitry Andric return (unsigned)Arr->getElementAsInteger(Index); 6420b57cec5SDimitry Andric }; 6430b57cec5SDimitry Andric auto Major = getVersionComponent(0); 6440b57cec5SDimitry Andric if (!Major) 6450b57cec5SDimitry Andric return {}; 6460b57cec5SDimitry Andric VersionTuple Result = VersionTuple(*Major); 6470b57cec5SDimitry Andric if (auto Minor = getVersionComponent(1)) { 6480b57cec5SDimitry Andric Result = VersionTuple(*Major, *Minor); 6490b57cec5SDimitry Andric if (auto Subminor = getVersionComponent(2)) { 6500b57cec5SDimitry Andric Result = VersionTuple(*Major, *Minor, *Subminor); 6510b57cec5SDimitry Andric } 6520b57cec5SDimitry Andric } 6530b57cec5SDimitry Andric return Result; 6540b57cec5SDimitry Andric } 6550b57cec5SDimitry Andric 6560b57cec5SDimitry Andric GlobalVariable *llvm::collectUsedGlobalVariables( 6570b57cec5SDimitry Andric const Module &M, SmallPtrSetImpl<GlobalValue *> &Set, bool CompilerUsed) { 6580b57cec5SDimitry Andric const char *Name = CompilerUsed ? "llvm.compiler.used" : "llvm.used"; 6590b57cec5SDimitry Andric GlobalVariable *GV = M.getGlobalVariable(Name); 6600b57cec5SDimitry Andric if (!GV || !GV->hasInitializer()) 6610b57cec5SDimitry Andric return GV; 6620b57cec5SDimitry Andric 6630b57cec5SDimitry Andric const ConstantArray *Init = cast<ConstantArray>(GV->getInitializer()); 6640b57cec5SDimitry Andric for (Value *Op : Init->operands()) { 6658bcb0991SDimitry Andric GlobalValue *G = cast<GlobalValue>(Op->stripPointerCasts()); 6660b57cec5SDimitry Andric Set.insert(G); 6670b57cec5SDimitry Andric } 6680b57cec5SDimitry Andric return GV; 6690b57cec5SDimitry Andric } 6705ffd83dbSDimitry Andric 6715ffd83dbSDimitry Andric void Module::setPartialSampleProfileRatio(const ModuleSummaryIndex &Index) { 6725ffd83dbSDimitry Andric if (auto *SummaryMD = getProfileSummary(/*IsCS*/ false)) { 6735ffd83dbSDimitry Andric std::unique_ptr<ProfileSummary> ProfileSummary( 6745ffd83dbSDimitry Andric ProfileSummary::getFromMD(SummaryMD)); 6755ffd83dbSDimitry Andric if (ProfileSummary) { 6765ffd83dbSDimitry Andric if (ProfileSummary->getKind() != ProfileSummary::PSK_Sample || 6775ffd83dbSDimitry Andric !ProfileSummary->isPartialProfile()) 6785ffd83dbSDimitry Andric return; 6795ffd83dbSDimitry Andric uint64_t BlockCount = Index.getBlockCount(); 6805ffd83dbSDimitry Andric uint32_t NumCounts = ProfileSummary->getNumCounts(); 6815ffd83dbSDimitry Andric if (!NumCounts) 6825ffd83dbSDimitry Andric return; 6835ffd83dbSDimitry Andric double Ratio = (double)BlockCount / NumCounts; 6845ffd83dbSDimitry Andric ProfileSummary->setPartialProfileRatio(Ratio); 6855ffd83dbSDimitry Andric setProfileSummary(ProfileSummary->getMD(getContext()), 6865ffd83dbSDimitry Andric ProfileSummary::PSK_Sample); 6875ffd83dbSDimitry Andric } 6885ffd83dbSDimitry Andric } 6895ffd83dbSDimitry Andric } 690