blob: bfb0980bc16505cec85bd1837bd68e9af35ee6c8 [file] [log] [blame]
Mehdi Amini7c4a1a82016-03-09 01:37:22 +00001//===-ThinLTOCodeGenerator.cpp - LLVM Link Time Optimizer -----------------===//
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 the Thin Link Time Optimization library. This library is
11// intended to be used by linker to optimize code at link time.
12//
13//===----------------------------------------------------------------------===//
14
Peter Collingbourne5c732202016-07-14 21:21:16 +000015#include "llvm/LTO/legacy/ThinLTOCodeGenerator.h"
Mehdi Amini7c4a1a82016-03-09 01:37:22 +000016
Mehdi Aminif95f77a2016-04-21 05:54:23 +000017#ifdef HAVE_LLVM_REVISION
18#include "LLVMLTORevision.h"
19#endif
Mehdi Amini059464f2016-04-24 03:18:01 +000020
Teresa Johnsoncec0cae2016-03-14 21:18:10 +000021#include "llvm/ADT/Statistic.h"
Teresa Johnson26ab5772016-03-15 00:04:37 +000022#include "llvm/ADT/StringExtras.h"
Teresa Johnson2d5487c2016-04-11 13:58:45 +000023#include "llvm/Analysis/ModuleSummaryAnalysis.h"
Mehdi Amini7c4a1a82016-03-09 01:37:22 +000024#include "llvm/Analysis/TargetLibraryInfo.h"
25#include "llvm/Analysis/TargetTransformInfo.h"
Teresa Johnsoncec0cae2016-03-14 21:18:10 +000026#include "llvm/Bitcode/BitcodeWriterPass.h"
Teresa Johnson26ab5772016-03-15 00:04:37 +000027#include "llvm/Bitcode/ReaderWriter.h"
Mehdi Amini7c4a1a82016-03-09 01:37:22 +000028#include "llvm/ExecutionEngine/ObjectMemoryBuffer.h"
Teresa Johnsoncec0cae2016-03-14 21:18:10 +000029#include "llvm/IR/DiagnosticPrinter.h"
Teresa Johnson26ab5772016-03-15 00:04:37 +000030#include "llvm/IR/LLVMContext.h"
Mehdi Amini7c4a1a82016-03-09 01:37:22 +000031#include "llvm/IR/LegacyPassManager.h"
32#include "llvm/IR/Mangler.h"
33#include "llvm/IRReader/IRReader.h"
Teresa Johnsondf6edc52016-05-23 22:54:06 +000034#include "llvm/LTO/LTO.h"
Mehdi Amini7c4a1a82016-03-09 01:37:22 +000035#include "llvm/Linker/Linker.h"
36#include "llvm/MC/SubtargetFeature.h"
Mehdi Amini059464f2016-04-24 03:18:01 +000037#include "llvm/Object/IRObjectFile.h"
Teresa Johnson26ab5772016-03-15 00:04:37 +000038#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
Mehdi Aminif95f77a2016-04-21 05:54:23 +000039#include "llvm/Support/CachePruning.h"
40#include "llvm/Support/Debug.h"
41#include "llvm/Support/Path.h"
42#include "llvm/Support/SHA1.h"
Mehdi Amini7c4a1a82016-03-09 01:37:22 +000043#include "llvm/Support/TargetRegistry.h"
44#include "llvm/Support/ThreadPool.h"
45#include "llvm/Target/TargetMachine.h"
46#include "llvm/Transforms/IPO.h"
47#include "llvm/Transforms/IPO/FunctionImport.h"
Mehdi Amini059464f2016-04-24 03:18:01 +000048#include "llvm/Transforms/IPO/Internalize.h"
Mehdi Amini7c4a1a82016-03-09 01:37:22 +000049#include "llvm/Transforms/IPO/PassManagerBuilder.h"
50#include "llvm/Transforms/ObjCARC.h"
51#include "llvm/Transforms/Utils/FunctionImportUtils.h"
52
Mehdi Amini819e9cd2016-05-16 19:33:07 +000053#include <numeric>
54
Mehdi Amini7c4a1a82016-03-09 01:37:22 +000055using namespace llvm;
56
Mehdi Amini1aafabf2016-04-16 07:02:16 +000057#define DEBUG_TYPE "thinlto"
58
Mehdi Amini09b4a8d2016-03-10 01:28:54 +000059namespace llvm {
60// Flags -discard-value-names, defined in LTOCodeGenerator.cpp
61extern cl::opt<bool> LTODiscardValueNames;
62}
63
Mehdi Amini7c4a1a82016-03-09 01:37:22 +000064namespace {
65
66static cl::opt<int> ThreadCount("threads",
67 cl::init(std::thread::hardware_concurrency()));
68
69static void diagnosticHandler(const DiagnosticInfo &DI) {
70 DiagnosticPrinterRawOStream DP(errs());
71 DI.print(DP);
72 errs() << '\n';
73}
74
Mehdi Amini7c4a1a82016-03-09 01:37:22 +000075// Simple helper to save temporary files for debug.
76static void saveTempBitcode(const Module &TheModule, StringRef TempDir,
77 unsigned count, StringRef Suffix) {
78 if (TempDir.empty())
79 return;
80 // User asked to save temps, let dump the bitcode file after import.
81 auto SaveTempPath = TempDir + llvm::utostr(count) + Suffix;
82 std::error_code EC;
83 raw_fd_ostream OS(SaveTempPath.str(), EC, sys::fs::F_None);
84 if (EC)
85 report_fatal_error(Twine("Failed to open ") + SaveTempPath +
86 " to save optimized bitcode\n");
Teresa Johnson3c35e092016-04-04 21:19:31 +000087 WriteBitcodeToFile(&TheModule, OS, /* ShouldPreserveUseListOrder */ true);
Mehdi Amini7c4a1a82016-03-09 01:37:22 +000088}
89
Teresa Johnson4d2613f2016-05-24 17:24:25 +000090static const GlobalValueSummary *
91getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList) {
92 // If there is any strong definition anywhere, get it.
93 auto StrongDefForLinker = llvm::find_if(
94 GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
95 auto Linkage = Summary->linkage();
96 return !GlobalValue::isAvailableExternallyLinkage(Linkage) &&
97 !GlobalValue::isWeakForLinker(Linkage);
98 });
99 if (StrongDefForLinker != GVSummaryList.end())
100 return StrongDefForLinker->get();
Mehdi Amini5a2e5d32016-04-01 21:53:50 +0000101 // Get the first *linker visible* definition for this global in the summary
102 // list.
103 auto FirstDefForLinker = llvm::find_if(
Teresa Johnson28e457b2016-04-24 14:57:11 +0000104 GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
105 auto Linkage = Summary->linkage();
Mehdi Amini5a2e5d32016-04-01 21:53:50 +0000106 return !GlobalValue::isAvailableExternallyLinkage(Linkage);
107 });
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000108 // Extern templates can be emitted as available_externally.
109 if (FirstDefForLinker == GVSummaryList.end())
110 return nullptr;
111 return FirstDefForLinker->get();
Hans Wennborgfa6e4142016-04-02 01:03:41 +0000112}
Mehdi Amini5a2e5d32016-04-01 21:53:50 +0000113
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000114// Populate map of GUID to the prevailing copy for any multiply defined
115// symbols. Currently assume first copy is prevailing, or any strong
116// definition. Can be refined with Linker information in the future.
117static void computePrevailingCopies(
118 const ModuleSummaryIndex &Index,
119 DenseMap<GlobalValue::GUID, const GlobalValueSummary *> &PrevailingCopy) {
Teresa Johnson28e457b2016-04-24 14:57:11 +0000120 auto HasMultipleCopies = [&](const GlobalValueSummaryList &GVSummaryList) {
121 return GVSummaryList.size() > 1;
122 };
Mehdi Amini5a2e5d32016-04-01 21:53:50 +0000123
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000124 for (auto &I : Index) {
125 if (HasMultipleCopies(I.second))
126 PrevailingCopy[I.first] = getFirstDefinitionForLinker(I.second);
Mehdi Amini5a2e5d32016-04-01 21:53:50 +0000127 }
Mehdi Amini5a2e5d32016-04-01 21:53:50 +0000128}
129
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000130static StringMap<MemoryBufferRef>
131generateModuleMap(const std::vector<MemoryBufferRef> &Modules) {
132 StringMap<MemoryBufferRef> ModuleMap;
133 for (auto &ModuleBuffer : Modules) {
134 assert(ModuleMap.find(ModuleBuffer.getBufferIdentifier()) ==
135 ModuleMap.end() &&
136 "Expect unique Buffer Identifier");
137 ModuleMap[ModuleBuffer.getBufferIdentifier()] = ModuleBuffer;
138 }
139 return ModuleMap;
140}
141
Teresa Johnson26ab5772016-03-15 00:04:37 +0000142static void promoteModule(Module &TheModule, const ModuleSummaryIndex &Index) {
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000143 if (renameModuleForThinLTO(TheModule, Index))
144 report_fatal_error("renameModuleForThinLTO failed");
145}
146
Mehdi Amini01e32132016-03-26 05:40:34 +0000147static void
148crossImportIntoModule(Module &TheModule, const ModuleSummaryIndex &Index,
149 StringMap<MemoryBufferRef> &ModuleMap,
150 const FunctionImporter::ImportMapTy &ImportList) {
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000151 ModuleLoader Loader(TheModule.getContext(), ModuleMap);
152 FunctionImporter Importer(Index, Loader);
Mehdi Amini01e32132016-03-26 05:40:34 +0000153 Importer.importFunctions(TheModule, ImportList);
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000154}
155
156static void optimizeModule(Module &TheModule, TargetMachine &TM) {
157 // Populate the PassManager
158 PassManagerBuilder PMB;
159 PMB.LibraryInfo = new TargetLibraryInfoImpl(TM.getTargetTriple());
160 PMB.Inliner = createFunctionInliningPass();
161 // FIXME: should get it from the bitcode?
162 PMB.OptLevel = 3;
163 PMB.LoopVectorize = true;
164 PMB.SLPVectorize = true;
165 PMB.VerifyInput = true;
166 PMB.VerifyOutput = false;
167
168 legacy::PassManager PM;
169
170 // Add the TTI (required to inform the vectorizer about register size for
171 // instance)
172 PM.add(createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis()));
173
174 // Add optimizations
175 PMB.populateThinLTOPassManager(PM);
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000176
177 PM.run(TheModule);
178}
179
Mehdi Amini059464f2016-04-24 03:18:01 +0000180// Convert the PreservedSymbols map from "Name" based to "GUID" based.
181static DenseSet<GlobalValue::GUID>
182computeGUIDPreservedSymbols(const StringSet<> &PreservedSymbols,
183 const Triple &TheTriple) {
184 DenseSet<GlobalValue::GUID> GUIDPreservedSymbols(PreservedSymbols.size());
185 for (auto &Entry : PreservedSymbols) {
186 StringRef Name = Entry.first();
187 if (TheTriple.isOSBinFormatMachO() && Name.size() > 0 && Name[0] == '_')
188 Name = Name.drop_front();
189 GUIDPreservedSymbols.insert(GlobalValue::getGUID(Name));
190 }
191 return GUIDPreservedSymbols;
192}
193
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000194std::unique_ptr<MemoryBuffer> codegenModule(Module &TheModule,
195 TargetMachine &TM) {
196 SmallVector<char, 128> OutputBuffer;
197
198 // CodeGen
199 {
200 raw_svector_ostream OS(OutputBuffer);
201 legacy::PassManager PM;
Mehdi Amini215d59e2016-04-01 08:22:59 +0000202
203 // If the bitcode files contain ARC code and were compiled with optimization,
204 // the ObjCARCContractPass must be run, so do it unconditionally here.
205 PM.add(createObjCARCContractPass());
206
207 // Setup the codegen now.
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000208 if (TM.addPassesToEmitFile(PM, OS, TargetMachine::CGFT_ObjectFile,
209 /* DisableVerify */ true))
210 report_fatal_error("Failed to setup codegen");
211
212 // Run codegen now. resulting binary is in OutputBuffer.
213 PM.run(TheModule);
214 }
215 return make_unique<ObjectMemoryBuffer>(std::move(OutputBuffer));
216}
217
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000218/// Manage caching for a single Module.
219class ModuleCacheEntry {
220 SmallString<128> EntryPath;
221
222public:
223 // Create a cache entry. This compute a unique hash for the Module considering
224 // the current list of export/import, and offer an interface to query to
225 // access the content in the cache.
226 ModuleCacheEntry(
227 StringRef CachePath, const ModuleSummaryIndex &Index, StringRef ModuleID,
228 const FunctionImporter::ImportMapTy &ImportList,
229 const FunctionImporter::ExportSetTy &ExportList,
230 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
Teresa Johnsonc851d212016-04-25 21:09:51 +0000231 const GVSummaryMapTy &DefinedFunctions,
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000232 const DenseSet<GlobalValue::GUID> &PreservedSymbols) {
233 if (CachePath.empty())
234 return;
235
236 // Compute the unique hash for this entry
237 // This is based on the current compiler version, the module itself, the
238 // export list, the hash for every single module in the import list, the
239 // list of ResolvedODR for the module, and the list of preserved symbols.
240
241 SHA1 Hasher;
242
243 // Start with the compiler revision
244 Hasher.update(LLVM_VERSION_STRING);
245#ifdef HAVE_LLVM_REVISION
246 Hasher.update(LLVM_REVISION);
247#endif
248
249 // Include the hash for the current module
250 auto ModHash = Index.getModuleHash(ModuleID);
251 Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash)));
252 for (auto F : ExportList)
253 // The export list can impact the internalization, be conservative here
254 Hasher.update(ArrayRef<uint8_t>((uint8_t *)&F, sizeof(F)));
255
256 // Include the hash for every module we import functions from
257 for (auto &Entry : ImportList) {
258 auto ModHash = Index.getModuleHash(Entry.first());
259 Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash)));
260 }
261
262 // Include the hash for the resolved ODR.
263 for (auto &Entry : ResolvedODR) {
Sjoerd Meijer41beee62016-04-27 18:35:02 +0000264 Hasher.update(ArrayRef<uint8_t>((const uint8_t *)&Entry.first,
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000265 sizeof(GlobalValue::GUID)));
Sjoerd Meijer41beee62016-04-27 18:35:02 +0000266 Hasher.update(ArrayRef<uint8_t>((const uint8_t *)&Entry.second,
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000267 sizeof(GlobalValue::LinkageTypes)));
268 }
269
270 // Include the hash for the preserved symbols.
271 for (auto &Entry : PreservedSymbols) {
272 if (DefinedFunctions.count(Entry))
273 Hasher.update(
Sjoerd Meijer41beee62016-04-27 18:35:02 +0000274 ArrayRef<uint8_t>((const uint8_t *)&Entry, sizeof(GlobalValue::GUID)));
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000275 }
276
277 sys::path::append(EntryPath, CachePath, toHex(Hasher.result()));
278 }
279
Mehdi Amini059464f2016-04-24 03:18:01 +0000280 // Access the path to this entry in the cache.
281 StringRef getEntryPath() { return EntryPath; }
282
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000283 // Try loading the buffer for this cache entry.
284 ErrorOr<std::unique_ptr<MemoryBuffer>> tryLoadingBuffer() {
285 if (EntryPath.empty())
286 return std::error_code();
287 return MemoryBuffer::getFile(EntryPath);
288 }
289
290 // Cache the Produced object file
Mehdi Amini001bb412016-05-16 19:11:59 +0000291 std::unique_ptr<MemoryBuffer>
292 write(std::unique_ptr<MemoryBuffer> OutputBuffer) {
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000293 if (EntryPath.empty())
Mehdi Amini001bb412016-05-16 19:11:59 +0000294 return OutputBuffer;
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000295
296 // Write to a temporary to avoid race condition
297 SmallString<128> TempFilename;
298 int TempFD;
299 std::error_code EC =
300 sys::fs::createTemporaryFile("Thin", "tmp.o", TempFD, TempFilename);
301 if (EC) {
302 errs() << "Error: " << EC.message() << "\n";
303 report_fatal_error("ThinLTO: Can't get a temporary file");
304 }
305 {
306 raw_fd_ostream OS(TempFD, /* ShouldClose */ true);
Mehdi Amini001bb412016-05-16 19:11:59 +0000307 OS << OutputBuffer->getBuffer();
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000308 }
309 // Rename to final destination (hopefully race condition won't matter here)
Mehdi Amini2a16a5f2016-05-14 04:58:38 +0000310 EC = sys::fs::rename(TempFilename, EntryPath);
311 if (EC) {
Mehdi Aminib02139d2016-05-14 05:16:35 +0000312 sys::fs::remove(TempFilename);
313 raw_fd_ostream OS(EntryPath, EC, sys::fs::F_None);
314 if (EC)
315 report_fatal_error(Twine("Failed to open ") + EntryPath +
316 " to save cached entry\n");
Mehdi Amini001bb412016-05-16 19:11:59 +0000317 OS << OutputBuffer->getBuffer();
Mehdi Amini2a16a5f2016-05-14 04:58:38 +0000318 }
Mehdi Amini001bb412016-05-16 19:11:59 +0000319 auto ReloadedBufferOrErr = MemoryBuffer::getFile(EntryPath);
320 if (auto EC = ReloadedBufferOrErr.getError()) {
321 // FIXME diagnose
322 errs() << "error: can't reload cached file '" << EntryPath
323 << "': " << EC.message() << "\n";
324 return OutputBuffer;
325 }
326 return std::move(*ReloadedBufferOrErr);
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000327 }
328};
329
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000330static std::unique_ptr<MemoryBuffer>
331ProcessThinLTOModule(Module &TheModule, ModuleSummaryIndex &Index,
332 StringMap<MemoryBufferRef> &ModuleMap, TargetMachine &TM,
333 const FunctionImporter::ImportMapTy &ImportList,
334 const FunctionImporter::ExportSetTy &ExportList,
335 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
336 const GVSummaryMapTy &DefinedGlobals,
Benjamin Kramerc321e532016-06-08 19:09:22 +0000337 const ThinLTOCodeGenerator::CachingOptions &CacheOptions,
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000338 bool DisableCodeGen, StringRef SaveTempsDir,
339 unsigned count) {
Mehdi Amini059464f2016-04-24 03:18:01 +0000340
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000341 // "Benchmark"-like optimization: single-source case
342 bool SingleModule = (ModuleMap.size() == 1);
343
344 if (!SingleModule) {
345 promoteModule(TheModule, Index);
346
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000347 // Apply summary-based LinkOnce/Weak resolution decisions.
348 thinLTOResolveWeakForLinkerModule(TheModule, DefinedGlobals);
Mehdi Amini5a2e5d32016-04-01 21:53:50 +0000349
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000350 // Save temps: after promotion.
Mehdi Amini4b300e0a2016-05-05 05:14:16 +0000351 saveTempBitcode(TheModule, SaveTempsDir, count, ".1.promoted.bc");
Mehdi Amini059464f2016-04-24 03:18:01 +0000352 }
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000353
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000354 // Be friendly and don't nuke totally the module when the client didn't
355 // supply anything to preserve.
356 if (!ExportList.empty() || !GUIDPreservedSymbols.empty()) {
357 // Apply summary-based internalization decisions.
358 thinLTOInternalizeModule(TheModule, DefinedGlobals);
359 }
Mehdi Amini059464f2016-04-24 03:18:01 +0000360
361 // Save internalized bitcode
Mehdi Amini4b300e0a2016-05-05 05:14:16 +0000362 saveTempBitcode(TheModule, SaveTempsDir, count, ".2.internalized.bc");
Mehdi Amini059464f2016-04-24 03:18:01 +0000363
364 if (!SingleModule) {
Mehdi Amini01e32132016-03-26 05:40:34 +0000365 crossImportIntoModule(TheModule, Index, ModuleMap, ImportList);
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000366
367 // Save temps: after cross-module import.
Mehdi Amini4b300e0a2016-05-05 05:14:16 +0000368 saveTempBitcode(TheModule, SaveTempsDir, count, ".3.imported.bc");
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000369 }
370
371 optimizeModule(TheModule, TM);
372
Mehdi Amini4b300e0a2016-05-05 05:14:16 +0000373 saveTempBitcode(TheModule, SaveTempsDir, count, ".4.opt.bc");
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000374
Mehdi Amini43b657b2016-04-01 06:47:02 +0000375 if (DisableCodeGen) {
376 // Configured to stop before CodeGen, serialize the bitcode and return.
377 SmallVector<char, 128> OutputBuffer;
378 {
379 raw_svector_ostream OS(OutputBuffer);
Teresa Johnson2d5487c2016-04-11 13:58:45 +0000380 ModuleSummaryIndexBuilder IndexBuilder(&TheModule);
381 WriteBitcodeToFile(&TheModule, OS, true, &IndexBuilder.getIndex());
Mehdi Amini43b657b2016-04-01 06:47:02 +0000382 }
383 return make_unique<ObjectMemoryBuffer>(std::move(OutputBuffer));
384 }
385
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000386 return codegenModule(TheModule, TM);
387}
388
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000389/// Resolve LinkOnce/Weak symbols. Record resolutions in the \p ResolvedODR map
390/// for caching, and in the \p Index for application during the ThinLTO
391/// backends. This is needed for correctness for exported symbols (ensure
392/// at least one copy kept) and a compile-time optimization (to drop duplicate
393/// copies when possible).
394static void resolveWeakForLinkerInIndex(
395 ModuleSummaryIndex &Index,
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000396 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>>
397 &ResolvedODR) {
398
399 DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy;
400 computePrevailingCopies(Index, PrevailingCopy);
401
402 auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {
403 const auto &Prevailing = PrevailingCopy.find(GUID);
404 // Not in map means that there was only one copy, which must be prevailing.
405 if (Prevailing == PrevailingCopy.end())
406 return true;
407 return Prevailing->second == S;
408 };
409
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000410 auto recordNewLinkage = [&](StringRef ModuleIdentifier,
411 GlobalValue::GUID GUID,
412 GlobalValue::LinkageTypes NewLinkage) {
413 ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
414 };
415
Peter Collingbourne73589f32016-07-07 18:31:51 +0000416 thinLTOResolveWeakForLinkerInIndex(Index, isPrevailing, recordNewLinkage);
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000417}
418
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000419// Initialize the TargetMachine builder for a given Triple
420static void initTMBuilder(TargetMachineBuilder &TMBuilder,
421 const Triple &TheTriple) {
422 // Set a default CPU for Darwin triples (copied from LTOCodeGenerator).
423 // FIXME this looks pretty terrible...
424 if (TMBuilder.MCpu.empty() && TheTriple.isOSDarwin()) {
425 if (TheTriple.getArch() == llvm::Triple::x86_64)
426 TMBuilder.MCpu = "core2";
427 else if (TheTriple.getArch() == llvm::Triple::x86)
428 TMBuilder.MCpu = "yonah";
429 else if (TheTriple.getArch() == llvm::Triple::aarch64)
430 TMBuilder.MCpu = "cyclone";
431 }
432 TMBuilder.TheTriple = std::move(TheTriple);
433}
434
435} // end anonymous namespace
436
437void ThinLTOCodeGenerator::addModule(StringRef Identifier, StringRef Data) {
438 MemoryBufferRef Buffer(Data, Identifier);
439 if (Modules.empty()) {
440 // First module added, so initialize the triple and some options
441 LLVMContext Context;
442 Triple TheTriple(getBitcodeTargetTriple(Buffer, Context));
443 initTMBuilder(TMBuilder, Triple(TheTriple));
444 }
445#ifndef NDEBUG
446 else {
447 LLVMContext Context;
448 assert(TMBuilder.TheTriple.str() ==
449 getBitcodeTargetTriple(Buffer, Context) &&
450 "ThinLTO modules with different triple not supported");
451 }
452#endif
453 Modules.push_back(Buffer);
454}
455
456void ThinLTOCodeGenerator::preserveSymbol(StringRef Name) {
457 PreservedSymbols.insert(Name);
458}
459
460void ThinLTOCodeGenerator::crossReferenceSymbol(StringRef Name) {
Mehdi Amini059464f2016-04-24 03:18:01 +0000461 // FIXME: At the moment, we don't take advantage of this extra information,
462 // we're conservatively considering cross-references as preserved.
463 // CrossReferencedSymbols.insert(Name);
464 PreservedSymbols.insert(Name);
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000465}
466
467// TargetMachine factory
468std::unique_ptr<TargetMachine> TargetMachineBuilder::create() const {
469 std::string ErrMsg;
470 const Target *TheTarget =
471 TargetRegistry::lookupTarget(TheTriple.str(), ErrMsg);
472 if (!TheTarget) {
473 report_fatal_error("Can't load target for this Triple: " + ErrMsg);
474 }
475
476 // Use MAttr as the default set of features.
477 SubtargetFeatures Features(MAttr);
478 Features.getDefaultSubtargetFeatures(TheTriple);
479 std::string FeatureStr = Features.getString();
480 return std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
481 TheTriple.str(), MCpu, FeatureStr, Options, RelocModel,
482 CodeModel::Default, CGOptLevel));
483}
484
485/**
Teresa Johnson26ab5772016-03-15 00:04:37 +0000486 * Produce the combined summary index from all the bitcode files:
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000487 * "thin-link".
488 */
Teresa Johnson26ab5772016-03-15 00:04:37 +0000489std::unique_ptr<ModuleSummaryIndex> ThinLTOCodeGenerator::linkCombinedIndex() {
490 std::unique_ptr<ModuleSummaryIndex> CombinedIndex;
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000491 uint64_t NextModuleId = 0;
492 for (auto &ModuleBuffer : Modules) {
Teresa Johnson26ab5772016-03-15 00:04:37 +0000493 ErrorOr<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> ObjOrErr =
494 object::ModuleSummaryIndexObjectFile::create(ModuleBuffer,
Teresa Johnson6fb3f192016-04-22 01:52:00 +0000495 diagnosticHandler);
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000496 if (std::error_code EC = ObjOrErr.getError()) {
497 // FIXME diagnose
Teresa Johnson26ab5772016-03-15 00:04:37 +0000498 errs() << "error: can't create ModuleSummaryIndexObjectFile for buffer: "
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000499 << EC.message() << "\n";
500 return nullptr;
501 }
502 auto Index = (*ObjOrErr)->takeIndex();
503 if (CombinedIndex) {
504 CombinedIndex->mergeFrom(std::move(Index), ++NextModuleId);
505 } else {
506 CombinedIndex = std::move(Index);
507 }
508 }
509 return CombinedIndex;
510}
511
512/**
513 * Perform promotion and renaming of exported internal functions.
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000514 * Index is updated to reflect linkage changes from weak resolution.
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000515 */
516void ThinLTOCodeGenerator::promote(Module &TheModule,
Teresa Johnson26ab5772016-03-15 00:04:37 +0000517 ModuleSummaryIndex &Index) {
Mehdi Aminia71a5a62016-04-21 05:47:17 +0000518 auto ModuleCount = Index.modulePaths().size();
Mehdi Amini1aafabf2016-04-16 07:02:16 +0000519 auto ModuleIdentifier = TheModule.getModuleIdentifier();
520 // Collect for each module the list of function it defines (GUID -> Summary).
Teresa Johnsonc851d212016-04-25 21:09:51 +0000521 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries;
Mehdi Amini1aafabf2016-04-16 07:02:16 +0000522 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
Mehdi Amini5a2e5d32016-04-01 21:53:50 +0000523
Mehdi Aminia71a5a62016-04-21 05:47:17 +0000524 // Generate import/export list
525 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
526 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
527 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
528 ExportLists);
Mehdi Aminia71a5a62016-04-21 05:47:17 +0000529
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000530 // Resolve LinkOnce/Weak symbols.
531 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
Peter Collingbourne73589f32016-07-07 18:31:51 +0000532 resolveWeakForLinkerInIndex(Index, ResolvedODR);
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000533
534 thinLTOResolveWeakForLinkerModule(
535 TheModule, ModuleToDefinedGVSummaries[ModuleIdentifier]);
Mehdi Amini5a2e5d32016-04-01 21:53:50 +0000536
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000537 promoteModule(TheModule, Index);
538}
539
540/**
541 * Perform cross-module importing for the module identified by ModuleIdentifier.
542 */
543void ThinLTOCodeGenerator::crossModuleImport(Module &TheModule,
Teresa Johnson26ab5772016-03-15 00:04:37 +0000544 ModuleSummaryIndex &Index) {
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000545 auto ModuleMap = generateModuleMap(Modules);
Mehdi Amini1aafabf2016-04-16 07:02:16 +0000546 auto ModuleCount = Index.modulePaths().size();
547
548 // Collect for each module the list of function it defines (GUID -> Summary).
Teresa Johnsonc851d212016-04-25 21:09:51 +0000549 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
Mehdi Amini1aafabf2016-04-16 07:02:16 +0000550 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
Mehdi Amini01e32132016-03-26 05:40:34 +0000551
552 // Generate import/export list
Mehdi Amini01e32132016-03-26 05:40:34 +0000553 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
554 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
Mehdi Amini1aafabf2016-04-16 07:02:16 +0000555 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
556 ExportLists);
Mehdi Amini01e32132016-03-26 05:40:34 +0000557 auto &ImportList = ImportLists[TheModule.getModuleIdentifier()];
558
559 crossImportIntoModule(TheModule, Index, ModuleMap, ImportList);
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000560}
561
562/**
Teresa Johnson84174c32016-05-10 13:48:23 +0000563 * Compute the list of summaries needed for importing into module.
564 */
565void ThinLTOCodeGenerator::gatherImportedSummariesForModule(
566 StringRef ModulePath, ModuleSummaryIndex &Index,
567 std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
568 auto ModuleCount = Index.modulePaths().size();
569
570 // Collect for each module the list of function it defines (GUID -> Summary).
571 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
572 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
573
574 // Generate import/export list
575 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
576 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
577 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
578 ExportLists);
579
580 llvm::gatherImportedSummariesForModule(ModulePath, ModuleToDefinedGVSummaries,
581 ImportLists,
582 ModuleToSummariesForIndex);
583}
584
585/**
Teresa Johnson8570fe42016-05-10 15:54:09 +0000586 * Emit the list of files needed for importing into module.
587 */
588void ThinLTOCodeGenerator::emitImports(StringRef ModulePath,
589 StringRef OutputName,
590 ModuleSummaryIndex &Index) {
591 auto ModuleCount = Index.modulePaths().size();
592
593 // Collect for each module the list of function it defines (GUID -> Summary).
594 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
595 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
596
597 // Generate import/export list
598 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
599 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
600 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
601 ExportLists);
602
603 std::error_code EC;
604 if ((EC = EmitImportsFiles(ModulePath, OutputName, ImportLists)))
605 report_fatal_error(Twine("Failed to open ") + OutputName +
606 " to save imports lists\n");
607}
608
609/**
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000610 * Perform internalization. Index is updated to reflect linkage changes.
Mehdi Amini059464f2016-04-24 03:18:01 +0000611 */
612void ThinLTOCodeGenerator::internalize(Module &TheModule,
613 ModuleSummaryIndex &Index) {
614 initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple()));
615 auto ModuleCount = Index.modulePaths().size();
616 auto ModuleIdentifier = TheModule.getModuleIdentifier();
617
618 // Convert the preserved symbols set from string to GUID
619 auto GUIDPreservedSymbols =
620 computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple);
621
622 // Collect for each module the list of function it defines (GUID -> Summary).
Teresa Johnsonc851d212016-04-25 21:09:51 +0000623 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
Mehdi Amini059464f2016-04-24 03:18:01 +0000624 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
625
626 // Generate import/export list
627 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
628 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
629 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
630 ExportLists);
631 auto &ExportList = ExportLists[ModuleIdentifier];
632
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000633 // Be friendly and don't nuke totally the module when the client didn't
634 // supply anything to preserve.
635 if (ExportList.empty() && GUIDPreservedSymbols.empty())
636 return;
637
Mehdi Amini059464f2016-04-24 03:18:01 +0000638 // Internalization
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000639 auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
640 const auto &ExportList = ExportLists.find(ModuleIdentifier);
Teresa Johnson4ae5ce72016-05-24 19:12:48 +0000641 return (ExportList != ExportLists.end() &&
642 ExportList->second.count(GUID)) ||
643 GUIDPreservedSymbols.count(GUID);
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000644 };
645 thinLTOInternalizeAndPromoteInIndex(Index, isExported);
646 thinLTOInternalizeModule(TheModule,
647 ModuleToDefinedGVSummaries[ModuleIdentifier]);
Mehdi Amini059464f2016-04-24 03:18:01 +0000648}
649
650/**
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000651 * Perform post-importing ThinLTO optimizations.
652 */
653void ThinLTOCodeGenerator::optimize(Module &TheModule) {
654 initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple()));
Mehdi Amini059464f2016-04-24 03:18:01 +0000655
656 // Optimize now
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000657 optimizeModule(TheModule, *TMBuilder.create());
658}
659
660/**
661 * Perform ThinLTO CodeGen.
662 */
663std::unique_ptr<MemoryBuffer> ThinLTOCodeGenerator::codegen(Module &TheModule) {
664 initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple()));
665 return codegenModule(TheModule, *TMBuilder.create());
666}
667
668// Main entry point for the ThinLTO processing
669void ThinLTOCodeGenerator::run() {
Mehdi Amini43b657b2016-04-01 06:47:02 +0000670 if (CodeGenOnly) {
671 // Perform only parallel codegen and return.
672 ThreadPool Pool;
673 assert(ProducedBinaries.empty() && "The generator should not be reused");
674 ProducedBinaries.resize(Modules.size());
675 int count = 0;
676 for (auto &ModuleBuffer : Modules) {
677 Pool.async([&](int count) {
678 LLVMContext Context;
679 Context.setDiscardValueNames(LTODiscardValueNames);
680
681 // Parse module now
682 auto TheModule = loadModuleFromBuffer(ModuleBuffer, Context, false);
683
684 // CodeGen
685 ProducedBinaries[count] = codegen(*TheModule);
686 }, count++);
687 }
688
689 return;
690 }
691
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000692 // Sequential linking phase
693 auto Index = linkCombinedIndex();
694
695 // Save temps: index.
696 if (!SaveTempsDir.empty()) {
697 auto SaveTempPath = SaveTempsDir + "index.bc";
698 std::error_code EC;
699 raw_fd_ostream OS(SaveTempPath, EC, sys::fs::F_None);
700 if (EC)
701 report_fatal_error(Twine("Failed to open ") + SaveTempPath +
702 " to save optimized bitcode\n");
Teresa Johnson76a1c1d2016-03-11 18:52:24 +0000703 WriteIndexToFile(*Index, OS);
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000704 }
705
706 // Prepare the resulting object vector
707 assert(ProducedBinaries.empty() && "The generator should not be reused");
708 ProducedBinaries.resize(Modules.size());
709
710 // Prepare the module map.
711 auto ModuleMap = generateModuleMap(Modules);
Mehdi Amini01e32132016-03-26 05:40:34 +0000712 auto ModuleCount = Modules.size();
713
Mehdi Amini1aafabf2016-04-16 07:02:16 +0000714 // Collect for each module the list of function it defines (GUID -> Summary).
Teresa Johnsonc851d212016-04-25 21:09:51 +0000715 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
Mehdi Amini1aafabf2016-04-16 07:02:16 +0000716 Index->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
717
Mehdi Amini01e32132016-03-26 05:40:34 +0000718 // Collect the import/export lists for all modules from the call-graph in the
719 // combined index.
720 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
721 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
Mehdi Amini1aafabf2016-04-16 07:02:16 +0000722 ComputeCrossModuleImport(*Index, ModuleToDefinedGVSummaries, ImportLists,
723 ExportLists);
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000724
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000725 // Convert the preserved symbols set from string to GUID, this is needed for
Mehdi Amini059464f2016-04-24 03:18:01 +0000726 // computing the caching hash and the internalization.
727 auto GUIDPreservedSymbols =
728 computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple);
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000729
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000730 // We use a std::map here to be able to have a defined ordering when
731 // producing a hash for the cache entry.
732 // FIXME: we should be able to compute the caching hash for the entry based
733 // on the index, and nuke this map.
734 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
735
736 // Resolve LinkOnce/Weak symbols, this has to be computed early because it
737 // impacts the caching.
Peter Collingbourne73589f32016-07-07 18:31:51 +0000738 resolveWeakForLinkerInIndex(*Index, ResolvedODR);
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000739
740 auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
741 const auto &ExportList = ExportLists.find(ModuleIdentifier);
Teresa Johnson4ae5ce72016-05-24 19:12:48 +0000742 return (ExportList != ExportLists.end() &&
743 ExportList->second.count(GUID)) ||
744 GUIDPreservedSymbols.count(GUID);
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000745 };
746
747 // Use global summary-based analysis to identify symbols that can be
748 // internalized (because they aren't exported or preserved as per callback).
749 // Changes are made in the index, consumed in the ThinLTO backends.
750 thinLTOInternalizeAndPromoteInIndex(*Index, isExported);
751
Teresa Johnson141149f2016-05-24 18:44:01 +0000752 // Make sure that every module has an entry in the ExportLists and
753 // ResolvedODR maps to enable threaded access to these maps below.
754 for (auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) {
Mehdi Aminiaf52f282016-05-15 05:49:47 +0000755 ExportLists[DefinedGVSummaries.first()];
Teresa Johnson141149f2016-05-24 18:44:01 +0000756 ResolvedODR[DefinedGVSummaries.first()];
757 }
Mehdi Aminiaf52f282016-05-15 05:49:47 +0000758
Mehdi Amini819e9cd2016-05-16 19:33:07 +0000759 // Compute the ordering we will process the inputs: the rough heuristic here
760 // is to sort them per size so that the largest module get schedule as soon as
761 // possible. This is purely a compile-time optimization.
762 std::vector<int> ModulesOrdering;
763 ModulesOrdering.resize(Modules.size());
764 std::iota(ModulesOrdering.begin(), ModulesOrdering.end(), 0);
765 std::sort(ModulesOrdering.begin(), ModulesOrdering.end(),
766 [&](int LeftIndex, int RightIndex) {
767 auto LSize = Modules[LeftIndex].getBufferSize();
768 auto RSize = Modules[RightIndex].getBufferSize();
769 return LSize > RSize;
770 });
771
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000772 // Parallel optimizer + codegen
773 {
774 ThreadPool Pool(ThreadCount);
Mehdi Amini819e9cd2016-05-16 19:33:07 +0000775 for (auto IndexCount : ModulesOrdering) {
776 auto &ModuleBuffer = Modules[IndexCount];
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000777 Pool.async([&](int count) {
Mehdi Amini1aafabf2016-04-16 07:02:16 +0000778 auto ModuleIdentifier = ModuleBuffer.getBufferIdentifier();
Mehdi Aminia71a5a62016-04-21 05:47:17 +0000779 auto &ExportList = ExportLists[ModuleIdentifier];
Mehdi Amini1aafabf2016-04-16 07:02:16 +0000780
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000781 auto &DefinedFunctions = ModuleToDefinedGVSummaries[ModuleIdentifier];
782
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000783 // The module may be cached, this helps handling it.
Mehdi Amini059464f2016-04-24 03:18:01 +0000784 ModuleCacheEntry CacheEntry(CacheOptions.Path, *Index, ModuleIdentifier,
785 ImportLists[ModuleIdentifier], ExportList,
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000786 ResolvedODR[ModuleIdentifier],
787 DefinedFunctions, GUIDPreservedSymbols);
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000788
789 {
790 auto ErrOrBuffer = CacheEntry.tryLoadingBuffer();
Mehdi Amini059464f2016-04-24 03:18:01 +0000791 DEBUG(dbgs() << "Cache " << (ErrOrBuffer ? "hit" : "miss") << " '"
792 << CacheEntry.getEntryPath() << "' for buffer " << count
793 << " " << ModuleIdentifier << "\n");
794
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000795 if (ErrOrBuffer) {
796 // Cache Hit!
797 ProducedBinaries[count] = std::move(ErrOrBuffer.get());
798 return;
799 }
800 }
801
802 LLVMContext Context;
803 Context.setDiscardValueNames(LTODiscardValueNames);
804 Context.enableDebugTypeODRUniquing();
805
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000806 // Parse module now
807 auto TheModule = loadModuleFromBuffer(ModuleBuffer, Context, false);
808
809 // Save temps: original file.
Mehdi Amini059464f2016-04-24 03:18:01 +0000810 saveTempBitcode(*TheModule, SaveTempsDir, count, ".0.original.bc");
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000811
Mehdi Amini1aafabf2016-04-16 07:02:16 +0000812 auto &ImportList = ImportLists[ModuleIdentifier];
Mehdi Amini059464f2016-04-24 03:18:01 +0000813 // Run the main process now, and generates a binary
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000814 auto OutputBuffer = ProcessThinLTOModule(
Mehdi Amini01e32132016-03-26 05:40:34 +0000815 *TheModule, *Index, ModuleMap, *TMBuilder.create(), ImportList,
Teresa Johnson4d2613f2016-05-24 17:24:25 +0000816 ExportList, GUIDPreservedSymbols,
817 ModuleToDefinedGVSummaries[ModuleIdentifier], CacheOptions,
Mehdi Amini059464f2016-04-24 03:18:01 +0000818 DisableCodeGen, SaveTempsDir, count);
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000819
Mehdi Amini001bb412016-05-16 19:11:59 +0000820 OutputBuffer = CacheEntry.write(std::move(OutputBuffer));
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000821 ProducedBinaries[count] = std::move(OutputBuffer);
Mehdi Amini819e9cd2016-05-16 19:33:07 +0000822 }, IndexCount);
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000823 }
824 }
825
Mehdi Aminif95f77a2016-04-21 05:54:23 +0000826 CachePruning(CacheOptions.Path)
827 .setPruningInterval(CacheOptions.PruningInterval)
828 .setEntryExpiration(CacheOptions.Expiration)
829 .setMaxSize(CacheOptions.MaxPercentageOfAvailableSpace)
830 .prune();
831
Mehdi Amini7c4a1a82016-03-09 01:37:22 +0000832 // If statistics were requested, print them out now.
833 if (llvm::AreStatisticsEnabled())
834 llvm::PrintStatistics();
835}