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"
21b040fcc6SCharles Saternos #include "llvm/ADT/StringSet.h"
22c15d60b7SPeter Collingbourne #include "llvm/Bitcode/BitcodeReader.h"
2342418abaSMehdi Amini #include "llvm/IR/AutoUpgrade.h"
2481bbf742STeresa Johnson #include "llvm/IR/Constants.h"
25e9ea08a0SEugene Zelenko #include "llvm/IR/Function.h"
26e9ea08a0SEugene Zelenko #include "llvm/IR/GlobalAlias.h"
27e9ea08a0SEugene Zelenko #include "llvm/IR/GlobalObject.h"
28e9ea08a0SEugene Zelenko #include "llvm/IR/GlobalValue.h"
29e9ea08a0SEugene Zelenko #include "llvm/IR/GlobalVariable.h"
30e9ea08a0SEugene Zelenko #include "llvm/IR/Metadata.h"
3142418abaSMehdi Amini #include "llvm/IR/Module.h"
32e9ea08a0SEugene Zelenko #include "llvm/IR/ModuleSummaryIndex.h"
3342418abaSMehdi Amini #include "llvm/IRReader/IRReader.h"
3405da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
35e9ea08a0SEugene Zelenko #include "llvm/Linker/IRMover.h"
36e9ea08a0SEugene Zelenko #include "llvm/Object/ModuleSymbolTable.h"
37e9ea08a0SEugene Zelenko #include "llvm/Object/SymbolicFile.h"
38e9ea08a0SEugene Zelenko #include "llvm/Pass.h"
39e9ea08a0SEugene Zelenko #include "llvm/Support/Casting.h"
4042418abaSMehdi Amini #include "llvm/Support/CommandLine.h"
4142418abaSMehdi Amini #include "llvm/Support/Debug.h"
42e9ea08a0SEugene Zelenko #include "llvm/Support/Error.h"
43e9ea08a0SEugene Zelenko #include "llvm/Support/ErrorHandling.h"
44e9ea08a0SEugene Zelenko #include "llvm/Support/FileSystem.h"
4542418abaSMehdi Amini #include "llvm/Support/SourceMgr.h"
46e9ea08a0SEugene Zelenko #include "llvm/Support/raw_ostream.h"
4704c9a2d6STeresa Johnson #include "llvm/Transforms/IPO/Internalize.h"
4881bbf742STeresa Johnson #include "llvm/Transforms/Utils/Cloning.h"
49488a800aSTeresa Johnson #include "llvm/Transforms/Utils/FunctionImportUtils.h"
5081bbf742STeresa Johnson #include "llvm/Transforms/Utils/ValueMapper.h"
51e9ea08a0SEugene Zelenko #include <cassert>
52e9ea08a0SEugene Zelenko #include <memory>
53e9ea08a0SEugene Zelenko #include <set>
54e9ea08a0SEugene Zelenko #include <string>
55e9ea08a0SEugene Zelenko #include <system_error>
56e9ea08a0SEugene Zelenko #include <tuple>
57e9ea08a0SEugene Zelenko #include <utility>
587e88d0daSMehdi Amini 
5942418abaSMehdi Amini using namespace llvm;
6042418abaSMehdi Amini 
61e9ea08a0SEugene Zelenko #define DEBUG_TYPE "function-import"
62e9ea08a0SEugene Zelenko 
63d2c234a4STeresa Johnson STATISTIC(NumImportedFunctionsThinLink,
64d2c234a4STeresa Johnson           "Number of functions thin link decided to import");
65d2c234a4STeresa Johnson STATISTIC(NumImportedHotFunctionsThinLink,
66d2c234a4STeresa Johnson           "Number of hot functions thin link decided to import");
67d2c234a4STeresa Johnson STATISTIC(NumImportedCriticalFunctionsThinLink,
68d2c234a4STeresa Johnson           "Number of critical functions thin link decided to import");
69d2c234a4STeresa Johnson STATISTIC(NumImportedGlobalVarsThinLink,
70d2c234a4STeresa Johnson           "Number of global variables thin link decided to import");
71d2c234a4STeresa Johnson STATISTIC(NumImportedFunctions, "Number of functions imported in backend");
72d2c234a4STeresa Johnson STATISTIC(NumImportedGlobalVars,
73d2c234a4STeresa Johnson           "Number of global variables imported in backend");
746c475a75STeresa Johnson STATISTIC(NumImportedModules, "Number of modules imported from");
756c475a75STeresa Johnson STATISTIC(NumDeadSymbols, "Number of dead stripped symbols in index");
766c475a75STeresa Johnson STATISTIC(NumLiveSymbols, "Number of live symbols in index");
77d29478f7STeresa Johnson 
7839303619STeresa Johnson /// Limit on instruction count of imported functions.
7939303619STeresa Johnson static cl::opt<unsigned> ImportInstrLimit(
8039303619STeresa Johnson     "import-instr-limit", cl::init(100), cl::Hidden, cl::value_desc("N"),
8139303619STeresa Johnson     cl::desc("Only import functions with less than N instructions"));
8239303619STeresa Johnson 
83974706ebSTeresa Johnson static cl::opt<int> ImportCutoff(
84974706ebSTeresa Johnson     "import-cutoff", cl::init(-1), cl::Hidden, cl::value_desc("N"),
85974706ebSTeresa Johnson     cl::desc("Only import first N functions if N>=0 (default -1)"));
86974706ebSTeresa Johnson 
8740641748SMehdi Amini static cl::opt<float>
8840641748SMehdi Amini     ImportInstrFactor("import-instr-evolution-factor", cl::init(0.7),
8940641748SMehdi Amini                       cl::Hidden, cl::value_desc("x"),
9040641748SMehdi Amini                       cl::desc("As we import functions, multiply the "
9140641748SMehdi Amini                                "`import-instr-limit` threshold by this factor "
9240641748SMehdi Amini                                "before processing newly imported functions"));
93ba72b95fSPiotr Padlewski 
94d2869473SPiotr Padlewski static cl::opt<float> ImportHotInstrFactor(
95d2869473SPiotr Padlewski     "import-hot-evolution-factor", cl::init(1.0), cl::Hidden,
96d2869473SPiotr Padlewski     cl::value_desc("x"),
97d2869473SPiotr Padlewski     cl::desc("As we import functions called from hot callsite, multiply the "
98d2869473SPiotr Padlewski              "`import-instr-limit` threshold by this factor "
99d2869473SPiotr Padlewski              "before processing newly imported functions"));
100d2869473SPiotr Padlewski 
101d9830eb7SPiotr Padlewski static cl::opt<float> ImportHotMultiplier(
1028260d665SDehao Chen     "import-hot-multiplier", cl::init(10.0), cl::Hidden, cl::value_desc("x"),
103ba72b95fSPiotr Padlewski     cl::desc("Multiply the `import-instr-limit` threshold for hot callsites"));
104ba72b95fSPiotr Padlewski 
10564c46574SDehao Chen static cl::opt<float> ImportCriticalMultiplier(
10664c46574SDehao Chen     "import-critical-multiplier", cl::init(100.0), cl::Hidden,
10764c46574SDehao Chen     cl::value_desc("x"),
10864c46574SDehao Chen     cl::desc(
10964c46574SDehao Chen         "Multiply the `import-instr-limit` threshold for critical callsites"));
11064c46574SDehao Chen 
111ba72b95fSPiotr Padlewski // FIXME: This multiplier was not really tuned up.
112ba72b95fSPiotr Padlewski static cl::opt<float> ImportColdMultiplier(
113ba72b95fSPiotr Padlewski     "import-cold-multiplier", cl::init(0), cl::Hidden, cl::value_desc("N"),
114ba72b95fSPiotr Padlewski     cl::desc("Multiply the `import-instr-limit` threshold for cold callsites"));
11540641748SMehdi Amini 
116d29478f7STeresa Johnson static cl::opt<bool> PrintImports("print-imports", cl::init(false), cl::Hidden,
117d29478f7STeresa Johnson                                   cl::desc("Print imported functions"));
118d29478f7STeresa Johnson 
119cb9a82fcSTeresa Johnson static cl::opt<bool> PrintImportFailures(
120cb9a82fcSTeresa Johnson     "print-import-failures", cl::init(false), cl::Hidden,
121cb9a82fcSTeresa Johnson     cl::desc("Print information for functions rejected for importing"));
122cb9a82fcSTeresa Johnson 
1236c475a75STeresa Johnson static cl::opt<bool> ComputeDead("compute-dead", cl::init(true), cl::Hidden,
1246c475a75STeresa Johnson                                  cl::desc("Compute dead symbols"));
1256c475a75STeresa Johnson 
1263b776128SPiotr Padlewski static cl::opt<bool> EnableImportMetadata(
127a90b42b0SFangrui Song     "enable-import-metadata", cl::init(false), cl::Hidden,
128a90b42b0SFangrui Song     cl::desc("Enable import metadata like 'thinlto_src_module'"));
1293b776128SPiotr Padlewski 
130e9ea08a0SEugene Zelenko /// Summary file to use for function importing when using -function-import from
131e9ea08a0SEugene Zelenko /// the command line.
132e9ea08a0SEugene Zelenko static cl::opt<std::string>
133e9ea08a0SEugene Zelenko     SummaryFile("summary-file",
134e9ea08a0SEugene Zelenko                 cl::desc("The summary file to use for function importing."));
135e9ea08a0SEugene Zelenko 
13681bbf742STeresa Johnson /// Used when testing importing from distributed indexes via opt
13781bbf742STeresa Johnson // -function-import.
13881bbf742STeresa Johnson static cl::opt<bool>
13981bbf742STeresa Johnson     ImportAllIndex("import-all-index",
14081bbf742STeresa Johnson                    cl::desc("Import all external functions in index."));
14181bbf742STeresa Johnson 
14242418abaSMehdi Amini // Load lazily a module from \p FileName in \p Context.
14342418abaSMehdi Amini static std::unique_ptr<Module> loadFile(const std::string &FileName,
14442418abaSMehdi Amini                                         LLVMContext &Context) {
14542418abaSMehdi Amini   SMDiagnostic Err;
146d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "Loading '" << FileName << "'\n");
1476cba37ceSTeresa Johnson   // Metadata isn't loaded until functions are imported, to minimize
1486cba37ceSTeresa Johnson   // the memory overhead.
149a1080ee6STeresa Johnson   std::unique_ptr<Module> Result =
150a1080ee6STeresa Johnson       getLazyIRFileModule(FileName, Err, Context,
151a1080ee6STeresa Johnson                           /* ShouldLazyLoadMetadata = */ true);
15242418abaSMehdi Amini   if (!Result) {
15342418abaSMehdi Amini     Err.print("function-import", errs());
154d7ad221cSMehdi Amini     report_fatal_error("Abort");
15542418abaSMehdi Amini   }
15642418abaSMehdi Amini 
15742418abaSMehdi Amini   return Result;
15842418abaSMehdi Amini }
15942418abaSMehdi Amini 
16001e32130SMehdi Amini /// Given a list of possible callee implementation for a call site, select one
16101e32130SMehdi Amini /// that fits the \p Threshold.
16201e32130SMehdi Amini ///
16301e32130SMehdi Amini /// FIXME: select "best" instead of first that fits. But what is "best"?
16401e32130SMehdi Amini /// - The smallest: more likely to be inlined.
16501e32130SMehdi Amini /// - The one with the least outgoing edges (already well optimized).
16601e32130SMehdi Amini /// - One from a module already being imported from in order to reduce the
16701e32130SMehdi Amini ///   number of source modules parsed/linked.
16801e32130SMehdi Amini /// - One that has PGO data attached.
16901e32130SMehdi Amini /// - [insert you fancy metric here]
1702d28f7aaSMehdi Amini static const GlobalValueSummary *
171b4e1e829SMehdi Amini selectCallee(const ModuleSummaryIndex &Index,
1729667b91bSPeter Collingbourne              ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
173cb9a82fcSTeresa Johnson              unsigned Threshold, StringRef CallerModulePath,
174cb9a82fcSTeresa Johnson              FunctionImporter::ImportFailureReason &Reason,
175cb9a82fcSTeresa Johnson              GlobalValue::GUID GUID) {
176cb9a82fcSTeresa Johnson   Reason = FunctionImporter::ImportFailureReason::None;
17701e32130SMehdi Amini   auto It = llvm::find_if(
17828e457bcSTeresa Johnson       CalleeSummaryList,
17928e457bcSTeresa Johnson       [&](const std::unique_ptr<GlobalValueSummary> &SummaryPtr) {
18028e457bcSTeresa Johnson         auto *GVSummary = SummaryPtr.get();
181cb9a82fcSTeresa Johnson         if (!Index.isGlobalValueLive(GVSummary)) {
182cb9a82fcSTeresa Johnson           Reason = FunctionImporter::ImportFailureReason::NotLive;
183eaf5172cSGeorge Rimar           return false;
184cb9a82fcSTeresa Johnson         }
185eaf5172cSGeorge Rimar 
18673305f82STeresa Johnson         // For SamplePGO, in computeImportForFunction the OriginalId
18773305f82STeresa Johnson         // may have been used to locate the callee summary list (See
18873305f82STeresa Johnson         // comment there).
18973305f82STeresa Johnson         // The mapping from OriginalId to GUID may return a GUID
19073305f82STeresa Johnson         // that corresponds to a static variable. Filter it out here.
19173305f82STeresa Johnson         // This can happen when
19273305f82STeresa Johnson         // 1) There is a call to a library function which is not defined
19373305f82STeresa Johnson         // in the index.
19473305f82STeresa Johnson         // 2) There is a static variable with the  OriginalGUID identical
19573305f82STeresa Johnson         // to the GUID of the library function in 1);
19673305f82STeresa Johnson         // When this happens, the logic for SamplePGO kicks in and
19773305f82STeresa Johnson         // the static variable in 2) will be found, which needs to be
19873305f82STeresa Johnson         // filtered out.
199cb9a82fcSTeresa Johnson         if (GVSummary->getSummaryKind() == GlobalValueSummary::GlobalVarKind) {
200cb9a82fcSTeresa Johnson           Reason = FunctionImporter::ImportFailureReason::GlobalVar;
20173305f82STeresa Johnson           return false;
202cb9a82fcSTeresa Johnson         }
203cb9a82fcSTeresa Johnson         if (GlobalValue::isInterposableLinkage(GVSummary->linkage())) {
204cb9a82fcSTeresa Johnson           Reason = FunctionImporter::ImportFailureReason::InterposableLinkage;
2055b85d8d6SMehdi Amini           // There is no point in importing these, we can't inline them
20601e32130SMehdi Amini           return false;
207cb9a82fcSTeresa Johnson         }
2082c719cc1SMehdi Amini 
20981bbf742STeresa Johnson         auto *Summary = cast<FunctionSummary>(GVSummary->getBaseObject());
2107e88d0daSMehdi Amini 
21183aaf358STeresa Johnson         // If this is a local function, make sure we import the copy
21283aaf358STeresa Johnson         // in the caller's module. The only time a local function can
21383aaf358STeresa Johnson         // share an entry in the index is if there is a local with the same name
21483aaf358STeresa Johnson         // in another module that had the same source file name (in a different
21583aaf358STeresa Johnson         // directory), where each was compiled in their own directory so there
21683aaf358STeresa Johnson         // was not distinguishing path.
21783aaf358STeresa Johnson         // However, do the import from another module if there is only one
21883aaf358STeresa Johnson         // entry in the list - in that case this must be a reference due
21983aaf358STeresa Johnson         // to indirect call profile data, since a function pointer can point to
22083aaf358STeresa Johnson         // a local in another module.
22183aaf358STeresa Johnson         if (GlobalValue::isLocalLinkage(Summary->linkage()) &&
22283aaf358STeresa Johnson             CalleeSummaryList.size() > 1 &&
223cb9a82fcSTeresa Johnson             Summary->modulePath() != CallerModulePath) {
224cb9a82fcSTeresa Johnson           Reason =
225cb9a82fcSTeresa Johnson               FunctionImporter::ImportFailureReason::LocalLinkageNotInModule;
22683aaf358STeresa Johnson           return false;
227cb9a82fcSTeresa Johnson         }
22883aaf358STeresa Johnson 
229b11391bbSTeresa Johnson         if ((Summary->instCount() > Threshold) &&
230b11391bbSTeresa Johnson             !Summary->fflags().AlwaysInline) {
231cb9a82fcSTeresa Johnson           Reason = FunctionImporter::ImportFailureReason::TooLarge;
232f9dc3deaSTeresa Johnson           return false;
233cb9a82fcSTeresa Johnson         }
234f9dc3deaSTeresa Johnson 
235cb397461STeresa Johnson         // Skip if it isn't legal to import (e.g. may reference unpromotable
236cb397461STeresa Johnson         // locals).
237cb9a82fcSTeresa Johnson         if (Summary->notEligibleToImport()) {
238cb9a82fcSTeresa Johnson           Reason = FunctionImporter::ImportFailureReason::NotEligible;
239b4e1e829SMehdi Amini           return false;
240cb9a82fcSTeresa Johnson         }
241b4e1e829SMehdi Amini 
242cb397461STeresa Johnson         // Don't bother importing if we can't inline it anyway.
243cb397461STeresa Johnson         if (Summary->fflags().NoInline) {
244cb397461STeresa Johnson           Reason = FunctionImporter::ImportFailureReason::NoInline;
245cb397461STeresa Johnson           return false;
246cb397461STeresa Johnson         }
247cb397461STeresa Johnson 
24801e32130SMehdi Amini         return true;
24901e32130SMehdi Amini       });
25028e457bcSTeresa Johnson   if (It == CalleeSummaryList.end())
25101e32130SMehdi Amini     return nullptr;
2527e88d0daSMehdi Amini 
253f9dc3deaSTeresa Johnson   return cast<GlobalValueSummary>(It->get());
254434e9561SRafael Espindola }
2557e88d0daSMehdi Amini 
256e9ea08a0SEugene Zelenko namespace {
257e9ea08a0SEugene Zelenko 
258d5b701b9SEvgeny Leviant using EdgeInfo =
259d5b701b9SEvgeny Leviant     std::tuple<const GlobalValueSummary *, unsigned /* Threshold */>;
26001e32130SMehdi Amini 
261e9ea08a0SEugene Zelenko } // anonymous namespace
262e9ea08a0SEugene Zelenko 
2631958083dSTeresa Johnson static ValueInfo
2641958083dSTeresa Johnson updateValueInfoForIndirectCalls(const ModuleSummaryIndex &Index, ValueInfo VI) {
2651958083dSTeresa Johnson   if (!VI.getSummaryList().empty())
2661958083dSTeresa Johnson     return VI;
2671958083dSTeresa Johnson   // For SamplePGO, the indirect call targets for local functions will
2681958083dSTeresa Johnson   // have its original name annotated in profile. We try to find the
2691958083dSTeresa Johnson   // corresponding PGOFuncName as the GUID.
2701958083dSTeresa Johnson   // FIXME: Consider updating the edges in the graph after building
2711958083dSTeresa Johnson   // it, rather than needing to perform this mapping on each walk.
2721958083dSTeresa Johnson   auto GUID = Index.getGUIDFromOriginalID(VI.getGUID());
2731958083dSTeresa Johnson   if (GUID == 0)
27428d8a49fSEugene Leviant     return ValueInfo();
2751958083dSTeresa Johnson   return Index.getValueInfo(GUID);
2761958083dSTeresa Johnson }
2771958083dSTeresa Johnson 
278*e97aab8dSKristina Bessonova static bool shouldImportGlobal(const ValueInfo &VI,
279*e97aab8dSKristina Bessonova                                const GVSummaryMapTy &DefinedGVSummaries) {
280*e97aab8dSKristina Bessonova   const auto &GVS = DefinedGVSummaries.find(VI.getGUID());
281*e97aab8dSKristina Bessonova   if (GVS == DefinedGVSummaries.end())
282*e97aab8dSKristina Bessonova     return true;
283*e97aab8dSKristina Bessonova   // We should not skip import if the module contains a definition with
284*e97aab8dSKristina Bessonova   // interposable linkage type. This is required for correctness in
285*e97aab8dSKristina Bessonova   // the situation with two following conditions:
286*e97aab8dSKristina Bessonova   // * the def with interposable linkage is non-prevailing,
287*e97aab8dSKristina Bessonova   // * there is a prevailing def available for import and marked read-only.
288*e97aab8dSKristina Bessonova   // In this case, the non-prevailing def will be converted to a declaration,
289*e97aab8dSKristina Bessonova   // while the prevailing one becomes internal, thus no definitions will be
290*e97aab8dSKristina Bessonova   // available for linking. In order to prevent undefined symbol link error,
291*e97aab8dSKristina Bessonova   // the prevailing definition must be imported.
292*e97aab8dSKristina Bessonova   // FIXME: Consider adding a check that the suitable prevailing definition
293*e97aab8dSKristina Bessonova   // exists and marked read-only.
294*e97aab8dSKristina Bessonova   if (VI.getSummaryList().size() > 1 &&
295*e97aab8dSKristina Bessonova       GlobalValue::isInterposableLinkage(GVS->second->linkage()))
296*e97aab8dSKristina Bessonova     return true;
297*e97aab8dSKristina Bessonova 
298*e97aab8dSKristina Bessonova   return false;
299*e97aab8dSKristina Bessonova }
300*e97aab8dSKristina Bessonova 
30119e23874SEugene Leviant static void computeImportForReferencedGlobals(
302d5b701b9SEvgeny Leviant     const GlobalValueSummary &Summary, const ModuleSummaryIndex &Index,
303dde58938Sevgeny     const GVSummaryMapTy &DefinedGVSummaries,
304d5b701b9SEvgeny Leviant     SmallVectorImpl<EdgeInfo> &Worklist,
30519e23874SEugene Leviant     FunctionImporter::ImportMapTy &ImportList,
30619e23874SEugene Leviant     StringMap<FunctionImporter::ExportSetTy> *ExportLists) {
30719e23874SEugene Leviant   for (auto &VI : Summary.refs()) {
308*e97aab8dSKristina Bessonova     if (!shouldImportGlobal(VI, DefinedGVSummaries)) {
309d34e60caSNicola Zaghen       LLVM_DEBUG(
310d34e60caSNicola Zaghen           dbgs() << "Ref ignored! Target already in destination module.\n");
31119e23874SEugene Leviant       continue;
31219e23874SEugene Leviant     }
31319e23874SEugene Leviant 
3147e7b13d0STeresa Johnson     LLVM_DEBUG(dbgs() << " ref -> " << VI << "\n");
31519e23874SEugene Leviant 
31693f99962STeresa Johnson     // If this is a local variable, make sure we import the copy
31793f99962STeresa Johnson     // in the caller's module. The only time a local variable can
31893f99962STeresa Johnson     // share an entry in the index is if there is a local with the same name
31993f99962STeresa Johnson     // in another module that had the same source file name (in a different
32093f99962STeresa Johnson     // directory), where each was compiled in their own directory so there
32193f99962STeresa Johnson     // was not distinguishing path.
32293f99962STeresa Johnson     auto LocalNotInModule = [&](const GlobalValueSummary *RefSummary) -> bool {
32393f99962STeresa Johnson       return GlobalValue::isLocalLinkage(RefSummary->linkage()) &&
32493f99962STeresa Johnson              RefSummary->modulePath() != Summary.modulePath();
32593f99962STeresa Johnson     };
32693f99962STeresa Johnson 
32719e23874SEugene Leviant     for (auto &RefSummary : VI.getSummaryList())
328bf46e741SEugene Leviant       if (isa<GlobalVarSummary>(RefSummary.get()) &&
329dde58938Sevgeny           Index.canImportGlobalVar(RefSummary.get(), /* AnalyzeRefs */ true) &&
33093f99962STeresa Johnson           !LocalNotInModule(RefSummary.get())) {
331d2c234a4STeresa Johnson         auto ILI = ImportList[RefSummary->modulePath()].insert(VI.getGUID());
332bed4d9c8STeresa Johnson         // Only update stat and exports if we haven't already imported this
333bed4d9c8STeresa Johnson         // variable.
334bed4d9c8STeresa Johnson         if (!ILI.second)
335bed4d9c8STeresa Johnson           break;
336d2c234a4STeresa Johnson         NumImportedGlobalVarsThinLink++;
337bed4d9c8STeresa Johnson         // Any references made by this variable will be marked exported later,
338bed4d9c8STeresa Johnson         // in ComputeCrossModuleImport, after import decisions are complete,
339bed4d9c8STeresa Johnson         // which is more efficient than adding them here.
340bed4d9c8STeresa Johnson         if (ExportLists)
341bed4d9c8STeresa Johnson           (*ExportLists)[RefSummary->modulePath()].insert(VI);
342d5b701b9SEvgeny Leviant 
343d5b701b9SEvgeny Leviant         // If variable is not writeonly we attempt to recursively analyze
344d5b701b9SEvgeny Leviant         // its references in order to import referenced constants.
345d5b701b9SEvgeny Leviant         if (!Index.isWriteOnly(cast<GlobalVarSummary>(RefSummary.get())))
346d5b701b9SEvgeny Leviant           Worklist.emplace_back(RefSummary.get(), 0);
34719e23874SEugene Leviant         break;
34819e23874SEugene Leviant       }
34919e23874SEugene Leviant   }
35019e23874SEugene Leviant }
35119e23874SEugene Leviant 
352cb9a82fcSTeresa Johnson static const char *
353cb9a82fcSTeresa Johnson getFailureName(FunctionImporter::ImportFailureReason Reason) {
354cb9a82fcSTeresa Johnson   switch (Reason) {
355cb9a82fcSTeresa Johnson   case FunctionImporter::ImportFailureReason::None:
356cb9a82fcSTeresa Johnson     return "None";
357cb9a82fcSTeresa Johnson   case FunctionImporter::ImportFailureReason::GlobalVar:
358cb9a82fcSTeresa Johnson     return "GlobalVar";
359cb9a82fcSTeresa Johnson   case FunctionImporter::ImportFailureReason::NotLive:
360cb9a82fcSTeresa Johnson     return "NotLive";
361cb9a82fcSTeresa Johnson   case FunctionImporter::ImportFailureReason::TooLarge:
362cb9a82fcSTeresa Johnson     return "TooLarge";
363cb9a82fcSTeresa Johnson   case FunctionImporter::ImportFailureReason::InterposableLinkage:
364cb9a82fcSTeresa Johnson     return "InterposableLinkage";
365cb9a82fcSTeresa Johnson   case FunctionImporter::ImportFailureReason::LocalLinkageNotInModule:
366cb9a82fcSTeresa Johnson     return "LocalLinkageNotInModule";
367cb9a82fcSTeresa Johnson   case FunctionImporter::ImportFailureReason::NotEligible:
368cb9a82fcSTeresa Johnson     return "NotEligible";
369cb397461STeresa Johnson   case FunctionImporter::ImportFailureReason::NoInline:
370cb397461STeresa Johnson     return "NoInline";
371cb9a82fcSTeresa Johnson   }
372cb9a82fcSTeresa Johnson   llvm_unreachable("invalid reason");
373cb9a82fcSTeresa Johnson }
374cb9a82fcSTeresa Johnson 
37501e32130SMehdi Amini /// Compute the list of functions to import for a given caller. Mark these
37601e32130SMehdi Amini /// imported functions and the symbols they reference in their source module as
37701e32130SMehdi Amini /// exported from their source module.
37801e32130SMehdi Amini static void computeImportForFunction(
3793255eec1STeresa Johnson     const FunctionSummary &Summary, const ModuleSummaryIndex &Index,
380d9830eb7SPiotr Padlewski     const unsigned Threshold, const GVSummaryMapTy &DefinedGVSummaries,
38101e32130SMehdi Amini     SmallVectorImpl<EdgeInfo> &Worklist,
3829b490f10SMehdi Amini     FunctionImporter::ImportMapTy &ImportList,
383d68935c5STeresa Johnson     StringMap<FunctionImporter::ExportSetTy> *ExportLists,
384d68935c5STeresa Johnson     FunctionImporter::ImportThresholdsTy &ImportThresholds) {
385dde58938Sevgeny   computeImportForReferencedGlobals(Summary, Index, DefinedGVSummaries,
386d5b701b9SEvgeny Leviant                                     Worklist, ImportList, ExportLists);
387974706ebSTeresa Johnson   static int ImportCount = 0;
38801e32130SMehdi Amini   for (auto &Edge : Summary.calls()) {
3899667b91bSPeter Collingbourne     ValueInfo VI = Edge.first;
3907e7b13d0STeresa Johnson     LLVM_DEBUG(dbgs() << " edge -> " << VI << " Threshold:" << Threshold
3917e7b13d0STeresa Johnson                       << "\n");
39201e32130SMehdi Amini 
393974706ebSTeresa Johnson     if (ImportCutoff >= 0 && ImportCount >= ImportCutoff) {
394d34e60caSNicola Zaghen       LLVM_DEBUG(dbgs() << "ignored! import-cutoff value of " << ImportCutoff
395974706ebSTeresa Johnson                         << " reached.\n");
396974706ebSTeresa Johnson       continue;
397974706ebSTeresa Johnson     }
398974706ebSTeresa Johnson 
3991958083dSTeresa Johnson     VI = updateValueInfoForIndirectCalls(Index, VI);
4009667b91bSPeter Collingbourne     if (!VI)
4019667b91bSPeter Collingbourne       continue;
4024a435e08SDehao Chen 
4039667b91bSPeter Collingbourne     if (DefinedGVSummaries.count(VI.getGUID())) {
404*e97aab8dSKristina Bessonova       // FIXME: Consider not skipping import if the module contains
405*e97aab8dSKristina Bessonova       // a non-prevailing def with interposable linkage. The prevailing copy
406*e97aab8dSKristina Bessonova       // can safely be imported (see shouldImportGlobal()).
407d34e60caSNicola Zaghen       LLVM_DEBUG(dbgs() << "ignored! Target already in destination module.\n");
4087e88d0daSMehdi Amini       continue;
409d450da32STeresa Johnson     }
41040641748SMehdi Amini 
411ba72b95fSPiotr Padlewski     auto GetBonusMultiplier = [](CalleeInfo::HotnessType Hotness) -> float {
412ba72b95fSPiotr Padlewski       if (Hotness == CalleeInfo::HotnessType::Hot)
413ba72b95fSPiotr Padlewski         return ImportHotMultiplier;
414ba72b95fSPiotr Padlewski       if (Hotness == CalleeInfo::HotnessType::Cold)
415ba72b95fSPiotr Padlewski         return ImportColdMultiplier;
41664c46574SDehao Chen       if (Hotness == CalleeInfo::HotnessType::Critical)
41764c46574SDehao Chen         return ImportCriticalMultiplier;
418ba72b95fSPiotr Padlewski       return 1.0;
419ba72b95fSPiotr Padlewski     };
420ba72b95fSPiotr Padlewski 
421d9830eb7SPiotr Padlewski     const auto NewThreshold =
422c73cec84SEaswaran Raman         Threshold * GetBonusMultiplier(Edge.second.getHotness());
423d2869473SPiotr Padlewski 
424cb9a82fcSTeresa Johnson     auto IT = ImportThresholds.insert(std::make_pair(
425cb9a82fcSTeresa Johnson         VI.getGUID(), std::make_tuple(NewThreshold, nullptr, nullptr)));
426d68935c5STeresa Johnson     bool PreviouslyVisited = !IT.second;
427cb9a82fcSTeresa Johnson     auto &ProcessedThreshold = std::get<0>(IT.first->second);
428cb9a82fcSTeresa Johnson     auto &CalleeSummary = std::get<1>(IT.first->second);
429cb9a82fcSTeresa Johnson     auto &FailureInfo = std::get<2>(IT.first->second);
430d68935c5STeresa Johnson 
431d2c234a4STeresa Johnson     bool IsHotCallsite =
432d2c234a4STeresa Johnson         Edge.second.getHotness() == CalleeInfo::HotnessType::Hot;
433d2c234a4STeresa Johnson     bool IsCriticalCallsite =
434d2c234a4STeresa Johnson         Edge.second.getHotness() == CalleeInfo::HotnessType::Critical;
435d2c234a4STeresa Johnson 
436d68935c5STeresa Johnson     const FunctionSummary *ResolvedCalleeSummary = nullptr;
437d68935c5STeresa Johnson     if (CalleeSummary) {
438d68935c5STeresa Johnson       assert(PreviouslyVisited);
439d68935c5STeresa Johnson       // Since the traversal of the call graph is DFS, we can revisit a function
440d68935c5STeresa Johnson       // a second time with a higher threshold. In this case, it is added back
441d68935c5STeresa Johnson       // to the worklist with the new threshold (so that its own callee chains
442d68935c5STeresa Johnson       // can be considered with the higher threshold).
443d68935c5STeresa Johnson       if (NewThreshold <= ProcessedThreshold) {
444d68935c5STeresa Johnson         LLVM_DEBUG(
445d68935c5STeresa Johnson             dbgs() << "ignored! Target was already imported with Threshold "
446d68935c5STeresa Johnson                    << ProcessedThreshold << "\n");
447d68935c5STeresa Johnson         continue;
448d68935c5STeresa Johnson       }
449d68935c5STeresa Johnson       // Update with new larger threshold.
450d68935c5STeresa Johnson       ProcessedThreshold = NewThreshold;
451d68935c5STeresa Johnson       ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
452d68935c5STeresa Johnson     } else {
453d68935c5STeresa Johnson       // If we already rejected importing a callee at the same or higher
454d68935c5STeresa Johnson       // threshold, don't waste time calling selectCallee.
455d68935c5STeresa Johnson       if (PreviouslyVisited && NewThreshold <= ProcessedThreshold) {
456d68935c5STeresa Johnson         LLVM_DEBUG(
457d68935c5STeresa Johnson             dbgs() << "ignored! Target was already rejected with Threshold "
458d68935c5STeresa Johnson             << ProcessedThreshold << "\n");
459cb9a82fcSTeresa Johnson         if (PrintImportFailures) {
460cb9a82fcSTeresa Johnson           assert(FailureInfo &&
461cb9a82fcSTeresa Johnson                  "Expected FailureInfo for previously rejected candidate");
462cb9a82fcSTeresa Johnson           FailureInfo->Attempts++;
463cb9a82fcSTeresa Johnson         }
464d68935c5STeresa Johnson         continue;
465d68935c5STeresa Johnson       }
466d68935c5STeresa Johnson 
467cb9a82fcSTeresa Johnson       FunctionImporter::ImportFailureReason Reason;
468d68935c5STeresa Johnson       CalleeSummary = selectCallee(Index, VI.getSummaryList(), NewThreshold,
469cb9a82fcSTeresa Johnson                                    Summary.modulePath(), Reason, VI.getGUID());
47001e32130SMehdi Amini       if (!CalleeSummary) {
471d68935c5STeresa Johnson         // Update with new larger threshold if this was a retry (otherwise
472cb9a82fcSTeresa Johnson         // we would have already inserted with NewThreshold above). Also
473cb9a82fcSTeresa Johnson         // update failure info if requested.
474cb9a82fcSTeresa Johnson         if (PreviouslyVisited) {
475d68935c5STeresa Johnson           ProcessedThreshold = NewThreshold;
476cb9a82fcSTeresa Johnson           if (PrintImportFailures) {
477cb9a82fcSTeresa Johnson             assert(FailureInfo &&
478cb9a82fcSTeresa Johnson                    "Expected FailureInfo for previously rejected candidate");
479cb9a82fcSTeresa Johnson             FailureInfo->Reason = Reason;
480cb9a82fcSTeresa Johnson             FailureInfo->Attempts++;
481cb9a82fcSTeresa Johnson             FailureInfo->MaxHotness =
482cb9a82fcSTeresa Johnson                 std::max(FailureInfo->MaxHotness, Edge.second.getHotness());
483cb9a82fcSTeresa Johnson           }
484cb9a82fcSTeresa Johnson         } else if (PrintImportFailures) {
485cb9a82fcSTeresa Johnson           assert(!FailureInfo &&
486cb9a82fcSTeresa Johnson                  "Expected no FailureInfo for newly rejected candidate");
4870eaee545SJonas Devlieghere           FailureInfo = std::make_unique<FunctionImporter::ImportFailureInfo>(
488cb9a82fcSTeresa Johnson               VI, Edge.second.getHotness(), Reason, 1);
489cb9a82fcSTeresa Johnson         }
490d34e60caSNicola Zaghen         LLVM_DEBUG(
491d34e60caSNicola Zaghen             dbgs() << "ignored! No qualifying callee with summary found.\n");
4927e88d0daSMehdi Amini         continue;
4937e88d0daSMehdi Amini       }
4942f0cc477SDavid Blaikie 
4952f0cc477SDavid Blaikie       // "Resolve" the summary
496d68935c5STeresa Johnson       CalleeSummary = CalleeSummary->getBaseObject();
497d68935c5STeresa Johnson       ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
4982d28f7aaSMehdi Amini 
499b11391bbSTeresa Johnson       assert((ResolvedCalleeSummary->fflags().AlwaysInline ||
500b11391bbSTeresa Johnson 	     (ResolvedCalleeSummary->instCount() <= NewThreshold)) &&
50101e32130SMehdi Amini              "selectCallee() didn't honor the threshold");
50201e32130SMehdi Amini 
5031b859a23STeresa Johnson       auto ExportModulePath = ResolvedCalleeSummary->modulePath();
504d68935c5STeresa Johnson       auto ILI = ImportList[ExportModulePath].insert(VI.getGUID());
505d68935c5STeresa Johnson       // We previously decided to import this GUID definition if it was already
506d68935c5STeresa Johnson       // inserted in the set of imports from the exporting module.
507d68935c5STeresa Johnson       bool PreviouslyImported = !ILI.second;
508d2c234a4STeresa Johnson       if (!PreviouslyImported) {
509d2c234a4STeresa Johnson         NumImportedFunctionsThinLink++;
510d2c234a4STeresa Johnson         if (IsHotCallsite)
511d2c234a4STeresa Johnson           NumImportedHotFunctionsThinLink++;
512d2c234a4STeresa Johnson         if (IsCriticalCallsite)
513d2c234a4STeresa Johnson           NumImportedCriticalFunctionsThinLink++;
514d2c234a4STeresa Johnson       }
515974706ebSTeresa Johnson 
516bed4d9c8STeresa Johnson       // Any calls/references made by this function will be marked exported
517bed4d9c8STeresa Johnson       // later, in ComputeCrossModuleImport, after import decisions are
518bed4d9c8STeresa Johnson       // complete, which is more efficient than adding them here.
519bed4d9c8STeresa Johnson       if (ExportLists)
520bed4d9c8STeresa Johnson         (*ExportLists)[ExportModulePath].insert(VI);
521d68935c5STeresa Johnson     }
522d68935c5STeresa Johnson 
523d68935c5STeresa Johnson     auto GetAdjustedThreshold = [](unsigned Threshold, bool IsHotCallsite) {
524d68935c5STeresa Johnson       // Adjust the threshold for next level of imported functions.
525d68935c5STeresa Johnson       // The threshold is different for hot callsites because we can then
526d68935c5STeresa Johnson       // inline chains of hot calls.
527d68935c5STeresa Johnson       if (IsHotCallsite)
528d68935c5STeresa Johnson         return Threshold * ImportHotInstrFactor;
529d68935c5STeresa Johnson       return Threshold * ImportInstrFactor;
530d68935c5STeresa Johnson     };
531d68935c5STeresa Johnson 
532d68935c5STeresa Johnson     const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite);
533d68935c5STeresa Johnson 
534d68935c5STeresa Johnson     ImportCount++;
535d2869473SPiotr Padlewski 
53601e32130SMehdi Amini     // Insert the newly imported function to the worklist.
537d5b701b9SEvgeny Leviant     Worklist.emplace_back(ResolvedCalleeSummary, AdjThreshold);
538d450da32STeresa Johnson   }
539d450da32STeresa Johnson }
540d450da32STeresa Johnson 
54101e32130SMehdi Amini /// Given the list of globals defined in a module, compute the list of imports
54201e32130SMehdi Amini /// as well as the list of "exports", i.e. the list of symbols referenced from
54301e32130SMehdi Amini /// another module (that may require promotion).
54401e32130SMehdi Amini static void ComputeImportForModule(
545c851d216STeresa Johnson     const GVSummaryMapTy &DefinedGVSummaries, const ModuleSummaryIndex &Index,
546cb9a82fcSTeresa Johnson     StringRef ModName, FunctionImporter::ImportMapTy &ImportList,
54756584bbfSEvgeniy Stepanov     StringMap<FunctionImporter::ExportSetTy> *ExportLists = nullptr) {
54801e32130SMehdi Amini   // Worklist contains the list of function imported in this module, for which
54901e32130SMehdi Amini   // we will analyse the callees and may import further down the callgraph.
55001e32130SMehdi Amini   SmallVector<EdgeInfo, 128> Worklist;
551d68935c5STeresa Johnson   FunctionImporter::ImportThresholdsTy ImportThresholds;
55201e32130SMehdi Amini 
55301e32130SMehdi Amini   // Populate the worklist with the import for the functions in the current
55401e32130SMehdi Amini   // module
55528e457bcSTeresa Johnson   for (auto &GVSummary : DefinedGVSummaries) {
5567e7b13d0STeresa Johnson #ifndef NDEBUG
5577e7b13d0STeresa Johnson     // FIXME: Change the GVSummaryMapTy to hold ValueInfo instead of GUID
5587e7b13d0STeresa Johnson     // so this map look up (and possibly others) can be avoided.
5597e7b13d0STeresa Johnson     auto VI = Index.getValueInfo(GVSummary.first);
5607e7b13d0STeresa Johnson #endif
56156584bbfSEvgeniy Stepanov     if (!Index.isGlobalValueLive(GVSummary.second)) {
5627e7b13d0STeresa Johnson       LLVM_DEBUG(dbgs() << "Ignores Dead GUID: " << VI << "\n");
5636c475a75STeresa Johnson       continue;
5646c475a75STeresa Johnson     }
565cfbd0892SPeter Collingbourne     auto *FuncSummary =
566cfbd0892SPeter Collingbourne         dyn_cast<FunctionSummary>(GVSummary.second->getBaseObject());
5671aafabf7SMehdi Amini     if (!FuncSummary)
5681aafabf7SMehdi Amini       // Skip import for global variables
5691aafabf7SMehdi Amini       continue;
5707e7b13d0STeresa Johnson     LLVM_DEBUG(dbgs() << "Initialize import for " << VI << "\n");
5712d28f7aaSMehdi Amini     computeImportForFunction(*FuncSummary, Index, ImportInstrLimit,
5729b490f10SMehdi Amini                              DefinedGVSummaries, Worklist, ImportList,
573d68935c5STeresa Johnson                              ExportLists, ImportThresholds);
57401e32130SMehdi Amini   }
57501e32130SMehdi Amini 
576d2869473SPiotr Padlewski   // Process the newly imported functions and add callees to the worklist.
57742418abaSMehdi Amini   while (!Worklist.empty()) {
578d5b701b9SEvgeny Leviant     auto GVInfo = Worklist.pop_back_val();
579d5b701b9SEvgeny Leviant     auto *Summary = std::get<0>(GVInfo);
580d5b701b9SEvgeny Leviant     auto Threshold = std::get<1>(GVInfo);
58142418abaSMehdi Amini 
582d5b701b9SEvgeny Leviant     if (auto *FS = dyn_cast<FunctionSummary>(Summary))
583d5b701b9SEvgeny Leviant       computeImportForFunction(*FS, Index, Threshold, DefinedGVSummaries,
584d68935c5STeresa Johnson                                Worklist, ImportList, ExportLists,
585d68935c5STeresa Johnson                                ImportThresholds);
586d5b701b9SEvgeny Leviant     else
587d5b701b9SEvgeny Leviant       computeImportForReferencedGlobals(*Summary, Index, DefinedGVSummaries,
588d5b701b9SEvgeny Leviant                                         Worklist, ImportList, ExportLists);
589c8c55170SMehdi Amini   }
590cb9a82fcSTeresa Johnson 
591cb9a82fcSTeresa Johnson   // Print stats about functions considered but rejected for importing
592cb9a82fcSTeresa Johnson   // when requested.
593cb9a82fcSTeresa Johnson   if (PrintImportFailures) {
594cb9a82fcSTeresa Johnson     dbgs() << "Missed imports into module " << ModName << "\n";
595cb9a82fcSTeresa Johnson     for (auto &I : ImportThresholds) {
596cb9a82fcSTeresa Johnson       auto &ProcessedThreshold = std::get<0>(I.second);
597cb9a82fcSTeresa Johnson       auto &CalleeSummary = std::get<1>(I.second);
598cb9a82fcSTeresa Johnson       auto &FailureInfo = std::get<2>(I.second);
599cb9a82fcSTeresa Johnson       if (CalleeSummary)
600cb9a82fcSTeresa Johnson         continue; // We are going to import.
601cb9a82fcSTeresa Johnson       assert(FailureInfo);
602cb9a82fcSTeresa Johnson       FunctionSummary *FS = nullptr;
603cb9a82fcSTeresa Johnson       if (!FailureInfo->VI.getSummaryList().empty())
604cb9a82fcSTeresa Johnson         FS = dyn_cast<FunctionSummary>(
605cb9a82fcSTeresa Johnson             FailureInfo->VI.getSummaryList()[0]->getBaseObject());
606cb9a82fcSTeresa Johnson       dbgs() << FailureInfo->VI
607cb9a82fcSTeresa Johnson              << ": Reason = " << getFailureName(FailureInfo->Reason)
608cb9a82fcSTeresa Johnson              << ", Threshold = " << ProcessedThreshold
609cb9a82fcSTeresa Johnson              << ", Size = " << (FS ? (int)FS->instCount() : -1)
610cb9a82fcSTeresa Johnson              << ", MaxHotness = " << getHotnessName(FailureInfo->MaxHotness)
611cb9a82fcSTeresa Johnson              << ", Attempts = " << FailureInfo->Attempts << "\n";
612cb9a82fcSTeresa Johnson     }
613cb9a82fcSTeresa Johnson   }
61442418abaSMehdi Amini }
615ffe2e4aaSMehdi Amini 
61619e23874SEugene Leviant #ifndef NDEBUG
6174ef9315cSevgeny static bool isGlobalVarSummary(const ModuleSummaryIndex &Index, ValueInfo VI) {
61819e23874SEugene Leviant   auto SL = VI.getSummaryList();
6194ef9315cSevgeny   return SL.empty()
6204ef9315cSevgeny              ? false
6214ef9315cSevgeny              : SL[0]->getSummaryKind() == GlobalValueSummary::GlobalVarKind;
62219e23874SEugene Leviant }
62319e23874SEugene Leviant 
6244ef9315cSevgeny static bool isGlobalVarSummary(const ModuleSummaryIndex &Index,
6254ef9315cSevgeny                                GlobalValue::GUID G) {
6264ef9315cSevgeny   if (const auto &VI = Index.getValueInfo(G))
6274ef9315cSevgeny     return isGlobalVarSummary(Index, VI);
6284ef9315cSevgeny   return false;
6294ef9315cSevgeny }
63019e23874SEugene Leviant 
63119e23874SEugene Leviant template <class T>
6321fc0da48SBenjamin Kramer static unsigned numGlobalVarSummaries(const ModuleSummaryIndex &Index,
6331fc0da48SBenjamin Kramer                                       T &Cont) {
63419e23874SEugene Leviant   unsigned NumGVS = 0;
63519e23874SEugene Leviant   for (auto &V : Cont)
6364ef9315cSevgeny     if (isGlobalVarSummary(Index, V))
63719e23874SEugene Leviant       ++NumGVS;
63819e23874SEugene Leviant   return NumGVS;
63919e23874SEugene Leviant }
64019e23874SEugene Leviant #endif
64119e23874SEugene Leviant 
6428bcd01f4SFangrui Song #ifndef NDEBUG
6433d708bf5Sevgeny static bool
6443d708bf5Sevgeny checkVariableImport(const ModuleSummaryIndex &Index,
6453d708bf5Sevgeny                     StringMap<FunctionImporter::ImportMapTy> &ImportLists,
6463d708bf5Sevgeny                     StringMap<FunctionImporter::ExportSetTy> &ExportLists) {
6473d708bf5Sevgeny 
6483d708bf5Sevgeny   DenseSet<GlobalValue::GUID> FlattenedImports;
6493d708bf5Sevgeny 
6503d708bf5Sevgeny   for (auto &ImportPerModule : ImportLists)
6513d708bf5Sevgeny     for (auto &ExportPerModule : ImportPerModule.second)
6523d708bf5Sevgeny       FlattenedImports.insert(ExportPerModule.second.begin(),
6533d708bf5Sevgeny                               ExportPerModule.second.end());
6543d708bf5Sevgeny 
6553d708bf5Sevgeny   // Checks that all GUIDs of read/writeonly vars we see in export lists
6563d708bf5Sevgeny   // are also in the import lists. Otherwise we my face linker undefs,
6573d708bf5Sevgeny   // because readonly and writeonly vars are internalized in their
6583d708bf5Sevgeny   // source modules.
6593d708bf5Sevgeny   auto IsReadOrWriteOnlyVar = [&](StringRef ModulePath, const ValueInfo &VI) {
6603d708bf5Sevgeny     auto *GVS = dyn_cast_or_null<GlobalVarSummary>(
6613d708bf5Sevgeny         Index.findSummaryInModule(VI, ModulePath));
6623d708bf5Sevgeny     return GVS && (Index.isReadOnly(GVS) || Index.isWriteOnly(GVS));
6633d708bf5Sevgeny   };
6643d708bf5Sevgeny 
6653d708bf5Sevgeny   for (auto &ExportPerModule : ExportLists)
6663d708bf5Sevgeny     for (auto &VI : ExportPerModule.second)
6673d708bf5Sevgeny       if (!FlattenedImports.count(VI.getGUID()) &&
6683d708bf5Sevgeny           IsReadOrWriteOnlyVar(ExportPerModule.first(), VI))
6693d708bf5Sevgeny         return false;
6703d708bf5Sevgeny 
6713d708bf5Sevgeny   return true;
6723d708bf5Sevgeny }
6738bcd01f4SFangrui Song #endif
6743d708bf5Sevgeny 
675c86af334STeresa Johnson /// Compute all the import and export for every module using the Index.
67601e32130SMehdi Amini void llvm::ComputeCrossModuleImport(
67701e32130SMehdi Amini     const ModuleSummaryIndex &Index,
678c851d216STeresa Johnson     const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,
67901e32130SMehdi Amini     StringMap<FunctionImporter::ImportMapTy> &ImportLists,
68056584bbfSEvgeniy Stepanov     StringMap<FunctionImporter::ExportSetTy> &ExportLists) {
68101e32130SMehdi Amini   // For each module that has function defined, compute the import/export lists.
6821aafabf7SMehdi Amini   for (auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) {
6839b490f10SMehdi Amini     auto &ImportList = ImportLists[DefinedGVSummaries.first()];
684d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "Computing import for Module '"
6851aafabf7SMehdi Amini                       << DefinedGVSummaries.first() << "'\n");
686cb9a82fcSTeresa Johnson     ComputeImportForModule(DefinedGVSummaries.second, Index,
687cb9a82fcSTeresa Johnson                            DefinedGVSummaries.first(), ImportList,
68856584bbfSEvgeniy Stepanov                            &ExportLists);
68901e32130SMehdi Amini   }
69001e32130SMehdi Amini 
691bed4d9c8STeresa Johnson   // When computing imports we only added the variables and functions being
692bed4d9c8STeresa Johnson   // imported to the export list. We also need to mark any references and calls
693bed4d9c8STeresa Johnson   // they make as exported as well. We do this here, as it is more efficient
694bed4d9c8STeresa Johnson   // since we may import the same values multiple times into different modules
695bed4d9c8STeresa Johnson   // during the import computation.
696edddca22STeresa Johnson   for (auto &ELI : ExportLists) {
697bed4d9c8STeresa Johnson     FunctionImporter::ExportSetTy NewExports;
698edddca22STeresa Johnson     const auto &DefinedGVSummaries =
699edddca22STeresa Johnson         ModuleToDefinedGVSummaries.lookup(ELI.first());
700bed4d9c8STeresa Johnson     for (auto &EI : ELI.second) {
701bed4d9c8STeresa Johnson       // Find the copy defined in the exporting module so that we can mark the
702bed4d9c8STeresa Johnson       // values it references in that specific definition as exported.
703bed4d9c8STeresa Johnson       // Below we will add all references and called values, without regard to
704bed4d9c8STeresa Johnson       // whether they are also defined in this module. We subsequently prune the
705bed4d9c8STeresa Johnson       // list to only include those defined in the exporting module, see comment
706bed4d9c8STeresa Johnson       // there as to why.
707bed4d9c8STeresa Johnson       auto DS = DefinedGVSummaries.find(EI.getGUID());
708bed4d9c8STeresa Johnson       // Anything marked exported during the import computation must have been
709bed4d9c8STeresa Johnson       // defined in the exporting module.
710bed4d9c8STeresa Johnson       assert(DS != DefinedGVSummaries.end());
711bed4d9c8STeresa Johnson       auto *S = DS->getSecond();
712bed4d9c8STeresa Johnson       S = S->getBaseObject();
713bed4d9c8STeresa Johnson       if (auto *GVS = dyn_cast<GlobalVarSummary>(S)) {
714bed4d9c8STeresa Johnson         // Export referenced functions and variables. We don't export/promote
715bed4d9c8STeresa Johnson         // objects referenced by writeonly variable initializer, because
716bed4d9c8STeresa Johnson         // we convert such variables initializers to "zeroinitializer".
717bed4d9c8STeresa Johnson         // See processGlobalForThinLTO.
718bed4d9c8STeresa Johnson         if (!Index.isWriteOnly(GVS))
719bed4d9c8STeresa Johnson           for (const auto &VI : GVS->refs())
720bed4d9c8STeresa Johnson             NewExports.insert(VI);
721bed4d9c8STeresa Johnson       } else {
722bed4d9c8STeresa Johnson         auto *FS = cast<FunctionSummary>(S);
723bed4d9c8STeresa Johnson         for (auto &Edge : FS->calls())
724bed4d9c8STeresa Johnson           NewExports.insert(Edge.first);
725bed4d9c8STeresa Johnson         for (auto &Ref : FS->refs())
726bed4d9c8STeresa Johnson           NewExports.insert(Ref);
727bed4d9c8STeresa Johnson       }
728bed4d9c8STeresa Johnson     }
729bed4d9c8STeresa Johnson     // Prune list computed above to only include values defined in the exporting
730bed4d9c8STeresa Johnson     // module. We do this after the above insertion since we may hit the same
731bed4d9c8STeresa Johnson     // ref/call target multiple times in above loop, and it is more efficient to
732bed4d9c8STeresa Johnson     // avoid a set lookup each time.
733bed4d9c8STeresa Johnson     for (auto EI = NewExports.begin(); EI != NewExports.end();) {
7343d708bf5Sevgeny       if (!DefinedGVSummaries.count(EI->getGUID()))
735bed4d9c8STeresa Johnson         NewExports.erase(EI++);
736360f6617SBenjamin Kramer       else
737360f6617SBenjamin Kramer         ++EI;
738360f6617SBenjamin Kramer     }
739bed4d9c8STeresa Johnson     ELI.second.insert(NewExports.begin(), NewExports.end());
740edddca22STeresa Johnson   }
741edddca22STeresa Johnson 
7423d708bf5Sevgeny   assert(checkVariableImport(Index, ImportLists, ExportLists));
74301e32130SMehdi Amini #ifndef NDEBUG
744d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "Import/Export lists for " << ImportLists.size()
74501e32130SMehdi Amini                     << " modules:\n");
74601e32130SMehdi Amini   for (auto &ModuleImports : ImportLists) {
74701e32130SMehdi Amini     auto ModName = ModuleImports.first();
74801e32130SMehdi Amini     auto &Exports = ExportLists[ModName];
74919e23874SEugene Leviant     unsigned NumGVS = numGlobalVarSummaries(Index, Exports);
750d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "* Module " << ModName << " exports "
75119e23874SEugene Leviant                       << Exports.size() - NumGVS << " functions and " << NumGVS
752d34e60caSNicola Zaghen                       << " vars. Imports from " << ModuleImports.second.size()
753d34e60caSNicola Zaghen                       << " modules.\n");
75401e32130SMehdi Amini     for (auto &Src : ModuleImports.second) {
75501e32130SMehdi Amini       auto SrcModName = Src.first();
75619e23874SEugene Leviant       unsigned NumGVSPerMod = numGlobalVarSummaries(Index, Src.second);
757d34e60caSNicola Zaghen       LLVM_DEBUG(dbgs() << " - " << Src.second.size() - NumGVSPerMod
75819e23874SEugene Leviant                         << " functions imported from " << SrcModName << "\n");
759d34e60caSNicola Zaghen       LLVM_DEBUG(dbgs() << " - " << NumGVSPerMod
760d34e60caSNicola Zaghen                         << " global vars imported from " << SrcModName << "\n");
76101e32130SMehdi Amini     }
76201e32130SMehdi Amini   }
76301e32130SMehdi Amini #endif
76401e32130SMehdi Amini }
76501e32130SMehdi Amini 
76681bbf742STeresa Johnson #ifndef NDEBUG
76719e23874SEugene Leviant static void dumpImportListForModule(const ModuleSummaryIndex &Index,
76819e23874SEugene Leviant                                     StringRef ModulePath,
76981bbf742STeresa Johnson                                     FunctionImporter::ImportMapTy &ImportList) {
770d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "* Module " << ModulePath << " imports from "
77181bbf742STeresa Johnson                     << ImportList.size() << " modules.\n");
77281bbf742STeresa Johnson   for (auto &Src : ImportList) {
77381bbf742STeresa Johnson     auto SrcModName = Src.first();
77419e23874SEugene Leviant     unsigned NumGVSPerMod = numGlobalVarSummaries(Index, Src.second);
775d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << " - " << Src.second.size() - NumGVSPerMod
77619e23874SEugene Leviant                       << " functions imported from " << SrcModName << "\n");
777d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << " - " << NumGVSPerMod << " vars imported from "
77881bbf742STeresa Johnson                       << SrcModName << "\n");
77981bbf742STeresa Johnson   }
78081bbf742STeresa Johnson }
78169b2de84STeresa Johnson #endif
78281bbf742STeresa Johnson 
783c86af334STeresa Johnson /// Compute all the imports for the given module in the Index.
784c86af334STeresa Johnson void llvm::ComputeCrossModuleImportForModule(
785c86af334STeresa Johnson     StringRef ModulePath, const ModuleSummaryIndex &Index,
786c86af334STeresa Johnson     FunctionImporter::ImportMapTy &ImportList) {
787c86af334STeresa Johnson   // Collect the list of functions this module defines.
788c86af334STeresa Johnson   // GUID -> Summary
789c851d216STeresa Johnson   GVSummaryMapTy FunctionSummaryMap;
79028e457bcSTeresa Johnson   Index.collectDefinedFunctionsForModule(ModulePath, FunctionSummaryMap);
791c86af334STeresa Johnson 
792c86af334STeresa Johnson   // Compute the import list for this module.
793d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "Computing import for Module '" << ModulePath << "'\n");
794cb9a82fcSTeresa Johnson   ComputeImportForModule(FunctionSummaryMap, Index, ModulePath, ImportList);
795c86af334STeresa Johnson 
796c86af334STeresa Johnson #ifndef NDEBUG
79719e23874SEugene Leviant   dumpImportListForModule(Index, ModulePath, ImportList);
79881bbf742STeresa Johnson #endif
799c86af334STeresa Johnson }
80081bbf742STeresa Johnson 
80181bbf742STeresa Johnson // Mark all external summaries in Index for import into the given module.
80281bbf742STeresa Johnson // Used for distributed builds using a distributed index.
80381bbf742STeresa Johnson void llvm::ComputeCrossModuleImportForModuleFromIndex(
80481bbf742STeresa Johnson     StringRef ModulePath, const ModuleSummaryIndex &Index,
80581bbf742STeresa Johnson     FunctionImporter::ImportMapTy &ImportList) {
80681bbf742STeresa Johnson   for (auto &GlobalList : Index) {
80781bbf742STeresa Johnson     // Ignore entries for undefined references.
80881bbf742STeresa Johnson     if (GlobalList.second.SummaryList.empty())
80981bbf742STeresa Johnson       continue;
81081bbf742STeresa Johnson 
81181bbf742STeresa Johnson     auto GUID = GlobalList.first;
81281bbf742STeresa Johnson     assert(GlobalList.second.SummaryList.size() == 1 &&
81381bbf742STeresa Johnson            "Expected individual combined index to have one summary per GUID");
81481bbf742STeresa Johnson     auto &Summary = GlobalList.second.SummaryList[0];
81581bbf742STeresa Johnson     // Skip the summaries for the importing module. These are included to
81681bbf742STeresa Johnson     // e.g. record required linkage changes.
81781bbf742STeresa Johnson     if (Summary->modulePath() == ModulePath)
81881bbf742STeresa Johnson       continue;
819d68935c5STeresa Johnson     // Add an entry to provoke importing by thinBackend.
820d68935c5STeresa Johnson     ImportList[Summary->modulePath()].insert(GUID);
82181bbf742STeresa Johnson   }
82281bbf742STeresa Johnson #ifndef NDEBUG
82319e23874SEugene Leviant   dumpImportListForModule(Index, ModulePath, ImportList);
824c86af334STeresa Johnson #endif
825c86af334STeresa Johnson }
826c86af334STeresa Johnson 
82756584bbfSEvgeniy Stepanov void llvm::computeDeadSymbols(
82856584bbfSEvgeniy Stepanov     ModuleSummaryIndex &Index,
829eaf5172cSGeorge Rimar     const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
830eaf5172cSGeorge Rimar     function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing) {
83156584bbfSEvgeniy Stepanov   assert(!Index.withGlobalValueDeadStripping());
8326c475a75STeresa Johnson   if (!ComputeDead)
83356584bbfSEvgeniy Stepanov     return;
8346c475a75STeresa Johnson   if (GUIDPreservedSymbols.empty())
8356c475a75STeresa Johnson     // Don't do anything when nothing is live, this is friendly with tests.
83656584bbfSEvgeniy Stepanov     return;
83756584bbfSEvgeniy Stepanov   unsigned LiveSymbols = 0;
8389667b91bSPeter Collingbourne   SmallVector<ValueInfo, 128> Worklist;
8399667b91bSPeter Collingbourne   Worklist.reserve(GUIDPreservedSymbols.size() * 2);
8409667b91bSPeter Collingbourne   for (auto GUID : GUIDPreservedSymbols) {
8419667b91bSPeter Collingbourne     ValueInfo VI = Index.getValueInfo(GUID);
8429667b91bSPeter Collingbourne     if (!VI)
8439667b91bSPeter Collingbourne       continue;
84456584bbfSEvgeniy Stepanov     for (auto &S : VI.getSummaryList())
84556584bbfSEvgeniy Stepanov       S->setLive(true);
8466c475a75STeresa Johnson   }
84756584bbfSEvgeniy Stepanov 
8486c475a75STeresa Johnson   // Add values flagged in the index as live roots to the worklist.
8497e7b13d0STeresa Johnson   for (const auto &Entry : Index) {
8507e7b13d0STeresa Johnson     auto VI = Index.getValueInfo(Entry);
85156584bbfSEvgeniy Stepanov     for (auto &S : Entry.second.SummaryList)
85256584bbfSEvgeniy Stepanov       if (S->isLive()) {
8537e7b13d0STeresa Johnson         LLVM_DEBUG(dbgs() << "Live root: " << VI << "\n");
8547e7b13d0STeresa Johnson         Worklist.push_back(VI);
85556584bbfSEvgeniy Stepanov         ++LiveSymbols;
85656584bbfSEvgeniy Stepanov         break;
8576c475a75STeresa Johnson       }
8587e7b13d0STeresa Johnson   }
8596c475a75STeresa Johnson 
86056584bbfSEvgeniy Stepanov   // Make value live and add it to the worklist if it was not live before.
861ea314fd4STeresa Johnson   auto visit = [&](ValueInfo VI, bool IsAliasee) {
8621958083dSTeresa Johnson     // FIXME: If we knew which edges were created for indirect call profiles,
8631958083dSTeresa Johnson     // we could skip them here. Any that are live should be reached via
8641958083dSTeresa Johnson     // other edges, e.g. reference edges. Otherwise, using a profile collected
8651958083dSTeresa Johnson     // on a slightly different binary might provoke preserving, importing
8661958083dSTeresa Johnson     // and ultimately promoting calls to functions not linked into this
8671958083dSTeresa Johnson     // binary, which increases the binary size unnecessarily. Note that
8681958083dSTeresa Johnson     // if this code changes, the importer needs to change so that edges
8691958083dSTeresa Johnson     // to functions marked dead are skipped.
8701958083dSTeresa Johnson     VI = updateValueInfoForIndirectCalls(Index, VI);
8711958083dSTeresa Johnson     if (!VI)
8721958083dSTeresa Johnson       return;
87333e3b4b9SXin Tong 
8745b2f6a1bSTeresa Johnson     if (llvm::any_of(VI.getSummaryList(),
87533e3b4b9SXin Tong                      [](const std::unique_ptr<llvm::GlobalValueSummary> &S) {
87633e3b4b9SXin Tong                        return S->isLive();
87733e3b4b9SXin Tong                      }))
878f625118eSTeresa Johnson       return;
879eaf5172cSGeorge Rimar 
880aab60006SVlad Tsyrklevich     // We only keep live symbols that are known to be non-prevailing if any are
881bfdad33bSXin Tong     // available_externally, linkonceodr, weakodr. Those symbols are discarded
882bfdad33bSXin Tong     // later in the EliminateAvailableExternally pass and setting them to
883bfdad33bSXin Tong     // not-live could break downstreams users of liveness information (PR36483)
884bfdad33bSXin Tong     // or limit optimization opportunities.
885aab60006SVlad Tsyrklevich     if (isPrevailing(VI.getGUID()) == PrevailingType::No) {
886bfdad33bSXin Tong       bool KeepAliveLinkage = false;
887aab60006SVlad Tsyrklevich       bool Interposable = false;
888aab60006SVlad Tsyrklevich       for (auto &S : VI.getSummaryList()) {
889bfdad33bSXin Tong         if (S->linkage() == GlobalValue::AvailableExternallyLinkage ||
890bfdad33bSXin Tong             S->linkage() == GlobalValue::WeakODRLinkage ||
891bfdad33bSXin Tong             S->linkage() == GlobalValue::LinkOnceODRLinkage)
892bfdad33bSXin Tong           KeepAliveLinkage = true;
893aab60006SVlad Tsyrklevich         else if (GlobalValue::isInterposableLinkage(S->linkage()))
894aab60006SVlad Tsyrklevich           Interposable = true;
895aab60006SVlad Tsyrklevich       }
896aab60006SVlad Tsyrklevich 
897ea314fd4STeresa Johnson       if (!IsAliasee) {
898bfdad33bSXin Tong         if (!KeepAliveLinkage)
899eaf5172cSGeorge Rimar           return;
900eaf5172cSGeorge Rimar 
901aab60006SVlad Tsyrklevich         if (Interposable)
902bfdad33bSXin Tong           report_fatal_error(
903ea314fd4STeresa Johnson               "Interposable and available_externally/linkonce_odr/weak_odr "
904ea314fd4STeresa Johnson               "symbol");
905ea314fd4STeresa Johnson       }
906aab60006SVlad Tsyrklevich     }
907aab60006SVlad Tsyrklevich 
908f625118eSTeresa Johnson     for (auto &S : VI.getSummaryList())
90956584bbfSEvgeniy Stepanov       S->setLive(true);
91056584bbfSEvgeniy Stepanov     ++LiveSymbols;
91156584bbfSEvgeniy Stepanov     Worklist.push_back(VI);
91256584bbfSEvgeniy Stepanov   };
91356584bbfSEvgeniy Stepanov 
9146c475a75STeresa Johnson   while (!Worklist.empty()) {
9159667b91bSPeter Collingbourne     auto VI = Worklist.pop_back_val();
9169667b91bSPeter Collingbourne     for (auto &Summary : VI.getSummaryList()) {
9171479cdfeSTeresa Johnson       Summary->setLive(true);
9185b2f6a1bSTeresa Johnson       if (auto *AS = dyn_cast<AliasSummary>(Summary.get())) {
9195b2f6a1bSTeresa Johnson         // If this is an alias, visit the aliasee VI to ensure that all copies
9205b2f6a1bSTeresa Johnson         // are marked live and it is added to the worklist for further
9215b2f6a1bSTeresa Johnson         // processing of its references.
922ea314fd4STeresa Johnson         visit(AS->getAliaseeVI(), true);
9235b2f6a1bSTeresa Johnson         continue;
9245b2f6a1bSTeresa Johnson       }
9255b2f6a1bSTeresa Johnson       for (auto Ref : Summary->refs())
926ea314fd4STeresa Johnson         visit(Ref, false);
9275b2f6a1bSTeresa Johnson       if (auto *FS = dyn_cast<FunctionSummary>(Summary.get()))
92856584bbfSEvgeniy Stepanov         for (auto Call : FS->calls())
929ea314fd4STeresa Johnson           visit(Call.first, false);
9306c475a75STeresa Johnson     }
9316c475a75STeresa Johnson   }
93256584bbfSEvgeniy Stepanov   Index.setWithGlobalValueDeadStripping();
93356584bbfSEvgeniy Stepanov 
93456584bbfSEvgeniy Stepanov   unsigned DeadSymbols = Index.size() - LiveSymbols;
935d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << LiveSymbols << " symbols Live, and " << DeadSymbols
93656584bbfSEvgeniy Stepanov                     << " symbols Dead \n");
93756584bbfSEvgeniy Stepanov   NumDeadSymbols += DeadSymbols;
93856584bbfSEvgeniy Stepanov   NumLiveSymbols += LiveSymbols;
9396c475a75STeresa Johnson }
9406c475a75STeresa Johnson 
941bf46e741SEugene Leviant // Compute dead symbols and propagate constants in combined index.
942bf46e741SEugene Leviant void llvm::computeDeadSymbolsWithConstProp(
943bf46e741SEugene Leviant     ModuleSummaryIndex &Index,
944bf46e741SEugene Leviant     const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
945bf46e741SEugene Leviant     function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing,
946bf46e741SEugene Leviant     bool ImportEnabled) {
947bf46e741SEugene Leviant   computeDeadSymbols(Index, GUIDPreservedSymbols, isPrevailing);
94854a3c2a8STeresa Johnson   if (ImportEnabled)
9493aef3528SEugene Leviant     Index.propagateAttributes(GUIDPreservedSymbols);
950bf46e741SEugene Leviant }
951bf46e741SEugene Leviant 
95284174c37STeresa Johnson /// Compute the set of summaries needed for a ThinLTO backend compilation of
95384174c37STeresa Johnson /// \p ModulePath.
95484174c37STeresa Johnson void llvm::gatherImportedSummariesForModule(
95584174c37STeresa Johnson     StringRef ModulePath,
95684174c37STeresa Johnson     const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,
957cdbcbf74SMehdi Amini     const FunctionImporter::ImportMapTy &ImportList,
95884174c37STeresa Johnson     std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
95984174c37STeresa Johnson   // Include all summaries from the importing module.
960adcd0268SBenjamin Kramer   ModuleToSummariesForIndex[std::string(ModulePath)] =
96184174c37STeresa Johnson       ModuleToDefinedGVSummaries.lookup(ModulePath);
96284174c37STeresa Johnson   // Include summaries for imports.
96388c491ddSMehdi Amini   for (auto &ILI : ImportList) {
964adcd0268SBenjamin Kramer     auto &SummariesForIndex =
965adcd0268SBenjamin Kramer         ModuleToSummariesForIndex[std::string(ILI.first())];
96684174c37STeresa Johnson     const auto &DefinedGVSummaries =
96784174c37STeresa Johnson         ModuleToDefinedGVSummaries.lookup(ILI.first());
96884174c37STeresa Johnson     for (auto &GI : ILI.second) {
969d68935c5STeresa Johnson       const auto &DS = DefinedGVSummaries.find(GI);
97084174c37STeresa Johnson       assert(DS != DefinedGVSummaries.end() &&
97184174c37STeresa Johnson              "Expected a defined summary for imported global value");
972d68935c5STeresa Johnson       SummariesForIndex[GI] = DS->second;
97384174c37STeresa Johnson     }
97484174c37STeresa Johnson   }
97584174c37STeresa Johnson }
97684174c37STeresa Johnson 
9778570fe47STeresa Johnson /// Emit the files \p ModulePath will import from into \p OutputFilename.
978c0320ef4STeresa Johnson std::error_code llvm::EmitImportsFiles(
979c0320ef4STeresa Johnson     StringRef ModulePath, StringRef OutputFilename,
980c0320ef4STeresa Johnson     const std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
9818570fe47STeresa Johnson   std::error_code EC;
982d9b948b6SFangrui Song   raw_fd_ostream ImportsOS(OutputFilename, EC, sys::fs::OpenFlags::OF_None);
9838570fe47STeresa Johnson   if (EC)
9848570fe47STeresa Johnson     return EC;
985c0320ef4STeresa Johnson   for (auto &ILI : ModuleToSummariesForIndex)
986c0320ef4STeresa Johnson     // The ModuleToSummariesForIndex map includes an entry for the current
987c0320ef4STeresa Johnson     // Module (needed for writing out the index files). We don't want to
988c0320ef4STeresa Johnson     // include it in the imports file, however, so filter it out.
989c0320ef4STeresa Johnson     if (ILI.first != ModulePath)
990c0320ef4STeresa Johnson       ImportsOS << ILI.first << "\n";
9918570fe47STeresa Johnson   return std::error_code();
9928570fe47STeresa Johnson }
9938570fe47STeresa Johnson 
9945a95c477STeresa Johnson bool llvm::convertToDeclaration(GlobalValue &GV) {
995d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "Converting to a declaration: `" << GV.getName()
996d34e60caSNicola Zaghen                     << "\n");
9974566c6dbSTeresa Johnson   if (Function *F = dyn_cast<Function>(&GV)) {
9984566c6dbSTeresa Johnson     F->deleteBody();
9994566c6dbSTeresa Johnson     F->clearMetadata();
10007873669bSPeter Collingbourne     F->setComdat(nullptr);
10014566c6dbSTeresa Johnson   } else if (GlobalVariable *V = dyn_cast<GlobalVariable>(&GV)) {
10024566c6dbSTeresa Johnson     V->setInitializer(nullptr);
10034566c6dbSTeresa Johnson     V->setLinkage(GlobalValue::ExternalLinkage);
10044566c6dbSTeresa Johnson     V->clearMetadata();
10057873669bSPeter Collingbourne     V->setComdat(nullptr);
10065a95c477STeresa Johnson   } else {
10075a95c477STeresa Johnson     GlobalValue *NewGV;
10085a95c477STeresa Johnson     if (GV.getValueType()->isFunctionTy())
10095a95c477STeresa Johnson       NewGV =
10105a95c477STeresa Johnson           Function::Create(cast<FunctionType>(GV.getValueType()),
1011f920da00SDylan McKay                            GlobalValue::ExternalLinkage, GV.getAddressSpace(),
1012f920da00SDylan McKay                            "", GV.getParent());
10135a95c477STeresa Johnson     else
10145a95c477STeresa Johnson       NewGV =
10155a95c477STeresa Johnson           new GlobalVariable(*GV.getParent(), GV.getValueType(),
10165a95c477STeresa Johnson                              /*isConstant*/ false, GlobalValue::ExternalLinkage,
10175a95c477STeresa Johnson                              /*init*/ nullptr, "",
10185a95c477STeresa Johnson                              /*insertbefore*/ nullptr, GV.getThreadLocalMode(),
10195a95c477STeresa Johnson                              GV.getType()->getAddressSpace());
10205a95c477STeresa Johnson     NewGV->takeName(&GV);
10215a95c477STeresa Johnson     GV.replaceAllUsesWith(NewGV);
10225a95c477STeresa Johnson     return false;
10235a95c477STeresa Johnson   }
1024952ee0dfSFangrui Song   if (!GV.isImplicitDSOLocal())
1025952ee0dfSFangrui Song     GV.setDSOLocal(false);
10265a95c477STeresa Johnson   return true;
1027eaf5172cSGeorge Rimar }
10284566c6dbSTeresa Johnson 
1029e61652a3SPirama Arumuga Nainar void llvm::thinLTOResolvePrevailingInModule(
1030eaf5172cSGeorge Rimar     Module &TheModule, const GVSummaryMapTy &DefinedGlobals) {
103104c9a2d6STeresa Johnson   auto updateLinkage = [&](GlobalValue &GV) {
103204c9a2d6STeresa Johnson     // See if the global summary analysis computed a new resolved linkage.
103304c9a2d6STeresa Johnson     const auto &GS = DefinedGlobals.find(GV.getGUID());
103404c9a2d6STeresa Johnson     if (GS == DefinedGlobals.end())
103504c9a2d6STeresa Johnson       return;
103604c9a2d6STeresa Johnson     auto NewLinkage = GS->second->linkage();
1037e61652a3SPirama Arumuga Nainar     if (GlobalValue::isLocalLinkage(GV.getLinkage()) ||
1038e5dd30f7SEugene Leviant         // Don't internalize anything here, because the code below
1039e5dd30f7SEugene Leviant         // lacks necessary correctness checks. Leave this job to
1040e5dd30f7SEugene Leviant         // LLVM 'internalize' pass.
10410f418677SEugene Leviant         GlobalValue::isLocalLinkage(NewLinkage) ||
1042e61652a3SPirama Arumuga Nainar         // In case it was dead and already converted to declaration.
1043e61652a3SPirama Arumuga Nainar         GV.isDeclaration())
10446a5fbe52SDavide Italiano       return;
1045ea314fd4STeresa Johnson 
104654fb3ca9SFangrui Song     // Set the potentially more constraining visibility computed from summaries.
104754fb3ca9SFangrui Song     // The DefaultVisibility condition is because older GlobalValueSummary does
104854fb3ca9SFangrui Song     // not record DefaultVisibility and we don't want to change protected/hidden
104954fb3ca9SFangrui Song     // to default.
105054fb3ca9SFangrui Song     if (GS->second->getVisibility() != GlobalValue::DefaultVisibility)
105154fb3ca9SFangrui Song       GV.setVisibility(GS->second->getVisibility());
105254fb3ca9SFangrui Song 
105354fb3ca9SFangrui Song     if (NewLinkage == GV.getLinkage())
105454fb3ca9SFangrui Song       return;
105554fb3ca9SFangrui Song 
10564566c6dbSTeresa Johnson     // Check for a non-prevailing def that has interposable linkage
10574566c6dbSTeresa Johnson     // (e.g. non-odr weak or linkonce). In that case we can't simply
10584566c6dbSTeresa Johnson     // convert to available_externally, since it would lose the
10594566c6dbSTeresa Johnson     // interposable property and possibly get inlined. Simply drop
10604566c6dbSTeresa Johnson     // the definition in that case.
10614566c6dbSTeresa Johnson     if (GlobalValue::isAvailableExternallyLinkage(NewLinkage) &&
10625a95c477STeresa Johnson         GlobalValue::isInterposableLinkage(GV.getLinkage())) {
10635a95c477STeresa Johnson       if (!convertToDeclaration(GV))
10645a95c477STeresa Johnson         // FIXME: Change this to collect replaced GVs and later erase
1065e61652a3SPirama Arumuga Nainar         // them from the parent module once thinLTOResolvePrevailingGUID is
10665a95c477STeresa Johnson         // changed to enable this for aliases.
10675a95c477STeresa Johnson         llvm_unreachable("Expected GV to be converted");
10685a95c477STeresa Johnson     } else {
106937b80122STeresa Johnson       // If all copies of the original symbol had global unnamed addr and
107037b80122STeresa Johnson       // linkonce_odr linkage, it should be an auto hide symbol. In that case
107137b80122STeresa Johnson       // the thin link would have marked it as CanAutoHide. Add hidden visibility
107237b80122STeresa Johnson       // to the symbol to preserve the property.
107337b80122STeresa Johnson       if (NewLinkage == GlobalValue::WeakODRLinkage &&
107437b80122STeresa Johnson           GS->second->canAutoHide()) {
107537b80122STeresa Johnson         assert(GV.hasLinkOnceODRLinkage() && GV.hasGlobalUnnamedAddr());
107633ba93c2SSteven Wu         GV.setVisibility(GlobalValue::HiddenVisibility);
107737b80122STeresa Johnson       }
107833ba93c2SSteven Wu 
1079d34e60caSNicola Zaghen       LLVM_DEBUG(dbgs() << "ODR fixing up linkage for `" << GV.getName()
1080d34e60caSNicola Zaghen                         << "` from " << GV.getLinkage() << " to " << NewLinkage
1081d34e60caSNicola Zaghen                         << "\n");
108204c9a2d6STeresa Johnson       GV.setLinkage(NewLinkage);
10834566c6dbSTeresa Johnson     }
10844566c6dbSTeresa Johnson     // Remove declarations from comdats, including available_externally
10856107a419STeresa Johnson     // as this is a declaration for the linker, and will be dropped eventually.
10866107a419STeresa Johnson     // It is illegal for comdats to contain declarations.
10876107a419STeresa Johnson     auto *GO = dyn_cast_or_null<GlobalObject>(&GV);
10884566c6dbSTeresa Johnson     if (GO && GO->isDeclarationForLinker() && GO->hasComdat())
10896107a419STeresa Johnson       GO->setComdat(nullptr);
109004c9a2d6STeresa Johnson   };
109104c9a2d6STeresa Johnson 
109204c9a2d6STeresa Johnson   // Process functions and global now
109304c9a2d6STeresa Johnson   for (auto &GV : TheModule)
109404c9a2d6STeresa Johnson     updateLinkage(GV);
109504c9a2d6STeresa Johnson   for (auto &GV : TheModule.globals())
109604c9a2d6STeresa Johnson     updateLinkage(GV);
109704c9a2d6STeresa Johnson   for (auto &GV : TheModule.aliases())
109804c9a2d6STeresa Johnson     updateLinkage(GV);
109904c9a2d6STeresa Johnson }
110004c9a2d6STeresa Johnson 
110104c9a2d6STeresa Johnson /// Run internalization on \p TheModule based on symmary analysis.
110204c9a2d6STeresa Johnson void llvm::thinLTOInternalizeModule(Module &TheModule,
110304c9a2d6STeresa Johnson                                     const GVSummaryMapTy &DefinedGlobals) {
110404c9a2d6STeresa Johnson   // Declare a callback for the internalize pass that will ask for every
110504c9a2d6STeresa Johnson   // candidate GlobalValue if it can be internalized or not.
110604c9a2d6STeresa Johnson   auto MustPreserveGV = [&](const GlobalValue &GV) -> bool {
110704c9a2d6STeresa Johnson     // Lookup the linkage recorded in the summaries during global analysis.
1108c3d677f9SPeter Collingbourne     auto GS = DefinedGlobals.find(GV.getGUID());
110904c9a2d6STeresa Johnson     if (GS == DefinedGlobals.end()) {
111004c9a2d6STeresa Johnson       // Must have been promoted (possibly conservatively). Find original
111104c9a2d6STeresa Johnson       // name so that we can access the correct summary and see if it can
111204c9a2d6STeresa Johnson       // be internalized again.
111304c9a2d6STeresa Johnson       // FIXME: Eventually we should control promotion instead of promoting
111404c9a2d6STeresa Johnson       // and internalizing again.
111504c9a2d6STeresa Johnson       StringRef OrigName =
111604c9a2d6STeresa Johnson           ModuleSummaryIndex::getOriginalNameBeforePromote(GV.getName());
111704c9a2d6STeresa Johnson       std::string OrigId = GlobalValue::getGlobalIdentifier(
111804c9a2d6STeresa Johnson           OrigName, GlobalValue::InternalLinkage,
111904c9a2d6STeresa Johnson           TheModule.getSourceFileName());
1120c3d677f9SPeter Collingbourne       GS = DefinedGlobals.find(GlobalValue::getGUID(OrigId));
11217ab1f692STeresa Johnson       if (GS == DefinedGlobals.end()) {
11227ab1f692STeresa Johnson         // Also check the original non-promoted non-globalized name. In some
11237ab1f692STeresa Johnson         // cases a preempted weak value is linked in as a local copy because
11247ab1f692STeresa Johnson         // it is referenced by an alias (IRLinker::linkGlobalValueProto).
11257ab1f692STeresa Johnson         // In that case, since it was originally not a local value, it was
11267ab1f692STeresa Johnson         // recorded in the index using the original name.
11277ab1f692STeresa Johnson         // FIXME: This may not be needed once PR27866 is fixed.
1128c3d677f9SPeter Collingbourne         GS = DefinedGlobals.find(GlobalValue::getGUID(OrigName));
112904c9a2d6STeresa Johnson         assert(GS != DefinedGlobals.end());
11307ab1f692STeresa Johnson       }
1131c3d677f9SPeter Collingbourne     }
1132c3d677f9SPeter Collingbourne     return !GlobalValue::isLocalLinkage(GS->second->linkage());
113304c9a2d6STeresa Johnson   };
113404c9a2d6STeresa Johnson 
113504c9a2d6STeresa Johnson   // FIXME: See if we can just internalize directly here via linkage changes
113604c9a2d6STeresa Johnson   // based on the index, rather than invoking internalizeModule.
1137e9ea08a0SEugene Zelenko   internalizeModule(TheModule, MustPreserveGV);
113804c9a2d6STeresa Johnson }
113904c9a2d6STeresa Johnson 
114081bbf742STeresa Johnson /// Make alias a clone of its aliasee.
114181bbf742STeresa Johnson static Function *replaceAliasWithAliasee(Module *SrcModule, GlobalAlias *GA) {
114281bbf742STeresa Johnson   Function *Fn = cast<Function>(GA->getBaseObject());
114381bbf742STeresa Johnson 
114481bbf742STeresa Johnson   ValueToValueMapTy VMap;
114581bbf742STeresa Johnson   Function *NewFn = CloneFunction(Fn, VMap);
11465b2088d1STeresa Johnson   // Clone should use the original alias's linkage, visibility and name, and we
11475b2088d1STeresa Johnson   // ensure all uses of alias instead use the new clone (casted if necessary).
114881bbf742STeresa Johnson   NewFn->setLinkage(GA->getLinkage());
11495b2088d1STeresa Johnson   NewFn->setVisibility(GA->getVisibility());
115081bbf742STeresa Johnson   GA->replaceAllUsesWith(ConstantExpr::getBitCast(NewFn, GA->getType()));
115181bbf742STeresa Johnson   NewFn->takeName(GA);
115281bbf742STeresa Johnson   return NewFn;
115381bbf742STeresa Johnson }
115481bbf742STeresa Johnson 
1155bf46e741SEugene Leviant // Internalize values that we marked with specific attribute
1156bf46e741SEugene Leviant // in processGlobalForThinLTO.
11573aef3528SEugene Leviant static void internalizeGVsAfterImport(Module &M) {
1158bf46e741SEugene Leviant   for (auto &GV : M.globals())
1159bf46e741SEugene Leviant     // Skip GVs which have been converted to declarations
1160bf46e741SEugene Leviant     // by dropDeadSymbols.
1161bf46e741SEugene Leviant     if (!GV.isDeclaration() && GV.hasAttribute("thinlto-internalize")) {
1162bf46e741SEugene Leviant       GV.setLinkage(GlobalValue::InternalLinkage);
1163bf46e741SEugene Leviant       GV.setVisibility(GlobalValue::DefaultVisibility);
1164bf46e741SEugene Leviant     }
1165bf46e741SEugene Leviant }
1166bf46e741SEugene Leviant 
1167c8c55170SMehdi Amini // Automatically import functions in Module \p DestModule based on the summaries
1168c8c55170SMehdi Amini // index.
11697f00d0a1SPeter Collingbourne Expected<bool> FunctionImporter::importFunctions(
117066043797SAdrian Prantl     Module &DestModule, const FunctionImporter::ImportMapTy &ImportList) {
1171d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "Starting import for Module "
1172311fef6eSMehdi Amini                     << DestModule.getModuleIdentifier() << "\n");
117319e23874SEugene Leviant   unsigned ImportedCount = 0, ImportedGVCount = 0;
1174c8c55170SMehdi Amini 
11756d8f817fSPeter Collingbourne   IRMover Mover(DestModule);
11767e88d0daSMehdi Amini   // Do the actual import of functions now, one Module at a time
117701e32130SMehdi Amini   std::set<StringRef> ModuleNameOrderedList;
117801e32130SMehdi Amini   for (auto &FunctionsToImportPerModule : ImportList) {
117901e32130SMehdi Amini     ModuleNameOrderedList.insert(FunctionsToImportPerModule.first());
118001e32130SMehdi Amini   }
118101e32130SMehdi Amini   for (auto &Name : ModuleNameOrderedList) {
11827e88d0daSMehdi Amini     // Get the module for the import
118301e32130SMehdi Amini     const auto &FunctionsToImportPerModule = ImportList.find(Name);
118401e32130SMehdi Amini     assert(FunctionsToImportPerModule != ImportList.end());
1185d9445c49SPeter Collingbourne     Expected<std::unique_ptr<Module>> SrcModuleOrErr = ModuleLoader(Name);
1186d9445c49SPeter Collingbourne     if (!SrcModuleOrErr)
1187d9445c49SPeter Collingbourne       return SrcModuleOrErr.takeError();
1188d9445c49SPeter Collingbourne     std::unique_ptr<Module> SrcModule = std::move(*SrcModuleOrErr);
11897e88d0daSMehdi Amini     assert(&DestModule.getContext() == &SrcModule->getContext() &&
11907e88d0daSMehdi Amini            "Context mismatch");
11917e88d0daSMehdi Amini 
11926cba37ceSTeresa Johnson     // If modules were created with lazy metadata loading, materialize it
11936cba37ceSTeresa Johnson     // now, before linking it (otherwise this will be a noop).
11947f00d0a1SPeter Collingbourne     if (Error Err = SrcModule->materializeMetadata())
1195c55cf4afSBill Wendling       return std::move(Err);
1196e5a61917STeresa Johnson 
119701e32130SMehdi Amini     auto &ImportGUIDs = FunctionsToImportPerModule->second;
119801e32130SMehdi Amini     // Find the globals to import
11996d8f817fSPeter Collingbourne     SetVector<GlobalValue *> GlobalsToImport;
12001f685e01SPiotr Padlewski     for (Function &F : *SrcModule) {
12011f685e01SPiotr Padlewski       if (!F.hasName())
12020beb858eSTeresa Johnson         continue;
12031f685e01SPiotr Padlewski       auto GUID = F.getGUID();
12040beb858eSTeresa Johnson       auto Import = ImportGUIDs.count(GUID);
1205d34e60caSNicola Zaghen       LLVM_DEBUG(dbgs() << (Import ? "Is" : "Not") << " importing function "
1206d34e60caSNicola Zaghen                         << GUID << " " << F.getName() << " from "
1207aeb1e59bSMehdi Amini                         << SrcModule->getSourceFileName() << "\n");
12080beb858eSTeresa Johnson       if (Import) {
12097f00d0a1SPeter Collingbourne         if (Error Err = F.materialize())
1210c55cf4afSBill Wendling           return std::move(Err);
12113b776128SPiotr Padlewski         if (EnableImportMetadata) {
12126deaa6afSPiotr Padlewski           // Add 'thinlto_src_module' metadata for statistics and debugging.
12133b776128SPiotr Padlewski           F.setMetadata(
12143b776128SPiotr Padlewski               "thinlto_src_module",
1215e9ea08a0SEugene Zelenko               MDNode::get(DestModule.getContext(),
1216e9ea08a0SEugene Zelenko                           {MDString::get(DestModule.getContext(),
12176deaa6afSPiotr Padlewski                                          SrcModule->getSourceFileName())}));
12183b776128SPiotr Padlewski         }
12191f685e01SPiotr Padlewski         GlobalsToImport.insert(&F);
122001e32130SMehdi Amini       }
122101e32130SMehdi Amini     }
12221f685e01SPiotr Padlewski     for (GlobalVariable &GV : SrcModule->globals()) {
12232d28f7aaSMehdi Amini       if (!GV.hasName())
12242d28f7aaSMehdi Amini         continue;
12252d28f7aaSMehdi Amini       auto GUID = GV.getGUID();
12262d28f7aaSMehdi Amini       auto Import = ImportGUIDs.count(GUID);
1227d34e60caSNicola Zaghen       LLVM_DEBUG(dbgs() << (Import ? "Is" : "Not") << " importing global "
1228d34e60caSNicola Zaghen                         << GUID << " " << GV.getName() << " from "
1229aeb1e59bSMehdi Amini                         << SrcModule->getSourceFileName() << "\n");
12302d28f7aaSMehdi Amini       if (Import) {
12317f00d0a1SPeter Collingbourne         if (Error Err = GV.materialize())
1232c55cf4afSBill Wendling           return std::move(Err);
123319e23874SEugene Leviant         ImportedGVCount += GlobalsToImport.insert(&GV);
12342d28f7aaSMehdi Amini       }
12352d28f7aaSMehdi Amini     }
12361f685e01SPiotr Padlewski     for (GlobalAlias &GA : SrcModule->aliases()) {
12371f685e01SPiotr Padlewski       if (!GA.hasName())
123801e32130SMehdi Amini         continue;
12391f685e01SPiotr Padlewski       auto GUID = GA.getGUID();
124081bbf742STeresa Johnson       auto Import = ImportGUIDs.count(GUID);
1241d34e60caSNicola Zaghen       LLVM_DEBUG(dbgs() << (Import ? "Is" : "Not") << " importing alias "
1242d34e60caSNicola Zaghen                         << GUID << " " << GA.getName() << " from "
1243aeb1e59bSMehdi Amini                         << SrcModule->getSourceFileName() << "\n");
124481bbf742STeresa Johnson       if (Import) {
124581bbf742STeresa Johnson         if (Error Err = GA.materialize())
1246c55cf4afSBill Wendling           return std::move(Err);
124781bbf742STeresa Johnson         // Import alias as a copy of its aliasee.
124881bbf742STeresa Johnson         GlobalObject *Base = GA.getBaseObject();
124981bbf742STeresa Johnson         if (Error Err = Base->materialize())
1250c55cf4afSBill Wendling           return std::move(Err);
125181bbf742STeresa Johnson         auto *Fn = replaceAliasWithAliasee(SrcModule.get(), &GA);
1252d34e60caSNicola Zaghen         LLVM_DEBUG(dbgs() << "Is importing aliasee fn " << Base->getGUID()
125381bbf742STeresa Johnson                           << " " << Base->getName() << " from "
125481bbf742STeresa Johnson                           << SrcModule->getSourceFileName() << "\n");
125581bbf742STeresa Johnson         if (EnableImportMetadata) {
125681bbf742STeresa Johnson           // Add 'thinlto_src_module' metadata for statistics and debugging.
125781bbf742STeresa Johnson           Fn->setMetadata(
125881bbf742STeresa Johnson               "thinlto_src_module",
125981bbf742STeresa Johnson               MDNode::get(DestModule.getContext(),
126081bbf742STeresa Johnson                           {MDString::get(DestModule.getContext(),
126181bbf742STeresa Johnson                                          SrcModule->getSourceFileName())}));
126201e32130SMehdi Amini         }
126381bbf742STeresa Johnson         GlobalsToImport.insert(Fn);
126481bbf742STeresa Johnson       }
126581bbf742STeresa Johnson     }
126601e32130SMehdi Amini 
126719ef4fadSMehdi Amini     // Upgrade debug info after we're done materializing all the globals and we
126819ef4fadSMehdi Amini     // have loaded all the required metadata!
126919ef4fadSMehdi Amini     UpgradeDebugInfo(*SrcModule);
127019ef4fadSMehdi Amini 
12716c27c61dSHiroshi Yamauchi     // Set the partial sample profile ratio in the profile summary module flag
12726c27c61dSHiroshi Yamauchi     // of the imported source module, if applicable, so that the profile summary
12736c27c61dSHiroshi Yamauchi     // module flag will match with that of the destination module when it's
12746c27c61dSHiroshi Yamauchi     // imported.
12756c27c61dSHiroshi Yamauchi     SrcModule->setPartialSampleProfileRatio(Index);
12766c27c61dSHiroshi Yamauchi 
12777e88d0daSMehdi Amini     // Link in the specified functions.
1278d2ef8c1fSFangrui Song     if (renameModuleForThinLTO(*SrcModule, Index, ClearDSOLocalOnDeclarations,
1279d2ef8c1fSFangrui Song                                &GlobalsToImport))
12808d05185aSMehdi Amini       return true;
12818d05185aSMehdi Amini 
1282d29478f7STeresa Johnson     if (PrintImports) {
1283d29478f7STeresa Johnson       for (const auto *GV : GlobalsToImport)
1284d29478f7STeresa Johnson         dbgs() << DestModule.getSourceFileName() << ": Import " << GV->getName()
1285d29478f7STeresa Johnson                << " from " << SrcModule->getSourceFileName() << "\n";
1286d29478f7STeresa Johnson     }
1287d29478f7STeresa Johnson 
128809684b08SSergei Trofimovich     if (Error Err = Mover.move(
128909684b08SSergei Trofimovich             std::move(SrcModule), GlobalsToImport.getArrayRef(),
12906d8f817fSPeter Collingbourne             [](GlobalValue &, IRMover::ValueAdder) {},
1291e6fd9ff9SPeter Collingbourne             /*IsPerformingImport=*/true))
129209684b08SSergei Trofimovich       report_fatal_error("Function Import: link error: " +
129309684b08SSergei Trofimovich                          toString(std::move(Err)));
12947e88d0daSMehdi Amini 
129501e32130SMehdi Amini     ImportedCount += GlobalsToImport.size();
12966c475a75STeresa Johnson     NumImportedModules++;
12977e88d0daSMehdi Amini   }
1298e5a61917STeresa Johnson 
12993aef3528SEugene Leviant   internalizeGVsAfterImport(DestModule);
1300bf46e741SEugene Leviant 
130119e23874SEugene Leviant   NumImportedFunctions += (ImportedCount - ImportedGVCount);
130219e23874SEugene Leviant   NumImportedGlobalVars += ImportedGVCount;
1303d29478f7STeresa Johnson 
1304d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "Imported " << ImportedCount - ImportedGVCount
1305d34e60caSNicola Zaghen                     << " functions for Module "
1306d34e60caSNicola Zaghen                     << DestModule.getModuleIdentifier() << "\n");
1307d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "Imported " << ImportedGVCount
130819e23874SEugene Leviant                     << " global variables for Module "
1309c8c55170SMehdi Amini                     << DestModule.getModuleIdentifier() << "\n");
1310c8c55170SMehdi Amini   return ImportedCount;
131142418abaSMehdi Amini }
131242418abaSMehdi Amini 
1313598bd2a2SPeter Collingbourne static bool doImportingForModule(Module &M) {
1314598bd2a2SPeter Collingbourne   if (SummaryFile.empty())
1315598bd2a2SPeter Collingbourne     report_fatal_error("error: -function-import requires -summary-file\n");
13166de481a3SPeter Collingbourne   Expected<std::unique_ptr<ModuleSummaryIndex>> IndexPtrOrErr =
13176de481a3SPeter Collingbourne       getModuleSummaryIndexForFile(SummaryFile);
13186de481a3SPeter Collingbourne   if (!IndexPtrOrErr) {
13196de481a3SPeter Collingbourne     logAllUnhandledErrors(IndexPtrOrErr.takeError(), errs(),
13206de481a3SPeter Collingbourne                           "Error loading file '" + SummaryFile + "': ");
132142418abaSMehdi Amini     return false;
132242418abaSMehdi Amini   }
1323598bd2a2SPeter Collingbourne   std::unique_ptr<ModuleSummaryIndex> Index = std::move(*IndexPtrOrErr);
132442418abaSMehdi Amini 
1325c86af334STeresa Johnson   // First step is collecting the import list.
1326c86af334STeresa Johnson   FunctionImporter::ImportMapTy ImportList;
132781bbf742STeresa Johnson   // If requested, simply import all functions in the index. This is used
132881bbf742STeresa Johnson   // when testing distributed backend handling via the opt tool, when
132981bbf742STeresa Johnson   // we have distributed indexes containing exactly the summaries to import.
133081bbf742STeresa Johnson   if (ImportAllIndex)
133181bbf742STeresa Johnson     ComputeCrossModuleImportForModuleFromIndex(M.getModuleIdentifier(), *Index,
133281bbf742STeresa Johnson                                                ImportList);
133381bbf742STeresa Johnson   else
1334c86af334STeresa Johnson     ComputeCrossModuleImportForModule(M.getModuleIdentifier(), *Index,
1335c86af334STeresa Johnson                                       ImportList);
133601e32130SMehdi Amini 
13374fef68cbSTeresa Johnson   // Conservatively mark all internal values as promoted. This interface is
13384fef68cbSTeresa Johnson   // only used when doing importing via the function importing pass. The pass
13394fef68cbSTeresa Johnson   // is only enabled when testing importing via the 'opt' tool, which does
13404fef68cbSTeresa Johnson   // not do the ThinLink that would normally determine what values to promote.
13414fef68cbSTeresa Johnson   for (auto &I : *Index) {
13429667b91bSPeter Collingbourne     for (auto &S : I.second.SummaryList) {
13434fef68cbSTeresa Johnson       if (GlobalValue::isLocalLinkage(S->linkage()))
13444fef68cbSTeresa Johnson         S->setLinkage(GlobalValue::ExternalLinkage);
13454fef68cbSTeresa Johnson     }
13464fef68cbSTeresa Johnson   }
13474fef68cbSTeresa Johnson 
134801e32130SMehdi Amini   // Next we need to promote to global scope and rename any local values that
13491b00f2d9STeresa Johnson   // are potentially exported to other modules.
13506913812aSFangrui Song   if (renameModuleForThinLTO(M, *Index, /*ClearDSOLocalOnDeclarations=*/false,
1351d2ef8c1fSFangrui Song                              /*GlobalsToImport=*/nullptr)) {
13521b00f2d9STeresa Johnson     errs() << "Error renaming module\n";
13531b00f2d9STeresa Johnson     return false;
13541b00f2d9STeresa Johnson   }
13551b00f2d9STeresa Johnson 
135642418abaSMehdi Amini   // Perform the import now.
1357d16c8065SMehdi Amini   auto ModuleLoader = [&M](StringRef Identifier) {
1358adcd0268SBenjamin Kramer     return loadFile(std::string(Identifier), M.getContext());
1359d16c8065SMehdi Amini   };
1360d2ef8c1fSFangrui Song   FunctionImporter Importer(*Index, ModuleLoader,
1361d2ef8c1fSFangrui Song                             /*ClearDSOLocalOnDeclarations=*/false);
136237e24591SPeter Collingbourne   Expected<bool> Result = Importer.importFunctions(M, ImportList);
13637f00d0a1SPeter Collingbourne 
13647f00d0a1SPeter Collingbourne   // FIXME: Probably need to propagate Errors through the pass manager.
13657f00d0a1SPeter Collingbourne   if (!Result) {
13667f00d0a1SPeter Collingbourne     logAllUnhandledErrors(Result.takeError(), errs(),
13677f00d0a1SPeter Collingbourne                           "Error importing module: ");
13687f00d0a1SPeter Collingbourne     return false;
13697f00d0a1SPeter Collingbourne   }
13707f00d0a1SPeter Collingbourne 
13717f00d0a1SPeter Collingbourne   return *Result;
137221241571STeresa Johnson }
137321241571STeresa Johnson 
137421241571STeresa Johnson namespace {
1375e9ea08a0SEugene Zelenko 
137621241571STeresa Johnson /// Pass that performs cross-module function import provided a summary file.
137721241571STeresa Johnson class FunctionImportLegacyPass : public ModulePass {
137821241571STeresa Johnson public:
137921241571STeresa Johnson   /// Pass identification, replacement for typeid
138021241571STeresa Johnson   static char ID;
138121241571STeresa Johnson 
1382e9ea08a0SEugene Zelenko   explicit FunctionImportLegacyPass() : ModulePass(ID) {}
1383e9ea08a0SEugene Zelenko 
138421241571STeresa Johnson   /// Specify pass name for debug output
1385117296c0SMehdi Amini   StringRef getPassName() const override { return "Function Importing"; }
138621241571STeresa Johnson 
138721241571STeresa Johnson   bool runOnModule(Module &M) override {
138821241571STeresa Johnson     if (skipModule(M))
138921241571STeresa Johnson       return false;
139021241571STeresa Johnson 
1391598bd2a2SPeter Collingbourne     return doImportingForModule(M);
139242418abaSMehdi Amini   }
139342418abaSMehdi Amini };
1394e9ea08a0SEugene Zelenko 
1395e9ea08a0SEugene Zelenko } // end anonymous namespace
139642418abaSMehdi Amini 
139721241571STeresa Johnson PreservedAnalyses FunctionImportPass::run(Module &M,
1398fd03ac6aSSean Silva                                           ModuleAnalysisManager &AM) {
1399598bd2a2SPeter Collingbourne   if (!doImportingForModule(M))
140021241571STeresa Johnson     return PreservedAnalyses::all();
140121241571STeresa Johnson 
140221241571STeresa Johnson   return PreservedAnalyses::none();
140321241571STeresa Johnson }
140421241571STeresa Johnson 
140521241571STeresa Johnson char FunctionImportLegacyPass::ID = 0;
140621241571STeresa Johnson INITIALIZE_PASS(FunctionImportLegacyPass, "function-import",
140742418abaSMehdi Amini                 "Summary Based Function Import", false, false)
140842418abaSMehdi Amini 
140942418abaSMehdi Amini namespace llvm {
1410e9ea08a0SEugene Zelenko 
1411598bd2a2SPeter Collingbourne Pass *createFunctionImportPass() {
1412598bd2a2SPeter Collingbourne   return new FunctionImportLegacyPass();
14135fcbdb71STeresa Johnson }
1414e9ea08a0SEugene Zelenko 
1415e9ea08a0SEugene Zelenko } // end namespace llvm
1416