10b57cec5SDimitry Andric //===- FunctionImport.cpp - ThinLTO Summary-based Function Import ---------===// 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 Function import based on summaries. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/Transforms/IPO/FunctionImport.h" 140b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 150b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 160b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h" 170b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 180b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h" 190b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 200b57cec5SDimitry Andric #include "llvm/Bitcode/BitcodeReader.h" 210b57cec5SDimitry Andric #include "llvm/IR/AutoUpgrade.h" 220b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 230b57cec5SDimitry Andric #include "llvm/IR/Function.h" 240b57cec5SDimitry Andric #include "llvm/IR/GlobalAlias.h" 250b57cec5SDimitry Andric #include "llvm/IR/GlobalObject.h" 260b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h" 270b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h" 280b57cec5SDimitry Andric #include "llvm/IR/Metadata.h" 290b57cec5SDimitry Andric #include "llvm/IR/Module.h" 300b57cec5SDimitry Andric #include "llvm/IR/ModuleSummaryIndex.h" 310b57cec5SDimitry Andric #include "llvm/IRReader/IRReader.h" 320b57cec5SDimitry Andric #include "llvm/Linker/IRMover.h" 330b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 340b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 350b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 36349cc55cSDimitry Andric #include "llvm/Support/Errc.h" 370b57cec5SDimitry Andric #include "llvm/Support/Error.h" 380b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 390b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h" 405f757f3fSDimitry Andric #include "llvm/Support/JSON.h" 410b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h" 420b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 430b57cec5SDimitry Andric #include "llvm/Transforms/IPO/Internalize.h" 440b57cec5SDimitry Andric #include "llvm/Transforms/Utils/Cloning.h" 450b57cec5SDimitry Andric #include "llvm/Transforms/Utils/FunctionImportUtils.h" 460b57cec5SDimitry Andric #include "llvm/Transforms/Utils/ValueMapper.h" 470b57cec5SDimitry Andric #include <cassert> 480b57cec5SDimitry Andric #include <memory> 490b57cec5SDimitry Andric #include <set> 500b57cec5SDimitry Andric #include <string> 510b57cec5SDimitry Andric #include <system_error> 520b57cec5SDimitry Andric #include <tuple> 530b57cec5SDimitry Andric #include <utility> 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric using namespace llvm; 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric #define DEBUG_TYPE "function-import" 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric STATISTIC(NumImportedFunctionsThinLink, 600b57cec5SDimitry Andric "Number of functions thin link decided to import"); 610b57cec5SDimitry Andric STATISTIC(NumImportedHotFunctionsThinLink, 620b57cec5SDimitry Andric "Number of hot functions thin link decided to import"); 630b57cec5SDimitry Andric STATISTIC(NumImportedCriticalFunctionsThinLink, 640b57cec5SDimitry Andric "Number of critical functions thin link decided to import"); 650b57cec5SDimitry Andric STATISTIC(NumImportedGlobalVarsThinLink, 660b57cec5SDimitry Andric "Number of global variables thin link decided to import"); 670b57cec5SDimitry Andric STATISTIC(NumImportedFunctions, "Number of functions imported in backend"); 680b57cec5SDimitry Andric STATISTIC(NumImportedGlobalVars, 690b57cec5SDimitry Andric "Number of global variables imported in backend"); 700b57cec5SDimitry Andric STATISTIC(NumImportedModules, "Number of modules imported from"); 710b57cec5SDimitry Andric STATISTIC(NumDeadSymbols, "Number of dead stripped symbols in index"); 720b57cec5SDimitry Andric STATISTIC(NumLiveSymbols, "Number of live symbols in index"); 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric /// Limit on instruction count of imported functions. 750b57cec5SDimitry Andric static cl::opt<unsigned> ImportInstrLimit( 760b57cec5SDimitry Andric "import-instr-limit", cl::init(100), cl::Hidden, cl::value_desc("N"), 770b57cec5SDimitry Andric cl::desc("Only import functions with less than N instructions")); 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric static cl::opt<int> ImportCutoff( 800b57cec5SDimitry Andric "import-cutoff", cl::init(-1), cl::Hidden, cl::value_desc("N"), 810b57cec5SDimitry Andric cl::desc("Only import first N functions if N>=0 (default -1)")); 820b57cec5SDimitry Andric 83fe6060f1SDimitry Andric static cl::opt<bool> 84fe6060f1SDimitry Andric ForceImportAll("force-import-all", cl::init(false), cl::Hidden, 85fe6060f1SDimitry Andric cl::desc("Import functions with noinline attribute")); 86fe6060f1SDimitry Andric 870b57cec5SDimitry Andric static cl::opt<float> 880b57cec5SDimitry Andric ImportInstrFactor("import-instr-evolution-factor", cl::init(0.7), 890b57cec5SDimitry Andric cl::Hidden, cl::value_desc("x"), 900b57cec5SDimitry Andric cl::desc("As we import functions, multiply the " 910b57cec5SDimitry Andric "`import-instr-limit` threshold by this factor " 920b57cec5SDimitry Andric "before processing newly imported functions")); 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric static cl::opt<float> ImportHotInstrFactor( 950b57cec5SDimitry Andric "import-hot-evolution-factor", cl::init(1.0), cl::Hidden, 960b57cec5SDimitry Andric cl::value_desc("x"), 970b57cec5SDimitry Andric cl::desc("As we import functions called from hot callsite, multiply the " 980b57cec5SDimitry Andric "`import-instr-limit` threshold by this factor " 990b57cec5SDimitry Andric "before processing newly imported functions")); 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric static cl::opt<float> ImportHotMultiplier( 1020b57cec5SDimitry Andric "import-hot-multiplier", cl::init(10.0), cl::Hidden, cl::value_desc("x"), 1030b57cec5SDimitry Andric cl::desc("Multiply the `import-instr-limit` threshold for hot callsites")); 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric static cl::opt<float> ImportCriticalMultiplier( 1060b57cec5SDimitry Andric "import-critical-multiplier", cl::init(100.0), cl::Hidden, 1070b57cec5SDimitry Andric cl::value_desc("x"), 1080b57cec5SDimitry Andric cl::desc( 1090b57cec5SDimitry Andric "Multiply the `import-instr-limit` threshold for critical callsites")); 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric // FIXME: This multiplier was not really tuned up. 1120b57cec5SDimitry Andric static cl::opt<float> ImportColdMultiplier( 1130b57cec5SDimitry Andric "import-cold-multiplier", cl::init(0), cl::Hidden, cl::value_desc("N"), 1140b57cec5SDimitry Andric cl::desc("Multiply the `import-instr-limit` threshold for cold callsites")); 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric static cl::opt<bool> PrintImports("print-imports", cl::init(false), cl::Hidden, 1170b57cec5SDimitry Andric cl::desc("Print imported functions")); 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric static cl::opt<bool> PrintImportFailures( 1200b57cec5SDimitry Andric "print-import-failures", cl::init(false), cl::Hidden, 1210b57cec5SDimitry Andric cl::desc("Print information for functions rejected for importing")); 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric static cl::opt<bool> ComputeDead("compute-dead", cl::init(true), cl::Hidden, 1240b57cec5SDimitry Andric cl::desc("Compute dead symbols")); 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric static cl::opt<bool> EnableImportMetadata( 127e8d8bef9SDimitry Andric "enable-import-metadata", cl::init(false), cl::Hidden, 128*0fca6ea1SDimitry Andric cl::desc("Enable import metadata like 'thinlto_src_module' and " 129*0fca6ea1SDimitry Andric "'thinlto_src_file'")); 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric /// Summary file to use for function importing when using -function-import from 1320b57cec5SDimitry Andric /// the command line. 1330b57cec5SDimitry Andric static cl::opt<std::string> 1340b57cec5SDimitry Andric SummaryFile("summary-file", 1350b57cec5SDimitry Andric cl::desc("The summary file to use for function importing.")); 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric /// Used when testing importing from distributed indexes via opt 1380b57cec5SDimitry Andric // -function-import. 1390b57cec5SDimitry Andric static cl::opt<bool> 1400b57cec5SDimitry Andric ImportAllIndex("import-all-index", 1410b57cec5SDimitry Andric cl::desc("Import all external functions in index.")); 1420b57cec5SDimitry Andric 143*0fca6ea1SDimitry Andric /// This is a test-only option. 144*0fca6ea1SDimitry Andric /// If this option is enabled, the ThinLTO indexing step will import each 145*0fca6ea1SDimitry Andric /// function declaration as a fallback. In a real build this may increase ram 146*0fca6ea1SDimitry Andric /// usage of the indexing step unnecessarily. 147*0fca6ea1SDimitry Andric /// TODO: Implement selective import (based on combined summary analysis) to 148*0fca6ea1SDimitry Andric /// ensure the imported function has a use case in the postlink pipeline. 149*0fca6ea1SDimitry Andric static cl::opt<bool> ImportDeclaration( 150*0fca6ea1SDimitry Andric "import-declaration", cl::init(false), cl::Hidden, 151*0fca6ea1SDimitry Andric cl::desc("If true, import function declaration as fallback if the function " 152*0fca6ea1SDimitry Andric "definition is not imported.")); 153*0fca6ea1SDimitry Andric 1545f757f3fSDimitry Andric /// Pass a workload description file - an example of workload would be the 1555f757f3fSDimitry Andric /// functions executed to satisfy a RPC request. A workload is defined by a root 1565f757f3fSDimitry Andric /// function and the list of functions that are (frequently) needed to satisfy 1575f757f3fSDimitry Andric /// it. The module that defines the root will have all those functions imported. 1585f757f3fSDimitry Andric /// The file contains a JSON dictionary. The keys are root functions, the values 1595f757f3fSDimitry Andric /// are lists of functions to import in the module defining the root. It is 1605f757f3fSDimitry Andric /// assumed -funique-internal-linkage-names was used, thus ensuring function 1615f757f3fSDimitry Andric /// names are unique even for local linkage ones. 1625f757f3fSDimitry Andric static cl::opt<std::string> WorkloadDefinitions( 1635f757f3fSDimitry Andric "thinlto-workload-def", 1645f757f3fSDimitry Andric cl::desc("Pass a workload definition. This is a file containing a JSON " 1655f757f3fSDimitry Andric "dictionary. The keys are root functions, the values are lists of " 1665f757f3fSDimitry Andric "functions to import in the module defining the root. It is " 1675f757f3fSDimitry Andric "assumed -funique-internal-linkage-names was used, to ensure " 1685f757f3fSDimitry Andric "local linkage functions have unique names. For example: \n" 1695f757f3fSDimitry Andric "{\n" 1705f757f3fSDimitry Andric " \"rootFunction_1\": [\"function_to_import_1\", " 1715f757f3fSDimitry Andric "\"function_to_import_2\"], \n" 1725f757f3fSDimitry Andric " \"rootFunction_2\": [\"function_to_import_3\", " 1735f757f3fSDimitry Andric "\"function_to_import_4\"] \n" 1745f757f3fSDimitry Andric "}"), 1755f757f3fSDimitry Andric cl::Hidden); 1765f757f3fSDimitry Andric 177*0fca6ea1SDimitry Andric namespace llvm { 178*0fca6ea1SDimitry Andric extern cl::opt<bool> EnableMemProfContextDisambiguation; 179*0fca6ea1SDimitry Andric } 180*0fca6ea1SDimitry Andric 1810b57cec5SDimitry Andric // Load lazily a module from \p FileName in \p Context. 1820b57cec5SDimitry Andric static std::unique_ptr<Module> loadFile(const std::string &FileName, 1830b57cec5SDimitry Andric LLVMContext &Context) { 1840b57cec5SDimitry Andric SMDiagnostic Err; 1850b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Loading '" << FileName << "'\n"); 1860b57cec5SDimitry Andric // Metadata isn't loaded until functions are imported, to minimize 1870b57cec5SDimitry Andric // the memory overhead. 1880b57cec5SDimitry Andric std::unique_ptr<Module> Result = 1890b57cec5SDimitry Andric getLazyIRFileModule(FileName, Err, Context, 1900b57cec5SDimitry Andric /* ShouldLazyLoadMetadata = */ true); 1910b57cec5SDimitry Andric if (!Result) { 1920b57cec5SDimitry Andric Err.print("function-import", errs()); 1930b57cec5SDimitry Andric report_fatal_error("Abort"); 1940b57cec5SDimitry Andric } 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric return Result; 1970b57cec5SDimitry Andric } 1980b57cec5SDimitry Andric 19906c3fb27SDimitry Andric /// Given a list of possible callee implementation for a call site, qualify the 20006c3fb27SDimitry Andric /// legality of importing each. The return is a range of pairs. Each pair 20106c3fb27SDimitry Andric /// corresponds to a candidate. The first value is the ImportFailureReason for 20206c3fb27SDimitry Andric /// that candidate, the second is the candidate. 20306c3fb27SDimitry Andric static auto qualifyCalleeCandidates( 20406c3fb27SDimitry Andric const ModuleSummaryIndex &Index, 2050b57cec5SDimitry Andric ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList, 20606c3fb27SDimitry Andric StringRef CallerModulePath) { 20706c3fb27SDimitry Andric return llvm::map_range( 2080b57cec5SDimitry Andric CalleeSummaryList, 20906c3fb27SDimitry Andric [&Index, CalleeSummaryList, 21006c3fb27SDimitry Andric CallerModulePath](const std::unique_ptr<GlobalValueSummary> &SummaryPtr) 21106c3fb27SDimitry Andric -> std::pair<FunctionImporter::ImportFailureReason, 21206c3fb27SDimitry Andric const GlobalValueSummary *> { 2130b57cec5SDimitry Andric auto *GVSummary = SummaryPtr.get(); 21406c3fb27SDimitry Andric if (!Index.isGlobalValueLive(GVSummary)) 21506c3fb27SDimitry Andric return {FunctionImporter::ImportFailureReason::NotLive, GVSummary}; 2160b57cec5SDimitry Andric 21706c3fb27SDimitry Andric if (GlobalValue::isInterposableLinkage(GVSummary->linkage())) 21806c3fb27SDimitry Andric return {FunctionImporter::ImportFailureReason::InterposableLinkage, 21906c3fb27SDimitry Andric GVSummary}; 2200b57cec5SDimitry Andric 22106c3fb27SDimitry Andric auto *Summary = dyn_cast<FunctionSummary>(GVSummary->getBaseObject()); 22206c3fb27SDimitry Andric 22306c3fb27SDimitry Andric // Ignore any callees that aren't actually functions. This could happen 22406c3fb27SDimitry Andric // in the case of GUID hash collisions. It could also happen in theory 22506c3fb27SDimitry Andric // for SamplePGO profiles collected on old versions of the code after 22606c3fb27SDimitry Andric // renaming, since we synthesize edges to any inlined callees appearing 22706c3fb27SDimitry Andric // in the profile. 22806c3fb27SDimitry Andric if (!Summary) 22906c3fb27SDimitry Andric return {FunctionImporter::ImportFailureReason::GlobalVar, GVSummary}; 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric // If this is a local function, make sure we import the copy 2320b57cec5SDimitry Andric // in the caller's module. The only time a local function can 2330b57cec5SDimitry Andric // share an entry in the index is if there is a local with the same name 2340b57cec5SDimitry Andric // in another module that had the same source file name (in a different 2350b57cec5SDimitry Andric // directory), where each was compiled in their own directory so there 2360b57cec5SDimitry Andric // was not distinguishing path. 2370b57cec5SDimitry Andric // However, do the import from another module if there is only one 2380b57cec5SDimitry Andric // entry in the list - in that case this must be a reference due 2390b57cec5SDimitry Andric // to indirect call profile data, since a function pointer can point to 2400b57cec5SDimitry Andric // a local in another module. 2410b57cec5SDimitry Andric if (GlobalValue::isLocalLinkage(Summary->linkage()) && 2420b57cec5SDimitry Andric CalleeSummaryList.size() > 1 && 24306c3fb27SDimitry Andric Summary->modulePath() != CallerModulePath) 24406c3fb27SDimitry Andric return { 24506c3fb27SDimitry Andric FunctionImporter::ImportFailureReason::LocalLinkageNotInModule, 24606c3fb27SDimitry Andric GVSummary}; 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric // Skip if it isn't legal to import (e.g. may reference unpromotable 2490b57cec5SDimitry Andric // locals). 25006c3fb27SDimitry Andric if (Summary->notEligibleToImport()) 25106c3fb27SDimitry Andric return {FunctionImporter::ImportFailureReason::NotEligible, 25206c3fb27SDimitry Andric GVSummary}; 25306c3fb27SDimitry Andric 25406c3fb27SDimitry Andric return {FunctionImporter::ImportFailureReason::None, GVSummary}; 25506c3fb27SDimitry Andric }); 25606c3fb27SDimitry Andric } 25706c3fb27SDimitry Andric 25806c3fb27SDimitry Andric /// Given a list of possible callee implementation for a call site, select one 259*0fca6ea1SDimitry Andric /// that fits the \p Threshold for function definition import. If none are 260*0fca6ea1SDimitry Andric /// found, the Reason will give the last reason for the failure (last, in the 261*0fca6ea1SDimitry Andric /// order of CalleeSummaryList entries). While looking for a callee definition, 262*0fca6ea1SDimitry Andric /// sets \p TooLargeOrNoInlineSummary to the last seen too-large or noinline 263*0fca6ea1SDimitry Andric /// candidate; other modules may want to know the function summary or 264*0fca6ea1SDimitry Andric /// declaration even if a definition is not needed. 26506c3fb27SDimitry Andric /// 26606c3fb27SDimitry Andric /// FIXME: select "best" instead of first that fits. But what is "best"? 26706c3fb27SDimitry Andric /// - The smallest: more likely to be inlined. 26806c3fb27SDimitry Andric /// - The one with the least outgoing edges (already well optimized). 26906c3fb27SDimitry Andric /// - One from a module already being imported from in order to reduce the 27006c3fb27SDimitry Andric /// number of source modules parsed/linked. 27106c3fb27SDimitry Andric /// - One that has PGO data attached. 27206c3fb27SDimitry Andric /// - [insert you fancy metric here] 27306c3fb27SDimitry Andric static const GlobalValueSummary * 27406c3fb27SDimitry Andric selectCallee(const ModuleSummaryIndex &Index, 27506c3fb27SDimitry Andric ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList, 27606c3fb27SDimitry Andric unsigned Threshold, StringRef CallerModulePath, 277*0fca6ea1SDimitry Andric const GlobalValueSummary *&TooLargeOrNoInlineSummary, 27806c3fb27SDimitry Andric FunctionImporter::ImportFailureReason &Reason) { 279*0fca6ea1SDimitry Andric // Records the last summary with reason noinline or too-large. 280*0fca6ea1SDimitry Andric TooLargeOrNoInlineSummary = nullptr; 28106c3fb27SDimitry Andric auto QualifiedCandidates = 28206c3fb27SDimitry Andric qualifyCalleeCandidates(Index, CalleeSummaryList, CallerModulePath); 28306c3fb27SDimitry Andric for (auto QualifiedValue : QualifiedCandidates) { 28406c3fb27SDimitry Andric Reason = QualifiedValue.first; 285*0fca6ea1SDimitry Andric // Skip a summary if its import is not (proved to be) legal. 28606c3fb27SDimitry Andric if (Reason != FunctionImporter::ImportFailureReason::None) 28706c3fb27SDimitry Andric continue; 28806c3fb27SDimitry Andric auto *Summary = 28906c3fb27SDimitry Andric cast<FunctionSummary>(QualifiedValue.second->getBaseObject()); 29006c3fb27SDimitry Andric 291*0fca6ea1SDimitry Andric // Don't bother importing the definition if the chance of inlining it is 292*0fca6ea1SDimitry Andric // not high enough (except under `--force-import-all`). 29306c3fb27SDimitry Andric if ((Summary->instCount() > Threshold) && !Summary->fflags().AlwaysInline && 29406c3fb27SDimitry Andric !ForceImportAll) { 295*0fca6ea1SDimitry Andric TooLargeOrNoInlineSummary = Summary; 29606c3fb27SDimitry Andric Reason = FunctionImporter::ImportFailureReason::TooLarge; 29706c3fb27SDimitry Andric continue; 2980b57cec5SDimitry Andric } 2990b57cec5SDimitry Andric 300*0fca6ea1SDimitry Andric // Don't bother importing the definition if we can't inline it anyway. 301fe6060f1SDimitry Andric if (Summary->fflags().NoInline && !ForceImportAll) { 302*0fca6ea1SDimitry Andric TooLargeOrNoInlineSummary = Summary; 3030b57cec5SDimitry Andric Reason = FunctionImporter::ImportFailureReason::NoInline; 30406c3fb27SDimitry Andric continue; 3050b57cec5SDimitry Andric } 3060b57cec5SDimitry Andric 30706c3fb27SDimitry Andric return Summary; 30806c3fb27SDimitry Andric } 3090b57cec5SDimitry Andric return nullptr; 3100b57cec5SDimitry Andric } 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric namespace { 3130b57cec5SDimitry Andric 31406c3fb27SDimitry Andric using EdgeInfo = std::tuple<const FunctionSummary *, unsigned /* Threshold */>; 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric } // anonymous namespace 3170b57cec5SDimitry Andric 31806c3fb27SDimitry Andric /// Import globals referenced by a function or other globals that are being 31906c3fb27SDimitry Andric /// imported, if importing such global is possible. 32006c3fb27SDimitry Andric class GlobalsImporter final { 32106c3fb27SDimitry Andric const ModuleSummaryIndex &Index; 32206c3fb27SDimitry Andric const GVSummaryMapTy &DefinedGVSummaries; 32306c3fb27SDimitry Andric function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 32406c3fb27SDimitry Andric IsPrevailing; 32506c3fb27SDimitry Andric FunctionImporter::ImportMapTy &ImportList; 3265f757f3fSDimitry Andric DenseMap<StringRef, FunctionImporter::ExportSetTy> *const ExportLists; 32706c3fb27SDimitry Andric 32806c3fb27SDimitry Andric bool shouldImportGlobal(const ValueInfo &VI) { 329fe6060f1SDimitry Andric const auto &GVS = DefinedGVSummaries.find(VI.getGUID()); 330fe6060f1SDimitry Andric if (GVS == DefinedGVSummaries.end()) 331fe6060f1SDimitry Andric return true; 33206c3fb27SDimitry Andric // We should not skip import if the module contains a non-prevailing 33306c3fb27SDimitry Andric // definition with interposable linkage type. This is required for 33406c3fb27SDimitry Andric // correctness in the situation where there is a prevailing def available 33506c3fb27SDimitry Andric // for import and marked read-only. In this case, the non-prevailing def 33606c3fb27SDimitry Andric // will be converted to a declaration, while the prevailing one becomes 33706c3fb27SDimitry Andric // internal, thus no definitions will be available for linking. In order to 33806c3fb27SDimitry Andric // prevent undefined symbol link error, the prevailing definition must be 33906c3fb27SDimitry Andric // imported. 340fe6060f1SDimitry Andric // FIXME: Consider adding a check that the suitable prevailing definition 341fe6060f1SDimitry Andric // exists and marked read-only. 342fe6060f1SDimitry Andric if (VI.getSummaryList().size() > 1 && 34306c3fb27SDimitry Andric GlobalValue::isInterposableLinkage(GVS->second->linkage()) && 34406c3fb27SDimitry Andric !IsPrevailing(VI.getGUID(), GVS->second)) 345fe6060f1SDimitry Andric return true; 346fe6060f1SDimitry Andric 347fe6060f1SDimitry Andric return false; 348fe6060f1SDimitry Andric } 349fe6060f1SDimitry Andric 35006c3fb27SDimitry Andric void 35106c3fb27SDimitry Andric onImportingSummaryImpl(const GlobalValueSummary &Summary, 35206c3fb27SDimitry Andric SmallVectorImpl<const GlobalVarSummary *> &Worklist) { 353bdd1243dSDimitry Andric for (const auto &VI : Summary.refs()) { 35406c3fb27SDimitry Andric if (!shouldImportGlobal(VI)) { 3550b57cec5SDimitry Andric LLVM_DEBUG( 3560b57cec5SDimitry Andric dbgs() << "Ref ignored! Target already in destination module.\n"); 3570b57cec5SDimitry Andric continue; 3580b57cec5SDimitry Andric } 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " ref -> " << VI << "\n"); 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric // If this is a local variable, make sure we import the copy 3630b57cec5SDimitry Andric // in the caller's module. The only time a local variable can 3640b57cec5SDimitry Andric // share an entry in the index is if there is a local with the same name 3650b57cec5SDimitry Andric // in another module that had the same source file name (in a different 3660b57cec5SDimitry Andric // directory), where each was compiled in their own directory so there 3670b57cec5SDimitry Andric // was not distinguishing path. 36806c3fb27SDimitry Andric auto LocalNotInModule = 36906c3fb27SDimitry Andric [&](const GlobalValueSummary *RefSummary) -> bool { 3700b57cec5SDimitry Andric return GlobalValue::isLocalLinkage(RefSummary->linkage()) && 3710b57cec5SDimitry Andric RefSummary->modulePath() != Summary.modulePath(); 3720b57cec5SDimitry Andric }; 3730b57cec5SDimitry Andric 37406c3fb27SDimitry Andric for (const auto &RefSummary : VI.getSummaryList()) { 37506c3fb27SDimitry Andric const auto *GVS = dyn_cast<GlobalVarSummary>(RefSummary.get()); 37606c3fb27SDimitry Andric // Functions could be referenced by global vars - e.g. a vtable; but we 37706c3fb27SDimitry Andric // don't currently imagine a reason those would be imported here, rather 37806c3fb27SDimitry Andric // than as part of the logic deciding which functions to import (i.e. 37906c3fb27SDimitry Andric // based on profile information). Should we decide to handle them here, 38006c3fb27SDimitry Andric // we can refactor accordingly at that time. 38106c3fb27SDimitry Andric if (!GVS || !Index.canImportGlobalVar(GVS, /* AnalyzeRefs */ true) || 38206c3fb27SDimitry Andric LocalNotInModule(GVS)) 38306c3fb27SDimitry Andric continue; 384*0fca6ea1SDimitry Andric 385*0fca6ea1SDimitry Andric // If there isn't an entry for GUID, insert <GUID, Definition> pair. 386*0fca6ea1SDimitry Andric // Otherwise, definition should take precedence over declaration. 387*0fca6ea1SDimitry Andric auto [Iter, Inserted] = 388*0fca6ea1SDimitry Andric ImportList[RefSummary->modulePath()].try_emplace( 389*0fca6ea1SDimitry Andric VI.getGUID(), GlobalValueSummary::Definition); 3905ffd83dbSDimitry Andric // Only update stat and exports if we haven't already imported this 3915ffd83dbSDimitry Andric // variable. 392*0fca6ea1SDimitry Andric if (!Inserted) { 393*0fca6ea1SDimitry Andric // Set the value to 'std::min(existing-value, new-value)' to make 394*0fca6ea1SDimitry Andric // sure a definition takes precedence over a declaration. 395*0fca6ea1SDimitry Andric Iter->second = std::min(GlobalValueSummary::Definition, Iter->second); 3965ffd83dbSDimitry Andric break; 397*0fca6ea1SDimitry Andric } 3980b57cec5SDimitry Andric NumImportedGlobalVarsThinLink++; 39906c3fb27SDimitry Andric // Any references made by this variable will be marked exported 40006c3fb27SDimitry Andric // later, in ComputeCrossModuleImport, after import decisions are 40106c3fb27SDimitry Andric // complete, which is more efficient than adding them here. 4025ffd83dbSDimitry Andric if (ExportLists) 4035ffd83dbSDimitry Andric (*ExportLists)[RefSummary->modulePath()].insert(VI); 404e8d8bef9SDimitry Andric 405e8d8bef9SDimitry Andric // If variable is not writeonly we attempt to recursively analyze 406e8d8bef9SDimitry Andric // its references in order to import referenced constants. 40706c3fb27SDimitry Andric if (!Index.isWriteOnly(GVS)) 40806c3fb27SDimitry Andric Worklist.emplace_back(GVS); 4090b57cec5SDimitry Andric break; 4100b57cec5SDimitry Andric } 4110b57cec5SDimitry Andric } 4120b57cec5SDimitry Andric } 4130b57cec5SDimitry Andric 41406c3fb27SDimitry Andric public: 41506c3fb27SDimitry Andric GlobalsImporter( 41606c3fb27SDimitry Andric const ModuleSummaryIndex &Index, const GVSummaryMapTy &DefinedGVSummaries, 41706c3fb27SDimitry Andric function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 41806c3fb27SDimitry Andric IsPrevailing, 41906c3fb27SDimitry Andric FunctionImporter::ImportMapTy &ImportList, 4205f757f3fSDimitry Andric DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists) 42106c3fb27SDimitry Andric : Index(Index), DefinedGVSummaries(DefinedGVSummaries), 42206c3fb27SDimitry Andric IsPrevailing(IsPrevailing), ImportList(ImportList), 42306c3fb27SDimitry Andric ExportLists(ExportLists) {} 42406c3fb27SDimitry Andric 42506c3fb27SDimitry Andric void onImportingSummary(const GlobalValueSummary &Summary) { 42606c3fb27SDimitry Andric SmallVector<const GlobalVarSummary *, 128> Worklist; 42706c3fb27SDimitry Andric onImportingSummaryImpl(Summary, Worklist); 42806c3fb27SDimitry Andric while (!Worklist.empty()) 42906c3fb27SDimitry Andric onImportingSummaryImpl(*Worklist.pop_back_val(), Worklist); 43006c3fb27SDimitry Andric } 43106c3fb27SDimitry Andric }; 43206c3fb27SDimitry Andric 4335f757f3fSDimitry Andric static const char *getFailureName(FunctionImporter::ImportFailureReason Reason); 4345f757f3fSDimitry Andric 4355f757f3fSDimitry Andric /// Determine the list of imports and exports for each module. 4365f757f3fSDimitry Andric class ModuleImportsManager { 4375f757f3fSDimitry Andric protected: 4385f757f3fSDimitry Andric function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 4395f757f3fSDimitry Andric IsPrevailing; 4405f757f3fSDimitry Andric const ModuleSummaryIndex &Index; 4415f757f3fSDimitry Andric DenseMap<StringRef, FunctionImporter::ExportSetTy> *const ExportLists; 4425f757f3fSDimitry Andric 4435f757f3fSDimitry Andric ModuleImportsManager( 4445f757f3fSDimitry Andric function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 4455f757f3fSDimitry Andric IsPrevailing, 4465f757f3fSDimitry Andric const ModuleSummaryIndex &Index, 4475f757f3fSDimitry Andric DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists = nullptr) 4485f757f3fSDimitry Andric : IsPrevailing(IsPrevailing), Index(Index), ExportLists(ExportLists) {} 4495f757f3fSDimitry Andric 4505f757f3fSDimitry Andric public: 4515f757f3fSDimitry Andric virtual ~ModuleImportsManager() = default; 4525f757f3fSDimitry Andric 4535f757f3fSDimitry Andric /// Given the list of globals defined in a module, compute the list of imports 4545f757f3fSDimitry Andric /// as well as the list of "exports", i.e. the list of symbols referenced from 4555f757f3fSDimitry Andric /// another module (that may require promotion). 4565f757f3fSDimitry Andric virtual void 4575f757f3fSDimitry Andric computeImportForModule(const GVSummaryMapTy &DefinedGVSummaries, 4585f757f3fSDimitry Andric StringRef ModName, 4595f757f3fSDimitry Andric FunctionImporter::ImportMapTy &ImportList); 4605f757f3fSDimitry Andric 4615f757f3fSDimitry Andric static std::unique_ptr<ModuleImportsManager> 4625f757f3fSDimitry Andric create(function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 4635f757f3fSDimitry Andric IsPrevailing, 4645f757f3fSDimitry Andric const ModuleSummaryIndex &Index, 4655f757f3fSDimitry Andric DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists = 4665f757f3fSDimitry Andric nullptr); 4675f757f3fSDimitry Andric }; 4685f757f3fSDimitry Andric 4695f757f3fSDimitry Andric /// A ModuleImportsManager that operates based on a workload definition (see 4705f757f3fSDimitry Andric /// -thinlto-workload-def). For modules that do not define workload roots, it 4715f757f3fSDimitry Andric /// applies the base ModuleImportsManager import policy. 4725f757f3fSDimitry Andric class WorkloadImportsManager : public ModuleImportsManager { 4735f757f3fSDimitry Andric // Keep a module name -> value infos to import association. We use it to 4745f757f3fSDimitry Andric // determine if a module's import list should be done by the base 4755f757f3fSDimitry Andric // ModuleImportsManager or by us. 4765f757f3fSDimitry Andric StringMap<DenseSet<ValueInfo>> Workloads; 4775f757f3fSDimitry Andric 4785f757f3fSDimitry Andric void 4795f757f3fSDimitry Andric computeImportForModule(const GVSummaryMapTy &DefinedGVSummaries, 4805f757f3fSDimitry Andric StringRef ModName, 4815f757f3fSDimitry Andric FunctionImporter::ImportMapTy &ImportList) override { 4825f757f3fSDimitry Andric auto SetIter = Workloads.find(ModName); 4835f757f3fSDimitry Andric if (SetIter == Workloads.end()) { 4845f757f3fSDimitry Andric LLVM_DEBUG(dbgs() << "[Workload] " << ModName 4855f757f3fSDimitry Andric << " does not contain the root of any context.\n"); 4865f757f3fSDimitry Andric return ModuleImportsManager::computeImportForModule(DefinedGVSummaries, 4875f757f3fSDimitry Andric ModName, ImportList); 4885f757f3fSDimitry Andric } 4895f757f3fSDimitry Andric LLVM_DEBUG(dbgs() << "[Workload] " << ModName 4905f757f3fSDimitry Andric << " contains the root(s) of context(s).\n"); 4915f757f3fSDimitry Andric 4925f757f3fSDimitry Andric GlobalsImporter GVI(Index, DefinedGVSummaries, IsPrevailing, ImportList, 4935f757f3fSDimitry Andric ExportLists); 4945f757f3fSDimitry Andric auto &ValueInfos = SetIter->second; 4955f757f3fSDimitry Andric SmallVector<EdgeInfo, 128> GlobWorklist; 4965f757f3fSDimitry Andric for (auto &VI : llvm::make_early_inc_range(ValueInfos)) { 4975f757f3fSDimitry Andric auto It = DefinedGVSummaries.find(VI.getGUID()); 4985f757f3fSDimitry Andric if (It != DefinedGVSummaries.end() && 4995f757f3fSDimitry Andric IsPrevailing(VI.getGUID(), It->second)) { 5005f757f3fSDimitry Andric LLVM_DEBUG( 5015f757f3fSDimitry Andric dbgs() << "[Workload] " << VI.name() 5025f757f3fSDimitry Andric << " has the prevailing variant already in the module " 5035f757f3fSDimitry Andric << ModName << ". No need to import\n"); 5045f757f3fSDimitry Andric continue; 5055f757f3fSDimitry Andric } 5065f757f3fSDimitry Andric auto Candidates = 5075f757f3fSDimitry Andric qualifyCalleeCandidates(Index, VI.getSummaryList(), ModName); 5085f757f3fSDimitry Andric 5095f757f3fSDimitry Andric const GlobalValueSummary *GVS = nullptr; 5105f757f3fSDimitry Andric auto PotentialCandidates = llvm::map_range( 5115f757f3fSDimitry Andric llvm::make_filter_range( 5125f757f3fSDimitry Andric Candidates, 5135f757f3fSDimitry Andric [&](const auto &Candidate) { 5145f757f3fSDimitry Andric LLVM_DEBUG(dbgs() << "[Workflow] Candidate for " << VI.name() 5155f757f3fSDimitry Andric << " from " << Candidate.second->modulePath() 5165f757f3fSDimitry Andric << " ImportFailureReason: " 5175f757f3fSDimitry Andric << getFailureName(Candidate.first) << "\n"); 5185f757f3fSDimitry Andric return Candidate.first == 5195f757f3fSDimitry Andric FunctionImporter::ImportFailureReason::None; 5205f757f3fSDimitry Andric }), 5215f757f3fSDimitry Andric [](const auto &Candidate) { return Candidate.second; }); 5225f757f3fSDimitry Andric if (PotentialCandidates.empty()) { 5235f757f3fSDimitry Andric LLVM_DEBUG(dbgs() << "[Workload] Not importing " << VI.name() 5245f757f3fSDimitry Andric << " because can't find eligible Callee. Guid is: " 5255f757f3fSDimitry Andric << Function::getGUID(VI.name()) << "\n"); 5265f757f3fSDimitry Andric continue; 5275f757f3fSDimitry Andric } 5285f757f3fSDimitry Andric /// We will prefer importing the prevailing candidate, if not, we'll 5295f757f3fSDimitry Andric /// still pick the first available candidate. The reason we want to make 5305f757f3fSDimitry Andric /// sure we do import the prevailing candidate is because the goal of 5315f757f3fSDimitry Andric /// workload-awareness is to enable optimizations specializing the call 5325f757f3fSDimitry Andric /// graph of that workload. Suppose a function is already defined in the 5335f757f3fSDimitry Andric /// module, but it's not the prevailing variant. Suppose also we do not 5345f757f3fSDimitry Andric /// inline it (in fact, if it were interposable, we can't inline it), 5355f757f3fSDimitry Andric /// but we could specialize it to the workload in other ways. However, 5365f757f3fSDimitry Andric /// the linker would drop it in the favor of the prevailing copy. 5375f757f3fSDimitry Andric /// Instead, by importing the prevailing variant (assuming also the use 5385f757f3fSDimitry Andric /// of `-avail-extern-to-local`), we keep the specialization. We could 5395f757f3fSDimitry Andric /// alteranatively make the non-prevailing variant local, but the 5405f757f3fSDimitry Andric /// prevailing one is also the one for which we would have previously 5415f757f3fSDimitry Andric /// collected profiles, making it preferrable. 5425f757f3fSDimitry Andric auto PrevailingCandidates = llvm::make_filter_range( 5435f757f3fSDimitry Andric PotentialCandidates, [&](const auto *Candidate) { 5445f757f3fSDimitry Andric return IsPrevailing(VI.getGUID(), Candidate); 5455f757f3fSDimitry Andric }); 5465f757f3fSDimitry Andric if (PrevailingCandidates.empty()) { 5475f757f3fSDimitry Andric GVS = *PotentialCandidates.begin(); 5485f757f3fSDimitry Andric if (!llvm::hasSingleElement(PotentialCandidates) && 5495f757f3fSDimitry Andric GlobalValue::isLocalLinkage(GVS->linkage())) 5505f757f3fSDimitry Andric LLVM_DEBUG( 5515f757f3fSDimitry Andric dbgs() 5525f757f3fSDimitry Andric << "[Workload] Found multiple non-prevailing candidates for " 5535f757f3fSDimitry Andric << VI.name() 5545f757f3fSDimitry Andric << ". This is unexpected. Are module paths passed to the " 5555f757f3fSDimitry Andric "compiler unique for the modules passed to the linker?"); 5565f757f3fSDimitry Andric // We could in theory have multiple (interposable) copies of a symbol 5575f757f3fSDimitry Andric // when there is no prevailing candidate, if say the prevailing copy was 5585f757f3fSDimitry Andric // in a native object being linked in. However, we should in theory be 5595f757f3fSDimitry Andric // marking all of these non-prevailing IR copies dead in that case, in 5605f757f3fSDimitry Andric // which case they won't be candidates. 5615f757f3fSDimitry Andric assert(GVS->isLive()); 5625f757f3fSDimitry Andric } else { 5635f757f3fSDimitry Andric assert(llvm::hasSingleElement(PrevailingCandidates)); 5645f757f3fSDimitry Andric GVS = *PrevailingCandidates.begin(); 5655f757f3fSDimitry Andric } 5665f757f3fSDimitry Andric 5675f757f3fSDimitry Andric auto ExportingModule = GVS->modulePath(); 5685f757f3fSDimitry Andric // We checked that for the prevailing case, but if we happen to have for 5695f757f3fSDimitry Andric // example an internal that's defined in this module, it'd have no 5705f757f3fSDimitry Andric // PrevailingCandidates. 5715f757f3fSDimitry Andric if (ExportingModule == ModName) { 5725f757f3fSDimitry Andric LLVM_DEBUG(dbgs() << "[Workload] Not importing " << VI.name() 5735f757f3fSDimitry Andric << " because its defining module is the same as the " 5745f757f3fSDimitry Andric "current module\n"); 5755f757f3fSDimitry Andric continue; 5765f757f3fSDimitry Andric } 5775f757f3fSDimitry Andric LLVM_DEBUG(dbgs() << "[Workload][Including]" << VI.name() << " from " 5785f757f3fSDimitry Andric << ExportingModule << " : " 5795f757f3fSDimitry Andric << Function::getGUID(VI.name()) << "\n"); 580*0fca6ea1SDimitry Andric ImportList[ExportingModule][VI.getGUID()] = 581*0fca6ea1SDimitry Andric GlobalValueSummary::Definition; 5825f757f3fSDimitry Andric GVI.onImportingSummary(*GVS); 5835f757f3fSDimitry Andric if (ExportLists) 5845f757f3fSDimitry Andric (*ExportLists)[ExportingModule].insert(VI); 5855f757f3fSDimitry Andric } 5865f757f3fSDimitry Andric LLVM_DEBUG(dbgs() << "[Workload] Done\n"); 5875f757f3fSDimitry Andric } 5885f757f3fSDimitry Andric 5895f757f3fSDimitry Andric public: 5905f757f3fSDimitry Andric WorkloadImportsManager( 5915f757f3fSDimitry Andric function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 5925f757f3fSDimitry Andric IsPrevailing, 5935f757f3fSDimitry Andric const ModuleSummaryIndex &Index, 5945f757f3fSDimitry Andric DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists) 5955f757f3fSDimitry Andric : ModuleImportsManager(IsPrevailing, Index, ExportLists) { 5965f757f3fSDimitry Andric // Since the workload def uses names, we need a quick lookup 5975f757f3fSDimitry Andric // name->ValueInfo. 5985f757f3fSDimitry Andric StringMap<ValueInfo> NameToValueInfo; 5995f757f3fSDimitry Andric StringSet<> AmbiguousNames; 6005f757f3fSDimitry Andric for (auto &I : Index) { 6015f757f3fSDimitry Andric ValueInfo VI = Index.getValueInfo(I); 6025f757f3fSDimitry Andric if (!NameToValueInfo.insert(std::make_pair(VI.name(), VI)).second) 6035f757f3fSDimitry Andric LLVM_DEBUG(AmbiguousNames.insert(VI.name())); 6045f757f3fSDimitry Andric } 6055f757f3fSDimitry Andric auto DbgReportIfAmbiguous = [&](StringRef Name) { 6065f757f3fSDimitry Andric LLVM_DEBUG(if (AmbiguousNames.count(Name) > 0) { 6075f757f3fSDimitry Andric dbgs() << "[Workload] Function name " << Name 6085f757f3fSDimitry Andric << " present in the workload definition is ambiguous. Consider " 6095f757f3fSDimitry Andric "compiling with -funique-internal-linkage-names."; 6105f757f3fSDimitry Andric }); 6115f757f3fSDimitry Andric }; 6125f757f3fSDimitry Andric std::error_code EC; 6135f757f3fSDimitry Andric auto BufferOrErr = MemoryBuffer::getFileOrSTDIN(WorkloadDefinitions); 6145f757f3fSDimitry Andric if (std::error_code EC = BufferOrErr.getError()) { 6155f757f3fSDimitry Andric report_fatal_error("Failed to open context file"); 6165f757f3fSDimitry Andric return; 6175f757f3fSDimitry Andric } 6185f757f3fSDimitry Andric auto Buffer = std::move(BufferOrErr.get()); 6195f757f3fSDimitry Andric std::map<std::string, std::vector<std::string>> WorkloadDefs; 6205f757f3fSDimitry Andric json::Path::Root NullRoot; 6215f757f3fSDimitry Andric // The JSON is supposed to contain a dictionary matching the type of 6225f757f3fSDimitry Andric // WorkloadDefs. For example: 6235f757f3fSDimitry Andric // { 6245f757f3fSDimitry Andric // "rootFunction_1": ["function_to_import_1", "function_to_import_2"], 6255f757f3fSDimitry Andric // "rootFunction_2": ["function_to_import_3", "function_to_import_4"] 6265f757f3fSDimitry Andric // } 6275f757f3fSDimitry Andric auto Parsed = json::parse(Buffer->getBuffer()); 6285f757f3fSDimitry Andric if (!Parsed) 6295f757f3fSDimitry Andric report_fatal_error(Parsed.takeError()); 6305f757f3fSDimitry Andric if (!json::fromJSON(*Parsed, WorkloadDefs, NullRoot)) 6315f757f3fSDimitry Andric report_fatal_error("Invalid thinlto contextual profile format."); 6325f757f3fSDimitry Andric for (const auto &Workload : WorkloadDefs) { 6335f757f3fSDimitry Andric const auto &Root = Workload.first; 6345f757f3fSDimitry Andric DbgReportIfAmbiguous(Root); 6355f757f3fSDimitry Andric LLVM_DEBUG(dbgs() << "[Workload] Root: " << Root << "\n"); 6365f757f3fSDimitry Andric const auto &AllCallees = Workload.second; 6375f757f3fSDimitry Andric auto RootIt = NameToValueInfo.find(Root); 6385f757f3fSDimitry Andric if (RootIt == NameToValueInfo.end()) { 6395f757f3fSDimitry Andric LLVM_DEBUG(dbgs() << "[Workload] Root " << Root 6405f757f3fSDimitry Andric << " not found in this linkage unit.\n"); 6415f757f3fSDimitry Andric continue; 6425f757f3fSDimitry Andric } 6435f757f3fSDimitry Andric auto RootVI = RootIt->second; 6445f757f3fSDimitry Andric if (RootVI.getSummaryList().size() != 1) { 6455f757f3fSDimitry Andric LLVM_DEBUG(dbgs() << "[Workload] Root " << Root 6465f757f3fSDimitry Andric << " should have exactly one summary, but has " 6475f757f3fSDimitry Andric << RootVI.getSummaryList().size() << ". Skipping.\n"); 6485f757f3fSDimitry Andric continue; 6495f757f3fSDimitry Andric } 6505f757f3fSDimitry Andric StringRef RootDefiningModule = 6515f757f3fSDimitry Andric RootVI.getSummaryList().front()->modulePath(); 6525f757f3fSDimitry Andric LLVM_DEBUG(dbgs() << "[Workload] Root defining module for " << Root 6535f757f3fSDimitry Andric << " is : " << RootDefiningModule << "\n"); 6545f757f3fSDimitry Andric auto &Set = Workloads[RootDefiningModule]; 6555f757f3fSDimitry Andric for (const auto &Callee : AllCallees) { 6565f757f3fSDimitry Andric LLVM_DEBUG(dbgs() << "[Workload] " << Callee << "\n"); 6575f757f3fSDimitry Andric DbgReportIfAmbiguous(Callee); 6585f757f3fSDimitry Andric auto ElemIt = NameToValueInfo.find(Callee); 6595f757f3fSDimitry Andric if (ElemIt == NameToValueInfo.end()) { 6605f757f3fSDimitry Andric LLVM_DEBUG(dbgs() << "[Workload] " << Callee << " not found\n"); 6615f757f3fSDimitry Andric continue; 6625f757f3fSDimitry Andric } 6635f757f3fSDimitry Andric Set.insert(ElemIt->second); 6645f757f3fSDimitry Andric } 6655f757f3fSDimitry Andric LLVM_DEBUG({ 6665f757f3fSDimitry Andric dbgs() << "[Workload] Root: " << Root << " we have " << Set.size() 6675f757f3fSDimitry Andric << " distinct callees.\n"; 6685f757f3fSDimitry Andric for (const auto &VI : Set) { 6695f757f3fSDimitry Andric dbgs() << "[Workload] Root: " << Root 6705f757f3fSDimitry Andric << " Would include: " << VI.getGUID() << "\n"; 6715f757f3fSDimitry Andric } 6725f757f3fSDimitry Andric }); 6735f757f3fSDimitry Andric } 6745f757f3fSDimitry Andric } 6755f757f3fSDimitry Andric }; 6765f757f3fSDimitry Andric 6775f757f3fSDimitry Andric std::unique_ptr<ModuleImportsManager> ModuleImportsManager::create( 6785f757f3fSDimitry Andric function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 6795f757f3fSDimitry Andric IsPrevailing, 6805f757f3fSDimitry Andric const ModuleSummaryIndex &Index, 6815f757f3fSDimitry Andric DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists) { 6825f757f3fSDimitry Andric if (WorkloadDefinitions.empty()) { 6835f757f3fSDimitry Andric LLVM_DEBUG(dbgs() << "[Workload] Using the regular imports manager.\n"); 6845f757f3fSDimitry Andric return std::unique_ptr<ModuleImportsManager>( 6855f757f3fSDimitry Andric new ModuleImportsManager(IsPrevailing, Index, ExportLists)); 6865f757f3fSDimitry Andric } 6875f757f3fSDimitry Andric LLVM_DEBUG(dbgs() << "[Workload] Using the contextual imports manager.\n"); 6885f757f3fSDimitry Andric return std::make_unique<WorkloadImportsManager>(IsPrevailing, Index, 6895f757f3fSDimitry Andric ExportLists); 6905f757f3fSDimitry Andric } 6915f757f3fSDimitry Andric 6920b57cec5SDimitry Andric static const char * 6930b57cec5SDimitry Andric getFailureName(FunctionImporter::ImportFailureReason Reason) { 6940b57cec5SDimitry Andric switch (Reason) { 6950b57cec5SDimitry Andric case FunctionImporter::ImportFailureReason::None: 6960b57cec5SDimitry Andric return "None"; 6970b57cec5SDimitry Andric case FunctionImporter::ImportFailureReason::GlobalVar: 6980b57cec5SDimitry Andric return "GlobalVar"; 6990b57cec5SDimitry Andric case FunctionImporter::ImportFailureReason::NotLive: 7000b57cec5SDimitry Andric return "NotLive"; 7010b57cec5SDimitry Andric case FunctionImporter::ImportFailureReason::TooLarge: 7020b57cec5SDimitry Andric return "TooLarge"; 7030b57cec5SDimitry Andric case FunctionImporter::ImportFailureReason::InterposableLinkage: 7040b57cec5SDimitry Andric return "InterposableLinkage"; 7050b57cec5SDimitry Andric case FunctionImporter::ImportFailureReason::LocalLinkageNotInModule: 7060b57cec5SDimitry Andric return "LocalLinkageNotInModule"; 7070b57cec5SDimitry Andric case FunctionImporter::ImportFailureReason::NotEligible: 7080b57cec5SDimitry Andric return "NotEligible"; 7090b57cec5SDimitry Andric case FunctionImporter::ImportFailureReason::NoInline: 7100b57cec5SDimitry Andric return "NoInline"; 7110b57cec5SDimitry Andric } 7120b57cec5SDimitry Andric llvm_unreachable("invalid reason"); 7130b57cec5SDimitry Andric } 7140b57cec5SDimitry Andric 7150b57cec5SDimitry Andric /// Compute the list of functions to import for a given caller. Mark these 7160b57cec5SDimitry Andric /// imported functions and the symbols they reference in their source module as 7170b57cec5SDimitry Andric /// exported from their source module. 7180b57cec5SDimitry Andric static void computeImportForFunction( 7190b57cec5SDimitry Andric const FunctionSummary &Summary, const ModuleSummaryIndex &Index, 7200b57cec5SDimitry Andric const unsigned Threshold, const GVSummaryMapTy &DefinedGVSummaries, 72106c3fb27SDimitry Andric function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 72206c3fb27SDimitry Andric isPrevailing, 72306c3fb27SDimitry Andric SmallVectorImpl<EdgeInfo> &Worklist, GlobalsImporter &GVImporter, 7240b57cec5SDimitry Andric FunctionImporter::ImportMapTy &ImportList, 7255f757f3fSDimitry Andric DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists, 7260b57cec5SDimitry Andric FunctionImporter::ImportThresholdsTy &ImportThresholds) { 72706c3fb27SDimitry Andric GVImporter.onImportingSummary(Summary); 7280b57cec5SDimitry Andric static int ImportCount = 0; 729bdd1243dSDimitry Andric for (const auto &Edge : Summary.calls()) { 7300b57cec5SDimitry Andric ValueInfo VI = Edge.first; 7310b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " edge -> " << VI << " Threshold:" << Threshold 7320b57cec5SDimitry Andric << "\n"); 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric if (ImportCutoff >= 0 && ImportCount >= ImportCutoff) { 7350b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "ignored! import-cutoff value of " << ImportCutoff 7360b57cec5SDimitry Andric << " reached.\n"); 7370b57cec5SDimitry Andric continue; 7380b57cec5SDimitry Andric } 7390b57cec5SDimitry Andric 7400b57cec5SDimitry Andric if (DefinedGVSummaries.count(VI.getGUID())) { 741fe6060f1SDimitry Andric // FIXME: Consider not skipping import if the module contains 742fe6060f1SDimitry Andric // a non-prevailing def with interposable linkage. The prevailing copy 743fe6060f1SDimitry Andric // can safely be imported (see shouldImportGlobal()). 7440b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "ignored! Target already in destination module.\n"); 7450b57cec5SDimitry Andric continue; 7460b57cec5SDimitry Andric } 7470b57cec5SDimitry Andric 7480b57cec5SDimitry Andric auto GetBonusMultiplier = [](CalleeInfo::HotnessType Hotness) -> float { 7490b57cec5SDimitry Andric if (Hotness == CalleeInfo::HotnessType::Hot) 7500b57cec5SDimitry Andric return ImportHotMultiplier; 7510b57cec5SDimitry Andric if (Hotness == CalleeInfo::HotnessType::Cold) 7520b57cec5SDimitry Andric return ImportColdMultiplier; 7530b57cec5SDimitry Andric if (Hotness == CalleeInfo::HotnessType::Critical) 7540b57cec5SDimitry Andric return ImportCriticalMultiplier; 7550b57cec5SDimitry Andric return 1.0; 7560b57cec5SDimitry Andric }; 7570b57cec5SDimitry Andric 7580b57cec5SDimitry Andric const auto NewThreshold = 7590b57cec5SDimitry Andric Threshold * GetBonusMultiplier(Edge.second.getHotness()); 7600b57cec5SDimitry Andric 7610b57cec5SDimitry Andric auto IT = ImportThresholds.insert(std::make_pair( 7620b57cec5SDimitry Andric VI.getGUID(), std::make_tuple(NewThreshold, nullptr, nullptr))); 7630b57cec5SDimitry Andric bool PreviouslyVisited = !IT.second; 7640b57cec5SDimitry Andric auto &ProcessedThreshold = std::get<0>(IT.first->second); 7650b57cec5SDimitry Andric auto &CalleeSummary = std::get<1>(IT.first->second); 7660b57cec5SDimitry Andric auto &FailureInfo = std::get<2>(IT.first->second); 7670b57cec5SDimitry Andric 7680b57cec5SDimitry Andric bool IsHotCallsite = 7690b57cec5SDimitry Andric Edge.second.getHotness() == CalleeInfo::HotnessType::Hot; 7700b57cec5SDimitry Andric bool IsCriticalCallsite = 7710b57cec5SDimitry Andric Edge.second.getHotness() == CalleeInfo::HotnessType::Critical; 7720b57cec5SDimitry Andric 7730b57cec5SDimitry Andric const FunctionSummary *ResolvedCalleeSummary = nullptr; 7740b57cec5SDimitry Andric if (CalleeSummary) { 7750b57cec5SDimitry Andric assert(PreviouslyVisited); 7760b57cec5SDimitry Andric // Since the traversal of the call graph is DFS, we can revisit a function 7770b57cec5SDimitry Andric // a second time with a higher threshold. In this case, it is added back 7780b57cec5SDimitry Andric // to the worklist with the new threshold (so that its own callee chains 7790b57cec5SDimitry Andric // can be considered with the higher threshold). 7800b57cec5SDimitry Andric if (NewThreshold <= ProcessedThreshold) { 7810b57cec5SDimitry Andric LLVM_DEBUG( 7820b57cec5SDimitry Andric dbgs() << "ignored! Target was already imported with Threshold " 7830b57cec5SDimitry Andric << ProcessedThreshold << "\n"); 7840b57cec5SDimitry Andric continue; 7850b57cec5SDimitry Andric } 7860b57cec5SDimitry Andric // Update with new larger threshold. 7870b57cec5SDimitry Andric ProcessedThreshold = NewThreshold; 7880b57cec5SDimitry Andric ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary); 7890b57cec5SDimitry Andric } else { 7900b57cec5SDimitry Andric // If we already rejected importing a callee at the same or higher 7910b57cec5SDimitry Andric // threshold, don't waste time calling selectCallee. 7920b57cec5SDimitry Andric if (PreviouslyVisited && NewThreshold <= ProcessedThreshold) { 7930b57cec5SDimitry Andric LLVM_DEBUG( 7940b57cec5SDimitry Andric dbgs() << "ignored! Target was already rejected with Threshold " 7950b57cec5SDimitry Andric << ProcessedThreshold << "\n"); 7960b57cec5SDimitry Andric if (PrintImportFailures) { 7970b57cec5SDimitry Andric assert(FailureInfo && 7980b57cec5SDimitry Andric "Expected FailureInfo for previously rejected candidate"); 7990b57cec5SDimitry Andric FailureInfo->Attempts++; 8000b57cec5SDimitry Andric } 8010b57cec5SDimitry Andric continue; 8020b57cec5SDimitry Andric } 8030b57cec5SDimitry Andric 8045f757f3fSDimitry Andric FunctionImporter::ImportFailureReason Reason{}; 805*0fca6ea1SDimitry Andric 806*0fca6ea1SDimitry Andric // `SummaryForDeclImport` is an summary eligible for declaration import. 807*0fca6ea1SDimitry Andric const GlobalValueSummary *SummaryForDeclImport = nullptr; 808*0fca6ea1SDimitry Andric CalleeSummary = 809*0fca6ea1SDimitry Andric selectCallee(Index, VI.getSummaryList(), NewThreshold, 810*0fca6ea1SDimitry Andric Summary.modulePath(), SummaryForDeclImport, Reason); 8110b57cec5SDimitry Andric if (!CalleeSummary) { 812*0fca6ea1SDimitry Andric // There isn't a callee for definition import but one for declaration 813*0fca6ea1SDimitry Andric // import. 814*0fca6ea1SDimitry Andric if (ImportDeclaration && SummaryForDeclImport) { 815*0fca6ea1SDimitry Andric StringRef DeclSourceModule = SummaryForDeclImport->modulePath(); 816*0fca6ea1SDimitry Andric 817*0fca6ea1SDimitry Andric // Since definition takes precedence over declaration for the same VI, 818*0fca6ea1SDimitry Andric // try emplace <VI, declaration> pair without checking insert result. 819*0fca6ea1SDimitry Andric // If insert doesn't happen, there must be an existing entry keyed by 820*0fca6ea1SDimitry Andric // VI. Note `ExportLists` only keeps track of exports due to imported 821*0fca6ea1SDimitry Andric // definitions. 822*0fca6ea1SDimitry Andric ImportList[DeclSourceModule].try_emplace( 823*0fca6ea1SDimitry Andric VI.getGUID(), GlobalValueSummary::Declaration); 824*0fca6ea1SDimitry Andric } 8250b57cec5SDimitry Andric // Update with new larger threshold if this was a retry (otherwise 8260b57cec5SDimitry Andric // we would have already inserted with NewThreshold above). Also 8270b57cec5SDimitry Andric // update failure info if requested. 8280b57cec5SDimitry Andric if (PreviouslyVisited) { 8290b57cec5SDimitry Andric ProcessedThreshold = NewThreshold; 8300b57cec5SDimitry Andric if (PrintImportFailures) { 8310b57cec5SDimitry Andric assert(FailureInfo && 8320b57cec5SDimitry Andric "Expected FailureInfo for previously rejected candidate"); 8330b57cec5SDimitry Andric FailureInfo->Reason = Reason; 8340b57cec5SDimitry Andric FailureInfo->Attempts++; 8350b57cec5SDimitry Andric FailureInfo->MaxHotness = 8360b57cec5SDimitry Andric std::max(FailureInfo->MaxHotness, Edge.second.getHotness()); 8370b57cec5SDimitry Andric } 8380b57cec5SDimitry Andric } else if (PrintImportFailures) { 8390b57cec5SDimitry Andric assert(!FailureInfo && 8400b57cec5SDimitry Andric "Expected no FailureInfo for newly rejected candidate"); 8418bcb0991SDimitry Andric FailureInfo = std::make_unique<FunctionImporter::ImportFailureInfo>( 8420b57cec5SDimitry Andric VI, Edge.second.getHotness(), Reason, 1); 8430b57cec5SDimitry Andric } 844fe6060f1SDimitry Andric if (ForceImportAll) { 845fe6060f1SDimitry Andric std::string Msg = std::string("Failed to import function ") + 846fe6060f1SDimitry Andric VI.name().str() + " due to " + 847fe6060f1SDimitry Andric getFailureName(Reason); 848fe6060f1SDimitry Andric auto Error = make_error<StringError>( 849349cc55cSDimitry Andric Msg, make_error_code(errc::not_supported)); 850fe6060f1SDimitry Andric logAllUnhandledErrors(std::move(Error), errs(), 851fe6060f1SDimitry Andric "Error importing module: "); 852fe6060f1SDimitry Andric break; 853fe6060f1SDimitry Andric } else { 854fe6060f1SDimitry Andric LLVM_DEBUG(dbgs() 855fe6060f1SDimitry Andric << "ignored! No qualifying callee with summary found.\n"); 8560b57cec5SDimitry Andric continue; 8570b57cec5SDimitry Andric } 858fe6060f1SDimitry Andric } 8590b57cec5SDimitry Andric 8600b57cec5SDimitry Andric // "Resolve" the summary 8610b57cec5SDimitry Andric CalleeSummary = CalleeSummary->getBaseObject(); 8620b57cec5SDimitry Andric ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary); 8630b57cec5SDimitry Andric 864fe6060f1SDimitry Andric assert((ResolvedCalleeSummary->fflags().AlwaysInline || ForceImportAll || 865480093f4SDimitry Andric (ResolvedCalleeSummary->instCount() <= NewThreshold)) && 8660b57cec5SDimitry Andric "selectCallee() didn't honor the threshold"); 8670b57cec5SDimitry Andric 8680b57cec5SDimitry Andric auto ExportModulePath = ResolvedCalleeSummary->modulePath(); 869*0fca6ea1SDimitry Andric 870*0fca6ea1SDimitry Andric // Try emplace the definition entry, and update stats based on insertion 871*0fca6ea1SDimitry Andric // status. 872*0fca6ea1SDimitry Andric auto [Iter, Inserted] = ImportList[ExportModulePath].try_emplace( 873*0fca6ea1SDimitry Andric VI.getGUID(), GlobalValueSummary::Definition); 874*0fca6ea1SDimitry Andric 8750b57cec5SDimitry Andric // We previously decided to import this GUID definition if it was already 8760b57cec5SDimitry Andric // inserted in the set of imports from the exporting module. 877*0fca6ea1SDimitry Andric if (Inserted || Iter->second == GlobalValueSummary::Declaration) { 8780b57cec5SDimitry Andric NumImportedFunctionsThinLink++; 8790b57cec5SDimitry Andric if (IsHotCallsite) 8800b57cec5SDimitry Andric NumImportedHotFunctionsThinLink++; 8810b57cec5SDimitry Andric if (IsCriticalCallsite) 8820b57cec5SDimitry Andric NumImportedCriticalFunctionsThinLink++; 8830b57cec5SDimitry Andric } 8840b57cec5SDimitry Andric 885*0fca6ea1SDimitry Andric if (Iter->second == GlobalValueSummary::Declaration) 886*0fca6ea1SDimitry Andric Iter->second = GlobalValueSummary::Definition; 887*0fca6ea1SDimitry Andric 8885ffd83dbSDimitry Andric // Any calls/references made by this function will be marked exported 8895ffd83dbSDimitry Andric // later, in ComputeCrossModuleImport, after import decisions are 8905ffd83dbSDimitry Andric // complete, which is more efficient than adding them here. 8915ffd83dbSDimitry Andric if (ExportLists) 8925ffd83dbSDimitry Andric (*ExportLists)[ExportModulePath].insert(VI); 8930b57cec5SDimitry Andric } 8940b57cec5SDimitry Andric 8950b57cec5SDimitry Andric auto GetAdjustedThreshold = [](unsigned Threshold, bool IsHotCallsite) { 8960b57cec5SDimitry Andric // Adjust the threshold for next level of imported functions. 8970b57cec5SDimitry Andric // The threshold is different for hot callsites because we can then 8980b57cec5SDimitry Andric // inline chains of hot calls. 8990b57cec5SDimitry Andric if (IsHotCallsite) 9000b57cec5SDimitry Andric return Threshold * ImportHotInstrFactor; 9010b57cec5SDimitry Andric return Threshold * ImportInstrFactor; 9020b57cec5SDimitry Andric }; 9030b57cec5SDimitry Andric 9040b57cec5SDimitry Andric const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite); 9050b57cec5SDimitry Andric 9060b57cec5SDimitry Andric ImportCount++; 9070b57cec5SDimitry Andric 9080b57cec5SDimitry Andric // Insert the newly imported function to the worklist. 909e8d8bef9SDimitry Andric Worklist.emplace_back(ResolvedCalleeSummary, AdjThreshold); 9100b57cec5SDimitry Andric } 9110b57cec5SDimitry Andric } 9120b57cec5SDimitry Andric 9135f757f3fSDimitry Andric void ModuleImportsManager::computeImportForModule( 9145f757f3fSDimitry Andric const GVSummaryMapTy &DefinedGVSummaries, StringRef ModName, 9155f757f3fSDimitry Andric FunctionImporter::ImportMapTy &ImportList) { 9160b57cec5SDimitry Andric // Worklist contains the list of function imported in this module, for which 9170b57cec5SDimitry Andric // we will analyse the callees and may import further down the callgraph. 9180b57cec5SDimitry Andric SmallVector<EdgeInfo, 128> Worklist; 9195f757f3fSDimitry Andric GlobalsImporter GVI(Index, DefinedGVSummaries, IsPrevailing, ImportList, 92006c3fb27SDimitry Andric ExportLists); 9210b57cec5SDimitry Andric FunctionImporter::ImportThresholdsTy ImportThresholds; 9220b57cec5SDimitry Andric 9230b57cec5SDimitry Andric // Populate the worklist with the import for the functions in the current 9240b57cec5SDimitry Andric // module 925bdd1243dSDimitry Andric for (const auto &GVSummary : DefinedGVSummaries) { 9260b57cec5SDimitry Andric #ifndef NDEBUG 9270b57cec5SDimitry Andric // FIXME: Change the GVSummaryMapTy to hold ValueInfo instead of GUID 9280b57cec5SDimitry Andric // so this map look up (and possibly others) can be avoided. 9290b57cec5SDimitry Andric auto VI = Index.getValueInfo(GVSummary.first); 9300b57cec5SDimitry Andric #endif 9310b57cec5SDimitry Andric if (!Index.isGlobalValueLive(GVSummary.second)) { 9320b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Ignores Dead GUID: " << VI << "\n"); 9330b57cec5SDimitry Andric continue; 9340b57cec5SDimitry Andric } 9350b57cec5SDimitry Andric auto *FuncSummary = 9360b57cec5SDimitry Andric dyn_cast<FunctionSummary>(GVSummary.second->getBaseObject()); 9370b57cec5SDimitry Andric if (!FuncSummary) 9380b57cec5SDimitry Andric // Skip import for global variables 9390b57cec5SDimitry Andric continue; 9400b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Initialize import for " << VI << "\n"); 9410b57cec5SDimitry Andric computeImportForFunction(*FuncSummary, Index, ImportInstrLimit, 9425f757f3fSDimitry Andric DefinedGVSummaries, IsPrevailing, Worklist, GVI, 94306c3fb27SDimitry Andric ImportList, ExportLists, ImportThresholds); 9440b57cec5SDimitry Andric } 9450b57cec5SDimitry Andric 9460b57cec5SDimitry Andric // Process the newly imported functions and add callees to the worklist. 9470b57cec5SDimitry Andric while (!Worklist.empty()) { 948e8d8bef9SDimitry Andric auto GVInfo = Worklist.pop_back_val(); 949e8d8bef9SDimitry Andric auto *Summary = std::get<0>(GVInfo); 950e8d8bef9SDimitry Andric auto Threshold = std::get<1>(GVInfo); 9510b57cec5SDimitry Andric 952e8d8bef9SDimitry Andric if (auto *FS = dyn_cast<FunctionSummary>(Summary)) 953e8d8bef9SDimitry Andric computeImportForFunction(*FS, Index, Threshold, DefinedGVSummaries, 9545f757f3fSDimitry Andric IsPrevailing, Worklist, GVI, ImportList, 95506c3fb27SDimitry Andric ExportLists, ImportThresholds); 9560b57cec5SDimitry Andric } 9570b57cec5SDimitry Andric 9580b57cec5SDimitry Andric // Print stats about functions considered but rejected for importing 9590b57cec5SDimitry Andric // when requested. 9600b57cec5SDimitry Andric if (PrintImportFailures) { 9610b57cec5SDimitry Andric dbgs() << "Missed imports into module " << ModName << "\n"; 9620b57cec5SDimitry Andric for (auto &I : ImportThresholds) { 9630b57cec5SDimitry Andric auto &ProcessedThreshold = std::get<0>(I.second); 9640b57cec5SDimitry Andric auto &CalleeSummary = std::get<1>(I.second); 9650b57cec5SDimitry Andric auto &FailureInfo = std::get<2>(I.second); 9660b57cec5SDimitry Andric if (CalleeSummary) 9670b57cec5SDimitry Andric continue; // We are going to import. 9680b57cec5SDimitry Andric assert(FailureInfo); 9690b57cec5SDimitry Andric FunctionSummary *FS = nullptr; 9700b57cec5SDimitry Andric if (!FailureInfo->VI.getSummaryList().empty()) 9710b57cec5SDimitry Andric FS = dyn_cast<FunctionSummary>( 9720b57cec5SDimitry Andric FailureInfo->VI.getSummaryList()[0]->getBaseObject()); 9730b57cec5SDimitry Andric dbgs() << FailureInfo->VI 9740b57cec5SDimitry Andric << ": Reason = " << getFailureName(FailureInfo->Reason) 9750b57cec5SDimitry Andric << ", Threshold = " << ProcessedThreshold 9760b57cec5SDimitry Andric << ", Size = " << (FS ? (int)FS->instCount() : -1) 9770b57cec5SDimitry Andric << ", MaxHotness = " << getHotnessName(FailureInfo->MaxHotness) 9780b57cec5SDimitry Andric << ", Attempts = " << FailureInfo->Attempts << "\n"; 9790b57cec5SDimitry Andric } 9800b57cec5SDimitry Andric } 9810b57cec5SDimitry Andric } 9820b57cec5SDimitry Andric 9830b57cec5SDimitry Andric #ifndef NDEBUG 984480093f4SDimitry Andric static bool isGlobalVarSummary(const ModuleSummaryIndex &Index, ValueInfo VI) { 9850b57cec5SDimitry Andric auto SL = VI.getSummaryList(); 986480093f4SDimitry Andric return SL.empty() 987480093f4SDimitry Andric ? false 988480093f4SDimitry Andric : SL[0]->getSummaryKind() == GlobalValueSummary::GlobalVarKind; 9890b57cec5SDimitry Andric } 9900b57cec5SDimitry Andric 991480093f4SDimitry Andric static bool isGlobalVarSummary(const ModuleSummaryIndex &Index, 992480093f4SDimitry Andric GlobalValue::GUID G) { 993480093f4SDimitry Andric if (const auto &VI = Index.getValueInfo(G)) 994480093f4SDimitry Andric return isGlobalVarSummary(Index, VI); 995480093f4SDimitry Andric return false; 996480093f4SDimitry Andric } 9970b57cec5SDimitry Andric 998*0fca6ea1SDimitry Andric // Return the number of global variable summaries in ExportSet. 999*0fca6ea1SDimitry Andric static unsigned 1000*0fca6ea1SDimitry Andric numGlobalVarSummaries(const ModuleSummaryIndex &Index, 1001*0fca6ea1SDimitry Andric FunctionImporter::ExportSetTy &ExportSet) { 10020b57cec5SDimitry Andric unsigned NumGVS = 0; 1003*0fca6ea1SDimitry Andric for (auto &VI : ExportSet) 1004*0fca6ea1SDimitry Andric if (isGlobalVarSummary(Index, VI.getGUID())) 10050b57cec5SDimitry Andric ++NumGVS; 10060b57cec5SDimitry Andric return NumGVS; 10070b57cec5SDimitry Andric } 1008*0fca6ea1SDimitry Andric 1009*0fca6ea1SDimitry Andric // Given ImportMap, return the number of global variable summaries and record 1010*0fca6ea1SDimitry Andric // the number of defined function summaries as output parameter. 1011*0fca6ea1SDimitry Andric static unsigned 1012*0fca6ea1SDimitry Andric numGlobalVarSummaries(const ModuleSummaryIndex &Index, 1013*0fca6ea1SDimitry Andric FunctionImporter::FunctionsToImportTy &ImportMap, 1014*0fca6ea1SDimitry Andric unsigned &DefinedFS) { 1015*0fca6ea1SDimitry Andric unsigned NumGVS = 0; 1016*0fca6ea1SDimitry Andric DefinedFS = 0; 1017*0fca6ea1SDimitry Andric for (auto &[GUID, Type] : ImportMap) { 1018*0fca6ea1SDimitry Andric if (isGlobalVarSummary(Index, GUID)) 1019*0fca6ea1SDimitry Andric ++NumGVS; 1020*0fca6ea1SDimitry Andric else if (Type == GlobalValueSummary::Definition) 1021*0fca6ea1SDimitry Andric ++DefinedFS; 1022*0fca6ea1SDimitry Andric } 1023*0fca6ea1SDimitry Andric return NumGVS; 1024*0fca6ea1SDimitry Andric } 10250b57cec5SDimitry Andric #endif 10260b57cec5SDimitry Andric 1027480093f4SDimitry Andric #ifndef NDEBUG 10285f757f3fSDimitry Andric static bool checkVariableImport( 10295f757f3fSDimitry Andric const ModuleSummaryIndex &Index, 10305f757f3fSDimitry Andric DenseMap<StringRef, FunctionImporter::ImportMapTy> &ImportLists, 10315f757f3fSDimitry Andric DenseMap<StringRef, FunctionImporter::ExportSetTy> &ExportLists) { 1032480093f4SDimitry Andric DenseSet<GlobalValue::GUID> FlattenedImports; 1033480093f4SDimitry Andric 1034480093f4SDimitry Andric for (auto &ImportPerModule : ImportLists) 1035480093f4SDimitry Andric for (auto &ExportPerModule : ImportPerModule.second) 1036*0fca6ea1SDimitry Andric for (auto &[GUID, Type] : ExportPerModule.second) 1037*0fca6ea1SDimitry Andric FlattenedImports.insert(GUID); 1038480093f4SDimitry Andric 1039480093f4SDimitry Andric // Checks that all GUIDs of read/writeonly vars we see in export lists 1040480093f4SDimitry Andric // are also in the import lists. Otherwise we my face linker undefs, 1041480093f4SDimitry Andric // because readonly and writeonly vars are internalized in their 104206c3fb27SDimitry Andric // source modules. The exception would be if it has a linkage type indicating 104306c3fb27SDimitry Andric // that there may have been a copy existing in the importing module (e.g. 104406c3fb27SDimitry Andric // linkonce_odr). In that case we cannot accurately do this checking. 104506c3fb27SDimitry Andric auto IsReadOrWriteOnlyVarNeedingImporting = [&](StringRef ModulePath, 104606c3fb27SDimitry Andric const ValueInfo &VI) { 1047480093f4SDimitry Andric auto *GVS = dyn_cast_or_null<GlobalVarSummary>( 1048480093f4SDimitry Andric Index.findSummaryInModule(VI, ModulePath)); 104906c3fb27SDimitry Andric return GVS && (Index.isReadOnly(GVS) || Index.isWriteOnly(GVS)) && 105006c3fb27SDimitry Andric !(GVS->linkage() == GlobalValue::AvailableExternallyLinkage || 105106c3fb27SDimitry Andric GVS->linkage() == GlobalValue::WeakODRLinkage || 105206c3fb27SDimitry Andric GVS->linkage() == GlobalValue::LinkOnceODRLinkage); 1053480093f4SDimitry Andric }; 1054480093f4SDimitry Andric 1055480093f4SDimitry Andric for (auto &ExportPerModule : ExportLists) 1056480093f4SDimitry Andric for (auto &VI : ExportPerModule.second) 1057480093f4SDimitry Andric if (!FlattenedImports.count(VI.getGUID()) && 10585f757f3fSDimitry Andric IsReadOrWriteOnlyVarNeedingImporting(ExportPerModule.first, VI)) 1059480093f4SDimitry Andric return false; 1060480093f4SDimitry Andric 1061480093f4SDimitry Andric return true; 1062480093f4SDimitry Andric } 1063480093f4SDimitry Andric #endif 1064480093f4SDimitry Andric 10650b57cec5SDimitry Andric /// Compute all the import and export for every module using the Index. 10660b57cec5SDimitry Andric void llvm::ComputeCrossModuleImport( 10670b57cec5SDimitry Andric const ModuleSummaryIndex &Index, 10685f757f3fSDimitry Andric const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries, 106906c3fb27SDimitry Andric function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 107006c3fb27SDimitry Andric isPrevailing, 10715f757f3fSDimitry Andric DenseMap<StringRef, FunctionImporter::ImportMapTy> &ImportLists, 10725f757f3fSDimitry Andric DenseMap<StringRef, FunctionImporter::ExportSetTy> &ExportLists) { 10735f757f3fSDimitry Andric auto MIS = ModuleImportsManager::create(isPrevailing, Index, &ExportLists); 10740b57cec5SDimitry Andric // For each module that has function defined, compute the import/export lists. 1075bdd1243dSDimitry Andric for (const auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) { 10765f757f3fSDimitry Andric auto &ImportList = ImportLists[DefinedGVSummaries.first]; 10770b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Computing import for Module '" 10785f757f3fSDimitry Andric << DefinedGVSummaries.first << "'\n"); 10795f757f3fSDimitry Andric MIS->computeImportForModule(DefinedGVSummaries.second, 10805f757f3fSDimitry Andric DefinedGVSummaries.first, ImportList); 10810b57cec5SDimitry Andric } 10820b57cec5SDimitry Andric 10835ffd83dbSDimitry Andric // When computing imports we only added the variables and functions being 10845ffd83dbSDimitry Andric // imported to the export list. We also need to mark any references and calls 10855ffd83dbSDimitry Andric // they make as exported as well. We do this here, as it is more efficient 10865ffd83dbSDimitry Andric // since we may import the same values multiple times into different modules 10875ffd83dbSDimitry Andric // during the import computation. 10880b57cec5SDimitry Andric for (auto &ELI : ExportLists) { 1089*0fca6ea1SDimitry Andric // `NewExports` tracks the VI that gets exported because the full definition 1090*0fca6ea1SDimitry Andric // of its user/referencer gets exported. 10915ffd83dbSDimitry Andric FunctionImporter::ExportSetTy NewExports; 10920b57cec5SDimitry Andric const auto &DefinedGVSummaries = 10935f757f3fSDimitry Andric ModuleToDefinedGVSummaries.lookup(ELI.first); 10945ffd83dbSDimitry Andric for (auto &EI : ELI.second) { 10955ffd83dbSDimitry Andric // Find the copy defined in the exporting module so that we can mark the 10965ffd83dbSDimitry Andric // values it references in that specific definition as exported. 10975ffd83dbSDimitry Andric // Below we will add all references and called values, without regard to 10985ffd83dbSDimitry Andric // whether they are also defined in this module. We subsequently prune the 10995ffd83dbSDimitry Andric // list to only include those defined in the exporting module, see comment 11005ffd83dbSDimitry Andric // there as to why. 11015ffd83dbSDimitry Andric auto DS = DefinedGVSummaries.find(EI.getGUID()); 11025ffd83dbSDimitry Andric // Anything marked exported during the import computation must have been 11035ffd83dbSDimitry Andric // defined in the exporting module. 11045ffd83dbSDimitry Andric assert(DS != DefinedGVSummaries.end()); 11055ffd83dbSDimitry Andric auto *S = DS->getSecond(); 11065ffd83dbSDimitry Andric S = S->getBaseObject(); 11075ffd83dbSDimitry Andric if (auto *GVS = dyn_cast<GlobalVarSummary>(S)) { 11085ffd83dbSDimitry Andric // Export referenced functions and variables. We don't export/promote 11095ffd83dbSDimitry Andric // objects referenced by writeonly variable initializer, because 11105ffd83dbSDimitry Andric // we convert such variables initializers to "zeroinitializer". 11115ffd83dbSDimitry Andric // See processGlobalForThinLTO. 11125ffd83dbSDimitry Andric if (!Index.isWriteOnly(GVS)) 11135ffd83dbSDimitry Andric for (const auto &VI : GVS->refs()) 11145ffd83dbSDimitry Andric NewExports.insert(VI); 11155ffd83dbSDimitry Andric } else { 11165ffd83dbSDimitry Andric auto *FS = cast<FunctionSummary>(S); 1117bdd1243dSDimitry Andric for (const auto &Edge : FS->calls()) 11185ffd83dbSDimitry Andric NewExports.insert(Edge.first); 1119bdd1243dSDimitry Andric for (const auto &Ref : FS->refs()) 11205ffd83dbSDimitry Andric NewExports.insert(Ref); 11215ffd83dbSDimitry Andric } 11225ffd83dbSDimitry Andric } 1123*0fca6ea1SDimitry Andric // Prune list computed above to only include values defined in the 1124*0fca6ea1SDimitry Andric // exporting module. We do this after the above insertion since we may hit 1125*0fca6ea1SDimitry Andric // the same ref/call target multiple times in above loop, and it is more 1126*0fca6ea1SDimitry Andric // efficient to avoid a set lookup each time. 11275ffd83dbSDimitry Andric for (auto EI = NewExports.begin(); EI != NewExports.end();) { 1128480093f4SDimitry Andric if (!DefinedGVSummaries.count(EI->getGUID())) 11295ffd83dbSDimitry Andric NewExports.erase(EI++); 11300b57cec5SDimitry Andric else 11310b57cec5SDimitry Andric ++EI; 11320b57cec5SDimitry Andric } 11335ffd83dbSDimitry Andric ELI.second.insert(NewExports.begin(), NewExports.end()); 11340b57cec5SDimitry Andric } 11350b57cec5SDimitry Andric 1136480093f4SDimitry Andric assert(checkVariableImport(Index, ImportLists, ExportLists)); 11370b57cec5SDimitry Andric #ifndef NDEBUG 11380b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Import/Export lists for " << ImportLists.size() 11390b57cec5SDimitry Andric << " modules:\n"); 11400b57cec5SDimitry Andric for (auto &ModuleImports : ImportLists) { 11415f757f3fSDimitry Andric auto ModName = ModuleImports.first; 11420b57cec5SDimitry Andric auto &Exports = ExportLists[ModName]; 11430b57cec5SDimitry Andric unsigned NumGVS = numGlobalVarSummaries(Index, Exports); 11440b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "* Module " << ModName << " exports " 11450b57cec5SDimitry Andric << Exports.size() - NumGVS << " functions and " << NumGVS 11460b57cec5SDimitry Andric << " vars. Imports from " << ModuleImports.second.size() 11470b57cec5SDimitry Andric << " modules.\n"); 11480b57cec5SDimitry Andric for (auto &Src : ModuleImports.second) { 11495f757f3fSDimitry Andric auto SrcModName = Src.first; 1150*0fca6ea1SDimitry Andric unsigned DefinedFS = 0; 1151*0fca6ea1SDimitry Andric unsigned NumGVSPerMod = 1152*0fca6ea1SDimitry Andric numGlobalVarSummaries(Index, Src.second, DefinedFS); 1153*0fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << " - " << DefinedFS << " function definitions and " 1154*0fca6ea1SDimitry Andric << Src.second.size() - NumGVSPerMod - DefinedFS 1155*0fca6ea1SDimitry Andric << " function declarations imported from " << SrcModName 1156*0fca6ea1SDimitry Andric << "\n"); 11570b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " - " << NumGVSPerMod 11580b57cec5SDimitry Andric << " global vars imported from " << SrcModName << "\n"); 11590b57cec5SDimitry Andric } 11600b57cec5SDimitry Andric } 11610b57cec5SDimitry Andric #endif 11620b57cec5SDimitry Andric } 11630b57cec5SDimitry Andric 11640b57cec5SDimitry Andric #ifndef NDEBUG 11650b57cec5SDimitry Andric static void dumpImportListForModule(const ModuleSummaryIndex &Index, 11660b57cec5SDimitry Andric StringRef ModulePath, 11670b57cec5SDimitry Andric FunctionImporter::ImportMapTy &ImportList) { 11680b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "* Module " << ModulePath << " imports from " 11690b57cec5SDimitry Andric << ImportList.size() << " modules.\n"); 11700b57cec5SDimitry Andric for (auto &Src : ImportList) { 11715f757f3fSDimitry Andric auto SrcModName = Src.first; 1172*0fca6ea1SDimitry Andric unsigned DefinedFS = 0; 1173*0fca6ea1SDimitry Andric unsigned NumGVSPerMod = numGlobalVarSummaries(Index, Src.second, DefinedFS); 1174*0fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << " - " << DefinedFS << " function definitions and " 1175*0fca6ea1SDimitry Andric << Src.second.size() - DefinedFS - NumGVSPerMod 1176*0fca6ea1SDimitry Andric << " function declarations imported from " << SrcModName 1177*0fca6ea1SDimitry Andric << "\n"); 11780b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " - " << NumGVSPerMod << " vars imported from " 11790b57cec5SDimitry Andric << SrcModName << "\n"); 11800b57cec5SDimitry Andric } 11810b57cec5SDimitry Andric } 11820b57cec5SDimitry Andric #endif 11830b57cec5SDimitry Andric 11845f757f3fSDimitry Andric /// Compute all the imports for the given module using the Index. 11855f757f3fSDimitry Andric /// 11865f757f3fSDimitry Andric /// \p isPrevailing is a callback that will be called with a global value's GUID 11875f757f3fSDimitry Andric /// and summary and should return whether the module corresponding to the 11885f757f3fSDimitry Andric /// summary contains the linker-prevailing copy of that value. 11895f757f3fSDimitry Andric /// 11905f757f3fSDimitry Andric /// \p ImportList will be populated with a map that can be passed to 11915f757f3fSDimitry Andric /// FunctionImporter::importFunctions() above (see description there). 11925f757f3fSDimitry Andric static void ComputeCrossModuleImportForModuleForTest( 119306c3fb27SDimitry Andric StringRef ModulePath, 119406c3fb27SDimitry Andric function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 119506c3fb27SDimitry Andric isPrevailing, 119606c3fb27SDimitry Andric const ModuleSummaryIndex &Index, 11970b57cec5SDimitry Andric FunctionImporter::ImportMapTy &ImportList) { 11980b57cec5SDimitry Andric // Collect the list of functions this module defines. 11990b57cec5SDimitry Andric // GUID -> Summary 12000b57cec5SDimitry Andric GVSummaryMapTy FunctionSummaryMap; 12010b57cec5SDimitry Andric Index.collectDefinedFunctionsForModule(ModulePath, FunctionSummaryMap); 12020b57cec5SDimitry Andric 12030b57cec5SDimitry Andric // Compute the import list for this module. 12040b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Computing import for Module '" << ModulePath << "'\n"); 12055f757f3fSDimitry Andric auto MIS = ModuleImportsManager::create(isPrevailing, Index); 12065f757f3fSDimitry Andric MIS->computeImportForModule(FunctionSummaryMap, ModulePath, ImportList); 12070b57cec5SDimitry Andric 12080b57cec5SDimitry Andric #ifndef NDEBUG 12090b57cec5SDimitry Andric dumpImportListForModule(Index, ModulePath, ImportList); 12100b57cec5SDimitry Andric #endif 12110b57cec5SDimitry Andric } 12120b57cec5SDimitry Andric 12135f757f3fSDimitry Andric /// Mark all external summaries in \p Index for import into the given module. 12145f757f3fSDimitry Andric /// Used for testing the case of distributed builds using a distributed index. 12155f757f3fSDimitry Andric /// 12165f757f3fSDimitry Andric /// \p ImportList will be populated with a map that can be passed to 12175f757f3fSDimitry Andric /// FunctionImporter::importFunctions() above (see description there). 12185f757f3fSDimitry Andric static void ComputeCrossModuleImportForModuleFromIndexForTest( 12190b57cec5SDimitry Andric StringRef ModulePath, const ModuleSummaryIndex &Index, 12200b57cec5SDimitry Andric FunctionImporter::ImportMapTy &ImportList) { 1221bdd1243dSDimitry Andric for (const auto &GlobalList : Index) { 12220b57cec5SDimitry Andric // Ignore entries for undefined references. 12230b57cec5SDimitry Andric if (GlobalList.second.SummaryList.empty()) 12240b57cec5SDimitry Andric continue; 12250b57cec5SDimitry Andric 12260b57cec5SDimitry Andric auto GUID = GlobalList.first; 12270b57cec5SDimitry Andric assert(GlobalList.second.SummaryList.size() == 1 && 12280b57cec5SDimitry Andric "Expected individual combined index to have one summary per GUID"); 12290b57cec5SDimitry Andric auto &Summary = GlobalList.second.SummaryList[0]; 12300b57cec5SDimitry Andric // Skip the summaries for the importing module. These are included to 12310b57cec5SDimitry Andric // e.g. record required linkage changes. 12320b57cec5SDimitry Andric if (Summary->modulePath() == ModulePath) 12330b57cec5SDimitry Andric continue; 12340b57cec5SDimitry Andric // Add an entry to provoke importing by thinBackend. 1235*0fca6ea1SDimitry Andric auto [Iter, Inserted] = ImportList[Summary->modulePath()].try_emplace( 1236*0fca6ea1SDimitry Andric GUID, Summary->importType()); 1237*0fca6ea1SDimitry Andric if (!Inserted) { 1238*0fca6ea1SDimitry Andric // Use 'std::min' to make sure definition (with enum value 0) takes 1239*0fca6ea1SDimitry Andric // precedence over declaration (with enum value 1). 1240*0fca6ea1SDimitry Andric Iter->second = std::min(Iter->second, Summary->importType()); 1241*0fca6ea1SDimitry Andric } 12420b57cec5SDimitry Andric } 12430b57cec5SDimitry Andric #ifndef NDEBUG 12440b57cec5SDimitry Andric dumpImportListForModule(Index, ModulePath, ImportList); 12450b57cec5SDimitry Andric #endif 12460b57cec5SDimitry Andric } 12470b57cec5SDimitry Andric 1248349cc55cSDimitry Andric // For SamplePGO, the indirect call targets for local functions will 1249349cc55cSDimitry Andric // have its original name annotated in profile. We try to find the 1250349cc55cSDimitry Andric // corresponding PGOFuncName as the GUID, and fix up the edges 1251349cc55cSDimitry Andric // accordingly. 1252349cc55cSDimitry Andric void updateValueInfoForIndirectCalls(ModuleSummaryIndex &Index, 1253349cc55cSDimitry Andric FunctionSummary *FS) { 1254349cc55cSDimitry Andric for (auto &EI : FS->mutableCalls()) { 1255349cc55cSDimitry Andric if (!EI.first.getSummaryList().empty()) 1256349cc55cSDimitry Andric continue; 1257349cc55cSDimitry Andric auto GUID = Index.getGUIDFromOriginalID(EI.first.getGUID()); 1258349cc55cSDimitry Andric if (GUID == 0) 1259349cc55cSDimitry Andric continue; 1260349cc55cSDimitry Andric // Update the edge to point directly to the correct GUID. 1261349cc55cSDimitry Andric auto VI = Index.getValueInfo(GUID); 1262349cc55cSDimitry Andric if (llvm::any_of( 1263349cc55cSDimitry Andric VI.getSummaryList(), 1264349cc55cSDimitry Andric [&](const std::unique_ptr<GlobalValueSummary> &SummaryPtr) { 1265349cc55cSDimitry Andric // The mapping from OriginalId to GUID may return a GUID 1266349cc55cSDimitry Andric // that corresponds to a static variable. Filter it out here. 1267349cc55cSDimitry Andric // This can happen when 1268349cc55cSDimitry Andric // 1) There is a call to a library function which is not defined 1269349cc55cSDimitry Andric // in the index. 1270349cc55cSDimitry Andric // 2) There is a static variable with the OriginalGUID identical 1271349cc55cSDimitry Andric // to the GUID of the library function in 1); 1272349cc55cSDimitry Andric // When this happens the static variable in 2) will be found, 1273349cc55cSDimitry Andric // which needs to be filtered out. 1274349cc55cSDimitry Andric return SummaryPtr->getSummaryKind() == 1275349cc55cSDimitry Andric GlobalValueSummary::GlobalVarKind; 1276349cc55cSDimitry Andric })) 1277349cc55cSDimitry Andric continue; 1278349cc55cSDimitry Andric EI.first = VI; 1279349cc55cSDimitry Andric } 1280349cc55cSDimitry Andric } 1281349cc55cSDimitry Andric 1282349cc55cSDimitry Andric void llvm::updateIndirectCalls(ModuleSummaryIndex &Index) { 1283349cc55cSDimitry Andric for (const auto &Entry : Index) { 1284bdd1243dSDimitry Andric for (const auto &S : Entry.second.SummaryList) { 1285349cc55cSDimitry Andric if (auto *FS = dyn_cast<FunctionSummary>(S.get())) 1286349cc55cSDimitry Andric updateValueInfoForIndirectCalls(Index, FS); 1287349cc55cSDimitry Andric } 1288349cc55cSDimitry Andric } 1289349cc55cSDimitry Andric } 1290349cc55cSDimitry Andric 1291349cc55cSDimitry Andric void llvm::computeDeadSymbolsAndUpdateIndirectCalls( 12920b57cec5SDimitry Andric ModuleSummaryIndex &Index, 12930b57cec5SDimitry Andric const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols, 12940b57cec5SDimitry Andric function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing) { 12950b57cec5SDimitry Andric assert(!Index.withGlobalValueDeadStripping()); 1296349cc55cSDimitry Andric if (!ComputeDead || 12970b57cec5SDimitry Andric // Don't do anything when nothing is live, this is friendly with tests. 1298349cc55cSDimitry Andric GUIDPreservedSymbols.empty()) { 1299349cc55cSDimitry Andric // Still need to update indirect calls. 1300349cc55cSDimitry Andric updateIndirectCalls(Index); 13010b57cec5SDimitry Andric return; 1302349cc55cSDimitry Andric } 13030b57cec5SDimitry Andric unsigned LiveSymbols = 0; 13040b57cec5SDimitry Andric SmallVector<ValueInfo, 128> Worklist; 13050b57cec5SDimitry Andric Worklist.reserve(GUIDPreservedSymbols.size() * 2); 13060b57cec5SDimitry Andric for (auto GUID : GUIDPreservedSymbols) { 13070b57cec5SDimitry Andric ValueInfo VI = Index.getValueInfo(GUID); 13080b57cec5SDimitry Andric if (!VI) 13090b57cec5SDimitry Andric continue; 1310bdd1243dSDimitry Andric for (const auto &S : VI.getSummaryList()) 13110b57cec5SDimitry Andric S->setLive(true); 13120b57cec5SDimitry Andric } 13130b57cec5SDimitry Andric 13140b57cec5SDimitry Andric // Add values flagged in the index as live roots to the worklist. 13150b57cec5SDimitry Andric for (const auto &Entry : Index) { 13160b57cec5SDimitry Andric auto VI = Index.getValueInfo(Entry); 1317bdd1243dSDimitry Andric for (const auto &S : Entry.second.SummaryList) { 1318349cc55cSDimitry Andric if (auto *FS = dyn_cast<FunctionSummary>(S.get())) 1319349cc55cSDimitry Andric updateValueInfoForIndirectCalls(Index, FS); 13200b57cec5SDimitry Andric if (S->isLive()) { 13210b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Live root: " << VI << "\n"); 13220b57cec5SDimitry Andric Worklist.push_back(VI); 13230b57cec5SDimitry Andric ++LiveSymbols; 13240b57cec5SDimitry Andric break; 13250b57cec5SDimitry Andric } 13260b57cec5SDimitry Andric } 1327349cc55cSDimitry Andric } 13280b57cec5SDimitry Andric 13290b57cec5SDimitry Andric // Make value live and add it to the worklist if it was not live before. 13308bcb0991SDimitry Andric auto visit = [&](ValueInfo VI, bool IsAliasee) { 13310b57cec5SDimitry Andric // FIXME: If we knew which edges were created for indirect call profiles, 13320b57cec5SDimitry Andric // we could skip them here. Any that are live should be reached via 13330b57cec5SDimitry Andric // other edges, e.g. reference edges. Otherwise, using a profile collected 13340b57cec5SDimitry Andric // on a slightly different binary might provoke preserving, importing 13350b57cec5SDimitry Andric // and ultimately promoting calls to functions not linked into this 13360b57cec5SDimitry Andric // binary, which increases the binary size unnecessarily. Note that 13370b57cec5SDimitry Andric // if this code changes, the importer needs to change so that edges 13380b57cec5SDimitry Andric // to functions marked dead are skipped. 13390b57cec5SDimitry Andric 13400b57cec5SDimitry Andric if (llvm::any_of(VI.getSummaryList(), 13410b57cec5SDimitry Andric [](const std::unique_ptr<llvm::GlobalValueSummary> &S) { 13420b57cec5SDimitry Andric return S->isLive(); 13430b57cec5SDimitry Andric })) 13440b57cec5SDimitry Andric return; 13450b57cec5SDimitry Andric 13460b57cec5SDimitry Andric // We only keep live symbols that are known to be non-prevailing if any are 13470b57cec5SDimitry Andric // available_externally, linkonceodr, weakodr. Those symbols are discarded 13480b57cec5SDimitry Andric // later in the EliminateAvailableExternally pass and setting them to 13490b57cec5SDimitry Andric // not-live could break downstreams users of liveness information (PR36483) 13500b57cec5SDimitry Andric // or limit optimization opportunities. 13510b57cec5SDimitry Andric if (isPrevailing(VI.getGUID()) == PrevailingType::No) { 13520b57cec5SDimitry Andric bool KeepAliveLinkage = false; 13530b57cec5SDimitry Andric bool Interposable = false; 1354bdd1243dSDimitry Andric for (const auto &S : VI.getSummaryList()) { 13550b57cec5SDimitry Andric if (S->linkage() == GlobalValue::AvailableExternallyLinkage || 13560b57cec5SDimitry Andric S->linkage() == GlobalValue::WeakODRLinkage || 13570b57cec5SDimitry Andric S->linkage() == GlobalValue::LinkOnceODRLinkage) 13580b57cec5SDimitry Andric KeepAliveLinkage = true; 13590b57cec5SDimitry Andric else if (GlobalValue::isInterposableLinkage(S->linkage())) 13600b57cec5SDimitry Andric Interposable = true; 13610b57cec5SDimitry Andric } 13620b57cec5SDimitry Andric 13638bcb0991SDimitry Andric if (!IsAliasee) { 13640b57cec5SDimitry Andric if (!KeepAliveLinkage) 13650b57cec5SDimitry Andric return; 13660b57cec5SDimitry Andric 13670b57cec5SDimitry Andric if (Interposable) 13680b57cec5SDimitry Andric report_fatal_error( 13698bcb0991SDimitry Andric "Interposable and available_externally/linkonce_odr/weak_odr " 13708bcb0991SDimitry Andric "symbol"); 13718bcb0991SDimitry Andric } 13720b57cec5SDimitry Andric } 13730b57cec5SDimitry Andric 1374bdd1243dSDimitry Andric for (const auto &S : VI.getSummaryList()) 13750b57cec5SDimitry Andric S->setLive(true); 13760b57cec5SDimitry Andric ++LiveSymbols; 13770b57cec5SDimitry Andric Worklist.push_back(VI); 13780b57cec5SDimitry Andric }; 13790b57cec5SDimitry Andric 13800b57cec5SDimitry Andric while (!Worklist.empty()) { 13810b57cec5SDimitry Andric auto VI = Worklist.pop_back_val(); 1382bdd1243dSDimitry Andric for (const auto &Summary : VI.getSummaryList()) { 13830b57cec5SDimitry Andric if (auto *AS = dyn_cast<AliasSummary>(Summary.get())) { 13840b57cec5SDimitry Andric // If this is an alias, visit the aliasee VI to ensure that all copies 13850b57cec5SDimitry Andric // are marked live and it is added to the worklist for further 13860b57cec5SDimitry Andric // processing of its references. 13878bcb0991SDimitry Andric visit(AS->getAliaseeVI(), true); 13880b57cec5SDimitry Andric continue; 13890b57cec5SDimitry Andric } 13900b57cec5SDimitry Andric for (auto Ref : Summary->refs()) 13918bcb0991SDimitry Andric visit(Ref, false); 13920b57cec5SDimitry Andric if (auto *FS = dyn_cast<FunctionSummary>(Summary.get())) 13930b57cec5SDimitry Andric for (auto Call : FS->calls()) 13948bcb0991SDimitry Andric visit(Call.first, false); 13950b57cec5SDimitry Andric } 13960b57cec5SDimitry Andric } 13970b57cec5SDimitry Andric Index.setWithGlobalValueDeadStripping(); 13980b57cec5SDimitry Andric 13990b57cec5SDimitry Andric unsigned DeadSymbols = Index.size() - LiveSymbols; 14000b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << LiveSymbols << " symbols Live, and " << DeadSymbols 14010b57cec5SDimitry Andric << " symbols Dead \n"); 14020b57cec5SDimitry Andric NumDeadSymbols += DeadSymbols; 14030b57cec5SDimitry Andric NumLiveSymbols += LiveSymbols; 14040b57cec5SDimitry Andric } 14050b57cec5SDimitry Andric 14060b57cec5SDimitry Andric // Compute dead symbols and propagate constants in combined index. 14070b57cec5SDimitry Andric void llvm::computeDeadSymbolsWithConstProp( 14080b57cec5SDimitry Andric ModuleSummaryIndex &Index, 14090b57cec5SDimitry Andric const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols, 14100b57cec5SDimitry Andric function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing, 14110b57cec5SDimitry Andric bool ImportEnabled) { 1412349cc55cSDimitry Andric computeDeadSymbolsAndUpdateIndirectCalls(Index, GUIDPreservedSymbols, 1413349cc55cSDimitry Andric isPrevailing); 1414480093f4SDimitry Andric if (ImportEnabled) 14150b57cec5SDimitry Andric Index.propagateAttributes(GUIDPreservedSymbols); 14160b57cec5SDimitry Andric } 14170b57cec5SDimitry Andric 14180b57cec5SDimitry Andric /// Compute the set of summaries needed for a ThinLTO backend compilation of 14190b57cec5SDimitry Andric /// \p ModulePath. 14200b57cec5SDimitry Andric void llvm::gatherImportedSummariesForModule( 14210b57cec5SDimitry Andric StringRef ModulePath, 14225f757f3fSDimitry Andric const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries, 14230b57cec5SDimitry Andric const FunctionImporter::ImportMapTy &ImportList, 1424*0fca6ea1SDimitry Andric std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex, 1425*0fca6ea1SDimitry Andric GVSummaryPtrSet &DecSummaries) { 14260b57cec5SDimitry Andric // Include all summaries from the importing module. 14275ffd83dbSDimitry Andric ModuleToSummariesForIndex[std::string(ModulePath)] = 14280b57cec5SDimitry Andric ModuleToDefinedGVSummaries.lookup(ModulePath); 14290b57cec5SDimitry Andric // Include summaries for imports. 1430bdd1243dSDimitry Andric for (const auto &ILI : ImportList) { 14315f757f3fSDimitry Andric auto &SummariesForIndex = ModuleToSummariesForIndex[std::string(ILI.first)]; 1432*0fca6ea1SDimitry Andric 14330b57cec5SDimitry Andric const auto &DefinedGVSummaries = 14345f757f3fSDimitry Andric ModuleToDefinedGVSummaries.lookup(ILI.first); 1435*0fca6ea1SDimitry Andric for (const auto &[GUID, Type] : ILI.second) { 1436*0fca6ea1SDimitry Andric const auto &DS = DefinedGVSummaries.find(GUID); 14370b57cec5SDimitry Andric assert(DS != DefinedGVSummaries.end() && 14380b57cec5SDimitry Andric "Expected a defined summary for imported global value"); 1439*0fca6ea1SDimitry Andric if (Type == GlobalValueSummary::Declaration) 1440*0fca6ea1SDimitry Andric DecSummaries.insert(DS->second); 1441*0fca6ea1SDimitry Andric 1442*0fca6ea1SDimitry Andric SummariesForIndex[GUID] = DS->second; 14430b57cec5SDimitry Andric } 14440b57cec5SDimitry Andric } 14450b57cec5SDimitry Andric } 14460b57cec5SDimitry Andric 14470b57cec5SDimitry Andric /// Emit the files \p ModulePath will import from into \p OutputFilename. 14480b57cec5SDimitry Andric std::error_code llvm::EmitImportsFiles( 14490b57cec5SDimitry Andric StringRef ModulePath, StringRef OutputFilename, 14500b57cec5SDimitry Andric const std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) { 14510b57cec5SDimitry Andric std::error_code EC; 1452*0fca6ea1SDimitry Andric raw_fd_ostream ImportsOS(OutputFilename, EC, sys::fs::OpenFlags::OF_Text); 14530b57cec5SDimitry Andric if (EC) 14540b57cec5SDimitry Andric return EC; 1455bdd1243dSDimitry Andric for (const auto &ILI : ModuleToSummariesForIndex) 14560b57cec5SDimitry Andric // The ModuleToSummariesForIndex map includes an entry for the current 14570b57cec5SDimitry Andric // Module (needed for writing out the index files). We don't want to 14580b57cec5SDimitry Andric // include it in the imports file, however, so filter it out. 14590b57cec5SDimitry Andric if (ILI.first != ModulePath) 14600b57cec5SDimitry Andric ImportsOS << ILI.first << "\n"; 14610b57cec5SDimitry Andric return std::error_code(); 14620b57cec5SDimitry Andric } 14630b57cec5SDimitry Andric 14640b57cec5SDimitry Andric bool llvm::convertToDeclaration(GlobalValue &GV) { 14650b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Converting to a declaration: `" << GV.getName() 14660b57cec5SDimitry Andric << "\n"); 14670b57cec5SDimitry Andric if (Function *F = dyn_cast<Function>(&GV)) { 14680b57cec5SDimitry Andric F->deleteBody(); 14690b57cec5SDimitry Andric F->clearMetadata(); 14700b57cec5SDimitry Andric F->setComdat(nullptr); 14710b57cec5SDimitry Andric } else if (GlobalVariable *V = dyn_cast<GlobalVariable>(&GV)) { 14720b57cec5SDimitry Andric V->setInitializer(nullptr); 14730b57cec5SDimitry Andric V->setLinkage(GlobalValue::ExternalLinkage); 14740b57cec5SDimitry Andric V->clearMetadata(); 14750b57cec5SDimitry Andric V->setComdat(nullptr); 14760b57cec5SDimitry Andric } else { 14770b57cec5SDimitry Andric GlobalValue *NewGV; 14780b57cec5SDimitry Andric if (GV.getValueType()->isFunctionTy()) 14790b57cec5SDimitry Andric NewGV = 14800b57cec5SDimitry Andric Function::Create(cast<FunctionType>(GV.getValueType()), 14810b57cec5SDimitry Andric GlobalValue::ExternalLinkage, GV.getAddressSpace(), 14820b57cec5SDimitry Andric "", GV.getParent()); 14830b57cec5SDimitry Andric else 14840b57cec5SDimitry Andric NewGV = 14850b57cec5SDimitry Andric new GlobalVariable(*GV.getParent(), GV.getValueType(), 14860b57cec5SDimitry Andric /*isConstant*/ false, GlobalValue::ExternalLinkage, 14870b57cec5SDimitry Andric /*init*/ nullptr, "", 14880b57cec5SDimitry Andric /*insertbefore*/ nullptr, GV.getThreadLocalMode(), 14890b57cec5SDimitry Andric GV.getType()->getAddressSpace()); 14900b57cec5SDimitry Andric NewGV->takeName(&GV); 14910b57cec5SDimitry Andric GV.replaceAllUsesWith(NewGV); 14920b57cec5SDimitry Andric return false; 14930b57cec5SDimitry Andric } 14945ffd83dbSDimitry Andric if (!GV.isImplicitDSOLocal()) 14955ffd83dbSDimitry Andric GV.setDSOLocal(false); 14960b57cec5SDimitry Andric return true; 14970b57cec5SDimitry Andric } 14980b57cec5SDimitry Andric 1499349cc55cSDimitry Andric void llvm::thinLTOFinalizeInModule(Module &TheModule, 1500349cc55cSDimitry Andric const GVSummaryMapTy &DefinedGlobals, 1501349cc55cSDimitry Andric bool PropagateAttrs) { 1502bdd1243dSDimitry Andric DenseSet<Comdat *> NonPrevailingComdats; 1503349cc55cSDimitry Andric auto FinalizeInModule = [&](GlobalValue &GV, bool Propagate = false) { 15040b57cec5SDimitry Andric // See if the global summary analysis computed a new resolved linkage. 15050b57cec5SDimitry Andric const auto &GS = DefinedGlobals.find(GV.getGUID()); 15060b57cec5SDimitry Andric if (GS == DefinedGlobals.end()) 15070b57cec5SDimitry Andric return; 1508349cc55cSDimitry Andric 1509349cc55cSDimitry Andric if (Propagate) 1510349cc55cSDimitry Andric if (FunctionSummary *FS = dyn_cast<FunctionSummary>(GS->second)) { 1511349cc55cSDimitry Andric if (Function *F = dyn_cast<Function>(&GV)) { 1512349cc55cSDimitry Andric // TODO: propagate ReadNone and ReadOnly. 1513349cc55cSDimitry Andric if (FS->fflags().ReadNone && !F->doesNotAccessMemory()) 1514349cc55cSDimitry Andric F->setDoesNotAccessMemory(); 1515349cc55cSDimitry Andric 1516349cc55cSDimitry Andric if (FS->fflags().ReadOnly && !F->onlyReadsMemory()) 1517349cc55cSDimitry Andric F->setOnlyReadsMemory(); 1518349cc55cSDimitry Andric 1519349cc55cSDimitry Andric if (FS->fflags().NoRecurse && !F->doesNotRecurse()) 1520349cc55cSDimitry Andric F->setDoesNotRecurse(); 1521349cc55cSDimitry Andric 1522349cc55cSDimitry Andric if (FS->fflags().NoUnwind && !F->doesNotThrow()) 1523349cc55cSDimitry Andric F->setDoesNotThrow(); 1524349cc55cSDimitry Andric } 1525349cc55cSDimitry Andric } 1526349cc55cSDimitry Andric 15270b57cec5SDimitry Andric auto NewLinkage = GS->second->linkage(); 15280b57cec5SDimitry Andric if (GlobalValue::isLocalLinkage(GV.getLinkage()) || 15298bcb0991SDimitry Andric // Don't internalize anything here, because the code below 15308bcb0991SDimitry Andric // lacks necessary correctness checks. Leave this job to 15318bcb0991SDimitry Andric // LLVM 'internalize' pass. 15328bcb0991SDimitry Andric GlobalValue::isLocalLinkage(NewLinkage) || 15330b57cec5SDimitry Andric // In case it was dead and already converted to declaration. 15340b57cec5SDimitry Andric GV.isDeclaration()) 15350b57cec5SDimitry Andric return; 15368bcb0991SDimitry Andric 1537fe6060f1SDimitry Andric // Set the potentially more constraining visibility computed from summaries. 1538fe6060f1SDimitry Andric // The DefaultVisibility condition is because older GlobalValueSummary does 1539fe6060f1SDimitry Andric // not record DefaultVisibility and we don't want to change protected/hidden 1540fe6060f1SDimitry Andric // to default. 1541fe6060f1SDimitry Andric if (GS->second->getVisibility() != GlobalValue::DefaultVisibility) 1542fe6060f1SDimitry Andric GV.setVisibility(GS->second->getVisibility()); 1543fe6060f1SDimitry Andric 1544fe6060f1SDimitry Andric if (NewLinkage == GV.getLinkage()) 1545fe6060f1SDimitry Andric return; 1546fe6060f1SDimitry Andric 15470b57cec5SDimitry Andric // Check for a non-prevailing def that has interposable linkage 15480b57cec5SDimitry Andric // (e.g. non-odr weak or linkonce). In that case we can't simply 15490b57cec5SDimitry Andric // convert to available_externally, since it would lose the 15500b57cec5SDimitry Andric // interposable property and possibly get inlined. Simply drop 15510b57cec5SDimitry Andric // the definition in that case. 15520b57cec5SDimitry Andric if (GlobalValue::isAvailableExternallyLinkage(NewLinkage) && 15530b57cec5SDimitry Andric GlobalValue::isInterposableLinkage(GV.getLinkage())) { 15540b57cec5SDimitry Andric if (!convertToDeclaration(GV)) 15550b57cec5SDimitry Andric // FIXME: Change this to collect replaced GVs and later erase 15560b57cec5SDimitry Andric // them from the parent module once thinLTOResolvePrevailingGUID is 15570b57cec5SDimitry Andric // changed to enable this for aliases. 15580b57cec5SDimitry Andric llvm_unreachable("Expected GV to be converted"); 15590b57cec5SDimitry Andric } else { 15600b57cec5SDimitry Andric // If all copies of the original symbol had global unnamed addr and 156181ad6265SDimitry Andric // linkonce_odr linkage, or if all of them had local unnamed addr linkage 156281ad6265SDimitry Andric // and are constants, then it should be an auto hide symbol. In that case 156381ad6265SDimitry Andric // the thin link would have marked it as CanAutoHide. Add hidden 156481ad6265SDimitry Andric // visibility to the symbol to preserve the property. 15650b57cec5SDimitry Andric if (NewLinkage == GlobalValue::WeakODRLinkage && 15660b57cec5SDimitry Andric GS->second->canAutoHide()) { 156781ad6265SDimitry Andric assert(GV.canBeOmittedFromSymbolTable()); 15680b57cec5SDimitry Andric GV.setVisibility(GlobalValue::HiddenVisibility); 15690b57cec5SDimitry Andric } 15700b57cec5SDimitry Andric 15710b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "ODR fixing up linkage for `" << GV.getName() 15720b57cec5SDimitry Andric << "` from " << GV.getLinkage() << " to " << NewLinkage 15730b57cec5SDimitry Andric << "\n"); 15740b57cec5SDimitry Andric GV.setLinkage(NewLinkage); 15750b57cec5SDimitry Andric } 15760b57cec5SDimitry Andric // Remove declarations from comdats, including available_externally 15770b57cec5SDimitry Andric // as this is a declaration for the linker, and will be dropped eventually. 15780b57cec5SDimitry Andric // It is illegal for comdats to contain declarations. 15790b57cec5SDimitry Andric auto *GO = dyn_cast_or_null<GlobalObject>(&GV); 1580bdd1243dSDimitry Andric if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) { 1581bdd1243dSDimitry Andric if (GO->getComdat()->getName() == GO->getName()) 1582bdd1243dSDimitry Andric NonPrevailingComdats.insert(GO->getComdat()); 15830b57cec5SDimitry Andric GO->setComdat(nullptr); 1584bdd1243dSDimitry Andric } 15850b57cec5SDimitry Andric }; 15860b57cec5SDimitry Andric 15870b57cec5SDimitry Andric // Process functions and global now 15880b57cec5SDimitry Andric for (auto &GV : TheModule) 1589349cc55cSDimitry Andric FinalizeInModule(GV, PropagateAttrs); 15900b57cec5SDimitry Andric for (auto &GV : TheModule.globals()) 1591349cc55cSDimitry Andric FinalizeInModule(GV); 15920b57cec5SDimitry Andric for (auto &GV : TheModule.aliases()) 1593349cc55cSDimitry Andric FinalizeInModule(GV); 1594bdd1243dSDimitry Andric 1595bdd1243dSDimitry Andric // For a non-prevailing comdat, all its members must be available_externally. 1596bdd1243dSDimitry Andric // FinalizeInModule has handled non-local-linkage GlobalValues. Here we handle 1597bdd1243dSDimitry Andric // local linkage GlobalValues. 1598bdd1243dSDimitry Andric if (NonPrevailingComdats.empty()) 1599bdd1243dSDimitry Andric return; 1600bdd1243dSDimitry Andric for (auto &GO : TheModule.global_objects()) { 1601bdd1243dSDimitry Andric if (auto *C = GO.getComdat(); C && NonPrevailingComdats.count(C)) { 1602bdd1243dSDimitry Andric GO.setComdat(nullptr); 1603bdd1243dSDimitry Andric GO.setLinkage(GlobalValue::AvailableExternallyLinkage); 1604bdd1243dSDimitry Andric } 1605bdd1243dSDimitry Andric } 1606bdd1243dSDimitry Andric bool Changed; 1607bdd1243dSDimitry Andric do { 1608bdd1243dSDimitry Andric Changed = false; 1609bdd1243dSDimitry Andric // If an alias references a GlobalValue in a non-prevailing comdat, change 1610bdd1243dSDimitry Andric // it to available_externally. For simplicity we only handle GlobalValue and 1611bdd1243dSDimitry Andric // ConstantExpr with a base object. ConstantExpr without a base object is 1612bdd1243dSDimitry Andric // unlikely used in a COMDAT. 1613bdd1243dSDimitry Andric for (auto &GA : TheModule.aliases()) { 1614bdd1243dSDimitry Andric if (GA.hasAvailableExternallyLinkage()) 1615bdd1243dSDimitry Andric continue; 1616bdd1243dSDimitry Andric GlobalObject *Obj = GA.getAliaseeObject(); 1617bdd1243dSDimitry Andric assert(Obj && "aliasee without an base object is unimplemented"); 1618bdd1243dSDimitry Andric if (Obj->hasAvailableExternallyLinkage()) { 1619bdd1243dSDimitry Andric GA.setLinkage(GlobalValue::AvailableExternallyLinkage); 1620bdd1243dSDimitry Andric Changed = true; 1621bdd1243dSDimitry Andric } 1622bdd1243dSDimitry Andric } 1623bdd1243dSDimitry Andric } while (Changed); 16240b57cec5SDimitry Andric } 16250b57cec5SDimitry Andric 16260b57cec5SDimitry Andric /// Run internalization on \p TheModule based on symmary analysis. 16270b57cec5SDimitry Andric void llvm::thinLTOInternalizeModule(Module &TheModule, 16280b57cec5SDimitry Andric const GVSummaryMapTy &DefinedGlobals) { 16290b57cec5SDimitry Andric // Declare a callback for the internalize pass that will ask for every 16300b57cec5SDimitry Andric // candidate GlobalValue if it can be internalized or not. 16310b57cec5SDimitry Andric auto MustPreserveGV = [&](const GlobalValue &GV) -> bool { 1632fcaf7f86SDimitry Andric // It may be the case that GV is on a chain of an ifunc, its alias and 1633fcaf7f86SDimitry Andric // subsequent aliases. In this case, the summary for the value is not 1634fcaf7f86SDimitry Andric // available. 1635fcaf7f86SDimitry Andric if (isa<GlobalIFunc>(&GV) || 1636fcaf7f86SDimitry Andric (isa<GlobalAlias>(&GV) && 1637fcaf7f86SDimitry Andric isa<GlobalIFunc>(cast<GlobalAlias>(&GV)->getAliaseeObject()))) 1638fcaf7f86SDimitry Andric return true; 1639fcaf7f86SDimitry Andric 16400b57cec5SDimitry Andric // Lookup the linkage recorded in the summaries during global analysis. 16410b57cec5SDimitry Andric auto GS = DefinedGlobals.find(GV.getGUID()); 16420b57cec5SDimitry Andric if (GS == DefinedGlobals.end()) { 16430b57cec5SDimitry Andric // Must have been promoted (possibly conservatively). Find original 16440b57cec5SDimitry Andric // name so that we can access the correct summary and see if it can 16450b57cec5SDimitry Andric // be internalized again. 16460b57cec5SDimitry Andric // FIXME: Eventually we should control promotion instead of promoting 16470b57cec5SDimitry Andric // and internalizing again. 16480b57cec5SDimitry Andric StringRef OrigName = 16490b57cec5SDimitry Andric ModuleSummaryIndex::getOriginalNameBeforePromote(GV.getName()); 16500b57cec5SDimitry Andric std::string OrigId = GlobalValue::getGlobalIdentifier( 16510b57cec5SDimitry Andric OrigName, GlobalValue::InternalLinkage, 16520b57cec5SDimitry Andric TheModule.getSourceFileName()); 16530b57cec5SDimitry Andric GS = DefinedGlobals.find(GlobalValue::getGUID(OrigId)); 16540b57cec5SDimitry Andric if (GS == DefinedGlobals.end()) { 16550b57cec5SDimitry Andric // Also check the original non-promoted non-globalized name. In some 16560b57cec5SDimitry Andric // cases a preempted weak value is linked in as a local copy because 16570b57cec5SDimitry Andric // it is referenced by an alias (IRLinker::linkGlobalValueProto). 16580b57cec5SDimitry Andric // In that case, since it was originally not a local value, it was 16590b57cec5SDimitry Andric // recorded in the index using the original name. 16600b57cec5SDimitry Andric // FIXME: This may not be needed once PR27866 is fixed. 16610b57cec5SDimitry Andric GS = DefinedGlobals.find(GlobalValue::getGUID(OrigName)); 16620b57cec5SDimitry Andric assert(GS != DefinedGlobals.end()); 16630b57cec5SDimitry Andric } 16640b57cec5SDimitry Andric } 16650b57cec5SDimitry Andric return !GlobalValue::isLocalLinkage(GS->second->linkage()); 16660b57cec5SDimitry Andric }; 16670b57cec5SDimitry Andric 16680b57cec5SDimitry Andric // FIXME: See if we can just internalize directly here via linkage changes 16690b57cec5SDimitry Andric // based on the index, rather than invoking internalizeModule. 16700b57cec5SDimitry Andric internalizeModule(TheModule, MustPreserveGV); 16710b57cec5SDimitry Andric } 16720b57cec5SDimitry Andric 16730b57cec5SDimitry Andric /// Make alias a clone of its aliasee. 16740b57cec5SDimitry Andric static Function *replaceAliasWithAliasee(Module *SrcModule, GlobalAlias *GA) { 1675349cc55cSDimitry Andric Function *Fn = cast<Function>(GA->getAliaseeObject()); 16760b57cec5SDimitry Andric 16770b57cec5SDimitry Andric ValueToValueMapTy VMap; 16780b57cec5SDimitry Andric Function *NewFn = CloneFunction(Fn, VMap); 16790b57cec5SDimitry Andric // Clone should use the original alias's linkage, visibility and name, and we 16800b57cec5SDimitry Andric // ensure all uses of alias instead use the new clone (casted if necessary). 16810b57cec5SDimitry Andric NewFn->setLinkage(GA->getLinkage()); 16820b57cec5SDimitry Andric NewFn->setVisibility(GA->getVisibility()); 16835f757f3fSDimitry Andric GA->replaceAllUsesWith(NewFn); 16840b57cec5SDimitry Andric NewFn->takeName(GA); 16850b57cec5SDimitry Andric return NewFn; 16860b57cec5SDimitry Andric } 16870b57cec5SDimitry Andric 16880b57cec5SDimitry Andric // Internalize values that we marked with specific attribute 16890b57cec5SDimitry Andric // in processGlobalForThinLTO. 16900b57cec5SDimitry Andric static void internalizeGVsAfterImport(Module &M) { 16910b57cec5SDimitry Andric for (auto &GV : M.globals()) 16920b57cec5SDimitry Andric // Skip GVs which have been converted to declarations 16930b57cec5SDimitry Andric // by dropDeadSymbols. 16940b57cec5SDimitry Andric if (!GV.isDeclaration() && GV.hasAttribute("thinlto-internalize")) { 16950b57cec5SDimitry Andric GV.setLinkage(GlobalValue::InternalLinkage); 16960b57cec5SDimitry Andric GV.setVisibility(GlobalValue::DefaultVisibility); 16970b57cec5SDimitry Andric } 16980b57cec5SDimitry Andric } 16990b57cec5SDimitry Andric 17000b57cec5SDimitry Andric // Automatically import functions in Module \p DestModule based on the summaries 17010b57cec5SDimitry Andric // index. 17020b57cec5SDimitry Andric Expected<bool> FunctionImporter::importFunctions( 17030b57cec5SDimitry Andric Module &DestModule, const FunctionImporter::ImportMapTy &ImportList) { 17040b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Starting import for Module " 17050b57cec5SDimitry Andric << DestModule.getModuleIdentifier() << "\n"); 17060b57cec5SDimitry Andric unsigned ImportedCount = 0, ImportedGVCount = 0; 17070b57cec5SDimitry Andric 17080b57cec5SDimitry Andric IRMover Mover(DestModule); 17090b57cec5SDimitry Andric // Do the actual import of functions now, one Module at a time 17100b57cec5SDimitry Andric std::set<StringRef> ModuleNameOrderedList; 1711bdd1243dSDimitry Andric for (const auto &FunctionsToImportPerModule : ImportList) { 17125f757f3fSDimitry Andric ModuleNameOrderedList.insert(FunctionsToImportPerModule.first); 17130b57cec5SDimitry Andric } 1714*0fca6ea1SDimitry Andric 1715*0fca6ea1SDimitry Andric auto getImportType = [&](const FunctionsToImportTy &GUIDToImportType, 1716*0fca6ea1SDimitry Andric GlobalValue::GUID GUID) 1717*0fca6ea1SDimitry Andric -> std::optional<GlobalValueSummary::ImportKind> { 1718*0fca6ea1SDimitry Andric auto Iter = GUIDToImportType.find(GUID); 1719*0fca6ea1SDimitry Andric if (Iter == GUIDToImportType.end()) 1720*0fca6ea1SDimitry Andric return std::nullopt; 1721*0fca6ea1SDimitry Andric return Iter->second; 1722*0fca6ea1SDimitry Andric }; 1723*0fca6ea1SDimitry Andric 1724bdd1243dSDimitry Andric for (const auto &Name : ModuleNameOrderedList) { 17250b57cec5SDimitry Andric // Get the module for the import 17260b57cec5SDimitry Andric const auto &FunctionsToImportPerModule = ImportList.find(Name); 17270b57cec5SDimitry Andric assert(FunctionsToImportPerModule != ImportList.end()); 17280b57cec5SDimitry Andric Expected<std::unique_ptr<Module>> SrcModuleOrErr = ModuleLoader(Name); 17290b57cec5SDimitry Andric if (!SrcModuleOrErr) 17300b57cec5SDimitry Andric return SrcModuleOrErr.takeError(); 17310b57cec5SDimitry Andric std::unique_ptr<Module> SrcModule = std::move(*SrcModuleOrErr); 17320b57cec5SDimitry Andric assert(&DestModule.getContext() == &SrcModule->getContext() && 17330b57cec5SDimitry Andric "Context mismatch"); 17340b57cec5SDimitry Andric 17350b57cec5SDimitry Andric // If modules were created with lazy metadata loading, materialize it 17360b57cec5SDimitry Andric // now, before linking it (otherwise this will be a noop). 17370b57cec5SDimitry Andric if (Error Err = SrcModule->materializeMetadata()) 17380b57cec5SDimitry Andric return std::move(Err); 17390b57cec5SDimitry Andric 17400b57cec5SDimitry Andric auto &ImportGUIDs = FunctionsToImportPerModule->second; 1741*0fca6ea1SDimitry Andric 17420b57cec5SDimitry Andric // Find the globals to import 17430b57cec5SDimitry Andric SetVector<GlobalValue *> GlobalsToImport; 17440b57cec5SDimitry Andric for (Function &F : *SrcModule) { 17450b57cec5SDimitry Andric if (!F.hasName()) 17460b57cec5SDimitry Andric continue; 17470b57cec5SDimitry Andric auto GUID = F.getGUID(); 1748*0fca6ea1SDimitry Andric auto MaybeImportType = getImportType(ImportGUIDs, GUID); 1749*0fca6ea1SDimitry Andric 1750*0fca6ea1SDimitry Andric bool ImportDefinition = 1751*0fca6ea1SDimitry Andric (MaybeImportType && 1752*0fca6ea1SDimitry Andric (*MaybeImportType == GlobalValueSummary::Definition)); 1753*0fca6ea1SDimitry Andric 1754*0fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << (MaybeImportType ? "Is" : "Not") 1755*0fca6ea1SDimitry Andric << " importing function" 1756*0fca6ea1SDimitry Andric << (ImportDefinition 1757*0fca6ea1SDimitry Andric ? " definition " 1758*0fca6ea1SDimitry Andric : (MaybeImportType ? " declaration " : " ")) 17590b57cec5SDimitry Andric << GUID << " " << F.getName() << " from " 17600b57cec5SDimitry Andric << SrcModule->getSourceFileName() << "\n"); 1761*0fca6ea1SDimitry Andric if (ImportDefinition) { 17620b57cec5SDimitry Andric if (Error Err = F.materialize()) 17630b57cec5SDimitry Andric return std::move(Err); 1764*0fca6ea1SDimitry Andric // MemProf should match function's definition and summary, 1765*0fca6ea1SDimitry Andric // 'thinlto_src_module' is needed. 1766*0fca6ea1SDimitry Andric if (EnableImportMetadata || EnableMemProfContextDisambiguation) { 1767*0fca6ea1SDimitry Andric // Add 'thinlto_src_module' and 'thinlto_src_file' metadata for 1768*0fca6ea1SDimitry Andric // statistics and debugging. 17690b57cec5SDimitry Andric F.setMetadata( 17700b57cec5SDimitry Andric "thinlto_src_module", 17710b57cec5SDimitry Andric MDNode::get(DestModule.getContext(), 17720b57cec5SDimitry Andric {MDString::get(DestModule.getContext(), 1773*0fca6ea1SDimitry Andric SrcModule->getModuleIdentifier())})); 1774*0fca6ea1SDimitry Andric F.setMetadata( 1775*0fca6ea1SDimitry Andric "thinlto_src_file", 1776*0fca6ea1SDimitry Andric MDNode::get(DestModule.getContext(), 1777*0fca6ea1SDimitry Andric {MDString::get(DestModule.getContext(), 17780b57cec5SDimitry Andric SrcModule->getSourceFileName())})); 17790b57cec5SDimitry Andric } 17800b57cec5SDimitry Andric GlobalsToImport.insert(&F); 17810b57cec5SDimitry Andric } 17820b57cec5SDimitry Andric } 17830b57cec5SDimitry Andric for (GlobalVariable &GV : SrcModule->globals()) { 17840b57cec5SDimitry Andric if (!GV.hasName()) 17850b57cec5SDimitry Andric continue; 17860b57cec5SDimitry Andric auto GUID = GV.getGUID(); 1787*0fca6ea1SDimitry Andric auto MaybeImportType = getImportType(ImportGUIDs, GUID); 1788*0fca6ea1SDimitry Andric 1789*0fca6ea1SDimitry Andric bool ImportDefinition = 1790*0fca6ea1SDimitry Andric (MaybeImportType && 1791*0fca6ea1SDimitry Andric (*MaybeImportType == GlobalValueSummary::Definition)); 1792*0fca6ea1SDimitry Andric 1793*0fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << (MaybeImportType ? "Is" : "Not") 1794*0fca6ea1SDimitry Andric << " importing global" 1795*0fca6ea1SDimitry Andric << (ImportDefinition 1796*0fca6ea1SDimitry Andric ? " definition " 1797*0fca6ea1SDimitry Andric : (MaybeImportType ? " declaration " : " ")) 17980b57cec5SDimitry Andric << GUID << " " << GV.getName() << " from " 17990b57cec5SDimitry Andric << SrcModule->getSourceFileName() << "\n"); 1800*0fca6ea1SDimitry Andric if (ImportDefinition) { 18010b57cec5SDimitry Andric if (Error Err = GV.materialize()) 18020b57cec5SDimitry Andric return std::move(Err); 18030b57cec5SDimitry Andric ImportedGVCount += GlobalsToImport.insert(&GV); 18040b57cec5SDimitry Andric } 18050b57cec5SDimitry Andric } 18060b57cec5SDimitry Andric for (GlobalAlias &GA : SrcModule->aliases()) { 1807fcaf7f86SDimitry Andric if (!GA.hasName() || isa<GlobalIFunc>(GA.getAliaseeObject())) 18080b57cec5SDimitry Andric continue; 18090b57cec5SDimitry Andric auto GUID = GA.getGUID(); 1810*0fca6ea1SDimitry Andric auto MaybeImportType = getImportType(ImportGUIDs, GUID); 1811*0fca6ea1SDimitry Andric 1812*0fca6ea1SDimitry Andric bool ImportDefinition = 1813*0fca6ea1SDimitry Andric (MaybeImportType && 1814*0fca6ea1SDimitry Andric (*MaybeImportType == GlobalValueSummary::Definition)); 1815*0fca6ea1SDimitry Andric 1816*0fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << (MaybeImportType ? "Is" : "Not") 1817*0fca6ea1SDimitry Andric << " importing alias" 1818*0fca6ea1SDimitry Andric << (ImportDefinition 1819*0fca6ea1SDimitry Andric ? " definition " 1820*0fca6ea1SDimitry Andric : (MaybeImportType ? " declaration " : " ")) 18210b57cec5SDimitry Andric << GUID << " " << GA.getName() << " from " 18220b57cec5SDimitry Andric << SrcModule->getSourceFileName() << "\n"); 1823*0fca6ea1SDimitry Andric if (ImportDefinition) { 18240b57cec5SDimitry Andric if (Error Err = GA.materialize()) 18250b57cec5SDimitry Andric return std::move(Err); 18260b57cec5SDimitry Andric // Import alias as a copy of its aliasee. 1827349cc55cSDimitry Andric GlobalObject *GO = GA.getAliaseeObject(); 1828349cc55cSDimitry Andric if (Error Err = GO->materialize()) 18290b57cec5SDimitry Andric return std::move(Err); 18300b57cec5SDimitry Andric auto *Fn = replaceAliasWithAliasee(SrcModule.get(), &GA); 1831349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << "Is importing aliasee fn " << GO->getGUID() << " " 1832349cc55cSDimitry Andric << GO->getName() << " from " 18330b57cec5SDimitry Andric << SrcModule->getSourceFileName() << "\n"); 1834*0fca6ea1SDimitry Andric if (EnableImportMetadata || EnableMemProfContextDisambiguation) { 1835*0fca6ea1SDimitry Andric // Add 'thinlto_src_module' and 'thinlto_src_file' metadata for 1836*0fca6ea1SDimitry Andric // statistics and debugging. 18370b57cec5SDimitry Andric Fn->setMetadata( 18380b57cec5SDimitry Andric "thinlto_src_module", 18390b57cec5SDimitry Andric MDNode::get(DestModule.getContext(), 18400b57cec5SDimitry Andric {MDString::get(DestModule.getContext(), 1841*0fca6ea1SDimitry Andric SrcModule->getModuleIdentifier())})); 1842*0fca6ea1SDimitry Andric Fn->setMetadata( 1843*0fca6ea1SDimitry Andric "thinlto_src_file", 1844*0fca6ea1SDimitry Andric MDNode::get(DestModule.getContext(), 1845*0fca6ea1SDimitry Andric {MDString::get(DestModule.getContext(), 18460b57cec5SDimitry Andric SrcModule->getSourceFileName())})); 18470b57cec5SDimitry Andric } 18480b57cec5SDimitry Andric GlobalsToImport.insert(Fn); 18490b57cec5SDimitry Andric } 18500b57cec5SDimitry Andric } 18510b57cec5SDimitry Andric 18520b57cec5SDimitry Andric // Upgrade debug info after we're done materializing all the globals and we 18530b57cec5SDimitry Andric // have loaded all the required metadata! 18540b57cec5SDimitry Andric UpgradeDebugInfo(*SrcModule); 18550b57cec5SDimitry Andric 18565ffd83dbSDimitry Andric // Set the partial sample profile ratio in the profile summary module flag 18575ffd83dbSDimitry Andric // of the imported source module, if applicable, so that the profile summary 18585ffd83dbSDimitry Andric // module flag will match with that of the destination module when it's 18595ffd83dbSDimitry Andric // imported. 18605ffd83dbSDimitry Andric SrcModule->setPartialSampleProfileRatio(Index); 18615ffd83dbSDimitry Andric 18620b57cec5SDimitry Andric // Link in the specified functions. 18635ffd83dbSDimitry Andric if (renameModuleForThinLTO(*SrcModule, Index, ClearDSOLocalOnDeclarations, 18645ffd83dbSDimitry Andric &GlobalsToImport)) 18650b57cec5SDimitry Andric return true; 18660b57cec5SDimitry Andric 18670b57cec5SDimitry Andric if (PrintImports) { 18680b57cec5SDimitry Andric for (const auto *GV : GlobalsToImport) 18690b57cec5SDimitry Andric dbgs() << DestModule.getSourceFileName() << ": Import " << GV->getName() 18700b57cec5SDimitry Andric << " from " << SrcModule->getSourceFileName() << "\n"; 18710b57cec5SDimitry Andric } 18720b57cec5SDimitry Andric 187381ad6265SDimitry Andric if (Error Err = Mover.move(std::move(SrcModule), 187481ad6265SDimitry Andric GlobalsToImport.getArrayRef(), nullptr, 18750b57cec5SDimitry Andric /*IsPerformingImport=*/true)) 187606c3fb27SDimitry Andric return createStringError(errc::invalid_argument, 187706c3fb27SDimitry Andric Twine("Function Import: link error: ") + 18785ffd83dbSDimitry Andric toString(std::move(Err))); 18790b57cec5SDimitry Andric 18800b57cec5SDimitry Andric ImportedCount += GlobalsToImport.size(); 18810b57cec5SDimitry Andric NumImportedModules++; 18820b57cec5SDimitry Andric } 18830b57cec5SDimitry Andric 18840b57cec5SDimitry Andric internalizeGVsAfterImport(DestModule); 18850b57cec5SDimitry Andric 18860b57cec5SDimitry Andric NumImportedFunctions += (ImportedCount - ImportedGVCount); 18870b57cec5SDimitry Andric NumImportedGlobalVars += ImportedGVCount; 18880b57cec5SDimitry Andric 1889*0fca6ea1SDimitry Andric // TODO: Print counters for definitions and declarations in the debugging log. 18900b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Imported " << ImportedCount - ImportedGVCount 18910b57cec5SDimitry Andric << " functions for Module " 18920b57cec5SDimitry Andric << DestModule.getModuleIdentifier() << "\n"); 18930b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Imported " << ImportedGVCount 18940b57cec5SDimitry Andric << " global variables for Module " 18950b57cec5SDimitry Andric << DestModule.getModuleIdentifier() << "\n"); 18960b57cec5SDimitry Andric return ImportedCount; 18970b57cec5SDimitry Andric } 18980b57cec5SDimitry Andric 18995f757f3fSDimitry Andric static bool doImportingForModuleForTest( 190006c3fb27SDimitry Andric Module &M, function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 190106c3fb27SDimitry Andric isPrevailing) { 19020b57cec5SDimitry Andric if (SummaryFile.empty()) 19030b57cec5SDimitry Andric report_fatal_error("error: -function-import requires -summary-file\n"); 19040b57cec5SDimitry Andric Expected<std::unique_ptr<ModuleSummaryIndex>> IndexPtrOrErr = 19050b57cec5SDimitry Andric getModuleSummaryIndexForFile(SummaryFile); 19060b57cec5SDimitry Andric if (!IndexPtrOrErr) { 19070b57cec5SDimitry Andric logAllUnhandledErrors(IndexPtrOrErr.takeError(), errs(), 19080b57cec5SDimitry Andric "Error loading file '" + SummaryFile + "': "); 19090b57cec5SDimitry Andric return false; 19100b57cec5SDimitry Andric } 19110b57cec5SDimitry Andric std::unique_ptr<ModuleSummaryIndex> Index = std::move(*IndexPtrOrErr); 19120b57cec5SDimitry Andric 19130b57cec5SDimitry Andric // First step is collecting the import list. 19140b57cec5SDimitry Andric FunctionImporter::ImportMapTy ImportList; 19150b57cec5SDimitry Andric // If requested, simply import all functions in the index. This is used 19160b57cec5SDimitry Andric // when testing distributed backend handling via the opt tool, when 19170b57cec5SDimitry Andric // we have distributed indexes containing exactly the summaries to import. 19180b57cec5SDimitry Andric if (ImportAllIndex) 19195f757f3fSDimitry Andric ComputeCrossModuleImportForModuleFromIndexForTest(M.getModuleIdentifier(), 192006c3fb27SDimitry Andric *Index, ImportList); 19215f757f3fSDimitry Andric else 19225f757f3fSDimitry Andric ComputeCrossModuleImportForModuleForTest(M.getModuleIdentifier(), 19235f757f3fSDimitry Andric isPrevailing, *Index, ImportList); 19240b57cec5SDimitry Andric 19250b57cec5SDimitry Andric // Conservatively mark all internal values as promoted. This interface is 19260b57cec5SDimitry Andric // only used when doing importing via the function importing pass. The pass 19270b57cec5SDimitry Andric // is only enabled when testing importing via the 'opt' tool, which does 19280b57cec5SDimitry Andric // not do the ThinLink that would normally determine what values to promote. 19290b57cec5SDimitry Andric for (auto &I : *Index) { 19300b57cec5SDimitry Andric for (auto &S : I.second.SummaryList) { 19310b57cec5SDimitry Andric if (GlobalValue::isLocalLinkage(S->linkage())) 19320b57cec5SDimitry Andric S->setLinkage(GlobalValue::ExternalLinkage); 19330b57cec5SDimitry Andric } 19340b57cec5SDimitry Andric } 19350b57cec5SDimitry Andric 19360b57cec5SDimitry Andric // Next we need to promote to global scope and rename any local values that 19370b57cec5SDimitry Andric // are potentially exported to other modules. 1938e8d8bef9SDimitry Andric if (renameModuleForThinLTO(M, *Index, /*ClearDSOLocalOnDeclarations=*/false, 19395ffd83dbSDimitry Andric /*GlobalsToImport=*/nullptr)) { 19400b57cec5SDimitry Andric errs() << "Error renaming module\n"; 194106c3fb27SDimitry Andric return true; 19420b57cec5SDimitry Andric } 19430b57cec5SDimitry Andric 19440b57cec5SDimitry Andric // Perform the import now. 19450b57cec5SDimitry Andric auto ModuleLoader = [&M](StringRef Identifier) { 19465ffd83dbSDimitry Andric return loadFile(std::string(Identifier), M.getContext()); 19470b57cec5SDimitry Andric }; 19485ffd83dbSDimitry Andric FunctionImporter Importer(*Index, ModuleLoader, 19495ffd83dbSDimitry Andric /*ClearDSOLocalOnDeclarations=*/false); 19500b57cec5SDimitry Andric Expected<bool> Result = Importer.importFunctions(M, ImportList); 19510b57cec5SDimitry Andric 19520b57cec5SDimitry Andric // FIXME: Probably need to propagate Errors through the pass manager. 19530b57cec5SDimitry Andric if (!Result) { 19540b57cec5SDimitry Andric logAllUnhandledErrors(Result.takeError(), errs(), 19550b57cec5SDimitry Andric "Error importing module: "); 195606c3fb27SDimitry Andric return true; 19570b57cec5SDimitry Andric } 19580b57cec5SDimitry Andric 195906c3fb27SDimitry Andric return true; 19600b57cec5SDimitry Andric } 19610b57cec5SDimitry Andric 19620b57cec5SDimitry Andric PreservedAnalyses FunctionImportPass::run(Module &M, 19630b57cec5SDimitry Andric ModuleAnalysisManager &AM) { 196406c3fb27SDimitry Andric // This is only used for testing the function import pass via opt, where we 196506c3fb27SDimitry Andric // don't have prevailing information from the LTO context available, so just 196606c3fb27SDimitry Andric // conservatively assume everything is prevailing (which is fine for the very 196706c3fb27SDimitry Andric // limited use of prevailing checking in this pass). 196806c3fb27SDimitry Andric auto isPrevailing = [](GlobalValue::GUID, const GlobalValueSummary *) { 196906c3fb27SDimitry Andric return true; 197006c3fb27SDimitry Andric }; 19715f757f3fSDimitry Andric if (!doImportingForModuleForTest(M, isPrevailing)) 19720b57cec5SDimitry Andric return PreservedAnalyses::all(); 19730b57cec5SDimitry Andric 19740b57cec5SDimitry Andric return PreservedAnalyses::none(); 19750b57cec5SDimitry Andric } 1976