28#include "llvm/Config/llvm-config.h"
56#include "llvm/Support/VCSRevision.h"
72#define DEBUG_TYPE "lto"
76 cl::desc(
"Dump the SCCs in the ThinLTO index's callgraph"));
87 cl::desc(
"Enable global value internalization in LTO"));
91 cl::desc(
"Keep copies of symbols in LTO indexing"));
108 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
119 Hasher.
update(LLVM_VERSION_STRING);
121 Hasher.
update(LLVM_REVISION);
129 auto AddUnsigned = [&](
unsigned I) {
139 auto AddUint8 = [&](
const uint8_t I) {
163 AddUnsigned(
static_cast<int>(Conf.
CGOptLevel));
164 AddUnsigned(
static_cast<int>(Conf.
CGFileType));
174 auto ModHash = Index.getModuleHash(ModuleID);
179 std::vector<uint64_t> ExportsGUID;
180 ExportsGUID.reserve(ExportList.
size());
181 for (
const auto &VI : ExportList)
182 ExportsGUID.push_back(VI.getGUID());
186 for (
auto GUID : ExportsGUID)
191 auto Comp = [&](
const std::pair<StringRef, GlobalValue::GUID> &L,
192 const std::pair<StringRef, GlobalValue::GUID> &R) {
193 return std::make_pair(Index.getModule(L.first)->second, L.second) <
194 std::make_pair(Index.getModule(R.first)->second, R.second);
200 for (
const auto &[FromModule, GUID,
Type] : SortedImportList)
201 ++ModuleToNumImports[FromModule];
203 std::optional<StringRef> LastModule;
204 for (
const auto &[FromModule, GUID,
Type] : SortedImportList) {
205 if (LastModule != FromModule) {
209 LastModule = FromModule;
210 auto ModHash = Index.getModule(FromModule)->second;
212 AddUint64(ModuleToNumImports[FromModule]);
219 for (
auto &Entry : ResolvedODR) {
228 std::set<GlobalValue::GUID> UsedCfiDefs;
229 std::set<GlobalValue::GUID> UsedCfiDecls;
232 std::set<GlobalValue::GUID> UsedTypeIds;
235 if (CfiFunctionDefs.
contains(ValueGUID))
236 UsedCfiDefs.insert(ValueGUID);
237 if (CfiFunctionDecls.
contains(ValueGUID))
238 UsedCfiDecls.insert(ValueGUID);
243 AddUnsigned(GS->getVisibility());
244 AddUnsigned(GS->isLive());
245 AddUnsigned(GS->canAutoHide());
247 AddUnsigned(VI.isDSOLocal(Index.withDSOLocalPropagation()));
248 AddUsedCfiGlobal(VI.getGUID());
251 AddUnsigned(GVS->maybeReadOnly());
252 AddUnsigned(GVS->maybeWriteOnly());
255 for (
auto &TT : FS->type_tests())
256 UsedTypeIds.insert(TT);
257 for (
auto &TT : FS->type_test_assume_vcalls())
258 UsedTypeIds.insert(TT.GUID);
259 for (
auto &TT : FS->type_checked_load_vcalls())
260 UsedTypeIds.insert(TT.GUID);
261 for (
auto &TT : FS->type_test_assume_const_vcalls())
262 UsedTypeIds.insert(TT.VFunc.GUID);
263 for (
auto &TT : FS->type_checked_load_const_vcalls())
264 UsedTypeIds.insert(TT.VFunc.GUID);
265 for (
auto &ET : FS->calls()) {
266 AddUnsigned(ET.first.isDSOLocal(Index.withDSOLocalPropagation()));
267 AddUsedCfiGlobal(ET.first.getGUID());
274 for (
auto &GS : DefinedGlobals) {
278 AddUsedCfiGlobal(GS.first);
279 AddUsedThings(GS.second);
284 for (
const auto &[FromModule, GUID,
Type] : SortedImportList) {
290 AddUsedThings(AS->getBaseObject());
296 AddUnsigned(S.TTRes.TheKind);
297 AddUnsigned(S.TTRes.SizeM1BitWidth);
299 AddUint64(S.TTRes.AlignLog2);
300 AddUint64(S.TTRes.SizeM1);
301 AddUint64(S.TTRes.BitMask);
302 AddUint64(S.TTRes.InlineBits);
304 AddUint64(S.WPDRes.size());
305 for (
auto &WPD : S.WPDRes) {
306 AddUnsigned(WPD.first);
307 AddUnsigned(WPD.second.TheKind);
308 AddString(WPD.second.SingleImplName);
310 AddUint64(WPD.second.ResByArg.size());
311 for (
auto &ByArg : WPD.second.ResByArg) {
312 AddUint64(ByArg.first.size());
315 AddUnsigned(ByArg.second.TheKind);
316 AddUint64(ByArg.second.Info);
317 AddUnsigned(ByArg.second.Byte);
318 AddUnsigned(ByArg.second.Bit);
325 auto TidIter = Index.typeIds().equal_range(TId);
327 AddTypeIdSummary(
I.second.first,
I.second.second);
330 AddUnsigned(UsedCfiDefs.size());
331 for (
auto &V : UsedCfiDefs)
334 AddUnsigned(UsedCfiDecls.size());
335 for (
auto &V : UsedCfiDecls)
341 Hasher.
update(FileOrErr.get()->getBuffer());
346 Hasher.
update(FileOrErr.get()->getBuffer());
377 C.VisibilityScheme ==
Config::ELF ? VI.getELFVisibility()
379 for (
auto &S : VI.getSummaryList()) {
394 if (isPrevailing(VI.getGUID(), S.get())) {
407 S->setCanAutoHide(VI.canAutoHide() &&
408 !GUIDPreservedSymbols.
count(VI.getGUID()));
411 Visibility = S->getVisibility();
425 S->setVisibility(Visibility);
427 if (S->linkage() != OriginalLinkage)
428 recordNewLinkage(S->modulePath(), VI.getGUID(), S->linkage());
432 for (
auto &S : VI.getSummaryList()) {
437 S->setVisibility(Visibility);
459 for (
auto &
I : Index)
460 for (
auto &S :
I.second.SummaryList)
462 GlobalInvolvedWithAlias.
insert(&AS->getAliasee());
464 for (
auto &
I : Index)
466 GlobalInvolvedWithAlias, isPrevailing,
467 recordNewLinkage, GUIDPreservedSymbols);
474 auto ExternallyVisibleCopies =
476 [](
const std::unique_ptr<GlobalValueSummary> &Summary) {
477 return !GlobalValue::isLocalLinkage(Summary->linkage());
480 for (
auto &S : VI.getSummaryList()) {
483 if (isExported(S->modulePath(), VI)) {
542 if (isPrevailing(VI.getGUID(), S.get()) && ExternallyVisibleCopies == 1)
554 for (
auto &
I : Index)
563 std::unique_ptr<InputFile> File(
new InputFile);
569 File->TargetTriple = FOrErr->TheReader.getTargetTriple();
570 File->SourceFileName = FOrErr->TheReader.getSourceFileName();
571 File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts();
572 File->DependentLibraries = FOrErr->TheReader.getDependentLibraries();
573 File->ComdatTable = FOrErr->TheReader.getComdatTable();
575 for (
unsigned I = 0;
I != FOrErr->Mods.size(); ++
I) {
576 size_t Begin = File->Symbols.size();
578 FOrErr->TheReader.module_symbols(
I))
581 if (Sym.isGlobal() && !Sym.isFormatSpecific())
582 File->Symbols.push_back(Sym);
583 File->ModuleSymIndices.push_back({Begin, File->Symbols.size()});
586 File->Mods = FOrErr->Mods;
587 File->Strtab = std::move(FOrErr->Strtab);
588 return std::move(File);
592 return Mods[0].getModuleIdentifier();
596 assert(Mods.size() == 1 &&
"Expect only one bitcode module");
600LTO::RegularLTOState::RegularLTOState(
unsigned ParallelCodeGenParallelismLevel,
602 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
603 Ctx(Conf), CombinedModule(
std::make_unique<
Module>(
"ld-temp.o", Ctx)),
604 Mover(
std::make_unique<
IRMover>(*CombinedModule)) {}
606LTO::ThinLTOState::ThinLTOState(
ThinBackend BackendParam)
607 : Backend(
std::
move(BackendParam)), CombinedIndex(
false) {
608 if (!Backend.isValid())
614 unsigned ParallelCodeGenParallelismLevel,
LTOKind LTOMode)
616 RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),
622 Alloc = std::make_unique<BumpPtrAllocator>();
623 GlobalResolutionSymbolSaver = std::make_unique<llvm::StringSaver>(*Alloc);
634 unsigned Partition,
bool InSummary) {
636 auto *ResI = Res.
begin();
637 auto *ResE = Res.
end();
645 if (GlobalResolutionSymbolSaver && !GlobalResolutions->contains(SymbolName))
646 SymbolName = GlobalResolutionSymbolSaver->save(SymbolName);
648 auto &GlobalRes = (*GlobalResolutions)[SymbolName];
649 GlobalRes.UnnamedAddr &= Sym.isUnnamedAddr();
651 assert(!GlobalRes.Prevailing &&
652 "Multiple prevailing defs are not allowed");
653 GlobalRes.Prevailing =
true;
654 GlobalRes.IRName = std::string(Sym.getIRName());
655 }
else if (!GlobalRes.Prevailing && GlobalRes.IRName.empty()) {
662 GlobalRes.IRName = std::string(Sym.getIRName());
676 if (GlobalRes.IRName != Sym.getIRName()) {
677 GlobalRes.Partition = GlobalResolution::External;
678 GlobalRes.VisibleOutsideSummary =
true;
686 (GlobalRes.Partition != GlobalResolution::Unknown &&
687 GlobalRes.Partition != Partition)) {
688 GlobalRes.Partition = GlobalResolution::External;
691 GlobalRes.Partition = Partition;
695 GlobalRes.VisibleOutsideSummary |=
702void LTO::releaseGlobalResolutionsMemory() {
704 GlobalResolutions.reset();
706 GlobalResolutionSymbolSaver.reset();
714 auto ResI = Res.
begin();
719 OS <<
"-r=" << Path <<
',' << Sym.getName() <<
',';
737 assert(!CalledGetMaxTasks);
739 if (Conf.ResolutionFile)
742 if (RegularLTO.CombinedModule->getTargetTriple().empty()) {
744 RegularLTO.CombinedModule->setTargetTriple(InputTriple);
750 for (
unsigned I = 0;
I !=
Input->Mods.size(); ++
I) {
751 if (
auto Err = addModule(*
Input, InputRes,
I, Res).moveInto(Res))
767 if (EnableSplitLTOUnit) {
771 if (*EnableSplitLTOUnit != LTOInfo->EnableSplitLTOUnit)
774 EnableSplitLTOUnit = LTOInfo->EnableSplitLTOUnit;
779 !LTOInfo->UnifiedLTO)
781 "unified LTO compilation must use "
782 "compatible bitcode modules (use -funified-lto)",
790 auto ModSyms =
Input.module_symbols(ModI);
791 addModuleToGlobalRes(ModSyms, Res,
792 IsThinLTO ? ThinLTO.ModuleMap.
size() + 1 : 0,
793 LTOInfo->HasSummary);
796 return addThinLTO(BM, ModSyms, Res);
798 RegularLTO.EmptyCombinedModule =
false;
799 auto ModOrErr = addRegularLTO(
Input, InputRes, BM, ModSyms, Res);
801 return ModOrErr.takeError();
802 Res = ModOrErr->second;
804 if (!LTOInfo->HasSummary) {
805 if (
Error Err = linkRegularLTO(std::move(ModOrErr->first),
815 RegularLTO.ModsWithSummaries.push_back(std::move(ModOrErr->first));
831 std::set<const Comdat *> &NonPrevailingComdats) {
836 if (!NonPrevailingComdats.count(
C))
846 GO->setComdat(
nullptr);
853 std::pair<LTO::RegularLTOState::AddedModule, ArrayRef<SymbolResolution>>>
857 llvm::TimeTraceScope timeScope(
"LTO add regular LTO");
859 Expected<std::unique_ptr<Module>> MOrErr =
865 Mod.M = std::move(*MOrErr);
867 if (
Error Err =
M.materializeMetadata())
868 return std::move(Err);
874 if (NamedMDNode *CfiFunctionsMD =
M.getNamedMetadata(
"cfi.functions"))
875 M.eraseNamedMetadata(CfiFunctionsMD);
876 }
else if (NamedMDNode *AliasesMD =
M.getNamedMetadata(
"aliases")) {
879 DenseSet<StringRef> Prevailing;
881 if (
R.Prevailing && !
I.getIRName().empty())
882 Prevailing.
insert(
I.getIRName());
883 std::vector<MDNode *> AliasGroups;
884 for (MDNode *AliasGroup : AliasesMD->operands()) {
885 std::vector<Metadata *> Aliases;
886 for (
Metadata *Alias : AliasGroup->operands()) {
889 Aliases.push_back(Alias);
891 if (Aliases.size() > 1)
892 AliasGroups.push_back(
MDTuple::get(RegularLTO.Ctx, Aliases));
894 AliasesMD->clearOperands();
895 for (MDNode *
G : AliasGroups)
896 AliasesMD->addOperand(
G);
901 ModuleSymbolTable SymTab;
904 for (GlobalVariable &GV :
M.globals())
905 if (GV.hasAppendingLinkage())
906 Mod.Keep.push_back(&GV);
908 DenseSet<GlobalObject *> AliasedGlobals;
909 for (
auto &GA :
M.aliases())
910 if (GlobalObject *GO = GA.getAliaseeObject())
911 AliasedGlobals.
insert(GO);
920 auto MsymI = SymTab.
symbols().begin(), MsymE = SymTab.
symbols().end();
922 while (MsymI != MsymE) {
932 std::set<const Comdat *> NonPrevailingComdats;
933 SmallSet<StringRef, 2> NonPrevailingAsmSymbols;
934 for (
const InputFile::Symbol &Sym : Syms) {
944 if (Sym.isUndefined())
946 Mod.Keep.push_back(GV);
950 if (
R.LinkerRedefined)
958 (GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||
959 GV->hasAvailableExternallyLinkage()) &&
966 Mod.Keep.push_back(GV);
969 NonPrevailingComdats.insert(GV->getComdat());
974 if (
R.FinalDefinitionInLinkageUnit) {
975 GV->setDSOLocal(
true);
976 if (GV->hasDLLImportStorageClass())
978 DefaultStorageClass);
980 }
else if (
auto *AS =
984 NonPrevailingAsmSymbols.
insert(AS->first);
992 if (Sym.isCommon()) {
995 auto &CommonRes = RegularLTO.Commons[std::string(Sym.getIRName())];
996 CommonRes.Size = std::max(CommonRes.Size, Sym.getCommonSize());
997 if (uint32_t SymAlignValue = Sym.getCommonAlignment()) {
998 CommonRes.Alignment =
999 std::max(
Align(SymAlignValue), CommonRes.Alignment);
1001 CommonRes.Prevailing |=
R.Prevailing;
1005 if (!
M.getComdatSymbolTable().empty())
1006 for (GlobalValue &GV :
M.global_values())
1011 if (!
M.getModuleInlineAsm().empty()) {
1012 std::string NewIA =
".lto_discard";
1013 if (!NonPrevailingAsmSymbols.
empty()) {
1016 M, [&](StringRef Name, StringRef Alias) {
1017 if (!NonPrevailingAsmSymbols.
count(Alias))
1018 NonPrevailingAsmSymbols.
erase(Name);
1020 NewIA +=
" " +
llvm::join(NonPrevailingAsmSymbols,
", ");
1023 M.setModuleInlineAsm(NewIA +
M.getModuleInlineAsm());
1027 return std::make_pair(std::move(
Mod), Res);
1030Error LTO::linkRegularLTO(RegularLTOState::AddedModule
Mod,
1031 bool LivenessFromIndex) {
1032 llvm::TimeTraceScope timeScope(
"LTO link regular LTO");
1033 std::vector<GlobalValue *>
Keep;
1034 for (GlobalValue *GV :
Mod.Keep) {
1035 if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->
getGUID())) {
1037 if (DiagnosticOutputFile) {
1038 if (
Error Err =
F->materialize())
1040 OptimizationRemarkEmitter ORE(
F,
nullptr);
1041 ORE.emit(OptimizationRemark(
DEBUG_TYPE,
"deadfunction",
F)
1043 <<
" not added to the combined module ");
1056 GlobalValue *CombinedGV =
1057 RegularLTO.CombinedModule->getNamedValue(GV->
getName());
1064 return RegularLTO.Mover->move(std::move(
Mod.M),
Keep,
nullptr,
1069Expected<ArrayRef<SymbolResolution>>
1072 llvm::TimeTraceScope timeScope(
"LTO add thin LTO");
1074 for (
const InputFile::Symbol &Sym : Syms) {
1078 if (!Sym.getIRName().empty()) {
1090 return ThinLTO.PrevailingModuleForGUID[GUID] ==
1091 BM.getModuleIdentifier();
1096 for (
const InputFile::Symbol &Sym : Syms) {
1100 if (!Sym.getIRName().empty()) {
1105 assert(ThinLTO.PrevailingModuleForGUID[GUID] ==
1112 if (
R.LinkerRedefined)
1113 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(
1120 if (
R.FinalDefinitionInLinkageUnit) {
1121 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(
1123 S->setDSOLocal(
true);
1129 if (!ThinLTO.ModuleMap.insert({BM.getModuleIdentifier(), BM}).second)
1131 "Expected at most one ThinLTO module per bitcode file",
1134 if (!Conf.ThinLTOModulesToCompile.empty()) {
1135 if (!ThinLTO.ModulesToCompile)
1136 ThinLTO.ModulesToCompile = ModuleMapType();
1139 for (
const std::string &Name : Conf.ThinLTOModulesToCompile) {
1143 <<
" to compile\n");
1152 CalledGetMaxTasks =
true;
1153 auto ModuleCount = ThinLTO.ModulesToCompile ? ThinLTO.ModulesToCompile->size()
1154 : ThinLTO.ModuleMap.size();
1155 return RegularLTO.ParallelCodeGenParallelismLevel + ModuleCount;
1160Error LTO::checkPartiallySplit() {
1164 const Module *Combined = RegularLTO.CombinedModule.get();
1170 Combined, Intrinsic::type_checked_load_relative);
1174 if ((TypeTestFunc && !TypeTestFunc->
use_empty()) ||
1175 (TypeCheckedLoadFunc && !TypeCheckedLoadFunc->
use_empty()) ||
1176 (TypeCheckedLoadRelativeFunc &&
1177 !TypeCheckedLoadRelativeFunc->
use_empty()))
1179 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1184 for (
auto &
P : ThinLTO.CombinedIndex) {
1185 for (
auto &S :
P.second.SummaryList) {
1189 if (!FS->type_test_assume_vcalls().empty() ||
1190 !FS->type_checked_load_vcalls().empty() ||
1191 !FS->type_test_assume_const_vcalls().empty() ||
1192 !FS->type_checked_load_const_vcalls().empty() ||
1193 !FS->type_tests().empty())
1195 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1206 for (
auto &Res : *GlobalResolutions) {
1209 if (Res.second.IRName.
empty())
1215 if (Res.second.VisibleOutsideSummary && Res.second.Prevailing)
1216 GUIDPreservedSymbols.
insert(GUID);
1218 if (Res.second.ExportDynamic)
1219 DynamicExportSymbols.insert(GUID);
1221 GUIDPrevailingResolutions[GUID] =
1226 auto It = GUIDPrevailingResolutions.
find(
G);
1227 if (It == GUIDPrevailingResolutions.
end())
1232 isPrevailing, Conf.OptLevel > 0);
1236 if (!StatsFileOrErr)
1237 return StatsFileOrErr.takeError();
1238 std::unique_ptr<ToolOutputFile> StatsFile = std::move(StatsFileOrErr.get());
1246 ThinLTO.CombinedIndex.setWithSupportsHotColdNew();
1248 Error Result = runRegularLTO(AddStream);
1252 Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols);
1263 if (Index.withSupportsHotColdNew())
1271 for (
auto &
F :
Mod) {
1272 for (
auto &BB :
F) {
1273 for (
auto &
I : BB) {
1277 if (CI->hasFnAttr(
"memprof"))
1278 CI->removeFnAttr(
"memprof");
1285 CI->setMetadata(LLVMContext::MD_memprof,
nullptr);
1286 CI->setMetadata(LLVMContext::MD_callsite,
nullptr);
1294 LLVMContext &CombinedCtx = RegularLTO.CombinedModule->getContext();
1301 return DiagFileOrErr.takeError();
1302 DiagnosticOutputFile = std::move(*DiagFileOrErr);
1308 for (
auto &M : RegularLTO.ModsWithSummaries)
1309 if (
Error Err = linkRegularLTO(std::move(M),
true))
1317 if (
Error Err = checkPartiallySplit())
1322 const DataLayout &
DL = RegularLTO.CombinedModule->getDataLayout();
1323 for (
auto &
I : RegularLTO.Commons) {
1324 if (!
I.second.Prevailing)
1327 GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(
I.first);
1328 if (OldGV &&
DL.getTypeAllocSize(OldGV->
getValueType()) ==
I.second.Size) {
1336 auto *GV =
new GlobalVariable(*RegularLTO.CombinedModule, Ty,
false,
1339 GV->setAlignment(
I.second.Alignment);
1351 bool WholeProgramVisibilityEnabledInLTO =
1352 Conf.HasWholeProgramVisibility &&
1355 (!Conf.ValidateAllVtablesHaveTypeInfos || Conf.AllVtablesHaveTypeInfos);
1359 auto IsVisibleToRegularObj = [&](StringRef
name) {
1360 auto It = GlobalResolutions->find(
name);
1361 return (It == GlobalResolutions->end() ||
1362 It->second.VisibleOutsideSummary || !It->second.Prevailing);
1368 *RegularLTO.CombinedModule, WholeProgramVisibilityEnabledInLTO,
1369 DynamicExportSymbols, Conf.ValidateAllVtablesHaveTypeInfos,
1370 IsVisibleToRegularObj);
1372 WholeProgramVisibilityEnabledInLTO);
1374 if (Conf.PreOptModuleHook &&
1375 !Conf.PreOptModuleHook(0, *RegularLTO.CombinedModule))
1378 if (!Conf.CodeGenOnly) {
1379 for (
const auto &R : *GlobalResolutions) {
1381 RegularLTO.CombinedModule->getNamedValue(
R.second.IRName);
1382 if (!
R.second.isPrevailingIRSymbol())
1384 if (
R.second.Partition != 0 &&
1385 R.second.Partition != GlobalResolution::External)
1413 if (Conf.PostInternalizeModuleHook &&
1414 !Conf.PostInternalizeModuleHook(0, *RegularLTO.CombinedModule))
1418 if (!RegularLTO.EmptyCombinedModule || Conf.AlwaysEmitRegularLTOObj) {
1420 backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,
1421 *RegularLTO.CombinedModule, ThinLTO.CombinedIndex))
1434 for (RTLIB::LibcallImpl Impl : LibcallImpls) {
1435 if (Impl != RTLIB::Unsupported)
1439 return LibcallSymbols;
1444 const std::string &NewModulePath)
const {
1445 return emitFiles(ImportList, ModulePath, NewModulePath,
1446 NewModulePath +
".thinlto.bc",
1452 const std::string &NewModulePath,
StringRef SummaryPath,
1453 std::optional<std::reference_wrapper<ImportsFilesContainer>> ImportsFiles)
1460 ImportList, ModuleToSummariesForIndex,
1461 DeclarationSummaries);
1468 &DeclarationSummaries);
1472 ModulePath, NewModulePath +
".imports", ModuleToSummariesForIndex);
1473 if (ImportsFilesError)
1474 return ImportsFilesError;
1480 ModulePath, ModuleToSummariesForIndex,
1481 [&](
StringRef M) { ImportsFiles->get().push_back(M.str()); });
1494 bool ShouldEmitIndexFiles;
1501 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
1504 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
1505 AddStream(
std::
move(AddStream)),
1506 ShouldEmitIndexFiles(ShouldEmitIndexFiles) {
1516class InProcessThinBackend :
public CGThinBackend {
1521 InProcessThinBackend(
1526 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles)
1527 : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
1528 AddStream, OnWrite, ShouldEmitIndexFiles,
1529 ShouldEmitImportsFiles, ThinLTOParallelism),
1532 virtual Error runThinLTOBackendThread(
1533 AddStreamFn AddStream, FileCache Cache,
unsigned Task, BitcodeModule BM,
1534 ModuleSummaryIndex &CombinedIndex,
1535 const FunctionImporter::ImportMapTy &ImportList,
1537 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1539 MapVector<StringRef, BitcodeModule> &ModuleMap) {
1541 llvm::TimeTraceScope timeScope(
"Run ThinLTO backend thread (in-process)",
1543 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1544 LTOLLVMContext BackendContext(Conf);
1545 Expected<std::unique_ptr<Module>> MOrErr = BM.
parseModule(BackendContext);
1549 return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,
1550 ImportList, DefinedGlobals, &ModuleMap,
1553 if (ShouldEmitIndexFiles) {
1554 if (
auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1560 [](uint32_t V) { return V == 0; }))
1563 return RunThinBackend(AddStream);
1567 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1568 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1569 Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task,
Key, ModuleID);
1572 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1574 return RunThinBackend(CacheAddStream);
1580 unsigned Task, BitcodeModule BM,
1581 const FunctionImporter::ImportMapTy &ImportList,
1583 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1584 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
1586 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
1588 ModuleToDefinedGVSummaries.
find(ModulePath)->second;
1589 BackendThreadPool.async(
1590 [=](BitcodeModule BM, ModuleSummaryIndex &CombinedIndex,
1591 const FunctionImporter::ImportMapTy &ImportList,
1593 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
1596 MapVector<StringRef, BitcodeModule> &ModuleMap) {
1600 Error E = runThinLTOBackendThread(
1601 AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList,
1602 ResolvedODR, DefinedGlobals, ModuleMap);
1604 std::unique_lock<std::mutex>
L(ErrMu);
1613 BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList),
1614 std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap));
1617 OnWrite(std::string(ModulePath));
1627class FirstRoundThinBackend :
public InProcessThinBackend {
1632 FirstRoundThinBackend(
1633 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
1634 ThreadPoolStrategy ThinLTOParallelism,
1635 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
1638 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
1639 ModuleToDefinedGVSummaries, std::
move(CGAddStream),
1640 std::
move(CGCache), nullptr,
1643 IRAddStream(std::
move(IRAddStream)), IRCache(std::
move(IRCache)) {}
1645 Error runThinLTOBackendThread(
1646 AddStreamFn CGAddStream, FileCache CGCache,
unsigned Task,
1647 BitcodeModule BM, ModuleSummaryIndex &CombinedIndex,
1648 const FunctionImporter::ImportMapTy &ImportList,
1650 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1652 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
1654 llvm::TimeTraceScope timeScope(
"Run ThinLTO backend thread (first round)",
1656 auto RunThinBackend = [&](
AddStreamFn CGAddStream,
1658 LTOLLVMContext BackendContext(Conf);
1659 Expected<std::unique_ptr<Module>> MOrErr = BM.
parseModule(BackendContext);
1663 return thinBackend(Conf, Task, CGAddStream, **MOrErr, CombinedIndex,
1664 ImportList, DefinedGlobals, &ModuleMap,
1670 if (ShouldEmitIndexFiles) {
1671 if (
auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1676 "Both caches for CG and IR should have matching availability");
1679 [](uint32_t V) { return V == 0; }))
1682 return RunThinBackend(CGAddStream, IRAddStream);
1686 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1687 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1688 Expected<AddStreamFn> CacheCGAddStreamOrErr =
1689 CGCache(Task, CGKey, ModuleID);
1692 AddStreamFn &CacheCGAddStream = *CacheCGAddStreamOrErr;
1696 Expected<AddStreamFn> CacheIRAddStreamOrErr =
1697 IRCache(Task, IRKey, ModuleID);
1700 AddStreamFn &CacheIRAddStream = *CacheIRAddStreamOrErr;
1706 if (CacheCGAddStream || CacheIRAddStream) {
1709 return RunThinBackend(CacheCGAddStream ? CacheCGAddStream : CGAddStream,
1710 CacheIRAddStream ? CacheIRAddStream : IRAddStream);
1722class SecondRoundThinBackend :
public InProcessThinBackend {
1723 std::unique_ptr<SmallVector<StringRef>> IRFiles;
1727 SecondRoundThinBackend(
1728 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
1729 ThreadPoolStrategy ThinLTOParallelism,
1730 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
1734 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
1735 ModuleToDefinedGVSummaries, std::
move(AddStream),
1740 IRFiles(std::
move(IRFiles)), CombinedCGDataHash(CombinedCGDataHash) {}
1742 virtual Error runThinLTOBackendThread(
1743 AddStreamFn AddStream, FileCache Cache,
unsigned Task, BitcodeModule BM,
1744 ModuleSummaryIndex &CombinedIndex,
1745 const FunctionImporter::ImportMapTy &ImportList,
1747 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1749 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
1751 llvm::TimeTraceScope timeScope(
"Run ThinLTO backend thread (second round)",
1753 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1754 LTOLLVMContext BackendContext(Conf);
1755 std::unique_ptr<Module> LoadedModule =
1758 return thinBackend(Conf, Task, AddStream, *LoadedModule, CombinedIndex,
1759 ImportList, DefinedGlobals, &ModuleMap,
1764 [](uint32_t V) { return V == 0; }))
1767 return RunThinBackend(AddStream);
1772 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1773 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1775 std::to_string(CombinedCGDataHash));
1776 Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task,
Key, ModuleID);
1779 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1781 if (CacheAddStream) {
1784 return RunThinBackend(CacheAddStream);
1794 bool ShouldEmitIndexFiles,
1795 bool ShouldEmitImportsFiles) {
1800 return std::make_unique<InProcessThinBackend>(
1801 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1802 AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
1803 ShouldEmitImportsFiles);
1829 return std::string(Path);
1833 if (!ParentPath.
empty()) {
1836 llvm::errs() <<
"warning: could not create directory '" << ParentPath
1837 <<
"': " << EC.message() <<
'\n';
1839 return std::string(NewPath);
1844 std::string OldPrefix, NewPrefix, NativeObjectPrefix;
1848 WriteIndexesThinBackend(
1852 std::string OldPrefix, std::string NewPrefix,
1853 std::string NativeObjectPrefix,
bool ShouldEmitImportsFiles,
1856 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
1857 OldPrefix(OldPrefix), NewPrefix(NewPrefix),
1858 NativeObjectPrefix(NativeObjectPrefix),
1859 LinkedObjectsFile(LinkedObjectsFile) {}
1865 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1873 if (LinkedObjectsFile) {
1874 std::string ObjectPrefix =
1875 NativeObjectPrefix.empty() ? NewPrefix : NativeObjectPrefix;
1876 std::string LinkedObjectsFilePath =
1878 *LinkedObjectsFile << LinkedObjectsFilePath <<
'\n';
1881 BackendThreadPool.async(
1882 [
this](
const StringRef ModulePath,
1883 const FunctionImporter::ImportMapTy &ImportList,
1884 const std::string &OldPrefix,
const std::string &NewPrefix) {
1885 std::string NewModulePath =
1887 auto E = emitFiles(ImportList, ModulePath, NewModulePath);
1889 std::unique_lock<std::mutex>
L(ErrMu);
1897 ModulePath, ImportList, OldPrefix, NewPrefix);
1900 OnWrite(std::string(ModulePath));
1904 bool isSensitiveToInputOrder()
override {
1914 std::string NewPrefix, std::string NativeObjectPrefix,
1921 return std::make_unique<WriteIndexesThinBackend>(
1922 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1923 OldPrefix, NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,
1924 LinkedObjectsFile, OnWrite);
1939 if (ThinLTO.ModuleMap.
empty())
1942 if (ThinLTO.ModulesToCompile && ThinLTO.ModulesToCompile->empty()) {
1943 llvm::errs() <<
"warning: [ThinLTO] No module compiled\n";
1947 if (Conf.CombinedIndexHook &&
1948 !Conf.CombinedIndexHook(ThinLTO.CombinedIndex, GUIDPreservedSymbols))
1953 DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries(
1954 ThinLTO.ModuleMap.size());
1955 ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule(
1956 ModuleToDefinedGVSummaries);
1964 for (
auto &
Mod : ThinLTO.ModuleMap)
1965 if (!ModuleToDefinedGVSummaries.
count(
Mod.first))
1968 FunctionImporter::ImportListsTy ImportLists(ThinLTO.ModuleMap.size());
1969 DenseMap<StringRef, FunctionImporter::ExportSetTy> ExportLists(
1970 ThinLTO.ModuleMap.size());
1971 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
1974 ThinLTO.CombinedIndex.dumpSCCs(
outs());
1976 std::set<GlobalValue::GUID> ExportedGUIDs;
1978 bool WholeProgramVisibilityEnabledInLTO =
1979 Conf.HasWholeProgramVisibility &&
1982 (!Conf.ValidateAllVtablesHaveTypeInfos || Conf.AllVtablesHaveTypeInfos);
1984 ThinLTO.CombinedIndex.setWithWholeProgramVisibility();
1989 DenseSet<GlobalValue::GUID> VisibleToRegularObjSymbols;
1990 if (WholeProgramVisibilityEnabledInLTO &&
1991 Conf.ValidateAllVtablesHaveTypeInfos) {
1994 auto IsVisibleToRegularObj = [&](StringRef
name) {
1995 auto It = GlobalResolutions->find(
name);
1996 return (It == GlobalResolutions->end() ||
1997 It->second.VisibleOutsideSummary || !It->second.Prevailing);
2001 VisibleToRegularObjSymbols,
2002 IsVisibleToRegularObj);
2008 ThinLTO.CombinedIndex, WholeProgramVisibilityEnabledInLTO,
2009 DynamicExportSymbols, VisibleToRegularObjSymbols);
2014 std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;
2016 LocalWPDTargetsMap);
2019 return ThinLTO.PrevailingModuleForGUID[
GUID] == S->modulePath();
2022 MemProfContextDisambiguation ContextDisambiguation;
2023 ContextDisambiguation.
run(ThinLTO.CombinedIndex, isPrevailing);
2030 for (
auto &Res : *GlobalResolutions) {
2033 if (Res.second.Partition != GlobalResolution::External ||
2034 !Res.second.isPrevailingIRSymbol())
2039 if (ThinLTO.CombinedIndex.isGUIDLive(GUID))
2040 ExportedGUIDs.insert(GUID);
2047 releaseGlobalResolutionsMemory();
2049 if (Conf.OptLevel > 0)
2051 isPrevailing, ImportLists, ExportLists);
2055 auto &Defs = ThinLTO.CombinedIndex.cfiFunctionDefs();
2056 ExportedGUIDs.insert(Defs.guid_begin(), Defs.guid_end());
2057 auto &Decls = ThinLTO.CombinedIndex.cfiFunctionDecls();
2058 ExportedGUIDs.insert(Decls.guid_begin(), Decls.guid_end());
2060 auto isExported = [&](StringRef ModuleIdentifier, ValueInfo
VI) {
2061 const auto &ExportList = ExportLists.
find(ModuleIdentifier);
2062 return (ExportList != ExportLists.end() && ExportList->second.
count(VI)) ||
2063 ExportedGUIDs.count(
VI.getGUID());
2069 LocalWPDTargetsMap);
2074 auto recordNewLinkage = [&](StringRef ModuleIdentifier,
2077 ResolvedODR[ModuleIdentifier][
GUID] = NewLinkage;
2080 recordNewLinkage, GUIDPreservedSymbols);
2089 TimeTraceScopeExit.release();
2092 ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;
2094 auto RunBackends = [&](ThinBackendProc *BackendProcess) ->
Error {
2095 auto ProcessOneModule = [&](
int I) ->
Error {
2099 return BackendProcess->start(
2100 RegularLTO.ParallelCodeGenParallelismLevel +
I,
Mod.second,
2101 ImportLists[
Mod.first], ExportLists[
Mod.first],
2102 ResolvedODR[
Mod.first], ThinLTO.ModuleMap);
2105 BackendProcess->setup(ModuleMap.
size(),
2106 RegularLTO.ParallelCodeGenParallelismLevel,
2107 RegularLTO.CombinedModule->getTargetTriple());
2109 if (BackendProcess->getThreadCount() == 1 ||
2110 BackendProcess->isSensitiveToInputOrder()) {
2116 for (
int I = 0,
E = ModuleMap.
size();
I !=
E; ++
I)
2117 if (
Error E = ProcessOneModule(
I))
2124 std::vector<BitcodeModule *> ModulesVec;
2125 ModulesVec.reserve(ModuleMap.
size());
2126 for (
auto &
Mod : ModuleMap)
2127 ModulesVec.push_back(&
Mod.second);
2129 if (
Error E = ProcessOneModule(
I))
2132 return BackendProcess->wait();
2136 std::unique_ptr<ThinBackendProc> BackendProc =
2137 ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
2139 return RunBackends(BackendProc.get());
2147 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Initializing ThinLTO two-codegen rounds\n");
2150 auto Parallelism = ThinLTO.Backend.getParallelism();
2153 cgdata::StreamCacheData CG(MaxTasks, Cache,
"CG"),
IR(MaxTasks, Cache,
"IR");
2158 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Running the first round of codegen\n");
2159 auto FirstRoundLTO = std::make_unique<FirstRoundThinBackend>(
2160 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2161 CG.AddStream, CG.Cache,
IR.AddStream,
IR.Cache);
2162 if (
Error E = RunBackends(FirstRoundLTO.get()))
2167 if (
Error E = CombinedHashOrErr.takeError())
2169 auto CombinedHash = *CombinedHashOrErr;
2170 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] CGData hash: " << CombinedHash <<
"\n");
2174 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Running the second round of codegen\n");
2175 auto SecondRoundLTO = std::make_unique<SecondRoundThinBackend>(
2176 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2177 AddStream, Cache,
IR.getResult(), CombinedHash);
2178 return RunBackends(SecondRoundLTO.get());
2188 if (!Filename.empty() &&
Count != -1)
2196 if (
Error E = ResultOrErr.takeError())
2197 return std::move(E);
2200 (*ResultOrErr)->keep();
2208 if (StatsFilename.
empty())
2219 return std::move(StatsFile);
2227 std::vector<int> ModulesOrdering(Seq.begin(), Seq.end());
2228 llvm::sort(ModulesOrdering, [&](
int LeftIndex,
int RightIndex) {
2229 auto LSize = R[LeftIndex]->getBuffer().size();
2230 auto RSize = R[RightIndex]->getBuffer().size();
2231 return LSize > RSize;
2233 return ModulesOrdering;
2243class OutOfProcessThinBackend :
public CGThinBackend {
2249 SString LinkerOutputFile;
2251 SString DistributorPath;
2254 SString RemoteCompiler;
2277 unsigned ThinLTOTaskOffset;
2280 llvm::Triple Triple;
2283 OutOfProcessThinBackend(
2284 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
2285 ThreadPoolStrategy ThinLTOParallelism,
2286 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
2288 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
2289 StringRef LinkerOutputFile, StringRef Distributor,
2292 : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
2293 AddStream, OnWrite, ShouldEmitIndexFiles,
2294 ShouldEmitImportsFiles, ThinLTOParallelism),
2295 LinkerOutputFile(LinkerOutputFile), DistributorPath(Distributor),
2296 DistributorArgs(DistributorArgs), RemoteCompiler(RemoteCompiler),
2297 RemoteCompilerArgs(RemoteCompilerArgs), SaveTemps(SaveTemps) {}
2299 virtual void setup(
unsigned ThinLTONumTasks,
unsigned ThinLTOTaskOffset,
2300 llvm::Triple Triple)
override {
2302 Jobs.
resize((
size_t)ThinLTONumTasks);
2303 this->ThinLTOTaskOffset = ThinLTOTaskOffset;
2304 this->Triple = Triple;
2308 unsigned Task, BitcodeModule BM,
2309 const FunctionImporter::ImportMapTy &ImportList,
2311 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
2312 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
2318 itostr(Task) +
"." + UID +
".native.o");
2320 Job &J = Jobs[Task - ThinLTOTaskOffset];
2324 Saver.
save(ObjFilePath.str()),
2325 Saver.
save(ObjFilePath.str() +
".thinlto.bc"),
2329 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
2333 BackendThreadPool.async(
2334 [=](Job &J,
const FunctionImporter::ImportMapTy &ImportList) {
2335 if (
auto E = emitFiles(ImportList, J.ModuleID, J.ModuleID.str(),
2336 J.SummaryIndexPath, J.ImportsFiles)) {
2337 std::unique_lock<std::mutex>
L(ErrMu);
2344 std::ref(J), std::ref(ImportList));
2358 void buildCommonRemoteCompilerOptions() {
2359 const lto::Config &
C = Conf;
2360 auto &
Ops = CodegenOptions;
2364 if (
C.Options.EmitAddrsig)
2365 Ops.push_back(
"-faddrsig");
2366 if (
C.Options.FunctionSections)
2367 Ops.push_back(
"-ffunction-sections");
2368 if (
C.Options.DataSections)
2369 Ops.push_back(
"-fdata-sections");
2374 Ops.push_back(
"-fpic");
2378 if (!
C.PGOWarnMismatch) {
2379 Ops.push_back(
"-mllvm");
2380 Ops.push_back(
"-no-pgo-warn-mismatch");
2385 if (!
C.SampleProfile.empty()) {
2387 Saver.
save(
"-fprofile-sample-use=" + Twine(
C.SampleProfile)));
2388 CommonInputs.
insert(
C.SampleProfile);
2392 Ops.push_back(
"-Wno-unused-command-line-argument");
2395 if (!RemoteCompilerArgs.
empty())
2396 for (
auto &a : RemoteCompilerArgs)
2402 bool emitDistributorJson(StringRef DistributorJson) {
2405 raw_fd_ostream OS(DistributorJson, EC);
2409 json::OStream JOS(OS);
2412 JOS.attributeObject(
"common", [&]() {
2413 JOS.attribute(
"linker_output", LinkerOutputFile);
2415 JOS.attributeArray(
"args", [&]() {
2416 JOS.value(RemoteCompiler);
2420 JOS.value(Saver.
save(
"--target=" + Triple.
str()));
2422 for (
const auto &
A : CodegenOptions)
2426 JOS.attribute(
"inputs",
Array(CommonInputs));
2430 JOS.attributeArray(
"jobs", [&]() {
2431 for (
const auto &J : Jobs) {
2435 SmallVector<StringRef, 1> Outputs;
2438 JOS.attributeArray(
"args", [&]() {
2439 JOS.value(J.ModuleID);
2443 Saver.
save(
"-fthinlto-index=" + Twine(J.SummaryIndexPath)));
2447 JOS.value(J.NativeObjectPath);
2455 JOS.attribute(
"inputs",
Array(Inputs));
2457 JOS.attribute(
"outputs",
Array(Outputs));
2466 void removeFile(StringRef FileName) {
2468 if (EC && EC != std::make_error_code(std::errc::no_such_file_or_directory))
2469 errs() <<
"warning: could not remove the file '" << FileName
2470 <<
"': " <<
EC.message() <<
"\n";
2473 Error wait()
override {
2476 BackendThreadPool.wait();
2478 return std::move(*Err);
2482 for (
auto &Job : Jobs) {
2483 removeFile(Job.NativeObjectPath);
2484 if (!ShouldEmitIndexFiles)
2485 removeFile(Job.SummaryIndexPath);
2489 const StringRef BCError =
"DTLTO backend compilation: ";
2491 buildCommonRemoteCompilerOptions();
2496 if (!emitDistributorJson(JsonFile))
2498 BCError +
"failed to generate distributor JSON script: " + JsonFile,
2502 removeFile(JsonFile);
2507 Args.push_back(JsonFile);
2513 BCError +
"distributor execution failed" +
2514 (!ErrMsg.empty() ?
": " + ErrMsg + Twine(
".") : Twine(
".")),
2518 for (
auto &Job : Jobs) {
2521 auto ObjFileMbOrErr =
2524 if (std::error_code EC = ObjFileMbOrErr.getError())
2526 BCError +
"cannot open native object file: " +
2527 Job.NativeObjectPath +
": " +
EC.message(),
2529 auto StreamOrErr = AddStream(Job.Task, Job.ModuleID);
2530 if (
Error Err = StreamOrErr.takeError())
2532 auto &Stream = *StreamOrErr->get();
2533 *Stream.OS << ObjFileMbOrErr->get()->getMemBufferRef().getBuffer();
2534 if (
Error Err = Stream.commit())
2545 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
2553 return std::make_unique<OutOfProcessThinBackend>(
2554 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2555 AddStream, OnWrite, ShouldEmitIndexFiles, ShouldEmitImportsFiles,
2556 LinkerOutputFile, Distributor, DistributorArgs, RemoteCompiler,
2557 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 cl::opt< bool > DumpThinCGSCCs("dump-thin-cg-sccs", cl::init(false), cl::Hidden, cl::desc("Dump the SCCs in the ThinLTO index's callgraph"))
static void thinLTOInternalizeAndPromoteGUID(ValueInfo VI, function_ref< bool(StringRef, ValueInfo)> isExported, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
Legalize the Machine IR a function s Machine IR
Machine Check Debug Module
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...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
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.
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
Type * getValueType() const
static bool isLinkOnceODRLinkage(LinkageTypes Linkage)
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)
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).
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
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 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...
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.
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.
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 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 ThinBackend createOutOfProcessThinBackend(ThreadPoolStrategy Parallelism, IndexWriteCallback OnWrite, bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles, StringRef LinkerOutputFile, StringRef Distributor, ArrayRef< StringRef > DistributorArgs, StringRef RemoteCompiler, ArrayRef< StringRef > RemoteCompilerArgs, bool SaveTemps)
This ThinBackend generates the index shards and then runs the individual backend jobs via an external...
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 void updateMemProfAttributes(Module &Mod, const ModuleSummaryIndex &Index)
Updates MemProf attributes (and metadata) based on whether the index has recorded that we are linking...
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 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"))
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.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
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.
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.
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 thinLTOInternalizeAndPromoteInIndex(ModuleSummaryIndex &Index, function_ref< bool(StringRef, ValueInfo)> isExported, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
Update the linkages in the given Index to mark exported values as external and non-exported values as...
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"))
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
cl::opt< bool > SupportsHotColdNew
Indicate we are linking with an allocator that supports hot/cold operator new interfaces.
LLVM_ABI void updateIndexWPDForExports(ModuleSummaryIndex &Summary, function_ref< bool(StringRef, ValueInfo)> isExported, std::map< ValueInfo, std::vector< VTableSlotSummary > > &LocalWPDTargetsMap)
Call after cross-module importing to update the recorded single impl devirt target names for any loca...
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.
LLVM_ABI void runWholeProgramDevirtOnIndex(ModuleSummaryIndex &Summary, std::set< GlobalValue::GUID > &ExportedGUIDs, std::map< ValueInfo, std::vector< VTableSlotSummary > > &LocalWPDTargetsMap)
Perform index-based whole program devirtualization on the Summary index.
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.
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
cl::opt< std::optional< uint64_t >, false, remarks::HotnessThresholdParser > RemarksHotnessThreshold("lto-pass-remarks-hotness-threshold", cl::desc("Minimum profile count required for an " "optimization remark to be output." " Use 'auto' to apply the threshold from profile summary."), cl::value_desc("uint or 'auto'"), cl::init(0), cl::Hidden)
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.
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.
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 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.
A simple container for information about the supported runtime calls.
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl)
Get the libcall routine name for the specified libcall implementation.
ArrayRef< RTLIB::LibcallImpl > getLibcallImpls() const
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
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.