28#include "llvm/Config/llvm-config.h"
56#include "llvm/Support/VCSRevision.h"
70using namespace object;
72#define DEBUG_TYPE "lto"
76 cl::desc(
"Dump the SCCs in the ThinLTO index's callgraph"));
86 cl::desc(
"Enable global value internalization in LTO"));
90 cl::desc(
"Keep copies of symbols in LTO indexing"));
107 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
118 Hasher.
update(LLVM_VERSION_STRING);
120 Hasher.
update(LLVM_REVISION);
128 auto AddUnsigned = [&](
unsigned I) {
138 auto AddUint8 = [&](
const uint8_t I) {
162 AddUnsigned(
static_cast<int>(Conf.
CGOptLevel));
163 AddUnsigned(
static_cast<int>(Conf.
CGFileType));
173 auto ModHash = Index.getModuleHash(ModuleID);
178 std::vector<uint64_t> ExportsGUID;
179 ExportsGUID.reserve(ExportList.
size());
180 for (
const auto &VI : ExportList)
181 ExportsGUID.push_back(VI.getGUID());
185 for (
auto GUID : ExportsGUID)
190 auto Comp = [&](
const std::pair<StringRef, GlobalValue::GUID> &L,
191 const std::pair<StringRef, GlobalValue::GUID> &R) {
192 return std::make_pair(Index.getModule(L.first)->second, L.second) <
193 std::make_pair(Index.getModule(R.first)->second, R.second);
199 for (
const auto &[FromModule, GUID,
Type] : SortedImportList)
200 ++ModuleToNumImports[FromModule];
202 std::optional<StringRef> LastModule;
203 for (
const auto &[FromModule, GUID,
Type] : SortedImportList) {
204 if (LastModule != FromModule) {
208 LastModule = FromModule;
209 auto ModHash = Index.getModule(FromModule)->second;
211 AddUint64(ModuleToNumImports[FromModule]);
218 for (
auto &Entry : ResolvedODR) {
227 std::set<GlobalValue::GUID> UsedCfiDefs;
228 std::set<GlobalValue::GUID> UsedCfiDecls;
231 std::set<GlobalValue::GUID> UsedTypeIds;
234 if (CfiFunctionDefs.
contains(ValueGUID))
235 UsedCfiDefs.insert(ValueGUID);
236 if (CfiFunctionDecls.
contains(ValueGUID))
237 UsedCfiDecls.insert(ValueGUID);
242 AddUnsigned(GS->getVisibility());
243 AddUnsigned(GS->isLive());
244 AddUnsigned(GS->canAutoHide());
246 AddUnsigned(VI.isDSOLocal(Index.withDSOLocalPropagation()));
247 AddUsedCfiGlobal(VI.getGUID());
249 if (
auto *GVS = dyn_cast<GlobalVarSummary>(GS)) {
250 AddUnsigned(GVS->maybeReadOnly());
251 AddUnsigned(GVS->maybeWriteOnly());
253 if (
auto *FS = dyn_cast<FunctionSummary>(GS)) {
254 for (
auto &TT : FS->type_tests())
255 UsedTypeIds.insert(TT);
256 for (
auto &TT : FS->type_test_assume_vcalls())
257 UsedTypeIds.insert(TT.GUID);
258 for (
auto &TT : FS->type_checked_load_vcalls())
259 UsedTypeIds.insert(TT.GUID);
260 for (
auto &TT : FS->type_test_assume_const_vcalls())
261 UsedTypeIds.insert(TT.VFunc.GUID);
262 for (
auto &TT : FS->type_checked_load_const_vcalls())
263 UsedTypeIds.insert(TT.VFunc.GUID);
264 for (
auto &ET : FS->calls()) {
265 AddUnsigned(ET.first.isDSOLocal(Index.withDSOLocalPropagation()));
266 AddUsedCfiGlobal(ET.first.getGUID());
273 for (
auto &GS : DefinedGlobals) {
277 AddUsedCfiGlobal(GS.first);
278 AddUsedThings(GS.second);
283 for (
const auto &[FromModule, GUID,
Type] : SortedImportList) {
288 if (
auto *AS = dyn_cast_or_null<AliasSummary>(S))
289 AddUsedThings(AS->getBaseObject());
295 AddUnsigned(S.TTRes.TheKind);
296 AddUnsigned(S.TTRes.SizeM1BitWidth);
298 AddUint64(S.TTRes.AlignLog2);
299 AddUint64(S.TTRes.SizeM1);
300 AddUint64(S.TTRes.BitMask);
301 AddUint64(S.TTRes.InlineBits);
303 AddUint64(S.WPDRes.size());
304 for (
auto &WPD : S.WPDRes) {
305 AddUnsigned(WPD.first);
306 AddUnsigned(WPD.second.TheKind);
307 AddString(WPD.second.SingleImplName);
309 AddUint64(WPD.second.ResByArg.size());
310 for (
auto &ByArg : WPD.second.ResByArg) {
311 AddUint64(ByArg.first.size());
314 AddUnsigned(ByArg.second.TheKind);
315 AddUint64(ByArg.second.Info);
316 AddUnsigned(ByArg.second.Byte);
317 AddUnsigned(ByArg.second.Bit);
324 auto TidIter = Index.typeIds().equal_range(TId);
326 AddTypeIdSummary(
I.second.first,
I.second.second);
329 AddUnsigned(UsedCfiDefs.size());
330 for (
auto &V : UsedCfiDefs)
333 AddUnsigned(UsedCfiDecls.size());
334 for (
auto &V : UsedCfiDecls)
340 Hasher.
update(FileOrErr.get()->getBuffer());
345 Hasher.
update(FileOrErr.get()->getBuffer());
350 return toHex(Hasher.
result());
364 return toHex(Hasher.
result());
376 C.VisibilityScheme ==
Config::ELF ? VI.getELFVisibility()
378 for (
auto &S : VI.getSummaryList()) {
393 if (isPrevailing(VI.getGUID(), S.get())) {
406 S->setCanAutoHide(VI.canAutoHide() &&
407 !GUIDPreservedSymbols.
count(VI.getGUID()));
410 Visibility = S->getVisibility();
416 else if (!isa<AliasSummary>(S.get()) &&
424 S->setVisibility(Visibility);
426 if (S->linkage() != OriginalLinkage)
427 recordNewLinkage(S->modulePath(), VI.getGUID(), S->linkage());
431 for (
auto &S : VI.getSummaryList()) {
436 S->setVisibility(Visibility);
458 for (
auto &
I : Index)
459 for (
auto &S :
I.second.SummaryList)
460 if (
auto AS = dyn_cast<AliasSummary>(S.get()))
461 GlobalInvolvedWithAlias.
insert(&AS->getAliasee());
463 for (
auto &
I : Index)
465 GlobalInvolvedWithAlias, isPrevailing,
466 recordNewLinkage, GUIDPreservedSymbols);
473 auto ExternallyVisibleCopies =
475 [](
const std::unique_ptr<GlobalValueSummary> &Summary) {
476 return !GlobalValue::isLocalLinkage(Summary->linkage());
479 for (
auto &S : VI.getSummaryList()) {
482 if (isExported(S->modulePath(), VI)) {
541 if (isPrevailing(VI.getGUID(), S.get()) && ExternallyVisibleCopies == 1)
553 for (
auto &
I : Index)
562 std::unique_ptr<InputFile> File(
new InputFile);
568 File->TargetTriple = FOrErr->TheReader.getTargetTriple();
569 File->SourceFileName = FOrErr->TheReader.getSourceFileName();
570 File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts();
571 File->DependentLibraries = FOrErr->TheReader.getDependentLibraries();
572 File->ComdatTable = FOrErr->TheReader.getComdatTable();
574 for (
unsigned I = 0;
I != FOrErr->Mods.size(); ++
I) {
575 size_t Begin = File->Symbols.size();
577 FOrErr->TheReader.module_symbols(
I))
581 File->Symbols.push_back(
Sym);
582 File->ModuleSymIndices.push_back({Begin, File->Symbols.size()});
585 File->Mods = FOrErr->Mods;
586 File->Strtab = std::move(FOrErr->Strtab);
587 return std::move(File);
591 return Mods[0].getModuleIdentifier();
595 assert(Mods.size() == 1 &&
"Expect only one bitcode module");
599LTO::RegularLTOState::RegularLTOState(
unsigned ParallelCodeGenParallelismLevel,
601 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
602 Ctx(Conf), CombinedModule(
std::make_unique<
Module>(
"ld-temp.o", Ctx)),
603 Mover(
std::make_unique<
IRMover>(*CombinedModule)) {}
605LTO::ThinLTOState::ThinLTOState(
ThinBackend BackendParam)
606 : Backend(
std::
move(BackendParam)), CombinedIndex(
false) {
607 if (!Backend.isValid())
613 unsigned ParallelCodeGenParallelismLevel,
LTOKind LTOMode)
615 RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),
621 Alloc = std::make_unique<BumpPtrAllocator>();
622 GlobalResolutionSymbolSaver = std::make_unique<llvm::StringSaver>(*Alloc);
633 unsigned Partition,
bool InSummary) {
634 auto *ResI = Res.
begin();
635 auto *ResE = Res.
end();
643 if (GlobalResolutionSymbolSaver && !GlobalResolutions->contains(SymbolName))
644 SymbolName = GlobalResolutionSymbolSaver->save(SymbolName);
646 auto &GlobalRes = (*GlobalResolutions)[SymbolName];
647 GlobalRes.UnnamedAddr &=
Sym.isUnnamedAddr();
649 assert(!GlobalRes.Prevailing &&
650 "Multiple prevailing defs are not allowed");
651 GlobalRes.Prevailing =
true;
652 GlobalRes.IRName = std::string(
Sym.getIRName());
653 }
else if (!GlobalRes.Prevailing && GlobalRes.IRName.empty()) {
660 GlobalRes.IRName = std::string(
Sym.getIRName());
674 if (GlobalRes.IRName !=
Sym.getIRName()) {
675 GlobalRes.Partition = GlobalResolution::External;
676 GlobalRes.VisibleOutsideSummary =
true;
684 (GlobalRes.Partition != GlobalResolution::Unknown &&
685 GlobalRes.Partition != Partition)) {
686 GlobalRes.Partition = GlobalResolution::External;
689 GlobalRes.Partition = Partition;
693 GlobalRes.VisibleOutsideSummary |=
700void LTO::releaseGlobalResolutionsMemory() {
702 GlobalResolutions.reset();
704 GlobalResolutionSymbolSaver.reset();
712 auto ResI = Res.
begin();
717 OS <<
"-r=" << Path <<
',' <<
Sym.getName() <<
',';
734 assert(!CalledGetMaxTasks);
739 if (RegularLTO.CombinedModule->getTargetTriple().empty()) {
740 Triple InputTriple(Input->getTargetTriple());
741 RegularLTO.CombinedModule->setTargetTriple(InputTriple);
747 for (
unsigned I = 0;
I != Input->Mods.size(); ++
I) {
748 if (
auto Err = addModule(*Input, InputRes,
I, Res).moveInto(Res))
763 if (EnableSplitLTOUnit) {
767 if (*EnableSplitLTOUnit != LTOInfo->EnableSplitLTOUnit)
768 ThinLTO.CombinedIndex.setPartiallySplitLTOUnits();
770 EnableSplitLTOUnit = LTOInfo->EnableSplitLTOUnit;
775 !LTOInfo->UnifiedLTO)
776 return make_error<StringError>(
777 "unified LTO compilation must use "
778 "compatible bitcode modules (use -funified-lto)",
786 auto ModSyms = Input.module_symbols(ModI);
787 addModuleToGlobalRes(ModSyms, Res,
788 IsThinLTO ? ThinLTO.ModuleMap.size() + 1 : 0,
789 LTOInfo->HasSummary);
792 return addThinLTO(BM, ModSyms, Res);
794 RegularLTO.EmptyCombinedModule =
false;
795 auto ModOrErr = addRegularLTO(Input, InputRes, BM, ModSyms, Res);
797 return ModOrErr.takeError();
798 Res = ModOrErr->second;
800 if (!LTOInfo->HasSummary) {
801 if (
Error Err = linkRegularLTO(std::move(ModOrErr->first),
811 RegularLTO.ModsWithSummaries.push_back(std::move(ModOrErr->first));
827 std::set<const Comdat *> &NonPrevailingComdats) {
832 if (!NonPrevailingComdats.count(
C))
841 if (
auto GO = dyn_cast<GlobalObject>(&GV))
842 GO->setComdat(
nullptr);
849 std::pair<LTO::RegularLTOState::AddedModule, ArrayRef<SymbolResolution>>>
853 RegularLTOState::AddedModule
Mod;
860 Mod.M = std::move(*MOrErr);
862 if (
Error Err =
M.materializeMetadata())
863 return std::move(Err);
869 if (
NamedMDNode *CfiFunctionsMD =
M.getNamedMetadata(
"cfi.functions"))
870 M.eraseNamedMetadata(CfiFunctionsMD);
871 }
else if (
NamedMDNode *AliasesMD =
M.getNamedMetadata(
"aliases")) {
876 if (
R.Prevailing && !
I.getIRName().empty())
877 Prevailing.
insert(
I.getIRName());
878 std::vector<MDNode *> AliasGroups;
880 std::vector<Metadata *> Aliases;
881 for (
Metadata *Alias : AliasGroup->operands()) {
882 if (isa<MDString>(Alias) &&
883 Prevailing.
count(cast<MDString>(Alias)->getString()))
884 Aliases.push_back(Alias);
886 if (Aliases.size() > 1)
887 AliasGroups.push_back(
MDTuple::get(RegularLTO.Ctx, Aliases));
889 AliasesMD->clearOperands();
891 AliasesMD->addOperand(
G);
900 if (GV.hasAppendingLinkage())
901 Mod.Keep.push_back(&GV);
904 for (
auto &GA :
M.aliases())
906 AliasedGlobals.
insert(GO);
915 auto MsymI = SymTab.
symbols().begin(), MsymE = SymTab.
symbols().end();
917 while (MsymI != MsymE) {
927 std::set<const Comdat *> NonPrevailingComdats;
937 if (
GlobalValue *GV = dyn_cast_if_present<GlobalValue *>(Msym)) {
939 if (
Sym.isUndefined())
941 Mod.Keep.push_back(GV);
945 if (
R.LinkerRedefined)
952 }
else if (isa<GlobalObject>(GV) &&
953 (GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||
954 GV->hasAvailableExternallyLinkage()) &&
955 !AliasedGlobals.
count(cast<GlobalObject>(GV))) {
961 Mod.Keep.push_back(GV);
964 NonPrevailingComdats.insert(GV->getComdat());
965 cast<GlobalObject>(GV)->setComdat(
nullptr);
969 if (
R.FinalDefinitionInLinkageUnit) {
970 GV->setDSOLocal(
true);
971 if (GV->hasDLLImportStorageClass())
973 DefaultStorageClass);
975 }
else if (
auto *AS =
976 dyn_cast_if_present<ModuleSymbolTable::AsmSymbol *>(Msym)) {
979 NonPrevailingAsmSymbols.
insert(AS->first);
987 if (
Sym.isCommon()) {
990 auto &CommonRes = RegularLTO.Commons[std::string(
Sym.getIRName())];
991 CommonRes.Size = std::max(CommonRes.Size,
Sym.getCommonSize());
992 if (
uint32_t SymAlignValue =
Sym.getCommonAlignment()) {
993 CommonRes.Alignment =
994 std::max(
Align(SymAlignValue), CommonRes.Alignment);
996 CommonRes.Prevailing |=
R.Prevailing;
1000 if (!
M.getComdatSymbolTable().empty())
1006 if (!
M.getModuleInlineAsm().empty()) {
1007 std::string NewIA =
".lto_discard";
1008 if (!NonPrevailingAsmSymbols.
empty()) {
1012 if (!NonPrevailingAsmSymbols.
count(Alias))
1015 NewIA +=
" " + llvm::join(NonPrevailingAsmSymbols,
", ");
1018 M.setModuleInlineAsm(NewIA +
M.getModuleInlineAsm());
1022 return std::make_pair(std::move(
Mod), Res);
1025Error LTO::linkRegularLTO(RegularLTOState::AddedModule
Mod,
1026 bool LivenessFromIndex) {
1027 std::vector<GlobalValue *>
Keep;
1029 if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->
getGUID())) {
1030 if (
Function *
F = dyn_cast<Function>(GV)) {
1031 if (DiagnosticOutputFile) {
1032 if (
Error Err =
F->materialize())
1037 <<
" not added to the combined module ");
1051 RegularLTO.CombinedModule->getNamedValue(GV->
getName());
1058 return RegularLTO.Mover->move(std::move(
Mod.M),
Keep,
nullptr,
1071 if (!
Sym.getIRName().empty()) {
1073 GlobalValue::getGlobalIdentifier(
Sym.getIRName(),
1083 return ThinLTO.PrevailingModuleForGUID[GUID] ==
1084 BM.getModuleIdentifier();
1093 if (!
Sym.getIRName().empty()) {
1095 GlobalValue::getGlobalIdentifier(
Sym.getIRName(),
1098 assert(ThinLTO.PrevailingModuleForGUID[GUID] ==
1105 if (
R.LinkerRedefined)
1106 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(
1113 if (
R.FinalDefinitionInLinkageUnit) {
1114 if (
auto S = ThinLTO.CombinedIndex.findSummaryInModule(
1116 S->setDSOLocal(
true);
1122 if (!ThinLTO.ModuleMap.insert({BM.getModuleIdentifier(), BM}).second)
1123 return make_error<StringError>(
1124 "Expected at most one ThinLTO module per bitcode file",
1128 if (!ThinLTO.ModulesToCompile)
1129 ThinLTO.ModulesToCompile = ModuleMapType();
1136 <<
" to compile\n");
1145 CalledGetMaxTasks =
true;
1146 auto ModuleCount = ThinLTO.ModulesToCompile ? ThinLTO.ModulesToCompile->size()
1147 : ThinLTO.ModuleMap.size();
1148 return RegularLTO.ParallelCodeGenParallelismLevel + ModuleCount;
1153Error LTO::checkPartiallySplit() {
1154 if (!ThinLTO.CombinedIndex.partiallySplitLTOUnits())
1157 const Module *Combined = RegularLTO.CombinedModule.get();
1163 Combined, Intrinsic::type_checked_load_relative);
1167 if ((TypeTestFunc && !TypeTestFunc->
use_empty()) ||
1168 (TypeCheckedLoadFunc && !TypeCheckedLoadFunc->
use_empty()) ||
1169 (TypeCheckedLoadRelativeFunc &&
1170 !TypeCheckedLoadRelativeFunc->
use_empty()))
1171 return make_error<StringError>(
1172 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1177 for (
auto &
P : ThinLTO.CombinedIndex) {
1178 for (
auto &S :
P.second.SummaryList) {
1179 auto *FS = dyn_cast<FunctionSummary>(S.get());
1182 if (!FS->type_test_assume_vcalls().empty() ||
1183 !FS->type_checked_load_vcalls().empty() ||
1184 !FS->type_test_assume_const_vcalls().empty() ||
1185 !FS->type_checked_load_const_vcalls().empty() ||
1186 !FS->type_tests().empty())
1187 return make_error<StringError>(
1188 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1199 for (
auto &Res : *GlobalResolutions) {
1202 if (Res.second.IRName.
empty())
1208 if (Res.second.VisibleOutsideSummary && Res.second.Prevailing)
1209 GUIDPreservedSymbols.
insert(GUID);
1211 if (Res.second.ExportDynamic)
1212 DynamicExportSymbols.insert(GUID);
1214 GUIDPrevailingResolutions[GUID] =
1219 auto It = GUIDPrevailingResolutions.
find(
G);
1220 if (It == GUIDPrevailingResolutions.
end())
1229 if (!StatsFileOrErr)
1230 return StatsFileOrErr.takeError();
1231 std::unique_ptr<ToolOutputFile> StatsFile = std::move(StatsFileOrErr.get());
1239 ThinLTO.CombinedIndex.setWithSupportsHotColdNew();
1241 Error Result = runRegularLTO(AddStream);
1245 Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols);
1255 if (Index.withSupportsHotColdNew())
1263 for (
auto &
F :
Mod) {
1264 for (
auto &BB :
F) {
1265 for (
auto &
I : BB) {
1266 auto *CI = dyn_cast<CallBase>(&
I);
1269 if (CI->hasFnAttr(
"memprof"))
1270 CI->removeFnAttr(
"memprof");
1277 CI->setMetadata(LLVMContext::MD_memprof,
nullptr);
1278 CI->setMetadata(LLVMContext::MD_callsite,
nullptr);
1292 return DiagFileOrErr.takeError();
1293 DiagnosticOutputFile = std::move(*DiagFileOrErr);
1297 for (
auto &M : RegularLTO.ModsWithSummaries)
1298 if (
Error Err = linkRegularLTO(std::move(M),
1306 if (
Error Err = checkPartiallySplit())
1311 const DataLayout &
DL = RegularLTO.CombinedModule->getDataLayout();
1312 for (
auto &
I : RegularLTO.Commons) {
1313 if (!
I.second.Prevailing)
1316 GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(
I.first);
1317 if (OldGV &&
DL.getTypeAllocSize(OldGV->
getValueType()) ==
I.second.Size) {
1325 auto *GV =
new GlobalVariable(*RegularLTO.CombinedModule, Ty,
false,
1328 GV->setAlignment(
I.second.Alignment);
1340 bool WholeProgramVisibilityEnabledInLTO =
1349 auto It = GlobalResolutions->find(
name);
1350 return (It == GlobalResolutions->end() ||
1351 It->second.VisibleOutsideSummary || !It->second.Prevailing);
1357 *RegularLTO.CombinedModule, WholeProgramVisibilityEnabledInLTO,
1359 IsVisibleToRegularObj);
1361 WholeProgramVisibilityEnabledInLTO);
1368 for (
const auto &R : *GlobalResolutions) {
1370 RegularLTO.CombinedModule->getNamedValue(
R.second.IRName);
1371 if (!
R.second.isPrevailingIRSymbol())
1373 if (
R.second.Partition != 0 &&
1374 R.second.Partition != GlobalResolution::External)
1409 backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,
1410 *RegularLTO.CombinedModule, ThinLTO.CombinedIndex))
1423 for (RTLIB::LibcallImpl Impl : LibcallImpls) {
1424 if (Impl != RTLIB::Unsupported)
1428 return LibcallSymbols;
1433 const std::string &NewModulePath)
const {
1434 return emitFiles(ImportList, ModulePath, NewModulePath,
1435 NewModulePath +
".thinlto.bc",
1441 const std::string &NewModulePath,
StringRef SummaryPath,
1442 std::optional<std::reference_wrapper<ImportsFilesContainer>> ImportsFiles)
1449 ImportList, ModuleToSummariesForIndex,
1450 DeclarationSummaries);
1457 &DeclarationSummaries);
1461 ModulePath, NewModulePath +
".imports", ModuleToSummariesForIndex);
1462 if (ImportsFilesError)
1463 return ImportsFilesError;
1469 ModulePath, ModuleToSummariesForIndex,
1470 [&](
StringRef M) { ImportsFiles->get().push_back(M.str()); });
1483 bool ShouldEmitIndexFiles;
1490 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
1493 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
1494 AddStream(
std::
move(AddStream)),
1495 ShouldEmitIndexFiles(ShouldEmitIndexFiles) {
1505class InProcessThinBackend :
public CGThinBackend {
1510 InProcessThinBackend(
1515 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles)
1516 : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
1517 AddStream, OnWrite, ShouldEmitIndexFiles,
1518 ShouldEmitImportsFiles, ThinLTOParallelism),
1521 virtual Error runThinLTOBackendThread(
1526 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1529 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1535 return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,
1536 ImportList, DefinedGlobals, &ModuleMap,
1542 if (ShouldEmitIndexFiles) {
1543 if (
auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1549 [](
uint32_t V) { return V == 0; }))
1552 return RunThinBackend(AddStream);
1556 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1557 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1561 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1563 return RunThinBackend(CacheAddStream);
1572 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1575 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
1577 ModuleToDefinedGVSummaries.
find(ModulePath)->second;
1578 BackendThreadPool.async(
1582 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
1589 Error E = runThinLTOBackendThread(
1590 AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList,
1591 ResolvedODR, DefinedGlobals, ModuleMap);
1593 std::unique_lock<std::mutex>
L(ErrMu);
1602 BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList),
1603 std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap));
1606 OnWrite(std::string(ModulePath));
1616class FirstRoundThinBackend :
public InProcessThinBackend {
1621 FirstRoundThinBackend(
1627 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
1628 ModuleToDefinedGVSummaries,
std::
move(CGAddStream),
1632 IRAddStream(
std::
move(IRAddStream)), IRCache(
std::
move(IRCache)) {}
1634 Error runThinLTOBackendThread(
1639 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1642 auto RunThinBackend = [&](
AddStreamFn CGAddStream,
1649 return thinBackend(Conf, Task, CGAddStream, **MOrErr, CombinedIndex,
1650 ImportList, DefinedGlobals, &ModuleMap,
1658 if (ShouldEmitIndexFiles) {
1659 if (
auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1664 "Both caches for CG and IR should have matching availability");
1667 [](
uint32_t V) { return V == 0; }))
1670 return RunThinBackend(CGAddStream, IRAddStream);
1674 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1675 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1677 CGCache(Task, CGKey, ModuleID);
1680 AddStreamFn &CacheCGAddStream = *CacheCGAddStreamOrErr;
1685 IRCache(Task, IRKey, ModuleID);
1688 AddStreamFn &CacheIRAddStream = *CacheIRAddStreamOrErr;
1694 if (CacheCGAddStream || CacheIRAddStream) {
1697 return RunThinBackend(CacheCGAddStream ? CacheCGAddStream : CGAddStream,
1698 CacheIRAddStream ? CacheIRAddStream : IRAddStream);
1710class SecondRoundThinBackend :
public InProcessThinBackend {
1711 std::unique_ptr<SmallVector<StringRef>> IRFiles;
1715 SecondRoundThinBackend(
1722 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
1723 ModuleToDefinedGVSummaries,
std::
move(AddStream),
1728 IRFiles(
std::
move(IRFiles)), CombinedCGDataHash(CombinedCGDataHash) {}
1730 virtual Error runThinLTOBackendThread(
1735 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1738 auto RunThinBackend = [&](
AddStreamFn AddStream) {
1740 std::unique_ptr<Module> LoadedModule =
1743 return thinBackend(Conf, Task, AddStream, *LoadedModule, CombinedIndex,
1744 ImportList, DefinedGlobals, &ModuleMap,
1751 [](
uint32_t V) { return V == 0; }))
1754 return RunThinBackend(AddStream);
1759 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1760 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1762 std::to_string(CombinedCGDataHash));
1766 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1768 if (CacheAddStream) {
1771 return RunThinBackend(CacheAddStream);
1781 bool ShouldEmitIndexFiles,
1782 bool ShouldEmitImportsFiles) {
1787 return std::make_unique<InProcessThinBackend>(
1788 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1789 AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
1790 ShouldEmitImportsFiles);
1816 return std::string(Path);
1820 if (!ParentPath.
empty()) {
1823 llvm::errs() <<
"warning: could not create directory '" << ParentPath
1824 <<
"': " << EC.message() <<
'\n';
1826 return std::string(NewPath);
1831 std::string OldPrefix, NewPrefix, NativeObjectPrefix;
1835 WriteIndexesThinBackend(
1839 std::string OldPrefix, std::string NewPrefix,
1840 std::string NativeObjectPrefix,
bool ShouldEmitImportsFiles,
1843 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
1844 OldPrefix(OldPrefix), NewPrefix(NewPrefix),
1845 NativeObjectPrefix(NativeObjectPrefix),
1846 LinkedObjectsFile(LinkedObjectsFile) {}
1852 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1860 if (LinkedObjectsFile) {
1861 std::string ObjectPrefix =
1862 NativeObjectPrefix.
empty() ? NewPrefix : NativeObjectPrefix;
1863 std::string LinkedObjectsFilePath =
1865 *LinkedObjectsFile << LinkedObjectsFilePath <<
'\n';
1868 BackendThreadPool.async(
1871 const std::string &OldPrefix,
const std::string &NewPrefix) {
1872 std::string NewModulePath =
1874 auto E = emitFiles(ImportList, ModulePath, NewModulePath);
1876 std::unique_lock<std::mutex>
L(ErrMu);
1884 ModulePath, ImportList, OldPrefix, NewPrefix);
1887 OnWrite(std::string(ModulePath));
1891 bool isSensitiveToInputOrder()
override {
1901 std::string NewPrefix, std::string NativeObjectPrefix,
1908 return std::make_unique<WriteIndexesThinBackend>(
1909 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1910 OldPrefix, NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,
1911 LinkedObjectsFile, OnWrite);
1919 ThinLTO.CombinedIndex.releaseTemporaryMemory();
1925 if (ThinLTO.ModuleMap.empty())
1928 if (ThinLTO.ModulesToCompile && ThinLTO.ModulesToCompile->empty()) {
1929 llvm::errs() <<
"warning: [ThinLTO] No module compiled\n";
1940 ThinLTO.ModuleMap.size());
1941 ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule(
1942 ModuleToDefinedGVSummaries);
1950 for (
auto &
Mod : ThinLTO.ModuleMap)
1951 if (!ModuleToDefinedGVSummaries.
count(
Mod.first))
1956 ThinLTO.ModuleMap.size());
1960 ThinLTO.CombinedIndex.dumpSCCs(
outs());
1962 std::set<GlobalValue::GUID> ExportedGUIDs;
1964 bool WholeProgramVisibilityEnabledInLTO =
1970 ThinLTO.CombinedIndex.setWithWholeProgramVisibility();
1976 if (WholeProgramVisibilityEnabledInLTO &&
1981 auto It = GlobalResolutions->
find(
name);
1982 return (It == GlobalResolutions->end() ||
1983 It->second.VisibleOutsideSummary || !It->second.Prevailing);
1987 VisibleToRegularObjSymbols,
1988 IsVisibleToRegularObj);
1994 ThinLTO.CombinedIndex, WholeProgramVisibilityEnabledInLTO,
1995 DynamicExportSymbols, VisibleToRegularObjSymbols);
2000 std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;
2002 LocalWPDTargetsMap);
2005 return ThinLTO.PrevailingModuleForGUID[
GUID] == S->modulePath();
2009 ContextDisambiguation.
run(ThinLTO.CombinedIndex, isPrevailing);
2016 for (
auto &Res : *GlobalResolutions) {
2019 if (Res.second.Partition != GlobalResolution::External ||
2020 !Res.second.isPrevailingIRSymbol())
2025 if (ThinLTO.CombinedIndex.isGUIDLive(GUID))
2026 ExportedGUIDs.insert(GUID);
2033 releaseGlobalResolutionsMemory();
2037 isPrevailing, ImportLists, ExportLists);
2041 auto &Defs = ThinLTO.CombinedIndex.cfiFunctionDefs();
2042 ExportedGUIDs.insert(Defs.guid_begin(), Defs.guid_end());
2043 auto &Decls = ThinLTO.CombinedIndex.cfiFunctionDecls();
2044 ExportedGUIDs.insert(Decls.guid_begin(), Decls.guid_end());
2047 const auto &ExportList = ExportLists.
find(ModuleIdentifier);
2048 return (ExportList != ExportLists.end() && ExportList->second.
count(VI)) ||
2049 ExportedGUIDs.count(
VI.getGUID());
2055 LocalWPDTargetsMap);
2060 auto recordNewLinkage = [&](
StringRef ModuleIdentifier,
2063 ResolvedODR[ModuleIdentifier][
GUID] = NewLinkage;
2066 recordNewLinkage, GUIDPreservedSymbols);
2075 TimeTraceScopeExit.release();
2078 ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;
2081 auto ProcessOneModule = [&](
int I) ->
Error {
2085 return BackendProcess->start(
2086 RegularLTO.ParallelCodeGenParallelismLevel +
I,
Mod.second,
2087 ImportLists[
Mod.first], ExportLists[
Mod.first],
2088 ResolvedODR[
Mod.first], ThinLTO.ModuleMap);
2091 BackendProcess->setup(ModuleMap.
size(),
2092 RegularLTO.ParallelCodeGenParallelismLevel,
2093 RegularLTO.CombinedModule->getTargetTriple());
2095 if (BackendProcess->getThreadCount() == 1 ||
2096 BackendProcess->isSensitiveToInputOrder()) {
2102 for (
int I = 0, E = ModuleMap.
size();
I != E; ++
I)
2103 if (
Error E = ProcessOneModule(
I))
2110 std::vector<BitcodeModule *> ModulesVec;
2111 ModulesVec.reserve(ModuleMap.
size());
2112 for (
auto &
Mod : ModuleMap)
2113 ModulesVec.push_back(&
Mod.second);
2115 if (
Error E = ProcessOneModule(
I))
2118 return BackendProcess->wait();
2122 std::unique_ptr<ThinBackendProc> BackendProc =
2123 ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
2125 return RunBackends(BackendProc.get());
2133 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Initializing ThinLTO two-codegen rounds\n");
2136 auto Parallelism = ThinLTO.Backend.getParallelism();
2144 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Running the first round of codegen\n");
2145 auto FirstRoundLTO = std::make_unique<FirstRoundThinBackend>(
2146 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2147 CG.AddStream, CG.Cache,
IR.AddStream,
IR.Cache);
2148 if (
Error E = RunBackends(FirstRoundLTO.get()))
2153 if (
Error E = CombinedHashOrErr.takeError())
2155 auto CombinedHash = *CombinedHashOrErr;
2156 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] CGData hash: " << CombinedHash <<
"\n");
2160 LLVM_DEBUG(
dbgs() <<
"[TwoRounds] Running the second round of codegen\n");
2161 auto SecondRoundLTO = std::make_unique<SecondRoundThinBackend>(
2162 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2163 AddStream, Cache,
IR.getResult(), CombinedHash);
2164 return RunBackends(SecondRoundLTO.get());
2174 if (!Filename.empty() && Count != -1)
2182 if (
Error E = ResultOrErr.takeError())
2183 return std::move(E);
2186 (*ResultOrErr)->keep();
2194 if (StatsFilename.
empty())
2205 return std::move(StatsFile);
2212 auto Seq = llvm::seq<int>(0, R.size());
2213 std::vector<int> ModulesOrdering(Seq.begin(), Seq.end());
2214 llvm::sort(ModulesOrdering, [&](
int LeftIndex,
int RightIndex) {
2215 auto LSize = R[LeftIndex]->getBuffer().
size();
2216 auto RSize = R[RightIndex]->getBuffer().
size();
2217 return LSize > RSize;
2219 return ModulesOrdering;
2229class OutOfProcessThinBackend :
public CGThinBackend {
2235 SString LinkerOutputFile;
2237 SString DistributorPath;
2240 SString RemoteCompiler;
2263 unsigned ThinLTOTaskOffset;
2269 OutOfProcessThinBackend(
2274 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
2278 : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
2279 AddStream, OnWrite, ShouldEmitIndexFiles,
2280 ShouldEmitImportsFiles, ThinLTOParallelism),
2281 LinkerOutputFile(LinkerOutputFile), DistributorPath(Distributor),
2282 DistributorArgs(DistributorArgs), RemoteCompiler(RemoteCompiler),
2283 RemoteCompilerArgs(RemoteCompilerArgs), SaveTemps(SaveTemps) {}
2285 virtual void setup(
unsigned ThinLTONumTasks,
unsigned ThinLTOTaskOffset,
2288 Jobs.
resize((
size_t)ThinLTONumTasks);
2289 this->ThinLTOTaskOffset = ThinLTOTaskOffset;
2297 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
2304 itostr(Task) +
"." + UID +
".native.o");
2306 Job &J = Jobs[Task - ThinLTOTaskOffset];
2310 Saver.save(ObjFilePath.str()),
2311 Saver.save(ObjFilePath.str() +
".thinlto.bc"),
2315 assert(ModuleToDefinedGVSummaries.
count(ModulePath));
2319 BackendThreadPool.async(
2321 if (
auto E = emitFiles(ImportList, J.ModuleID, J.ModuleID.str(),
2322 J.SummaryIndexPath, J.ImportsFiles)) {
2323 std::unique_lock<std::mutex> L(ErrMu);
2325 Err = joinErrors(std::move(*Err), std::move(E));
2330 std::ref(J), std::ref(ImportList));
2344 void buildCommonRemoteCompilerOptions() {
2346 auto &Ops = CodegenOptions;
2350 if (
C.Options.EmitAddrsig)
2351 Ops.push_back(
"-faddrsig");
2352 if (
C.Options.FunctionSections)
2353 Ops.push_back(
"-ffunction-sections");
2354 if (
C.Options.DataSections)
2355 Ops.push_back(
"-fdata-sections");
2360 Ops.push_back(
"-fpic");
2364 if (!
C.PGOWarnMismatch) {
2365 Ops.push_back(
"-mllvm");
2366 Ops.push_back(
"-no-pgo-warn-mismatch");
2371 if (!
C.SampleProfile.empty()) {
2373 Saver.save(
"-fprofile-sample-use=" +
Twine(
C.SampleProfile)));
2374 CommonInputs.
insert(
C.SampleProfile);
2378 Ops.push_back(
"-Wno-unused-command-line-argument");
2381 if (!RemoteCompilerArgs.
empty())
2382 for (
auto &a : RemoteCompilerArgs)
2388 bool emitDistributorJson(
StringRef DistributorJson) {
2398 JOS.attributeObject(
"common", [&]() {
2399 JOS.attribute(
"linker_output", LinkerOutputFile);
2401 JOS.attributeArray(
"args", [&]() {
2402 JOS.value(RemoteCompiler);
2406 JOS.value(Saver.save(
"--target=" +
Triple.
str()));
2408 for (
const auto &
A : CodegenOptions)
2412 JOS.attribute(
"inputs",
Array(CommonInputs));
2416 JOS.attributeArray(
"jobs", [&]() {
2417 for (
const auto &J : Jobs) {
2424 JOS.attributeArray(
"args", [&]() {
2425 JOS.value(J.ModuleID);
2429 Saver.save(
"-fthinlto-index=" +
Twine(J.SummaryIndexPath)));
2433 JOS.value(J.NativeObjectPath);
2441 JOS.attribute(
"inputs",
Array(Inputs));
2443 JOS.attribute(
"outputs",
Array(Outputs));
2454 if (EC && EC != std::make_error_code(std::errc::no_such_file_or_directory))
2455 errs() <<
"warning: could not remove the file '" << FileName
2456 <<
"': " <<
EC.message() <<
"\n";
2459 Error wait()
override {
2462 BackendThreadPool.wait();
2464 return std::move(*Err);
2468 for (
auto &Job : Jobs) {
2469 removeFile(Job.NativeObjectPath);
2470 if (!ShouldEmitIndexFiles)
2471 removeFile(Job.SummaryIndexPath);
2475 const StringRef BCError =
"DTLTO backend compilation: ";
2477 buildCommonRemoteCompilerOptions();
2482 if (!emitDistributorJson(JsonFile))
2483 return make_error<StringError>(
2484 BCError +
"failed to generate distributor JSON script: " + JsonFile,
2488 removeFile(JsonFile);
2493 Args.push_back(JsonFile);
2498 return make_error<StringError>(
2499 BCError +
"distributor execution failed" +
2500 (!ErrMsg.empty() ?
": " + ErrMsg +
Twine(
".") :
Twine(
".")),
2504 for (
auto &Job : Jobs) {
2507 auto ObjFileMbOrErr =
2510 if (std::error_code EC = ObjFileMbOrErr.getError())
2511 return make_error<StringError>(
2512 BCError +
"cannot open native object file: " +
2513 Job.NativeObjectPath +
": " +
EC.message(),
2515 auto StreamOrErr = AddStream(Job.Task, Job.ModuleID);
2516 if (
Error Err = StreamOrErr.takeError())
2518 auto &Stream = *StreamOrErr->get();
2519 *Stream.OS << ObjFileMbOrErr->get()->getMemBufferRef().getBuffer();
2520 if (
Error Err = Stream.commit())
2531 bool ShouldEmitIndexFiles,
bool ShouldEmitImportsFiles,
2539 return std::make_unique<OutOfProcessThinBackend>(
2540 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2541 AddStream, OnWrite, ShouldEmitIndexFiles, ShouldEmitImportsFiles,
2542 LinkerOutputFile, Distributor, DistributorArgs, RemoteCompiler,
2543 RemoteCompilerArgs, SaveTemps);
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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."))
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)
cl::opt< bool > CodeGenDataThinLTOTwoRounds
cl::opt< bool > ForceImportAll
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
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),...
size_t size() const
size - Get the array size.
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.
Allocate memory in an ever growing pool, as if by bump-pointer.
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.
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.
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)
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.
LLVM_ABI const GlobalObject * getAliaseeObject() const
static bool isExternalLinkage(LinkageTypes Linkage)
VisibilityTypes
An enumeration for the kinds of visibility of global values.
@ DefaultVisibility
The GV is visible.
static LinkageTypes getWeakLinkage(bool ODR)
bool isWeakForLinker() const
bool hasAppendingLinkage() const
bool hasAvailableExternallyLinkage() const
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.
ArrayRef< MDOperand > operands() const
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)
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()
const ModuleHash & getModuleHash(const StringRef ModPath) const
Get the module SHA1 hash recorded for the given module path.
const StringMap< ModuleHash > & modulePaths() const
Table of modules, containing module hash and id.
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.
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 discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...
A class that wrap the SHA1 algorithm.
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().
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef str() const
Explicit conversion to StringRef.
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...
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
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.
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().
An Array is a JSON array, which contains heterogeneous JSON values.
json::OStream allows writing well-formed JSON without materializing all structures as json::Value ahe...
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...
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 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.
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.
std::function< void(const std::string &)> IndexWriteCallback
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 Error backend(const Config &C, AddStreamFn AddStream, unsigned ParallelCodeGenParallelismLevel, Module &M, ModuleSummaryIndex &CombinedIndex)
Runs a regular LTO backend.
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 Error finalizeOptimizationRemarks(std::unique_ptr< ToolOutputFile > DiagOutputFile)
LLVM_ABI ThinBackend createOutOfProcessThinBackend(ThreadPoolStrategy Parallelism, IndexWriteCallback OnWrite, bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles, StringRef LinkerOutputFile, StringRef Distributor, ArrayRef< StringRef > DistributorArgs, StringRef RemoteCompiler, ArrayRef< StringRef > RemoteCompilerArgs, bool SaveTemps)
This ThinBackend generates the index shards and then runs the individual backend jobs via an external...
LLVM_ABI std::vector< int > generateModulesOrdering(ArrayRef< BitcodeModule * > R)
Produces a container ordering for optimal multi-threaded processing.
LLVM_ABI Expected< std::unique_ptr< ToolOutputFile > > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::optional< uint64_t > RemarksHotnessThreshold=0, int Count=-1)
Setup optimization remarks.
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_ABI void updateMemProfAttributes(Module &Mod, const ModuleSummaryIndex &Index)
Updates MemProf attributes (and metadata) based on whether the index has recorded that we are linking...
LLVM_ABI Expected< IRSymtabFile > readIRSymtab(MemoryBufferRef MBRef)
Reads a bitcode file, creating its irsymtab if necessary.
void write64le(void *P, uint64_t V)
void write32le(void *P, uint32_t V)
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 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.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
void generateParamAccessSummary(ModuleSummaryIndex &Index)
cl::opt< std::string > RemarksPasses("lto-pass-remarks-filter", cl::desc("Only record optimization remarks from passes whose " "names match the given regular expression"), cl::value_desc("regex"))
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.
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.
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.
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.
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.
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)
LLVM_ABI Expected< std::unique_ptr< ToolOutputFile > > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::optional< uint64_t > RemarksHotnessThreshold=0)
Setup optimization remarks that output to a file.
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...
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.
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.
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.
std::unordered_set< GlobalValueSummary * > GVSummaryPtrSet
A set of global value summary pointers.
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.
std::map< std::string, GVSummaryMapTy, std::less<> > ModuleToSummariesForIndexTy
Map of a module name to the GUIDs and summaries we will import from that module.
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.
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
cl::opt< std::optional< uint64_t >, false, remarks::HotnessThresholdParser > RemarksHotnessThreshold("lto-pass-remarks-hotness-threshold", cl::desc("Minimum profile count required for an " "optimization remark to be output." " Use 'auto' to apply the threshold from profile summary."), cl::value_desc("uint or 'auto'"), cl::init(0), cl::Hidden)
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.
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.
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 struct is a compact representation of a valid (non-zero power of two) alignment.
Used in the streaming interface as the general argument type.
This type represents a file cache system that manages caching of files.
A simple container for information about the supported runtime calls.
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl)
Get the libcall routine name for the specified libcall implementation.
ArrayRef< RTLIB::LibcallImpl > getLibcallImpls() const
Struct that holds a reference to a particular GUID in a global value summary.
bool isFormatSpecific() const
bool HasWholeProgramVisibility
Asserts whether we can assume whole program visibility during the LTO link.
bool ValidateAllVtablesHaveTypeInfos
We're validating that all native vtables have corresponding type infos.
bool KeepSymbolNameCopies
If true, the LTO instance creates copies of the symbol names for LTO::run.
std::optional< uint64_t > RemarksHotnessThreshold
The minimum hotness value a diagnostic needs in order to be included in optimization diagnostics.
std::string StatsFile
Statistics output file path.
ModuleHookFn PreOptModuleHook
This module hook is called after linking (regular LTO) or loading (ThinLTO) the module,...
CombinedIndexHookFn CombinedIndexHook
std::optional< CodeModel::Model > CodeModel
bool CodeGenOnly
Disable entirely the optimizer, including importing for ThinLTO.
std::vector< std::string > MAttrs
std::vector< std::string > MllvmArgs
std::vector< std::string > ThinLTOModulesToCompile
Specific thinLTO modules to compile.
CodeGenOptLevel CGOptLevel
std::unique_ptr< raw_ostream > ResolutionFile
If this field is set, LTO will write input file paths and symbol resolutions here in llvm-lto2 comman...
std::string DefaultTriple
Setting this field will replace unspecified target triples in input files with this triple.
bool AlwaysEmitRegularLTOObj
Always emit a Regular LTO object even when it is empty because no Regular LTO modules were linked.
std::string DwoDir
The directory to store .dwo files.
std::string RemarksFilename
Optimization remarks file path.
VisScheme VisibilityScheme
Allows non-imported definitions to get the potentially more constraining visibility from the prevaili...
std::string OverrideTriple
Setting this field will replace target triples in input files with this triple.
std::string ProfileRemapping
Name remapping file for profile data.
bool AllVtablesHaveTypeInfos
If all native vtables have corresponding type infos, allow usage of RTTI to block devirtualization on...
bool TimeTraceEnabled
Time trace enabled.
std::string RemarksPasses
Optimization remarks pass filter.
std::string OptPipeline
If this field is set, the set of passes run in the middle-end optimizer will be the one specified by ...
ModuleHookFn PostInternalizeModuleHook
This hook is called after internalizing the module.
unsigned TimeTraceGranularity
Time trace granularity.
bool RemarksWithHotness
Whether to emit optimization remarks with hotness informations.
std::optional< Reloc::Model > RelocModel
CodeGenFileType CGFileType
bool Freestanding
Flag to indicate that the optimizer should not assume builtins are present on the target.
std::string SampleProfile
Sample PGO profile path.
std::string RemarksFormat
The format used for serializing remarks (default: YAML).
A derived class of LLVMContext that initializes itself according to a given Config object.
The resolution for a symbol.
unsigned FinalDefinitionInLinkageUnit
The definition of this symbol is unpreemptable at runtime and is known to be in this linkage unit.
unsigned ExportDynamic
The symbol was exported dynamically, and therefore could be referenced by a shared library not visibl...
unsigned Prevailing
The linker has chosen this definition of the symbol.
unsigned LinkerRedefined
Linker redefined version of the symbol which appeared in -wrap or -defsym linker option.
unsigned VisibleToRegularObj
The definition of this symbol is visible outside of the LTO unit.
This type defines the behavior following the thin-link phase during ThinLTO.