Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/IPO/FunctionImport.cpp
35266 views
//===- FunctionImport.cpp - ThinLTO Summary-based Function Import ---------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements Function import based on summaries.9//10//===----------------------------------------------------------------------===//1112#include "llvm/Transforms/IPO/FunctionImport.h"13#include "llvm/ADT/ArrayRef.h"14#include "llvm/ADT/STLExtras.h"15#include "llvm/ADT/SetVector.h"16#include "llvm/ADT/SmallVector.h"17#include "llvm/ADT/Statistic.h"18#include "llvm/ADT/StringRef.h"19#include "llvm/Bitcode/BitcodeReader.h"20#include "llvm/IR/AutoUpgrade.h"21#include "llvm/IR/Constants.h"22#include "llvm/IR/Function.h"23#include "llvm/IR/GlobalAlias.h"24#include "llvm/IR/GlobalObject.h"25#include "llvm/IR/GlobalValue.h"26#include "llvm/IR/GlobalVariable.h"27#include "llvm/IR/Metadata.h"28#include "llvm/IR/Module.h"29#include "llvm/IR/ModuleSummaryIndex.h"30#include "llvm/IRReader/IRReader.h"31#include "llvm/Linker/IRMover.h"32#include "llvm/Support/Casting.h"33#include "llvm/Support/CommandLine.h"34#include "llvm/Support/Debug.h"35#include "llvm/Support/Errc.h"36#include "llvm/Support/Error.h"37#include "llvm/Support/ErrorHandling.h"38#include "llvm/Support/FileSystem.h"39#include "llvm/Support/JSON.h"40#include "llvm/Support/SourceMgr.h"41#include "llvm/Support/raw_ostream.h"42#include "llvm/Transforms/IPO/Internalize.h"43#include "llvm/Transforms/Utils/Cloning.h"44#include "llvm/Transforms/Utils/FunctionImportUtils.h"45#include "llvm/Transforms/Utils/ValueMapper.h"46#include <cassert>47#include <memory>48#include <set>49#include <string>50#include <system_error>51#include <tuple>52#include <utility>5354using namespace llvm;5556#define DEBUG_TYPE "function-import"5758STATISTIC(NumImportedFunctionsThinLink,59"Number of functions thin link decided to import");60STATISTIC(NumImportedHotFunctionsThinLink,61"Number of hot functions thin link decided to import");62STATISTIC(NumImportedCriticalFunctionsThinLink,63"Number of critical functions thin link decided to import");64STATISTIC(NumImportedGlobalVarsThinLink,65"Number of global variables thin link decided to import");66STATISTIC(NumImportedFunctions, "Number of functions imported in backend");67STATISTIC(NumImportedGlobalVars,68"Number of global variables imported in backend");69STATISTIC(NumImportedModules, "Number of modules imported from");70STATISTIC(NumDeadSymbols, "Number of dead stripped symbols in index");71STATISTIC(NumLiveSymbols, "Number of live symbols in index");7273/// Limit on instruction count of imported functions.74static cl::opt<unsigned> ImportInstrLimit(75"import-instr-limit", cl::init(100), cl::Hidden, cl::value_desc("N"),76cl::desc("Only import functions with less than N instructions"));7778static cl::opt<int> ImportCutoff(79"import-cutoff", cl::init(-1), cl::Hidden, cl::value_desc("N"),80cl::desc("Only import first N functions if N>=0 (default -1)"));8182static cl::opt<bool>83ForceImportAll("force-import-all", cl::init(false), cl::Hidden,84cl::desc("Import functions with noinline attribute"));8586static cl::opt<float>87ImportInstrFactor("import-instr-evolution-factor", cl::init(0.7),88cl::Hidden, cl::value_desc("x"),89cl::desc("As we import functions, multiply the "90"`import-instr-limit` threshold by this factor "91"before processing newly imported functions"));9293static cl::opt<float> ImportHotInstrFactor(94"import-hot-evolution-factor", cl::init(1.0), cl::Hidden,95cl::value_desc("x"),96cl::desc("As we import functions called from hot callsite, multiply the "97"`import-instr-limit` threshold by this factor "98"before processing newly imported functions"));99100static cl::opt<float> ImportHotMultiplier(101"import-hot-multiplier", cl::init(10.0), cl::Hidden, cl::value_desc("x"),102cl::desc("Multiply the `import-instr-limit` threshold for hot callsites"));103104static cl::opt<float> ImportCriticalMultiplier(105"import-critical-multiplier", cl::init(100.0), cl::Hidden,106cl::value_desc("x"),107cl::desc(108"Multiply the `import-instr-limit` threshold for critical callsites"));109110// FIXME: This multiplier was not really tuned up.111static cl::opt<float> ImportColdMultiplier(112"import-cold-multiplier", cl::init(0), cl::Hidden, cl::value_desc("N"),113cl::desc("Multiply the `import-instr-limit` threshold for cold callsites"));114115static cl::opt<bool> PrintImports("print-imports", cl::init(false), cl::Hidden,116cl::desc("Print imported functions"));117118static cl::opt<bool> PrintImportFailures(119"print-import-failures", cl::init(false), cl::Hidden,120cl::desc("Print information for functions rejected for importing"));121122static cl::opt<bool> ComputeDead("compute-dead", cl::init(true), cl::Hidden,123cl::desc("Compute dead symbols"));124125static cl::opt<bool> EnableImportMetadata(126"enable-import-metadata", cl::init(false), cl::Hidden,127cl::desc("Enable import metadata like 'thinlto_src_module' and "128"'thinlto_src_file'"));129130/// Summary file to use for function importing when using -function-import from131/// the command line.132static cl::opt<std::string>133SummaryFile("summary-file",134cl::desc("The summary file to use for function importing."));135136/// Used when testing importing from distributed indexes via opt137// -function-import.138static cl::opt<bool>139ImportAllIndex("import-all-index",140cl::desc("Import all external functions in index."));141142/// This is a test-only option.143/// If this option is enabled, the ThinLTO indexing step will import each144/// function declaration as a fallback. In a real build this may increase ram145/// usage of the indexing step unnecessarily.146/// TODO: Implement selective import (based on combined summary analysis) to147/// ensure the imported function has a use case in the postlink pipeline.148static cl::opt<bool> ImportDeclaration(149"import-declaration", cl::init(false), cl::Hidden,150cl::desc("If true, import function declaration as fallback if the function "151"definition is not imported."));152153/// Pass a workload description file - an example of workload would be the154/// functions executed to satisfy a RPC request. A workload is defined by a root155/// function and the list of functions that are (frequently) needed to satisfy156/// it. The module that defines the root will have all those functions imported.157/// The file contains a JSON dictionary. The keys are root functions, the values158/// are lists of functions to import in the module defining the root. It is159/// assumed -funique-internal-linkage-names was used, thus ensuring function160/// names are unique even for local linkage ones.161static cl::opt<std::string> WorkloadDefinitions(162"thinlto-workload-def",163cl::desc("Pass a workload definition. This is a file containing a JSON "164"dictionary. The keys are root functions, the values are lists of "165"functions to import in the module defining the root. It is "166"assumed -funique-internal-linkage-names was used, to ensure "167"local linkage functions have unique names. For example: \n"168"{\n"169" \"rootFunction_1\": [\"function_to_import_1\", "170"\"function_to_import_2\"], \n"171" \"rootFunction_2\": [\"function_to_import_3\", "172"\"function_to_import_4\"] \n"173"}"),174cl::Hidden);175176namespace llvm {177extern cl::opt<bool> EnableMemProfContextDisambiguation;178}179180// Load lazily a module from \p FileName in \p Context.181static std::unique_ptr<Module> loadFile(const std::string &FileName,182LLVMContext &Context) {183SMDiagnostic Err;184LLVM_DEBUG(dbgs() << "Loading '" << FileName << "'\n");185// Metadata isn't loaded until functions are imported, to minimize186// the memory overhead.187std::unique_ptr<Module> Result =188getLazyIRFileModule(FileName, Err, Context,189/* ShouldLazyLoadMetadata = */ true);190if (!Result) {191Err.print("function-import", errs());192report_fatal_error("Abort");193}194195return Result;196}197198/// Given a list of possible callee implementation for a call site, qualify the199/// legality of importing each. The return is a range of pairs. Each pair200/// corresponds to a candidate. The first value is the ImportFailureReason for201/// that candidate, the second is the candidate.202static auto qualifyCalleeCandidates(203const ModuleSummaryIndex &Index,204ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,205StringRef CallerModulePath) {206return llvm::map_range(207CalleeSummaryList,208[&Index, CalleeSummaryList,209CallerModulePath](const std::unique_ptr<GlobalValueSummary> &SummaryPtr)210-> std::pair<FunctionImporter::ImportFailureReason,211const GlobalValueSummary *> {212auto *GVSummary = SummaryPtr.get();213if (!Index.isGlobalValueLive(GVSummary))214return {FunctionImporter::ImportFailureReason::NotLive, GVSummary};215216if (GlobalValue::isInterposableLinkage(GVSummary->linkage()))217return {FunctionImporter::ImportFailureReason::InterposableLinkage,218GVSummary};219220auto *Summary = dyn_cast<FunctionSummary>(GVSummary->getBaseObject());221222// Ignore any callees that aren't actually functions. This could happen223// in the case of GUID hash collisions. It could also happen in theory224// for SamplePGO profiles collected on old versions of the code after225// renaming, since we synthesize edges to any inlined callees appearing226// in the profile.227if (!Summary)228return {FunctionImporter::ImportFailureReason::GlobalVar, GVSummary};229230// If this is a local function, make sure we import the copy231// in the caller's module. The only time a local function can232// share an entry in the index is if there is a local with the same name233// in another module that had the same source file name (in a different234// directory), where each was compiled in their own directory so there235// was not distinguishing path.236// However, do the import from another module if there is only one237// entry in the list - in that case this must be a reference due238// to indirect call profile data, since a function pointer can point to239// a local in another module.240if (GlobalValue::isLocalLinkage(Summary->linkage()) &&241CalleeSummaryList.size() > 1 &&242Summary->modulePath() != CallerModulePath)243return {244FunctionImporter::ImportFailureReason::LocalLinkageNotInModule,245GVSummary};246247// Skip if it isn't legal to import (e.g. may reference unpromotable248// locals).249if (Summary->notEligibleToImport())250return {FunctionImporter::ImportFailureReason::NotEligible,251GVSummary};252253return {FunctionImporter::ImportFailureReason::None, GVSummary};254});255}256257/// Given a list of possible callee implementation for a call site, select one258/// that fits the \p Threshold for function definition import. If none are259/// found, the Reason will give the last reason for the failure (last, in the260/// order of CalleeSummaryList entries). While looking for a callee definition,261/// sets \p TooLargeOrNoInlineSummary to the last seen too-large or noinline262/// candidate; other modules may want to know the function summary or263/// declaration even if a definition is not needed.264///265/// FIXME: select "best" instead of first that fits. But what is "best"?266/// - The smallest: more likely to be inlined.267/// - The one with the least outgoing edges (already well optimized).268/// - One from a module already being imported from in order to reduce the269/// number of source modules parsed/linked.270/// - One that has PGO data attached.271/// - [insert you fancy metric here]272static const GlobalValueSummary *273selectCallee(const ModuleSummaryIndex &Index,274ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,275unsigned Threshold, StringRef CallerModulePath,276const GlobalValueSummary *&TooLargeOrNoInlineSummary,277FunctionImporter::ImportFailureReason &Reason) {278// Records the last summary with reason noinline or too-large.279TooLargeOrNoInlineSummary = nullptr;280auto QualifiedCandidates =281qualifyCalleeCandidates(Index, CalleeSummaryList, CallerModulePath);282for (auto QualifiedValue : QualifiedCandidates) {283Reason = QualifiedValue.first;284// Skip a summary if its import is not (proved to be) legal.285if (Reason != FunctionImporter::ImportFailureReason::None)286continue;287auto *Summary =288cast<FunctionSummary>(QualifiedValue.second->getBaseObject());289290// Don't bother importing the definition if the chance of inlining it is291// not high enough (except under `--force-import-all`).292if ((Summary->instCount() > Threshold) && !Summary->fflags().AlwaysInline &&293!ForceImportAll) {294TooLargeOrNoInlineSummary = Summary;295Reason = FunctionImporter::ImportFailureReason::TooLarge;296continue;297}298299// Don't bother importing the definition if we can't inline it anyway.300if (Summary->fflags().NoInline && !ForceImportAll) {301TooLargeOrNoInlineSummary = Summary;302Reason = FunctionImporter::ImportFailureReason::NoInline;303continue;304}305306return Summary;307}308return nullptr;309}310311namespace {312313using EdgeInfo = std::tuple<const FunctionSummary *, unsigned /* Threshold */>;314315} // anonymous namespace316317/// Import globals referenced by a function or other globals that are being318/// imported, if importing such global is possible.319class GlobalsImporter final {320const ModuleSummaryIndex &Index;321const GVSummaryMapTy &DefinedGVSummaries;322function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>323IsPrevailing;324FunctionImporter::ImportMapTy &ImportList;325DenseMap<StringRef, FunctionImporter::ExportSetTy> *const ExportLists;326327bool shouldImportGlobal(const ValueInfo &VI) {328const auto &GVS = DefinedGVSummaries.find(VI.getGUID());329if (GVS == DefinedGVSummaries.end())330return true;331// We should not skip import if the module contains a non-prevailing332// definition with interposable linkage type. This is required for333// correctness in the situation where there is a prevailing def available334// for import and marked read-only. In this case, the non-prevailing def335// will be converted to a declaration, while the prevailing one becomes336// internal, thus no definitions will be available for linking. In order to337// prevent undefined symbol link error, the prevailing definition must be338// imported.339// FIXME: Consider adding a check that the suitable prevailing definition340// exists and marked read-only.341if (VI.getSummaryList().size() > 1 &&342GlobalValue::isInterposableLinkage(GVS->second->linkage()) &&343!IsPrevailing(VI.getGUID(), GVS->second))344return true;345346return false;347}348349void350onImportingSummaryImpl(const GlobalValueSummary &Summary,351SmallVectorImpl<const GlobalVarSummary *> &Worklist) {352for (const auto &VI : Summary.refs()) {353if (!shouldImportGlobal(VI)) {354LLVM_DEBUG(355dbgs() << "Ref ignored! Target already in destination module.\n");356continue;357}358359LLVM_DEBUG(dbgs() << " ref -> " << VI << "\n");360361// If this is a local variable, make sure we import the copy362// in the caller's module. The only time a local variable can363// share an entry in the index is if there is a local with the same name364// in another module that had the same source file name (in a different365// directory), where each was compiled in their own directory so there366// was not distinguishing path.367auto LocalNotInModule =368[&](const GlobalValueSummary *RefSummary) -> bool {369return GlobalValue::isLocalLinkage(RefSummary->linkage()) &&370RefSummary->modulePath() != Summary.modulePath();371};372373for (const auto &RefSummary : VI.getSummaryList()) {374const auto *GVS = dyn_cast<GlobalVarSummary>(RefSummary.get());375// Functions could be referenced by global vars - e.g. a vtable; but we376// don't currently imagine a reason those would be imported here, rather377// than as part of the logic deciding which functions to import (i.e.378// based on profile information). Should we decide to handle them here,379// we can refactor accordingly at that time.380if (!GVS || !Index.canImportGlobalVar(GVS, /* AnalyzeRefs */ true) ||381LocalNotInModule(GVS))382continue;383384// If there isn't an entry for GUID, insert <GUID, Definition> pair.385// Otherwise, definition should take precedence over declaration.386auto [Iter, Inserted] =387ImportList[RefSummary->modulePath()].try_emplace(388VI.getGUID(), GlobalValueSummary::Definition);389// Only update stat and exports if we haven't already imported this390// variable.391if (!Inserted) {392// Set the value to 'std::min(existing-value, new-value)' to make393// sure a definition takes precedence over a declaration.394Iter->second = std::min(GlobalValueSummary::Definition, Iter->second);395break;396}397NumImportedGlobalVarsThinLink++;398// Any references made by this variable will be marked exported399// later, in ComputeCrossModuleImport, after import decisions are400// complete, which is more efficient than adding them here.401if (ExportLists)402(*ExportLists)[RefSummary->modulePath()].insert(VI);403404// If variable is not writeonly we attempt to recursively analyze405// its references in order to import referenced constants.406if (!Index.isWriteOnly(GVS))407Worklist.emplace_back(GVS);408break;409}410}411}412413public:414GlobalsImporter(415const ModuleSummaryIndex &Index, const GVSummaryMapTy &DefinedGVSummaries,416function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>417IsPrevailing,418FunctionImporter::ImportMapTy &ImportList,419DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists)420: Index(Index), DefinedGVSummaries(DefinedGVSummaries),421IsPrevailing(IsPrevailing), ImportList(ImportList),422ExportLists(ExportLists) {}423424void onImportingSummary(const GlobalValueSummary &Summary) {425SmallVector<const GlobalVarSummary *, 128> Worklist;426onImportingSummaryImpl(Summary, Worklist);427while (!Worklist.empty())428onImportingSummaryImpl(*Worklist.pop_back_val(), Worklist);429}430};431432static const char *getFailureName(FunctionImporter::ImportFailureReason Reason);433434/// Determine the list of imports and exports for each module.435class ModuleImportsManager {436protected:437function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>438IsPrevailing;439const ModuleSummaryIndex &Index;440DenseMap<StringRef, FunctionImporter::ExportSetTy> *const ExportLists;441442ModuleImportsManager(443function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>444IsPrevailing,445const ModuleSummaryIndex &Index,446DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists = nullptr)447: IsPrevailing(IsPrevailing), Index(Index), ExportLists(ExportLists) {}448449public:450virtual ~ModuleImportsManager() = default;451452/// Given the list of globals defined in a module, compute the list of imports453/// as well as the list of "exports", i.e. the list of symbols referenced from454/// another module (that may require promotion).455virtual void456computeImportForModule(const GVSummaryMapTy &DefinedGVSummaries,457StringRef ModName,458FunctionImporter::ImportMapTy &ImportList);459460static std::unique_ptr<ModuleImportsManager>461create(function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>462IsPrevailing,463const ModuleSummaryIndex &Index,464DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists =465nullptr);466};467468/// A ModuleImportsManager that operates based on a workload definition (see469/// -thinlto-workload-def). For modules that do not define workload roots, it470/// applies the base ModuleImportsManager import policy.471class WorkloadImportsManager : public ModuleImportsManager {472// Keep a module name -> value infos to import association. We use it to473// determine if a module's import list should be done by the base474// ModuleImportsManager or by us.475StringMap<DenseSet<ValueInfo>> Workloads;476477void478computeImportForModule(const GVSummaryMapTy &DefinedGVSummaries,479StringRef ModName,480FunctionImporter::ImportMapTy &ImportList) override {481auto SetIter = Workloads.find(ModName);482if (SetIter == Workloads.end()) {483LLVM_DEBUG(dbgs() << "[Workload] " << ModName484<< " does not contain the root of any context.\n");485return ModuleImportsManager::computeImportForModule(DefinedGVSummaries,486ModName, ImportList);487}488LLVM_DEBUG(dbgs() << "[Workload] " << ModName489<< " contains the root(s) of context(s).\n");490491GlobalsImporter GVI(Index, DefinedGVSummaries, IsPrevailing, ImportList,492ExportLists);493auto &ValueInfos = SetIter->second;494SmallVector<EdgeInfo, 128> GlobWorklist;495for (auto &VI : llvm::make_early_inc_range(ValueInfos)) {496auto It = DefinedGVSummaries.find(VI.getGUID());497if (It != DefinedGVSummaries.end() &&498IsPrevailing(VI.getGUID(), It->second)) {499LLVM_DEBUG(500dbgs() << "[Workload] " << VI.name()501<< " has the prevailing variant already in the module "502<< ModName << ". No need to import\n");503continue;504}505auto Candidates =506qualifyCalleeCandidates(Index, VI.getSummaryList(), ModName);507508const GlobalValueSummary *GVS = nullptr;509auto PotentialCandidates = llvm::map_range(510llvm::make_filter_range(511Candidates,512[&](const auto &Candidate) {513LLVM_DEBUG(dbgs() << "[Workflow] Candidate for " << VI.name()514<< " from " << Candidate.second->modulePath()515<< " ImportFailureReason: "516<< getFailureName(Candidate.first) << "\n");517return Candidate.first ==518FunctionImporter::ImportFailureReason::None;519}),520[](const auto &Candidate) { return Candidate.second; });521if (PotentialCandidates.empty()) {522LLVM_DEBUG(dbgs() << "[Workload] Not importing " << VI.name()523<< " because can't find eligible Callee. Guid is: "524<< Function::getGUID(VI.name()) << "\n");525continue;526}527/// We will prefer importing the prevailing candidate, if not, we'll528/// still pick the first available candidate. The reason we want to make529/// sure we do import the prevailing candidate is because the goal of530/// workload-awareness is to enable optimizations specializing the call531/// graph of that workload. Suppose a function is already defined in the532/// module, but it's not the prevailing variant. Suppose also we do not533/// inline it (in fact, if it were interposable, we can't inline it),534/// but we could specialize it to the workload in other ways. However,535/// the linker would drop it in the favor of the prevailing copy.536/// Instead, by importing the prevailing variant (assuming also the use537/// of `-avail-extern-to-local`), we keep the specialization. We could538/// alteranatively make the non-prevailing variant local, but the539/// prevailing one is also the one for which we would have previously540/// collected profiles, making it preferrable.541auto PrevailingCandidates = llvm::make_filter_range(542PotentialCandidates, [&](const auto *Candidate) {543return IsPrevailing(VI.getGUID(), Candidate);544});545if (PrevailingCandidates.empty()) {546GVS = *PotentialCandidates.begin();547if (!llvm::hasSingleElement(PotentialCandidates) &&548GlobalValue::isLocalLinkage(GVS->linkage()))549LLVM_DEBUG(550dbgs()551<< "[Workload] Found multiple non-prevailing candidates for "552<< VI.name()553<< ". This is unexpected. Are module paths passed to the "554"compiler unique for the modules passed to the linker?");555// We could in theory have multiple (interposable) copies of a symbol556// when there is no prevailing candidate, if say the prevailing copy was557// in a native object being linked in. However, we should in theory be558// marking all of these non-prevailing IR copies dead in that case, in559// which case they won't be candidates.560assert(GVS->isLive());561} else {562assert(llvm::hasSingleElement(PrevailingCandidates));563GVS = *PrevailingCandidates.begin();564}565566auto ExportingModule = GVS->modulePath();567// We checked that for the prevailing case, but if we happen to have for568// example an internal that's defined in this module, it'd have no569// PrevailingCandidates.570if (ExportingModule == ModName) {571LLVM_DEBUG(dbgs() << "[Workload] Not importing " << VI.name()572<< " because its defining module is the same as the "573"current module\n");574continue;575}576LLVM_DEBUG(dbgs() << "[Workload][Including]" << VI.name() << " from "577<< ExportingModule << " : "578<< Function::getGUID(VI.name()) << "\n");579ImportList[ExportingModule][VI.getGUID()] =580GlobalValueSummary::Definition;581GVI.onImportingSummary(*GVS);582if (ExportLists)583(*ExportLists)[ExportingModule].insert(VI);584}585LLVM_DEBUG(dbgs() << "[Workload] Done\n");586}587588public:589WorkloadImportsManager(590function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>591IsPrevailing,592const ModuleSummaryIndex &Index,593DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists)594: ModuleImportsManager(IsPrevailing, Index, ExportLists) {595// Since the workload def uses names, we need a quick lookup596// name->ValueInfo.597StringMap<ValueInfo> NameToValueInfo;598StringSet<> AmbiguousNames;599for (auto &I : Index) {600ValueInfo VI = Index.getValueInfo(I);601if (!NameToValueInfo.insert(std::make_pair(VI.name(), VI)).second)602LLVM_DEBUG(AmbiguousNames.insert(VI.name()));603}604auto DbgReportIfAmbiguous = [&](StringRef Name) {605LLVM_DEBUG(if (AmbiguousNames.count(Name) > 0) {606dbgs() << "[Workload] Function name " << Name607<< " present in the workload definition is ambiguous. Consider "608"compiling with -funique-internal-linkage-names.";609});610};611std::error_code EC;612auto BufferOrErr = MemoryBuffer::getFileOrSTDIN(WorkloadDefinitions);613if (std::error_code EC = BufferOrErr.getError()) {614report_fatal_error("Failed to open context file");615return;616}617auto Buffer = std::move(BufferOrErr.get());618std::map<std::string, std::vector<std::string>> WorkloadDefs;619json::Path::Root NullRoot;620// The JSON is supposed to contain a dictionary matching the type of621// WorkloadDefs. For example:622// {623// "rootFunction_1": ["function_to_import_1", "function_to_import_2"],624// "rootFunction_2": ["function_to_import_3", "function_to_import_4"]625// }626auto Parsed = json::parse(Buffer->getBuffer());627if (!Parsed)628report_fatal_error(Parsed.takeError());629if (!json::fromJSON(*Parsed, WorkloadDefs, NullRoot))630report_fatal_error("Invalid thinlto contextual profile format.");631for (const auto &Workload : WorkloadDefs) {632const auto &Root = Workload.first;633DbgReportIfAmbiguous(Root);634LLVM_DEBUG(dbgs() << "[Workload] Root: " << Root << "\n");635const auto &AllCallees = Workload.second;636auto RootIt = NameToValueInfo.find(Root);637if (RootIt == NameToValueInfo.end()) {638LLVM_DEBUG(dbgs() << "[Workload] Root " << Root639<< " not found in this linkage unit.\n");640continue;641}642auto RootVI = RootIt->second;643if (RootVI.getSummaryList().size() != 1) {644LLVM_DEBUG(dbgs() << "[Workload] Root " << Root645<< " should have exactly one summary, but has "646<< RootVI.getSummaryList().size() << ". Skipping.\n");647continue;648}649StringRef RootDefiningModule =650RootVI.getSummaryList().front()->modulePath();651LLVM_DEBUG(dbgs() << "[Workload] Root defining module for " << Root652<< " is : " << RootDefiningModule << "\n");653auto &Set = Workloads[RootDefiningModule];654for (const auto &Callee : AllCallees) {655LLVM_DEBUG(dbgs() << "[Workload] " << Callee << "\n");656DbgReportIfAmbiguous(Callee);657auto ElemIt = NameToValueInfo.find(Callee);658if (ElemIt == NameToValueInfo.end()) {659LLVM_DEBUG(dbgs() << "[Workload] " << Callee << " not found\n");660continue;661}662Set.insert(ElemIt->second);663}664LLVM_DEBUG({665dbgs() << "[Workload] Root: " << Root << " we have " << Set.size()666<< " distinct callees.\n";667for (const auto &VI : Set) {668dbgs() << "[Workload] Root: " << Root669<< " Would include: " << VI.getGUID() << "\n";670}671});672}673}674};675676std::unique_ptr<ModuleImportsManager> ModuleImportsManager::create(677function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>678IsPrevailing,679const ModuleSummaryIndex &Index,680DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists) {681if (WorkloadDefinitions.empty()) {682LLVM_DEBUG(dbgs() << "[Workload] Using the regular imports manager.\n");683return std::unique_ptr<ModuleImportsManager>(684new ModuleImportsManager(IsPrevailing, Index, ExportLists));685}686LLVM_DEBUG(dbgs() << "[Workload] Using the contextual imports manager.\n");687return std::make_unique<WorkloadImportsManager>(IsPrevailing, Index,688ExportLists);689}690691static const char *692getFailureName(FunctionImporter::ImportFailureReason Reason) {693switch (Reason) {694case FunctionImporter::ImportFailureReason::None:695return "None";696case FunctionImporter::ImportFailureReason::GlobalVar:697return "GlobalVar";698case FunctionImporter::ImportFailureReason::NotLive:699return "NotLive";700case FunctionImporter::ImportFailureReason::TooLarge:701return "TooLarge";702case FunctionImporter::ImportFailureReason::InterposableLinkage:703return "InterposableLinkage";704case FunctionImporter::ImportFailureReason::LocalLinkageNotInModule:705return "LocalLinkageNotInModule";706case FunctionImporter::ImportFailureReason::NotEligible:707return "NotEligible";708case FunctionImporter::ImportFailureReason::NoInline:709return "NoInline";710}711llvm_unreachable("invalid reason");712}713714/// Compute the list of functions to import for a given caller. Mark these715/// imported functions and the symbols they reference in their source module as716/// exported from their source module.717static void computeImportForFunction(718const FunctionSummary &Summary, const ModuleSummaryIndex &Index,719const unsigned Threshold, const GVSummaryMapTy &DefinedGVSummaries,720function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>721isPrevailing,722SmallVectorImpl<EdgeInfo> &Worklist, GlobalsImporter &GVImporter,723FunctionImporter::ImportMapTy &ImportList,724DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists,725FunctionImporter::ImportThresholdsTy &ImportThresholds) {726GVImporter.onImportingSummary(Summary);727static int ImportCount = 0;728for (const auto &Edge : Summary.calls()) {729ValueInfo VI = Edge.first;730LLVM_DEBUG(dbgs() << " edge -> " << VI << " Threshold:" << Threshold731<< "\n");732733if (ImportCutoff >= 0 && ImportCount >= ImportCutoff) {734LLVM_DEBUG(dbgs() << "ignored! import-cutoff value of " << ImportCutoff735<< " reached.\n");736continue;737}738739if (DefinedGVSummaries.count(VI.getGUID())) {740// FIXME: Consider not skipping import if the module contains741// a non-prevailing def with interposable linkage. The prevailing copy742// can safely be imported (see shouldImportGlobal()).743LLVM_DEBUG(dbgs() << "ignored! Target already in destination module.\n");744continue;745}746747auto GetBonusMultiplier = [](CalleeInfo::HotnessType Hotness) -> float {748if (Hotness == CalleeInfo::HotnessType::Hot)749return ImportHotMultiplier;750if (Hotness == CalleeInfo::HotnessType::Cold)751return ImportColdMultiplier;752if (Hotness == CalleeInfo::HotnessType::Critical)753return ImportCriticalMultiplier;754return 1.0;755};756757const auto NewThreshold =758Threshold * GetBonusMultiplier(Edge.second.getHotness());759760auto IT = ImportThresholds.insert(std::make_pair(761VI.getGUID(), std::make_tuple(NewThreshold, nullptr, nullptr)));762bool PreviouslyVisited = !IT.second;763auto &ProcessedThreshold = std::get<0>(IT.first->second);764auto &CalleeSummary = std::get<1>(IT.first->second);765auto &FailureInfo = std::get<2>(IT.first->second);766767bool IsHotCallsite =768Edge.second.getHotness() == CalleeInfo::HotnessType::Hot;769bool IsCriticalCallsite =770Edge.second.getHotness() == CalleeInfo::HotnessType::Critical;771772const FunctionSummary *ResolvedCalleeSummary = nullptr;773if (CalleeSummary) {774assert(PreviouslyVisited);775// Since the traversal of the call graph is DFS, we can revisit a function776// a second time with a higher threshold. In this case, it is added back777// to the worklist with the new threshold (so that its own callee chains778// can be considered with the higher threshold).779if (NewThreshold <= ProcessedThreshold) {780LLVM_DEBUG(781dbgs() << "ignored! Target was already imported with Threshold "782<< ProcessedThreshold << "\n");783continue;784}785// Update with new larger threshold.786ProcessedThreshold = NewThreshold;787ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);788} else {789// If we already rejected importing a callee at the same or higher790// threshold, don't waste time calling selectCallee.791if (PreviouslyVisited && NewThreshold <= ProcessedThreshold) {792LLVM_DEBUG(793dbgs() << "ignored! Target was already rejected with Threshold "794<< ProcessedThreshold << "\n");795if (PrintImportFailures) {796assert(FailureInfo &&797"Expected FailureInfo for previously rejected candidate");798FailureInfo->Attempts++;799}800continue;801}802803FunctionImporter::ImportFailureReason Reason{};804805// `SummaryForDeclImport` is an summary eligible for declaration import.806const GlobalValueSummary *SummaryForDeclImport = nullptr;807CalleeSummary =808selectCallee(Index, VI.getSummaryList(), NewThreshold,809Summary.modulePath(), SummaryForDeclImport, Reason);810if (!CalleeSummary) {811// There isn't a callee for definition import but one for declaration812// import.813if (ImportDeclaration && SummaryForDeclImport) {814StringRef DeclSourceModule = SummaryForDeclImport->modulePath();815816// Since definition takes precedence over declaration for the same VI,817// try emplace <VI, declaration> pair without checking insert result.818// If insert doesn't happen, there must be an existing entry keyed by819// VI. Note `ExportLists` only keeps track of exports due to imported820// definitions.821ImportList[DeclSourceModule].try_emplace(822VI.getGUID(), GlobalValueSummary::Declaration);823}824// Update with new larger threshold if this was a retry (otherwise825// we would have already inserted with NewThreshold above). Also826// update failure info if requested.827if (PreviouslyVisited) {828ProcessedThreshold = NewThreshold;829if (PrintImportFailures) {830assert(FailureInfo &&831"Expected FailureInfo for previously rejected candidate");832FailureInfo->Reason = Reason;833FailureInfo->Attempts++;834FailureInfo->MaxHotness =835std::max(FailureInfo->MaxHotness, Edge.second.getHotness());836}837} else if (PrintImportFailures) {838assert(!FailureInfo &&839"Expected no FailureInfo for newly rejected candidate");840FailureInfo = std::make_unique<FunctionImporter::ImportFailureInfo>(841VI, Edge.second.getHotness(), Reason, 1);842}843if (ForceImportAll) {844std::string Msg = std::string("Failed to import function ") +845VI.name().str() + " due to " +846getFailureName(Reason);847auto Error = make_error<StringError>(848Msg, make_error_code(errc::not_supported));849logAllUnhandledErrors(std::move(Error), errs(),850"Error importing module: ");851break;852} else {853LLVM_DEBUG(dbgs()854<< "ignored! No qualifying callee with summary found.\n");855continue;856}857}858859// "Resolve" the summary860CalleeSummary = CalleeSummary->getBaseObject();861ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);862863assert((ResolvedCalleeSummary->fflags().AlwaysInline || ForceImportAll ||864(ResolvedCalleeSummary->instCount() <= NewThreshold)) &&865"selectCallee() didn't honor the threshold");866867auto ExportModulePath = ResolvedCalleeSummary->modulePath();868869// Try emplace the definition entry, and update stats based on insertion870// status.871auto [Iter, Inserted] = ImportList[ExportModulePath].try_emplace(872VI.getGUID(), GlobalValueSummary::Definition);873874// We previously decided to import this GUID definition if it was already875// inserted in the set of imports from the exporting module.876if (Inserted || Iter->second == GlobalValueSummary::Declaration) {877NumImportedFunctionsThinLink++;878if (IsHotCallsite)879NumImportedHotFunctionsThinLink++;880if (IsCriticalCallsite)881NumImportedCriticalFunctionsThinLink++;882}883884if (Iter->second == GlobalValueSummary::Declaration)885Iter->second = GlobalValueSummary::Definition;886887// Any calls/references made by this function will be marked exported888// later, in ComputeCrossModuleImport, after import decisions are889// complete, which is more efficient than adding them here.890if (ExportLists)891(*ExportLists)[ExportModulePath].insert(VI);892}893894auto GetAdjustedThreshold = [](unsigned Threshold, bool IsHotCallsite) {895// Adjust the threshold for next level of imported functions.896// The threshold is different for hot callsites because we can then897// inline chains of hot calls.898if (IsHotCallsite)899return Threshold * ImportHotInstrFactor;900return Threshold * ImportInstrFactor;901};902903const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite);904905ImportCount++;906907// Insert the newly imported function to the worklist.908Worklist.emplace_back(ResolvedCalleeSummary, AdjThreshold);909}910}911912void ModuleImportsManager::computeImportForModule(913const GVSummaryMapTy &DefinedGVSummaries, StringRef ModName,914FunctionImporter::ImportMapTy &ImportList) {915// Worklist contains the list of function imported in this module, for which916// we will analyse the callees and may import further down the callgraph.917SmallVector<EdgeInfo, 128> Worklist;918GlobalsImporter GVI(Index, DefinedGVSummaries, IsPrevailing, ImportList,919ExportLists);920FunctionImporter::ImportThresholdsTy ImportThresholds;921922// Populate the worklist with the import for the functions in the current923// module924for (const auto &GVSummary : DefinedGVSummaries) {925#ifndef NDEBUG926// FIXME: Change the GVSummaryMapTy to hold ValueInfo instead of GUID927// so this map look up (and possibly others) can be avoided.928auto VI = Index.getValueInfo(GVSummary.first);929#endif930if (!Index.isGlobalValueLive(GVSummary.second)) {931LLVM_DEBUG(dbgs() << "Ignores Dead GUID: " << VI << "\n");932continue;933}934auto *FuncSummary =935dyn_cast<FunctionSummary>(GVSummary.second->getBaseObject());936if (!FuncSummary)937// Skip import for global variables938continue;939LLVM_DEBUG(dbgs() << "Initialize import for " << VI << "\n");940computeImportForFunction(*FuncSummary, Index, ImportInstrLimit,941DefinedGVSummaries, IsPrevailing, Worklist, GVI,942ImportList, ExportLists, ImportThresholds);943}944945// Process the newly imported functions and add callees to the worklist.946while (!Worklist.empty()) {947auto GVInfo = Worklist.pop_back_val();948auto *Summary = std::get<0>(GVInfo);949auto Threshold = std::get<1>(GVInfo);950951if (auto *FS = dyn_cast<FunctionSummary>(Summary))952computeImportForFunction(*FS, Index, Threshold, DefinedGVSummaries,953IsPrevailing, Worklist, GVI, ImportList,954ExportLists, ImportThresholds);955}956957// Print stats about functions considered but rejected for importing958// when requested.959if (PrintImportFailures) {960dbgs() << "Missed imports into module " << ModName << "\n";961for (auto &I : ImportThresholds) {962auto &ProcessedThreshold = std::get<0>(I.second);963auto &CalleeSummary = std::get<1>(I.second);964auto &FailureInfo = std::get<2>(I.second);965if (CalleeSummary)966continue; // We are going to import.967assert(FailureInfo);968FunctionSummary *FS = nullptr;969if (!FailureInfo->VI.getSummaryList().empty())970FS = dyn_cast<FunctionSummary>(971FailureInfo->VI.getSummaryList()[0]->getBaseObject());972dbgs() << FailureInfo->VI973<< ": Reason = " << getFailureName(FailureInfo->Reason)974<< ", Threshold = " << ProcessedThreshold975<< ", Size = " << (FS ? (int)FS->instCount() : -1)976<< ", MaxHotness = " << getHotnessName(FailureInfo->MaxHotness)977<< ", Attempts = " << FailureInfo->Attempts << "\n";978}979}980}981982#ifndef NDEBUG983static bool isGlobalVarSummary(const ModuleSummaryIndex &Index, ValueInfo VI) {984auto SL = VI.getSummaryList();985return SL.empty()986? false987: SL[0]->getSummaryKind() == GlobalValueSummary::GlobalVarKind;988}989990static bool isGlobalVarSummary(const ModuleSummaryIndex &Index,991GlobalValue::GUID G) {992if (const auto &VI = Index.getValueInfo(G))993return isGlobalVarSummary(Index, VI);994return false;995}996997// Return the number of global variable summaries in ExportSet.998static unsigned999numGlobalVarSummaries(const ModuleSummaryIndex &Index,1000FunctionImporter::ExportSetTy &ExportSet) {1001unsigned NumGVS = 0;1002for (auto &VI : ExportSet)1003if (isGlobalVarSummary(Index, VI.getGUID()))1004++NumGVS;1005return NumGVS;1006}10071008// Given ImportMap, return the number of global variable summaries and record1009// the number of defined function summaries as output parameter.1010static unsigned1011numGlobalVarSummaries(const ModuleSummaryIndex &Index,1012FunctionImporter::FunctionsToImportTy &ImportMap,1013unsigned &DefinedFS) {1014unsigned NumGVS = 0;1015DefinedFS = 0;1016for (auto &[GUID, Type] : ImportMap) {1017if (isGlobalVarSummary(Index, GUID))1018++NumGVS;1019else if (Type == GlobalValueSummary::Definition)1020++DefinedFS;1021}1022return NumGVS;1023}1024#endif10251026#ifndef NDEBUG1027static bool checkVariableImport(1028const ModuleSummaryIndex &Index,1029DenseMap<StringRef, FunctionImporter::ImportMapTy> &ImportLists,1030DenseMap<StringRef, FunctionImporter::ExportSetTy> &ExportLists) {1031DenseSet<GlobalValue::GUID> FlattenedImports;10321033for (auto &ImportPerModule : ImportLists)1034for (auto &ExportPerModule : ImportPerModule.second)1035for (auto &[GUID, Type] : ExportPerModule.second)1036FlattenedImports.insert(GUID);10371038// Checks that all GUIDs of read/writeonly vars we see in export lists1039// are also in the import lists. Otherwise we my face linker undefs,1040// because readonly and writeonly vars are internalized in their1041// source modules. The exception would be if it has a linkage type indicating1042// that there may have been a copy existing in the importing module (e.g.1043// linkonce_odr). In that case we cannot accurately do this checking.1044auto IsReadOrWriteOnlyVarNeedingImporting = [&](StringRef ModulePath,1045const ValueInfo &VI) {1046auto *GVS = dyn_cast_or_null<GlobalVarSummary>(1047Index.findSummaryInModule(VI, ModulePath));1048return GVS && (Index.isReadOnly(GVS) || Index.isWriteOnly(GVS)) &&1049!(GVS->linkage() == GlobalValue::AvailableExternallyLinkage ||1050GVS->linkage() == GlobalValue::WeakODRLinkage ||1051GVS->linkage() == GlobalValue::LinkOnceODRLinkage);1052};10531054for (auto &ExportPerModule : ExportLists)1055for (auto &VI : ExportPerModule.second)1056if (!FlattenedImports.count(VI.getGUID()) &&1057IsReadOrWriteOnlyVarNeedingImporting(ExportPerModule.first, VI))1058return false;10591060return true;1061}1062#endif10631064/// Compute all the import and export for every module using the Index.1065void llvm::ComputeCrossModuleImport(1066const ModuleSummaryIndex &Index,1067const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,1068function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>1069isPrevailing,1070DenseMap<StringRef, FunctionImporter::ImportMapTy> &ImportLists,1071DenseMap<StringRef, FunctionImporter::ExportSetTy> &ExportLists) {1072auto MIS = ModuleImportsManager::create(isPrevailing, Index, &ExportLists);1073// For each module that has function defined, compute the import/export lists.1074for (const auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) {1075auto &ImportList = ImportLists[DefinedGVSummaries.first];1076LLVM_DEBUG(dbgs() << "Computing import for Module '"1077<< DefinedGVSummaries.first << "'\n");1078MIS->computeImportForModule(DefinedGVSummaries.second,1079DefinedGVSummaries.first, ImportList);1080}10811082// When computing imports we only added the variables and functions being1083// imported to the export list. We also need to mark any references and calls1084// they make as exported as well. We do this here, as it is more efficient1085// since we may import the same values multiple times into different modules1086// during the import computation.1087for (auto &ELI : ExportLists) {1088// `NewExports` tracks the VI that gets exported because the full definition1089// of its user/referencer gets exported.1090FunctionImporter::ExportSetTy NewExports;1091const auto &DefinedGVSummaries =1092ModuleToDefinedGVSummaries.lookup(ELI.first);1093for (auto &EI : ELI.second) {1094// Find the copy defined in the exporting module so that we can mark the1095// values it references in that specific definition as exported.1096// Below we will add all references and called values, without regard to1097// whether they are also defined in this module. We subsequently prune the1098// list to only include those defined in the exporting module, see comment1099// there as to why.1100auto DS = DefinedGVSummaries.find(EI.getGUID());1101// Anything marked exported during the import computation must have been1102// defined in the exporting module.1103assert(DS != DefinedGVSummaries.end());1104auto *S = DS->getSecond();1105S = S->getBaseObject();1106if (auto *GVS = dyn_cast<GlobalVarSummary>(S)) {1107// Export referenced functions and variables. We don't export/promote1108// objects referenced by writeonly variable initializer, because1109// we convert such variables initializers to "zeroinitializer".1110// See processGlobalForThinLTO.1111if (!Index.isWriteOnly(GVS))1112for (const auto &VI : GVS->refs())1113NewExports.insert(VI);1114} else {1115auto *FS = cast<FunctionSummary>(S);1116for (const auto &Edge : FS->calls())1117NewExports.insert(Edge.first);1118for (const auto &Ref : FS->refs())1119NewExports.insert(Ref);1120}1121}1122// Prune list computed above to only include values defined in the1123// exporting module. We do this after the above insertion since we may hit1124// the same ref/call target multiple times in above loop, and it is more1125// efficient to avoid a set lookup each time.1126for (auto EI = NewExports.begin(); EI != NewExports.end();) {1127if (!DefinedGVSummaries.count(EI->getGUID()))1128NewExports.erase(EI++);1129else1130++EI;1131}1132ELI.second.insert(NewExports.begin(), NewExports.end());1133}11341135assert(checkVariableImport(Index, ImportLists, ExportLists));1136#ifndef NDEBUG1137LLVM_DEBUG(dbgs() << "Import/Export lists for " << ImportLists.size()1138<< " modules:\n");1139for (auto &ModuleImports : ImportLists) {1140auto ModName = ModuleImports.first;1141auto &Exports = ExportLists[ModName];1142unsigned NumGVS = numGlobalVarSummaries(Index, Exports);1143LLVM_DEBUG(dbgs() << "* Module " << ModName << " exports "1144<< Exports.size() - NumGVS << " functions and " << NumGVS1145<< " vars. Imports from " << ModuleImports.second.size()1146<< " modules.\n");1147for (auto &Src : ModuleImports.second) {1148auto SrcModName = Src.first;1149unsigned DefinedFS = 0;1150unsigned NumGVSPerMod =1151numGlobalVarSummaries(Index, Src.second, DefinedFS);1152LLVM_DEBUG(dbgs() << " - " << DefinedFS << " function definitions and "1153<< Src.second.size() - NumGVSPerMod - DefinedFS1154<< " function declarations imported from " << SrcModName1155<< "\n");1156LLVM_DEBUG(dbgs() << " - " << NumGVSPerMod1157<< " global vars imported from " << SrcModName << "\n");1158}1159}1160#endif1161}11621163#ifndef NDEBUG1164static void dumpImportListForModule(const ModuleSummaryIndex &Index,1165StringRef ModulePath,1166FunctionImporter::ImportMapTy &ImportList) {1167LLVM_DEBUG(dbgs() << "* Module " << ModulePath << " imports from "1168<< ImportList.size() << " modules.\n");1169for (auto &Src : ImportList) {1170auto SrcModName = Src.first;1171unsigned DefinedFS = 0;1172unsigned NumGVSPerMod = numGlobalVarSummaries(Index, Src.second, DefinedFS);1173LLVM_DEBUG(dbgs() << " - " << DefinedFS << " function definitions and "1174<< Src.second.size() - DefinedFS - NumGVSPerMod1175<< " function declarations imported from " << SrcModName1176<< "\n");1177LLVM_DEBUG(dbgs() << " - " << NumGVSPerMod << " vars imported from "1178<< SrcModName << "\n");1179}1180}1181#endif11821183/// Compute all the imports for the given module using the Index.1184///1185/// \p isPrevailing is a callback that will be called with a global value's GUID1186/// and summary and should return whether the module corresponding to the1187/// summary contains the linker-prevailing copy of that value.1188///1189/// \p ImportList will be populated with a map that can be passed to1190/// FunctionImporter::importFunctions() above (see description there).1191static void ComputeCrossModuleImportForModuleForTest(1192StringRef ModulePath,1193function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>1194isPrevailing,1195const ModuleSummaryIndex &Index,1196FunctionImporter::ImportMapTy &ImportList) {1197// Collect the list of functions this module defines.1198// GUID -> Summary1199GVSummaryMapTy FunctionSummaryMap;1200Index.collectDefinedFunctionsForModule(ModulePath, FunctionSummaryMap);12011202// Compute the import list for this module.1203LLVM_DEBUG(dbgs() << "Computing import for Module '" << ModulePath << "'\n");1204auto MIS = ModuleImportsManager::create(isPrevailing, Index);1205MIS->computeImportForModule(FunctionSummaryMap, ModulePath, ImportList);12061207#ifndef NDEBUG1208dumpImportListForModule(Index, ModulePath, ImportList);1209#endif1210}12111212/// Mark all external summaries in \p Index for import into the given module.1213/// Used for testing the case of distributed builds using a distributed index.1214///1215/// \p ImportList will be populated with a map that can be passed to1216/// FunctionImporter::importFunctions() above (see description there).1217static void ComputeCrossModuleImportForModuleFromIndexForTest(1218StringRef ModulePath, const ModuleSummaryIndex &Index,1219FunctionImporter::ImportMapTy &ImportList) {1220for (const auto &GlobalList : Index) {1221// Ignore entries for undefined references.1222if (GlobalList.second.SummaryList.empty())1223continue;12241225auto GUID = GlobalList.first;1226assert(GlobalList.second.SummaryList.size() == 1 &&1227"Expected individual combined index to have one summary per GUID");1228auto &Summary = GlobalList.second.SummaryList[0];1229// Skip the summaries for the importing module. These are included to1230// e.g. record required linkage changes.1231if (Summary->modulePath() == ModulePath)1232continue;1233// Add an entry to provoke importing by thinBackend.1234auto [Iter, Inserted] = ImportList[Summary->modulePath()].try_emplace(1235GUID, Summary->importType());1236if (!Inserted) {1237// Use 'std::min' to make sure definition (with enum value 0) takes1238// precedence over declaration (with enum value 1).1239Iter->second = std::min(Iter->second, Summary->importType());1240}1241}1242#ifndef NDEBUG1243dumpImportListForModule(Index, ModulePath, ImportList);1244#endif1245}12461247// For SamplePGO, the indirect call targets for local functions will1248// have its original name annotated in profile. We try to find the1249// corresponding PGOFuncName as the GUID, and fix up the edges1250// accordingly.1251void updateValueInfoForIndirectCalls(ModuleSummaryIndex &Index,1252FunctionSummary *FS) {1253for (auto &EI : FS->mutableCalls()) {1254if (!EI.first.getSummaryList().empty())1255continue;1256auto GUID = Index.getGUIDFromOriginalID(EI.first.getGUID());1257if (GUID == 0)1258continue;1259// Update the edge to point directly to the correct GUID.1260auto VI = Index.getValueInfo(GUID);1261if (llvm::any_of(1262VI.getSummaryList(),1263[&](const std::unique_ptr<GlobalValueSummary> &SummaryPtr) {1264// The mapping from OriginalId to GUID may return a GUID1265// that corresponds to a static variable. Filter it out here.1266// This can happen when1267// 1) There is a call to a library function which is not defined1268// in the index.1269// 2) There is a static variable with the OriginalGUID identical1270// to the GUID of the library function in 1);1271// When this happens the static variable in 2) will be found,1272// which needs to be filtered out.1273return SummaryPtr->getSummaryKind() ==1274GlobalValueSummary::GlobalVarKind;1275}))1276continue;1277EI.first = VI;1278}1279}12801281void llvm::updateIndirectCalls(ModuleSummaryIndex &Index) {1282for (const auto &Entry : Index) {1283for (const auto &S : Entry.second.SummaryList) {1284if (auto *FS = dyn_cast<FunctionSummary>(S.get()))1285updateValueInfoForIndirectCalls(Index, FS);1286}1287}1288}12891290void llvm::computeDeadSymbolsAndUpdateIndirectCalls(1291ModuleSummaryIndex &Index,1292const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,1293function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing) {1294assert(!Index.withGlobalValueDeadStripping());1295if (!ComputeDead ||1296// Don't do anything when nothing is live, this is friendly with tests.1297GUIDPreservedSymbols.empty()) {1298// Still need to update indirect calls.1299updateIndirectCalls(Index);1300return;1301}1302unsigned LiveSymbols = 0;1303SmallVector<ValueInfo, 128> Worklist;1304Worklist.reserve(GUIDPreservedSymbols.size() * 2);1305for (auto GUID : GUIDPreservedSymbols) {1306ValueInfo VI = Index.getValueInfo(GUID);1307if (!VI)1308continue;1309for (const auto &S : VI.getSummaryList())1310S->setLive(true);1311}13121313// Add values flagged in the index as live roots to the worklist.1314for (const auto &Entry : Index) {1315auto VI = Index.getValueInfo(Entry);1316for (const auto &S : Entry.second.SummaryList) {1317if (auto *FS = dyn_cast<FunctionSummary>(S.get()))1318updateValueInfoForIndirectCalls(Index, FS);1319if (S->isLive()) {1320LLVM_DEBUG(dbgs() << "Live root: " << VI << "\n");1321Worklist.push_back(VI);1322++LiveSymbols;1323break;1324}1325}1326}13271328// Make value live and add it to the worklist if it was not live before.1329auto visit = [&](ValueInfo VI, bool IsAliasee) {1330// FIXME: If we knew which edges were created for indirect call profiles,1331// we could skip them here. Any that are live should be reached via1332// other edges, e.g. reference edges. Otherwise, using a profile collected1333// on a slightly different binary might provoke preserving, importing1334// and ultimately promoting calls to functions not linked into this1335// binary, which increases the binary size unnecessarily. Note that1336// if this code changes, the importer needs to change so that edges1337// to functions marked dead are skipped.13381339if (llvm::any_of(VI.getSummaryList(),1340[](const std::unique_ptr<llvm::GlobalValueSummary> &S) {1341return S->isLive();1342}))1343return;13441345// We only keep live symbols that are known to be non-prevailing if any are1346// available_externally, linkonceodr, weakodr. Those symbols are discarded1347// later in the EliminateAvailableExternally pass and setting them to1348// not-live could break downstreams users of liveness information (PR36483)1349// or limit optimization opportunities.1350if (isPrevailing(VI.getGUID()) == PrevailingType::No) {1351bool KeepAliveLinkage = false;1352bool Interposable = false;1353for (const auto &S : VI.getSummaryList()) {1354if (S->linkage() == GlobalValue::AvailableExternallyLinkage ||1355S->linkage() == GlobalValue::WeakODRLinkage ||1356S->linkage() == GlobalValue::LinkOnceODRLinkage)1357KeepAliveLinkage = true;1358else if (GlobalValue::isInterposableLinkage(S->linkage()))1359Interposable = true;1360}13611362if (!IsAliasee) {1363if (!KeepAliveLinkage)1364return;13651366if (Interposable)1367report_fatal_error(1368"Interposable and available_externally/linkonce_odr/weak_odr "1369"symbol");1370}1371}13721373for (const auto &S : VI.getSummaryList())1374S->setLive(true);1375++LiveSymbols;1376Worklist.push_back(VI);1377};13781379while (!Worklist.empty()) {1380auto VI = Worklist.pop_back_val();1381for (const auto &Summary : VI.getSummaryList()) {1382if (auto *AS = dyn_cast<AliasSummary>(Summary.get())) {1383// If this is an alias, visit the aliasee VI to ensure that all copies1384// are marked live and it is added to the worklist for further1385// processing of its references.1386visit(AS->getAliaseeVI(), true);1387continue;1388}1389for (auto Ref : Summary->refs())1390visit(Ref, false);1391if (auto *FS = dyn_cast<FunctionSummary>(Summary.get()))1392for (auto Call : FS->calls())1393visit(Call.first, false);1394}1395}1396Index.setWithGlobalValueDeadStripping();13971398unsigned DeadSymbols = Index.size() - LiveSymbols;1399LLVM_DEBUG(dbgs() << LiveSymbols << " symbols Live, and " << DeadSymbols1400<< " symbols Dead \n");1401NumDeadSymbols += DeadSymbols;1402NumLiveSymbols += LiveSymbols;1403}14041405// Compute dead symbols and propagate constants in combined index.1406void llvm::computeDeadSymbolsWithConstProp(1407ModuleSummaryIndex &Index,1408const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,1409function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing,1410bool ImportEnabled) {1411computeDeadSymbolsAndUpdateIndirectCalls(Index, GUIDPreservedSymbols,1412isPrevailing);1413if (ImportEnabled)1414Index.propagateAttributes(GUIDPreservedSymbols);1415}14161417/// Compute the set of summaries needed for a ThinLTO backend compilation of1418/// \p ModulePath.1419void llvm::gatherImportedSummariesForModule(1420StringRef ModulePath,1421const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,1422const FunctionImporter::ImportMapTy &ImportList,1423std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,1424GVSummaryPtrSet &DecSummaries) {1425// Include all summaries from the importing module.1426ModuleToSummariesForIndex[std::string(ModulePath)] =1427ModuleToDefinedGVSummaries.lookup(ModulePath);1428// Include summaries for imports.1429for (const auto &ILI : ImportList) {1430auto &SummariesForIndex = ModuleToSummariesForIndex[std::string(ILI.first)];14311432const auto &DefinedGVSummaries =1433ModuleToDefinedGVSummaries.lookup(ILI.first);1434for (const auto &[GUID, Type] : ILI.second) {1435const auto &DS = DefinedGVSummaries.find(GUID);1436assert(DS != DefinedGVSummaries.end() &&1437"Expected a defined summary for imported global value");1438if (Type == GlobalValueSummary::Declaration)1439DecSummaries.insert(DS->second);14401441SummariesForIndex[GUID] = DS->second;1442}1443}1444}14451446/// Emit the files \p ModulePath will import from into \p OutputFilename.1447std::error_code llvm::EmitImportsFiles(1448StringRef ModulePath, StringRef OutputFilename,1449const std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {1450std::error_code EC;1451raw_fd_ostream ImportsOS(OutputFilename, EC, sys::fs::OpenFlags::OF_Text);1452if (EC)1453return EC;1454for (const auto &ILI : ModuleToSummariesForIndex)1455// The ModuleToSummariesForIndex map includes an entry for the current1456// Module (needed for writing out the index files). We don't want to1457// include it in the imports file, however, so filter it out.1458if (ILI.first != ModulePath)1459ImportsOS << ILI.first << "\n";1460return std::error_code();1461}14621463bool llvm::convertToDeclaration(GlobalValue &GV) {1464LLVM_DEBUG(dbgs() << "Converting to a declaration: `" << GV.getName()1465<< "\n");1466if (Function *F = dyn_cast<Function>(&GV)) {1467F->deleteBody();1468F->clearMetadata();1469F->setComdat(nullptr);1470} else if (GlobalVariable *V = dyn_cast<GlobalVariable>(&GV)) {1471V->setInitializer(nullptr);1472V->setLinkage(GlobalValue::ExternalLinkage);1473V->clearMetadata();1474V->setComdat(nullptr);1475} else {1476GlobalValue *NewGV;1477if (GV.getValueType()->isFunctionTy())1478NewGV =1479Function::Create(cast<FunctionType>(GV.getValueType()),1480GlobalValue::ExternalLinkage, GV.getAddressSpace(),1481"", GV.getParent());1482else1483NewGV =1484new GlobalVariable(*GV.getParent(), GV.getValueType(),1485/*isConstant*/ false, GlobalValue::ExternalLinkage,1486/*init*/ nullptr, "",1487/*insertbefore*/ nullptr, GV.getThreadLocalMode(),1488GV.getType()->getAddressSpace());1489NewGV->takeName(&GV);1490GV.replaceAllUsesWith(NewGV);1491return false;1492}1493if (!GV.isImplicitDSOLocal())1494GV.setDSOLocal(false);1495return true;1496}14971498void llvm::thinLTOFinalizeInModule(Module &TheModule,1499const GVSummaryMapTy &DefinedGlobals,1500bool PropagateAttrs) {1501DenseSet<Comdat *> NonPrevailingComdats;1502auto FinalizeInModule = [&](GlobalValue &GV, bool Propagate = false) {1503// See if the global summary analysis computed a new resolved linkage.1504const auto &GS = DefinedGlobals.find(GV.getGUID());1505if (GS == DefinedGlobals.end())1506return;15071508if (Propagate)1509if (FunctionSummary *FS = dyn_cast<FunctionSummary>(GS->second)) {1510if (Function *F = dyn_cast<Function>(&GV)) {1511// TODO: propagate ReadNone and ReadOnly.1512if (FS->fflags().ReadNone && !F->doesNotAccessMemory())1513F->setDoesNotAccessMemory();15141515if (FS->fflags().ReadOnly && !F->onlyReadsMemory())1516F->setOnlyReadsMemory();15171518if (FS->fflags().NoRecurse && !F->doesNotRecurse())1519F->setDoesNotRecurse();15201521if (FS->fflags().NoUnwind && !F->doesNotThrow())1522F->setDoesNotThrow();1523}1524}15251526auto NewLinkage = GS->second->linkage();1527if (GlobalValue::isLocalLinkage(GV.getLinkage()) ||1528// Don't internalize anything here, because the code below1529// lacks necessary correctness checks. Leave this job to1530// LLVM 'internalize' pass.1531GlobalValue::isLocalLinkage(NewLinkage) ||1532// In case it was dead and already converted to declaration.1533GV.isDeclaration())1534return;15351536// Set the potentially more constraining visibility computed from summaries.1537// The DefaultVisibility condition is because older GlobalValueSummary does1538// not record DefaultVisibility and we don't want to change protected/hidden1539// to default.1540if (GS->second->getVisibility() != GlobalValue::DefaultVisibility)1541GV.setVisibility(GS->second->getVisibility());15421543if (NewLinkage == GV.getLinkage())1544return;15451546// Check for a non-prevailing def that has interposable linkage1547// (e.g. non-odr weak or linkonce). In that case we can't simply1548// convert to available_externally, since it would lose the1549// interposable property and possibly get inlined. Simply drop1550// the definition in that case.1551if (GlobalValue::isAvailableExternallyLinkage(NewLinkage) &&1552GlobalValue::isInterposableLinkage(GV.getLinkage())) {1553if (!convertToDeclaration(GV))1554// FIXME: Change this to collect replaced GVs and later erase1555// them from the parent module once thinLTOResolvePrevailingGUID is1556// changed to enable this for aliases.1557llvm_unreachable("Expected GV to be converted");1558} else {1559// If all copies of the original symbol had global unnamed addr and1560// linkonce_odr linkage, or if all of them had local unnamed addr linkage1561// and are constants, then it should be an auto hide symbol. In that case1562// the thin link would have marked it as CanAutoHide. Add hidden1563// visibility to the symbol to preserve the property.1564if (NewLinkage == GlobalValue::WeakODRLinkage &&1565GS->second->canAutoHide()) {1566assert(GV.canBeOmittedFromSymbolTable());1567GV.setVisibility(GlobalValue::HiddenVisibility);1568}15691570LLVM_DEBUG(dbgs() << "ODR fixing up linkage for `" << GV.getName()1571<< "` from " << GV.getLinkage() << " to " << NewLinkage1572<< "\n");1573GV.setLinkage(NewLinkage);1574}1575// Remove declarations from comdats, including available_externally1576// as this is a declaration for the linker, and will be dropped eventually.1577// It is illegal for comdats to contain declarations.1578auto *GO = dyn_cast_or_null<GlobalObject>(&GV);1579if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {1580if (GO->getComdat()->getName() == GO->getName())1581NonPrevailingComdats.insert(GO->getComdat());1582GO->setComdat(nullptr);1583}1584};15851586// Process functions and global now1587for (auto &GV : TheModule)1588FinalizeInModule(GV, PropagateAttrs);1589for (auto &GV : TheModule.globals())1590FinalizeInModule(GV);1591for (auto &GV : TheModule.aliases())1592FinalizeInModule(GV);15931594// For a non-prevailing comdat, all its members must be available_externally.1595// FinalizeInModule has handled non-local-linkage GlobalValues. Here we handle1596// local linkage GlobalValues.1597if (NonPrevailingComdats.empty())1598return;1599for (auto &GO : TheModule.global_objects()) {1600if (auto *C = GO.getComdat(); C && NonPrevailingComdats.count(C)) {1601GO.setComdat(nullptr);1602GO.setLinkage(GlobalValue::AvailableExternallyLinkage);1603}1604}1605bool Changed;1606do {1607Changed = false;1608// If an alias references a GlobalValue in a non-prevailing comdat, change1609// it to available_externally. For simplicity we only handle GlobalValue and1610// ConstantExpr with a base object. ConstantExpr without a base object is1611// unlikely used in a COMDAT.1612for (auto &GA : TheModule.aliases()) {1613if (GA.hasAvailableExternallyLinkage())1614continue;1615GlobalObject *Obj = GA.getAliaseeObject();1616assert(Obj && "aliasee without an base object is unimplemented");1617if (Obj->hasAvailableExternallyLinkage()) {1618GA.setLinkage(GlobalValue::AvailableExternallyLinkage);1619Changed = true;1620}1621}1622} while (Changed);1623}16241625/// Run internalization on \p TheModule based on symmary analysis.1626void llvm::thinLTOInternalizeModule(Module &TheModule,1627const GVSummaryMapTy &DefinedGlobals) {1628// Declare a callback for the internalize pass that will ask for every1629// candidate GlobalValue if it can be internalized or not.1630auto MustPreserveGV = [&](const GlobalValue &GV) -> bool {1631// It may be the case that GV is on a chain of an ifunc, its alias and1632// subsequent aliases. In this case, the summary for the value is not1633// available.1634if (isa<GlobalIFunc>(&GV) ||1635(isa<GlobalAlias>(&GV) &&1636isa<GlobalIFunc>(cast<GlobalAlias>(&GV)->getAliaseeObject())))1637return true;16381639// Lookup the linkage recorded in the summaries during global analysis.1640auto GS = DefinedGlobals.find(GV.getGUID());1641if (GS == DefinedGlobals.end()) {1642// Must have been promoted (possibly conservatively). Find original1643// name so that we can access the correct summary and see if it can1644// be internalized again.1645// FIXME: Eventually we should control promotion instead of promoting1646// and internalizing again.1647StringRef OrigName =1648ModuleSummaryIndex::getOriginalNameBeforePromote(GV.getName());1649std::string OrigId = GlobalValue::getGlobalIdentifier(1650OrigName, GlobalValue::InternalLinkage,1651TheModule.getSourceFileName());1652GS = DefinedGlobals.find(GlobalValue::getGUID(OrigId));1653if (GS == DefinedGlobals.end()) {1654// Also check the original non-promoted non-globalized name. In some1655// cases a preempted weak value is linked in as a local copy because1656// it is referenced by an alias (IRLinker::linkGlobalValueProto).1657// In that case, since it was originally not a local value, it was1658// recorded in the index using the original name.1659// FIXME: This may not be needed once PR27866 is fixed.1660GS = DefinedGlobals.find(GlobalValue::getGUID(OrigName));1661assert(GS != DefinedGlobals.end());1662}1663}1664return !GlobalValue::isLocalLinkage(GS->second->linkage());1665};16661667// FIXME: See if we can just internalize directly here via linkage changes1668// based on the index, rather than invoking internalizeModule.1669internalizeModule(TheModule, MustPreserveGV);1670}16711672/// Make alias a clone of its aliasee.1673static Function *replaceAliasWithAliasee(Module *SrcModule, GlobalAlias *GA) {1674Function *Fn = cast<Function>(GA->getAliaseeObject());16751676ValueToValueMapTy VMap;1677Function *NewFn = CloneFunction(Fn, VMap);1678// Clone should use the original alias's linkage, visibility and name, and we1679// ensure all uses of alias instead use the new clone (casted if necessary).1680NewFn->setLinkage(GA->getLinkage());1681NewFn->setVisibility(GA->getVisibility());1682GA->replaceAllUsesWith(NewFn);1683NewFn->takeName(GA);1684return NewFn;1685}16861687// Internalize values that we marked with specific attribute1688// in processGlobalForThinLTO.1689static void internalizeGVsAfterImport(Module &M) {1690for (auto &GV : M.globals())1691// Skip GVs which have been converted to declarations1692// by dropDeadSymbols.1693if (!GV.isDeclaration() && GV.hasAttribute("thinlto-internalize")) {1694GV.setLinkage(GlobalValue::InternalLinkage);1695GV.setVisibility(GlobalValue::DefaultVisibility);1696}1697}16981699// Automatically import functions in Module \p DestModule based on the summaries1700// index.1701Expected<bool> FunctionImporter::importFunctions(1702Module &DestModule, const FunctionImporter::ImportMapTy &ImportList) {1703LLVM_DEBUG(dbgs() << "Starting import for Module "1704<< DestModule.getModuleIdentifier() << "\n");1705unsigned ImportedCount = 0, ImportedGVCount = 0;17061707IRMover Mover(DestModule);1708// Do the actual import of functions now, one Module at a time1709std::set<StringRef> ModuleNameOrderedList;1710for (const auto &FunctionsToImportPerModule : ImportList) {1711ModuleNameOrderedList.insert(FunctionsToImportPerModule.first);1712}17131714auto getImportType = [&](const FunctionsToImportTy &GUIDToImportType,1715GlobalValue::GUID GUID)1716-> std::optional<GlobalValueSummary::ImportKind> {1717auto Iter = GUIDToImportType.find(GUID);1718if (Iter == GUIDToImportType.end())1719return std::nullopt;1720return Iter->second;1721};17221723for (const auto &Name : ModuleNameOrderedList) {1724// Get the module for the import1725const auto &FunctionsToImportPerModule = ImportList.find(Name);1726assert(FunctionsToImportPerModule != ImportList.end());1727Expected<std::unique_ptr<Module>> SrcModuleOrErr = ModuleLoader(Name);1728if (!SrcModuleOrErr)1729return SrcModuleOrErr.takeError();1730std::unique_ptr<Module> SrcModule = std::move(*SrcModuleOrErr);1731assert(&DestModule.getContext() == &SrcModule->getContext() &&1732"Context mismatch");17331734// If modules were created with lazy metadata loading, materialize it1735// now, before linking it (otherwise this will be a noop).1736if (Error Err = SrcModule->materializeMetadata())1737return std::move(Err);17381739auto &ImportGUIDs = FunctionsToImportPerModule->second;17401741// Find the globals to import1742SetVector<GlobalValue *> GlobalsToImport;1743for (Function &F : *SrcModule) {1744if (!F.hasName())1745continue;1746auto GUID = F.getGUID();1747auto MaybeImportType = getImportType(ImportGUIDs, GUID);17481749bool ImportDefinition =1750(MaybeImportType &&1751(*MaybeImportType == GlobalValueSummary::Definition));17521753LLVM_DEBUG(dbgs() << (MaybeImportType ? "Is" : "Not")1754<< " importing function"1755<< (ImportDefinition1756? " definition "1757: (MaybeImportType ? " declaration " : " "))1758<< GUID << " " << F.getName() << " from "1759<< SrcModule->getSourceFileName() << "\n");1760if (ImportDefinition) {1761if (Error Err = F.materialize())1762return std::move(Err);1763// MemProf should match function's definition and summary,1764// 'thinlto_src_module' is needed.1765if (EnableImportMetadata || EnableMemProfContextDisambiguation) {1766// Add 'thinlto_src_module' and 'thinlto_src_file' metadata for1767// statistics and debugging.1768F.setMetadata(1769"thinlto_src_module",1770MDNode::get(DestModule.getContext(),1771{MDString::get(DestModule.getContext(),1772SrcModule->getModuleIdentifier())}));1773F.setMetadata(1774"thinlto_src_file",1775MDNode::get(DestModule.getContext(),1776{MDString::get(DestModule.getContext(),1777SrcModule->getSourceFileName())}));1778}1779GlobalsToImport.insert(&F);1780}1781}1782for (GlobalVariable &GV : SrcModule->globals()) {1783if (!GV.hasName())1784continue;1785auto GUID = GV.getGUID();1786auto MaybeImportType = getImportType(ImportGUIDs, GUID);17871788bool ImportDefinition =1789(MaybeImportType &&1790(*MaybeImportType == GlobalValueSummary::Definition));17911792LLVM_DEBUG(dbgs() << (MaybeImportType ? "Is" : "Not")1793<< " importing global"1794<< (ImportDefinition1795? " definition "1796: (MaybeImportType ? " declaration " : " "))1797<< GUID << " " << GV.getName() << " from "1798<< SrcModule->getSourceFileName() << "\n");1799if (ImportDefinition) {1800if (Error Err = GV.materialize())1801return std::move(Err);1802ImportedGVCount += GlobalsToImport.insert(&GV);1803}1804}1805for (GlobalAlias &GA : SrcModule->aliases()) {1806if (!GA.hasName() || isa<GlobalIFunc>(GA.getAliaseeObject()))1807continue;1808auto GUID = GA.getGUID();1809auto MaybeImportType = getImportType(ImportGUIDs, GUID);18101811bool ImportDefinition =1812(MaybeImportType &&1813(*MaybeImportType == GlobalValueSummary::Definition));18141815LLVM_DEBUG(dbgs() << (MaybeImportType ? "Is" : "Not")1816<< " importing alias"1817<< (ImportDefinition1818? " definition "1819: (MaybeImportType ? " declaration " : " "))1820<< GUID << " " << GA.getName() << " from "1821<< SrcModule->getSourceFileName() << "\n");1822if (ImportDefinition) {1823if (Error Err = GA.materialize())1824return std::move(Err);1825// Import alias as a copy of its aliasee.1826GlobalObject *GO = GA.getAliaseeObject();1827if (Error Err = GO->materialize())1828return std::move(Err);1829auto *Fn = replaceAliasWithAliasee(SrcModule.get(), &GA);1830LLVM_DEBUG(dbgs() << "Is importing aliasee fn " << GO->getGUID() << " "1831<< GO->getName() << " from "1832<< SrcModule->getSourceFileName() << "\n");1833if (EnableImportMetadata || EnableMemProfContextDisambiguation) {1834// Add 'thinlto_src_module' and 'thinlto_src_file' metadata for1835// statistics and debugging.1836Fn->setMetadata(1837"thinlto_src_module",1838MDNode::get(DestModule.getContext(),1839{MDString::get(DestModule.getContext(),1840SrcModule->getModuleIdentifier())}));1841Fn->setMetadata(1842"thinlto_src_file",1843MDNode::get(DestModule.getContext(),1844{MDString::get(DestModule.getContext(),1845SrcModule->getSourceFileName())}));1846}1847GlobalsToImport.insert(Fn);1848}1849}18501851// Upgrade debug info after we're done materializing all the globals and we1852// have loaded all the required metadata!1853UpgradeDebugInfo(*SrcModule);18541855// Set the partial sample profile ratio in the profile summary module flag1856// of the imported source module, if applicable, so that the profile summary1857// module flag will match with that of the destination module when it's1858// imported.1859SrcModule->setPartialSampleProfileRatio(Index);18601861// Link in the specified functions.1862if (renameModuleForThinLTO(*SrcModule, Index, ClearDSOLocalOnDeclarations,1863&GlobalsToImport))1864return true;18651866if (PrintImports) {1867for (const auto *GV : GlobalsToImport)1868dbgs() << DestModule.getSourceFileName() << ": Import " << GV->getName()1869<< " from " << SrcModule->getSourceFileName() << "\n";1870}18711872if (Error Err = Mover.move(std::move(SrcModule),1873GlobalsToImport.getArrayRef(), nullptr,1874/*IsPerformingImport=*/true))1875return createStringError(errc::invalid_argument,1876Twine("Function Import: link error: ") +1877toString(std::move(Err)));18781879ImportedCount += GlobalsToImport.size();1880NumImportedModules++;1881}18821883internalizeGVsAfterImport(DestModule);18841885NumImportedFunctions += (ImportedCount - ImportedGVCount);1886NumImportedGlobalVars += ImportedGVCount;18871888// TODO: Print counters for definitions and declarations in the debugging log.1889LLVM_DEBUG(dbgs() << "Imported " << ImportedCount - ImportedGVCount1890<< " functions for Module "1891<< DestModule.getModuleIdentifier() << "\n");1892LLVM_DEBUG(dbgs() << "Imported " << ImportedGVCount1893<< " global variables for Module "1894<< DestModule.getModuleIdentifier() << "\n");1895return ImportedCount;1896}18971898static bool doImportingForModuleForTest(1899Module &M, function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>1900isPrevailing) {1901if (SummaryFile.empty())1902report_fatal_error("error: -function-import requires -summary-file\n");1903Expected<std::unique_ptr<ModuleSummaryIndex>> IndexPtrOrErr =1904getModuleSummaryIndexForFile(SummaryFile);1905if (!IndexPtrOrErr) {1906logAllUnhandledErrors(IndexPtrOrErr.takeError(), errs(),1907"Error loading file '" + SummaryFile + "': ");1908return false;1909}1910std::unique_ptr<ModuleSummaryIndex> Index = std::move(*IndexPtrOrErr);19111912// First step is collecting the import list.1913FunctionImporter::ImportMapTy ImportList;1914// If requested, simply import all functions in the index. This is used1915// when testing distributed backend handling via the opt tool, when1916// we have distributed indexes containing exactly the summaries to import.1917if (ImportAllIndex)1918ComputeCrossModuleImportForModuleFromIndexForTest(M.getModuleIdentifier(),1919*Index, ImportList);1920else1921ComputeCrossModuleImportForModuleForTest(M.getModuleIdentifier(),1922isPrevailing, *Index, ImportList);19231924// Conservatively mark all internal values as promoted. This interface is1925// only used when doing importing via the function importing pass. The pass1926// is only enabled when testing importing via the 'opt' tool, which does1927// not do the ThinLink that would normally determine what values to promote.1928for (auto &I : *Index) {1929for (auto &S : I.second.SummaryList) {1930if (GlobalValue::isLocalLinkage(S->linkage()))1931S->setLinkage(GlobalValue::ExternalLinkage);1932}1933}19341935// Next we need to promote to global scope and rename any local values that1936// are potentially exported to other modules.1937if (renameModuleForThinLTO(M, *Index, /*ClearDSOLocalOnDeclarations=*/false,1938/*GlobalsToImport=*/nullptr)) {1939errs() << "Error renaming module\n";1940return true;1941}19421943// Perform the import now.1944auto ModuleLoader = [&M](StringRef Identifier) {1945return loadFile(std::string(Identifier), M.getContext());1946};1947FunctionImporter Importer(*Index, ModuleLoader,1948/*ClearDSOLocalOnDeclarations=*/false);1949Expected<bool> Result = Importer.importFunctions(M, ImportList);19501951// FIXME: Probably need to propagate Errors through the pass manager.1952if (!Result) {1953logAllUnhandledErrors(Result.takeError(), errs(),1954"Error importing module: ");1955return true;1956}19571958return true;1959}19601961PreservedAnalyses FunctionImportPass::run(Module &M,1962ModuleAnalysisManager &AM) {1963// This is only used for testing the function import pass via opt, where we1964// don't have prevailing information from the LTO context available, so just1965// conservatively assume everything is prevailing (which is fine for the very1966// limited use of prevailing checking in this pass).1967auto isPrevailing = [](GlobalValue::GUID, const GlobalValueSummary *) {1968return true;1969};1970if (!doImportingForModuleForTest(M, isPrevailing))1971return PreservedAnalyses::all();19721973return PreservedAnalyses::none();1974}197519761977