blob: 896ac5d3003a174e6a4411e00afe4965c2fc6264 [file] [log] [blame]
Mehdi Amini42418ab2015-11-24 06:07:49 +00001//===- 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
Mehdi Amini01e32132016-03-26 05:40:34 +000016#include "llvm/ADT/SmallVector.h"
Mehdi Amini42418ab2015-11-24 06:07:49 +000017#include "llvm/ADT/StringSet.h"
18#include "llvm/IR/AutoUpgrade.h"
19#include "llvm/IR/DiagnosticPrinter.h"
20#include "llvm/IR/IntrinsicInst.h"
21#include "llvm/IR/Module.h"
22#include "llvm/IRReader/IRReader.h"
23#include "llvm/Linker/Linker.h"
Teresa Johnson26ab5772016-03-15 00:04:37 +000024#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
Mehdi Amini42418ab2015-11-24 06:07:49 +000025#include "llvm/Support/CommandLine.h"
26#include "llvm/Support/Debug.h"
27#include "llvm/Support/SourceMgr.h"
Teresa Johnson488a8002016-02-10 18:11:31 +000028#include "llvm/Transforms/Utils/FunctionImportUtils.h"
Mehdi Amini7e88d0d2015-12-09 08:17:35 +000029
Mehdi Amini01e32132016-03-26 05:40:34 +000030#define DEBUG_TYPE "function-import"
Mehdi Amini7e88d0d2015-12-09 08:17:35 +000031
Mehdi Amini42418ab2015-11-24 06:07:49 +000032using namespace llvm;
33
Teresa Johnson39303612015-11-24 22:55:46 +000034/// Limit on instruction count of imported functions.
35static cl::opt<unsigned> ImportInstrLimit(
36 "import-instr-limit", cl::init(100), cl::Hidden, cl::value_desc("N"),
37 cl::desc("Only import functions with less than N instructions"));
38
Mehdi Amini40641742016-02-10 23:31:45 +000039static cl::opt<float>
40 ImportInstrFactor("import-instr-evolution-factor", cl::init(0.7),
41 cl::Hidden, cl::value_desc("x"),
42 cl::desc("As we import functions, multiply the "
43 "`import-instr-limit` threshold by this factor "
44 "before processing newly imported functions"));
45
Mehdi Amini42418ab2015-11-24 06:07:49 +000046// Load lazily a module from \p FileName in \p Context.
47static std::unique_ptr<Module> loadFile(const std::string &FileName,
48 LLVMContext &Context) {
49 SMDiagnostic Err;
50 DEBUG(dbgs() << "Loading '" << FileName << "'\n");
Teresa Johnson6cba37c2016-01-22 00:15:53 +000051 // Metadata isn't loaded until functions are imported, to minimize
52 // the memory overhead.
Teresa Johnsona1080ee2016-01-08 14:17:41 +000053 std::unique_ptr<Module> Result =
54 getLazyIRFileModule(FileName, Err, Context,
55 /* ShouldLazyLoadMetadata = */ true);
Mehdi Amini42418ab2015-11-24 06:07:49 +000056 if (!Result) {
57 Err.print("function-import", errs());
58 return nullptr;
59 }
60
Mehdi Amini42418ab2015-11-24 06:07:49 +000061 return Result;
62}
63
Mehdi Amini7e88d0d2015-12-09 08:17:35 +000064namespace {
Mehdi Amini40641742016-02-10 23:31:45 +000065
Mehdi Amini01e32132016-03-26 05:40:34 +000066/// Given a list of possible callee implementation for a call site, select one
67/// that fits the \p Threshold.
68///
69/// FIXME: select "best" instead of first that fits. But what is "best"?
70/// - The smallest: more likely to be inlined.
71/// - The one with the least outgoing edges (already well optimized).
72/// - One from a module already being imported from in order to reduce the
73/// number of source modules parsed/linked.
74/// - One that has PGO data attached.
75/// - [insert you fancy metric here]
76static const FunctionSummary *
77selectCallee(const GlobalValueInfoList &CalleeInfoList, unsigned Threshold) {
78 auto It = llvm::find_if(
79 CalleeInfoList, [&](const std::unique_ptr<GlobalValueInfo> &GlobInfo) {
80 assert(GlobInfo->summary() &&
81 "We should not have a Global Info without summary");
82 auto *Summary = cast<FunctionSummary>(GlobInfo->summary());
Mehdi Amini40641742016-02-10 23:31:45 +000083
Mehdi Amini01e32132016-03-26 05:40:34 +000084 if (GlobalValue::isWeakAnyLinkage(Summary->linkage()))
85 return false;
Mehdi Amini7e88d0d2015-12-09 08:17:35 +000086
Mehdi Amini01e32132016-03-26 05:40:34 +000087 if (Summary->instCount() > Threshold)
88 return false;
Mehdi Amini7e88d0d2015-12-09 08:17:35 +000089
Mehdi Amini01e32132016-03-26 05:40:34 +000090 return true;
91 });
92 if (It == CalleeInfoList.end())
93 return nullptr;
Mehdi Amini7e88d0d2015-12-09 08:17:35 +000094
Mehdi Amini01e32132016-03-26 05:40:34 +000095 return cast<FunctionSummary>((*It)->summary());
Mehdi Amini7e88d0d2015-12-09 08:17:35 +000096}
Mehdi Amini7e88d0d2015-12-09 08:17:35 +000097
Mehdi Amini01e32132016-03-26 05:40:34 +000098/// Return the summary for the function \p GUID that fits the \p Threshold, or
99/// null if there's no match.
100static const FunctionSummary *selectCallee(uint64_t GUID, unsigned Threshold,
101 const ModuleSummaryIndex &Index) {
102 auto CalleeInfoList = Index.findGlobalValueInfoList(GUID);
103 if (CalleeInfoList == Index.end()) {
104 return nullptr; // This function does not have a summary
105 }
106 return selectCallee(CalleeInfoList->second, Threshold);
107}
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000108
Mehdi Amini01e32132016-03-26 05:40:34 +0000109/// Return true if the global \p GUID is exported by module \p ExportModulePath.
110static bool isGlobalExported(const ModuleSummaryIndex &Index,
111 StringRef ExportModulePath, uint64_t GUID) {
112 auto CalleeInfoList = Index.findGlobalValueInfoList(GUID);
113 if (CalleeInfoList == Index.end())
114 // This global does not have a summary, it is not part of the ThinLTO
115 // process
116 return false;
117 auto DefinedInCalleeModule = llvm::find_if(
118 CalleeInfoList->second,
119 [&](const std::unique_ptr<GlobalValueInfo> &GlobInfo) {
120 auto *Summary = GlobInfo->summary();
121 assert(Summary && "Unexpected GlobalValueInfo without summary");
122 return Summary->modulePath() == ExportModulePath;
123 });
124 return (DefinedInCalleeModule != CalleeInfoList->second.end());
125}
Mehdi Amini40641742016-02-10 23:31:45 +0000126
Mehdi Amini01e32132016-03-26 05:40:34 +0000127using EdgeInfo = std::pair<const FunctionSummary *, unsigned /* Threshold */>;
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000128
Mehdi Amini01e32132016-03-26 05:40:34 +0000129/// Compute the list of functions to import for a given caller. Mark these
130/// imported functions and the symbols they reference in their source module as
131/// exported from their source module.
132static void computeImportForFunction(
133 StringRef ModulePath, const FunctionSummary &Summary,
134 const ModuleSummaryIndex &Index, unsigned Threshold,
135 const std::map<uint64_t, FunctionSummary *> &DefinedFunctions,
136 SmallVectorImpl<EdgeInfo> &Worklist,
137 FunctionImporter::ImportMapTy &ImportsForModule,
138 StringMap<FunctionImporter::ExportSetTy> &ExportLists) {
139 for (auto &Edge : Summary.calls()) {
140 auto GUID = Edge.first;
141 DEBUG(dbgs() << " edge -> " << GUID << " Threshold:" << Threshold << "\n");
142
143 if (DefinedFunctions.count(GUID)) {
144 DEBUG(dbgs() << "ignored! Target already in destination module.\n");
145 continue;
Teresa Johnsond450da32015-11-24 21:15:19 +0000146 }
Mehdi Amini01e32132016-03-26 05:40:34 +0000147
148 auto *CalleeSummary = selectCallee(GUID, Threshold, Index);
149 if (!CalleeSummary) {
150 DEBUG(dbgs() << "ignored! No qualifying callee with summary found.\n");
151 continue;
152 }
153 assert(CalleeSummary->instCount() <= Threshold &&
154 "selectCallee() didn't honor the threshold");
155
156 auto &ProcessedThreshold =
157 ImportsForModule[CalleeSummary->modulePath()][GUID];
158 /// Since the traversal of the call graph is DFS, we can revisit a function
159 /// a second time with a higher threshold. In this case, it is added back to
160 /// the worklist with the new threshold.
161 if (ProcessedThreshold && ProcessedThreshold > Threshold) {
162 DEBUG(dbgs() << "ignored! Target was already seen with Threshold "
163 << ProcessedThreshold << "\n");
164 continue;
165 }
166 // Mark this function as imported in this module, with the current Threshold
167 ProcessedThreshold = Threshold;
168
169 // Make exports in the source module.
170 auto ExportModulePath = CalleeSummary->modulePath();
171 auto ExportList = ExportLists[ExportModulePath];
172 ExportList.insert(GUID);
173 // Mark all functions and globals referenced by this function as exported to
174 // the outside if they are defined in the same source module.
175 for (auto &Edge : CalleeSummary->calls()) {
176 auto CalleeGUID = Edge.first;
177 if (isGlobalExported(Index, ExportModulePath, CalleeGUID))
178 ExportList.insert(CalleeGUID);
179 }
180 for (auto &GUID : CalleeSummary->refs()) {
181 if (isGlobalExported(Index, ExportModulePath, GUID))
182 ExportList.insert(GUID);
183 }
184
185 // Insert the newly imported function to the worklist.
186 Worklist.push_back(std::make_pair(CalleeSummary, Threshold));
Teresa Johnsond450da32015-11-24 21:15:19 +0000187 }
188}
189
Mehdi Amini01e32132016-03-26 05:40:34 +0000190/// Given the list of globals defined in a module, compute the list of imports
191/// as well as the list of "exports", i.e. the list of symbols referenced from
192/// another module (that may require promotion).
193static void ComputeImportForModule(
194 StringRef ModulePath,
195 const std::map<uint64_t, FunctionSummary *> &DefinedFunctions,
196 const ModuleSummaryIndex &Index,
197 FunctionImporter::ImportMapTy &ImportsForModule,
198 StringMap<FunctionImporter::ExportSetTy> &ExportLists) {
199 // Worklist contains the list of function imported in this module, for which
200 // we will analyse the callees and may import further down the callgraph.
201 SmallVector<EdgeInfo, 128> Worklist;
202
203 // Populate the worklist with the import for the functions in the current
204 // module
205 for (auto &FuncInfo : DefinedFunctions) {
206 auto *Summary = FuncInfo.second;
207 DEBUG(dbgs() << "Initalize import for " << FuncInfo.first << "\n");
208 computeImportForFunction(ModulePath, *Summary, Index, ImportInstrLimit,
209 DefinedFunctions, Worklist, ImportsForModule,
210 ExportLists);
211 }
212
Mehdi Amini42418ab2015-11-24 06:07:49 +0000213 while (!Worklist.empty()) {
Mehdi Amini01e32132016-03-26 05:40:34 +0000214 auto FuncInfo = Worklist.pop_back_val();
215 auto *Summary = FuncInfo.first;
216 auto Threshold = FuncInfo.second;
Mehdi Amini42418ab2015-11-24 06:07:49 +0000217
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000218 // Process the newly imported functions and add callees to the worklist.
Mehdi Amini40641742016-02-10 23:31:45 +0000219 // Adjust the threshold
220 Threshold = Threshold * ImportInstrFactor;
Mehdi Amini01e32132016-03-26 05:40:34 +0000221
222 computeImportForFunction(ModulePath, *Summary, Index, Threshold,
223 DefinedFunctions, Worklist, ImportsForModule,
224 ExportLists);
Mehdi Amini42418ab2015-11-24 06:07:49 +0000225 }
Mehdi Aminic8c55172015-12-03 02:37:33 +0000226}
Mehdi Aminiffe2e4a2015-12-02 04:34:28 +0000227
Mehdi Amini01e32132016-03-26 05:40:34 +0000228} // anonymous namespace
229
230/// Compute all the import and export for every module in the Index.
231void llvm::ComputeCrossModuleImport(
232 const ModuleSummaryIndex &Index,
233 StringMap<FunctionImporter::ImportMapTy> &ImportLists,
234 StringMap<FunctionImporter::ExportSetTy> &ExportLists) {
235 auto ModuleCount = Index.modulePaths().size();
236
237 // Collect for each module the list of function it defines.
238 // GUID -> Summary
239 StringMap<std::map<uint64_t, FunctionSummary *>> Module2FunctionInfoMap(
240 ModuleCount);
241
242 for (auto &GlobalList : Index) {
243 auto GUID = GlobalList.first;
244 for (auto &GlobInfo : GlobalList.second) {
245 auto *Summary = dyn_cast_or_null<FunctionSummary>(GlobInfo->summary());
246 if (!Summary)
247 /// Ignore global variable, focus on functions
248 continue;
249 DEBUG(dbgs() << "Adding definition: Module '" << Summary->modulePath()
250 << "' defines '" << GUID << "'\n");
251 Module2FunctionInfoMap[Summary->modulePath()][GUID] = Summary;
252 }
253 }
254
255 // For each module that has function defined, compute the import/export lists.
256 for (auto &DefinedFunctions : Module2FunctionInfoMap) {
257 auto &ImportsForModule = ImportLists[DefinedFunctions.first()];
258 DEBUG(dbgs() << "Computing import for Module '" << DefinedFunctions.first()
259 << "'\n");
260 ComputeImportForModule(DefinedFunctions.first(), DefinedFunctions.second,
261 Index, ImportsForModule, ExportLists);
262 }
263
264#ifndef NDEBUG
265 DEBUG(dbgs() << "Import/Export lists for " << ImportLists.size()
266 << " modules:\n");
267 for (auto &ModuleImports : ImportLists) {
268 auto ModName = ModuleImports.first();
269 auto &Exports = ExportLists[ModName];
270 DEBUG(dbgs() << "* Module " << ModName << " exports " << Exports.size()
271 << " functions. Imports from " << ModuleImports.second.size()
272 << " modules.\n");
273 for (auto &Src : ModuleImports.second) {
274 auto SrcModName = Src.first();
275 DEBUG(dbgs() << " - " << Src.second.size() << " functions imported from "
276 << SrcModName << "\n");
277 }
278 }
279#endif
280}
281
Mehdi Aminic8c55172015-12-03 02:37:33 +0000282// Automatically import functions in Module \p DestModule based on the summaries
283// index.
284//
Mehdi Amini01e32132016-03-26 05:40:34 +0000285bool FunctionImporter::importFunctions(
286 Module &DestModule, const FunctionImporter::ImportMapTy &ImportList) {
Mehdi Amini5411d052015-12-08 23:04:19 +0000287 DEBUG(dbgs() << "Starting import for Module "
Mehdi Amini311fef62015-12-03 02:58:14 +0000288 << DestModule.getModuleIdentifier() << "\n");
Mehdi Aminic8c55172015-12-03 02:37:33 +0000289 unsigned ImportedCount = 0;
290
Mehdi Aminic8c55172015-12-03 02:37:33 +0000291 // Linker that will be used for importing function
Rafael Espindola9d2bfc42015-12-14 23:17:03 +0000292 Linker TheLinker(DestModule);
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000293 // Do the actual import of functions now, one Module at a time
Mehdi Amini01e32132016-03-26 05:40:34 +0000294 std::set<StringRef> ModuleNameOrderedList;
295 for (auto &FunctionsToImportPerModule : ImportList) {
296 ModuleNameOrderedList.insert(FunctionsToImportPerModule.first());
297 }
298 for (auto &Name : ModuleNameOrderedList) {
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000299 // Get the module for the import
Mehdi Amini01e32132016-03-26 05:40:34 +0000300 const auto &FunctionsToImportPerModule = ImportList.find(Name);
301 assert(FunctionsToImportPerModule != ImportList.end());
302 std::unique_ptr<Module> SrcModule = ModuleLoader(Name);
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000303 assert(&DestModule.getContext() == &SrcModule->getContext() &&
304 "Context mismatch");
305
Teresa Johnson6cba37c2016-01-22 00:15:53 +0000306 // If modules were created with lazy metadata loading, materialize it
307 // now, before linking it (otherwise this will be a noop).
308 SrcModule->materializeMetadata();
309 UpgradeDebugInfo(*SrcModule);
Teresa Johnsone5a61912015-12-17 17:14:09 +0000310
Mehdi Amini01e32132016-03-26 05:40:34 +0000311 auto &ImportGUIDs = FunctionsToImportPerModule->second;
312 // Find the globals to import
313 DenseSet<const GlobalValue *> GlobalsToImport;
314 for (auto &GV : *SrcModule) {
315 if (GV.hasName() && ImportGUIDs.count(GV.getGUID())) {
316 GV.materialize();
317 GlobalsToImport.insert(&GV);
318 }
319 }
320 for (auto &GV : SrcModule->aliases()) {
321 if (!GV.hasName())
322 continue;
323 auto GUID = GV.getGUID();
324 if (ImportGUIDs.count(GUID)) {
Mehdi Amini01e32132016-03-26 05:40:34 +0000325 // Alias can't point to "available_externally". However when we import
Teresa Johnson9aae3952016-03-27 15:01:11 +0000326 // linkOnceODR the linkage does not change. So we import the alias
327 // and aliasee only in this case.
Mehdi Amini01e32132016-03-26 05:40:34 +0000328 const GlobalObject *GO = GV.getBaseObject();
329 if (!GO->hasLinkOnceODRLinkage())
330 continue;
Teresa Johnson9aae3952016-03-27 15:01:11 +0000331 GV.materialize();
332 GlobalsToImport.insert(&GV);
Mehdi Amini01e32132016-03-26 05:40:34 +0000333 GlobalsToImport.insert(GO);
334 }
335 }
336 for (auto &GV : SrcModule->globals()) {
337 if (!GV.hasName())
338 continue;
339 auto GUID = Function::getGUID(Function::getGlobalIdentifier(
340 GV.getName(), GV.getLinkage(), SrcModule->getModuleIdentifier()));
341 if (ImportGUIDs.count(GUID)) {
342 GV.materialize();
343 GlobalsToImport.insert(&GV);
344 }
345 }
346
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000347 // Link in the specified functions.
Mehdi Amini01e32132016-03-26 05:40:34 +0000348 if (renameModuleForThinLTO(*SrcModule, Index, &GlobalsToImport))
Mehdi Amini8d051852016-03-19 00:40:31 +0000349 return true;
350
Rafael Espindola434e9562015-12-16 23:16:33 +0000351 if (TheLinker.linkInModule(std::move(SrcModule), Linker::Flags::None,
Mehdi Amini01e32132016-03-26 05:40:34 +0000352 &GlobalsToImport))
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000353 report_fatal_error("Function Import: link error");
354
Mehdi Amini01e32132016-03-26 05:40:34 +0000355 ImportedCount += GlobalsToImport.size();
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000356 }
Teresa Johnsone5a61912015-12-17 17:14:09 +0000357
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000358 DEBUG(dbgs() << "Imported " << ImportedCount << " functions for Module "
Mehdi Aminic8c55172015-12-03 02:37:33 +0000359 << DestModule.getModuleIdentifier() << "\n");
360 return ImportedCount;
Mehdi Amini42418ab2015-11-24 06:07:49 +0000361}
362
363/// Summary file to use for function importing when using -function-import from
364/// the command line.
365static cl::opt<std::string>
366 SummaryFile("summary-file",
367 cl::desc("The summary file to use for function importing."));
368
369static void diagnosticHandler(const DiagnosticInfo &DI) {
370 raw_ostream &OS = errs();
371 DiagnosticPrinterRawOStream DP(OS);
372 DI.print(DP);
373 OS << '\n';
374}
375
Teresa Johnson26ab5772016-03-15 00:04:37 +0000376/// Parse the summary index out of an IR file and return the summary
Mehdi Amini42418ab2015-11-24 06:07:49 +0000377/// index object if found, or nullptr if not.
Teresa Johnson26ab5772016-03-15 00:04:37 +0000378static std::unique_ptr<ModuleSummaryIndex>
379getModuleSummaryIndexForFile(StringRef Path, std::string &Error,
380 DiagnosticHandlerFunction DiagnosticHandler) {
Mehdi Amini42418ab2015-11-24 06:07:49 +0000381 std::unique_ptr<MemoryBuffer> Buffer;
382 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
383 MemoryBuffer::getFile(Path);
384 if (std::error_code EC = BufferOrErr.getError()) {
385 Error = EC.message();
386 return nullptr;
387 }
388 Buffer = std::move(BufferOrErr.get());
Teresa Johnson26ab5772016-03-15 00:04:37 +0000389 ErrorOr<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> ObjOrErr =
390 object::ModuleSummaryIndexObjectFile::create(Buffer->getMemBufferRef(),
391 DiagnosticHandler);
Mehdi Amini42418ab2015-11-24 06:07:49 +0000392 if (std::error_code EC = ObjOrErr.getError()) {
393 Error = EC.message();
394 return nullptr;
395 }
396 return (*ObjOrErr)->takeIndex();
397}
398
Benjamin Kramerfe2b5412015-12-24 10:03:35 +0000399namespace {
Mehdi Amini42418ab2015-11-24 06:07:49 +0000400/// Pass that performs cross-module function import provided a summary file.
401class FunctionImportPass : public ModulePass {
Teresa Johnson26ab5772016-03-15 00:04:37 +0000402 /// Optional module summary index to use for importing, otherwise
Teresa Johnson5fcbdb72015-12-07 19:21:11 +0000403 /// the summary-file option must be specified.
Teresa Johnson26ab5772016-03-15 00:04:37 +0000404 const ModuleSummaryIndex *Index;
Mehdi Amini42418ab2015-11-24 06:07:49 +0000405
406public:
407 /// Pass identification, replacement for typeid
408 static char ID;
409
Teresa Johnson5fcbdb72015-12-07 19:21:11 +0000410 /// Specify pass name for debug output
411 const char *getPassName() const override {
412 return "Function Importing";
413 }
414
Teresa Johnson26ab5772016-03-15 00:04:37 +0000415 explicit FunctionImportPass(const ModuleSummaryIndex *Index = nullptr)
Teresa Johnson5fcbdb72015-12-07 19:21:11 +0000416 : ModulePass(ID), Index(Index) {}
Mehdi Amini42418ab2015-11-24 06:07:49 +0000417
418 bool runOnModule(Module &M) override {
Teresa Johnson5fcbdb72015-12-07 19:21:11 +0000419 if (SummaryFile.empty() && !Index)
420 report_fatal_error("error: -function-import requires -summary-file or "
421 "file from frontend\n");
Teresa Johnson26ab5772016-03-15 00:04:37 +0000422 std::unique_ptr<ModuleSummaryIndex> IndexPtr;
Teresa Johnson5fcbdb72015-12-07 19:21:11 +0000423 if (!SummaryFile.empty()) {
424 if (Index)
425 report_fatal_error("error: -summary-file and index from frontend\n");
426 std::string Error;
Teresa Johnson26ab5772016-03-15 00:04:37 +0000427 IndexPtr =
428 getModuleSummaryIndexForFile(SummaryFile, Error, diagnosticHandler);
Teresa Johnson5fcbdb72015-12-07 19:21:11 +0000429 if (!IndexPtr) {
430 errs() << "Error loading file '" << SummaryFile << "': " << Error
431 << "\n";
432 return false;
433 }
434 Index = IndexPtr.get();
Mehdi Amini42418ab2015-11-24 06:07:49 +0000435 }
436
Mehdi Amini01e32132016-03-26 05:40:34 +0000437 // First step is collecting the import/export lists
438 // The export list is not used yet, but could limit the amount of renaming
439 // performed in renameModuleForThinLTO()
440 StringMap<FunctionImporter::ImportMapTy> ImportLists;
441 StringMap<FunctionImporter::ExportSetTy> ExportLists;
442 ComputeCrossModuleImport(*Index, ImportLists, ExportLists);
443 auto &ImportList = ImportLists[M.getModuleIdentifier()];
444
445 // Next we need to promote to global scope and rename any local values that
Teresa Johnson1b00f2d2016-01-08 17:06:29 +0000446 // are potentially exported to other modules.
Mehdi Amini01e32132016-03-26 05:40:34 +0000447 if (renameModuleForThinLTO(M, *Index, nullptr)) {
Teresa Johnson1b00f2d2016-01-08 17:06:29 +0000448 errs() << "Error renaming module\n";
449 return false;
450 }
451
Mehdi Amini42418ab2015-11-24 06:07:49 +0000452 // Perform the import now.
Mehdi Aminid16c8062015-12-08 22:39:40 +0000453 auto ModuleLoader = [&M](StringRef Identifier) {
454 return loadFile(Identifier, M.getContext());
455 };
Rafael Espindola9d2bfc42015-12-14 23:17:03 +0000456 FunctionImporter Importer(*Index, ModuleLoader);
Mehdi Amini01e32132016-03-26 05:40:34 +0000457 return Importer.importFunctions(M, ImportList);
Mehdi Amini42418ab2015-11-24 06:07:49 +0000458 }
459};
Benjamin Kramerfe2b5412015-12-24 10:03:35 +0000460} // anonymous namespace
Mehdi Amini42418ab2015-11-24 06:07:49 +0000461
462char FunctionImportPass::ID = 0;
463INITIALIZE_PASS_BEGIN(FunctionImportPass, "function-import",
464 "Summary Based Function Import", false, false)
465INITIALIZE_PASS_END(FunctionImportPass, "function-import",
466 "Summary Based Function Import", false, false)
467
468namespace llvm {
Teresa Johnson26ab5772016-03-15 00:04:37 +0000469Pass *createFunctionImportPass(const ModuleSummaryIndex *Index = nullptr) {
Teresa Johnson5fcbdb72015-12-07 19:21:11 +0000470 return new FunctionImportPass(Index);
471}
Mehdi Amini42418ab2015-11-24 06:07:49 +0000472}