27#include "llvm/Config/llvm-config.h"
57#include "llvm/Support/VCSRevision.h"
73#define DEBUG_TYPE "lto"
75Error LTO::setupOptimizationRemarks() {
82 return DiagFileOrErr.takeError();
84 DiagnosticOutputFile = std::move(*DiagFileOrErr);
91 if (!LinkerRemarkFunction) {
92 DummyModule = std::make_unique<Module>(
"remark_dummy", RegularLTO.Ctx);
110 cl::desc(
"Dump the SCCs in the ThinLTO index's callgraph"));
121 cl::desc(
"Enable global value internalization in LTO"));
125 cl::desc(
"Keep copies of symbols in LTO indexing"));
142 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
153 Hasher.
update(LLVM_VERSION_STRING);
155 Hasher.
update(LLVM_REVISION);
163 auto AddUnsigned = [&](
unsigned I) {
173 auto AddUint8 = [&](
const uint8_t I) {
197 AddUnsigned(
static_cast<int>(Conf.
CGOptLevel));
198 AddUnsigned(
static_cast<int>(Conf.
CGFileType));
206 AddUint8(Conf.
Dtlto);
209 auto ModHash = Index.getModuleHash(ModuleID);
214 std::vector<uint64_t> ExportsGUID;
215 ExportsGUID.reserve(ExportList.
size());
216 for (
const auto &VI : ExportList)
217 ExportsGUID.push_back(VI.getGUID());
221 for (
auto GUID : ExportsGUID)
226 auto Comp = [&](
const std::pair<StringRef, GlobalValue::GUID> &L,
227 const std::pair<StringRef, GlobalValue::GUID> &R) {
228 return std::make_pair(Index.getModule(L.first)->second, L.second) <
229 std::make_pair(Index.getModule(R.first)->second, R.second);
235 for (
const auto &[FromModule, GUID,
Type] : SortedImportList)
236 ++ModuleToNumImports[FromModule];
238 std::optional<StringRef> LastModule;
239 for (
const auto &[FromModule, GUID,
Type] : SortedImportList) {
240 if (LastModule != FromModule) {
244 LastModule = FromModule;
245 auto ModHash = Index.getModule(FromModule)->second;
247 AddUint64(ModuleToNumImports[FromModule]);
254 for (
auto &Entry : ResolvedODR) {
263 std::set<GlobalValue::GUID> UsedCfiDefs;
264 std::set<GlobalValue::GUID> UsedCfiDecls;
267 std::set<GlobalValue::GUID> UsedTypeIds;
270 if (CfiFunctionDefs.
contains(ValueGUID))
271 UsedCfiDefs.insert(ValueGUID);
272 if (CfiFunctionDecls.
contains(ValueGUID))
273 UsedCfiDecls.insert(ValueGUID);
278 AddUnsigned(GS->getVisibility());
279 AddUnsigned(GS->isLive());
280 AddUnsigned(GS->canAutoHide());
282 AddUnsigned(VI.isDSOLocal(Index.withDSOLocalPropagation()));
283 AddUsedCfiGlobal(VI.getGUID());
286 AddUnsigned(GVS->maybeReadOnly());
287 AddUnsigned(GVS->maybeWriteOnly());
290 for (
auto &TT : FS->type_tests())
291 UsedTypeIds.insert(TT);
292 for (
auto &TT : FS->type_test_assume_vcalls())
293 UsedTypeIds.insert(TT.GUID);
294 for (
auto &TT : FS->type_checked_load_vcalls())
295 UsedTypeIds.insert(TT.GUID);
296 for (
auto &TT : FS->type_test_assume_const_vcalls())
297 UsedTypeIds.insert(TT.VFunc.GUID);
298 for (
auto &TT : FS->type_checked_load_const_vcalls())
299 UsedTypeIds.insert(TT.VFunc.GUID);
300 for (
auto &ET : FS->calls()) {
301 AddUnsigned(ET.first.isDSOLocal(Index.withDSOLocalPropagation()));
302 AddUsedCfiGlobal(ET.first.getGUID());
309 for (
auto &GS : DefinedGlobals) {
313 AddUsedCfiGlobal(GS.first);
314 AddUsedThings(GS.second);
319 for (
const auto &[FromModule, GUID,
Type] : SortedImportList) {
325 AddUsedThings(AS->getBaseObject());
331 AddUnsigned(S.TTRes.TheKind);
332 AddUnsigned(S.TTRes.SizeM1BitWidth);
334 AddUint64(S.TTRes.AlignLog2);
335 AddUint64(S.TTRes.SizeM1);
336 AddUint64(S.TTRes.BitMask);
337 AddUint64(S.TTRes.InlineBits);
339 AddUint64(S.WPDRes.size());
340 for (
auto &WPD : S.WPDRes) {
341 AddUnsigned(WPD.first);
342 AddUnsigned(WPD.second.TheKind);
343 AddString(WPD.second.SingleImplName);
345 AddUint64(WPD.second.ResByArg.size());
346 for (
auto &ByArg : WPD.second.ResByArg) {
347 AddUint64(ByArg.first.size());
350 AddUnsigned(ByArg.second.TheKind);
351 AddUint64(ByArg.second.Info);
352 AddUnsigned(ByArg.second.Byte);
353 AddUnsigned(ByArg.second.Bit);
360 auto TidIter = Index.typeIds().equal_range(TId);
362 AddTypeIdSummary(
I.second.first,
I.second.second);
365 AddUnsigned(UsedCfiDefs.size());
366 for (
auto &V : UsedCfiDefs)
369 AddUnsigned(UsedCfiDecls.size());
370 for (
auto &V : UsedCfiDecls)
376 Hasher.
update(FileOrErr.get()->getBuffer());
381 Hasher.
update(FileOrErr.get()->getBuffer());
412 C.VisibilityScheme ==
Config::ELF ? VI.getELFVisibility()
414 for (
auto &S : VI.getSummaryList()) {
429 if (isPrevailing(VI.getGUID(), S.get())) {
430 assert(!S->wasPromoted() &&
431 "promoted symbols used to be internal linkage and shouldn't have "
432 "a prevailing variant");
445 S->setCanAutoHide(VI.canAutoHide() &&
446 !GUIDPreservedSymbols.
count(VI.getGUID()));
449 Visibility = S->getVisibility();
466 S->setVisibility(Visibility);
468 if (S->linkage() != OriginalLinkage)
469 recordNewLinkage(S->modulePath(), VI.getGUID(), S->linkage());
473 for (
auto &S : VI.getSummaryList()) {
478 S->setVisibility(Visibility);
500 for (
auto &
I : Index)
501 for (
auto &S :
I.second.getSummaryList())
503 GlobalInvolvedWithAlias.
insert(&AS->getAliasee());
505 for (
auto &
I : Index)
507 GlobalInvolvedWithAlias, isPrevailing,
508 recordNewLinkage, GUIDPreservedSymbols);
520 const bool SingleExternallyVisibleCopy =
521 VI.getSummaryList().size() == 1 &&
524 bool NameRecorded =
false;
525 for (
auto &S : VI.getSummaryList()) {
528 if (isExported(S->modulePath(), VI)) {
534 if (ExternallyVisibleSymbolNamesPtr && !NameRecorded) {
536 if (ExternallyVisibleSymbolNamesPtr->
insert(VI.name()).second)
537 S->setNoRenameOnPromotion(
true);
600 if (SingleExternallyVisibleCopy && isPrevailing(VI.getGUID(), S.get()))
613 assert(!Index.withInternalizeAndPromote());
615 for (
auto &
I : Index)
618 ExternallyVisibleSymbolNamesPtr);
619 Index.setWithInternalizeAndPromote();
626 std::unique_ptr<InputFile> File(
new InputFile);
632 File->TargetTriple = FOrErr->TheReader.getTargetTriple();
633 File->SourceFileName = FOrErr->TheReader.getSourceFileName();
634 File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts();
635 File->DependentLibraries = FOrErr->TheReader.getDependentLibraries();
636 File->ComdatTable = FOrErr->TheReader.getComdatTable();
640 for (
unsigned I = 0;
I != FOrErr->Mods.size(); ++
I) {
641 size_t Begin = File->Symbols.size();
643 FOrErr->TheReader.module_symbols(
I))
646 if (Sym.isGlobal() && !Sym.isFormatSpecific())
647 File->Symbols.push_back(Sym);
648 File->ModuleSymIndices.push_back({Begin, File->Symbols.size()});
651 File->Mods = FOrErr->Mods;
652 File->Strtab = std::move(FOrErr->Strtab);
653 return std::move(File);
662 return Mods[0].getModuleIdentifier();
666 assert(Mods.size() == 1 &&
"Expect only one bitcode module");
672LTO::RegularLTOState::RegularLTOState(
unsigned ParallelCodeGenParallelismLevel,
674 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
675 Ctx(Conf), CombinedModule(
std::make_unique<
Module>(
"ld-temp.o", Ctx)),
676 Mover(
std::make_unique<
IRMover>(*CombinedModule)) {}
678LTO::ThinLTOState::ThinLTOState(
ThinBackend BackendParam)
679 : Backend(
std::
move(BackendParam)), CombinedIndex(
false) {
680 if (!Backend.isValid())
686 unsigned ParallelCodeGenParallelismLevel,
LTOKind LTOMode)
688 RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),
694 Alloc = std::make_unique<BumpPtrAllocator>();
695 GlobalResolutionSymbolSaver = std::make_unique<llvm::StringSaver>(*Alloc);
704 LinkerRemarkFunction =
nullptr;
712 unsigned Partition,
bool InSummary,
715 auto *ResI = Res.
begin();
716 auto *ResE = Res.
end();
725 if (GlobalResolutionSymbolSaver && !GlobalResolutions->contains(SymbolName))
726 SymbolName = GlobalResolutionSymbolSaver->save(SymbolName);
728 auto &GlobalRes = (*GlobalResolutions)[SymbolName];
729 GlobalRes.UnnamedAddr &= Sym.isUnnamedAddr();
731 assert(!GlobalRes.Prevailing &&
732 "Multiple prevailing defs are not allowed");
733 GlobalRes.Prevailing =
true;
734 GlobalRes.IRName = std::string(Sym.getIRName());
735 }
else if (!GlobalRes.Prevailing && GlobalRes.IRName.empty()) {
742 GlobalRes.IRName = std::string(Sym.getIRName());
756 if (GlobalRes.IRName != Sym.getIRName()) {
757 GlobalRes.Partition = GlobalResolution::External;
758 GlobalRes.VisibleOutsideSummary =
true;
761 bool IsLibcall = Sym.isLibcall(Libcalls);
769 (GlobalRes.Partition != GlobalResolution::Unknown &&
770 GlobalRes.Partition != Partition)) {
771 GlobalRes.Partition = GlobalResolution::External;
774 GlobalRes.Partition = Partition;
778 GlobalRes.VisibleOutsideSummary |=
785void LTO::releaseGlobalResolutionsMemory() {
787 GlobalResolutions.reset();
789 GlobalResolutionSymbolSaver.reset();
797 auto ResI = Res.
begin();
802 OS <<
"-r=" << Path <<
',' << Sym.getName() <<
',';
820 assert(!CalledGetMaxTasks);
826 InputFile *
Input = (*InputOrErr).get();
828 if (Conf.ResolutionFile)
831 if (RegularLTO.CombinedModule->getTargetTriple().empty()) {
833 RegularLTO.CombinedModule->setTargetTriple(InputTriple);
839 for (
unsigned I = 0;
I !=
Input->Mods.size(); ++
I) {
840 if (
auto Err = addModule(*
Input, InputRes,
I, Res).moveInto(Res))
856 if (EnableSplitLTOUnit) {
860 if (*EnableSplitLTOUnit != LTOInfo->EnableSplitLTOUnit)
863 EnableSplitLTOUnit = LTOInfo->EnableSplitLTOUnit;
868 !LTOInfo->UnifiedLTO)
870 "unified LTO compilation must use "
871 "compatible bitcode modules (use -funified-lto)",
881 Input.IsThinLTO |= IsThinLTO;
883 auto ModSyms =
Input.module_symbols(ModI);
884 addModuleToGlobalRes(ModSyms, Res,
885 IsThinLTO ? ThinLTO.ModuleMap.
size() + 1 : 0,
886 LTOInfo->HasSummary,
Triple(
Input.getTargetTriple()));
889 return addThinLTO(BM, ModSyms, Res);
891 RegularLTO.EmptyCombinedModule =
false;
892 auto ModOrErr = addRegularLTO(
Input, InputRes, BM, ModSyms, Res);
894 return ModOrErr.takeError();
895 Res = ModOrErr->second;
897 if (!LTOInfo->HasSummary) {
898 if (
Error Err = linkRegularLTO(std::move(ModOrErr->first),
908 RegularLTO.ModsWithSummaries.push_back(std::move(ModOrErr->first));
924 std::set<const Comdat *> &NonPrevailingComdats) {
929 if (!NonPrevailingComdats.count(
C))
939 GO->setComdat(
nullptr);
946 std::pair<LTO::RegularLTOState::AddedModule, ArrayRef<SymbolResolution>>>
950 llvm::TimeTraceScope timeScope(
"LTO add regular LTO");
952 Expected<std::unique_ptr<Module>> MOrErr =
958 Mod.M = std::move(*MOrErr);
960 if (
Error Err =
M.materializeMetadata())
961 return std::move(Err);
967 if (NamedMDNode *CfiFunctionsMD =
M.getNamedMetadata(
"cfi.functions"))
968 M.eraseNamedMetadata(CfiFunctionsMD);
969 }
else if (NamedMDNode *AliasesMD =
M.getNamedMetadata(
"aliases")) {
972 DenseSet<StringRef> Prevailing;
974 if (
R.Prevailing && !
I.getIRName().empty())
975 Prevailing.
insert(
I.getIRName());
976 std::vector<MDNode *> AliasGroups;
977 for (MDNode *AliasGroup : AliasesMD->operands()) {
978 std::vector<Metadata *> Aliases;
979 for (
Metadata *Alias : AliasGroup->operands()) {
982 Aliases.push_back(Alias);
984 if (Aliases.size() > 1)
985 AliasGroups.push_back(
MDTuple::get(RegularLTO.Ctx, Aliases));
987 AliasesMD->clearOperands();
988 for (MDNode *
G : AliasGroups)
989 AliasesMD->addOperand(
G);
994 ModuleSymbolTable SymTab;
997 for (GlobalVariable &GV :
M.globals())
998 if (GV.hasAppendingLinkage())
999 Mod.Keep.push_back(&GV);
1001 DenseSet<GlobalObject *> AliasedGlobals;
1002 for (
auto &GA :
M.aliases())
1003 if (GlobalObject *GO = GA.getAliaseeObject())
1004 AliasedGlobals.
insert(GO);
1013 auto MsymI = SymTab.
symbols().begin(), MsymE = SymTab.
symbols().end();
1015 while (MsymI != MsymE) {
1025 std::set<const Comdat *> NonPrevailingComdats;
1026 SmallSet<StringRef, 2> NonPrevailingAsmSymbols;
1027 for (
const InputFile::Symbol &Sym : Syms) {
1037 if (Sym.isUndefined())
1039 Mod.Keep.push_back(GV);
1043 if (
R.LinkerRedefined)
1051 (GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||
1052 GV->hasAvailableExternallyLinkage()) &&
1059 Mod.Keep.push_back(GV);
1061 if (GV->hasComdat())
1062 NonPrevailingComdats.insert(GV->getComdat());
1067 if (
R.FinalDefinitionInLinkageUnit) {
1068 GV->setDSOLocal(
true);
1069 if (GV->hasDLLImportStorageClass())
1071 DefaultStorageClass);
1073 }
else if (
auto *AS =
1077 NonPrevailingAsmSymbols.
insert(AS->first);
1085 if (Sym.isCommon()) {
1088 auto &CommonRes = RegularLTO.Commons[std::string(Sym.getIRName())];
1089 CommonRes.Size = std::max(CommonRes.Size, Sym.getCommonSize());
1090 if (uint32_t SymAlignValue = Sym.getCommonAlignment()) {
1091 CommonRes.Alignment =
1092 std::max(
Align(SymAlignValue), CommonRes.Alignment);
1094 CommonRes.Prevailing |=
R.Prevailing;
1098 if (!
M.getComdatSymbolTable().empty())
1099 for (GlobalValue &GV :
M.global_values())
1104 if (!
M.getModuleInlineAsm().empty()) {
1105 std::string NewIA =
".lto_discard";
1106 if (!NonPrevailingAsmSymbols.
empty()) {
1109 M, [&](StringRef Name, StringRef Alias) {
1110 if (!NonPrevailingAsmSymbols.
count(Alias))
1111 NonPrevailingAsmSymbols.
erase(Name);
1113 NewIA +=
" " +
llvm::join(NonPrevailingAsmSymbols,
", ");
1116 M.setModuleInlineAsm(NewIA +
M.getModuleInlineAsm());
1120 return std::make_pair(std::move(
Mod), Res);
1123Error LTO::linkRegularLTO(RegularLTOState::AddedModule
Mod,
1124 bool LivenessFromIndex) {
1125 llvm::TimeTraceScope timeScope(
"LTO link regular LTO");
1126 std::vector<GlobalValue *>
Keep;
1127 for (GlobalValue *GV :
Mod.Keep) {
1128 if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->
getGUID())) {
1130 if (DiagnosticOutputFile) {
1131 if (
Error Err =
F->materialize())
1133 auto R = OptimizationRemark(
DEBUG_TYPE,
"deadfunction",
F);
1134 R <<
ore::NV(
"Function",
F) <<
" not added to the combined module ";
1148 GlobalValue *CombinedGV =
1149 RegularLTO.CombinedModule->getNamedValue(GV->
getName());
1156 return RegularLTO.Mover->move(std::move(
Mod.M),
Keep,
nullptr,
1161Expected<ArrayRef<SymbolResolution>>
1164 llvm::TimeTraceScope timeScope(
"LTO add thin LTO");
1167 for (
const InputFile::Symbol &Sym : Syms) {
1171 if (!Sym.getIRName().empty() &&
R.Prevailing) {
1175 ThinLTO.setPrevailingModuleForGUID(GUID, BMID);
1181 return ThinLTO.isPrevailingModuleForGUID(GUID, BMID);
1186 for (
const InputFile::Symbol &Sym : Syms) {
1190 if (!Sym.getIRName().empty() &&
1191 (
R.Prevailing ||
R.FinalDefinitionInLinkageUnit)) {
1196 assert(ThinLTO.isPrevailingModuleForGUID(GUID, BMID));
1202 if (
R.LinkerRedefined)
1203 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(GUID, BMID))
1209 if (
R.FinalDefinitionInLinkageUnit) {
1210 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(GUID, BMID)) {
1211 S->setDSOLocal(
true);
1217 if (!ThinLTO.ModuleMap.insert({BMID, BM}).second)
1219 "Expected at most one ThinLTO module per bitcode file",
1222 if (!Conf.ThinLTOModulesToCompile.empty()) {
1223 if (!ThinLTO.ModulesToCompile)
1224 ThinLTO.ModulesToCompile = ModuleMapType();
1227 for (
const std::string &Name : Conf.ThinLTOModulesToCompile) {
1228 if (BMID.contains(Name)) {
1229 ThinLTO.ModulesToCompile->insert({BMID, BM});
1230 LLVM_DEBUG(
dbgs() <<
"[ThinLTO] Selecting " << BMID <<
" to compile\n");
1240 CalledGetMaxTasks =
true;
1241 auto ModuleCount = ThinLTO.ModulesToCompile ? ThinLTO.ModulesToCompile->size()
1242 : ThinLTO.ModuleMap.size();
1243 return RegularLTO.ParallelCodeGenParallelismLevel + ModuleCount;
1248Error LTO::checkPartiallySplit() {
1252 const Module *Combined = RegularLTO.CombinedModule.get();
1258 Combined, Intrinsic::type_checked_load_relative);
1262 if ((TypeTestFunc && !TypeTestFunc->
use_empty()) ||
1263 (TypeCheckedLoadFunc && !TypeCheckedLoadFunc->
use_empty()) ||
1264 (TypeCheckedLoadRelativeFunc &&
1265 !TypeCheckedLoadRelativeFunc->
use_empty()))
1267 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1272 for (
auto &
P : ThinLTO.CombinedIndex) {
1273 for (
auto &S :
P.second.getSummaryList()) {
1277 if (!FS->type_test_assume_vcalls().empty() ||
1278 !FS->type_checked_load_vcalls().empty() ||
1279 !FS->type_test_assume_const_vcalls().empty() ||
1280 !FS->type_checked_load_const_vcalls().empty() ||
1281 !FS->type_tests().empty())
1283 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1299 for (
auto &Res : *GlobalResolutions) {
1302 if (Res.second.IRName.
empty())
1308 if (Res.second.VisibleOutsideSummary && Res.second.Prevailing)
1309 GUIDPreservedSymbols.
insert(GUID);
1311 if (Res.second.ExportDynamic)
1312 DynamicExportSymbols.insert(GUID);
1314 GUIDPrevailingResolutions[GUID] =
1319 auto It = GUIDPrevailingResolutions.
find(
G);
1320 if (It == GUIDPrevailingResolutions.
end())
1325 isPrevailing, Conf.OptLevel > 0);
1329 if (!StatsFileOrErr)
1330 return StatsFileOrErr.takeError();
1331 std::unique_ptr<ToolOutputFile> StatsFile = std::move(StatsFileOrErr.get());
1333 if (
Error Err = setupOptimizationRemarks())
1342 ThinLTO.CombinedIndex.setWithSupportsHotColdNew();
1344 Error Result = runRegularLTO(AddStream);
1348 Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols);
1364 for (
auto &M : RegularLTO.ModsWithSummaries)
1365 if (
Error Err = linkRegularLTO(std::move(M),
true))
1373 if (
Error Err = checkPartiallySplit())
1378 const DataLayout &
DL = RegularLTO.CombinedModule->getDataLayout();
1379 for (
auto &
I : RegularLTO.Commons) {
1380 if (!
I.second.Prevailing)
1383 GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(
I.first);
1392 auto *GV =
new GlobalVariable(*RegularLTO.CombinedModule, Ty,
false,
1395 GV->setAlignment(
I.second.Alignment);
1405 bool WholeProgramVisibilityEnabledInLTO =
1406 Conf.HasWholeProgramVisibility &&
1409 (!Conf.ValidateAllVtablesHaveTypeInfos || Conf.AllVtablesHaveTypeInfos);
1413 auto IsVisibleToRegularObj = [&](StringRef
name) {
1414 auto It = GlobalResolutions->find(
name);
1415 return (It == GlobalResolutions->end() ||
1416 It->second.VisibleOutsideSummary || !It->second.Prevailing);
1422 *RegularLTO.CombinedModule, WholeProgramVisibilityEnabledInLTO,
1423 DynamicExportSymbols, Conf.ValidateAllVtablesHaveTypeInfos,
1424 IsVisibleToRegularObj);
1426 WholeProgramVisibilityEnabledInLTO);
1428 if (Conf.PreOptModuleHook &&
1429 !Conf.PreOptModuleHook(0, *RegularLTO.CombinedModule))
1432 if (!Conf.CodeGenOnly) {
1433 for (
const auto &R : *GlobalResolutions) {
1435 RegularLTO.CombinedModule->getNamedValue(
R.second.IRName);
1436 if (!
R.second.isPrevailingIRSymbol())
1438 if (
R.second.Partition != 0 &&
1439 R.second.Partition != GlobalResolution::External)
1467 if (Conf.PostInternalizeModuleHook &&
1468 !Conf.PostInternalizeModuleHook(0, *RegularLTO.CombinedModule))
1472 if (!RegularLTO.EmptyCombinedModule || Conf.AlwaysEmitRegularLTOObj) {
1474 backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,
1475 *RegularLTO.CombinedModule, ThinLTO.CombinedIndex))
1492 return LibcallSymbols;
1497 const std::string &NewModulePath)
const {
1498 return emitFiles(ImportList, ModulePath, NewModulePath,
1499 NewModulePath +
".thinlto.bc",
1505 const std::string &NewModulePath,
StringRef SummaryPath,
1506 std::optional<std::reference_wrapper<ImportsFilesContainer>> ImportsFiles)
1513 ImportList, ModuleToSummariesForIndex,
1514 DeclarationSummaries);
1521 &DeclarationSummaries);
1525 ModulePath, NewModulePath +
".imports", ModuleToSummariesForIndex);
1526 if (ImportsFilesError)
1527 return ImportsFilesError;
1533 ModulePath, ModuleToSummariesForIndex,
1534 [&](
StringRef M) { ImportsFiles->get().push_back(M.str()); });
1547 bool ShouldEmitIndexFiles;
1554 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
1557 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
1558 AddStream(
std::
move(AddStream)),
1559 ShouldEmitIndexFiles(ShouldEmitIndexFiles) {
1569class InProcessThinBackend :
public CGThinBackend {
1574 InProcessThinBackend(
1579 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles)
1580 : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
1581 AddStream, OnWrite, ShouldEmitIndexFiles,
1582 ShouldEmitImportsFiles, ThinLTOParallelism),
1585 virtual Error runThinLTOBackendThread(
1586 AddStreamFn AddStream, FileCache Cache,
unsigned Task, BitcodeModule BM,
1587 ModuleSummaryIndex &CombinedIndex,
1588 const FunctionImporter::ImportMapTy &ImportList,
1590 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1592 MapVector<StringRef, BitcodeModule> &ModuleMap) {
1594 llvm::TimeTraceScope timeScope(
"Run ThinLTO backend thread (in-process)",
1596 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1597 LTOLLVMContext BackendContext(Conf);
1598 Expected<std::unique_ptr<Module>> MOrErr = BM.
parseModule(BackendContext);
1602 return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,
1603 ImportList, DefinedGlobals, &ModuleMap,
1606 if (ShouldEmitIndexFiles) {
1607 if (
auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1613 [](uint32_t V) { return V == 0; }))
1616 return RunThinBackend(AddStream);
1620 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1621 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1622 Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task,
Key, ModuleID);
1625 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1627 return RunThinBackend(CacheAddStream);
1633 unsigned Task, BitcodeModule BM,
1634 const FunctionImporter::ImportMapTy &ImportList,
1636 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1637 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
1639 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
1641 ModuleToDefinedGVSummaries.
find(ModulePath)->second;
1642 BackendThreadPool.async(
1643 [=](BitcodeModule BM, ModuleSummaryIndex &CombinedIndex,
1644 const FunctionImporter::ImportMapTy &ImportList,
1646 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
1649 MapVector<StringRef, BitcodeModule> &ModuleMap) {
1653 Error E = runThinLTOBackendThread(
1654 AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList,
1655 ResolvedODR, DefinedGlobals, ModuleMap);
1657 std::unique_lock<std::mutex>
L(ErrMu);
1666 BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList),
1667 std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap));
1670 OnWrite(std::string(ModulePath));
1680class FirstRoundThinBackend :
public InProcessThinBackend {
1685 FirstRoundThinBackend(
1686 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
1687 ThreadPoolStrategy ThinLTOParallelism,
1688 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
1691 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
1692 ModuleToDefinedGVSummaries, std::
move(CGAddStream),
1693 std::
move(CGCache), nullptr,
1696 IRAddStream(std::
move(IRAddStream)), IRCache(std::
move(IRCache)) {}
1698 Error runThinLTOBackendThread(
1699 AddStreamFn CGAddStream, FileCache CGCache,
unsigned Task,
1700 BitcodeModule BM, ModuleSummaryIndex &CombinedIndex,
1701 const FunctionImporter::ImportMapTy &ImportList,
1703 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1705 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
1707 llvm::TimeTraceScope timeScope(
"Run ThinLTO backend thread (first round)",
1709 auto RunThinBackend = [&](
AddStreamFn CGAddStream,
1711 LTOLLVMContext BackendContext(Conf);
1712 Expected<std::unique_ptr<Module>> MOrErr = BM.
parseModule(BackendContext);
1716 return thinBackend(Conf, Task, CGAddStream, **MOrErr, CombinedIndex,
1717 ImportList, DefinedGlobals, &ModuleMap,
1723 if (ShouldEmitIndexFiles) {
1724 if (
auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1729 "Both caches for CG and IR should have matching availability");
1732 [](uint32_t V) { return V == 0; }))
1735 return RunThinBackend(CGAddStream, IRAddStream);
1739 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1740 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1741 Expected<AddStreamFn> CacheCGAddStreamOrErr =
1742 CGCache(Task, CGKey, ModuleID);
1745 AddStreamFn &CacheCGAddStream = *CacheCGAddStreamOrErr;
1749 Expected<AddStreamFn> CacheIRAddStreamOrErr =
1750 IRCache(Task, IRKey, ModuleID);
1753 AddStreamFn &CacheIRAddStream = *CacheIRAddStreamOrErr;
1759 if (CacheCGAddStream || CacheIRAddStream) {
1762 return RunThinBackend(CacheCGAddStream ? CacheCGAddStream : CGAddStream,
1763 CacheIRAddStream ? CacheIRAddStream : IRAddStream);
1775class SecondRoundThinBackend :
public InProcessThinBackend {
1776 std::unique_ptr<SmallVector<StringRef>> IRFiles;
1780 SecondRoundThinBackend(
1781 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
1782 ThreadPoolStrategy ThinLTOParallelism,
1783 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
1787 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
1788 ModuleToDefinedGVSummaries, std::
move(AddStream),
1793 IRFiles(std::
move(IRFiles)), CombinedCGDataHash(CombinedCGDataHash) {}
1795 Error runThinLTOBackendThread(
1796 AddStreamFn AddStream, FileCache Cache,
unsigned Task, BitcodeModule BM,
1797 ModuleSummaryIndex &CombinedIndex,
1798 const FunctionImporter::ImportMapTy &ImportList,
1800 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1802 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
1804 llvm::TimeTraceScope timeScope(
"Run ThinLTO backend thread (second round)",
1806 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1807 LTOLLVMContext BackendContext(Conf);
1808 std::unique_ptr<Module> LoadedModule =
1811 return thinBackend(Conf, Task, AddStream, *LoadedModule, CombinedIndex,
1812 ImportList, DefinedGlobals, &ModuleMap,
1817 [](uint32_t V) { return V == 0; }))
1820 return RunThinBackend(AddStream);
1825 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1826 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1828 std::to_string(CombinedCGDataHash));
1829 Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task,
Key, ModuleID);
1832 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1834 if (CacheAddStream) {
1837 return RunThinBackend(CacheAddStream);
1847 bool ShouldEmitIndexFiles,
1848 bool ShouldEmitImportsFiles) {
1853 return std::make_unique<InProcessThinBackend>(
1854 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1855 AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
1856 ShouldEmitImportsFiles);
1882 return std::string(Path);
1886 if (!ParentPath.
empty()) {
1889 llvm::errs() <<
"warning: could not create directory '" << ParentPath
1890 <<
"': " << EC.message() <<
'\n';
1892 return std::string(NewPath);
1897 std::string OldPrefix, NewPrefix, NativeObjectPrefix;
1901 WriteIndexesThinBackend(
1905 std::string OldPrefix, std::string NewPrefix,
1906 std::string NativeObjectPrefix,
bool ShouldEmitImportsFiles,
1909 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
1910 OldPrefix(OldPrefix), NewPrefix(NewPrefix),
1911 NativeObjectPrefix(NativeObjectPrefix),
1912 LinkedObjectsFile(LinkedObjectsFile) {}
1918 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1926 if (LinkedObjectsFile) {
1927 std::string ObjectPrefix =
1928 NativeObjectPrefix.empty() ? NewPrefix : NativeObjectPrefix;
1929 std::string LinkedObjectsFilePath =
1931 *LinkedObjectsFile << LinkedObjectsFilePath <<
'\n';
1934 BackendThreadPool.async(
1935 [
this](
const StringRef ModulePath,
1936 const FunctionImporter::ImportMapTy &ImportList,
1937 const std::string &OldPrefix,
const std::string &NewPrefix) {
1938 std::string NewModulePath =
1940 auto E = emitFiles(ImportList, ModulePath, NewModulePath);
1942 std::unique_lock<std::mutex>
L(ErrMu);
1950 ModulePath, ImportList, OldPrefix, NewPrefix);
1953 OnWrite(std::string(ModulePath));
1957 bool isSensitiveToInputOrder()
override {
1967 std::string NewPrefix, std::string NativeObjectPrefix,
1974 return std::make_unique<WriteIndexesThinBackend>(
1975 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1976 OldPrefix, NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,
1977 LinkedObjectsFile, OnWrite);
1992 if (ThinLTO.ModuleMap.
empty())
1995 if (ThinLTO.ModulesToCompile && ThinLTO.ModulesToCompile->empty()) {
1996 llvm::errs() <<
"warning: [ThinLTO] No module compiled\n";
2000 if (Conf.CombinedIndexHook &&
2001 !Conf.CombinedIndexHook(ThinLTO.CombinedIndex, GUIDPreservedSymbols))
2006 DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries(
2007 ThinLTO.ModuleMap.size());
2008 ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule(
2009 ModuleToDefinedGVSummaries);
2017 for (
auto &
Mod : ThinLTO.ModuleMap)
2018 if (!ModuleToDefinedGVSummaries.
count(
Mod.first))
2021 FunctionImporter::ImportListsTy ImportLists(ThinLTO.ModuleMap.size());
2022 DenseMap<StringRef, FunctionImporter::ExportSetTy> ExportLists(
2023 ThinLTO.ModuleMap.size());
2024 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
2027 ThinLTO.CombinedIndex.dumpSCCs(
outs());
2029 std::set<GlobalValue::GUID> ExportedGUIDs;
2031 bool WholeProgramVisibilityEnabledInLTO =
2032 Conf.HasWholeProgramVisibility &&
2035 (!Conf.ValidateAllVtablesHaveTypeInfos || Conf.AllVtablesHaveTypeInfos);
2037 ThinLTO.CombinedIndex.setWithWholeProgramVisibility();
2042 DenseSet<GlobalValue::GUID> VisibleToRegularObjSymbols;
2043 if (WholeProgramVisibilityEnabledInLTO &&
2044 Conf.ValidateAllVtablesHaveTypeInfos) {
2047 auto IsVisibleToRegularObj = [&](StringRef
name) {
2048 auto It = GlobalResolutions->find(
name);
2049 return (It == GlobalResolutions->end() ||
2050 It->second.VisibleOutsideSummary || !It->second.Prevailing);
2054 VisibleToRegularObjSymbols,
2055 IsVisibleToRegularObj);
2061 ThinLTO.CombinedIndex, WholeProgramVisibilityEnabledInLTO,
2062 DynamicExportSymbols, VisibleToRegularObjSymbols);
2067 std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;
2068 DenseSet<StringRef> ExternallyVisibleSymbolNames;
2074 DenseSet<StringRef> *ExternallyVisibleSymbolNamesPtr =
2076 ? &ExternallyVisibleSymbolNames
2080 ExternallyVisibleSymbolNamesPtr);
2083 return ThinLTO.isPrevailingModuleForGUID(GUID, S->modulePath());
2086 MemProfContextDisambiguation ContextDisambiguation;
2087 ContextDisambiguation.
run(
2088 ThinLTO.CombinedIndex, isPrevailing, RegularLTO.Ctx,
2089 [&](StringRef
PassName, StringRef RemarkName,
const Twine &Msg) {
2090 auto R = OptimizationRemark(PassName.data(), RemarkName,
2091 LinkerRemarkFunction);
2101 for (
auto &Res : *GlobalResolutions) {
2104 if (Res.second.Partition != GlobalResolution::External ||
2105 !Res.second.isPrevailingIRSymbol())
2110 if (ThinLTO.CombinedIndex.isGUIDLive(GUID))
2111 ExportedGUIDs.insert(GUID);
2118 releaseGlobalResolutionsMemory();
2120 if (Conf.OptLevel > 0)
2122 isPrevailing, ImportLists, ExportLists);
2126 auto &Defs = ThinLTO.CombinedIndex.cfiFunctionDefs();
2127 ExportedGUIDs.insert(Defs.guid_begin(), Defs.guid_end());
2128 auto &Decls = ThinLTO.CombinedIndex.cfiFunctionDecls();
2129 ExportedGUIDs.insert(Decls.guid_begin(), Decls.guid_end());
2131 auto isExported = [&](StringRef ModuleIdentifier, ValueInfo
VI) {
2132 const auto &ExportList = ExportLists.
find(ModuleIdentifier);
2133 return (ExportList != ExportLists.end() && ExportList->second.
count(VI)) ||
2134 ExportedGUIDs.count(
VI.getGUID());
2140 LocalWPDTargetsMap, ExternallyVisibleSymbolNamesPtr);
2142 if (ExternallyVisibleSymbolNamesPtr) {
2145 for (
auto &
I : ThinLTO.CombinedIndex) {
2146 ValueInfo
VI = ThinLTO.CombinedIndex.getValueInfo(
I);
2147 for (
const auto &Summary :
VI.getSummaryList()) {
2148 const GlobalValueSummary *
Base =
Summary->getBaseObject();
2152 ExternallyVisibleSymbolNamesPtr->
insert(
VI.name());
2160 ExternallyVisibleSymbolNamesPtr);
2162 auto recordNewLinkage = [&](StringRef ModuleIdentifier,
2165 ResolvedODR[ModuleIdentifier][
GUID] = NewLinkage;
2168 recordNewLinkage, GUIDPreservedSymbols);
2177 TimeTraceScopeExit.release();
2180 ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;
2182 auto RunBackends = [&](ThinBackendProc *BackendProcess) ->
Error {
2183 auto ProcessOneModule = [&](
int I) ->
Error {
2187 return BackendProcess->start(
2188 RegularLTO.ParallelCodeGenParallelismLevel +
I,
Mod.second,
2189 ImportLists[
Mod.first], ExportLists[
Mod.first],
2190 ResolvedODR[
Mod.first], ThinLTO.ModuleMap);
2193 BackendProcess->setup(ModuleMap.
size(),
2194 RegularLTO.ParallelCodeGenParallelismLevel,
2195 RegularLTO.CombinedModule->getTargetTriple());
2197 if (BackendProcess->getThreadCount() == 1 ||
2198 BackendProcess->isSensitiveToInputOrder()) {
2204 for (
int I = 0,
E = ModuleMap.
size();
I !=
E; ++
I)
2205 if (
Error E = ProcessOneModule(
I))
2212 std::vector<BitcodeModule *> ModulesVec;
2213 ModulesVec.reserve(ModuleMap.
size());
2214 for (
auto &
Mod : ModuleMap)
2215 ModulesVec.push_back(&
Mod.second);
2217 if (
Error E = ProcessOneModule(
I))
2220 return BackendProcess->wait();
2224 std::unique_ptr<ThinBackendProc> BackendProc =
2225 ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
2227 return RunBackends(BackendProc.get());
2235 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Initializing ThinLTO two-codegen rounds\n");
2238 auto Parallelism = ThinLTO.Backend.getParallelism();
2241 cgdata::StreamCacheData CG(MaxTasks, Cache,
"CG"),
IR(MaxTasks, Cache,
"IR");
2246 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Running the first round of codegen\n");
2247 auto FirstRoundLTO = std::make_unique<FirstRoundThinBackend>(
2248 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2249 CG.AddStream, CG.Cache,
IR.AddStream,
IR.Cache);
2250 if (
Error E = RunBackends(FirstRoundLTO.get()))
2255 if (
Error E = CombinedHashOrErr.takeError())
2257 auto CombinedHash = *CombinedHashOrErr;
2258 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] CGData hash: " << CombinedHash <<
"\n");
2262 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Running the second round of codegen\n");
2263 auto SecondRoundLTO = std::make_unique<SecondRoundThinBackend>(
2264 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2265 AddStream, Cache,
IR.getResult(), CombinedHash);
2266 return RunBackends(SecondRoundLTO.get());
2284 if (
Error E = ResultOrErr.takeError())
2285 return std::move(E);
2288 (*ResultOrErr)->keep();
2296 if (StatsFilename.
empty())
2307 return std::move(StatsFile);
2315 std::vector<int> ModulesOrdering(Seq.begin(), Seq.end());
2316 llvm::sort(ModulesOrdering, [&](
int LeftIndex,
int RightIndex) {
2317 auto LSize = R[LeftIndex]->getBuffer().size();
2318 auto RSize = R[RightIndex]->getBuffer().size();
2319 return LSize > RSize;
2321 return ModulesOrdering;
2329 BackgroundDeletion()
2332 ~BackgroundDeletion() {
2334 for (
const std::string &
Warning : Warnings)
2335 errs() <<
"warning: could not remove the file " <<
Warning <<
"\n";
2338 void remove(SmallVector<std::string> &&Files,
const Config &Conf) {
2341 if (LLVM_ENABLE_THREADS && TTE)
2342 timeTraceProfilerInitialize(TTG,
"Remove DTLTO temporary files");
2344 llvm::TimeTraceScope TimeScope(
"Remove DTLTO temporary files");
2345 for (const auto &F : Files) {
2346 std::error_code EC = sys::fs::remove(F, true);
2348 EC != std::make_error_code(std::errc::no_such_file_or_directory))
2349 Warnings.emplace_back(
"'" + F +
"': " + EC.message());
2352 if (LLVM_ENABLE_THREADS && TTE)
2362static llvm::ManagedStatic<BackgroundDeletion> BackgroundDeleter;
2370class OutOfProcessThinBackend :
public CGThinBackend {
2371 using SString = SmallString<128>;
2374 StringSaver Saver{
Alloc};
2376 SString LinkerOutputFile;
2378 SString DistributorPath;
2381 SString RemoteCompiler;
2388 DenseSet<StringRef> CommonInputs;
2390 std::atomic<size_t> CachedJobs{0};
2395 StringRef NativeObjectPath;
2396 StringRef SummaryIndexPath;
2398 std::string CacheKey;
2400 bool Cached =
false;
2409 unsigned ThinLTOTaskOffset;
2412 llvm::Triple Triple;
2418 OutOfProcessThinBackend(
2419 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
2420 ThreadPoolStrategy ThinLTOParallelism,
2421 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
2423 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
2424 StringRef LinkerOutputFile, StringRef Distributor,
2428 : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
2429 AddStream, OnWrite, ShouldEmitIndexFiles,
2430 ShouldEmitImportsFiles, ThinLTOParallelism),
2431 LinkerOutputFile(LinkerOutputFile), DistributorPath(Distributor),
2432 DistributorArgs(DistributorArgs), RemoteCompiler(RemoteCompiler),
2433 RemoteCompilerPrependArgs(RemoteCompilerPrependArgs),
2434 RemoteCompilerArgs(RemoteCompilerArgs), SaveTemps(SaveTemps),
2435 Cache(std::
move(CacheFn)) {}
2437 void setup(
unsigned ThinLTONumTasks,
unsigned ThinLTOTaskOffset,
2438 llvm::Triple Triple)
override {
2440 Jobs.
resize((
size_t)ThinLTONumTasks);
2441 this->ThinLTOTaskOffset = ThinLTOTaskOffset;
2442 this->Triple = std::move(Triple);
2443 this->Conf.
Dtlto = 1;
2446 virtual Error runThinLTOBackendThread(
2447 Job &J,
const FunctionImporter::ImportMapTy &ImportList,
2449 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
2452 TimeTraceScope TimeScope(
"Emit individual index for DTLTO",
2453 J.SummaryIndexPath);
2454 if (
auto E = emitFiles(ImportList, J.ModuleID, J.ModuleID.str(),
2455 J.SummaryIndexPath, J.ImportsFiles))
2461 [](uint32_t V) { return V == 0; }))
2466 TimeTraceScope TimeScope(
"Check cache for DTLTO", J.SummaryIndexPath);
2468 ModuleToDefinedGVSummaries.
find(J.ModuleID)->second;
2472 ExportList, ResolvedODR, DefinedGlobals,
2473 CfiFunctionDefs, CfiFunctionDecls);
2476 auto CacheAddStreamExp = Cache(J.Task, J.CacheKey, J.ModuleID);
2477 if (
Error Err = CacheAddStreamExp.takeError())
2482 if (!CacheAddStream) {
2484 CachedJobs.fetch_add(1);
2489 J.CacheAddStream = std::move(CacheAddStream);
2495 unsigned Task, BitcodeModule BM,
2496 const FunctionImporter::ImportMapTy &ImportList,
2498 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
2499 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
2505 itostr(Task) +
"." + UID +
".native.o");
2507 Job &J = Jobs[Task - ThinLTOTaskOffset];
2510 Saver.
save(ObjFilePath.str()),
2511 Saver.
save(ObjFilePath.str() +
".thinlto.bc"),
2520 if (!ShouldEmitIndexFiles)
2524 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
2528 BackendThreadPool.async(
2529 [=](Job &J,
const FunctionImporter::ImportMapTy &ImportList,
2531 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
2536 "Emit individual index and check cache for DTLTO");
2538 runThinLTOBackendThread(J, ImportList, ExportList, ResolvedODR);
2540 std::unique_lock<std::mutex>
L(ErrMu);
2549 std::ref(J), std::ref(ImportList), std::ref(ExportList),
2550 std::ref(ResolvedODR));
2564 void buildCommonRemoteCompilerOptions() {
2565 const lto::Config &
C = Conf;
2566 auto &
Ops = CodegenOptions;
2570 if (
C.Options.EmitAddrsig)
2571 Ops.push_back(
"-faddrsig");
2572 if (
C.Options.FunctionSections)
2573 Ops.push_back(
"-ffunction-sections");
2574 if (
C.Options.DataSections)
2575 Ops.push_back(
"-fdata-sections");
2580 Ops.push_back(
"-fpic");
2584 if (!
C.PGOWarnMismatch) {
2585 Ops.push_back(
"-mllvm");
2586 Ops.push_back(
"-no-pgo-warn-mismatch");
2591 if (!
C.SampleProfile.empty()) {
2593 Saver.
save(
"-fprofile-sample-use=" + Twine(
C.SampleProfile)));
2594 CommonInputs.
insert(
C.SampleProfile);
2598 Ops.push_back(
"-Wno-unused-command-line-argument");
2601 if (!RemoteCompilerArgs.
empty())
2602 for (
auto &a : RemoteCompilerArgs)
2608 bool emitDistributorJson(StringRef DistributorJson) {
2611 raw_fd_ostream OS(DistributorJson, EC);
2615 json::OStream JOS(OS);
2618 JOS.attributeObject(
"common", [&]() {
2619 JOS.attribute(
"linker_output", LinkerOutputFile);
2621 JOS.attributeArray(
"args", [&]() {
2622 JOS.value(RemoteCompiler);
2625 if (!RemoteCompilerPrependArgs.
empty())
2626 for (
auto &
A : RemoteCompilerPrependArgs)
2631 JOS.value(Saver.
save(
"--target=" + Triple.
str()));
2633 for (
const auto &
A : CodegenOptions)
2637 JOS.attribute(
"inputs",
Array(CommonInputs));
2641 JOS.attributeArray(
"jobs", [&]() {
2642 for (
const auto &J : Jobs) {
2650 SmallVector<StringRef, 1> Outputs;
2653 JOS.attributeArray(
"args", [&]() {
2654 JOS.value(J.ModuleID);
2658 Saver.
save(
"-fthinlto-index=" + Twine(J.SummaryIndexPath)));
2662 JOS.value(J.NativeObjectPath);
2670 JOS.attribute(
"inputs",
Array(Inputs));
2672 JOS.attribute(
"outputs",
Array(Outputs));
2681 void removeFile(StringRef FileName) {
2683 if (EC && EC != std::make_error_code(std::errc::no_such_file_or_directory))
2684 errs() <<
"warning: could not remove the file '" << FileName
2685 <<
"': " <<
EC.message() <<
"\n";
2688 Error wait()
override {
2691 BackendThreadPool.wait();
2693 return std::move(*Err);
2698 SmallVector<std::string>
Files;
2699 for (
auto &Job : Jobs) {
2700 Files.push_back(std::string(Job.NativeObjectPath));
2701 if (!ShouldEmitIndexFiles)
2702 Files.push_back(std::string(Job.SummaryIndexPath));
2704 BackgroundDeleter->remove(std::move(Files), Conf);
2707 const StringRef BCError =
"DTLTO backend compilation: ";
2709 buildCommonRemoteCompilerOptions();
2713 llvm::TimeTraceScope TimeScope(
"Emit DTLTO JSON");
2715 UID +
".dist-file.json");
2719 if (!emitDistributorJson(JsonFile))
2721 BCError +
"failed to generate distributor JSON script: " + JsonFile,
2726 removeFile(JsonFile);
2730 llvm::TimeTraceScope TimeScope(
"Execute DTLTO distributor",
2733 if (CachedJobs.load() < Jobs.size()) {
2736 Args.push_back(JsonFile);
2743 BCError +
"distributor execution failed" +
2744 (!ErrMsg.empty() ?
": " + ErrMsg + Twine(
".") : Twine(
".")),
2751 llvm::TimeTraceScope FilesScope(
"Add DTLTO files to the link");
2752 for (
auto &Job : Jobs) {
2753 if (!Job.CacheKey.empty() && Job.Cached) {
2759 auto ObjFileMbOrErr =
2762 if (std::error_code EC = ObjFileMbOrErr.getError())
2764 BCError +
"cannot open native object file: " +
2765 Job.NativeObjectPath +
": " +
EC.message(),
2768 MemoryBufferRef ObjFileMbRef = ObjFileMbOrErr->get()->getMemBufferRef();
2772 assert(Job.CacheAddStream);
2774 auto CachedFileStreamOrErr =
2775 Job.CacheAddStream(Job.Task, Job.ModuleID);
2776 if (!CachedFileStreamOrErr)
2778 CachedFileStreamOrErr.takeError(),
2780 "Cannot get a cache file stream: %s",
2781 Job.NativeObjectPath.data()));
2783 auto &CacheStream = *(CachedFileStreamOrErr->get());
2784 *(CacheStream.OS) << ObjFileMbRef.
getBuffer();
2785 if (
Error Err = CacheStream.commit())
2788 auto StreamOrErr = AddStream(Job.Task, Job.ModuleID);
2789 if (
Error Err = StreamOrErr.takeError())
2791 auto &Stream = *StreamOrErr->get();
2793 if (
Error Err = Stream.commit())
2805 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
2814 return std::make_unique<OutOfProcessThinBackend>(
2815 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2816 AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
2817 ShouldEmitImportsFiles, LinkerOutputFile, Distributor,
2818 DistributorArgs, RemoteCompiler, RemoteCompilerPrependArgs,
2819 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).
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
SingleThreadExecutor DefaultThreadPool
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.