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);
666 return Mods[0].getModuleIdentifier();
670 assert(Mods.size() == 1 &&
"Expect only one bitcode module");
676LTO::RegularLTOState::RegularLTOState(
unsigned ParallelCodeGenParallelismLevel,
678 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
679 Ctx(Conf), CombinedModule(
std::make_unique<
Module>(
"ld-temp.o", Ctx)),
680 Mover(
std::make_unique<
IRMover>(*CombinedModule)) {}
682LTO::ThinLTOState::ThinLTOState(
ThinBackend BackendParam)
683 : Backend(
std::
move(BackendParam)), CombinedIndex(
false) {
684 if (!Backend.isValid())
690 unsigned ParallelCodeGenParallelismLevel,
LTOKind LTOMode)
692 RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),
698 Alloc = std::make_unique<BumpPtrAllocator>();
699 GlobalResolutionSymbolSaver = std::make_unique<llvm::StringSaver>(*Alloc);
708 LinkerRemarkFunction =
nullptr;
716 unsigned Partition,
bool InSummary,
719 auto *ResI = Res.
begin();
720 auto *ResE = Res.
end();
731 if (GlobalResolutionSymbolSaver && !GlobalResolutions->contains(SymbolName))
732 SymbolName = GlobalResolutionSymbolSaver->save(SymbolName);
734 auto &GlobalRes = (*GlobalResolutions)[SymbolName];
735 GlobalRes.UnnamedAddr &= Sym.isUnnamedAddr();
737 assert(!GlobalRes.Prevailing &&
738 "Multiple prevailing defs are not allowed");
739 GlobalRes.Prevailing =
true;
740 GlobalRes.IRName = std::string(Sym.getIRName());
741 }
else if (!GlobalRes.Prevailing && GlobalRes.IRName.empty()) {
748 GlobalRes.IRName = std::string(Sym.getIRName());
763 if (GlobalRes.IRName != Sym.getIRName()) {
764 GlobalRes.Partition = GlobalResolution::External;
765 GlobalRes.VisibleOutsideSummary =
true;
768 bool IsLibcall = Sym.isLibcall(TLI, Libcalls);
776 (GlobalRes.Partition != GlobalResolution::Unknown &&
777 GlobalRes.Partition != Partition)) {
778 GlobalRes.Partition = GlobalResolution::External;
781 GlobalRes.Partition = Partition;
785 GlobalRes.VisibleOutsideSummary |=
792void LTO::releaseGlobalResolutionsMemory() {
794 GlobalResolutions.reset();
796 GlobalResolutionSymbolSaver.reset();
804 auto ResI = Res.
begin();
809 OS <<
"-r=" << Path <<
',' << Sym.getName() <<
',';
827 assert(!CalledGetMaxTasks);
833 InputFile *
Input = (*InputOrErr).get();
835 if (Conf.ResolutionFile)
838 if (RegularLTO.CombinedModule->getTargetTriple().empty()) {
840 RegularLTO.CombinedModule->setTargetTriple(InputTriple);
846 for (
unsigned I = 0;
I !=
Input->Mods.size(); ++
I) {
847 if (
auto Err = addModule(*
Input, InputRes,
I, Res).moveInto(Res))
857 "bitcode libfuncs were set twice; maybe accidentally clobbered?");
858 this->BitcodeLibFuncs.append(BitcodeLibFuncs.begin(), BitcodeLibFuncs.end());
869 if (EnableSplitLTOUnit) {
873 if (*EnableSplitLTOUnit != LTOInfo->EnableSplitLTOUnit)
876 EnableSplitLTOUnit = LTOInfo->EnableSplitLTOUnit;
881 !LTOInfo->UnifiedLTO)
883 "unified LTO compilation must use "
884 "compatible bitcode modules (use -funified-lto)",
894 Input.IsThinLTO |= IsThinLTO;
896 auto ModSyms =
Input.module_symbols(ModI);
897 addModuleToGlobalRes(ModSyms, Res,
898 IsThinLTO ? ThinLTO.ModuleMap.
size() + 1 : 0,
899 LTOInfo->HasSummary,
Triple(
Input.getTargetTriple()));
902 return addThinLTO(BM, ModSyms, Res);
904 RegularLTO.EmptyCombinedModule =
false;
905 auto ModOrErr = addRegularLTO(
Input, InputRes, BM, ModSyms, Res);
907 return ModOrErr.takeError();
908 Res = ModOrErr->second;
910 if (!LTOInfo->HasSummary) {
911 if (
Error Err = linkRegularLTO(std::move(ModOrErr->first),
921 RegularLTO.ModsWithSummaries.push_back(std::move(ModOrErr->first));
937 std::set<const Comdat *> &NonPrevailingComdats) {
942 if (!NonPrevailingComdats.count(
C))
952 GO->setComdat(
nullptr);
959 std::pair<LTO::RegularLTOState::AddedModule, ArrayRef<SymbolResolution>>>
963 llvm::TimeTraceScope timeScope(
"LTO add regular LTO");
965 Expected<std::unique_ptr<Module>> MOrErr =
971 Mod.M = std::move(*MOrErr);
973 if (
Error Err =
M.materializeMetadata())
974 return std::move(Err);
980 if (NamedMDNode *CfiFunctionsMD =
M.getNamedMetadata(
"cfi.functions"))
981 M.eraseNamedMetadata(CfiFunctionsMD);
982 }
else if (NamedMDNode *AliasesMD =
M.getNamedMetadata(
"aliases")) {
985 DenseSet<StringRef> Prevailing;
987 if (
R.Prevailing && !
I.getIRName().empty())
988 Prevailing.
insert(
I.getIRName());
989 std::vector<MDNode *> AliasGroups;
990 for (MDNode *AliasGroup : AliasesMD->operands()) {
991 std::vector<Metadata *> Aliases;
992 for (
Metadata *Alias : AliasGroup->operands()) {
995 Aliases.push_back(Alias);
997 if (Aliases.size() > 1)
998 AliasGroups.push_back(
MDTuple::get(RegularLTO.Ctx, Aliases));
1000 AliasesMD->clearOperands();
1001 for (MDNode *
G : AliasGroups)
1002 AliasesMD->addOperand(
G);
1007 ModuleSymbolTable SymTab;
1010 for (GlobalVariable &GV :
M.globals())
1011 if (GV.hasAppendingLinkage())
1012 Mod.Keep.push_back(&GV);
1014 DenseSet<GlobalObject *> AliasedGlobals;
1015 for (
auto &GA :
M.aliases())
1016 if (GlobalObject *GO = GA.getAliaseeObject())
1017 AliasedGlobals.
insert(GO);
1026 auto MsymI = SymTab.
symbols().begin(), MsymE = SymTab.
symbols().end();
1028 while (MsymI != MsymE) {
1038 std::set<const Comdat *> NonPrevailingComdats;
1039 SmallSet<StringRef, 2> NonPrevailingAsmSymbols;
1040 for (
const InputFile::Symbol &Sym : Syms) {
1050 if (Sym.isUndefined())
1052 Mod.Keep.push_back(GV);
1056 if (
R.LinkerRedefined)
1064 (GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||
1065 GV->hasAvailableExternallyLinkage()) &&
1072 Mod.Keep.push_back(GV);
1074 if (GV->hasComdat())
1075 NonPrevailingComdats.insert(GV->getComdat());
1080 if (
R.FinalDefinitionInLinkageUnit) {
1081 GV->setDSOLocal(
true);
1082 if (GV->hasDLLImportStorageClass())
1084 DefaultStorageClass);
1086 }
else if (
auto *AS =
1090 NonPrevailingAsmSymbols.
insert(AS->first);
1098 if (Sym.isCommon()) {
1101 auto &CommonRes = RegularLTO.Commons[std::string(Sym.getIRName())];
1102 CommonRes.Size = std::max(CommonRes.Size, Sym.getCommonSize());
1103 if (uint32_t SymAlignValue = Sym.getCommonAlignment()) {
1104 CommonRes.Alignment =
1105 std::max(
Align(SymAlignValue), CommonRes.Alignment);
1107 CommonRes.Prevailing |=
R.Prevailing;
1111 if (!
M.getComdatSymbolTable().empty())
1112 for (GlobalValue &GV :
M.global_values())
1117 if (!
M.getModuleInlineAsm().empty()) {
1118 std::string NewIA =
".lto_discard";
1119 if (!NonPrevailingAsmSymbols.
empty()) {
1122 M, [&](StringRef Name, StringRef Alias) {
1123 if (!NonPrevailingAsmSymbols.
count(Alias))
1124 NonPrevailingAsmSymbols.
erase(Name);
1126 NewIA +=
" " +
llvm::join(NonPrevailingAsmSymbols,
", ");
1129 M.setModuleInlineAsm(NewIA +
M.getModuleInlineAsm());
1133 return std::make_pair(std::move(
Mod), Res);
1136Error LTO::linkRegularLTO(RegularLTOState::AddedModule
Mod,
1137 bool LivenessFromIndex) {
1138 llvm::TimeTraceScope timeScope(
"LTO link regular LTO");
1139 std::vector<GlobalValue *>
Keep;
1140 for (GlobalValue *GV :
Mod.Keep) {
1141 if (LivenessFromIndex) {
1143 if (!ThinLTO.CombinedIndex.isGUIDLive(GUID)) {
1145 if (DiagnosticOutputFile) {
1146 if (
Error Err =
F->materialize())
1148 auto R = OptimizationRemark(
DEBUG_TYPE,
"deadfunction",
F);
1149 R <<
ore::NV(
"Function",
F) <<
" not added to the combined module ";
1164 GlobalValue *CombinedGV =
1165 RegularLTO.CombinedModule->getNamedValue(GV->
getName());
1172 return RegularLTO.Mover->move(std::move(
Mod.M),
Keep,
nullptr,
1177Expected<ArrayRef<SymbolResolution>>
1180 llvm::TimeTraceScope timeScope(
"LTO add thin LTO");
1183 DenseSet<StringRef> Prevailing;
1184 for (
const InputFile::Symbol &Sym : Syms) {
1187 if (!Sym.getIRName().empty() &&
R.Prevailing)
1188 Prevailing.
insert(Sym.getIRName());
1192 StringMap<GlobalValue::GUID> IRSpecifiedGUIDs;
1194 ThinLTO.CombinedIndex, BMID,
1195 [&](StringRef Name) { return (Prevailing.count(Name) > 0); },
1197 auto IT = IRSpecifiedGUIDs.insert({VI.name(), VI.getGUID()});
1200 if (
auto GRIt = GlobalResolutions->find(
VI.name());
1201 GRIt != GlobalResolutions->end() &&
1202 Prevailing.
count(
VI.name())) {
1203 GRIt->second.setGUID(VI.getGUID());
1212 auto GUIDIter = IRSpecifiedGUIDs.
find(Sym.getIRName());
1217 GUIDIter == IRSpecifiedGUIDs.
end()
1222 if (!Sym.getIRName().empty() &&
1223 (
R.Prevailing ||
R.FinalDefinitionInLinkageUnit)) {
1225 ThinLTO.setPrevailingModuleForGUID(GUID, BMID);
1230 if (
R.LinkerRedefined)
1231 if (
auto *S = ThinLTO.CombinedIndex.findSummaryInModule(GUID, BMID))
1237 if (
R.FinalDefinitionInLinkageUnit) {
1238 if (
auto *S = ThinLTO.CombinedIndex.findSummaryInModule(GUID, BMID)) {
1239 S->setDSOLocal(
true);
1245 if (!ThinLTO.ModuleMap.insert({BMID, BM}).second)
1247 "Expected at most one ThinLTO module per bitcode file",
1250 if (!Conf.ThinLTOModulesToCompile.empty()) {
1251 if (!ThinLTO.ModulesToCompile)
1252 ThinLTO.ModulesToCompile = ModuleMapType();
1255 for (
const std::string &Name : Conf.ThinLTOModulesToCompile) {
1256 if (BMID.contains(Name)) {
1257 ThinLTO.ModulesToCompile->insert({BMID, BM});
1258 LLVM_DEBUG(
dbgs() <<
"[ThinLTO] Selecting " << BMID <<
" to compile\n");
1268 CalledGetMaxTasks =
true;
1269 auto ModuleCount = ThinLTO.ModulesToCompile ? ThinLTO.ModulesToCompile->size()
1270 : ThinLTO.ModuleMap.size();
1271 return RegularLTO.ParallelCodeGenParallelismLevel + ModuleCount;
1276Error LTO::checkPartiallySplit() {
1280 const Module *Combined = RegularLTO.CombinedModule.get();
1286 Combined, Intrinsic::type_checked_load_relative);
1290 if ((TypeTestFunc && !TypeTestFunc->
use_empty()) ||
1291 (TypeCheckedLoadFunc && !TypeCheckedLoadFunc->
use_empty()) ||
1292 (TypeCheckedLoadRelativeFunc &&
1293 !TypeCheckedLoadRelativeFunc->
use_empty()))
1295 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1300 for (
auto &
P : ThinLTO.CombinedIndex) {
1301 for (
auto &S :
P.second.getSummaryList()) {
1305 if (!FS->type_test_assume_vcalls().empty() ||
1306 !FS->type_checked_load_vcalls().empty() ||
1307 !FS->type_test_assume_const_vcalls().empty() ||
1308 !FS->type_checked_load_const_vcalls().empty() ||
1309 !FS->type_tests().empty())
1311 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1327 for (
auto &Res : *GlobalResolutions) {
1330 if (Res.second.IRName.
empty())
1335 if (Res.second.VisibleOutsideSummary && Res.second.Prevailing)
1336 GUIDPreservedSymbols.
insert(GUID);
1338 if (Res.second.ExportDynamic)
1339 DynamicExportSymbols.insert(GUID);
1341 GUIDPrevailingResolutions[GUID] =
1346 auto It = GUIDPrevailingResolutions.
find(
G);
1347 if (It == GUIDPrevailingResolutions.
end())
1352 isPrevailing, Conf.OptLevel > 0);
1356 if (!StatsFileOrErr)
1357 return StatsFileOrErr.takeError();
1358 std::unique_ptr<ToolOutputFile> StatsFile = std::move(StatsFileOrErr.get());
1360 if (
Error Err = setupOptimizationRemarks())
1369 ThinLTO.CombinedIndex.setWithSupportsHotColdNew();
1371 Error Result = runRegularLTO(AddStream);
1375 Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols);
1391 for (
auto &M : RegularLTO.ModsWithSummaries)
1392 if (
Error Err = linkRegularLTO(std::move(M),
true))
1400 if (
Error Err = checkPartiallySplit())
1405 const DataLayout &
DL = RegularLTO.CombinedModule->getDataLayout();
1406 for (
auto &
I : RegularLTO.Commons) {
1407 if (!
I.second.Prevailing)
1410 GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(
I.first);
1419 auto *GV =
new GlobalVariable(*RegularLTO.CombinedModule, Ty,
false,
1422 GV->setAlignment(
I.second.Alignment);
1432 bool WholeProgramVisibilityEnabledInLTO =
1433 Conf.HasWholeProgramVisibility &&
1436 (!Conf.ValidateAllVtablesHaveTypeInfos || Conf.AllVtablesHaveTypeInfos);
1440 auto IsVisibleToRegularObj = [&](StringRef
name) {
1441 auto It = GlobalResolutions->find(
name);
1442 return (It == GlobalResolutions->end() ||
1443 It->second.VisibleOutsideSummary || !It->second.Prevailing);
1449 *RegularLTO.CombinedModule, WholeProgramVisibilityEnabledInLTO,
1450 DynamicExportSymbols, Conf.ValidateAllVtablesHaveTypeInfos,
1451 IsVisibleToRegularObj);
1453 WholeProgramVisibilityEnabledInLTO);
1455 if (Conf.PreOptModuleHook &&
1456 !Conf.PreOptModuleHook(0, *RegularLTO.CombinedModule))
1459 if (!Conf.CodeGenOnly) {
1460 for (
const auto &R : *GlobalResolutions) {
1462 RegularLTO.CombinedModule->getNamedValue(
R.second.IRName);
1463 if (!
R.second.isPrevailingIRSymbol())
1465 if (
R.second.Partition != 0 &&
1466 R.second.Partition != GlobalResolution::External)
1494 if (Conf.PostInternalizeModuleHook &&
1495 !Conf.PostInternalizeModuleHook(0, *RegularLTO.CombinedModule))
1499 if (!RegularLTO.EmptyCombinedModule || Conf.AlwaysEmitRegularLTOObj) {
1501 Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,
1502 *RegularLTO.CombinedModule, ThinLTO.CombinedIndex, BitcodeLibFuncs))
1519 return LibcallSymbols;
1524 auto TLII = std::make_unique<TargetLibraryInfoImpl>(TT);
1527 LibFuncSymbols.
reserve(LibFunc::NumLibFuncs);
1528 for (
unsigned I = LibFunc::Begin_LibFunc;
I != LibFunc::End_LibFunc; ++
I) {
1529 LibFunc
F =
static_cast<LibFunc
>(
I);
1533 return LibFuncSymbols;
1538 const std::string &NewModulePath)
const {
1539 return emitFiles(ImportList, ModulePath, NewModulePath,
1540 NewModulePath +
".thinlto.bc",
1546 const std::string &NewModulePath,
StringRef SummaryPath,
1547 std::optional<std::reference_wrapper<ImportsFilesContainer>> ImportsFiles)
1554 ImportList, ModuleToSummariesForIndex,
1555 DeclarationSummaries);
1562 &DeclarationSummaries);
1566 ModulePath, NewModulePath +
".imports", ModuleToSummariesForIndex);
1567 if (ImportsFilesError)
1568 return ImportsFilesError;
1574 ModulePath, ModuleToSummariesForIndex,
1575 [&](
StringRef M) { ImportsFiles->get().push_back(M.str()); });
1587 bool ShouldEmitIndexFiles;
1596 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
1597 ShouldEmitIndexFiles(ShouldEmitIndexFiles) {
1607class InProcessThinBackend :
public CGThinBackend {
1616 InProcessThinBackend(
1621 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
1623 : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries, OnWrite,
1624 ShouldEmitIndexFiles, ShouldEmitImportsFiles,
1625 ThinLTOParallelism),
1627 BitcodeLibFuncs(BitcodeLibFuncs) {}
1629 virtual Error runThinLTOBackendThread(
1630 AddStreamFn AddStream, FileCache Cache,
unsigned Task, BitcodeModule BM,
1631 ModuleSummaryIndex &CombinedIndex,
1632 const FunctionImporter::ImportMapTy &ImportList,
1634 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1636 MapVector<StringRef, BitcodeModule> &ModuleMap) {
1638 llvm::TimeTraceScope timeScope(
"Run ThinLTO backend thread (in-process)",
1640 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1641 LTOLLVMContext BackendContext(Conf);
1642 Expected<std::unique_ptr<Module>> MOrErr = BM.
parseModule(BackendContext);
1646 return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,
1647 ImportList, DefinedGlobals, &ModuleMap,
1650 if (ShouldEmitIndexFiles) {
1651 if (
auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1657 [](uint32_t V) { return V == 0; }))
1660 return RunThinBackend(AddStream);
1664 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1665 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1666 Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task,
Key, ModuleID);
1669 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1671 return RunThinBackend(CacheAddStream);
1677 unsigned Task, BitcodeModule BM,
1678 const FunctionImporter::ImportMapTy &ImportList,
1680 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1681 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
1683 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
1685 ModuleToDefinedGVSummaries.
find(ModulePath)->second;
1686 BackendThreadPool.async(
1687 [=](BitcodeModule BM, ModuleSummaryIndex &CombinedIndex,
1688 const FunctionImporter::ImportMapTy &ImportList,
1690 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
1693 MapVector<StringRef, BitcodeModule> &ModuleMap) {
1697 Error E = runThinLTOBackendThread(
1698 AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList,
1699 ResolvedODR, DefinedGlobals, ModuleMap);
1701 std::unique_lock<std::mutex>
L(ErrMu);
1710 BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList),
1711 std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap));
1714 OnWrite(std::string(ModulePath));
1724class FirstRoundThinBackend :
public InProcessThinBackend {
1729 FirstRoundThinBackend(
1730 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
1731 ThreadPoolStrategy ThinLTOParallelism,
1732 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
1736 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
1737 ModuleToDefinedGVSummaries, std::
move(CGAddStream),
1738 std::
move(CGCache), nullptr,
1740 false, BitcodeLibFuncs),
1741 IRAddStream(std::
move(IRAddStream)), IRCache(std::
move(IRCache)) {}
1743 Error runThinLTOBackendThread(
1744 AddStreamFn CGAddStream, FileCache CGCache,
unsigned Task,
1745 BitcodeModule BM, ModuleSummaryIndex &CombinedIndex,
1746 const FunctionImporter::ImportMapTy &ImportList,
1748 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1750 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
1752 llvm::TimeTraceScope timeScope(
"Run ThinLTO backend thread (first round)",
1754 auto RunThinBackend = [&](
AddStreamFn CGAddStream,
1756 LTOLLVMContext BackendContext(Conf);
1757 Expected<std::unique_ptr<Module>> MOrErr = BM.
parseModule(BackendContext);
1761 return thinBackend(Conf, Task, CGAddStream, **MOrErr, CombinedIndex,
1762 ImportList, DefinedGlobals, &ModuleMap,
1768 if (ShouldEmitIndexFiles) {
1769 if (
auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1774 "Both caches for CG and IR should have matching availability");
1777 [](uint32_t V) { return V == 0; }))
1780 return RunThinBackend(CGAddStream, IRAddStream);
1784 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1785 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1786 Expected<AddStreamFn> CacheCGAddStreamOrErr =
1787 CGCache(Task, CGKey, ModuleID);
1790 AddStreamFn &CacheCGAddStream = *CacheCGAddStreamOrErr;
1794 Expected<AddStreamFn> CacheIRAddStreamOrErr =
1795 IRCache(Task, IRKey, ModuleID);
1798 AddStreamFn &CacheIRAddStream = *CacheIRAddStreamOrErr;
1804 if (CacheCGAddStream || CacheIRAddStream) {
1807 return RunThinBackend(CacheCGAddStream ? CacheCGAddStream : CGAddStream,
1808 CacheIRAddStream ? CacheIRAddStream : IRAddStream);
1820class SecondRoundThinBackend :
public InProcessThinBackend {
1821 std::unique_ptr<SmallVector<StringRef>> IRFiles;
1825 SecondRoundThinBackend(
1826 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
1827 ThreadPoolStrategy ThinLTOParallelism,
1828 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
1833 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
1834 ModuleToDefinedGVSummaries, std::
move(AddStream),
1838 false, BitcodeLibFuncs),
1839 IRFiles(std::
move(IRFiles)), CombinedCGDataHash(CombinedCGDataHash) {}
1841 Error runThinLTOBackendThread(
1842 AddStreamFn AddStream, FileCache Cache,
unsigned Task, BitcodeModule BM,
1843 ModuleSummaryIndex &CombinedIndex,
1844 const FunctionImporter::ImportMapTy &ImportList,
1846 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1848 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
1850 llvm::TimeTraceScope timeScope(
"Run ThinLTO backend thread (second round)",
1852 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1853 LTOLLVMContext BackendContext(Conf);
1854 std::unique_ptr<Module> LoadedModule =
1857 return thinBackend(Conf, Task, AddStream, *LoadedModule, CombinedIndex,
1858 ImportList, DefinedGlobals, &ModuleMap,
1859 true, BitcodeLibFuncs);
1863 [](uint32_t V) { return V == 0; }))
1866 return RunThinBackend(AddStream);
1871 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1872 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1874 std::to_string(CombinedCGDataHash));
1875 Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task,
Key, ModuleID);
1878 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1880 if (CacheAddStream) {
1883 return RunThinBackend(CacheAddStream);
1893 bool ShouldEmitIndexFiles,
1894 bool ShouldEmitImportsFiles) {
1900 return std::make_unique<InProcessThinBackend>(
1901 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1902 AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
1903 ShouldEmitImportsFiles, BitcodeLibFuncs);
1929 return std::string(Path);
1933 if (!ParentPath.
empty()) {
1936 llvm::errs() <<
"warning: could not create directory '" << ParentPath
1937 <<
"': " << EC.message() <<
'\n';
1939 return std::string(NewPath);
1944 std::string OldPrefix, NewPrefix, NativeObjectPrefix;
1948 WriteIndexesThinBackend(
1952 std::string OldPrefix, std::string NewPrefix,
1953 std::string NativeObjectPrefix,
bool ShouldEmitImportsFiles,
1956 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
1957 OldPrefix(OldPrefix), NewPrefix(NewPrefix),
1958 NativeObjectPrefix(NativeObjectPrefix),
1959 LinkedObjectsFile(LinkedObjectsFile) {}
1965 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1973 if (LinkedObjectsFile) {
1974 std::string ObjectPrefix =
1975 NativeObjectPrefix.empty() ? NewPrefix : NativeObjectPrefix;
1976 std::string LinkedObjectsFilePath =
1978 *LinkedObjectsFile << LinkedObjectsFilePath <<
'\n';
1981 BackendThreadPool.async(
1982 [
this](
const StringRef ModulePath,
1983 const FunctionImporter::ImportMapTy &ImportList,
1984 const std::string &OldPrefix,
const std::string &NewPrefix) {
1985 std::string NewModulePath =
1987 auto E = emitFiles(ImportList, ModulePath, NewModulePath);
1989 std::unique_lock<std::mutex>
L(ErrMu);
1997 ModulePath, ImportList, OldPrefix, NewPrefix);
2000 OnWrite(std::string(ModulePath));
2004 bool isSensitiveToInputOrder()
override {
2014 std::string NewPrefix, std::string NativeObjectPrefix,
2022 return std::make_unique<WriteIndexesThinBackend>(
2023 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2024 OldPrefix, NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,
2025 LinkedObjectsFile, OnWrite);
2040 if (ThinLTO.ModuleMap.
empty())
2043 if (ThinLTO.ModulesToCompile && ThinLTO.ModulesToCompile->empty()) {
2044 llvm::errs() <<
"warning: [ThinLTO] No module compiled\n";
2048 if (Conf.CombinedIndexHook &&
2049 !Conf.CombinedIndexHook(ThinLTO.CombinedIndex, GUIDPreservedSymbols))
2054 DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries(
2055 ThinLTO.ModuleMap.size());
2056 ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule(
2057 ModuleToDefinedGVSummaries);
2065 for (
auto &
Mod : ThinLTO.ModuleMap)
2066 if (!ModuleToDefinedGVSummaries.
count(
Mod.first))
2069 FunctionImporter::ImportListsTy ImportLists(ThinLTO.ModuleMap.size());
2070 DenseMap<StringRef, FunctionImporter::ExportSetTy> ExportLists(
2071 ThinLTO.ModuleMap.size());
2072 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
2075 ThinLTO.CombinedIndex.dumpSCCs(
outs());
2077 std::set<GlobalValue::GUID> ExportedGUIDs;
2079 bool WholeProgramVisibilityEnabledInLTO =
2080 Conf.HasWholeProgramVisibility &&
2083 (!Conf.ValidateAllVtablesHaveTypeInfos || Conf.AllVtablesHaveTypeInfos);
2085 ThinLTO.CombinedIndex.setWithWholeProgramVisibility();
2090 DenseSet<GlobalValue::GUID> VisibleToRegularObjSymbols;
2091 if (WholeProgramVisibilityEnabledInLTO &&
2092 Conf.ValidateAllVtablesHaveTypeInfos) {
2095 auto IsVisibleToRegularObj = [&](StringRef
name) {
2096 auto It = GlobalResolutions->find(
name);
2097 return (It == GlobalResolutions->end() ||
2098 It->second.VisibleOutsideSummary || !It->second.Prevailing);
2102 VisibleToRegularObjSymbols,
2103 IsVisibleToRegularObj);
2109 ThinLTO.CombinedIndex, WholeProgramVisibilityEnabledInLTO,
2110 DynamicExportSymbols, VisibleToRegularObjSymbols);
2115 std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;
2116 DenseSet<StringRef> ExternallyVisibleSymbolNames;
2122 DenseSet<StringRef> *ExternallyVisibleSymbolNamesPtr =
2124 ? &ExternallyVisibleSymbolNames
2128 ExternallyVisibleSymbolNamesPtr);
2131 return ThinLTO.isPrevailingModuleForGUID(GUID, S->modulePath());
2134 MemProfContextDisambiguation ContextDisambiguation;
2135 ContextDisambiguation.
run(
2136 ThinLTO.CombinedIndex, isPrevailing, RegularLTO.Ctx,
2137 [&](StringRef
PassName, StringRef RemarkName,
const Twine &Msg) {
2138 auto R = OptimizationRemark(PassName.data(), RemarkName,
2139 LinkerRemarkFunction);
2149 for (
auto &Res : *GlobalResolutions) {
2152 if (Res.second.Partition != GlobalResolution::External ||
2153 !Res.second.isPrevailingIRSymbol())
2155 auto GUID = Res.second.getGUID();
2157 if (ThinLTO.CombinedIndex.isGUIDLive(GUID))
2158 ExportedGUIDs.insert(GUID);
2165 releaseGlobalResolutionsMemory();
2167 if (Conf.OptLevel > 0)
2169 isPrevailing, ImportLists, ExportLists);
2173 auto &Defs = ThinLTO.CombinedIndex.cfiFunctionDefs();
2174 ExportedGUIDs.insert(Defs.guid_begin(), Defs.guid_end());
2175 auto &Decls = ThinLTO.CombinedIndex.cfiFunctionDecls();
2176 ExportedGUIDs.insert(Decls.guid_begin(), Decls.guid_end());
2178 auto isExported = [&](StringRef ModuleIdentifier, ValueInfo
VI) {
2179 const auto &ExportList = ExportLists.
find(ModuleIdentifier);
2180 return (ExportList != ExportLists.end() && ExportList->second.
count(VI)) ||
2181 ExportedGUIDs.count(
VI.getGUID());
2187 LocalWPDTargetsMap, ExternallyVisibleSymbolNamesPtr);
2189 if (ExternallyVisibleSymbolNamesPtr) {
2192 for (
auto &
I : ThinLTO.CombinedIndex) {
2193 ValueInfo
VI = ThinLTO.CombinedIndex.getValueInfo(
I);
2194 for (
const auto &Summary :
VI.getSummaryList()) {
2195 const GlobalValueSummary *
Base =
Summary->getBaseObject();
2199 ExternallyVisibleSymbolNamesPtr->
insert(
VI.name());
2207 ExternallyVisibleSymbolNamesPtr);
2209 auto recordNewLinkage = [&](StringRef ModuleIdentifier,
2212 ResolvedODR[ModuleIdentifier][
GUID] = NewLinkage;
2215 recordNewLinkage, GUIDPreservedSymbols);
2224 TimeTraceScopeExit.release();
2227 ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;
2229 auto RunBackends = [&](ThinBackendProc *BackendProcess) ->
Error {
2230 auto ProcessOneModule = [&](
int I) ->
Error {
2234 return BackendProcess->start(
2235 RegularLTO.ParallelCodeGenParallelismLevel +
I,
Mod.second,
2236 ImportLists[
Mod.first], ExportLists[
Mod.first],
2237 ResolvedODR[
Mod.first], ThinLTO.ModuleMap);
2240 BackendProcess->setup(ModuleMap.
size(),
2241 RegularLTO.ParallelCodeGenParallelismLevel,
2242 RegularLTO.CombinedModule->getTargetTriple());
2244 if (BackendProcess->getThreadCount() == 1 ||
2245 BackendProcess->isSensitiveToInputOrder()) {
2251 for (
int I = 0,
E = ModuleMap.
size();
I !=
E; ++
I)
2252 if (
Error E = ProcessOneModule(
I))
2259 std::vector<BitcodeModule *> ModulesVec;
2260 ModulesVec.reserve(ModuleMap.
size());
2261 for (
auto &
Mod : ModuleMap)
2262 ModulesVec.push_back(&
Mod.second);
2264 if (
Error E = ProcessOneModule(
I))
2267 return BackendProcess->wait();
2271 std::unique_ptr<ThinBackendProc> BackendProc =
2272 ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
2273 AddStream, Cache, BitcodeLibFuncs);
2274 return RunBackends(BackendProc.get());
2282 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Initializing ThinLTO two-codegen rounds\n");
2285 auto Parallelism = ThinLTO.Backend.getParallelism();
2288 cgdata::StreamCacheData CG(MaxTasks, Cache,
"CG"),
IR(MaxTasks, Cache,
"IR");
2293 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Running the first round of codegen\n");
2294 auto FirstRoundLTO = std::make_unique<FirstRoundThinBackend>(
2295 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2296 CG.AddStream, CG.Cache, BitcodeLibFuncs,
IR.AddStream,
IR.Cache);
2297 if (
Error E = RunBackends(FirstRoundLTO.get()))
2302 if (
Error E = CombinedHashOrErr.takeError())
2304 auto CombinedHash = *CombinedHashOrErr;
2305 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] CGData hash: " << CombinedHash <<
"\n");
2309 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Running the second round of codegen\n");
2310 auto SecondRoundLTO = std::make_unique<SecondRoundThinBackend>(
2311 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2312 AddStream, Cache, BitcodeLibFuncs,
IR.getResult(), CombinedHash);
2313 return RunBackends(SecondRoundLTO.get());
2331 if (
Error E = ResultOrErr.takeError())
2332 return std::move(E);
2335 (*ResultOrErr)->keep();
2343 if (StatsFilename.
empty())
2354 return std::move(StatsFile);
2362 std::vector<int> ModulesOrdering(Seq.begin(), Seq.end());
2363 llvm::sort(ModulesOrdering, [&](
int LeftIndex,
int RightIndex) {
2364 auto LSize = R[LeftIndex]->getBuffer().size();
2365 auto RSize = R[RightIndex]->getBuffer().size();
2366 return LSize > RSize;
2368 return ModulesOrdering;
2378class OutOfProcessThinBackend :
public CGThinBackend {
2384 SString LinkerOutputFile;
2386 SString DistributorPath;
2389 SString RemoteCompiler;
2398 std::atomic<size_t> CachedJobs{0};
2403 StringRef NativeObjectPath;
2404 StringRef SummaryIndexPath;
2406 std::string CacheKey;
2408 bool Cached =
false;
2417 unsigned ThinLTOTaskOffset;
2420 llvm::Triple Triple;
2429 OutOfProcessThinBackend(
2430 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
2431 ThreadPoolStrategy ThinLTOParallelism,
2432 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
2434 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
2435 StringRef LinkerOutputFile, StringRef Distributor,
2440 : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries, OnWrite,
2441 ShouldEmitIndexFiles, ShouldEmitImportsFiles,
2442 ThinLTOParallelism),
2443 LinkerOutputFile(LinkerOutputFile), DistributorPath(Distributor),
2444 DistributorArgs(DistributorArgs), RemoteCompiler(RemoteCompiler),
2445 RemoteCompilerPrependArgs(RemoteCompilerPrependArgs),
2446 RemoteCompilerArgs(RemoteCompilerArgs), SaveTemps(SaveTemps),
2447 Cache(std::
move(CacheFn)), AddBuffer(std::
move(AddBuffer)) {}
2449 void setup(
unsigned ThinLTONumTasks,
unsigned ThinLTOTaskOffset,
2450 llvm::Triple Triple)
override {
2452 Jobs.
resize((
size_t)ThinLTONumTasks);
2453 this->ThinLTOTaskOffset = ThinLTOTaskOffset;
2454 this->Triple = std::move(Triple);
2455 this->Conf.
Dtlto = 1;
2458 virtual Error runThinLTOBackendThread(
2459 Job &J,
const FunctionImporter::ImportMapTy &ImportList,
2461 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
2464 TimeTraceScope TimeScope(
"Emit individual index for DTLTO",
2465 J.SummaryIndexPath);
2466 if (
auto E = emitFiles(ImportList, J.ModuleID, J.ModuleID.str(),
2467 J.SummaryIndexPath, J.ImportsFiles))
2473 [](uint32_t V) { return V == 0; }))
2478 TimeTraceScope TimeScope(
"Check cache for DTLTO", J.SummaryIndexPath);
2480 ModuleToDefinedGVSummaries.
find(J.ModuleID)->second;
2484 ExportList, ResolvedODR, DefinedGlobals,
2485 CfiFunctionDefs, CfiFunctionDecls);
2488 auto CacheAddStreamExp = Cache(J.Task, J.CacheKey, J.ModuleID);
2489 if (
Error Err = CacheAddStreamExp.takeError())
2494 if (!CacheAddStream) {
2496 CachedJobs.fetch_add(1);
2501 J.CacheAddStream = std::move(CacheAddStream);
2507 unsigned Task, BitcodeModule BM,
2508 const FunctionImporter::ImportMapTy &ImportList,
2510 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
2511 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
2517 itostr(Task) +
"." + UID +
".native.o");
2519 Job &J = Jobs[Task - ThinLTOTaskOffset];
2522 Saver.
save(ObjFilePath.str()),
2523 Saver.
save(ObjFilePath.str() +
".thinlto.bc"),
2532 if (!ShouldEmitIndexFiles)
2536 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
2540 BackendThreadPool.async(
2541 [=](Job &J,
const FunctionImporter::ImportMapTy &ImportList,
2543 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
2548 "Emit individual index and check cache for DTLTO");
2550 runThinLTOBackendThread(J, ImportList, ExportList, ResolvedODR);
2552 std::unique_lock<std::mutex>
L(ErrMu);
2561 std::ref(J), std::ref(ImportList), std::ref(ExportList),
2562 std::ref(ResolvedODR));
2576 void buildCommonRemoteCompilerOptions() {
2577 const lto::Config &
C = Conf;
2578 auto &
Ops = CodegenOptions;
2582 if (
C.Options.EmitAddrsig)
2583 Ops.push_back(
"-faddrsig");
2584 if (
C.Options.FunctionSections)
2585 Ops.push_back(
"-ffunction-sections");
2586 if (
C.Options.DataSections)
2587 Ops.push_back(
"-fdata-sections");
2592 Ops.push_back(
"-fpic");
2596 if (!
C.PGOWarnMismatch) {
2597 Ops.push_back(
"-mllvm");
2598 Ops.push_back(
"-no-pgo-warn-mismatch");
2603 if (!
C.SampleProfile.empty()) {
2605 Saver.
save(
"-fprofile-sample-use=" + Twine(
C.SampleProfile)));
2606 CommonInputs.
insert(
C.SampleProfile);
2610 Ops.push_back(
"-Wno-unused-command-line-argument");
2613 if (!RemoteCompilerArgs.
empty())
2614 for (
auto &a : RemoteCompilerArgs)
2620 bool emitDistributorJson(StringRef DistributorJson) {
2623 raw_fd_ostream OS(DistributorJson, EC);
2627 json::OStream JOS(OS);
2630 JOS.attributeObject(
"common", [&]() {
2631 JOS.attribute(
"linker_output", LinkerOutputFile);
2633 JOS.attributeArray(
"args", [&]() {
2634 JOS.value(RemoteCompiler);
2637 if (!RemoteCompilerPrependArgs.
empty())
2638 for (
auto &
A : RemoteCompilerPrependArgs)
2643 JOS.value(Saver.
save(
"--target=" + Triple.
str()));
2645 for (
const auto &
A : CodegenOptions)
2649 JOS.attribute(
"inputs",
Array(CommonInputs));
2653 JOS.attributeArray(
"jobs", [&]() {
2654 for (
const auto &J : Jobs) {
2662 SmallVector<StringRef, 1> Outputs;
2665 JOS.attributeArray(
"args", [&]() {
2666 JOS.value(J.ModuleID);
2670 Saver.
save(
"-fthinlto-index=" + Twine(J.SummaryIndexPath)));
2674 JOS.value(J.NativeObjectPath);
2682 JOS.attribute(
"inputs",
Array(Inputs));
2684 JOS.attribute(
"outputs",
Array(Outputs));
2693 void removeFile(StringRef FileName) {
2695 if (EC && EC != std::make_error_code(std::errc::no_such_file_or_directory))
2696 errs() <<
"warning: could not remove the file '" << FileName
2697 <<
"': " <<
EC.message() <<
"\n";
2700 Error wait()
override {
2703 BackendThreadPool.wait();
2705 return std::move(*Err);
2708 llvm::TimeTraceScope TimeScope(
"Remove DTLTO temporary files");
2710 for (
auto &Job : Jobs) {
2711 removeFile(Job.NativeObjectPath);
2712 if (!ShouldEmitIndexFiles)
2713 removeFile(Job.SummaryIndexPath);
2717 const StringRef BCError =
"DTLTO backend compilation: ";
2719 buildCommonRemoteCompilerOptions();
2723 llvm::TimeTraceScope TimeScope(
"Emit DTLTO JSON");
2725 UID +
".dist-file.json");
2729 if (!emitDistributorJson(JsonFile))
2731 BCError +
"failed to generate distributor JSON script: " + JsonFile,
2736 removeFile(JsonFile);
2740 llvm::TimeTraceScope TimeScope(
"Execute DTLTO distributor",
2743 if (CachedJobs.load() < Jobs.size()) {
2746 Args.push_back(JsonFile);
2753 BCError +
"distributor execution failed" +
2754 (!ErrMsg.empty() ?
": " + ErrMsg + Twine(
".") : Twine(
".")),
2761 llvm::TimeTraceScope FilesScope(
"Add DTLTO files to the link");
2762 for (
auto &Job : Jobs) {
2763 if (!Job.CacheKey.empty() && Job.Cached) {
2769 auto ObjFileMbOrErr =
2772 if (std::error_code EC = ObjFileMbOrErr.getError())
2774 BCError +
"cannot open native object file: " +
2775 Job.NativeObjectPath +
": " +
EC.message(),
2781 assert(Job.CacheAddStream);
2782 MemoryBufferRef ObjFileMbRef =
2783 ObjFileMbOrErr->get()->getMemBufferRef();
2785 auto CachedFileStreamOrErr =
2786 Job.CacheAddStream(Job.Task, Job.ModuleID);
2787 if (!CachedFileStreamOrErr)
2789 CachedFileStreamOrErr.takeError(),
2791 "Cannot get a cache file stream: %s",
2792 Job.NativeObjectPath.data()));
2794 auto &CacheStream = *(CachedFileStreamOrErr->get());
2795 *(CacheStream.OS) << ObjFileMbRef.
getBuffer();
2796 if (
Error Err = CacheStream.commit())
2799 AddBuffer(Job.Task, Job.ModuleID, std::move(*ObjFileMbOrErr));
2810 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
2820 return std::make_unique<OutOfProcessThinBackend>(
2821 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries, Cache,
2822 OnWrite, ShouldEmitIndexFiles, ShouldEmitImportsFiles,
2823 LinkerOutputFile, Distributor, DistributorArgs, RemoteCompiler,
2824 RemoteCompilerPrependArgs, RemoteCompilerArgs, SaveTemps,
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
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[]
Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
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 Expected< std::unique_ptr< Module > > parseModule(LLVMContext &Context, ParserCallbacks Callbacks={})
Read the entire bitcode module and return it.
LLVM_ABI Error readSummary(ModuleSummaryIndex &CombinedIndex, StringRef ModulePath, std::function< bool(StringRef)> IsPrevailing=nullptr, std::function< void(ValueInfo)> OnValueInfo=nullptr)
Parse the specified bitcode buffer and merge its module summary index into CombinedIndex.
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
GUID getGUIDOrFallback() const
Return the GUID for this value if it has been assigned, otherwise fall back to computing it based on ...
LLVM_ABI const Comdat * getComdat() const
static bool isLinkOnceLinkage(LinkageTypes Linkage)
void setLinkage(LinkageTypes LT)
DLLStorageClassTypes
Storage classes of global values for PE targets.
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.
LLVM_ABI 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...
iterator find(StringRef Key)
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
Represent a constant reference to a string, i.e.
constexpr bool empty() const
Check if the string is empty.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
StringRef save(const char *S)
Implementation of the target library information.
Provides information about what library functions are available for the current target.
bool has(LibFunc F) const
Tests whether a library function is available.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
StringRef getName(LibFunc F) const
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)
LLVM_ABI void setBitcodeLibFuncs(ArrayRef< StringRef > BitcodeLibFuncs)
Set the list of functions implemented in bitcode that were not extracted from an archive.
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.
static LLVM_ABI SmallVector< StringRef > getLibFuncSymbols(const Triple &TT, llvm::StringSaver &Saver)
Static method that returns a list of library function symbols that can be generated by LTO but might ...
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 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, AddBufferFn AddBuffer)
This ThinBackend generates the index shards and then runs the individual backend jobs via an external...
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, ArrayRef< StringRef > BitcodeLibFuncs, AddStreamFn IRAddStream=nullptr, const std::vector< uint8_t > &CmdArgs=std::vector< uint8_t >())
Runs a ThinLTO backend.
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, ArrayRef< StringRef > BitcodeLibFuncs)
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::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.
LLVM_ABI 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...
std::function< void(unsigned Task, const Twine &ModuleName, std::unique_ptr< MemoryBuffer > MB)> AddBufferFn
This type defines the callback to add a pre-existing file (e.g.
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)
cl::opt< bool > AlwaysRenamePromotedLocals("always-rename-promoted-locals", cl::init(true), cl::Hidden, cl::desc("Always rename promoted locals."))
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.
FunctionAddr VTableAddr Count
std::map< std::string, GVSummaryMapTy, std::less<> > ModuleToSummariesForIndexTy
Map of a module name to the GUIDs and summaries we will import from that module.
LLVM_ABI cl::opt< bool > EnableLTOInternalization
Enable global value internalization in LTO.
cl::opt< bool > RemarksWithHotness("lto-pass-remarks-with-hotness", cl::desc("With PGO, include profile count in optimization remarks"), cl::Hidden)
LLVM_ABI void timeTraceProfilerEnd()
Manually end the last time section.
cl::opt< std::string > RemarksFilename("lto-pass-remarks-output", cl::desc("Output filename for pass remarks"), cl::value_desc("filename"))
cl::opt< bool > SupportsHotColdNew
Indicate we are linking with an allocator that supports hot/cold operator new interfaces.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI void thinLTOResolvePrevailingInIndex(const lto::Config &C, ModuleSummaryIndex &Index, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, function_ref< void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> recordNewLinkage, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols)
Resolve linkage for prevailing symbols in the Index.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Mod
The access may modify the value stored in memory.
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
cl::opt< bool > EnableMemProfContextDisambiguation
Enable MemProf context disambiguation for thin link.
cl::opt< bool > ForceImportAll
LLVM_ABI void gatherImportedSummariesForModule(StringRef ModulePath, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, const FunctionImporter::ImportMapTy &ImportList, ModuleToSummariesForIndexTy &ModuleToSummariesForIndex, GVSummaryPtrSet &DecSummaries)
Compute the set of summaries needed for a ThinLTO backend compilation of ModulePath.
ArrayRef(const T &OneElt) -> ArrayRef< T >
void toHex(ArrayRef< uint8_t > Input, bool LowerCase, SmallVectorImpl< char > &Output)
Convert buffer Input to its hexadecimal representation. The returned string is double the size of Inp...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void processImportsFiles(StringRef ModulePath, const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex, function_ref< void(const std::string &)> F)
Call F passing each of the files module ModulePath will import from.
cl::opt< std::optional< uint64_t >, false, remarks::HotnessThresholdParser > RemarksHotnessThreshold("lto-pass-remarks-hotness-threshold", cl::desc("Minimum profile count required for an " "optimization remark to be output." " Use 'auto' to apply the threshold from profile summary."), cl::value_desc("uint or 'auto'"), cl::init(0), cl::Hidden)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI std::string computeLTOCacheKey(const lto::Config &Conf, const ModuleSummaryIndex &Index, StringRef ModuleID, const FunctionImporter::ImportMapTy &ImportList, const FunctionImporter::ExportSetTy &ExportList, const std::map< GlobalValue::GUID, GlobalValue::LinkageTypes > &ResolvedODR, const GVSummaryMapTy &DefinedGlobals, const DenseSet< GlobalValue::GUID > &CfiFunctionDefs={}, const DenseSet< GlobalValue::GUID > &CfiFunctionDecls={})
Computes a unique hash for the Module considering the current list of export/import and other global ...
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
static cl::opt< bool > LTOKeepSymbolCopies("lto-keep-symbol-copies", cl::init(false), cl::Hidden, cl::desc("Keep copies of symbols in LTO indexing"))
LLVM_ABI bool UpgradeDebugInfo(Module &M)
Check the debug info version number, if it is out-dated, drop the debug info.
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
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.