blob: a33216d1852a598579beb8ccf618c18dd5e0dc20 [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
16#include "llvm/ADT/StringSet.h"
17#include "llvm/IR/AutoUpgrade.h"
18#include "llvm/IR/DiagnosticPrinter.h"
19#include "llvm/IR/IntrinsicInst.h"
20#include "llvm/IR/Module.h"
21#include "llvm/IRReader/IRReader.h"
22#include "llvm/Linker/Linker.h"
23#include "llvm/Object/FunctionIndexObjectFile.h"
24#include "llvm/Support/CommandLine.h"
25#include "llvm/Support/Debug.h"
26#include "llvm/Support/SourceMgr.h"
Teresa Johnson488a8002016-02-10 18:11:31 +000027#include "llvm/Transforms/Utils/FunctionImportUtils.h"
Mehdi Amini7e88d0d2015-12-09 08:17:35 +000028
29#include <map>
30
Mehdi Amini42418ab2015-11-24 06:07:49 +000031using namespace llvm;
32
33#define DEBUG_TYPE "function-import"
34
Teresa Johnson39303612015-11-24 22:55:46 +000035/// Limit on instruction count of imported functions.
36static cl::opt<unsigned> ImportInstrLimit(
37 "import-instr-limit", cl::init(100), cl::Hidden, cl::value_desc("N"),
38 cl::desc("Only import functions with less than N instructions"));
39
Mehdi Amini42418ab2015-11-24 06:07:49 +000040// Load lazily a module from \p FileName in \p Context.
41static std::unique_ptr<Module> loadFile(const std::string &FileName,
42 LLVMContext &Context) {
43 SMDiagnostic Err;
44 DEBUG(dbgs() << "Loading '" << FileName << "'\n");
Teresa Johnson6cba37c2016-01-22 00:15:53 +000045 // Metadata isn't loaded until functions are imported, to minimize
46 // the memory overhead.
Teresa Johnsona1080ee2016-01-08 14:17:41 +000047 std::unique_ptr<Module> Result =
48 getLazyIRFileModule(FileName, Err, Context,
49 /* ShouldLazyLoadMetadata = */ true);
Mehdi Amini42418ab2015-11-24 06:07:49 +000050 if (!Result) {
51 Err.print("function-import", errs());
52 return nullptr;
53 }
54
Mehdi Amini42418ab2015-11-24 06:07:49 +000055 return Result;
56}
57
Mehdi Amini7e88d0d2015-12-09 08:17:35 +000058namespace {
59/// Helper to load on demand a Module from file and cache it for subsequent
60/// queries. It can be used with the FunctionImporter.
61class ModuleLazyLoaderCache {
62 /// Cache of lazily loaded module for import.
63 StringMap<std::unique_ptr<Module>> ModuleMap;
64
65 /// Retrieve a Module from the cache or lazily load it on demand.
66 std::function<std::unique_ptr<Module>(StringRef FileName)> createLazyModule;
67
68public:
69 /// Create the loader, Module will be initialized in \p Context.
70 ModuleLazyLoaderCache(std::function<
71 std::unique_ptr<Module>(StringRef FileName)> createLazyModule)
72 : createLazyModule(createLazyModule) {}
73
74 /// Retrieve a Module from the cache or lazily load it on demand.
75 Module &operator()(StringRef FileName);
Rafael Espindola434e9562015-12-16 23:16:33 +000076
77 std::unique_ptr<Module> takeModule(StringRef FileName) {
78 auto I = ModuleMap.find(FileName);
79 assert(I != ModuleMap.end());
80 std::unique_ptr<Module> Ret = std::move(I->second);
81 ModuleMap.erase(I);
82 return Ret;
83 }
Mehdi Amini7e88d0d2015-12-09 08:17:35 +000084};
85
86// Get a Module for \p FileName from the cache, or load it lazily.
87Module &ModuleLazyLoaderCache::operator()(StringRef Identifier) {
88 auto &Module = ModuleMap[Identifier];
89 if (!Module)
90 Module = createLazyModule(Identifier);
91 return *Module;
92}
93} // anonymous namespace
94
Teresa Johnsond450da32015-11-24 21:15:19 +000095/// Walk through the instructions in \p F looking for external
96/// calls not already in the \p CalledFunctions set. If any are
97/// found they are added to the \p Worklist for importing.
Mehdi Amini7e88d0d2015-12-09 08:17:35 +000098static void findExternalCalls(const Module &DestModule, Function &F,
99 const FunctionInfoIndex &Index,
100 StringSet<> &CalledFunctions,
Teresa Johnsond450da32015-11-24 21:15:19 +0000101 SmallVector<StringRef, 64> &Worklist) {
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000102 // We need to suffix internal function calls imported from other modules,
103 // prepare the suffix ahead of time.
Rafael Espindola9edc3b82015-12-09 20:41:10 +0000104 std::string Suffix;
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000105 if (F.getParent() != &DestModule)
106 Suffix =
107 (Twine(".llvm.") +
108 Twine(Index.getModuleId(F.getParent()->getModuleIdentifier()))).str();
109
Teresa Johnsond450da32015-11-24 21:15:19 +0000110 for (auto &BB : F) {
111 for (auto &I : BB) {
112 if (isa<CallInst>(I)) {
Teresa Johnsond450da32015-11-24 21:15:19 +0000113 auto CalledFunction = cast<CallInst>(I).getCalledFunction();
114 // Insert any new external calls that have not already been
115 // added to set/worklist.
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000116 if (!CalledFunction || !CalledFunction->hasName())
117 continue;
118 // Ignore intrinsics early
119 if (CalledFunction->isIntrinsic()) {
120 assert(CalledFunction->getIntrinsicID() != 0);
121 continue;
Teresa Johnsond450da32015-11-24 21:15:19 +0000122 }
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000123 auto ImportedName = CalledFunction->getName();
124 auto Renamed = (ImportedName + Suffix).str();
125 // Rename internal functions
126 if (CalledFunction->hasInternalLinkage()) {
127 ImportedName = Renamed;
128 }
Teresa Johnsone1164de2016-02-10 21:55:02 +0000129 // Compute the global identifier used in the function index.
130 auto CalledFunctionGlobalID = Function::getGlobalIdentifier(
131 CalledFunction->getName(), CalledFunction->getLinkage(),
132 CalledFunction->getParent()->getSourceFileName());
133 auto It = CalledFunctions.insert(CalledFunctionGlobalID);
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000134 if (!It.second) {
135 // This is a call to a function we already considered, skip.
136 continue;
137 }
138 // Ignore functions already present in the destination module
139 auto *SrcGV = DestModule.getNamedValue(ImportedName);
140 if (SrcGV) {
Teresa Johnson388497e2016-01-12 17:48:44 +0000141 if (GlobalAlias *SGA = dyn_cast<GlobalAlias>(SrcGV))
142 SrcGV = SGA->getBaseObject();
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000143 assert(isa<Function>(SrcGV) && "Name collision during import");
144 if (!cast<Function>(SrcGV)->isDeclaration()) {
Teresa Johnson9f2ff9c2015-12-10 16:39:07 +0000145 DEBUG(dbgs() << DestModule.getModuleIdentifier() << ": Ignoring "
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000146 << ImportedName << " already in DestinationModule\n");
147 continue;
148 }
149 }
150
151 Worklist.push_back(It.first->getKey());
152 DEBUG(dbgs() << DestModule.getModuleIdentifier()
Teresa Johnson9f2ff9c2015-12-10 16:39:07 +0000153 << ": Adding callee for : " << ImportedName << " : "
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000154 << F.getName() << "\n");
Teresa Johnsond450da32015-11-24 21:15:19 +0000155 }
156 }
157 }
158}
159
Mehdi Aminic8c55172015-12-03 02:37:33 +0000160// Helper function: given a worklist and an index, will process all the worklist
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000161// and decide what to import based on the summary information.
162//
163// Nothing is actually imported, functions are materialized in their source
164// module and analyzed there.
165//
166// \p ModuleToFunctionsToImportMap is filled with the set of Function to import
167// per Module.
Rafael Espindola434e9562015-12-16 23:16:33 +0000168static void GetImportList(Module &DestModule,
169 SmallVector<StringRef, 64> &Worklist,
170 StringSet<> &CalledFunctions,
171 std::map<StringRef, DenseSet<const GlobalValue *>>
172 &ModuleToFunctionsToImportMap,
173 const FunctionInfoIndex &Index,
174 ModuleLazyLoaderCache &ModuleLoaderCache) {
Mehdi Amini42418ab2015-11-24 06:07:49 +0000175 while (!Worklist.empty()) {
176 auto CalledFunctionName = Worklist.pop_back_val();
Teresa Johnson9f2ff9c2015-12-10 16:39:07 +0000177 DEBUG(dbgs() << DestModule.getModuleIdentifier() << ": Process import for "
Mehdi Amini5411d052015-12-08 23:04:19 +0000178 << CalledFunctionName << "\n");
Mehdi Amini42418ab2015-11-24 06:07:49 +0000179
180 // Try to get a summary for this function call.
181 auto InfoList = Index.findFunctionInfoList(CalledFunctionName);
182 if (InfoList == Index.end()) {
Teresa Johnson9f2ff9c2015-12-10 16:39:07 +0000183 DEBUG(dbgs() << DestModule.getModuleIdentifier() << ": No summary for "
Mehdi Amini5411d052015-12-08 23:04:19 +0000184 << CalledFunctionName << " Ignoring.\n");
Mehdi Amini42418ab2015-11-24 06:07:49 +0000185 continue;
186 }
187 assert(!InfoList->second.empty() && "No summary, error at import?");
188
189 // Comdat can have multiple entries, FIXME: what do we do with them?
190 auto &Info = InfoList->second[0];
191 assert(Info && "Nullptr in list, error importing summaries?\n");
192
193 auto *Summary = Info->functionSummary();
194 if (!Summary) {
195 // FIXME: in case we are lazyloading summaries, we can do it now.
Mehdi Amini5411d052015-12-08 23:04:19 +0000196 DEBUG(dbgs() << DestModule.getModuleIdentifier()
Teresa Johnson9f2ff9c2015-12-10 16:39:07 +0000197 << ": Missing summary for " << CalledFunctionName
Teresa Johnson430110c2015-12-01 17:12:10 +0000198 << ", error at import?\n");
Mehdi Amini42418ab2015-11-24 06:07:49 +0000199 llvm_unreachable("Missing summary");
200 }
201
Teresa Johnson39303612015-11-24 22:55:46 +0000202 if (Summary->instCount() > ImportInstrLimit) {
Teresa Johnson9f2ff9c2015-12-10 16:39:07 +0000203 DEBUG(dbgs() << DestModule.getModuleIdentifier() << ": Skip import of "
Mehdi Amini5411d052015-12-08 23:04:19 +0000204 << CalledFunctionName << " with " << Summary->instCount()
205 << " instructions (limit " << ImportInstrLimit << ")\n");
Teresa Johnson39303612015-11-24 22:55:46 +0000206 continue;
207 }
208
Mehdi Amini42418ab2015-11-24 06:07:49 +0000209 // Get the module path from the summary.
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000210 auto ModuleIdentifier = Summary->modulePath();
Teresa Johnson9f2ff9c2015-12-10 16:39:07 +0000211 DEBUG(dbgs() << DestModule.getModuleIdentifier() << ": Importing "
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000212 << CalledFunctionName << " from " << ModuleIdentifier << "\n");
Mehdi Amini42418ab2015-11-24 06:07:49 +0000213
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000214 auto &SrcModule = ModuleLoaderCache(ModuleIdentifier);
Mehdi Amini42418ab2015-11-24 06:07:49 +0000215
216 // The function that we will import!
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000217 GlobalValue *SGV = SrcModule.getNamedValue(CalledFunctionName);
218
Teresa Johnson130de7a2015-11-24 19:55:04 +0000219 if (!SGV) {
Teresa Johnsone1164de2016-02-10 21:55:02 +0000220 // The function is referenced by a global identifier, which has the
221 // source file name prepended for functions that were originally local
222 // in the source module. Strip any prepended name to recover the original
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000223 // name in the source module.
Teresa Johnsone1164de2016-02-10 21:55:02 +0000224 std::pair<StringRef, StringRef> Split = CalledFunctionName.split(":");
225 SGV = SrcModule.getNamedValue(Split.second);
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000226 assert(SGV && "Can't find function to import in source module");
Teresa Johnson130de7a2015-11-24 19:55:04 +0000227 }
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000228 if (!SGV) {
229 report_fatal_error(Twine("Can't load function '") + CalledFunctionName +
230 "' in Module '" + SrcModule.getModuleIdentifier() +
231 "', error in the summary?\n");
232 }
233
Mehdi Amini42418ab2015-11-24 06:07:49 +0000234 Function *F = dyn_cast<Function>(SGV);
235 if (!F && isa<GlobalAlias>(SGV)) {
236 auto *SGA = dyn_cast<GlobalAlias>(SGV);
237 F = dyn_cast<Function>(SGA->getBaseObject());
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000238 CalledFunctionName = F->getName();
Mehdi Amini42418ab2015-11-24 06:07:49 +0000239 }
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000240 assert(F && "Imported Function is ... not a Function");
Mehdi Amini42418ab2015-11-24 06:07:49 +0000241
Teresa Johnson17626652015-11-24 16:10:43 +0000242 // We cannot import weak_any functions/aliases without possibly affecting
243 // the order they are seen and selected by the linker, changing program
Mehdi Amini42418ab2015-11-24 06:07:49 +0000244 // semantics.
Teresa Johnson17626652015-11-24 16:10:43 +0000245 if (SGV->hasWeakAnyLinkage()) {
Mehdi Amini5411d052015-12-08 23:04:19 +0000246 DEBUG(dbgs() << DestModule.getModuleIdentifier()
Teresa Johnson9f2ff9c2015-12-10 16:39:07 +0000247 << ": Ignoring import request for weak-any "
Teresa Johnson17626652015-11-24 16:10:43 +0000248 << (isa<Function>(SGV) ? "function " : "alias ")
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000249 << CalledFunctionName << " from "
250 << SrcModule.getModuleIdentifier() << "\n");
Mehdi Amini42418ab2015-11-24 06:07:49 +0000251 continue;
252 }
253
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000254 // Add the function to the import list
255 auto &Entry = ModuleToFunctionsToImportMap[SrcModule.getModuleIdentifier()];
Rafael Espindola434e9562015-12-16 23:16:33 +0000256 Entry.insert(F);
Mehdi Amini42418ab2015-11-24 06:07:49 +0000257
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000258 // Process the newly imported functions and add callees to the worklist.
259 F->materialize();
260 findExternalCalls(DestModule, *F, Index, CalledFunctions, Worklist);
Mehdi Amini42418ab2015-11-24 06:07:49 +0000261 }
Mehdi Aminic8c55172015-12-03 02:37:33 +0000262}
Mehdi Aminiffe2e4a2015-12-02 04:34:28 +0000263
Mehdi Aminic8c55172015-12-03 02:37:33 +0000264// Automatically import functions in Module \p DestModule based on the summaries
265// index.
266//
267// The current implementation imports every called functions that exists in the
268// summaries index.
269bool FunctionImporter::importFunctions(Module &DestModule) {
Mehdi Amini5411d052015-12-08 23:04:19 +0000270 DEBUG(dbgs() << "Starting import for Module "
Mehdi Amini311fef62015-12-03 02:58:14 +0000271 << DestModule.getModuleIdentifier() << "\n");
Mehdi Aminic8c55172015-12-03 02:37:33 +0000272 unsigned ImportedCount = 0;
273
274 /// First step is collecting the called external functions.
275 StringSet<> CalledFunctions;
276 SmallVector<StringRef, 64> Worklist;
277 for (auto &F : DestModule) {
278 if (F.isDeclaration() || F.hasFnAttribute(Attribute::OptimizeNone))
279 continue;
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000280 findExternalCalls(DestModule, F, Index, CalledFunctions, Worklist);
Mehdi Aminic8c55172015-12-03 02:37:33 +0000281 }
282 if (Worklist.empty())
283 return false;
284
285 /// Second step: for every call to an external function, try to import it.
286
287 // Linker that will be used for importing function
Rafael Espindola9d2bfc42015-12-14 23:17:03 +0000288 Linker TheLinker(DestModule);
Mehdi Aminic8c55172015-12-03 02:37:33 +0000289
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000290 // Map of Module -> List of Function to import from the Module
Rafael Espindola434e9562015-12-16 23:16:33 +0000291 std::map<StringRef, DenseSet<const GlobalValue *>>
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000292 ModuleToFunctionsToImportMap;
Mehdi Aminic8c55172015-12-03 02:37:33 +0000293
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000294 // Analyze the summaries and get the list of functions to import by
295 // populating ModuleToFunctionsToImportMap
296 ModuleLazyLoaderCache ModuleLoaderCache(ModuleLoader);
297 GetImportList(DestModule, Worklist, CalledFunctions,
298 ModuleToFunctionsToImportMap, Index, ModuleLoaderCache);
299 assert(Worklist.empty() && "Worklist hasn't been flushed in GetImportList");
300
301 // Do the actual import of functions now, one Module at a time
302 for (auto &FunctionsToImportPerModule : ModuleToFunctionsToImportMap) {
303 // Get the module for the import
Rafael Espindola434e9562015-12-16 23:16:33 +0000304 auto &FunctionsToImport = FunctionsToImportPerModule.second;
305 std::unique_ptr<Module> SrcModule =
306 ModuleLoaderCache.takeModule(FunctionsToImportPerModule.first);
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000307 assert(&DestModule.getContext() == &SrcModule->getContext() &&
308 "Context mismatch");
309
Teresa Johnson6cba37c2016-01-22 00:15:53 +0000310 // If modules were created with lazy metadata loading, materialize it
311 // now, before linking it (otherwise this will be a noop).
312 SrcModule->materializeMetadata();
313 UpgradeDebugInfo(*SrcModule);
Teresa Johnsone5a61912015-12-17 17:14:09 +0000314
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000315 // Link in the specified functions.
Rafael Espindola434e9562015-12-16 23:16:33 +0000316 if (TheLinker.linkInModule(std::move(SrcModule), Linker::Flags::None,
Teresa Johnson6cba37c2016-01-22 00:15:53 +0000317 &Index, &FunctionsToImport))
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000318 report_fatal_error("Function Import: link error");
319
320 ImportedCount += FunctionsToImport.size();
321 }
Teresa Johnsone5a61912015-12-17 17:14:09 +0000322
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000323 DEBUG(dbgs() << "Imported " << ImportedCount << " functions for Module "
Mehdi Aminic8c55172015-12-03 02:37:33 +0000324 << DestModule.getModuleIdentifier() << "\n");
325 return ImportedCount;
Mehdi Amini42418ab2015-11-24 06:07:49 +0000326}
327
328/// Summary file to use for function importing when using -function-import from
329/// the command line.
330static cl::opt<std::string>
331 SummaryFile("summary-file",
332 cl::desc("The summary file to use for function importing."));
333
334static void diagnosticHandler(const DiagnosticInfo &DI) {
335 raw_ostream &OS = errs();
336 DiagnosticPrinterRawOStream DP(OS);
337 DI.print(DP);
338 OS << '\n';
339}
340
341/// Parse the function index out of an IR file and return the function
342/// index object if found, or nullptr if not.
343static std::unique_ptr<FunctionInfoIndex>
344getFunctionIndexForFile(StringRef Path, std::string &Error,
345 DiagnosticHandlerFunction DiagnosticHandler) {
346 std::unique_ptr<MemoryBuffer> Buffer;
347 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
348 MemoryBuffer::getFile(Path);
349 if (std::error_code EC = BufferOrErr.getError()) {
350 Error = EC.message();
351 return nullptr;
352 }
353 Buffer = std::move(BufferOrErr.get());
354 ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr =
355 object::FunctionIndexObjectFile::create(Buffer->getMemBufferRef(),
356 DiagnosticHandler);
357 if (std::error_code EC = ObjOrErr.getError()) {
358 Error = EC.message();
359 return nullptr;
360 }
361 return (*ObjOrErr)->takeIndex();
362}
363
Benjamin Kramerfe2b5412015-12-24 10:03:35 +0000364namespace {
Mehdi Amini42418ab2015-11-24 06:07:49 +0000365/// Pass that performs cross-module function import provided a summary file.
366class FunctionImportPass : public ModulePass {
Teresa Johnson5fcbdb72015-12-07 19:21:11 +0000367 /// Optional function summary index to use for importing, otherwise
368 /// the summary-file option must be specified.
Teresa Johnson7f961e12015-12-09 19:39:47 +0000369 const FunctionInfoIndex *Index;
Mehdi Amini42418ab2015-11-24 06:07:49 +0000370
371public:
372 /// Pass identification, replacement for typeid
373 static char ID;
374
Teresa Johnson5fcbdb72015-12-07 19:21:11 +0000375 /// Specify pass name for debug output
376 const char *getPassName() const override {
377 return "Function Importing";
378 }
379
Teresa Johnson7f961e12015-12-09 19:39:47 +0000380 explicit FunctionImportPass(const FunctionInfoIndex *Index = nullptr)
Teresa Johnson5fcbdb72015-12-07 19:21:11 +0000381 : ModulePass(ID), Index(Index) {}
Mehdi Amini42418ab2015-11-24 06:07:49 +0000382
383 bool runOnModule(Module &M) override {
Teresa Johnson5fcbdb72015-12-07 19:21:11 +0000384 if (SummaryFile.empty() && !Index)
385 report_fatal_error("error: -function-import requires -summary-file or "
386 "file from frontend\n");
387 std::unique_ptr<FunctionInfoIndex> IndexPtr;
388 if (!SummaryFile.empty()) {
389 if (Index)
390 report_fatal_error("error: -summary-file and index from frontend\n");
391 std::string Error;
392 IndexPtr = getFunctionIndexForFile(SummaryFile, Error, diagnosticHandler);
393 if (!IndexPtr) {
394 errs() << "Error loading file '" << SummaryFile << "': " << Error
395 << "\n";
396 return false;
397 }
398 Index = IndexPtr.get();
Mehdi Amini42418ab2015-11-24 06:07:49 +0000399 }
400
Teresa Johnson1b00f2d2016-01-08 17:06:29 +0000401 // First we need to promote to global scope and rename any local values that
402 // are potentially exported to other modules.
403 if (renameModuleForThinLTO(M, Index)) {
404 errs() << "Error renaming module\n";
405 return false;
406 }
407
Mehdi Amini42418ab2015-11-24 06:07:49 +0000408 // Perform the import now.
Mehdi Aminid16c8062015-12-08 22:39:40 +0000409 auto ModuleLoader = [&M](StringRef Identifier) {
410 return loadFile(Identifier, M.getContext());
411 };
Rafael Espindola9d2bfc42015-12-14 23:17:03 +0000412 FunctionImporter Importer(*Index, ModuleLoader);
Mehdi Amini42418ab2015-11-24 06:07:49 +0000413 return Importer.importFunctions(M);
Mehdi Amini42418ab2015-11-24 06:07:49 +0000414 }
415};
Benjamin Kramerfe2b5412015-12-24 10:03:35 +0000416} // anonymous namespace
Mehdi Amini42418ab2015-11-24 06:07:49 +0000417
418char FunctionImportPass::ID = 0;
419INITIALIZE_PASS_BEGIN(FunctionImportPass, "function-import",
420 "Summary Based Function Import", false, false)
421INITIALIZE_PASS_END(FunctionImportPass, "function-import",
422 "Summary Based Function Import", false, false)
423
424namespace llvm {
Teresa Johnson7f961e12015-12-09 19:39:47 +0000425Pass *createFunctionImportPass(const FunctionInfoIndex *Index = nullptr) {
Teresa Johnson5fcbdb72015-12-07 19:21:11 +0000426 return new FunctionImportPass(Index);
427}
Mehdi Amini42418ab2015-11-24 06:07:49 +0000428}