25#include "llvm/Config/llvm-config.h"
50#include "llvm/Support/VCSRevision.h"
64using namespace object;
66#define DEBUG_TYPE "lto"
70 cl::desc(
"Dump the SCCs in the ThinLTO index's callgraph"));
76 cl::desc(
"Enable global value internalization in LTO"));
93 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
95 const std::set<GlobalValue::GUID> &CfiFunctionDefs,
96 const std::set<GlobalValue::GUID> &CfiFunctionDecls) {
104 Hasher.
update(LLVM_VERSION_STRING);
106 Hasher.
update(LLVM_REVISION);
114 auto AddUnsigned = [&](
unsigned I) {
145 AddUnsigned(
static_cast<int>(Conf.
CGOptLevel));
146 AddUnsigned(
static_cast<int>(Conf.
CGFileType));
156 auto ModHash =
Index.getModuleHash(ModuleID);
159 std::vector<uint64_t> ExportsGUID;
160 ExportsGUID.reserve(ExportList.
size());
161 for (
const auto &VI : ExportList) {
162 auto GUID = VI.getGUID();
163 ExportsGUID.push_back(GUID);
177 struct ImportModule {
178 ImportMapIteratorTy ModIt;
181 StringRef getIdentifier()
const {
return ModIt->getFirst(); }
183 return ModIt->second;
189 std::vector<ImportModule> ImportModulesVector;
190 ImportModulesVector.reserve(ImportList.
size());
192 for (ImportMapIteratorTy It = ImportList.
begin(); It != ImportList.
end();
194 ImportModulesVector.push_back({It,
Index.getModule(It->getFirst())});
199 [](
const ImportModule &Lhs,
const ImportModule &Rhs) ->
bool {
200 return Lhs.getHash() < Rhs.getHash();
202 for (
const ImportModule &Entry : ImportModulesVector) {
203 auto ModHash = Entry.getHash();
206 AddUint64(Entry.getFunctions().size());
207 for (
auto &Fn : Entry.getFunctions())
212 for (
auto &Entry : ResolvedODR) {
221 std::set<GlobalValue::GUID> UsedCfiDefs;
222 std::set<GlobalValue::GUID> UsedCfiDecls;
225 std::set<GlobalValue::GUID> UsedTypeIds;
228 if (CfiFunctionDefs.count(ValueGUID))
229 UsedCfiDefs.insert(ValueGUID);
230 if (CfiFunctionDecls.count(ValueGUID))
231 UsedCfiDecls.insert(ValueGUID);
236 AddUnsigned(GS->getVisibility());
237 AddUnsigned(GS->isLive());
238 AddUnsigned(GS->canAutoHide());
240 AddUnsigned(VI.isDSOLocal(
Index.withDSOLocalPropagation()));
241 AddUsedCfiGlobal(VI.getGUID());
243 if (
auto *GVS = dyn_cast<GlobalVarSummary>(GS)) {
244 AddUnsigned(GVS->maybeReadOnly());
245 AddUnsigned(GVS->maybeWriteOnly());
247 if (
auto *FS = dyn_cast<FunctionSummary>(GS)) {
248 for (
auto &TT : FS->type_tests())
249 UsedTypeIds.insert(TT);
250 for (
auto &TT : FS->type_test_assume_vcalls())
251 UsedTypeIds.insert(TT.GUID);
252 for (
auto &TT : FS->type_checked_load_vcalls())
253 UsedTypeIds.insert(TT.GUID);
254 for (
auto &TT : FS->type_test_assume_const_vcalls())
255 UsedTypeIds.insert(TT.VFunc.GUID);
256 for (
auto &TT : FS->type_checked_load_const_vcalls())
257 UsedTypeIds.insert(TT.VFunc.GUID);
258 for (
auto &ET : FS->calls()) {
259 AddUnsigned(ET.first.isDSOLocal(
Index.withDSOLocalPropagation()));
260 AddUsedCfiGlobal(ET.first.getGUID());
267 for (
auto &GS : DefinedGlobals) {
271 AddUsedCfiGlobal(GS.first);
272 AddUsedThings(GS.second);
277 for (
const ImportModule &ImpM : ImportModulesVector)
278 for (
auto &ImpF : ImpM.getFunctions()) {
280 Index.findSummaryInModule(ImpF, ImpM.getIdentifier());
284 if (
auto *AS = dyn_cast_or_null<AliasSummary>(S))
285 AddUsedThings(AS->getBaseObject());
291 AddUnsigned(S.TTRes.TheKind);
292 AddUnsigned(S.TTRes.SizeM1BitWidth);
294 AddUint64(S.TTRes.AlignLog2);
295 AddUint64(S.TTRes.SizeM1);
296 AddUint64(S.TTRes.BitMask);
297 AddUint64(S.TTRes.InlineBits);
299 AddUint64(S.WPDRes.size());
300 for (
auto &WPD : S.WPDRes) {
301 AddUnsigned(WPD.first);
302 AddUnsigned(WPD.second.TheKind);
303 AddString(WPD.second.SingleImplName);
305 AddUint64(WPD.second.ResByArg.size());
306 for (
auto &ByArg : WPD.second.ResByArg) {
307 AddUint64(ByArg.first.size());
310 AddUnsigned(ByArg.second.TheKind);
311 AddUint64(ByArg.second.Info);
312 AddUnsigned(ByArg.second.Byte);
313 AddUnsigned(ByArg.second.Bit);
320 auto TidIter =
Index.typeIds().equal_range(TId);
321 for (
auto It = TidIter.first; It != TidIter.second; ++It)
322 AddTypeIdSummary(It->second.first, It->second.second);
325 AddUnsigned(UsedCfiDefs.size());
326 for (
auto &V : UsedCfiDefs)
329 AddUnsigned(UsedCfiDecls.size());
330 for (
auto &V : UsedCfiDecls)
336 Hasher.
update(FileOrErr.get()->getBuffer());
341 Hasher.
update(FileOrErr.get()->getBuffer());
346 Key = toHex(Hasher.
result());
358 C.VisibilityScheme ==
Config::ELF ? VI.getELFVisibility()
360 for (
auto &S : VI.getSummaryList()) {
375 if (isPrevailing(VI.getGUID(), S.get())) {
388 S->setCanAutoHide(VI.canAutoHide() &&
389 !GUIDPreservedSymbols.
count(VI.getGUID()));
392 Visibility = S->getVisibility();
395 else if (!isa<AliasSummary>(S.get()) &&
396 !GlobalInvolvedWithAlias.
count(S.get()))
403 S->setVisibility(Visibility);
405 if (S->linkage() != OriginalLinkage)
406 recordNewLinkage(S->modulePath(), VI.getGUID(), S->linkage());
410 for (
auto &S : VI.getSummaryList()) {
415 S->setVisibility(Visibility);
438 for (
auto &S :
I.second.SummaryList)
439 if (
auto AS = dyn_cast<AliasSummary>(S.get()))
440 GlobalInvolvedWithAlias.
insert(&AS->getAliasee());
444 GlobalInvolvedWithAlias, isPrevailing,
445 recordNewLinkage, GUIDPreservedSymbols);
452 auto ExternallyVisibleCopies =
454 [](
const std::unique_ptr<GlobalValueSummary> &Summary) {
455 return !GlobalValue::isLocalLinkage(Summary->linkage());
458 for (
auto &S : VI.getSummaryList()) {
461 if (isExported(S->modulePath(), VI)) {
520 if (isPrevailing(VI.getGUID(), S.get()) && ExternallyVisibleCopies == 1)
541 std::unique_ptr<InputFile> File(
new InputFile);
547 File->TargetTriple = FOrErr->TheReader.getTargetTriple();
548 File->SourceFileName = FOrErr->TheReader.getSourceFileName();
549 File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts();
550 File->DependentLibraries = FOrErr->TheReader.getDependentLibraries();
551 File->ComdatTable = FOrErr->TheReader.getComdatTable();
553 for (
unsigned I = 0;
I != FOrErr->Mods.size(); ++
I) {
554 size_t Begin = File->Symbols.size();
556 FOrErr->TheReader.module_symbols(
I))
559 if (
Sym.isGlobal() && !
Sym.isFormatSpecific())
560 File->Symbols.push_back(
Sym);
561 File->ModuleSymIndices.push_back({Begin, File->Symbols.size()});
564 File->Mods = FOrErr->Mods;
565 File->Strtab = std::move(FOrErr->Strtab);
566 return std::move(File);
570 return Mods[0].getModuleIdentifier();
574 assert(Mods.size() == 1 &&
"Expect only one bitcode module");
578LTO::RegularLTOState::RegularLTOState(
unsigned ParallelCodeGenParallelismLevel,
580 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
581 Ctx(Conf), CombinedModule(
std::make_unique<
Module>(
"ld-temp.o", Ctx)),
582 Mover(
std::make_unique<
IRMover>(*CombinedModule)) {}
584LTO::ThinLTOState::ThinLTOState(
ThinBackend Backend)
585 : Backend(Backend), CombinedIndex(
false) {
592 unsigned ParallelCodeGenParallelismLevel,
LTOKind LTOMode)
594 RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),
595 ThinLTO(
std::
move(Backend)), LTOMode(LTOMode) {}
604 unsigned Partition,
bool InSummary) {
605 auto *ResI = Res.
begin();
606 auto *ResE = Res.
end();
608 const Triple TT(RegularLTO.CombinedModule->getTargetTriple());
613 auto &GlobalRes = GlobalResolutions[
Sym.getName()];
614 GlobalRes.UnnamedAddr &=
Sym.isUnnamedAddr();
616 assert(!GlobalRes.Prevailing &&
617 "Multiple prevailing defs are not allowed");
618 GlobalRes.Prevailing =
true;
619 GlobalRes.IRName = std::string(
Sym.getIRName());
620 }
else if (!GlobalRes.Prevailing && GlobalRes.IRName.empty()) {
627 GlobalRes.IRName = std::string(
Sym.getIRName());
641 if (GlobalRes.IRName !=
Sym.getIRName()) {
642 GlobalRes.Partition = GlobalResolution::External;
643 GlobalRes.VisibleOutsideSummary =
true;
651 (GlobalRes.Partition != GlobalResolution::Unknown &&
652 GlobalRes.Partition != Partition)) {
653 GlobalRes.Partition = GlobalResolution::External;
656 GlobalRes.Partition = Partition;
660 GlobalRes.VisibleOutsideSummary |=
671 auto ResI = Res.
begin();
676 OS <<
"-r=" << Path <<
',' <<
Sym.getName() <<
',';
693 assert(!CalledGetMaxTasks);
698 if (RegularLTO.CombinedModule->getTargetTriple().empty()) {
699 RegularLTO.CombinedModule->setTargetTriple(Input->getTargetTriple());
705 for (
unsigned I = 0;
I != Input->Mods.size(); ++
I)
706 if (
Error Err = addModule(*Input,
I, ResI, Res.
end()))
720 if (EnableSplitLTOUnit) {
724 if (*EnableSplitLTOUnit != LTOInfo->EnableSplitLTOUnit)
725 ThinLTO.CombinedIndex.setPartiallySplitLTOUnits();
727 EnableSplitLTOUnit = LTOInfo->EnableSplitLTOUnit;
732 !LTOInfo->UnifiedLTO)
733 return make_error<StringError>(
734 "unified LTO compilation must use "
735 "compatible bitcode modules (use -funified-lto)",
743 auto ModSyms = Input.module_symbols(ModI);
744 addModuleToGlobalRes(ModSyms, {ResI, ResE},
745 IsThinLTO ? ThinLTO.ModuleMap.size() + 1 : 0,
746 LTOInfo->HasSummary);
749 return addThinLTO(BM, ModSyms, ResI, ResE);
751 RegularLTO.EmptyCombinedModule =
false;
753 addRegularLTO(BM, ModSyms, ResI, ResE);
757 if (!LTOInfo->HasSummary)
758 return linkRegularLTO(std::move(*ModOrErr),
false);
764 RegularLTO.ModsWithSummaries.push_back(std::move(*ModOrErr));
780 std::set<const Comdat *> &NonPrevailingComdats) {
785 if (!NonPrevailingComdats.count(
C))
794 if (
auto GO = dyn_cast<GlobalObject>(&GV))
795 GO->setComdat(
nullptr);
805 RegularLTOState::AddedModule
Mod;
812 Mod.M = std::move(*MOrErr);
814 if (
Error Err =
M.materializeMetadata())
815 return std::move(Err);
822 if (
NamedMDNode *CfiFunctionsMD =
M.getNamedMetadata(
"cfi.functions"))
823 M.eraseNamedMetadata(CfiFunctionsMD);
831 if (GV.hasAppendingLinkage())
832 Mod.Keep.push_back(&GV);
835 for (
auto &GA :
M.aliases())
837 AliasedGlobals.
insert(GO);
846 auto MsymI = SymTab.
symbols().begin(), MsymE = SymTab.
symbols().end();
848 while (MsymI != MsymE) {
858 std::set<const Comdat *> NonPrevailingComdats;
868 if (
GlobalValue *GV = dyn_cast_if_present<GlobalValue *>(Msym)) {
870 if (
Sym.isUndefined())
872 Mod.Keep.push_back(GV);
883 }
else if (isa<GlobalObject>(GV) &&
884 (GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||
885 GV->hasAvailableExternallyLinkage()) &&
886 !AliasedGlobals.
count(cast<GlobalObject>(GV))) {
892 Mod.Keep.push_back(GV);
895 NonPrevailingComdats.insert(GV->getComdat());
896 cast<GlobalObject>(GV)->setComdat(
nullptr);
901 GV->setDSOLocal(
true);
902 if (GV->hasDLLImportStorageClass())
904 DefaultStorageClass);
906 }
else if (
auto *AS =
907 dyn_cast_if_present<ModuleSymbolTable::AsmSymbol *>(Msym)) {
910 NonPrevailingAsmSymbols.
insert(AS->first);
918 if (
Sym.isCommon()) {
921 auto &CommonRes = RegularLTO.Commons[std::string(
Sym.getIRName())];
922 CommonRes.Size = std::max(CommonRes.Size,
Sym.getCommonSize());
923 if (
uint32_t SymAlignValue =
Sym.getCommonAlignment()) {
924 CommonRes.Alignment =
925 std::max(
Align(SymAlignValue), CommonRes.Alignment);
931 if (!
M.getComdatSymbolTable().empty())
937 if (!
M.getModuleInlineAsm().empty()) {
938 std::string NewIA =
".lto_discard";
939 if (!NonPrevailingAsmSymbols.
empty()) {
943 if (!NonPrevailingAsmSymbols.
count(Alias))
946 NewIA +=
" " + llvm::join(NonPrevailingAsmSymbols,
", ");
949 M.setModuleInlineAsm(NewIA +
M.getModuleInlineAsm());
953 return std::move(
Mod);
956Error LTO::linkRegularLTO(RegularLTOState::AddedModule
Mod,
957 bool LivenessFromIndex) {
958 std::vector<GlobalValue *>
Keep;
960 if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->
getGUID())) {
961 if (
Function *
F = dyn_cast<Function>(GV)) {
962 if (DiagnosticOutputFile) {
963 if (
Error Err =
F->materialize())
968 <<
" not added to the combined module ");
982 RegularLTO.CombinedModule->getNamedValue(GV->
getName());
989 return RegularLTO.Mover->move(std::move(
Mod.M),
Keep,
nullptr,
1002 if (!
Sym.getIRName().empty()) {
1013 return ThinLTO.PrevailingModuleForGUID[GUID] ==
1014 BM.getModuleIdentifier();
1023 if (!
Sym.getIRName().empty()) {
1027 assert(ThinLTO.PrevailingModuleForGUID[GUID] ==
1035 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(
1043 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(
1045 S->setDSOLocal(
true);
1051 if (!ThinLTO.ModuleMap.insert({BM.getModuleIdentifier(), BM}).second)
1052 return make_error<StringError>(
1053 "Expected at most one ThinLTO module per bitcode file",
1057 if (!ThinLTO.ModulesToCompile)
1058 ThinLTO.ModulesToCompile = ModuleMapType();
1074 CalledGetMaxTasks =
true;
1075 auto ModuleCount = ThinLTO.ModulesToCompile ? ThinLTO.ModulesToCompile->size()
1076 : ThinLTO.ModuleMap.size();
1077 return RegularLTO.ParallelCodeGenParallelismLevel + ModuleCount;
1082Error LTO::checkPartiallySplit() {
1083 if (!ThinLTO.CombinedIndex.partiallySplitLTOUnits())
1086 Function *TypeTestFunc = RegularLTO.CombinedModule->getFunction(
1088 Function *TypeCheckedLoadFunc = RegularLTO.CombinedModule->getFunction(
1090 Function *TypeCheckedLoadRelativeFunc =
1091 RegularLTO.CombinedModule->getFunction(
1096 if ((TypeTestFunc && !TypeTestFunc->
use_empty()) ||
1097 (TypeCheckedLoadFunc && !TypeCheckedLoadFunc->
use_empty()) ||
1098 (TypeCheckedLoadRelativeFunc &&
1099 !TypeCheckedLoadRelativeFunc->
use_empty()))
1100 return make_error<StringError>(
1101 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1106 for (
auto &
P : ThinLTO.CombinedIndex) {
1107 for (
auto &S :
P.second.SummaryList) {
1108 auto *FS = dyn_cast<FunctionSummary>(S.get());
1111 if (!FS->type_test_assume_vcalls().empty() ||
1112 !FS->type_checked_load_vcalls().empty() ||
1113 !FS->type_test_assume_const_vcalls().empty() ||
1114 !FS->type_checked_load_const_vcalls().empty() ||
1115 !FS->type_tests().empty())
1116 return make_error<StringError>(
1117 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1128 for (
auto &Res : GlobalResolutions) {
1131 if (Res.second.IRName.empty())
1137 if (Res.second.VisibleOutsideSummary && Res.second.
Prevailing)
1138 GUIDPreservedSymbols.
insert(GUID);
1141 DynamicExportSymbols.insert(GUID);
1143 GUIDPrevailingResolutions[GUID] =
1148 auto It = GUIDPrevailingResolutions.
find(
G);
1149 if (It == GUIDPrevailingResolutions.
end())
1158 if (!StatsFileOrErr)
1159 return StatsFileOrErr.takeError();
1160 std::unique_ptr<ToolOutputFile> StatsFile = std::move(StatsFileOrErr.get());
1168 ThinLTO.CombinedIndex.setWithSupportsHotColdNew();
1170 Error Result = runRegularLTO(AddStream);
1172 Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols);
1182 if (
Index.withSupportsHotColdNew())
1190 for (
auto &
F :
Mod) {
1191 for (
auto &BB :
F) {
1192 for (
auto &
I : BB) {
1193 auto *CI = dyn_cast<CallBase>(&
I);
1196 if (CI->hasFnAttr(
"memprof"))
1197 CI->removeFnAttr(
"memprof");
1204 CI->setMetadata(LLVMContext::MD_memprof,
nullptr);
1205 CI->setMetadata(LLVMContext::MD_callsite,
nullptr);
1219 return DiagFileOrErr.takeError();
1220 DiagnosticOutputFile = std::move(*DiagFileOrErr);
1224 for (
auto &M : RegularLTO.ModsWithSummaries)
1225 if (
Error Err = linkRegularLTO(std::move(M),
1233 if (
Error Err = checkPartiallySplit())
1238 const DataLayout &
DL = RegularLTO.CombinedModule->getDataLayout();
1239 for (
auto &
I : RegularLTO.Commons) {
1240 if (!
I.second.Prevailing)
1243 GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(
I.first);
1244 if (OldGV &&
DL.getTypeAllocSize(OldGV->
getValueType()) ==
I.second.Size) {
1252 auto *GV =
new GlobalVariable(*RegularLTO.CombinedModule, Ty,
false,
1255 GV->setAlignment(
I.second.Alignment);
1267 bool WholeProgramVisibilityEnabledInLTO =
1276 auto It = GlobalResolutions.
find(
name);
1277 return (It == GlobalResolutions.
end() || It->second.VisibleOutsideSummary);
1283 *RegularLTO.CombinedModule, WholeProgramVisibilityEnabledInLTO,
1285 IsVisibleToRegularObj);
1287 WholeProgramVisibilityEnabledInLTO);
1294 for (
const auto &R : GlobalResolutions) {
1296 RegularLTO.CombinedModule->getNamedValue(
R.second.IRName);
1297 if (!
R.second.isPrevailingIRSymbol())
1299 if (
R.second.Partition != 0 &&
1300 R.second.Partition != GlobalResolution::External)
1335 backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,
1336 *RegularLTO.CombinedModule, ThinLTO.CombinedIndex))
1344#define HANDLE_LIBCALL(code, name) name,
1345#include "llvm/IR/RuntimeLibcalls.def"
1346#undef HANDLE_LIBCALL
1367 : Conf(Conf), CombinedIndex(CombinedIndex),
1368 ModuleToDefinedGVSummaries(ModuleToDefinedGVSummaries),
1369 OnWrite(OnWrite), ShouldEmitImportsFiles(ShouldEmitImportsFiles) {}
1376 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1384 const std::string &NewModulePath) {
1385 std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
1388 ImportList, ModuleToSummariesForIndex);
1391 sys::fs::OpenFlags::OF_None);
1396 if (ShouldEmitImportsFiles) {
1398 ModuleToSummariesForIndex);
1411 std::set<GlobalValue::GUID> CfiFunctionDefs;
1412 std::set<GlobalValue::GUID> CfiFunctionDecls;
1414 std::optional<Error> Err;
1417 bool ShouldEmitIndexFiles;
1420 InProcessThinBackend(
1425 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles)
1427 OnWrite, ShouldEmitImportsFiles),
1428 BackendThreadPool(ThinLTOParallelism), AddStream(
std::
move(AddStream)),
1429 Cache(
std::
move(Cache)), ShouldEmitIndexFiles(ShouldEmitIndexFiles) {
1431 CfiFunctionDefs.insert(
1434 CfiFunctionDecls.insert(
1438 Error runThinLTOBackendThread(
1443 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1446 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1452 return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,
1453 ImportList, DefinedGlobals, &ModuleMap);
1458 if (ShouldEmitIndexFiles) {
1459 if (
auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1465 [](
uint32_t V) { return V == 0; }))
1468 return RunThinBackend(AddStream);
1473 ExportList, ResolvedODR, DefinedGlobals, CfiFunctionDefs,
1478 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1480 return RunThinBackend(CacheAddStream);
1489 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1492 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
1494 ModuleToDefinedGVSummaries.
find(ModulePath)->second;
1495 BackendThreadPool.
async(
1499 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
1506 Error E = runThinLTOBackendThread(
1507 AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList,
1508 ResolvedODR, DefinedGlobals, ModuleMap);
1510 std::unique_lock<std::mutex>
L(ErrMu);
1519 BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList),
1520 std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap));
1523 OnWrite(std::string(ModulePath));
1527 Error wait()
override {
1528 BackendThreadPool.
wait();
1530 return std::move(*Err);
1543 bool ShouldEmitIndexFiles,
1544 bool ShouldEmitImportsFiles) {
1549 return std::make_unique<InProcessThinBackend>(
1550 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1551 AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
1552 ShouldEmitImportsFiles);
1562 return std::string(Path);
1566 if (!ParentPath.
empty()) {
1569 llvm::errs() <<
"warning: could not create directory '" << ParentPath
1570 <<
"': " << EC.message() <<
'\n';
1572 return std::string(NewPath.
str());
1577 std::string OldPrefix, NewPrefix, NativeObjectPrefix;
1581 WriteIndexesThinBackend(
1584 std::string OldPrefix, std::string NewPrefix,
1585 std::string NativeObjectPrefix,
bool ShouldEmitImportsFiles,
1588 OnWrite, ShouldEmitImportsFiles),
1589 OldPrefix(OldPrefix), NewPrefix(NewPrefix),
1590 NativeObjectPrefix(NativeObjectPrefix),
1591 LinkedObjectsFile(LinkedObjectsFile) {}
1597 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1600 std::string NewModulePath =
1603 if (LinkedObjectsFile) {
1604 std::string ObjectPrefix =
1605 NativeObjectPrefix.empty() ? NewPrefix : NativeObjectPrefix;
1606 std::string LinkedObjectsFilePath =
1608 *LinkedObjectsFile << LinkedObjectsFilePath <<
'\n';
1611 if (
auto E = emitFiles(ImportList, ModulePath, NewModulePath))
1615 OnWrite(std::string(ModulePath));
1628 std::string OldPrefix, std::string NewPrefix,
1629 std::string NativeObjectPrefix,
bool ShouldEmitImportsFiles,
1635 return std::make_unique<WriteIndexesThinBackend>(
1636 Conf, CombinedIndex, ModuleToDefinedGVSummaries, OldPrefix,
1637 NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,
1638 LinkedObjectsFile, OnWrite);
1645 ThinLTO.CombinedIndex.releaseTemporaryMemory();
1651 if (ThinLTO.ModuleMap.empty())
1654 if (ThinLTO.ModulesToCompile && ThinLTO.ModulesToCompile->empty()) {
1655 llvm::errs() <<
"warning: [ThinLTO] No module compiled\n";
1666 ThinLTO.ModuleMap.size());
1667 ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule(
1668 ModuleToDefinedGVSummaries);
1676 for (
auto &
Mod : ThinLTO.ModuleMap)
1677 if (!ModuleToDefinedGVSummaries.
count(
Mod.first))
1684 ThinLTO.ModuleMap.size());
1686 ThinLTO.ModuleMap.size());
1690 ThinLTO.CombinedIndex.dumpSCCs(
outs());
1692 std::set<GlobalValue::GUID> ExportedGUIDs;
1694 bool WholeProgramVisibilityEnabledInLTO =
1700 ThinLTO.CombinedIndex.setWithWholeProgramVisibility();
1706 if (WholeProgramVisibilityEnabledInLTO &&
1711 auto It = GlobalResolutions.
find(
name);
1712 return (It == GlobalResolutions.end() ||
1713 It->second.VisibleOutsideSummary);
1717 VisibleToRegularObjSymbols,
1718 IsVisibleToRegularObj);
1724 ThinLTO.CombinedIndex, WholeProgramVisibilityEnabledInLTO,
1725 DynamicExportSymbols, VisibleToRegularObjSymbols);
1730 std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;
1732 LocalWPDTargetsMap);
1735 return ThinLTO.PrevailingModuleForGUID[GUID] == S->modulePath();
1739 ContextDisambiguation.
run(ThinLTO.CombinedIndex, isPrevailing);
1744 isPrevailing, ImportLists, ExportLists);
1750 for (
auto &Res : GlobalResolutions) {
1753 if (Res.second.Partition != GlobalResolution::External ||
1754 !Res.second.isPrevailingIRSymbol())
1759 if (ThinLTO.CombinedIndex.isGUIDLive(GUID))
1760 ExportedGUIDs.insert(GUID);
1765 for (
auto &Def : ThinLTO.CombinedIndex.cfiFunctionDefs())
1766 ExportedGUIDs.insert(
1768 for (
auto &Decl : ThinLTO.CombinedIndex.cfiFunctionDecls())
1769 ExportedGUIDs.insert(
1773 const auto &ExportList = ExportLists.
find(ModuleIdentifier);
1774 return (ExportList != ExportLists.end() && ExportList->second.
count(VI)) ||
1775 ExportedGUIDs.count(
VI.getGUID());
1781 LocalWPDTargetsMap);
1786 auto recordNewLinkage = [&](
StringRef ModuleIdentifier,
1789 ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
1792 recordNewLinkage, GUIDPreservedSymbols);
1801 TimeTraceScopeExit.release();
1803 std::unique_ptr<ThinBackendProc> BackendProc =
1804 ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
1808 ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;
1810 auto ProcessOneModule = [&](
int I) ->
Error {
1814 return BackendProc->start(RegularLTO.ParallelCodeGenParallelismLevel +
I,
1815 Mod.second, ImportLists[
Mod.first],
1816 ExportLists[
Mod.first], ResolvedODR[
Mod.first],
1820 if (BackendProc->getThreadCount() == 1) {
1825 for (
int I = 0,
E = ModuleMap.
size();
I !=
E; ++
I)
1826 if (
Error E = ProcessOneModule(
I))
1833 std::vector<BitcodeModule *> ModulesVec;
1834 ModulesVec.reserve(ModuleMap.
size());
1835 for (
auto &
Mod : ModuleMap)
1836 ModulesVec.push_back(&
Mod.second);
1838 if (
Error E = ProcessOneModule(
I))
1841 return BackendProc->wait();
1851 if (!Filename.empty() && Count != -1)
1859 if (
Error E = ResultOrErr.takeError())
1860 return std::move(
E);
1863 (*ResultOrErr)->keep();
1871 if (StatsFilename.
empty())
1882 return std::move(StatsFile);
1889 auto Seq = llvm::seq<int>(0, R.size());
1890 std::vector<int> ModulesOrdering(Seq.begin(), Seq.end());
1891 llvm::sort(ModulesOrdering, [&](
int LeftIndex,
int RightIndex) {
1892 auto LSize = R[LeftIndex]->getBuffer().
size();
1893 auto RSize = R[RightIndex]->getBuffer().
size();
1894 return LSize > RSize;
1896 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)
static const char * libcallRoutineNames[]
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_set< GlobalValue::GUID > FunctionsToImportTy
Set of functions to import from a source module.
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)
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 GUID getGUID(StringRef GlobalName)
Return a 64-bit global unique ID constructed from global value name (i.e.
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().
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.
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",...
iterator find(StringRef Key)
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.
unsigned RelaxELFRelocations
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.
A ThreadPool for asynchronous parallel execution on a defined number of threads.
void wait()
Blocking wait for all the threads to complete and the queue to be empty.
unsigned getThreadCount() const
auto async(Function &&F, Args &&...ArgList)
Asynchronous submission of a task to the pool.
Triple - Helper class for working with autoconf configuration names.
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...
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.
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.
static ArrayRef< const char * > getRuntimeLibcallSymbols()
Static method that returns a list of libcall symbols that can be generated by LTO but might not be vi...
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.
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 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 timeTraceProfilerInitialize(unsigned TimeTraceGranularity, StringRef ProcName)
Initialize the time trace profiler.
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...
void writeIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out, const std::map< std::string, GVSummaryMapTy > *ModuleToSummariesForIndex=nullptr)
Write the specified module summary index to the given raw output stream, where it will be written in ...
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.
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 timeTraceProfilerFinishThread()
Finish a time trace profiler running on a worker thread.
void timeTraceProfilerBegin(StringRef Name, StringRef Detail)
Manually begin a time section, with the given Name and Detail.
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)
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.
cl::opt< bool > EnableMemProfContextDisambiguation
Enable MemProf context disambiguation for thin link.
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.
void gatherImportedSummariesForModule(StringRef ModulePath, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, const FunctionImporter::ImportMapTy &ImportList, std::map< std::string, GVSummaryMapTy > &ModuleToSummariesForIndex)
Compute the set of summaries needed for a ThinLTO backend compilation of ModulePath.
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.
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.
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...
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.
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.