27#include "llvm/Config/llvm-config.h"
56#include "llvm/Support/VCSRevision.h"
72#define DEBUG_TYPE "lto"
76 cl::desc(
"Dump the SCCs in the ThinLTO index's callgraph"));
87 cl::desc(
"Enable global value internalization in LTO"));
91 cl::desc(
"Keep copies of symbols in LTO indexing"));
108 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
119 Hasher.
update(LLVM_VERSION_STRING);
121 Hasher.
update(LLVM_REVISION);
129 auto AddUnsigned = [&](
unsigned I) {
139 auto AddUint8 = [&](
const uint8_t I) {
163 AddUnsigned(
static_cast<int>(Conf.
CGOptLevel));
164 AddUnsigned(
static_cast<int>(Conf.
CGFileType));
172 AddUint8(Conf.
Dtlto);
175 auto ModHash = Index.getModuleHash(ModuleID);
180 std::vector<uint64_t> ExportsGUID;
181 ExportsGUID.reserve(ExportList.
size());
182 for (
const auto &VI : ExportList)
183 ExportsGUID.push_back(VI.getGUID());
187 for (
auto GUID : ExportsGUID)
192 auto Comp = [&](
const std::pair<StringRef, GlobalValue::GUID> &L,
193 const std::pair<StringRef, GlobalValue::GUID> &R) {
194 return std::make_pair(Index.getModule(L.first)->second, L.second) <
195 std::make_pair(Index.getModule(R.first)->second, R.second);
201 for (
const auto &[FromModule, GUID,
Type] : SortedImportList)
202 ++ModuleToNumImports[FromModule];
204 std::optional<StringRef> LastModule;
205 for (
const auto &[FromModule, GUID,
Type] : SortedImportList) {
206 if (LastModule != FromModule) {
210 LastModule = FromModule;
211 auto ModHash = Index.getModule(FromModule)->second;
213 AddUint64(ModuleToNumImports[FromModule]);
220 for (
auto &Entry : ResolvedODR) {
229 std::set<GlobalValue::GUID> UsedCfiDefs;
230 std::set<GlobalValue::GUID> UsedCfiDecls;
233 std::set<GlobalValue::GUID> UsedTypeIds;
236 if (CfiFunctionDefs.
contains(ValueGUID))
237 UsedCfiDefs.insert(ValueGUID);
238 if (CfiFunctionDecls.
contains(ValueGUID))
239 UsedCfiDecls.insert(ValueGUID);
244 AddUnsigned(GS->getVisibility());
245 AddUnsigned(GS->isLive());
246 AddUnsigned(GS->canAutoHide());
248 AddUnsigned(VI.isDSOLocal(Index.withDSOLocalPropagation()));
249 AddUsedCfiGlobal(VI.getGUID());
252 AddUnsigned(GVS->maybeReadOnly());
253 AddUnsigned(GVS->maybeWriteOnly());
256 for (
auto &TT : FS->type_tests())
257 UsedTypeIds.insert(TT);
258 for (
auto &TT : FS->type_test_assume_vcalls())
259 UsedTypeIds.insert(TT.GUID);
260 for (
auto &TT : FS->type_checked_load_vcalls())
261 UsedTypeIds.insert(TT.GUID);
262 for (
auto &TT : FS->type_test_assume_const_vcalls())
263 UsedTypeIds.insert(TT.VFunc.GUID);
264 for (
auto &TT : FS->type_checked_load_const_vcalls())
265 UsedTypeIds.insert(TT.VFunc.GUID);
266 for (
auto &ET : FS->calls()) {
267 AddUnsigned(ET.first.isDSOLocal(Index.withDSOLocalPropagation()));
268 AddUsedCfiGlobal(ET.first.getGUID());
275 for (
auto &GS : DefinedGlobals) {
279 AddUsedCfiGlobal(GS.first);
280 AddUsedThings(GS.second);
285 for (
const auto &[FromModule, GUID,
Type] : SortedImportList) {
291 AddUsedThings(AS->getBaseObject());
297 AddUnsigned(S.TTRes.TheKind);
298 AddUnsigned(S.TTRes.SizeM1BitWidth);
300 AddUint64(S.TTRes.AlignLog2);
301 AddUint64(S.TTRes.SizeM1);
302 AddUint64(S.TTRes.BitMask);
303 AddUint64(S.TTRes.InlineBits);
305 AddUint64(S.WPDRes.size());
306 for (
auto &WPD : S.WPDRes) {
307 AddUnsigned(WPD.first);
308 AddUnsigned(WPD.second.TheKind);
309 AddString(WPD.second.SingleImplName);
311 AddUint64(WPD.second.ResByArg.size());
312 for (
auto &ByArg : WPD.second.ResByArg) {
313 AddUint64(ByArg.first.size());
316 AddUnsigned(ByArg.second.TheKind);
317 AddUint64(ByArg.second.Info);
318 AddUnsigned(ByArg.second.Byte);
319 AddUnsigned(ByArg.second.Bit);
326 auto TidIter = Index.typeIds().equal_range(TId);
328 AddTypeIdSummary(
I.second.first,
I.second.second);
331 AddUnsigned(UsedCfiDefs.size());
332 for (
auto &V : UsedCfiDefs)
335 AddUnsigned(UsedCfiDecls.size());
336 for (
auto &V : UsedCfiDecls)
342 Hasher.
update(FileOrErr.get()->getBuffer());
347 Hasher.
update(FileOrErr.get()->getBuffer());
378 C.VisibilityScheme ==
Config::ELF ? VI.getELFVisibility()
380 for (
auto &S : VI.getSummaryList()) {
395 if (isPrevailing(VI.getGUID(), S.get())) {
408 S->setCanAutoHide(VI.canAutoHide() &&
409 !GUIDPreservedSymbols.
count(VI.getGUID()));
412 Visibility = S->getVisibility();
426 S->setVisibility(Visibility);
428 if (S->linkage() != OriginalLinkage)
429 recordNewLinkage(S->modulePath(), VI.getGUID(), S->linkage());
433 for (
auto &S : VI.getSummaryList()) {
438 S->setVisibility(Visibility);
460 for (
auto &
I : Index)
461 for (
auto &S :
I.second.getSummaryList())
463 GlobalInvolvedWithAlias.
insert(&AS->getAliasee());
465 for (
auto &
I : Index)
467 GlobalInvolvedWithAlias, isPrevailing,
468 recordNewLinkage, GUIDPreservedSymbols);
479 const bool SingleExternallyVisibleCopy =
480 VI.getSummaryList().size() == 1 &&
483 for (
auto &S : VI.getSummaryList()) {
486 if (isExported(S->modulePath(), VI)) {
547 if (SingleExternallyVisibleCopy && isPrevailing(VI.getGUID(), S.get()))
559 assert(!Index.withInternalizeAndPromote());
560 for (
auto &
I : Index)
563 Index.setWithInternalizeAndPromote();
570 std::unique_ptr<InputFile> File(
new InputFile);
576 File->TargetTriple = FOrErr->TheReader.getTargetTriple();
577 File->SourceFileName = FOrErr->TheReader.getSourceFileName();
578 File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts();
579 File->DependentLibraries = FOrErr->TheReader.getDependentLibraries();
580 File->ComdatTable = FOrErr->TheReader.getComdatTable();
584 for (
unsigned I = 0;
I != FOrErr->Mods.size(); ++
I) {
585 size_t Begin = File->Symbols.size();
587 FOrErr->TheReader.module_symbols(
I))
590 if (Sym.isGlobal() && !Sym.isFormatSpecific())
591 File->Symbols.push_back(Sym);
592 File->ModuleSymIndices.push_back({Begin, File->Symbols.size()});
595 File->Mods = FOrErr->Mods;
596 File->Strtab = std::move(FOrErr->Strtab);
597 return std::move(File);
606 return Mods[0].getModuleIdentifier();
610 assert(Mods.size() == 1 &&
"Expect only one bitcode module");
616LTO::RegularLTOState::RegularLTOState(
unsigned ParallelCodeGenParallelismLevel,
618 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
619 Ctx(Conf), CombinedModule(
std::make_unique<
Module>(
"ld-temp.o", Ctx)),
620 Mover(
std::make_unique<
IRMover>(*CombinedModule)) {}
622LTO::ThinLTOState::ThinLTOState(
ThinBackend BackendParam)
623 : Backend(
std::
move(BackendParam)), CombinedIndex(
false) {
624 if (!Backend.isValid())
630 unsigned ParallelCodeGenParallelismLevel,
LTOKind LTOMode)
632 RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),
638 Alloc = std::make_unique<BumpPtrAllocator>();
639 GlobalResolutionSymbolSaver = std::make_unique<llvm::StringSaver>(*Alloc);
650 unsigned Partition,
bool InSummary,
653 auto *ResI = Res.
begin();
654 auto *ResE = Res.
end();
663 if (GlobalResolutionSymbolSaver && !GlobalResolutions->contains(SymbolName))
664 SymbolName = GlobalResolutionSymbolSaver->save(SymbolName);
666 auto &GlobalRes = (*GlobalResolutions)[SymbolName];
667 GlobalRes.UnnamedAddr &= Sym.isUnnamedAddr();
669 assert(!GlobalRes.Prevailing &&
670 "Multiple prevailing defs are not allowed");
671 GlobalRes.Prevailing =
true;
672 GlobalRes.IRName = std::string(Sym.getIRName());
673 }
else if (!GlobalRes.Prevailing && GlobalRes.IRName.empty()) {
680 GlobalRes.IRName = std::string(Sym.getIRName());
694 if (GlobalRes.IRName != Sym.getIRName()) {
695 GlobalRes.Partition = GlobalResolution::External;
696 GlobalRes.VisibleOutsideSummary =
true;
699 bool IsLibcall = Sym.isLibcall(Libcalls);
707 (GlobalRes.Partition != GlobalResolution::Unknown &&
708 GlobalRes.Partition != Partition)) {
709 GlobalRes.Partition = GlobalResolution::External;
712 GlobalRes.Partition = Partition;
716 GlobalRes.VisibleOutsideSummary |=
723void LTO::releaseGlobalResolutionsMemory() {
725 GlobalResolutions.reset();
727 GlobalResolutionSymbolSaver.reset();
735 auto ResI = Res.
begin();
740 OS <<
"-r=" << Path <<
',' << Sym.getName() <<
',';
758 assert(!CalledGetMaxTasks);
764 InputFile *
Input = (*InputOrErr).get();
766 if (Conf.ResolutionFile)
769 if (RegularLTO.CombinedModule->getTargetTriple().empty()) {
771 RegularLTO.CombinedModule->setTargetTriple(InputTriple);
777 for (
unsigned I = 0;
I !=
Input->Mods.size(); ++
I) {
778 if (
auto Err = addModule(*
Input, InputRes,
I, Res).moveInto(Res))
794 if (EnableSplitLTOUnit) {
798 if (*EnableSplitLTOUnit != LTOInfo->EnableSplitLTOUnit)
801 EnableSplitLTOUnit = LTOInfo->EnableSplitLTOUnit;
806 !LTOInfo->UnifiedLTO)
808 "unified LTO compilation must use "
809 "compatible bitcode modules (use -funified-lto)",
819 Input.IsThinLTO |= IsThinLTO;
821 auto ModSyms =
Input.module_symbols(ModI);
822 addModuleToGlobalRes(ModSyms, Res,
823 IsThinLTO ? ThinLTO.ModuleMap.
size() + 1 : 0,
824 LTOInfo->HasSummary,
Triple(
Input.getTargetTriple()));
827 return addThinLTO(BM, ModSyms, Res);
829 RegularLTO.EmptyCombinedModule =
false;
830 auto ModOrErr = addRegularLTO(
Input, InputRes, BM, ModSyms, Res);
832 return ModOrErr.takeError();
833 Res = ModOrErr->second;
835 if (!LTOInfo->HasSummary) {
836 if (
Error Err = linkRegularLTO(std::move(ModOrErr->first),
846 RegularLTO.ModsWithSummaries.push_back(std::move(ModOrErr->first));
862 std::set<const Comdat *> &NonPrevailingComdats) {
867 if (!NonPrevailingComdats.count(
C))
877 GO->setComdat(
nullptr);
884 std::pair<LTO::RegularLTOState::AddedModule, ArrayRef<SymbolResolution>>>
888 llvm::TimeTraceScope timeScope(
"LTO add regular LTO");
890 Expected<std::unique_ptr<Module>> MOrErr =
896 Mod.M = std::move(*MOrErr);
898 if (
Error Err =
M.materializeMetadata())
899 return std::move(Err);
905 if (NamedMDNode *CfiFunctionsMD =
M.getNamedMetadata(
"cfi.functions"))
906 M.eraseNamedMetadata(CfiFunctionsMD);
907 }
else if (NamedMDNode *AliasesMD =
M.getNamedMetadata(
"aliases")) {
910 DenseSet<StringRef> Prevailing;
912 if (
R.Prevailing && !
I.getIRName().empty())
913 Prevailing.
insert(
I.getIRName());
914 std::vector<MDNode *> AliasGroups;
915 for (MDNode *AliasGroup : AliasesMD->operands()) {
916 std::vector<Metadata *> Aliases;
917 for (
Metadata *Alias : AliasGroup->operands()) {
920 Aliases.push_back(Alias);
922 if (Aliases.size() > 1)
923 AliasGroups.push_back(
MDTuple::get(RegularLTO.Ctx, Aliases));
925 AliasesMD->clearOperands();
926 for (MDNode *
G : AliasGroups)
927 AliasesMD->addOperand(
G);
932 ModuleSymbolTable SymTab;
935 for (GlobalVariable &GV :
M.globals())
936 if (GV.hasAppendingLinkage())
937 Mod.Keep.push_back(&GV);
939 DenseSet<GlobalObject *> AliasedGlobals;
940 for (
auto &GA :
M.aliases())
941 if (GlobalObject *GO = GA.getAliaseeObject())
942 AliasedGlobals.
insert(GO);
951 auto MsymI = SymTab.
symbols().begin(), MsymE = SymTab.
symbols().end();
953 while (MsymI != MsymE) {
963 std::set<const Comdat *> NonPrevailingComdats;
964 SmallSet<StringRef, 2> NonPrevailingAsmSymbols;
965 for (
const InputFile::Symbol &Sym : Syms) {
975 if (Sym.isUndefined())
977 Mod.Keep.push_back(GV);
981 if (
R.LinkerRedefined)
989 (GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||
990 GV->hasAvailableExternallyLinkage()) &&
997 Mod.Keep.push_back(GV);
1000 NonPrevailingComdats.insert(GV->getComdat());
1005 if (
R.FinalDefinitionInLinkageUnit) {
1006 GV->setDSOLocal(
true);
1007 if (GV->hasDLLImportStorageClass())
1009 DefaultStorageClass);
1011 }
else if (
auto *AS =
1015 NonPrevailingAsmSymbols.
insert(AS->first);
1023 if (Sym.isCommon()) {
1026 auto &CommonRes = RegularLTO.Commons[std::string(Sym.getIRName())];
1027 CommonRes.Size = std::max(CommonRes.Size, Sym.getCommonSize());
1028 if (uint32_t SymAlignValue = Sym.getCommonAlignment()) {
1029 CommonRes.Alignment =
1030 std::max(
Align(SymAlignValue), CommonRes.Alignment);
1032 CommonRes.Prevailing |=
R.Prevailing;
1036 if (!
M.getComdatSymbolTable().empty())
1037 for (GlobalValue &GV :
M.global_values())
1042 if (!
M.getModuleInlineAsm().empty()) {
1043 std::string NewIA =
".lto_discard";
1044 if (!NonPrevailingAsmSymbols.
empty()) {
1047 M, [&](StringRef Name, StringRef Alias) {
1048 if (!NonPrevailingAsmSymbols.
count(Alias))
1049 NonPrevailingAsmSymbols.
erase(Name);
1051 NewIA +=
" " +
llvm::join(NonPrevailingAsmSymbols,
", ");
1054 M.setModuleInlineAsm(NewIA +
M.getModuleInlineAsm());
1058 return std::make_pair(std::move(
Mod), Res);
1061Error LTO::linkRegularLTO(RegularLTOState::AddedModule
Mod,
1062 bool LivenessFromIndex) {
1063 llvm::TimeTraceScope timeScope(
"LTO link regular LTO");
1064 std::vector<GlobalValue *>
Keep;
1065 for (GlobalValue *GV :
Mod.Keep) {
1066 if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->
getGUID())) {
1068 if (DiagnosticOutputFile) {
1069 if (
Error Err =
F->materialize())
1071 OptimizationRemarkEmitter ORE(
F,
nullptr);
1072 ORE.emit(OptimizationRemark(
DEBUG_TYPE,
"deadfunction",
F)
1074 <<
" not added to the combined module ");
1087 GlobalValue *CombinedGV =
1088 RegularLTO.CombinedModule->getNamedValue(GV->
getName());
1095 return RegularLTO.Mover->move(std::move(
Mod.M),
Keep,
nullptr,
1100Expected<ArrayRef<SymbolResolution>>
1103 llvm::TimeTraceScope timeScope(
"LTO add thin LTO");
1106 for (
const InputFile::Symbol &Sym : Syms) {
1110 if (!Sym.getIRName().empty() &&
R.Prevailing) {
1114 ThinLTO.setPrevailingModuleForGUID(GUID, BMID);
1120 return ThinLTO.isPrevailingModuleForGUID(GUID, BMID);
1125 for (
const InputFile::Symbol &Sym : Syms) {
1129 if (!Sym.getIRName().empty() &&
1130 (
R.Prevailing ||
R.FinalDefinitionInLinkageUnit)) {
1135 assert(ThinLTO.isPrevailingModuleForGUID(GUID, BMID));
1141 if (
R.LinkerRedefined)
1142 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(GUID, BMID))
1148 if (
R.FinalDefinitionInLinkageUnit) {
1149 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(GUID, BMID)) {
1150 S->setDSOLocal(
true);
1156 if (!ThinLTO.ModuleMap.insert({BMID, BM}).second)
1158 "Expected at most one ThinLTO module per bitcode file",
1161 if (!Conf.ThinLTOModulesToCompile.empty()) {
1162 if (!ThinLTO.ModulesToCompile)
1163 ThinLTO.ModulesToCompile = ModuleMapType();
1166 for (
const std::string &Name : Conf.ThinLTOModulesToCompile) {
1167 if (BMID.contains(Name)) {
1168 ThinLTO.ModulesToCompile->insert({BMID, BM});
1169 LLVM_DEBUG(
dbgs() <<
"[ThinLTO] Selecting " << BMID <<
" to compile\n");
1179 CalledGetMaxTasks =
true;
1180 auto ModuleCount = ThinLTO.ModulesToCompile ? ThinLTO.ModulesToCompile->size()
1181 : ThinLTO.ModuleMap.size();
1182 return RegularLTO.ParallelCodeGenParallelismLevel + ModuleCount;
1187Error LTO::checkPartiallySplit() {
1191 const Module *Combined = RegularLTO.CombinedModule.get();
1197 Combined, Intrinsic::type_checked_load_relative);
1201 if ((TypeTestFunc && !TypeTestFunc->
use_empty()) ||
1202 (TypeCheckedLoadFunc && !TypeCheckedLoadFunc->
use_empty()) ||
1203 (TypeCheckedLoadRelativeFunc &&
1204 !TypeCheckedLoadRelativeFunc->
use_empty()))
1206 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1211 for (
auto &
P : ThinLTO.CombinedIndex) {
1212 for (
auto &S :
P.second.getSummaryList()) {
1216 if (!FS->type_test_assume_vcalls().empty() ||
1217 !FS->type_checked_load_vcalls().empty() ||
1218 !FS->type_test_assume_const_vcalls().empty() ||
1219 !FS->type_checked_load_const_vcalls().empty() ||
1220 !FS->type_tests().empty())
1222 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1238 for (
auto &Res : *GlobalResolutions) {
1241 if (Res.second.IRName.
empty())
1247 if (Res.second.VisibleOutsideSummary && Res.second.Prevailing)
1248 GUIDPreservedSymbols.
insert(GUID);
1250 if (Res.second.ExportDynamic)
1251 DynamicExportSymbols.insert(GUID);
1253 GUIDPrevailingResolutions[GUID] =
1258 auto It = GUIDPrevailingResolutions.
find(
G);
1259 if (It == GUIDPrevailingResolutions.
end())
1264 isPrevailing, Conf.OptLevel > 0);
1268 if (!StatsFileOrErr)
1269 return StatsFileOrErr.takeError();
1270 std::unique_ptr<ToolOutputFile> StatsFile = std::move(StatsFileOrErr.get());
1278 ThinLTO.CombinedIndex.setWithSupportsHotColdNew();
1280 Error Result = runRegularLTO(AddStream);
1284 Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols);
1294 LLVMContext &CombinedCtx = RegularLTO.CombinedModule->getContext();
1301 return DiagFileOrErr.takeError();
1302 DiagnosticOutputFile = std::move(*DiagFileOrErr);
1308 for (
auto &M : RegularLTO.ModsWithSummaries)
1309 if (
Error Err = linkRegularLTO(std::move(M),
true))
1317 if (
Error Err = checkPartiallySplit())
1322 const DataLayout &
DL = RegularLTO.CombinedModule->getDataLayout();
1323 for (
auto &
I : RegularLTO.Commons) {
1324 if (!
I.second.Prevailing)
1327 GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(
I.first);
1328 if (OldGV &&
DL.getTypeAllocSize(OldGV->
getValueType()) ==
I.second.Size) {
1336 auto *GV =
new GlobalVariable(*RegularLTO.CombinedModule, Ty,
false,
1339 GV->setAlignment(
I.second.Alignment);
1349 bool WholeProgramVisibilityEnabledInLTO =
1350 Conf.HasWholeProgramVisibility &&
1353 (!Conf.ValidateAllVtablesHaveTypeInfos || Conf.AllVtablesHaveTypeInfos);
1357 auto IsVisibleToRegularObj = [&](StringRef
name) {
1358 auto It = GlobalResolutions->find(
name);
1359 return (It == GlobalResolutions->end() ||
1360 It->second.VisibleOutsideSummary || !It->second.Prevailing);
1366 *RegularLTO.CombinedModule, WholeProgramVisibilityEnabledInLTO,
1367 DynamicExportSymbols, Conf.ValidateAllVtablesHaveTypeInfos,
1368 IsVisibleToRegularObj);
1370 WholeProgramVisibilityEnabledInLTO);
1372 if (Conf.PreOptModuleHook &&
1373 !Conf.PreOptModuleHook(0, *RegularLTO.CombinedModule))
1376 if (!Conf.CodeGenOnly) {
1377 for (
const auto &R : *GlobalResolutions) {
1379 RegularLTO.CombinedModule->getNamedValue(
R.second.IRName);
1380 if (!
R.second.isPrevailingIRSymbol())
1382 if (
R.second.Partition != 0 &&
1383 R.second.Partition != GlobalResolution::External)
1411 if (Conf.PostInternalizeModuleHook &&
1412 !Conf.PostInternalizeModuleHook(0, *RegularLTO.CombinedModule))
1416 if (!RegularLTO.EmptyCombinedModule || Conf.AlwaysEmitRegularLTOObj) {
1418 backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,
1419 *RegularLTO.CombinedModule, ThinLTO.CombinedIndex))
1436 return LibcallSymbols;
1441 const std::string &NewModulePath)
const {
1442 return emitFiles(ImportList, ModulePath, NewModulePath,
1443 NewModulePath +
".thinlto.bc",
1449 const std::string &NewModulePath,
StringRef SummaryPath,
1450 std::optional<std::reference_wrapper<ImportsFilesContainer>> ImportsFiles)
1457 ImportList, ModuleToSummariesForIndex,
1458 DeclarationSummaries);
1465 &DeclarationSummaries);
1469 ModulePath, NewModulePath +
".imports", ModuleToSummariesForIndex);
1470 if (ImportsFilesError)
1471 return ImportsFilesError;
1477 ModulePath, ModuleToSummariesForIndex,
1478 [&](
StringRef M) { ImportsFiles->get().push_back(M.str()); });
1491 bool ShouldEmitIndexFiles;
1498 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
1501 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
1502 AddStream(
std::
move(AddStream)),
1503 ShouldEmitIndexFiles(ShouldEmitIndexFiles) {
1513class InProcessThinBackend :
public CGThinBackend {
1518 InProcessThinBackend(
1523 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles)
1524 : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
1525 AddStream, OnWrite, ShouldEmitIndexFiles,
1526 ShouldEmitImportsFiles, ThinLTOParallelism),
1529 virtual Error runThinLTOBackendThread(
1530 AddStreamFn AddStream, FileCache Cache,
unsigned Task, BitcodeModule BM,
1531 ModuleSummaryIndex &CombinedIndex,
1532 const FunctionImporter::ImportMapTy &ImportList,
1534 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1536 MapVector<StringRef, BitcodeModule> &ModuleMap) {
1538 llvm::TimeTraceScope timeScope(
"Run ThinLTO backend thread (in-process)",
1540 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1541 LTOLLVMContext BackendContext(Conf);
1542 Expected<std::unique_ptr<Module>> MOrErr = BM.
parseModule(BackendContext);
1546 return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,
1547 ImportList, DefinedGlobals, &ModuleMap,
1550 if (ShouldEmitIndexFiles) {
1551 if (
auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1557 [](uint32_t V) { return V == 0; }))
1560 return RunThinBackend(AddStream);
1564 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1565 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1566 Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task,
Key, ModuleID);
1569 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1571 return RunThinBackend(CacheAddStream);
1577 unsigned Task, BitcodeModule BM,
1578 const FunctionImporter::ImportMapTy &ImportList,
1580 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1581 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
1583 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
1585 ModuleToDefinedGVSummaries.
find(ModulePath)->second;
1586 BackendThreadPool.async(
1587 [=](BitcodeModule BM, ModuleSummaryIndex &CombinedIndex,
1588 const FunctionImporter::ImportMapTy &ImportList,
1590 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
1593 MapVector<StringRef, BitcodeModule> &ModuleMap) {
1597 Error E = runThinLTOBackendThread(
1598 AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList,
1599 ResolvedODR, DefinedGlobals, ModuleMap);
1601 std::unique_lock<std::mutex>
L(ErrMu);
1610 BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList),
1611 std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap));
1614 OnWrite(std::string(ModulePath));
1624class FirstRoundThinBackend :
public InProcessThinBackend {
1629 FirstRoundThinBackend(
1630 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
1631 ThreadPoolStrategy ThinLTOParallelism,
1632 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
1635 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
1636 ModuleToDefinedGVSummaries, std::
move(CGAddStream),
1637 std::
move(CGCache), nullptr,
1640 IRAddStream(std::
move(IRAddStream)), IRCache(std::
move(IRCache)) {}
1642 Error runThinLTOBackendThread(
1643 AddStreamFn CGAddStream, FileCache CGCache,
unsigned Task,
1644 BitcodeModule BM, ModuleSummaryIndex &CombinedIndex,
1645 const FunctionImporter::ImportMapTy &ImportList,
1647 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1649 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
1651 llvm::TimeTraceScope timeScope(
"Run ThinLTO backend thread (first round)",
1653 auto RunThinBackend = [&](
AddStreamFn CGAddStream,
1655 LTOLLVMContext BackendContext(Conf);
1656 Expected<std::unique_ptr<Module>> MOrErr = BM.
parseModule(BackendContext);
1660 return thinBackend(Conf, Task, CGAddStream, **MOrErr, CombinedIndex,
1661 ImportList, DefinedGlobals, &ModuleMap,
1667 if (ShouldEmitIndexFiles) {
1668 if (
auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1673 "Both caches for CG and IR should have matching availability");
1676 [](uint32_t V) { return V == 0; }))
1679 return RunThinBackend(CGAddStream, IRAddStream);
1683 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1684 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1685 Expected<AddStreamFn> CacheCGAddStreamOrErr =
1686 CGCache(Task, CGKey, ModuleID);
1689 AddStreamFn &CacheCGAddStream = *CacheCGAddStreamOrErr;
1693 Expected<AddStreamFn> CacheIRAddStreamOrErr =
1694 IRCache(Task, IRKey, ModuleID);
1697 AddStreamFn &CacheIRAddStream = *CacheIRAddStreamOrErr;
1703 if (CacheCGAddStream || CacheIRAddStream) {
1706 return RunThinBackend(CacheCGAddStream ? CacheCGAddStream : CGAddStream,
1707 CacheIRAddStream ? CacheIRAddStream : IRAddStream);
1719class SecondRoundThinBackend :
public InProcessThinBackend {
1720 std::unique_ptr<SmallVector<StringRef>> IRFiles;
1724 SecondRoundThinBackend(
1725 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
1726 ThreadPoolStrategy ThinLTOParallelism,
1727 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
1731 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
1732 ModuleToDefinedGVSummaries, std::
move(AddStream),
1737 IRFiles(std::
move(IRFiles)), CombinedCGDataHash(CombinedCGDataHash) {}
1739 Error runThinLTOBackendThread(
1740 AddStreamFn AddStream, FileCache Cache,
unsigned Task, BitcodeModule BM,
1741 ModuleSummaryIndex &CombinedIndex,
1742 const FunctionImporter::ImportMapTy &ImportList,
1744 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1746 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
1748 llvm::TimeTraceScope timeScope(
"Run ThinLTO backend thread (second round)",
1750 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1751 LTOLLVMContext BackendContext(Conf);
1752 std::unique_ptr<Module> LoadedModule =
1755 return thinBackend(Conf, Task, AddStream, *LoadedModule, CombinedIndex,
1756 ImportList, DefinedGlobals, &ModuleMap,
1761 [](uint32_t V) { return V == 0; }))
1764 return RunThinBackend(AddStream);
1769 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1770 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1772 std::to_string(CombinedCGDataHash));
1773 Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task,
Key, ModuleID);
1776 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1778 if (CacheAddStream) {
1781 return RunThinBackend(CacheAddStream);
1791 bool ShouldEmitIndexFiles,
1792 bool ShouldEmitImportsFiles) {
1797 return std::make_unique<InProcessThinBackend>(
1798 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1799 AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
1800 ShouldEmitImportsFiles);
1826 return std::string(Path);
1830 if (!ParentPath.
empty()) {
1833 llvm::errs() <<
"warning: could not create directory '" << ParentPath
1834 <<
"': " << EC.message() <<
'\n';
1836 return std::string(NewPath);
1841 std::string OldPrefix, NewPrefix, NativeObjectPrefix;
1845 WriteIndexesThinBackend(
1849 std::string OldPrefix, std::string NewPrefix,
1850 std::string NativeObjectPrefix,
bool ShouldEmitImportsFiles,
1853 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
1854 OldPrefix(OldPrefix), NewPrefix(NewPrefix),
1855 NativeObjectPrefix(NativeObjectPrefix),
1856 LinkedObjectsFile(LinkedObjectsFile) {}
1862 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1870 if (LinkedObjectsFile) {
1871 std::string ObjectPrefix =
1872 NativeObjectPrefix.empty() ? NewPrefix : NativeObjectPrefix;
1873 std::string LinkedObjectsFilePath =
1875 *LinkedObjectsFile << LinkedObjectsFilePath <<
'\n';
1878 BackendThreadPool.async(
1879 [
this](
const StringRef ModulePath,
1880 const FunctionImporter::ImportMapTy &ImportList,
1881 const std::string &OldPrefix,
const std::string &NewPrefix) {
1882 std::string NewModulePath =
1884 auto E = emitFiles(ImportList, ModulePath, NewModulePath);
1886 std::unique_lock<std::mutex>
L(ErrMu);
1894 ModulePath, ImportList, OldPrefix, NewPrefix);
1897 OnWrite(std::string(ModulePath));
1901 bool isSensitiveToInputOrder()
override {
1911 std::string NewPrefix, std::string NativeObjectPrefix,
1918 return std::make_unique<WriteIndexesThinBackend>(
1919 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1920 OldPrefix, NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,
1921 LinkedObjectsFile, OnWrite);
1936 if (ThinLTO.ModuleMap.
empty())
1939 if (ThinLTO.ModulesToCompile && ThinLTO.ModulesToCompile->empty()) {
1940 llvm::errs() <<
"warning: [ThinLTO] No module compiled\n";
1944 if (Conf.CombinedIndexHook &&
1945 !Conf.CombinedIndexHook(ThinLTO.CombinedIndex, GUIDPreservedSymbols))
1950 DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries(
1951 ThinLTO.ModuleMap.size());
1952 ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule(
1953 ModuleToDefinedGVSummaries);
1961 for (
auto &
Mod : ThinLTO.ModuleMap)
1962 if (!ModuleToDefinedGVSummaries.
count(
Mod.first))
1965 FunctionImporter::ImportListsTy ImportLists(ThinLTO.ModuleMap.size());
1966 DenseMap<StringRef, FunctionImporter::ExportSetTy> ExportLists(
1967 ThinLTO.ModuleMap.size());
1968 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
1971 ThinLTO.CombinedIndex.dumpSCCs(
outs());
1973 std::set<GlobalValue::GUID> ExportedGUIDs;
1975 bool WholeProgramVisibilityEnabledInLTO =
1976 Conf.HasWholeProgramVisibility &&
1979 (!Conf.ValidateAllVtablesHaveTypeInfos || Conf.AllVtablesHaveTypeInfos);
1981 ThinLTO.CombinedIndex.setWithWholeProgramVisibility();
1986 DenseSet<GlobalValue::GUID> VisibleToRegularObjSymbols;
1987 if (WholeProgramVisibilityEnabledInLTO &&
1988 Conf.ValidateAllVtablesHaveTypeInfos) {
1991 auto IsVisibleToRegularObj = [&](StringRef
name) {
1992 auto It = GlobalResolutions->find(
name);
1993 return (It == GlobalResolutions->end() ||
1994 It->second.VisibleOutsideSummary || !It->second.Prevailing);
1998 VisibleToRegularObjSymbols,
1999 IsVisibleToRegularObj);
2005 ThinLTO.CombinedIndex, WholeProgramVisibilityEnabledInLTO,
2006 DynamicExportSymbols, VisibleToRegularObjSymbols);
2011 std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;
2013 LocalWPDTargetsMap);
2016 return ThinLTO.isPrevailingModuleForGUID(GUID, S->modulePath());
2019 MemProfContextDisambiguation ContextDisambiguation;
2020 ContextDisambiguation.
run(ThinLTO.CombinedIndex, isPrevailing);
2027 for (
auto &Res : *GlobalResolutions) {
2030 if (Res.second.Partition != GlobalResolution::External ||
2031 !Res.second.isPrevailingIRSymbol())
2036 if (ThinLTO.CombinedIndex.isGUIDLive(GUID))
2037 ExportedGUIDs.insert(GUID);
2044 releaseGlobalResolutionsMemory();
2046 if (Conf.OptLevel > 0)
2048 isPrevailing, ImportLists, ExportLists);
2052 auto &Defs = ThinLTO.CombinedIndex.cfiFunctionDefs();
2053 ExportedGUIDs.insert(Defs.guid_begin(), Defs.guid_end());
2054 auto &Decls = ThinLTO.CombinedIndex.cfiFunctionDecls();
2055 ExportedGUIDs.insert(Decls.guid_begin(), Decls.guid_end());
2057 auto isExported = [&](StringRef ModuleIdentifier, ValueInfo
VI) {
2058 const auto &ExportList = ExportLists.
find(ModuleIdentifier);
2059 return (ExportList != ExportLists.end() && ExportList->second.
count(VI)) ||
2060 ExportedGUIDs.count(
VI.getGUID());
2066 LocalWPDTargetsMap);
2071 auto recordNewLinkage = [&](StringRef ModuleIdentifier,
2074 ResolvedODR[ModuleIdentifier][
GUID] = NewLinkage;
2077 recordNewLinkage, GUIDPreservedSymbols);
2086 TimeTraceScopeExit.release();
2089 ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;
2091 auto RunBackends = [&](ThinBackendProc *BackendProcess) ->
Error {
2092 auto ProcessOneModule = [&](
int I) ->
Error {
2096 return BackendProcess->start(
2097 RegularLTO.ParallelCodeGenParallelismLevel +
I,
Mod.second,
2098 ImportLists[
Mod.first], ExportLists[
Mod.first],
2099 ResolvedODR[
Mod.first], ThinLTO.ModuleMap);
2102 BackendProcess->setup(ModuleMap.
size(),
2103 RegularLTO.ParallelCodeGenParallelismLevel,
2104 RegularLTO.CombinedModule->getTargetTriple());
2106 if (BackendProcess->getThreadCount() == 1 ||
2107 BackendProcess->isSensitiveToInputOrder()) {
2113 for (
int I = 0,
E = ModuleMap.
size();
I !=
E; ++
I)
2114 if (
Error E = ProcessOneModule(
I))
2121 std::vector<BitcodeModule *> ModulesVec;
2122 ModulesVec.reserve(ModuleMap.
size());
2123 for (
auto &
Mod : ModuleMap)
2124 ModulesVec.push_back(&
Mod.second);
2126 if (
Error E = ProcessOneModule(
I))
2129 return BackendProcess->wait();
2133 std::unique_ptr<ThinBackendProc> BackendProc =
2134 ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
2136 return RunBackends(BackendProc.get());
2144 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Initializing ThinLTO two-codegen rounds\n");
2147 auto Parallelism = ThinLTO.Backend.getParallelism();
2150 cgdata::StreamCacheData CG(MaxTasks, Cache,
"CG"),
IR(MaxTasks, Cache,
"IR");
2155 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Running the first round of codegen\n");
2156 auto FirstRoundLTO = std::make_unique<FirstRoundThinBackend>(
2157 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2158 CG.AddStream, CG.Cache,
IR.AddStream,
IR.Cache);
2159 if (
Error E = RunBackends(FirstRoundLTO.get()))
2164 if (
Error E = CombinedHashOrErr.takeError())
2166 auto CombinedHash = *CombinedHashOrErr;
2167 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] CGData hash: " << CombinedHash <<
"\n");
2171 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Running the second round of codegen\n");
2172 auto SecondRoundLTO = std::make_unique<SecondRoundThinBackend>(
2173 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2174 AddStream, Cache,
IR.getResult(), CombinedHash);
2175 return RunBackends(SecondRoundLTO.get());
2193 if (
Error E = ResultOrErr.takeError())
2194 return std::move(E);
2197 (*ResultOrErr)->keep();
2205 if (StatsFilename.
empty())
2216 return std::move(StatsFile);
2224 std::vector<int> ModulesOrdering(Seq.begin(), Seq.end());
2225 llvm::sort(ModulesOrdering, [&](
int LeftIndex,
int RightIndex) {
2226 auto LSize = R[LeftIndex]->getBuffer().size();
2227 auto RSize = R[RightIndex]->getBuffer().size();
2228 return LSize > RSize;
2230 return ModulesOrdering;
2240class OutOfProcessThinBackend :
public CGThinBackend {
2246 SString LinkerOutputFile;
2248 SString DistributorPath;
2251 SString RemoteCompiler;
2260 std::atomic<size_t> CachedJobs{0};
2265 StringRef NativeObjectPath;
2266 StringRef SummaryIndexPath;
2268 std::string CacheKey;
2270 bool Cached =
false;
2279 unsigned ThinLTOTaskOffset;
2282 llvm::Triple Triple;
2288 OutOfProcessThinBackend(
2289 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
2290 ThreadPoolStrategy ThinLTOParallelism,
2291 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
2293 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
2294 StringRef LinkerOutputFile, StringRef Distributor,
2298 : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
2299 AddStream, OnWrite, ShouldEmitIndexFiles,
2300 ShouldEmitImportsFiles, ThinLTOParallelism),
2301 LinkerOutputFile(LinkerOutputFile), DistributorPath(Distributor),
2302 DistributorArgs(DistributorArgs), RemoteCompiler(RemoteCompiler),
2303 RemoteCompilerPrependArgs(RemoteCompilerPrependArgs),
2304 RemoteCompilerArgs(RemoteCompilerArgs), SaveTemps(SaveTemps),
2305 Cache(std::
move(CacheFn)) {}
2307 void setup(
unsigned ThinLTONumTasks,
unsigned ThinLTOTaskOffset,
2308 llvm::Triple Triple)
override {
2310 Jobs.
resize((
size_t)ThinLTONumTasks);
2311 this->ThinLTOTaskOffset = ThinLTOTaskOffset;
2312 this->Triple = Triple;
2313 this->Conf.
Dtlto = 1;
2316 virtual Error runThinLTOBackendThread(
2317 Job &J,
const FunctionImporter::ImportMapTy &ImportList,
2319 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
2322 TimeTraceScope TimeScope(
"Emit individual index for DTLTO",
2323 J.SummaryIndexPath);
2324 if (
auto E = emitFiles(ImportList, J.ModuleID, J.ModuleID.str(),
2325 J.SummaryIndexPath, J.ImportsFiles))
2331 [](uint32_t V) { return V == 0; }))
2336 TimeTraceScope TimeScope(
"Check cache for DTLTO", J.SummaryIndexPath);
2338 ModuleToDefinedGVSummaries.
find(J.ModuleID)->second;
2342 ExportList, ResolvedODR, DefinedGlobals,
2343 CfiFunctionDefs, CfiFunctionDecls);
2346 auto CacheAddStreamExp = Cache(J.Task, J.CacheKey, J.ModuleID);
2347 if (
Error Err = CacheAddStreamExp.takeError())
2352 if (!CacheAddStream) {
2354 CachedJobs.fetch_add(1);
2359 J.CacheAddStream = std::move(CacheAddStream);
2365 unsigned Task, BitcodeModule BM,
2366 const FunctionImporter::ImportMapTy &ImportList,
2368 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
2369 MapVector<StringRef, BitcodeModule> &ModuleMap)
override {
2375 itostr(Task) +
"." + UID +
".native.o");
2377 Job &J = Jobs[Task - ThinLTOTaskOffset];
2380 Saver.
save(ObjFilePath.str()),
2381 Saver.
save(ObjFilePath.str() +
".thinlto.bc"),
2390 if (!ShouldEmitIndexFiles)
2394 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
2398 BackendThreadPool.async(
2399 [=](Job &J,
const FunctionImporter::ImportMapTy &ImportList,
2401 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
2406 "Emit individual index and check cache for DTLTO");
2408 runThinLTOBackendThread(J, ImportList, ExportList, ResolvedODR);
2410 std::unique_lock<std::mutex>
L(ErrMu);
2419 std::ref(J), std::ref(ImportList), std::ref(ExportList),
2420 std::ref(ResolvedODR));
2434 void buildCommonRemoteCompilerOptions() {
2435 const lto::Config &
C = Conf;
2436 auto &
Ops = CodegenOptions;
2440 if (
C.Options.EmitAddrsig)
2441 Ops.push_back(
"-faddrsig");
2442 if (
C.Options.FunctionSections)
2443 Ops.push_back(
"-ffunction-sections");
2444 if (
C.Options.DataSections)
2445 Ops.push_back(
"-fdata-sections");
2450 Ops.push_back(
"-fpic");
2454 if (!
C.PGOWarnMismatch) {
2455 Ops.push_back(
"-mllvm");
2456 Ops.push_back(
"-no-pgo-warn-mismatch");
2461 if (!
C.SampleProfile.empty()) {
2463 Saver.
save(
"-fprofile-sample-use=" + Twine(
C.SampleProfile)));
2464 CommonInputs.
insert(
C.SampleProfile);
2468 Ops.push_back(
"-Wno-unused-command-line-argument");
2471 if (!RemoteCompilerArgs.
empty())
2472 for (
auto &a : RemoteCompilerArgs)
2478 bool emitDistributorJson(StringRef DistributorJson) {
2481 raw_fd_ostream OS(DistributorJson, EC);
2485 json::OStream JOS(OS);
2488 JOS.attributeObject(
"common", [&]() {
2489 JOS.attribute(
"linker_output", LinkerOutputFile);
2491 JOS.attributeArray(
"args", [&]() {
2492 JOS.value(RemoteCompiler);
2495 if (!RemoteCompilerPrependArgs.
empty())
2496 for (
auto &
A : RemoteCompilerPrependArgs)
2501 JOS.value(Saver.
save(
"--target=" + Triple.
str()));
2503 for (
const auto &
A : CodegenOptions)
2507 JOS.attribute(
"inputs",
Array(CommonInputs));
2511 JOS.attributeArray(
"jobs", [&]() {
2512 for (
const auto &J : Jobs) {
2520 SmallVector<StringRef, 1> Outputs;
2523 JOS.attributeArray(
"args", [&]() {
2524 JOS.value(J.ModuleID);
2528 Saver.
save(
"-fthinlto-index=" + Twine(J.SummaryIndexPath)));
2532 JOS.value(J.NativeObjectPath);
2540 JOS.attribute(
"inputs",
Array(Inputs));
2542 JOS.attribute(
"outputs",
Array(Outputs));
2551 void removeFile(StringRef FileName) {
2553 if (EC && EC != std::make_error_code(std::errc::no_such_file_or_directory))
2554 errs() <<
"warning: could not remove the file '" << FileName
2555 <<
"': " <<
EC.message() <<
"\n";
2558 Error wait()
override {
2561 BackendThreadPool.wait();
2563 return std::move(*Err);
2566 llvm::TimeTraceScope TimeScope(
"Remove DTLTO temporary files");
2568 for (
auto &Job : Jobs) {
2569 removeFile(Job.NativeObjectPath);
2570 if (!ShouldEmitIndexFiles)
2571 removeFile(Job.SummaryIndexPath);
2575 const StringRef BCError =
"DTLTO backend compilation: ";
2577 buildCommonRemoteCompilerOptions();
2581 llvm::TimeTraceScope TimeScope(
"Emit DTLTO JSON");
2583 UID +
".dist-file.json");
2587 if (!emitDistributorJson(JsonFile))
2589 BCError +
"failed to generate distributor JSON script: " + JsonFile,
2594 removeFile(JsonFile);
2598 llvm::TimeTraceScope TimeScope(
"Execute DTLTO distributor",
2601 if (CachedJobs.load() < Jobs.size()) {
2604 Args.push_back(JsonFile);
2611 BCError +
"distributor execution failed" +
2612 (!ErrMsg.empty() ?
": " + ErrMsg + Twine(
".") : Twine(
".")),
2619 llvm::TimeTraceScope FilesScope(
"Add DTLTO files to the link");
2620 for (
auto &Job : Jobs) {
2621 if (!Job.CacheKey.empty() && Job.Cached) {
2627 auto ObjFileMbOrErr =
2630 if (std::error_code EC = ObjFileMbOrErr.getError())
2632 BCError +
"cannot open native object file: " +
2633 Job.NativeObjectPath +
": " +
EC.message(),
2636 MemoryBufferRef ObjFileMbRef = ObjFileMbOrErr->get()->getMemBufferRef();
2640 assert(Job.CacheAddStream);
2642 auto CachedFileStreamOrErr =
2643 Job.CacheAddStream(Job.Task, Job.ModuleID);
2644 if (!CachedFileStreamOrErr)
2646 CachedFileStreamOrErr.takeError(),
2648 "Cannot get a cache file stream: %s",
2649 Job.NativeObjectPath.data()));
2651 auto &CacheStream = *(CachedFileStreamOrErr->get());
2652 *(CacheStream.OS) << ObjFileMbRef.
getBuffer();
2653 if (
Error Err = CacheStream.commit())
2656 auto StreamOrErr = AddStream(Job.Task, Job.ModuleID);
2657 if (
Error Err = StreamOrErr.takeError())
2659 auto &Stream = *StreamOrErr->get();
2661 if (
Error Err = Stream.commit())
2673 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
2682 return std::make_unique<OutOfProcessThinBackend>(
2683 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2684 AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
2685 ShouldEmitImportsFiles, LinkerOutputFile, Distributor,
2686 DistributorArgs, RemoteCompiler, RemoteCompilerPrependArgs,
2687 RemoteCompilerArgs, SaveTemps);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file supports working with JSON data.
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)
Legalize the Machine IR a function s Machine IR
Machine Check Debug Module
static constexpr StringLiteral Filename
Provides a library for accessing information about this process and other processes on the operating ...
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),...
bool empty() const
empty - Check if the array is empty.
const T & consume_front()
consume_front() - Returns the first element and drops it from ArrayRef.
static LLVM_ABI 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
LLVM_ABI 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.
LLVM_ABI Expected< std::unique_ptr< Module > > parseModule(LLVMContext &Context, ParserCallbacks Callbacks={})
Read the entire bitcode module and return it.
LLVM_ABI 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 LLVM_ABI 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.
The map maintains the list of imports.
DenseSet< ValueInfo > ExportSetTy
The set contains an entry for every global value that the module exports.
Function and variable summary information to aid decisions and implementation of importing.
static bool isAppendingLinkage(LinkageTypes Linkage)
static LLVM_ABI GUID getGUIDAssumingExternalLinkage(StringRef GlobalName)
Return a 64-bit global unique ID constructed from the name of a global symbol.
static bool isExternalWeakLinkage(LinkageTypes Linkage)
static bool isLocalLinkage(LinkageTypes Linkage)
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
void setUnnamedAddr(UnnamedAddr Val)
uint64_t GUID
Declare a type to represent a global unique identifier for a global value.
bool hasLocalLinkage() const
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
LLVM_ABI const Comdat * getComdat() const
static bool isLinkOnceLinkage(LinkageTypes Linkage)
void setLinkage(LinkageTypes LT)
DLLStorageClassTypes
Storage classes of global values for PE targets.
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
static bool isExternalLinkage(LinkageTypes Linkage)
VisibilityTypes
An enumeration for the kinds of visibility of global values.
@ DefaultVisibility
The GV is visible.
static LLVM_ABI std::string getGlobalIdentifier(StringRef Name, GlobalValue::LinkageTypes Linkage, StringRef FileName)
Return the modified name for a global value suitable to be used as the key for a global lookup (e....
static LinkageTypes getWeakLinkage(bool ODR)
static bool isWeakForLinker(LinkageTypes Linkage)
Whether the definition of this global may be replaced at link time.
bool hasAppendingLinkage() const
bool hasAvailableExternallyLinkage() const
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)
LLVM_ABI void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
This is an important class for using LLVM in a threaded context.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
This class implements a map that also provides access to all stored values in a deterministic order.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
StringRef getBuffer() const
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...
CfiFunctionIndex & cfiFunctionDecls()
void setPartiallySplitLTOUnits()
void releaseTemporaryMemory()
const ModuleHash & getModuleHash(const StringRef ModPath) const
Get the module SHA1 hash recorded for the given module path.
bool partiallySplitLTOUnits() const
const StringMap< ModuleHash > & modulePaths() const
Table of modules, containing module hash and id.
CfiFunctionIndex & cfiFunctionDefs()
LLVM_ABI void addModule(Module *M)
static LLVM_ABI 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.
PointerUnion< GlobalValue *, AsmSymbol * > Symbol
LLVM_ABI 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 class that wrap the SHA1 algorithm.
LLVM_ABI void update(ArrayRef< uint8_t > Data)
Digest more data.
LLVM_ABI std::array< uint8_t, 20 > result()
Return the current raw 160-bits SHA1 for the digested data since the last call to init().
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.
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
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.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
StringRef save(const char *S)
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.
This tells how a thread pool will be used.
The TimeTraceScope is a helper class to call the begin and end functions of the time trace profiler.
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 isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
const std::string & str() const
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, DriverKit, XROS, or bridgeOS).
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 LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI 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)
void insert_range(Range &&R)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
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().
LLVM_ABI LTO(Config Conf, ThinBackend Backend={}, unsigned ParallelCodeGenParallelismLevel=1, LTOKind LTOMode=LTOK_Default)
Create an LTO object.
LLVM_ABI Error add(std::unique_ptr< InputFile > Obj, ArrayRef< SymbolResolution > Res)
Add an input file to the LTO link, using the provided symbol resolutions.
static LLVM_ABI SmallVector< const char * > getRuntimeLibcallSymbols(const Triple &TT)
Static method that returns a list of libcall symbols that can be generated by LTO but might not be vi...
virtual Error handleArchiveInputs()
virtual Expected< std::shared_ptr< lto::InputFile > > addInput(std::unique_ptr< lto::InputFile > InputPtr)
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.
LLVM_ABI unsigned getMaxTasks() const
Returns an upper bound on the number of tasks that the client may expect.
LLVM_ABI Error run(AddStreamFn AddStream, FileCache Cache={})
Runs the LTO pipeline.
This class defines the interface to the ThinLTO backend.
bool ShouldEmitImportsFiles
const DenseMap< StringRef, GVSummaryMapTy > & ModuleToDefinedGVSummaries
LLVM_ABI Error emitFiles(const FunctionImporter::ImportMapTy &ImportList, StringRef ModulePath, const std::string &NewModulePath) const
ModuleSummaryIndex & CombinedIndex
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.
static LLVM_ABI Pid getProcessId()
Get the process's identifier.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI Function * getDeclarationIfExists(const Module *M, ID id)
Look up the Function declaration of the intrinsic id in the Module M and return it if it exists.
static auto libcall_impls()
LLVM_ABI Expected< stable_hash > mergeCodeGenData(ArrayRef< StringRef > ObjectFiles)
Merge the codegen data from the scratch objects ObjectFiles from the first codegen round.
LLVM_ABI std::unique_ptr< Module > loadModuleForTwoRounds(BitcodeModule &OrigModule, unsigned Task, LLVMContext &Context, ArrayRef< StringRef > IRFiles)
Load the optimized bitcode module for the second codegen round.
initializer< Ty > init(const Ty &Val)
LLVM_ABI ThinBackend createInProcessThinBackend(ThreadPoolStrategy Parallelism, IndexWriteCallback OnWrite=nullptr, bool ShouldEmitIndexFiles=false, bool ShouldEmitImportsFiles=false)
This ThinBackend runs the individual backend jobs in-process.
LLVM_ABI 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.
LLVM_ABI StringLiteral getThinLTODefaultCPU(const Triple &TheTriple)
LLVM_ABI Expected< std::unique_ptr< ToolOutputFile > > setupStatsFile(StringRef StatsFilename)
Setups the output file for saving statistics.
LLVM_ABI ThinBackend createOutOfProcessThinBackend(ThreadPoolStrategy Parallelism, IndexWriteCallback OnWrite, bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles, StringRef LinkerOutputFile, StringRef Distributor, ArrayRef< StringRef > DistributorArgs, StringRef RemoteCompiler, ArrayRef< StringRef > RemoteCompilerPrependArgs, ArrayRef< StringRef > RemoteCompilerArgs, bool SaveTemps)
This ThinBackend generates the index shards and then runs the individual backend jobs via an external...
LLVM_ABI Error backend(const Config &C, AddStreamFn AddStream, unsigned ParallelCodeGenParallelismLevel, Module &M, ModuleSummaryIndex &CombinedIndex)
Runs a regular LTO backend.
std::function< void(const std::string &)> IndexWriteCallback
LLVM_ABI Error finalizeOptimizationRemarks(LLVMRemarkFileHandle DiagOutputFile)
LLVM_ABI ThinBackend createWriteIndexesThinBackend(ThreadPoolStrategy Parallelism, 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...
LLVM_ABI Expected< LLVMRemarkFileHandle > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::optional< uint64_t > RemarksHotnessThreshold=0, int Count=-1)
Setup optimization remarks.
LLVM_ABI std::vector< int > generateModulesOrdering(ArrayRef< BitcodeModule * > R)
Produces a container ordering for optimal multi-threaded processing.
LLVM_ABI 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, bool CodeGenOnly, AddStreamFn IRAddStream=nullptr, const std::vector< uint8_t > &CmdArgs=std::vector< uint8_t >())
Runs a ThinLTO backend.
llvm::SmallVector< std::string > ImportsFilesContainer
LLVM_ABI Expected< IRSymtabFile > readIRSymtab(MemoryBufferRef MBRef)
Reads a bitcode file, creating its irsymtab if necessary.
DiagnosticInfoOptimizationBase::Argument NV
void write64le(void *P, uint64_t V)
void write32le(void *P, uint32_t V)
LLVM_ABI std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
LLVM_ABI 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.
LLVM_ABI StringRef stem(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get stem.
LLVM_ABI StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
LLVM_ABI bool replace_path_prefix(SmallVectorImpl< char > &Path, StringRef OldPrefix, StringRef NewPrefix, Style style=Style::native)
Replace matching path prefix with another path.
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
LLVM_ABI bool RemoveFileOnSignal(StringRef Filename, std::string *ErrMsg=nullptr)
This function registers signal handlers to ensure that if a signal gets delivered that the named file...
LLVM_ABI int ExecuteAndWait(StringRef Program, ArrayRef< StringRef > Args, std::optional< ArrayRef< StringRef > > Env=std::nullopt, ArrayRef< std::optional< StringRef > > Redirects={}, unsigned SecondsToWait=0, unsigned MemoryLimit=0, std::string *ErrMsg=nullptr, bool *ExecutionFailed=nullptr, std::optional< ProcessStatistics > *ProcStat=nullptr, BitVector *AffinityMask=nullptr)
This function executes the program using the arguments provided.
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.
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
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.
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
std::unordered_set< GlobalValueSummary * > GVSummaryPtrSet
A set of global value summary pointers.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void generateParamAccessSummary(ModuleSummaryIndex &Index)
cl::opt< bool > CodeGenDataThinLTOTwoRounds("codegen-data-thinlto-two-rounds", cl::init(false), cl::Hidden, cl::desc("Enable two-round ThinLTO code generation. The first round " "emits codegen data, while the second round uses the emitted " "codegen data for further optimizations."))
LLVM_ABI Expected< LLVMRemarkFileHandle > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::optional< uint64_t > RemarksHotnessThreshold=0)
Set up optimization remarks that output to a file.
scope_exit(Callable) -> scope_exit< Callable >
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"))
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
DenseMap< GlobalValue::GUID, GlobalValueSummary * > GVSummaryMapTy
Map of global value GUID to its summary, used to identify values defined in a particular module,...
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
uint64_t stable_hash
An opaque object representing a stable hash code.
std::string utostr(uint64_t X, bool isNeg=false)
LLVM_ABI 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.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
LLVM_ABI bool hasWholeProgramVisibility(bool WholeProgramVisibilityEnabledInLTO)
LLVM_ABI void writeIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out, const ModuleToSummariesForIndexTy *ModuleToSummariesForIndex=nullptr, const GVSummaryPtrSet *DecSummaries=nullptr)
Write the specified module summary index to the given raw output stream, where it will be written in ...
LLVM_ABI void ComputeCrossModuleImport(const ModuleSummaryIndex &Index, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, FunctionImporter::ImportListsTy &ImportLists, DenseMap< StringRef, FunctionImporter::ExportSetTy > &ExportLists)
Compute all the imports and exports for every module in the Index.
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI void EnableStatistics(bool DoPrintOnExit=true)
Enable the collection and printing of statistics.
LLVM_ABI 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...
LLVM_ABI void timeTraceProfilerInitialize(unsigned TimeTraceGranularity, StringRef ProcName, bool TimeTraceVerbose=false)
Initialize the time trace profiler.
LLVM_ABI void timeTraceProfilerFinishThread()
Finish a time trace profiler running on a worker thread.
LLVM_ABI std::string recomputeLTOCacheKey(const std::string &Key, StringRef ExtraID)
Recomputes the LTO cache key for a given key with an extra identifier.
Error joinErrors(Error E1, Error E2)
Concatenate errors.
LLVM_ABI void updatePublicTypeTestCalls(Module &M, bool WholeProgramVisibilityEnabledInLTO)
LLVM_ABI void getVisibleToRegularObjVtableGUIDs(ModuleSummaryIndex &Index, DenseSet< GlobalValue::GUID > &VisibleToRegularObjSymbols, function_ref< bool(StringRef)> IsVisibleToRegularObj)
Based on typeID string, get all associated vtable GUIDS that are visible to regular objects.
void sort(IteratorTy Start, IteratorTy End)
bool timeTraceProfilerEnabled()
Is the time trace profiler enabled, i.e. initialized?
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
std::map< std::string, GVSummaryMapTy, std::less<> > ModuleToSummariesForIndexTy
Map of a module name to the GUIDs and summaries we will import from that module.
LLVM_ABI 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)
LLVM_ABI 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.
LLVM_ABI 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...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI 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.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
LLVM_ABI 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.
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
cl::opt< bool > EnableMemProfContextDisambiguation
Enable MemProf context disambiguation for thin link.
LLVM_ABI 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.
cl::opt< bool > ForceImportAll
LLVM_ABI void gatherImportedSummariesForModule(StringRef ModulePath, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, const FunctionImporter::ImportMapTy &ImportList, ModuleToSummariesForIndexTy &ModuleToSummariesForIndex, GVSummaryPtrSet &DecSummaries)
Compute the set of summaries needed for a ThinLTO backend compilation of ModulePath.
ArrayRef(const T &OneElt) -> ArrayRef< T >
void toHex(ArrayRef< uint8_t > Input, bool LowerCase, SmallVectorImpl< char > &Output)
Convert buffer Input to its hexadecimal representation. The returned string is double the size of Inp...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void processImportsFiles(StringRef ModulePath, const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex, function_ref< void(const std::string &)> F)
Call F passing each of the files module ModulePath will import from.
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)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI std::string computeLTOCacheKey(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 DenseSet< GlobalValue::GUID > &CfiFunctionDefs={}, const DenseSet< GlobalValue::GUID > &CfiFunctionDecls={})
Computes a unique hash for the Module considering the current list of export/import and other global ...
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
static cl::opt< bool > LTOKeepSymbolCopies("lto-keep-symbol-copies", cl::init(false), cl::Hidden, cl::desc("Keep copies of symbols in LTO indexing"))
LLVM_ABI bool UpgradeDebugInfo(Module &M)
Check the debug info version number, if it is out-dated, drop the debug info.
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
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.
LLVM_ABI void PrintStatisticsJSON(raw_ostream &OS)
Print statistics in JSON format.
LLVM_ABI 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.
LLVM_ABI Error EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename, const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex)
Emit into OutputFilename the files module ModulePath will import from.
@ Keep
No function return thunk.
std::string itostr(int64_t X)
LLVM_ABI 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...
LLVM_ABI TimeTraceProfilerEntry * timeTraceProfilerBegin(StringRef Name, StringRef Detail)
Manually begin a time section, with the given Name and Detail.
LLVM_ABI 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 type represents a file cache system that manages caching of files.
const std::string & getCacheDirectoryPath() const
A simple container for information about the supported runtime calls.
unsigned getNumAvailableLibcallImpls() const
bool isAvailable(RTLIB::LibcallImpl Impl) const
LLVM_ABI RTLIB::LibcallImpl getSupportedLibcallImpl(StringRef FuncName) const
Check if this is valid libcall for the current module, otherwise RTLIB::Unsupported.
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl)
Get the libcall routine name for the specified libcall implementation.
Struct that holds a reference to a particular GUID in a global value summary.
std::optional< uint64_t > RemarksHotnessThreshold
The minimum hotness value a diagnostic needs in order to be included in optimization diagnostics.
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
CodeGenOptLevel CGOptLevel
bool Dtlto
This flag is used as one of parameters to calculate cache entries and to ensure that in-process cache...
std::string DefaultTriple
Setting this field will replace unspecified target triples in input files with this triple.
std::string DwoDir
The directory to store .dwo files.
std::string RemarksFilename
Optimization remarks file path.
std::string OverrideTriple
Setting this field will replace target triples in input files with this triple.
std::string ProfileRemapping
Name remapping file for profile data.
bool TimeTraceEnabled
Time trace enabled.
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 ...
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).
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.
This type defines the behavior following the thin-link phase during ThinLTO.