1 //===-ThinLTOCodeGenerator.cpp - LLVM Link Time Optimizer -----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the Thin Link Time Optimization library. This library is
10 // intended to be used by linker to optimize code at link time.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/LTO/legacy/ThinLTOCodeGenerator.h"
15 #include "llvm/Support/CommandLine.h"
16
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/ADT/StringExtras.h"
19 #include "llvm/Analysis/ModuleSummaryAnalysis.h"
20 #include "llvm/Analysis/ProfileSummaryInfo.h"
21 #include "llvm/Analysis/TargetLibraryInfo.h"
22 #include "llvm/Analysis/TargetTransformInfo.h"
23 #include "llvm/Bitcode/BitcodeReader.h"
24 #include "llvm/Bitcode/BitcodeWriter.h"
25 #include "llvm/Bitcode/BitcodeWriterPass.h"
26 #include "llvm/Config/llvm-config.h"
27 #include "llvm/IR/DebugInfo.h"
28 #include "llvm/IR/DiagnosticPrinter.h"
29 #include "llvm/IR/LLVMContext.h"
30 #include "llvm/IR/LLVMRemarkStreamer.h"
31 #include "llvm/IR/LegacyPassManager.h"
32 #include "llvm/IR/Mangler.h"
33 #include "llvm/IR/PassTimingInfo.h"
34 #include "llvm/IR/Verifier.h"
35 #include "llvm/IRReader/IRReader.h"
36 #include "llvm/LTO/LTO.h"
37 #include "llvm/LTO/SummaryBasedOptimizations.h"
38 #include "llvm/MC/SubtargetFeature.h"
39 #include "llvm/Object/IRObjectFile.h"
40 #include "llvm/Remarks/HotnessThresholdParser.h"
41 #include "llvm/Support/CachePruning.h"
42 #include "llvm/Support/Debug.h"
43 #include "llvm/Support/Error.h"
44 #include "llvm/Support/FileUtilities.h"
45 #include "llvm/Support/Path.h"
46 #include "llvm/Support/SHA1.h"
47 #include "llvm/Support/SmallVectorMemoryBuffer.h"
48 #include "llvm/Support/TargetRegistry.h"
49 #include "llvm/Support/ThreadPool.h"
50 #include "llvm/Support/Threading.h"
51 #include "llvm/Support/ToolOutputFile.h"
52 #include "llvm/Target/TargetMachine.h"
53 #include "llvm/Transforms/IPO.h"
54 #include "llvm/Transforms/IPO/FunctionImport.h"
55 #include "llvm/Transforms/IPO/Internalize.h"
56 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
57 #include "llvm/Transforms/IPO/WholeProgramDevirt.h"
58 #include "llvm/Transforms/ObjCARC.h"
59 #include "llvm/Transforms/Utils/FunctionImportUtils.h"
60
61 #include <numeric>
62
63 #if !defined(_MSC_VER) && !defined(__MINGW32__)
64 #include <unistd.h>
65 #else
66 #include <io.h>
67 #endif
68
69 using namespace llvm;
70
71 #define DEBUG_TYPE "thinlto"
72
73 namespace llvm {
74 // Flags -discard-value-names, defined in LTOCodeGenerator.cpp
75 extern cl::opt<bool> LTODiscardValueNames;
76 extern cl::opt<std::string> RemarksFilename;
77 extern cl::opt<std::string> RemarksPasses;
78 extern cl::opt<bool> RemarksWithHotness;
79 extern cl::opt<Optional<uint64_t>, false, remarks::HotnessThresholdParser>
80 RemarksHotnessThreshold;
81 extern cl::opt<std::string> RemarksFormat;
82 }
83
84 namespace {
85
86 // Default to using all available threads in the system, but using only one
87 // thred per core, as indicated by the usage of
88 // heavyweight_hardware_concurrency() below.
89 static cl::opt<int> ThreadCount("threads", cl::init(0));
90
91 // Simple helper to save temporary files for debug.
saveTempBitcode(const Module & TheModule,StringRef TempDir,unsigned count,StringRef Suffix)92 static void saveTempBitcode(const Module &TheModule, StringRef TempDir,
93 unsigned count, StringRef Suffix) {
94 if (TempDir.empty())
95 return;
96 // User asked to save temps, let dump the bitcode file after import.
97 std::string SaveTempPath = (TempDir + llvm::Twine(count) + Suffix).str();
98 std::error_code EC;
99 raw_fd_ostream OS(SaveTempPath, EC, sys::fs::OF_None);
100 if (EC)
101 report_fatal_error(Twine("Failed to open ") + SaveTempPath +
102 " to save optimized bitcode\n");
103 WriteBitcodeToFile(TheModule, OS, /* ShouldPreserveUseListOrder */ true);
104 }
105
106 static const GlobalValueSummary *
getFirstDefinitionForLinker(const GlobalValueSummaryList & GVSummaryList)107 getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList) {
108 // If there is any strong definition anywhere, get it.
109 auto StrongDefForLinker = llvm::find_if(
110 GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
111 auto Linkage = Summary->linkage();
112 return !GlobalValue::isAvailableExternallyLinkage(Linkage) &&
113 !GlobalValue::isWeakForLinker(Linkage);
114 });
115 if (StrongDefForLinker != GVSummaryList.end())
116 return StrongDefForLinker->get();
117 // Get the first *linker visible* definition for this global in the summary
118 // list.
119 auto FirstDefForLinker = llvm::find_if(
120 GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
121 auto Linkage = Summary->linkage();
122 return !GlobalValue::isAvailableExternallyLinkage(Linkage);
123 });
124 // Extern templates can be emitted as available_externally.
125 if (FirstDefForLinker == GVSummaryList.end())
126 return nullptr;
127 return FirstDefForLinker->get();
128 }
129
130 // Populate map of GUID to the prevailing copy for any multiply defined
131 // symbols. Currently assume first copy is prevailing, or any strong
132 // definition. Can be refined with Linker information in the future.
computePrevailingCopies(const ModuleSummaryIndex & Index,DenseMap<GlobalValue::GUID,const GlobalValueSummary * > & PrevailingCopy)133 static void computePrevailingCopies(
134 const ModuleSummaryIndex &Index,
135 DenseMap<GlobalValue::GUID, const GlobalValueSummary *> &PrevailingCopy) {
136 auto HasMultipleCopies = [&](const GlobalValueSummaryList &GVSummaryList) {
137 return GVSummaryList.size() > 1;
138 };
139
140 for (auto &I : Index) {
141 if (HasMultipleCopies(I.second.SummaryList))
142 PrevailingCopy[I.first] =
143 getFirstDefinitionForLinker(I.second.SummaryList);
144 }
145 }
146
147 static StringMap<lto::InputFile *>
generateModuleMap(std::vector<std::unique_ptr<lto::InputFile>> & Modules)148 generateModuleMap(std::vector<std::unique_ptr<lto::InputFile>> &Modules) {
149 StringMap<lto::InputFile *> ModuleMap;
150 for (auto &M : Modules) {
151 assert(ModuleMap.find(M->getName()) == ModuleMap.end() &&
152 "Expect unique Buffer Identifier");
153 ModuleMap[M->getName()] = M.get();
154 }
155 return ModuleMap;
156 }
157
promoteModule(Module & TheModule,const ModuleSummaryIndex & Index,bool ClearDSOLocalOnDeclarations)158 static void promoteModule(Module &TheModule, const ModuleSummaryIndex &Index,
159 bool ClearDSOLocalOnDeclarations) {
160 if (renameModuleForThinLTO(TheModule, Index, ClearDSOLocalOnDeclarations))
161 report_fatal_error("renameModuleForThinLTO failed");
162 }
163
164 namespace {
165 class ThinLTODiagnosticInfo : public DiagnosticInfo {
166 const Twine &Msg;
167 public:
ThinLTODiagnosticInfo(const Twine & DiagMsg,DiagnosticSeverity Severity=DS_Error)168 ThinLTODiagnosticInfo(const Twine &DiagMsg,
169 DiagnosticSeverity Severity = DS_Error)
170 : DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {}
print(DiagnosticPrinter & DP) const171 void print(DiagnosticPrinter &DP) const override { DP << Msg; }
172 };
173 }
174
175 /// Verify the module and strip broken debug info.
verifyLoadedModule(Module & TheModule)176 static void verifyLoadedModule(Module &TheModule) {
177 bool BrokenDebugInfo = false;
178 if (verifyModule(TheModule, &dbgs(), &BrokenDebugInfo))
179 report_fatal_error("Broken module found, compilation aborted!");
180 if (BrokenDebugInfo) {
181 TheModule.getContext().diagnose(ThinLTODiagnosticInfo(
182 "Invalid debug info found, debug info will be stripped", DS_Warning));
183 StripDebugInfo(TheModule);
184 }
185 }
186
loadModuleFromInput(lto::InputFile * Input,LLVMContext & Context,bool Lazy,bool IsImporting)187 static std::unique_ptr<Module> loadModuleFromInput(lto::InputFile *Input,
188 LLVMContext &Context,
189 bool Lazy,
190 bool IsImporting) {
191 auto &Mod = Input->getSingleBitcodeModule();
192 SMDiagnostic Err;
193 Expected<std::unique_ptr<Module>> ModuleOrErr =
194 Lazy ? Mod.getLazyModule(Context,
195 /* ShouldLazyLoadMetadata */ true, IsImporting)
196 : Mod.parseModule(Context);
197 if (!ModuleOrErr) {
198 handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
199 SMDiagnostic Err = SMDiagnostic(Mod.getModuleIdentifier(),
200 SourceMgr::DK_Error, EIB.message());
201 Err.print("ThinLTO", errs());
202 });
203 report_fatal_error("Can't load module, abort.");
204 }
205 if (!Lazy)
206 verifyLoadedModule(*ModuleOrErr.get());
207 return std::move(*ModuleOrErr);
208 }
209
210 static void
crossImportIntoModule(Module & TheModule,const ModuleSummaryIndex & Index,StringMap<lto::InputFile * > & ModuleMap,const FunctionImporter::ImportMapTy & ImportList,bool ClearDSOLocalOnDeclarations)211 crossImportIntoModule(Module &TheModule, const ModuleSummaryIndex &Index,
212 StringMap<lto::InputFile *> &ModuleMap,
213 const FunctionImporter::ImportMapTy &ImportList,
214 bool ClearDSOLocalOnDeclarations) {
215 auto Loader = [&](StringRef Identifier) {
216 auto &Input = ModuleMap[Identifier];
217 return loadModuleFromInput(Input, TheModule.getContext(),
218 /*Lazy=*/true, /*IsImporting*/ true);
219 };
220
221 FunctionImporter Importer(Index, Loader, ClearDSOLocalOnDeclarations);
222 Expected<bool> Result = Importer.importFunctions(TheModule, ImportList);
223 if (!Result) {
224 handleAllErrors(Result.takeError(), [&](ErrorInfoBase &EIB) {
225 SMDiagnostic Err = SMDiagnostic(TheModule.getModuleIdentifier(),
226 SourceMgr::DK_Error, EIB.message());
227 Err.print("ThinLTO", errs());
228 });
229 report_fatal_error("importFunctions failed");
230 }
231 // Verify again after cross-importing.
232 verifyLoadedModule(TheModule);
233 }
234
optimizeModule(Module & TheModule,TargetMachine & TM,unsigned OptLevel,bool Freestanding,ModuleSummaryIndex * Index)235 static void optimizeModule(Module &TheModule, TargetMachine &TM,
236 unsigned OptLevel, bool Freestanding,
237 ModuleSummaryIndex *Index) {
238 // Populate the PassManager
239 PassManagerBuilder PMB;
240 PMB.LibraryInfo = new TargetLibraryInfoImpl(TM.getTargetTriple());
241 if (Freestanding)
242 PMB.LibraryInfo->disableAllFunctions();
243 PMB.Inliner = createFunctionInliningPass();
244 // FIXME: should get it from the bitcode?
245 PMB.OptLevel = OptLevel;
246 PMB.LoopVectorize = true;
247 PMB.SLPVectorize = true;
248 // Already did this in verifyLoadedModule().
249 PMB.VerifyInput = false;
250 PMB.VerifyOutput = false;
251 PMB.ImportSummary = Index;
252
253 legacy::PassManager PM;
254
255 // Add the TTI (required to inform the vectorizer about register size for
256 // instance)
257 PM.add(createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis()));
258
259 // Add optimizations
260 PMB.populateThinLTOPassManager(PM);
261
262 PM.run(TheModule);
263 }
264
265 static void
addUsedSymbolToPreservedGUID(const lto::InputFile & File,DenseSet<GlobalValue::GUID> & PreservedGUID)266 addUsedSymbolToPreservedGUID(const lto::InputFile &File,
267 DenseSet<GlobalValue::GUID> &PreservedGUID) {
268 for (const auto &Sym : File.symbols()) {
269 if (Sym.isUsed())
270 PreservedGUID.insert(GlobalValue::getGUID(Sym.getIRName()));
271 }
272 }
273
274 // Convert the PreservedSymbols map from "Name" based to "GUID" based.
computeGUIDPreservedSymbols(const lto::InputFile & File,const StringSet<> & PreservedSymbols,const Triple & TheTriple,DenseSet<GlobalValue::GUID> & GUIDs)275 static void computeGUIDPreservedSymbols(const lto::InputFile &File,
276 const StringSet<> &PreservedSymbols,
277 const Triple &TheTriple,
278 DenseSet<GlobalValue::GUID> &GUIDs) {
279 // Iterate the symbols in the input file and if the input has preserved symbol
280 // compute the GUID for the symbol.
281 for (const auto &Sym : File.symbols()) {
282 if (PreservedSymbols.count(Sym.getName()) && !Sym.getIRName().empty())
283 GUIDs.insert(GlobalValue::getGUID(GlobalValue::getGlobalIdentifier(
284 Sym.getIRName(), GlobalValue::ExternalLinkage, "")));
285 }
286 }
287
288 static DenseSet<GlobalValue::GUID>
computeGUIDPreservedSymbols(const lto::InputFile & File,const StringSet<> & PreservedSymbols,const Triple & TheTriple)289 computeGUIDPreservedSymbols(const lto::InputFile &File,
290 const StringSet<> &PreservedSymbols,
291 const Triple &TheTriple) {
292 DenseSet<GlobalValue::GUID> GUIDPreservedSymbols(PreservedSymbols.size());
293 computeGUIDPreservedSymbols(File, PreservedSymbols, TheTriple,
294 GUIDPreservedSymbols);
295 return GUIDPreservedSymbols;
296 }
297
codegenModule(Module & TheModule,TargetMachine & TM)298 std::unique_ptr<MemoryBuffer> codegenModule(Module &TheModule,
299 TargetMachine &TM) {
300 SmallVector<char, 128> OutputBuffer;
301
302 // CodeGen
303 {
304 raw_svector_ostream OS(OutputBuffer);
305 legacy::PassManager PM;
306
307 // If the bitcode files contain ARC code and were compiled with optimization,
308 // the ObjCARCContractPass must be run, so do it unconditionally here.
309 PM.add(createObjCARCContractPass());
310
311 // Setup the codegen now.
312 if (TM.addPassesToEmitFile(PM, OS, nullptr, CGFT_ObjectFile,
313 /* DisableVerify */ true))
314 report_fatal_error("Failed to setup codegen");
315
316 // Run codegen now. resulting binary is in OutputBuffer.
317 PM.run(TheModule);
318 }
319 return std::make_unique<SmallVectorMemoryBuffer>(std::move(OutputBuffer));
320 }
321
322 /// Manage caching for a single Module.
323 class ModuleCacheEntry {
324 SmallString<128> EntryPath;
325
326 public:
327 // Create a cache entry. This compute a unique hash for the Module considering
328 // the current list of export/import, and offer an interface to query to
329 // access the content in the cache.
ModuleCacheEntry(StringRef CachePath,const ModuleSummaryIndex & Index,StringRef ModuleID,const FunctionImporter::ImportMapTy & ImportList,const FunctionImporter::ExportSetTy & ExportList,const std::map<GlobalValue::GUID,GlobalValue::LinkageTypes> & ResolvedODR,const GVSummaryMapTy & DefinedGVSummaries,unsigned OptLevel,bool Freestanding,const TargetMachineBuilder & TMBuilder)330 ModuleCacheEntry(
331 StringRef CachePath, const ModuleSummaryIndex &Index, StringRef ModuleID,
332 const FunctionImporter::ImportMapTy &ImportList,
333 const FunctionImporter::ExportSetTy &ExportList,
334 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
335 const GVSummaryMapTy &DefinedGVSummaries, unsigned OptLevel,
336 bool Freestanding, const TargetMachineBuilder &TMBuilder) {
337 if (CachePath.empty())
338 return;
339
340 if (!Index.modulePaths().count(ModuleID))
341 // The module does not have an entry, it can't have a hash at all
342 return;
343
344 if (all_of(Index.getModuleHash(ModuleID),
345 [](uint32_t V) { return V == 0; }))
346 // No hash entry, no caching!
347 return;
348
349 llvm::lto::Config Conf;
350 Conf.OptLevel = OptLevel;
351 Conf.Options = TMBuilder.Options;
352 Conf.CPU = TMBuilder.MCpu;
353 Conf.MAttrs.push_back(TMBuilder.MAttr);
354 Conf.RelocModel = TMBuilder.RelocModel;
355 Conf.CGOptLevel = TMBuilder.CGOptLevel;
356 Conf.Freestanding = Freestanding;
357 SmallString<40> Key;
358 computeLTOCacheKey(Key, Conf, Index, ModuleID, ImportList, ExportList,
359 ResolvedODR, DefinedGVSummaries);
360
361 // This choice of file name allows the cache to be pruned (see pruneCache()
362 // in include/llvm/Support/CachePruning.h).
363 sys::path::append(EntryPath, CachePath, "llvmcache-" + Key);
364 }
365
366 // Access the path to this entry in the cache.
getEntryPath()367 StringRef getEntryPath() { return EntryPath; }
368
369 // Try loading the buffer for this cache entry.
tryLoadingBuffer()370 ErrorOr<std::unique_ptr<MemoryBuffer>> tryLoadingBuffer() {
371 if (EntryPath.empty())
372 return std::error_code();
373 SmallString<64> ResultPath;
374 Expected<sys::fs::file_t> FDOrErr = sys::fs::openNativeFileForRead(
375 Twine(EntryPath), sys::fs::OF_UpdateAtime, &ResultPath);
376 if (!FDOrErr)
377 return errorToErrorCode(FDOrErr.takeError());
378 ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getOpenFile(
379 *FDOrErr, EntryPath, /*FileSize=*/-1, /*RequiresNullTerminator=*/false);
380 sys::fs::closeFile(*FDOrErr);
381 return MBOrErr;
382 }
383
384 // Cache the Produced object file
write(const MemoryBuffer & OutputBuffer)385 void write(const MemoryBuffer &OutputBuffer) {
386 if (EntryPath.empty())
387 return;
388
389 // Write to a temporary to avoid race condition
390 SmallString<128> TempFilename;
391 SmallString<128> CachePath(EntryPath);
392 llvm::sys::path::remove_filename(CachePath);
393 sys::path::append(TempFilename, CachePath, "Thin-%%%%%%.tmp.o");
394
395 if (auto Err = handleErrors(
396 llvm::writeFileAtomically(TempFilename, EntryPath,
397 OutputBuffer.getBuffer()),
398 [](const llvm::AtomicFileWriteError &E) {
399 std::string ErrorMsgBuffer;
400 llvm::raw_string_ostream S(ErrorMsgBuffer);
401 E.log(S);
402
403 if (E.Error ==
404 llvm::atomic_write_error::failed_to_create_uniq_file) {
405 errs() << "Error: " << ErrorMsgBuffer << "\n";
406 report_fatal_error("ThinLTO: Can't get a temporary file");
407 }
408 })) {
409 // FIXME
410 consumeError(std::move(Err));
411 }
412 }
413 };
414
415 static std::unique_ptr<MemoryBuffer>
ProcessThinLTOModule(Module & TheModule,ModuleSummaryIndex & Index,StringMap<lto::InputFile * > & ModuleMap,TargetMachine & TM,const FunctionImporter::ImportMapTy & ImportList,const FunctionImporter::ExportSetTy & ExportList,const DenseSet<GlobalValue::GUID> & GUIDPreservedSymbols,const GVSummaryMapTy & DefinedGlobals,const ThinLTOCodeGenerator::CachingOptions & CacheOptions,bool DisableCodeGen,StringRef SaveTempsDir,bool Freestanding,unsigned OptLevel,unsigned count)416 ProcessThinLTOModule(Module &TheModule, ModuleSummaryIndex &Index,
417 StringMap<lto::InputFile *> &ModuleMap, TargetMachine &TM,
418 const FunctionImporter::ImportMapTy &ImportList,
419 const FunctionImporter::ExportSetTy &ExportList,
420 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
421 const GVSummaryMapTy &DefinedGlobals,
422 const ThinLTOCodeGenerator::CachingOptions &CacheOptions,
423 bool DisableCodeGen, StringRef SaveTempsDir,
424 bool Freestanding, unsigned OptLevel, unsigned count) {
425
426 // "Benchmark"-like optimization: single-source case
427 bool SingleModule = (ModuleMap.size() == 1);
428
429 // When linking an ELF shared object, dso_local should be dropped. We
430 // conservatively do this for -fpic.
431 bool ClearDSOLocalOnDeclarations =
432 TM.getTargetTriple().isOSBinFormatELF() &&
433 TM.getRelocationModel() != Reloc::Static &&
434 TheModule.getPIELevel() == PIELevel::Default;
435
436 if (!SingleModule) {
437 promoteModule(TheModule, Index, ClearDSOLocalOnDeclarations);
438
439 // Apply summary-based prevailing-symbol resolution decisions.
440 thinLTOResolvePrevailingInModule(TheModule, DefinedGlobals);
441
442 // Save temps: after promotion.
443 saveTempBitcode(TheModule, SaveTempsDir, count, ".1.promoted.bc");
444 }
445
446 // Be friendly and don't nuke totally the module when the client didn't
447 // supply anything to preserve.
448 if (!ExportList.empty() || !GUIDPreservedSymbols.empty()) {
449 // Apply summary-based internalization decisions.
450 thinLTOInternalizeModule(TheModule, DefinedGlobals);
451 }
452
453 // Save internalized bitcode
454 saveTempBitcode(TheModule, SaveTempsDir, count, ".2.internalized.bc");
455
456 if (!SingleModule) {
457 crossImportIntoModule(TheModule, Index, ModuleMap, ImportList,
458 ClearDSOLocalOnDeclarations);
459
460 // Save temps: after cross-module import.
461 saveTempBitcode(TheModule, SaveTempsDir, count, ".3.imported.bc");
462 }
463
464 optimizeModule(TheModule, TM, OptLevel, Freestanding, &Index);
465
466 saveTempBitcode(TheModule, SaveTempsDir, count, ".4.opt.bc");
467
468 if (DisableCodeGen) {
469 // Configured to stop before CodeGen, serialize the bitcode and return.
470 SmallVector<char, 128> OutputBuffer;
471 {
472 raw_svector_ostream OS(OutputBuffer);
473 ProfileSummaryInfo PSI(TheModule);
474 auto Index = buildModuleSummaryIndex(TheModule, nullptr, &PSI);
475 WriteBitcodeToFile(TheModule, OS, true, &Index);
476 }
477 return std::make_unique<SmallVectorMemoryBuffer>(std::move(OutputBuffer));
478 }
479
480 return codegenModule(TheModule, TM);
481 }
482
483 /// Resolve prevailing symbols. Record resolutions in the \p ResolvedODR map
484 /// for caching, and in the \p Index for application during the ThinLTO
485 /// backends. This is needed for correctness for exported symbols (ensure
486 /// at least one copy kept) and a compile-time optimization (to drop duplicate
487 /// copies when possible).
resolvePrevailingInIndex(ModuleSummaryIndex & Index,StringMap<std::map<GlobalValue::GUID,GlobalValue::LinkageTypes>> & ResolvedODR,const DenseSet<GlobalValue::GUID> & GUIDPreservedSymbols,const DenseMap<GlobalValue::GUID,const GlobalValueSummary * > & PrevailingCopy)488 static void resolvePrevailingInIndex(
489 ModuleSummaryIndex &Index,
490 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>>
491 &ResolvedODR,
492 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
493 const DenseMap<GlobalValue::GUID, const GlobalValueSummary *>
494 &PrevailingCopy) {
495
496 auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {
497 const auto &Prevailing = PrevailingCopy.find(GUID);
498 // Not in map means that there was only one copy, which must be prevailing.
499 if (Prevailing == PrevailingCopy.end())
500 return true;
501 return Prevailing->second == S;
502 };
503
504 auto recordNewLinkage = [&](StringRef ModuleIdentifier,
505 GlobalValue::GUID GUID,
506 GlobalValue::LinkageTypes NewLinkage) {
507 ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
508 };
509
510 thinLTOResolvePrevailingInIndex(Index, isPrevailing, recordNewLinkage,
511 GUIDPreservedSymbols);
512 }
513
514 // Initialize the TargetMachine builder for a given Triple
initTMBuilder(TargetMachineBuilder & TMBuilder,const Triple & TheTriple)515 static void initTMBuilder(TargetMachineBuilder &TMBuilder,
516 const Triple &TheTriple) {
517 // Set a default CPU for Darwin triples (copied from LTOCodeGenerator).
518 // FIXME this looks pretty terrible...
519 if (TMBuilder.MCpu.empty() && TheTriple.isOSDarwin()) {
520 if (TheTriple.getArch() == llvm::Triple::x86_64)
521 TMBuilder.MCpu = "core2";
522 else if (TheTriple.getArch() == llvm::Triple::x86)
523 TMBuilder.MCpu = "yonah";
524 else if (TheTriple.getArch() == llvm::Triple::aarch64 ||
525 TheTriple.getArch() == llvm::Triple::aarch64_32)
526 TMBuilder.MCpu = "cyclone";
527 }
528 TMBuilder.TheTriple = std::move(TheTriple);
529 }
530
531 } // end anonymous namespace
532
addModule(StringRef Identifier,StringRef Data)533 void ThinLTOCodeGenerator::addModule(StringRef Identifier, StringRef Data) {
534 MemoryBufferRef Buffer(Data, Identifier);
535
536 auto InputOrError = lto::InputFile::create(Buffer);
537 if (!InputOrError)
538 report_fatal_error("ThinLTO cannot create input file: " +
539 toString(InputOrError.takeError()));
540
541 auto TripleStr = (*InputOrError)->getTargetTriple();
542 Triple TheTriple(TripleStr);
543
544 if (Modules.empty())
545 initTMBuilder(TMBuilder, Triple(TheTriple));
546 else if (TMBuilder.TheTriple != TheTriple) {
547 if (!TMBuilder.TheTriple.isCompatibleWith(TheTriple))
548 report_fatal_error("ThinLTO modules with incompatible triples not "
549 "supported");
550 initTMBuilder(TMBuilder, Triple(TMBuilder.TheTriple.merge(TheTriple)));
551 }
552
553 Modules.emplace_back(std::move(*InputOrError));
554 }
555
preserveSymbol(StringRef Name)556 void ThinLTOCodeGenerator::preserveSymbol(StringRef Name) {
557 PreservedSymbols.insert(Name);
558 }
559
crossReferenceSymbol(StringRef Name)560 void ThinLTOCodeGenerator::crossReferenceSymbol(StringRef Name) {
561 // FIXME: At the moment, we don't take advantage of this extra information,
562 // we're conservatively considering cross-references as preserved.
563 // CrossReferencedSymbols.insert(Name);
564 PreservedSymbols.insert(Name);
565 }
566
567 // TargetMachine factory
create() const568 std::unique_ptr<TargetMachine> TargetMachineBuilder::create() const {
569 std::string ErrMsg;
570 const Target *TheTarget =
571 TargetRegistry::lookupTarget(TheTriple.str(), ErrMsg);
572 if (!TheTarget) {
573 report_fatal_error("Can't load target for this Triple: " + ErrMsg);
574 }
575
576 // Use MAttr as the default set of features.
577 SubtargetFeatures Features(MAttr);
578 Features.getDefaultSubtargetFeatures(TheTriple);
579 std::string FeatureStr = Features.getString();
580
581 std::unique_ptr<TargetMachine> TM(
582 TheTarget->createTargetMachine(TheTriple.str(), MCpu, FeatureStr, Options,
583 RelocModel, None, CGOptLevel));
584 assert(TM && "Cannot create target machine");
585
586 return TM;
587 }
588
589 /**
590 * Produce the combined summary index from all the bitcode files:
591 * "thin-link".
592 */
linkCombinedIndex()593 std::unique_ptr<ModuleSummaryIndex> ThinLTOCodeGenerator::linkCombinedIndex() {
594 std::unique_ptr<ModuleSummaryIndex> CombinedIndex =
595 std::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false);
596 uint64_t NextModuleId = 0;
597 for (auto &Mod : Modules) {
598 auto &M = Mod->getSingleBitcodeModule();
599 if (Error Err =
600 M.readSummary(*CombinedIndex, Mod->getName(), NextModuleId++)) {
601 // FIXME diagnose
602 logAllUnhandledErrors(
603 std::move(Err), errs(),
604 "error: can't create module summary index for buffer: ");
605 return nullptr;
606 }
607 }
608 return CombinedIndex;
609 }
610
611 namespace {
612 struct IsExported {
613 const StringMap<FunctionImporter::ExportSetTy> &ExportLists;
614 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols;
615
IsExported__anonf071cc090d11::IsExported616 IsExported(const StringMap<FunctionImporter::ExportSetTy> &ExportLists,
617 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols)
618 : ExportLists(ExportLists), GUIDPreservedSymbols(GUIDPreservedSymbols) {}
619
operator ()__anonf071cc090d11::IsExported620 bool operator()(StringRef ModuleIdentifier, ValueInfo VI) const {
621 const auto &ExportList = ExportLists.find(ModuleIdentifier);
622 return (ExportList != ExportLists.end() && ExportList->second.count(VI)) ||
623 GUIDPreservedSymbols.count(VI.getGUID());
624 }
625 };
626
627 struct IsPrevailing {
628 const DenseMap<GlobalValue::GUID, const GlobalValueSummary *> &PrevailingCopy;
IsPrevailing__anonf071cc090d11::IsPrevailing629 IsPrevailing(const DenseMap<GlobalValue::GUID, const GlobalValueSummary *>
630 &PrevailingCopy)
631 : PrevailingCopy(PrevailingCopy) {}
632
operator ()__anonf071cc090d11::IsPrevailing633 bool operator()(GlobalValue::GUID GUID, const GlobalValueSummary *S) const {
634 const auto &Prevailing = PrevailingCopy.find(GUID);
635 // Not in map means that there was only one copy, which must be prevailing.
636 if (Prevailing == PrevailingCopy.end())
637 return true;
638 return Prevailing->second == S;
639 };
640 };
641 } // namespace
642
computeDeadSymbolsInIndex(ModuleSummaryIndex & Index,const DenseSet<GlobalValue::GUID> & GUIDPreservedSymbols)643 static void computeDeadSymbolsInIndex(
644 ModuleSummaryIndex &Index,
645 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) {
646 // We have no symbols resolution available. And can't do any better now in the
647 // case where the prevailing symbol is in a native object. It can be refined
648 // with linker information in the future.
649 auto isPrevailing = [&](GlobalValue::GUID G) {
650 return PrevailingType::Unknown;
651 };
652 computeDeadSymbolsWithConstProp(Index, GUIDPreservedSymbols, isPrevailing,
653 /* ImportEnabled = */ true);
654 }
655
656 /**
657 * Perform promotion and renaming of exported internal functions.
658 * Index is updated to reflect linkage changes from weak resolution.
659 */
promote(Module & TheModule,ModuleSummaryIndex & Index,const lto::InputFile & File)660 void ThinLTOCodeGenerator::promote(Module &TheModule, ModuleSummaryIndex &Index,
661 const lto::InputFile &File) {
662 auto ModuleCount = Index.modulePaths().size();
663 auto ModuleIdentifier = TheModule.getModuleIdentifier();
664
665 // Collect for each module the list of function it defines (GUID -> Summary).
666 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries;
667 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
668
669 // Convert the preserved symbols set from string to GUID
670 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
671 File, PreservedSymbols, Triple(TheModule.getTargetTriple()));
672
673 // Add used symbol to the preserved symbols.
674 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
675
676 // Compute "dead" symbols, we don't want to import/export these!
677 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
678
679 // Generate import/export list
680 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
681 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
682 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
683 ExportLists);
684
685 DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy;
686 computePrevailingCopies(Index, PrevailingCopy);
687
688 // Resolve prevailing symbols
689 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
690 resolvePrevailingInIndex(Index, ResolvedODR, GUIDPreservedSymbols,
691 PrevailingCopy);
692
693 thinLTOResolvePrevailingInModule(
694 TheModule, ModuleToDefinedGVSummaries[ModuleIdentifier]);
695
696 // Promote the exported values in the index, so that they are promoted
697 // in the module.
698 thinLTOInternalizeAndPromoteInIndex(
699 Index, IsExported(ExportLists, GUIDPreservedSymbols),
700 IsPrevailing(PrevailingCopy));
701
702 // FIXME Set ClearDSOLocalOnDeclarations.
703 promoteModule(TheModule, Index, /*ClearDSOLocalOnDeclarations=*/false);
704 }
705
706 /**
707 * Perform cross-module importing for the module identified by ModuleIdentifier.
708 */
crossModuleImport(Module & TheModule,ModuleSummaryIndex & Index,const lto::InputFile & File)709 void ThinLTOCodeGenerator::crossModuleImport(Module &TheModule,
710 ModuleSummaryIndex &Index,
711 const lto::InputFile &File) {
712 auto ModuleMap = generateModuleMap(Modules);
713 auto ModuleCount = Index.modulePaths().size();
714
715 // Collect for each module the list of function it defines (GUID -> Summary).
716 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
717 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
718
719 // Convert the preserved symbols set from string to GUID
720 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
721 File, PreservedSymbols, Triple(TheModule.getTargetTriple()));
722
723 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
724
725 // Compute "dead" symbols, we don't want to import/export these!
726 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
727
728 // Generate import/export list
729 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
730 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
731 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
732 ExportLists);
733 auto &ImportList = ImportLists[TheModule.getModuleIdentifier()];
734
735 // FIXME Set ClearDSOLocalOnDeclarations.
736 crossImportIntoModule(TheModule, Index, ModuleMap, ImportList,
737 /*ClearDSOLocalOnDeclarations=*/false);
738 }
739
740 /**
741 * Compute the list of summaries needed for importing into module.
742 */
gatherImportedSummariesForModule(Module & TheModule,ModuleSummaryIndex & Index,std::map<std::string,GVSummaryMapTy> & ModuleToSummariesForIndex,const lto::InputFile & File)743 void ThinLTOCodeGenerator::gatherImportedSummariesForModule(
744 Module &TheModule, ModuleSummaryIndex &Index,
745 std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
746 const lto::InputFile &File) {
747 auto ModuleCount = Index.modulePaths().size();
748 auto ModuleIdentifier = TheModule.getModuleIdentifier();
749
750 // Collect for each module the list of function it defines (GUID -> Summary).
751 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
752 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
753
754 // Convert the preserved symbols set from string to GUID
755 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
756 File, PreservedSymbols, Triple(TheModule.getTargetTriple()));
757
758 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
759
760 // Compute "dead" symbols, we don't want to import/export these!
761 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
762
763 // Generate import/export list
764 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
765 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
766 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
767 ExportLists);
768
769 llvm::gatherImportedSummariesForModule(
770 ModuleIdentifier, ModuleToDefinedGVSummaries,
771 ImportLists[ModuleIdentifier], ModuleToSummariesForIndex);
772 }
773
774 /**
775 * Emit the list of files needed for importing into module.
776 */
emitImports(Module & TheModule,StringRef OutputName,ModuleSummaryIndex & Index,const lto::InputFile & File)777 void ThinLTOCodeGenerator::emitImports(Module &TheModule, StringRef OutputName,
778 ModuleSummaryIndex &Index,
779 const lto::InputFile &File) {
780 auto ModuleCount = Index.modulePaths().size();
781 auto ModuleIdentifier = TheModule.getModuleIdentifier();
782
783 // Collect for each module the list of function it defines (GUID -> Summary).
784 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
785 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
786
787 // Convert the preserved symbols set from string to GUID
788 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
789 File, PreservedSymbols, Triple(TheModule.getTargetTriple()));
790
791 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
792
793 // Compute "dead" symbols, we don't want to import/export these!
794 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
795
796 // Generate import/export list
797 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
798 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
799 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
800 ExportLists);
801
802 std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
803 llvm::gatherImportedSummariesForModule(
804 ModuleIdentifier, ModuleToDefinedGVSummaries,
805 ImportLists[ModuleIdentifier], ModuleToSummariesForIndex);
806
807 std::error_code EC;
808 if ((EC = EmitImportsFiles(ModuleIdentifier, OutputName,
809 ModuleToSummariesForIndex)))
810 report_fatal_error(Twine("Failed to open ") + OutputName +
811 " to save imports lists\n");
812 }
813
814 /**
815 * Perform internalization. Runs promote and internalization together.
816 * Index is updated to reflect linkage changes.
817 */
internalize(Module & TheModule,ModuleSummaryIndex & Index,const lto::InputFile & File)818 void ThinLTOCodeGenerator::internalize(Module &TheModule,
819 ModuleSummaryIndex &Index,
820 const lto::InputFile &File) {
821 initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple()));
822 auto ModuleCount = Index.modulePaths().size();
823 auto ModuleIdentifier = TheModule.getModuleIdentifier();
824
825 // Convert the preserved symbols set from string to GUID
826 auto GUIDPreservedSymbols =
827 computeGUIDPreservedSymbols(File, PreservedSymbols, TMBuilder.TheTriple);
828
829 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
830
831 // Collect for each module the list of function it defines (GUID -> Summary).
832 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
833 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
834
835 // Compute "dead" symbols, we don't want to import/export these!
836 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
837
838 // Generate import/export list
839 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
840 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
841 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
842 ExportLists);
843 auto &ExportList = ExportLists[ModuleIdentifier];
844
845 // Be friendly and don't nuke totally the module when the client didn't
846 // supply anything to preserve.
847 if (ExportList.empty() && GUIDPreservedSymbols.empty())
848 return;
849
850 DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy;
851 computePrevailingCopies(Index, PrevailingCopy);
852
853 // Resolve prevailing symbols
854 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
855 resolvePrevailingInIndex(Index, ResolvedODR, GUIDPreservedSymbols,
856 PrevailingCopy);
857
858 // Promote the exported values in the index, so that they are promoted
859 // in the module.
860 thinLTOInternalizeAndPromoteInIndex(
861 Index, IsExported(ExportLists, GUIDPreservedSymbols),
862 IsPrevailing(PrevailingCopy));
863
864 // FIXME Set ClearDSOLocalOnDeclarations.
865 promoteModule(TheModule, Index, /*ClearDSOLocalOnDeclarations=*/false);
866
867 // Internalization
868 thinLTOResolvePrevailingInModule(
869 TheModule, ModuleToDefinedGVSummaries[ModuleIdentifier]);
870
871 thinLTOInternalizeModule(TheModule,
872 ModuleToDefinedGVSummaries[ModuleIdentifier]);
873 }
874
875 /**
876 * Perform post-importing ThinLTO optimizations.
877 */
optimize(Module & TheModule)878 void ThinLTOCodeGenerator::optimize(Module &TheModule) {
879 initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple()));
880
881 // Optimize now
882 optimizeModule(TheModule, *TMBuilder.create(), OptLevel, Freestanding,
883 nullptr);
884 }
885
886 /// Write out the generated object file, either from CacheEntryPath or from
887 /// OutputBuffer, preferring hard-link when possible.
888 /// Returns the path to the generated file in SavedObjectsDirectoryPath.
889 std::string
writeGeneratedObject(int count,StringRef CacheEntryPath,const MemoryBuffer & OutputBuffer)890 ThinLTOCodeGenerator::writeGeneratedObject(int count, StringRef CacheEntryPath,
891 const MemoryBuffer &OutputBuffer) {
892 auto ArchName = TMBuilder.TheTriple.getArchName();
893 SmallString<128> OutputPath(SavedObjectsDirectoryPath);
894 llvm::sys::path::append(OutputPath,
895 Twine(count) + "." + ArchName + ".thinlto.o");
896 OutputPath.c_str(); // Ensure the string is null terminated.
897 if (sys::fs::exists(OutputPath))
898 sys::fs::remove(OutputPath);
899
900 // We don't return a memory buffer to the linker, just a list of files.
901 if (!CacheEntryPath.empty()) {
902 // Cache is enabled, hard-link the entry (or copy if hard-link fails).
903 auto Err = sys::fs::create_hard_link(CacheEntryPath, OutputPath);
904 if (!Err)
905 return std::string(OutputPath.str());
906 // Hard linking failed, try to copy.
907 Err = sys::fs::copy_file(CacheEntryPath, OutputPath);
908 if (!Err)
909 return std::string(OutputPath.str());
910 // Copy failed (could be because the CacheEntry was removed from the cache
911 // in the meantime by another process), fall back and try to write down the
912 // buffer to the output.
913 errs() << "remark: can't link or copy from cached entry '" << CacheEntryPath
914 << "' to '" << OutputPath << "'\n";
915 }
916 // No cache entry, just write out the buffer.
917 std::error_code Err;
918 raw_fd_ostream OS(OutputPath, Err, sys::fs::OF_None);
919 if (Err)
920 report_fatal_error("Can't open output '" + OutputPath + "'\n");
921 OS << OutputBuffer.getBuffer();
922 return std::string(OutputPath.str());
923 }
924
925 // Main entry point for the ThinLTO processing
run()926 void ThinLTOCodeGenerator::run() {
927 // Prepare the resulting object vector
928 assert(ProducedBinaries.empty() && "The generator should not be reused");
929 if (SavedObjectsDirectoryPath.empty())
930 ProducedBinaries.resize(Modules.size());
931 else {
932 sys::fs::create_directories(SavedObjectsDirectoryPath);
933 bool IsDir;
934 sys::fs::is_directory(SavedObjectsDirectoryPath, IsDir);
935 if (!IsDir)
936 report_fatal_error("Unexistent dir: '" + SavedObjectsDirectoryPath + "'");
937 ProducedBinaryFiles.resize(Modules.size());
938 }
939
940 if (CodeGenOnly) {
941 // Perform only parallel codegen and return.
942 ThreadPool Pool;
943 int count = 0;
944 for (auto &Mod : Modules) {
945 Pool.async([&](int count) {
946 LLVMContext Context;
947 Context.setDiscardValueNames(LTODiscardValueNames);
948
949 // Parse module now
950 auto TheModule = loadModuleFromInput(Mod.get(), Context, false,
951 /*IsImporting*/ false);
952
953 // CodeGen
954 auto OutputBuffer = codegenModule(*TheModule, *TMBuilder.create());
955 if (SavedObjectsDirectoryPath.empty())
956 ProducedBinaries[count] = std::move(OutputBuffer);
957 else
958 ProducedBinaryFiles[count] =
959 writeGeneratedObject(count, "", *OutputBuffer);
960 }, count++);
961 }
962
963 return;
964 }
965
966 // Sequential linking phase
967 auto Index = linkCombinedIndex();
968
969 // Save temps: index.
970 if (!SaveTempsDir.empty()) {
971 auto SaveTempPath = SaveTempsDir + "index.bc";
972 std::error_code EC;
973 raw_fd_ostream OS(SaveTempPath, EC, sys::fs::OF_None);
974 if (EC)
975 report_fatal_error(Twine("Failed to open ") + SaveTempPath +
976 " to save optimized bitcode\n");
977 WriteIndexToFile(*Index, OS);
978 }
979
980
981 // Prepare the module map.
982 auto ModuleMap = generateModuleMap(Modules);
983 auto ModuleCount = Modules.size();
984
985 // Collect for each module the list of function it defines (GUID -> Summary).
986 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
987 Index->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
988
989 // Convert the preserved symbols set from string to GUID, this is needed for
990 // computing the caching hash and the internalization.
991 DenseSet<GlobalValue::GUID> GUIDPreservedSymbols;
992 for (const auto &M : Modules)
993 computeGUIDPreservedSymbols(*M, PreservedSymbols, TMBuilder.TheTriple,
994 GUIDPreservedSymbols);
995
996 // Add used symbol from inputs to the preserved symbols.
997 for (const auto &M : Modules)
998 addUsedSymbolToPreservedGUID(*M, GUIDPreservedSymbols);
999
1000 // Compute "dead" symbols, we don't want to import/export these!
1001 computeDeadSymbolsInIndex(*Index, GUIDPreservedSymbols);
1002
1003 // Synthesize entry counts for functions in the combined index.
1004 computeSyntheticCounts(*Index);
1005
1006 // Currently there is no support for enabling whole program visibility via a
1007 // linker option in the old LTO API, but this call allows it to be specified
1008 // via the internal option. Must be done before WPD below.
1009 updateVCallVisibilityInIndex(*Index,
1010 /* WholeProgramVisibilityEnabledInLTO */ false);
1011
1012 // Perform index-based WPD. This will return immediately if there are
1013 // no index entries in the typeIdMetadata map (e.g. if we are instead
1014 // performing IR-based WPD in hybrid regular/thin LTO mode).
1015 std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;
1016 std::set<GlobalValue::GUID> ExportedGUIDs;
1017 runWholeProgramDevirtOnIndex(*Index, ExportedGUIDs, LocalWPDTargetsMap);
1018 for (auto GUID : ExportedGUIDs)
1019 GUIDPreservedSymbols.insert(GUID);
1020
1021 // Collect the import/export lists for all modules from the call-graph in the
1022 // combined index.
1023 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
1024 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
1025 ComputeCrossModuleImport(*Index, ModuleToDefinedGVSummaries, ImportLists,
1026 ExportLists);
1027
1028 // We use a std::map here to be able to have a defined ordering when
1029 // producing a hash for the cache entry.
1030 // FIXME: we should be able to compute the caching hash for the entry based
1031 // on the index, and nuke this map.
1032 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
1033
1034 DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy;
1035 computePrevailingCopies(*Index, PrevailingCopy);
1036
1037 // Resolve prevailing symbols, this has to be computed early because it
1038 // impacts the caching.
1039 resolvePrevailingInIndex(*Index, ResolvedODR, GUIDPreservedSymbols,
1040 PrevailingCopy);
1041
1042 // Use global summary-based analysis to identify symbols that can be
1043 // internalized (because they aren't exported or preserved as per callback).
1044 // Changes are made in the index, consumed in the ThinLTO backends.
1045 updateIndexWPDForExports(*Index,
1046 IsExported(ExportLists, GUIDPreservedSymbols),
1047 LocalWPDTargetsMap);
1048 thinLTOInternalizeAndPromoteInIndex(
1049 *Index, IsExported(ExportLists, GUIDPreservedSymbols),
1050 IsPrevailing(PrevailingCopy));
1051
1052 // Make sure that every module has an entry in the ExportLists, ImportList,
1053 // GVSummary and ResolvedODR maps to enable threaded access to these maps
1054 // below.
1055 for (auto &Module : Modules) {
1056 auto ModuleIdentifier = Module->getName();
1057 ExportLists[ModuleIdentifier];
1058 ImportLists[ModuleIdentifier];
1059 ResolvedODR[ModuleIdentifier];
1060 ModuleToDefinedGVSummaries[ModuleIdentifier];
1061 }
1062
1063 std::vector<BitcodeModule *> ModulesVec;
1064 ModulesVec.reserve(Modules.size());
1065 for (auto &Mod : Modules)
1066 ModulesVec.push_back(&Mod->getSingleBitcodeModule());
1067 std::vector<int> ModulesOrdering = lto::generateModulesOrdering(ModulesVec);
1068
1069 // Parallel optimizer + codegen
1070 {
1071 ThreadPool Pool(heavyweight_hardware_concurrency(ThreadCount));
1072 for (auto IndexCount : ModulesOrdering) {
1073 auto &Mod = Modules[IndexCount];
1074 Pool.async([&](int count) {
1075 auto ModuleIdentifier = Mod->getName();
1076 auto &ExportList = ExportLists[ModuleIdentifier];
1077
1078 auto &DefinedGVSummaries = ModuleToDefinedGVSummaries[ModuleIdentifier];
1079
1080 // The module may be cached, this helps handling it.
1081 ModuleCacheEntry CacheEntry(CacheOptions.Path, *Index, ModuleIdentifier,
1082 ImportLists[ModuleIdentifier], ExportList,
1083 ResolvedODR[ModuleIdentifier],
1084 DefinedGVSummaries, OptLevel, Freestanding,
1085 TMBuilder);
1086 auto CacheEntryPath = CacheEntry.getEntryPath();
1087
1088 {
1089 auto ErrOrBuffer = CacheEntry.tryLoadingBuffer();
1090 LLVM_DEBUG(dbgs() << "Cache " << (ErrOrBuffer ? "hit" : "miss")
1091 << " '" << CacheEntryPath << "' for buffer "
1092 << count << " " << ModuleIdentifier << "\n");
1093
1094 if (ErrOrBuffer) {
1095 // Cache Hit!
1096 if (SavedObjectsDirectoryPath.empty())
1097 ProducedBinaries[count] = std::move(ErrOrBuffer.get());
1098 else
1099 ProducedBinaryFiles[count] = writeGeneratedObject(
1100 count, CacheEntryPath, *ErrOrBuffer.get());
1101 return;
1102 }
1103 }
1104
1105 LLVMContext Context;
1106 Context.setDiscardValueNames(LTODiscardValueNames);
1107 Context.enableDebugTypeODRUniquing();
1108 auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
1109 Context, RemarksFilename, RemarksPasses, RemarksFormat,
1110 RemarksWithHotness, RemarksHotnessThreshold, count);
1111 if (!DiagFileOrErr) {
1112 errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
1113 report_fatal_error("ThinLTO: Can't get an output file for the "
1114 "remarks");
1115 }
1116
1117 // Parse module now
1118 auto TheModule = loadModuleFromInput(Mod.get(), Context, false,
1119 /*IsImporting*/ false);
1120
1121 // Save temps: original file.
1122 saveTempBitcode(*TheModule, SaveTempsDir, count, ".0.original.bc");
1123
1124 auto &ImportList = ImportLists[ModuleIdentifier];
1125 // Run the main process now, and generates a binary
1126 auto OutputBuffer = ProcessThinLTOModule(
1127 *TheModule, *Index, ModuleMap, *TMBuilder.create(), ImportList,
1128 ExportList, GUIDPreservedSymbols,
1129 ModuleToDefinedGVSummaries[ModuleIdentifier], CacheOptions,
1130 DisableCodeGen, SaveTempsDir, Freestanding, OptLevel, count);
1131
1132 // Commit to the cache (if enabled)
1133 CacheEntry.write(*OutputBuffer);
1134
1135 if (SavedObjectsDirectoryPath.empty()) {
1136 // We need to generated a memory buffer for the linker.
1137 if (!CacheEntryPath.empty()) {
1138 // When cache is enabled, reload from the cache if possible.
1139 // Releasing the buffer from the heap and reloading it from the
1140 // cache file with mmap helps us to lower memory pressure.
1141 // The freed memory can be used for the next input file.
1142 // The final binary link will read from the VFS cache (hopefully!)
1143 // or from disk (if the memory pressure was too high).
1144 auto ReloadedBufferOrErr = CacheEntry.tryLoadingBuffer();
1145 if (auto EC = ReloadedBufferOrErr.getError()) {
1146 // On error, keep the preexisting buffer and print a diagnostic.
1147 errs() << "remark: can't reload cached file '" << CacheEntryPath
1148 << "': " << EC.message() << "\n";
1149 } else {
1150 OutputBuffer = std::move(*ReloadedBufferOrErr);
1151 }
1152 }
1153 ProducedBinaries[count] = std::move(OutputBuffer);
1154 return;
1155 }
1156 ProducedBinaryFiles[count] = writeGeneratedObject(
1157 count, CacheEntryPath, *OutputBuffer);
1158 }, IndexCount);
1159 }
1160 }
1161
1162 pruneCache(CacheOptions.Path, CacheOptions.Policy);
1163
1164 // If statistics were requested, print them out now.
1165 if (llvm::AreStatisticsEnabled())
1166 llvm::PrintStatistics();
1167 reportAndResetTimings();
1168 }
1169