LLVM: lib/LTO/LTO.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
27#include "llvm/Config/llvm-config.h"
52#include "llvm/Support/VCSRevision.h"
60
61#include
62#include
63
64using namespace llvm;
65using namespace lto;
66using namespace object;
67
68#define DEBUG_TYPE "lto"
69
71
74 cl::desc("Dump the SCCs in the ThinLTO index's callgraph"));
75
77
78namespace llvm {
79
82 cl::desc("Enable global value internalization in LTO"));
83
86 cl::desc("Keep copies of symbols in LTO indexing"));
87
88
89
91
92
94}
95
96
97
98
103 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
107
108
109
110
112
113
114 Hasher.update(LLVM_VERSION_STRING);
115#ifdef LLVM_REVISION
116 Hasher.update(LLVM_REVISION);
117#endif
118
119
120 auto AddString = [&](StringRef Str) {
123 };
124 auto AddUnsigned = [&](unsigned I) {
128 };
129 auto AddUint64 = [&](uint64_t I) {
133 };
134 auto AddUint8 = [&](const uint8_t I) {
136 };
137 AddString(Conf.CPU);
138
139
140
141
146 for (auto &A : Conf.MAttrs)
147 AddString(A);
150 else
151 AddUnsigned(-1);
154 else
155 AddUnsigned(-1);
156 for (const auto &S : Conf.MllvmArgs)
157 AddString(S);
158 AddUnsigned(static_cast<int>(Conf.CGOptLevel));
159 AddUnsigned(static_cast<int>(Conf.CGFileType));
166 AddString(Conf.DwoDir);
167
168
169 auto ModHash = Index.getModuleHash(ModuleID);
171
172
173
174 std::vector<uint64_t> ExportsGUID;
175 ExportsGUID.reserve(ExportList.size());
176 for (const auto &VI : ExportList)
177 ExportsGUID.push_back(VI.getGUID());
178
179
181 for (auto GUID : ExportsGUID)
183
184
185
186 auto Comp = [&](const std::pair<StringRef, GlobalValue::GUID> &L,
187 const std::pair<StringRef, GlobalValue::GUID> &R) {
188 return std::make_pair(Index.getModule(L.first)->second, L.second) <
189 std::make_pair(Index.getModule(R.first)->second, R.second);
190 };
192
193
195 for (const auto &[FromModule, GUID, Type] : SortedImportList)
196 ++ModuleToNumImports[FromModule];
197
198 std::optional LastModule;
199 for (const auto &[FromModule, GUID, Type] : SortedImportList) {
200 if (LastModule != FromModule) {
201
202
203
204 LastModule = FromModule;
205 auto ModHash = Index.getModule(FromModule)->second;
207 AddUint64(ModuleToNumImports[FromModule]);
208 }
209 AddUint64(GUID);
210 AddUint8(Type);
211 }
212
213
214 for (auto &Entry : ResolvedODR) {
219 }
220
221
222
223 std::setGlobalValue::GUID UsedCfiDefs;
224 std::setGlobalValue::GUID UsedCfiDecls;
225
226
227 std::setGlobalValue::GUID UsedTypeIds;
228
230 if (CfiFunctionDefs.contains(ValueGUID))
231 UsedCfiDefs.insert(ValueGUID);
232 if (CfiFunctionDecls.contains(ValueGUID))
233 UsedCfiDecls.insert(ValueGUID);
234 };
235
237 if (!GS) return;
238 AddUnsigned(GS->getVisibility());
239 AddUnsigned(GS->isLive());
240 AddUnsigned(GS->canAutoHide());
241 for (const ValueInfo &VI : GS->refs()) {
242 AddUnsigned(VI.isDSOLocal(Index.withDSOLocalPropagation()));
243 AddUsedCfiGlobal(VI.getGUID());
244 }
245 if (auto *GVS = dyn_cast(GS)) {
246 AddUnsigned(GVS->maybeReadOnly());
247 AddUnsigned(GVS->maybeWriteOnly());
248 }
249 if (auto *FS = dyn_cast(GS)) {
250 for (auto &TT : FS->type_tests())
251 UsedTypeIds.insert(TT);
252 for (auto &TT : FS->type_test_assume_vcalls())
253 UsedTypeIds.insert(TT.GUID);
254 for (auto &TT : FS->type_checked_load_vcalls())
255 UsedTypeIds.insert(TT.GUID);
256 for (auto &TT : FS->type_test_assume_const_vcalls())
257 UsedTypeIds.insert(TT.VFunc.GUID);
258 for (auto &TT : FS->type_checked_load_const_vcalls())
259 UsedTypeIds.insert(TT.VFunc.GUID);
260 for (auto &ET : FS->calls()) {
261 AddUnsigned(ET.first.isDSOLocal(Index.withDSOLocalPropagation()));
262 AddUsedCfiGlobal(ET.first.getGUID());
263 }
264 }
265 };
266
267
268
269 for (auto &GS : DefinedGlobals) {
273 AddUsedCfiGlobal(GS.first);
274 AddUsedThings(GS.second);
275 }
276
277
278
279 for (const auto &[FromModule, GUID, Type] : SortedImportList) {
281 AddUsedThings(S);
282
283
284 if (auto *AS = dyn_cast_or_null(S))
285 AddUsedThings(AS->getBaseObject());
286 }
287
289 AddString(TId);
290
291 AddUnsigned(S.TTRes.TheKind);
292 AddUnsigned(S.TTRes.SizeM1BitWidth);
293
294 AddUint64(S.TTRes.AlignLog2);
295 AddUint64(S.TTRes.SizeM1);
296 AddUint64(S.TTRes.BitMask);
297 AddUint64(S.TTRes.InlineBits);
298
299 AddUint64(S.WPDRes.size());
300 for (auto &WPD : S.WPDRes) {
301 AddUnsigned(WPD.first);
302 AddUnsigned(WPD.second.TheKind);
303 AddString(WPD.second.SingleImplName);
304
305 AddUint64(WPD.second.ResByArg.size());
306 for (auto &ByArg : WPD.second.ResByArg) {
307 AddUint64(ByArg.first.size());
308 for (uint64_t Arg : ByArg.first)
309 AddUint64(Arg);
310 AddUnsigned(ByArg.second.TheKind);
311 AddUint64(ByArg.second.Info);
312 AddUnsigned(ByArg.second.Byte);
313 AddUnsigned(ByArg.second.Bit);
314 }
315 }
316 };
317
318
320 auto TidIter = Index.typeIds().equal_range(TId);
321 for (const auto &I : make_range(TidIter))
322 AddTypeIdSummary(I.second.first, I.second.second);
323 }
324
325 AddUnsigned(UsedCfiDefs.size());
326 for (auto &V : UsedCfiDefs)
327 AddUint64(V);
328
329 AddUnsigned(UsedCfiDecls.size());
330 for (auto &V : UsedCfiDecls)
331 AddUint64(V);
332
335 if (FileOrErr) {
336 Hasher.update(FileOrErr.get()->getBuffer());
337
340 if (FileOrErr)
341 Hasher.update(FileOrErr.get()->getBuffer());
342 }
343 }
344 }
345
346 return toHex(Hasher.result());
347}
348
352
353 auto AddString = [&](StringRef Str) {
356 };
357 AddString(Key);
358 AddString(ExtraID);
359
360 return toHex(Hasher.result());
361}
362
367 isPrevailing,
369 recordNewLinkage,
372 C.VisibilityScheme == Config::ELF ? VI.getELFVisibility()
374 for (auto &S : VI.getSummaryList()) {
376
377
380 continue;
381
382
383
384
385
386
387
388
389 if (isPrevailing(VI.getGUID(), S.get())) {
393
394
395
396
397
398
399
400
401
402 S->setCanAutoHide(VI.canAutoHide() &&
403 !GUIDPreservedSymbols.count(VI.getGUID()));
404 }
406 Visibility = S->getVisibility();
407 }
408
409 else if (!isa(S.get()) &&
410 !GlobalInvolvedWithAlias.count(S.get()))
412
413
414
415
417 S->setVisibility(Visibility);
418
419 if (S->linkage() != OriginalLinkage)
420 recordNewLinkage(S->modulePath(), VI.getGUID(), S->linkage());
421 }
422
424 for (auto &S : VI.getSummaryList()) {
428 continue;
429 S->setVisibility(Visibility);
430 }
431 }
432}
433
434
435
436
437
438
439
443 isPrevailing,
445 recordNewLinkage,
447
448
449
451 for (auto &I : Index)
452 for (auto &S : I.second.SummaryList)
453 if (auto AS = dyn_cast(S.get()))
454 GlobalInvolvedWithAlias.insert(&AS->getAliasee());
455
456 for (auto &I : Index)
458 GlobalInvolvedWithAlias, isPrevailing,
459 recordNewLinkage, GUIDPreservedSymbols);
460}
461
465 isPrevailing) {
466 auto ExternallyVisibleCopies =
468 [](const std::unique_ptr &Summary) {
469 return !GlobalValue::isLocalLinkage(Summary->linkage());
470 });
471
472 for (auto &S : VI.getSummaryList()) {
473
474
475 if (isExported(S->modulePath(), VI)) {
478 continue;
479 }
480
481
483 continue;
484
485
488 continue;
489 }
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
532 continue;
533
534 if (isPrevailing(VI.getGUID(), S.get()) && ExternallyVisibleCopies == 1)
536 }
537}
538
539
540
545 isPrevailing) {
546 for (auto &I : Index)
548 isPrevailing);
549}
550
551
553
555 std::unique_ptr File(new InputFile);
556
558 if (!FOrErr)
560
561 File->TargetTriple = FOrErr->TheReader.getTargetTriple();
562 File->SourceFileName = FOrErr->TheReader.getSourceFileName();
563 File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts();
564 File->DependentLibraries = FOrErr->TheReader.getDependentLibraries();
565 File->ComdatTable = FOrErr->TheReader.getComdatTable();
566
567 for (unsigned I = 0; I != FOrErr->Mods.size(); ++I) {
568 size_t Begin = File->Symbols.size();
570 FOrErr->TheReader.module_symbols(I))
571
572
574 File->Symbols.push_back(Sym);
575 File->ModuleSymIndices.push_back({Begin, File->Symbols.size()});
576 }
577
578 File->Mods = FOrErr->Mods;
579 File->Strtab = std::move(FOrErr->Strtab);
580 return std::move(File);
581}
582
584 return Mods[0].getModuleIdentifier();
585}
586
588 assert(Mods.size() == 1 && "Expect only one bitcode module");
589 return Mods[0];
590}
591
592LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel,
594 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
595 Ctx(Conf), CombinedModule(std::make_unique<Module>("ld-temp.o", Ctx)),
596 Mover(std::make_unique<IRMover>(*CombinedModule)) {
598}
599
600LTO::ThinLTOState::ThinLTOState(ThinBackend BackendParam)
601 : Backend(std::move(BackendParam)), CombinedIndex( false) {
602 if (!Backend.isValid())
603 Backend =
605}
606
608 unsigned ParallelCodeGenParallelismLevel, LTOKind LTOMode)
610 RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),
611 ThinLTO(std::move(Backend)),
612 GlobalResolutions(
614 LTOMode(LTOMode) {
616 Alloc = std::make_unique();
617 GlobalResolutionSymbolSaver = std::make_uniquellvm::StringSaver(*Alloc);
618 }
619}
620
621
623
624
625
628 unsigned Partition, bool InSummary) {
629 auto *ResI = Res.begin();
630 auto *ResE = Res.end();
631 (void)ResE;
632 const Triple TT(RegularLTO.CombinedModule->getTargetTriple());
634 assert(ResI != ResE);
636
638
639 if (GlobalResolutionSymbolSaver && !GlobalResolutions->contains(SymbolName))
640 SymbolName = GlobalResolutionSymbolSaver->save(SymbolName);
641
642 auto &GlobalRes = (*GlobalResolutions)[SymbolName];
643 GlobalRes.UnnamedAddr &= Sym.isUnnamedAddr();
645 assert(!GlobalRes.Prevailing &&
646 "Multiple prevailing defs are not allowed");
647 GlobalRes.Prevailing = true;
648 GlobalRes.IRName = std::string(Sym.getIRName());
649 } else if (!GlobalRes.Prevailing && GlobalRes.IRName.empty()) {
650
651
652
653
654
655
656 GlobalRes.IRName = std::string(Sym.getIRName());
657 }
658
659
660
661
662
663
664
665
666
667
668
669
670 if (GlobalRes.IRName != Sym.getIRName()) {
671 GlobalRes.Partition = GlobalResolution::External;
672 GlobalRes.VisibleOutsideSummary = true;
673 }
674
675
676
677
678
680 (GlobalRes.Partition != GlobalResolution::Unknown &&
681 GlobalRes.Partition != Partition)) {
682 GlobalRes.Partition = GlobalResolution::External;
683 } else
684
685 GlobalRes.Partition = Partition;
686
687
688
689 GlobalRes.VisibleOutsideSummary |=
691
693 }
694}
695
696void LTO::releaseGlobalResolutionsMemory() {
697
698 GlobalResolutions.reset();
699
700 GlobalResolutionSymbolSaver.reset();
701 Alloc.reset();
702}
703
707 OS << Path << '\n';
708 auto ResI = Res.begin();
712
713 OS << "-r=" << Path << ',' << Sym.getName() << ',';
715 OS << 'p';
717 OS << 'l';
719 OS << 'x';
721 OS << 'r';
722 OS << '\n';
723 }
726}
727
730 assert(!CalledGetMaxTasks);
731
734
735 if (RegularLTO.CombinedModule->getTargetTriple().empty()) {
736 RegularLTO.CombinedModule->setTargetTriple(Input->getTargetTriple());
739 }
740
742 for (unsigned I = 0; I != Input->Mods.size(); ++I)
743 if (Error Err = addModule(*Input, I, ResI, Res.end()))
744 return Err;
745
748}
749
754 if (!LTOInfo)
756
757 if (EnableSplitLTOUnit) {
758
759
760
761 if (*EnableSplitLTOUnit != LTOInfo->EnableSplitLTOUnit)
762 ThinLTO.CombinedIndex.setPartiallySplitLTOUnits();
763 } else
764 EnableSplitLTOUnit = LTOInfo->EnableSplitLTOUnit;
765
767
769 !LTOInfo->UnifiedLTO)
770 return make_error(
771 "unified LTO compilation must use "
772 "compatible bitcode modules (use -funified-lto)",
774
775 if (LTOInfo->UnifiedLTO && LTOMode == LTOK_Default)
777
779
780 auto ModSyms = Input.module_symbols(ModI);
781 addModuleToGlobalRes(ModSyms, {ResI, ResE},
782 IsThinLTO ? ThinLTO.ModuleMap.size() + 1 : 0,
783 LTOInfo->HasSummary);
784
785 if (IsThinLTO)
786 return addThinLTO(BM, ModSyms, ResI, ResE);
787
788 RegularLTO.EmptyCombinedModule = false;
790 addRegularLTO(BM, ModSyms, ResI, ResE);
791 if (!ModOrErr)
793
794 if (!LTOInfo->HasSummary)
795 return linkRegularLTO(std::move(*ModOrErr), false);
796
797
798
800 return Err;
801 RegularLTO.ModsWithSummaries.push_back(std::move(*ModOrErr));
803}
804
805
806
807
808
809
810
811
812
813
814
815static void
817 std::set<const Comdat *> &NonPrevailingComdats) {
819 if ()
820 return;
821
822 if (!NonPrevailingComdats.count(C))
823 return;
824
825
826
827
828
830
831 if (auto GO = dyn_cast(&GV))
832 GO->setComdat(nullptr);
833}
834
835
836
837
842 RegularLTOState::AddedModule Mod;
844 BM.getLazyModule(RegularLTO.Ctx, true,
845 false);
846 if (!MOrErr)
849 Mod.M = std::move(*MOrErr);
850
851 if (Error Err = M.materializeMetadata())
852 return std::move(Err);
853
854
855
856
857
859 if (NamedMDNode *CfiFunctionsMD = M.getNamedMetadata("cfi.functions"))
860 M.eraseNamedMetadata(CfiFunctionsMD);
861
863
866
868 if (GV.hasAppendingLinkage())
869 Mod.Keep.push_back(&GV);
870
872 for (auto &GA : M.aliases())
874 AliasedGlobals.insert(GO);
875
876
877
878
879
880
881
882
883 auto MsymI = SymTab.symbols().begin(), MsymE = SymTab.symbols().end();
884 auto Skip = [&]() {
885 while (MsymI != MsymE) {
889 return;
890 ++MsymI;
891 }
892 };
894
895 std::set<const Comdat *> NonPrevailingComdats;
898 assert(ResI != ResE);
900
901 assert(MsymI != MsymE);
904
905 if (GlobalValue *GV = dyn_cast_if_present<GlobalValue *>(Msym)) {
907 if (Sym.isUndefined())
908 continue;
909 Mod.Keep.push_back(GV);
910
911
912
915
920 } else if (isa(GV) &&
921 (GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||
922 GV->hasAvailableExternallyLinkage()) &&
923 !AliasedGlobals.count(cast(GV))) {
924
925
926
927
928
929 Mod.Keep.push_back(GV);
931 if (GV->hasComdat())
932 NonPrevailingComdats.insert(GV->getComdat());
933 cast(GV)->setComdat(nullptr);
934 }
935
936
938 GV->setDSOLocal(true);
939 if (GV->hasDLLImportStorageClass())
941 DefaultStorageClass);
942 }
943 } else if (auto *AS =
944 dyn_cast_if_present<ModuleSymbolTable::AsmSymbol *>(Msym)) {
945
947 NonPrevailingAsmSymbols.insert(AS->first);
948 } else {
950 }
951
952
953
954
955 if (Sym.isCommon()) {
956
957
958 auto &CommonRes = RegularLTO.Commons[std::string(Sym.getIRName())];
959 CommonRes.Size = std::max(CommonRes.Size, Sym.getCommonSize());
960 if (uint32_t SymAlignValue = Sym.getCommonAlignment()) {
961 CommonRes.Alignment =
962 std::max(Align(SymAlignValue), CommonRes.Alignment);
963 }
964 CommonRes.Prevailing |= Res.Prevailing;
965 }
966 }
967
968 if (.getComdatSymbolTable().empty())
971
972
973
974 if (.getModuleInlineAsm().empty()) {
975 std::string NewIA = ".lto_discard";
976 if (!NonPrevailingAsmSymbols.empty()) {
977
980 if (!NonPrevailingAsmSymbols.count(Alias))
981 NonPrevailingAsmSymbols.erase(Name);
982 });
983 NewIA += " " + llvm::join(NonPrevailingAsmSymbols, ", ");
984 }
985 NewIA += "\n";
986 M.setModuleInlineAsm(NewIA + M.getModuleInlineAsm());
987 }
988
989 assert(MsymI == MsymE);
990 return std::move(Mod);
991}
992
993Error LTO::linkRegularLTO(RegularLTOState::AddedModule Mod,
994 bool LivenessFromIndex) {
995 std::vector<GlobalValue *> Keep;
997 if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->getGUID())) {
998 if (Function *F = dyn_cast(GV)) {
999 if (DiagnosticOutputFile) {
1000 if (Error Err = F->materialize())
1001 return Err;
1005 << " not added to the combined module ");
1006 }
1007 }
1008 continue;
1009 }
1010
1012 Keep.push_back(GV);
1013 continue;
1014 }
1015
1016
1017
1019 RegularLTO.CombinedModule->getNamedValue(GV->getName());
1021 continue;
1022
1023 Keep.push_back(GV);
1024 }
1025
1026 return RegularLTO.Mover->move(std::move(Mod.M), Keep, nullptr,
1027 false);
1028}
1029
1030
1036 assert(ResITmp != ResE);
1038
1039 if (.getIRName().empty()) {
1044 }
1045 }
1046
1050 return ThinLTO.PrevailingModuleForGUID[GUID] ==
1051 BM.getModuleIdentifier();
1052 }))
1053 return Err;
1055
1057 assert(ResI != ResE);
1059
1060 if (.getIRName().empty()) {
1064 assert(ThinLTO.PrevailingModuleForGUID[GUID] ==
1066
1067
1068
1069
1070
1072 if (auto S = ThinLTO.CombinedIndex.findSummaryInModule(
1075 }
1076
1077
1078
1080 if (auto S = ThinLTO.CombinedIndex.findSummaryInModule(
1082 S->setDSOLocal(true);
1083 }
1084 }
1085 }
1086 }
1087
1088 if (!ThinLTO.ModuleMap.insert({BM.getModuleIdentifier(), BM}).second)
1089 return make_error(
1090 "Expected at most one ThinLTO module per bitcode file",
1092
1094 if (!ThinLTO.ModulesToCompile)
1095 ThinLTO.ModulesToCompile = ModuleMapType();
1096
1097
1102 << " to compile\n");
1103 }
1104 }
1105 }
1106
1108}
1109
1111 CalledGetMaxTasks = true;
1112 auto ModuleCount = ThinLTO.ModulesToCompile ? ThinLTO.ModulesToCompile->size()
1113 : ThinLTO.ModuleMap.size();
1114 return RegularLTO.ParallelCodeGenParallelismLevel + ModuleCount;
1115}
1116
1117
1118
1119Error LTO::checkPartiallySplit() {
1120 if (!ThinLTO.CombinedIndex.partiallySplitLTOUnits())
1122
1123 const Module *Combined = RegularLTO.CombinedModule.get();
1126 Function *TypeCheckedLoadFunc =
1129 Combined, Intrinsic::type_checked_load_relative);
1130
1131
1132
1133 if ((TypeTestFunc && !TypeTestFunc->use_empty()) ||
1134 (TypeCheckedLoadFunc && !TypeCheckedLoadFunc->use_empty()) ||
1135 (TypeCheckedLoadRelativeFunc &&
1136 !TypeCheckedLoadRelativeFunc->use_empty()))
1137 return make_error(
1138 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1140
1141
1142
1143 for (auto &P : ThinLTO.CombinedIndex) {
1144 for (auto &S : P.second.SummaryList) {
1145 auto *FS = dyn_cast(S.get());
1146 if (!FS)
1147 continue;
1148 if (!FS->type_test_assume_vcalls().empty() ||
1149 !FS->type_checked_load_vcalls().empty() ||
1150 !FS->type_test_assume_const_vcalls().empty() ||
1151 !FS->type_checked_load_const_vcalls().empty() ||
1152 !FS->type_tests().empty())
1153 return make_error(
1154 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1156 }
1157 }
1159}
1160
1162
1165 for (auto &Res : *GlobalResolutions) {
1166
1167
1168 if (Res.second.IRName.empty())
1169 continue;
1170
1173
1174 if (Res.second.VisibleOutsideSummary && Res.second.Prevailing)
1175 GUIDPreservedSymbols.insert(GUID);
1176
1178 DynamicExportSymbols.insert(GUID);
1179
1180 GUIDPrevailingResolutions[GUID] =
1182 }
1183
1185 auto It = GUIDPrevailingResolutions.find(G);
1186 if (It == GUIDPrevailingResolutions.end())
1188 return It->second;
1189 };
1191 isPrevailing, Conf.OptLevel > 0);
1192
1193
1195 if (!StatsFileOrErr)
1196 return StatsFileOrErr.takeError();
1197 std::unique_ptr StatsFile = std::move(StatsFileOrErr.get());
1198
1199
1200
1201
1202
1203
1205 ThinLTO.CombinedIndex.setWithSupportsHotColdNew();
1206
1207 Error Result = runRegularLTO(AddStream);
1208 if (!Result)
1209
1210
1211 Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols);
1212
1213 if (StatsFile)
1215
1216 return Result;
1217}
1218
1221 if (Index.withSupportsHotColdNew())
1222 return;
1223
1224
1225
1226
1227
1228
1230 for (auto &BB : F) {
1231 for (auto &I : BB) {
1232 auto *CI = dyn_cast(&I);
1233 if (!CI)
1234 continue;
1235 if (CI->hasFnAttr("memprof"))
1236 CI->removeFnAttr("memprof");
1237
1238
1239
1240
1241
1242
1243 CI->setMetadata(LLVMContext::MD_memprof, nullptr);
1244 CI->setMetadata(LLVMContext::MD_callsite, nullptr);
1245 }
1246 }
1247 }
1248}
1249
1251
1253 RegularLTO.CombinedModule->getContext(), Conf.RemarksFilename,
1257 if (!DiagFileOrErr)
1258 return DiagFileOrErr.takeError();
1259 DiagnosticOutputFile = std::move(*DiagFileOrErr);
1260
1261
1262
1263 for (auto &M : RegularLTO.ModsWithSummaries)
1264 if (Error Err = linkRegularLTO(std::move(M),
1265 true))
1266 return Err;
1267
1268
1269
1270
1271
1272 if (Error Err = checkPartiallySplit())
1273 return Err;
1274
1275
1276
1277 const DataLayout &DL = RegularLTO.CombinedModule->getDataLayout();
1278 for (auto &I : RegularLTO.Commons) {
1279 if (.second.Prevailing)
1280
1281 continue;
1282 GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(I.first);
1283 if (OldGV && DL.getTypeAllocSize(OldGV->getValueType()) == I.second.Size) {
1284
1285
1287 continue;
1288 }
1291 auto *GV = new GlobalVariable(*RegularLTO.CombinedModule, Ty, false,
1294 GV->setAlignment(I.second.Alignment);
1295 if (OldGV) {
1299 } else {
1301 }
1302 }
1303
1305
1306 bool WholeProgramVisibilityEnabledInLTO =
1308
1309
1311
1312
1313
1314 auto IsVisibleToRegularObj = [&](StringRef name) {
1315 auto It = GlobalResolutions->find(name);
1316 return (It == GlobalResolutions->end() || It->second.VisibleOutsideSummary);
1317 };
1318
1319
1320
1322 *RegularLTO.CombinedModule, WholeProgramVisibilityEnabledInLTO,
1324 IsVisibleToRegularObj);
1326 WholeProgramVisibilityEnabledInLTO);
1327
1331
1333 for (const auto &R : *GlobalResolutions) {
1335 RegularLTO.CombinedModule->getNamedValue(R.second.IRName);
1336 if (.second.isPrevailingIRSymbol())
1337 continue;
1338 if (R.second.Partition != 0 &&
1339 R.second.Partition != GlobalResolution::External)
1340 continue;
1341
1342
1343
1345 continue;
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1359 continue;
1360
1365 }
1366
1370 }
1371
1374 backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,
1375 *RegularLTO.CombinedModule, ThinLTO.CombinedIndex))
1376 return Err;
1377 }
1378
1380}
1381
1386 [](const char *Name) { return Name; });
1387 return LibcallSymbols;
1388}
1389
1392 const std::string &NewModulePath) const {
1395
1396 std::error_code EC;
1398 ImportList, ModuleToSummariesForIndex,
1399 DeclarationSummaries);
1400
1403 if (EC)
1404 return createFileError("cannot open " + NewModulePath + ".thinlto.bc", EC);
1405
1407 &DeclarationSummaries);
1408
1411 ModulePath, NewModulePath + ".imports", ModuleToSummariesForIndex);
1412 if (ImportFilesError)
1413 return ImportFilesError;
1414 }
1416}
1417
1418namespace {
1420protected:
1425
1426 bool ShouldEmitIndexFiles;
1427
1428public:
1429 InProcessThinBackend(
1434 bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles)
1435 : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
1436 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
1437 AddStream(std::move(AddStream)), Cache(std::move(Cache)),
1438 ShouldEmitIndexFiles(ShouldEmitIndexFiles) {
1440 CfiFunctionDefs.insert(
1443 CfiFunctionDecls.insert(
1445 }
1446
1447 virtual Error runThinLTOBackendThread(
1452 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1455 auto RunThinBackend = [&](AddStreamFn AddStream) {
1458 if (!MOrErr)
1460
1461 return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,
1462 ImportList, DefinedGlobals, &ModuleMap,
1464 };
1465
1467
1468 if (ShouldEmitIndexFiles) {
1469 if (auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1470 return E;
1471 }
1472
1475 [](uint32_t V) { return V == 0; }))
1476
1477
1478 return RunThinBackend(AddStream);
1479
1480
1482 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1483 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1486 return Err;
1487 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1488 if (CacheAddStream)
1489 return RunThinBackend(CacheAddStream);
1490
1492 }
1493
1498 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1501 assert(ModuleToDefinedGVSummaries.count(ModulePath));
1503 ModuleToDefinedGVSummaries.find(ModulePath)->second;
1504 BackendThreadPool.async(
1508 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
1509 &ResolvedODR,
1514 "thin backend");
1515 Error E = runThinLTOBackendThread(
1516 AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList,
1517 ResolvedODR, DefinedGlobals, ModuleMap);
1518 if (E) {
1519 std::unique_lockstd::mutex L(ErrMu);
1520 if (Err)
1521 Err = joinErrors(std::move(*Err), std::move(E));
1522 else
1523 Err = std::move(E);
1524 }
1527 },
1528 BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList),
1529 std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap));
1530
1531 if (OnWrite)
1532 OnWrite(std::string(ModulePath));
1534 }
1535};
1536
1537
1538
1539
1540
1541
1542class FirstRoundThinBackend : public InProcessThinBackend {
1545
1546public:
1547 FirstRoundThinBackend(
1553 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
1554 ModuleToDefinedGVSummaries, std::move(CGAddStream),
1555 std::move(CGCache), nullptr,
1556 false,
1557 false),
1558 IRAddStream(std::move(IRAddStream)), IRCache(std::move(IRCache)) {}
1559
1560 Error runThinLTOBackendThread(
1565 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1568 auto RunThinBackend = [&](AddStreamFn CGAddStream,
1572 if (!MOrErr)
1574
1575 return thinBackend(Conf, Task, CGAddStream, **MOrErr, CombinedIndex,
1576 ImportList, DefinedGlobals, &ModuleMap,
1578 };
1579
1581
1582
1583
1584 if (ShouldEmitIndexFiles) {
1585 if (auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1586 return E;
1587 }
1588
1590 "Both caches for CG and IR should have matching availability");
1593 [](uint32_t V) { return V == 0; }))
1594
1595
1596 return RunThinBackend(CGAddStream, IRAddStream);
1597
1598
1600 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1601 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1603 CGCache(Task, CGKey, ModuleID);
1605 return Err;
1606 AddStreamFn &CacheCGAddStream = *CacheCGAddStreamOrErr;
1607
1608
1611 IRCache(Task, IRKey, ModuleID);
1613 return Err;
1614 AddStreamFn &CacheIRAddStream = *CacheIRAddStreamOrErr;
1615
1616
1617
1618
1619
1620 if (CacheCGAddStream || CacheIRAddStream) {
1623 return RunThinBackend(CacheCGAddStream ? CacheCGAddStream : CGAddStream,
1624 CacheIRAddStream ? CacheIRAddStream : IRAddStream);
1625 }
1626
1628 }
1629};
1630
1631
1632
1633
1634
1635
1636class SecondRoundThinBackend : public InProcessThinBackend {
1637 std::unique_ptr<SmallVector> IRFiles;
1639
1640public:
1641 SecondRoundThinBackend(
1648 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
1649 ModuleToDefinedGVSummaries, std::move(AddStream),
1651 nullptr,
1652 false,
1653 false),
1654 IRFiles(std::move(IRFiles)), CombinedCGDataHash(CombinedCGDataHash) {}
1655
1656 virtual Error runThinLTOBackendThread(
1661 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1664 auto RunThinBackend = [&](AddStreamFn AddStream) {
1666 std::unique_ptr LoadedModule =
1668
1669 return thinBackend(Conf, Task, AddStream, *LoadedModule, CombinedIndex,
1670 ImportList, DefinedGlobals, &ModuleMap,
1671 true);
1672 };
1673
1677 [](uint32_t V) { return V == 0; }))
1678
1679
1680 return RunThinBackend(AddStream);
1681
1682
1683
1685 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1686 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1688 std::to_string(CombinedCGDataHash));
1691 return Err;
1692 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1693
1694 if (CacheAddStream) {
1695 LLVM_DEBUG(dbgs() << "[SecondRound] Cache Miss for "
1697 return RunThinBackend(CacheAddStream);
1698 }
1699
1701 }
1702};
1703}
1704
1707 bool ShouldEmitIndexFiles,
1708 bool ShouldEmitImportsFiles) {
1709 auto Func =
1713 return std::make_unique(
1714 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1715 AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
1716 ShouldEmitImportsFiles);
1717 };
1719}
1720
1723 return "";
1725 return "core2";
1727 return "yonah";
1729 return "apple-a12";
1732 return "cyclone";
1733 return "";
1734}
1735
1736
1737
1738
1741 if (OldPrefix.empty() && NewPrefix.empty())
1742 return std::string(Path);
1746 if (!ParentPath.empty()) {
1747
1749 llvm::errs() << "warning: could not create directory '" << ParentPath
1750 << "': " << EC.message() << '\n';
1751 }
1752 return std::string(NewPath);
1753}
1754
1755namespace {
1757 std::string OldPrefix, NewPrefix, NativeObjectPrefix;
1759
1760public:
1761 WriteIndexesThinBackend(
1765 std::string OldPrefix, std::string NewPrefix,
1766 std::string NativeObjectPrefix, bool ShouldEmitImportsFiles,
1768 : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
1769 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
1770 OldPrefix(OldPrefix), NewPrefix(NewPrefix),
1771 NativeObjectPrefix(NativeObjectPrefix),
1772 LinkedObjectsFile(LinkedObjectsFile) {}
1773
1778 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1781
1782
1783
1784
1785
1786 if (LinkedObjectsFile) {
1787 std::string ObjectPrefix =
1788 NativeObjectPrefix.empty() ? NewPrefix : NativeObjectPrefix;
1789 std::string LinkedObjectsFilePath =
1791 *LinkedObjectsFile << LinkedObjectsFilePath << '\n';
1792 }
1793
1794 BackendThreadPool.async(
1795 [this](const StringRef ModulePath,
1797 const std::string &OldPrefix, const std::string &NewPrefix) {
1798 std::string NewModulePath =
1800 auto E = emitFiles(ImportList, ModulePath, NewModulePath);
1801 if (E) {
1802 std::unique_lockstd::mutex L(ErrMu);
1803 if (Err)
1804 Err = joinErrors(std::move(*Err), std::move(E));
1805 else
1806 Err = std::move(E);
1807 return;
1808 }
1809 },
1810 ModulePath, ImportList, OldPrefix, NewPrefix);
1811
1812 if (OnWrite)
1813 OnWrite(std::string(ModulePath));
1815 }
1816
1817 bool isSensitiveToInputOrder() override {
1818
1819
1820 return true;
1821 }
1822};
1823}
1824
1827 std::string NewPrefix, std::string NativeObjectPrefix,
1828 bool ShouldEmitImportsFiles, raw_fd_ostream *LinkedObjectsFile,
1830 auto Func =
1834 return std::make_unique(
1835 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1836 OldPrefix, NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,
1837 LinkedObjectsFile, OnWrite);
1838 };
1840}
1841
1845 ThinLTO.CombinedIndex.releaseTemporaryMemory();
1850 });
1851 if (ThinLTO.ModuleMap.empty())
1853
1854 if (ThinLTO.ModulesToCompile && ThinLTO.ModulesToCompile->empty()) {
1855 llvm::errs() << "warning: [ThinLTO] No module compiled\n";
1857 }
1858
1860 !Conf.CombinedIndexHook(ThinLTO.CombinedIndex, GUIDPreservedSymbols))
1862
1863
1864
1866 ThinLTO.ModuleMap.size());
1867 ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule(
1868 ModuleToDefinedGVSummaries);
1869
1870
1871
1872
1873
1874
1875
1876 for (auto &Mod : ThinLTO.ModuleMap)
1877 if (!ModuleToDefinedGVSummaries.count(Mod.first))
1879
1882 ThinLTO.ModuleMap.size());
1884
1886 ThinLTO.CombinedIndex.dumpSCCs(outs());
1887
1888 std::setGlobalValue::GUID ExportedGUIDs;
1889
1890 bool WholeProgramVisibilityEnabledInLTO =
1892
1893
1896 ThinLTO.CombinedIndex.setWithWholeProgramVisibility();
1897
1898
1899
1900
1902 if (WholeProgramVisibilityEnabledInLTO &&
1904
1905
1906 auto IsVisibleToRegularObj = [&](StringRef name) {
1907 auto It = GlobalResolutions->find(name);
1908 return (It == GlobalResolutions->end() ||
1909 It->second.VisibleOutsideSummary);
1910 };
1911
1913 VisibleToRegularObjSymbols,
1914 IsVisibleToRegularObj);
1915 }
1916
1917
1918
1920 ThinLTO.CombinedIndex, WholeProgramVisibilityEnabledInLTO,
1921 DynamicExportSymbols, VisibleToRegularObjSymbols);
1922
1923
1924
1925
1926 std::map<ValueInfo, std::vector> LocalWPDTargetsMap;
1928 LocalWPDTargetsMap);
1929
1931 return ThinLTO.PrevailingModuleForGUID[GUID] == S->modulePath();
1932 };
1935 ContextDisambiguation.run(ThinLTO.CombinedIndex, isPrevailing);
1936 }
1937
1938
1939
1940
1941
1942 for (auto &Res : *GlobalResolutions) {
1943
1944
1945 if (Res.second.Partition != GlobalResolution::External ||
1946 !Res.second.isPrevailingIRSymbol())
1947 continue;
1950
1951 if (ThinLTO.CombinedIndex.isGUIDLive(GUID))
1952 ExportedGUIDs.insert(GUID);
1953 }
1954
1955
1956
1957
1958
1959 releaseGlobalResolutionsMemory();
1960
1963 isPrevailing, ImportLists, ExportLists);
1964
1965
1966
1967 for (auto &Def : ThinLTO.CombinedIndex.cfiFunctionDefs())
1968 ExportedGUIDs.insert(
1970 for (auto &Decl : ThinLTO.CombinedIndex.cfiFunctionDecls())
1971 ExportedGUIDs.insert(
1973
1975 const auto &ExportList = ExportLists.find(ModuleIdentifier);
1976 return (ExportList != ExportLists.end() && ExportList->second.count(VI)) ||
1977 ExportedGUIDs.count(VI.getGUID());
1978 };
1979
1980
1981
1983 LocalWPDTargetsMap);
1984
1986 isPrevailing);
1987
1988 auto recordNewLinkage = [&](StringRef ModuleIdentifier,
1991 ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
1992 };
1994 recordNewLinkage, GUIDPreservedSymbols);
1995
1997
1999
2002
2003 TimeTraceScopeExit.release();
2004
2005 auto &ModuleMap =
2006 ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;
2007
2009 auto ProcessOneModule = [&](int I) -> Error {
2010 auto &Mod = *(ModuleMap.begin() + I);
2011
2012
2013 return BackendProcess->start(
2014 RegularLTO.ParallelCodeGenParallelismLevel + I, Mod.second,
2015 ImportLists[Mod.first], ExportLists[Mod.first],
2016 ResolvedODR[Mod.first], ThinLTO.ModuleMap);
2017 };
2018
2019 if (BackendProcess->getThreadCount() == 1 ||
2020 BackendProcess->isSensitiveToInputOrder()) {
2021
2022
2023
2024
2025
2026 for (int I = 0, E = ModuleMap.size(); I != E; ++I)
2027 if (Error E = ProcessOneModule(I))
2028 return E;
2029 } else {
2030
2031
2032
2033
2034 std::vector<BitcodeModule *> ModulesVec;
2035 ModulesVec.reserve(ModuleMap.size());
2036 for (auto &Mod : ModuleMap)
2037 ModulesVec.push_back(&Mod.second);
2039 if (Error E = ProcessOneModule(I))
2040 return E;
2041 }
2042 return BackendProcess->wait();
2043 };
2044
2046 std::unique_ptr BackendProc =
2047 ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
2048 AddStream, Cache);
2049 return RunBackends(BackendProc.get());
2050 }
2051
2052
2053
2054
2055
2056
2057 LLVM_DEBUG(dbgs() << "[TwoRounds] Initializing ThinLTO two-codegen rounds\n");
2058
2060 auto Parallelism = ThinLTO.Backend.getParallelism();
2061
2062
2064
2065
2066
2067
2068 LLVM_DEBUG(dbgs() << "[TwoRounds] Running the first round of codegen\n");
2069 auto FirstRoundLTO = std::make_unique(
2070 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2071 CG.AddStream, CG.Cache, IR.AddStream, IR.Cache);
2072 if (Error E = RunBackends(FirstRoundLTO.get()))
2073 return E;
2074
2075 LLVM_DEBUG(dbgs() << "[TwoRounds] Merging codegen data\n");
2077 if (Error E = CombinedHashOrErr.takeError())
2078 return E;
2079 auto CombinedHash = *CombinedHashOrErr;
2080 LLVM_DEBUG(dbgs() << "[TwoRounds] CGData hash: " << CombinedHash << "\n");
2081
2082
2083
2084 LLVM_DEBUG(dbgs() << "[TwoRounds] Running the second round of codegen\n");
2085 auto SecondRoundLTO = std::make_unique(
2086 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2087 AddStream, Cache, IR.getResult(), CombinedHash);
2088 return RunBackends(SecondRoundLTO.get());
2089}
2090
2096
2097
2098 if (!Filename.empty() && Count != -1)
2099 Filename =
2100 (Twine(Filename) + ".thin." + llvm::utostr(Count) + "." + RemarksFormat)
2101 .str();
2102
2106 if (Error E = ResultOrErr.takeError())
2107 return std::move(E);
2108
2109 if (*ResultOrErr)
2110 (*ResultOrErr)->keep();
2111
2112 return ResultOrErr;
2113}
2114
2117
2118 if (StatsFilename.empty())
2119 return nullptr;
2120
2122 std::error_code EC;
2123 auto StatsFile =
2124 std::make_unique(StatsFilename, EC, sys::fs::OF_None);
2125 if (EC)
2127
2128 StatsFile->keep();
2129 return std::move(StatsFile);
2130}
2131
2132
2133
2134
2136 auto Seq = llvm::seq(0, R.size());
2137 std::vector ModulesOrdering(Seq.begin(), Seq.end());
2138 llvm::sort(ModulesOrdering, [&](int LeftIndex, int RightIndex) {
2139 auto LSize = R[LeftIndex]->getBuffer().size();
2140 auto RSize = R[RightIndex]->getBuffer().size();
2141 return LSize > RSize;
2142 });
2143 return ModulesOrdering;
2144}
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."))
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
static cl::opt< bool > DumpThinCGSCCs("dump-thin-cg-sccs", cl::init(false), cl::Hidden, cl::desc("Dump the SCCs in the ThinLTO index's callgraph"))
static void thinLTOInternalizeAndPromoteGUID(ValueInfo VI, function_ref< bool(StringRef, ValueInfo)> isExported, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
cl::opt< bool > UseNewDbgInfoFormat
Legalize the Machine IR a function s Machine IR
llvm:🆑:opt< bool > UseNewDbgInfoFormat
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This file defines the SmallSet class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
This pass exposes codegen information to IR-level passes.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Represents a module in a bitcode file.
StringRef getModuleIdentifier() const
Error readSummary(ModuleSummaryIndex &CombinedIndex, StringRef ModulePath, std::function< bool(GlobalValue::GUID)> IsPrevailing=nullptr)
Parse the specified bitcode buffer and merge its module summary index into CombinedIndex.
Expected< std::unique_ptr< Module > > parseModule(LLVMContext &Context, ParserCallbacks Callbacks={})
Read the entire bitcode module and return it.
Expected< std::unique_ptr< Module > > getLazyModule(LLVMContext &Context, bool ShouldLazyLoadMetadata, bool IsImporting, ParserCallbacks Callbacks={})
Read the bitcode module and prepare for lazy deserialization of function bodies.
static ConstantAggregateZero * get(Type *Ty)
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Implements a dense probed hash-table based set.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
The map maintains the list of imports.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalObject.
Function and variable summary information to aid decisions and implementation of importing.
static bool isAppendingLinkage(LinkageTypes Linkage)
static bool isExternalWeakLinkage(LinkageTypes Linkage)
static bool isLocalLinkage(LinkageTypes Linkage)
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
void setUnnamedAddr(UnnamedAddr Val)
bool hasLocalLinkage() const
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
const Comdat * getComdat() const
static bool isLinkOnceLinkage(LinkageTypes Linkage)
static GUID getGUID(StringRef GlobalName)
Return a 64-bit global unique ID constructed from global value name (i.e.
void setLinkage(LinkageTypes LT)
DLLStorageClassTypes
Storage classes of global values for PE targets.
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
const GlobalObject * getAliaseeObject() const
static bool isExternalLinkage(LinkageTypes Linkage)
VisibilityTypes
An enumeration for the kinds of visibility of global values.
@ DefaultVisibility
The GV is visible.
static LinkageTypes getWeakLinkage(bool ODR)
bool isWeakForLinker() const
bool hasAppendingLinkage() const
bool hasAvailableExternallyLinkage() const
std::string getGlobalIdentifier() const
Return the modified name for this global value suitable to be used as the key for a global lookup (e....
LinkageTypes
An enumeration for the kinds of linkage for global values.
@ CommonLinkage
Tentative definitions.
@ InternalLinkage
Rename collisions when linking (static functions).
@ ExternalLinkage
Externally visible function.
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
@ AvailableExternallyLinkage
Available for inspection, not emission.
DLLStorageClassTypes getDLLStorageClass() const
Type * getValueType() const
static bool isLinkOnceODRLinkage(LinkageTypes Linkage)
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
This is an important class for using LLVM in a threaded context.
This class implements a map that also provides access to all stored values in a deterministic order.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
Class to hold module path string table and global value map, and encapsulate methods for operating on...
const ModuleHash & getModuleHash(const StringRef ModPath) const
Get the module SHA1 hash recorded for the given module path.
const StringMap< ModuleHash > & modulePaths() const
Table of modules, containing module hash and id.
std::set< std::string, std::less<> > & cfiFunctionDefs()
std::set< std::string, std::less<> > & cfiFunctionDecls()
void addModule(Module *M)
static void CollectAsmSymvers(const Module &M, function_ref< void(StringRef, StringRef)> AsmSymver)
Parse inline ASM and collect the symvers directives that are defined in the current module.
uint32_t getSymbolFlags(Symbol S) const
ArrayRef< Symbol > symbols() const
A Module instance is used to store all the information related to an LLVM module.
A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...
A class that wrap the SHA1 algorithm.
void update(ArrayRef< uint8_t > Data)
Digest more data.
std::array< uint8_t, 20 > result()
Return the current raw 160-bits SHA1 for the digested data since the last call to init().
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.
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.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
MCTargetOptions MCOptions
Machine level options.
DebuggerKind DebuggerTuning
Which debugger to tune for.
unsigned FunctionSections
Emit functions into separate sections.
unsigned DataSections
Emit data into separate sections.
This tells how a thread pool will be used.
Triple - Helper class for working with autoconf configuration names.
bool isArm64e() const
Tests whether the target is the Apple "arm64e" AArch64 subarch.
ArchType getArch() const
Get the parsed architecture type of this triple.
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, XROS, or DriverKit).
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static IntegerType * getInt8Ty(LLVMContext &C)
void setName(const Twine &Name)
Change the name of the value.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
std::pair< iterator, bool > insert(const ValueT &V)
iterator find(const_arg_type_t< ValueT > V)
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().
static Expected< std::unique_ptr< InputFile > > create(MemoryBufferRef Object)
Create an InputFile.
ArrayRef< Symbol > symbols() const
A range over the symbols in this InputFile.
StringRef getName() const
Returns the path to the InputFile.
BitcodeModule & getSingleBitcodeModule()
LTO(Config Conf, ThinBackend Backend={}, unsigned ParallelCodeGenParallelismLevel=1, LTOKind LTOMode=LTOK_Default)
Create an LTO object.
Error add(std::unique_ptr< InputFile > Obj, ArrayRef< SymbolResolution > Res)
Add an input file to the LTO link, using the provided symbol resolutions.
static 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.
unsigned getMaxTasks() const
Returns an upper bound on the number of tasks that the client may expect.
Error run(AddStreamFn AddStream, FileCache Cache={})
Runs the LTO pipeline.
This class defines the interface to the ThinLTO backend.
Error emitFiles(const FunctionImporter::ImportMapTy &ImportList, llvm::StringRef ModulePath, const std::string &NewModulePath) const
bool ShouldEmitImportsFiles
const DenseMap< StringRef, GVSummaryMapTy > & ModuleToDefinedGVSummaries
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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclarationIfExists(Module *M, ID id, ArrayRef< Type * > Tys, FunctionType *FT=nullptr)
This version supports overloaded intrinsics.
Expected< stable_hash > mergeCodeGenData(ArrayRef< StringRef > ObjectFiles)
Merge the codegen data from the scratch objects ObjectFiles from the first codegen round.
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)
ThinBackend createInProcessThinBackend(ThreadPoolStrategy Parallelism, IndexWriteCallback OnWrite=nullptr, bool ShouldEmitIndexFiles=false, bool ShouldEmitImportsFiles=false)
This ThinBackend runs the individual backend jobs in-process.
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
StringLiteral getThinLTODefaultCPU(const Triple &TheTriple)
Expected< std::unique_ptr< ToolOutputFile > > setupStatsFile(StringRef StatsFilename)
Setups the output file for saving statistics.
Error backend(const Config &C, AddStreamFn AddStream, unsigned ParallelCodeGenParallelismLevel, Module &M, ModuleSummaryIndex &CombinedIndex)
Runs a regular LTO backend.
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...
Error finalizeOptimizationRemarks(std::unique_ptr< ToolOutputFile > DiagOutputFile)
std::vector< int > generateModulesOrdering(ArrayRef< BitcodeModule * > R)
Produces a container ordering for optimal multi-threaded processing.
Expected< std::unique_ptr< ToolOutputFile > > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::optional< uint64_t > RemarksHotnessThreshold=0, int Count=-1)
Setup optimization remarks.
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.
void updateMemProfAttributes(Module &Mod, const ModuleSummaryIndex &Index)
Updates MemProf attributes (and metadata) based on whether the index has recorded that we are linking...
Expected< IRSymtabFile > readIRSymtab(MemoryBufferRef MBRef)
Reads a bitcode file, creating its irsymtab if necessary.
void write64le(void *P, uint64_t V)
void write32le(void *P, uint32_t V)
std::error_code create_directories(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create all the non-existent directories in path.
StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
bool replace_path_prefix(SmallVectorImpl< char > &Path, StringRef OldPrefix, StringRef NewPrefix, Style style=Style::native)
Replace matching path prefix with another path.
This is an optimization pass for GlobalISel generic memory operations.
ThreadPoolStrategy heavyweight_hardware_concurrency(unsigned ThreadCount=0)
Returns a thread strategy for tasks requiring significant memory or other resources.
cl::opt< std::string > RemarksFormat("lto-pass-remarks-format", cl::desc("The format used for serializing remarks (default: YAML)"), cl::value_desc("format"), cl::init("yaml"))
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
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"))
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
std::function< Expected< std::unique_ptr< CachedFileStream > >(unsigned Task, const Twine &ModuleName)> AddStreamFn
This type defines the callback to add a file that is generated on the fly.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
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.
OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P)
Provide wrappers to std::copy_if which take ranges instead of having to pass begin/end explicitly.
bool hasWholeProgramVisibility(bool WholeProgramVisibilityEnabledInLTO)
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 ...
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.
void EnableStatistics(bool DoPrintOnExit=true)
Enable the collection and printing of statistics.
void thinLTOInternalizeAndPromoteInIndex(ModuleSummaryIndex &Index, function_ref< bool(StringRef, ValueInfo)> isExported, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
Update the linkages in the given Index to mark exported values as external and non-exported values as...
void timeTraceProfilerInitialize(unsigned TimeTraceGranularity, StringRef ProcName, bool TimeTraceVerbose=false)
Initialize the time trace profiler.
void timeTraceProfilerFinishThread()
Finish a time trace profiler running on a worker thread.
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.
void updatePublicTypeTestCalls(Module &M, bool WholeProgramVisibilityEnabledInLTO)
void getVisibleToRegularObjVtableGUIDs(ModuleSummaryIndex &Index, DenseSet< GlobalValue::GUID > &VisibleToRegularObjSymbols, function_ref< bool(StringRef)> IsVisibleToRegularObj)
Based on typeID string, get all associated vtable GUIDS that are visible to regular objects.
void sort(IteratorTy Start, IteratorTy End)
bool timeTraceProfilerEnabled()
Is the time trace profiler enabled, i.e. initialized?
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Expected< std::unique_ptr< ToolOutputFile > > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::optional< uint64_t > RemarksHotnessThreshold=0)
Setup optimization remarks that output to a file.
cl::opt< bool > EnableLTOInternalization
Enable global value internalization in LTO.
cl::opt< bool > RemarksWithHotness("lto-pass-remarks-with-hotness", cl::desc("With PGO, include profile count in optimization remarks"), cl::Hidden)
void timeTraceProfilerEnd()
Manually end the last time section.
cl::opt< std::string > RemarksFilename("lto-pass-remarks-output", cl::desc("Output filename for pass remarks"), cl::value_desc("filename"))
cl::opt< bool > SupportsHotColdNew
Indicate we are linking with an allocator that supports hot/cold operator new interfaces.
void updateIndexWPDForExports(ModuleSummaryIndex &Summary, function_ref< bool(StringRef, ValueInfo)> isExported, std::map< ValueInfo, std::vector< VTableSlotSummary > > &LocalWPDTargetsMap)
Call after cross-module importing to update the recorded single impl devirt target names for any loca...
void thinLTOResolvePrevailingInIndex(const lto::Config &C, ModuleSummaryIndex &Index, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, function_ref< void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> recordNewLinkage, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols)
Resolve linkage for prevailing symbols in the Index.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Mod
The access may modify the value stored in memory.
cl::opt< bool > EnableMemProfContextDisambiguation
Enable MemProf context disambiguation for thin link.
void runWholeProgramDevirtOnIndex(ModuleSummaryIndex &Summary, std::set< GlobalValue::GUID > &ExportedGUIDs, std::map< ValueInfo, std::vector< VTableSlotSummary > > &LocalWPDTargetsMap)
Perform index-based whole program devirtualization on the Summary index.
std::unordered_set< GlobalValueSummary * > GVSummaryPtrSet
A set of global value summary pointers.
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.
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)
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 ...
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"))
bool UpgradeDebugInfo(Module &M)
Check the debug info version number, if it is out-dated, drop the debug info.
void PrintStatisticsJSON(raw_ostream &OS)
Print statistics in JSON format.
void computeDeadSymbolsWithConstProp(ModuleSummaryIndex &Index, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols, function_ref< PrevailingType(GlobalValue::GUID)> isPrevailing, bool ImportEnabled)
Compute dead symbols and run constant propagation in combined index after that.
Error EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename, const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex)
Emit into OutputFilename the files module ModulePath will import from.
@ Keep
No function return thunk.
void updateVCallVisibilityInModule(Module &M, bool WholeProgramVisibilityEnabledInLTO, const DenseSet< GlobalValue::GUID > &DynamicExportSymbols, bool ValidateAllVtablesHaveTypeInfos, function_ref< bool(StringRef)> IsVisibleToRegularObj)
If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...
TimeTraceProfilerEntry * timeTraceProfilerBegin(StringRef Name, StringRef Detail)
Manually begin a time section, with the given Name and Detail.
void updateVCallVisibilityInIndex(ModuleSummaryIndex &Index, bool WholeProgramVisibilityEnabledInLTO, const DenseSet< GlobalValue::GUID > &DynamicExportSymbols, const DenseSet< GlobalValue::GUID > &VisibleToRegularObjSymbols)
If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...
Implement std::hash so that hash_code can be used in STL containers.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Used in the streaming interface as the general argument type.
This type represents a file cache system that manages caching of files.
A simple container for information about the supported runtime calls.
iterator_range< const char ** > getLibcallNames()
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).
The purpose of this struct is to only expose the symbol information that an LTO client should need in...
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.