25#include "llvm/Config/llvm-config.h"
51#include "llvm/Support/VCSRevision.h"
65using namespace object;
67#define DEBUG_TYPE "lto"
73 cl::desc(
"Dump the SCCs in the ThinLTO index's callgraph"));
79 cl::desc(
"Enable global value internalization in LTO"));
96 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
98 const std::set<GlobalValue::GUID> &CfiFunctionDefs,
99 const std::set<GlobalValue::GUID> &CfiFunctionDecls) {
107 Hasher.
update(LLVM_VERSION_STRING);
109 Hasher.
update(LLVM_REVISION);
117 auto AddUnsigned = [&](
unsigned I) {
127 auto AddUint8 = [&](
const uint8_t
I) {
151 AddUnsigned(
static_cast<int>(Conf.
CGOptLevel));
152 AddUnsigned(
static_cast<int>(Conf.
CGFileType));
162 auto ModHash =
Index.getModuleHash(ModuleID);
167 std::vector<uint64_t> ExportsGUID;
168 ExportsGUID.reserve(ExportList.
size());
169 for (
const auto &VI : ExportList)
170 ExportsGUID.push_back(VI.getGUID());
174 for (
auto GUID : ExportsGUID)
181 struct ImportModule {
182 ImportMapIteratorTy ModIt;
185 StringRef getIdentifier()
const {
return ModIt->getFirst(); }
187 return ModIt->second;
193 std::vector<ImportModule> ImportModulesVector;
194 ImportModulesVector.reserve(ImportList.
size());
196 for (ImportMapIteratorTy It = ImportList.
begin(); It != ImportList.
end();
198 ImportModulesVector.push_back({It,
Index.getModule(It->getFirst())});
203 [](
const ImportModule &Lhs,
const ImportModule &Rhs) ->
bool {
204 return Lhs.getHash() < Rhs.getHash();
206 std::vector<std::pair<uint64_t, uint8_t>> ImportedGUIDs;
207 for (
const ImportModule &Entry : ImportModulesVector) {
208 auto ModHash = Entry.getHash();
211 AddUint64(Entry.getFunctions().size());
213 ImportedGUIDs.clear();
214 for (
auto &[Fn, ImportType] : Entry.getFunctions())
215 ImportedGUIDs.push_back(std::make_pair(Fn, ImportType));
217 for (
auto &[GUID,
Type] : ImportedGUIDs) {
224 for (
auto &Entry : ResolvedODR) {
233 std::set<GlobalValue::GUID> UsedCfiDefs;
234 std::set<GlobalValue::GUID> UsedCfiDecls;
237 std::set<GlobalValue::GUID> UsedTypeIds;
240 if (CfiFunctionDefs.count(ValueGUID))
241 UsedCfiDefs.insert(ValueGUID);
242 if (CfiFunctionDecls.count(ValueGUID))
243 UsedCfiDecls.insert(ValueGUID);
248 AddUnsigned(GS->getVisibility());
249 AddUnsigned(GS->isLive());
250 AddUnsigned(GS->canAutoHide());
252 AddUnsigned(VI.isDSOLocal(
Index.withDSOLocalPropagation()));
253 AddUsedCfiGlobal(VI.getGUID());
255 if (
auto *GVS = dyn_cast<GlobalVarSummary>(GS)) {
256 AddUnsigned(GVS->maybeReadOnly());
257 AddUnsigned(GVS->maybeWriteOnly());
259 if (
auto *FS = dyn_cast<FunctionSummary>(GS)) {
260 for (
auto &TT : FS->type_tests())
261 UsedTypeIds.insert(TT);
262 for (
auto &TT : FS->type_test_assume_vcalls())
263 UsedTypeIds.insert(TT.GUID);
264 for (
auto &TT : FS->type_checked_load_vcalls())
265 UsedTypeIds.insert(TT.GUID);
266 for (
auto &TT : FS->type_test_assume_const_vcalls())
267 UsedTypeIds.insert(TT.VFunc.GUID);
268 for (
auto &TT : FS->type_checked_load_const_vcalls())
269 UsedTypeIds.insert(TT.VFunc.GUID);
270 for (
auto &ET : FS->calls()) {
271 AddUnsigned(ET.first.isDSOLocal(
Index.withDSOLocalPropagation()));
272 AddUsedCfiGlobal(ET.first.getGUID());
279 for (
auto &GS : DefinedGlobals) {
283 AddUsedCfiGlobal(GS.first);
284 AddUsedThings(GS.second);
289 for (
const ImportModule &ImpM : ImportModulesVector)
290 for (
auto &[GUID, UnusedImportType] : ImpM.getFunctions()) {
292 Index.findSummaryInModule(GUID, ImpM.getIdentifier());
296 if (
auto *AS = dyn_cast_or_null<AliasSummary>(S))
297 AddUsedThings(AS->getBaseObject());
303 AddUnsigned(S.TTRes.TheKind);
304 AddUnsigned(S.TTRes.SizeM1BitWidth);
306 AddUint64(S.TTRes.AlignLog2);
307 AddUint64(S.TTRes.SizeM1);
308 AddUint64(S.TTRes.BitMask);
309 AddUint64(S.TTRes.InlineBits);
311 AddUint64(S.WPDRes.size());
312 for (
auto &WPD : S.WPDRes) {
313 AddUnsigned(WPD.first);
314 AddUnsigned(WPD.second.TheKind);
315 AddString(WPD.second.SingleImplName);
317 AddUint64(WPD.second.ResByArg.size());
318 for (
auto &ByArg : WPD.second.ResByArg) {
319 AddUint64(ByArg.first.size());
322 AddUnsigned(ByArg.second.TheKind);
323 AddUint64(ByArg.second.Info);
324 AddUnsigned(ByArg.second.Byte);
325 AddUnsigned(ByArg.second.Bit);
332 auto TidIter =
Index.typeIds().equal_range(TId);
333 for (
auto It = TidIter.first; It != TidIter.second; ++It)
334 AddTypeIdSummary(It->second.first, It->second.second);
337 AddUnsigned(UsedCfiDefs.size());
338 for (
auto &V : UsedCfiDefs)
341 AddUnsigned(UsedCfiDecls.size());
342 for (
auto &V : UsedCfiDecls)
348 Hasher.
update(FileOrErr.get()->getBuffer());
353 Hasher.
update(FileOrErr.get()->getBuffer());
358 Key = toHex(Hasher.
result());
370 C.VisibilityScheme ==
Config::ELF ? VI.getELFVisibility()
372 for (
auto &S : VI.getSummaryList()) {
387 if (isPrevailing(VI.getGUID(), S.get())) {
400 S->setCanAutoHide(VI.canAutoHide() &&
401 !GUIDPreservedSymbols.
count(VI.getGUID()));
404 Visibility = S->getVisibility();
407 else if (!isa<AliasSummary>(S.get()) &&
408 !GlobalInvolvedWithAlias.
count(S.get()))
415 S->setVisibility(Visibility);
417 if (S->linkage() != OriginalLinkage)
418 recordNewLinkage(S->modulePath(), VI.getGUID(), S->linkage());
422 for (
auto &S : VI.getSummaryList()) {
427 S->setVisibility(Visibility);
450 for (
auto &S :
I.second.SummaryList)
451 if (
auto AS = dyn_cast<AliasSummary>(S.get()))
452 GlobalInvolvedWithAlias.
insert(&AS->getAliasee());
456 GlobalInvolvedWithAlias, isPrevailing,
457 recordNewLinkage, GUIDPreservedSymbols);
464 auto ExternallyVisibleCopies =
466 [](
const std::unique_ptr<GlobalValueSummary> &Summary) {
467 return !GlobalValue::isLocalLinkage(Summary->linkage());
470 for (
auto &S : VI.getSummaryList()) {
473 if (isExported(S->modulePath(), VI)) {
532 if (isPrevailing(VI.getGUID(), S.get()) && ExternallyVisibleCopies == 1)
553 std::unique_ptr<InputFile> File(
new InputFile);
559 File->TargetTriple = FOrErr->TheReader.getTargetTriple();
560 File->SourceFileName = FOrErr->TheReader.getSourceFileName();
561 File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts();
562 File->DependentLibraries = FOrErr->TheReader.getDependentLibraries();
563 File->ComdatTable = FOrErr->TheReader.getComdatTable();
565 for (
unsigned I = 0;
I != FOrErr->Mods.size(); ++
I) {
566 size_t Begin = File->Symbols.size();
568 FOrErr->TheReader.module_symbols(
I))
571 if (
Sym.isGlobal() && !
Sym.isFormatSpecific())
572 File->Symbols.push_back(
Sym);
573 File->ModuleSymIndices.push_back({Begin, File->Symbols.size()});
576 File->Mods = FOrErr->Mods;
577 File->Strtab = std::move(FOrErr->Strtab);
578 return std::move(File);
582 return Mods[0].getModuleIdentifier();
586 assert(Mods.size() == 1 &&
"Expect only one bitcode module");
590LTO::RegularLTOState::RegularLTOState(
unsigned ParallelCodeGenParallelismLevel,
592 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
593 Ctx(Conf), CombinedModule(
std::make_unique<
Module>(
"ld-temp.o", Ctx)),
594 Mover(
std::make_unique<
IRMover>(*CombinedModule)) {
598LTO::ThinLTOState::ThinLTOState(
ThinBackend Backend)
599 : Backend(Backend), CombinedIndex(
false) {
606 unsigned ParallelCodeGenParallelismLevel,
LTOKind LTOMode)
608 RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),
610 GlobalResolutions(
std::make_optional<
StringMap<GlobalResolution>>()),
620 unsigned Partition,
bool InSummary) {
621 auto *ResI = Res.
begin();
622 auto *ResE = Res.
end();
624 const Triple TT(RegularLTO.CombinedModule->getTargetTriple());
629 auto &GlobalRes = (*GlobalResolutions)[
Sym.getName()];
630 GlobalRes.UnnamedAddr &=
Sym.isUnnamedAddr();
632 assert(!GlobalRes.Prevailing &&
633 "Multiple prevailing defs are not allowed");
634 GlobalRes.Prevailing =
true;
635 GlobalRes.IRName = std::string(
Sym.getIRName());
636 }
else if (!GlobalRes.Prevailing && GlobalRes.IRName.empty()) {
643 GlobalRes.IRName = std::string(
Sym.getIRName());
657 if (GlobalRes.IRName !=
Sym.getIRName()) {
658 GlobalRes.Partition = GlobalResolution::External;
659 GlobalRes.VisibleOutsideSummary =
true;
667 (GlobalRes.Partition != GlobalResolution::Unknown &&
668 GlobalRes.Partition != Partition)) {
669 GlobalRes.Partition = GlobalResolution::External;
672 GlobalRes.Partition = Partition;
676 GlobalRes.VisibleOutsideSummary |=
687 auto ResI = Res.
begin();
692 OS <<
"-r=" << Path <<
',' <<
Sym.getName() <<
',';
709 assert(!CalledGetMaxTasks);
714 if (RegularLTO.CombinedModule->getTargetTriple().empty()) {
715 RegularLTO.CombinedModule->setTargetTriple(Input->getTargetTriple());
721 for (
unsigned I = 0;
I != Input->Mods.size(); ++
I)
722 if (
Error Err = addModule(*Input,
I, ResI, Res.
end()))
736 if (EnableSplitLTOUnit) {
740 if (*EnableSplitLTOUnit != LTOInfo->EnableSplitLTOUnit)
741 ThinLTO.CombinedIndex.setPartiallySplitLTOUnits();
743 EnableSplitLTOUnit = LTOInfo->EnableSplitLTOUnit;
748 !LTOInfo->UnifiedLTO)
749 return make_error<StringError>(
750 "unified LTO compilation must use "
751 "compatible bitcode modules (use -funified-lto)",
759 auto ModSyms = Input.module_symbols(ModI);
760 addModuleToGlobalRes(ModSyms, {ResI, ResE},
761 IsThinLTO ? ThinLTO.ModuleMap.size() + 1 : 0,
762 LTOInfo->HasSummary);
765 return addThinLTO(BM, ModSyms, ResI, ResE);
767 RegularLTO.EmptyCombinedModule =
false;
769 addRegularLTO(BM, ModSyms, ResI, ResE);
773 if (!LTOInfo->HasSummary)
774 return linkRegularLTO(std::move(*ModOrErr),
false);
780 RegularLTO.ModsWithSummaries.push_back(std::move(*ModOrErr));
796 std::set<const Comdat *> &NonPrevailingComdats) {
801 if (!NonPrevailingComdats.count(
C))
810 if (
auto GO = dyn_cast<GlobalObject>(&GV))
811 GO->setComdat(
nullptr);
821 RegularLTOState::AddedModule
Mod;
828 Mod.M = std::move(*MOrErr);
830 if (
Error Err =
M.materializeMetadata())
831 return std::move(Err);
838 if (
NamedMDNode *CfiFunctionsMD =
M.getNamedMetadata(
"cfi.functions"))
839 M.eraseNamedMetadata(CfiFunctionsMD);
847 if (GV.hasAppendingLinkage())
848 Mod.Keep.push_back(&GV);
851 for (
auto &GA :
M.aliases())
853 AliasedGlobals.
insert(GO);
862 auto MsymI = SymTab.
symbols().begin(), MsymE = SymTab.
symbols().end();
864 while (MsymI != MsymE) {
874 std::set<const Comdat *> NonPrevailingComdats;
884 if (
GlobalValue *GV = dyn_cast_if_present<GlobalValue *>(Msym)) {
886 if (
Sym.isUndefined())
888 Mod.Keep.push_back(GV);
899 }
else if (isa<GlobalObject>(GV) &&
900 (GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||
901 GV->hasAvailableExternallyLinkage()) &&
902 !AliasedGlobals.
count(cast<GlobalObject>(GV))) {
908 Mod.Keep.push_back(GV);
911 NonPrevailingComdats.insert(GV->getComdat());
912 cast<GlobalObject>(GV)->setComdat(
nullptr);
917 GV->setDSOLocal(
true);
918 if (GV->hasDLLImportStorageClass())
920 DefaultStorageClass);
922 }
else if (
auto *AS =
923 dyn_cast_if_present<ModuleSymbolTable::AsmSymbol *>(Msym)) {
926 NonPrevailingAsmSymbols.
insert(AS->first);
934 if (
Sym.isCommon()) {
937 auto &CommonRes = RegularLTO.Commons[std::string(
Sym.getIRName())];
938 CommonRes.Size = std::max(CommonRes.Size,
Sym.getCommonSize());
939 if (
uint32_t SymAlignValue =
Sym.getCommonAlignment()) {
940 CommonRes.Alignment =
941 std::max(
Align(SymAlignValue), CommonRes.Alignment);
947 if (!
M.getComdatSymbolTable().empty())
953 if (!
M.getModuleInlineAsm().empty()) {
954 std::string NewIA =
".lto_discard";
955 if (!NonPrevailingAsmSymbols.
empty()) {
959 if (!NonPrevailingAsmSymbols.
count(Alias))
962 NewIA +=
" " + llvm::join(NonPrevailingAsmSymbols,
", ");
965 M.setModuleInlineAsm(NewIA +
M.getModuleInlineAsm());
969 return std::move(
Mod);
972Error LTO::linkRegularLTO(RegularLTOState::AddedModule
Mod,
973 bool LivenessFromIndex) {
974 std::vector<GlobalValue *>
Keep;
976 if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->
getGUID())) {
977 if (
Function *
F = dyn_cast<Function>(GV)) {
978 if (DiagnosticOutputFile) {
979 if (
Error Err =
F->materialize())
984 <<
" not added to the combined module ");
998 RegularLTO.CombinedModule->getNamedValue(GV->
getName());
1005 return RegularLTO.Mover->move(std::move(
Mod.M),
Keep,
nullptr,
1018 if (!
Sym.getIRName().empty()) {
1029 return ThinLTO.PrevailingModuleForGUID[GUID] ==
1030 BM.getModuleIdentifier();
1039 if (!
Sym.getIRName().empty()) {
1043 assert(ThinLTO.PrevailingModuleForGUID[GUID] ==
1051 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(
1059 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(
1061 S->setDSOLocal(
true);
1067 if (!ThinLTO.ModuleMap.insert({BM.getModuleIdentifier(), BM}).second)
1068 return make_error<StringError>(
1069 "Expected at most one ThinLTO module per bitcode file",
1073 if (!ThinLTO.ModulesToCompile)
1074 ThinLTO.ModulesToCompile = ModuleMapType();
1090 CalledGetMaxTasks =
true;
1091 auto ModuleCount = ThinLTO.ModulesToCompile ? ThinLTO.ModulesToCompile->size()
1092 : ThinLTO.ModuleMap.size();
1093 return RegularLTO.ParallelCodeGenParallelismLevel + ModuleCount;
1098Error LTO::checkPartiallySplit() {
1099 if (!ThinLTO.CombinedIndex.partiallySplitLTOUnits())
1102 Function *TypeTestFunc = RegularLTO.CombinedModule->getFunction(
1104 Function *TypeCheckedLoadFunc = RegularLTO.CombinedModule->getFunction(
1106 Function *TypeCheckedLoadRelativeFunc =
1107 RegularLTO.CombinedModule->getFunction(
1112 if ((TypeTestFunc && !TypeTestFunc->
use_empty()) ||
1113 (TypeCheckedLoadFunc && !TypeCheckedLoadFunc->
use_empty()) ||
1114 (TypeCheckedLoadRelativeFunc &&
1115 !TypeCheckedLoadRelativeFunc->
use_empty()))
1116 return make_error<StringError>(
1117 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1122 for (
auto &
P : ThinLTO.CombinedIndex) {
1123 for (
auto &S :
P.second.SummaryList) {
1124 auto *FS = dyn_cast<FunctionSummary>(S.get());
1127 if (!FS->type_test_assume_vcalls().empty() ||
1128 !FS->type_checked_load_vcalls().empty() ||
1129 !FS->type_test_assume_const_vcalls().empty() ||
1130 !FS->type_checked_load_const_vcalls().empty() ||
1131 !FS->type_tests().empty())
1132 return make_error<StringError>(
1133 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1144 for (
auto &Res : *GlobalResolutions) {
1147 if (Res.second.IRName.empty())
1153 if (Res.second.VisibleOutsideSummary && Res.second.
Prevailing)
1154 GUIDPreservedSymbols.
insert(GUID);
1157 DynamicExportSymbols.insert(GUID);
1159 GUIDPrevailingResolutions[GUID] =
1164 auto It = GUIDPrevailingResolutions.
find(
G);
1165 if (It == GUIDPrevailingResolutions.
end())
1174 if (!StatsFileOrErr)
1175 return StatsFileOrErr.takeError();
1176 std::unique_ptr<ToolOutputFile> StatsFile = std::move(StatsFileOrErr.get());
1184 ThinLTO.CombinedIndex.setWithSupportsHotColdNew();
1186 Error Result = runRegularLTO(AddStream);
1190 Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols);
1200 if (
Index.withSupportsHotColdNew())
1208 for (
auto &
F :
Mod) {
1209 for (
auto &BB :
F) {
1210 for (
auto &
I : BB) {
1211 auto *CI = dyn_cast<CallBase>(&
I);
1214 if (CI->hasFnAttr(
"memprof"))
1215 CI->removeFnAttr(
"memprof");
1222 CI->setMetadata(LLVMContext::MD_memprof,
nullptr);
1223 CI->setMetadata(LLVMContext::MD_callsite,
nullptr);
1237 return DiagFileOrErr.takeError();
1238 DiagnosticOutputFile = std::move(*DiagFileOrErr);
1242 for (
auto &M : RegularLTO.ModsWithSummaries)
1243 if (
Error Err = linkRegularLTO(std::move(M),
1251 if (
Error Err = checkPartiallySplit())
1256 const DataLayout &
DL = RegularLTO.CombinedModule->getDataLayout();
1257 for (
auto &
I : RegularLTO.Commons) {
1258 if (!
I.second.Prevailing)
1261 GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(
I.first);
1262 if (OldGV &&
DL.getTypeAllocSize(OldGV->
getValueType()) ==
I.second.Size) {
1270 auto *GV =
new GlobalVariable(*RegularLTO.CombinedModule, Ty,
false,
1273 GV->setAlignment(
I.second.Alignment);
1285 bool WholeProgramVisibilityEnabledInLTO =
1294 auto It = GlobalResolutions->find(
name);
1295 return (It == GlobalResolutions->end() || It->second.VisibleOutsideSummary);
1301 *RegularLTO.CombinedModule, WholeProgramVisibilityEnabledInLTO,
1303 IsVisibleToRegularObj);
1305 WholeProgramVisibilityEnabledInLTO);
1312 for (
const auto &R : *GlobalResolutions) {
1314 RegularLTO.CombinedModule->getNamedValue(
R.second.IRName);
1315 if (!
R.second.isPrevailingIRSymbol())
1317 if (
R.second.Partition != 0 &&
1318 R.second.Partition != GlobalResolution::External)
1353 backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,
1354 *RegularLTO.CombinedModule, ThinLTO.CombinedIndex))
1365 [](
const char *
Name) { return Name; });
1366 return LibcallSymbols;
1383 : Conf(Conf), CombinedIndex(CombinedIndex),
1384 ModuleToDefinedGVSummaries(ModuleToDefinedGVSummaries),
1385 OnWrite(OnWrite), ShouldEmitImportsFiles(ShouldEmitImportsFiles) {}
1392 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1400 const std::string &NewModulePath) {
1401 std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
1406 ImportList, ModuleToSummariesForIndex,
1407 DeclarationSummaries);
1410 sys::fs::OpenFlags::OF_None);
1415 &DeclarationSummaries);
1417 if (ShouldEmitImportsFiles) {
1419 ModuleToSummariesForIndex);
1432 std::set<GlobalValue::GUID> CfiFunctionDefs;
1433 std::set<GlobalValue::GUID> CfiFunctionDecls;
1435 std::optional<Error> Err;
1438 bool ShouldEmitIndexFiles;
1441 InProcessThinBackend(
1446 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles)
1448 OnWrite, ShouldEmitImportsFiles),
1449 BackendThreadPool(ThinLTOParallelism), AddStream(
std::
move(AddStream)),
1450 Cache(
std::
move(Cache)), ShouldEmitIndexFiles(ShouldEmitIndexFiles) {
1452 CfiFunctionDefs.insert(
1455 CfiFunctionDecls.insert(
1459 Error runThinLTOBackendThread(
1464 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1467 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1473 return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,
1474 ImportList, DefinedGlobals, &ModuleMap);
1479 if (ShouldEmitIndexFiles) {
1480 if (
auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1486 [](
uint32_t V) { return V == 0; }))
1489 return RunThinBackend(AddStream);
1494 ExportList, ResolvedODR, DefinedGlobals, CfiFunctionDefs,
1499 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1501 return RunThinBackend(CacheAddStream);
1510 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1513 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
1515 ModuleToDefinedGVSummaries.
find(ModulePath)->second;
1516 BackendThreadPool.
async(
1520 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
1527 Error E = runThinLTOBackendThread(
1528 AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList,
1529 ResolvedODR, DefinedGlobals, ModuleMap);
1531 std::unique_lock<std::mutex>
L(ErrMu);
1540 BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList),
1541 std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap));
1544 OnWrite(std::string(ModulePath));
1548 Error wait()
override {
1549 BackendThreadPool.
wait();
1551 return std::move(*Err);
1564 bool ShouldEmitIndexFiles,
1565 bool ShouldEmitImportsFiles) {
1570 return std::make_unique<InProcessThinBackend>(
1571 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1572 AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
1573 ShouldEmitImportsFiles);
1598 return std::string(Path);
1602 if (!ParentPath.
empty()) {
1605 llvm::errs() <<
"warning: could not create directory '" << ParentPath
1606 <<
"': " << EC.message() <<
'\n';
1608 return std::string(NewPath);
1613 std::string OldPrefix, NewPrefix, NativeObjectPrefix;
1617 WriteIndexesThinBackend(
1620 std::string OldPrefix, std::string NewPrefix,
1621 std::string NativeObjectPrefix,
bool ShouldEmitImportsFiles,
1624 OnWrite, ShouldEmitImportsFiles),
1625 OldPrefix(OldPrefix), NewPrefix(NewPrefix),
1626 NativeObjectPrefix(NativeObjectPrefix),
1627 LinkedObjectsFile(LinkedObjectsFile) {}
1633 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1636 std::string NewModulePath =
1639 if (LinkedObjectsFile) {
1640 std::string ObjectPrefix =
1641 NativeObjectPrefix.empty() ? NewPrefix : NativeObjectPrefix;
1642 std::string LinkedObjectsFilePath =
1644 *LinkedObjectsFile << LinkedObjectsFilePath <<
'\n';
1647 if (
auto E = emitFiles(ImportList, ModulePath, NewModulePath))
1651 OnWrite(std::string(ModulePath));
1664 std::string OldPrefix, std::string NewPrefix,
1665 std::string NativeObjectPrefix,
bool ShouldEmitImportsFiles,
1671 return std::make_unique<WriteIndexesThinBackend>(
1672 Conf, CombinedIndex, ModuleToDefinedGVSummaries, OldPrefix,
1673 NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,
1674 LinkedObjectsFile, OnWrite);
1681 ThinLTO.CombinedIndex.releaseTemporaryMemory();
1687 if (ThinLTO.ModuleMap.empty())
1690 if (ThinLTO.ModulesToCompile && ThinLTO.ModulesToCompile->empty()) {
1691 llvm::errs() <<
"warning: [ThinLTO] No module compiled\n";
1702 ThinLTO.ModuleMap.size());
1703 ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule(
1704 ModuleToDefinedGVSummaries);
1712 for (
auto &
Mod : ThinLTO.ModuleMap)
1713 if (!ModuleToDefinedGVSummaries.
count(
Mod.first))
1720 ThinLTO.ModuleMap.size());
1722 ThinLTO.ModuleMap.size());
1726 ThinLTO.CombinedIndex.dumpSCCs(
outs());
1728 std::set<GlobalValue::GUID> ExportedGUIDs;
1730 bool WholeProgramVisibilityEnabledInLTO =
1736 ThinLTO.CombinedIndex.setWithWholeProgramVisibility();
1742 if (WholeProgramVisibilityEnabledInLTO &&
1747 auto It = GlobalResolutions->
find(
name);
1748 return (It == GlobalResolutions->end() ||
1749 It->second.VisibleOutsideSummary);
1753 VisibleToRegularObjSymbols,
1754 IsVisibleToRegularObj);
1760 ThinLTO.CombinedIndex, WholeProgramVisibilityEnabledInLTO,
1761 DynamicExportSymbols, VisibleToRegularObjSymbols);
1766 std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;
1768 LocalWPDTargetsMap);
1771 return ThinLTO.PrevailingModuleForGUID[
GUID] == S->modulePath();
1775 ContextDisambiguation.
run(ThinLTO.CombinedIndex, isPrevailing);
1782 for (
auto &Res : *GlobalResolutions) {
1785 if (Res.second.Partition != GlobalResolution::External ||
1786 !Res.second.isPrevailingIRSymbol())
1791 if (ThinLTO.CombinedIndex.isGUIDLive(GUID))
1792 ExportedGUIDs.insert(GUID);
1799 GlobalResolutions.reset();
1803 isPrevailing, ImportLists, ExportLists);
1807 for (
auto &Def : ThinLTO.CombinedIndex.cfiFunctionDefs())
1808 ExportedGUIDs.insert(
1810 for (
auto &Decl : ThinLTO.CombinedIndex.cfiFunctionDecls())
1811 ExportedGUIDs.insert(
1815 const auto &ExportList = ExportLists.
find(ModuleIdentifier);
1816 return (ExportList != ExportLists.end() && ExportList->second.
count(VI)) ||
1817 ExportedGUIDs.count(
VI.getGUID());
1823 LocalWPDTargetsMap);
1828 auto recordNewLinkage = [&](
StringRef ModuleIdentifier,
1831 ResolvedODR[ModuleIdentifier][
GUID] = NewLinkage;
1834 recordNewLinkage, GUIDPreservedSymbols);
1843 TimeTraceScopeExit.release();
1845 std::unique_ptr<ThinBackendProc> BackendProc =
1846 ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
1850 ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;
1852 auto ProcessOneModule = [&](
int I) ->
Error {
1856 return BackendProc->start(RegularLTO.ParallelCodeGenParallelismLevel +
I,
1857 Mod.second, ImportLists[
Mod.first],
1858 ExportLists[
Mod.first], ResolvedODR[
Mod.first],
1862 if (BackendProc->getThreadCount() == 1) {
1867 for (
int I = 0, E = ModuleMap.
size();
I != E; ++
I)
1868 if (
Error E = ProcessOneModule(
I))
1875 std::vector<BitcodeModule *> ModulesVec;
1876 ModulesVec.reserve(ModuleMap.
size());
1877 for (
auto &
Mod : ModuleMap)
1878 ModulesVec.push_back(&
Mod.second);
1880 if (
Error E = ProcessOneModule(
I))
1883 return BackendProc->wait();
1893 if (!Filename.empty() && Count != -1)
1901 if (
Error E = ResultOrErr.takeError())
1902 return std::move(E);
1905 (*ResultOrErr)->keep();
1913 if (StatsFilename.
empty())
1924 return std::move(StatsFile);
1931 auto Seq = llvm::seq<int>(0, R.size());
1932 std::vector<int> ModulesOrdering(Seq.begin(), Seq.end());
1933 llvm::sort(ModulesOrdering, [&](
int LeftIndex,
int RightIndex) {
1934 auto LSize = R[LeftIndex]->getBuffer().
size();
1935 auto RSize = R[RightIndex]->getBuffer().
size();
1936 return LSize > RSize;
1938 return ModulesOrdering;
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static void writeToResolutionFile(raw_ostream &OS, InputFile *Input, ArrayRef< SymbolResolution > Res)
static void thinLTOResolvePrevailingGUID(const Config &C, ValueInfo VI, DenseSet< GlobalValueSummary * > &GlobalInvolvedWithAlias, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, function_ref< void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> recordNewLinkage, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols)
static void handleNonPrevailingComdat(GlobalValue &GV, std::set< const Comdat * > &NonPrevailingComdats)
static cl::opt< bool > DumpThinCGSCCs("dump-thin-cg-sccs", cl::init(false), cl::Hidden, cl::desc("Dump the SCCs in the ThinLTO index's callgraph"))
static void thinLTOInternalizeAndPromoteGUID(ValueInfo VI, function_ref< bool(StringRef, ValueInfo)> isExported, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
cl::opt< bool > UseNewDbgInfoFormat
llvm::cl::opt< bool > UseNewDbgInfoFormat
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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),...
static 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
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.
Expected< std::unique_ptr< Module > > parseModule(LLVMContext &Context, ParserCallbacks Callbacks={})
Read the entire bitcode module and return it.
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 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.
std::unordered_map< GlobalValue::GUID, GlobalValueSummary::ImportKind > FunctionsToImportTy
The functions to import from a source module and their import type.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalObject.
Function and variable summary information to aid decisions and implementation of importing.
static bool isAppendingLinkage(LinkageTypes Linkage)
static bool isExternalWeakLinkage(LinkageTypes Linkage)
static bool isLocalLinkage(LinkageTypes Linkage)
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
void setUnnamedAddr(UnnamedAddr Val)
bool hasLocalLinkage() const
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
const Comdat * getComdat() const
static bool isLinkOnceLinkage(LinkageTypes Linkage)
static GUID getGUID(StringRef GlobalName)
Return a 64-bit global unique ID constructed from global value name (i.e.
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.
const GlobalObject * getAliaseeObject() const
static bool isExternalLinkage(LinkageTypes Linkage)
VisibilityTypes
An enumeration for the kinds of visibility of global values.
@ DefaultVisibility
The GV is visible.
static LinkageTypes getWeakLinkage(bool ODR)
bool isWeakForLinker() const
bool hasAppendingLinkage() const
bool hasAvailableExternallyLinkage() const
std::string getGlobalIdentifier() const
Return the modified name for this global value suitable to be used as the key for a global lookup (e....
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)
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
This is an important class for using LLVM in a threaded context.
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...
std::set< std::string > & cfiFunctionDecls()
const ModuleHash & getModuleHash(const StringRef ModPath) const
Get the module SHA1 hash recorded for the given module path.
const StringMap< ModuleHash > & modulePaths() const
Table of modules, containing module hash and id.
std::set< std::string > & cfiFunctionDefs()
void addModule(Module *M)
static 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.
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 discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...
A class that wrap the SHA1 algorithm.
void update(ArrayRef< uint8_t > Data)
Digest more data.
std::array< uint8_t, 20 > result()
Return the current raw 160-bits SHA1 for the digested data since the last call to init().
A non-threaded implementation.
void wait() override
Blocking wait for all the tasks to execute first.
unsigned getMaxConcurrency() const override
Returns always 1: there is no concurrency.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
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.
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...
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
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.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
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.
auto async(Function &&F, Args &&...ArgList)
Asynchronous submission of a task to the pool.
This tells how a thread pool will be used.
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 isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, XROS, or DriverKit).
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 IntegerType * getInt8Ty(LLVMContext &C)
void setName(const Twine &Name)
Change the name of the value.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
StringRef getName() const
Return a constant reference to the value's name.
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)
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().
Error add(std::unique_ptr< InputFile > Obj, ArrayRef< SymbolResolution > Res)
Add an input file to the LTO link, using the provided symbol resolutions.
static 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...
LTO(Config Conf, ThinBackend Backend=nullptr, unsigned ParallelCodeGenParallelismLevel=1, LTOKind LTOMode=LTOK_Default)
Create an LTO object.
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.
Error run(AddStreamFn AddStream, FileCache Cache=nullptr)
Runs the LTO pipeline.
unsigned getMaxTasks() const
Returns an upper bound on the number of tasks that the client may expect.
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.
This class defines the interface to the ThinLTO backend.
virtual unsigned getThreadCount()=0
bool ShouldEmitImportsFiles
lto::IndexWriteCallback OnWrite
Error emitFiles(const FunctionImporter::ImportMapTy &ImportList, llvm::StringRef ModulePath, const std::string &NewModulePath)
ThinBackendProc(const Config &Conf, ModuleSummaryIndex &CombinedIndex, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, lto::IndexWriteCallback OnWrite, bool ShouldEmitImportsFiles)
const DenseMap< StringRef, GVSummaryMapTy > & ModuleToDefinedGVSummaries
ModuleSummaryIndex & CombinedIndex
virtual ~ThinBackendProc()=default
virtual Error start(unsigned Task, BitcodeModule BM, const FunctionImporter::ImportMapTy &ImportList, const FunctionImporter::ExportSetTy &ExportList, const std::map< GlobalValue::GUID, GlobalValue::LinkageTypes > &ResolvedODR, MapVector< StringRef, BitcodeModule > &ModuleMap)=0
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
StringRef getName(ID id)
Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
initializer< Ty > init(const Ty &Val)
ThinBackend createInProcessThinBackend(ThreadPoolStrategy Parallelism, IndexWriteCallback OnWrite=nullptr, bool ShouldEmitIndexFiles=false, bool ShouldEmitImportsFiles=false)
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, const std::vector< uint8_t > &CmdArgs=std::vector< uint8_t >())
Runs a ThinLTO backend.
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.
std::function< std::unique_ptr< ThinBackendProc >(const Config &C, ModuleSummaryIndex &CombinedIndex, DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, AddStreamFn AddStream, FileCache Cache)> ThinBackend
A ThinBackend defines what happens after the thin-link phase during ThinLTO.
std::function< void(const std::string &)> IndexWriteCallback
This ThinBackend runs the individual backend jobs in-process.
StringLiteral getThinLTODefaultCPU(const Triple &TheTriple)
Expected< std::unique_ptr< ToolOutputFile > > setupStatsFile(StringRef StatsFilename)
Setups the output file for saving statistics.
Error backend(const Config &C, AddStreamFn AddStream, unsigned ParallelCodeGenParallelismLevel, Module &M, ModuleSummaryIndex &CombinedIndex)
Runs a regular LTO backend.
Error finalizeOptimizationRemarks(std::unique_ptr< ToolOutputFile > DiagOutputFile)
ThinBackend createWriteIndexesThinBackend(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...
std::vector< int > generateModulesOrdering(ArrayRef< BitcodeModule * > R)
Produces a container ordering for optimal multi-threaded processing.
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.
void updateMemProfAttributes(Module &Mod, const ModuleSummaryIndex &Index)
Updates MemProf attributes (and metadata) based on whether the index has recorded that we are linking...
Expected< IRSymtabFile > readIRSymtab(MemoryBufferRef MBRef)
Reads a bitcode file, creating its irsymtab if necessary.
void write64le(void *P, uint64_t V)
void write32le(void *P, uint32_t V)
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.
StringRef parent_path(StringRef path, Style style=Style::native)
Get parent path.
bool replace_path_prefix(SmallVectorImpl< char > &Path, StringRef OldPrefix, StringRef NewPrefix, Style style=Style::native)
Replace matching path prefix with another path.
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.
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.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
void gatherImportedSummariesForModule(StringRef ModulePath, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, const FunctionImporter::ImportMapTy &ImportList, std::map< std::string, GVSummaryMapTy > &ModuleToSummariesForIndex, GVSummaryPtrSet &DecSummaries)
Compute the set of summaries needed for a ThinLTO backend compilation of ModulePath.
void ComputeCrossModuleImport(const ModuleSummaryIndex &Index, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, DenseMap< StringRef, FunctionImporter::ImportMapTy > &ImportLists, DenseMap< StringRef, FunctionImporter::ExportSetTy > &ExportLists)
Compute all the imports and exports for every module in the Index.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
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"))
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
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.
std::error_code EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename, const std::map< std::string, GVSummaryMapTy > &ModuleToSummariesForIndex)
Emit into OutputFilename the files module ModulePath will import from.
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.
OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P)
Provide wrappers to std::copy_if which take ranges instead of having to pass begin/end explicitly.
bool hasWholeProgramVisibility(bool WholeProgramVisibilityEnabledInLTO)
void EnableStatistics(bool DoPrintOnExit=true)
Enable the collection and printing of statistics.
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...
void computeLTOCacheKey(SmallString< 40 > &Key, 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 std::set< GlobalValue::GUID > &CfiFunctionDefs={}, const std::set< GlobalValue::GUID > &CfiFunctionDecls={})
Computes a unique hash for the Module considering the current list of export/import and other global ...
void timeTraceProfilerInitialize(unsigned TimeTraceGranularity, StringRef ProcName, bool TimeTraceVerbose=false)
Initialize the time trace profiler.
void timeTraceProfilerFinishThread()
Finish a time trace profiler running on a worker thread.
Error joinErrors(Error E1, Error E2)
Concatenate errors.
void updatePublicTypeTestCalls(Module &M, bool WholeProgramVisibilityEnabledInLTO)
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)
void writeIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out, const std::map< std::string, GVSummaryMapTy > *ModuleToSummariesForIndex=nullptr, const GVSummaryPtrSet *DecSummaries=nullptr)
Write the specified module summary index to the given raw output stream, where it will be written in ...
bool timeTraceProfilerEnabled()
Is the time trace profiler enabled, i.e. initialized?
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
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.
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)
void computeSyntheticCounts(ModuleSummaryIndex &Index)
Compute synthetic function entry counts.
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.
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...
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.
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.
cl::opt< bool > EnableMemProfContextDisambiguation
Enable MemProf context disambiguation for thin link.
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.
std::unordered_set< GlobalValueSummary * > GVSummaryPtrSet
A set of global value summary pointers.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
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)
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
bool UpgradeDebugInfo(Module &M)
Check the debug info version number, if it is out-dated, drop the debug info.
std::array< uint32_t, 5 > ModuleHash
160 bits SHA1
std::function< Expected< AddStreamFn >(unsigned Task, StringRef Key, const Twine &ModuleName)> FileCache
This is the type of a file cache.
void PrintStatisticsJSON(raw_ostream &OS)
Print statistics in JSON format.
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.
@ Keep
No function return thunk.
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...
TimeTraceProfilerEntry * timeTraceProfilerBegin(StringRef Name, StringRef Detail)
Manually begin a time section, with the given Name and Detail.
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 struct is a compact representation of a valid (non-zero power of two) alignment.
Used in the streaming interface as the general argument type.
A simple container for information about the supported runtime calls.
iterator_range< const char ** > getLibcallNames()
Struct that holds a reference to a particular GUID in a global value summary.
bool HasWholeProgramVisibility
Asserts whether we can assume whole program visibility during the LTO link.
bool ValidateAllVtablesHaveTypeInfos
We're validating that all native vtables have corresponding type infos.
std::optional< uint64_t > RemarksHotnessThreshold
The minimum hotness value a diagnostic needs in order to be included in optimization diagnostics.
std::string StatsFile
Statistics output file path.
ModuleHookFn PreOptModuleHook
This module hook is called after linking (regular LTO) or loading (ThinLTO) the module,...
CombinedIndexHookFn CombinedIndexHook
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
std::vector< std::string > ThinLTOModulesToCompile
Specific thinLTO modules to compile.
CodeGenOptLevel CGOptLevel
std::unique_ptr< raw_ostream > ResolutionFile
If this field is set, LTO will write input file paths and symbol resolutions here in llvm-lto2 comman...
std::string DefaultTriple
Setting this field will replace unspecified target triples in input files with this triple.
bool AlwaysEmitRegularLTOObj
Always emit a Regular LTO object even when it is empty because no Regular LTO modules were linked.
std::string DwoDir
The directory to store .dwo files.
std::string RemarksFilename
Optimization remarks file path.
VisScheme VisibilityScheme
Allows non-imported definitions to get the potentially more constraining visibility from the prevaili...
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 AllVtablesHaveTypeInfos
If all native vtables have corresponding type infos, allow usage of RTTI to block devirtualization on...
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 ...
ModuleHookFn PostInternalizeModuleHook
This hook is called after internalizing the module.
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).
A derived class of LLVMContext that initializes itself according to a given Config object.
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.