27#include "llvm/Config/llvm-config.h"
56#include "llvm/Support/VCSRevision.h"
72#define DEBUG_TYPE "lto"
74Error LTO::setupOptimizationRemarks() {
81 return DiagFileOrErr.takeError();
83 DiagnosticOutputFile = std::move(*DiagFileOrErr);
90 if (!LinkerRemarkFunction) {
91 DummyModule = std::make_unique<Module>(
"remark_dummy", RegularLTO.Ctx);
109 cl::desc(
"Dump the SCCs in the ThinLTO index's callgraph"));
120 cl::desc(
"Enable global value internalization in LTO"));
124 cl::desc(
"Keep copies of symbols in LTO indexing"));
141 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
152 Hasher.
update(LLVM_VERSION_STRING);
154 Hasher.
update(LLVM_REVISION);
162 auto AddUnsigned = [&](
unsigned I) {
172 auto AddUint8 = [&](
const uint8_t I) {
196 AddUnsigned(
static_cast<int>(Conf.
CGOptLevel));
197 AddUnsigned(
static_cast<int>(Conf.
CGFileType));
205 AddUint8(Conf.
Dtlto);
208 auto ModHash = Index.getModuleHash(ModuleID);
213 std::vector<uint64_t> ExportsGUID;
214 ExportsGUID.reserve(ExportList.
size());
215 for (
const auto &VI : ExportList)
216 ExportsGUID.push_back(VI.getGUID());
220 for (
auto GUID : ExportsGUID)
225 auto Comp = [&](
const std::pair<StringRef, GlobalValue::GUID> &L,
226 const std::pair<StringRef, GlobalValue::GUID> &R) {
227 return std::make_pair(Index.getModule(L.first)->second, L.second) <
228 std::make_pair(Index.getModule(R.first)->second, R.second);
234 for (
const auto &[FromModule, GUID,
Type] : SortedImportList)
235 ++ModuleToNumImports[FromModule];
237 std::optional<StringRef> LastModule;
238 for (
const auto &[FromModule, GUID,
Type] : SortedImportList) {
239 if (LastModule != FromModule) {
243 LastModule = FromModule;
244 auto ModHash = Index.getModule(FromModule)->second;
246 AddUint64(ModuleToNumImports[FromModule]);
253 for (
auto &Entry : ResolvedODR) {
262 std::set<GlobalValue::GUID> UsedCfiDefs;
263 std::set<GlobalValue::GUID> UsedCfiDecls;
266 std::set<GlobalValue::GUID> UsedTypeIds;
269 if (CfiFunctionDefs.
contains(ValueGUID))
270 UsedCfiDefs.insert(ValueGUID);
271 if (CfiFunctionDecls.
contains(ValueGUID))
272 UsedCfiDecls.insert(ValueGUID);
277 AddUnsigned(GS->getVisibility());
278 AddUnsigned(GS->isLive());
279 AddUnsigned(GS->canAutoHide());
281 AddUnsigned(VI.isDSOLocal(Index.withDSOLocalPropagation()));
282 AddUsedCfiGlobal(VI.getGUID());
285 AddUnsigned(GVS->maybeReadOnly());
286 AddUnsigned(GVS->maybeWriteOnly());
289 for (
auto &TT : FS->type_tests())
290 UsedTypeIds.insert(TT);
291 for (
auto &TT : FS->type_test_assume_vcalls())
292 UsedTypeIds.insert(TT.GUID);
293 for (
auto &TT : FS->type_checked_load_vcalls())
294 UsedTypeIds.insert(TT.GUID);
295 for (
auto &TT : FS->type_test_assume_const_vcalls())
296 UsedTypeIds.insert(TT.VFunc.GUID);
297 for (
auto &TT : FS->type_checked_load_const_vcalls())
298 UsedTypeIds.insert(TT.VFunc.GUID);
299 for (
auto &ET : FS->calls()) {
300 AddUnsigned(ET.first.isDSOLocal(Index.withDSOLocalPropagation()));
301 AddUsedCfiGlobal(ET.first.getGUID());
308 for (
auto &GS : DefinedGlobals) {
312 AddUsedCfiGlobal(GS.first);
313 AddUsedThings(GS.second);
318 for (
const auto &[FromModule, GUID,
Type] : SortedImportList) {
324 AddUsedThings(AS->getBaseObject());
330 AddUnsigned(S.TTRes.TheKind);
331 AddUnsigned(S.TTRes.SizeM1BitWidth);
333 AddUint64(S.TTRes.AlignLog2);
334 AddUint64(S.TTRes.SizeM1);
335 AddUint64(S.TTRes.BitMask);
336 AddUint64(S.TTRes.InlineBits);
338 AddUint64(S.WPDRes.size());
339 for (
auto &WPD : S.WPDRes) {
340 AddUnsigned(WPD.first);
341 AddUnsigned(WPD.second.TheKind);
342 AddString(WPD.second.SingleImplName);
344 AddUint64(WPD.second.ResByArg.size());
345 for (
auto &ByArg : WPD.second.ResByArg) {
346 AddUint64(ByArg.first.size());
349 AddUnsigned(ByArg.second.TheKind);
350 AddUint64(ByArg.second.Info);
351 AddUnsigned(ByArg.second.Byte);
352 AddUnsigned(ByArg.second.Bit);
359 auto TidIter = Index.typeIds().equal_range(TId);
361 AddTypeIdSummary(
I.second.first,
I.second.second);
364 AddUnsigned(UsedCfiDefs.size());
365 for (
auto &V : UsedCfiDefs)
368 AddUnsigned(UsedCfiDecls.size());
369 for (
auto &V : UsedCfiDecls)
375 Hasher.
update(FileOrErr.get()->getBuffer());
380 Hasher.
update(FileOrErr.get()->getBuffer());
411 C.VisibilityScheme ==
Config::ELF ? VI.getELFVisibility()
413 for (
auto &S : VI.getSummaryList()) {
428 if (isPrevailing(VI.getGUID(), S.get())) {
429 assert(!S->wasPromoted() &&
430 "promoted symbols used to be internal linkage and shouldn't have "
431 "a prevailing variant");
444 S->setCanAutoHide(VI.canAutoHide() &&
445 !GUIDPreservedSymbols.
count(VI.getGUID()));
448 Visibility = S->getVisibility();
465 S->setVisibility(Visibility);
467 if (S->linkage() != OriginalLinkage)
468 recordNewLinkage(S->modulePath(), VI.getGUID(), S->linkage());
472 for (
auto &S : VI.getSummaryList()) {
477 S->setVisibility(Visibility);
499 for (
auto &
I : Index)
500 for (
auto &S :
I.second.getSummaryList())
502 GlobalInvolvedWithAlias.
insert(&AS->getAliasee());
504 for (
auto &
I : Index)
506 GlobalInvolvedWithAlias, isPrevailing,
507 recordNewLinkage, GUIDPreservedSymbols);
519 const bool SingleExternallyVisibleCopy =
520 VI.getSummaryList().size() == 1 &&
523 bool NameRecorded =
false;
524 for (
auto &S : VI.getSummaryList()) {
527 if (isExported(S->modulePath(), VI)) {
533 if (ExternallyVisibleSymbolNamesPtr && !NameRecorded) {
535 if (ExternallyVisibleSymbolNamesPtr->
insert(VI.name()).second)
536 S->setNoRenameOnPromotion(
true);
599 if (SingleExternallyVisibleCopy && isPrevailing(VI.getGUID(), S.get()))
612 assert(!Index.withInternalizeAndPromote());
614 for (
auto &
I : Index)
617 ExternallyVisibleSymbolNamesPtr);
618 Index.setWithInternalizeAndPromote();
625 std::unique_ptr<InputFile> File(
new InputFile);
631 File->TargetTriple = FOrErr->TheReader.getTargetTriple();
632 File->SourceFileName = FOrErr->TheReader.getSourceFileName();
633 File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts();
634 File->DependentLibraries = FOrErr->TheReader.getDependentLibraries();
635 File->ComdatTable = FOrErr->TheReader.getComdatTable();
639 for (
unsigned I = 0;
I != FOrErr->Mods.size(); ++
I) {
640 size_t Begin = File->Symbols.size();
642 FOrErr->TheReader.module_symbols(
I))
645 if (Sym.isGlobal() && !Sym.isFormatSpecific())
646 File->Symbols.push_back(Sym);
647 File->ModuleSymIndices.push_back({Begin, File->Symbols.size()});
650 File->Mods = FOrErr->Mods;
651 File->Strtab = std::move(FOrErr->Strtab);
652 return std::move(File);
661 return Mods[0].getModuleIdentifier();
665 assert(Mods.size() == 1 &&
"Expect only one bitcode module");
671LTO::RegularLTOState::RegularLTOState(
unsigned ParallelCodeGenParallelismLevel,
673 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
674 Ctx(Conf), CombinedModule(
std::make_unique<
Module>(
"ld-temp.o", Ctx)),
675 Mover(
std::make_unique<
IRMover>(*CombinedModule)) {}
677LTO::ThinLTOState::ThinLTOState(
ThinBackend BackendParam)
678 : Backend(
std::
move(BackendParam)), CombinedIndex(
false) {
679 if (!Backend.isValid())
685 unsigned ParallelCodeGenParallelismLevel,
LTOKind LTOMode)
687 RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),
693 Alloc = std::make_unique<BumpPtrAllocator>();
694 GlobalResolutionSymbolSaver = std::make_unique<llvm::StringSaver>(*Alloc);
703 LinkerRemarkFunction =
nullptr;
711 unsigned Partition,
bool InSummary,
714 auto *ResI = Res.
begin();
715 auto *ResE = Res.
end();
724 if (GlobalResolutionSymbolSaver && !GlobalResolutions->contains(SymbolName))
725 SymbolName = GlobalResolutionSymbolSaver->save(SymbolName);
727 auto &GlobalRes = (*GlobalResolutions)[SymbolName];
728 GlobalRes.UnnamedAddr &= Sym.isUnnamedAddr();
730 assert(!GlobalRes.Prevailing &&
731 "Multiple prevailing defs are not allowed");
732 GlobalRes.Prevailing =
true;
733 GlobalRes.IRName = std::string(Sym.getIRName());
734 }
else if (!GlobalRes.Prevailing && GlobalRes.IRName.empty()) {
741 GlobalRes.IRName = std::string(Sym.getIRName());
755 if (GlobalRes.IRName != Sym.getIRName()) {
756 GlobalRes.Partition = GlobalResolution::External;
757 GlobalRes.VisibleOutsideSummary =
true;
760 bool IsLibcall = Sym.isLibcall(Libcalls);
768 (GlobalRes.Partition != GlobalResolution::Unknown &&
769 GlobalRes.Partition != Partition)) {
770 GlobalRes.Partition = GlobalResolution::External;
773 GlobalRes.Partition = Partition;
777 GlobalRes.VisibleOutsideSummary |=
784void LTO::releaseGlobalResolutionsMemory() {
786 GlobalResolutions.reset();
788 GlobalResolutionSymbolSaver.reset();
796 auto ResI = Res.
begin();
801 OS <<
"-r=" << Path <<
',' << Sym.getName() <<
',';
819 assert(!CalledGetMaxTasks);
825 InputFile *
Input = (*InputOrErr).get();
827 if (Conf.ResolutionFile)
830 if (RegularLTO.CombinedModule->getTargetTriple().empty()) {
832 RegularLTO.CombinedModule->setTargetTriple(InputTriple);
838 for (
unsigned I = 0;
I !=
Input->Mods.size(); ++
I) {
839 if (
auto Err = addModule(*
Input, InputRes,
I, Res).moveInto(Res))
855 if (EnableSplitLTOUnit) {
859 if (*EnableSplitLTOUnit != LTOInfo->EnableSplitLTOUnit)
862 EnableSplitLTOUnit = LTOInfo->EnableSplitLTOUnit;
867 !LTOInfo->UnifiedLTO)
869 "unified LTO compilation must use "
870 "compatible bitcode modules (use -funified-lto)",
880 Input.IsThinLTO |= IsThinLTO;
882 auto ModSyms =
Input.module_symbols(ModI);
883 addModuleToGlobalRes(ModSyms, Res,
884 IsThinLTO ? ThinLTO.ModuleMap.
size() + 1 : 0,
885 LTOInfo->HasSummary,
Triple(
Input.getTargetTriple()));
888 return addThinLTO(BM, ModSyms, Res);
890 RegularLTO.EmptyCombinedModule =
false;
891 auto ModOrErr = addRegularLTO(
Input, InputRes, BM, ModSyms, Res);
893 return ModOrErr.takeError();
894 Res = ModOrErr->second;
896 if (!LTOInfo->HasSummary) {
897 if (
Error Err = linkRegularLTO(std::move(ModOrErr->first),
907 RegularLTO.ModsWithSummaries.push_back(std::move(ModOrErr->first));
923 std::set<const Comdat *> &NonPrevailingComdats) {
928 if (!NonPrevailingComdats.count(
C))
938 GO->setComdat(
nullptr);
945 std::pair<LTO::RegularLTOState::AddedModule, ArrayRef<SymbolResolution>>>
949 llvm::TimeTraceScope timeScope(
"LTO add regular LTO");
951 Expected<std::unique_ptr<Module>> MOrErr =
957 Mod.M = std::move(*MOrErr);
959 if (
Error Err =
M.materializeMetadata())
960 return std::move(Err);
966 if (NamedMDNode *CfiFunctionsMD =
M.getNamedMetadata(
"cfi.functions"))
967 M.eraseNamedMetadata(CfiFunctionsMD);
968 }
else if (NamedMDNode *AliasesMD =
M.getNamedMetadata(
"aliases")) {
971 DenseSet<StringRef> Prevailing;
973 if (
R.Prevailing && !
I.getIRName().empty())
974 Prevailing.
insert(
I.getIRName());
975 std::vector<MDNode *> AliasGroups;
976 for (MDNode *AliasGroup : AliasesMD->operands()) {
977 std::vector<Metadata *> Aliases;
978 for (
Metadata *Alias : AliasGroup->operands()) {
981 Aliases.push_back(Alias);
983 if (Aliases.size() > 1)
984 AliasGroups.push_back(
MDTuple::get(RegularLTO.Ctx, Aliases));
986 AliasesMD->clearOperands();
987 for (MDNode *
G : AliasGroups)
988 AliasesMD->addOperand(
G);
993 ModuleSymbolTable SymTab;
996 for (GlobalVariable &GV :
M.globals())
997 if (GV.hasAppendingLinkage())
998 Mod.Keep.push_back(&GV);
1000 DenseSet<GlobalObject *> AliasedGlobals;
1001 for (
auto &GA :
M.aliases())
1002 if (GlobalObject *GO = GA.getAliaseeObject())
1003 AliasedGlobals.
insert(GO);
1012 auto MsymI = SymTab.
symbols().begin(), MsymE = SymTab.
symbols().end();
1014 while (MsymI != MsymE) {
1024 std::set<const Comdat *> NonPrevailingComdats;
1025 SmallSet<StringRef, 2> NonPrevailingAsmSymbols;
1026 for (
const InputFile::Symbol &Sym : Syms) {
1036 if (Sym.isUndefined())
1038 Mod.Keep.push_back(GV);
1042 if (
R.LinkerRedefined)
1050 (GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||
1051 GV->hasAvailableExternallyLinkage()) &&
1058 Mod.Keep.push_back(GV);
1060 if (GV->hasComdat())
1061 NonPrevailingComdats.insert(GV->getComdat());
1066 if (
R.FinalDefinitionInLinkageUnit) {
1067 GV->setDSOLocal(
true);
1068 if (GV->hasDLLImportStorageClass())
1070 DefaultStorageClass);
1072 }
else if (
auto *AS =
1076 NonPrevailingAsmSymbols.
insert(AS->first);
1084 if (Sym.isCommon()) {
1087 auto &CommonRes = RegularLTO.Commons[std::string(Sym.getIRName())];
1088 CommonRes.Size = std::max(CommonRes.Size, Sym.getCommonSize());
1089 if (uint32_t SymAlignValue = Sym.getCommonAlignment()) {
1090 CommonRes.Alignment =
1091 std::max(
Align(SymAlignValue), CommonRes.Alignment);
1093 CommonRes.Prevailing |=
R.Prevailing;
1097 if (!
M.getComdatSymbolTable().empty())
1098 for (GlobalValue &GV :
M.global_values())
1103 if (!
M.getModuleInlineAsm().empty()) {
1104 std::string NewIA =
".lto_discard";
1105 if (!NonPrevailingAsmSymbols.
empty()) {
1108 M, [&](StringRef Name, StringRef Alias) {
1109 if (!NonPrevailingAsmSymbols.
count(Alias))
1110 NonPrevailingAsmSymbols.
erase(Name);
1112 NewIA +=
" " +
llvm::join(NonPrevailingAsmSymbols,
", ");
1115 M.setModuleInlineAsm(NewIA +
M.getModuleInlineAsm());
1119 return std::make_pair(std::move(
Mod), Res);
1122Error LTO::linkRegularLTO(RegularLTOState::AddedModule
Mod,
1123 bool LivenessFromIndex) {
1124 llvm::TimeTraceScope timeScope(
"LTO link regular LTO");
1125 std::vector<GlobalValue *>
Keep;
1126 for (GlobalValue *GV :
Mod.Keep) {
1127 if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->
getGUID())) {
1129 if (DiagnosticOutputFile) {
1130 if (
Error Err =
F->materialize())
1132 auto R = OptimizationRemark(
DEBUG_TYPE,
"deadfunction",
F);
1133 R <<
ore::NV(
"Function",
F) <<
" not added to the combined module ";
1147 GlobalValue *CombinedGV =
1148 RegularLTO.CombinedModule->getNamedValue(GV->
getName());
1155 return RegularLTO.Mover->move(std::move(
Mod.M),
Keep,
nullptr,
1160Expected<ArrayRef<SymbolResolution>>
1163 llvm::TimeTraceScope timeScope(
"LTO add thin LTO");
1166 for (
const InputFile::Symbol &Sym : Syms) {
1170 if (!Sym.getIRName().empty() &&
R.Prevailing) {
1174 ThinLTO.setPrevailingModuleForGUID(GUID, BMID);
1180 return ThinLTO.isPrevailingModuleForGUID(GUID, BMID);
1185 for (
const InputFile::Symbol &Sym : Syms) {
1189 if (!Sym.getIRName().empty() &&
1190 (
R.Prevailing ||
R.FinalDefinitionInLinkageUnit)) {
1195 assert(ThinLTO.isPrevailingModuleForGUID(GUID, BMID));
1201 if (
R.LinkerRedefined)
1202 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(GUID, BMID))
1208 if (
R.FinalDefinitionInLinkageUnit) {
1209 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(GUID, BMID)) {
1210 S->setDSOLocal(
true);
1216 if (!ThinLTO.ModuleMap.insert({BMID, BM}).second)
1218 "Expected at most one ThinLTO module per bitcode file",
1221 if (!Conf.ThinLTOModulesToCompile.empty()) {
1222 if (!ThinLTO.ModulesToCompile)
1223 ThinLTO.ModulesToCompile = ModuleMapType();
1226 for (
const std::string &Name : Conf.ThinLTOModulesToCompile) {
1227 if (BMID.contains(Name)) {
1228 ThinLTO.ModulesToCompile->insert({BMID, BM});
1229 LLVM_DEBUG(
dbgs() <<
"[ThinLTO] Selecting " << BMID <<
" to compile\n");
1239 CalledGetMaxTasks =
true;
1240 auto ModuleCount = ThinLTO.ModulesToCompile ? ThinLTO.ModulesToCompile->size()
1241 : ThinLTO.ModuleMap.size();
1242 return RegularLTO.ParallelCodeGenParallelismLevel + ModuleCount;
1247Error LTO::checkPartiallySplit() {
1251 const Module *Combined = RegularLTO.CombinedModule.get();
1257 Combined, Intrinsic::type_checked_load_relative);
1261 if ((TypeTestFunc && !TypeTestFunc->
use_empty()) ||
1262 (TypeCheckedLoadFunc && !TypeCheckedLoadFunc->
use_empty()) ||
1263 (TypeCheckedLoadRelativeFunc &&
1264 !TypeCheckedLoadRelativeFunc->
use_empty()))
1266 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1271 for (
auto &
P : ThinLTO.CombinedIndex) {
1272 for (
auto &S :
P.second.getSummaryList()) {
1276 if (!FS->type_test_assume_vcalls().empty() ||
1277 !FS->type_checked_load_vcalls().empty() ||
1278 !FS->type_test_assume_const_vcalls().empty() ||
1279 !FS->type_checked_load_const_vcalls().empty() ||
1280 !FS->type_tests().empty())
1282 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1298 for (
auto &Res : *GlobalResolutions) {
1301 if (Res.second.IRName.
empty())
1307 if (Res.second.VisibleOutsideSummary && Res.second.Prevailing)
1308 GUIDPreservedSymbols.
insert(GUID);
1310 if (Res.second.ExportDynamic)
1311 DynamicExportSymbols.insert(GUID);
1313 GUIDPrevailingResolutions[GUID] =
1318 auto It = GUIDPrevailingResolutions.
find(
G);
1319 if (It == GUIDPrevailingResolutions.
end())
1324 isPrevailing, Conf.OptLevel > 0);
1328 if (!StatsFileOrErr)
1329 return StatsFileOrErr.takeError();
1330 std::unique_ptr<ToolOutputFile> StatsFile = std::move(StatsFileOrErr.get());
1332 if (
Error Err = setupOptimizationRemarks())
1341 ThinLTO.CombinedIndex.setWithSupportsHotColdNew();
1343 Error Result = runRegularLTO(AddStream);
1347 Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols);
1363 for (
auto &M : RegularLTO.ModsWithSummaries)
1364 if (
Error Err = linkRegularLTO(std::move(M),
true))
1372 if (
Error Err = checkPartiallySplit())
1377 const DataLayout &
DL = RegularLTO.CombinedModule->getDataLayout();
1378 for (
auto &
I : RegularLTO.Commons) {
1379 if (!
I.second.Prevailing)
1382 GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(
I.first);
1391 auto *GV =
new GlobalVariable(*RegularLTO.CombinedModule, Ty,
false,
1394 GV->setAlignment(
I.second.Alignment);
1404 bool WholeProgramVisibilityEnabledInLTO =
1405 Conf.HasWholeProgramVisibility &&
1408 (!Conf.ValidateAllVtablesHaveTypeInfos || Conf.AllVtablesHaveTypeInfos);
1412 auto IsVisibleToRegularObj = [&](StringRef
name) {
1413 auto It = GlobalResolutions->find(
name);
1414 return (It == GlobalResolutions->end() ||
1415 It->second.VisibleOutsideSummary || !It->second.Prevailing);
1421 *RegularLTO.CombinedModule, WholeProgramVisibilityEnabledInLTO,
1422 DynamicExportSymbols, Conf.ValidateAllVtablesHaveTypeInfos,
1423 IsVisibleToRegularObj);
1425 WholeProgramVisibilityEnabledInLTO);
1427 if (Conf.PreOptModuleHook &&
1428 !Conf.PreOptModuleHook(0, *RegularLTO.CombinedModule))
1431 if (!Conf.CodeGenOnly) {
1432 for (
const auto &R : *GlobalResolutions) {
1434 RegularLTO.CombinedModule->getNamedValue(
R.second.IRName);
1435 if (!
R.second.isPrevailingIRSymbol())
1437 if (
R.second.Partition != 0 &&
1438 R.second.Partition != GlobalResolution::External)
1466 if (Conf.PostInternalizeModuleHook &&
1467 !Conf.PostInternalizeModuleHook(0, *RegularLTO.CombinedModule))
1471 if (!RegularLTO.EmptyCombinedModule || Conf.AlwaysEmitRegularLTOObj) {
1473 backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,
1474 *RegularLTO.CombinedModule, ThinLTO.CombinedIndex))
1491 return LibcallSymbols;
1496 const std::string &NewModulePath)
const {
1497 return emitFiles(ImportList, ModulePath, NewModulePath,
1498 NewModulePath +
".thinlto.bc",
1504 const std::string &NewModulePath,
StringRef SummaryPath,
1505 std::optional<std::reference_wrapper<ImportsFilesContainer>> ImportsFiles)
1512 ImportList, ModuleToSummariesForIndex,
1513 DeclarationSummaries);
1520 &DeclarationSummaries);
1524 ModulePath, NewModulePath +
".imports", ModuleToSummariesForIndex);
1525 if (ImportsFilesError)
1526 return ImportsFilesError;
1532 ModulePath, ModuleToSummariesForIndex,
1533 [&](
StringRef M) { ImportsFiles->get().push_back(M.str()); });
1546 bool ShouldEmitIndexFiles;
1553 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
1556 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
1557 AddStream(
std::
move(AddStream)),
1558 ShouldEmitIndexFiles(ShouldEmitIndexFiles) {
1568class InProcessThinBackend :
public CGThinBackend {
1573 InProcessThinBackend(
1578 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles)
1579 : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
1580 AddStream, OnWrite, ShouldEmitIndexFiles,
1581 ShouldEmitImportsFiles, ThinLTOParallelism),
1584 virtual Error runThinLTOBackendThread(
1585 AddStreamFn AddStream, FileCache Cache,
unsigned Task, BitcodeModule BM,
1586 ModuleSummaryIndex &CombinedIndex,
1587 const FunctionImporter::ImportMapTy &ImportList,
1589 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1591 MapVector<StringRef, BitcodeModule> &ModuleMap) {
1593 llvm::TimeTraceScope timeScope(
"Run ThinLTO backend thread (in-process)",
1595 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1596 LTOLLVMContext BackendContext(Conf);
1597 Expected<std::unique_ptr<Module>> MOrErr = BM.
parseModule(BackendContext);
1601 return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,
1602 ImportList, DefinedGlobals, &ModuleMap,
1605 if (ShouldEmitIndexFiles) {
1606 if (
auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1612 [](uint32_t V) { return V == 0; }))
1615 return RunThinBackend(AddStream);
1619 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1620 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1621 Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task,
Key, ModuleID);
1624 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1626 return RunThinBackend(CacheAddStream);
1632 unsigned Task, BitcodeModule BM,
1633 const FunctionImporter::ImportMapTy &ImportList,
1635 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1636 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
1638 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
1640 ModuleToDefinedGVSummaries.
find(ModulePath)->second;
1641 BackendThreadPool.async(
1642 [=](BitcodeModule BM, ModuleSummaryIndex &CombinedIndex,
1643 const FunctionImporter::ImportMapTy &ImportList,
1645 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
1648 MapVector<StringRef, BitcodeModule> &ModuleMap) {
1652 Error E = runThinLTOBackendThread(
1653 AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList,
1654 ResolvedODR, DefinedGlobals, ModuleMap);
1656 std::unique_lock<std::mutex>
L(ErrMu);
1665 BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList),
1666 std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap));
1669 OnWrite(std::string(ModulePath));
1679class FirstRoundThinBackend :
public InProcessThinBackend {
1684 FirstRoundThinBackend(
1685 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
1686 ThreadPoolStrategy ThinLTOParallelism,
1687 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
1690 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
1691 ModuleToDefinedGVSummaries, std::
move(CGAddStream),
1692 std::
move(CGCache), nullptr,
1695 IRAddStream(std::
move(IRAddStream)), IRCache(std::
move(IRCache)) {}
1697 Error runThinLTOBackendThread(
1698 AddStreamFn CGAddStream, FileCache CGCache,
unsigned Task,
1699 BitcodeModule BM, ModuleSummaryIndex &CombinedIndex,
1700 const FunctionImporter::ImportMapTy &ImportList,
1702 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1704 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
1706 llvm::TimeTraceScope timeScope(
"Run ThinLTO backend thread (first round)",
1708 auto RunThinBackend = [&](
AddStreamFn CGAddStream,
1710 LTOLLVMContext BackendContext(Conf);
1711 Expected<std::unique_ptr<Module>> MOrErr = BM.
parseModule(BackendContext);
1715 return thinBackend(Conf, Task, CGAddStream, **MOrErr, CombinedIndex,
1716 ImportList, DefinedGlobals, &ModuleMap,
1722 if (ShouldEmitIndexFiles) {
1723 if (
auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1728 "Both caches for CG and IR should have matching availability");
1731 [](uint32_t V) { return V == 0; }))
1734 return RunThinBackend(CGAddStream, IRAddStream);
1738 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1739 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1740 Expected<AddStreamFn> CacheCGAddStreamOrErr =
1741 CGCache(Task, CGKey, ModuleID);
1744 AddStreamFn &CacheCGAddStream = *CacheCGAddStreamOrErr;
1748 Expected<AddStreamFn> CacheIRAddStreamOrErr =
1749 IRCache(Task, IRKey, ModuleID);
1752 AddStreamFn &CacheIRAddStream = *CacheIRAddStreamOrErr;
1758 if (CacheCGAddStream || CacheIRAddStream) {
1761 return RunThinBackend(CacheCGAddStream ? CacheCGAddStream : CGAddStream,
1762 CacheIRAddStream ? CacheIRAddStream : IRAddStream);
1774class SecondRoundThinBackend :
public InProcessThinBackend {
1775 std::unique_ptr<SmallVector<StringRef>> IRFiles;
1779 SecondRoundThinBackend(
1780 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
1781 ThreadPoolStrategy ThinLTOParallelism,
1782 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
1786 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
1787 ModuleToDefinedGVSummaries, std::
move(AddStream),
1792 IRFiles(std::
move(IRFiles)), CombinedCGDataHash(CombinedCGDataHash) {}
1794 Error runThinLTOBackendThread(
1795 AddStreamFn AddStream, FileCache Cache,
unsigned Task, BitcodeModule BM,
1796 ModuleSummaryIndex &CombinedIndex,
1797 const FunctionImporter::ImportMapTy &ImportList,
1799 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1801 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
1803 llvm::TimeTraceScope timeScope(
"Run ThinLTO backend thread (second round)",
1805 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1806 LTOLLVMContext BackendContext(Conf);
1807 std::unique_ptr<Module> LoadedModule =
1810 return thinBackend(Conf, Task, AddStream, *LoadedModule, CombinedIndex,
1811 ImportList, DefinedGlobals, &ModuleMap,
1816 [](uint32_t V) { return V == 0; }))
1819 return RunThinBackend(AddStream);
1824 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1825 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1827 std::to_string(CombinedCGDataHash));
1828 Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task,
Key, ModuleID);
1831 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1833 if (CacheAddStream) {
1836 return RunThinBackend(CacheAddStream);
1846 bool ShouldEmitIndexFiles,
1847 bool ShouldEmitImportsFiles) {
1852 return std::make_unique<InProcessThinBackend>(
1853 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1854 AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
1855 ShouldEmitImportsFiles);
1881 return std::string(Path);
1885 if (!ParentPath.
empty()) {
1888 llvm::errs() <<
"warning: could not create directory '" << ParentPath
1889 <<
"': " << EC.message() <<
'\n';
1891 return std::string(NewPath);
1896 std::string OldPrefix, NewPrefix, NativeObjectPrefix;
1900 WriteIndexesThinBackend(
1904 std::string OldPrefix, std::string NewPrefix,
1905 std::string NativeObjectPrefix,
bool ShouldEmitImportsFiles,
1908 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
1909 OldPrefix(OldPrefix), NewPrefix(NewPrefix),
1910 NativeObjectPrefix(NativeObjectPrefix),
1911 LinkedObjectsFile(LinkedObjectsFile) {}
1917 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1925 if (LinkedObjectsFile) {
1926 std::string ObjectPrefix =
1927 NativeObjectPrefix.empty() ? NewPrefix : NativeObjectPrefix;
1928 std::string LinkedObjectsFilePath =
1930 *LinkedObjectsFile << LinkedObjectsFilePath <<
'\n';
1933 BackendThreadPool.async(
1934 [
this](
const StringRef ModulePath,
1935 const FunctionImporter::ImportMapTy &ImportList,
1936 const std::string &OldPrefix,
const std::string &NewPrefix) {
1937 std::string NewModulePath =
1939 auto E = emitFiles(ImportList, ModulePath, NewModulePath);
1941 std::unique_lock<std::mutex>
L(ErrMu);
1949 ModulePath, ImportList, OldPrefix, NewPrefix);
1952 OnWrite(std::string(ModulePath));
1956 bool isSensitiveToInputOrder()
override {
1966 std::string NewPrefix, std::string NativeObjectPrefix,
1973 return std::make_unique<WriteIndexesThinBackend>(
1974 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1975 OldPrefix, NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,
1976 LinkedObjectsFile, OnWrite);
1991 if (ThinLTO.ModuleMap.
empty())
1994 if (ThinLTO.ModulesToCompile && ThinLTO.ModulesToCompile->empty()) {
1995 llvm::errs() <<
"warning: [ThinLTO] No module compiled\n";
1999 if (Conf.CombinedIndexHook &&
2000 !Conf.CombinedIndexHook(ThinLTO.CombinedIndex, GUIDPreservedSymbols))
2005 DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries(
2006 ThinLTO.ModuleMap.size());
2007 ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule(
2008 ModuleToDefinedGVSummaries);
2016 for (
auto &
Mod : ThinLTO.ModuleMap)
2017 if (!ModuleToDefinedGVSummaries.
count(
Mod.first))
2020 FunctionImporter::ImportListsTy ImportLists(ThinLTO.ModuleMap.size());
2021 DenseMap<StringRef, FunctionImporter::ExportSetTy> ExportLists(
2022 ThinLTO.ModuleMap.size());
2023 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
2026 ThinLTO.CombinedIndex.dumpSCCs(
outs());
2028 std::set<GlobalValue::GUID> ExportedGUIDs;
2030 bool WholeProgramVisibilityEnabledInLTO =
2031 Conf.HasWholeProgramVisibility &&
2034 (!Conf.ValidateAllVtablesHaveTypeInfos || Conf.AllVtablesHaveTypeInfos);
2036 ThinLTO.CombinedIndex.setWithWholeProgramVisibility();
2041 DenseSet<GlobalValue::GUID> VisibleToRegularObjSymbols;
2042 if (WholeProgramVisibilityEnabledInLTO &&
2043 Conf.ValidateAllVtablesHaveTypeInfos) {
2046 auto IsVisibleToRegularObj = [&](StringRef
name) {
2047 auto It = GlobalResolutions->find(
name);
2048 return (It == GlobalResolutions->end() ||
2049 It->second.VisibleOutsideSummary || !It->second.Prevailing);
2053 VisibleToRegularObjSymbols,
2054 IsVisibleToRegularObj);
2060 ThinLTO.CombinedIndex, WholeProgramVisibilityEnabledInLTO,
2061 DynamicExportSymbols, VisibleToRegularObjSymbols);
2066 std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;
2067 DenseSet<StringRef> ExternallyVisibleSymbolNames;
2073 DenseSet<StringRef> *ExternallyVisibleSymbolNamesPtr =
2075 ? &ExternallyVisibleSymbolNames
2079 ExternallyVisibleSymbolNamesPtr);
2082 return ThinLTO.isPrevailingModuleForGUID(GUID, S->modulePath());
2085 MemProfContextDisambiguation ContextDisambiguation;
2086 ContextDisambiguation.
run(
2087 ThinLTO.CombinedIndex, isPrevailing,
2088 [&](StringRef
PassName, StringRef RemarkName,
const Twine &Msg) {
2089 auto R = OptimizationRemark(PassName.data(), RemarkName,
2090 LinkerRemarkFunction);
2100 for (
auto &Res : *GlobalResolutions) {
2103 if (Res.second.Partition != GlobalResolution::External ||
2104 !Res.second.isPrevailingIRSymbol())
2109 if (ThinLTO.CombinedIndex.isGUIDLive(GUID))
2110 ExportedGUIDs.insert(GUID);
2117 releaseGlobalResolutionsMemory();
2119 if (Conf.OptLevel > 0)
2121 isPrevailing, ImportLists, ExportLists);
2125 auto &Defs = ThinLTO.CombinedIndex.cfiFunctionDefs();
2126 ExportedGUIDs.insert(Defs.guid_begin(), Defs.guid_end());
2127 auto &Decls = ThinLTO.CombinedIndex.cfiFunctionDecls();
2128 ExportedGUIDs.insert(Decls.guid_begin(), Decls.guid_end());
2130 auto isExported = [&](StringRef ModuleIdentifier, ValueInfo
VI) {
2131 const auto &ExportList = ExportLists.
find(ModuleIdentifier);
2132 return (ExportList != ExportLists.end() && ExportList->second.
count(VI)) ||
2133 ExportedGUIDs.count(
VI.getGUID());
2139 LocalWPDTargetsMap, ExternallyVisibleSymbolNamesPtr);
2141 if (ExternallyVisibleSymbolNamesPtr) {
2144 for (
auto &
I : ThinLTO.CombinedIndex) {
2145 ValueInfo
VI = ThinLTO.CombinedIndex.getValueInfo(
I);
2146 for (
const auto &Summary :
VI.getSummaryList()) {
2147 const GlobalValueSummary *
Base =
Summary->getBaseObject();
2151 ExternallyVisibleSymbolNamesPtr->
insert(
VI.name());
2159 ExternallyVisibleSymbolNamesPtr);
2161 auto recordNewLinkage = [&](StringRef ModuleIdentifier,
2164 ResolvedODR[ModuleIdentifier][
GUID] = NewLinkage;
2167 recordNewLinkage, GUIDPreservedSymbols);
2176 TimeTraceScopeExit.release();
2179 ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;
2181 auto RunBackends = [&](ThinBackendProc *BackendProcess) ->
Error {
2182 auto ProcessOneModule = [&](
int I) ->
Error {
2186 return BackendProcess->start(
2187 RegularLTO.ParallelCodeGenParallelismLevel +
I,
Mod.second,
2188 ImportLists[
Mod.first], ExportLists[
Mod.first],
2189 ResolvedODR[
Mod.first], ThinLTO.ModuleMap);
2192 BackendProcess->setup(ModuleMap.
size(),
2193 RegularLTO.ParallelCodeGenParallelismLevel,
2194 RegularLTO.CombinedModule->getTargetTriple());
2196 if (BackendProcess->getThreadCount() == 1 ||
2197 BackendProcess->isSensitiveToInputOrder()) {
2203 for (
int I = 0,
E = ModuleMap.
size();
I !=
E; ++
I)
2204 if (
Error E = ProcessOneModule(
I))
2211 std::vector<BitcodeModule *> ModulesVec;
2212 ModulesVec.reserve(ModuleMap.
size());
2213 for (
auto &
Mod : ModuleMap)
2214 ModulesVec.push_back(&
Mod.second);
2216 if (
Error E = ProcessOneModule(
I))
2219 return BackendProcess->wait();
2223 std::unique_ptr<ThinBackendProc> BackendProc =
2224 ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
2226 return RunBackends(BackendProc.get());
2234 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Initializing ThinLTO two-codegen rounds\n");
2237 auto Parallelism = ThinLTO.Backend.getParallelism();
2240 cgdata::StreamCacheData CG(MaxTasks, Cache,
"CG"),
IR(MaxTasks, Cache,
"IR");
2245 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Running the first round of codegen\n");
2246 auto FirstRoundLTO = std::make_unique<FirstRoundThinBackend>(
2247 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2248 CG.AddStream, CG.Cache,
IR.AddStream,
IR.Cache);
2249 if (
Error E = RunBackends(FirstRoundLTO.get()))
2254 if (
Error E = CombinedHashOrErr.takeError())
2256 auto CombinedHash = *CombinedHashOrErr;
2257 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] CGData hash: " << CombinedHash <<
"\n");
2261 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Running the second round of codegen\n");
2262 auto SecondRoundLTO = std::make_unique<SecondRoundThinBackend>(
2263 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2264 AddStream, Cache,
IR.getResult(), CombinedHash);
2265 return RunBackends(SecondRoundLTO.get());
2283 if (
Error E = ResultOrErr.takeError())
2284 return std::move(E);
2287 (*ResultOrErr)->keep();
2295 if (StatsFilename.
empty())
2306 return std::move(StatsFile);
2314 std::vector<int> ModulesOrdering(Seq.begin(), Seq.end());
2315 llvm::sort(ModulesOrdering, [&](
int LeftIndex,
int RightIndex) {
2316 auto LSize = R[LeftIndex]->getBuffer().size();
2317 auto RSize = R[RightIndex]->getBuffer().size();
2318 return LSize > RSize;
2320 return ModulesOrdering;
2330class OutOfProcessThinBackend :
public CGThinBackend {
2336 SString LinkerOutputFile;
2338 SString DistributorPath;
2341 SString RemoteCompiler;
2350 std::atomic<size_t> CachedJobs{0};
2355 StringRef NativeObjectPath;
2356 StringRef SummaryIndexPath;
2358 std::string CacheKey;
2360 bool Cached =
false;
2369 unsigned ThinLTOTaskOffset;
2372 llvm::Triple Triple;
2378 OutOfProcessThinBackend(
2379 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
2380 ThreadPoolStrategy ThinLTOParallelism,
2381 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
2383 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
2384 StringRef LinkerOutputFile, StringRef Distributor,
2388 : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
2389 AddStream, OnWrite, ShouldEmitIndexFiles,
2390 ShouldEmitImportsFiles, ThinLTOParallelism),
2391 LinkerOutputFile(LinkerOutputFile), DistributorPath(Distributor),
2392 DistributorArgs(DistributorArgs), RemoteCompiler(RemoteCompiler),
2393 RemoteCompilerPrependArgs(RemoteCompilerPrependArgs),
2394 RemoteCompilerArgs(RemoteCompilerArgs), SaveTemps(SaveTemps),
2395 Cache(std::
move(CacheFn)) {}
2397 void setup(
unsigned ThinLTONumTasks,
unsigned ThinLTOTaskOffset,
2398 llvm::Triple Triple)
override {
2400 Jobs.
resize((
size_t)ThinLTONumTasks);
2401 this->ThinLTOTaskOffset = ThinLTOTaskOffset;
2402 this->Triple = std::move(Triple);
2403 this->Conf.
Dtlto = 1;
2406 virtual Error runThinLTOBackendThread(
2407 Job &J,
const FunctionImporter::ImportMapTy &ImportList,
2409 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
2412 TimeTraceScope TimeScope(
"Emit individual index for DTLTO",
2413 J.SummaryIndexPath);
2414 if (
auto E = emitFiles(ImportList, J.ModuleID, J.ModuleID.str(),
2415 J.SummaryIndexPath, J.ImportsFiles))
2421 [](uint32_t V) { return V == 0; }))
2426 TimeTraceScope TimeScope(
"Check cache for DTLTO", J.SummaryIndexPath);
2428 ModuleToDefinedGVSummaries.
find(J.ModuleID)->second;
2432 ExportList, ResolvedODR, DefinedGlobals,
2433 CfiFunctionDefs, CfiFunctionDecls);
2436 auto CacheAddStreamExp = Cache(J.Task, J.CacheKey, J.ModuleID);
2437 if (
Error Err = CacheAddStreamExp.takeError())
2442 if (!CacheAddStream) {
2444 CachedJobs.fetch_add(1);
2449 J.CacheAddStream = std::move(CacheAddStream);
2455 unsigned Task, BitcodeModule BM,
2456 const FunctionImporter::ImportMapTy &ImportList,
2458 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
2459 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
2465 itostr(Task) +
"." + UID +
".native.o");
2467 Job &J = Jobs[Task - ThinLTOTaskOffset];
2470 Saver.
save(ObjFilePath.str()),
2471 Saver.
save(ObjFilePath.str() +
".thinlto.bc"),
2480 if (!ShouldEmitIndexFiles)
2484 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
2488 BackendThreadPool.async(
2489 [=](Job &J,
const FunctionImporter::ImportMapTy &ImportList,
2491 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
2496 "Emit individual index and check cache for DTLTO");
2498 runThinLTOBackendThread(J, ImportList, ExportList, ResolvedODR);
2500 std::unique_lock<std::mutex>
L(ErrMu);
2509 std::ref(J), std::ref(ImportList), std::ref(ExportList),
2510 std::ref(ResolvedODR));
2524 void buildCommonRemoteCompilerOptions() {
2525 const lto::Config &
C = Conf;
2526 auto &
Ops = CodegenOptions;
2530 if (
C.Options.EmitAddrsig)
2531 Ops.push_back(
"-faddrsig");
2532 if (
C.Options.FunctionSections)
2533 Ops.push_back(
"-ffunction-sections");
2534 if (
C.Options.DataSections)
2535 Ops.push_back(
"-fdata-sections");
2540 Ops.push_back(
"-fpic");
2544 if (!
C.PGOWarnMismatch) {
2545 Ops.push_back(
"-mllvm");
2546 Ops.push_back(
"-no-pgo-warn-mismatch");
2551 if (!
C.SampleProfile.empty()) {
2553 Saver.
save(
"-fprofile-sample-use=" + Twine(
C.SampleProfile)));
2554 CommonInputs.
insert(
C.SampleProfile);
2558 Ops.push_back(
"-Wno-unused-command-line-argument");
2561 if (!RemoteCompilerArgs.
empty())
2562 for (
auto &a : RemoteCompilerArgs)
2568 bool emitDistributorJson(StringRef DistributorJson) {
2571 raw_fd_ostream OS(DistributorJson, EC);
2575 json::OStream JOS(OS);
2578 JOS.attributeObject(
"common", [&]() {
2579 JOS.attribute(
"linker_output", LinkerOutputFile);
2581 JOS.attributeArray(
"args", [&]() {
2582 JOS.value(RemoteCompiler);
2585 if (!RemoteCompilerPrependArgs.
empty())
2586 for (
auto &
A : RemoteCompilerPrependArgs)
2591 JOS.value(Saver.
save(
"--target=" + Triple.
str()));
2593 for (
const auto &
A : CodegenOptions)
2597 JOS.attribute(
"inputs",
Array(CommonInputs));
2601 JOS.attributeArray(
"jobs", [&]() {
2602 for (
const auto &J : Jobs) {
2610 SmallVector<StringRef, 1> Outputs;
2613 JOS.attributeArray(
"args", [&]() {
2614 JOS.value(J.ModuleID);
2618 Saver.
save(
"-fthinlto-index=" + Twine(J.SummaryIndexPath)));
2622 JOS.value(J.NativeObjectPath);
2630 JOS.attribute(
"inputs",
Array(Inputs));
2632 JOS.attribute(
"outputs",
Array(Outputs));
2641 void removeFile(StringRef FileName) {
2643 if (EC && EC != std::make_error_code(std::errc::no_such_file_or_directory))
2644 errs() <<
"warning: could not remove the file '" << FileName
2645 <<
"': " <<
EC.message() <<
"\n";
2648 Error wait()
override {
2651 BackendThreadPool.wait();
2653 return std::move(*Err);
2656 llvm::TimeTraceScope TimeScope(
"Remove DTLTO temporary files");
2658 for (
auto &Job : Jobs) {
2659 removeFile(Job.NativeObjectPath);
2660 if (!ShouldEmitIndexFiles)
2661 removeFile(Job.SummaryIndexPath);
2665 const StringRef BCError =
"DTLTO backend compilation: ";
2667 buildCommonRemoteCompilerOptions();
2671 llvm::TimeTraceScope TimeScope(
"Emit DTLTO JSON");
2673 UID +
".dist-file.json");
2677 if (!emitDistributorJson(JsonFile))
2679 BCError +
"failed to generate distributor JSON script: " + JsonFile,
2684 removeFile(JsonFile);
2688 llvm::TimeTraceScope TimeScope(
"Execute DTLTO distributor",
2691 if (CachedJobs.load() < Jobs.size()) {
2694 Args.push_back(JsonFile);
2701 BCError +
"distributor execution failed" +
2702 (!ErrMsg.empty() ?
": " + ErrMsg + Twine(
".") : Twine(
".")),
2709 llvm::TimeTraceScope FilesScope(
"Add DTLTO files to the link");
2710 for (
auto &Job : Jobs) {
2711 if (!Job.CacheKey.empty() && Job.Cached) {
2717 auto ObjFileMbOrErr =
2720 if (std::error_code EC = ObjFileMbOrErr.getError())
2722 BCError +
"cannot open native object file: " +
2723 Job.NativeObjectPath +
": " +
EC.message(),
2726 MemoryBufferRef ObjFileMbRef = ObjFileMbOrErr->get()->getMemBufferRef();
2730 assert(Job.CacheAddStream);
2732 auto CachedFileStreamOrErr =
2733 Job.CacheAddStream(Job.Task, Job.ModuleID);
2734 if (!CachedFileStreamOrErr)
2736 CachedFileStreamOrErr.takeError(),
2738 "Cannot get a cache file stream: %s",
2739 Job.NativeObjectPath.data()));
2741 auto &CacheStream = *(CachedFileStreamOrErr->get());
2742 *(CacheStream.OS) << ObjFileMbRef.
getBuffer();
2743 if (
Error Err = CacheStream.commit())
2746 auto StreamOrErr = AddStream(Job.Task, Job.ModuleID);
2747 if (
Error Err = StreamOrErr.takeError())
2749 auto &Stream = *StreamOrErr->get();
2751 if (
Error Err = Stream.commit())
2763 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
2772 return std::make_unique<OutOfProcessThinBackend>(
2773 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2774 AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
2775 ShouldEmitImportsFiles, LinkerOutputFile, Distributor,
2776 DistributorArgs, RemoteCompiler, RemoteCompilerPrependArgs,
2777 RemoteCompilerArgs, SaveTemps);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file supports working with JSON data.
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 void thinLTOInternalizeAndPromoteGUID(ValueInfo VI, function_ref< bool(StringRef, ValueInfo)> isExported, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, DenseSet< StringRef > *ExternallyVisibleSymbolNamesPtr)
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"))
Legalize the Machine IR a function s Machine IR
Machine Check Debug Module
static constexpr StringLiteral Filename
Provides a library for accessing information about this process and other processes on the operating ...
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...
static const char PassName[]
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
empty - Check if the array is empty.
const T & consume_front()
consume_front() - Returns the first element and drops it from ArrayRef.
static LLVM_ABI 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
LLVM_ABI 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.
LLVM_ABI Expected< std::unique_ptr< Module > > parseModule(LLVMContext &Context, ParserCallbacks Callbacks={})
Read the entire bitcode module and return it.
LLVM_ABI 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 LLVM_ABI 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.
The map maintains the list of imports.
DenseSet< ValueInfo > ExportSetTy
The set contains an entry for every global value that the module exports.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Function and variable summary information to aid decisions and implementation of importing.
static bool isAppendingLinkage(LinkageTypes Linkage)
static LLVM_ABI GUID getGUIDAssumingExternalLinkage(StringRef GlobalName)
Return a 64-bit global unique ID constructed from the name of a global symbol.
static bool isExternalWeakLinkage(LinkageTypes Linkage)
static bool isLocalLinkage(LinkageTypes Linkage)
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
void setUnnamedAddr(UnnamedAddr Val)
uint64_t GUID
Declare a type to represent a global unique identifier for a global value.
bool hasLocalLinkage() const
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
LLVM_ABI const Comdat * getComdat() const
static bool isLinkOnceLinkage(LinkageTypes Linkage)
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.
static bool isExternalLinkage(LinkageTypes Linkage)
VisibilityTypes
An enumeration for the kinds of visibility of global values.
@ DefaultVisibility
The GV is visible.
static LLVM_ABI std::string getGlobalIdentifier(StringRef Name, GlobalValue::LinkageTypes Linkage, StringRef FileName)
Return the modified name for a global value suitable to be used as the key for a global lookup (e....
static LinkageTypes getWeakLinkage(bool ODR)
static bool isWeakForLinker(LinkageTypes Linkage)
Whether the definition of this global may be replaced at link time.
bool hasAppendingLinkage() const
bool hasAvailableExternallyLinkage() const
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
static bool isLinkOnceODRLinkage(LinkageTypes Linkage)
LLVM_ABI uint64_t getGlobalSize(const DataLayout &DL) const
Get the size of this global variable in bytes.
LLVM_ABI void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
This is an important class for using LLVM in a threaded context.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
This class implements a map that also provides access to all stored values in a deterministic order.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
StringRef getBuffer() const
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...
CfiFunctionIndex & cfiFunctionDecls()
void setPartiallySplitLTOUnits()
void releaseTemporaryMemory()
const ModuleHash & getModuleHash(const StringRef ModPath) const
Get the module SHA1 hash recorded for the given module path.
bool partiallySplitLTOUnits() const
const StringMap< ModuleHash > & modulePaths() const
Table of modules, containing module hash and id.
CfiFunctionIndex & cfiFunctionDefs()
LLVM_ABI void addModule(Module *M)
static LLVM_ABI 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.
PointerUnion< GlobalValue *, AsmSymbol * > Symbol
LLVM_ABI 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 class that wrap the SHA1 algorithm.
LLVM_ABI void update(ArrayRef< uint8_t > Data)
Digest more data.
LLVM_ABI std::array< uint8_t, 20 > result()
Return the current raw 160-bits SHA1 for the digested data since the last call to init().
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.
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
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.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
StringRef save(const char *S)
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.
This tells how a thread pool will be used.
The TimeTraceScope is a helper class to call the begin and end functions of the time trace profiler.
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 isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
const std::string & str() const
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, DriverKit, XROS, or bridgeOS).
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 LLVM_ABI Type * getVoidTy(LLVMContext &C)
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI 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)
void insert_range(Range &&R)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
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().
LLVM_ABI LTO(Config Conf, ThinBackend Backend={}, unsigned ParallelCodeGenParallelismLevel=1, LTOKind LTOMode=LTOK_Default)
Create an LTO object.
LLVM_ABI Error add(std::unique_ptr< InputFile > Obj, ArrayRef< SymbolResolution > Res)
Add an input file to the LTO link, using the provided symbol resolutions.
static LLVM_ABI SmallVector< const char * > getRuntimeLibcallSymbols(const Triple &TT)
Static method that returns a list of libcall symbols that can be generated by LTO but might not be vi...
virtual Expected< std::shared_ptr< lto::InputFile > > addInput(std::unique_ptr< lto::InputFile > InputPtr)
virtual Error serializeInputsForDistribution()
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.
void emitRemark(OptimizationRemark &Remark)
Helper to emit an optimization remark during the LTO link when outside of the standard optimization p...
LLVM_ABI unsigned getMaxTasks() const
Returns an upper bound on the number of tasks that the client may expect.
LLVM_ABI Error run(AddStreamFn AddStream, FileCache Cache={})
Runs the LTO pipeline.
This class defines the interface to the ThinLTO backend.
bool ShouldEmitImportsFiles
const DenseMap< StringRef, GVSummaryMapTy > & ModuleToDefinedGVSummaries
LLVM_ABI Error emitFiles(const FunctionImporter::ImportMapTy &ImportList, StringRef ModulePath, const std::string &NewModulePath) const
ModuleSummaryIndex & CombinedIndex
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.
static LLVM_ABI Pid getProcessId()
Get the process's identifier.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI Function * getDeclarationIfExists(const Module *M, ID id)
Look up the Function declaration of the intrinsic id in the Module M and return it if it exists.
static auto libcall_impls()
LLVM_ABI Expected< stable_hash > mergeCodeGenData(ArrayRef< StringRef > ObjectFiles)
Merge the codegen data from the scratch objects ObjectFiles from the first codegen round.
LLVM_ABI std::unique_ptr< Module > loadModuleForTwoRounds(BitcodeModule &OrigModule, unsigned Task, LLVMContext &Context, ArrayRef< StringRef > IRFiles)
Load the optimized bitcode module for the second codegen round.
initializer< Ty > init(const Ty &Val)
LLVM_ABI ThinBackend createInProcessThinBackend(ThreadPoolStrategy Parallelism, IndexWriteCallback OnWrite=nullptr, bool ShouldEmitIndexFiles=false, bool ShouldEmitImportsFiles=false)
This ThinBackend runs the individual backend jobs in-process.
LLVM_ABI 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.
LLVM_ABI StringLiteral getThinLTODefaultCPU(const Triple &TheTriple)
LLVM_ABI Expected< std::unique_ptr< ToolOutputFile > > setupStatsFile(StringRef StatsFilename)
Setups the output file for saving statistics.
LLVM_ABI ThinBackend createOutOfProcessThinBackend(ThreadPoolStrategy Parallelism, IndexWriteCallback OnWrite, bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles, StringRef LinkerOutputFile, StringRef Distributor, ArrayRef< StringRef > DistributorArgs, StringRef RemoteCompiler, ArrayRef< StringRef > RemoteCompilerPrependArgs, ArrayRef< StringRef > RemoteCompilerArgs, bool SaveTemps)
This ThinBackend generates the index shards and then runs the individual backend jobs via an external...
LLVM_ABI Error backend(const Config &C, AddStreamFn AddStream, unsigned ParallelCodeGenParallelismLevel, Module &M, ModuleSummaryIndex &CombinedIndex)
Runs a regular LTO backend.
std::function< void(const std::string &)> IndexWriteCallback
LLVM_ABI Error finalizeOptimizationRemarks(LLVMRemarkFileHandle DiagOutputFile)
LLVM_ABI ThinBackend createWriteIndexesThinBackend(ThreadPoolStrategy Parallelism, 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...
LLVM_ABI Expected< LLVMRemarkFileHandle > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::optional< uint64_t > RemarksHotnessThreshold=0, int Count=-1)
Setup optimization remarks.
LLVM_ABI std::vector< int > generateModulesOrdering(ArrayRef< BitcodeModule * > R)
Produces a container ordering for optimal multi-threaded processing.
LLVM_ABI 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, bool CodeGenOnly, AddStreamFn IRAddStream=nullptr, const std::vector< uint8_t > &CmdArgs=std::vector< uint8_t >())
Runs a ThinLTO backend.
llvm::SmallVector< std::string > ImportsFilesContainer
LLVM_ABI Expected< IRSymtabFile > readIRSymtab(MemoryBufferRef MBRef)
Reads a bitcode file, creating its irsymtab if necessary.
DiagnosticInfoOptimizationBase::Argument NV
void write64le(void *P, uint64_t V)
void write32le(void *P, uint32_t V)
LLVM_ABI std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
LLVM_ABI 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.
LLVM_ABI StringRef stem(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get stem.
LLVM_ABI StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
LLVM_ABI bool replace_path_prefix(SmallVectorImpl< char > &Path, StringRef OldPrefix, StringRef NewPrefix, Style style=Style::native)
Replace matching path prefix with another path.
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
LLVM_ABI bool RemoveFileOnSignal(StringRef Filename, std::string *ErrMsg=nullptr)
This function registers signal handlers to ensure that if a signal gets delivered that the named file...
LLVM_ABI int ExecuteAndWait(StringRef Program, ArrayRef< StringRef > Args, std::optional< ArrayRef< StringRef > > Env=std::nullopt, ArrayRef< std::optional< StringRef > > Redirects={}, unsigned SecondsToWait=0, unsigned MemoryLimit=0, std::string *ErrMsg=nullptr, bool *ExecutionFailed=nullptr, std::optional< ProcessStatistics > *ProcStat=nullptr, BitVector *AffinityMask=nullptr)
This function executes the program using the arguments provided.
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.
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
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"))
LLVM_ABI void runWholeProgramDevirtOnIndex(ModuleSummaryIndex &Summary, std::set< GlobalValue::GUID > &ExportedGUIDs, std::map< ValueInfo, std::vector< VTableSlotSummary > > &LocalWPDTargetsMap, DenseSet< StringRef > *ExternallyVisibleSymbolNamesPtr=nullptr)
Perform index-based whole program devirtualization on the Summary index.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
std::unordered_set< GlobalValueSummary * > GVSummaryPtrSet
A set of global value summary pointers.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void generateParamAccessSummary(ModuleSummaryIndex &Index)
cl::opt< bool > CodeGenDataThinLTOTwoRounds("codegen-data-thinlto-two-rounds", cl::init(false), cl::Hidden, cl::desc("Enable two-round ThinLTO code generation. The first round " "emits codegen data, while the second round uses the emitted " "codegen data for further optimizations."))
LLVM_ABI Expected< LLVMRemarkFileHandle > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::optional< uint64_t > RemarksHotnessThreshold=0)
Set up optimization remarks that output to a file.
scope_exit(Callable) -> scope_exit< Callable >
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"))
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
DenseMap< GlobalValue::GUID, GlobalValueSummary * > GVSummaryMapTy
Map of global value GUID to its summary, used to identify values defined in a particular module,...
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
uint64_t stable_hash
An opaque object representing a stable hash code.
std::string utostr(uint64_t X, bool isNeg=false)
LLVM_ABI 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.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
LLVM_ABI bool hasWholeProgramVisibility(bool WholeProgramVisibilityEnabledInLTO)
LLVM_ABI 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 ...
LLVM_ABI 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.
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI void EnableStatistics(bool DoPrintOnExit=true)
Enable the collection and printing of statistics.
LLVM_ABI void updateIndexWPDForExports(ModuleSummaryIndex &Summary, function_ref< bool(StringRef, ValueInfo)> isExported, std::map< ValueInfo, std::vector< VTableSlotSummary > > &LocalWPDTargetsMap, DenseSet< StringRef > *ExternallyVisibleSymbolNamesPtr=nullptr)
Call after cross-module importing to update the recorded single impl devirt target names for any loca...
LLVM_ABI void timeTraceProfilerInitialize(unsigned TimeTraceGranularity, StringRef ProcName, bool TimeTraceVerbose=false)
Initialize the time trace profiler.
LLVM_ABI void timeTraceProfilerFinishThread()
Finish a time trace profiler running on a worker thread.
LLVM_ABI std::string recomputeLTOCacheKey(const std::string &Key, StringRef ExtraID)
Recomputes the LTO cache key for a given key with an extra identifier.
Error joinErrors(Error E1, Error E2)
Concatenate errors.
LLVM_ABI void updatePublicTypeTestCalls(Module &M, bool WholeProgramVisibilityEnabledInLTO)
LLVM_ABI 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?
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
std::map< std::string, GVSummaryMapTy, std::less<> > ModuleToSummariesForIndexTy
Map of a module name to the GUIDs and summaries we will import from that module.
LLVM_ABI 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)
LLVM_ABI 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.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI 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.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
LLVM_ABI 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.
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
cl::opt< bool > EnableMemProfContextDisambiguation
Enable MemProf context disambiguation for thin link.
cl::opt< bool > ForceImportAll
LLVM_ABI 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.
ArrayRef(const T &OneElt) -> ArrayRef< T >
void toHex(ArrayRef< uint8_t > Input, bool LowerCase, SmallVectorImpl< char > &Output)
Convert buffer Input to its hexadecimal representation. The returned string is double the size of Inp...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void processImportsFiles(StringRef ModulePath, const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex, function_ref< void(const std::string &)> F)
Call F passing each of the files module ModulePath will import from.
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)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI 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 ...
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
static cl::opt< bool > LTOKeepSymbolCopies("lto-keep-symbol-copies", cl::init(false), cl::Hidden, cl::desc("Keep copies of symbols in LTO indexing"))
LLVM_ABI bool UpgradeDebugInfo(Module &M)
Check the debug info version number, if it is out-dated, drop the debug info.
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
cl::opt< bool > AlwaysRenamePromotedLocals
FIXME: The current optimization that avoids unnecessary renaming of promoted locals is incompatible w...
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.
LLVM_ABI void PrintStatisticsJSON(raw_ostream &OS)
Print statistics in JSON format.
void consumeError(Error Err)
Consume a Error without doing anything.
LLVM_ABI 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.
LLVM_ABI Error EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename, const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex)
Emit into OutputFilename the files module ModulePath will import from.
@ Keep
No function return thunk.
std::string itostr(int64_t X)
LLVM_ABI 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...
LLVM_ABI TimeTraceProfilerEntry * timeTraceProfilerBegin(StringRef Name, StringRef Detail)
Manually begin a time section, with the given Name and Detail.
LLVM_ABI void thinLTOInternalizeAndPromoteInIndex(ModuleSummaryIndex &Index, function_ref< bool(StringRef, ValueInfo)> isExported, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, DenseSet< StringRef > *ExternallyVisibleSymbolNamesPtr=nullptr)
Update the linkages in the given Index to mark exported values as external and non-exported values as...
LLVM_ABI 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 type represents a file cache system that manages caching of files.
const std::string & getCacheDirectoryPath() const
A simple container for information about the supported runtime calls.
unsigned getNumAvailableLibcallImpls() const
bool isAvailable(RTLIB::LibcallImpl Impl) const
LLVM_ABI RTLIB::LibcallImpl getSupportedLibcallImpl(StringRef FuncName) const
Check if this is valid libcall for the current module, otherwise RTLIB::Unsupported.
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl)
Get the libcall routine name for the specified libcall implementation.
Struct that holds a reference to a particular GUID in a global value summary.
std::optional< uint64_t > RemarksHotnessThreshold
The minimum hotness value a diagnostic needs in order to be included in optimization diagnostics.
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
CodeGenOptLevel CGOptLevel
bool Dtlto
This flag is used as one of parameters to calculate cache entries and to ensure that in-process cache...
std::string DefaultTriple
Setting this field will replace unspecified target triples in input files with this triple.
std::string DwoDir
The directory to store .dwo files.
std::string RemarksFilename
Optimization remarks file path.
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 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 ...
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).
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.
This type defines the behavior following the thin-link phase during ThinLTO.