Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
35233 views
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.
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 *
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.
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 *>
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
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:
173
ThinLTODiagnosticInfo(const Twine &DiagMsg,
174
DiagnosticSeverity Severity = DS_Error)
175
: DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {}
176
void print(DiagnosticPrinter &DP) const override { DP << Msg; }
177
};
178
}
179
180
/// Verify the module and strip broken debug info.
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
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
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
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
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.
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>
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
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.
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.
399
StringRef getEntryPath() { return EntryPath; }
400
401
// Try loading the buffer for this cache entry.
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
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>
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).
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
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
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
573
void ThinLTOCodeGenerator::preserveSymbol(StringRef Name) {
574
PreservedSymbols.insert(Name);
575
}
576
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
585
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
*/
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
631
IsExported(
632
const DenseMap<StringRef, FunctionImporter::ExportSetTy> &ExportLists,
633
const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols)
634
: ExportLists(ExportLists), GUIDPreservedSymbols(GUIDPreservedSymbols) {}
635
636
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;
645
IsPrevailing(const DenseMap<GlobalValue::GUID, const GlobalValueSummary *>
646
&PrevailingCopy)
647
: PrevailingCopy(PrevailingCopy) {}
648
649
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
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
*/
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
*/
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
*/
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
*/
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
*/
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
*/
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
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
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
1234