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