1 //===- FunctionImport.cpp - ThinLTO Summary-based Function Import ---------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements Function import based on summaries.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/Transforms/IPO/FunctionImport.h"
15 
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/ADT/StringSet.h"
19 #include "llvm/IR/AutoUpgrade.h"
20 #include "llvm/IR/DiagnosticPrinter.h"
21 #include "llvm/IR/IntrinsicInst.h"
22 #include "llvm/IR/Module.h"
23 #include "llvm/IRReader/IRReader.h"
24 #include "llvm/Linker/Linker.h"
25 #include "llvm/Object/ModuleSummaryIndexObjectFile.h"
26 #include "llvm/Support/CommandLine.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/SourceMgr.h"
29 #include "llvm/Transforms/Utils/FunctionImportUtils.h"
30 
31 #define DEBUG_TYPE "function-import"
32 
33 using namespace llvm;
34 
35 STATISTIC(NumImported, "Number of functions imported");
36 
37 /// Limit on instruction count of imported functions.
38 static cl::opt<unsigned> ImportInstrLimit(
39     "import-instr-limit", cl::init(100), cl::Hidden, cl::value_desc("N"),
40     cl::desc("Only import functions with less than N instructions"));
41 
42 static cl::opt<float>
43     ImportInstrFactor("import-instr-evolution-factor", cl::init(0.7),
44                       cl::Hidden, cl::value_desc("x"),
45                       cl::desc("As we import functions, multiply the "
46                                "`import-instr-limit` threshold by this factor "
47                                "before processing newly imported functions"));
48 
49 static cl::opt<bool> PrintImports("print-imports", cl::init(false), cl::Hidden,
50                                   cl::desc("Print imported functions"));
51 
52 // Load lazily a module from \p FileName in \p Context.
53 static std::unique_ptr<Module> loadFile(const std::string &FileName,
54                                         LLVMContext &Context) {
55   SMDiagnostic Err;
56   DEBUG(dbgs() << "Loading '" << FileName << "'\n");
57   // Metadata isn't loaded until functions are imported, to minimize
58   // the memory overhead.
59   std::unique_ptr<Module> Result =
60       getLazyIRFileModule(FileName, Err, Context,
61                           /* ShouldLazyLoadMetadata = */ true);
62   if (!Result) {
63     Err.print("function-import", errs());
64     return nullptr;
65   }
66 
67   return Result;
68 }
69 
70 namespace {
71 
72 /// Given a list of possible callee implementation for a call site, select one
73 /// that fits the \p Threshold.
74 ///
75 /// FIXME: select "best" instead of first that fits. But what is "best"?
76 /// - The smallest: more likely to be inlined.
77 /// - The one with the least outgoing edges (already well optimized).
78 /// - One from a module already being imported from in order to reduce the
79 ///   number of source modules parsed/linked.
80 /// - One that has PGO data attached.
81 /// - [insert you fancy metric here]
82 static const FunctionSummary *
83 selectCallee(const GlobalValueInfoList &CalleeInfoList, unsigned Threshold) {
84   auto It = llvm::find_if(
85       CalleeInfoList, [&](const std::unique_ptr<GlobalValueInfo> &GlobInfo) {
86         assert(GlobInfo->summary() &&
87                "We should not have a Global Info without summary");
88         auto *Summary = cast<FunctionSummary>(GlobInfo->summary());
89 
90         if (GlobalValue::isWeakAnyLinkage(Summary->linkage()))
91           return false;
92 
93         if (Summary->instCount() > Threshold)
94           return false;
95 
96         return true;
97       });
98   if (It == CalleeInfoList.end())
99     return nullptr;
100 
101   return cast<FunctionSummary>((*It)->summary());
102 }
103 
104 /// Return the summary for the function \p GUID that fits the \p Threshold, or
105 /// null if there's no match.
106 static const FunctionSummary *selectCallee(uint64_t GUID, unsigned Threshold,
107                                            const ModuleSummaryIndex &Index) {
108   auto CalleeInfoList = Index.findGlobalValueInfoList(GUID);
109   if (CalleeInfoList == Index.end()) {
110     return nullptr; // This function does not have a summary
111   }
112   return selectCallee(CalleeInfoList->second, Threshold);
113 }
114 
115 /// Return true if the global \p GUID is exported by module \p ExportModulePath.
116 static bool isGlobalExported(const ModuleSummaryIndex &Index,
117                              StringRef ExportModulePath, uint64_t GUID) {
118   auto CalleeInfoList = Index.findGlobalValueInfoList(GUID);
119   if (CalleeInfoList == Index.end())
120     // This global does not have a summary, it is not part of the ThinLTO
121     // process
122     return false;
123   auto DefinedInCalleeModule = llvm::find_if(
124       CalleeInfoList->second,
125       [&](const std::unique_ptr<GlobalValueInfo> &GlobInfo) {
126         auto *Summary = GlobInfo->summary();
127         assert(Summary && "Unexpected GlobalValueInfo without summary");
128         return Summary->modulePath() == ExportModulePath;
129       });
130   return (DefinedInCalleeModule != CalleeInfoList->second.end());
131 }
132 
133 using EdgeInfo = std::pair<const FunctionSummary *, unsigned /* Threshold */>;
134 
135 /// Compute the list of functions to import for a given caller. Mark these
136 /// imported functions and the symbols they reference in their source module as
137 /// exported from their source module.
138 static void computeImportForFunction(
139     StringRef ModulePath, const FunctionSummary &Summary,
140     const ModuleSummaryIndex &Index, unsigned Threshold,
141     const std::map<uint64_t, FunctionSummary *> &DefinedFunctions,
142     SmallVectorImpl<EdgeInfo> &Worklist,
143     FunctionImporter::ImportMapTy &ImportsForModule,
144     StringMap<FunctionImporter::ExportSetTy> &ExportLists) {
145   for (auto &Edge : Summary.calls()) {
146     auto GUID = Edge.first;
147     DEBUG(dbgs() << " edge -> " << GUID << " Threshold:" << Threshold << "\n");
148 
149     if (DefinedFunctions.count(GUID)) {
150       DEBUG(dbgs() << "ignored! Target already in destination module.\n");
151       continue;
152     }
153 
154     auto *CalleeSummary = selectCallee(GUID, Threshold, Index);
155     if (!CalleeSummary) {
156       DEBUG(dbgs() << "ignored! No qualifying callee with summary found.\n");
157       continue;
158     }
159     assert(CalleeSummary->instCount() <= Threshold &&
160            "selectCallee() didn't honor the threshold");
161 
162     auto &ProcessedThreshold =
163         ImportsForModule[CalleeSummary->modulePath()][GUID];
164     /// Since the traversal of the call graph is DFS, we can revisit a function
165     /// a second time with a higher threshold. In this case, it is added back to
166     /// the worklist with the new threshold.
167     if (ProcessedThreshold && ProcessedThreshold > Threshold) {
168       DEBUG(dbgs() << "ignored! Target was already seen with Threshold "
169                    << ProcessedThreshold << "\n");
170       continue;
171     }
172     // Mark this function as imported in this module, with the current Threshold
173     ProcessedThreshold = Threshold;
174 
175     // Make exports in the source module.
176     auto ExportModulePath = CalleeSummary->modulePath();
177     auto ExportList = ExportLists[ExportModulePath];
178     ExportList.insert(GUID);
179     // Mark all functions and globals referenced by this function as exported to
180     // the outside if they are defined in the same source module.
181     for (auto &Edge : CalleeSummary->calls()) {
182       auto CalleeGUID = Edge.first;
183       if (isGlobalExported(Index, ExportModulePath, CalleeGUID))
184         ExportList.insert(CalleeGUID);
185     }
186     for (auto &GUID : CalleeSummary->refs()) {
187       if (isGlobalExported(Index, ExportModulePath, GUID))
188         ExportList.insert(GUID);
189     }
190 
191     // Insert the newly imported function to the worklist.
192     Worklist.push_back(std::make_pair(CalleeSummary, Threshold));
193   }
194 }
195 
196 /// Given the list of globals defined in a module, compute the list of imports
197 /// as well as the list of "exports", i.e. the list of symbols referenced from
198 /// another module (that may require promotion).
199 static void ComputeImportForModule(
200     StringRef ModulePath,
201     const std::map<uint64_t, FunctionSummary *> &DefinedFunctions,
202     const ModuleSummaryIndex &Index,
203     FunctionImporter::ImportMapTy &ImportsForModule,
204     StringMap<FunctionImporter::ExportSetTy> &ExportLists) {
205   // Worklist contains the list of function imported in this module, for which
206   // we will analyse the callees and may import further down the callgraph.
207   SmallVector<EdgeInfo, 128> Worklist;
208 
209   // Populate the worklist with the import for the functions in the current
210   // module
211   for (auto &FuncInfo : DefinedFunctions) {
212     auto *Summary = FuncInfo.second;
213     DEBUG(dbgs() << "Initalize import for " << FuncInfo.first << "\n");
214     computeImportForFunction(ModulePath, *Summary, Index, ImportInstrLimit,
215                              DefinedFunctions, Worklist, ImportsForModule,
216                              ExportLists);
217   }
218 
219   while (!Worklist.empty()) {
220     auto FuncInfo = Worklist.pop_back_val();
221     auto *Summary = FuncInfo.first;
222     auto Threshold = FuncInfo.second;
223 
224     // Process the newly imported functions and add callees to the worklist.
225     // Adjust the threshold
226     Threshold = Threshold * ImportInstrFactor;
227 
228     computeImportForFunction(ModulePath, *Summary, Index, Threshold,
229                              DefinedFunctions, Worklist, ImportsForModule,
230                              ExportLists);
231   }
232 }
233 
234 } // anonymous namespace
235 
236 /// Compute all the import and export for every module in the Index.
237 void llvm::ComputeCrossModuleImport(
238     const ModuleSummaryIndex &Index,
239     StringMap<FunctionImporter::ImportMapTy> &ImportLists,
240     StringMap<FunctionImporter::ExportSetTy> &ExportLists) {
241   auto ModuleCount = Index.modulePaths().size();
242 
243   // Collect for each module the list of function it defines.
244   // GUID -> Summary
245   StringMap<std::map<uint64_t, FunctionSummary *>> Module2FunctionInfoMap(
246       ModuleCount);
247 
248   for (auto &GlobalList : Index) {
249     auto GUID = GlobalList.first;
250     for (auto &GlobInfo : GlobalList.second) {
251       auto *Summary = dyn_cast_or_null<FunctionSummary>(GlobInfo->summary());
252       if (!Summary)
253         /// Ignore global variable, focus on functions
254         continue;
255       DEBUG(dbgs() << "Adding definition: Module '" << Summary->modulePath()
256                    << "' defines '" << GUID << "'\n");
257       Module2FunctionInfoMap[Summary->modulePath()][GUID] = Summary;
258     }
259   }
260 
261   // For each module that has function defined, compute the import/export lists.
262   for (auto &DefinedFunctions : Module2FunctionInfoMap) {
263     auto &ImportsForModule = ImportLists[DefinedFunctions.first()];
264     DEBUG(dbgs() << "Computing import for Module '" << DefinedFunctions.first()
265                  << "'\n");
266     ComputeImportForModule(DefinedFunctions.first(), DefinedFunctions.second,
267                            Index, ImportsForModule, ExportLists);
268   }
269 
270 #ifndef NDEBUG
271   DEBUG(dbgs() << "Import/Export lists for " << ImportLists.size()
272                << " modules:\n");
273   for (auto &ModuleImports : ImportLists) {
274     auto ModName = ModuleImports.first();
275     auto &Exports = ExportLists[ModName];
276     DEBUG(dbgs() << "* Module " << ModName << " exports " << Exports.size()
277                  << " functions. Imports from " << ModuleImports.second.size()
278                  << " modules.\n");
279     for (auto &Src : ModuleImports.second) {
280       auto SrcModName = Src.first();
281       DEBUG(dbgs() << " - " << Src.second.size() << " functions imported from "
282                    << SrcModName << "\n");
283     }
284   }
285 #endif
286 }
287 
288 // Automatically import functions in Module \p DestModule based on the summaries
289 // index.
290 //
291 bool FunctionImporter::importFunctions(
292     Module &DestModule, const FunctionImporter::ImportMapTy &ImportList) {
293   DEBUG(dbgs() << "Starting import for Module "
294                << DestModule.getModuleIdentifier() << "\n");
295   unsigned ImportedCount = 0;
296 
297   // Linker that will be used for importing function
298   Linker TheLinker(DestModule);
299   // Do the actual import of functions now, one Module at a time
300   std::set<StringRef> ModuleNameOrderedList;
301   for (auto &FunctionsToImportPerModule : ImportList) {
302     ModuleNameOrderedList.insert(FunctionsToImportPerModule.first());
303   }
304   for (auto &Name : ModuleNameOrderedList) {
305     // Get the module for the import
306     const auto &FunctionsToImportPerModule = ImportList.find(Name);
307     assert(FunctionsToImportPerModule != ImportList.end());
308     std::unique_ptr<Module> SrcModule = ModuleLoader(Name);
309     assert(&DestModule.getContext() == &SrcModule->getContext() &&
310            "Context mismatch");
311 
312     // If modules were created with lazy metadata loading, materialize it
313     // now, before linking it (otherwise this will be a noop).
314     SrcModule->materializeMetadata();
315     UpgradeDebugInfo(*SrcModule);
316 
317     auto &ImportGUIDs = FunctionsToImportPerModule->second;
318     // Find the globals to import
319     DenseSet<const GlobalValue *> GlobalsToImport;
320     for (auto &GV : *SrcModule) {
321       if (GV.hasName() && ImportGUIDs.count(GV.getGUID())) {
322         GV.materialize();
323         GlobalsToImport.insert(&GV);
324       }
325     }
326     for (auto &GV : SrcModule->aliases()) {
327       if (!GV.hasName())
328         continue;
329       auto GUID = GV.getGUID();
330       if (ImportGUIDs.count(GUID)) {
331         // Alias can't point to "available_externally". However when we import
332         // linkOnceODR the linkage does not change. So we import the alias
333         // and aliasee only in this case.
334         const GlobalObject *GO = GV.getBaseObject();
335         if (!GO->hasLinkOnceODRLinkage())
336           continue;
337         GV.materialize();
338         GlobalsToImport.insert(&GV);
339         GlobalsToImport.insert(GO);
340       }
341     }
342     for (auto &GV : SrcModule->globals()) {
343       if (!GV.hasName())
344         continue;
345       auto GUID = Function::getGUID(Function::getGlobalIdentifier(
346           GV.getName(), GV.getLinkage(), SrcModule->getModuleIdentifier()));
347       if (ImportGUIDs.count(GUID)) {
348         GV.materialize();
349         GlobalsToImport.insert(&GV);
350       }
351     }
352 
353     // Link in the specified functions.
354     if (renameModuleForThinLTO(*SrcModule, Index, &GlobalsToImport))
355       return true;
356 
357     if (PrintImports) {
358       for (const auto *GV : GlobalsToImport)
359         dbgs() << DestModule.getSourceFileName() << ": Import " << GV->getName()
360                << " from " << SrcModule->getSourceFileName() << "\n";
361     }
362 
363     if (TheLinker.linkInModule(std::move(SrcModule), Linker::Flags::None,
364                                &GlobalsToImport))
365       report_fatal_error("Function Import: link error");
366 
367     ImportedCount += GlobalsToImport.size();
368   }
369 
370   NumImported += ImportedCount;
371 
372   DEBUG(dbgs() << "Imported " << ImportedCount << " functions for Module "
373                << DestModule.getModuleIdentifier() << "\n");
374   return ImportedCount;
375 }
376 
377 /// Summary file to use for function importing when using -function-import from
378 /// the command line.
379 static cl::opt<std::string>
380     SummaryFile("summary-file",
381                 cl::desc("The summary file to use for function importing."));
382 
383 static void diagnosticHandler(const DiagnosticInfo &DI) {
384   raw_ostream &OS = errs();
385   DiagnosticPrinterRawOStream DP(OS);
386   DI.print(DP);
387   OS << '\n';
388 }
389 
390 /// Parse the summary index out of an IR file and return the summary
391 /// index object if found, or nullptr if not.
392 static std::unique_ptr<ModuleSummaryIndex>
393 getModuleSummaryIndexForFile(StringRef Path, std::string &Error,
394                              DiagnosticHandlerFunction DiagnosticHandler) {
395   std::unique_ptr<MemoryBuffer> Buffer;
396   ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
397       MemoryBuffer::getFile(Path);
398   if (std::error_code EC = BufferOrErr.getError()) {
399     Error = EC.message();
400     return nullptr;
401   }
402   Buffer = std::move(BufferOrErr.get());
403   ErrorOr<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> ObjOrErr =
404       object::ModuleSummaryIndexObjectFile::create(Buffer->getMemBufferRef(),
405                                                    DiagnosticHandler);
406   if (std::error_code EC = ObjOrErr.getError()) {
407     Error = EC.message();
408     return nullptr;
409   }
410   return (*ObjOrErr)->takeIndex();
411 }
412 
413 namespace {
414 /// Pass that performs cross-module function import provided a summary file.
415 class FunctionImportPass : public ModulePass {
416   /// Optional module summary index to use for importing, otherwise
417   /// the summary-file option must be specified.
418   const ModuleSummaryIndex *Index;
419 
420 public:
421   /// Pass identification, replacement for typeid
422   static char ID;
423 
424   /// Specify pass name for debug output
425   const char *getPassName() const override {
426     return "Function Importing";
427   }
428 
429   explicit FunctionImportPass(const ModuleSummaryIndex *Index = nullptr)
430       : ModulePass(ID), Index(Index) {}
431 
432   bool runOnModule(Module &M) override {
433     if (SummaryFile.empty() && !Index)
434       report_fatal_error("error: -function-import requires -summary-file or "
435                          "file from frontend\n");
436     std::unique_ptr<ModuleSummaryIndex> IndexPtr;
437     if (!SummaryFile.empty()) {
438       if (Index)
439         report_fatal_error("error: -summary-file and index from frontend\n");
440       std::string Error;
441       IndexPtr =
442           getModuleSummaryIndexForFile(SummaryFile, Error, diagnosticHandler);
443       if (!IndexPtr) {
444         errs() << "Error loading file '" << SummaryFile << "': " << Error
445                << "\n";
446         return false;
447       }
448       Index = IndexPtr.get();
449     }
450 
451     // First step is collecting the import/export lists
452     // The export list is not used yet, but could limit the amount of renaming
453     // performed in renameModuleForThinLTO()
454     StringMap<FunctionImporter::ImportMapTy> ImportLists;
455     StringMap<FunctionImporter::ExportSetTy> ExportLists;
456     ComputeCrossModuleImport(*Index, ImportLists, ExportLists);
457     auto &ImportList = ImportLists[M.getModuleIdentifier()];
458 
459     // Next we need to promote to global scope and rename any local values that
460     // are potentially exported to other modules.
461     if (renameModuleForThinLTO(M, *Index, nullptr)) {
462       errs() << "Error renaming module\n";
463       return false;
464     }
465 
466     // Perform the import now.
467     auto ModuleLoader = [&M](StringRef Identifier) {
468       return loadFile(Identifier, M.getContext());
469     };
470     FunctionImporter Importer(*Index, ModuleLoader);
471     return Importer.importFunctions(M, ImportList);
472   }
473 };
474 } // anonymous namespace
475 
476 char FunctionImportPass::ID = 0;
477 INITIALIZE_PASS_BEGIN(FunctionImportPass, "function-import",
478                       "Summary Based Function Import", false, false)
479 INITIALIZE_PASS_END(FunctionImportPass, "function-import",
480                     "Summary Based Function Import", false, false)
481 
482 namespace llvm {
483 Pass *createFunctionImportPass(const ModuleSummaryIndex *Index = nullptr) {
484   return new FunctionImportPass(Index);
485 }
486 }
487