25#include "llvm/Config/llvm-config.h"
50#include "llvm/Support/VCSRevision.h"
64using namespace object;
66#define DEBUG_TYPE "lto"
72 cl::desc(
"Dump the SCCs in the ThinLTO index's callgraph"));
78 cl::desc(
"Enable global value internalization in LTO"));
95 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
97 const std::set<GlobalValue::GUID> &CfiFunctionDefs,
98 const std::set<GlobalValue::GUID> &CfiFunctionDecls) {
106 Hasher.
update(LLVM_VERSION_STRING);
108 Hasher.
update(LLVM_REVISION);
116 auto AddUnsigned = [&](
unsigned I) {
126 auto AddUint8 = [&](
const uint8_t
I) {
150 AddUnsigned(
static_cast<int>(Conf.
CGOptLevel));
151 AddUnsigned(
static_cast<int>(Conf.
CGFileType));
161 auto ModHash =
Index.getModuleHash(ModuleID);
166 std::vector<uint64_t> ExportsGUID;
167 ExportsGUID.reserve(ExportList.
size());
168 for (
const auto &VI : ExportList)
169 ExportsGUID.push_back(VI.getGUID());
173 for (
auto GUID : ExportsGUID)
180 struct ImportModule {
181 ImportMapIteratorTy ModIt;
184 StringRef getIdentifier()
const {
return ModIt->getFirst(); }
186 return ModIt->second;
192 std::vector<ImportModule> ImportModulesVector;
193 ImportModulesVector.reserve(ImportList.
size());
195 for (ImportMapIteratorTy It = ImportList.
begin(); It != ImportList.
end();
197 ImportModulesVector.push_back({It,
Index.getModule(It->getFirst())});
202 [](
const ImportModule &Lhs,
const ImportModule &Rhs) ->
bool {
203 return Lhs.getHash() < Rhs.getHash();
205 std::vector<std::pair<uint64_t, uint8_t>> ImportedGUIDs;
206 for (
const ImportModule &Entry : ImportModulesVector) {
207 auto ModHash = Entry.getHash();
210 AddUint64(Entry.getFunctions().size());
212 ImportedGUIDs.clear();
213 for (
auto &[Fn, ImportType] : Entry.getFunctions())
214 ImportedGUIDs.push_back(std::make_pair(Fn, ImportType));
216 for (
auto &[GUID,
Type] : ImportedGUIDs) {
223 for (
auto &Entry : ResolvedODR) {
232 std::set<GlobalValue::GUID> UsedCfiDefs;
233 std::set<GlobalValue::GUID> UsedCfiDecls;
236 std::set<GlobalValue::GUID> UsedTypeIds;
239 if (CfiFunctionDefs.count(ValueGUID))
240 UsedCfiDefs.insert(ValueGUID);
241 if (CfiFunctionDecls.count(ValueGUID))
242 UsedCfiDecls.insert(ValueGUID);
247 AddUnsigned(GS->getVisibility());
248 AddUnsigned(GS->isLive());
249 AddUnsigned(GS->canAutoHide());
251 AddUnsigned(VI.isDSOLocal(
Index.withDSOLocalPropagation()));
252 AddUsedCfiGlobal(VI.getGUID());
254 if (
auto *GVS = dyn_cast<GlobalVarSummary>(GS)) {
255 AddUnsigned(GVS->maybeReadOnly());
256 AddUnsigned(GVS->maybeWriteOnly());
258 if (
auto *FS = dyn_cast<FunctionSummary>(GS)) {
259 for (
auto &TT : FS->type_tests())
260 UsedTypeIds.insert(TT);
261 for (
auto &TT : FS->type_test_assume_vcalls())
262 UsedTypeIds.insert(TT.GUID);
263 for (
auto &TT : FS->type_checked_load_vcalls())
264 UsedTypeIds.insert(TT.GUID);
265 for (
auto &TT : FS->type_test_assume_const_vcalls())
266 UsedTypeIds.insert(TT.VFunc.GUID);
267 for (
auto &TT : FS->type_checked_load_const_vcalls())
268 UsedTypeIds.insert(TT.VFunc.GUID);
269 for (
auto &ET : FS->calls()) {
270 AddUnsigned(ET.first.isDSOLocal(
Index.withDSOLocalPropagation()));
271 AddUsedCfiGlobal(ET.first.getGUID());
278 for (
auto &GS : DefinedGlobals) {
282 AddUsedCfiGlobal(GS.first);
283 AddUsedThings(GS.second);
288 for (
const ImportModule &ImpM : ImportModulesVector)
289 for (
auto &[GUID, UnusedImportType] : ImpM.getFunctions()) {
291 Index.findSummaryInModule(GUID, ImpM.getIdentifier());
295 if (
auto *AS = dyn_cast_or_null<AliasSummary>(S))
296 AddUsedThings(AS->getBaseObject());
302 AddUnsigned(S.TTRes.TheKind);
303 AddUnsigned(S.TTRes.SizeM1BitWidth);
305 AddUint64(S.TTRes.AlignLog2);
306 AddUint64(S.TTRes.SizeM1);
307 AddUint64(S.TTRes.BitMask);
308 AddUint64(S.TTRes.InlineBits);
310 AddUint64(S.WPDRes.size());
311 for (
auto &WPD : S.WPDRes) {
312 AddUnsigned(WPD.first);
313 AddUnsigned(WPD.second.TheKind);
314 AddString(WPD.second.SingleImplName);
316 AddUint64(WPD.second.ResByArg.size());
317 for (
auto &ByArg : WPD.second.ResByArg) {
318 AddUint64(ByArg.first.size());
321 AddUnsigned(ByArg.second.TheKind);
322 AddUint64(ByArg.second.Info);
323 AddUnsigned(ByArg.second.Byte);
324 AddUnsigned(ByArg.second.Bit);
331 auto TidIter =
Index.typeIds().equal_range(TId);
332 for (
auto It = TidIter.first; It != TidIter.second; ++It)
333 AddTypeIdSummary(It->second.first, It->second.second);
336 AddUnsigned(UsedCfiDefs.size());
337 for (
auto &V : UsedCfiDefs)
340 AddUnsigned(UsedCfiDecls.size());
341 for (
auto &V : UsedCfiDecls)
347 Hasher.
update(FileOrErr.get()->getBuffer());
352 Hasher.
update(FileOrErr.get()->getBuffer());
357 Key = toHex(Hasher.
result());
369 C.VisibilityScheme ==
Config::ELF ? VI.getELFVisibility()
371 for (
auto &S : VI.getSummaryList()) {
386 if (isPrevailing(VI.getGUID(), S.get())) {
399 S->setCanAutoHide(VI.canAutoHide() &&
400 !GUIDPreservedSymbols.
count(VI.getGUID()));
403 Visibility = S->getVisibility();
406 else if (!isa<AliasSummary>(S.get()) &&
407 !GlobalInvolvedWithAlias.
count(S.get()))
414 S->setVisibility(Visibility);
416 if (S->linkage() != OriginalLinkage)
417 recordNewLinkage(S->modulePath(), VI.getGUID(), S->linkage());
421 for (
auto &S : VI.getSummaryList()) {
426 S->setVisibility(Visibility);
449 for (
auto &S :
I.second.SummaryList)
450 if (
auto AS = dyn_cast<AliasSummary>(S.get()))
451 GlobalInvolvedWithAlias.
insert(&AS->getAliasee());
455 GlobalInvolvedWithAlias, isPrevailing,
456 recordNewLinkage, GUIDPreservedSymbols);
463 auto ExternallyVisibleCopies =
465 [](
const std::unique_ptr<GlobalValueSummary> &Summary) {
466 return !GlobalValue::isLocalLinkage(Summary->linkage());
469 for (
auto &S : VI.getSummaryList()) {
472 if (isExported(S->modulePath(), VI)) {
531 if (isPrevailing(VI.getGUID(), S.get()) && ExternallyVisibleCopies == 1)
552 std::unique_ptr<InputFile> File(
new InputFile);
558 File->TargetTriple = FOrErr->TheReader.getTargetTriple();
559 File->SourceFileName = FOrErr->TheReader.getSourceFileName();
560 File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts();
561 File->DependentLibraries = FOrErr->TheReader.getDependentLibraries();
562 File->ComdatTable = FOrErr->TheReader.getComdatTable();
564 for (
unsigned I = 0;
I != FOrErr->Mods.size(); ++
I) {
565 size_t Begin = File->Symbols.size();
567 FOrErr->TheReader.module_symbols(
I))
570 if (
Sym.isGlobal() && !
Sym.isFormatSpecific())
571 File->Symbols.push_back(
Sym);
572 File->ModuleSymIndices.push_back({Begin, File->Symbols.size()});
575 File->Mods = FOrErr->Mods;
576 File->Strtab = std::move(FOrErr->Strtab);
577 return std::move(File);
581 return Mods[0].getModuleIdentifier();
585 assert(Mods.size() == 1 &&
"Expect only one bitcode module");
589LTO::RegularLTOState::RegularLTOState(
unsigned ParallelCodeGenParallelismLevel,
591 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
592 Ctx(Conf), CombinedModule(
std::make_unique<
Module>(
"ld-temp.o", Ctx)),
593 Mover(
std::make_unique<
IRMover>(*CombinedModule)) {
597LTO::ThinLTOState::ThinLTOState(
ThinBackend Backend)
598 : Backend(Backend), CombinedIndex(
false) {
605 unsigned ParallelCodeGenParallelismLevel,
LTOKind LTOMode)
607 RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),
609 GlobalResolutions(
std::make_optional<
StringMap<GlobalResolution>>()),
619 unsigned Partition,
bool InSummary) {
620 auto *ResI = Res.
begin();
621 auto *ResE = Res.
end();
623 const Triple TT(RegularLTO.CombinedModule->getTargetTriple());
628 auto &GlobalRes = (*GlobalResolutions)[
Sym.getName()];
629 GlobalRes.UnnamedAddr &=
Sym.isUnnamedAddr();
631 assert(!GlobalRes.Prevailing &&
632 "Multiple prevailing defs are not allowed");
633 GlobalRes.Prevailing =
true;
634 GlobalRes.IRName = std::string(
Sym.getIRName());
635 }
else if (!GlobalRes.Prevailing && GlobalRes.IRName.empty()) {
642 GlobalRes.IRName = std::string(
Sym.getIRName());
656 if (GlobalRes.IRName !=
Sym.getIRName()) {
657 GlobalRes.Partition = GlobalResolution::External;
658 GlobalRes.VisibleOutsideSummary =
true;
666 (GlobalRes.Partition != GlobalResolution::Unknown &&
667 GlobalRes.Partition != Partition)) {
668 GlobalRes.Partition = GlobalResolution::External;
671 GlobalRes.Partition = Partition;
675 GlobalRes.VisibleOutsideSummary |=
686 auto ResI = Res.
begin();
691 OS <<
"-r=" << Path <<
',' <<
Sym.getName() <<
',';
708 assert(!CalledGetMaxTasks);
713 if (RegularLTO.CombinedModule->getTargetTriple().empty()) {
714 RegularLTO.CombinedModule->setTargetTriple(Input->getTargetTriple());
720 for (
unsigned I = 0;
I != Input->Mods.size(); ++
I)
721 if (
Error Err = addModule(*Input,
I, ResI, Res.
end()))
735 if (EnableSplitLTOUnit) {
739 if (*EnableSplitLTOUnit != LTOInfo->EnableSplitLTOUnit)
740 ThinLTO.CombinedIndex.setPartiallySplitLTOUnits();
742 EnableSplitLTOUnit = LTOInfo->EnableSplitLTOUnit;
747 !LTOInfo->UnifiedLTO)
748 return make_error<StringError>(
749 "unified LTO compilation must use "
750 "compatible bitcode modules (use -funified-lto)",
758 auto ModSyms = Input.module_symbols(ModI);
759 addModuleToGlobalRes(ModSyms, {ResI, ResE},
760 IsThinLTO ? ThinLTO.ModuleMap.size() + 1 : 0,
761 LTOInfo->HasSummary);
764 return addThinLTO(BM, ModSyms, ResI, ResE);
766 RegularLTO.EmptyCombinedModule =
false;
768 addRegularLTO(BM, ModSyms, ResI, ResE);
772 if (!LTOInfo->HasSummary)
773 return linkRegularLTO(std::move(*ModOrErr),
false);
779 RegularLTO.ModsWithSummaries.push_back(std::move(*ModOrErr));
795 std::set<const Comdat *> &NonPrevailingComdats) {
800 if (!NonPrevailingComdats.count(
C))
809 if (
auto GO = dyn_cast<GlobalObject>(&GV))
810 GO->setComdat(
nullptr);
820 RegularLTOState::AddedModule
Mod;
827 Mod.M = std::move(*MOrErr);
829 if (
Error Err =
M.materializeMetadata())
830 return std::move(Err);
837 if (
NamedMDNode *CfiFunctionsMD =
M.getNamedMetadata(
"cfi.functions"))
838 M.eraseNamedMetadata(CfiFunctionsMD);
846 if (GV.hasAppendingLinkage())
847 Mod.Keep.push_back(&GV);
850 for (
auto &GA :
M.aliases())
852 AliasedGlobals.
insert(GO);
861 auto MsymI = SymTab.
symbols().begin(), MsymE = SymTab.
symbols().end();
863 while (MsymI != MsymE) {
873 std::set<const Comdat *> NonPrevailingComdats;
883 if (
GlobalValue *GV = dyn_cast_if_present<GlobalValue *>(Msym)) {
885 if (
Sym.isUndefined())
887 Mod.Keep.push_back(GV);
898 }
else if (isa<GlobalObject>(GV) &&
899 (GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||
900 GV->hasAvailableExternallyLinkage()) &&
901 !AliasedGlobals.
count(cast<GlobalObject>(GV))) {
907 Mod.Keep.push_back(GV);
910 NonPrevailingComdats.insert(GV->getComdat());
911 cast<GlobalObject>(GV)->setComdat(
nullptr);
916 GV->setDSOLocal(
true);
917 if (GV->hasDLLImportStorageClass())
919 DefaultStorageClass);
921 }
else if (
auto *AS =
922 dyn_cast_if_present<ModuleSymbolTable::AsmSymbol *>(Msym)) {
925 NonPrevailingAsmSymbols.
insert(AS->first);
933 if (
Sym.isCommon()) {
936 auto &CommonRes = RegularLTO.Commons[std::string(
Sym.getIRName())];
937 CommonRes.Size = std::max(CommonRes.Size,
Sym.getCommonSize());
938 if (
uint32_t SymAlignValue =
Sym.getCommonAlignment()) {
939 CommonRes.Alignment =
940 std::max(
Align(SymAlignValue), CommonRes.Alignment);
946 if (!
M.getComdatSymbolTable().empty())
952 if (!
M.getModuleInlineAsm().empty()) {
953 std::string NewIA =
".lto_discard";
954 if (!NonPrevailingAsmSymbols.
empty()) {
958 if (!NonPrevailingAsmSymbols.
count(Alias))
961 NewIA +=
" " + llvm::join(NonPrevailingAsmSymbols,
", ");
964 M.setModuleInlineAsm(NewIA +
M.getModuleInlineAsm());
968 return std::move(
Mod);
971Error LTO::linkRegularLTO(RegularLTOState::AddedModule
Mod,
972 bool LivenessFromIndex) {
973 std::vector<GlobalValue *>
Keep;
975 if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->
getGUID())) {
976 if (
Function *
F = dyn_cast<Function>(GV)) {
977 if (DiagnosticOutputFile) {
978 if (
Error Err =
F->materialize())
983 <<
" not added to the combined module ");
997 RegularLTO.CombinedModule->getNamedValue(GV->
getName());
1004 return RegularLTO.Mover->move(std::move(
Mod.M),
Keep,
nullptr,
1017 if (!
Sym.getIRName().empty()) {
1028 return ThinLTO.PrevailingModuleForGUID[GUID] ==
1029 BM.getModuleIdentifier();
1038 if (!
Sym.getIRName().empty()) {
1042 assert(ThinLTO.PrevailingModuleForGUID[GUID] ==
1050 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(
1058 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(
1060 S->setDSOLocal(
true);
1066 if (!ThinLTO.ModuleMap.insert({BM.getModuleIdentifier(), BM}).second)
1067 return make_error<StringError>(
1068 "Expected at most one ThinLTO module per bitcode file",
1072 if (!ThinLTO.ModulesToCompile)
1073 ThinLTO.ModulesToCompile = ModuleMapType();
1089 CalledGetMaxTasks =
true;
1090 auto ModuleCount = ThinLTO.ModulesToCompile ? ThinLTO.ModulesToCompile->size()
1091 : ThinLTO.ModuleMap.size();
1092 return RegularLTO.ParallelCodeGenParallelismLevel + ModuleCount;
1097Error LTO::checkPartiallySplit() {
1098 if (!ThinLTO.CombinedIndex.partiallySplitLTOUnits())
1101 Function *TypeTestFunc = RegularLTO.CombinedModule->getFunction(
1103 Function *TypeCheckedLoadFunc = RegularLTO.CombinedModule->getFunction(
1105 Function *TypeCheckedLoadRelativeFunc =
1106 RegularLTO.CombinedModule->getFunction(
1111 if ((TypeTestFunc && !TypeTestFunc->
use_empty()) ||
1112 (TypeCheckedLoadFunc && !TypeCheckedLoadFunc->
use_empty()) ||
1113 (TypeCheckedLoadRelativeFunc &&
1114 !TypeCheckedLoadRelativeFunc->
use_empty()))
1115 return make_error<StringError>(
1116 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1121 for (
auto &
P : ThinLTO.CombinedIndex) {
1122 for (
auto &S :
P.second.SummaryList) {
1123 auto *FS = dyn_cast<FunctionSummary>(S.get());
1126 if (!FS->type_test_assume_vcalls().empty() ||
1127 !FS->type_checked_load_vcalls().empty() ||
1128 !FS->type_test_assume_const_vcalls().empty() ||
1129 !FS->type_checked_load_const_vcalls().empty() ||
1130 !FS->type_tests().empty())
1131 return make_error<StringError>(
1132 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1143 for (
auto &Res : *GlobalResolutions) {
1146 if (Res.second.IRName.empty())
1152 if (Res.second.VisibleOutsideSummary && Res.second.
Prevailing)
1153 GUIDPreservedSymbols.
insert(GUID);
1156 DynamicExportSymbols.insert(GUID);
1158 GUIDPrevailingResolutions[GUID] =
1163 auto It = GUIDPrevailingResolutions.
find(
G);
1164 if (It == GUIDPrevailingResolutions.
end())
1173 if (!StatsFileOrErr)
1174 return StatsFileOrErr.takeError();
1175 std::unique_ptr<ToolOutputFile> StatsFile = std::move(StatsFileOrErr.get());
1183 ThinLTO.CombinedIndex.setWithSupportsHotColdNew();
1185 Error Result = runRegularLTO(AddStream);
1189 Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols);
1199 if (
Index.withSupportsHotColdNew())
1207 for (
auto &
F :
Mod) {
1208 for (
auto &BB :
F) {
1209 for (
auto &
I : BB) {
1210 auto *CI = dyn_cast<CallBase>(&
I);
1213 if (CI->hasFnAttr(
"memprof"))
1214 CI->removeFnAttr(
"memprof");
1221 CI->setMetadata(LLVMContext::MD_memprof,
nullptr);
1222 CI->setMetadata(LLVMContext::MD_callsite,
nullptr);
1236 return DiagFileOrErr.takeError();
1237 DiagnosticOutputFile = std::move(*DiagFileOrErr);
1241 for (
auto &M : RegularLTO.ModsWithSummaries)
1242 if (
Error Err = linkRegularLTO(std::move(M),
1250 if (
Error Err = checkPartiallySplit())
1255 const DataLayout &
DL = RegularLTO.CombinedModule->getDataLayout();
1256 for (
auto &
I : RegularLTO.Commons) {
1257 if (!
I.second.Prevailing)
1260 GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(
I.first);
1261 if (OldGV &&
DL.getTypeAllocSize(OldGV->
getValueType()) ==
I.second.Size) {
1269 auto *GV =
new GlobalVariable(*RegularLTO.CombinedModule, Ty,
false,
1272 GV->setAlignment(
I.second.Alignment);
1284 bool WholeProgramVisibilityEnabledInLTO =
1293 auto It = GlobalResolutions->find(
name);
1294 return (It == GlobalResolutions->end() || It->second.VisibleOutsideSummary);
1300 *RegularLTO.CombinedModule, WholeProgramVisibilityEnabledInLTO,
1302 IsVisibleToRegularObj);
1304 WholeProgramVisibilityEnabledInLTO);
1311 for (
const auto &R : *GlobalResolutions) {
1313 RegularLTO.CombinedModule->getNamedValue(
R.second.IRName);
1314 if (!
R.second.isPrevailingIRSymbol())
1316 if (
R.second.Partition != 0 &&
1317 R.second.Partition != GlobalResolution::External)
1352 backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,
1353 *RegularLTO.CombinedModule, ThinLTO.CombinedIndex))
1361#define HANDLE_LIBCALL(code, name) name,
1362#include "llvm/IR/RuntimeLibcalls.def"
1363#undef HANDLE_LIBCALL
1384 : Conf(Conf), CombinedIndex(CombinedIndex),
1385 ModuleToDefinedGVSummaries(ModuleToDefinedGVSummaries),
1386 OnWrite(OnWrite), ShouldEmitImportsFiles(ShouldEmitImportsFiles) {}
1393 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1401 const std::string &NewModulePath) {
1402 std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
1407 ImportList, ModuleToSummariesForIndex,
1408 DeclarationSummaries);
1411 sys::fs::OpenFlags::OF_None);
1416 &DeclarationSummaries);
1418 if (ShouldEmitImportsFiles) {
1420 ModuleToSummariesForIndex);
1433 std::set<GlobalValue::GUID> CfiFunctionDefs;
1434 std::set<GlobalValue::GUID> CfiFunctionDecls;
1436 std::optional<Error> Err;
1439 bool ShouldEmitIndexFiles;
1442 InProcessThinBackend(
1447 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles)
1449 OnWrite, ShouldEmitImportsFiles),
1450 BackendThreadPool(ThinLTOParallelism), AddStream(
std::
move(AddStream)),
1451 Cache(
std::
move(Cache)), ShouldEmitIndexFiles(ShouldEmitIndexFiles) {
1453 CfiFunctionDefs.insert(
1456 CfiFunctionDecls.insert(
1460 Error runThinLTOBackendThread(
1465 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1468 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1474 return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,
1475 ImportList, DefinedGlobals, &ModuleMap);
1480 if (ShouldEmitIndexFiles) {
1481 if (
auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1487 [](
uint32_t V) { return V == 0; }))
1490 return RunThinBackend(AddStream);
1495 ExportList, ResolvedODR, DefinedGlobals, CfiFunctionDefs,
1500 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1502 return RunThinBackend(CacheAddStream);
1511 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1514 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
1516 ModuleToDefinedGVSummaries.
find(ModulePath)->second;
1517 BackendThreadPool.
async(
1521 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
1528 Error E = runThinLTOBackendThread(
1529 AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList,
1530 ResolvedODR, DefinedGlobals, ModuleMap);
1532 std::unique_lock<std::mutex>
L(ErrMu);
1541 BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList),
1542 std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap));
1545 OnWrite(std::string(ModulePath));
1549 Error wait()
override {
1550 BackendThreadPool.
wait();
1552 return std::move(*Err);
1565 bool ShouldEmitIndexFiles,
1566 bool ShouldEmitImportsFiles) {
1571 return std::make_unique<InProcessThinBackend>(
1572 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1573 AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
1574 ShouldEmitImportsFiles);
1599 return std::string(Path);
1603 if (!ParentPath.
empty()) {
1606 llvm::errs() <<
"warning: could not create directory '" << ParentPath
1607 <<
"': " << EC.message() <<
'\n';
1609 return std::string(NewPath);
1614 std::string OldPrefix, NewPrefix, NativeObjectPrefix;
1618 WriteIndexesThinBackend(
1621 std::string OldPrefix, std::string NewPrefix,
1622 std::string NativeObjectPrefix,
bool ShouldEmitImportsFiles,
1625 OnWrite, ShouldEmitImportsFiles),
1626 OldPrefix(OldPrefix), NewPrefix(NewPrefix),
1627 NativeObjectPrefix(NativeObjectPrefix),
1628 LinkedObjectsFile(LinkedObjectsFile) {}
1634 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1637 std::string NewModulePath =
1640 if (LinkedObjectsFile) {
1641 std::string ObjectPrefix =
1642 NativeObjectPrefix.empty() ? NewPrefix : NativeObjectPrefix;
1643 std::string LinkedObjectsFilePath =
1645 *LinkedObjectsFile << LinkedObjectsFilePath <<
'\n';
1648 if (
auto E = emitFiles(ImportList, ModulePath, NewModulePath))
1652 OnWrite(std::string(ModulePath));
1665 std::string OldPrefix, std::string NewPrefix,
1666 std::string NativeObjectPrefix,
bool ShouldEmitImportsFiles,
1672 return std::make_unique<WriteIndexesThinBackend>(
1673 Conf, CombinedIndex, ModuleToDefinedGVSummaries, OldPrefix,
1674 NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,
1675 LinkedObjectsFile, OnWrite);
1682 ThinLTO.CombinedIndex.releaseTemporaryMemory();
1688 if (ThinLTO.ModuleMap.empty())
1691 if (ThinLTO.ModulesToCompile && ThinLTO.ModulesToCompile->empty()) {
1692 llvm::errs() <<
"warning: [ThinLTO] No module compiled\n";
1703 ThinLTO.ModuleMap.size());
1704 ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule(
1705 ModuleToDefinedGVSummaries);
1713 for (
auto &
Mod : ThinLTO.ModuleMap)
1714 if (!ModuleToDefinedGVSummaries.
count(
Mod.first))
1721 ThinLTO.ModuleMap.size());
1723 ThinLTO.ModuleMap.size());
1727 ThinLTO.CombinedIndex.dumpSCCs(
outs());
1729 std::set<GlobalValue::GUID> ExportedGUIDs;
1731 bool WholeProgramVisibilityEnabledInLTO =
1737 ThinLTO.CombinedIndex.setWithWholeProgramVisibility();
1743 if (WholeProgramVisibilityEnabledInLTO &&
1748 auto It = GlobalResolutions->
find(
name);
1749 return (It == GlobalResolutions->end() ||
1750 It->second.VisibleOutsideSummary);
1754 VisibleToRegularObjSymbols,
1755 IsVisibleToRegularObj);
1761 ThinLTO.CombinedIndex, WholeProgramVisibilityEnabledInLTO,
1762 DynamicExportSymbols, VisibleToRegularObjSymbols);
1767 std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;
1769 LocalWPDTargetsMap);
1772 return ThinLTO.PrevailingModuleForGUID[
GUID] == S->modulePath();
1776 ContextDisambiguation.
run(ThinLTO.CombinedIndex, isPrevailing);
1783 for (
auto &Res : *GlobalResolutions) {
1786 if (Res.second.Partition != GlobalResolution::External ||
1787 !Res.second.isPrevailingIRSymbol())
1792 if (ThinLTO.CombinedIndex.isGUIDLive(GUID))
1793 ExportedGUIDs.insert(GUID);
1800 GlobalResolutions.reset();
1804 isPrevailing, ImportLists, ExportLists);
1808 for (
auto &Def : ThinLTO.CombinedIndex.cfiFunctionDefs())
1809 ExportedGUIDs.insert(
1811 for (
auto &Decl : ThinLTO.CombinedIndex.cfiFunctionDecls())
1812 ExportedGUIDs.insert(
1816 const auto &ExportList = ExportLists.
find(ModuleIdentifier);
1817 return (ExportList != ExportLists.end() && ExportList->second.
count(VI)) ||
1818 ExportedGUIDs.count(
VI.getGUID());
1824 LocalWPDTargetsMap);
1829 auto recordNewLinkage = [&](
StringRef ModuleIdentifier,
1832 ResolvedODR[ModuleIdentifier][
GUID] = NewLinkage;
1835 recordNewLinkage, GUIDPreservedSymbols);
1844 TimeTraceScopeExit.release();
1846 std::unique_ptr<ThinBackendProc> BackendProc =
1847 ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
1851 ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;
1853 auto ProcessOneModule = [&](
int I) ->
Error {
1857 return BackendProc->start(RegularLTO.ParallelCodeGenParallelismLevel +
I,
1858 Mod.second, ImportLists[
Mod.first],
1859 ExportLists[
Mod.first], ResolvedODR[
Mod.first],
1863 if (BackendProc->getThreadCount() == 1) {
1868 for (
int I = 0, E = ModuleMap.
size();
I != E; ++
I)
1869 if (
Error E = ProcessOneModule(
I))
1876 std::vector<BitcodeModule *> ModulesVec;
1877 ModulesVec.reserve(ModuleMap.
size());
1878 for (
auto &
Mod : ModuleMap)
1879 ModulesVec.push_back(&
Mod.second);
1881 if (
Error E = ProcessOneModule(
I))
1884 return BackendProc->wait();
1894 if (!Filename.empty() && Count != -1)
1902 if (
Error E = ResultOrErr.takeError())
1903 return std::move(E);
1906 (*ResultOrErr)->keep();
1914 if (StatsFilename.
empty())
1925 return std::move(StatsFile);
1932 auto Seq = llvm::seq<int>(0, R.size());
1933 std::vector<int> ModulesOrdering(Seq.begin(), Seq.end());
1934 llvm::sort(ModulesOrdering, [&](
int LeftIndex,
int RightIndex) {
1935 auto LSize = R[LeftIndex]->getBuffer().
size();
1936 auto RSize = R[RightIndex]->getBuffer().
size();
1937 return LSize > RSize;
1939 return ModulesOrdering;
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static void writeToResolutionFile(raw_ostream &OS, InputFile *Input, ArrayRef< SymbolResolution > Res)
static void thinLTOResolvePrevailingGUID(const Config &C, ValueInfo VI, DenseSet< GlobalValueSummary * > &GlobalInvolvedWithAlias, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, function_ref< void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> recordNewLinkage, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols)
static void handleNonPrevailingComdat(GlobalValue &GV, std::set< const Comdat * > &NonPrevailingComdats)
static cl::opt< bool > DumpThinCGSCCs("dump-thin-cg-sccs", cl::init(false), cl::Hidden, cl::desc("Dump the SCCs in the ThinLTO index's callgraph"))
static void thinLTOInternalizeAndPromoteGUID(ValueInfo VI, function_ref< bool(StringRef, ValueInfo)> isExported, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
cl::opt< bool > UseNewDbgInfoFormat
static const char * libcallRoutineNames[]
llvm::cl::opt< bool > UseNewDbgInfoFormat
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This file defines the SmallSet class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Represents a module in a bitcode file.
StringRef getModuleIdentifier() const
Error readSummary(ModuleSummaryIndex &CombinedIndex, StringRef ModulePath, std::function< bool(GlobalValue::GUID)> IsPrevailing=nullptr)
Parse the specified bitcode buffer and merge its module summary index into CombinedIndex.
Expected< std::unique_ptr< Module > > parseModule(LLVMContext &Context, ParserCallbacks Callbacks={})
Read the entire bitcode module and return it.
Expected< std::unique_ptr< Module > > getLazyModule(LLVMContext &Context, bool ShouldLazyLoadMetadata, bool IsImporting, ParserCallbacks Callbacks={})
Read the bitcode module and prepare for lazy deserialization of function bodies.
static ConstantAggregateZero * get(Type *Ty)
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&... Args)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Implements a dense probed hash-table based set.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
std::unordered_map< GlobalValue::GUID, GlobalValueSummary::ImportKind > FunctionsToImportTy
The functions to import from a source module and their import type.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalObject.
Function and variable summary information to aid decisions and implementation of importing.
static bool isAppendingLinkage(LinkageTypes Linkage)
static bool isExternalWeakLinkage(LinkageTypes Linkage)
static bool isLocalLinkage(LinkageTypes Linkage)
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
void setUnnamedAddr(UnnamedAddr Val)
bool hasLocalLinkage() const
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
const Comdat * getComdat() const
static bool isLinkOnceLinkage(LinkageTypes Linkage)
static GUID getGUID(StringRef GlobalName)
Return a 64-bit global unique ID constructed from global value name (i.e.
void setLinkage(LinkageTypes LT)
DLLStorageClassTypes
Storage classes of global values for PE targets.
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
const GlobalObject * getAliaseeObject() const
static bool isExternalLinkage(LinkageTypes Linkage)
VisibilityTypes
An enumeration for the kinds of visibility of global values.
@ DefaultVisibility
The GV is visible.
static LinkageTypes getWeakLinkage(bool ODR)
bool isWeakForLinker() const
bool hasAppendingLinkage() const
bool hasAvailableExternallyLinkage() const
std::string getGlobalIdentifier() const
Return the modified name for this global value suitable to be used as the key for a global lookup (e....
LinkageTypes
An enumeration for the kinds of linkage for global values.
@ CommonLinkage
Tentative definitions.
@ InternalLinkage
Rename collisions when linking (static functions).
@ ExternalLinkage
Externally visible function.
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
@ AvailableExternallyLinkage
Available for inspection, not emission.
DLLStorageClassTypes getDLLStorageClass() const
Type * getValueType() const
static bool isLinkOnceODRLinkage(LinkageTypes Linkage)
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
This is an important class for using LLVM in a threaded context.
This class implements a map that also provides access to all stored values in a deterministic order.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
Class to hold module path string table and global value map, and encapsulate methods for operating on...
std::set< std::string > & cfiFunctionDecls()
const ModuleHash & getModuleHash(const StringRef ModPath) const
Get the module SHA1 hash recorded for the given module path.
const StringMap< ModuleHash > & modulePaths() const
Table of modules, containing module hash and id.
std::set< std::string > & cfiFunctionDefs()
void addModule(Module *M)
static void CollectAsmSymvers(const Module &M, function_ref< void(StringRef, StringRef)> AsmSymver)
Parse inline ASM and collect the symvers directives that are defined in the current module.
uint32_t getSymbolFlags(Symbol S) const
ArrayRef< Symbol > symbols() const
A Module instance is used to store all the information related to an LLVM module.
A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...
A class that wrap the SHA1 algorithm.
void update(ArrayRef< uint8_t > Data)
Digest more data.
std::array< uint8_t, 20 > result()
Return the current raw 160-bits SHA1 for the digested data since the last call to init().
A non-threaded implementation.
void wait() override
Blocking wait for all the tasks to execute first.
unsigned getMaxConcurrency() const override
Returns always 1: there is no concurrency.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef str() const
Explicit conversion to StringRef.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
MCTargetOptions MCOptions
Machine level options.
DebuggerKind DebuggerTuning
Which debugger to tune for.
unsigned FunctionSections
Emit functions into separate sections.
unsigned DataSections
Emit data into separate sections.
auto async(Function &&F, Args &&...ArgList)
Asynchronous submission of a task to the pool.
This tells how a thread pool will be used.
Triple - Helper class for working with autoconf configuration names.
bool isArm64e() const
Tests whether the target is the Apple "arm64e" AArch64 subarch.
ArchType getArch() const
Get the parsed architecture type of this triple.
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, XROS, or DriverKit).
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static IntegerType * getInt8Ty(LLVMContext &C)
void setName(const Twine &Name)
Change the name of the value.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
std::pair< iterator, bool > insert(const ValueT &V)
iterator find(const_arg_type_t< ValueT > V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
An efficient, type-erasing, non-owning reference to a callable.
Ephemeral symbols produced by Reader::symbols() and Reader::module_symbols().
Error add(std::unique_ptr< InputFile > Obj, ArrayRef< SymbolResolution > Res)
Add an input file to the LTO link, using the provided symbol resolutions.
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.
StringLiteral getThinLTODefaultCPU(const Triple &TheTriple)
Expected< std::unique_ptr< ToolOutputFile > > setupStatsFile(StringRef StatsFilename)
Setups the output file for saving statistics.
Error backend(const Config &C, AddStreamFn AddStream, unsigned ParallelCodeGenParallelismLevel, Module &M, ModuleSummaryIndex &CombinedIndex)
Runs a regular LTO backend.
Error finalizeOptimizationRemarks(std::unique_ptr< ToolOutputFile > DiagOutputFile)
ThinBackend createWriteIndexesThinBackend(std::string OldPrefix, std::string NewPrefix, std::string NativeObjectPrefix, bool ShouldEmitImportsFiles, raw_fd_ostream *LinkedObjectsFile, IndexWriteCallback OnWrite)
This ThinBackend writes individual module indexes to files, instead of running the individual backend...
std::vector< int > generateModulesOrdering(ArrayRef< BitcodeModule * > R)
Produces a container ordering for optimal multi-threaded processing.
Expected< std::unique_ptr< ToolOutputFile > > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::optional< uint64_t > RemarksHotnessThreshold=0, int Count=-1)
Setup optimization remarks.
void updateMemProfAttributes(Module &Mod, const ModuleSummaryIndex &Index)
Updates MemProf attributes (and metadata) based on whether the index has recorded that we are linking...
Expected< IRSymtabFile > readIRSymtab(MemoryBufferRef MBRef)
Reads a bitcode file, creating its irsymtab if necessary.
void write64le(void *P, uint64_t V)
void write32le(void *P, uint32_t V)
std::error_code create_directories(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create all the non-existent directories in path.
StringRef parent_path(StringRef path, Style style=Style::native)
Get parent path.
bool replace_path_prefix(SmallVectorImpl< char > &Path, StringRef OldPrefix, StringRef NewPrefix, Style style=Style::native)
Replace matching path prefix with another path.
This is an optimization pass for GlobalISel generic memory operations.
ThreadPoolStrategy heavyweight_hardware_concurrency(unsigned ThreadCount=0)
Returns a thread strategy for tasks requiring significant memory or other resources.
cl::opt< std::string > RemarksFormat("lto-pass-remarks-format", cl::desc("The format used for serializing remarks (default: YAML)"), cl::value_desc("format"), cl::init("yaml"))
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
void gatherImportedSummariesForModule(StringRef ModulePath, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, const FunctionImporter::ImportMapTy &ImportList, std::map< std::string, GVSummaryMapTy > &ModuleToSummariesForIndex, GVSummaryPtrSet &DecSummaries)
Compute the set of summaries needed for a ThinLTO backend compilation of ModulePath.
void ComputeCrossModuleImport(const ModuleSummaryIndex &Index, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, DenseMap< StringRef, FunctionImporter::ImportMapTy > &ImportLists, DenseMap< StringRef, FunctionImporter::ExportSetTy > &ExportLists)
Compute all the imports and exports for every module in the Index.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
void 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...
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.
Error joinErrors(Error E1, Error E2)
Concatenate errors.
void updatePublicTypeTestCalls(Module &M, bool WholeProgramVisibilityEnabledInLTO)
void getVisibleToRegularObjVtableGUIDs(ModuleSummaryIndex &Index, DenseSet< GlobalValue::GUID > &VisibleToRegularObjSymbols, function_ref< bool(StringRef)> IsVisibleToRegularObj)
Based on typeID string, get all associated vtable GUIDS that are visible to regular objects.
void sort(IteratorTy Start, IteratorTy End)
void writeIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out, const std::map< std::string, GVSummaryMapTy > *ModuleToSummariesForIndex=nullptr, const GVSummaryPtrSet *DecSummaries=nullptr)
Write the specified module summary index to the given raw output stream, where it will be written in ...
bool timeTraceProfilerEnabled()
Is the time trace profiler enabled, i.e. initialized?
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Expected< std::unique_ptr< ToolOutputFile > > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::optional< uint64_t > RemarksHotnessThreshold=0)
Setup optimization remarks that output to a file.
cl::opt< bool > EnableLTOInternalization
Enable global value internalization in LTO.
cl::opt< bool > RemarksWithHotness("lto-pass-remarks-with-hotness", cl::desc("With PGO, include profile count in optimization remarks"), cl::Hidden)
void computeSyntheticCounts(ModuleSummaryIndex &Index)
Compute synthetic function entry counts.
void timeTraceProfilerEnd()
Manually end the last time section.
cl::opt< std::string > RemarksFilename("lto-pass-remarks-output", cl::desc("Output filename for pass remarks"), cl::value_desc("filename"))
cl::opt< bool > SupportsHotColdNew
Indicate we are linking with an allocator that supports hot/cold operator new interfaces.
void updateIndexWPDForExports(ModuleSummaryIndex &Summary, function_ref< bool(StringRef, ValueInfo)> isExported, std::map< ValueInfo, std::vector< VTableSlotSummary > > &LocalWPDTargetsMap)
Call after cross-module importing to update the recorded single impl devirt target names for any loca...
void thinLTOResolvePrevailingInIndex(const lto::Config &C, ModuleSummaryIndex &Index, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, function_ref< void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> recordNewLinkage, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols)
Resolve linkage for prevailing symbols in the Index.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Mod
The access may modify the value stored in memory.
cl::opt< bool > EnableMemProfContextDisambiguation
Enable MemProf context disambiguation for thin link.
void runWholeProgramDevirtOnIndex(ModuleSummaryIndex &Summary, std::set< GlobalValue::GUID > &ExportedGUIDs, std::map< ValueInfo, std::vector< VTableSlotSummary > > &LocalWPDTargetsMap)
Perform index-based whole program devirtualization on the Summary index.
std::unordered_set< GlobalValueSummary * > GVSummaryPtrSet
A set of global value summary pointers.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
cl::opt< std::optional< uint64_t >, false, remarks::HotnessThresholdParser > RemarksHotnessThreshold("lto-pass-remarks-hotness-threshold", cl::desc("Minimum profile count required for an " "optimization remark to be output." " Use 'auto' to apply the threshold from profile summary."), cl::value_desc("uint or 'auto'"), cl::init(0), cl::Hidden)
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
bool UpgradeDebugInfo(Module &M)
Check the debug info version number, if it is out-dated, drop the debug info.
std::array< uint32_t, 5 > ModuleHash
160 bits SHA1
std::function< Expected< AddStreamFn >(unsigned Task, StringRef Key, const Twine &ModuleName)> FileCache
This is the type of a file cache.
void PrintStatisticsJSON(raw_ostream &OS)
Print statistics in JSON format.
void computeDeadSymbolsWithConstProp(ModuleSummaryIndex &Index, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols, function_ref< PrevailingType(GlobalValue::GUID)> isPrevailing, bool ImportEnabled)
Compute dead symbols and run constant propagation in combined index after that.
@ Keep
No function return thunk.
void updateVCallVisibilityInModule(Module &M, bool WholeProgramVisibilityEnabledInLTO, const DenseSet< GlobalValue::GUID > &DynamicExportSymbols, bool ValidateAllVtablesHaveTypeInfos, function_ref< bool(StringRef)> IsVisibleToRegularObj)
If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...
TimeTraceProfilerEntry * timeTraceProfilerBegin(StringRef Name, StringRef Detail)
Manually begin a time section, with the given Name and Detail.
void updateVCallVisibilityInIndex(ModuleSummaryIndex &Index, bool WholeProgramVisibilityEnabledInLTO, const DenseSet< GlobalValue::GUID > &DynamicExportSymbols, const DenseSet< GlobalValue::GUID > &VisibleToRegularObjSymbols)
If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...
Implement std::hash so that hash_code can be used in STL containers.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Used in the streaming interface as the general argument type.
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.