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