22 #include "llvm/Config/llvm-config.h" 45 #include "llvm/Support/VCSRevision.h" 59 using namespace object;
61 #define DEBUG_TYPE "lto" 65 cl::desc(
"Dump the SCCs in the ThinLTO index's callgraph"));
70 cl::desc(
"Enable global value internalization in LTO"));
79 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
81 const std::set<GlobalValue::GUID> &CfiFunctionDefs,
82 const std::set<GlobalValue::GUID> &CfiFunctionDecls) {
90 Hasher.
update(LLVM_VERSION_STRING);
92 Hasher.
update(LLVM_REVISION);
100 auto AddUnsigned = [&](
unsigned I) {
105 auto AddUint64 = [&](uint64_t
I) {
119 for (
auto &A : Conf.
MAttrs)
141 auto ModHash =
Index.getModuleHash(ModuleID);
144 std::vector<uint64_t> ExportsGUID;
145 ExportsGUID.reserve(ExportList.
size());
146 for (
const auto &
VI : ExportList) {
147 auto GUID =
VI.getGUID();
148 ExportsGUID.push_back(GUID);
153 for (uint64_t GUID : ExportsGUID) {
162 std::vector<ImportMapIteratorTy> ImportModulesVector;
163 ImportModulesVector.reserve(ImportList.
size());
165 for (ImportMapIteratorTy It = ImportList.
begin(); It != ImportList.
end();
167 ImportModulesVector.push_back(It);
170 [](
const ImportMapIteratorTy &Lhs,
const ImportMapIteratorTy &Rhs)
171 ->
bool {
return Lhs->getKey() < Rhs->getKey(); });
172 for (
const ImportMapIteratorTy &EntryIt : ImportModulesVector) {
173 auto ModHash =
Index.getModuleHash(EntryIt->first());
176 AddUint64(EntryIt->second.size());
177 for (
auto &Fn : EntryIt->second)
182 for (
auto &Entry : ResolvedODR) {
191 std::set<GlobalValue::GUID> UsedCfiDefs;
192 std::set<GlobalValue::GUID> UsedCfiDecls;
195 std::set<GlobalValue::GUID> UsedTypeIds;
198 if (CfiFunctionDefs.count(ValueGUID))
199 UsedCfiDefs.insert(ValueGUID);
200 if (CfiFunctionDecls.count(ValueGUID))
201 UsedCfiDecls.insert(ValueGUID);
206 AddUnsigned(
GS->isLive());
207 AddUnsigned(
GS->canAutoHide());
209 AddUnsigned(
VI.isDSOLocal());
210 AddUsedCfiGlobal(
VI.getGUID());
212 if (
auto *GVS = dyn_cast<GlobalVarSummary>(
GS)) {
213 AddUnsigned(GVS->maybeReadOnly());
214 AddUnsigned(GVS->maybeWriteOnly());
216 if (
auto *
FS = dyn_cast<FunctionSummary>(
GS)) {
217 for (
auto &TT :
FS->type_tests())
218 UsedTypeIds.insert(TT);
219 for (
auto &TT :
FS->type_test_assume_vcalls())
220 UsedTypeIds.insert(TT.GUID);
221 for (
auto &TT :
FS->type_checked_load_vcalls())
222 UsedTypeIds.insert(TT.GUID);
223 for (
auto &TT :
FS->type_test_assume_const_vcalls())
224 UsedTypeIds.insert(TT.VFunc.GUID);
225 for (
auto &TT :
FS->type_checked_load_const_vcalls())
226 UsedTypeIds.insert(TT.VFunc.GUID);
227 for (
auto &ET :
FS->calls()) {
228 AddUnsigned(ET.first.isDSOLocal());
229 AddUsedCfiGlobal(ET.first.getGUID());
236 for (
auto &
GS : DefinedGlobals) {
240 AddUsedCfiGlobal(
GS.first);
241 AddUsedThings(
GS.second);
246 for (
auto &ImpM : ImportList)
247 for (
auto &ImpF : ImpM.second) {
252 if (
auto *AS = dyn_cast_or_null<AliasSummary>(S))
253 AddUsedThings(AS->getBaseObject());
259 AddUnsigned(S.TTRes.TheKind);
260 AddUnsigned(S.TTRes.SizeM1BitWidth);
262 AddUint64(S.TTRes.AlignLog2);
263 AddUint64(S.TTRes.SizeM1);
264 AddUint64(S.TTRes.BitMask);
265 AddUint64(S.TTRes.InlineBits);
267 AddUint64(S.WPDRes.size());
268 for (
auto &WPD : S.WPDRes) {
269 AddUnsigned(WPD.first);
270 AddUnsigned(WPD.second.TheKind);
271 AddString(WPD.second.SingleImplName);
273 AddUint64(WPD.second.ResByArg.size());
274 for (
auto &ByArg : WPD.second.ResByArg) {
275 AddUint64(ByArg.first.size());
276 for (uint64_t
Arg : ByArg.first)
278 AddUnsigned(ByArg.second.TheKind);
279 AddUint64(ByArg.second.Info);
280 AddUnsigned(ByArg.second.Byte);
281 AddUnsigned(ByArg.second.Bit);
288 auto TidIter =
Index.typeIds().equal_range(TId);
289 for (
auto It = TidIter.first; It != TidIter.second; ++It)
290 AddTypeIdSummary(It->second.first, It->second.second);
293 AddUnsigned(UsedCfiDefs.size());
294 for (
auto &V : UsedCfiDefs)
297 AddUnsigned(UsedCfiDecls.size());
298 for (
auto &V : UsedCfiDecls)
304 Hasher.
update(FileOrErr.get()->getBuffer());
309 Hasher.
update(FileOrErr.get()->getBuffer());
324 for (
auto &S :
VI.getSummaryList()) {
339 if (isPrevailing(
VI.getGUID(), S.get())) {
352 S->setCanAutoHide(
VI.canAutoHide() &&
353 !GUIDPreservedSymbols.
count(
VI.getGUID()));
357 else if (!isa<AliasSummary>(S.get()) &&
358 !GlobalInvolvedWithAlias.
count(S.get()))
360 if (S->linkage() != OriginalLinkage)
361 recordNewLinkage(S->modulePath(),
VI.getGUID(), S->linkage());
383 for (
auto &S :
I.second.SummaryList)
384 if (
auto AS = dyn_cast<AliasSummary>(S.get()))
385 GlobalInvolvedWithAlias.
insert(&AS->getAliasee());
389 isPrevailing, recordNewLinkage,
390 GUIDPreservedSymbols);
394 if (
auto *VarSummary = dyn_cast<GlobalVarSummary>(GVS->
getBaseObject()))
395 return !VarSummary->maybeReadOnly() && !VarSummary->maybeWriteOnly() &&
405 for (
auto &S :
VI.getSummaryList()) {
406 if (isExported(S->modulePath(),
VI)) {
414 isPrevailing(
VI.getGUID(), S.get())) &&
451 File->TargetTriple = FOrErr->TheReader.getTargetTriple();
452 File->SourceFileName = FOrErr->TheReader.getSourceFileName();
453 File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts();
454 File->DependentLibraries = FOrErr->TheReader.getDependentLibraries();
455 File->ComdatTable = FOrErr->TheReader.getComdatTable();
457 for (
unsigned I = 0;
I != FOrErr->Mods.size(); ++
I) {
458 size_t Begin =
File->Symbols.size();
460 FOrErr->TheReader.module_symbols(
I))
463 if (Sym.isGlobal() && !Sym.isFormatSpecific())
464 File->Symbols.push_back(Sym);
465 File->ModuleSymIndices.push_back({Begin,
File->Symbols.size()});
468 File->Mods = FOrErr->Mods;
474 return Mods[0].getModuleIdentifier();
478 assert(Mods.size() == 1 &&
"Expect only one bitcode module");
482 LTO::RegularLTOState::RegularLTOState(
unsigned ParallelCodeGenParallelismLevel,
484 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
485 Ctx(Conf), CombinedModule(
std::make_unique<
Module>(
"ld-temp.o", Ctx)),
486 Mover(
std::make_unique<
IRMover>(*CombinedModule)) {}
488 LTO::ThinLTOState::ThinLTOState(
ThinBackend Backend)
489 : Backend(Backend), CombinedIndex(
false) {
496 unsigned ParallelCodeGenParallelismLevel)
498 RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),
508 unsigned Partition,
bool InSummary) {
509 auto *ResI = Res.
begin();
510 auto *ResE = Res.
end();
517 Triple TT(RegularLTO.CombinedModule->getTargetTriple());
521 if (TT.isOSBinFormatCOFF() &&
Name.startswith(
"__imp_"))
522 Name =
Name.substr(strlen(
"__imp_"));
523 auto &GlobalRes = GlobalResolutions[
Name];
524 GlobalRes.UnnamedAddr &= Sym.isUnnamedAddr();
526 assert(!GlobalRes.Prevailing &&
527 "Multiple prevailing defs are not allowed");
528 GlobalRes.Prevailing =
true;
529 GlobalRes.IRName = std::string(Sym.getIRName());
530 }
else if (!GlobalRes.Prevailing && GlobalRes.IRName.empty()) {
537 GlobalRes.IRName = std::string(Sym.getIRName());
546 GlobalRes.Partition != Partition)) {
547 GlobalRes.Partition = GlobalResolution::External;
550 GlobalRes.Partition = Partition;
554 GlobalRes.VisibleOutsideSummary |=
563 auto ResI = Res.
begin();
568 OS <<
"-r=" << Path <<
',' << Sym.getName() <<
',';
571 if (Res.FinalDefinitionInLinkageUnit)
573 if (Res.VisibleToRegularObj)
575 if (Res.LinkerRedefined)
585 assert(!CalledGetMaxTasks);
590 if (RegularLTO.CombinedModule->getTargetTriple().empty())
591 RegularLTO.CombinedModule->setTargetTriple(Input->getTargetTriple());
594 for (
unsigned I = 0;
I != Input->Mods.size(); ++
I)
595 if (
Error Err = addModule(*Input,
I, ResI, Res.
end()))
609 if (EnableSplitLTOUnit.
hasValue()) {
613 if (EnableSplitLTOUnit.
getValue() != LTOInfo->EnableSplitLTOUnit)
614 ThinLTO.CombinedIndex.setPartiallySplitLTOUnits();
616 EnableSplitLTOUnit = LTOInfo->EnableSplitLTOUnit;
619 auto ModSyms = Input.module_symbols(ModI);
620 addModuleToGlobalRes(ModSyms, {ResI, ResE},
621 LTOInfo->IsThinLTO ? ThinLTO.ModuleMap.size() + 1 : 0,
622 LTOInfo->HasSummary);
624 if (LTOInfo->IsThinLTO)
625 return addThinLTO(BM, ModSyms, ResI, ResE);
627 RegularLTO.EmptyCombinedModule =
false;
629 addRegularLTO(BM, ModSyms, ResI, ResE);
633 if (!LTOInfo->HasSummary)
634 return linkRegularLTO(
std::move(*ModOrErr),
false);
640 RegularLTO.ModsWithSummaries.push_back(
std::move(*ModOrErr));
656 std::set<const Comdat *> &NonPrevailingComdats) {
661 if (!NonPrevailingComdats.count(
C))
670 if (
auto GO = dyn_cast<GlobalObject>(&GV))
671 GO->setComdat(
nullptr);
681 RegularLTOState::AddedModule
Mod;
690 if (
Error Err =
M.materializeMetadata())
698 if (GV.hasAppendingLinkage())
699 Mod.Keep.push_back(&GV);
702 for (
auto &GA :
M.aliases())
704 AliasedGlobals.
insert(GO);
713 auto MsymI = SymTab.
symbols().begin(), MsymE = SymTab.
symbols().end();
715 while (MsymI != MsymE) {
725 std::set<const Comdat *> NonPrevailingComdats;
736 if (Sym.isUndefined())
738 Mod.Keep.push_back(GV);
749 }
else if (isa<GlobalObject>(GV) &&
750 (GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||
751 GV->hasAvailableExternallyLinkage()) &&
752 !AliasedGlobals.
count(cast<GlobalObject>(GV))) {
758 Mod.Keep.push_back(GV);
761 NonPrevailingComdats.insert(GV->getComdat());
762 cast<GlobalObject>(GV)->setComdat(
nullptr);
767 GV->setDSOLocal(
true);
768 if (GV->hasDLLImportStorageClass())
770 DefaultStorageClass);
776 if (Sym.isCommon()) {
779 auto &CommonRes = RegularLTO.Commons[std::string(Sym.getIRName())];
780 CommonRes.Size =
std::max(CommonRes.Size, Sym.getCommonSize());
781 MaybeAlign SymAlign(Sym.getCommonAlignment());
783 CommonRes.Align =
max(*SymAlign, CommonRes.Align);
788 if (!
M.getComdatSymbolTable().empty())
795 Error LTO::linkRegularLTO(RegularLTOState::AddedModule Mod,
796 bool LivenessFromIndex) {
797 std::vector<GlobalValue *> Keep;
799 if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->
getGUID())) {
800 if (
Function *
F = dyn_cast<Function>(GV)) {
804 <<
" not added to the combined module ");
817 RegularLTO.CombinedModule->getNamedValue(GV->
getName());
835 ThinLTO.ModuleMap.size()))
842 if (!Sym.getIRName().empty()) {
853 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(
861 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(
863 S->setDSOLocal(
true);
869 if (!ThinLTO.ModuleMap.insert({BM.getModuleIdentifier(), BM}).second)
870 return make_error<StringError>(
871 "Expected at most one ThinLTO module per bitcode file",
875 if (!ThinLTO.ModulesToCompile)
876 ThinLTO.ModulesToCompile = ModuleMapType();
892 CalledGetMaxTasks =
true;
893 auto ModuleCount = ThinLTO.ModulesToCompile ? ThinLTO.ModulesToCompile->size()
894 : ThinLTO.ModuleMap.size();
895 return RegularLTO.ParallelCodeGenParallelismLevel + ModuleCount;
900 Error LTO::checkPartiallySplit() {
901 if (!ThinLTO.CombinedIndex.partiallySplitLTOUnits())
904 Function *TypeTestFunc = RegularLTO.CombinedModule->getFunction(
906 Function *TypeCheckedLoadFunc = RegularLTO.CombinedModule->getFunction(
911 if ((TypeTestFunc && !TypeTestFunc->
use_empty()) ||
912 (TypeCheckedLoadFunc && !TypeCheckedLoadFunc->
use_empty()))
913 return make_error<StringError>(
914 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
919 for (
auto &
P : ThinLTO.CombinedIndex) {
920 for (
auto &S :
P.second.SummaryList) {
921 auto *
FS = dyn_cast<FunctionSummary>(S.get());
924 if (!
FS->type_test_assume_vcalls().empty() ||
925 !
FS->type_checked_load_vcalls().empty() ||
926 !
FS->type_test_assume_const_vcalls().empty() ||
927 !
FS->type_checked_load_const_vcalls().empty() ||
928 !
FS->type_tests().empty())
929 return make_error<StringError>(
930 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
941 for (
auto &Res : GlobalResolutions) {
944 if (Res.second.IRName.empty())
950 if (Res.second.VisibleOutsideSummary && Res.second.
Prevailing)
951 GUIDPreservedSymbols.
insert(GUID);
953 GUIDPrevailingResolutions[GUID] =
958 auto It = GUIDPrevailingResolutions.
find(
G);
959 if (It == GUIDPrevailingResolutions.
end())
969 return StatsFileOrErr.takeError();
970 std::unique_ptr<ToolOutputFile> StatsFile =
std::move(StatsFileOrErr.get());
972 Error Result = runRegularLTO(AddStream);
974 Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols);
989 return DiagFileOrErr.takeError();
993 for (
auto &M : RegularLTO.ModsWithSummaries)
1002 if (
Error Err = checkPartiallySplit())
1007 const DataLayout &
DL = RegularLTO.CombinedModule->getDataLayout();
1008 for (
auto &
I : RegularLTO.Commons) {
1009 if (!
I.second.Prevailing)
1012 GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(
I.first);
1013 if (OldGV &&
DL.getTypeAllocSize(OldGV->
getValueType()) ==
I.second.Size) {
1021 auto *GV =
new GlobalVariable(*RegularLTO.CombinedModule, Ty,
false,
1024 GV->setAlignment(
I.second.Align);
1044 for (
const auto &R : GlobalResolutions) {
1045 if (!
R.second.isPrevailingIRSymbol())
1047 if (
R.second.Partition != 0 &&
1048 R.second.Partition != GlobalResolution::External)
1052 RegularLTO.CombinedModule->getNamedValue(
R.second.IRName);
1063 RegularLTO.CombinedModule->addModuleFlag(
Module::Error,
"LTOPostLink", 1);
1072 Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,
1073 std::move(RegularLTO.CombinedModule), ThinLTO.CombinedIndex))
1081 #define HANDLE_LIBCALL(code, name) name, 1082 #include "llvm/IR/RuntimeLibcalls.def" 1083 #undef HANDLE_LIBCALL 1100 : Conf(Conf), CombinedIndex(CombinedIndex),
1101 ModuleToDefinedGVSummaries(ModuleToDefinedGVSummaries) {}
1104 virtual Error start(
1108 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1110 virtual Error wait() = 0;
1111 virtual unsigned getThreadCount() = 0;
1119 std::set<GlobalValue::GUID> CfiFunctionDefs;
1120 std::set<GlobalValue::GUID> CfiFunctionDecls;
1126 InProcessThinBackend(
1132 BackendThreadPool(ThinLTOParallelism), AddStream(
std::
move(AddStream)),
1135 CfiFunctionDefs.insert(
1138 CfiFunctionDecls.insert(
1142 Error runThinLTOBackendThread(
1147 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1150 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1156 return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,
1157 ImportList, DefinedGlobals, ModuleMap);
1164 [](
uint32_t V) {
return V == 0; }))
1167 return RunThinBackend(AddStream);
1172 ExportList, ResolvedODR, DefinedGlobals, CfiFunctionDefs,
1175 return RunThinBackend(CacheAddStream);
1184 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1187 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
1189 ModuleToDefinedGVSummaries.
find(ModulePath)->second;
1190 BackendThreadPool.
async(
1194 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
1201 Error E = runThinLTOBackendThread(
1202 AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList,
1203 ResolvedODR, DefinedGlobals, ModuleMap);
1205 std::unique_lock<std::mutex> L(ErrMu);
1214 BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList),
1215 std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap));
1219 Error wait()
override {
1220 BackendThreadPool.
wait();
1227 unsigned getThreadCount()
override {
1237 return std::make_unique<InProcessThinBackend>(
1238 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries, AddStream,
1247 const std::string &OldPrefix,
1248 const std::string &NewPrefix) {
1249 if (OldPrefix.empty() && NewPrefix.empty())
1254 if (!ParentPath.
empty()) {
1257 llvm::errs() <<
"warning: could not create directory '" << ParentPath
1258 <<
"': " << EC.message() <<
'\n';
1260 return std::string(NewPath.
str());
1265 std::string OldPrefix, NewPrefix;
1266 bool ShouldEmitImportsFiles;
1271 WriteIndexesThinBackend(
1274 std::string OldPrefix, std::string NewPrefix,
bool ShouldEmitImportsFiles,
1277 OldPrefix(OldPrefix), NewPrefix(NewPrefix),
1278 ShouldEmitImportsFiles(ShouldEmitImportsFiles),
1279 LinkedObjectsFile(LinkedObjectsFile), OnWrite(OnWrite) {}
1285 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1288 std::string NewModulePath =
1291 if (LinkedObjectsFile)
1292 *LinkedObjectsFile << NewModulePath <<
'\n';
1294 std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
1296 ImportList, ModuleToSummariesForIndex);
1305 if (ShouldEmitImportsFiles) {
1307 ModuleToSummariesForIndex);
1313 OnWrite(std::string(ModulePath));
1321 unsigned getThreadCount()
override {
return 1; }
1326 std::string OldPrefix, std::string NewPrefix,
bool ShouldEmitImportsFiles,
1331 return std::make_unique<WriteIndexesThinBackend>(
1332 Conf, CombinedIndex, ModuleToDefinedGVSummaries, OldPrefix, NewPrefix,
1333 ShouldEmitImportsFiles, LinkedObjectsFile, OnWrite);
1339 if (ThinLTO.ModuleMap.empty())
1342 if (ThinLTO.ModulesToCompile && ThinLTO.ModulesToCompile->empty()) {
1343 llvm::errs() <<
"warning: [ThinLTO] No module compiled\n";
1354 ModuleToDefinedGVSummaries(ThinLTO.ModuleMap.size());
1355 ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule(
1356 ModuleToDefinedGVSummaries);
1364 for (
auto &Mod : ThinLTO.ModuleMap)
1365 if (!ModuleToDefinedGVSummaries.
count(
Mod.first))
1372 ThinLTO.ModuleMap.size());
1374 ThinLTO.ModuleMap.size());
1378 ThinLTO.CombinedIndex.dumpSCCs(
outs());
1380 std::set<GlobalValue::GUID> ExportedGUIDs;
1390 std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;
1392 LocalWPDTargetsMap);
1396 ImportLists, ExportLists);
1402 for (
auto &Res : GlobalResolutions) {
1405 if (Res.second.Partition != GlobalResolution::External ||
1406 !Res.second.isPrevailingIRSymbol())
1411 if (ThinLTO.CombinedIndex.isGUIDLive(GUID))
1412 ExportedGUIDs.insert(GUID);
1417 for (
auto &
Def : ThinLTO.CombinedIndex.cfiFunctionDefs())
1418 ExportedGUIDs.insert(
1422 const auto &ExportList = ExportLists.
find(ModuleIdentifier);
1423 return (ExportList != ExportLists.end() && ExportList->second.
count(
VI)) ||
1424 ExportedGUIDs.count(
VI.getGUID());
1430 LocalWPDTargetsMap);
1434 return ThinLTO.PrevailingModuleForGUID[GUID] == S->modulePath();
1439 auto recordNewLinkage = [&](
StringRef ModuleIdentifier,
1442 ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
1445 recordNewLinkage, GUIDPreservedSymbols);
1449 std::unique_ptr<ThinBackendProc> BackendProc =
1450 ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
1454 ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;
1456 auto ProcessOneModule = [&](
int I) ->
Error {
1460 return BackendProc->start(RegularLTO.ParallelCodeGenParallelismLevel +
I,
1461 Mod.second, ImportLists[
Mod.first],
1462 ExportLists[
Mod.first], ResolvedODR[
Mod.first],
1466 if (BackendProc->getThreadCount() == 1) {
1471 for (
int I = 0,
E = ModuleMap.
size();
I !=
E; ++
I)
1472 if (
Error E = ProcessOneModule(
I))
1479 std::vector<BitcodeModule *> ModulesVec;
1480 ModulesVec.reserve(ModuleMap.
size());
1481 for (
auto &Mod : ModuleMap)
1482 ModulesVec.push_back(&
Mod.second);
1484 if (
Error E = ProcessOneModule(
I))
1487 return BackendProc->wait();
1497 if (!Filename.empty() && Count != -1)
1505 if (
Error E = ResultOrErr.takeError())
1509 (*ResultOrErr)->keep();
1517 if (StatsFilename.
empty())
1535 std::vector<int> ModulesOrdering;
1536 ModulesOrdering.resize(R.size());
1537 std::iota(ModulesOrdering.begin(), ModulesOrdering.end(), 0);
1538 llvm::sort(ModulesOrdering, [&](
int LeftIndex,
int RightIndex) {
1539 auto LSize = R[LeftIndex]->getBuffer().size();
1540 auto RSize = R[RightIndex]->getBuffer().size();
1541 return LSize > RSize;
1543 return ModulesOrdering;
static bool isInterposableLinkage(LinkageTypes Linkage)
Whether the definition of this global may be replaced by something non-equivalent at link time.
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.
A parsed version of the target data layout string in and methods for querying it.
This class defines the interface to the ThinLTO backend.
bool hasLocalLinkage() const
bool TimeTraceEnabled
Time trace enabled.
Special purpose, only applies to global arrays.
uint32_t getSymbolFlags(Symbol S) const
Error finalizeOptimizationRemarks(std::unique_ptr< ToolOutputFile > DiagOutputFile)
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...
unsigned Prevailing
The linker has chosen this definition of the symbol.
CodeGenOpt::Level CGOptLevel
uint64_t GUID
Declare a type to represent a global unique identifier for a global value.
This class represents lattice values for constants.
cl::opt< bool > RemarksWithHotness("lto-pass-remarks-with-hotness", cl::desc("With PGO, include profile count in optimization remarks"), cl::Hidden)
A Module instance is used to store all the information related to an LLVM module.
ThinBackend createInProcessThinBackend(ThreadPoolStrategy Parallelism)
This ThinBackend runs the individual backend jobs in-process.
Same, but only replaced by something equivalent.
Implements a dense probed hash-table based set.
std::string OverrideTriple
Setting this field will replace target triples in input files with this triple.
Available for inspection, not emission.
unsigned DataSections
Emit data into separate sections.
static ConstantAggregateZero * get(Type *Ty)
void timeTraceProfilerFinishThread()
Finish a time trace profiler running on a worker thread.
static void thinLTOResolvePrevailingGUID(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)
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 CodeGenOnly
Disable entirely the optimizer, including importing for ThinLTO.
Error readSummary(ModuleSummaryIndex &CombinedIndex, StringRef ModulePath, uint64_t ModuleId)
Parse the specified bitcode buffer and merge its module summary index into CombinedIndex.
bool hasAvailableExternallyLinkage() const
unsigned LinkerRedefined
Linker redefined version of the symbol which appeared in -wrap or -defsym linker option.
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::vector< std::string > ThinLTOModulesToCompile
Specific thinLTO modules to compile.
An efficient, type-erasing, non-owning reference to a callable.
iterator find(StringRef Key)
const StringMap< std::pair< uint64_t, ModuleHash > > & modulePaths() const
Table of modules, containing module hash and id.
Externally visible function.
The resolution for a symbol.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
void write32le(void *P, uint32_t V)
const StringMap< GVSummaryMapTy > & ModuleToDefinedGVSummaries
A class that wrap the SHA1 algorithm.
Error takeError()
Take ownership of the stored error.
std::string getGlobalIdentifier() const
Return the modified name for this global value suitable to be used as the key for a global lookup (e....
std::function< void(const std::string &)> IndexWriteCallback
This ThinBackend writes individual module indexes to files, instead of running the individual backend...
std::shared_future< void > async(Function &&F, Args &&... ArgList)
Asynchronous submission of a task to the pool.
StringRef getModuleIdentifier() const
ThinBackend createWriteIndexesThinBackend(std::string OldPrefix, std::string NewPrefix, bool ShouldEmitImportsFiles, raw_fd_ostream *LinkedObjectsFile, IndexWriteCallback OnWrite)
static bool isLocalLinkage(LinkageTypes Linkage)
static bool isLinkOnceLinkage(LinkageTypes Linkage)
CombinedIndexHookFn CombinedIndexHook
static void thinLTOInternalizeAndPromoteGUID(ValueInfo VI, function_ref< bool(StringRef, ValueInfo)> isExported, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
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"))
T dyn_cast() const
Returns the current pointer if it is of the specified pointer type, otherwise returns null.
bool RemarksWithHotness
Whether to emit optimization remarks with hotness informations.
StringRef getName(ID id)
Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Represents a module in a bitcode file.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
std::string DwoDir
The directory to store .dwo files.
std::vector< std::string > MAttrs
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...
unsigned getThreadCount() const
std::string ProfileRemapping
Name remapping file for profile data.
ModuleSummaryIndex & CombinedIndex
ArrayRef< Symbol > symbols() const
void setName(const Twine &Name)
Change the name of the value.
Tagged union holding either a T or a Error.
StringRef result()
Return a reference to the current raw 160-bits SHA1 for the digested data since the last call to init...
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
void addModule(Module *M)
static bool isLinkOnceODRLinkage(LinkageTypes Linkage)
StringRef str() const
Explicit conversion to StringRef.
Error backend(const Config &C, AddStreamFn AddStream, unsigned ParallelCodeGenParallelismLevel, std::unique_ptr< Module > M, ModuleSummaryIndex &CombinedIndex)
Runs a regular LTO backend.
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.
void updateVCallVisibilityInIndex(ModuleSummaryIndex &Index, bool WholeProgramVisibilityEnabledInLTO)
If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...
ThinBackendProc(const Config &Conf, ModuleSummaryIndex &CombinedIndex, const StringMap< GVSummaryMapTy > &ModuleToDefinedGVSummaries)
Class to represent array types.
std::string SampleProfile
Sample PGO profile path.
unsigned FunctionSections
Emit functions into separate sections.
Optional< CodeModel::Model > CodeModel
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
A ThreadPool for asynchronous parallel execution on a defined number of threads.
static bool isAppendingLinkage(LinkageTypes Linkage)
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
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...
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.
llvm::Optional< uint64_t > RemarksHotnessThreshold
The minimum hotness value a diagnostic needs in order to be included in optimization diagnostics.
void takeName(Value *V)
Transfer the name from V to this value.
Class to hold module path string table and global value map, and encapsulate methods for operating on...
void timeTraceProfilerInitialize(unsigned TimeTraceGranularity, StringRef ProcName)
Initialize the time trace profiler.
Expected< std::unique_ptr< ToolOutputFile > > setupStatsFile(StringRef StatsFilename)
Setups the output file for saving statistics.
void update(ArrayRef< uint8_t > Data)
Digest more data.
iterator find(const_arg_type_t< KeyT > Val)
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
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.
std::vector< int > generateModulesOrdering(ArrayRef< BitcodeModule * > R)
Produces a container ordering for optimal multi-threaded processing.
bool AlwaysEmitRegularLTOObj
Always emit a Regular LTO object even when it is empty because no Regular LTO modules were linked.
std::function< std::unique_ptr< ThinBackendProc >(const Config &C, ModuleSummaryIndex &CombinedIndex, StringMap< GVSummaryMapTy > &ModuleToDefinedGVSummaries, AddStreamFn AddStream, NativeObjectCache Cache)> ThinBackend
A ThinBackend defines what happens after the thin-link phase during ThinLTO.
DebuggerKind DebuggerTuning
Which debugger to tune for.
Same, but only replaced by something equivalent.
initializer< Ty > init(const Ty &Val)
ModuleHookFn PreOptModuleHook
This module hook is called after linking (regular LTO) or loading (ThinLTO) the module,...
Emits an error if two values disagree, otherwise the resulting value is that of the operands.
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"))
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.
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
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.
void generateParamAccessSummary(ModuleSummaryIndex &Index)
This is an important class for using LLVM in a threaded context.
Instrumentation for Order File
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
std::pair< iterator, bool > insert(const ValueT &V)
bool UseNewPM
Use the new pass manager.
bool UpgradeDebugInfo(Module &M)
Check the debug info version number, if it is out-dated, drop the debug info.
std::function< AddStreamFn(unsigned Task, StringRef Key)> NativeObjectCache
This is the type of a native object cache.
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
cl::opt< 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)
This tells how a thread pool will be used.
std::string DefaultTriple
Setting this field will replace unspecified target triples in input files with this triple.
DLLStorageClassTypes
Storage classes of global values for PE targets.
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
const ModuleHash & getModuleHash(const StringRef ModPath) const
Get the module SHA1 hash recorded for the given module path.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void thinLTOResolvePrevailingInIndex(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.
LLVM_NODISCARD bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
void sort(IteratorTy Start, IteratorTy End)
StringRef parent_path(StringRef path, Style style=Style::native)
Get parent path.
Expected< std::unique_ptr< ToolOutputFile > > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, Optional< uint64_t > RemarksHotnessThreshold=0)
Setup optimization remarks that output to a file.
Function and variable summary information to aid decisions and implementation of importing.
static GUID getGUID(StringRef GlobalName)
Return a 64-bit global unique ID constructed from global value name (i.e.
std::string StatsFile
Statistics output file path.
Used in the streaming interface as the general argument type.
ModuleHookFn PostInternalizeModuleHook
This hook is called after internalizing the module.
static bool isWeakObjectWithRWAccess(GlobalValueSummary *GVS)
std::function< std::unique_ptr< NativeObjectStream >(unsigned Task)> AddStreamFn
This type defines the callback to add a native object that is generated on the fly.
Triple - Helper class for working with autoconf configuration names.
static LinkageTypes getWeakLinkage(bool ODR)
Struct that holds a reference to a particular GUID in a global value summary.
static void writeToResolutionFile(raw_ostream &OS, InputFile *Input, ArrayRef< SymbolResolution > Res)
void computeSyntheticCounts(ModuleSummaryIndex &Index)
Compute synthetic function entry counts.
std::string RemarksFilename
Optimization remarks file path.
void PrintStatisticsJSON(raw_ostream &OS)
Print statistics in JSON format.
static ErrorSuccess success()
Create a success value.
GlobalValueSummary * getBaseObject()
If this is an alias summary, returns the summary of the aliased object (a global variable or function...
Align max(MaybeAlign Lhs, Align Rhs)
unsigned getMaxTasks() const
Returns an upper bound on the number of tasks that the client may expect.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
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 ...
constexpr const T & getValue() const LLVM_LVALUE_FUNCTION
virtual ~ThinBackendProc()
bool HasWholeProgramVisibility
Asserts whether we can assume whole program visibility during the LTO link.
Optional< Reloc::Model > RelocModel
constexpr bool hasValue() const
Expected< std::unique_ptr< ToolOutputFile > > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, Optional< uint64_t > RemarksHotnessThreshold=0, int Count=-1)
Setup optimization remarks.
void setLinkage(LinkageTypes LT)
The access may modify the value stored in memory.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
const Comdat * getComdat() const
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
CodeGenFileType CGFileType
LinkageTypes
An enumeration for the kinds of linkage for global values.
std::string OptPipeline
If this field is set, the set of passes run in the middle-end optimizer will be the one specified by ...
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 ...
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
unsigned RelaxELFRelocations
unsigned TimeTraceGranularity
Time trace granularity.
std::string RemarksFormat
The format used for serializing remarks (default: YAML).
static const char * libcallRoutineNames[]
raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
std::set< std::string > & cfiFunctionDefs()
void ComputeCrossModuleImport(const ModuleSummaryIndex &Index, const StringMap< GVSummaryMapTy > &ModuleToDefinedGVSummaries, StringMap< FunctionImporter::ImportMapTy > &ImportLists, StringMap< FunctionImporter::ExportSetTy > &ExportLists)
Compute all the imports and exports for every module in the Index.
void setAlignment(MaybeAlign Align)
A raw_ostream that writes to a file descriptor.
LTO(Config Conf, ThinBackend Backend=nullptr, unsigned ParallelCodeGenParallelismLevel=1)
Create an LTO object.
void write64le(void *P, uint64_t V)
void setUnnamedAddr(UnnamedAddr Val)
Linkage
Describes symbol linkage.
Error joinErrors(Error E1, Error E2)
Concatenate errors.
StringRef getName() const
Return a constant reference to the value's name.
iterator find(const_arg_type_t< ValueT > V)
Error run(AddStreamFn AddStream, NativeObjectCache Cache=nullptr)
Runs the LTO pipeline.
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Type * getValueType() const
Keep one copy of named function when linking (weak)
Rename collisions when linking (static functions).
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
unsigned VisibleToRegularObj
The definition of this symbol is visible outside of the LTO unit.
std::string RemarksPasses
Optimization remarks pass filter.
cl::opt< bool > EnableLTOInternalization("enable-lto-internalization", cl::init(true), cl::Hidden, cl::desc("Enable global value internalization in LTO"))
Enable global value internalization in LTO.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
const GlobalObject * getBaseObject() const
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, int64_t FileSize=-1, bool RequiresNullTerminator=true, bool IsVolatile=false)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::set< std::string > & cfiFunctionDecls()
std::function< void(GlobalValue &)> ValueAdder
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"))
Expected< std::unique_ptr< Module > > parseModule(LLVMContext &Context, DataLayoutCallbackTy DataLayoutCallback=[](StringRef) { return None;})
Read the entire bitcode module and return it.
cl::opt< std::string > RemarksFilename("lto-pass-remarks-output", cl::desc("Output filename for pass remarks"), cl::value_desc("filename"))
Lightweight error class with error context and mandatory checking.
void EnableStatistics(bool DoPrintOnExit=true)
Enable the collection and printing of statistics.
This class implements an extremely fast bulk output stream that can only output to a stream.
Expected< std::unique_ptr< Module > > getLazyModule(LLVMContext &Context, bool ShouldLazyLoadMetadata, bool IsImporting)
Read the bitcode module and prepare for lazy deserialization of function bodies.
bool replace_path_prefix(SmallVectorImpl< char > &Path, StringRef OldPrefix, StringRef NewPrefix, Style style=Style::native)
Replace matching path prefix with another path.
ThreadPoolStrategy heavyweight_hardware_concurrency(unsigned ThreadCount=0)
Returns a thread strategy for tasks requiring significant memory or other resources.
A derived class of LLVMContext that initializes itself according to a given Config object.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
StringRef - Represent a constant reference to a string, i.e.
bool Freestanding
Flag to indicate that the optimizer should not assume builtins are present on the target.
unsigned FinalDefinitionInLinkageUnit
The definition of this symbol is unpreemptable at runtime and is known to be in this linkage unit.
StringMapConstIterator< ValueTy > const_iterator
Expected< IRSymtabFile > readIRSymtab(MemoryBufferRef MBRef)
Reads a bitcode file, creating its irsymtab if necessary.
static void handleNonPrevailingComdat(GlobalValue &GV, std::set< const Comdat * > &NonPrevailingComdats)
void updateVCallVisibilityInModule(Module &M, bool WholeProgramVisibilityEnabledInLTO)
If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...
void wait()
Blocking wait for all the threads to complete and the queue to be empty.
static IntegerType * getInt8Ty(LLVMContext &C)
PointerType * getType() const
Global values are always pointers.
std::string getThinLTOOutputFile(const std::string &Path, const std::string &OldPrefix, const std::string &NewPrefix)
Given the original Path to an output file, replace any path prefix matching OldPrefix with NewPrefix.
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL