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) {
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->getKey(); }
183 return ModIt->second;
190 std::vector<ImportModule> ImportModulesVector;
191 ImportModulesVector.reserve(ImportList.
size());
193 for (ImportMapIteratorTy It = ImportList.
begin(); It != ImportList.
end();
195 ImportModulesVector.push_back({It,
Index.getModule(It->getKey())});
200 [](
const ImportModule &Lhs,
const ImportModule &Rhs) ->
bool {
201 return Lhs.getId() < Rhs.getId();
203 for (
const ImportModule &Entry : ImportModulesVector) {
204 auto ModHash = Entry.getHash();
207 AddUint64(Entry.getFunctions().size());
208 for (
auto &Fn : Entry.getFunctions())
213 for (
auto &Entry : ResolvedODR) {
222 std::set<GlobalValue::GUID> UsedCfiDefs;
223 std::set<GlobalValue::GUID> UsedCfiDecls;
226 std::set<GlobalValue::GUID> UsedTypeIds;
229 if (CfiFunctionDefs.count(ValueGUID))
230 UsedCfiDefs.insert(ValueGUID);
231 if (CfiFunctionDecls.count(ValueGUID))
232 UsedCfiDecls.insert(ValueGUID);
237 AddUnsigned(GS->getVisibility());
238 AddUnsigned(GS->isLive());
239 AddUnsigned(GS->canAutoHide());
241 AddUnsigned(
VI.isDSOLocal(
Index.withDSOLocalPropagation()));
242 AddUsedCfiGlobal(
VI.getGUID());
244 if (
auto *GVS = dyn_cast<GlobalVarSummary>(GS)) {
245 AddUnsigned(GVS->maybeReadOnly());
246 AddUnsigned(GVS->maybeWriteOnly());
248 if (
auto *FS = dyn_cast<FunctionSummary>(GS)) {
249 for (
auto &TT : FS->type_tests())
250 UsedTypeIds.insert(TT);
251 for (
auto &TT : FS->type_test_assume_vcalls())
252 UsedTypeIds.insert(TT.GUID);
253 for (
auto &TT : FS->type_checked_load_vcalls())
254 UsedTypeIds.insert(TT.GUID);
255 for (
auto &TT : FS->type_test_assume_const_vcalls())
256 UsedTypeIds.insert(TT.VFunc.GUID);
257 for (
auto &TT : FS->type_checked_load_const_vcalls())
258 UsedTypeIds.insert(TT.VFunc.GUID);
259 for (
auto &ET : FS->calls()) {
260 AddUnsigned(ET.first.isDSOLocal(
Index.withDSOLocalPropagation()));
261 AddUsedCfiGlobal(ET.first.getGUID());
268 for (
auto &GS : DefinedGlobals) {
272 AddUsedCfiGlobal(GS.first);
273 AddUsedThings(GS.second);
278 for (
const ImportModule &ImpM : ImportModulesVector)
279 for (
auto &ImpF : ImpM.getFunctions()) {
281 Index.findSummaryInModule(ImpF, ImpM.getIdentifier());
285 if (
auto *AS = dyn_cast_or_null<AliasSummary>(S))
286 AddUsedThings(AS->getBaseObject());
292 AddUnsigned(S.TTRes.TheKind);
293 AddUnsigned(S.TTRes.SizeM1BitWidth);
295 AddUint64(S.TTRes.AlignLog2);
296 AddUint64(S.TTRes.SizeM1);
297 AddUint64(S.TTRes.BitMask);
298 AddUint64(S.TTRes.InlineBits);
300 AddUint64(S.WPDRes.size());
301 for (
auto &WPD : S.WPDRes) {
302 AddUnsigned(WPD.first);
303 AddUnsigned(WPD.second.TheKind);
304 AddString(WPD.second.SingleImplName);
306 AddUint64(WPD.second.ResByArg.size());
307 for (
auto &ByArg : WPD.second.ResByArg) {
308 AddUint64(ByArg.first.size());
311 AddUnsigned(ByArg.second.TheKind);
312 AddUint64(ByArg.second.Info);
313 AddUnsigned(ByArg.second.Byte);
314 AddUnsigned(ByArg.second.Bit);
321 auto TidIter =
Index.typeIds().equal_range(TId);
322 for (
auto It = TidIter.first; It != TidIter.second; ++It)
323 AddTypeIdSummary(It->second.first, It->second.second);
326 AddUnsigned(UsedCfiDefs.size());
327 for (
auto &V : UsedCfiDefs)
330 AddUnsigned(UsedCfiDecls.size());
331 for (
auto &V : UsedCfiDecls)
337 Hasher.
update(FileOrErr.get()->getBuffer());
342 Hasher.
update(FileOrErr.get()->getBuffer());
347 Key = toHex(Hasher.
result());
361 for (
auto &S :
VI.getSummaryList()) {
376 if (isPrevailing(
VI.getGUID(), S.get())) {
389 S->setCanAutoHide(
VI.canAutoHide() &&
390 !GUIDPreservedSymbols.
count(
VI.getGUID()));
393 Visibility = S->getVisibility();
396 else if (!isa<AliasSummary>(S.get()) &&
397 !GlobalInvolvedWithAlias.
count(S.get()))
404 S->setVisibility(Visibility);
406 if (S->linkage() != OriginalLinkage)
407 recordNewLinkage(S->modulePath(),
VI.getGUID(), S->linkage());
411 for (
auto &S :
VI.getSummaryList()) {
416 S->setVisibility(Visibility);
439 for (
auto &S :
I.second.SummaryList)
440 if (
auto AS = dyn_cast<AliasSummary>(S.get()))
441 GlobalInvolvedWithAlias.
insert(&AS->getAliasee());
445 GlobalInvolvedWithAlias, isPrevailing,
446 recordNewLinkage, GUIDPreservedSymbols);
453 auto ExternallyVisibleCopies =
455 [](
const std::unique_ptr<GlobalValueSummary> &Summary) {
456 return !GlobalValue::isLocalLinkage(Summary->linkage());
459 for (
auto &S :
VI.getSummaryList()) {
462 if (isExported(S->modulePath(),
VI)) {
484 bool IsPrevailing = isPrevailing(
VI.getGUID(), S.get());
532 (!IsPrevailing || ExternallyVisibleCopies > 1))
555 std::unique_ptr<InputFile> File(
new InputFile);
561 File->TargetTriple = FOrErr->TheReader.getTargetTriple();
562 File->SourceFileName = FOrErr->TheReader.getSourceFileName();
563 File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts();
564 File->DependentLibraries = FOrErr->TheReader.getDependentLibraries();
565 File->ComdatTable = FOrErr->TheReader.getComdatTable();
567 for (
unsigned I = 0;
I != FOrErr->Mods.size(); ++
I) {
568 size_t Begin = File->Symbols.size();
570 FOrErr->TheReader.module_symbols(
I))
573 if (
Sym.isGlobal() && !
Sym.isFormatSpecific())
574 File->Symbols.push_back(
Sym);
575 File->ModuleSymIndices.push_back({Begin, File->Symbols.size()});
578 File->Mods = FOrErr->Mods;
579 File->Strtab = std::move(FOrErr->Strtab);
580 return std::move(File);
584 return Mods[0].getModuleIdentifier();
588 assert(Mods.size() == 1 &&
"Expect only one bitcode module");
592LTO::RegularLTOState::RegularLTOState(
unsigned ParallelCodeGenParallelismLevel,
594 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
595 Ctx(Conf), CombinedModule(
std::make_unique<
Module>(
"ld-temp.o", Ctx)),
596 Mover(
std::make_unique<
IRMover>(*CombinedModule)) {}
598LTO::ThinLTOState::ThinLTOState(
ThinBackend Backend)
599 : Backend(Backend), CombinedIndex(
false) {
606 unsigned ParallelCodeGenParallelismLevel)
608 RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),
618 unsigned Partition,
bool InSummary) {
619 auto *ResI = Res.
begin();
620 auto *ResE = Res.
end();
622 const Triple TT(RegularLTO.CombinedModule->getTargetTriple());
631 if (TT.isOSBinFormatCOFF() &&
Name.startswith(
"__imp_"))
632 Name =
Name.substr(strlen(
"__imp_"));
633 auto &GlobalRes = GlobalResolutions[
Name];
634 GlobalRes.UnnamedAddr &=
Sym.isUnnamedAddr();
636 assert(!GlobalRes.Prevailing &&
637 "Multiple prevailing defs are not allowed");
638 GlobalRes.Prevailing =
true;
639 GlobalRes.IRName = std::string(
Sym.getIRName());
640 }
else if (!GlobalRes.Prevailing && GlobalRes.IRName.empty()) {
647 GlobalRes.IRName = std::string(
Sym.getIRName());
661 if (GlobalRes.IRName !=
Sym.getIRName()) {
662 GlobalRes.Partition = GlobalResolution::External;
663 GlobalRes.VisibleOutsideSummary =
true;
671 (GlobalRes.Partition != GlobalResolution::Unknown &&
672 GlobalRes.Partition != Partition)) {
673 GlobalRes.Partition = GlobalResolution::External;
676 GlobalRes.Partition = Partition;
680 GlobalRes.VisibleOutsideSummary |=
691 auto ResI = Res.
begin();
696 OS <<
"-r=" << Path <<
',' <<
Sym.getName() <<
',';
713 assert(!CalledGetMaxTasks);
718 if (RegularLTO.CombinedModule->getTargetTriple().empty()) {
719 RegularLTO.CombinedModule->setTargetTriple(Input->getTargetTriple());
725 for (
unsigned I = 0;
I != Input->Mods.size(); ++
I)
726 if (
Error Err = addModule(*Input,
I, ResI, Res.
end()))
740 if (EnableSplitLTOUnit) {
744 if (*EnableSplitLTOUnit != LTOInfo->EnableSplitLTOUnit)
745 ThinLTO.CombinedIndex.setPartiallySplitLTOUnits();
747 EnableSplitLTOUnit = LTOInfo->EnableSplitLTOUnit;
750 auto ModSyms = Input.module_symbols(ModI);
751 addModuleToGlobalRes(ModSyms, {ResI, ResE},
752 LTOInfo->IsThinLTO ? ThinLTO.ModuleMap.size() + 1 : 0,
753 LTOInfo->HasSummary);
755 if (LTOInfo->IsThinLTO)
756 return addThinLTO(BM, ModSyms, ResI, ResE);
758 RegularLTO.EmptyCombinedModule =
false;
760 addRegularLTO(BM, ModSyms, ResI, ResE);
764 if (!LTOInfo->HasSummary)
765 return linkRegularLTO(std::move(*ModOrErr),
false);
771 RegularLTO.ModsWithSummaries.push_back(std::move(*ModOrErr));
787 std::set<const Comdat *> &NonPrevailingComdats) {
792 if (!NonPrevailingComdats.count(
C))
801 if (
auto GO = dyn_cast<GlobalObject>(&GV))
802 GO->setComdat(
nullptr);
812 RegularLTOState::AddedModule
Mod;
819 Mod.M = std::move(*MOrErr);
821 if (
Error Err =
M.materializeMetadata())
822 return std::move(Err);
829 if (GV.hasAppendingLinkage())
830 Mod.Keep.push_back(&GV);
833 for (
auto &GA :
M.aliases())
835 AliasedGlobals.
insert(GO);
844 auto MsymI = SymTab.
symbols().begin(), MsymE = SymTab.
symbols().end();
846 while (MsymI != MsymE) {
856 std::set<const Comdat *> NonPrevailingComdats;
866 if (
GlobalValue *GV = dyn_cast_if_present<GlobalValue *>(Msym)) {
868 if (
Sym.isUndefined())
870 Mod.Keep.push_back(GV);
881 }
else if (isa<GlobalObject>(GV) &&
882 (GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||
883 GV->hasAvailableExternallyLinkage()) &&
884 !AliasedGlobals.
count(cast<GlobalObject>(GV))) {
890 Mod.Keep.push_back(GV);
893 NonPrevailingComdats.insert(GV->getComdat());
894 cast<GlobalObject>(GV)->setComdat(
nullptr);
899 GV->setDSOLocal(
true);
900 if (GV->hasDLLImportStorageClass())
902 DefaultStorageClass);
904 }
else if (
auto *AS =
905 dyn_cast_if_present<ModuleSymbolTable::AsmSymbol *>(Msym)) {
908 NonPrevailingAsmSymbols.
insert(AS->first);
916 if (
Sym.isCommon()) {
919 auto &CommonRes = RegularLTO.Commons[std::string(
Sym.getIRName())];
920 CommonRes.Size = std::max(CommonRes.Size,
Sym.getCommonSize());
921 if (
uint32_t SymAlignValue =
Sym.getCommonAlignment()) {
922 CommonRes.Alignment =
923 std::max(
Align(SymAlignValue), CommonRes.Alignment);
929 if (!
M.getComdatSymbolTable().empty())
935 if (!
M.getModuleInlineAsm().empty()) {
936 std::string NewIA =
".lto_discard";
937 if (!NonPrevailingAsmSymbols.
empty()) {
941 if (!NonPrevailingAsmSymbols.
count(Alias))
944 NewIA +=
" " + llvm::join(NonPrevailingAsmSymbols,
", ");
947 M.setModuleInlineAsm(NewIA +
M.getModuleInlineAsm());
951 return std::move(
Mod);
954Error LTO::linkRegularLTO(RegularLTOState::AddedModule
Mod,
955 bool LivenessFromIndex) {
956 std::vector<GlobalValue *>
Keep;
958 if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->
getGUID())) {
959 if (
Function *
F = dyn_cast<Function>(GV)) {
960 if (DiagnosticOutputFile) {
961 if (
Error Err =
F->materialize())
966 <<
" not added to the combined module ");
980 RegularLTO.CombinedModule->getNamedValue(GV->
getName());
987 return RegularLTO.Mover->move(std::move(
Mod.M),
Keep,
nullptr,
1000 if (!
Sym.getIRName().empty()) {
1008 uint64_t ModuleId = ThinLTO.ModuleMap.size();
1012 return ThinLTO.PrevailingModuleForGUID[GUID] ==
1013 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(
1093 if ((TypeTestFunc && !TypeTestFunc->
use_empty()) ||
1094 (TypeCheckedLoadFunc && !TypeCheckedLoadFunc->
use_empty()))
1095 return make_error<StringError>(
1096 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1101 for (
auto &
P : ThinLTO.CombinedIndex) {
1102 for (
auto &S :
P.second.SummaryList) {
1103 auto *FS = dyn_cast<FunctionSummary>(S.get());
1106 if (!FS->type_test_assume_vcalls().empty() ||
1107 !FS->type_checked_load_vcalls().empty() ||
1108 !FS->type_test_assume_const_vcalls().empty() ||
1109 !FS->type_checked_load_const_vcalls().empty() ||
1110 !FS->type_tests().empty())
1111 return make_error<StringError>(
1112 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1123 for (
auto &Res : GlobalResolutions) {
1126 if (Res.second.IRName.empty())
1132 if (Res.second.VisibleOutsideSummary && Res.second.
Prevailing)
1133 GUIDPreservedSymbols.
insert(GUID);
1136 DynamicExportSymbols.insert(GUID);
1138 GUIDPrevailingResolutions[GUID] =
1143 auto It = GUIDPrevailingResolutions.
find(
G);
1144 if (It == GUIDPrevailingResolutions.
end())
1153 if (!StatsFileOrErr)
1154 return StatsFileOrErr.takeError();
1155 std::unique_ptr<ToolOutputFile> StatsFile = std::move(StatsFileOrErr.get());
1163 ThinLTO.CombinedIndex.setWithSupportsHotColdNew();
1165 Error Result = runRegularLTO(AddStream);
1167 Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols);
1177 if (
Index.withSupportsHotColdNew())
1185 for (
auto &
F :
Mod) {
1186 for (
auto &BB :
F) {
1187 for (
auto &
I : BB) {
1188 auto *CI = dyn_cast<CallBase>(&
I);
1191 if (CI->hasFnAttr(
"memprof"))
1192 CI->removeFnAttr(
"memprof");
1199 CI->setMetadata(LLVMContext::MD_memprof,
nullptr);
1200 CI->setMetadata(LLVMContext::MD_callsite,
nullptr);
1213 return DiagFileOrErr.takeError();
1214 DiagnosticOutputFile = std::move(*DiagFileOrErr);
1218 for (
auto &M : RegularLTO.ModsWithSummaries)
1219 if (
Error Err = linkRegularLTO(std::move(M),
1227 if (
Error Err = checkPartiallySplit())
1232 const DataLayout &
DL = RegularLTO.CombinedModule->getDataLayout();
1233 for (
auto &
I : RegularLTO.Commons) {
1234 if (!
I.second.Prevailing)
1237 GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(
I.first);
1238 if (OldGV &&
DL.getTypeAllocSize(OldGV->
getValueType()) ==
I.second.Size) {
1246 auto *GV =
new GlobalVariable(*RegularLTO.CombinedModule, Ty,
false,
1249 GV->setAlignment(
I.second.Alignment);
1265 DynamicExportSymbols);
1274 for (
const auto &R : GlobalResolutions) {
1275 if (!
R.second.isPrevailingIRSymbol())
1277 if (
R.second.Partition != 0 &&
1278 R.second.Partition != GlobalResolution::External)
1282 RegularLTO.CombinedModule->getNamedValue(
R.second.IRName);
1293 RegularLTO.CombinedModule->addModuleFlag(
Module::Error,
"LTOPostLink", 1);
1302 backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,
1303 *RegularLTO.CombinedModule, ThinLTO.CombinedIndex))
1311#define HANDLE_LIBCALL(code, name) name,
1312#include "llvm/IR/RuntimeLibcalls.def"
1313#undef HANDLE_LIBCALL
1333 : Conf(Conf), CombinedIndex(CombinedIndex),
1334 ModuleToDefinedGVSummaries(ModuleToDefinedGVSummaries),
1335 OnWrite(OnWrite), ShouldEmitImportsFiles(ShouldEmitImportsFiles) {}
1342 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1350 const std::string &NewModulePath) {
1351 std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
1354 ImportList, ModuleToSummariesForIndex);
1357 sys::fs::OpenFlags::OF_None);
1362 if (ShouldEmitImportsFiles) {
1364 ModuleToSummariesForIndex);
1377 std::set<GlobalValue::GUID> CfiFunctionDefs;
1378 std::set<GlobalValue::GUID> CfiFunctionDecls;
1380 std::optional<Error> Err;
1383 bool ShouldEmitIndexFiles;
1386 InProcessThinBackend(
1391 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles)
1393 OnWrite, ShouldEmitImportsFiles),
1394 BackendThreadPool(ThinLTOParallelism), AddStream(
std::
move(AddStream)),
1395 Cache(
std::
move(Cache)), ShouldEmitIndexFiles(ShouldEmitIndexFiles) {
1397 CfiFunctionDefs.insert(
1400 CfiFunctionDecls.insert(
1404 Error runThinLTOBackendThread(
1409 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1412 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1418 return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,
1419 ImportList, DefinedGlobals, &ModuleMap);
1424 if (ShouldEmitIndexFiles) {
1425 if (
auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1431 [](
uint32_t V) { return V == 0; }))
1434 return RunThinBackend(AddStream);
1439 ExportList, ResolvedODR, DefinedGlobals, CfiFunctionDefs,
1444 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1446 return RunThinBackend(CacheAddStream);
1455 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1458 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
1460 ModuleToDefinedGVSummaries.
find(ModulePath)->second;
1461 BackendThreadPool.
async(
1465 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
1472 Error E = runThinLTOBackendThread(
1473 AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList,
1474 ResolvedODR, DefinedGlobals, ModuleMap);
1476 std::unique_lock<std::mutex>
L(ErrMu);
1485 BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList),
1486 std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap));
1489 OnWrite(std::string(ModulePath));
1493 Error wait()
override {
1494 BackendThreadPool.
wait();
1496 return std::move(*Err);
1509 bool ShouldEmitIndexFiles,
1510 bool ShouldEmitImportsFiles) {
1514 return std::make_unique<InProcessThinBackend>(
1515 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries, AddStream,
1516 Cache, OnWrite, ShouldEmitIndexFiles, ShouldEmitImportsFiles);
1526 return std::string(Path);
1530 if (!ParentPath.
empty()) {
1533 llvm::errs() <<
"warning: could not create directory '" << ParentPath
1534 <<
"': " << EC.message() <<
'\n';
1536 return std::string(NewPath.
str());
1541 std::string OldPrefix, NewPrefix, NativeObjectPrefix;
1545 WriteIndexesThinBackend(
1548 std::string OldPrefix, std::string NewPrefix,
1549 std::string NativeObjectPrefix,
bool ShouldEmitImportsFiles,
1552 OnWrite, ShouldEmitImportsFiles),
1553 OldPrefix(OldPrefix), NewPrefix(NewPrefix),
1554 NativeObjectPrefix(NativeObjectPrefix),
1555 LinkedObjectsFile(LinkedObjectsFile) {}
1561 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1564 std::string NewModulePath =
1567 if (LinkedObjectsFile) {
1568 std::string ObjectPrefix =
1569 NativeObjectPrefix.empty() ? NewPrefix : NativeObjectPrefix;
1570 std::string LinkedObjectsFilePath =
1572 *LinkedObjectsFile << LinkedObjectsFilePath <<
'\n';
1575 if (
auto E = emitFiles(ImportList, ModulePath, NewModulePath))
1579 OnWrite(std::string(ModulePath));
1592 std::string OldPrefix, std::string NewPrefix,
1593 std::string NativeObjectPrefix,
bool ShouldEmitImportsFiles,
1598 return std::make_unique<WriteIndexesThinBackend>(
1599 Conf, CombinedIndex, ModuleToDefinedGVSummaries, OldPrefix, NewPrefix,
1600 NativeObjectPrefix, ShouldEmitImportsFiles, LinkedObjectsFile, OnWrite);
1606 ThinLTO.CombinedIndex.releaseTemporaryMemory();
1612 if (ThinLTO.ModuleMap.empty())
1615 if (ThinLTO.ModulesToCompile && ThinLTO.ModulesToCompile->empty()) {
1616 llvm::errs() <<
"warning: [ThinLTO] No module compiled\n";
1627 ModuleToDefinedGVSummaries(ThinLTO.ModuleMap.size());
1628 ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule(
1629 ModuleToDefinedGVSummaries);
1637 for (
auto &
Mod : ThinLTO.ModuleMap)
1638 if (!ModuleToDefinedGVSummaries.
count(
Mod.first))
1645 ThinLTO.ModuleMap.size());
1647 ThinLTO.ModuleMap.size());
1651 ThinLTO.CombinedIndex.dumpSCCs(
outs());
1653 std::set<GlobalValue::GUID> ExportedGUIDs;
1656 ThinLTO.CombinedIndex.setWithWholeProgramVisibility();
1661 DynamicExportSymbols);
1666 std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;
1668 LocalWPDTargetsMap);
1671 return ThinLTO.PrevailingModuleForGUID[GUID] == S->modulePath();
1675 ContextDisambiguation.
run(ThinLTO.CombinedIndex, isPrevailing);
1680 isPrevailing, ImportLists, ExportLists);
1686 for (
auto &Res : GlobalResolutions) {
1689 if (Res.second.Partition != GlobalResolution::External ||
1690 !Res.second.isPrevailingIRSymbol())
1695 if (ThinLTO.CombinedIndex.isGUIDLive(GUID))
1696 ExportedGUIDs.insert(GUID);
1701 for (
auto &Def : ThinLTO.CombinedIndex.cfiFunctionDefs())
1702 ExportedGUIDs.insert(
1704 for (
auto &Decl : ThinLTO.CombinedIndex.cfiFunctionDecls())
1705 ExportedGUIDs.insert(
1709 const auto &ExportList = ExportLists.
find(ModuleIdentifier);
1710 return (ExportList != ExportLists.end() && ExportList->second.
count(VI)) ||
1711 ExportedGUIDs.count(
VI.getGUID());
1717 LocalWPDTargetsMap);
1722 auto recordNewLinkage = [&](
StringRef ModuleIdentifier,
1725 ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
1728 recordNewLinkage, GUIDPreservedSymbols);
1737 TimeTraceScopeExit.release();
1739 std::unique_ptr<ThinBackendProc> BackendProc =
1740 ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
1744 ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;
1746 auto ProcessOneModule = [&](
int I) ->
Error {
1750 return BackendProc->start(RegularLTO.ParallelCodeGenParallelismLevel +
I,
1751 Mod.second, ImportLists[
Mod.first],
1752 ExportLists[
Mod.first], ResolvedODR[
Mod.first],
1756 if (BackendProc->getThreadCount() == 1) {
1761 for (
int I = 0,
E = ModuleMap.
size();
I !=
E; ++
I)
1762 if (
Error E = ProcessOneModule(
I))
1769 std::vector<BitcodeModule *> ModulesVec;
1770 ModulesVec.reserve(ModuleMap.
size());
1771 for (
auto &
Mod : ModuleMap)
1772 ModulesVec.push_back(&
Mod.second);
1774 if (
Error E = ProcessOneModule(
I))
1777 return BackendProc->wait();
1787 if (!Filename.empty() && Count != -1)
1795 if (
Error E = ResultOrErr.takeError())
1796 return std::move(
E);
1799 (*ResultOrErr)->keep();
1807 if (StatsFilename.
empty())
1818 return std::move(StatsFile);
1825 auto Seq = llvm::seq<int>(0, R.size());
1826 std::vector<int> ModulesOrdering(Seq.begin(), Seq.end());
1827 llvm::sort(ModulesOrdering, [&](
int LeftIndex,
int RightIndex) {
1828 auto LSize = R[LeftIndex]->getBuffer().
size();
1829 auto RSize = R[RightIndex]->getBuffer().
size();
1830 return LSize > RSize;
1832 return ModulesOrdering;
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
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)
cl::opt< bool > SupportsHotColdNew
Indicate we are linking with an allocator that supports hot/cold operator new interfaces.
cl::opt< bool > EnableMemProfContextDisambiguation
Enable MemProf context disambiguation for thin link.
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
Expected< std::unique_ptr< Module > > parseModule(LLVMContext &Context, ParserCallbacks Callbacks={})
Read the entire bitcode module and return it.
Error readSummary(ModuleSummaryIndex &CombinedIndex, StringRef ModulePath, uint64_t ModuleId, 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 > > 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)
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
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 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
PointerType * getType() const
Global values are always pointers.
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 bool isInterposableLinkage(LinkageTypes Linkage)
Whether the definition of this global may be replaced by something non-equivalent at link time.
static LinkageTypes getWeakLinkage(bool ODR)
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).
@ WeakODRLinkage
Same, but only replaced by something equivalent.
@ ExternalLinkage
Externally visible function.
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
@ AppendingLinkage
Special purpose, only applies to global arrays.
@ AvailableExternallyLinkage
Available for inspection, not emission.
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
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< std::pair< uint64_t, 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.
@ Error
Emits an error if two values disagree, otherwise the resulting value is that of the operands.
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",...
StringMapConstIterator< ValueTy > const_iterator
iterator find(StringRef Key)
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
std::pair< iterator, bool > try_emplace(StringRef Key, ArgsTy &&...Args)
Emplace a new element for the specified key into the map if the key isn't already in the map.
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.
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.
LTO(Config Conf, ThinBackend Backend=nullptr, unsigned ParallelCodeGenParallelismLevel=1)
Create an LTO object.
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
ThinBackendProc(const Config &Conf, ModuleSummaryIndex &CombinedIndex, const StringMap< GVSummaryMapTy > &ModuleToDefinedGVSummaries, lto::IndexWriteCallback OnWrite, bool ShouldEmitImportsFiles)
Error emitFiles(const FunctionImporter::ImportMapTy &ImportList, llvm::StringRef ModulePath, const std::string &NewModulePath)
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
const StringMap< GVSummaryMapTy > & ModuleToDefinedGVSummaries
#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, StringMap< 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.
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)
void updateVCallVisibilityInModule(Module &M, bool WholeProgramVisibilityEnabledInLTO, const DenseSet< GlobalValue::GUID > &DynamicExportSymbols)
If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...
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.
void gatherImportedSummariesForModule(StringRef ModulePath, const StringMap< 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.
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.
void ComputeCrossModuleImport(const ModuleSummaryIndex &Index, const StringMap< GVSummaryMapTy > &ModuleToDefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, StringMap< FunctionImporter::ImportMapTy > &ImportLists, StringMap< FunctionImporter::ExportSetTy > &ExportLists)
Compute all the imports and exports for every module in the Index.
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 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.
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"))
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.
void updateVCallVisibilityInIndex(ModuleSummaryIndex &Index, bool WholeProgramVisibilityEnabledInLTO, const DenseSet< GlobalValue::GUID > &DynamicExportSymbols)
If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...
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.
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.
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.
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 TimeTraceEnabled
Time trace enabled.
CodeGenOpt::Level CGOptLevel
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.