142418abaSMehdi Amini //===- FunctionImport.cpp - ThinLTO Summary-based Function Import ---------===//
242418abaSMehdi Amini //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
642418abaSMehdi Amini //
742418abaSMehdi Amini //===----------------------------------------------------------------------===//
842418abaSMehdi Amini //
942418abaSMehdi Amini // This file implements Function import based on summaries.
1042418abaSMehdi Amini //
1142418abaSMehdi Amini //===----------------------------------------------------------------------===//
1242418abaSMehdi Amini
1342418abaSMehdi Amini #include "llvm/Transforms/IPO/FunctionImport.h"
14e9ea08a0SEugene Zelenko #include "llvm/ADT/ArrayRef.h"
15e9ea08a0SEugene Zelenko #include "llvm/ADT/STLExtras.h"
16e9ea08a0SEugene Zelenko #include "llvm/ADT/SetVector.h"
1701e32130SMehdi Amini #include "llvm/ADT/SmallVector.h"
18d29478f7STeresa Johnson #include "llvm/ADT/Statistic.h"
19e9ea08a0SEugene Zelenko #include "llvm/ADT/StringMap.h"
200efed325SSimon Pilgrim #include "llvm/ADT/StringRef.h"
21c15d60b7SPeter Collingbourne #include "llvm/Bitcode/BitcodeReader.h"
2242418abaSMehdi Amini #include "llvm/IR/AutoUpgrade.h"
2381bbf742STeresa Johnson #include "llvm/IR/Constants.h"
24e9ea08a0SEugene Zelenko #include "llvm/IR/Function.h"
25e9ea08a0SEugene Zelenko #include "llvm/IR/GlobalAlias.h"
26e9ea08a0SEugene Zelenko #include "llvm/IR/GlobalObject.h"
27e9ea08a0SEugene Zelenko #include "llvm/IR/GlobalValue.h"
28e9ea08a0SEugene Zelenko #include "llvm/IR/GlobalVariable.h"
29e9ea08a0SEugene Zelenko #include "llvm/IR/Metadata.h"
3042418abaSMehdi Amini #include "llvm/IR/Module.h"
31e9ea08a0SEugene Zelenko #include "llvm/IR/ModuleSummaryIndex.h"
3242418abaSMehdi Amini #include "llvm/IRReader/IRReader.h"
3305da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
34e9ea08a0SEugene Zelenko #include "llvm/Linker/IRMover.h"
35e9ea08a0SEugene Zelenko #include "llvm/Pass.h"
36e9ea08a0SEugene Zelenko #include "llvm/Support/Casting.h"
3742418abaSMehdi Amini #include "llvm/Support/CommandLine.h"
3842418abaSMehdi Amini #include "llvm/Support/Debug.h"
393c503ba0SNikita Popov #include "llvm/Support/Errc.h"
40e9ea08a0SEugene Zelenko #include "llvm/Support/Error.h"
41e9ea08a0SEugene Zelenko #include "llvm/Support/ErrorHandling.h"
42e9ea08a0SEugene Zelenko #include "llvm/Support/FileSystem.h"
4342418abaSMehdi Amini #include "llvm/Support/SourceMgr.h"
44e9ea08a0SEugene Zelenko #include "llvm/Support/raw_ostream.h"
4504c9a2d6STeresa Johnson #include "llvm/Transforms/IPO/Internalize.h"
4681bbf742STeresa Johnson #include "llvm/Transforms/Utils/Cloning.h"
47488a800aSTeresa Johnson #include "llvm/Transforms/Utils/FunctionImportUtils.h"
4881bbf742STeresa Johnson #include "llvm/Transforms/Utils/ValueMapper.h"
49e9ea08a0SEugene Zelenko #include <cassert>
50e9ea08a0SEugene Zelenko #include <memory>
51e9ea08a0SEugene Zelenko #include <set>
52e9ea08a0SEugene Zelenko #include <string>
53e9ea08a0SEugene Zelenko #include <system_error>
54e9ea08a0SEugene Zelenko #include <tuple>
55e9ea08a0SEugene Zelenko #include <utility>
567e88d0daSMehdi Amini
5742418abaSMehdi Amini using namespace llvm;
5842418abaSMehdi Amini
59e9ea08a0SEugene Zelenko #define DEBUG_TYPE "function-import"
60e9ea08a0SEugene Zelenko
61d2c234a4STeresa Johnson STATISTIC(NumImportedFunctionsThinLink,
62d2c234a4STeresa Johnson "Number of functions thin link decided to import");
63d2c234a4STeresa Johnson STATISTIC(NumImportedHotFunctionsThinLink,
64d2c234a4STeresa Johnson "Number of hot functions thin link decided to import");
65d2c234a4STeresa Johnson STATISTIC(NumImportedCriticalFunctionsThinLink,
66d2c234a4STeresa Johnson "Number of critical functions thin link decided to import");
67d2c234a4STeresa Johnson STATISTIC(NumImportedGlobalVarsThinLink,
68d2c234a4STeresa Johnson "Number of global variables thin link decided to import");
69d2c234a4STeresa Johnson STATISTIC(NumImportedFunctions, "Number of functions imported in backend");
70d2c234a4STeresa Johnson STATISTIC(NumImportedGlobalVars,
71d2c234a4STeresa Johnson "Number of global variables imported in backend");
726c475a75STeresa Johnson STATISTIC(NumImportedModules, "Number of modules imported from");
736c475a75STeresa Johnson STATISTIC(NumDeadSymbols, "Number of dead stripped symbols in index");
746c475a75STeresa Johnson STATISTIC(NumLiveSymbols, "Number of live symbols in index");
75d29478f7STeresa Johnson
7639303619STeresa Johnson /// Limit on instruction count of imported functions.
7739303619STeresa Johnson static cl::opt<unsigned> ImportInstrLimit(
7839303619STeresa Johnson "import-instr-limit", cl::init(100), cl::Hidden, cl::value_desc("N"),
7939303619STeresa Johnson cl::desc("Only import functions with less than N instructions"));
8039303619STeresa Johnson
81974706ebSTeresa Johnson static cl::opt<int> ImportCutoff(
82974706ebSTeresa Johnson "import-cutoff", cl::init(-1), cl::Hidden, cl::value_desc("N"),
83974706ebSTeresa Johnson cl::desc("Only import first N functions if N>=0 (default -1)"));
84974706ebSTeresa Johnson
85bf612458SYaxun (Sam) Liu static cl::opt<bool>
86bf612458SYaxun (Sam) Liu ForceImportAll("force-import-all", cl::init(false), cl::Hidden,
87bf612458SYaxun (Sam) Liu cl::desc("Import functions with noinline attribute"));
88bf612458SYaxun (Sam) Liu
8940641748SMehdi Amini static cl::opt<float>
9040641748SMehdi Amini ImportInstrFactor("import-instr-evolution-factor", cl::init(0.7),
9140641748SMehdi Amini cl::Hidden, cl::value_desc("x"),
9240641748SMehdi Amini cl::desc("As we import functions, multiply the "
9340641748SMehdi Amini "`import-instr-limit` threshold by this factor "
9440641748SMehdi Amini "before processing newly imported functions"));
95ba72b95fSPiotr Padlewski
96d2869473SPiotr Padlewski static cl::opt<float> ImportHotInstrFactor(
97d2869473SPiotr Padlewski "import-hot-evolution-factor", cl::init(1.0), cl::Hidden,
98d2869473SPiotr Padlewski cl::value_desc("x"),
99d2869473SPiotr Padlewski cl::desc("As we import functions called from hot callsite, multiply the "
100d2869473SPiotr Padlewski "`import-instr-limit` threshold by this factor "
101d2869473SPiotr Padlewski "before processing newly imported functions"));
102d2869473SPiotr Padlewski
103d9830eb7SPiotr Padlewski static cl::opt<float> ImportHotMultiplier(
1048260d665SDehao Chen "import-hot-multiplier", cl::init(10.0), cl::Hidden, cl::value_desc("x"),
105ba72b95fSPiotr Padlewski cl::desc("Multiply the `import-instr-limit` threshold for hot callsites"));
106ba72b95fSPiotr Padlewski
10764c46574SDehao Chen static cl::opt<float> ImportCriticalMultiplier(
10864c46574SDehao Chen "import-critical-multiplier", cl::init(100.0), cl::Hidden,
10964c46574SDehao Chen cl::value_desc("x"),
11064c46574SDehao Chen cl::desc(
11164c46574SDehao Chen "Multiply the `import-instr-limit` threshold for critical callsites"));
11264c46574SDehao Chen
113ba72b95fSPiotr Padlewski // FIXME: This multiplier was not really tuned up.
114ba72b95fSPiotr Padlewski static cl::opt<float> ImportColdMultiplier(
115ba72b95fSPiotr Padlewski "import-cold-multiplier", cl::init(0), cl::Hidden, cl::value_desc("N"),
116ba72b95fSPiotr Padlewski cl::desc("Multiply the `import-instr-limit` threshold for cold callsites"));
11740641748SMehdi Amini
118d29478f7STeresa Johnson static cl::opt<bool> PrintImports("print-imports", cl::init(false), cl::Hidden,
119d29478f7STeresa Johnson cl::desc("Print imported functions"));
120d29478f7STeresa Johnson
121cb9a82fcSTeresa Johnson static cl::opt<bool> PrintImportFailures(
122cb9a82fcSTeresa Johnson "print-import-failures", cl::init(false), cl::Hidden,
123cb9a82fcSTeresa Johnson cl::desc("Print information for functions rejected for importing"));
124cb9a82fcSTeresa Johnson
1256c475a75STeresa Johnson static cl::opt<bool> ComputeDead("compute-dead", cl::init(true), cl::Hidden,
1266c475a75STeresa Johnson cl::desc("Compute dead symbols"));
1276c475a75STeresa Johnson
1283b776128SPiotr Padlewski static cl::opt<bool> EnableImportMetadata(
129a90b42b0SFangrui Song "enable-import-metadata", cl::init(false), cl::Hidden,
130a90b42b0SFangrui Song cl::desc("Enable import metadata like 'thinlto_src_module'"));
1313b776128SPiotr Padlewski
132e9ea08a0SEugene Zelenko /// Summary file to use for function importing when using -function-import from
133e9ea08a0SEugene Zelenko /// the command line.
134e9ea08a0SEugene Zelenko static cl::opt<std::string>
135e9ea08a0SEugene Zelenko SummaryFile("summary-file",
136e9ea08a0SEugene Zelenko cl::desc("The summary file to use for function importing."));
137e9ea08a0SEugene Zelenko
13881bbf742STeresa Johnson /// Used when testing importing from distributed indexes via opt
13981bbf742STeresa Johnson // -function-import.
14081bbf742STeresa Johnson static cl::opt<bool>
14181bbf742STeresa Johnson ImportAllIndex("import-all-index",
14281bbf742STeresa Johnson cl::desc("Import all external functions in index."));
14381bbf742STeresa Johnson
14442418abaSMehdi Amini // Load lazily a module from \p FileName in \p Context.
loadFile(const std::string & FileName,LLVMContext & Context)14542418abaSMehdi Amini static std::unique_ptr<Module> loadFile(const std::string &FileName,
14642418abaSMehdi Amini LLVMContext &Context) {
14742418abaSMehdi Amini SMDiagnostic Err;
148d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Loading '" << FileName << "'\n");
1496cba37ceSTeresa Johnson // Metadata isn't loaded until functions are imported, to minimize
1506cba37ceSTeresa Johnson // the memory overhead.
151a1080ee6STeresa Johnson std::unique_ptr<Module> Result =
152a1080ee6STeresa Johnson getLazyIRFileModule(FileName, Err, Context,
153a1080ee6STeresa Johnson /* ShouldLazyLoadMetadata = */ true);
15442418abaSMehdi Amini if (!Result) {
15542418abaSMehdi Amini Err.print("function-import", errs());
156d7ad221cSMehdi Amini report_fatal_error("Abort");
15742418abaSMehdi Amini }
15842418abaSMehdi Amini
15942418abaSMehdi Amini return Result;
16042418abaSMehdi Amini }
16142418abaSMehdi Amini
16201e32130SMehdi Amini /// Given a list of possible callee implementation for a call site, select one
16301e32130SMehdi Amini /// that fits the \p Threshold.
16401e32130SMehdi Amini ///
16501e32130SMehdi Amini /// FIXME: select "best" instead of first that fits. But what is "best"?
16601e32130SMehdi Amini /// - The smallest: more likely to be inlined.
16701e32130SMehdi Amini /// - The one with the least outgoing edges (already well optimized).
16801e32130SMehdi Amini /// - One from a module already being imported from in order to reduce the
16901e32130SMehdi Amini /// number of source modules parsed/linked.
17001e32130SMehdi Amini /// - One that has PGO data attached.
17101e32130SMehdi Amini /// - [insert you fancy metric here]
1722d28f7aaSMehdi Amini static const GlobalValueSummary *
selectCallee(const ModuleSummaryIndex & Index,ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,unsigned Threshold,StringRef CallerModulePath,FunctionImporter::ImportFailureReason & Reason,GlobalValue::GUID GUID)173b4e1e829SMehdi Amini selectCallee(const ModuleSummaryIndex &Index,
1749667b91bSPeter Collingbourne ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
175cb9a82fcSTeresa Johnson unsigned Threshold, StringRef CallerModulePath,
176cb9a82fcSTeresa Johnson FunctionImporter::ImportFailureReason &Reason,
177cb9a82fcSTeresa Johnson GlobalValue::GUID GUID) {
178cb9a82fcSTeresa Johnson Reason = FunctionImporter::ImportFailureReason::None;
17901e32130SMehdi Amini auto It = llvm::find_if(
18028e457bcSTeresa Johnson CalleeSummaryList,
18128e457bcSTeresa Johnson [&](const std::unique_ptr<GlobalValueSummary> &SummaryPtr) {
18228e457bcSTeresa Johnson auto *GVSummary = SummaryPtr.get();
183cb9a82fcSTeresa Johnson if (!Index.isGlobalValueLive(GVSummary)) {
184cb9a82fcSTeresa Johnson Reason = FunctionImporter::ImportFailureReason::NotLive;
185eaf5172cSGeorge Rimar return false;
186cb9a82fcSTeresa Johnson }
187eaf5172cSGeorge Rimar
188cb9a82fcSTeresa Johnson if (GlobalValue::isInterposableLinkage(GVSummary->linkage())) {
189cb9a82fcSTeresa Johnson Reason = FunctionImporter::ImportFailureReason::InterposableLinkage;
1905b85d8d6SMehdi Amini // There is no point in importing these, we can't inline them
19101e32130SMehdi Amini return false;
192cb9a82fcSTeresa Johnson }
1932c719cc1SMehdi Amini
19481bbf742STeresa Johnson auto *Summary = cast<FunctionSummary>(GVSummary->getBaseObject());
1957e88d0daSMehdi Amini
19683aaf358STeresa Johnson // If this is a local function, make sure we import the copy
19783aaf358STeresa Johnson // in the caller's module. The only time a local function can
19883aaf358STeresa Johnson // share an entry in the index is if there is a local with the same name
19983aaf358STeresa Johnson // in another module that had the same source file name (in a different
20083aaf358STeresa Johnson // directory), where each was compiled in their own directory so there
20183aaf358STeresa Johnson // was not distinguishing path.
20283aaf358STeresa Johnson // However, do the import from another module if there is only one
20383aaf358STeresa Johnson // entry in the list - in that case this must be a reference due
20483aaf358STeresa Johnson // to indirect call profile data, since a function pointer can point to
20583aaf358STeresa Johnson // a local in another module.
20683aaf358STeresa Johnson if (GlobalValue::isLocalLinkage(Summary->linkage()) &&
20783aaf358STeresa Johnson CalleeSummaryList.size() > 1 &&
208cb9a82fcSTeresa Johnson Summary->modulePath() != CallerModulePath) {
209cb9a82fcSTeresa Johnson Reason =
210cb9a82fcSTeresa Johnson FunctionImporter::ImportFailureReason::LocalLinkageNotInModule;
21183aaf358STeresa Johnson return false;
212cb9a82fcSTeresa Johnson }
21383aaf358STeresa Johnson
214b11391bbSTeresa Johnson if ((Summary->instCount() > Threshold) &&
215bf612458SYaxun (Sam) Liu !Summary->fflags().AlwaysInline && !ForceImportAll) {
216cb9a82fcSTeresa Johnson Reason = FunctionImporter::ImportFailureReason::TooLarge;
217f9dc3deaSTeresa Johnson return false;
218cb9a82fcSTeresa Johnson }
219f9dc3deaSTeresa Johnson
220cb397461STeresa Johnson // Skip if it isn't legal to import (e.g. may reference unpromotable
221cb397461STeresa Johnson // locals).
222cb9a82fcSTeresa Johnson if (Summary->notEligibleToImport()) {
223cb9a82fcSTeresa Johnson Reason = FunctionImporter::ImportFailureReason::NotEligible;
224b4e1e829SMehdi Amini return false;
225cb9a82fcSTeresa Johnson }
226b4e1e829SMehdi Amini
227cb397461STeresa Johnson // Don't bother importing if we can't inline it anyway.
228bf612458SYaxun (Sam) Liu if (Summary->fflags().NoInline && !ForceImportAll) {
229cb397461STeresa Johnson Reason = FunctionImporter::ImportFailureReason::NoInline;
230cb397461STeresa Johnson return false;
231cb397461STeresa Johnson }
232cb397461STeresa Johnson
23301e32130SMehdi Amini return true;
23401e32130SMehdi Amini });
23528e457bcSTeresa Johnson if (It == CalleeSummaryList.end())
23601e32130SMehdi Amini return nullptr;
2377e88d0daSMehdi Amini
238f9dc3deaSTeresa Johnson return cast<GlobalValueSummary>(It->get());
239434e9561SRafael Espindola }
2407e88d0daSMehdi Amini
241e9ea08a0SEugene Zelenko namespace {
242e9ea08a0SEugene Zelenko
243d5b701b9SEvgeny Leviant using EdgeInfo =
244d5b701b9SEvgeny Leviant std::tuple<const GlobalValueSummary *, unsigned /* Threshold */>;
24501e32130SMehdi Amini
246e9ea08a0SEugene Zelenko } // anonymous namespace
247e9ea08a0SEugene Zelenko
shouldImportGlobal(const ValueInfo & VI,const GVSummaryMapTy & DefinedGVSummaries)248e97aab8dSKristina Bessonova static bool shouldImportGlobal(const ValueInfo &VI,
249e97aab8dSKristina Bessonova const GVSummaryMapTy &DefinedGVSummaries) {
250e97aab8dSKristina Bessonova const auto &GVS = DefinedGVSummaries.find(VI.getGUID());
251e97aab8dSKristina Bessonova if (GVS == DefinedGVSummaries.end())
252e97aab8dSKristina Bessonova return true;
253e97aab8dSKristina Bessonova // We should not skip import if the module contains a definition with
254e97aab8dSKristina Bessonova // interposable linkage type. This is required for correctness in
255e97aab8dSKristina Bessonova // the situation with two following conditions:
256e97aab8dSKristina Bessonova // * the def with interposable linkage is non-prevailing,
257e97aab8dSKristina Bessonova // * there is a prevailing def available for import and marked read-only.
258e97aab8dSKristina Bessonova // In this case, the non-prevailing def will be converted to a declaration,
259e97aab8dSKristina Bessonova // while the prevailing one becomes internal, thus no definitions will be
260e97aab8dSKristina Bessonova // available for linking. In order to prevent undefined symbol link error,
261e97aab8dSKristina Bessonova // the prevailing definition must be imported.
262e97aab8dSKristina Bessonova // FIXME: Consider adding a check that the suitable prevailing definition
263e97aab8dSKristina Bessonova // exists and marked read-only.
264e97aab8dSKristina Bessonova if (VI.getSummaryList().size() > 1 &&
265e97aab8dSKristina Bessonova GlobalValue::isInterposableLinkage(GVS->second->linkage()))
266e97aab8dSKristina Bessonova return true;
267e97aab8dSKristina Bessonova
268e97aab8dSKristina Bessonova return false;
269e97aab8dSKristina Bessonova }
270e97aab8dSKristina Bessonova
computeImportForReferencedGlobals(const GlobalValueSummary & Summary,const ModuleSummaryIndex & Index,const GVSummaryMapTy & DefinedGVSummaries,SmallVectorImpl<EdgeInfo> & Worklist,FunctionImporter::ImportMapTy & ImportList,StringMap<FunctionImporter::ExportSetTy> * ExportLists)27119e23874SEugene Leviant static void computeImportForReferencedGlobals(
272d5b701b9SEvgeny Leviant const GlobalValueSummary &Summary, const ModuleSummaryIndex &Index,
273dde58938Sevgeny const GVSummaryMapTy &DefinedGVSummaries,
274d5b701b9SEvgeny Leviant SmallVectorImpl<EdgeInfo> &Worklist,
27519e23874SEugene Leviant FunctionImporter::ImportMapTy &ImportList,
27619e23874SEugene Leviant StringMap<FunctionImporter::ExportSetTy> *ExportLists) {
27719e23874SEugene Leviant for (auto &VI : Summary.refs()) {
278e97aab8dSKristina Bessonova if (!shouldImportGlobal(VI, DefinedGVSummaries)) {
279d34e60caSNicola Zaghen LLVM_DEBUG(
280d34e60caSNicola Zaghen dbgs() << "Ref ignored! Target already in destination module.\n");
28119e23874SEugene Leviant continue;
28219e23874SEugene Leviant }
28319e23874SEugene Leviant
2847e7b13d0STeresa Johnson LLVM_DEBUG(dbgs() << " ref -> " << VI << "\n");
28519e23874SEugene Leviant
28693f99962STeresa Johnson // If this is a local variable, make sure we import the copy
28793f99962STeresa Johnson // in the caller's module. The only time a local variable can
28893f99962STeresa Johnson // share an entry in the index is if there is a local with the same name
28993f99962STeresa Johnson // in another module that had the same source file name (in a different
29093f99962STeresa Johnson // directory), where each was compiled in their own directory so there
29193f99962STeresa Johnson // was not distinguishing path.
29293f99962STeresa Johnson auto LocalNotInModule = [&](const GlobalValueSummary *RefSummary) -> bool {
29393f99962STeresa Johnson return GlobalValue::isLocalLinkage(RefSummary->linkage()) &&
29493f99962STeresa Johnson RefSummary->modulePath() != Summary.modulePath();
29593f99962STeresa Johnson };
29693f99962STeresa Johnson
29719e23874SEugene Leviant for (auto &RefSummary : VI.getSummaryList())
298bf46e741SEugene Leviant if (isa<GlobalVarSummary>(RefSummary.get()) &&
299dde58938Sevgeny Index.canImportGlobalVar(RefSummary.get(), /* AnalyzeRefs */ true) &&
30093f99962STeresa Johnson !LocalNotInModule(RefSummary.get())) {
301d2c234a4STeresa Johnson auto ILI = ImportList[RefSummary->modulePath()].insert(VI.getGUID());
302bed4d9c8STeresa Johnson // Only update stat and exports if we haven't already imported this
303bed4d9c8STeresa Johnson // variable.
304bed4d9c8STeresa Johnson if (!ILI.second)
305bed4d9c8STeresa Johnson break;
306d2c234a4STeresa Johnson NumImportedGlobalVarsThinLink++;
307bed4d9c8STeresa Johnson // Any references made by this variable will be marked exported later,
308bed4d9c8STeresa Johnson // in ComputeCrossModuleImport, after import decisions are complete,
309bed4d9c8STeresa Johnson // which is more efficient than adding them here.
310bed4d9c8STeresa Johnson if (ExportLists)
311bed4d9c8STeresa Johnson (*ExportLists)[RefSummary->modulePath()].insert(VI);
312d5b701b9SEvgeny Leviant
313d5b701b9SEvgeny Leviant // If variable is not writeonly we attempt to recursively analyze
314d5b701b9SEvgeny Leviant // its references in order to import referenced constants.
315d5b701b9SEvgeny Leviant if (!Index.isWriteOnly(cast<GlobalVarSummary>(RefSummary.get())))
316d5b701b9SEvgeny Leviant Worklist.emplace_back(RefSummary.get(), 0);
31719e23874SEugene Leviant break;
31819e23874SEugene Leviant }
31919e23874SEugene Leviant }
32019e23874SEugene Leviant }
32119e23874SEugene Leviant
322cb9a82fcSTeresa Johnson static const char *
getFailureName(FunctionImporter::ImportFailureReason Reason)323cb9a82fcSTeresa Johnson getFailureName(FunctionImporter::ImportFailureReason Reason) {
324cb9a82fcSTeresa Johnson switch (Reason) {
325cb9a82fcSTeresa Johnson case FunctionImporter::ImportFailureReason::None:
326cb9a82fcSTeresa Johnson return "None";
327cb9a82fcSTeresa Johnson case FunctionImporter::ImportFailureReason::GlobalVar:
328cb9a82fcSTeresa Johnson return "GlobalVar";
329cb9a82fcSTeresa Johnson case FunctionImporter::ImportFailureReason::NotLive:
330cb9a82fcSTeresa Johnson return "NotLive";
331cb9a82fcSTeresa Johnson case FunctionImporter::ImportFailureReason::TooLarge:
332cb9a82fcSTeresa Johnson return "TooLarge";
333cb9a82fcSTeresa Johnson case FunctionImporter::ImportFailureReason::InterposableLinkage:
334cb9a82fcSTeresa Johnson return "InterposableLinkage";
335cb9a82fcSTeresa Johnson case FunctionImporter::ImportFailureReason::LocalLinkageNotInModule:
336cb9a82fcSTeresa Johnson return "LocalLinkageNotInModule";
337cb9a82fcSTeresa Johnson case FunctionImporter::ImportFailureReason::NotEligible:
338cb9a82fcSTeresa Johnson return "NotEligible";
339cb397461STeresa Johnson case FunctionImporter::ImportFailureReason::NoInline:
340cb397461STeresa Johnson return "NoInline";
341cb9a82fcSTeresa Johnson }
342cb9a82fcSTeresa Johnson llvm_unreachable("invalid reason");
343cb9a82fcSTeresa Johnson }
344cb9a82fcSTeresa Johnson
34501e32130SMehdi Amini /// Compute the list of functions to import for a given caller. Mark these
34601e32130SMehdi Amini /// imported functions and the symbols they reference in their source module as
34701e32130SMehdi Amini /// exported from their source module.
computeImportForFunction(const FunctionSummary & Summary,const ModuleSummaryIndex & Index,const unsigned Threshold,const GVSummaryMapTy & DefinedGVSummaries,SmallVectorImpl<EdgeInfo> & Worklist,FunctionImporter::ImportMapTy & ImportList,StringMap<FunctionImporter::ExportSetTy> * ExportLists,FunctionImporter::ImportThresholdsTy & ImportThresholds)34801e32130SMehdi Amini static void computeImportForFunction(
3493255eec1STeresa Johnson const FunctionSummary &Summary, const ModuleSummaryIndex &Index,
350d9830eb7SPiotr Padlewski const unsigned Threshold, const GVSummaryMapTy &DefinedGVSummaries,
35101e32130SMehdi Amini SmallVectorImpl<EdgeInfo> &Worklist,
3529b490f10SMehdi Amini FunctionImporter::ImportMapTy &ImportList,
353d68935c5STeresa Johnson StringMap<FunctionImporter::ExportSetTy> *ExportLists,
354d68935c5STeresa Johnson FunctionImporter::ImportThresholdsTy &ImportThresholds) {
355dde58938Sevgeny computeImportForReferencedGlobals(Summary, Index, DefinedGVSummaries,
356d5b701b9SEvgeny Leviant Worklist, ImportList, ExportLists);
357974706ebSTeresa Johnson static int ImportCount = 0;
35801e32130SMehdi Amini for (auto &Edge : Summary.calls()) {
3599667b91bSPeter Collingbourne ValueInfo VI = Edge.first;
3607e7b13d0STeresa Johnson LLVM_DEBUG(dbgs() << " edge -> " << VI << " Threshold:" << Threshold
3617e7b13d0STeresa Johnson << "\n");
36201e32130SMehdi Amini
363974706ebSTeresa Johnson if (ImportCutoff >= 0 && ImportCount >= ImportCutoff) {
364d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "ignored! import-cutoff value of " << ImportCutoff
365974706ebSTeresa Johnson << " reached.\n");
366974706ebSTeresa Johnson continue;
367974706ebSTeresa Johnson }
368974706ebSTeresa Johnson
3699667b91bSPeter Collingbourne if (DefinedGVSummaries.count(VI.getGUID())) {
370e97aab8dSKristina Bessonova // FIXME: Consider not skipping import if the module contains
371e97aab8dSKristina Bessonova // a non-prevailing def with interposable linkage. The prevailing copy
372e97aab8dSKristina Bessonova // can safely be imported (see shouldImportGlobal()).
373d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "ignored! Target already in destination module.\n");
3747e88d0daSMehdi Amini continue;
375d450da32STeresa Johnson }
37640641748SMehdi Amini
377ba72b95fSPiotr Padlewski auto GetBonusMultiplier = [](CalleeInfo::HotnessType Hotness) -> float {
378ba72b95fSPiotr Padlewski if (Hotness == CalleeInfo::HotnessType::Hot)
379ba72b95fSPiotr Padlewski return ImportHotMultiplier;
380ba72b95fSPiotr Padlewski if (Hotness == CalleeInfo::HotnessType::Cold)
381ba72b95fSPiotr Padlewski return ImportColdMultiplier;
38264c46574SDehao Chen if (Hotness == CalleeInfo::HotnessType::Critical)
38364c46574SDehao Chen return ImportCriticalMultiplier;
384ba72b95fSPiotr Padlewski return 1.0;
385ba72b95fSPiotr Padlewski };
386ba72b95fSPiotr Padlewski
387d9830eb7SPiotr Padlewski const auto NewThreshold =
388c73cec84SEaswaran Raman Threshold * GetBonusMultiplier(Edge.second.getHotness());
389d2869473SPiotr Padlewski
390cb9a82fcSTeresa Johnson auto IT = ImportThresholds.insert(std::make_pair(
391cb9a82fcSTeresa Johnson VI.getGUID(), std::make_tuple(NewThreshold, nullptr, nullptr)));
392d68935c5STeresa Johnson bool PreviouslyVisited = !IT.second;
393cb9a82fcSTeresa Johnson auto &ProcessedThreshold = std::get<0>(IT.first->second);
394cb9a82fcSTeresa Johnson auto &CalleeSummary = std::get<1>(IT.first->second);
395cb9a82fcSTeresa Johnson auto &FailureInfo = std::get<2>(IT.first->second);
396d68935c5STeresa Johnson
397d2c234a4STeresa Johnson bool IsHotCallsite =
398d2c234a4STeresa Johnson Edge.second.getHotness() == CalleeInfo::HotnessType::Hot;
399d2c234a4STeresa Johnson bool IsCriticalCallsite =
400d2c234a4STeresa Johnson Edge.second.getHotness() == CalleeInfo::HotnessType::Critical;
401d2c234a4STeresa Johnson
402d68935c5STeresa Johnson const FunctionSummary *ResolvedCalleeSummary = nullptr;
403d68935c5STeresa Johnson if (CalleeSummary) {
404d68935c5STeresa Johnson assert(PreviouslyVisited);
405d68935c5STeresa Johnson // Since the traversal of the call graph is DFS, we can revisit a function
406d68935c5STeresa Johnson // a second time with a higher threshold. In this case, it is added back
407d68935c5STeresa Johnson // to the worklist with the new threshold (so that its own callee chains
408d68935c5STeresa Johnson // can be considered with the higher threshold).
409d68935c5STeresa Johnson if (NewThreshold <= ProcessedThreshold) {
410d68935c5STeresa Johnson LLVM_DEBUG(
411d68935c5STeresa Johnson dbgs() << "ignored! Target was already imported with Threshold "
412d68935c5STeresa Johnson << ProcessedThreshold << "\n");
413d68935c5STeresa Johnson continue;
414d68935c5STeresa Johnson }
415d68935c5STeresa Johnson // Update with new larger threshold.
416d68935c5STeresa Johnson ProcessedThreshold = NewThreshold;
417d68935c5STeresa Johnson ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
418d68935c5STeresa Johnson } else {
419d68935c5STeresa Johnson // If we already rejected importing a callee at the same or higher
420d68935c5STeresa Johnson // threshold, don't waste time calling selectCallee.
421d68935c5STeresa Johnson if (PreviouslyVisited && NewThreshold <= ProcessedThreshold) {
422d68935c5STeresa Johnson LLVM_DEBUG(
423d68935c5STeresa Johnson dbgs() << "ignored! Target was already rejected with Threshold "
424d68935c5STeresa Johnson << ProcessedThreshold << "\n");
425cb9a82fcSTeresa Johnson if (PrintImportFailures) {
426cb9a82fcSTeresa Johnson assert(FailureInfo &&
427cb9a82fcSTeresa Johnson "Expected FailureInfo for previously rejected candidate");
428cb9a82fcSTeresa Johnson FailureInfo->Attempts++;
429cb9a82fcSTeresa Johnson }
430d68935c5STeresa Johnson continue;
431d68935c5STeresa Johnson }
432d68935c5STeresa Johnson
433cb9a82fcSTeresa Johnson FunctionImporter::ImportFailureReason Reason;
434d68935c5STeresa Johnson CalleeSummary = selectCallee(Index, VI.getSummaryList(), NewThreshold,
435cb9a82fcSTeresa Johnson Summary.modulePath(), Reason, VI.getGUID());
43601e32130SMehdi Amini if (!CalleeSummary) {
437d68935c5STeresa Johnson // Update with new larger threshold if this was a retry (otherwise
438cb9a82fcSTeresa Johnson // we would have already inserted with NewThreshold above). Also
439cb9a82fcSTeresa Johnson // update failure info if requested.
440cb9a82fcSTeresa Johnson if (PreviouslyVisited) {
441d68935c5STeresa Johnson ProcessedThreshold = NewThreshold;
442cb9a82fcSTeresa Johnson if (PrintImportFailures) {
443cb9a82fcSTeresa Johnson assert(FailureInfo &&
444cb9a82fcSTeresa Johnson "Expected FailureInfo for previously rejected candidate");
445cb9a82fcSTeresa Johnson FailureInfo->Reason = Reason;
446cb9a82fcSTeresa Johnson FailureInfo->Attempts++;
447cb9a82fcSTeresa Johnson FailureInfo->MaxHotness =
448cb9a82fcSTeresa Johnson std::max(FailureInfo->MaxHotness, Edge.second.getHotness());
449cb9a82fcSTeresa Johnson }
450cb9a82fcSTeresa Johnson } else if (PrintImportFailures) {
451cb9a82fcSTeresa Johnson assert(!FailureInfo &&
452cb9a82fcSTeresa Johnson "Expected no FailureInfo for newly rejected candidate");
4530eaee545SJonas Devlieghere FailureInfo = std::make_unique<FunctionImporter::ImportFailureInfo>(
454cb9a82fcSTeresa Johnson VI, Edge.second.getHotness(), Reason, 1);
455cb9a82fcSTeresa Johnson }
456bf612458SYaxun (Sam) Liu if (ForceImportAll) {
457bf612458SYaxun (Sam) Liu std::string Msg = std::string("Failed to import function ") +
458bf612458SYaxun (Sam) Liu VI.name().str() + " due to " +
459bf612458SYaxun (Sam) Liu getFailureName(Reason);
460bf612458SYaxun (Sam) Liu auto Error = make_error<StringError>(
4613c503ba0SNikita Popov Msg, make_error_code(errc::not_supported));
462bf612458SYaxun (Sam) Liu logAllUnhandledErrors(std::move(Error), errs(),
463bf612458SYaxun (Sam) Liu "Error importing module: ");
464bf612458SYaxun (Sam) Liu break;
465bf612458SYaxun (Sam) Liu } else {
466bf612458SYaxun (Sam) Liu LLVM_DEBUG(dbgs()
467bf612458SYaxun (Sam) Liu << "ignored! No qualifying callee with summary found.\n");
4687e88d0daSMehdi Amini continue;
4697e88d0daSMehdi Amini }
470bf612458SYaxun (Sam) Liu }
4712f0cc477SDavid Blaikie
4722f0cc477SDavid Blaikie // "Resolve" the summary
473d68935c5STeresa Johnson CalleeSummary = CalleeSummary->getBaseObject();
474d68935c5STeresa Johnson ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
4752d28f7aaSMehdi Amini
476bf612458SYaxun (Sam) Liu assert((ResolvedCalleeSummary->fflags().AlwaysInline || ForceImportAll ||
477b11391bbSTeresa Johnson (ResolvedCalleeSummary->instCount() <= NewThreshold)) &&
47801e32130SMehdi Amini "selectCallee() didn't honor the threshold");
47901e32130SMehdi Amini
4801b859a23STeresa Johnson auto ExportModulePath = ResolvedCalleeSummary->modulePath();
481d68935c5STeresa Johnson auto ILI = ImportList[ExportModulePath].insert(VI.getGUID());
482d68935c5STeresa Johnson // We previously decided to import this GUID definition if it was already
483d68935c5STeresa Johnson // inserted in the set of imports from the exporting module.
484d68935c5STeresa Johnson bool PreviouslyImported = !ILI.second;
485d2c234a4STeresa Johnson if (!PreviouslyImported) {
486d2c234a4STeresa Johnson NumImportedFunctionsThinLink++;
487d2c234a4STeresa Johnson if (IsHotCallsite)
488d2c234a4STeresa Johnson NumImportedHotFunctionsThinLink++;
489d2c234a4STeresa Johnson if (IsCriticalCallsite)
490d2c234a4STeresa Johnson NumImportedCriticalFunctionsThinLink++;
491d2c234a4STeresa Johnson }
492974706ebSTeresa Johnson
493bed4d9c8STeresa Johnson // Any calls/references made by this function will be marked exported
494bed4d9c8STeresa Johnson // later, in ComputeCrossModuleImport, after import decisions are
495bed4d9c8STeresa Johnson // complete, which is more efficient than adding them here.
496bed4d9c8STeresa Johnson if (ExportLists)
497bed4d9c8STeresa Johnson (*ExportLists)[ExportModulePath].insert(VI);
498d68935c5STeresa Johnson }
499d68935c5STeresa Johnson
500d68935c5STeresa Johnson auto GetAdjustedThreshold = [](unsigned Threshold, bool IsHotCallsite) {
501d68935c5STeresa Johnson // Adjust the threshold for next level of imported functions.
502d68935c5STeresa Johnson // The threshold is different for hot callsites because we can then
503d68935c5STeresa Johnson // inline chains of hot calls.
504d68935c5STeresa Johnson if (IsHotCallsite)
505d68935c5STeresa Johnson return Threshold * ImportHotInstrFactor;
506d68935c5STeresa Johnson return Threshold * ImportInstrFactor;
507d68935c5STeresa Johnson };
508d68935c5STeresa Johnson
509d68935c5STeresa Johnson const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite);
510d68935c5STeresa Johnson
511d68935c5STeresa Johnson ImportCount++;
512d2869473SPiotr Padlewski
51301e32130SMehdi Amini // Insert the newly imported function to the worklist.
514d5b701b9SEvgeny Leviant Worklist.emplace_back(ResolvedCalleeSummary, AdjThreshold);
515d450da32STeresa Johnson }
516d450da32STeresa Johnson }
517d450da32STeresa Johnson
51801e32130SMehdi Amini /// Given the list of globals defined in a module, compute the list of imports
51901e32130SMehdi Amini /// as well as the list of "exports", i.e. the list of symbols referenced from
52001e32130SMehdi Amini /// another module (that may require promotion).
ComputeImportForModule(const GVSummaryMapTy & DefinedGVSummaries,const ModuleSummaryIndex & Index,StringRef ModName,FunctionImporter::ImportMapTy & ImportList,StringMap<FunctionImporter::ExportSetTy> * ExportLists=nullptr)52101e32130SMehdi Amini static void ComputeImportForModule(
522c851d216STeresa Johnson const GVSummaryMapTy &DefinedGVSummaries, const ModuleSummaryIndex &Index,
523cb9a82fcSTeresa Johnson StringRef ModName, FunctionImporter::ImportMapTy &ImportList,
52456584bbfSEvgeniy Stepanov StringMap<FunctionImporter::ExportSetTy> *ExportLists = nullptr) {
52501e32130SMehdi Amini // Worklist contains the list of function imported in this module, for which
52601e32130SMehdi Amini // we will analyse the callees and may import further down the callgraph.
52701e32130SMehdi Amini SmallVector<EdgeInfo, 128> Worklist;
528d68935c5STeresa Johnson FunctionImporter::ImportThresholdsTy ImportThresholds;
52901e32130SMehdi Amini
53001e32130SMehdi Amini // Populate the worklist with the import for the functions in the current
53101e32130SMehdi Amini // module
53228e457bcSTeresa Johnson for (auto &GVSummary : DefinedGVSummaries) {
5337e7b13d0STeresa Johnson #ifndef NDEBUG
5347e7b13d0STeresa Johnson // FIXME: Change the GVSummaryMapTy to hold ValueInfo instead of GUID
5357e7b13d0STeresa Johnson // so this map look up (and possibly others) can be avoided.
5367e7b13d0STeresa Johnson auto VI = Index.getValueInfo(GVSummary.first);
5377e7b13d0STeresa Johnson #endif
53856584bbfSEvgeniy Stepanov if (!Index.isGlobalValueLive(GVSummary.second)) {
5397e7b13d0STeresa Johnson LLVM_DEBUG(dbgs() << "Ignores Dead GUID: " << VI << "\n");
5406c475a75STeresa Johnson continue;
5416c475a75STeresa Johnson }
542cfbd0892SPeter Collingbourne auto *FuncSummary =
543cfbd0892SPeter Collingbourne dyn_cast<FunctionSummary>(GVSummary.second->getBaseObject());
5441aafabf7SMehdi Amini if (!FuncSummary)
5451aafabf7SMehdi Amini // Skip import for global variables
5461aafabf7SMehdi Amini continue;
5477e7b13d0STeresa Johnson LLVM_DEBUG(dbgs() << "Initialize import for " << VI << "\n");
5482d28f7aaSMehdi Amini computeImportForFunction(*FuncSummary, Index, ImportInstrLimit,
5499b490f10SMehdi Amini DefinedGVSummaries, Worklist, ImportList,
550d68935c5STeresa Johnson ExportLists, ImportThresholds);
55101e32130SMehdi Amini }
55201e32130SMehdi Amini
553d2869473SPiotr Padlewski // Process the newly imported functions and add callees to the worklist.
55442418abaSMehdi Amini while (!Worklist.empty()) {
555d5b701b9SEvgeny Leviant auto GVInfo = Worklist.pop_back_val();
556d5b701b9SEvgeny Leviant auto *Summary = std::get<0>(GVInfo);
557d5b701b9SEvgeny Leviant auto Threshold = std::get<1>(GVInfo);
55842418abaSMehdi Amini
559d5b701b9SEvgeny Leviant if (auto *FS = dyn_cast<FunctionSummary>(Summary))
560d5b701b9SEvgeny Leviant computeImportForFunction(*FS, Index, Threshold, DefinedGVSummaries,
561d68935c5STeresa Johnson Worklist, ImportList, ExportLists,
562d68935c5STeresa Johnson ImportThresholds);
563d5b701b9SEvgeny Leviant else
564d5b701b9SEvgeny Leviant computeImportForReferencedGlobals(*Summary, Index, DefinedGVSummaries,
565d5b701b9SEvgeny Leviant Worklist, ImportList, ExportLists);
566c8c55170SMehdi Amini }
567cb9a82fcSTeresa Johnson
568cb9a82fcSTeresa Johnson // Print stats about functions considered but rejected for importing
569cb9a82fcSTeresa Johnson // when requested.
570cb9a82fcSTeresa Johnson if (PrintImportFailures) {
571cb9a82fcSTeresa Johnson dbgs() << "Missed imports into module " << ModName << "\n";
572cb9a82fcSTeresa Johnson for (auto &I : ImportThresholds) {
573cb9a82fcSTeresa Johnson auto &ProcessedThreshold = std::get<0>(I.second);
574cb9a82fcSTeresa Johnson auto &CalleeSummary = std::get<1>(I.second);
575cb9a82fcSTeresa Johnson auto &FailureInfo = std::get<2>(I.second);
576cb9a82fcSTeresa Johnson if (CalleeSummary)
577cb9a82fcSTeresa Johnson continue; // We are going to import.
578cb9a82fcSTeresa Johnson assert(FailureInfo);
579cb9a82fcSTeresa Johnson FunctionSummary *FS = nullptr;
580cb9a82fcSTeresa Johnson if (!FailureInfo->VI.getSummaryList().empty())
581cb9a82fcSTeresa Johnson FS = dyn_cast<FunctionSummary>(
582cb9a82fcSTeresa Johnson FailureInfo->VI.getSummaryList()[0]->getBaseObject());
583cb9a82fcSTeresa Johnson dbgs() << FailureInfo->VI
584cb9a82fcSTeresa Johnson << ": Reason = " << getFailureName(FailureInfo->Reason)
585cb9a82fcSTeresa Johnson << ", Threshold = " << ProcessedThreshold
586cb9a82fcSTeresa Johnson << ", Size = " << (FS ? (int)FS->instCount() : -1)
587cb9a82fcSTeresa Johnson << ", MaxHotness = " << getHotnessName(FailureInfo->MaxHotness)
588cb9a82fcSTeresa Johnson << ", Attempts = " << FailureInfo->Attempts << "\n";
589cb9a82fcSTeresa Johnson }
590cb9a82fcSTeresa Johnson }
59142418abaSMehdi Amini }
592ffe2e4aaSMehdi Amini
59319e23874SEugene Leviant #ifndef NDEBUG
isGlobalVarSummary(const ModuleSummaryIndex & Index,ValueInfo VI)5944ef9315cSevgeny static bool isGlobalVarSummary(const ModuleSummaryIndex &Index, ValueInfo VI) {
59519e23874SEugene Leviant auto SL = VI.getSummaryList();
5964ef9315cSevgeny return SL.empty()
5974ef9315cSevgeny ? false
5984ef9315cSevgeny : SL[0]->getSummaryKind() == GlobalValueSummary::GlobalVarKind;
59919e23874SEugene Leviant }
60019e23874SEugene Leviant
isGlobalVarSummary(const ModuleSummaryIndex & Index,GlobalValue::GUID G)6014ef9315cSevgeny static bool isGlobalVarSummary(const ModuleSummaryIndex &Index,
6024ef9315cSevgeny GlobalValue::GUID G) {
6034ef9315cSevgeny if (const auto &VI = Index.getValueInfo(G))
6044ef9315cSevgeny return isGlobalVarSummary(Index, VI);
6054ef9315cSevgeny return false;
6064ef9315cSevgeny }
60719e23874SEugene Leviant
60819e23874SEugene Leviant template <class T>
numGlobalVarSummaries(const ModuleSummaryIndex & Index,T & Cont)6091fc0da48SBenjamin Kramer static unsigned numGlobalVarSummaries(const ModuleSummaryIndex &Index,
6101fc0da48SBenjamin Kramer T &Cont) {
61119e23874SEugene Leviant unsigned NumGVS = 0;
61219e23874SEugene Leviant for (auto &V : Cont)
6134ef9315cSevgeny if (isGlobalVarSummary(Index, V))
61419e23874SEugene Leviant ++NumGVS;
61519e23874SEugene Leviant return NumGVS;
61619e23874SEugene Leviant }
61719e23874SEugene Leviant #endif
61819e23874SEugene Leviant
6198bcd01f4SFangrui Song #ifndef NDEBUG
6203d708bf5Sevgeny static bool
checkVariableImport(const ModuleSummaryIndex & Index,StringMap<FunctionImporter::ImportMapTy> & ImportLists,StringMap<FunctionImporter::ExportSetTy> & ExportLists)6213d708bf5Sevgeny checkVariableImport(const ModuleSummaryIndex &Index,
6223d708bf5Sevgeny StringMap<FunctionImporter::ImportMapTy> &ImportLists,
6233d708bf5Sevgeny StringMap<FunctionImporter::ExportSetTy> &ExportLists) {
6243d708bf5Sevgeny
6253d708bf5Sevgeny DenseSet<GlobalValue::GUID> FlattenedImports;
6263d708bf5Sevgeny
6273d708bf5Sevgeny for (auto &ImportPerModule : ImportLists)
6283d708bf5Sevgeny for (auto &ExportPerModule : ImportPerModule.second)
6293d708bf5Sevgeny FlattenedImports.insert(ExportPerModule.second.begin(),
6303d708bf5Sevgeny ExportPerModule.second.end());
6313d708bf5Sevgeny
6323d708bf5Sevgeny // Checks that all GUIDs of read/writeonly vars we see in export lists
6333d708bf5Sevgeny // are also in the import lists. Otherwise we my face linker undefs,
6343d708bf5Sevgeny // because readonly and writeonly vars are internalized in their
6353d708bf5Sevgeny // source modules.
6363d708bf5Sevgeny auto IsReadOrWriteOnlyVar = [&](StringRef ModulePath, const ValueInfo &VI) {
6373d708bf5Sevgeny auto *GVS = dyn_cast_or_null<GlobalVarSummary>(
6383d708bf5Sevgeny Index.findSummaryInModule(VI, ModulePath));
6393d708bf5Sevgeny return GVS && (Index.isReadOnly(GVS) || Index.isWriteOnly(GVS));
6403d708bf5Sevgeny };
6413d708bf5Sevgeny
6423d708bf5Sevgeny for (auto &ExportPerModule : ExportLists)
6433d708bf5Sevgeny for (auto &VI : ExportPerModule.second)
6443d708bf5Sevgeny if (!FlattenedImports.count(VI.getGUID()) &&
6453d708bf5Sevgeny IsReadOrWriteOnlyVar(ExportPerModule.first(), VI))
6463d708bf5Sevgeny return false;
6473d708bf5Sevgeny
6483d708bf5Sevgeny return true;
6493d708bf5Sevgeny }
6508bcd01f4SFangrui Song #endif
6513d708bf5Sevgeny
652c86af334STeresa Johnson /// Compute all the import and export for every module using the Index.
ComputeCrossModuleImport(const ModuleSummaryIndex & Index,const StringMap<GVSummaryMapTy> & ModuleToDefinedGVSummaries,StringMap<FunctionImporter::ImportMapTy> & ImportLists,StringMap<FunctionImporter::ExportSetTy> & ExportLists)65301e32130SMehdi Amini void llvm::ComputeCrossModuleImport(
65401e32130SMehdi Amini const ModuleSummaryIndex &Index,
655c851d216STeresa Johnson const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,
65601e32130SMehdi Amini StringMap<FunctionImporter::ImportMapTy> &ImportLists,
65756584bbfSEvgeniy Stepanov StringMap<FunctionImporter::ExportSetTy> &ExportLists) {
65801e32130SMehdi Amini // For each module that has function defined, compute the import/export lists.
6591aafabf7SMehdi Amini for (auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) {
6609b490f10SMehdi Amini auto &ImportList = ImportLists[DefinedGVSummaries.first()];
661d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Computing import for Module '"
6621aafabf7SMehdi Amini << DefinedGVSummaries.first() << "'\n");
663cb9a82fcSTeresa Johnson ComputeImportForModule(DefinedGVSummaries.second, Index,
664cb9a82fcSTeresa Johnson DefinedGVSummaries.first(), ImportList,
66556584bbfSEvgeniy Stepanov &ExportLists);
66601e32130SMehdi Amini }
66701e32130SMehdi Amini
668bed4d9c8STeresa Johnson // When computing imports we only added the variables and functions being
669bed4d9c8STeresa Johnson // imported to the export list. We also need to mark any references and calls
670bed4d9c8STeresa Johnson // they make as exported as well. We do this here, as it is more efficient
671bed4d9c8STeresa Johnson // since we may import the same values multiple times into different modules
672bed4d9c8STeresa Johnson // during the import computation.
673edddca22STeresa Johnson for (auto &ELI : ExportLists) {
674bed4d9c8STeresa Johnson FunctionImporter::ExportSetTy NewExports;
675edddca22STeresa Johnson const auto &DefinedGVSummaries =
676edddca22STeresa Johnson ModuleToDefinedGVSummaries.lookup(ELI.first());
677bed4d9c8STeresa Johnson for (auto &EI : ELI.second) {
678bed4d9c8STeresa Johnson // Find the copy defined in the exporting module so that we can mark the
679bed4d9c8STeresa Johnson // values it references in that specific definition as exported.
680bed4d9c8STeresa Johnson // Below we will add all references and called values, without regard to
681bed4d9c8STeresa Johnson // whether they are also defined in this module. We subsequently prune the
682bed4d9c8STeresa Johnson // list to only include those defined in the exporting module, see comment
683bed4d9c8STeresa Johnson // there as to why.
684bed4d9c8STeresa Johnson auto DS = DefinedGVSummaries.find(EI.getGUID());
685bed4d9c8STeresa Johnson // Anything marked exported during the import computation must have been
686bed4d9c8STeresa Johnson // defined in the exporting module.
687bed4d9c8STeresa Johnson assert(DS != DefinedGVSummaries.end());
688bed4d9c8STeresa Johnson auto *S = DS->getSecond();
689bed4d9c8STeresa Johnson S = S->getBaseObject();
690bed4d9c8STeresa Johnson if (auto *GVS = dyn_cast<GlobalVarSummary>(S)) {
691bed4d9c8STeresa Johnson // Export referenced functions and variables. We don't export/promote
692bed4d9c8STeresa Johnson // objects referenced by writeonly variable initializer, because
693bed4d9c8STeresa Johnson // we convert such variables initializers to "zeroinitializer".
694bed4d9c8STeresa Johnson // See processGlobalForThinLTO.
695bed4d9c8STeresa Johnson if (!Index.isWriteOnly(GVS))
696bed4d9c8STeresa Johnson for (const auto &VI : GVS->refs())
697bed4d9c8STeresa Johnson NewExports.insert(VI);
698bed4d9c8STeresa Johnson } else {
699bed4d9c8STeresa Johnson auto *FS = cast<FunctionSummary>(S);
700bed4d9c8STeresa Johnson for (auto &Edge : FS->calls())
701bed4d9c8STeresa Johnson NewExports.insert(Edge.first);
702bed4d9c8STeresa Johnson for (auto &Ref : FS->refs())
703bed4d9c8STeresa Johnson NewExports.insert(Ref);
704bed4d9c8STeresa Johnson }
705bed4d9c8STeresa Johnson }
706bed4d9c8STeresa Johnson // Prune list computed above to only include values defined in the exporting
707bed4d9c8STeresa Johnson // module. We do this after the above insertion since we may hit the same
708bed4d9c8STeresa Johnson // ref/call target multiple times in above loop, and it is more efficient to
709bed4d9c8STeresa Johnson // avoid a set lookup each time.
710bed4d9c8STeresa Johnson for (auto EI = NewExports.begin(); EI != NewExports.end();) {
7113d708bf5Sevgeny if (!DefinedGVSummaries.count(EI->getGUID()))
712bed4d9c8STeresa Johnson NewExports.erase(EI++);
713360f6617SBenjamin Kramer else
714360f6617SBenjamin Kramer ++EI;
715360f6617SBenjamin Kramer }
716bed4d9c8STeresa Johnson ELI.second.insert(NewExports.begin(), NewExports.end());
717edddca22STeresa Johnson }
718edddca22STeresa Johnson
7193d708bf5Sevgeny assert(checkVariableImport(Index, ImportLists, ExportLists));
72001e32130SMehdi Amini #ifndef NDEBUG
721d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Import/Export lists for " << ImportLists.size()
72201e32130SMehdi Amini << " modules:\n");
72301e32130SMehdi Amini for (auto &ModuleImports : ImportLists) {
72401e32130SMehdi Amini auto ModName = ModuleImports.first();
72501e32130SMehdi Amini auto &Exports = ExportLists[ModName];
72619e23874SEugene Leviant unsigned NumGVS = numGlobalVarSummaries(Index, Exports);
727d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "* Module " << ModName << " exports "
72819e23874SEugene Leviant << Exports.size() - NumGVS << " functions and " << NumGVS
729d34e60caSNicola Zaghen << " vars. Imports from " << ModuleImports.second.size()
730d34e60caSNicola Zaghen << " modules.\n");
73101e32130SMehdi Amini for (auto &Src : ModuleImports.second) {
73201e32130SMehdi Amini auto SrcModName = Src.first();
73319e23874SEugene Leviant unsigned NumGVSPerMod = numGlobalVarSummaries(Index, Src.second);
734d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " - " << Src.second.size() - NumGVSPerMod
73519e23874SEugene Leviant << " functions imported from " << SrcModName << "\n");
736d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " - " << NumGVSPerMod
737d34e60caSNicola Zaghen << " global vars imported from " << SrcModName << "\n");
73801e32130SMehdi Amini }
73901e32130SMehdi Amini }
74001e32130SMehdi Amini #endif
74101e32130SMehdi Amini }
74201e32130SMehdi Amini
74381bbf742STeresa Johnson #ifndef NDEBUG
dumpImportListForModule(const ModuleSummaryIndex & Index,StringRef ModulePath,FunctionImporter::ImportMapTy & ImportList)74419e23874SEugene Leviant static void dumpImportListForModule(const ModuleSummaryIndex &Index,
74519e23874SEugene Leviant StringRef ModulePath,
74681bbf742STeresa Johnson FunctionImporter::ImportMapTy &ImportList) {
747d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "* Module " << ModulePath << " imports from "
74881bbf742STeresa Johnson << ImportList.size() << " modules.\n");
74981bbf742STeresa Johnson for (auto &Src : ImportList) {
75081bbf742STeresa Johnson auto SrcModName = Src.first();
75119e23874SEugene Leviant unsigned NumGVSPerMod = numGlobalVarSummaries(Index, Src.second);
752d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " - " << Src.second.size() - NumGVSPerMod
75319e23874SEugene Leviant << " functions imported from " << SrcModName << "\n");
754d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " - " << NumGVSPerMod << " vars imported from "
75581bbf742STeresa Johnson << SrcModName << "\n");
75681bbf742STeresa Johnson }
75781bbf742STeresa Johnson }
75869b2de84STeresa Johnson #endif
75981bbf742STeresa Johnson
760c86af334STeresa Johnson /// Compute all the imports for the given module in the Index.
ComputeCrossModuleImportForModule(StringRef ModulePath,const ModuleSummaryIndex & Index,FunctionImporter::ImportMapTy & ImportList)761c86af334STeresa Johnson void llvm::ComputeCrossModuleImportForModule(
762c86af334STeresa Johnson StringRef ModulePath, const ModuleSummaryIndex &Index,
763c86af334STeresa Johnson FunctionImporter::ImportMapTy &ImportList) {
764c86af334STeresa Johnson // Collect the list of functions this module defines.
765c86af334STeresa Johnson // GUID -> Summary
766c851d216STeresa Johnson GVSummaryMapTy FunctionSummaryMap;
76728e457bcSTeresa Johnson Index.collectDefinedFunctionsForModule(ModulePath, FunctionSummaryMap);
768c86af334STeresa Johnson
769c86af334STeresa Johnson // Compute the import list for this module.
770d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Computing import for Module '" << ModulePath << "'\n");
771cb9a82fcSTeresa Johnson ComputeImportForModule(FunctionSummaryMap, Index, ModulePath, ImportList);
772c86af334STeresa Johnson
773c86af334STeresa Johnson #ifndef NDEBUG
77419e23874SEugene Leviant dumpImportListForModule(Index, ModulePath, ImportList);
77581bbf742STeresa Johnson #endif
776c86af334STeresa Johnson }
77781bbf742STeresa Johnson
77881bbf742STeresa Johnson // Mark all external summaries in Index for import into the given module.
77981bbf742STeresa Johnson // Used for distributed builds using a distributed index.
ComputeCrossModuleImportForModuleFromIndex(StringRef ModulePath,const ModuleSummaryIndex & Index,FunctionImporter::ImportMapTy & ImportList)78081bbf742STeresa Johnson void llvm::ComputeCrossModuleImportForModuleFromIndex(
78181bbf742STeresa Johnson StringRef ModulePath, const ModuleSummaryIndex &Index,
78281bbf742STeresa Johnson FunctionImporter::ImportMapTy &ImportList) {
78381bbf742STeresa Johnson for (auto &GlobalList : Index) {
78481bbf742STeresa Johnson // Ignore entries for undefined references.
78581bbf742STeresa Johnson if (GlobalList.second.SummaryList.empty())
78681bbf742STeresa Johnson continue;
78781bbf742STeresa Johnson
78881bbf742STeresa Johnson auto GUID = GlobalList.first;
78981bbf742STeresa Johnson assert(GlobalList.second.SummaryList.size() == 1 &&
79081bbf742STeresa Johnson "Expected individual combined index to have one summary per GUID");
79181bbf742STeresa Johnson auto &Summary = GlobalList.second.SummaryList[0];
79281bbf742STeresa Johnson // Skip the summaries for the importing module. These are included to
79381bbf742STeresa Johnson // e.g. record required linkage changes.
79481bbf742STeresa Johnson if (Summary->modulePath() == ModulePath)
79581bbf742STeresa Johnson continue;
796d68935c5STeresa Johnson // Add an entry to provoke importing by thinBackend.
797d68935c5STeresa Johnson ImportList[Summary->modulePath()].insert(GUID);
79881bbf742STeresa Johnson }
79981bbf742STeresa Johnson #ifndef NDEBUG
80019e23874SEugene Leviant dumpImportListForModule(Index, ModulePath, ImportList);
801c86af334STeresa Johnson #endif
802c86af334STeresa Johnson }
803c86af334STeresa Johnson
80496cb97c4STeresa Johnson // For SamplePGO, the indirect call targets for local functions will
80596cb97c4STeresa Johnson // have its original name annotated in profile. We try to find the
80696cb97c4STeresa Johnson // corresponding PGOFuncName as the GUID, and fix up the edges
80796cb97c4STeresa Johnson // accordingly.
updateValueInfoForIndirectCalls(ModuleSummaryIndex & Index,FunctionSummary * FS)80896cb97c4STeresa Johnson void updateValueInfoForIndirectCalls(ModuleSummaryIndex &Index,
80996cb97c4STeresa Johnson FunctionSummary *FS) {
81096cb97c4STeresa Johnson for (auto &EI : FS->mutableCalls()) {
81196cb97c4STeresa Johnson if (!EI.first.getSummaryList().empty())
81296cb97c4STeresa Johnson continue;
81396cb97c4STeresa Johnson auto GUID = Index.getGUIDFromOriginalID(EI.first.getGUID());
81496cb97c4STeresa Johnson if (GUID == 0)
81596cb97c4STeresa Johnson continue;
81696cb97c4STeresa Johnson // Update the edge to point directly to the correct GUID.
81796cb97c4STeresa Johnson auto VI = Index.getValueInfo(GUID);
81896cb97c4STeresa Johnson if (llvm::any_of(
81996cb97c4STeresa Johnson VI.getSummaryList(),
82096cb97c4STeresa Johnson [&](const std::unique_ptr<GlobalValueSummary> &SummaryPtr) {
82196cb97c4STeresa Johnson // The mapping from OriginalId to GUID may return a GUID
82296cb97c4STeresa Johnson // that corresponds to a static variable. Filter it out here.
82396cb97c4STeresa Johnson // This can happen when
82496cb97c4STeresa Johnson // 1) There is a call to a library function which is not defined
82596cb97c4STeresa Johnson // in the index.
82696cb97c4STeresa Johnson // 2) There is a static variable with the OriginalGUID identical
82796cb97c4STeresa Johnson // to the GUID of the library function in 1);
82896cb97c4STeresa Johnson // When this happens the static variable in 2) will be found,
82996cb97c4STeresa Johnson // which needs to be filtered out.
83096cb97c4STeresa Johnson return SummaryPtr->getSummaryKind() ==
83196cb97c4STeresa Johnson GlobalValueSummary::GlobalVarKind;
83296cb97c4STeresa Johnson }))
83396cb97c4STeresa Johnson continue;
83496cb97c4STeresa Johnson EI.first = VI;
83596cb97c4STeresa Johnson }
83696cb97c4STeresa Johnson }
83796cb97c4STeresa Johnson
updateIndirectCalls(ModuleSummaryIndex & Index)83896cb97c4STeresa Johnson void llvm::updateIndirectCalls(ModuleSummaryIndex &Index) {
83996cb97c4STeresa Johnson for (const auto &Entry : Index) {
84096cb97c4STeresa Johnson for (auto &S : Entry.second.SummaryList) {
84196cb97c4STeresa Johnson if (auto *FS = dyn_cast<FunctionSummary>(S.get()))
84296cb97c4STeresa Johnson updateValueInfoForIndirectCalls(Index, FS);
84396cb97c4STeresa Johnson }
84496cb97c4STeresa Johnson }
84596cb97c4STeresa Johnson }
84696cb97c4STeresa Johnson
computeDeadSymbolsAndUpdateIndirectCalls(ModuleSummaryIndex & Index,const DenseSet<GlobalValue::GUID> & GUIDPreservedSymbols,function_ref<PrevailingType (GlobalValue::GUID)> isPrevailing)84796cb97c4STeresa Johnson void llvm::computeDeadSymbolsAndUpdateIndirectCalls(
84856584bbfSEvgeniy Stepanov ModuleSummaryIndex &Index,
849eaf5172cSGeorge Rimar const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
850eaf5172cSGeorge Rimar function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing) {
85156584bbfSEvgeniy Stepanov assert(!Index.withGlobalValueDeadStripping());
85296cb97c4STeresa Johnson if (!ComputeDead ||
8536c475a75STeresa Johnson // Don't do anything when nothing is live, this is friendly with tests.
85496cb97c4STeresa Johnson GUIDPreservedSymbols.empty()) {
85596cb97c4STeresa Johnson // Still need to update indirect calls.
85696cb97c4STeresa Johnson updateIndirectCalls(Index);
85756584bbfSEvgeniy Stepanov return;
85896cb97c4STeresa Johnson }
85956584bbfSEvgeniy Stepanov unsigned LiveSymbols = 0;
8609667b91bSPeter Collingbourne SmallVector<ValueInfo, 128> Worklist;
8619667b91bSPeter Collingbourne Worklist.reserve(GUIDPreservedSymbols.size() * 2);
8629667b91bSPeter Collingbourne for (auto GUID : GUIDPreservedSymbols) {
8639667b91bSPeter Collingbourne ValueInfo VI = Index.getValueInfo(GUID);
8649667b91bSPeter Collingbourne if (!VI)
8659667b91bSPeter Collingbourne continue;
86656584bbfSEvgeniy Stepanov for (auto &S : VI.getSummaryList())
86756584bbfSEvgeniy Stepanov S->setLive(true);
8686c475a75STeresa Johnson }
86956584bbfSEvgeniy Stepanov
8706c475a75STeresa Johnson // Add values flagged in the index as live roots to the worklist.
8717e7b13d0STeresa Johnson for (const auto &Entry : Index) {
8727e7b13d0STeresa Johnson auto VI = Index.getValueInfo(Entry);
87396cb97c4STeresa Johnson for (auto &S : Entry.second.SummaryList) {
87496cb97c4STeresa Johnson if (auto *FS = dyn_cast<FunctionSummary>(S.get()))
87596cb97c4STeresa Johnson updateValueInfoForIndirectCalls(Index, FS);
87656584bbfSEvgeniy Stepanov if (S->isLive()) {
8777e7b13d0STeresa Johnson LLVM_DEBUG(dbgs() << "Live root: " << VI << "\n");
8787e7b13d0STeresa Johnson Worklist.push_back(VI);
87956584bbfSEvgeniy Stepanov ++LiveSymbols;
88056584bbfSEvgeniy Stepanov break;
8816c475a75STeresa Johnson }
8827e7b13d0STeresa Johnson }
88396cb97c4STeresa Johnson }
8846c475a75STeresa Johnson
88556584bbfSEvgeniy Stepanov // Make value live and add it to the worklist if it was not live before.
886ea314fd4STeresa Johnson auto visit = [&](ValueInfo VI, bool IsAliasee) {
8871958083dSTeresa Johnson // FIXME: If we knew which edges were created for indirect call profiles,
8881958083dSTeresa Johnson // we could skip them here. Any that are live should be reached via
8891958083dSTeresa Johnson // other edges, e.g. reference edges. Otherwise, using a profile collected
8901958083dSTeresa Johnson // on a slightly different binary might provoke preserving, importing
8911958083dSTeresa Johnson // and ultimately promoting calls to functions not linked into this
8921958083dSTeresa Johnson // binary, which increases the binary size unnecessarily. Note that
8931958083dSTeresa Johnson // if this code changes, the importer needs to change so that edges
8941958083dSTeresa Johnson // to functions marked dead are skipped.
89533e3b4b9SXin Tong
8965b2f6a1bSTeresa Johnson if (llvm::any_of(VI.getSummaryList(),
89733e3b4b9SXin Tong [](const std::unique_ptr<llvm::GlobalValueSummary> &S) {
89833e3b4b9SXin Tong return S->isLive();
89933e3b4b9SXin Tong }))
900f625118eSTeresa Johnson return;
901eaf5172cSGeorge Rimar
902aab60006SVlad Tsyrklevich // We only keep live symbols that are known to be non-prevailing if any are
903bfdad33bSXin Tong // available_externally, linkonceodr, weakodr. Those symbols are discarded
904bfdad33bSXin Tong // later in the EliminateAvailableExternally pass and setting them to
905bfdad33bSXin Tong // not-live could break downstreams users of liveness information (PR36483)
906bfdad33bSXin Tong // or limit optimization opportunities.
907aab60006SVlad Tsyrklevich if (isPrevailing(VI.getGUID()) == PrevailingType::No) {
908bfdad33bSXin Tong bool KeepAliveLinkage = false;
909aab60006SVlad Tsyrklevich bool Interposable = false;
910aab60006SVlad Tsyrklevich for (auto &S : VI.getSummaryList()) {
911bfdad33bSXin Tong if (S->linkage() == GlobalValue::AvailableExternallyLinkage ||
912bfdad33bSXin Tong S->linkage() == GlobalValue::WeakODRLinkage ||
913bfdad33bSXin Tong S->linkage() == GlobalValue::LinkOnceODRLinkage)
914bfdad33bSXin Tong KeepAliveLinkage = true;
915aab60006SVlad Tsyrklevich else if (GlobalValue::isInterposableLinkage(S->linkage()))
916aab60006SVlad Tsyrklevich Interposable = true;
917aab60006SVlad Tsyrklevich }
918aab60006SVlad Tsyrklevich
919ea314fd4STeresa Johnson if (!IsAliasee) {
920bfdad33bSXin Tong if (!KeepAliveLinkage)
921eaf5172cSGeorge Rimar return;
922eaf5172cSGeorge Rimar
923aab60006SVlad Tsyrklevich if (Interposable)
924bfdad33bSXin Tong report_fatal_error(
925ea314fd4STeresa Johnson "Interposable and available_externally/linkonce_odr/weak_odr "
926ea314fd4STeresa Johnson "symbol");
927ea314fd4STeresa Johnson }
928aab60006SVlad Tsyrklevich }
929aab60006SVlad Tsyrklevich
930f625118eSTeresa Johnson for (auto &S : VI.getSummaryList())
93156584bbfSEvgeniy Stepanov S->setLive(true);
93256584bbfSEvgeniy Stepanov ++LiveSymbols;
93356584bbfSEvgeniy Stepanov Worklist.push_back(VI);
93456584bbfSEvgeniy Stepanov };
93556584bbfSEvgeniy Stepanov
9366c475a75STeresa Johnson while (!Worklist.empty()) {
9379667b91bSPeter Collingbourne auto VI = Worklist.pop_back_val();
9389667b91bSPeter Collingbourne for (auto &Summary : VI.getSummaryList()) {
9395b2f6a1bSTeresa Johnson if (auto *AS = dyn_cast<AliasSummary>(Summary.get())) {
9405b2f6a1bSTeresa Johnson // If this is an alias, visit the aliasee VI to ensure that all copies
9415b2f6a1bSTeresa Johnson // are marked live and it is added to the worklist for further
9425b2f6a1bSTeresa Johnson // processing of its references.
943ea314fd4STeresa Johnson visit(AS->getAliaseeVI(), true);
9445b2f6a1bSTeresa Johnson continue;
9455b2f6a1bSTeresa Johnson }
9465b2f6a1bSTeresa Johnson for (auto Ref : Summary->refs())
947ea314fd4STeresa Johnson visit(Ref, false);
9485b2f6a1bSTeresa Johnson if (auto *FS = dyn_cast<FunctionSummary>(Summary.get()))
94956584bbfSEvgeniy Stepanov for (auto Call : FS->calls())
950ea314fd4STeresa Johnson visit(Call.first, false);
9516c475a75STeresa Johnson }
9526c475a75STeresa Johnson }
95356584bbfSEvgeniy Stepanov Index.setWithGlobalValueDeadStripping();
95456584bbfSEvgeniy Stepanov
95556584bbfSEvgeniy Stepanov unsigned DeadSymbols = Index.size() - LiveSymbols;
956d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << LiveSymbols << " symbols Live, and " << DeadSymbols
95756584bbfSEvgeniy Stepanov << " symbols Dead \n");
95856584bbfSEvgeniy Stepanov NumDeadSymbols += DeadSymbols;
95956584bbfSEvgeniy Stepanov NumLiveSymbols += LiveSymbols;
9606c475a75STeresa Johnson }
9616c475a75STeresa Johnson
962bf46e741SEugene Leviant // Compute dead symbols and propagate constants in combined index.
computeDeadSymbolsWithConstProp(ModuleSummaryIndex & Index,const DenseSet<GlobalValue::GUID> & GUIDPreservedSymbols,function_ref<PrevailingType (GlobalValue::GUID)> isPrevailing,bool ImportEnabled)963bf46e741SEugene Leviant void llvm::computeDeadSymbolsWithConstProp(
964bf46e741SEugene Leviant ModuleSummaryIndex &Index,
965bf46e741SEugene Leviant const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
966bf46e741SEugene Leviant function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing,
967bf46e741SEugene Leviant bool ImportEnabled) {
96896cb97c4STeresa Johnson computeDeadSymbolsAndUpdateIndirectCalls(Index, GUIDPreservedSymbols,
96996cb97c4STeresa Johnson isPrevailing);
97054a3c2a8STeresa Johnson if (ImportEnabled)
9713aef3528SEugene Leviant Index.propagateAttributes(GUIDPreservedSymbols);
972bf46e741SEugene Leviant }
973bf46e741SEugene Leviant
97484174c37STeresa Johnson /// Compute the set of summaries needed for a ThinLTO backend compilation of
97584174c37STeresa Johnson /// \p ModulePath.
gatherImportedSummariesForModule(StringRef ModulePath,const StringMap<GVSummaryMapTy> & ModuleToDefinedGVSummaries,const FunctionImporter::ImportMapTy & ImportList,std::map<std::string,GVSummaryMapTy> & ModuleToSummariesForIndex)97684174c37STeresa Johnson void llvm::gatherImportedSummariesForModule(
97784174c37STeresa Johnson StringRef ModulePath,
97884174c37STeresa Johnson const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,
979cdbcbf74SMehdi Amini const FunctionImporter::ImportMapTy &ImportList,
98084174c37STeresa Johnson std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
98184174c37STeresa Johnson // Include all summaries from the importing module.
982adcd0268SBenjamin Kramer ModuleToSummariesForIndex[std::string(ModulePath)] =
98384174c37STeresa Johnson ModuleToDefinedGVSummaries.lookup(ModulePath);
98484174c37STeresa Johnson // Include summaries for imports.
98588c491ddSMehdi Amini for (auto &ILI : ImportList) {
986adcd0268SBenjamin Kramer auto &SummariesForIndex =
987adcd0268SBenjamin Kramer ModuleToSummariesForIndex[std::string(ILI.first())];
98884174c37STeresa Johnson const auto &DefinedGVSummaries =
98984174c37STeresa Johnson ModuleToDefinedGVSummaries.lookup(ILI.first());
99084174c37STeresa Johnson for (auto &GI : ILI.second) {
991d68935c5STeresa Johnson const auto &DS = DefinedGVSummaries.find(GI);
99284174c37STeresa Johnson assert(DS != DefinedGVSummaries.end() &&
99384174c37STeresa Johnson "Expected a defined summary for imported global value");
994d68935c5STeresa Johnson SummariesForIndex[GI] = DS->second;
99584174c37STeresa Johnson }
99684174c37STeresa Johnson }
99784174c37STeresa Johnson }
99884174c37STeresa Johnson
9998570fe47STeresa Johnson /// Emit the files \p ModulePath will import from into \p OutputFilename.
EmitImportsFiles(StringRef ModulePath,StringRef OutputFilename,const std::map<std::string,GVSummaryMapTy> & ModuleToSummariesForIndex)1000c0320ef4STeresa Johnson std::error_code llvm::EmitImportsFiles(
1001c0320ef4STeresa Johnson StringRef ModulePath, StringRef OutputFilename,
1002c0320ef4STeresa Johnson const std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
10038570fe47STeresa Johnson std::error_code EC;
1004d9b948b6SFangrui Song raw_fd_ostream ImportsOS(OutputFilename, EC, sys::fs::OpenFlags::OF_None);
10058570fe47STeresa Johnson if (EC)
10068570fe47STeresa Johnson return EC;
1007c0320ef4STeresa Johnson for (auto &ILI : ModuleToSummariesForIndex)
1008c0320ef4STeresa Johnson // The ModuleToSummariesForIndex map includes an entry for the current
1009c0320ef4STeresa Johnson // Module (needed for writing out the index files). We don't want to
1010c0320ef4STeresa Johnson // include it in the imports file, however, so filter it out.
1011c0320ef4STeresa Johnson if (ILI.first != ModulePath)
1012c0320ef4STeresa Johnson ImportsOS << ILI.first << "\n";
10138570fe47STeresa Johnson return std::error_code();
10148570fe47STeresa Johnson }
10158570fe47STeresa Johnson
convertToDeclaration(GlobalValue & GV)10165a95c477STeresa Johnson bool llvm::convertToDeclaration(GlobalValue &GV) {
1017d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Converting to a declaration: `" << GV.getName()
1018d34e60caSNicola Zaghen << "\n");
10194566c6dbSTeresa Johnson if (Function *F = dyn_cast<Function>(&GV)) {
10204566c6dbSTeresa Johnson F->deleteBody();
10214566c6dbSTeresa Johnson F->clearMetadata();
10227873669bSPeter Collingbourne F->setComdat(nullptr);
10234566c6dbSTeresa Johnson } else if (GlobalVariable *V = dyn_cast<GlobalVariable>(&GV)) {
10244566c6dbSTeresa Johnson V->setInitializer(nullptr);
10254566c6dbSTeresa Johnson V->setLinkage(GlobalValue::ExternalLinkage);
10264566c6dbSTeresa Johnson V->clearMetadata();
10277873669bSPeter Collingbourne V->setComdat(nullptr);
10285a95c477STeresa Johnson } else {
10295a95c477STeresa Johnson GlobalValue *NewGV;
10305a95c477STeresa Johnson if (GV.getValueType()->isFunctionTy())
10315a95c477STeresa Johnson NewGV =
10325a95c477STeresa Johnson Function::Create(cast<FunctionType>(GV.getValueType()),
1033f920da00SDylan McKay GlobalValue::ExternalLinkage, GV.getAddressSpace(),
1034f920da00SDylan McKay "", GV.getParent());
10355a95c477STeresa Johnson else
10365a95c477STeresa Johnson NewGV =
10375a95c477STeresa Johnson new GlobalVariable(*GV.getParent(), GV.getValueType(),
10385a95c477STeresa Johnson /*isConstant*/ false, GlobalValue::ExternalLinkage,
10395a95c477STeresa Johnson /*init*/ nullptr, "",
10405a95c477STeresa Johnson /*insertbefore*/ nullptr, GV.getThreadLocalMode(),
10415a95c477STeresa Johnson GV.getType()->getAddressSpace());
10425a95c477STeresa Johnson NewGV->takeName(&GV);
10435a95c477STeresa Johnson GV.replaceAllUsesWith(NewGV);
10445a95c477STeresa Johnson return false;
10455a95c477STeresa Johnson }
1046952ee0dfSFangrui Song if (!GV.isImplicitDSOLocal())
1047952ee0dfSFangrui Song GV.setDSOLocal(false);
10485a95c477STeresa Johnson return true;
1049eaf5172cSGeorge Rimar }
10504566c6dbSTeresa Johnson
thinLTOFinalizeInModule(Module & TheModule,const GVSummaryMapTy & DefinedGlobals,bool PropagateAttrs)105120faf789Smodimo void llvm::thinLTOFinalizeInModule(Module &TheModule,
105220faf789Smodimo const GVSummaryMapTy &DefinedGlobals,
105320faf789Smodimo bool PropagateAttrs) {
105420faf789Smodimo auto FinalizeInModule = [&](GlobalValue &GV, bool Propagate = false) {
105504c9a2d6STeresa Johnson // See if the global summary analysis computed a new resolved linkage.
105604c9a2d6STeresa Johnson const auto &GS = DefinedGlobals.find(GV.getGUID());
105704c9a2d6STeresa Johnson if (GS == DefinedGlobals.end())
105804c9a2d6STeresa Johnson return;
105920faf789Smodimo
106020faf789Smodimo if (Propagate)
106120faf789Smodimo if (FunctionSummary *FS = dyn_cast<FunctionSummary>(GS->second)) {
106220faf789Smodimo if (Function *F = dyn_cast<Function>(&GV)) {
106320faf789Smodimo // TODO: propagate ReadNone and ReadOnly.
106420faf789Smodimo if (FS->fflags().ReadNone && !F->doesNotAccessMemory())
106520faf789Smodimo F->setDoesNotAccessMemory();
106620faf789Smodimo
106720faf789Smodimo if (FS->fflags().ReadOnly && !F->onlyReadsMemory())
106820faf789Smodimo F->setOnlyReadsMemory();
106920faf789Smodimo
107020faf789Smodimo if (FS->fflags().NoRecurse && !F->doesNotRecurse())
107120faf789Smodimo F->setDoesNotRecurse();
107220faf789Smodimo
107320faf789Smodimo if (FS->fflags().NoUnwind && !F->doesNotThrow())
107420faf789Smodimo F->setDoesNotThrow();
107520faf789Smodimo }
107620faf789Smodimo }
107720faf789Smodimo
107804c9a2d6STeresa Johnson auto NewLinkage = GS->second->linkage();
1079e61652a3SPirama Arumuga Nainar if (GlobalValue::isLocalLinkage(GV.getLinkage()) ||
1080e5dd30f7SEugene Leviant // Don't internalize anything here, because the code below
1081e5dd30f7SEugene Leviant // lacks necessary correctness checks. Leave this job to
1082e5dd30f7SEugene Leviant // LLVM 'internalize' pass.
10830f418677SEugene Leviant GlobalValue::isLocalLinkage(NewLinkage) ||
1084e61652a3SPirama Arumuga Nainar // In case it was dead and already converted to declaration.
1085e61652a3SPirama Arumuga Nainar GV.isDeclaration())
10866a5fbe52SDavide Italiano return;
1087ea314fd4STeresa Johnson
108854fb3ca9SFangrui Song // Set the potentially more constraining visibility computed from summaries.
108954fb3ca9SFangrui Song // The DefaultVisibility condition is because older GlobalValueSummary does
109054fb3ca9SFangrui Song // not record DefaultVisibility and we don't want to change protected/hidden
109154fb3ca9SFangrui Song // to default.
109254fb3ca9SFangrui Song if (GS->second->getVisibility() != GlobalValue::DefaultVisibility)
109354fb3ca9SFangrui Song GV.setVisibility(GS->second->getVisibility());
109454fb3ca9SFangrui Song
109554fb3ca9SFangrui Song if (NewLinkage == GV.getLinkage())
109654fb3ca9SFangrui Song return;
109754fb3ca9SFangrui Song
10984566c6dbSTeresa Johnson // Check for a non-prevailing def that has interposable linkage
10994566c6dbSTeresa Johnson // (e.g. non-odr weak or linkonce). In that case we can't simply
11004566c6dbSTeresa Johnson // convert to available_externally, since it would lose the
11014566c6dbSTeresa Johnson // interposable property and possibly get inlined. Simply drop
11024566c6dbSTeresa Johnson // the definition in that case.
11034566c6dbSTeresa Johnson if (GlobalValue::isAvailableExternallyLinkage(NewLinkage) &&
11045a95c477STeresa Johnson GlobalValue::isInterposableLinkage(GV.getLinkage())) {
11055a95c477STeresa Johnson if (!convertToDeclaration(GV))
11065a95c477STeresa Johnson // FIXME: Change this to collect replaced GVs and later erase
1107e61652a3SPirama Arumuga Nainar // them from the parent module once thinLTOResolvePrevailingGUID is
11085a95c477STeresa Johnson // changed to enable this for aliases.
11095a95c477STeresa Johnson llvm_unreachable("Expected GV to be converted");
11105a95c477STeresa Johnson } else {
111137b80122STeresa Johnson // If all copies of the original symbol had global unnamed addr and
1112dd29597eSJez Ng // linkonce_odr linkage, or if all of them had local unnamed addr linkage
1113dd29597eSJez Ng // and are constants, then it should be an auto hide symbol. In that case
1114dd29597eSJez Ng // the thin link would have marked it as CanAutoHide. Add hidden
1115dd29597eSJez Ng // visibility to the symbol to preserve the property.
111637b80122STeresa Johnson if (NewLinkage == GlobalValue::WeakODRLinkage &&
111737b80122STeresa Johnson GS->second->canAutoHide()) {
1118dd29597eSJez Ng assert(GV.canBeOmittedFromSymbolTable());
111933ba93c2SSteven Wu GV.setVisibility(GlobalValue::HiddenVisibility);
112037b80122STeresa Johnson }
112133ba93c2SSteven Wu
1122d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "ODR fixing up linkage for `" << GV.getName()
1123d34e60caSNicola Zaghen << "` from " << GV.getLinkage() << " to " << NewLinkage
1124d34e60caSNicola Zaghen << "\n");
112504c9a2d6STeresa Johnson GV.setLinkage(NewLinkage);
11264566c6dbSTeresa Johnson }
11274566c6dbSTeresa Johnson // Remove declarations from comdats, including available_externally
11286107a419STeresa Johnson // as this is a declaration for the linker, and will be dropped eventually.
11296107a419STeresa Johnson // It is illegal for comdats to contain declarations.
11306107a419STeresa Johnson auto *GO = dyn_cast_or_null<GlobalObject>(&GV);
11314566c6dbSTeresa Johnson if (GO && GO->isDeclarationForLinker() && GO->hasComdat())
11326107a419STeresa Johnson GO->setComdat(nullptr);
113304c9a2d6STeresa Johnson };
113404c9a2d6STeresa Johnson
113504c9a2d6STeresa Johnson // Process functions and global now
113604c9a2d6STeresa Johnson for (auto &GV : TheModule)
113720faf789Smodimo FinalizeInModule(GV, PropagateAttrs);
113804c9a2d6STeresa Johnson for (auto &GV : TheModule.globals())
113920faf789Smodimo FinalizeInModule(GV);
114004c9a2d6STeresa Johnson for (auto &GV : TheModule.aliases())
114120faf789Smodimo FinalizeInModule(GV);
114204c9a2d6STeresa Johnson }
114304c9a2d6STeresa Johnson
114404c9a2d6STeresa Johnson /// Run internalization on \p TheModule based on symmary analysis.
thinLTOInternalizeModule(Module & TheModule,const GVSummaryMapTy & DefinedGlobals)114504c9a2d6STeresa Johnson void llvm::thinLTOInternalizeModule(Module &TheModule,
114604c9a2d6STeresa Johnson const GVSummaryMapTy &DefinedGlobals) {
114704c9a2d6STeresa Johnson // Declare a callback for the internalize pass that will ask for every
114804c9a2d6STeresa Johnson // candidate GlobalValue if it can be internalized or not.
114904c9a2d6STeresa Johnson auto MustPreserveGV = [&](const GlobalValue &GV) -> bool {
1150*30402720SSchrodinger ZHU Yifan // It may be the case that GV is on a chain of an ifunc, its alias and
1151*30402720SSchrodinger ZHU Yifan // subsequent aliases. In this case, the summary for the value is not
1152*30402720SSchrodinger ZHU Yifan // available.
1153*30402720SSchrodinger ZHU Yifan if (isa<GlobalIFunc>(&GV) ||
1154*30402720SSchrodinger ZHU Yifan (isa<GlobalAlias>(&GV) &&
1155*30402720SSchrodinger ZHU Yifan isa<GlobalIFunc>(cast<GlobalAlias>(&GV)->getAliaseeObject())))
1156*30402720SSchrodinger ZHU Yifan return true;
1157*30402720SSchrodinger ZHU Yifan
115804c9a2d6STeresa Johnson // Lookup the linkage recorded in the summaries during global analysis.
1159c3d677f9SPeter Collingbourne auto GS = DefinedGlobals.find(GV.getGUID());
116004c9a2d6STeresa Johnson if (GS == DefinedGlobals.end()) {
116104c9a2d6STeresa Johnson // Must have been promoted (possibly conservatively). Find original
116204c9a2d6STeresa Johnson // name so that we can access the correct summary and see if it can
116304c9a2d6STeresa Johnson // be internalized again.
116404c9a2d6STeresa Johnson // FIXME: Eventually we should control promotion instead of promoting
116504c9a2d6STeresa Johnson // and internalizing again.
116604c9a2d6STeresa Johnson StringRef OrigName =
116704c9a2d6STeresa Johnson ModuleSummaryIndex::getOriginalNameBeforePromote(GV.getName());
116804c9a2d6STeresa Johnson std::string OrigId = GlobalValue::getGlobalIdentifier(
116904c9a2d6STeresa Johnson OrigName, GlobalValue::InternalLinkage,
117004c9a2d6STeresa Johnson TheModule.getSourceFileName());
1171c3d677f9SPeter Collingbourne GS = DefinedGlobals.find(GlobalValue::getGUID(OrigId));
11727ab1f692STeresa Johnson if (GS == DefinedGlobals.end()) {
11737ab1f692STeresa Johnson // Also check the original non-promoted non-globalized name. In some
11747ab1f692STeresa Johnson // cases a preempted weak value is linked in as a local copy because
11757ab1f692STeresa Johnson // it is referenced by an alias (IRLinker::linkGlobalValueProto).
11767ab1f692STeresa Johnson // In that case, since it was originally not a local value, it was
11777ab1f692STeresa Johnson // recorded in the index using the original name.
11787ab1f692STeresa Johnson // FIXME: This may not be needed once PR27866 is fixed.
1179c3d677f9SPeter Collingbourne GS = DefinedGlobals.find(GlobalValue::getGUID(OrigName));
118004c9a2d6STeresa Johnson assert(GS != DefinedGlobals.end());
11817ab1f692STeresa Johnson }
1182c3d677f9SPeter Collingbourne }
1183c3d677f9SPeter Collingbourne return !GlobalValue::isLocalLinkage(GS->second->linkage());
118404c9a2d6STeresa Johnson };
118504c9a2d6STeresa Johnson
118604c9a2d6STeresa Johnson // FIXME: See if we can just internalize directly here via linkage changes
118704c9a2d6STeresa Johnson // based on the index, rather than invoking internalizeModule.
1188e9ea08a0SEugene Zelenko internalizeModule(TheModule, MustPreserveGV);
118904c9a2d6STeresa Johnson }
119004c9a2d6STeresa Johnson
119181bbf742STeresa Johnson /// Make alias a clone of its aliasee.
replaceAliasWithAliasee(Module * SrcModule,GlobalAlias * GA)119281bbf742STeresa Johnson static Function *replaceAliasWithAliasee(Module *SrcModule, GlobalAlias *GA) {
119340ec1c0fSItay Bookstein Function *Fn = cast<Function>(GA->getAliaseeObject());
119481bbf742STeresa Johnson
119581bbf742STeresa Johnson ValueToValueMapTy VMap;
119681bbf742STeresa Johnson Function *NewFn = CloneFunction(Fn, VMap);
11975b2088d1STeresa Johnson // Clone should use the original alias's linkage, visibility and name, and we
11985b2088d1STeresa Johnson // ensure all uses of alias instead use the new clone (casted if necessary).
119981bbf742STeresa Johnson NewFn->setLinkage(GA->getLinkage());
12005b2088d1STeresa Johnson NewFn->setVisibility(GA->getVisibility());
120181bbf742STeresa Johnson GA->replaceAllUsesWith(ConstantExpr::getBitCast(NewFn, GA->getType()));
120281bbf742STeresa Johnson NewFn->takeName(GA);
120381bbf742STeresa Johnson return NewFn;
120481bbf742STeresa Johnson }
120581bbf742STeresa Johnson
1206bf46e741SEugene Leviant // Internalize values that we marked with specific attribute
1207bf46e741SEugene Leviant // in processGlobalForThinLTO.
internalizeGVsAfterImport(Module & M)12083aef3528SEugene Leviant static void internalizeGVsAfterImport(Module &M) {
1209bf46e741SEugene Leviant for (auto &GV : M.globals())
1210bf46e741SEugene Leviant // Skip GVs which have been converted to declarations
1211bf46e741SEugene Leviant // by dropDeadSymbols.
1212bf46e741SEugene Leviant if (!GV.isDeclaration() && GV.hasAttribute("thinlto-internalize")) {
1213bf46e741SEugene Leviant GV.setLinkage(GlobalValue::InternalLinkage);
1214bf46e741SEugene Leviant GV.setVisibility(GlobalValue::DefaultVisibility);
1215bf46e741SEugene Leviant }
1216bf46e741SEugene Leviant }
1217bf46e741SEugene Leviant
1218c8c55170SMehdi Amini // Automatically import functions in Module \p DestModule based on the summaries
1219c8c55170SMehdi Amini // index.
importFunctions(Module & DestModule,const FunctionImporter::ImportMapTy & ImportList)12207f00d0a1SPeter Collingbourne Expected<bool> FunctionImporter::importFunctions(
122166043797SAdrian Prantl Module &DestModule, const FunctionImporter::ImportMapTy &ImportList) {
1222d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Starting import for Module "
1223311fef6eSMehdi Amini << DestModule.getModuleIdentifier() << "\n");
122419e23874SEugene Leviant unsigned ImportedCount = 0, ImportedGVCount = 0;
1225c8c55170SMehdi Amini
12266d8f817fSPeter Collingbourne IRMover Mover(DestModule);
12277e88d0daSMehdi Amini // Do the actual import of functions now, one Module at a time
122801e32130SMehdi Amini std::set<StringRef> ModuleNameOrderedList;
122901e32130SMehdi Amini for (auto &FunctionsToImportPerModule : ImportList) {
123001e32130SMehdi Amini ModuleNameOrderedList.insert(FunctionsToImportPerModule.first());
123101e32130SMehdi Amini }
123201e32130SMehdi Amini for (auto &Name : ModuleNameOrderedList) {
12337e88d0daSMehdi Amini // Get the module for the import
123401e32130SMehdi Amini const auto &FunctionsToImportPerModule = ImportList.find(Name);
123501e32130SMehdi Amini assert(FunctionsToImportPerModule != ImportList.end());
1236d9445c49SPeter Collingbourne Expected<std::unique_ptr<Module>> SrcModuleOrErr = ModuleLoader(Name);
1237d9445c49SPeter Collingbourne if (!SrcModuleOrErr)
1238d9445c49SPeter Collingbourne return SrcModuleOrErr.takeError();
1239d9445c49SPeter Collingbourne std::unique_ptr<Module> SrcModule = std::move(*SrcModuleOrErr);
12407e88d0daSMehdi Amini assert(&DestModule.getContext() == &SrcModule->getContext() &&
12417e88d0daSMehdi Amini "Context mismatch");
12427e88d0daSMehdi Amini
12436cba37ceSTeresa Johnson // If modules were created with lazy metadata loading, materialize it
12446cba37ceSTeresa Johnson // now, before linking it (otherwise this will be a noop).
12457f00d0a1SPeter Collingbourne if (Error Err = SrcModule->materializeMetadata())
1246c55cf4afSBill Wendling return std::move(Err);
1247e5a61917STeresa Johnson
124801e32130SMehdi Amini auto &ImportGUIDs = FunctionsToImportPerModule->second;
124901e32130SMehdi Amini // Find the globals to import
12506d8f817fSPeter Collingbourne SetVector<GlobalValue *> GlobalsToImport;
12511f685e01SPiotr Padlewski for (Function &F : *SrcModule) {
12521f685e01SPiotr Padlewski if (!F.hasName())
12530beb858eSTeresa Johnson continue;
12541f685e01SPiotr Padlewski auto GUID = F.getGUID();
12550beb858eSTeresa Johnson auto Import = ImportGUIDs.count(GUID);
1256d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << (Import ? "Is" : "Not") << " importing function "
1257d34e60caSNicola Zaghen << GUID << " " << F.getName() << " from "
1258aeb1e59bSMehdi Amini << SrcModule->getSourceFileName() << "\n");
12590beb858eSTeresa Johnson if (Import) {
12607f00d0a1SPeter Collingbourne if (Error Err = F.materialize())
1261c55cf4afSBill Wendling return std::move(Err);
12623b776128SPiotr Padlewski if (EnableImportMetadata) {
12636deaa6afSPiotr Padlewski // Add 'thinlto_src_module' metadata for statistics and debugging.
12643b776128SPiotr Padlewski F.setMetadata(
12653b776128SPiotr Padlewski "thinlto_src_module",
1266e9ea08a0SEugene Zelenko MDNode::get(DestModule.getContext(),
1267e9ea08a0SEugene Zelenko {MDString::get(DestModule.getContext(),
12686deaa6afSPiotr Padlewski SrcModule->getSourceFileName())}));
12693b776128SPiotr Padlewski }
12701f685e01SPiotr Padlewski GlobalsToImport.insert(&F);
127101e32130SMehdi Amini }
127201e32130SMehdi Amini }
12731f685e01SPiotr Padlewski for (GlobalVariable &GV : SrcModule->globals()) {
12742d28f7aaSMehdi Amini if (!GV.hasName())
12752d28f7aaSMehdi Amini continue;
12762d28f7aaSMehdi Amini auto GUID = GV.getGUID();
12772d28f7aaSMehdi Amini auto Import = ImportGUIDs.count(GUID);
1278d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << (Import ? "Is" : "Not") << " importing global "
1279d34e60caSNicola Zaghen << GUID << " " << GV.getName() << " from "
1280aeb1e59bSMehdi Amini << SrcModule->getSourceFileName() << "\n");
12812d28f7aaSMehdi Amini if (Import) {
12827f00d0a1SPeter Collingbourne if (Error Err = GV.materialize())
1283c55cf4afSBill Wendling return std::move(Err);
128419e23874SEugene Leviant ImportedGVCount += GlobalsToImport.insert(&GV);
12852d28f7aaSMehdi Amini }
12862d28f7aaSMehdi Amini }
12871f685e01SPiotr Padlewski for (GlobalAlias &GA : SrcModule->aliases()) {
1288*30402720SSchrodinger ZHU Yifan if (!GA.hasName() || isa<GlobalIFunc>(GA.getAliaseeObject()))
128901e32130SMehdi Amini continue;
12901f685e01SPiotr Padlewski auto GUID = GA.getGUID();
129181bbf742STeresa Johnson auto Import = ImportGUIDs.count(GUID);
1292d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << (Import ? "Is" : "Not") << " importing alias "
1293d34e60caSNicola Zaghen << GUID << " " << GA.getName() << " from "
1294aeb1e59bSMehdi Amini << SrcModule->getSourceFileName() << "\n");
129581bbf742STeresa Johnson if (Import) {
129681bbf742STeresa Johnson if (Error Err = GA.materialize())
1297c55cf4afSBill Wendling return std::move(Err);
129881bbf742STeresa Johnson // Import alias as a copy of its aliasee.
129940ec1c0fSItay Bookstein GlobalObject *GO = GA.getAliaseeObject();
130040ec1c0fSItay Bookstein if (Error Err = GO->materialize())
1301c55cf4afSBill Wendling return std::move(Err);
130281bbf742STeresa Johnson auto *Fn = replaceAliasWithAliasee(SrcModule.get(), &GA);
130340ec1c0fSItay Bookstein LLVM_DEBUG(dbgs() << "Is importing aliasee fn " << GO->getGUID() << " "
130440ec1c0fSItay Bookstein << GO->getName() << " from "
130581bbf742STeresa Johnson << SrcModule->getSourceFileName() << "\n");
130681bbf742STeresa Johnson if (EnableImportMetadata) {
130781bbf742STeresa Johnson // Add 'thinlto_src_module' metadata for statistics and debugging.
130881bbf742STeresa Johnson Fn->setMetadata(
130981bbf742STeresa Johnson "thinlto_src_module",
131081bbf742STeresa Johnson MDNode::get(DestModule.getContext(),
131181bbf742STeresa Johnson {MDString::get(DestModule.getContext(),
131281bbf742STeresa Johnson SrcModule->getSourceFileName())}));
131301e32130SMehdi Amini }
131481bbf742STeresa Johnson GlobalsToImport.insert(Fn);
131581bbf742STeresa Johnson }
131681bbf742STeresa Johnson }
131701e32130SMehdi Amini
131819ef4fadSMehdi Amini // Upgrade debug info after we're done materializing all the globals and we
131919ef4fadSMehdi Amini // have loaded all the required metadata!
132019ef4fadSMehdi Amini UpgradeDebugInfo(*SrcModule);
132119ef4fadSMehdi Amini
13226c27c61dSHiroshi Yamauchi // Set the partial sample profile ratio in the profile summary module flag
13236c27c61dSHiroshi Yamauchi // of the imported source module, if applicable, so that the profile summary
13246c27c61dSHiroshi Yamauchi // module flag will match with that of the destination module when it's
13256c27c61dSHiroshi Yamauchi // imported.
13266c27c61dSHiroshi Yamauchi SrcModule->setPartialSampleProfileRatio(Index);
13276c27c61dSHiroshi Yamauchi
13287e88d0daSMehdi Amini // Link in the specified functions.
1329d2ef8c1fSFangrui Song if (renameModuleForThinLTO(*SrcModule, Index, ClearDSOLocalOnDeclarations,
1330d2ef8c1fSFangrui Song &GlobalsToImport))
13318d05185aSMehdi Amini return true;
13328d05185aSMehdi Amini
1333d29478f7STeresa Johnson if (PrintImports) {
1334d29478f7STeresa Johnson for (const auto *GV : GlobalsToImport)
1335d29478f7STeresa Johnson dbgs() << DestModule.getSourceFileName() << ": Import " << GV->getName()
1336d29478f7STeresa Johnson << " from " << SrcModule->getSourceFileName() << "\n";
1337d29478f7STeresa Johnson }
1338d29478f7STeresa Johnson
1339236695e7SNick Desaulniers if (Error Err = Mover.move(std::move(SrcModule),
1340236695e7SNick Desaulniers GlobalsToImport.getArrayRef(), nullptr,
1341e6fd9ff9SPeter Collingbourne /*IsPerformingImport=*/true))
134221661607SSimon Pilgrim report_fatal_error(Twine("Function Import: link error: ") +
134309684b08SSergei Trofimovich toString(std::move(Err)));
13447e88d0daSMehdi Amini
134501e32130SMehdi Amini ImportedCount += GlobalsToImport.size();
13466c475a75STeresa Johnson NumImportedModules++;
13477e88d0daSMehdi Amini }
1348e5a61917STeresa Johnson
13493aef3528SEugene Leviant internalizeGVsAfterImport(DestModule);
1350bf46e741SEugene Leviant
135119e23874SEugene Leviant NumImportedFunctions += (ImportedCount - ImportedGVCount);
135219e23874SEugene Leviant NumImportedGlobalVars += ImportedGVCount;
1353d29478f7STeresa Johnson
1354d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Imported " << ImportedCount - ImportedGVCount
1355d34e60caSNicola Zaghen << " functions for Module "
1356d34e60caSNicola Zaghen << DestModule.getModuleIdentifier() << "\n");
1357d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Imported " << ImportedGVCount
135819e23874SEugene Leviant << " global variables for Module "
1359c8c55170SMehdi Amini << DestModule.getModuleIdentifier() << "\n");
1360c8c55170SMehdi Amini return ImportedCount;
136142418abaSMehdi Amini }
136242418abaSMehdi Amini
doImportingForModule(Module & M)1363598bd2a2SPeter Collingbourne static bool doImportingForModule(Module &M) {
1364598bd2a2SPeter Collingbourne if (SummaryFile.empty())
1365598bd2a2SPeter Collingbourne report_fatal_error("error: -function-import requires -summary-file\n");
13666de481a3SPeter Collingbourne Expected<std::unique_ptr<ModuleSummaryIndex>> IndexPtrOrErr =
13676de481a3SPeter Collingbourne getModuleSummaryIndexForFile(SummaryFile);
13686de481a3SPeter Collingbourne if (!IndexPtrOrErr) {
13696de481a3SPeter Collingbourne logAllUnhandledErrors(IndexPtrOrErr.takeError(), errs(),
13706de481a3SPeter Collingbourne "Error loading file '" + SummaryFile + "': ");
137142418abaSMehdi Amini return false;
137242418abaSMehdi Amini }
1373598bd2a2SPeter Collingbourne std::unique_ptr<ModuleSummaryIndex> Index = std::move(*IndexPtrOrErr);
137442418abaSMehdi Amini
1375c86af334STeresa Johnson // First step is collecting the import list.
1376c86af334STeresa Johnson FunctionImporter::ImportMapTy ImportList;
137781bbf742STeresa Johnson // If requested, simply import all functions in the index. This is used
137881bbf742STeresa Johnson // when testing distributed backend handling via the opt tool, when
137981bbf742STeresa Johnson // we have distributed indexes containing exactly the summaries to import.
138081bbf742STeresa Johnson if (ImportAllIndex)
138181bbf742STeresa Johnson ComputeCrossModuleImportForModuleFromIndex(M.getModuleIdentifier(), *Index,
138281bbf742STeresa Johnson ImportList);
138381bbf742STeresa Johnson else
1384c86af334STeresa Johnson ComputeCrossModuleImportForModule(M.getModuleIdentifier(), *Index,
1385c86af334STeresa Johnson ImportList);
138601e32130SMehdi Amini
13874fef68cbSTeresa Johnson // Conservatively mark all internal values as promoted. This interface is
13884fef68cbSTeresa Johnson // only used when doing importing via the function importing pass. The pass
13894fef68cbSTeresa Johnson // is only enabled when testing importing via the 'opt' tool, which does
13904fef68cbSTeresa Johnson // not do the ThinLink that would normally determine what values to promote.
13914fef68cbSTeresa Johnson for (auto &I : *Index) {
13929667b91bSPeter Collingbourne for (auto &S : I.second.SummaryList) {
13934fef68cbSTeresa Johnson if (GlobalValue::isLocalLinkage(S->linkage()))
13944fef68cbSTeresa Johnson S->setLinkage(GlobalValue::ExternalLinkage);
13954fef68cbSTeresa Johnson }
13964fef68cbSTeresa Johnson }
13974fef68cbSTeresa Johnson
139801e32130SMehdi Amini // Next we need to promote to global scope and rename any local values that
13991b00f2d9STeresa Johnson // are potentially exported to other modules.
14006913812aSFangrui Song if (renameModuleForThinLTO(M, *Index, /*ClearDSOLocalOnDeclarations=*/false,
1401d2ef8c1fSFangrui Song /*GlobalsToImport=*/nullptr)) {
14021b00f2d9STeresa Johnson errs() << "Error renaming module\n";
14031b00f2d9STeresa Johnson return false;
14041b00f2d9STeresa Johnson }
14051b00f2d9STeresa Johnson
140642418abaSMehdi Amini // Perform the import now.
1407d16c8065SMehdi Amini auto ModuleLoader = [&M](StringRef Identifier) {
1408adcd0268SBenjamin Kramer return loadFile(std::string(Identifier), M.getContext());
1409d16c8065SMehdi Amini };
1410d2ef8c1fSFangrui Song FunctionImporter Importer(*Index, ModuleLoader,
1411d2ef8c1fSFangrui Song /*ClearDSOLocalOnDeclarations=*/false);
141237e24591SPeter Collingbourne Expected<bool> Result = Importer.importFunctions(M, ImportList);
14137f00d0a1SPeter Collingbourne
14147f00d0a1SPeter Collingbourne // FIXME: Probably need to propagate Errors through the pass manager.
14157f00d0a1SPeter Collingbourne if (!Result) {
14167f00d0a1SPeter Collingbourne logAllUnhandledErrors(Result.takeError(), errs(),
14177f00d0a1SPeter Collingbourne "Error importing module: ");
14187f00d0a1SPeter Collingbourne return false;
14197f00d0a1SPeter Collingbourne }
14207f00d0a1SPeter Collingbourne
14217f00d0a1SPeter Collingbourne return *Result;
142221241571STeresa Johnson }
142321241571STeresa Johnson
run(Module & M,ModuleAnalysisManager & AM)142421241571STeresa Johnson PreservedAnalyses FunctionImportPass::run(Module &M,
1425fd03ac6aSSean Silva ModuleAnalysisManager &AM) {
1426598bd2a2SPeter Collingbourne if (!doImportingForModule(M))
142721241571STeresa Johnson return PreservedAnalyses::all();
142821241571STeresa Johnson
142921241571STeresa Johnson return PreservedAnalyses::none();
143021241571STeresa Johnson }
1431