LLVM 17.0.0git
ThinLTOCodeGenerator.cpp
Go to the documentation of this file.
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
16
17#include "llvm/ADT/ScopeExit.h"
18#include "llvm/ADT/Statistic.h"
27#include "llvm/Config/llvm-config.h"
28#include "llvm/IR/DebugInfo.h"
31#include "llvm/IR/LLVMContext.h"
33#include "llvm/IR/Mangler.h"
35#include "llvm/IR/Verifier.h"
37#include "llvm/LTO/LTO.h"
46#include "llvm/Support/Debug.h"
47#include "llvm/Support/Error.h"
49#include "llvm/Support/Path.h"
50#include "llvm/Support/SHA1.h"
62
63#include <numeric>
64
65#if !defined(_MSC_VER) && !defined(__MINGW32__)
66#include <unistd.h>
67#else
68#include <io.h>
69#endif
70
71using namespace llvm;
72
73#define DEBUG_TYPE "thinlto"
74
75namespace llvm {
76// Flags -discard-value-names, defined in LTOCodeGenerator.cpp
84}
85
86namespace {
87
88// Default to using all available threads in the system, but using only one
89// thred per core, as indicated by the usage of
90// heavyweight_hardware_concurrency() below.
91static cl::opt<int> ThreadCount("threads", cl::init(0));
92
93// Simple helper to save temporary files for debug.
94static void saveTempBitcode(const Module &TheModule, StringRef TempDir,
95 unsigned count, StringRef Suffix) {
96 if (TempDir.empty())
97 return;
98 // User asked to save temps, let dump the bitcode file after import.
99 std::string SaveTempPath = (TempDir + llvm::Twine(count) + Suffix).str();
100 std::error_code EC;
101 raw_fd_ostream OS(SaveTempPath, EC, sys::fs::OF_None);
102 if (EC)
103 report_fatal_error(Twine("Failed to open ") + SaveTempPath +
104 " to save optimized bitcode\n");
105 WriteBitcodeToFile(TheModule, OS, /* ShouldPreserveUseListOrder */ true);
106}
107
108static const GlobalValueSummary *
109getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList) {
110 // If there is any strong definition anywhere, get it.
111 auto StrongDefForLinker = llvm::find_if(
112 GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
113 auto Linkage = Summary->linkage();
116 });
117 if (StrongDefForLinker != GVSummaryList.end())
118 return StrongDefForLinker->get();
119 // Get the first *linker visible* definition for this global in the summary
120 // list.
121 auto FirstDefForLinker = llvm::find_if(
122 GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
123 auto Linkage = Summary->linkage();
125 });
126 // Extern templates can be emitted as available_externally.
127 if (FirstDefForLinker == GVSummaryList.end())
128 return nullptr;
129 return FirstDefForLinker->get();
130}
131
132// Populate map of GUID to the prevailing copy for any multiply defined
133// symbols. Currently assume first copy is prevailing, or any strong
134// definition. Can be refined with Linker information in the future.
135static void computePrevailingCopies(
138 auto HasMultipleCopies = [&](const GlobalValueSummaryList &GVSummaryList) {
139 return GVSummaryList.size() > 1;
140 };
141
142 for (auto &I : Index) {
143 if (HasMultipleCopies(I.second.SummaryList))
144 PrevailingCopy[I.first] =
145 getFirstDefinitionForLinker(I.second.SummaryList);
146 }
147}
148
150generateModuleMap(std::vector<std::unique_ptr<lto::InputFile>> &Modules) {
152 for (auto &M : Modules) {
153 assert(!ModuleMap.contains(M->getName()) &&
154 "Expect unique Buffer Identifier");
155 ModuleMap[M->getName()] = M.get();
156 }
157 return ModuleMap;
158}
159
160static void promoteModule(Module &TheModule, const ModuleSummaryIndex &Index,
161 bool ClearDSOLocalOnDeclarations) {
162 if (renameModuleForThinLTO(TheModule, Index, ClearDSOLocalOnDeclarations))
163 report_fatal_error("renameModuleForThinLTO failed");
164}
165
166namespace {
167class ThinLTODiagnosticInfo : public DiagnosticInfo {
168 const Twine &Msg;
169public:
170 ThinLTODiagnosticInfo(const Twine &DiagMsg,
171 DiagnosticSeverity Severity = DS_Error)
172 : DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {}
173 void print(DiagnosticPrinter &DP) const override { DP << Msg; }
174};
175}
176
177/// Verify the module and strip broken debug info.
178static void verifyLoadedModule(Module &TheModule) {
179 bool BrokenDebugInfo = false;
180 if (verifyModule(TheModule, &dbgs(), &BrokenDebugInfo))
181 report_fatal_error("Broken module found, compilation aborted!");
182 if (BrokenDebugInfo) {
183 TheModule.getContext().diagnose(ThinLTODiagnosticInfo(
184 "Invalid debug info found, debug info will be stripped", DS_Warning));
185 StripDebugInfo(TheModule);
186 }
187}
188
189static std::unique_ptr<Module> loadModuleFromInput(lto::InputFile *Input,
190 LLVMContext &Context,
191 bool Lazy,
192 bool IsImporting) {
193 auto &Mod = Input->getSingleBitcodeModule();
194 SMDiagnostic Err;
196 Lazy ? Mod.getLazyModule(Context,
197 /* ShouldLazyLoadMetadata */ true, IsImporting)
198 : Mod.parseModule(Context);
199 if (!ModuleOrErr) {
200 handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
201 SMDiagnostic Err = SMDiagnostic(Mod.getModuleIdentifier(),
202 SourceMgr::DK_Error, EIB.message());
203 Err.print("ThinLTO", errs());
204 });
205 report_fatal_error("Can't load module, abort.");
206 }
207 if (!Lazy)
208 verifyLoadedModule(*ModuleOrErr.get());
209 return std::move(*ModuleOrErr);
210}
211
212static void
213crossImportIntoModule(Module &TheModule, const ModuleSummaryIndex &Index,
215 const FunctionImporter::ImportMapTy &ImportList,
216 bool ClearDSOLocalOnDeclarations) {
217 auto Loader = [&](StringRef Identifier) {
218 auto &Input = ModuleMap[Identifier];
219 return loadModuleFromInput(Input, TheModule.getContext(),
220 /*Lazy=*/true, /*IsImporting*/ true);
221 };
222
223 FunctionImporter Importer(Index, Loader, ClearDSOLocalOnDeclarations);
224 Expected<bool> Result = Importer.importFunctions(TheModule, ImportList);
225 if (!Result) {
226 handleAllErrors(Result.takeError(), [&](ErrorInfoBase &EIB) {
227 SMDiagnostic Err = SMDiagnostic(TheModule.getModuleIdentifier(),
228 SourceMgr::DK_Error, EIB.message());
229 Err.print("ThinLTO", errs());
230 });
231 report_fatal_error("importFunctions failed");
232 }
233 // Verify again after cross-importing.
234 verifyLoadedModule(TheModule);
235}
236
237static void optimizeModule(Module &TheModule, TargetMachine &TM,
238 unsigned OptLevel, bool Freestanding,
239 bool DebugPassManager, ModuleSummaryIndex *Index) {
240 std::optional<PGOOptions> PGOOpt;
245
247 StandardInstrumentations SI(TheModule.getContext(), DebugPassManager);
248 SI.registerCallbacks(PIC, &MAM);
250 PTO.LoopVectorization = true;
251 PTO.SLPVectorization = true;
252 PassBuilder PB(&TM, PTO, PGOOpt, &PIC);
253
254 std::unique_ptr<TargetLibraryInfoImpl> TLII(
255 new TargetLibraryInfoImpl(Triple(TM.getTargetTriple())));
256 if (Freestanding)
257 TLII->disableAllFunctions();
258 FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
259
260 // Register all the basic analyses with the managers.
266
268
270
271 switch (OptLevel) {
272 default:
273 llvm_unreachable("Invalid optimization level");
274 case 0:
276 break;
277 case 1:
279 break;
280 case 2:
282 break;
283 case 3:
285 break;
286 }
287
289
290 MPM.run(TheModule, MAM);
291}
292
293static void
294addUsedSymbolToPreservedGUID(const lto::InputFile &File,
295 DenseSet<GlobalValue::GUID> &PreservedGUID) {
296 for (const auto &Sym : File.symbols()) {
297 if (Sym.isUsed())
298 PreservedGUID.insert(GlobalValue::getGUID(Sym.getIRName()));
299 }
300}
301
302// Convert the PreservedSymbols map from "Name" based to "GUID" based.
303static void computeGUIDPreservedSymbols(const lto::InputFile &File,
305 const Triple &TheTriple,
307 // Iterate the symbols in the input file and if the input has preserved symbol
308 // compute the GUID for the symbol.
309 for (const auto &Sym : File.symbols()) {
310 if (PreservedSymbols.count(Sym.getName()) && !Sym.getIRName().empty())
312 Sym.getIRName(), GlobalValue::ExternalLinkage, "")));
313 }
314}
315
317computeGUIDPreservedSymbols(const lto::InputFile &File,
319 const Triple &TheTriple) {
320 DenseSet<GlobalValue::GUID> GUIDPreservedSymbols(PreservedSymbols.size());
321 computeGUIDPreservedSymbols(File, PreservedSymbols, TheTriple,
322 GUIDPreservedSymbols);
323 return GUIDPreservedSymbols;
324}
325
326std::unique_ptr<MemoryBuffer> codegenModule(Module &TheModule,
327 TargetMachine &TM) {
329
330 // CodeGen
331 {
334
335 // If the bitcode files contain ARC code and were compiled with optimization,
336 // the ObjCARCContractPass must be run, so do it unconditionally here.
338
339 // Setup the codegen now.
340 if (TM.addPassesToEmitFile(PM, OS, nullptr, CGFT_ObjectFile,
341 /* DisableVerify */ true))
342 report_fatal_error("Failed to setup codegen");
343
344 // Run codegen now. resulting binary is in OutputBuffer.
345 PM.run(TheModule);
346 }
347 return std::make_unique<SmallVectorMemoryBuffer>(
348 std::move(OutputBuffer), /*RequiresNullTerminator=*/false);
349}
350
351/// Manage caching for a single Module.
352class ModuleCacheEntry {
353 SmallString<128> EntryPath;
354
355public:
356 // Create a cache entry. This compute a unique hash for the Module considering
357 // the current list of export/import, and offer an interface to query to
358 // access the content in the cache.
359 ModuleCacheEntry(
360 StringRef CachePath, const ModuleSummaryIndex &Index, StringRef ModuleID,
361 const FunctionImporter::ImportMapTy &ImportList,
362 const FunctionImporter::ExportSetTy &ExportList,
363 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
364 const GVSummaryMapTy &DefinedGVSummaries, unsigned OptLevel,
365 bool Freestanding, const TargetMachineBuilder &TMBuilder) {
366 if (CachePath.empty())
367 return;
368
369 if (!Index.modulePaths().count(ModuleID))
370 // The module does not have an entry, it can't have a hash at all
371 return;
372
373 if (all_of(Index.getModuleHash(ModuleID),
374 [](uint32_t V) { return V == 0; }))
375 // No hash entry, no caching!
376 return;
377
379 Conf.OptLevel = OptLevel;
380 Conf.Options = TMBuilder.Options;
381 Conf.CPU = TMBuilder.MCpu;
382 Conf.MAttrs.push_back(TMBuilder.MAttr);
383 Conf.RelocModel = TMBuilder.RelocModel;
384 Conf.CGOptLevel = TMBuilder.CGOptLevel;
385 Conf.Freestanding = Freestanding;
387 computeLTOCacheKey(Key, Conf, Index, ModuleID, ImportList, ExportList,
388 ResolvedODR, DefinedGVSummaries);
389
390 // This choice of file name allows the cache to be pruned (see pruneCache()
391 // in include/llvm/Support/CachePruning.h).
392 sys::path::append(EntryPath, CachePath, "llvmcache-" + Key);
393 }
394
395 // Access the path to this entry in the cache.
396 StringRef getEntryPath() { return EntryPath; }
397
398 // Try loading the buffer for this cache entry.
399 ErrorOr<std::unique_ptr<MemoryBuffer>> tryLoadingBuffer() {
400 if (EntryPath.empty())
401 return std::error_code();
402 SmallString<64> ResultPath;
404 Twine(EntryPath), sys::fs::OF_UpdateAtime, &ResultPath);
405 if (!FDOrErr)
406 return errorToErrorCode(FDOrErr.takeError());
408 *FDOrErr, EntryPath, /*FileSize=*/-1, /*RequiresNullTerminator=*/false);
409 sys::fs::closeFile(*FDOrErr);
410 return MBOrErr;
411 }
412
413 // Cache the Produced object file
414 void write(const MemoryBuffer &OutputBuffer) {
415 if (EntryPath.empty())
416 return;
417
418 // Write to a temporary to avoid race condition
419 SmallString<128> TempFilename;
420 SmallString<128> CachePath(EntryPath);
422 sys::path::append(TempFilename, CachePath, "Thin-%%%%%%.tmp.o");
423
424 if (auto Err = handleErrors(
425 llvm::writeFileAtomically(TempFilename, EntryPath,
427 [](const llvm::AtomicFileWriteError &E) {
428 std::string ErrorMsgBuffer;
429 llvm::raw_string_ostream S(ErrorMsgBuffer);
430 E.log(S);
431
432 if (E.Error ==
433 llvm::atomic_write_error::failed_to_create_uniq_file) {
434 errs() << "Error: " << ErrorMsgBuffer << "\n";
435 report_fatal_error("ThinLTO: Can't get a temporary file");
436 }
437 })) {
438 // FIXME
439 consumeError(std::move(Err));
440 }
441 }
442};
443
444static std::unique_ptr<MemoryBuffer>
445ProcessThinLTOModule(Module &TheModule, ModuleSummaryIndex &Index,
447 const FunctionImporter::ImportMapTy &ImportList,
448 const FunctionImporter::ExportSetTy &ExportList,
449 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
450 const GVSummaryMapTy &DefinedGlobals,
451 const ThinLTOCodeGenerator::CachingOptions &CacheOptions,
452 bool DisableCodeGen, StringRef SaveTempsDir,
453 bool Freestanding, unsigned OptLevel, unsigned count,
454 bool DebugPassManager) {
455 // "Benchmark"-like optimization: single-source case
456 bool SingleModule = (ModuleMap.size() == 1);
457
458 // When linking an ELF shared object, dso_local should be dropped. We
459 // conservatively do this for -fpic.
460 bool ClearDSOLocalOnDeclarations =
461 TM.getTargetTriple().isOSBinFormatELF() &&
462 TM.getRelocationModel() != Reloc::Static &&
463 TheModule.getPIELevel() == PIELevel::Default;
464
465 if (!SingleModule) {
466 promoteModule(TheModule, Index, ClearDSOLocalOnDeclarations);
467
468 // Apply summary-based prevailing-symbol resolution decisions.
469 thinLTOFinalizeInModule(TheModule, DefinedGlobals, /*PropagateAttrs=*/true);
470
471 // Save temps: after promotion.
472 saveTempBitcode(TheModule, SaveTempsDir, count, ".1.promoted.bc");
473 }
474
475 // Be friendly and don't nuke totally the module when the client didn't
476 // supply anything to preserve.
477 if (!ExportList.empty() || !GUIDPreservedSymbols.empty()) {
478 // Apply summary-based internalization decisions.
479 thinLTOInternalizeModule(TheModule, DefinedGlobals);
480 }
481
482 // Save internalized bitcode
483 saveTempBitcode(TheModule, SaveTempsDir, count, ".2.internalized.bc");
484
485 if (!SingleModule)
486 crossImportIntoModule(TheModule, Index, ModuleMap, ImportList,
487 ClearDSOLocalOnDeclarations);
488
489 // Do this after any importing so that imported code is updated.
490 // See comment at call to updateVCallVisibilityInIndex() for why
491 // WholeProgramVisibilityEnabledInLTO is false.
493 /* WholeProgramVisibilityEnabledInLTO */ false);
494
495 // Save temps: after cross-module import.
496 saveTempBitcode(TheModule, SaveTempsDir, count, ".3.imported.bc");
497
498 optimizeModule(TheModule, TM, OptLevel, Freestanding, DebugPassManager,
499 &Index);
500
501 saveTempBitcode(TheModule, SaveTempsDir, count, ".4.opt.bc");
502
503 if (DisableCodeGen) {
504 // Configured to stop before CodeGen, serialize the bitcode and return.
506 {
508 ProfileSummaryInfo PSI(TheModule);
509 auto Index = buildModuleSummaryIndex(TheModule, nullptr, &PSI);
510 WriteBitcodeToFile(TheModule, OS, true, &Index);
511 }
512 return std::make_unique<SmallVectorMemoryBuffer>(
513 std::move(OutputBuffer), /*RequiresNullTerminator=*/false);
514 }
515
516 return codegenModule(TheModule, TM);
517}
518
519/// Resolve prevailing symbols. Record resolutions in the \p ResolvedODR map
520/// for caching, and in the \p Index for application during the ThinLTO
521/// backends. This is needed for correctness for exported symbols (ensure
522/// at least one copy kept) and a compile-time optimization (to drop duplicate
523/// copies when possible).
524static void resolvePrevailingInIndex(
526 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>>
527 &ResolvedODR,
528 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
530 &PrevailingCopy) {
531
532 auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {
533 const auto &Prevailing = PrevailingCopy.find(GUID);
534 // Not in map means that there was only one copy, which must be prevailing.
535 if (Prevailing == PrevailingCopy.end())
536 return true;
537 return Prevailing->second == S;
538 };
539
540 auto recordNewLinkage = [&](StringRef ModuleIdentifier,
542 GlobalValue::LinkageTypes NewLinkage) {
543 ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
544 };
545
546 // TODO Conf.VisibilityScheme can be lto::Config::ELF for ELF.
547 lto::Config Conf;
548 thinLTOResolvePrevailingInIndex(Conf, Index, isPrevailing, recordNewLinkage,
549 GUIDPreservedSymbols);
550}
551
552// Initialize the TargetMachine builder for a given Triple
553static void initTMBuilder(TargetMachineBuilder &TMBuilder,
554 const Triple &TheTriple) {
555 // Set a default CPU for Darwin triples (copied from LTOCodeGenerator).
556 // FIXME this looks pretty terrible...
557 if (TMBuilder.MCpu.empty() && TheTriple.isOSDarwin()) {
558 if (TheTriple.getArch() == llvm::Triple::x86_64)
559 TMBuilder.MCpu = "core2";
560 else if (TheTriple.getArch() == llvm::Triple::x86)
561 TMBuilder.MCpu = "yonah";
562 else if (TheTriple.getArch() == llvm::Triple::aarch64 ||
563 TheTriple.getArch() == llvm::Triple::aarch64_32)
564 TMBuilder.MCpu = "cyclone";
565 }
566 TMBuilder.TheTriple = std::move(TheTriple);
567}
568
569} // end anonymous namespace
570
572 MemoryBufferRef Buffer(Data, Identifier);
573
574 auto InputOrError = lto::InputFile::create(Buffer);
575 if (!InputOrError)
576 report_fatal_error(Twine("ThinLTO cannot create input file: ") +
577 toString(InputOrError.takeError()));
578
579 auto TripleStr = (*InputOrError)->getTargetTriple();
580 Triple TheTriple(TripleStr);
581
582 if (Modules.empty())
583 initTMBuilder(TMBuilder, Triple(TheTriple));
584 else if (TMBuilder.TheTriple != TheTriple) {
585 if (!TMBuilder.TheTriple.isCompatibleWith(TheTriple))
586 report_fatal_error("ThinLTO modules with incompatible triples not "
587 "supported");
588 initTMBuilder(TMBuilder, Triple(TMBuilder.TheTriple.merge(TheTriple)));
589 }
590
591 Modules.emplace_back(std::move(*InputOrError));
592}
593
595 PreservedSymbols.insert(Name);
596}
597
599 // FIXME: At the moment, we don't take advantage of this extra information,
600 // we're conservatively considering cross-references as preserved.
601 // CrossReferencedSymbols.insert(Name);
602 PreservedSymbols.insert(Name);
603}
604
605// TargetMachine factory
606std::unique_ptr<TargetMachine> TargetMachineBuilder::create() const {
607 std::string ErrMsg;
608 const Target *TheTarget =
610 if (!TheTarget) {
611 report_fatal_error(Twine("Can't load target for this Triple: ") + ErrMsg);
612 }
613
614 // Use MAttr as the default set of features.
615 SubtargetFeatures Features(MAttr);
617 std::string FeatureStr = Features.getString();
618
619 std::unique_ptr<TargetMachine> TM(
620 TheTarget->createTargetMachine(TheTriple.str(), MCpu, FeatureStr, Options,
621 RelocModel, std::nullopt, CGOptLevel));
622 assert(TM && "Cannot create target machine");
623
624 return TM;
625}
626
627/**
628 * Produce the combined summary index from all the bitcode files:
629 * "thin-link".
630 */
631std::unique_ptr<ModuleSummaryIndex> ThinLTOCodeGenerator::linkCombinedIndex() {
632 std::unique_ptr<ModuleSummaryIndex> CombinedIndex =
633 std::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false);
634 uint64_t NextModuleId = 0;
635 for (auto &Mod : Modules) {
636 auto &M = Mod->getSingleBitcodeModule();
637 if (Error Err =
638 M.readSummary(*CombinedIndex, Mod->getName(), NextModuleId++)) {
639 // FIXME diagnose
641 std::move(Err), errs(),
642 "error: can't create module summary index for buffer: ");
643 return nullptr;
644 }
645 }
646 return CombinedIndex;
647}
648
649namespace {
650struct IsExported {
652 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols;
653
654 IsExported(const StringMap<FunctionImporter::ExportSetTy> &ExportLists,
655 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols)
656 : ExportLists(ExportLists), GUIDPreservedSymbols(GUIDPreservedSymbols) {}
657
658 bool operator()(StringRef ModuleIdentifier, ValueInfo VI) const {
659 const auto &ExportList = ExportLists.find(ModuleIdentifier);
660 return (ExportList != ExportLists.end() && ExportList->second.count(VI)) ||
661 GUIDPreservedSymbols.count(VI.getGUID());
662 }
663};
664
665struct IsPrevailing {
668 &PrevailingCopy)
669 : PrevailingCopy(PrevailingCopy) {}
670
671 bool operator()(GlobalValue::GUID GUID, const GlobalValueSummary *S) const {
672 const auto &Prevailing = PrevailingCopy.find(GUID);
673 // Not in map means that there was only one copy, which must be prevailing.
674 if (Prevailing == PrevailingCopy.end())
675 return true;
676 return Prevailing->second == S;
677 };
678};
679} // namespace
680
683 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) {
684 // We have no symbols resolution available. And can't do any better now in the
685 // case where the prevailing symbol is in a native object. It can be refined
686 // with linker information in the future.
687 auto isPrevailing = [&](GlobalValue::GUID G) {
689 };
690 computeDeadSymbolsWithConstProp(Index, GUIDPreservedSymbols, isPrevailing,
691 /* ImportEnabled = */ true);
692}
693
694/**
695 * Perform promotion and renaming of exported internal functions.
696 * Index is updated to reflect linkage changes from weak resolution.
697 */
699 const lto::InputFile &File) {
700 auto ModuleCount = Index.modulePaths().size();
701 auto ModuleIdentifier = TheModule.getModuleIdentifier();
702
703 // Collect for each module the list of function it defines (GUID -> Summary).
704 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries;
705 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
706
707 // Convert the preserved symbols set from string to GUID
708 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
709 File, PreservedSymbols, Triple(TheModule.getTargetTriple()));
710
711 // Add used symbol to the preserved symbols.
712 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
713
714 // Compute "dead" symbols, we don't want to import/export these!
715 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
716
717 // Compute prevailing symbols
719 computePrevailingCopies(Index, PrevailingCopy);
720
721 // Generate import/export list
722 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
723 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
724 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries,
725 IsPrevailing(PrevailingCopy), ImportLists,
726 ExportLists);
727
728 // Resolve prevailing symbols
730 resolvePrevailingInIndex(Index, ResolvedODR, GUIDPreservedSymbols,
731 PrevailingCopy);
732
733 thinLTOFinalizeInModule(TheModule,
734 ModuleToDefinedGVSummaries[ModuleIdentifier],
735 /*PropagateAttrs=*/false);
736
737 // Promote the exported values in the index, so that they are promoted
738 // in the module.
740 Index, IsExported(ExportLists, GUIDPreservedSymbols),
741 IsPrevailing(PrevailingCopy));
742
743 // FIXME Set ClearDSOLocalOnDeclarations.
744 promoteModule(TheModule, Index, /*ClearDSOLocalOnDeclarations=*/false);
745}
746
747/**
748 * Perform cross-module importing for the module identified by ModuleIdentifier.
749 */
752 const lto::InputFile &File) {
753 auto ModuleMap = generateModuleMap(Modules);
754 auto ModuleCount = Index.modulePaths().size();
755
756 // Collect for each module the list of function it defines (GUID -> Summary).
757 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
758 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
759
760 // Convert the preserved symbols set from string to GUID
761 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
762 File, PreservedSymbols, Triple(TheModule.getTargetTriple()));
763
764 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
765
766 // Compute "dead" symbols, we don't want to import/export these!
767 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
768
769 // Compute prevailing symbols
771 computePrevailingCopies(Index, PrevailingCopy);
772
773 // Generate import/export list
774 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
775 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
776 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries,
777 IsPrevailing(PrevailingCopy), ImportLists,
778 ExportLists);
779 auto &ImportList = ImportLists[TheModule.getModuleIdentifier()];
780
781 // FIXME Set ClearDSOLocalOnDeclarations.
782 crossImportIntoModule(TheModule, Index, ModuleMap, ImportList,
783 /*ClearDSOLocalOnDeclarations=*/false);
784}
785
786/**
787 * Compute the list of summaries needed for importing into module.
788 */
790 Module &TheModule, ModuleSummaryIndex &Index,
791 std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
792 const lto::InputFile &File) {
793 auto ModuleCount = Index.modulePaths().size();
794 auto ModuleIdentifier = TheModule.getModuleIdentifier();
795
796 // Collect for each module the list of function it defines (GUID -> Summary).
797 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
798 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
799
800 // Convert the preserved symbols set from string to GUID
801 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
802 File, PreservedSymbols, Triple(TheModule.getTargetTriple()));
803
804 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
805
806 // Compute "dead" symbols, we don't want to import/export these!
807 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
808
809 // Compute prevailing symbols
811 computePrevailingCopies(Index, PrevailingCopy);
812
813 // Generate import/export list
814 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
815 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
816 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries,
817 IsPrevailing(PrevailingCopy), ImportLists,
818 ExportLists);
819
821 ModuleIdentifier, ModuleToDefinedGVSummaries,
822 ImportLists[ModuleIdentifier], ModuleToSummariesForIndex);
823}
824
825/**
826 * Emit the list of files needed for importing into module.
827 */
830 const lto::InputFile &File) {
831 auto ModuleCount = Index.modulePaths().size();
832 auto ModuleIdentifier = TheModule.getModuleIdentifier();
833
834 // Collect for each module the list of function it defines (GUID -> Summary).
835 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
836 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
837
838 // Convert the preserved symbols set from string to GUID
839 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
840 File, PreservedSymbols, Triple(TheModule.getTargetTriple()));
841
842 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
843
844 // Compute "dead" symbols, we don't want to import/export these!
845 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
846
847 // Compute prevailing symbols
849 computePrevailingCopies(Index, PrevailingCopy);
850
851 // Generate import/export list
852 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
853 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
854 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries,
855 IsPrevailing(PrevailingCopy), ImportLists,
856 ExportLists);
857
858 std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
860 ModuleIdentifier, ModuleToDefinedGVSummaries,
861 ImportLists[ModuleIdentifier], ModuleToSummariesForIndex);
862
863 std::error_code EC;
864 if ((EC = EmitImportsFiles(ModuleIdentifier, OutputName,
865 ModuleToSummariesForIndex)))
866 report_fatal_error(Twine("Failed to open ") + OutputName +
867 " to save imports lists\n");
868}
869
870/**
871 * Perform internalization. Runs promote and internalization together.
872 * Index is updated to reflect linkage changes.
873 */
876 const lto::InputFile &File) {
877 initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple()));
878 auto ModuleCount = Index.modulePaths().size();
879 auto ModuleIdentifier = TheModule.getModuleIdentifier();
880
881 // Convert the preserved symbols set from string to GUID
882 auto GUIDPreservedSymbols =
883 computeGUIDPreservedSymbols(File, PreservedSymbols, TMBuilder.TheTriple);
884
885 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
886
887 // Collect for each module the list of function it defines (GUID -> Summary).
888 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
889 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
890
891 // Compute "dead" symbols, we don't want to import/export these!
892 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
893
894 // Compute prevailing symbols
896 computePrevailingCopies(Index, PrevailingCopy);
897
898 // Generate import/export list
899 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
900 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
901 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries,
902 IsPrevailing(PrevailingCopy), ImportLists,
903 ExportLists);
904 auto &ExportList = ExportLists[ModuleIdentifier];
905
906 // Be friendly and don't nuke totally the module when the client didn't
907 // supply anything to preserve.
908 if (ExportList.empty() && GUIDPreservedSymbols.empty())
909 return;
910
911 // Resolve prevailing symbols
913 resolvePrevailingInIndex(Index, ResolvedODR, GUIDPreservedSymbols,
914 PrevailingCopy);
915
916 // Promote the exported values in the index, so that they are promoted
917 // in the module.
919 Index, IsExported(ExportLists, GUIDPreservedSymbols),
920 IsPrevailing(PrevailingCopy));
921
922 // FIXME Set ClearDSOLocalOnDeclarations.
923 promoteModule(TheModule, Index, /*ClearDSOLocalOnDeclarations=*/false);
924
925 // Internalization
926 thinLTOFinalizeInModule(TheModule,
927 ModuleToDefinedGVSummaries[ModuleIdentifier],
928 /*PropagateAttrs=*/false);
929
930 thinLTOInternalizeModule(TheModule,
931 ModuleToDefinedGVSummaries[ModuleIdentifier]);
932}
933
934/**
935 * Perform post-importing ThinLTO optimizations.
936 */
938 initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple()));
939
940 // Optimize now
941 optimizeModule(TheModule, *TMBuilder.create(), OptLevel, Freestanding,
942 DebugPassManager, nullptr);
943}
944
945/// Write out the generated object file, either from CacheEntryPath or from
946/// OutputBuffer, preferring hard-link when possible.
947/// Returns the path to the generated file in SavedObjectsDirectoryPath.
948std::string
950 const MemoryBuffer &OutputBuffer) {
951 auto ArchName = TMBuilder.TheTriple.getArchName();
952 SmallString<128> OutputPath(SavedObjectsDirectoryPath);
953 llvm::sys::path::append(OutputPath,
954 Twine(count) + "." + ArchName + ".thinlto.o");
955 OutputPath.c_str(); // Ensure the string is null terminated.
956 if (sys::fs::exists(OutputPath))
957 sys::fs::remove(OutputPath);
958
959 // We don't return a memory buffer to the linker, just a list of files.
960 if (!CacheEntryPath.empty()) {
961 // Cache is enabled, hard-link the entry (or copy if hard-link fails).
962 auto Err = sys::fs::create_hard_link(CacheEntryPath, OutputPath);
963 if (!Err)
964 return std::string(OutputPath.str());
965 // Hard linking failed, try to copy.
966 Err = sys::fs::copy_file(CacheEntryPath, OutputPath);
967 if (!Err)
968 return std::string(OutputPath.str());
969 // Copy failed (could be because the CacheEntry was removed from the cache
970 // in the meantime by another process), fall back and try to write down the
971 // buffer to the output.
972 errs() << "remark: can't link or copy from cached entry '" << CacheEntryPath
973 << "' to '" << OutputPath << "'\n";
974 }
975 // No cache entry, just write out the buffer.
976 std::error_code Err;
977 raw_fd_ostream OS(OutputPath, Err, sys::fs::OF_None);
978 if (Err)
979 report_fatal_error(Twine("Can't open output '") + OutputPath + "'\n");
980 OS << OutputBuffer.getBuffer();
981 return std::string(OutputPath.str());
982}
983
984// Main entry point for the ThinLTO processing
986 timeTraceProfilerBegin("ThinLink", StringRef(""));
987 auto TimeTraceScopeExit = llvm::make_scope_exit([]() {
990 });
991 // Prepare the resulting object vector
992 assert(ProducedBinaries.empty() && "The generator should not be reused");
993 if (SavedObjectsDirectoryPath.empty())
994 ProducedBinaries.resize(Modules.size());
995 else {
996 sys::fs::create_directories(SavedObjectsDirectoryPath);
997 bool IsDir;
998 sys::fs::is_directory(SavedObjectsDirectoryPath, IsDir);
999 if (!IsDir)
1000 report_fatal_error(Twine("Unexistent dir: '") + SavedObjectsDirectoryPath + "'");
1001 ProducedBinaryFiles.resize(Modules.size());
1002 }
1003
1004 if (CodeGenOnly) {
1005 // Perform only parallel codegen and return.
1006 ThreadPool Pool;
1007 int count = 0;
1008 for (auto &Mod : Modules) {
1009 Pool.async([&](int count) {
1012
1013 // Parse module now
1014 auto TheModule = loadModuleFromInput(Mod.get(), Context, false,
1015 /*IsImporting*/ false);
1016
1017 // CodeGen
1018 auto OutputBuffer = codegenModule(*TheModule, *TMBuilder.create());
1019 if (SavedObjectsDirectoryPath.empty())
1020 ProducedBinaries[count] = std::move(OutputBuffer);
1021 else
1022 ProducedBinaryFiles[count] =
1023 writeGeneratedObject(count, "", *OutputBuffer);
1024 }, count++);
1025 }
1026
1027 return;
1028 }
1029
1030 // Sequential linking phase
1031 auto Index = linkCombinedIndex();
1032
1033 // Save temps: index.
1034 if (!SaveTempsDir.empty()) {
1035 auto SaveTempPath = SaveTempsDir + "index.bc";
1036 std::error_code EC;
1037 raw_fd_ostream OS(SaveTempPath, EC, sys::fs::OF_None);
1038 if (EC)
1039 report_fatal_error(Twine("Failed to open ") + SaveTempPath +
1040 " to save optimized bitcode\n");
1042 }
1043
1044
1045 // Prepare the module map.
1046 auto ModuleMap = generateModuleMap(Modules);
1047 auto ModuleCount = Modules.size();
1048
1049 // Collect for each module the list of function it defines (GUID -> Summary).
1050 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
1051 Index->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
1052
1053 // Convert the preserved symbols set from string to GUID, this is needed for
1054 // computing the caching hash and the internalization.
1055 DenseSet<GlobalValue::GUID> GUIDPreservedSymbols;
1056 for (const auto &M : Modules)
1057 computeGUIDPreservedSymbols(*M, PreservedSymbols, TMBuilder.TheTriple,
1058 GUIDPreservedSymbols);
1059
1060 // Add used symbol from inputs to the preserved symbols.
1061 for (const auto &M : Modules)
1062 addUsedSymbolToPreservedGUID(*M, GUIDPreservedSymbols);
1063
1064 // Compute "dead" symbols, we don't want to import/export these!
1065 computeDeadSymbolsInIndex(*Index, GUIDPreservedSymbols);
1066
1067 // Synthesize entry counts for functions in the combined index.
1069
1070 // Currently there is no support for enabling whole program visibility via a
1071 // linker option in the old LTO API, but this call allows it to be specified
1072 // via the internal option. Must be done before WPD below.
1073 if (hasWholeProgramVisibility(/* WholeProgramVisibilityEnabledInLTO */ false))
1074 Index->setWithWholeProgramVisibility();
1076 /* WholeProgramVisibilityEnabledInLTO */ false,
1077 // FIXME: This needs linker information via a
1078 // TBD new interface.
1079 /* DynamicExportSymbols */ {});
1080
1081 // Perform index-based WPD. This will return immediately if there are
1082 // no index entries in the typeIdMetadata map (e.g. if we are instead
1083 // performing IR-based WPD in hybrid regular/thin LTO mode).
1084 std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;
1085 std::set<GlobalValue::GUID> ExportedGUIDs;
1086 runWholeProgramDevirtOnIndex(*Index, ExportedGUIDs, LocalWPDTargetsMap);
1087 for (auto GUID : ExportedGUIDs)
1088 GUIDPreservedSymbols.insert(GUID);
1089
1090 // Compute prevailing symbols
1092 computePrevailingCopies(*Index, PrevailingCopy);
1093
1094 // Collect the import/export lists for all modules from the call-graph in the
1095 // combined index.
1096 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
1097 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
1098 ComputeCrossModuleImport(*Index, ModuleToDefinedGVSummaries,
1099 IsPrevailing(PrevailingCopy), ImportLists,
1100 ExportLists);
1101
1102 // We use a std::map here to be able to have a defined ordering when
1103 // producing a hash for the cache entry.
1104 // FIXME: we should be able to compute the caching hash for the entry based
1105 // on the index, and nuke this map.
1107
1108 // Resolve prevailing symbols, this has to be computed early because it
1109 // impacts the caching.
1110 resolvePrevailingInIndex(*Index, ResolvedODR, GUIDPreservedSymbols,
1111 PrevailingCopy);
1112
1113 // Use global summary-based analysis to identify symbols that can be
1114 // internalized (because they aren't exported or preserved as per callback).
1115 // Changes are made in the index, consumed in the ThinLTO backends.
1117 IsExported(ExportLists, GUIDPreservedSymbols),
1118 LocalWPDTargetsMap);
1120 *Index, IsExported(ExportLists, GUIDPreservedSymbols),
1121 IsPrevailing(PrevailingCopy));
1122
1123 thinLTOPropagateFunctionAttrs(*Index, IsPrevailing(PrevailingCopy));
1124
1125 // Make sure that every module has an entry in the ExportLists, ImportList,
1126 // GVSummary and ResolvedODR maps to enable threaded access to these maps
1127 // below.
1128 for (auto &Module : Modules) {
1129 auto ModuleIdentifier = Module->getName();
1130 ExportLists[ModuleIdentifier];
1131 ImportLists[ModuleIdentifier];
1132 ResolvedODR[ModuleIdentifier];
1133 ModuleToDefinedGVSummaries[ModuleIdentifier];
1134 }
1135
1136 std::vector<BitcodeModule *> ModulesVec;
1137 ModulesVec.reserve(Modules.size());
1138 for (auto &Mod : Modules)
1139 ModulesVec.push_back(&Mod->getSingleBitcodeModule());
1140 std::vector<int> ModulesOrdering = lto::generateModulesOrdering(ModulesVec);
1141
1144
1145 TimeTraceScopeExit.release();
1146
1147 // Parallel optimizer + codegen
1148 {
1150 for (auto IndexCount : ModulesOrdering) {
1151 auto &Mod = Modules[IndexCount];
1152 Pool.async([&](int count) {
1153 auto ModuleIdentifier = Mod->getName();
1154 auto &ExportList = ExportLists[ModuleIdentifier];
1155
1156 auto &DefinedGVSummaries = ModuleToDefinedGVSummaries[ModuleIdentifier];
1157
1158 // The module may be cached, this helps handling it.
1159 ModuleCacheEntry CacheEntry(CacheOptions.Path, *Index, ModuleIdentifier,
1160 ImportLists[ModuleIdentifier], ExportList,
1161 ResolvedODR[ModuleIdentifier],
1162 DefinedGVSummaries, OptLevel, Freestanding,
1163 TMBuilder);
1164 auto CacheEntryPath = CacheEntry.getEntryPath();
1165
1166 {
1167 auto ErrOrBuffer = CacheEntry.tryLoadingBuffer();
1168 LLVM_DEBUG(dbgs() << "Cache " << (ErrOrBuffer ? "hit" : "miss")
1169 << " '" << CacheEntryPath << "' for buffer "
1170 << count << " " << ModuleIdentifier << "\n");
1171
1172 if (ErrOrBuffer) {
1173 // Cache Hit!
1174 if (SavedObjectsDirectoryPath.empty())
1175 ProducedBinaries[count] = std::move(ErrOrBuffer.get());
1176 else
1177 ProducedBinaryFiles[count] = writeGeneratedObject(
1178 count, CacheEntryPath, *ErrOrBuffer.get());
1179 return;
1180 }
1181 }
1182
1186 auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
1189 if (!DiagFileOrErr) {
1190 errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
1191 report_fatal_error("ThinLTO: Can't get an output file for the "
1192 "remarks");
1193 }
1194
1195 // Parse module now
1196 auto TheModule = loadModuleFromInput(Mod.get(), Context, false,
1197 /*IsImporting*/ false);
1198
1199 // Save temps: original file.
1200 saveTempBitcode(*TheModule, SaveTempsDir, count, ".0.original.bc");
1201
1202 auto &ImportList = ImportLists[ModuleIdentifier];
1203 // Run the main process now, and generates a binary
1204 auto OutputBuffer = ProcessThinLTOModule(
1205 *TheModule, *Index, ModuleMap, *TMBuilder.create(), ImportList,
1206 ExportList, GUIDPreservedSymbols,
1207 ModuleToDefinedGVSummaries[ModuleIdentifier], CacheOptions,
1208 DisableCodeGen, SaveTempsDir, Freestanding, OptLevel, count,
1209 DebugPassManager);
1210
1211 // Commit to the cache (if enabled)
1212 CacheEntry.write(*OutputBuffer);
1213
1214 if (SavedObjectsDirectoryPath.empty()) {
1215 // We need to generated a memory buffer for the linker.
1216 if (!CacheEntryPath.empty()) {
1217 // When cache is enabled, reload from the cache if possible.
1218 // Releasing the buffer from the heap and reloading it from the
1219 // cache file with mmap helps us to lower memory pressure.
1220 // The freed memory can be used for the next input file.
1221 // The final binary link will read from the VFS cache (hopefully!)
1222 // or from disk (if the memory pressure was too high).
1223 auto ReloadedBufferOrErr = CacheEntry.tryLoadingBuffer();
1224 if (auto EC = ReloadedBufferOrErr.getError()) {
1225 // On error, keep the preexisting buffer and print a diagnostic.
1226 errs() << "remark: can't reload cached file '" << CacheEntryPath
1227 << "': " << EC.message() << "\n";
1228 } else {
1229 OutputBuffer = std::move(*ReloadedBufferOrErr);
1230 }
1231 }
1232 ProducedBinaries[count] = std::move(OutputBuffer);
1233 return;
1234 }
1235 ProducedBinaryFiles[count] = writeGeneratedObject(
1236 count, CacheEntryPath, *OutputBuffer);
1237 }, IndexCount);
1238 }
1239 }
1240
1241 pruneCache(CacheOptions.Path, CacheOptions.Policy, ProducedBinaries);
1242
1243 // If statistics were requested, print them out now.
1247}
This file provides a bitcode writing pass.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DEBUG(X)
Definition: Debug.h:101
std::string Name
Symbol * Sym
Definition: ELF_riscv.cpp:463
Provides passes for computing function attributes based on interprocedural analyses.
This file implements a simple parser to decode commandline option for remarks hotness threshold that ...
static const char * PreservedSymbols[]
Definition: IRSymtab.cpp:48
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
This is the interface to build a ModuleSummaryIndex for a module.
LLVMContext & Context
CGSCCAnalysisManager CGAM
ModulePassManager MPM
Module * Mod
LoopAnalysisManager LAM
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
const char LLVMTargetMachineRef TM
PassInstrumentationCallbacks PIC
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
This header defines classes/functions to handle pass execution timing information with interfaces for...
@ SI
@ VI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This header defines a class that provides bookkeeping for all standard (i.e in-tree) pass instrumenta...
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
This file contains some functions that are useful when dealing with strings.
static void computeDeadSymbolsInIndex(ModuleSummaryIndex &Index, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols)
char * getBuffer()
Definition: Utility.h:182
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:620
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
Definition: PassManager.h:836
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:155
iterator end()
Definition: DenseMap.h:84
Implements a dense probed hash-table based set.
Definition: DenseSet.h:271
This is the base abstract class for diagnostic reporting in the backend.
virtual void print(DiagnosticPrinter &DP) const =0
Print using the given DP a user-friendly message.
Interface for custom diagnostic printing.
Base class for error info classes.
Definition: Error.h:47
Represents either an error or a value T.
Definition: ErrorOr.h:56
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
Tagged union holding either a T or a Error.
Definition: Error.h:470
Error takeError()
Take ownership of the stored error.
Definition: Error.h:597
reference get()
Returns a reference to the stored T value.
Definition: Error.h:567
The function importer is automatically importing function from other modules based on the provided su...
Function and variable summary information to aid decisions and implementation of importing.
static bool isAvailableExternallyLinkage(LinkageTypes Linkage)
Definition: GlobalValue.h:374
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
Definition: GlobalValue.h:591
bool isWeakForLinker() const
Definition: GlobalValue.h:547
std::string getGlobalIdentifier() const
Return the modified name for this global value suitable to be used as the key for a global lookup (e....
Definition: Globals.cpp:168
LinkageTypes
An enumeration for the kinds of linkage for global values.
Definition: GlobalValue.h:47
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:48
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
void enableDebugTypeODRUniquing()
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
void setDiscardValueNames(bool Discard)
Set the Context runtime configuration to discard all value name (but GlobalValue).
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:51
static ErrorOr< std::unique_ptr< MemoryBuffer > > getOpenFile(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Given an already-open file descriptor, read the file and return a MemoryBuffer.
StringRef getBuffer() const
Definition: MemoryBuffer.h:70
Class to hold module path string table and global value map, and encapsulate methods for operating on...
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
LLVMContext & getContext() const
Get the global data context.
Definition: Module.h:262
StringRef getName() const
Get a short "name" for the module.
Definition: Module.h:245
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
Definition: Module.h:258
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
Definition: Module.h:228
PIELevel::Level getPIELevel() const
Returns the PIE level (small or large model)
Definition: Module.cpp:604
static const OptimizationLevel O3
Optimize for fast execution as much as possible.
static const OptimizationLevel O0
Disable as many optimizations as possible.
static const OptimizationLevel O2
Optimize for fast execution as much as possible without triggering significant incremental compile ti...
static const OptimizationLevel O1
Optimize quickly without destroying debuggability.
This class provides access to building LLVM's passes.
Definition: PassBuilder.h:100
void registerLoopAnalyses(LoopAnalysisManager &LAM)
Registers all available loop analysis passes.
void crossRegisterProxies(LoopAnalysisManager &LAM, FunctionAnalysisManager &FAM, CGSCCAnalysisManager &CGAM, ModuleAnalysisManager &MAM)
Cross register the analysis managers through their proxies.
ModulePassManager buildThinLTODefaultPipeline(OptimizationLevel Level, const ModuleSummaryIndex *ImportSummary)
Build an ThinLTO default optimization pipeline to a pass manager.
void registerModuleAnalyses(ModuleAnalysisManager &MAM)
Registers all available module analysis passes.
void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM)
Registers all available CGSCC analysis passes.
void registerFunctionAnalyses(FunctionAnalysisManager &FAM)
Registers all available function analysis passes.
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same< PassT, PassManager >::value > addPass(PassT &&Pass)
Definition: PassManager.h:544
PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs)
Run all of the passes in this manager over the given unit of IR.
Definition: PassManager.h:498
Tunable parameters for passes in the default pipelines.
Definition: PassBuilder.h:41
bool SLPVectorization
Tuning option to enable/disable slp loop vectorization, set based on opt level.
Definition: PassBuilder.h:56
bool LoopVectorization
Tuning option to enable/disable loop vectorization, set based on opt level.
Definition: PassBuilder.h:52
Analysis providing profile information.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
Definition: SourceMgr.h:281
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
const char * c_str()
Definition: SmallString.h:264
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:261
bool empty() const
Definition: SmallVector.h:94
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
This class provides an interface to register all the standard pass instrumentations and manages their...
unsigned size() const
Definition: StringMap.h:95
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:111
iterator end()
Definition: StringMap.h:204
iterator find(StringRef Key)
Definition: StringMap.h:217
bool contains(StringRef Key) const
contains - Return true if the element is in the map, false otherwise.
Definition: StringMap.h:253
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition: StringSet.h:23
std::pair< typename Base::iterator, bool > insert(StringRef key)
Definition: StringSet.h:34
Manages the enabling and disabling of subtarget specific features.
void getDefaultSubtargetFeatures(const Triple &Triple)
Adds the default features for the specified target triple.
std::string getString() const
Returns features as a string.
Analysis pass providing the TargetLibraryInfo.
Implementation of the target library information.
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:78
Target - Wrapper for Target specific information.
TargetMachine * createTargetMachine(StringRef TT, StringRef CPU, StringRef Features, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM=std::nullopt, CodeGenOpt::Level OL=CodeGenOpt::Default, bool JIT=false) const
createTargetMachine - Create a target specific machine implementation for the specified Triple.
void preserveSymbol(StringRef Name)
Adds to a list of all global symbols that must exist in the final generated code.
void run()
Process all the modules that were added to the code generator in parallel.
void crossReferenceSymbol(StringRef Name)
Adds to a list of all global symbols that are cross-referenced between ThinLTO files.
void addModule(StringRef Identifier, StringRef Data)
Add given module to the code generator.
A ThreadPool for asynchronous parallel execution on a defined number of threads.
Definition: ThreadPool.h:52
auto async(Function &&F, Args &&...ArgList)
Asynchronous submission of a task to the pool.
Definition: ThreadPool.h:66
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
@ aarch64_32
Definition: Triple.h:53
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition: Triple.h:356
const std::string & str() const
Definition: Triple.h:415
std::string merge(const Triple &Other) const
Merge target triples.
Definition: Triple.cpp:1817
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, or DriverKit).
Definition: Triple.h:519
StringRef getArchName() const
Get the architecture (first) component of the triple.
Definition: Triple.cpp:1142
bool isCompatibleWith(const Triple &Other) const
Test whether target triples are compatible.
Definition: Triple.cpp:1793
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Definition: DenseSet.h:97
PassManager manages ModulePassManagers.
void add(Pass *P) override
Add a pass to the queue of passes to run.
bool run(Module &M)
run - Execute all of the passes scheduled for execution.
An input file.
Definition: LTO.h:109
static Expected< std::unique_ptr< InputFile > > create(MemoryBufferRef Object)
Create an InputFile.
Definition: LTO.cpp:500
BitcodeModule & getSingleBitcodeModule()
Definition: LTO.cpp:533
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:454
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:672
void optimize(Module &Module)
Perform post-importing ThinLTO optimizations.
std::unique_ptr< ModuleSummaryIndex > linkCombinedIndex()
Produce the combined summary index from all the bitcode files: "thin-link".
void crossModuleImport(Module &Module, ModuleSummaryIndex &Index, const lto::InputFile &File)
Perform cross-module importing for the module identified by ModuleIdentifier.
void emitImports(Module &Module, StringRef OutputName, ModuleSummaryIndex &Index, const lto::InputFile &File)
Compute and emit the imported files for module at ModulePath.
void gatherImportedSummariesForModule(Module &Module, ModuleSummaryIndex &Index, std::map< std::string, GVSummaryMapTy > &ModuleToSummariesForIndex, const lto::InputFile &File)
Compute the list of summaries needed for importing into module.
void internalize(Module &Module, ModuleSummaryIndex &Index, const lto::InputFile &File)
Perform internalization.
void promote(Module &Module, ModuleSummaryIndex &Index, const lto::InputFile &File)
Perform promotion and renaming of exported internal functions, and additionally resolve weak and link...
std::string writeGeneratedObject(int count, StringRef CacheEntryPath, const MemoryBuffer &OutputBuffer)
Write temporary object file to SavedObjectDirectoryPath, write symlink to Cache directory if needed.
Interfaces for registering analysis passes, producing common pass manager configurations,...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Key
PAL metadata keys.
const CustomOperand< const MCSubtargetInfo & > Msg[]
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:445
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
std::vector< int > generateModulesOrdering(ArrayRef< BitcodeModule * > R)
Produces a container ordering for optimal multi-threaded processing.
Definition: LTO.cpp:1770
Expected< std::unique_ptr< ToolOutputFile > > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::optional< uint64_t > RemarksHotnessThreshold=0, int Count=-1)
Setup optimization remarks.
Definition: LTO.cpp:1726
std::error_code closeFile(file_t &F)
Close the file object.
bool exists(const basic_file_status &status)
Does file exist?
Definition: Path.cpp:1078
@ OF_UpdateAtime
Force files Atime to be updated on access.
Definition: FileSystem.h:785
std::error_code create_hard_link(const Twine &to, const Twine &from)
Create a hard link from from to to, or return an error.
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
std::error_code create_directories(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create all the non-existent directories in path.
Definition: Path.cpp:968
std::error_code copy_file(const Twine &From, const Twine &To)
Copy the contents of From to To.
Definition: Path.cpp:1017
Expected< file_t > openNativeFileForRead(const Twine &Name, OpenFlags Flags=OF_None, SmallVectorImpl< char > *RealPath=nullptr)
Opens the file with the given name in a read-only mode, returning its open file descriptor.
bool is_directory(const basic_file_status &status)
Does status represent a directory?
Definition: Path.cpp:1093
void remove_filename(SmallVectorImpl< char > &path, Style style=Style::native)
Remove the last component from path unless it is the root dir.
Definition: Path.cpp:475
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:457
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::Error writeFileAtomically(StringRef TempPathModel, StringRef FinalPath, StringRef Buffer)
Creates a unique file with name according to the given TempPathModel, writes content of Buffer to the...
ThreadPoolStrategy heavyweight_hardware_concurrency(unsigned ThreadCount=0)
Returns a thread strategy for tasks requiring significant memory or other resources.
Definition: Threading.h:162
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
Definition: Error.cpp:63
cl::opt< std::string > RemarksFormat("lto-pass-remarks-format", cl::desc("The format used for serializing remarks (default: YAML)"), cl::value_desc("format"), cl::init("yaml"))
Error write(MCStreamer &Out, ArrayRef< std::string > Inputs)
Definition: DWP.cpp:551
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1819
cl::opt< bool > LTODiscardValueNames("lto-discard-value-names", cl::desc("Strip names from Value during LTO (other than GlobalValue)."), cl::init(false), cl::Hidden)
void WriteBitcodeToFile(const Module &M, raw_ostream &Out, bool ShouldPreserveUseListOrder=false, const ModuleSummaryIndex *Index=nullptr, bool GenerateHash=false, ModuleHash *ModHash=nullptr)
Write the specified module to the specified raw output stream.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
Definition: ScopeExit.h:59
cl::opt< std::string > RemarksPasses("lto-pass-remarks-filter", cl::desc("Only record optimization remarks from passes whose " "names match the given regular expression"), cl::value_desc("regex"))
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition: Error.h:966
void writeIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out, const std::map< std::string, GVSummaryMapTy > *ModuleToSummariesForIndex=nullptr)
Write the specified module summary index to the given raw output stream, where it will be written in ...
void gatherImportedSummariesForModule(StringRef ModulePath, const StringMap< GVSummaryMapTy > &ModuleToDefinedGVSummaries, const FunctionImporter::ImportMapTy &ImportList, std::map< std::string, GVSummaryMapTy > &ModuleToSummariesForIndex)
Compute the set of summaries needed for a ThinLTO backend compilation of ModulePath.
Error handleErrors(Error E, HandlerTs &&... Hs)
Pass the ErrorInfo(s) contained in E to their respective handlers.
Definition: Error.h:943
std::error_code EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename, const std::map< std::string, GVSummaryMapTy > &ModuleToSummariesForIndex)
Emit into OutputFilename the files module ModulePath will import from.
void ComputeCrossModuleImport(const ModuleSummaryIndex &Index, const StringMap< GVSummaryMapTy > &ModuleToDefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, StringMap< FunctionImporter::ImportMapTy > &ImportLists, StringMap< FunctionImporter::ExportSetTy > &ExportLists)
Compute all the imports and exports for every module in the Index.
bool thinLTOPropagateFunctionAttrs(ModuleSummaryIndex &Index, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
Propagate function attributes for function summaries along the index's callgraph during thinlink.
ModuleSummaryIndex buildModuleSummaryIndex(const Module &M, std::function< BlockFrequencyInfo *(const Function &F)> GetBFICallback, ProfileSummaryInfo *PSI, std::function< const StackSafetyInfo *(const Function &F)> GetSSICallback=[](const Function &F) -> const StackSafetyInfo *{ return nullptr;})
Direct function to compute a ModuleSummaryIndex from a given module.
void reportAndResetTimings(raw_ostream *OutStream=nullptr)
If -time-passes has been specified, report the timings immediately and then reset the timers to zero.
@ DK_Linker
bool hasWholeProgramVisibility(bool WholeProgramVisibilityEnabledInLTO)
bool renameModuleForThinLTO(Module &M, const ModuleSummaryIndex &Index, bool ClearDSOLocalOnDeclarations, SetVector< GlobalValue * > *GlobalsToImport=nullptr)
Perform in-place global value handling on the given Module for exported local functions renamed and p...
void thinLTOInternalizeAndPromoteInIndex(ModuleSummaryIndex &Index, function_ref< bool(StringRef, ValueInfo)> isExported, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
Update the linkages in the given Index to mark exported values as external and non-exported values as...
Definition: LTO.cpp:487
void computeLTOCacheKey(SmallString< 40 > &Key, const lto::Config &Conf, const ModuleSummaryIndex &Index, StringRef ModuleID, const FunctionImporter::ImportMapTy &ImportList, const FunctionImporter::ExportSetTy &ExportList, const std::map< GlobalValue::GUID, GlobalValue::LinkageTypes > &ResolvedODR, const GVSummaryMapTy &DefinedGlobals, const std::set< GlobalValue::GUID > &CfiFunctionDefs={}, const std::set< GlobalValue::GUID > &CfiFunctionDecls={})
Computes a unique hash for the Module considering the current list of export/import and other global ...
Definition: LTO.cpp:89
void timeTraceProfilerBegin(StringRef Name, StringRef Detail)
Manually begin a time section, with the given Name and Detail.
void updatePublicTypeTestCalls(Module &M, bool WholeProgramVisibilityEnabledInLTO)
@ CGFT_ObjectFile
Definition: CodeGen.h:86
bool timeTraceProfilerEnabled()
Is the time trace profiler enabled, i.e. initialized?
Definition: TimeProfiler.h:102
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
bool AreStatisticsEnabled()
Check if statistics are enabled.
Definition: Statistic.cpp:139
cl::opt< bool > RemarksWithHotness("lto-pass-remarks-with-hotness", cl::desc("With PGO, include profile count in optimization remarks"), cl::Hidden)
void computeSyntheticCounts(ModuleSummaryIndex &Index)
Compute synthetic function entry counts.
void timeTraceProfilerEnd()
Manually end the last time section.
cl::opt< std::string > RemarksFilename("lto-pass-remarks-output", cl::desc("Output filename for pass remarks"), cl::value_desc("filename"))
void updateIndexWPDForExports(ModuleSummaryIndex &Summary, function_ref< bool(StringRef, ValueInfo)> isExported, std::map< ValueInfo, std::vector< VTableSlotSummary > > &LocalWPDTargetsMap)
Call after cross-module importing to update the recorded single impl devirt target names for any loca...
void thinLTOResolvePrevailingInIndex(const lto::Config &C, ModuleSummaryIndex &Index, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, function_ref< void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> recordNewLinkage, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols)
Resolve linkage for prevailing symbols in the Index.
Definition: LTO.cpp:427
std::vector< std::unique_ptr< GlobalValueSummary > > GlobalValueSummaryList
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
bool StripDebugInfo(Module &M)
Strip debug info in the module if it exists.
Definition: DebugInfo.cpp:533
@ Mod
The access may modify the value stored in memory.
void PrintStatistics()
Print statistics to the file returned by CreateInfoOutputFile().
Definition: Statistic.cpp:229
void updateVCallVisibilityInIndex(ModuleSummaryIndex &Index, bool WholeProgramVisibilityEnabledInLTO, const DenseSet< GlobalValue::GUID > &DynamicExportSymbols)
If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...
void runWholeProgramDevirtOnIndex(ModuleSummaryIndex &Summary, std::set< GlobalValue::GUID > &ExportedGUIDs, std::map< ValueInfo, std::vector< VTableSlotSummary > > &LocalWPDTargetsMap)
Perform index-based whole program devirtualization on the Summary index.
bool pruneCache(StringRef Path, CachePruningPolicy Policy, const std::vector< std::unique_ptr< MemoryBuffer > > &Files={})
Peform pruning using the supplied policy, returns true if pruning occurred, i.e.
void thinLTOInternalizeModule(Module &TheModule, const GVSummaryMapTy &DefinedGlobals)
Internalize TheModule based on the information recorded in the summaries during global summary-based ...
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
Definition: STLExtras.h:2011
DiagnosticSeverity
Defines the different supported severity of a diagnostic.
@ DS_Warning
@ DS_Error
cl::opt< std::optional< uint64_t >, false, remarks::HotnessThresholdParser > RemarksHotnessThreshold("lto-pass-remarks-hotness-threshold", cl::desc("Minimum profile count required for an " "optimization remark to be output." " Use 'auto' to apply the threshold from profile summary."), cl::value_desc("uint or 'auto'"), cl::init(0), cl::Hidden)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1846
Pass * createObjCARCContractPass()
std::error_code errorToErrorCode(Error Err)
Helper for converting an ECError to a std::error_code.
Definition: Error.cpp:98
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1043
void computeDeadSymbolsWithConstProp(ModuleSummaryIndex &Index, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols, function_ref< PrevailingType(GlobalValue::GUID)> isPrevailing, bool ImportEnabled)
Compute dead symbols and run constant propagation in combined index after that.
bool verifyModule(const Module &M, raw_ostream *OS=nullptr, bool *BrokenDebugInfo=nullptr)
Check a module for errors.
Definition: Verifier.cpp:6522
void thinLTOFinalizeInModule(Module &TheModule, const GVSummaryMapTy &DefinedGlobals, bool PropagateAttrs)
Based on the information recorded in the summaries during global summary-based analysis:
Helper to gather options relevant to the target machine creation.
std::unique_ptr< TargetMachine > create() const
std::optional< Reloc::Model > RelocModel
static const Target * lookupTarget(StringRef Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.
Struct that holds a reference to a particular GUID in a global value summary.
LTO configuration.
Definition: Config.h:41
std::vector< std::string > MAttrs
Definition: Config.h:50
std::string CPU
Definition: Config.h:48
TargetOptions Options
Definition: Config.h:49
CodeGenOpt::Level CGOptLevel
Definition: Config.h:57
unsigned OptLevel
Definition: Config.h:59
std::optional< Reloc::Model > RelocModel
Definition: Config.h:55
bool Freestanding
Flag to indicate that the optimizer should not assume builtins are present on the target.
Definition: Config.h:67