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"));
86 cl::desc(
"Enable global value internalization in LTO"));
90 cl::desc(
"Keep copies of symbols in LTO indexing"));
107 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
118 Hasher.
update(LLVM_VERSION_STRING);
120 Hasher.
update(LLVM_REVISION);
128 auto AddUnsigned = [&](
unsigned I) {
138 auto AddUint8 = [&](
const uint8_t I) {
162 AddUnsigned(
static_cast<int>(Conf.
CGOptLevel));
163 AddUnsigned(
static_cast<int>(Conf.
CGFileType));
173 auto ModHash = Index.getModuleHash(ModuleID);
178 std::vector<uint64_t> ExportsGUID;
179 ExportsGUID.reserve(ExportList.
size());
180 for (
const auto &VI : ExportList)
181 ExportsGUID.push_back(VI.getGUID());
185 for (
auto GUID : ExportsGUID)
190 auto Comp = [&](
const std::pair<StringRef, GlobalValue::GUID> &L,
191 const std::pair<StringRef, GlobalValue::GUID> &R) {
192 return std::make_pair(Index.getModule(L.first)->second, L.second) <
193 std::make_pair(Index.getModule(R.first)->second, R.second);
199 for (
const auto &[FromModule, GUID,
Type] : SortedImportList)
200 ++ModuleToNumImports[FromModule];
202 std::optional<StringRef> LastModule;
203 for (
const auto &[FromModule, GUID,
Type] : SortedImportList) {
204 if (LastModule != FromModule) {
208 LastModule = FromModule;
209 auto ModHash = Index.getModule(FromModule)->second;
211 AddUint64(ModuleToNumImports[FromModule]);
218 for (
auto &Entry : ResolvedODR) {
227 std::set<GlobalValue::GUID> UsedCfiDefs;
228 std::set<GlobalValue::GUID> UsedCfiDecls;
231 std::set<GlobalValue::GUID> UsedTypeIds;
234 if (CfiFunctionDefs.
contains(ValueGUID))
235 UsedCfiDefs.insert(ValueGUID);
236 if (CfiFunctionDecls.
contains(ValueGUID))
237 UsedCfiDecls.insert(ValueGUID);
242 AddUnsigned(GS->getVisibility());
243 AddUnsigned(GS->isLive());
244 AddUnsigned(GS->canAutoHide());
246 AddUnsigned(VI.isDSOLocal(Index.withDSOLocalPropagation()));
247 AddUsedCfiGlobal(VI.getGUID());
250 AddUnsigned(GVS->maybeReadOnly());
251 AddUnsigned(GVS->maybeWriteOnly());
254 for (
auto &TT : FS->type_tests())
255 UsedTypeIds.insert(TT);
256 for (
auto &TT : FS->type_test_assume_vcalls())
257 UsedTypeIds.insert(TT.GUID);
258 for (
auto &TT : FS->type_checked_load_vcalls())
259 UsedTypeIds.insert(TT.GUID);
260 for (
auto &TT : FS->type_test_assume_const_vcalls())
261 UsedTypeIds.insert(TT.VFunc.GUID);
262 for (
auto &TT : FS->type_checked_load_const_vcalls())
263 UsedTypeIds.insert(TT.VFunc.GUID);
264 for (
auto &ET : FS->calls()) {
265 AddUnsigned(ET.first.isDSOLocal(Index.withDSOLocalPropagation()));
266 AddUsedCfiGlobal(ET.first.getGUID());
273 for (
auto &GS : DefinedGlobals) {
277 AddUsedCfiGlobal(GS.first);
278 AddUsedThings(GS.second);
283 for (
const auto &[FromModule, GUID,
Type] : SortedImportList) {
289 AddUsedThings(AS->getBaseObject());
295 AddUnsigned(S.TTRes.TheKind);
296 AddUnsigned(S.TTRes.SizeM1BitWidth);
298 AddUint64(S.TTRes.AlignLog2);
299 AddUint64(S.TTRes.SizeM1);
300 AddUint64(S.TTRes.BitMask);
301 AddUint64(S.TTRes.InlineBits);
303 AddUint64(S.WPDRes.size());
304 for (
auto &WPD : S.WPDRes) {
305 AddUnsigned(WPD.first);
306 AddUnsigned(WPD.second.TheKind);
307 AddString(WPD.second.SingleImplName);
309 AddUint64(WPD.second.ResByArg.size());
310 for (
auto &ByArg : WPD.second.ResByArg) {
311 AddUint64(ByArg.first.size());
314 AddUnsigned(ByArg.second.TheKind);
315 AddUint64(ByArg.second.Info);
316 AddUnsigned(ByArg.second.Byte);
317 AddUnsigned(ByArg.second.Bit);
324 auto TidIter = Index.typeIds().equal_range(TId);
326 AddTypeIdSummary(
I.second.first,
I.second.second);
329 AddUnsigned(UsedCfiDefs.size());
330 for (
auto &V : UsedCfiDefs)
333 AddUnsigned(UsedCfiDecls.size());
334 for (
auto &V : UsedCfiDecls)
340 Hasher.
update(FileOrErr.get()->getBuffer());
345 Hasher.
update(FileOrErr.get()->getBuffer());
376 C.VisibilityScheme ==
Config::ELF ? VI.getELFVisibility()
378 for (
auto &S : VI.getSummaryList()) {
393 if (isPrevailing(VI.getGUID(), S.get())) {
406 S->setCanAutoHide(VI.canAutoHide() &&
407 !GUIDPreservedSymbols.
count(VI.getGUID()));
410 Visibility = S->getVisibility();
424 S->setVisibility(Visibility);
426 if (S->linkage() != OriginalLinkage)
427 recordNewLinkage(S->modulePath(), VI.getGUID(), S->linkage());
431 for (
auto &S : VI.getSummaryList()) {
436 S->setVisibility(Visibility);
458 for (
auto &
I : Index)
459 for (
auto &S :
I.second.SummaryList)
461 GlobalInvolvedWithAlias.
insert(&AS->getAliasee());
463 for (
auto &
I : Index)
465 GlobalInvolvedWithAlias, isPrevailing,
466 recordNewLinkage, GUIDPreservedSymbols);
473 auto ExternallyVisibleCopies =
475 [](
const std::unique_ptr<GlobalValueSummary> &Summary) {
476 return !GlobalValue::isLocalLinkage(Summary->linkage());
479 for (
auto &S : VI.getSummaryList()) {
482 if (isExported(S->modulePath(), VI)) {
541 if (isPrevailing(VI.getGUID(), S.get()) && ExternallyVisibleCopies == 1)
553 for (
auto &
I : Index)
562 std::unique_ptr<InputFile> File(
new InputFile);
568 File->TargetTriple = FOrErr->TheReader.getTargetTriple();
569 File->SourceFileName = FOrErr->TheReader.getSourceFileName();
570 File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts();
571 File->DependentLibraries = FOrErr->TheReader.getDependentLibraries();
572 File->ComdatTable = FOrErr->TheReader.getComdatTable();
574 for (
unsigned I = 0;
I != FOrErr->Mods.size(); ++
I) {
575 size_t Begin = File->Symbols.size();
577 FOrErr->TheReader.module_symbols(
I))
580 if (Sym.isGlobal() && !Sym.isFormatSpecific())
581 File->Symbols.push_back(Sym);
582 File->ModuleSymIndices.push_back({Begin, File->Symbols.size()});
585 File->Mods = FOrErr->Mods;
586 File->Strtab = std::move(FOrErr->Strtab);
587 return std::move(File);
591 return Mods[0].getModuleIdentifier();
595 assert(Mods.size() == 1 &&
"Expect only one bitcode module");
599LTO::RegularLTOState::RegularLTOState(
unsigned ParallelCodeGenParallelismLevel,
601 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
602 Ctx(Conf), CombinedModule(
std::make_unique<
Module>(
"ld-temp.o", Ctx)),
603 Mover(
std::make_unique<
IRMover>(*CombinedModule)) {}
605LTO::ThinLTOState::ThinLTOState(
ThinBackend BackendParam)
606 : Backend(
std::
move(BackendParam)), CombinedIndex(
false) {
607 if (!Backend.isValid())
613 unsigned ParallelCodeGenParallelismLevel,
LTOKind LTOMode)
615 RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),
621 Alloc = std::make_unique<BumpPtrAllocator>();
622 GlobalResolutionSymbolSaver = std::make_unique<llvm::StringSaver>(*Alloc);
633 unsigned Partition,
bool InSummary) {
635 auto *ResI = Res.
begin();
636 auto *ResE = Res.
end();
644 if (GlobalResolutionSymbolSaver && !GlobalResolutions->contains(SymbolName))
645 SymbolName = GlobalResolutionSymbolSaver->save(SymbolName);
647 auto &GlobalRes = (*GlobalResolutions)[SymbolName];
648 GlobalRes.UnnamedAddr &= Sym.isUnnamedAddr();
650 assert(!GlobalRes.Prevailing &&
651 "Multiple prevailing defs are not allowed");
652 GlobalRes.Prevailing =
true;
653 GlobalRes.IRName = std::string(Sym.getIRName());
654 }
else if (!GlobalRes.Prevailing && GlobalRes.IRName.empty()) {
661 GlobalRes.IRName = std::string(Sym.getIRName());
675 if (GlobalRes.IRName != Sym.getIRName()) {
676 GlobalRes.Partition = GlobalResolution::External;
677 GlobalRes.VisibleOutsideSummary =
true;
685 (GlobalRes.Partition != GlobalResolution::Unknown &&
686 GlobalRes.Partition != Partition)) {
687 GlobalRes.Partition = GlobalResolution::External;
690 GlobalRes.Partition = Partition;
694 GlobalRes.VisibleOutsideSummary |=
701void LTO::releaseGlobalResolutionsMemory() {
703 GlobalResolutions.reset();
705 GlobalResolutionSymbolSaver.reset();
713 auto ResI = Res.
begin();
718 OS <<
"-r=" << Path <<
',' << Sym.getName() <<
',';
736 assert(!CalledGetMaxTasks);
738 if (Conf.ResolutionFile)
741 if (RegularLTO.CombinedModule->getTargetTriple().empty()) {
743 RegularLTO.CombinedModule->setTargetTriple(InputTriple);
749 for (
unsigned I = 0;
I !=
Input->Mods.size(); ++
I) {
750 if (
auto Err = addModule(*
Input, InputRes,
I, Res).moveInto(Res))
766 if (EnableSplitLTOUnit) {
770 if (*EnableSplitLTOUnit != LTOInfo->EnableSplitLTOUnit)
773 EnableSplitLTOUnit = LTOInfo->EnableSplitLTOUnit;
778 !LTOInfo->UnifiedLTO)
780 "unified LTO compilation must use "
781 "compatible bitcode modules (use -funified-lto)",
789 auto ModSyms =
Input.module_symbols(ModI);
790 addModuleToGlobalRes(ModSyms, Res,
791 IsThinLTO ? ThinLTO.ModuleMap.
size() + 1 : 0,
792 LTOInfo->HasSummary);
795 return addThinLTO(BM, ModSyms, Res);
797 RegularLTO.EmptyCombinedModule =
false;
798 auto ModOrErr = addRegularLTO(
Input, InputRes, BM, ModSyms, Res);
800 return ModOrErr.takeError();
801 Res = ModOrErr->second;
803 if (!LTOInfo->HasSummary) {
804 if (
Error Err = linkRegularLTO(std::move(ModOrErr->first),
814 RegularLTO.ModsWithSummaries.push_back(std::move(ModOrErr->first));
830 std::set<const Comdat *> &NonPrevailingComdats) {
835 if (!NonPrevailingComdats.count(
C))
845 GO->setComdat(
nullptr);
852 std::pair<LTO::RegularLTOState::AddedModule, ArrayRef<SymbolResolution>>>
856 llvm::TimeTraceScope timeScope(
"LTO add regular LTO");
858 Expected<std::unique_ptr<Module>> MOrErr =
864 Mod.M = std::move(*MOrErr);
866 if (
Error Err =
M.materializeMetadata())
867 return std::move(Err);
873 if (NamedMDNode *CfiFunctionsMD =
M.getNamedMetadata(
"cfi.functions"))
874 M.eraseNamedMetadata(CfiFunctionsMD);
875 }
else if (NamedMDNode *AliasesMD =
M.getNamedMetadata(
"aliases")) {
878 DenseSet<StringRef> Prevailing;
880 if (
R.Prevailing && !
I.getIRName().empty())
881 Prevailing.
insert(
I.getIRName());
882 std::vector<MDNode *> AliasGroups;
883 for (MDNode *AliasGroup : AliasesMD->operands()) {
884 std::vector<Metadata *> Aliases;
885 for (
Metadata *Alias : AliasGroup->operands()) {
888 Aliases.push_back(Alias);
890 if (Aliases.size() > 1)
891 AliasGroups.push_back(
MDTuple::get(RegularLTO.Ctx, Aliases));
893 AliasesMD->clearOperands();
894 for (MDNode *
G : AliasGroups)
895 AliasesMD->addOperand(
G);
900 ModuleSymbolTable SymTab;
903 for (GlobalVariable &GV :
M.globals())
904 if (GV.hasAppendingLinkage())
905 Mod.Keep.push_back(&GV);
907 DenseSet<GlobalObject *> AliasedGlobals;
908 for (
auto &GA :
M.aliases())
909 if (GlobalObject *GO = GA.getAliaseeObject())
910 AliasedGlobals.
insert(GO);
919 auto MsymI = SymTab.
symbols().begin(), MsymE = SymTab.
symbols().end();
921 while (MsymI != MsymE) {
931 std::set<const Comdat *> NonPrevailingComdats;
932 SmallSet<StringRef, 2> NonPrevailingAsmSymbols;
933 for (
const InputFile::Symbol &Sym : Syms) {
943 if (Sym.isUndefined())
945 Mod.Keep.push_back(GV);
949 if (
R.LinkerRedefined)
957 (GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||
958 GV->hasAvailableExternallyLinkage()) &&
965 Mod.Keep.push_back(GV);
968 NonPrevailingComdats.insert(GV->getComdat());
973 if (
R.FinalDefinitionInLinkageUnit) {
974 GV->setDSOLocal(
true);
975 if (GV->hasDLLImportStorageClass())
977 DefaultStorageClass);
979 }
else if (
auto *AS =
983 NonPrevailingAsmSymbols.
insert(AS->first);
991 if (Sym.isCommon()) {
994 auto &CommonRes = RegularLTO.Commons[std::string(Sym.getIRName())];
995 CommonRes.Size = std::max(CommonRes.Size, Sym.getCommonSize());
996 if (uint32_t SymAlignValue = Sym.getCommonAlignment()) {
997 CommonRes.Alignment =
998 std::max(
Align(SymAlignValue), CommonRes.Alignment);
1000 CommonRes.Prevailing |=
R.Prevailing;
1004 if (!
M.getComdatSymbolTable().empty())
1005 for (GlobalValue &GV :
M.global_values())
1010 if (!
M.getModuleInlineAsm().empty()) {
1011 std::string NewIA =
".lto_discard";
1012 if (!NonPrevailingAsmSymbols.
empty()) {
1015 M, [&](StringRef Name, StringRef Alias) {
1016 if (!NonPrevailingAsmSymbols.
count(Alias))
1017 NonPrevailingAsmSymbols.
erase(Name);
1019 NewIA +=
" " +
llvm::join(NonPrevailingAsmSymbols,
", ");
1022 M.setModuleInlineAsm(NewIA +
M.getModuleInlineAsm());
1026 return std::make_pair(std::move(
Mod), Res);
1029Error LTO::linkRegularLTO(RegularLTOState::AddedModule
Mod,
1030 bool LivenessFromIndex) {
1031 llvm::TimeTraceScope timeScope(
"LTO link regular LTO");
1032 std::vector<GlobalValue *>
Keep;
1033 for (GlobalValue *GV :
Mod.Keep) {
1034 if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->
getGUID())) {
1036 if (DiagnosticOutputFile) {
1037 if (
Error Err =
F->materialize())
1039 OptimizationRemarkEmitter ORE(
F,
nullptr);
1040 ORE.emit(OptimizationRemark(
DEBUG_TYPE,
"deadfunction",
F)
1042 <<
" not added to the combined module ");
1055 GlobalValue *CombinedGV =
1056 RegularLTO.CombinedModule->getNamedValue(GV->
getName());
1063 return RegularLTO.Mover->move(std::move(
Mod.M),
Keep,
nullptr,
1068Expected<ArrayRef<SymbolResolution>>
1071 llvm::TimeTraceScope timeScope(
"LTO add thin LTO");
1073 for (
const InputFile::Symbol &Sym : Syms) {
1077 if (!Sym.getIRName().empty()) {
1089 return ThinLTO.PrevailingModuleForGUID[GUID] ==
1090 BM.getModuleIdentifier();
1095 for (
const InputFile::Symbol &Sym : Syms) {
1099 if (!Sym.getIRName().empty()) {
1104 assert(ThinLTO.PrevailingModuleForGUID[GUID] ==
1111 if (
R.LinkerRedefined)
1112 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(
1119 if (
R.FinalDefinitionInLinkageUnit) {
1120 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(
1122 S->setDSOLocal(
true);
1128 if (!ThinLTO.ModuleMap.insert({BM.getModuleIdentifier(), BM}).second)
1130 "Expected at most one ThinLTO module per bitcode file",
1133 if (!Conf.ThinLTOModulesToCompile.empty()) {
1134 if (!ThinLTO.ModulesToCompile)
1135 ThinLTO.ModulesToCompile = ModuleMapType();
1138 for (
const std::string &Name : Conf.ThinLTOModulesToCompile) {
1142 <<
" to compile\n");
1151 CalledGetMaxTasks =
true;
1152 auto ModuleCount = ThinLTO.ModulesToCompile ? ThinLTO.ModulesToCompile->size()
1153 : ThinLTO.ModuleMap.size();
1154 return RegularLTO.ParallelCodeGenParallelismLevel + ModuleCount;
1159Error LTO::checkPartiallySplit() {
1163 const Module *Combined = RegularLTO.CombinedModule.get();
1169 Combined, Intrinsic::type_checked_load_relative);
1173 if ((TypeTestFunc && !TypeTestFunc->
use_empty()) ||
1174 (TypeCheckedLoadFunc && !TypeCheckedLoadFunc->
use_empty()) ||
1175 (TypeCheckedLoadRelativeFunc &&
1176 !TypeCheckedLoadRelativeFunc->
use_empty()))
1178 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1183 for (
auto &
P : ThinLTO.CombinedIndex) {
1184 for (
auto &S :
P.second.SummaryList) {
1188 if (!FS->type_test_assume_vcalls().empty() ||
1189 !FS->type_checked_load_vcalls().empty() ||
1190 !FS->type_test_assume_const_vcalls().empty() ||
1191 !FS->type_checked_load_const_vcalls().empty() ||
1192 !FS->type_tests().empty())
1194 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1205 for (
auto &Res : *GlobalResolutions) {
1208 if (Res.second.IRName.
empty())
1214 if (Res.second.VisibleOutsideSummary && Res.second.Prevailing)
1215 GUIDPreservedSymbols.
insert(GUID);
1217 if (Res.second.ExportDynamic)
1218 DynamicExportSymbols.insert(GUID);
1220 GUIDPrevailingResolutions[GUID] =
1225 auto It = GUIDPrevailingResolutions.
find(
G);
1226 if (It == GUIDPrevailingResolutions.
end())
1231 isPrevailing, Conf.OptLevel > 0);
1235 if (!StatsFileOrErr)
1236 return StatsFileOrErr.takeError();
1237 std::unique_ptr<ToolOutputFile> StatsFile = std::move(StatsFileOrErr.get());
1245 ThinLTO.CombinedIndex.setWithSupportsHotColdNew();
1247 Error Result = runRegularLTO(AddStream);
1251 Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols);
1262 if (Index.withSupportsHotColdNew())
1270 for (
auto &
F :
Mod) {
1271 for (
auto &BB :
F) {
1272 for (
auto &
I : BB) {
1276 if (CI->hasFnAttr(
"memprof"))
1277 CI->removeFnAttr(
"memprof");
1284 CI->setMetadata(LLVMContext::MD_memprof,
nullptr);
1285 CI->setMetadata(LLVMContext::MD_callsite,
nullptr);
1300 return DiagFileOrErr.takeError();
1301 DiagnosticOutputFile = std::move(*DiagFileOrErr);
1307 for (
auto &M : RegularLTO.ModsWithSummaries)
1308 if (
Error Err = linkRegularLTO(std::move(M),
true))
1316 if (
Error Err = checkPartiallySplit())
1321 const DataLayout &
DL = RegularLTO.CombinedModule->getDataLayout();
1322 for (
auto &
I : RegularLTO.Commons) {
1323 if (!
I.second.Prevailing)
1326 GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(
I.first);
1327 if (OldGV &&
DL.getTypeAllocSize(OldGV->
getValueType()) ==
I.second.Size) {
1335 auto *GV =
new GlobalVariable(*RegularLTO.CombinedModule, Ty,
false,
1338 GV->setAlignment(
I.second.Alignment);
1350 bool WholeProgramVisibilityEnabledInLTO =
1351 Conf.HasWholeProgramVisibility &&
1354 (!Conf.ValidateAllVtablesHaveTypeInfos || Conf.AllVtablesHaveTypeInfos);
1358 auto IsVisibleToRegularObj = [&](StringRef
name) {
1359 auto It = GlobalResolutions->find(
name);
1360 return (It == GlobalResolutions->end() ||
1361 It->second.VisibleOutsideSummary || !It->second.Prevailing);
1367 *RegularLTO.CombinedModule, WholeProgramVisibilityEnabledInLTO,
1368 DynamicExportSymbols, Conf.ValidateAllVtablesHaveTypeInfos,
1369 IsVisibleToRegularObj);
1371 WholeProgramVisibilityEnabledInLTO);
1373 if (Conf.PreOptModuleHook &&
1374 !Conf.PreOptModuleHook(0, *RegularLTO.CombinedModule))
1377 if (!Conf.CodeGenOnly) {
1378 for (
const auto &R : *GlobalResolutions) {
1380 RegularLTO.CombinedModule->getNamedValue(
R.second.IRName);
1381 if (!
R.second.isPrevailingIRSymbol())
1383 if (
R.second.Partition != 0 &&
1384 R.second.Partition != GlobalResolution::External)
1412 if (Conf.PostInternalizeModuleHook &&
1413 !Conf.PostInternalizeModuleHook(0, *RegularLTO.CombinedModule))
1417 if (!RegularLTO.EmptyCombinedModule || Conf.AlwaysEmitRegularLTOObj) {
1419 backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,
1420 *RegularLTO.CombinedModule, ThinLTO.CombinedIndex))
1433 for (RTLIB::LibcallImpl Impl : LibcallImpls) {
1434 if (Impl != RTLIB::Unsupported)
1438 return LibcallSymbols;
1443 const std::string &NewModulePath)
const {
1444 return emitFiles(ImportList, ModulePath, NewModulePath,
1445 NewModulePath +
".thinlto.bc",
1451 const std::string &NewModulePath,
StringRef SummaryPath,
1452 std::optional<std::reference_wrapper<ImportsFilesContainer>> ImportsFiles)
1459 ImportList, ModuleToSummariesForIndex,
1460 DeclarationSummaries);
1467 &DeclarationSummaries);
1471 ModulePath, NewModulePath +
".imports", ModuleToSummariesForIndex);
1472 if (ImportsFilesError)
1473 return ImportsFilesError;
1479 ModulePath, ModuleToSummariesForIndex,
1480 [&](
StringRef M) { ImportsFiles->get().push_back(M.str()); });
1493 bool ShouldEmitIndexFiles;
1500 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
1503 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
1504 AddStream(
std::
move(AddStream)),
1505 ShouldEmitIndexFiles(ShouldEmitIndexFiles) {
1515class InProcessThinBackend :
public CGThinBackend {
1520 InProcessThinBackend(
1525 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles)
1526 : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
1527 AddStream, OnWrite, ShouldEmitIndexFiles,
1528 ShouldEmitImportsFiles, ThinLTOParallelism),
1531 virtual Error runThinLTOBackendThread(
1532 AddStreamFn AddStream, FileCache Cache,
unsigned Task, BitcodeModule BM,
1533 ModuleSummaryIndex &CombinedIndex,
1534 const FunctionImporter::ImportMapTy &ImportList,
1536 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1538 MapVector<StringRef, BitcodeModule> &ModuleMap) {
1540 llvm::TimeTraceScope timeScope(
"Run ThinLTO backend thread (in-process)",
1542 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1543 LTOLLVMContext BackendContext(Conf);
1544 Expected<std::unique_ptr<Module>> MOrErr = BM.
parseModule(BackendContext);
1548 return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,
1549 ImportList, DefinedGlobals, &ModuleMap,
1552 if (ShouldEmitIndexFiles) {
1553 if (
auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1559 [](uint32_t V) { return V == 0; }))
1562 return RunThinBackend(AddStream);
1566 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1567 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1568 Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task,
Key, ModuleID);
1571 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1573 return RunThinBackend(CacheAddStream);
1579 unsigned Task, BitcodeModule BM,
1580 const FunctionImporter::ImportMapTy &ImportList,
1582 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1583 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
1585 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
1587 ModuleToDefinedGVSummaries.
find(ModulePath)->second;
1588 BackendThreadPool.async(
1589 [=](BitcodeModule BM, ModuleSummaryIndex &CombinedIndex,
1590 const FunctionImporter::ImportMapTy &ImportList,
1592 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
1595 MapVector<StringRef, BitcodeModule> &ModuleMap) {
1599 Error E = runThinLTOBackendThread(
1600 AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList,
1601 ResolvedODR, DefinedGlobals, ModuleMap);
1603 std::unique_lock<std::mutex>
L(ErrMu);
1612 BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList),
1613 std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap));
1616 OnWrite(std::string(ModulePath));
1626class FirstRoundThinBackend :
public InProcessThinBackend {
1631 FirstRoundThinBackend(
1632 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
1633 ThreadPoolStrategy ThinLTOParallelism,
1634 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
1637 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
1638 ModuleToDefinedGVSummaries, std::
move(CGAddStream),
1639 std::
move(CGCache), nullptr,
1642 IRAddStream(std::
move(IRAddStream)), IRCache(std::
move(IRCache)) {}
1644 Error runThinLTOBackendThread(
1645 AddStreamFn CGAddStream, FileCache CGCache,
unsigned Task,
1646 BitcodeModule BM, ModuleSummaryIndex &CombinedIndex,
1647 const FunctionImporter::ImportMapTy &ImportList,
1649 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1651 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
1653 llvm::TimeTraceScope timeScope(
"Run ThinLTO backend thread (first round)",
1655 auto RunThinBackend = [&](
AddStreamFn CGAddStream,
1657 LTOLLVMContext BackendContext(Conf);
1658 Expected<std::unique_ptr<Module>> MOrErr = BM.
parseModule(BackendContext);
1662 return thinBackend(Conf, Task, CGAddStream, **MOrErr, CombinedIndex,
1663 ImportList, DefinedGlobals, &ModuleMap,
1669 if (ShouldEmitIndexFiles) {
1670 if (
auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1675 "Both caches for CG and IR should have matching availability");
1678 [](uint32_t V) { return V == 0; }))
1681 return RunThinBackend(CGAddStream, IRAddStream);
1685 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1686 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1687 Expected<AddStreamFn> CacheCGAddStreamOrErr =
1688 CGCache(Task, CGKey, ModuleID);
1691 AddStreamFn &CacheCGAddStream = *CacheCGAddStreamOrErr;
1695 Expected<AddStreamFn> CacheIRAddStreamOrErr =
1696 IRCache(Task, IRKey, ModuleID);
1699 AddStreamFn &CacheIRAddStream = *CacheIRAddStreamOrErr;
1705 if (CacheCGAddStream || CacheIRAddStream) {
1708 return RunThinBackend(CacheCGAddStream ? CacheCGAddStream : CGAddStream,
1709 CacheIRAddStream ? CacheIRAddStream : IRAddStream);
1721class SecondRoundThinBackend :
public InProcessThinBackend {
1722 std::unique_ptr<SmallVector<StringRef>> IRFiles;
1726 SecondRoundThinBackend(
1727 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
1728 ThreadPoolStrategy ThinLTOParallelism,
1729 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
1733 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
1734 ModuleToDefinedGVSummaries, std::
move(AddStream),
1739 IRFiles(std::
move(IRFiles)), CombinedCGDataHash(CombinedCGDataHash) {}
1741 virtual Error runThinLTOBackendThread(
1742 AddStreamFn AddStream, FileCache Cache,
unsigned Task, BitcodeModule BM,
1743 ModuleSummaryIndex &CombinedIndex,
1744 const FunctionImporter::ImportMapTy &ImportList,
1746 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1748 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
1750 llvm::TimeTraceScope timeScope(
"Run ThinLTO backend thread (second round)",
1752 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1753 LTOLLVMContext BackendContext(Conf);
1754 std::unique_ptr<Module> LoadedModule =
1757 return thinBackend(Conf, Task, AddStream, *LoadedModule, CombinedIndex,
1758 ImportList, DefinedGlobals, &ModuleMap,
1763 [](uint32_t V) { return V == 0; }))
1766 return RunThinBackend(AddStream);
1771 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1772 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1774 std::to_string(CombinedCGDataHash));
1775 Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task,
Key, ModuleID);
1778 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1780 if (CacheAddStream) {
1783 return RunThinBackend(CacheAddStream);
1793 bool ShouldEmitIndexFiles,
1794 bool ShouldEmitImportsFiles) {
1799 return std::make_unique<InProcessThinBackend>(
1800 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1801 AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
1802 ShouldEmitImportsFiles);
1828 return std::string(Path);
1832 if (!ParentPath.
empty()) {
1835 llvm::errs() <<
"warning: could not create directory '" << ParentPath
1836 <<
"': " << EC.message() <<
'\n';
1838 return std::string(NewPath);
1843 std::string OldPrefix, NewPrefix, NativeObjectPrefix;
1847 WriteIndexesThinBackend(
1851 std::string OldPrefix, std::string NewPrefix,
1852 std::string NativeObjectPrefix,
bool ShouldEmitImportsFiles,
1855 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
1856 OldPrefix(OldPrefix), NewPrefix(NewPrefix),
1857 NativeObjectPrefix(NativeObjectPrefix),
1858 LinkedObjectsFile(LinkedObjectsFile) {}
1864 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1872 if (LinkedObjectsFile) {
1873 std::string ObjectPrefix =
1874 NativeObjectPrefix.empty() ? NewPrefix : NativeObjectPrefix;
1875 std::string LinkedObjectsFilePath =
1877 *LinkedObjectsFile << LinkedObjectsFilePath <<
'\n';
1880 BackendThreadPool.async(
1881 [
this](
const StringRef ModulePath,
1882 const FunctionImporter::ImportMapTy &ImportList,
1883 const std::string &OldPrefix,
const std::string &NewPrefix) {
1884 std::string NewModulePath =
1886 auto E = emitFiles(ImportList, ModulePath, NewModulePath);
1888 std::unique_lock<std::mutex>
L(ErrMu);
1896 ModulePath, ImportList, OldPrefix, NewPrefix);
1899 OnWrite(std::string(ModulePath));
1903 bool isSensitiveToInputOrder()
override {
1913 std::string NewPrefix, std::string NativeObjectPrefix,
1920 return std::make_unique<WriteIndexesThinBackend>(
1921 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1922 OldPrefix, NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,
1923 LinkedObjectsFile, OnWrite);
1938 if (ThinLTO.ModuleMap.
empty())
1941 if (ThinLTO.ModulesToCompile && ThinLTO.ModulesToCompile->empty()) {
1942 llvm::errs() <<
"warning: [ThinLTO] No module compiled\n";
1946 if (Conf.CombinedIndexHook &&
1947 !Conf.CombinedIndexHook(ThinLTO.CombinedIndex, GUIDPreservedSymbols))
1952 DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries(
1953 ThinLTO.ModuleMap.size());
1954 ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule(
1955 ModuleToDefinedGVSummaries);
1963 for (
auto &
Mod : ThinLTO.ModuleMap)
1964 if (!ModuleToDefinedGVSummaries.
count(
Mod.first))
1967 FunctionImporter::ImportListsTy ImportLists(ThinLTO.ModuleMap.size());
1968 DenseMap<StringRef, FunctionImporter::ExportSetTy> ExportLists(
1969 ThinLTO.ModuleMap.size());
1970 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
1973 ThinLTO.CombinedIndex.dumpSCCs(
outs());
1975 std::set<GlobalValue::GUID> ExportedGUIDs;
1977 bool WholeProgramVisibilityEnabledInLTO =
1978 Conf.HasWholeProgramVisibility &&
1981 (!Conf.ValidateAllVtablesHaveTypeInfos || Conf.AllVtablesHaveTypeInfos);
1983 ThinLTO.CombinedIndex.setWithWholeProgramVisibility();
1988 DenseSet<GlobalValue::GUID> VisibleToRegularObjSymbols;
1989 if (WholeProgramVisibilityEnabledInLTO &&
1990 Conf.ValidateAllVtablesHaveTypeInfos) {
1993 auto IsVisibleToRegularObj = [&](StringRef
name) {
1994 auto It = GlobalResolutions->find(
name);
1995 return (It == GlobalResolutions->end() ||
1996 It->second.VisibleOutsideSummary || !It->second.Prevailing);
2000 VisibleToRegularObjSymbols,
2001 IsVisibleToRegularObj);
2007 ThinLTO.CombinedIndex, WholeProgramVisibilityEnabledInLTO,
2008 DynamicExportSymbols, VisibleToRegularObjSymbols);
2013 std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;
2015 LocalWPDTargetsMap);
2018 return ThinLTO.PrevailingModuleForGUID[
GUID] == S->modulePath();
2021 MemProfContextDisambiguation ContextDisambiguation;
2022 ContextDisambiguation.
run(ThinLTO.CombinedIndex, isPrevailing);
2029 for (
auto &Res : *GlobalResolutions) {
2032 if (Res.second.Partition != GlobalResolution::External ||
2033 !Res.second.isPrevailingIRSymbol())
2038 if (ThinLTO.CombinedIndex.isGUIDLive(GUID))
2039 ExportedGUIDs.insert(GUID);
2046 releaseGlobalResolutionsMemory();
2048 if (Conf.OptLevel > 0)
2050 isPrevailing, ImportLists, ExportLists);
2054 auto &Defs = ThinLTO.CombinedIndex.cfiFunctionDefs();
2055 ExportedGUIDs.insert(Defs.guid_begin(), Defs.guid_end());
2056 auto &Decls = ThinLTO.CombinedIndex.cfiFunctionDecls();
2057 ExportedGUIDs.insert(Decls.guid_begin(), Decls.guid_end());
2059 auto isExported = [&](StringRef ModuleIdentifier, ValueInfo
VI) {
2060 const auto &ExportList = ExportLists.
find(ModuleIdentifier);
2061 return (ExportList != ExportLists.end() && ExportList->second.
count(VI)) ||
2062 ExportedGUIDs.count(
VI.getGUID());
2068 LocalWPDTargetsMap);
2073 auto recordNewLinkage = [&](StringRef ModuleIdentifier,
2076 ResolvedODR[ModuleIdentifier][
GUID] = NewLinkage;
2079 recordNewLinkage, GUIDPreservedSymbols);
2088 TimeTraceScopeExit.release();
2091 ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;
2093 auto RunBackends = [&](ThinBackendProc *BackendProcess) ->
Error {
2094 auto ProcessOneModule = [&](
int I) ->
Error {
2098 return BackendProcess->start(
2099 RegularLTO.ParallelCodeGenParallelismLevel +
I,
Mod.second,
2100 ImportLists[
Mod.first], ExportLists[
Mod.first],
2101 ResolvedODR[
Mod.first], ThinLTO.ModuleMap);
2104 BackendProcess->setup(ModuleMap.
size(),
2105 RegularLTO.ParallelCodeGenParallelismLevel,
2106 RegularLTO.CombinedModule->getTargetTriple());
2108 if (BackendProcess->getThreadCount() == 1 ||
2109 BackendProcess->isSensitiveToInputOrder()) {
2115 for (
int I = 0,
E = ModuleMap.
size();
I !=
E; ++
I)
2116 if (
Error E = ProcessOneModule(
I))
2123 std::vector<BitcodeModule *> ModulesVec;
2124 ModulesVec.reserve(ModuleMap.
size());
2125 for (
auto &
Mod : ModuleMap)
2126 ModulesVec.push_back(&
Mod.second);
2128 if (
Error E = ProcessOneModule(
I))
2131 return BackendProcess->wait();
2135 std::unique_ptr<ThinBackendProc> BackendProc =
2136 ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
2138 return RunBackends(BackendProc.get());
2146 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Initializing ThinLTO two-codegen rounds\n");
2149 auto Parallelism = ThinLTO.Backend.getParallelism();
2152 cgdata::StreamCacheData CG(MaxTasks, Cache,
"CG"),
IR(MaxTasks, Cache,
"IR");
2157 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Running the first round of codegen\n");
2158 auto FirstRoundLTO = std::make_unique<FirstRoundThinBackend>(
2159 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2160 CG.AddStream, CG.Cache,
IR.AddStream,
IR.Cache);
2161 if (
Error E = RunBackends(FirstRoundLTO.get()))
2166 if (
Error E = CombinedHashOrErr.takeError())
2168 auto CombinedHash = *CombinedHashOrErr;
2169 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] CGData hash: " << CombinedHash <<
"\n");
2173 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Running the second round of codegen\n");
2174 auto SecondRoundLTO = std::make_unique<SecondRoundThinBackend>(
2175 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2176 AddStream, Cache,
IR.getResult(), CombinedHash);
2177 return RunBackends(SecondRoundLTO.get());
2187 if (!Filename.empty() &&
Count != -1)
2195 if (
Error E = ResultOrErr.takeError())
2196 return std::move(E);
2199 (*ResultOrErr)->keep();
2207 if (StatsFilename.
empty())
2218 return std::move(StatsFile);
2226 std::vector<int> ModulesOrdering(Seq.begin(), Seq.end());
2227 llvm::sort(ModulesOrdering, [&](
int LeftIndex,
int RightIndex) {
2228 auto LSize = R[LeftIndex]->getBuffer().size();
2229 auto RSize = R[RightIndex]->getBuffer().size();
2230 return LSize > RSize;
2232 return ModulesOrdering;
2242class OutOfProcessThinBackend :
public CGThinBackend {
2248 SString LinkerOutputFile;
2250 SString DistributorPath;
2253 SString RemoteCompiler;
2276 unsigned ThinLTOTaskOffset;
2279 llvm::Triple Triple;
2282 OutOfProcessThinBackend(
2283 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
2284 ThreadPoolStrategy ThinLTOParallelism,
2285 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
2287 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
2288 StringRef LinkerOutputFile, StringRef Distributor,
2291 : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
2292 AddStream, OnWrite, ShouldEmitIndexFiles,
2293 ShouldEmitImportsFiles, ThinLTOParallelism),
2294 LinkerOutputFile(LinkerOutputFile), DistributorPath(Distributor),
2295 DistributorArgs(DistributorArgs), RemoteCompiler(RemoteCompiler),
2296 RemoteCompilerArgs(RemoteCompilerArgs), SaveTemps(SaveTemps) {}
2298 virtual void setup(
unsigned ThinLTONumTasks,
unsigned ThinLTOTaskOffset,
2299 llvm::Triple Triple)
override {
2301 Jobs.
resize((
size_t)ThinLTONumTasks);
2302 this->ThinLTOTaskOffset = ThinLTOTaskOffset;
2303 this->Triple = Triple;
2307 unsigned Task, BitcodeModule BM,
2308 const FunctionImporter::ImportMapTy &ImportList,
2310 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
2311 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
2317 itostr(Task) +
"." + UID +
".native.o");
2319 Job &J = Jobs[Task - ThinLTOTaskOffset];
2323 Saver.
save(ObjFilePath.str()),
2324 Saver.
save(ObjFilePath.str() +
".thinlto.bc"),
2328 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
2332 BackendThreadPool.async(
2333 [=](Job &J,
const FunctionImporter::ImportMapTy &ImportList) {
2334 if (
auto E = emitFiles(ImportList, J.ModuleID, J.ModuleID.str(),
2335 J.SummaryIndexPath, J.ImportsFiles)) {
2336 std::unique_lock<std::mutex>
L(ErrMu);
2343 std::ref(J), std::ref(ImportList));
2357 void buildCommonRemoteCompilerOptions() {
2358 const lto::Config &
C = Conf;
2359 auto &
Ops = CodegenOptions;
2363 if (
C.Options.EmitAddrsig)
2364 Ops.push_back(
"-faddrsig");
2365 if (
C.Options.FunctionSections)
2366 Ops.push_back(
"-ffunction-sections");
2367 if (
C.Options.DataSections)
2368 Ops.push_back(
"-fdata-sections");
2373 Ops.push_back(
"-fpic");
2377 if (!
C.PGOWarnMismatch) {
2378 Ops.push_back(
"-mllvm");
2379 Ops.push_back(
"-no-pgo-warn-mismatch");
2384 if (!
C.SampleProfile.empty()) {
2386 Saver.
save(
"-fprofile-sample-use=" + Twine(
C.SampleProfile)));
2387 CommonInputs.
insert(
C.SampleProfile);
2391 Ops.push_back(
"-Wno-unused-command-line-argument");
2394 if (!RemoteCompilerArgs.
empty())
2395 for (
auto &a : RemoteCompilerArgs)
2401 bool emitDistributorJson(StringRef DistributorJson) {
2404 raw_fd_ostream OS(DistributorJson, EC);
2408 json::OStream JOS(OS);
2411 JOS.attributeObject(
"common", [&]() {
2412 JOS.attribute(
"linker_output", LinkerOutputFile);
2414 JOS.attributeArray(
"args", [&]() {
2415 JOS.value(RemoteCompiler);
2419 JOS.value(Saver.
save(
"--target=" + Triple.
str()));
2421 for (
const auto &
A : CodegenOptions)
2425 JOS.attribute(
"inputs",
Array(CommonInputs));
2429 JOS.attributeArray(
"jobs", [&]() {
2430 for (
const auto &J : Jobs) {
2434 SmallVector<StringRef, 1> Outputs;
2437 JOS.attributeArray(
"args", [&]() {
2438 JOS.value(J.ModuleID);
2442 Saver.
save(
"-fthinlto-index=" + Twine(J.SummaryIndexPath)));
2446 JOS.value(J.NativeObjectPath);
2454 JOS.attribute(
"inputs",
Array(Inputs));
2456 JOS.attribute(
"outputs",
Array(Outputs));
2465 void removeFile(StringRef FileName) {
2467 if (EC && EC != std::make_error_code(std::errc::no_such_file_or_directory))
2468 errs() <<
"warning: could not remove the file '" << FileName
2469 <<
"': " <<
EC.message() <<
"\n";
2472 Error wait()
override {
2475 BackendThreadPool.wait();
2477 return std::move(*Err);
2481 for (
auto &Job : Jobs) {
2482 removeFile(Job.NativeObjectPath);
2483 if (!ShouldEmitIndexFiles)
2484 removeFile(Job.SummaryIndexPath);
2488 const StringRef BCError =
"DTLTO backend compilation: ";
2490 buildCommonRemoteCompilerOptions();
2495 if (!emitDistributorJson(JsonFile))
2497 BCError +
"failed to generate distributor JSON script: " + JsonFile,
2501 removeFile(JsonFile);
2506 Args.push_back(JsonFile);
2512 BCError +
"distributor execution failed" +
2513 (!ErrMsg.empty() ?
": " + ErrMsg + Twine(
".") : Twine(
".")),
2517 for (
auto &Job : Jobs) {
2520 auto ObjFileMbOrErr =
2523 if (std::error_code EC = ObjFileMbOrErr.getError())
2525 BCError +
"cannot open native object file: " +
2526 Job.NativeObjectPath +
": " +
EC.message(),
2528 auto StreamOrErr = AddStream(Job.Task, Job.ModuleID);
2529 if (
Error Err = StreamOrErr.takeError())
2531 auto &Stream = *StreamOrErr->get();
2532 *Stream.OS << ObjFileMbOrErr->get()->getMemBufferRef().getBuffer();
2533 if (
Error Err = Stream.commit())
2544 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
2552 return std::make_unique<OutOfProcessThinBackend>(
2553 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2554 AddStream, OnWrite, ShouldEmitIndexFiles, ShouldEmitImportsFiles,
2555 LinkerOutputFile, Distributor, DistributorArgs, RemoteCompiler,
2556 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")
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."))
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)
cl::opt< bool > ForceImportAll
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 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 Error finalizeOptimizationRemarks(std::unique_ptr< ToolOutputFile > DiagOutputFile)
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 Expected< std::unique_ptr< ToolOutputFile > > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::optional< uint64_t > RemarksHotnessThreshold=0, int Count=-1)
Setup optimization remarks.
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< 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 Expected< std::unique_ptr< ToolOutputFile > > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::optional< uint64_t > RemarksHotnessThreshold=0)
Setup optimization remarks that output to a file.
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.
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.