LLVM: lib/LTO/ThinLTOCodeGenerator.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
16
27#include "llvm/Config/llvm-config.h"
63
64#include
65
66#if !defined(_MSC_VER) && !defined(__MINGW32__)
67#include <unistd.h>
68#else
69#include <io.h>
70#endif
71
72using namespace llvm;
73using namespace ThinLTOCodeGeneratorImpl;
74
75#define DEBUG_TYPE "thinlto"
76
77namespace llvm {
78
86}
87
88
89
90
92
93
96 if (TempDir.empty())
97 return;
98
99 std::string SaveTempPath = (TempDir + llvm::Twine(count) + Suffix).str();
100 std::error_code EC;
102 if (EC)
104 " to save optimized bitcode\n");
106}
107
110
112 GVSummaryList, [](const std::unique_ptr &Summary) {
113 auto Linkage = Summary->linkage();
116 });
117 if (StrongDefForLinker != GVSummaryList.end())
118 return StrongDefForLinker->get();
119
120
122 GVSummaryList, [](const std::unique_ptr &Summary) {
123 auto Linkage = Summary->linkage();
125 });
126
127 if (FirstDefForLinker == GVSummaryList.end())
128 return nullptr;
129 return FirstDefForLinker->get();
130}
131
132
133
134
139 return GVSummaryList.size() > 1;
140 };
141
142 for (auto &I : Index) {
143 if (HasMultipleCopies(I.second.SummaryList))
144 PrevailingCopy[I.first] =
146 }
147}
148
152 for (auto &M : Modules) {
153 LLVM_DEBUG(dbgs() << "Adding module " << M->getName() << " to ModuleMap\n");
155 "Expect unique Buffer Identifier");
156 ModuleMap[M->getName()] = M.get();
157 }
158 return ModuleMap;
159}
160
162 bool ClearDSOLocalOnDeclarations) {
164}
165
166namespace {
168 const Twine &Msg;
169public:
170 ThinLTODiagnosticInfo(const Twine &DiagMsg,
174};
175}
176
177
179 bool BrokenDebugInfo = false;
182 if (BrokenDebugInfo) {
184 "Invalid debug info found, debug info will be stripped", DS_Warning));
186 }
187}
188
191 bool Lazy,
192 bool IsImporting) {
196 Lazy ? Mod.getLazyModule(Context,
197 true, IsImporting)
198 : Mod.parseModule(Context);
199 if (!ModuleOrErr) {
201 SMDiagnostic Err = SMDiagnostic(Mod.getModuleIdentifier(),
202 SourceMgr::DK_Error, EIB.message());
203 Err.print("ThinLTO", errs());
204 });
206 }
207 if (!Lazy)
209 return std::move(*ModuleOrErr);
210}
211
212static void
216 bool ClearDSOLocalOnDeclarations) {
217 auto Loader = [&](StringRef Identifier) {
218 auto &Input = ModuleMap[Identifier];
220 true, true);
221 };
222
223 FunctionImporter Importer(Index, Loader, ClearDSOLocalOnDeclarations);
225 if (!Result) {
227 SMDiagnostic Err = SMDiagnostic(TheModule.getModuleIdentifier(),
228 SourceMgr::DK_Error, EIB.message());
229 Err.print("ThinLTO", errs());
230 });
232 }
233
235}
236
238 unsigned OptLevel, bool Freestanding,
240 std::optional PGOOpt;
245
248 SI.registerCallbacks(PIC, &MAM);
253
254 std::unique_ptr TLII(
256 if (Freestanding)
257 TLII->disableAllFunctions();
259
260
266
268
270
271 switch (OptLevel) {
272 default:
274 case 0:
276 break;
277 case 1:
279 break;
280 case 2:
282 break;
283 case 3:
285 break;
286 }
287
289
291}
292
293static void
296 for (const auto &Sym : File.symbols()) {
297 if (Sym.isUsed())
299 }
300}
301
302
305 const Triple &TheTriple,
307
308
309 for (const auto &Sym : File.symbols()) {
313 }
314}
315
319 const Triple &TheTriple) {
322 GUIDPreservedSymbols);
323 return GUIDPreservedSymbols;
324}
325
329
330
331 {
334
335
336 if (TM.addPassesToEmitFile(PM, OS, nullptr, CodeGenFileType::ObjectFile,
337 true))
339
340
341 PM.run(TheModule);
342 }
343 return std::make_unique(
344 std::move(OutputBuffer), false);
345}
346
347namespace {
348
349class ModuleCacheEntry {
351
352public:
353
354
355
356 ModuleCacheEntry(
360 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
361 const GVSummaryMapTy &DefinedGVSummaries, unsigned OptLevel,
363 if (CachePath.empty())
364 return;
365
366 if (.modulePaths().count(ModuleID))
367
368 return;
369
370 if (all_of(Index.getModuleHash(ModuleID),
371 [](uint32_t V) { return V == 0; }))
372
373 return;
374
378 Conf.CPU = TMBuilder.MCpu;
383 std::string Key =
385 ResolvedODR, DefinedGVSummaries);
386
387
388
390 }
391
392
393 StringRef getEntryPath() { return EntryPath; }
394
395
397 if (EntryPath.empty())
398 return std::error_code();
402 if (!FDOrErr)
405 *FDOrErr, EntryPath, -1, false);
407 return MBOrErr;
408 }
409
410
412 if (EntryPath.empty())
413 return;
414
419 }))
421 EntryPath,
423 }
424};
425}
426
427static std::unique_ptr
435 bool DisableCodeGen, StringRef SaveTempsDir,
436 bool Freestanding, unsigned OptLevel, unsigned count,
437 bool DebugPassManager) {
438
439 bool SingleModule = (ModuleMap.size() == 1);
440
441
442
443 bool ClearDSOLocalOnDeclarations =
444 TM.getTargetTriple().isOSBinFormatELF() &&
447
448 if (!SingleModule) {
449 promoteModule(TheModule, Index, ClearDSOLocalOnDeclarations);
450
451
453
454
456 }
457
458
459
460 if (!ExportList.empty() || !GUIDPreservedSymbols.empty()) {
461
463 }
464
465
467
468 if (!SingleModule)
470 ClearDSOLocalOnDeclarations);
471
472
473
474
476 false);
477
478
480
481 optimizeModule(TheModule, TM, OptLevel, Freestanding, DebugPassManager,
482 &Index);
483
485
486 if (DisableCodeGen) {
487
489 {
494 }
495 return std::make_unique(
496 std::move(OutputBuffer), false);
497 }
498
500}
501
502
503
504
505
506
509 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>>
510 &ResolvedODR,
513 &PrevailingCopy) {
514
516 const auto &Prevailing = PrevailingCopy.find(GUID);
517
518 if (Prevailing == PrevailingCopy.end())
519 return true;
520 return Prevailing->second == S;
521 };
522
523 auto recordNewLinkage = [&](StringRef ModuleIdentifier,
526 ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
527 };
528
529
532 GUIDPreservedSymbols);
533}
534
535
537 const Triple &TheTriple) {
538 if (TMBuilder.MCpu.empty())
540 TMBuilder.TheTriple = std::move(TheTriple);
541}
542
545
547 if (!InputOrError)
549 toString(InputOrError.takeError()));
550
551 auto TripleStr = (*InputOrError)->getTargetTriple();
552 Triple TheTriple(TripleStr);
553
554 if (Modules.empty())
556 else if (TMBuilder.TheTriple != TheTriple) {
559 "supported");
561 }
562
563 Modules.emplace_back(std::move(*InputOrError));
564}
565
568}
569
571
572
573
575}
576
577
579 std::string ErrMsg;
580 const Target *TheTarget =
582 if (!TheTarget) {
584 }
585
586
589 std::string FeatureStr = Features.getString();
590
591 std::unique_ptr TM(
593 RelocModel, std::nullopt, CGOptLevel));
594 assert(TM && "Cannot create target machine");
595
596 return TM;
597}
598
599
600
601
602
604 std::unique_ptr CombinedIndex =
605 std::make_unique(false);
606 for (auto &Mod : Modules) {
607 auto &M = Mod->getSingleBitcodeModule();
608 if (Error Err = M.readSummary(*CombinedIndex, Mod->getName())) {
609
611 std::move(Err), errs(),
612 "error: can't create module summary index for buffer: ");
613 return nullptr;
614 }
615 }
616 return CombinedIndex;
617}
618
619namespace {
620struct IsExported {
623
624 IsExported(
627 : ExportLists(ExportLists), GUIDPreservedSymbols(GUIDPreservedSymbols) {}
628
630 const auto &ExportList = ExportLists.find(ModuleIdentifier);
631 return (ExportList != ExportLists.end() && ExportList->second.count(VI)) ||
632 GUIDPreservedSymbols.count(VI.getGUID());
633 }
634};
635
636struct IsPrevailing {
639 &PrevailingCopy)
640 : PrevailingCopy(PrevailingCopy) {}
641
643 const auto &Prevailing = PrevailingCopy.find(GUID);
644
645 if (Prevailing == PrevailingCopy.end())
646 return true;
647 return Prevailing->second == S;
648 };
649};
650}
651
655
656
657
660 };
662 true);
663}
664
665
666
667
668
671 auto ModuleCount = Index.modulePaths().size();
673
674
676 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
677
678
681
682
684
685
687
688
691
692
696 IsPrevailing(PrevailingCopy), ImportLists,
697 ExportLists);
698
699
702 PrevailingCopy);
703
705 ModuleToDefinedGVSummaries[ModuleIdentifier],
706 false);
707
708
709
711 Index, IsExported(ExportLists, GUIDPreservedSymbols),
712 IsPrevailing(PrevailingCopy));
713
714
715 promoteModule(TheModule, Index, false);
716}
717
718
719
720
725 auto ModuleCount = Index.modulePaths().size();
726
727
729 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
730
731
734
736
737
739
740
743
744
748 IsPrevailing(PrevailingCopy), ImportLists,
749 ExportLists);
751
752
754 false);
755}
756
757
758
759
764 auto ModuleCount = Index.modulePaths().size();
766
767
769 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
770
771
774
776
777
779
780
783
784
788 IsPrevailing(PrevailingCopy), ImportLists,
789 ExportLists);
790
792 ModuleIdentifier, ModuleToDefinedGVSummaries,
793 ImportLists[ModuleIdentifier], ModuleToSummariesForIndex, DecSummaries);
794}
795
796
797
798
802 auto ModuleCount = Index.modulePaths().size();
804
805
807 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
808
809
812
814
815
817
818
821
822
826 IsPrevailing(PrevailingCopy), ImportLists,
827 ExportLists);
828
829
830
831
835 ModuleIdentifier, ModuleToDefinedGVSummaries,
836 ImportLists[ModuleIdentifier], ModuleToSummariesForIndex, DecSummaries);
837
839 ModuleToSummariesForIndex))
841 " to save imports lists\n");
842}
843
844
845
846
847
852 auto ModuleCount = Index.modulePaths().size();
854
855
856 auto GUIDPreservedSymbols =
858
860
861
863 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
864
865
867
868
871
872
876 IsPrevailing(PrevailingCopy), ImportLists,
877 ExportLists);
878 auto &ExportList = ExportLists[ModuleIdentifier];
879
880
881
882 if (ExportList.empty() && GUIDPreservedSymbols.empty())
883 return;
884
885
888 PrevailingCopy);
889
890
891
893 Index, IsExported(ExportLists, GUIDPreservedSymbols),
894 IsPrevailing(PrevailingCopy));
895
896
897 promoteModule(TheModule, Index, false);
898
899
901 ModuleToDefinedGVSummaries[ModuleIdentifier],
902 false);
903
905 ModuleToDefinedGVSummaries[ModuleIdentifier]);
906}
907
908
909
910
913
914
916 DebugPassManager, nullptr);
917}
918
919
920
921
922std::string
928 Twine(count) + "." + ArchName + ".thinlto.o");
929 OutputPath.c_str();
932
933
934 if (!CacheEntryPath.empty()) {
935
937 if (!Err)
938 return std::string(OutputPath);
939
941 if (!Err)
942 return std::string(OutputPath);
943
944
945
946 errs() << "remark: can't link or copy from cached entry '" << CacheEntryPath
947 << "' to '" << OutputPath << "'\n";
948 }
949
950 std::error_code Err;
952 if (Err)
955 return std::string(OutputPath);
956}
957
958
964 });
965
966 assert(ProducedBinaries.empty() && "The generator should not be reused");
967 if (SavedObjectsDirectoryPath.empty())
968 ProducedBinaries.resize(Modules.size());
969 else {
971 bool IsDir;
973 if (!IsDir)
975 ProducedBinaryFiles.resize(Modules.size());
976 }
977
978 if (CodeGenOnly) {
979
982 for (auto &Mod : Modules) {
986
987
989 false);
990
991
993 if (SavedObjectsDirectoryPath.empty())
994 ProducedBinaries[count] = std::move(OutputBuffer);
995 else
996 ProducedBinaryFiles[count] =
999 }
1000
1001 return;
1002 }
1003
1004
1006
1007
1008 if (!SaveTempsDir.empty()) {
1009 auto SaveTempPath = SaveTempsDir + "index.bc";
1010 std::error_code EC;
1012 if (EC)
1014 " to save optimized bitcode\n");
1016 }
1017
1018
1019
1021 auto ModuleCount = Modules.size();
1022
1023
1025 Index->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
1026
1027
1028
1030 for (const auto &M : Modules)
1032 GUIDPreservedSymbols);
1033
1034
1035 for (const auto &M : Modules)
1037
1038
1040
1041
1042
1043
1045 Index->setWithWholeProgramVisibility();
1046
1047
1049 false,
1050
1051
1052 {},
1053 {});
1054
1055
1056
1057
1058 std::map<ValueInfo, std::vector> LocalWPDTargetsMap;
1059 std::setGlobalValue::GUID ExportedGUIDs;
1061 for (auto GUID : ExportedGUIDs)
1062 GUIDPreservedSymbols.insert(GUID);
1063
1064
1067
1068
1069
1073 IsPrevailing(PrevailingCopy), ImportLists,
1074 ExportLists);
1075
1076
1077
1078
1079
1081
1082
1083
1085 PrevailingCopy);
1086
1087
1088
1089
1091 IsExported(ExportLists, GUIDPreservedSymbols),
1092 LocalWPDTargetsMap);
1094 *Index, IsExported(ExportLists, GUIDPreservedSymbols),
1095 IsPrevailing(PrevailingCopy));
1096
1098
1099
1100
1101
1102 for (auto &Module : Modules) {
1104 ExportLists[ModuleIdentifier];
1105 ImportLists[ModuleIdentifier];
1106 ResolvedODR[ModuleIdentifier];
1107 ModuleToDefinedGVSummaries[ModuleIdentifier];
1108 }
1109
1110 std::vector<BitcodeModule *> ModulesVec;
1111 ModulesVec.reserve(Modules.size());
1112 for (auto &Mod : Modules)
1113 ModulesVec.push_back(&Mod->getSingleBitcodeModule());
1115
1118
1119 TimeTraceScopeExit.release();
1120
1121
1122 {
1124 for (auto IndexCount : ModulesOrdering) {
1125 auto &Mod = Modules[IndexCount];
1127 auto ModuleIdentifier = Mod->getName();
1128 auto &ExportList = ExportLists[ModuleIdentifier];
1129
1130 auto &DefinedGVSummaries = ModuleToDefinedGVSummaries[ModuleIdentifier];
1131
1132
1133 ModuleCacheEntry CacheEntry(CacheOptions.Path, *Index, ModuleIdentifier,
1134 ImportLists[ModuleIdentifier], ExportList,
1135 ResolvedODR[ModuleIdentifier],
1136 DefinedGVSummaries, OptLevel, Freestanding,
1137 TMBuilder);
1138 auto CacheEntryPath = CacheEntry.getEntryPath();
1139
1140 {
1141 auto ErrOrBuffer = CacheEntry.tryLoadingBuffer();
1142 LLVM_DEBUG(dbgs() << "Cache " << (ErrOrBuffer ? "hit" : "miss")
1143 << " '" << CacheEntryPath << "' for buffer "
1144 << count << " " << ModuleIdentifier << "\n");
1145
1146 if (ErrOrBuffer) {
1147
1148 if (SavedObjectsDirectoryPath.empty())
1149 ProducedBinaries[count] = std::move(ErrOrBuffer.get());
1150 else
1152 count, CacheEntryPath, *ErrOrBuffer.get());
1153 return;
1154 }
1155 }
1156
1163 if (!DiagFileOrErr) {
1164 errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
1166 "remarks");
1167 }
1168
1169
1171 false);
1172
1173
1175
1176 auto &ImportList = ImportLists[ModuleIdentifier];
1177
1179 *TheModule, *Index, ModuleMap, *TMBuilder.create(), ImportList,
1180 ExportList, GUIDPreservedSymbols,
1181 ModuleToDefinedGVSummaries[ModuleIdentifier], CacheOptions,
1182 DisableCodeGen, SaveTempsDir, Freestanding, OptLevel, count,
1183 DebugPassManager);
1184
1185
1186 CacheEntry.write(*OutputBuffer);
1187
1188 if (SavedObjectsDirectoryPath.empty()) {
1189
1190 if (!CacheEntryPath.empty()) {
1191
1192
1193
1194
1195
1196
1197 auto ReloadedBufferOrErr = CacheEntry.tryLoadingBuffer();
1198 if (auto EC = ReloadedBufferOrErr.getError()) {
1199
1200 errs() << "remark: can't reload cached file '" << CacheEntryPath
1201 << "': " << EC.message() << "\n";
1202 } else {
1203 OutputBuffer = std::move(*ReloadedBufferOrErr);
1204 }
1205 }
1206 ProducedBinaries[count] = std::move(OutputBuffer);
1207 return;
1208 }
1210 count, CacheEntryPath, *OutputBuffer);
1211 }, IndexCount);
1212 }
1213 }
1214
1216
1217
1221}
This file provides a bitcode writing pass.
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[]
This is the interface to build a ModuleSummaryIndex for a module.
CGSCCAnalysisManager CGAM
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
PassInstrumentationCallbacks PIC
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
This header defines classes/functions to handle pass execution timing information with interfaces for...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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...
static void crossImportIntoModule(Module &TheModule, const ModuleSummaryIndex &Index, StringMap< lto::InputFile * > &ModuleMap, const FunctionImporter::ImportMapTy &ImportList, bool ClearDSOLocalOnDeclarations)
static void computeDeadSymbolsInIndex(ModuleSummaryIndex &Index, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols)
static StringMap< lto::InputFile * > generateModuleMap(std::vector< std::unique_ptr< lto::InputFile > > &Modules)
static void initTMBuilder(TargetMachineBuilder &TMBuilder, const Triple &TheTriple)
static void resolvePrevailingInIndex(ModuleSummaryIndex &Index, StringMap< std::map< GlobalValue::GUID, GlobalValue::LinkageTypes > > &ResolvedODR, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols, const DenseMap< GlobalValue::GUID, const GlobalValueSummary * > &PrevailingCopy)
Resolve prevailing symbols.
static void computePrevailingCopies(const ModuleSummaryIndex &Index, DenseMap< GlobalValue::GUID, const GlobalValueSummary * > &PrevailingCopy)
static void saveTempBitcode(const Module &TheModule, StringRef TempDir, unsigned count, StringRef Suffix)
static void verifyLoadedModule(Module &TheModule)
Verify the module and strip broken debug info.
static void addUsedSymbolToPreservedGUID(const lto::InputFile &File, DenseSet< GlobalValue::GUID > &PreservedGUID)
static std::unique_ptr< MemoryBuffer > ProcessThinLTOModule(Module &TheModule, ModuleSummaryIndex &Index, StringMap< lto::InputFile * > &ModuleMap, TargetMachine &TM, const FunctionImporter::ImportMapTy &ImportList, const FunctionImporter::ExportSetTy &ExportList, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols, const GVSummaryMapTy &DefinedGlobals, const ThinLTOCodeGenerator::CachingOptions &CacheOptions, bool DisableCodeGen, StringRef SaveTempsDir, bool Freestanding, unsigned OptLevel, unsigned count, bool DebugPassManager)
static cl::opt< int > ThreadCount("threads", cl::init(0))
static std::unique_ptr< MemoryBuffer > codegenModule(Module &TheModule, TargetMachine &TM)
static void optimizeModule(Module &TheModule, TargetMachine &TM, unsigned OptLevel, bool Freestanding, bool DebugPassManager, ModuleSummaryIndex *Index)
static void computeGUIDPreservedSymbols(const lto::InputFile &File, const StringSet<> &PreservedSymbols, const Triple &TheTriple, DenseSet< GlobalValue::GUID > &GUIDs)
static std::unique_ptr< Module > loadModuleFromInput(lto::InputFile *Input, LLVMContext &Context, bool Lazy, bool IsImporting)
static const GlobalValueSummary * getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList)
static void promoteModule(Module &TheModule, const ModuleSummaryIndex &Index, bool ClearDSOLocalOnDeclarations)
A container for analyses that lazily runs them and caches their results.
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
iterator find(const_arg_type_t< KeyT > Val)
void reserve(size_type NumEntries)
Grow the densemap so that it can contain at least NumEntries items before resizing again.
Implements a dense probed hash-table based set.
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.
Represents either an error or a value T.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
The map maintains the list of imports.
The function importer is automatically importing function from other modules based on the provided su...
Expected< bool > importFunctions(Module &M, const ImportMapTy &ImportList)
Import functions in Module M based on the supplied import list.
Function and variable summary information to aid decisions and implementation of importing.
static bool isAvailableExternallyLinkage(LinkageTypes Linkage)
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
bool isWeakForLinker() const
std::string getGlobalIdentifier() const
Return the modified name for this global value suitable to be used as the key for a global lookup (e....
LinkageTypes
An enumeration for the kinds of linkage for global values.
@ ExternalLinkage
Externally visible function.
This is an important class for using LLVM in a threaded context.
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...
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
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.
LLVMContext & getContext() const
Get the global data context.
StringRef getName() const
Get a short "name" for the module.
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
PIELevel::Level getPIELevel() const
Returns the PIE level (small or large model)
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.
void registerLoopAnalyses(LoopAnalysisManager &LAM)
Registers all available loop analysis passes.
void crossRegisterProxies(LoopAnalysisManager &LAM, FunctionAnalysisManager &FAM, CGSCCAnalysisManager &CGAM, ModuleAnalysisManager &MAM, MachineFunctionAnalysisManager *MFAM=nullptr)
Cross register the analysis managers through their proxies.
ModulePassManager buildThinLTODefaultPipeline(OptimizationLevel Level, const ModuleSummaryIndex *ImportSummary)
Build a 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.
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs)
Run all of the passes in this manager over the given unit of IR.
Tunable parameters for passes in the default pipelines.
bool SLPVectorization
Tuning option to enable/disable slp loop vectorization, set based on opt level.
bool LoopVectorization
Tuning option to enable/disable loop vectorization, set based on opt level.
Analysis providing profile information.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
A non-threaded implementation.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class provides an interface to register all the standard pass instrumentations and manages their...
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
bool contains(StringRef Key) const
contains - Return true if the element is in the map, false otherwise.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
StringSet - A wrapper for StringMap that provides set-like functionality.
std::pair< typename Base::iterator, bool > insert(StringRef key)
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.
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, CodeGenOptLevel OL=CodeGenOptLevel::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.
auto async(Function &&F, Args &&...ArgList)
Asynchronous submission of a task to the pool.
Triple - Helper class for working with autoconf configuration names.
std::string merge(const Triple &Other) const
Merge target triples.
StringRef getArchName() const
Get the architecture (first) component of the triple.
bool isCompatibleWith(const Triple &Other) const
Test whether target triples are compatible.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
PassManager manages ModulePassManagers.
bool run(Module &M)
run - Execute all of the passes scheduled for execution.
static Expected< std::unique_ptr< InputFile > > create(MemoryBufferRef Object)
Create an InputFile.
BitcodeModule & getSingleBitcodeModule()
A raw_ostream that writes to a file descriptor.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an SmallVector or SmallString.
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 internalize(Module &Module, ModuleSummaryIndex &Index, const lto::InputFile &File)
Perform internalization.
void gatherImportedSummariesForModule(Module &Module, ModuleSummaryIndex &Index, ModuleToSummariesForIndexTy &ModuleToSummariesForIndex, GVSummaryPtrSet &DecSummaries, const lto::InputFile &File)
Compute the list of summaries and the subset of declaration summaries needed for importing into modul...
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.
initializer< Ty > init(const Ty &Val)
StringLiteral getThinLTODefaultCPU(const Triple &TheTriple)
std::vector< int > generateModulesOrdering(ArrayRef< BitcodeModule * > R)
Produces a container ordering for optimal multi-threaded processing.
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.
std::error_code closeFile(file_t &F)
Close the file object.
bool exists(const basic_file_status &status)
Does file exist?
@ OF_UpdateAtime
Force files Atime to be updated on access.
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.
std::error_code copy_file(const Twine &From, const Twine &To)
Copy the contents of From to To.
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?
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
This is an optimization pass for GlobalISel generic memory operations.
ThreadPoolStrategy heavyweight_hardware_concurrency(unsigned ThreadCount=0)
Returns a thread strategy for tasks requiring significant memory or other resources.
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
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"))
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
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)
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...
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
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.
void 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...
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.
bool hasWholeProgramVisibility(bool WholeProgramVisibilityEnabledInLTO)
void writeIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out, const ModuleToSummariesForIndexTy *ModuleToSummariesForIndex=nullptr, const GVSummaryPtrSet *DecSummaries=nullptr)
Write the specified module summary index to the given raw output stream, where it will be written in ...
void ComputeCrossModuleImport(const ModuleSummaryIndex &Index, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, FunctionImporter::ImportListsTy &ImportLists, DenseMap< StringRef, FunctionImporter::ExportSetTy > &ExportLists)
Compute all the imports and exports for every module in the Index.
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...
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
void updatePublicTypeTestCalls(Module &M, bool WholeProgramVisibilityEnabledInLTO)
Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue)
bool timeTraceProfilerEnabled()
Is the time trace profiler enabled, i.e. initialized?
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Error writeToOutput(StringRef OutputFileName, std::function< Error(raw_ostream &)> Write)
This helper creates an output stream and then passes it to Write.
bool AreStatisticsEnabled()
Check if statistics are enabled.
cl::opt< bool > RemarksWithHotness("lto-pass-remarks-with-hotness", cl::desc("With PGO, include profile count in optimization remarks"), cl::Hidden)
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.
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.
@ Mod
The access may modify the value stored in memory.
void PrintStatistics()
Print statistics to the file returned by CreateInfoOutputFile().
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 ...
std::unordered_set< GlobalValueSummary * > GVSummaryPtrSet
A set of global value summary pointers.
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...
void gatherImportedSummariesForModule(StringRef ModulePath, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, const FunctionImporter::ImportMapTy &ImportList, ModuleToSummariesForIndexTy &ModuleToSummariesForIndex, GVSummaryPtrSet &DecSummaries)
Compute the set of summaries needed for a ThinLTO backend compilation of ModulePath.
std::map< std::string, GVSummaryMapTy, std::less<> > ModuleToSummariesForIndexTy
Map of a module name to the GUIDs and summaries we will import from that module.
DiagnosticSeverity
Defines the different supported severity of a diagnostic.
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.
std::string computeLTOCacheKey(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 DenseSet< GlobalValue::GUID > &CfiFunctionDefs={}, const DenseSet< GlobalValue::GUID > &CfiFunctionDecls={})
Computes a unique hash for the Module considering the current list of export/import and other global ...
const char * toString(DWARFSectionKind Kind)
std::error_code errorToErrorCode(Error Err)
Helper for converting an ECError to a std::error_code.
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.
Error EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename, const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex)
Emit into OutputFilename the files module ModulePath will import from.
bool verifyModule(const Module &M, raw_ostream *OS=nullptr, bool *BrokenDebugInfo=nullptr)
Check a module for errors.
TimeTraceProfilerEntry * timeTraceProfilerBegin(StringRef Name, StringRef Detail)
Manually begin a time section, with the given Name and Detail.
void updateVCallVisibilityInIndex(ModuleSummaryIndex &Index, bool WholeProgramVisibilityEnabledInLTO, const DenseSet< GlobalValue::GUID > &DynamicExportSymbols, const DenseSet< GlobalValue::GUID > &VisibleToRegularObjSymbols)
If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...
void thinLTOFinalizeInModule(Module &TheModule, const GVSummaryMapTy &DefinedGlobals, bool PropagateAttrs)
Based on the information recorded in the summaries during global summary-based analysis:
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
static const Target * lookupTarget(StringRef Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.
Helper to gather options relevant to the target machine creation.
std::unique_ptr< TargetMachine > create() const
std::optional< Reloc::Model > RelocModel
CodeGenOptLevel CGOptLevel
CachePruningPolicy Policy
Struct that holds a reference to a particular GUID in a global value summary.
std::vector< std::string > MAttrs
CodeGenOptLevel CGOptLevel
std::optional< Reloc::Model > RelocModel
bool Freestanding
Flag to indicate that the optimizer should not assume builtins are present on the target.