25#include "llvm/Config/llvm-config.h"
50#include "llvm/Support/VCSRevision.h"
64using namespace object;
66#define DEBUG_TYPE "lto"
72 cl::desc(
"Dump the SCCs in the ThinLTO index's callgraph"));
78 cl::desc(
"Enable global value internalization in LTO"));
95 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
97 const std::set<GlobalValue::GUID> &CfiFunctionDefs,
98 const std::set<GlobalValue::GUID> &CfiFunctionDecls) {
106 Hasher.
update(LLVM_VERSION_STRING);
108 Hasher.
update(LLVM_REVISION);
116 auto AddUnsigned = [&](
unsigned I) {
126 auto AddUint8 = [&](
const uint8_t
I) {
150 AddUnsigned(
static_cast<int>(Conf.
CGOptLevel));
151 AddUnsigned(
static_cast<int>(Conf.
CGFileType));
161 auto ModHash =
Index.getModuleHash(ModuleID);
164 std::vector<std::pair<uint64_t, uint8_t>> ExportsGUID;
165 ExportsGUID.reserve(ExportList.
size());
166 for (
const auto &[VI, ExportType] : ExportList)
167 ExportsGUID.push_back(
168 std::make_pair(VI.getGUID(),
static_cast<uint8_t
>(ExportType)));
172 for (
auto [GUID, ExportType] : ExportsGUID) {
175 AddUint8(ExportType);
182 struct ImportModule {
183 ImportMapIteratorTy ModIt;
186 StringRef getIdentifier()
const {
return ModIt->getFirst(); }
188 return ModIt->second;
194 std::vector<ImportModule> ImportModulesVector;
195 ImportModulesVector.reserve(ImportList.
size());
197 for (ImportMapIteratorTy It = ImportList.
begin(); It != ImportList.
end();
199 ImportModulesVector.push_back({It,
Index.getModule(It->getFirst())});
204 [](
const ImportModule &Lhs,
const ImportModule &Rhs) ->
bool {
205 return Lhs.getHash() < Rhs.getHash();
207 std::vector<std::pair<uint64_t, uint8_t>> ImportedGUIDs;
208 for (
const ImportModule &Entry : ImportModulesVector) {
209 auto ModHash = Entry.getHash();
212 AddUint64(Entry.getFunctions().size());
214 ImportedGUIDs.clear();
215 for (
auto &[Fn, ImportType] : Entry.getFunctions())
216 ImportedGUIDs.push_back(std::make_pair(Fn, ImportType));
218 for (
auto &[GUID,
Type] : ImportedGUIDs) {
225 for (
auto &Entry : ResolvedODR) {
234 std::set<GlobalValue::GUID> UsedCfiDefs;
235 std::set<GlobalValue::GUID> UsedCfiDecls;
238 std::set<GlobalValue::GUID> UsedTypeIds;
241 if (CfiFunctionDefs.count(ValueGUID))
242 UsedCfiDefs.insert(ValueGUID);
243 if (CfiFunctionDecls.count(ValueGUID))
244 UsedCfiDecls.insert(ValueGUID);
249 AddUnsigned(GS->getVisibility());
250 AddUnsigned(GS->isLive());
251 AddUnsigned(GS->canAutoHide());
253 AddUnsigned(VI.isDSOLocal(
Index.withDSOLocalPropagation()));
254 AddUsedCfiGlobal(VI.getGUID());
256 if (
auto *GVS = dyn_cast<GlobalVarSummary>(GS)) {
257 AddUnsigned(GVS->maybeReadOnly());
258 AddUnsigned(GVS->maybeWriteOnly());
260 if (
auto *FS = dyn_cast<FunctionSummary>(GS)) {
261 for (
auto &TT : FS->type_tests())
262 UsedTypeIds.insert(TT);
263 for (
auto &TT : FS->type_test_assume_vcalls())
264 UsedTypeIds.insert(TT.GUID);
265 for (
auto &TT : FS->type_checked_load_vcalls())
266 UsedTypeIds.insert(TT.GUID);
267 for (
auto &TT : FS->type_test_assume_const_vcalls())
268 UsedTypeIds.insert(TT.VFunc.GUID);
269 for (
auto &TT : FS->type_checked_load_const_vcalls())
270 UsedTypeIds.insert(TT.VFunc.GUID);
271 for (
auto &ET : FS->calls()) {
272 AddUnsigned(ET.first.isDSOLocal(
Index.withDSOLocalPropagation()));
273 AddUsedCfiGlobal(ET.first.getGUID());
280 for (
auto &GS : DefinedGlobals) {
284 AddUsedCfiGlobal(GS.first);
285 AddUsedThings(GS.second);
290 for (
const ImportModule &ImpM : ImportModulesVector)
291 for (
auto &[GUID, UnusedImportType] : ImpM.getFunctions()) {
293 Index.findSummaryInModule(GUID, ImpM.getIdentifier());
297 if (
auto *AS = dyn_cast_or_null<AliasSummary>(S))
298 AddUsedThings(AS->getBaseObject());
304 AddUnsigned(S.TTRes.TheKind);
305 AddUnsigned(S.TTRes.SizeM1BitWidth);
307 AddUint64(S.TTRes.AlignLog2);
308 AddUint64(S.TTRes.SizeM1);
309 AddUint64(S.TTRes.BitMask);
310 AddUint64(S.TTRes.InlineBits);
312 AddUint64(S.WPDRes.size());
313 for (
auto &WPD : S.WPDRes) {
314 AddUnsigned(WPD.first);
315 AddUnsigned(WPD.second.TheKind);
316 AddString(WPD.second.SingleImplName);
318 AddUint64(WPD.second.ResByArg.size());
319 for (
auto &ByArg : WPD.second.ResByArg) {
320 AddUint64(ByArg.first.size());
323 AddUnsigned(ByArg.second.TheKind);
324 AddUint64(ByArg.second.Info);
325 AddUnsigned(ByArg.second.Byte);
326 AddUnsigned(ByArg.second.Bit);
333 auto TidIter =
Index.typeIds().equal_range(TId);
334 for (
auto It = TidIter.first; It != TidIter.second; ++It)
335 AddTypeIdSummary(It->second.first, It->second.second);
338 AddUnsigned(UsedCfiDefs.size());
339 for (
auto &V : UsedCfiDefs)
342 AddUnsigned(UsedCfiDecls.size());
343 for (
auto &V : UsedCfiDecls)
349 Hasher.
update(FileOrErr.get()->getBuffer());
354 Hasher.
update(FileOrErr.get()->getBuffer());
359 Key = toHex(Hasher.
result());
371 C.VisibilityScheme ==
Config::ELF ? VI.getELFVisibility()
373 for (
auto &S : VI.getSummaryList()) {
388 if (isPrevailing(VI.getGUID(), S.get())) {
401 S->setCanAutoHide(VI.canAutoHide() &&
402 !GUIDPreservedSymbols.
count(VI.getGUID()));
405 Visibility = S->getVisibility();
408 else if (!isa<AliasSummary>(S.get()) &&
409 !GlobalInvolvedWithAlias.
count(S.get()))
416 S->setVisibility(Visibility);
418 if (S->linkage() != OriginalLinkage)
419 recordNewLinkage(S->modulePath(), VI.getGUID(), S->linkage());
423 for (
auto &S : VI.getSummaryList()) {
428 S->setVisibility(Visibility);
451 for (
auto &S :
I.second.SummaryList)
452 if (
auto AS = dyn_cast<AliasSummary>(S.get()))
453 GlobalInvolvedWithAlias.
insert(&AS->getAliasee());
457 GlobalInvolvedWithAlias, isPrevailing,
458 recordNewLinkage, GUIDPreservedSymbols);
465 auto ExternallyVisibleCopies =
467 [](
const std::unique_ptr<GlobalValueSummary> &Summary) {
468 return !GlobalValue::isLocalLinkage(Summary->linkage());
471 for (
auto &S : VI.getSummaryList()) {
474 if (isExported(S->modulePath(), VI)) {
533 if (isPrevailing(VI.getGUID(), S.get()) && ExternallyVisibleCopies == 1)
554 std::unique_ptr<InputFile> File(
new InputFile);
560 File->TargetTriple = FOrErr->TheReader.getTargetTriple();
561 File->SourceFileName = FOrErr->TheReader.getSourceFileName();
562 File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts();
563 File->DependentLibraries = FOrErr->TheReader.getDependentLibraries();
564 File->ComdatTable = FOrErr->TheReader.getComdatTable();
566 for (
unsigned I = 0;
I != FOrErr->Mods.size(); ++
I) {
567 size_t Begin = File->Symbols.size();
569 FOrErr->TheReader.module_symbols(
I))
572 if (
Sym.isGlobal() && !
Sym.isFormatSpecific())
573 File->Symbols.push_back(
Sym);
574 File->ModuleSymIndices.push_back({Begin, File->Symbols.size()});
577 File->Mods = FOrErr->Mods;
578 File->Strtab = std::move(FOrErr->Strtab);
579 return std::move(File);
583 return Mods[0].getModuleIdentifier();
587 assert(Mods.size() == 1 &&
"Expect only one bitcode module");
591LTO::RegularLTOState::RegularLTOState(
unsigned ParallelCodeGenParallelismLevel,
593 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
594 Ctx(Conf), CombinedModule(
std::make_unique<
Module>(
"ld-temp.o", Ctx)),
595 Mover(
std::make_unique<
IRMover>(*CombinedModule)) {
599LTO::ThinLTOState::ThinLTOState(
ThinBackend Backend)
600 : Backend(Backend), CombinedIndex(
false) {
607 unsigned ParallelCodeGenParallelismLevel,
LTOKind LTOMode)
609 RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),
611 GlobalResolutions(
std::make_optional<
StringMap<GlobalResolution>>()),
621 unsigned Partition,
bool InSummary) {
622 auto *ResI = Res.
begin();
623 auto *ResE = Res.
end();
625 const Triple TT(RegularLTO.CombinedModule->getTargetTriple());
630 auto &GlobalRes = (*GlobalResolutions)[
Sym.getName()];
631 GlobalRes.UnnamedAddr &=
Sym.isUnnamedAddr();
633 assert(!GlobalRes.Prevailing &&
634 "Multiple prevailing defs are not allowed");
635 GlobalRes.Prevailing =
true;
636 GlobalRes.IRName = std::string(
Sym.getIRName());
637 }
else if (!GlobalRes.Prevailing && GlobalRes.IRName.empty()) {
644 GlobalRes.IRName = std::string(
Sym.getIRName());
658 if (GlobalRes.IRName !=
Sym.getIRName()) {
659 GlobalRes.Partition = GlobalResolution::External;
660 GlobalRes.VisibleOutsideSummary =
true;
668 (GlobalRes.Partition != GlobalResolution::Unknown &&
669 GlobalRes.Partition != Partition)) {
670 GlobalRes.Partition = GlobalResolution::External;
673 GlobalRes.Partition = Partition;
677 GlobalRes.VisibleOutsideSummary |=
688 auto ResI = Res.
begin();
693 OS <<
"-r=" << Path <<
',' <<
Sym.getName() <<
',';
710 assert(!CalledGetMaxTasks);
715 if (RegularLTO.CombinedModule->getTargetTriple().empty()) {
716 RegularLTO.CombinedModule->setTargetTriple(Input->getTargetTriple());
722 for (
unsigned I = 0;
I != Input->Mods.size(); ++
I)
723 if (
Error Err = addModule(*Input,
I, ResI, Res.
end()))
737 if (EnableSplitLTOUnit) {
741 if (*EnableSplitLTOUnit != LTOInfo->EnableSplitLTOUnit)
742 ThinLTO.CombinedIndex.setPartiallySplitLTOUnits();
744 EnableSplitLTOUnit = LTOInfo->EnableSplitLTOUnit;
749 !LTOInfo->UnifiedLTO)
750 return make_error<StringError>(
751 "unified LTO compilation must use "
752 "compatible bitcode modules (use -funified-lto)",
760 auto ModSyms = Input.module_symbols(ModI);
761 addModuleToGlobalRes(ModSyms, {ResI, ResE},
762 IsThinLTO ? ThinLTO.ModuleMap.size() + 1 : 0,
763 LTOInfo->HasSummary);
766 return addThinLTO(BM, ModSyms, ResI, ResE);
768 RegularLTO.EmptyCombinedModule =
false;
770 addRegularLTO(BM, ModSyms, ResI, ResE);
774 if (!LTOInfo->HasSummary)
775 return linkRegularLTO(std::move(*ModOrErr),
false);
781 RegularLTO.ModsWithSummaries.push_back(std::move(*ModOrErr));
797 std::set<const Comdat *> &NonPrevailingComdats) {
802 if (!NonPrevailingComdats.count(
C))
811 if (
auto GO = dyn_cast<GlobalObject>(&GV))
812 GO->setComdat(
nullptr);
822 RegularLTOState::AddedModule
Mod;
829 Mod.M = std::move(*MOrErr);
831 if (
Error Err =
M.materializeMetadata())
832 return std::move(Err);
839 if (
NamedMDNode *CfiFunctionsMD =
M.getNamedMetadata(
"cfi.functions"))
840 M.eraseNamedMetadata(CfiFunctionsMD);
848 if (GV.hasAppendingLinkage())
849 Mod.Keep.push_back(&GV);
852 for (
auto &GA :
M.aliases())
854 AliasedGlobals.
insert(GO);
863 auto MsymI = SymTab.
symbols().begin(), MsymE = SymTab.
symbols().end();
865 while (MsymI != MsymE) {
875 std::set<const Comdat *> NonPrevailingComdats;
885 if (
GlobalValue *GV = dyn_cast_if_present<GlobalValue *>(Msym)) {
887 if (
Sym.isUndefined())
889 Mod.Keep.push_back(GV);
900 }
else if (isa<GlobalObject>(GV) &&
901 (GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||
902 GV->hasAvailableExternallyLinkage()) &&
903 !AliasedGlobals.
count(cast<GlobalObject>(GV))) {
909 Mod.Keep.push_back(GV);
912 NonPrevailingComdats.insert(GV->getComdat());
913 cast<GlobalObject>(GV)->setComdat(
nullptr);
918 GV->setDSOLocal(
true);
919 if (GV->hasDLLImportStorageClass())
921 DefaultStorageClass);
923 }
else if (
auto *AS =
924 dyn_cast_if_present<ModuleSymbolTable::AsmSymbol *>(Msym)) {
927 NonPrevailingAsmSymbols.
insert(AS->first);
935 if (
Sym.isCommon()) {
938 auto &CommonRes = RegularLTO.Commons[std::string(
Sym.getIRName())];
939 CommonRes.Size = std::max(CommonRes.Size,
Sym.getCommonSize());
940 if (
uint32_t SymAlignValue =
Sym.getCommonAlignment()) {
941 CommonRes.Alignment =
942 std::max(
Align(SymAlignValue), CommonRes.Alignment);
948 if (!
M.getComdatSymbolTable().empty())
954 if (!
M.getModuleInlineAsm().empty()) {
955 std::string NewIA =
".lto_discard";
956 if (!NonPrevailingAsmSymbols.
empty()) {
960 if (!NonPrevailingAsmSymbols.
count(Alias))
963 NewIA +=
" " + llvm::join(NonPrevailingAsmSymbols,
", ");
966 M.setModuleInlineAsm(NewIA +
M.getModuleInlineAsm());
970 return std::move(
Mod);
973Error LTO::linkRegularLTO(RegularLTOState::AddedModule
Mod,
974 bool LivenessFromIndex) {
975 std::vector<GlobalValue *>
Keep;
977 if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->
getGUID())) {
978 if (
Function *
F = dyn_cast<Function>(GV)) {
979 if (DiagnosticOutputFile) {
980 if (
Error Err =
F->materialize())
985 <<
" not added to the combined module ");
999 RegularLTO.CombinedModule->getNamedValue(GV->
getName());
1006 return RegularLTO.Mover->move(std::move(
Mod.M),
Keep,
nullptr,
1019 if (!
Sym.getIRName().empty()) {
1030 return ThinLTO.PrevailingModuleForGUID[GUID] ==
1031 BM.getModuleIdentifier();
1040 if (!
Sym.getIRName().empty()) {
1044 assert(ThinLTO.PrevailingModuleForGUID[GUID] ==
1052 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(
1060 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(
1062 S->setDSOLocal(
true);
1068 if (!ThinLTO.ModuleMap.insert({BM.getModuleIdentifier(), BM}).second)
1069 return make_error<StringError>(
1070 "Expected at most one ThinLTO module per bitcode file",
1074 if (!ThinLTO.ModulesToCompile)
1075 ThinLTO.ModulesToCompile = ModuleMapType();
1091 CalledGetMaxTasks =
true;
1092 auto ModuleCount = ThinLTO.ModulesToCompile ? ThinLTO.ModulesToCompile->size()
1093 : ThinLTO.ModuleMap.size();
1094 return RegularLTO.ParallelCodeGenParallelismLevel + ModuleCount;
1099Error LTO::checkPartiallySplit() {
1100 if (!ThinLTO.CombinedIndex.partiallySplitLTOUnits())
1103 Function *TypeTestFunc = RegularLTO.CombinedModule->getFunction(
1105 Function *TypeCheckedLoadFunc = RegularLTO.CombinedModule->getFunction(
1107 Function *TypeCheckedLoadRelativeFunc =
1108 RegularLTO.CombinedModule->getFunction(
1113 if ((TypeTestFunc && !TypeTestFunc->
use_empty()) ||
1114 (TypeCheckedLoadFunc && !TypeCheckedLoadFunc->
use_empty()) ||
1115 (TypeCheckedLoadRelativeFunc &&
1116 !TypeCheckedLoadRelativeFunc->
use_empty()))
1117 return make_error<StringError>(
1118 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1123 for (
auto &
P : ThinLTO.CombinedIndex) {
1124 for (
auto &S :
P.second.SummaryList) {
1125 auto *FS = dyn_cast<FunctionSummary>(S.get());
1128 if (!FS->type_test_assume_vcalls().empty() ||
1129 !FS->type_checked_load_vcalls().empty() ||
1130 !FS->type_test_assume_const_vcalls().empty() ||
1131 !FS->type_checked_load_const_vcalls().empty() ||
1132 !FS->type_tests().empty())
1133 return make_error<StringError>(
1134 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1145 for (
auto &Res : *GlobalResolutions) {
1148 if (Res.second.IRName.empty())
1154 if (Res.second.VisibleOutsideSummary && Res.second.
Prevailing)
1155 GUIDPreservedSymbols.
insert(GUID);
1158 DynamicExportSymbols.insert(GUID);
1160 GUIDPrevailingResolutions[GUID] =
1165 auto It = GUIDPrevailingResolutions.
find(
G);
1166 if (It == GUIDPrevailingResolutions.
end())
1175 if (!StatsFileOrErr)
1176 return StatsFileOrErr.takeError();
1177 std::unique_ptr<ToolOutputFile> StatsFile = std::move(StatsFileOrErr.get());
1185 ThinLTO.CombinedIndex.setWithSupportsHotColdNew();
1187 Error Result = runRegularLTO(AddStream);
1191 Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols);
1201 if (
Index.withSupportsHotColdNew())
1209 for (
auto &
F :
Mod) {
1210 for (
auto &BB :
F) {
1211 for (
auto &
I : BB) {
1212 auto *CI = dyn_cast<CallBase>(&
I);
1215 if (CI->hasFnAttr(
"memprof"))
1216 CI->removeFnAttr(
"memprof");
1223 CI->setMetadata(LLVMContext::MD_memprof,
nullptr);
1224 CI->setMetadata(LLVMContext::MD_callsite,
nullptr);
1238 return DiagFileOrErr.takeError();
1239 DiagnosticOutputFile = std::move(*DiagFileOrErr);
1243 for (
auto &M : RegularLTO.ModsWithSummaries)
1244 if (
Error Err = linkRegularLTO(std::move(M),
1252 if (
Error Err = checkPartiallySplit())
1257 const DataLayout &
DL = RegularLTO.CombinedModule->getDataLayout();
1258 for (
auto &
I : RegularLTO.Commons) {
1259 if (!
I.second.Prevailing)
1262 GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(
I.first);
1263 if (OldGV &&
DL.getTypeAllocSize(OldGV->
getValueType()) ==
I.second.Size) {
1271 auto *GV =
new GlobalVariable(*RegularLTO.CombinedModule, Ty,
false,
1274 GV->setAlignment(
I.second.Alignment);
1286 bool WholeProgramVisibilityEnabledInLTO =
1295 auto It = GlobalResolutions->find(
name);
1296 return (It == GlobalResolutions->end() || It->second.VisibleOutsideSummary);
1302 *RegularLTO.CombinedModule, WholeProgramVisibilityEnabledInLTO,
1304 IsVisibleToRegularObj);
1306 WholeProgramVisibilityEnabledInLTO);
1313 for (
const auto &R : *GlobalResolutions) {
1315 RegularLTO.CombinedModule->getNamedValue(
R.second.IRName);
1316 if (!
R.second.isPrevailingIRSymbol())
1318 if (
R.second.Partition != 0 &&
1319 R.second.Partition != GlobalResolution::External)
1354 backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,
1355 *RegularLTO.CombinedModule, ThinLTO.CombinedIndex))
1363#define HANDLE_LIBCALL(code, name) name,
1364#include "llvm/IR/RuntimeLibcalls.def"
1365#undef HANDLE_LIBCALL
1386 : Conf(Conf), CombinedIndex(CombinedIndex),
1387 ModuleToDefinedGVSummaries(ModuleToDefinedGVSummaries),
1388 OnWrite(OnWrite), ShouldEmitImportsFiles(ShouldEmitImportsFiles) {}
1395 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1403 const std::string &NewModulePath) {
1404 std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
1408 ImportList, ModuleToSummariesForIndex);
1411 sys::fs::OpenFlags::OF_None);
1418 if (ShouldEmitImportsFiles) {
1420 ModuleToSummariesForIndex);
1433 std::set<GlobalValue::GUID> CfiFunctionDefs;
1434 std::set<GlobalValue::GUID> CfiFunctionDecls;
1436 std::optional<Error> Err;
1439 bool ShouldEmitIndexFiles;
1442 InProcessThinBackend(
1447 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles)
1449 OnWrite, ShouldEmitImportsFiles),
1450 BackendThreadPool(ThinLTOParallelism), AddStream(
std::
move(AddStream)),
1451 Cache(
std::
move(Cache)), ShouldEmitIndexFiles(ShouldEmitIndexFiles) {
1453 CfiFunctionDefs.insert(
1456 CfiFunctionDecls.insert(
1460 Error runThinLTOBackendThread(
1465 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1468 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1474 return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,
1475 ImportList, DefinedGlobals, &ModuleMap);
1480 if (ShouldEmitIndexFiles) {
1481 if (
auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1487 [](
uint32_t V) { return V == 0; }))
1490 return RunThinBackend(AddStream);
1495 ExportList, ResolvedODR, DefinedGlobals, CfiFunctionDefs,
1500 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1502 return RunThinBackend(CacheAddStream);
1511 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1514 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
1516 ModuleToDefinedGVSummaries.
find(ModulePath)->second;
1517 BackendThreadPool.
async(
1521 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
1528 Error E = runThinLTOBackendThread(
1529 AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList,
1530 ResolvedODR, DefinedGlobals, ModuleMap);
1532 std::unique_lock<std::mutex>
L(ErrMu);
1541 BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList),
1542 std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap));
1545 OnWrite(std::string(ModulePath));
1549 Error wait()
override {
1550 BackendThreadPool.
wait();
1552 return std::move(*Err);
1565 bool ShouldEmitIndexFiles,
1566 bool ShouldEmitImportsFiles) {
1571 return std::make_unique<InProcessThinBackend>(
1572 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1573 AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
1574 ShouldEmitImportsFiles);
1599 return std::string(Path);
1603 if (!ParentPath.
empty()) {
1606 llvm::errs() <<
"warning: could not create directory '" << ParentPath
1607 <<
"': " << EC.message() <<
'\n';
1609 return std::string(NewPath);
1614 std::string OldPrefix, NewPrefix, NativeObjectPrefix;
1618 WriteIndexesThinBackend(
1621 std::string OldPrefix, std::string NewPrefix,
1622 std::string NativeObjectPrefix,
bool ShouldEmitImportsFiles,
1625 OnWrite, ShouldEmitImportsFiles),
1626 OldPrefix(OldPrefix), NewPrefix(NewPrefix),
1627 NativeObjectPrefix(NativeObjectPrefix),
1628 LinkedObjectsFile(LinkedObjectsFile) {}
1634 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1637 std::string NewModulePath =
1640 if (LinkedObjectsFile) {
1641 std::string ObjectPrefix =
1642 NativeObjectPrefix.empty() ? NewPrefix : NativeObjectPrefix;
1643 std::string LinkedObjectsFilePath =
1645 *LinkedObjectsFile << LinkedObjectsFilePath <<
'\n';
1648 if (
auto E = emitFiles(ImportList, ModulePath, NewModulePath))
1652 OnWrite(std::string(ModulePath));
1665 std::string OldPrefix, std::string NewPrefix,
1666 std::string NativeObjectPrefix,
bool ShouldEmitImportsFiles,
1672 return std::make_unique<WriteIndexesThinBackend>(
1673 Conf, CombinedIndex, ModuleToDefinedGVSummaries, OldPrefix,
1674 NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,
1675 LinkedObjectsFile, OnWrite);
1682 ThinLTO.CombinedIndex.releaseTemporaryMemory();
1688 if (ThinLTO.ModuleMap.empty())
1691 if (ThinLTO.ModulesToCompile && ThinLTO.ModulesToCompile->empty()) {
1692 llvm::errs() <<
"warning: [ThinLTO] No module compiled\n";
1703 ThinLTO.ModuleMap.size());
1704 ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule(
1705 ModuleToDefinedGVSummaries);
1713 for (
auto &
Mod : ThinLTO.ModuleMap)
1714 if (!ModuleToDefinedGVSummaries.
count(
Mod.first))
1721 ThinLTO.ModuleMap.size());
1723 ThinLTO.ModuleMap.size());
1727 ThinLTO.CombinedIndex.dumpSCCs(
outs());
1729 std::set<GlobalValue::GUID> ExportedGUIDs;
1731 bool WholeProgramVisibilityEnabledInLTO =
1737 ThinLTO.CombinedIndex.setWithWholeProgramVisibility();
1743 if (WholeProgramVisibilityEnabledInLTO &&
1748 auto It = GlobalResolutions->
find(
name);
1749 return (It == GlobalResolutions->end() ||
1750 It->second.VisibleOutsideSummary);
1754 VisibleToRegularObjSymbols,
1755 IsVisibleToRegularObj);
1761 ThinLTO.CombinedIndex, WholeProgramVisibilityEnabledInLTO,
1762 DynamicExportSymbols, VisibleToRegularObjSymbols);
1767 std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;
1769 LocalWPDTargetsMap);
1772 return ThinLTO.PrevailingModuleForGUID[
GUID] == S->modulePath();
1776 ContextDisambiguation.
run(ThinLTO.CombinedIndex, isPrevailing);
1783 for (
auto &Res : *GlobalResolutions) {
1786 if (Res.second.Partition != GlobalResolution::External ||
1787 !Res.second.isPrevailingIRSymbol())
1792 if (ThinLTO.CombinedIndex.isGUIDLive(GUID))
1793 ExportedGUIDs.insert(GUID);
1800 GlobalResolutions.reset();
1804 isPrevailing, ImportLists, ExportLists);
1808 for (
auto &Def : ThinLTO.CombinedIndex.cfiFunctionDefs())
1809 ExportedGUIDs.insert(
1811 for (
auto &Decl : ThinLTO.CombinedIndex.cfiFunctionDecls())
1812 ExportedGUIDs.insert(
1816 const auto &ExportList = ExportLists.
find(ModuleIdentifier);
1817 return (ExportList != ExportLists.end() && ExportList->second.
count(VI)) ||
1818 ExportedGUIDs.count(
VI.getGUID());
1824 LocalWPDTargetsMap);
1829 auto recordNewLinkage = [&](
StringRef ModuleIdentifier,
1832 ResolvedODR[ModuleIdentifier][
GUID] = NewLinkage;
1835 recordNewLinkage, GUIDPreservedSymbols);
1844 TimeTraceScopeExit.release();
1846 std::unique_ptr<ThinBackendProc> BackendProc =
1847 ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
1851 ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;
1853 auto ProcessOneModule = [&](
int I) ->
Error {
1857 return BackendProc->start(RegularLTO.ParallelCodeGenParallelismLevel +
I,
1858 Mod.second, ImportLists[
Mod.first],
1859 ExportLists[
Mod.first], ResolvedODR[
Mod.first],
1863 if (BackendProc->getThreadCount() == 1) {
1868 for (
int I = 0, E = ModuleMap.
size();
I != E; ++
I)
1869 if (
Error E = ProcessOneModule(
I))
1876 std::vector<BitcodeModule *> ModulesVec;
1877 ModulesVec.reserve(ModuleMap.
size());
1878 for (
auto &
Mod : ModuleMap)
1879 ModulesVec.push_back(&
Mod.second);
1881 if (
Error E = ProcessOneModule(
I))
1884 return BackendProc->wait();
1894 if (!Filename.empty() && Count != -1)
1902 if (
Error E = ResultOrErr.takeError())
1903 return std::move(E);
1906 (*ResultOrErr)->keep();
1914 if (StatsFilename.
empty())
1925 return std::move(StatsFile);
1932 auto Seq = llvm::seq<int>(0, R.size());
1933 std::vector<int> ModulesOrdering(Seq.begin(), Seq.end());
1934 llvm::sort(ModulesOrdering, [&](
int LeftIndex,
int RightIndex) {
1935 auto LSize = R[LeftIndex]->getBuffer().
size();
1936 auto RSize = R[RightIndex]->getBuffer().
size();
1937 return LSize > RSize;
1939 return ModulesOrdering;
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static void writeToResolutionFile(raw_ostream &OS, InputFile *Input, ArrayRef< SymbolResolution > Res)
static void thinLTOResolvePrevailingGUID(const Config &C, ValueInfo VI, DenseSet< GlobalValueSummary * > &GlobalInvolvedWithAlias, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, function_ref< void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> recordNewLinkage, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols)
static void handleNonPrevailingComdat(GlobalValue &GV, std::set< const Comdat * > &NonPrevailingComdats)
static cl::opt< bool > DumpThinCGSCCs("dump-thin-cg-sccs", cl::init(false), cl::Hidden, cl::desc("Dump the SCCs in the ThinLTO index's callgraph"))
static void thinLTOInternalizeAndPromoteGUID(ValueInfo VI, function_ref< bool(StringRef, ValueInfo)> isExported, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
cl::opt< bool > UseNewDbgInfoFormat
static const char * libcallRoutineNames[]
llvm::cl::opt< bool > UseNewDbgInfoFormat
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 file defines the SmallSet class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Represents a module in a bitcode file.
StringRef getModuleIdentifier() const
Error readSummary(ModuleSummaryIndex &CombinedIndex, StringRef ModulePath, std::function< bool(GlobalValue::GUID)> IsPrevailing=nullptr)
Parse the specified bitcode buffer and merge its module summary index into CombinedIndex.
Expected< std::unique_ptr< Module > > parseModule(LLVMContext &Context, ParserCallbacks Callbacks={})
Read the entire bitcode module and return it.
Expected< std::unique_ptr< Module > > getLazyModule(LLVMContext &Context, bool ShouldLazyLoadMetadata, bool IsImporting, ParserCallbacks Callbacks={})
Read the bitcode module and prepare for lazy deserialization of function bodies.
static ConstantAggregateZero * get(Type *Ty)
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&... Args)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Implements a dense probed hash-table based set.
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.
std::unordered_map< GlobalValue::GUID, GlobalValueSummary::ImportKind > FunctionsToImportTy
The functions to import from a source module and their import type.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalObject.
Function and variable summary information to aid decisions and implementation of importing.
static bool isAppendingLinkage(LinkageTypes Linkage)
static bool isExternalWeakLinkage(LinkageTypes Linkage)
static bool isLocalLinkage(LinkageTypes Linkage)
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
void setUnnamedAddr(UnnamedAddr Val)
bool hasLocalLinkage() const
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
const Comdat * getComdat() const
static bool isLinkOnceLinkage(LinkageTypes Linkage)
static GUID getGUID(StringRef GlobalName)
Return a 64-bit global unique ID constructed from global value name (i.e.
void setLinkage(LinkageTypes LT)
DLLStorageClassTypes
Storage classes of global values for PE targets.
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
const GlobalObject * getAliaseeObject() const
static bool isExternalLinkage(LinkageTypes Linkage)
VisibilityTypes
An enumeration for the kinds of visibility of global values.
@ DefaultVisibility
The GV is visible.
static LinkageTypes getWeakLinkage(bool ODR)
bool isWeakForLinker() const
bool hasAppendingLinkage() const
bool hasAvailableExternallyLinkage() 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.
@ CommonLinkage
Tentative definitions.
@ InternalLinkage
Rename collisions when linking (static functions).
@ ExternalLinkage
Externally visible function.
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
@ AvailableExternallyLinkage
Available for inspection, not emission.
DLLStorageClassTypes getDLLStorageClass() const
Type * getValueType() const
static bool isLinkOnceODRLinkage(LinkageTypes Linkage)
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
This is an important class for using LLVM in a threaded context.
This class implements a map that also provides access to all stored values in a deterministic order.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
Class to hold module path string table and global value map, and encapsulate methods for operating on...
std::set< std::string > & cfiFunctionDecls()
const ModuleHash & getModuleHash(const StringRef ModPath) const
Get the module SHA1 hash recorded for the given module path.
const StringMap< ModuleHash > & modulePaths() const
Table of modules, containing module hash and id.
std::set< std::string > & cfiFunctionDefs()
void addModule(Module *M)
static void CollectAsmSymvers(const Module &M, function_ref< void(StringRef, StringRef)> AsmSymver)
Parse inline ASM and collect the symvers directives that are defined in the current module.
uint32_t getSymbolFlags(Symbol S) const
ArrayRef< Symbol > symbols() const
A Module instance is used to store all the information related to an LLVM module.
A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...
A class that wrap the SHA1 algorithm.
void update(ArrayRef< uint8_t > Data)
Digest more data.
std::array< uint8_t, 20 > result()
Return the current raw 160-bits SHA1 for the digested data since the last call to init().
A non-threaded implementation.
void wait() override
Blocking wait for all the tasks to execute first.
unsigned getMaxConcurrency() const override
Returns always 1: there is no concurrency.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef str() const
Explicit conversion to StringRef.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
MCTargetOptions MCOptions
Machine level options.
DebuggerKind DebuggerTuning
Which debugger to tune for.
unsigned FunctionSections
Emit functions into separate sections.
unsigned DataSections
Emit data into separate sections.
auto async(Function &&F, Args &&...ArgList)
Asynchronous submission of a task to the pool.
This tells how a thread pool will be used.
Triple - Helper class for working with autoconf configuration names.
bool isArm64e() const
Tests whether the target is the Apple "arm64e" AArch64 subarch.
ArchType getArch() const
Get the parsed architecture type of this triple.
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, XROS, or DriverKit).
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static IntegerType * getInt8Ty(LLVMContext &C)
void setName(const Twine &Name)
Change the name of the value.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
std::pair< iterator, bool > insert(const ValueT &V)
iterator find(const_arg_type_t< ValueT > V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
An efficient, type-erasing, non-owning reference to a callable.
Ephemeral symbols produced by Reader::symbols() and Reader::module_symbols().
Error add(std::unique_ptr< InputFile > Obj, ArrayRef< SymbolResolution > Res)
Add an input file to the LTO link, using the provided symbol resolutions.
LTO(Config Conf, ThinBackend Backend=nullptr, unsigned ParallelCodeGenParallelismLevel=1, LTOKind LTOMode=LTOK_Default)
Create an LTO object.
LTOKind
Unified LTO modes.
@ LTOK_UnifiedRegular
Regular LTO, with Unified LTO enabled.
@ LTOK_Default
Any LTO mode without Unified LTO. The default mode.
@ LTOK_UnifiedThin
ThinLTO, with Unified LTO enabled.
static ArrayRef< const char * > getRuntimeLibcallSymbols()
Static method that returns a list of libcall symbols that can be generated by LTO but might not be vi...
Error run(AddStreamFn AddStream, FileCache Cache=nullptr)
Runs the LTO pipeline.
unsigned getMaxTasks() const
Returns an upper bound on the number of tasks that the client may expect.
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.
This class defines the interface to the ThinLTO backend.
virtual unsigned getThreadCount()=0
bool ShouldEmitImportsFiles
lto::IndexWriteCallback OnWrite
Error emitFiles(const FunctionImporter::ImportMapTy &ImportList, llvm::StringRef ModulePath, const std::string &NewModulePath)
ThinBackendProc(const Config &Conf, ModuleSummaryIndex &CombinedIndex, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, lto::IndexWriteCallback OnWrite, bool ShouldEmitImportsFiles)
const DenseMap< StringRef, GVSummaryMapTy > & ModuleToDefinedGVSummaries
ModuleSummaryIndex & CombinedIndex
virtual ~ThinBackendProc()=default
virtual Error start(unsigned Task, BitcodeModule BM, const FunctionImporter::ImportMapTy &ImportList, const FunctionImporter::ExportSetTy &ExportList, const std::map< GlobalValue::GUID, GlobalValue::LinkageTypes > &ResolvedODR, MapVector< StringRef, BitcodeModule > &ModuleMap)=0
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
StringRef getName(ID id)
Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
initializer< Ty > init(const Ty &Val)
ThinBackend createInProcessThinBackend(ThreadPoolStrategy Parallelism, IndexWriteCallback OnWrite=nullptr, bool ShouldEmitIndexFiles=false, bool ShouldEmitImportsFiles=false)
Error thinBackend(const Config &C, unsigned Task, AddStreamFn AddStream, Module &M, const ModuleSummaryIndex &CombinedIndex, const FunctionImporter::ImportMapTy &ImportList, const GVSummaryMapTy &DefinedGlobals, MapVector< StringRef, BitcodeModule > *ModuleMap, const std::vector< uint8_t > &CmdArgs=std::vector< uint8_t >())
Runs a ThinLTO backend.
std::string getThinLTOOutputFile(StringRef Path, StringRef OldPrefix, StringRef NewPrefix)
Given the original Path to an output file, replace any path prefix matching OldPrefix with NewPrefix.
std::function< std::unique_ptr< ThinBackendProc >(const Config &C, ModuleSummaryIndex &CombinedIndex, DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, AddStreamFn AddStream, FileCache Cache)> ThinBackend
A ThinBackend defines what happens after the thin-link phase during ThinLTO.
std::function< void(const std::string &)> IndexWriteCallback
This ThinBackend runs the individual backend jobs in-process.
StringLiteral getThinLTODefaultCPU(const Triple &TheTriple)
Expected< std::unique_ptr< ToolOutputFile > > setupStatsFile(StringRef StatsFilename)
Setups the output file for saving statistics.
Error backend(const Config &C, AddStreamFn AddStream, unsigned ParallelCodeGenParallelismLevel, Module &M, ModuleSummaryIndex &CombinedIndex)
Runs a regular LTO backend.
Error finalizeOptimizationRemarks(std::unique_ptr< ToolOutputFile > DiagOutputFile)
ThinBackend createWriteIndexesThinBackend(std::string OldPrefix, std::string NewPrefix, std::string NativeObjectPrefix, bool ShouldEmitImportsFiles, raw_fd_ostream *LinkedObjectsFile, IndexWriteCallback OnWrite)
This ThinBackend writes individual module indexes to files, instead of running the individual backend...
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.
void updateMemProfAttributes(Module &Mod, const ModuleSummaryIndex &Index)
Updates MemProf attributes (and metadata) based on whether the index has recorded that we are linking...
Expected< IRSymtabFile > readIRSymtab(MemoryBufferRef MBRef)
Reads a bitcode file, creating its irsymtab if necessary.
void write64le(void *P, uint64_t V)
void write32le(void *P, uint32_t V)
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.
StringRef parent_path(StringRef path, Style style=Style::native)
Get parent path.
bool replace_path_prefix(SmallVectorImpl< char > &Path, StringRef OldPrefix, StringRef NewPrefix, Style style=Style::native)
Replace matching path prefix with another 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.
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.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
void ComputeCrossModuleImport(const ModuleSummaryIndex &Index, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, DenseMap< StringRef, FunctionImporter::ImportMapTy > &ImportLists, DenseMap< StringRef, FunctionImporter::ExportSetTy > &ExportLists)
Compute all the imports and exports for every module in the Index.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
void timeTraceProfilerInitialize(unsigned TimeTraceGranularity, StringRef ProcName)
Initialize the time trace profiler.
void generateParamAccessSummary(ModuleSummaryIndex &Index)
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"))
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
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 ...
raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
std::function< Expected< std::unique_ptr< CachedFileStream > >(unsigned Task, const Twine &ModuleName)> AddStreamFn
This type defines the callback to add a file that is generated on the fly.
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.
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.
bool hasWholeProgramVisibility(bool WholeProgramVisibilityEnabledInLTO)
void EnableStatistics(bool DoPrintOnExit=true)
Enable the collection and printing of statistics.
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...
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 ...
void timeTraceProfilerFinishThread()
Finish a time trace profiler running on a worker thread.
Error joinErrors(Error E1, Error E2)
Concatenate errors.
void updatePublicTypeTestCalls(Module &M, bool WholeProgramVisibilityEnabledInLTO)
void getVisibleToRegularObjVtableGUIDs(ModuleSummaryIndex &Index, DenseSet< GlobalValue::GUID > &VisibleToRegularObjSymbols, function_ref< bool(StringRef)> IsVisibleToRegularObj)
Based on typeID string, get all associated vtable GUIDS that are visible to regular objects.
void sort(IteratorTy Start, IteratorTy End)
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.
Expected< std::unique_ptr< ToolOutputFile > > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::optional< uint64_t > RemarksHotnessThreshold=0)
Setup optimization remarks that output to a file.
cl::opt< bool > EnableLTOInternalization
Enable global value internalization in LTO.
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"))
cl::opt< bool > SupportsHotColdNew
Indicate we are linking with an allocator that supports hot/cold operator new interfaces.
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.
void gatherImportedSummariesForModule(StringRef ModulePath, const DenseMap< StringRef, 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.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Mod
The access may modify the value stored in memory.
cl::opt< bool > EnableMemProfContextDisambiguation
Enable MemProf context disambiguation for thin link.
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.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
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)
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
bool UpgradeDebugInfo(Module &M)
Check the debug info version number, if it is out-dated, drop the debug info.
std::array< uint32_t, 5 > ModuleHash
160 bits SHA1
std::function< Expected< AddStreamFn >(unsigned Task, StringRef Key, const Twine &ModuleName)> FileCache
This is the type of a file cache.
void PrintStatisticsJSON(raw_ostream &OS)
Print statistics in JSON format.
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.
@ Keep
No function return thunk.
void updateVCallVisibilityInModule(Module &M, bool WholeProgramVisibilityEnabledInLTO, const DenseSet< GlobalValue::GUID > &DynamicExportSymbols, bool ValidateAllVtablesHaveTypeInfos, function_ref< bool(StringRef)> IsVisibleToRegularObj)
If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...
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...
Implement std::hash so that hash_code can be used in STL containers.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Used in the streaming interface as the general argument type.
Struct that holds a reference to a particular GUID in a global value summary.
bool HasWholeProgramVisibility
Asserts whether we can assume whole program visibility during the LTO link.
bool ValidateAllVtablesHaveTypeInfos
We're validating that all native vtables have corresponding type infos.
std::optional< uint64_t > RemarksHotnessThreshold
The minimum hotness value a diagnostic needs in order to be included in optimization diagnostics.
std::string StatsFile
Statistics output file path.
ModuleHookFn PreOptModuleHook
This module hook is called after linking (regular LTO) or loading (ThinLTO) the module,...
CombinedIndexHookFn CombinedIndexHook
std::optional< CodeModel::Model > CodeModel
bool CodeGenOnly
Disable entirely the optimizer, including importing for ThinLTO.
std::vector< std::string > MAttrs
std::vector< std::string > MllvmArgs
std::vector< std::string > ThinLTOModulesToCompile
Specific thinLTO modules to compile.
CodeGenOptLevel CGOptLevel
std::unique_ptr< raw_ostream > ResolutionFile
If this field is set, LTO will write input file paths and symbol resolutions here in llvm-lto2 comman...
std::string DefaultTriple
Setting this field will replace unspecified target triples in input files with this triple.
bool AlwaysEmitRegularLTOObj
Always emit a Regular LTO object even when it is empty because no Regular LTO modules were linked.
std::string DwoDir
The directory to store .dwo files.
std::string RemarksFilename
Optimization remarks file path.
VisScheme VisibilityScheme
Allows non-imported definitions to get the potentially more constraining visibility from the prevaili...
std::string OverrideTriple
Setting this field will replace target triples in input files with this triple.
std::string ProfileRemapping
Name remapping file for profile data.
bool AllVtablesHaveTypeInfos
If all native vtables have corresponding type infos, allow usage of RTTI to block devirtualization on...
bool TimeTraceEnabled
Time trace enabled.
std::string RemarksPasses
Optimization remarks pass filter.
std::string OptPipeline
If this field is set, the set of passes run in the middle-end optimizer will be the one specified by ...
ModuleHookFn PostInternalizeModuleHook
This hook is called after internalizing the module.
unsigned TimeTraceGranularity
Time trace granularity.
bool RemarksWithHotness
Whether to emit optimization remarks with hotness informations.
std::optional< Reloc::Model > RelocModel
CodeGenFileType CGFileType
bool Freestanding
Flag to indicate that the optimizer should not assume builtins are present on the target.
std::string SampleProfile
Sample PGO profile path.
std::string RemarksFormat
The format used for serializing remarks (default: YAML).
A derived class of LLVMContext that initializes itself according to a given Config object.
The resolution for a symbol.
unsigned FinalDefinitionInLinkageUnit
The definition of this symbol is unpreemptable at runtime and is known to be in this linkage unit.
unsigned ExportDynamic
The symbol was exported dynamically, and therefore could be referenced by a shared library not visibl...
unsigned Prevailing
The linker has chosen this definition of the symbol.
unsigned LinkerRedefined
Linker redefined version of the symbol which appeared in -wrap or -defsym linker option.
unsigned VisibleToRegularObj
The definition of this symbol is visible outside of the LTO unit.