blob: 8aa9753517076ce3b26cf9a5646cebc5570573e4 [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"
Teresa Johnsoncec0cae2016-03-14 21:18:10 +000023#include "llvm/Object/FunctionIndexObjectFile.h"
Mehdi Amini42418ab2015-11-24 06:07:49 +000024#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 Amini40641742016-02-10 23:31:45 +000040static cl::opt<float>
41 ImportInstrFactor("import-instr-evolution-factor", cl::init(0.7),
42 cl::Hidden, cl::value_desc("x"),
43 cl::desc("As we import functions, multiply the "
44 "`import-instr-limit` threshold by this factor "
45 "before processing newly imported functions"));
46
Mehdi Amini42418ab2015-11-24 06:07:49 +000047// Load lazily a module from \p FileName in \p Context.
48static std::unique_ptr<Module> loadFile(const std::string &FileName,
49 LLVMContext &Context) {
50 SMDiagnostic Err;
51 DEBUG(dbgs() << "Loading '" << FileName << "'\n");
Teresa Johnson6cba37c2016-01-22 00:15:53 +000052 // Metadata isn't loaded until functions are imported, to minimize
53 // the memory overhead.
Teresa Johnsona1080ee2016-01-08 14:17:41 +000054 std::unique_ptr<Module> Result =
55 getLazyIRFileModule(FileName, Err, Context,
56 /* ShouldLazyLoadMetadata = */ true);
Mehdi Amini42418ab2015-11-24 06:07:49 +000057 if (!Result) {
58 Err.print("function-import", errs());
59 return nullptr;
60 }
61
Mehdi Amini42418ab2015-11-24 06:07:49 +000062 return Result;
63}
64
Mehdi Amini7e88d0d2015-12-09 08:17:35 +000065namespace {
Mehdi Amini40641742016-02-10 23:31:45 +000066
67/// Track functions already seen using a map that record the current
68/// Threshold and the importing decision. Since the traversal of the call graph
69/// is DFS, we can revisit a function a second time with a higher threshold. In
70/// this case and if the function was not imported the first time, it is added
71/// back to the worklist with the new threshold
72using VisitedFunctionTrackerTy = StringMap<std::pair<unsigned, bool>>;
73
Mehdi Amini7e88d0d2015-12-09 08:17:35 +000074/// Helper to load on demand a Module from file and cache it for subsequent
75/// queries. It can be used with the FunctionImporter.
76class ModuleLazyLoaderCache {
77 /// Cache of lazily loaded module for import.
78 StringMap<std::unique_ptr<Module>> ModuleMap;
79
80 /// Retrieve a Module from the cache or lazily load it on demand.
81 std::function<std::unique_ptr<Module>(StringRef FileName)> createLazyModule;
82
83public:
84 /// Create the loader, Module will be initialized in \p Context.
85 ModuleLazyLoaderCache(std::function<
86 std::unique_ptr<Module>(StringRef FileName)> createLazyModule)
87 : createLazyModule(createLazyModule) {}
88
89 /// Retrieve a Module from the cache or lazily load it on demand.
90 Module &operator()(StringRef FileName);
Rafael Espindola434e9562015-12-16 23:16:33 +000091
92 std::unique_ptr<Module> takeModule(StringRef FileName) {
93 auto I = ModuleMap.find(FileName);
94 assert(I != ModuleMap.end());
95 std::unique_ptr<Module> Ret = std::move(I->second);
96 ModuleMap.erase(I);
97 return Ret;
98 }
Mehdi Amini7e88d0d2015-12-09 08:17:35 +000099};
100
101// Get a Module for \p FileName from the cache, or load it lazily.
102Module &ModuleLazyLoaderCache::operator()(StringRef Identifier) {
103 auto &Module = ModuleMap[Identifier];
104 if (!Module)
105 Module = createLazyModule(Identifier);
106 return *Module;
107}
108} // anonymous namespace
109
Teresa Johnsond450da32015-11-24 21:15:19 +0000110/// Walk through the instructions in \p F looking for external
Mehdi Amini40641742016-02-10 23:31:45 +0000111/// calls not already in the \p VisitedFunctions map. If any are
Teresa Johnsond450da32015-11-24 21:15:19 +0000112/// found they are added to the \p Worklist for importing.
Mehdi Amini40641742016-02-10 23:31:45 +0000113static void findExternalCalls(
Teresa Johnsoncec0cae2016-03-14 21:18:10 +0000114 const Module &DestModule, Function &F, const FunctionInfoIndex &Index,
Mehdi Amini40641742016-02-10 23:31:45 +0000115 VisitedFunctionTrackerTy &VisitedFunctions, unsigned Threshold,
116 SmallVectorImpl<std::pair<StringRef, unsigned>> &Worklist) {
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000117 // We need to suffix internal function calls imported from other modules,
118 // prepare the suffix ahead of time.
Rafael Espindola9edc3b82015-12-09 20:41:10 +0000119 std::string Suffix;
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000120 if (F.getParent() != &DestModule)
121 Suffix =
122 (Twine(".llvm.") +
123 Twine(Index.getModuleId(F.getParent()->getModuleIdentifier()))).str();
124
Teresa Johnsond450da32015-11-24 21:15:19 +0000125 for (auto &BB : F) {
126 for (auto &I : BB) {
127 if (isa<CallInst>(I)) {
Teresa Johnsond450da32015-11-24 21:15:19 +0000128 auto CalledFunction = cast<CallInst>(I).getCalledFunction();
129 // Insert any new external calls that have not already been
130 // added to set/worklist.
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000131 if (!CalledFunction || !CalledFunction->hasName())
132 continue;
133 // Ignore intrinsics early
134 if (CalledFunction->isIntrinsic()) {
135 assert(CalledFunction->getIntrinsicID() != 0);
136 continue;
Teresa Johnsond450da32015-11-24 21:15:19 +0000137 }
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000138 auto ImportedName = CalledFunction->getName();
139 auto Renamed = (ImportedName + Suffix).str();
140 // Rename internal functions
141 if (CalledFunction->hasInternalLinkage()) {
142 ImportedName = Renamed;
143 }
Teresa Johnsoncec0cae2016-03-14 21:18:10 +0000144 // Compute the global identifier used in the function index.
Teresa Johnsone1164de2016-02-10 21:55:02 +0000145 auto CalledFunctionGlobalID = Function::getGlobalIdentifier(
146 CalledFunction->getName(), CalledFunction->getLinkage(),
147 CalledFunction->getParent()->getSourceFileName());
Mehdi Amini40641742016-02-10 23:31:45 +0000148
149 auto CalledFunctionInfo = std::make_pair(Threshold, false);
150 auto It = VisitedFunctions.insert(
151 std::make_pair(CalledFunctionGlobalID, CalledFunctionInfo));
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000152 if (!It.second) {
Mehdi Amini40641742016-02-10 23:31:45 +0000153 // This is a call to a function we already considered, if the function
154 // has been imported the first time, or if the current threshold is
155 // not higher, skip it.
156 auto &FunctionInfo = It.first->second;
157 if (FunctionInfo.second || FunctionInfo.first >= Threshold)
158 continue;
159 It.first->second = CalledFunctionInfo;
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000160 }
161 // Ignore functions already present in the destination module
162 auto *SrcGV = DestModule.getNamedValue(ImportedName);
163 if (SrcGV) {
Teresa Johnson388497e2016-01-12 17:48:44 +0000164 if (GlobalAlias *SGA = dyn_cast<GlobalAlias>(SrcGV))
165 SrcGV = SGA->getBaseObject();
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000166 assert(isa<Function>(SrcGV) && "Name collision during import");
167 if (!cast<Function>(SrcGV)->isDeclaration()) {
Teresa Johnson9f2ff9c2015-12-10 16:39:07 +0000168 DEBUG(dbgs() << DestModule.getModuleIdentifier() << ": Ignoring "
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000169 << ImportedName << " already in DestinationModule\n");
170 continue;
171 }
172 }
173
Mehdi Amini40641742016-02-10 23:31:45 +0000174 Worklist.push_back(std::make_pair(It.first->getKey(), Threshold));
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000175 DEBUG(dbgs() << DestModule.getModuleIdentifier()
Teresa Johnson9f2ff9c2015-12-10 16:39:07 +0000176 << ": Adding callee for : " << ImportedName << " : "
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000177 << F.getName() << "\n");
Teresa Johnsond450da32015-11-24 21:15:19 +0000178 }
179 }
180 }
181}
182
Mehdi Aminic8c55172015-12-03 02:37:33 +0000183// Helper function: given a worklist and an index, will process all the worklist
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000184// and decide what to import based on the summary information.
185//
186// Nothing is actually imported, functions are materialized in their source
187// module and analyzed there.
188//
189// \p ModuleToFunctionsToImportMap is filled with the set of Function to import
190// per Module.
Mehdi Amini40641742016-02-10 23:31:45 +0000191static void
192GetImportList(Module &DestModule,
193 SmallVectorImpl<std::pair<StringRef, unsigned>> &Worklist,
194 VisitedFunctionTrackerTy &VisitedFunctions,
Teresa Johnsoncec0cae2016-03-14 21:18:10 +0000195 std::map<StringRef, DenseSet<const GlobalValue *>> &
196 ModuleToFunctionsToImportMap,
197 const FunctionInfoIndex &Index,
Mehdi Amini40641742016-02-10 23:31:45 +0000198 ModuleLazyLoaderCache &ModuleLoaderCache) {
Mehdi Amini42418ab2015-11-24 06:07:49 +0000199 while (!Worklist.empty()) {
Mehdi Amini40641742016-02-10 23:31:45 +0000200 StringRef CalledFunctionName;
201 unsigned Threshold;
202 std::tie(CalledFunctionName, Threshold) = Worklist.pop_back_val();
Teresa Johnson9f2ff9c2015-12-10 16:39:07 +0000203 DEBUG(dbgs() << DestModule.getModuleIdentifier() << ": Process import for "
Mehdi Amini40641742016-02-10 23:31:45 +0000204 << CalledFunctionName << " with Threshold " << Threshold
205 << "\n");
Mehdi Amini42418ab2015-11-24 06:07:49 +0000206
207 // Try to get a summary for this function call.
Teresa Johnson76a1c1d2016-03-11 18:52:24 +0000208 auto InfoList = Index.findGlobalValueInfoList(CalledFunctionName);
Mehdi Amini42418ab2015-11-24 06:07:49 +0000209 if (InfoList == Index.end()) {
Teresa Johnson9f2ff9c2015-12-10 16:39:07 +0000210 DEBUG(dbgs() << DestModule.getModuleIdentifier() << ": No summary for "
Mehdi Amini5411d052015-12-08 23:04:19 +0000211 << CalledFunctionName << " Ignoring.\n");
Mehdi Amini42418ab2015-11-24 06:07:49 +0000212 continue;
213 }
214 assert(!InfoList->second.empty() && "No summary, error at import?");
215
216 // Comdat can have multiple entries, FIXME: what do we do with them?
217 auto &Info = InfoList->second[0];
218 assert(Info && "Nullptr in list, error importing summaries?\n");
219
Teresa Johnson76a1c1d2016-03-11 18:52:24 +0000220 auto *Summary = dyn_cast<FunctionSummary>(Info->summary());
Mehdi Amini42418ab2015-11-24 06:07:49 +0000221 if (!Summary) {
222 // FIXME: in case we are lazyloading summaries, we can do it now.
Mehdi Amini5411d052015-12-08 23:04:19 +0000223 DEBUG(dbgs() << DestModule.getModuleIdentifier()
Teresa Johnson9f2ff9c2015-12-10 16:39:07 +0000224 << ": Missing summary for " << CalledFunctionName
Teresa Johnson430110c2015-12-01 17:12:10 +0000225 << ", error at import?\n");
Mehdi Amini42418ab2015-11-24 06:07:49 +0000226 llvm_unreachable("Missing summary");
227 }
228
Mehdi Amini40641742016-02-10 23:31:45 +0000229 if (Summary->instCount() > Threshold) {
Teresa Johnson9f2ff9c2015-12-10 16:39:07 +0000230 DEBUG(dbgs() << DestModule.getModuleIdentifier() << ": Skip import of "
Mehdi Amini5411d052015-12-08 23:04:19 +0000231 << CalledFunctionName << " with " << Summary->instCount()
Mehdi Amini40641742016-02-10 23:31:45 +0000232 << " instructions (limit " << Threshold << ")\n");
Teresa Johnson39303612015-11-24 22:55:46 +0000233 continue;
234 }
235
Mehdi Amini40641742016-02-10 23:31:45 +0000236 // Mark the function as imported in the VisitedFunctions tracker
237 assert(VisitedFunctions.count(CalledFunctionName));
238 VisitedFunctions[CalledFunctionName].second = true;
239
Mehdi Amini42418ab2015-11-24 06:07:49 +0000240 // Get the module path from the summary.
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000241 auto ModuleIdentifier = Summary->modulePath();
Teresa Johnson9f2ff9c2015-12-10 16:39:07 +0000242 DEBUG(dbgs() << DestModule.getModuleIdentifier() << ": Importing "
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000243 << CalledFunctionName << " from " << ModuleIdentifier << "\n");
Mehdi Amini42418ab2015-11-24 06:07:49 +0000244
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000245 auto &SrcModule = ModuleLoaderCache(ModuleIdentifier);
Mehdi Amini42418ab2015-11-24 06:07:49 +0000246
247 // The function that we will import!
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000248 GlobalValue *SGV = SrcModule.getNamedValue(CalledFunctionName);
249
Teresa Johnson130de7a2015-11-24 19:55:04 +0000250 if (!SGV) {
Teresa Johnsone1164de2016-02-10 21:55:02 +0000251 // The function is referenced by a global identifier, which has the
252 // source file name prepended for functions that were originally local
253 // in the source module. Strip any prepended name to recover the original
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000254 // name in the source module.
Teresa Johnson41806852016-02-10 23:47:38 +0000255 std::pair<StringRef, StringRef> Split = CalledFunctionName.rsplit(':');
Teresa Johnsone1164de2016-02-10 21:55:02 +0000256 SGV = SrcModule.getNamedValue(Split.second);
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000257 assert(SGV && "Can't find function to import in source module");
Teresa Johnson130de7a2015-11-24 19:55:04 +0000258 }
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000259 if (!SGV) {
260 report_fatal_error(Twine("Can't load function '") + CalledFunctionName +
261 "' in Module '" + SrcModule.getModuleIdentifier() +
262 "', error in the summary?\n");
263 }
264
Mehdi Amini42418ab2015-11-24 06:07:49 +0000265 Function *F = dyn_cast<Function>(SGV);
266 if (!F && isa<GlobalAlias>(SGV)) {
267 auto *SGA = dyn_cast<GlobalAlias>(SGV);
268 F = dyn_cast<Function>(SGA->getBaseObject());
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000269 CalledFunctionName = F->getName();
Mehdi Amini42418ab2015-11-24 06:07:49 +0000270 }
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000271 assert(F && "Imported Function is ... not a Function");
Mehdi Amini42418ab2015-11-24 06:07:49 +0000272
Teresa Johnson17626652015-11-24 16:10:43 +0000273 // We cannot import weak_any functions/aliases without possibly affecting
274 // the order they are seen and selected by the linker, changing program
Mehdi Amini42418ab2015-11-24 06:07:49 +0000275 // semantics.
Teresa Johnson17626652015-11-24 16:10:43 +0000276 if (SGV->hasWeakAnyLinkage()) {
Mehdi Amini5411d052015-12-08 23:04:19 +0000277 DEBUG(dbgs() << DestModule.getModuleIdentifier()
Teresa Johnson9f2ff9c2015-12-10 16:39:07 +0000278 << ": Ignoring import request for weak-any "
Teresa Johnson17626652015-11-24 16:10:43 +0000279 << (isa<Function>(SGV) ? "function " : "alias ")
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000280 << CalledFunctionName << " from "
281 << SrcModule.getModuleIdentifier() << "\n");
Mehdi Amini42418ab2015-11-24 06:07:49 +0000282 continue;
283 }
284
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000285 // Add the function to the import list
286 auto &Entry = ModuleToFunctionsToImportMap[SrcModule.getModuleIdentifier()];
Rafael Espindola434e9562015-12-16 23:16:33 +0000287 Entry.insert(F);
Mehdi Amini42418ab2015-11-24 06:07:49 +0000288
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000289 // Process the newly imported functions and add callees to the worklist.
Mehdi Amini40641742016-02-10 23:31:45 +0000290 // Adjust the threshold
291 Threshold = Threshold * ImportInstrFactor;
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000292 F->materialize();
Mehdi Amini40641742016-02-10 23:31:45 +0000293 findExternalCalls(DestModule, *F, Index, VisitedFunctions, Threshold,
294 Worklist);
Mehdi Amini42418ab2015-11-24 06:07:49 +0000295 }
Mehdi Aminic8c55172015-12-03 02:37:33 +0000296}
Mehdi Aminiffe2e4a2015-12-02 04:34:28 +0000297
Mehdi Aminic8c55172015-12-03 02:37:33 +0000298// Automatically import functions in Module \p DestModule based on the summaries
299// index.
300//
301// The current implementation imports every called functions that exists in the
302// summaries index.
303bool FunctionImporter::importFunctions(Module &DestModule) {
Mehdi Amini5411d052015-12-08 23:04:19 +0000304 DEBUG(dbgs() << "Starting import for Module "
Mehdi Amini311fef62015-12-03 02:58:14 +0000305 << DestModule.getModuleIdentifier() << "\n");
Mehdi Aminic8c55172015-12-03 02:37:33 +0000306 unsigned ImportedCount = 0;
307
Mehdi Amini40641742016-02-10 23:31:45 +0000308 // First step is collecting the called external functions.
309 // We keep the function name as well as the import threshold for its callees.
310 VisitedFunctionTrackerTy VisitedFunctions;
311 SmallVector<std::pair<StringRef, unsigned>, 64> Worklist;
Mehdi Aminic8c55172015-12-03 02:37:33 +0000312 for (auto &F : DestModule) {
313 if (F.isDeclaration() || F.hasFnAttribute(Attribute::OptimizeNone))
314 continue;
Mehdi Amini40641742016-02-10 23:31:45 +0000315 findExternalCalls(DestModule, F, Index, VisitedFunctions, ImportInstrLimit,
316 Worklist);
Mehdi Aminic8c55172015-12-03 02:37:33 +0000317 }
318 if (Worklist.empty())
319 return false;
320
321 /// Second step: for every call to an external function, try to import it.
322
323 // Linker that will be used for importing function
Rafael Espindola9d2bfc42015-12-14 23:17:03 +0000324 Linker TheLinker(DestModule);
Mehdi Aminic8c55172015-12-03 02:37:33 +0000325
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000326 // Map of Module -> List of Function to import from the Module
Rafael Espindola434e9562015-12-16 23:16:33 +0000327 std::map<StringRef, DenseSet<const GlobalValue *>>
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000328 ModuleToFunctionsToImportMap;
Mehdi Aminic8c55172015-12-03 02:37:33 +0000329
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000330 // Analyze the summaries and get the list of functions to import by
331 // populating ModuleToFunctionsToImportMap
332 ModuleLazyLoaderCache ModuleLoaderCache(ModuleLoader);
Mehdi Amini40641742016-02-10 23:31:45 +0000333 GetImportList(DestModule, Worklist, VisitedFunctions,
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000334 ModuleToFunctionsToImportMap, Index, ModuleLoaderCache);
335 assert(Worklist.empty() && "Worklist hasn't been flushed in GetImportList");
336
337 // Do the actual import of functions now, one Module at a time
338 for (auto &FunctionsToImportPerModule : ModuleToFunctionsToImportMap) {
339 // Get the module for the import
Rafael Espindola434e9562015-12-16 23:16:33 +0000340 auto &FunctionsToImport = FunctionsToImportPerModule.second;
341 std::unique_ptr<Module> SrcModule =
342 ModuleLoaderCache.takeModule(FunctionsToImportPerModule.first);
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000343 assert(&DestModule.getContext() == &SrcModule->getContext() &&
344 "Context mismatch");
345
Teresa Johnson6cba37c2016-01-22 00:15:53 +0000346 // If modules were created with lazy metadata loading, materialize it
347 // now, before linking it (otherwise this will be a noop).
348 SrcModule->materializeMetadata();
349 UpgradeDebugInfo(*SrcModule);
Teresa Johnsone5a61912015-12-17 17:14:09 +0000350
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000351 // Link in the specified functions.
Rafael Espindola434e9562015-12-16 23:16:33 +0000352 if (TheLinker.linkInModule(std::move(SrcModule), Linker::Flags::None,
Teresa Johnson6cba37c2016-01-22 00:15:53 +0000353 &Index, &FunctionsToImport))
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000354 report_fatal_error("Function Import: link error");
355
356 ImportedCount += FunctionsToImport.size();
357 }
Teresa Johnsone5a61912015-12-17 17:14:09 +0000358
Mehdi Amini7e88d0d2015-12-09 08:17:35 +0000359 DEBUG(dbgs() << "Imported " << ImportedCount << " functions for Module "
Mehdi Aminic8c55172015-12-03 02:37:33 +0000360 << DestModule.getModuleIdentifier() << "\n");
361 return ImportedCount;
Mehdi Amini42418ab2015-11-24 06:07:49 +0000362}
363
364/// Summary file to use for function importing when using -function-import from
365/// the command line.
366static cl::opt<std::string>
367 SummaryFile("summary-file",
368 cl::desc("The summary file to use for function importing."));
369
370static void diagnosticHandler(const DiagnosticInfo &DI) {
371 raw_ostream &OS = errs();
372 DiagnosticPrinterRawOStream DP(OS);
373 DI.print(DP);
374 OS << '\n';
375}
376
Teresa Johnsoncec0cae2016-03-14 21:18:10 +0000377/// Parse the function index out of an IR file and return the function
Mehdi Amini42418ab2015-11-24 06:07:49 +0000378/// index object if found, or nullptr if not.
Teresa Johnsoncec0cae2016-03-14 21:18:10 +0000379static std::unique_ptr<FunctionInfoIndex>
380getFunctionIndexForFile(StringRef Path, std::string &Error,
381 DiagnosticHandlerFunction DiagnosticHandler) {
Mehdi Amini42418ab2015-11-24 06:07:49 +0000382 std::unique_ptr<MemoryBuffer> Buffer;
383 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
384 MemoryBuffer::getFile(Path);
385 if (std::error_code EC = BufferOrErr.getError()) {
386 Error = EC.message();
387 return nullptr;
388 }
389 Buffer = std::move(BufferOrErr.get());
Teresa Johnsoncec0cae2016-03-14 21:18:10 +0000390 ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr =
391 object::FunctionIndexObjectFile::create(Buffer->getMemBufferRef(),
392 DiagnosticHandler);
Mehdi Amini42418ab2015-11-24 06:07:49 +0000393 if (std::error_code EC = ObjOrErr.getError()) {
394 Error = EC.message();
395 return nullptr;
396 }
397 return (*ObjOrErr)->takeIndex();
398}
399
Benjamin Kramerfe2b5412015-12-24 10:03:35 +0000400namespace {
Mehdi Amini42418ab2015-11-24 06:07:49 +0000401/// Pass that performs cross-module function import provided a summary file.
402class FunctionImportPass : public ModulePass {
Teresa Johnsoncec0cae2016-03-14 21:18:10 +0000403 /// Optional function summary index to use for importing, otherwise
Teresa Johnson5fcbdb72015-12-07 19:21:11 +0000404 /// the summary-file option must be specified.
Teresa Johnsoncec0cae2016-03-14 21:18:10 +0000405 const FunctionInfoIndex *Index;
Mehdi Amini42418ab2015-11-24 06:07:49 +0000406
407public:
408 /// Pass identification, replacement for typeid
409 static char ID;
410
Teresa Johnson5fcbdb72015-12-07 19:21:11 +0000411 /// Specify pass name for debug output
412 const char *getPassName() const override {
413 return "Function Importing";
414 }
415
Teresa Johnsoncec0cae2016-03-14 21:18:10 +0000416 explicit FunctionImportPass(const FunctionInfoIndex *Index = nullptr)
Teresa Johnson5fcbdb72015-12-07 19:21:11 +0000417 : ModulePass(ID), Index(Index) {}
Mehdi Amini42418ab2015-11-24 06:07:49 +0000418
419 bool runOnModule(Module &M) override {
Teresa Johnson5fcbdb72015-12-07 19:21:11 +0000420 if (SummaryFile.empty() && !Index)
421 report_fatal_error("error: -function-import requires -summary-file or "
422 "file from frontend\n");
Teresa Johnsoncec0cae2016-03-14 21:18:10 +0000423 std::unique_ptr<FunctionInfoIndex> IndexPtr;
Teresa Johnson5fcbdb72015-12-07 19:21:11 +0000424 if (!SummaryFile.empty()) {
425 if (Index)
426 report_fatal_error("error: -summary-file and index from frontend\n");
427 std::string Error;
Teresa Johnsoncec0cae2016-03-14 21:18:10 +0000428 IndexPtr = getFunctionIndexForFile(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
Teresa Johnson1b00f2d2016-01-08 17:06:29 +0000437 // First we need to promote to global scope and rename any local values that
438 // are potentially exported to other modules.
Mehdi Aminibd04e8f2016-03-09 01:37:14 +0000439 if (renameModuleForThinLTO(M, *Index)) {
Teresa Johnson1b00f2d2016-01-08 17:06:29 +0000440 errs() << "Error renaming module\n";
441 return false;
442 }
443
Mehdi Amini42418ab2015-11-24 06:07:49 +0000444 // Perform the import now.
Mehdi Aminid16c8062015-12-08 22:39:40 +0000445 auto ModuleLoader = [&M](StringRef Identifier) {
446 return loadFile(Identifier, M.getContext());
447 };
Rafael Espindola9d2bfc42015-12-14 23:17:03 +0000448 FunctionImporter Importer(*Index, ModuleLoader);
Mehdi Amini42418ab2015-11-24 06:07:49 +0000449 return Importer.importFunctions(M);
Mehdi Amini42418ab2015-11-24 06:07:49 +0000450 }
451};
Benjamin Kramerfe2b5412015-12-24 10:03:35 +0000452} // anonymous namespace
Mehdi Amini42418ab2015-11-24 06:07:49 +0000453
454char FunctionImportPass::ID = 0;
455INITIALIZE_PASS_BEGIN(FunctionImportPass, "function-import",
456 "Summary Based Function Import", false, false)
457INITIALIZE_PASS_END(FunctionImportPass, "function-import",
458 "Summary Based Function Import", false, false)
459
460namespace llvm {
Teresa Johnsoncec0cae2016-03-14 21:18:10 +0000461Pass *createFunctionImportPass(const FunctionInfoIndex *Index = nullptr) {
Teresa Johnson5fcbdb72015-12-07 19:21:11 +0000462 return new FunctionImportPass(Index);
463}
Mehdi Amini42418ab2015-11-24 06:07:49 +0000464}