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"
55#include "llvm/Support/VCSRevision.h"
63
64#include
65#include
66
67using namespace llvm;
68using namespace lto;
69using namespace object;
70
71#define DEBUG_TYPE "lto"
72
75 cl::desc("Dump the SCCs in the ThinLTO index's callgraph"));
76
77namespace llvm {
80}
81
82namespace llvm {
83
86 cl::desc("Enable global value internalization in LTO"));
87
90 cl::desc("Keep copies of symbols in LTO indexing"));
91
92
93
95
96
98}
99
100
101
102
107 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
111
112
113
114
116
117
118 Hasher.update(LLVM_VERSION_STRING);
119#ifdef LLVM_REVISION
120 Hasher.update(LLVM_REVISION);
121#endif
122
123
124 auto AddString = [&](StringRef Str) {
127 };
128 auto AddUnsigned = [&](unsigned I) {
132 };
133 auto AddUint64 = [&](uint64_t I) {
137 };
138 auto AddUint8 = [&](const uint8_t I) {
140 };
141 AddString(Conf.CPU);
142
143
144
145
150 for (auto &A : Conf.MAttrs)
151 AddString(A);
154 else
155 AddUnsigned(-1);
158 else
159 AddUnsigned(-1);
160 for (const auto &S : Conf.MllvmArgs)
161 AddString(S);
162 AddUnsigned(static_cast<int>(Conf.CGOptLevel));
163 AddUnsigned(static_cast<int>(Conf.CGFileType));
170 AddString(Conf.DwoDir);
171 AddUint8(Conf.Dtlto);
172
173
174 auto ModHash = Index.getModuleHash(ModuleID);
176
177
178
179 std::vector<uint64_t> ExportsGUID;
180 ExportsGUID.reserve(ExportList.size());
181 for (const auto &VI : ExportList)
182 ExportsGUID.push_back(VI.getGUID());
183
184
186 for (auto GUID : ExportsGUID)
188
189
190
191 auto Comp = [&](const std::pair<StringRef, GlobalValue::GUID> &L,
192 const std::pair<StringRef, GlobalValue::GUID> &R) {
193 return std::make_pair(Index.getModule(L.first)->second, L.second) <
194 std::make_pair(Index.getModule(R.first)->second, R.second);
195 };
197
198
200 for (const auto &[FromModule, GUID, Type] : SortedImportList)
201 ++ModuleToNumImports[FromModule];
202
203 std::optional LastModule;
204 for (const auto &[FromModule, GUID, Type] : SortedImportList) {
205 if (LastModule != FromModule) {
206
207
208
209 LastModule = FromModule;
210 auto ModHash = Index.getModule(FromModule)->second;
212 AddUint64(ModuleToNumImports[FromModule]);
213 }
214 AddUint64(GUID);
215 AddUint8(Type);
216 }
217
218
219 for (auto &Entry : ResolvedODR) {
224 }
225
226
227
228 std::setGlobalValue::GUID UsedCfiDefs;
229 std::setGlobalValue::GUID UsedCfiDecls;
230
231
232 std::setGlobalValue::GUID UsedTypeIds;
233
235 if (CfiFunctionDefs.contains(ValueGUID))
236 UsedCfiDefs.insert(ValueGUID);
237 if (CfiFunctionDecls.contains(ValueGUID))
238 UsedCfiDecls.insert(ValueGUID);
239 };
240
242 if (!GS) return;
243 AddUnsigned(GS->getVisibility());
244 AddUnsigned(GS->isLive());
245 AddUnsigned(GS->canAutoHide());
246 for (const ValueInfo &VI : GS->refs()) {
247 AddUnsigned(VI.isDSOLocal(Index.withDSOLocalPropagation()));
248 AddUsedCfiGlobal(VI.getGUID());
249 }
251 AddUnsigned(GVS->maybeReadOnly());
252 AddUnsigned(GVS->maybeWriteOnly());
253 }
255 for (auto &TT : FS->type_tests())
256 UsedTypeIds.insert(TT);
257 for (auto &TT : FS->type_test_assume_vcalls())
258 UsedTypeIds.insert(TT.GUID);
259 for (auto &TT : FS->type_checked_load_vcalls())
260 UsedTypeIds.insert(TT.GUID);
261 for (auto &TT : FS->type_test_assume_const_vcalls())
262 UsedTypeIds.insert(TT.VFunc.GUID);
263 for (auto &TT : FS->type_checked_load_const_vcalls())
264 UsedTypeIds.insert(TT.VFunc.GUID);
265 for (auto &ET : FS->calls()) {
266 AddUnsigned(ET.first.isDSOLocal(Index.withDSOLocalPropagation()));
267 AddUsedCfiGlobal(ET.first.getGUID());
268 }
269 }
270 };
271
272
273
274 for (auto &GS : DefinedGlobals) {
278 AddUsedCfiGlobal(GS.first);
279 AddUsedThings(GS.second);
280 }
281
282
283
284 for (const auto &[FromModule, GUID, Type] : SortedImportList) {
286 AddUsedThings(S);
287
288
290 AddUsedThings(AS->getBaseObject());
291 }
292
294 AddString(TId);
295
296 AddUnsigned(S.TTRes.TheKind);
297 AddUnsigned(S.TTRes.SizeM1BitWidth);
298
299 AddUint64(S.TTRes.AlignLog2);
300 AddUint64(S.TTRes.SizeM1);
301 AddUint64(S.TTRes.BitMask);
302 AddUint64(S.TTRes.InlineBits);
303
304 AddUint64(S.WPDRes.size());
305 for (auto &WPD : S.WPDRes) {
306 AddUnsigned(WPD.first);
307 AddUnsigned(WPD.second.TheKind);
308 AddString(WPD.second.SingleImplName);
309
310 AddUint64(WPD.second.ResByArg.size());
311 for (auto &ByArg : WPD.second.ResByArg) {
312 AddUint64(ByArg.first.size());
313 for (uint64_t Arg : ByArg.first)
314 AddUint64(Arg);
315 AddUnsigned(ByArg.second.TheKind);
316 AddUint64(ByArg.second.Info);
317 AddUnsigned(ByArg.second.Byte);
318 AddUnsigned(ByArg.second.Bit);
319 }
320 }
321 };
322
323
325 auto TidIter = Index.typeIds().equal_range(TId);
326 for (const auto &I : make_range(TidIter))
327 AddTypeIdSummary(I.second.first, I.second.second);
328 }
329
330 AddUnsigned(UsedCfiDefs.size());
331 for (auto &V : UsedCfiDefs)
332 AddUint64(V);
333
334 AddUnsigned(UsedCfiDecls.size());
335 for (auto &V : UsedCfiDecls)
336 AddUint64(V);
337
340 if (FileOrErr) {
341 Hasher.update(FileOrErr.get()->getBuffer());
342
345 if (FileOrErr)
346 Hasher.update(FileOrErr.get()->getBuffer());
347 }
348 }
349 }
350
352}
353
357
358 auto AddString = [&](StringRef Str) {
361 };
362 AddString(Key);
363 AddString(ExtraID);
364
366}
367
372 isPrevailing,
374 recordNewLinkage,
377 C.VisibilityScheme == Config::ELF ? VI.getELFVisibility()
379 for (auto &S : VI.getSummaryList()) {
381
382
385 continue;
386
387
388
389
390
391
392
393
394 if (isPrevailing(VI.getGUID(), S.get())) {
398
399
400
401
402
403
404
405
406
407 S->setCanAutoHide(VI.canAutoHide() &&
408 !GUIDPreservedSymbols.count(VI.getGUID()));
409 }
411 Visibility = S->getVisibility();
412 }
413
414
415
416
420
421
422
423
425 S->setVisibility(Visibility);
426
427 if (S->linkage() != OriginalLinkage)
428 recordNewLinkage(S->modulePath(), VI.getGUID(), S->linkage());
429 }
430
432 for (auto &S : VI.getSummaryList()) {
436 continue;
437 S->setVisibility(Visibility);
438 }
439 }
440}
441
442
443
444
445
446
447
451 isPrevailing,
453 recordNewLinkage,
455
456
457
459 for (auto &I : Index)
460 for (auto &S : I.second.getSummaryList())
462 GlobalInvolvedWithAlias.insert(&AS->getAliasee());
463
464 for (auto &I : Index)
466 GlobalInvolvedWithAlias, isPrevailing,
467 recordNewLinkage, GUIDPreservedSymbols);
468}
469
473 isPrevailing) {
474
475
476 VI.verifyLocal();
477
478 const bool SingleExternallyVisibleCopy =
479 VI.getSummaryList().size() == 1 &&
481
482 for (auto &S : VI.getSummaryList()) {
483
484
485 if (isExported(S->modulePath(), VI)) {
488 continue;
489 }
490
491
493 continue;
494
495
498 continue;
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
530
531
532
533
534
535
536
537
538
539
542 continue;
543
544
545
546 if (SingleExternallyVisibleCopy && isPrevailing(VI.getGUID(), S.get()))
548 }
549}
550
551
552
557 isPrevailing) {
558 assert(!Index.withInternalizeAndPromote());
559 for (auto &I : Index)
561 isPrevailing);
562 Index.setWithInternalizeAndPromote();
563}
564
565
567
569 std::unique_ptr File(new InputFile);
570
572 if (!FOrErr)
574
575 File->TargetTriple = FOrErr->TheReader.getTargetTriple();
576 File->SourceFileName = FOrErr->TheReader.getSourceFileName();
577 File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts();
578 File->DependentLibraries = FOrErr->TheReader.getDependentLibraries();
579 File->ComdatTable = FOrErr->TheReader.getComdatTable();
580
581 for (unsigned I = 0; I != FOrErr->Mods.size(); ++I) {
582 size_t Begin = File->Symbols.size();
584 FOrErr->TheReader.module_symbols(I))
585
586
587 if (Sym.isGlobal() && !Sym.isFormatSpecific())
588 File->Symbols.push_back(Sym);
589 File->ModuleSymIndices.push_back({Begin, File->Symbols.size()});
590 }
591
592 File->Mods = FOrErr->Mods;
593 File->Strtab = std::move(FOrErr->Strtab);
594 return std::move(File);
595}
596
598 return Mods[0].getModuleIdentifier();
599}
600
602 assert(Mods.size() == 1 && "Expect only one bitcode module");
603 return Mods[0];
604}
605
606LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel,
608 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
609 Ctx(Conf), CombinedModule(std::make_unique<Module>("ld-temp.o", Ctx)),
610 Mover(std::make_unique<IRMover>(*CombinedModule)) {}
611
612LTO::ThinLTOState::ThinLTOState(ThinBackend BackendParam)
613 : Backend(std::move(BackendParam)), CombinedIndex( false) {
614 if (!Backend.isValid())
615 Backend =
617}
618
620 unsigned ParallelCodeGenParallelismLevel, LTOKind LTOMode)
622 RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),
623 ThinLTO(std::move(Backend)),
624 GlobalResolutions(
626 LTOMode(LTOMode) {
628 Alloc = std::make_unique();
629 GlobalResolutionSymbolSaver = std::make_uniquellvm::StringSaver(*Alloc);
630 }
631}
632
633
635
636
637
640 unsigned Partition, bool InSummary) {
642 auto *ResI = Res.begin();
643 auto *ResE = Res.end();
644 (void)ResE;
646 assert(ResI != ResE);
648
649 StringRef SymbolName = Sym.getName();
650
651 if (GlobalResolutionSymbolSaver && !GlobalResolutions->contains(SymbolName))
652 SymbolName = GlobalResolutionSymbolSaver->save(SymbolName);
653
654 auto &GlobalRes = (*GlobalResolutions)[SymbolName];
655 GlobalRes.UnnamedAddr &= Sym.isUnnamedAddr();
657 assert(!GlobalRes.Prevailing &&
658 "Multiple prevailing defs are not allowed");
659 GlobalRes.Prevailing = true;
660 GlobalRes.IRName = std::string(Sym.getIRName());
661 } else if (!GlobalRes.Prevailing && GlobalRes.IRName.empty()) {
662
663
664
665
666
667
668 GlobalRes.IRName = std::string(Sym.getIRName());
669 }
670
671
672
673
674
675
676
677
678
679
680
681
682 if (GlobalRes.IRName != Sym.getIRName()) {
683 GlobalRes.Partition = GlobalResolution::External;
684 GlobalRes.VisibleOutsideSummary = true;
685 }
686
687
688
689
690
692 (GlobalRes.Partition != GlobalResolution::Unknown &&
693 GlobalRes.Partition != Partition)) {
694 GlobalRes.Partition = GlobalResolution::External;
695 } else
696
697 GlobalRes.Partition = Partition;
698
699
700
701 GlobalRes.VisibleOutsideSummary |=
703
705 }
706}
707
708void LTO::releaseGlobalResolutionsMemory() {
709
710 GlobalResolutions.reset();
711
712 GlobalResolutionSymbolSaver.reset();
713 Alloc.reset();
714}
715
719 OS << Path << '\n';
720 auto ResI = Res.begin();
724
725 OS << "-r=" << Path << ',' << Sym.getName() << ',';
727 OS << 'p';
729 OS << 'l';
731 OS << 'x';
733 OS << 'r';
734 OS << '\n';
735 }
738}
739
743 assert(!CalledGetMaxTasks);
744
745 if (Conf.ResolutionFile)
747
748 if (RegularLTO.CombinedModule->getTargetTriple().empty()) {
749 Triple InputTriple(Input->getTargetTriple());
750 RegularLTO.CombinedModule->setTargetTriple(InputTriple);
753 }
754
756 for (unsigned I = 0; I != Input->Mods.size(); ++I) {
757 if (auto Err = addModule(*Input, InputRes, I, Res).moveInto(Res))
758 return Err;
759 }
760
763}
764
770 if (!LTOInfo)
772
773 if (EnableSplitLTOUnit) {
774
775
776
777 if (*EnableSplitLTOUnit != LTOInfo->EnableSplitLTOUnit)
779 } else
780 EnableSplitLTOUnit = LTOInfo->EnableSplitLTOUnit;
781
783
785 !LTOInfo->UnifiedLTO)
787 "unified LTO compilation must use "
788 "compatible bitcode modules (use -funified-lto)",
790
791 if (LTOInfo->UnifiedLTO && LTOMode == LTOK_Default)
793
795
796 auto ModSyms = Input.module_symbols(ModI);
797 addModuleToGlobalRes(ModSyms, Res,
798 IsThinLTO ? ThinLTO.ModuleMap.size() + 1 : 0,
799 LTOInfo->HasSummary);
800
801 if (IsThinLTO)
802 return addThinLTO(BM, ModSyms, Res);
803
804 RegularLTO.EmptyCombinedModule = false;
805 auto ModOrErr = addRegularLTO(Input, InputRes, BM, ModSyms, Res);
806 if (!ModOrErr)
807 return ModOrErr.takeError();
808 Res = ModOrErr->second;
809
810 if (!LTOInfo->HasSummary) {
811 if (Error Err = linkRegularLTO(std::move(ModOrErr->first),
812 false))
813 return Err;
814 return Res;
815 }
816
817
818
820 return Err;
821 RegularLTO.ModsWithSummaries.push_back(std::move(ModOrErr->first));
822 return Res;
823}
824
825
826
827
828
829
830
831
832
833
834
835static void
837 std::set<const Comdat *> &NonPrevailingComdats) {
839 if ()
840 return;
841
842 if (!NonPrevailingComdats.count(C))
843 return;
844
845
846
847
848
850
852 GO->setComdat(nullptr);
853}
854
855
856
857
858Expected<
859 std::pair<LTO::RegularLTOState::AddedModule, ArrayRef>>
863 llvm::TimeTraceScope timeScope("LTO add regular LTO");
865 Expected<std::unique_ptr> MOrErr =
866 BM.getLazyModule(RegularLTO.Ctx, true,
867 false);
868 if (!MOrErr)
871 Mod.M = std::move(*MOrErr);
872
873 if (Error Err = M.materializeMetadata())
874 return std::move(Err);
875
877
878
879
880 if (NamedMDNode *CfiFunctionsMD = M.getNamedMetadata("cfi.functions"))
881 M.eraseNamedMetadata(CfiFunctionsMD);
882 } else if (NamedMDNode *AliasesMD = M.getNamedMetadata("aliases")) {
883
884
885 DenseSet Prevailing;
886 for (auto [I, R] : zip(Input.symbols(), InputRes))
887 if (R.Prevailing && .getIRName().empty())
888 Prevailing.insert(I.getIRName());
889 std::vector<MDNode *> AliasGroups;
890 for (MDNode *AliasGroup : AliasesMD->operands()) {
891 std::vector<Metadata *> Aliases;
892 for (Metadata *Alias : AliasGroup->operands()) {
895 Aliases.push_back(Alias);
896 }
897 if (Aliases.size() > 1)
898 AliasGroups.push_back(MDTuple::get(RegularLTO.Ctx, Aliases));
899 }
900 AliasesMD->clearOperands();
901 for (MDNode *G : AliasGroups)
902 AliasesMD->addOperand(G);
903 }
904
906
907 ModuleSymbolTable SymTab;
909
910 for (GlobalVariable &GV : M.globals())
911 if (GV.hasAppendingLinkage())
912 Mod.Keep.push_back(&GV);
913
914 DenseSet<GlobalObject *> AliasedGlobals;
915 for (auto &GA : M.aliases())
916 if (GlobalObject *GO = GA.getAliaseeObject())
917 AliasedGlobals.insert(GO);
918
919
920
921
922
923
924
925
926 auto MsymI = SymTab.symbols().begin(), MsymE = SymTab.symbols().end();
927 auto Skip = [&]() {
928 while (MsymI != MsymE) {
932 return;
933 ++MsymI;
934 }
935 };
937
938 std::set<const Comdat *> NonPrevailingComdats;
939 SmallSet<StringRef, 2> NonPrevailingAsmSymbols;
940 for (const InputFile::Symbol &Sym : Syms) {
943
944 assert(MsymI != MsymE);
947
949 if (R.Prevailing) {
950 if (Sym.isUndefined())
951 continue;
952 Mod.Keep.push_back(GV);
953
954
955
956 if (R.LinkerRedefined)
958
964 (GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||
965 GV->hasAvailableExternallyLinkage()) &&
967
968
969
970
971
972 Mod.Keep.push_back(GV);
974 if (GV->hasComdat())
975 NonPrevailingComdats.insert(GV->getComdat());
977 }
978
979
980 if (R.FinalDefinitionInLinkageUnit) {
981 GV->setDSOLocal(true);
982 if (GV->hasDLLImportStorageClass())
984 DefaultStorageClass);
985 }
986 } else if (auto *AS =
988
989 if (.Prevailing)
990 NonPrevailingAsmSymbols.insert(AS->first);
991 } else {
993 }
994
995
996
997
998 if (Sym.isCommon()) {
999
1000
1001 auto &CommonRes = RegularLTO.Commons[std::string(Sym.getIRName())];
1002 CommonRes.Size = std::max(CommonRes.Size, Sym.getCommonSize());
1003 if (uint32_t SymAlignValue = Sym.getCommonAlignment()) {
1004 CommonRes.Alignment =
1005 std::max(Align(SymAlignValue), CommonRes.Alignment);
1006 }
1007 CommonRes.Prevailing |= R.Prevailing;
1008 }
1009 }
1010
1011 if (.getComdatSymbolTable().empty())
1012 for (GlobalValue &GV : M.global_values())
1014
1015
1016
1017 if (.getModuleInlineAsm().empty()) {
1018 std::string NewIA = ".lto_discard";
1019 if (!NonPrevailingAsmSymbols.empty()) {
1020
1022 M, [&](StringRef Name, StringRef Alias) {
1023 if (!NonPrevailingAsmSymbols.count(Alias))
1024 NonPrevailingAsmSymbols.erase(Name);
1025 });
1026 NewIA += " " + llvm::join(NonPrevailingAsmSymbols, ", ");
1027 }
1028 NewIA += "\n";
1029 M.setModuleInlineAsm(NewIA + M.getModuleInlineAsm());
1030 }
1031
1032 assert(MsymI == MsymE);
1033 return std::make_pair(std::move(Mod), Res);
1034}
1035
1036Error LTO::linkRegularLTO(RegularLTOState::AddedModule Mod,
1037 bool LivenessFromIndex) {
1038 llvm::TimeTraceScope timeScope("LTO link regular LTO");
1039 std::vector<GlobalValue *> Keep;
1040 for (GlobalValue *GV : Mod.Keep) {
1041 if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->getGUID())) {
1043 if (DiagnosticOutputFile) {
1044 if (Error Err = F->materialize())
1045 return Err;
1046 OptimizationRemarkEmitter ORE(F, nullptr);
1047 ORE.emit(OptimizationRemark(DEBUG_TYPE, "deadfunction", F)
1049 << " not added to the combined module ");
1050 }
1051 }
1052 continue;
1053 }
1054
1056 Keep.push_back(GV);
1057 continue;
1058 }
1059
1060
1061
1062 GlobalValue *CombinedGV =
1063 RegularLTO.CombinedModule->getNamedValue(GV->getName());
1065 continue;
1066
1067 Keep.push_back(GV);
1068 }
1069
1070 return RegularLTO.Mover->move(std::move(Mod.M), Keep, nullptr,
1071 false);
1072}
1073
1074
1075Expected<ArrayRef>
1078 llvm::TimeTraceScope timeScope("LTO add thin LTO");
1081 for (const InputFile::Symbol &Sym : Syms) {
1084
1085 if (!Sym.getIRName().empty() && R.Prevailing) {
1089 ThinLTO.setPrevailingModuleForGUID(GUID, BMID);
1090 }
1091 }
1092
1095 return ThinLTO.isPrevailingModuleForGUID(GUID, BMID);
1096 }))
1097 return Err;
1099
1100 for (const InputFile::Symbol &Sym : Syms) {
1103
1104 if (!Sym.getIRName().empty() &&
1105 (R.Prevailing || R.FinalDefinitionInLinkageUnit)) {
1109 if (R.Prevailing) {
1110 assert(ThinLTO.isPrevailingModuleForGUID(GUID, BMID));
1111
1112
1113
1114
1115
1116 if (R.LinkerRedefined)
1117 if (auto S = ThinLTO.CombinedIndex.findSummaryInModule(GUID, BMID))
1119 }
1120
1121
1122
1123 if (R.FinalDefinitionInLinkageUnit) {
1124 if (auto S = ThinLTO.CombinedIndex.findSummaryInModule(GUID, BMID)) {
1125 S->setDSOLocal(true);
1126 }
1127 }
1128 }
1129 }
1130
1131 if (!ThinLTO.ModuleMap.insert({BMID, BM}).second)
1133 "Expected at most one ThinLTO module per bitcode file",
1135
1136 if (!Conf.ThinLTOModulesToCompile.empty()) {
1137 if (!ThinLTO.ModulesToCompile)
1138 ThinLTO.ModulesToCompile = ModuleMapType();
1139
1140
1141 for (const std::string &Name : Conf.ThinLTOModulesToCompile) {
1142 if (BMID.contains(Name)) {
1143 ThinLTO.ModulesToCompile->insert({BMID, BM});
1144 LLVM_DEBUG(dbgs() << "[ThinLTO] Selecting " << BMID << " to compile\n");
1145 break;
1146 }
1147 }
1148 }
1149
1150 return Res;
1151}
1152
1154 CalledGetMaxTasks = true;
1155 auto ModuleCount = ThinLTO.ModulesToCompile ? ThinLTO.ModulesToCompile->size()
1156 : ThinLTO.ModuleMap.size();
1157 return RegularLTO.ParallelCodeGenParallelismLevel + ModuleCount;
1158}
1159
1160
1161
1162Error LTO::checkPartiallySplit() {
1165
1166 const Module *Combined = RegularLTO.CombinedModule.get();
1169 Function *TypeCheckedLoadFunc =
1172 Combined, Intrinsic::type_checked_load_relative);
1173
1174
1175
1176 if ((TypeTestFunc && !TypeTestFunc->use_empty()) ||
1177 (TypeCheckedLoadFunc && !TypeCheckedLoadFunc->use_empty()) ||
1178 (TypeCheckedLoadRelativeFunc &&
1179 !TypeCheckedLoadRelativeFunc->use_empty()))
1181 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1183
1184
1185
1186 for (auto &P : ThinLTO.CombinedIndex) {
1187 for (auto &S : P.second.getSummaryList()) {
1189 if (!FS)
1190 continue;
1191 if (!FS->type_test_assume_vcalls().empty() ||
1192 !FS->type_checked_load_vcalls().empty() ||
1193 !FS->type_test_assume_const_vcalls().empty() ||
1194 !FS->type_checked_load_const_vcalls().empty() ||
1195 !FS->type_tests().empty())
1197 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",
1199 }
1200 }
1202}
1203
1205
1208 for (auto &Res : *GlobalResolutions) {
1209
1210
1211 if (Res.second.IRName.empty())
1212 continue;
1213
1216
1217 if (Res.second.VisibleOutsideSummary && Res.second.Prevailing)
1218 GUIDPreservedSymbols.insert(GUID);
1219
1220 if (Res.second.ExportDynamic)
1221 DynamicExportSymbols.insert(GUID);
1222
1223 GUIDPrevailingResolutions[GUID] =
1225 }
1226
1228 auto It = GUIDPrevailingResolutions.find(G);
1229 if (It == GUIDPrevailingResolutions.end())
1231 return It->second;
1232 };
1234 isPrevailing, Conf.OptLevel > 0);
1235
1236
1237 auto StatsFileOrErr = setupStatsFile(Conf.StatsFile);
1238 if (!StatsFileOrErr)
1239 return StatsFileOrErr.takeError();
1240 std::unique_ptr StatsFile = std::move(StatsFileOrErr.get());
1241
1242
1243
1244
1245
1246
1248 ThinLTO.CombinedIndex.setWithSupportsHotColdNew();
1249
1250 Error Result = runRegularLTO(AddStream);
1251 if (!Result)
1252
1253
1254 Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols);
1255
1256 if (StatsFile)
1258
1259 return Result;
1260}
1261
1264 LLVMContext &CombinedCtx = RegularLTO.CombinedModule->getContext();
1265
1270 if (!DiagFileOrErr)
1271 return DiagFileOrErr.takeError();
1272 DiagnosticOutputFile = std::move(*DiagFileOrErr);
1273
1274
1275
1276 {
1278 for (auto &M : RegularLTO.ModsWithSummaries)
1279 if (Error Err = linkRegularLTO(std::move(M), true))
1280 return Err;
1281 }
1282
1283
1284
1285
1286
1287 if (Error Err = checkPartiallySplit())
1288 return Err;
1289
1290
1291
1292 const DataLayout &DL = RegularLTO.CombinedModule->getDataLayout();
1293 for (auto &I : RegularLTO.Commons) {
1294 if (.second.Prevailing)
1295
1296 continue;
1297 GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(I.first);
1298 if (OldGV && DL.getTypeAllocSize(OldGV->getValueType()) == I.second.Size) {
1299
1300
1302 continue;
1303 }
1306 auto *GV = new GlobalVariable(*RegularLTO.CombinedModule, Ty, false,
1309 GV->setAlignment(I.second.Alignment);
1310 if (OldGV) {
1314 } else {
1316 }
1317 }
1318
1319 bool WholeProgramVisibilityEnabledInLTO =
1320 Conf.HasWholeProgramVisibility &&
1321
1322
1323 (!Conf.ValidateAllVtablesHaveTypeInfos || Conf.AllVtablesHaveTypeInfos);
1324
1325
1326
1327 auto IsVisibleToRegularObj = [&](StringRef name) {
1328 auto It = GlobalResolutions->find(name);
1329 return (It == GlobalResolutions->end() ||
1330 It->second.VisibleOutsideSummary || !It->second.Prevailing);
1331 };
1332
1333
1334
1336 *RegularLTO.CombinedModule, WholeProgramVisibilityEnabledInLTO,
1337 DynamicExportSymbols, Conf.ValidateAllVtablesHaveTypeInfos,
1338 IsVisibleToRegularObj);
1340 WholeProgramVisibilityEnabledInLTO);
1341
1342 if (Conf.PreOptModuleHook &&
1343 !Conf.PreOptModuleHook(0, *RegularLTO.CombinedModule))
1345
1346 if (!Conf.CodeGenOnly) {
1347 for (const auto &R : *GlobalResolutions) {
1348 GlobalValue *GV =
1349 RegularLTO.CombinedModule->getNamedValue(R.second.IRName);
1350 if (.second.isPrevailingIRSymbol())
1351 continue;
1352 if (R.second.Partition != 0 &&
1353 R.second.Partition != GlobalResolution::External)
1354 continue;
1355
1356
1357
1359 continue;
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1373 continue;
1374
1379 }
1380
1381 if (Conf.PostInternalizeModuleHook &&
1382 !Conf.PostInternalizeModuleHook(0, *RegularLTO.CombinedModule))
1384 }
1385
1386 if (!RegularLTO.EmptyCombinedModule || Conf.AlwaysEmitRegularLTOObj) {
1388 backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,
1389 *RegularLTO.CombinedModule, ThinLTO.CombinedIndex))
1390 return Err;
1391 }
1392
1394}
1395
1400
1404 }
1405
1406 return LibcallSymbols;
1407}
1408
1411 const std::string &NewModulePath) const {
1412 return emitFiles(ImportList, ModulePath, NewModulePath,
1413 NewModulePath + ".thinlto.bc",
1414 std::nullopt);
1415}
1416
1419 const std::string &NewModulePath, StringRef SummaryPath,
1420 std::optional<std::reference_wrapper> ImportsFiles)
1421 const {
1424
1425 std::error_code EC;
1427 ImportList, ModuleToSummariesForIndex,
1428 DeclarationSummaries);
1429
1431 if (EC)
1433
1435 &DeclarationSummaries);
1436
1439 ModulePath, NewModulePath + ".imports", ModuleToSummariesForIndex);
1440 if (ImportsFilesError)
1441 return ImportsFilesError;
1442 }
1443
1444
1445 if (ImportsFiles)
1447 ModulePath, ModuleToSummariesForIndex,
1448 [&](StringRef M) { ImportsFiles->get().push_back(M.str()); });
1449
1451}
1452
1453namespace {
1454
1455
1457protected:
1461 bool ShouldEmitIndexFiles;
1462
1463public:
1464 CGThinBackend(
1468 bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles,
1470 : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
1471 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
1472 AddStream(std::move(AddStream)),
1473 ShouldEmitIndexFiles(ShouldEmitIndexFiles) {
1477 CfiFunctionDecls.insert_range(Decls.guids());
1478 }
1479};
1480
1481
1482
1483class InProcessThinBackend : public CGThinBackend {
1484protected:
1486
1487public:
1488 InProcessThinBackend(
1493 bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles)
1494 : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
1495 AddStream, OnWrite, ShouldEmitIndexFiles,
1496 ShouldEmitImportsFiles, ThinLTOParallelism),
1497 Cache(std::move(Cache)) {}
1498
1499 virtual Error runThinLTOBackendThread(
1500 AddStreamFn AddStream, FileCache Cache, unsigned Task, BitcodeModule BM,
1501 ModuleSummaryIndex &CombinedIndex,
1502 const FunctionImporter::ImportMapTy &ImportList,
1504 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1506 MapVector<StringRef, BitcodeModule> &ModuleMap) {
1508 llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (in-process)",
1509 ModuleID);
1510 auto RunThinBackend = [&](AddStreamFn AddStream) {
1511 LTOLLVMContext BackendContext(Conf);
1512 Expected<std::unique_ptr> MOrErr = BM.parseModule(BackendContext);
1513 if (!MOrErr)
1515
1516 return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,
1517 ImportList, DefinedGlobals, &ModuleMap,
1519 };
1520 if (ShouldEmitIndexFiles) {
1521 if (auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1522 return E;
1523 }
1524
1527 [](uint32_t V) { return V == 0; }))
1528
1529
1530 return RunThinBackend(AddStream);
1531
1532
1534 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1535 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1536 Expected CacheAddStreamOrErr = Cache(Task, Key, ModuleID);
1538 return Err;
1539 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1540 if (CacheAddStream)
1541 return RunThinBackend(CacheAddStream);
1542
1544 }
1545
1547 unsigned Task, BitcodeModule BM,
1548 const FunctionImporter::ImportMapTy &ImportList,
1550 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1551 MapVector<StringRef, BitcodeModule> &ModuleMap) override {
1553 assert(ModuleToDefinedGVSummaries.count(ModulePath));
1555 ModuleToDefinedGVSummaries.find(ModulePath)->second;
1556 BackendThreadPool.async(
1557 [=](BitcodeModule BM, ModuleSummaryIndex &CombinedIndex,
1558 const FunctionImporter::ImportMapTy &ImportList,
1560 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
1561 &ResolvedODR,
1563 MapVector<StringRef, BitcodeModule> &ModuleMap) {
1566 "thin backend");
1567 Error E = runThinLTOBackendThread(
1568 AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList,
1569 ResolvedODR, DefinedGlobals, ModuleMap);
1570 if (E) {
1571 std::unique_lockstd::mutex L(ErrMu);
1572 if (Err)
1573 Err = joinErrors(std::move(*Err), std::move(E));
1574 else
1575 Err = std::move(E);
1576 }
1579 },
1580 BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList),
1581 std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap));
1582
1583 if (OnWrite)
1584 OnWrite(std::string(ModulePath));
1586 }
1587};
1588
1589
1590
1591
1592
1593
1594class FirstRoundThinBackend : public InProcessThinBackend {
1596 FileCache IRCache;
1597
1598public:
1599 FirstRoundThinBackend(
1600 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
1601 ThreadPoolStrategy ThinLTOParallelism,
1602 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
1604 FileCache IRCache)
1605 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
1606 ModuleToDefinedGVSummaries, std::move(CGAddStream),
1607 std::move(CGCache), nullptr,
1608 false,
1609 false),
1610 IRAddStream(std::move(IRAddStream)), IRCache(std::move(IRCache)) {}
1611
1612 Error runThinLTOBackendThread(
1613 AddStreamFn CGAddStream, FileCache CGCache, unsigned Task,
1614 BitcodeModule BM, ModuleSummaryIndex &CombinedIndex,
1615 const FunctionImporter::ImportMapTy &ImportList,
1617 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1619 MapVector<StringRef, BitcodeModule> &ModuleMap) override {
1621 llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (first round)",
1622 ModuleID);
1623 auto RunThinBackend = [&](AddStreamFn CGAddStream,
1625 LTOLLVMContext BackendContext(Conf);
1626 Expected<std::unique_ptr> MOrErr = BM.parseModule(BackendContext);
1627 if (!MOrErr)
1629
1630 return thinBackend(Conf, Task, CGAddStream, **MOrErr, CombinedIndex,
1631 ImportList, DefinedGlobals, &ModuleMap,
1633 };
1634
1635
1636
1637 if (ShouldEmitIndexFiles) {
1638 if (auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
1639 return E;
1640 }
1641
1643 "Both caches for CG and IR should have matching availability");
1646 [](uint32_t V) { return V == 0; }))
1647
1648
1649 return RunThinBackend(CGAddStream, IRAddStream);
1650
1651
1653 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1654 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1655 Expected CacheCGAddStreamOrErr =
1656 CGCache(Task, CGKey, ModuleID);
1658 return Err;
1659 AddStreamFn &CacheCGAddStream = *CacheCGAddStreamOrErr;
1660
1661
1663 Expected CacheIRAddStreamOrErr =
1664 IRCache(Task, IRKey, ModuleID);
1666 return Err;
1667 AddStreamFn &CacheIRAddStream = *CacheIRAddStreamOrErr;
1668
1669
1670
1671
1672
1673 if (CacheCGAddStream || CacheIRAddStream) {
1676 return RunThinBackend(CacheCGAddStream ? CacheCGAddStream : CGAddStream,
1677 CacheIRAddStream ? CacheIRAddStream : IRAddStream);
1678 }
1679
1681 }
1682};
1683
1684
1685
1686
1687
1688
1689class SecondRoundThinBackend : public InProcessThinBackend {
1690 std::unique_ptr<SmallVector> IRFiles;
1692
1693public:
1694 SecondRoundThinBackend(
1695 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
1696 ThreadPoolStrategy ThinLTOParallelism,
1697 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
1701 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
1702 ModuleToDefinedGVSummaries, std::move(AddStream),
1703 std::move(Cache),
1704 nullptr,
1705 false,
1706 false),
1707 IRFiles(std::move(IRFiles)), CombinedCGDataHash(CombinedCGDataHash) {}
1708
1709 Error runThinLTOBackendThread(
1710 AddStreamFn AddStream, FileCache Cache, unsigned Task, BitcodeModule BM,
1711 ModuleSummaryIndex &CombinedIndex,
1712 const FunctionImporter::ImportMapTy &ImportList,
1714 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1716 MapVector<StringRef, BitcodeModule> &ModuleMap) override {
1718 llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (second round)",
1719 ModuleID);
1720 auto RunThinBackend = [&](AddStreamFn AddStream) {
1721 LTOLLVMContext BackendContext(Conf);
1722 std::unique_ptr LoadedModule =
1724
1725 return thinBackend(Conf, Task, AddStream, *LoadedModule, CombinedIndex,
1726 ImportList, DefinedGlobals, &ModuleMap,
1727 true);
1728 };
1731 [](uint32_t V) { return V == 0; }))
1732
1733
1734 return RunThinBackend(AddStream);
1735
1736
1737
1739 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
1740 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
1742 std::to_string(CombinedCGDataHash));
1743 Expected CacheAddStreamOrErr = Cache(Task, Key, ModuleID);
1745 return Err;
1746 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
1747
1748 if (CacheAddStream) {
1749 LLVM_DEBUG(dbgs() << "[SecondRound] Cache Miss for "
1751 return RunThinBackend(CacheAddStream);
1752 }
1753
1755 }
1756};
1757}
1758
1761 bool ShouldEmitIndexFiles,
1762 bool ShouldEmitImportsFiles) {
1763 auto Func =
1767 return std::make_unique(
1768 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1769 AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
1770 ShouldEmitImportsFiles);
1771 };
1773}
1774
1777 return "";
1779 return "core2";
1781 return "yonah";
1783 return "apple-a12";
1786 return "cyclone";
1787 return "";
1788}
1789
1790
1791
1792
1795 if (OldPrefix.empty() && NewPrefix.empty())
1796 return std::string(Path);
1800 if (!ParentPath.empty()) {
1801
1803 llvm::errs() << "warning: could not create directory '" << ParentPath
1804 << "': " << EC.message() << '\n';
1805 }
1806 return std::string(NewPath);
1807}
1808
1809namespace {
1811 std::string OldPrefix, NewPrefix, NativeObjectPrefix;
1813
1814public:
1815 WriteIndexesThinBackend(
1819 std::string OldPrefix, std::string NewPrefix,
1820 std::string NativeObjectPrefix, bool ShouldEmitImportsFiles,
1822 : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
1823 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
1824 OldPrefix(OldPrefix), NewPrefix(NewPrefix),
1825 NativeObjectPrefix(NativeObjectPrefix),
1826 LinkedObjectsFile(LinkedObjectsFile) {}
1827
1832 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
1835
1836
1837
1838
1839
1840 if (LinkedObjectsFile) {
1841 std::string ObjectPrefix =
1842 NativeObjectPrefix.empty() ? NewPrefix : NativeObjectPrefix;
1843 std::string LinkedObjectsFilePath =
1845 *LinkedObjectsFile << LinkedObjectsFilePath << '\n';
1846 }
1847
1848 BackendThreadPool.async(
1849 [this](const StringRef ModulePath,
1850 const FunctionImporter::ImportMapTy &ImportList,
1851 const std::string &OldPrefix, const std::string &NewPrefix) {
1852 std::string NewModulePath =
1854 auto E = emitFiles(ImportList, ModulePath, NewModulePath);
1855 if (E) {
1856 std::unique_lockstd::mutex L(ErrMu);
1857 if (Err)
1858 Err = joinErrors(std::move(*Err), std::move(E));
1859 else
1860 Err = std::move(E);
1861 return;
1862 }
1863 },
1864 ModulePath, ImportList, OldPrefix, NewPrefix);
1865
1866 if (OnWrite)
1867 OnWrite(std::string(ModulePath));
1869 }
1870
1871 bool isSensitiveToInputOrder() override {
1872
1873
1874 return true;
1875 }
1876};
1877}
1878
1881 std::string NewPrefix, std::string NativeObjectPrefix,
1882 bool ShouldEmitImportsFiles, raw_fd_ostream *LinkedObjectsFile,
1884 auto Func =
1888 return std::make_unique(
1889 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
1890 OldPrefix, NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,
1891 LinkedObjectsFile, OnWrite);
1892 };
1894}
1895
1905 });
1906 if (ThinLTO.ModuleMap.empty())
1908
1909 if (ThinLTO.ModulesToCompile && ThinLTO.ModulesToCompile->empty()) {
1910 llvm::errs() << "warning: [ThinLTO] No module compiled\n";
1912 }
1913
1914 if (Conf.CombinedIndexHook &&
1915 !Conf.CombinedIndexHook(ThinLTO.CombinedIndex, GUIDPreservedSymbols))
1917
1918
1919
1920 DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries(
1921 ThinLTO.ModuleMap.size());
1922 ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule(
1923 ModuleToDefinedGVSummaries);
1924
1925
1926
1927
1928
1929
1930
1931 for (auto &Mod : ThinLTO.ModuleMap)
1932 if (!ModuleToDefinedGVSummaries.count(Mod.first))
1934
1935 FunctionImporter::ImportListsTy ImportLists(ThinLTO.ModuleMap.size());
1936 DenseMap<StringRef, FunctionImporter::ExportSetTy> ExportLists(
1937 ThinLTO.ModuleMap.size());
1938 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
1939
1941 ThinLTO.CombinedIndex.dumpSCCs(outs());
1942
1943 std::setGlobalValue::GUID ExportedGUIDs;
1944
1945 bool WholeProgramVisibilityEnabledInLTO =
1946 Conf.HasWholeProgramVisibility &&
1947
1948
1949 (!Conf.ValidateAllVtablesHaveTypeInfos || Conf.AllVtablesHaveTypeInfos);
1951 ThinLTO.CombinedIndex.setWithWholeProgramVisibility();
1952
1953
1954
1955
1956 DenseSetGlobalValue::GUID VisibleToRegularObjSymbols;
1957 if (WholeProgramVisibilityEnabledInLTO &&
1958 Conf.ValidateAllVtablesHaveTypeInfos) {
1959
1960
1961 auto IsVisibleToRegularObj = [&](StringRef name) {
1962 auto It = GlobalResolutions->find(name);
1963 return (It == GlobalResolutions->end() ||
1964 It->second.VisibleOutsideSummary || !It->second.Prevailing);
1965 };
1966
1968 VisibleToRegularObjSymbols,
1969 IsVisibleToRegularObj);
1970 }
1971
1972
1973
1975 ThinLTO.CombinedIndex, WholeProgramVisibilityEnabledInLTO,
1976 DynamicExportSymbols, VisibleToRegularObjSymbols);
1977
1978
1979
1980
1981 std::map<ValueInfo, std::vector> LocalWPDTargetsMap;
1983 LocalWPDTargetsMap);
1984
1986 return ThinLTO.isPrevailingModuleForGUID(GUID, S->modulePath());
1987 };
1989 MemProfContextDisambiguation ContextDisambiguation;
1990 ContextDisambiguation.run(ThinLTO.CombinedIndex, isPrevailing);
1991 }
1992
1993
1994
1995
1996
1997 for (auto &Res : *GlobalResolutions) {
1998
1999
2000 if (Res.second.Partition != GlobalResolution::External ||
2001 !Res.second.isPrevailingIRSymbol())
2002 continue;
2005
2006 if (ThinLTO.CombinedIndex.isGUIDLive(GUID))
2007 ExportedGUIDs.insert(GUID);
2008 }
2009
2010
2011
2012
2013
2014 releaseGlobalResolutionsMemory();
2015
2016 if (Conf.OptLevel > 0)
2018 isPrevailing, ImportLists, ExportLists);
2019
2020
2021
2022 auto &Defs = ThinLTO.CombinedIndex.cfiFunctionDefs();
2023 ExportedGUIDs.insert(Defs.guid_begin(), Defs.guid_end());
2024 auto &Decls = ThinLTO.CombinedIndex.cfiFunctionDecls();
2025 ExportedGUIDs.insert(Decls.guid_begin(), Decls.guid_end());
2026
2027 auto isExported = [&](StringRef ModuleIdentifier, ValueInfo VI) {
2028 const auto &ExportList = ExportLists.find(ModuleIdentifier);
2029 return (ExportList != ExportLists.end() && ExportList->second.count(VI)) ||
2030 ExportedGUIDs.count(VI.getGUID());
2031 };
2032
2033
2034
2036 LocalWPDTargetsMap);
2037
2039 isPrevailing);
2040
2041 auto recordNewLinkage = [&](StringRef ModuleIdentifier,
2044 ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
2045 };
2047 recordNewLinkage, GUIDPreservedSymbols);
2048
2050
2052
2055
2056 TimeTraceScopeExit.release();
2057
2058 auto &ModuleMap =
2059 ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;
2060
2061 auto RunBackends = [&](ThinBackendProc *BackendProcess) -> Error {
2062 auto ProcessOneModule = [&](int I) -> Error {
2063 auto &Mod = *(ModuleMap.begin() + I);
2064
2065
2066 return BackendProcess->start(
2067 RegularLTO.ParallelCodeGenParallelismLevel + I, Mod.second,
2068 ImportLists[Mod.first], ExportLists[Mod.first],
2069 ResolvedODR[Mod.first], ThinLTO.ModuleMap);
2070 };
2071
2072 BackendProcess->setup(ModuleMap.size(),
2073 RegularLTO.ParallelCodeGenParallelismLevel,
2074 RegularLTO.CombinedModule->getTargetTriple());
2075
2076 if (BackendProcess->getThreadCount() == 1 ||
2077 BackendProcess->isSensitiveToInputOrder()) {
2078
2079
2080
2081
2082
2083 for (int I = 0, E = ModuleMap.size(); I != E; ++I)
2084 if (Error E = ProcessOneModule(I))
2085 return E;
2086 } else {
2087
2088
2089
2090
2091 std::vector<BitcodeModule *> ModulesVec;
2092 ModulesVec.reserve(ModuleMap.size());
2093 for (auto &Mod : ModuleMap)
2094 ModulesVec.push_back(&Mod.second);
2096 if (Error E = ProcessOneModule(I))
2097 return E;
2098 }
2099 return BackendProcess->wait();
2100 };
2101
2103 std::unique_ptr BackendProc =
2104 ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
2105 AddStream, Cache);
2106 return RunBackends(BackendProc.get());
2107 }
2108
2109
2110
2111
2112
2113
2114 LLVM_DEBUG(dbgs() << "[TwoRounds] Initializing ThinLTO two-codegen rounds\n");
2115
2117 auto Parallelism = ThinLTO.Backend.getParallelism();
2118
2119
2120 cgdata::StreamCacheData CG(MaxTasks, Cache, "CG"), IR(MaxTasks, Cache, "IR");
2121
2122
2123
2124
2125 LLVM_DEBUG(dbgs() << "[TwoRounds] Running the first round of codegen\n");
2126 auto FirstRoundLTO = std::make_unique(
2127 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2128 CG.AddStream, CG.Cache, IR.AddStream, IR.Cache);
2129 if (Error E = RunBackends(FirstRoundLTO.get()))
2130 return E;
2131
2132 LLVM_DEBUG(dbgs() << "[TwoRounds] Merging codegen data\n");
2134 if (Error E = CombinedHashOrErr.takeError())
2135 return E;
2136 auto CombinedHash = *CombinedHashOrErr;
2137 LLVM_DEBUG(dbgs() << "[TwoRounds] CGData hash: " << CombinedHash << "\n");
2138
2139
2140
2141 LLVM_DEBUG(dbgs() << "[TwoRounds] Running the second round of codegen\n");
2142 auto SecondRoundLTO = std::make_unique(
2143 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2144 AddStream, Cache, IR.getResult(), CombinedHash);
2145 return RunBackends(SecondRoundLTO.get());
2146}
2147
2153
2154
2155 if (!Filename.empty() && Count != -1)
2156 Filename =
2158 .str();
2159
2163 if (Error E = ResultOrErr.takeError())
2164 return std::move(E);
2165
2166 if (*ResultOrErr)
2167 (*ResultOrErr)->keep();
2168
2169 return ResultOrErr;
2170}
2171
2174
2175 if (StatsFilename.empty())
2176 return nullptr;
2177
2179 std::error_code EC;
2180 auto StatsFile =
2181 std::make_unique(StatsFilename, EC, sys::fs::OF_None);
2182 if (EC)
2184
2185 StatsFile->keep();
2186 return std::move(StatsFile);
2187}
2188
2189
2190
2191
2194 std::vector ModulesOrdering(Seq.begin(), Seq.end());
2195 llvm::sort(ModulesOrdering, [&](int LeftIndex, int RightIndex) {
2196 auto LSize = R[LeftIndex]->getBuffer().size();
2197 auto RSize = R[RightIndex]->getBuffer().size();
2198 return LSize > RSize;
2199 });
2200 return ModulesOrdering;
2201}
2202
2203namespace {
2204
2205
2206
2207
2208
2209
2210class OutOfProcessThinBackend : public CGThinBackend {
2212
2215
2216 SString LinkerOutputFile;
2217
2218 SString DistributorPath;
2220
2221 SString RemoteCompiler;
2224
2225 bool SaveTemps;
2226
2229
2230 std::atomic<size_t> CachedJobs{0};
2231
2232 struct Job {
2233 unsigned Task;
2234 StringRef ModuleID;
2235 StringRef NativeObjectPath;
2236 StringRef SummaryIndexPath;
2238 std::string CacheKey;
2240 bool Cached = false;
2241 };
2242
2244
2245
2246 SmallString<8> UID;
2247
2248
2249 unsigned ThinLTOTaskOffset;
2250
2251
2252 llvm::Triple Triple;
2253
2254
2255 FileCache Cache;
2256
2257public:
2258 OutOfProcessThinBackend(
2259 const Config &Conf, ModuleSummaryIndex &CombinedIndex,
2260 ThreadPoolStrategy ThinLTOParallelism,
2261 const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
2263 bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles,
2264 StringRef LinkerOutputFile, StringRef Distributor,
2268 : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
2269 AddStream, OnWrite, ShouldEmitIndexFiles,
2270 ShouldEmitImportsFiles, ThinLTOParallelism),
2271 LinkerOutputFile(LinkerOutputFile), DistributorPath(Distributor),
2272 DistributorArgs(DistributorArgs), RemoteCompiler(RemoteCompiler),
2273 RemoteCompilerPrependArgs(RemoteCompilerPrependArgs),
2274 RemoteCompilerArgs(RemoteCompilerArgs), SaveTemps(SaveTemps),
2275 Cache(std::move(CacheFn)) {}
2276
2277 void setup(unsigned ThinLTONumTasks, unsigned ThinLTOTaskOffset,
2278 llvm::Triple Triple) override {
2280 Jobs.resize((size_t)ThinLTONumTasks);
2281 this->ThinLTOTaskOffset = ThinLTOTaskOffset;
2282 this->Triple = Triple;
2283 this->Conf.Dtlto = 1;
2284 }
2285
2286 virtual Error runThinLTOBackendThread(
2287 Job &J, const FunctionImporter::ImportMapTy &ImportList,
2289 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
2290 &ResolvedODR) {
2291
2292 llvm::TimeTraceScope timeScope(
2293 "Run ThinLTO backend thread (out-of-process)", J.ModuleID);
2294
2295 if (auto E = emitFiles(ImportList, J.ModuleID, J.ModuleID.str(),
2296 J.SummaryIndexPath, J.ImportsFiles))
2297 return E;
2298
2301 [](uint32_t V) { return V == 0; }))
2302
2303
2305
2307 ModuleToDefinedGVSummaries.find(J.ModuleID)->second;
2308
2309
2310 J.CacheKey = computeLTOCacheKey(Conf, CombinedIndex, J.ModuleID, ImportList,
2311 ExportList, ResolvedODR, DefinedGlobals,
2312 CfiFunctionDefs, CfiFunctionDecls);
2313
2314
2315 auto CacheAddStreamExp = Cache(J.Task, J.CacheKey, J.ModuleID);
2316 if (Error Err = CacheAddStreamExp.takeError())
2317 return Err;
2318 AddStreamFn &CacheAddStream = *CacheAddStreamExp;
2319
2320
2321 if (!CacheAddStream) {
2322 J.Cached = true;
2323 CachedJobs.fetch_add(1);
2324 } else {
2325
2326
2327
2328 J.CacheAddStream = std::move(CacheAddStream);
2329 }
2331 }
2332
2334 unsigned Task, BitcodeModule BM,
2335 const FunctionImporter::ImportMapTy &ImportList,
2337 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
2338 MapVector<StringRef, BitcodeModule> &ModuleMap) override {
2339
2341
2344 itostr(Task) + "." + UID + ".native.o");
2345
2346 Job &J = Jobs[Task - ThinLTOTaskOffset];
2347 J = {Task,
2348 ModulePath,
2349 Saver.save(ObjFilePath.str()),
2350 Saver.save(ObjFilePath.str() + ".thinlto.bc"),
2351 {},
2352 "",
2353 nullptr,
2354 false};
2355
2356 assert(ModuleToDefinedGVSummaries.count(ModulePath));
2357
2358
2359
2360 BackendThreadPool.async(
2361 [=](Job &J, const FunctionImporter::ImportMapTy &ImportList,
2363 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
2364 &ResolvedODR) {
2366 runThinLTOBackendThread(J, ImportList, ExportList, ResolvedODR);
2367 if (E) {
2368 std::unique_lockstd::mutex L(ErrMu);
2369 if (Err)
2370 Err = joinErrors(std::move(*Err), std::move(E));
2371 else
2372 Err = std::move(E);
2373 }
2374 },
2375 std::ref(J), std::ref(ImportList), std::ref(ExportList),
2376 std::ref(ResolvedODR));
2377
2379 }
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390 void buildCommonRemoteCompilerOptions() {
2391 const lto::Config &C = Conf;
2392 auto &Ops = CodegenOptions;
2393
2395
2396 if (C.Options.EmitAddrsig)
2397 Ops.push_back("-faddrsig");
2398 if (C.Options.FunctionSections)
2399 Ops.push_back("-ffunction-sections");
2400 if (C.Options.DataSections)
2401 Ops.push_back("-fdata-sections");
2402
2404
2406 Ops.push_back("-fpic");
2407
2408
2409
2410 if (.PGOWarnMismatch) {
2411 Ops.push_back("-mllvm");
2412 Ops.push_back("-no-pgo-warn-mismatch");
2413 }
2414
2415
2416
2417 if (.SampleProfile.empty()) {
2418 Ops.push_back(
2419 Saver.save("-fprofile-sample-use=" + Twine(C.SampleProfile)));
2420 CommonInputs.insert(C.SampleProfile);
2421 }
2422
2423
2424 Ops.push_back("-Wno-unused-command-line-argument");
2425
2426
2427 if (!RemoteCompilerArgs.empty())
2428 for (auto &a : RemoteCompilerArgs)
2429 Ops.push_back(a);
2430 }
2431
2432
2433
2434 bool emitDistributorJson(StringRef DistributorJson) {
2435 using json::Array;
2436 std::error_code EC;
2437 raw_fd_ostream OS(DistributorJson, EC);
2438 if (EC)
2439 return false;
2440
2441 json::OStream JOS(OS);
2442 JOS.object([&]() {
2443
2444 JOS.attributeObject("common", [&]() {
2445 JOS.attribute("linker_output", LinkerOutputFile);
2446
2447 JOS.attributeArray("args", [&]() {
2448 JOS.value(RemoteCompiler);
2449
2450
2451 if (!RemoteCompilerPrependArgs.empty())
2452 for (auto &A : RemoteCompilerPrependArgs)
2453 JOS.value(A);
2454
2455 JOS.value("-c");
2456
2457 JOS.value(Saver.save("--target=" + Triple.str()));
2458
2459 for (const auto &A : CodegenOptions)
2460 JOS.value(A);
2461 });
2462
2463 JOS.attribute("inputs", Array(CommonInputs));
2464 });
2465
2466
2467 JOS.attributeArray("jobs", [&]() {
2468 for (const auto &J : Jobs) {
2469 assert(J.Task != 0);
2470 if (J.Cached) {
2472 continue;
2473 }
2474
2476 SmallVector<StringRef, 1> Outputs;
2477
2478 JOS.object([&]() {
2479 JOS.attributeArray("args", [&]() {
2480 JOS.value(J.ModuleID);
2482
2483 JOS.value(
2484 Saver.save("-fthinlto-index=" + Twine(J.SummaryIndexPath)));
2485 Inputs.push_back(J.SummaryIndexPath);
2486
2487 JOS.value("-o");
2488 JOS.value(J.NativeObjectPath);
2489 Outputs.push_back(J.NativeObjectPath);
2490 });
2491
2492
2493
2494
2496 JOS.attribute("inputs", Array(Inputs));
2497
2498 JOS.attribute("outputs", Array(Outputs));
2499 });
2500 }
2501 });
2502 });
2503
2504 return true;
2505 }
2506
2507 void removeFile(StringRef FileName) {
2509 if (EC && EC != std::make_error_code(std::errc::no_such_file_or_directory))
2510 errs() << "warning: could not remove the file '" << FileName
2511 << "': " << EC.message() << "\n";
2512 }
2513
2514 Error wait() override {
2515
2516
2517 BackendThreadPool.wait();
2518 if (Err)
2519 return std::move(*Err);
2520
2522 if (!SaveTemps)
2523 for (auto &Job : Jobs) {
2524 removeFile(Job.NativeObjectPath);
2525 if (!ShouldEmitIndexFiles)
2526 removeFile(Job.SummaryIndexPath);
2527 }
2528 });
2529
2530 const StringRef BCError = "DTLTO backend compilation: ";
2531
2532 buildCommonRemoteCompilerOptions();
2533
2536 ".dist-file.json");
2537 if (!emitDistributorJson(JsonFile))
2539 BCError + "failed to generate distributor JSON script: " + JsonFile,
2542 if (!SaveTemps)
2543 removeFile(JsonFile);
2544 });
2545
2546
2547 if (CachedJobs.load() < Jobs.size()) {
2550 Args.push_back(JsonFile);
2551 std::string ErrMsg;
2553 std::nullopt, {},
2554 0, 0,
2555 &ErrMsg)) {
2557 BCError + "distributor execution failed" +
2558 (!ErrMsg.empty() ? ": " + ErrMsg + Twine(".") : Twine(".")),
2560 }
2561 }
2562
2563 for (auto &Job : Jobs) {
2564 if (!Job.CacheKey.empty() && Job.Cached) {
2566 continue;
2567 }
2568
2569
2570 auto ObjFileMbOrErr =
2572 false);
2573 if (std::error_code EC = ObjFileMbOrErr.getError())
2575 BCError + "cannot open native object file: " +
2576 Job.NativeObjectPath + ": " + EC.message(),
2578
2579 MemoryBufferRef ObjFileMbRef = ObjFileMbOrErr->get()->getMemBufferRef();
2581
2582
2583 assert(Job.CacheAddStream);
2584
2585 auto CachedFileStreamOrErr = Job.CacheAddStream(Job.Task, Job.ModuleID);
2586 if (!CachedFileStreamOrErr)
2588 CachedFileStreamOrErr.takeError(),
2590 "Cannot get a cache file stream: %s",
2591 Job.NativeObjectPath.data()));
2592
2593 auto &CacheStream = *(CachedFileStreamOrErr->get());
2594 *(CacheStream.OS) << ObjFileMbRef.getBuffer();
2595 if (Error Err = CacheStream.commit())
2596 return Err;
2597 } else {
2598 auto StreamOrErr = AddStream(Job.Task, Job.ModuleID);
2599 if (Error Err = StreamOrErr.takeError())
2601 auto &Stream = *StreamOrErr->get();
2602 *Stream.OS << ObjFileMbRef.getBuffer();
2603 if (Error Err = Stream.commit())
2605 }
2606 }
2608 }
2609};
2610}
2611
2614 bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles,
2619 auto Func =
2623 return std::make_unique(
2624 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
2625 AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
2626 ShouldEmitImportsFiles, LinkerOutputFile, Distributor,
2627 DistributorArgs, RemoteCompiler, RemoteCompilerPrependArgs,
2628 RemoteCompilerArgs, SaveTemps);
2629 };
2631}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file supports working with JSON data.
static void writeToResolutionFile(raw_ostream &OS, InputFile *Input, ArrayRef< SymbolResolution > Res)
Definition LTO.cpp:716
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)
Definition LTO.cpp:368
static void handleNonPrevailingComdat(GlobalValue &GV, std::set< const Comdat * > &NonPrevailingComdats)
Definition LTO.cpp:836
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)
Definition LTO.cpp:470
Legalize the Machine IR a function s Machine IR
Machine Check Debug Module
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...
This pass exposes codegen information to IR-level passes.
The Input class is used to parse a yaml document into in-memory structs and vectors.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
empty - Check if the array is empty.
const T & consume_front()
consume_front() - Returns the first element and drops it from ArrayRef.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Represents a module in a bitcode file.
StringRef getModuleIdentifier() const
LLVM_ABI Error readSummary(ModuleSummaryIndex &CombinedIndex, StringRef ModulePath, std::function< bool(GlobalValue::GUID)> IsPrevailing=nullptr)
Parse the specified bitcode buffer and merge its module summary index into CombinedIndex.
LLVM_ABI Expected< std::unique_ptr< Module > > parseModule(LLVMContext &Context, ParserCallbacks Callbacks={})
Read the entire bitcode module and return it.
LLVM_ABI Expected< std::unique_ptr< Module > > getLazyModule(LLVMContext &Context, bool ShouldLazyLoadMetadata, bool IsImporting, ParserCallbacks Callbacks={})
Read the bitcode module and prepare for lazy deserialization of function bodies.
static LLVM_ABI ConstantAggregateZero * get(Type *Ty)
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Implements a dense probed hash-table based set.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
The map maintains the list of imports.
DenseSet< ValueInfo > ExportSetTy
The set contains an entry for every global value that the module exports.
Function and variable summary information to aid decisions and implementation of importing.
static bool isAppendingLinkage(LinkageTypes Linkage)
static LLVM_ABI GUID getGUIDAssumingExternalLinkage(StringRef GlobalName)
Return a 64-bit global unique ID constructed from the name of a global symbol.
static bool isExternalWeakLinkage(LinkageTypes Linkage)
static bool isLocalLinkage(LinkageTypes Linkage)
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
void setUnnamedAddr(UnnamedAddr Val)
uint64_t GUID
Declare a type to represent a global unique identifier for a global value.
bool hasLocalLinkage() const
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
LLVM_ABI const Comdat * getComdat() const
static bool isLinkOnceLinkage(LinkageTypes Linkage)
void setLinkage(LinkageTypes LT)
DLLStorageClassTypes
Storage classes of global values for PE targets.
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
static bool isExternalLinkage(LinkageTypes Linkage)
VisibilityTypes
An enumeration for the kinds of visibility of global values.
@ DefaultVisibility
The GV is visible.
static LLVM_ABI std::string getGlobalIdentifier(StringRef Name, GlobalValue::LinkageTypes Linkage, StringRef FileName)
Return the modified name for a global value suitable to be used as the key for a global lookup (e....
static LinkageTypes getWeakLinkage(bool ODR)
static bool isWeakForLinker(LinkageTypes Linkage)
Whether the definition of this global may be replaced at link time.
bool hasAppendingLinkage() const
bool hasAvailableExternallyLinkage() const
LinkageTypes
An enumeration for the kinds of linkage for global values.
@ CommonLinkage
Tentative definitions.
@ InternalLinkage
Rename collisions when linking (static functions).
@ ExternalLinkage
Externally visible function.
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
@ AvailableExternallyLinkage
Available for inspection, not emission.
DLLStorageClassTypes getDLLStorageClass() const
Type * getValueType() const
static bool isLinkOnceODRLinkage(LinkageTypes Linkage)
LLVM_ABI void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
This is an important class for using LLVM in a threaded context.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
This class implements a map that also provides access to all stored values in a deterministic order.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
StringRef getBuffer() const
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
Class to hold module path string table and global value map, and encapsulate methods for operating on...
CfiFunctionIndex & cfiFunctionDecls()
void setPartiallySplitLTOUnits()
void releaseTemporaryMemory()
const ModuleHash & getModuleHash(const StringRef ModPath) const
Get the module SHA1 hash recorded for the given module path.
bool partiallySplitLTOUnits() const
const StringMap< ModuleHash > & modulePaths() const
Table of modules, containing module hash and id.
CfiFunctionIndex & cfiFunctionDefs()
LLVM_ABI void addModule(Module *M)
static LLVM_ABI void CollectAsmSymvers(const Module &M, function_ref< void(StringRef, StringRef)> AsmSymver)
Parse inline ASM and collect the symvers directives that are defined in the current module.
PointerUnion< GlobalValue *, AsmSymbol * > Symbol
LLVM_ABI uint32_t getSymbolFlags(Symbol S) const
ArrayRef< Symbol > symbols() const
A Module instance is used to store all the information related to an LLVM module.
A class that wrap the SHA1 algorithm.
LLVM_ABI void update(ArrayRef< uint8_t > Data)
Digest more data.
LLVM_ABI std::array< uint8_t, 20 > result()
Return the current raw 160-bits SHA1 for the digested data since the last call to init().
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef str() const
Explicit conversion to StringRef.
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
StringRef save(const char *S)
MCTargetOptions MCOptions
Machine level options.
DebuggerKind DebuggerTuning
Which debugger to tune for.
unsigned FunctionSections
Emit functions into separate sections.
unsigned DataSections
Emit data into separate sections.
This tells how a thread pool will be used.
The TimeTraceScope is a helper class to call the begin and end functions of the time trace profiler.
Triple - Helper class for working with autoconf configuration names.
bool isArm64e() const
Tests whether the target is the Apple "arm64e" AArch64 subarch.
ArchType getArch() const
Get the parsed architecture type of this triple.
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
const std::string & str() const
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, DriverKit, XROS, or bridgeOS).
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
std::pair< iterator, bool > insert(const ValueT &V)
iterator find(const_arg_type_t< ValueT > V)
void insert_range(Range &&R)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
An efficient, type-erasing, non-owning reference to a callable.
Ephemeral symbols produced by Reader::symbols() and Reader::module_symbols().
static LLVM_ABI Expected< std::unique_ptr< InputFile > > create(MemoryBufferRef Object)
Create an InputFile.
Definition LTO.cpp:568
ArrayRef< Symbol > symbols() const
A range over the symbols in this InputFile.
LLVM_ABI StringRef getName() const
Returns the path to the InputFile.
Definition LTO.cpp:597
LLVM_ABI BitcodeModule & getSingleBitcodeModule()
Definition LTO.cpp:601
LLVM_ABI LTO(Config Conf, ThinBackend Backend={}, unsigned ParallelCodeGenParallelismLevel=1, LTOKind LTOMode=LTOK_Default)
Create an LTO object.
Definition LTO.cpp:619
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.
Definition LTO.cpp:740
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...
Definition LTO.cpp:1396
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.
Definition LTO.cpp:1153
LLVM_ABI Error run(AddStreamFn AddStream, FileCache Cache={})
Runs the LTO pipeline.
Definition LTO.cpp:1204
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
Definition LTO.cpp:1409
ModuleSummaryIndex & CombinedIndex
A raw_ostream that writes to a file descriptor.
This class implements an extremely fast bulk output stream that can only output to a stream.
static LLVM_ABI Pid getProcessId()
Get the process's identifier.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI Function * getDeclarationIfExists(const Module *M, ID id)
Look up the Function declaration of the intrinsic id in the Module M and return it if it exists.
static auto libcall_impls()
LLVM_ABI Expected< stable_hash > mergeCodeGenData(ArrayRef< StringRef > ObjectFiles)
Merge the codegen data from the scratch objects ObjectFiles from the first codegen round.
LLVM_ABI std::unique_ptr< Module > loadModuleForTwoRounds(BitcodeModule &OrigModule, unsigned Task, LLVMContext &Context, ArrayRef< StringRef > IRFiles)
Load the optimized bitcode module for the second codegen round.
initializer< Ty > init(const Ty &Val)
LLVM_ABI ThinBackend createInProcessThinBackend(ThreadPoolStrategy Parallelism, IndexWriteCallback OnWrite=nullptr, bool ShouldEmitIndexFiles=false, bool ShouldEmitImportsFiles=false)
This ThinBackend runs the individual backend jobs in-process.
Definition LTO.cpp:1759
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.
Definition LTO.cpp:1793
LLVM_ABI StringLiteral getThinLTODefaultCPU(const Triple &TheTriple)
Definition LTO.cpp:1775
LLVM_ABI Expected< std::unique_ptr< ToolOutputFile > > setupStatsFile(StringRef StatsFilename)
Setups the output file for saving statistics.
Definition LTO.cpp:2173
LLVM_ABI ThinBackend createOutOfProcessThinBackend(ThreadPoolStrategy Parallelism, IndexWriteCallback OnWrite, bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles, StringRef LinkerOutputFile, StringRef Distributor, ArrayRef< StringRef > DistributorArgs, StringRef RemoteCompiler, ArrayRef< StringRef > RemoteCompilerPrependArgs, ArrayRef< StringRef > RemoteCompilerArgs, bool SaveTemps)
This ThinBackend generates the index shards and then runs the individual backend jobs via an external...
Definition LTO.cpp:2612
LLVM_ABI Error backend(const Config &C, AddStreamFn AddStream, unsigned ParallelCodeGenParallelismLevel, Module &M, ModuleSummaryIndex &CombinedIndex)
Runs a regular LTO backend.
std::function< void(const std::string &)> IndexWriteCallback
LLVM_ABI Error finalizeOptimizationRemarks(LLVMRemarkFileHandle DiagOutputFile)
LLVM_ABI ThinBackend createWriteIndexesThinBackend(ThreadPoolStrategy Parallelism, std::string OldPrefix, std::string NewPrefix, std::string NativeObjectPrefix, bool ShouldEmitImportsFiles, raw_fd_ostream *LinkedObjectsFile, IndexWriteCallback OnWrite)
This ThinBackend writes individual module indexes to files, instead of running the individual backend...
Definition LTO.cpp:1879
LLVM_ABI Expected< LLVMRemarkFileHandle > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::optional< uint64_t > RemarksHotnessThreshold=0, int Count=-1)
Setup optimization remarks.
Definition LTO.cpp:2148
LLVM_ABI std::vector< int > generateModulesOrdering(ArrayRef< BitcodeModule * > R)
Produces a container ordering for optimal multi-threaded processing.
Definition LTO.cpp:2192
LLVM_ABI Error thinBackend(const Config &C, unsigned Task, AddStreamFn AddStream, Module &M, const ModuleSummaryIndex &CombinedIndex, const FunctionImporter::ImportMapTy &ImportList, const GVSummaryMapTy &DefinedGlobals, MapVector< StringRef, BitcodeModule > *ModuleMap, bool CodeGenOnly, AddStreamFn IRAddStream=nullptr, const std::vector< uint8_t > &CmdArgs=std::vector< uint8_t >())
Runs a ThinLTO backend.
llvm::SmallVector< std::string > ImportsFilesContainer
LLVM_ABI Expected< IRSymtabFile > readIRSymtab(MemoryBufferRef MBRef)
Reads a bitcode file, creating its irsymtab if necessary.
DiagnosticInfoOptimizationBase::Argument NV
void write64le(void *P, uint64_t V)
void write32le(void *P, uint32_t V)
LLVM_ABI std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
LLVM_ABI std::error_code create_directories(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create all the non-existent directories in path.
LLVM_ABI StringRef stem(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get stem.
LLVM_ABI StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
LLVM_ABI bool replace_path_prefix(SmallVectorImpl< char > &Path, StringRef OldPrefix, StringRef NewPrefix, Style style=Style::native)
Replace matching path prefix with another path.
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
LLVM_ABI int ExecuteAndWait(StringRef Program, ArrayRef< StringRef > Args, std::optional< ArrayRef< StringRef > > Env=std::nullopt, ArrayRef< std::optional< StringRef > > Redirects={}, unsigned SecondsToWait=0, unsigned MemoryLimit=0, std::string *ErrMsg=nullptr, bool *ExecutionFailed=nullptr, std::optional< ProcessStatistics > *ProcStat=nullptr, BitVector *AffinityMask=nullptr)
This function executes the program using the arguments provided.
This is an optimization pass for GlobalISel generic memory operations.
ThreadPoolStrategy heavyweight_hardware_concurrency(unsigned ThreadCount=0)
Returns a thread strategy for tasks requiring significant memory or other resources.
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
cl::opt< std::string > RemarksFormat("lto-pass-remarks-format", cl::desc("The format used for serializing remarks (default: YAML)"), cl::value_desc("format"), cl::init("yaml"))
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
std::unordered_set< GlobalValueSummary * > GVSummaryPtrSet
A set of global value summary pointers.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
void generateParamAccessSummary(ModuleSummaryIndex &Index)
cl::opt< bool > CodeGenDataThinLTOTwoRounds("codegen-data-thinlto-two-rounds", cl::init(false), cl::Hidden, cl::desc("Enable two-round ThinLTO code generation. The first round " "emits codegen data, while the second round uses the emitted " "codegen data for further optimizations."))
Definition LTO.cpp:78
LLVM_ABI Expected< LLVMRemarkFileHandle > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::optional< uint64_t > RemarksHotnessThreshold=0)
Set up optimization remarks that output to a file.
cl::opt< std::string > RemarksPasses("lto-pass-remarks-filter", cl::desc("Only record optimization remarks from passes whose " "names match the given regular expression"), cl::value_desc("regex"))
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
DenseMap< GlobalValue::GUID, GlobalValueSummary * > GVSummaryMapTy
Map of global value GUID to its summary, used to identify values defined in a particular module,...
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present - Functionally identical to dyn_cast, except that a null (or none in the case ...
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
uint64_t stable_hash
An opaque object representing a stable hash code.
std::string utostr(uint64_t X, bool isNeg=false)
LLVM_ABI bool thinLTOPropagateFunctionAttrs(ModuleSummaryIndex &Index, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
Propagate function attributes for function summaries along the index's callgraph during thinlink.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
LLVM_ABI bool hasWholeProgramVisibility(bool WholeProgramVisibilityEnabledInLTO)
LLVM_ABI void writeIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out, const ModuleToSummariesForIndexTy *ModuleToSummariesForIndex=nullptr, const GVSummaryPtrSet *DecSummaries=nullptr)
Write the specified module summary index to the given raw output stream, where it will be written in ...
LLVM_ABI void ComputeCrossModuleImport(const ModuleSummaryIndex &Index, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, FunctionImporter::ImportListsTy &ImportLists, DenseMap< StringRef, FunctionImporter::ExportSetTy > &ExportLists)
Compute all the imports and exports for every module in the Index.
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI void EnableStatistics(bool DoPrintOnExit=true)
Enable the collection and printing of statistics.
LLVM_ABI void thinLTOInternalizeAndPromoteInIndex(ModuleSummaryIndex &Index, function_ref< bool(StringRef, ValueInfo)> isExported, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
Update the linkages in the given Index to mark exported values as external and non-exported values as...
Definition LTO.cpp:553
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.
Definition LTO.cpp:354
Error joinErrors(Error E1, Error E2)
Concatenate errors.
LLVM_ABI void updatePublicTypeTestCalls(Module &M, bool WholeProgramVisibilityEnabledInLTO)
LLVM_ABI void getVisibleToRegularObjVtableGUIDs(ModuleSummaryIndex &Index, DenseSet< GlobalValue::GUID > &VisibleToRegularObjSymbols, function_ref< bool(StringRef)> IsVisibleToRegularObj)
Based on typeID string, get all associated vtable GUIDS that are visible to regular objects.
void sort(IteratorTy Start, IteratorTy End)
bool timeTraceProfilerEnabled()
Is the time trace profiler enabled, i.e. initialized?
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
std::map< std::string, GVSummaryMapTy, std::less<> > ModuleToSummariesForIndexTy
Map of a module name to the GUIDs and summaries we will import from that module.
LLVM_ABI cl::opt< bool > EnableLTOInternalization
Enable global value internalization in LTO.
cl::opt< bool > RemarksWithHotness("lto-pass-remarks-with-hotness", cl::desc("With PGO, include profile count in optimization remarks"), cl::Hidden)
LLVM_ABI void timeTraceProfilerEnd()
Manually end the last time section.
cl::opt< std::string > RemarksFilename("lto-pass-remarks-output", cl::desc("Output filename for pass remarks"), cl::value_desc("filename"))
cl::opt< bool > SupportsHotColdNew
Indicate we are linking with an allocator that supports hot/cold operator new interfaces.
LLVM_ABI void updateIndexWPDForExports(ModuleSummaryIndex &Summary, function_ref< bool(StringRef, ValueInfo)> isExported, std::map< ValueInfo, std::vector< VTableSlotSummary > > &LocalWPDTargetsMap)
Call after cross-module importing to update the recorded single impl devirt target names for any loca...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI void thinLTOResolvePrevailingInIndex(const lto::Config &C, ModuleSummaryIndex &Index, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, function_ref< void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> recordNewLinkage, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols)
Resolve linkage for prevailing symbols in the Index.
Definition LTO.cpp:448
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Mod
The access may modify the value stored in memory.
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
cl::opt< bool > EnableMemProfContextDisambiguation
Enable MemProf context disambiguation for thin link.
LLVM_ABI void runWholeProgramDevirtOnIndex(ModuleSummaryIndex &Summary, std::set< GlobalValue::GUID > &ExportedGUIDs, std::map< ValueInfo, std::vector< VTableSlotSummary > > &LocalWPDTargetsMap)
Perform index-based whole program devirtualization on the Summary index.
cl::opt< bool > ForceImportAll
LLVM_ABI void gatherImportedSummariesForModule(StringRef ModulePath, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, const FunctionImporter::ImportMapTy &ImportList, ModuleToSummariesForIndexTy &ModuleToSummariesForIndex, GVSummaryPtrSet &DecSummaries)
Compute the set of summaries needed for a ThinLTO backend compilation of ModulePath.
ArrayRef(const T &OneElt) -> ArrayRef< T >
void toHex(ArrayRef< uint8_t > Input, bool LowerCase, SmallVectorImpl< char > &Output)
Convert buffer Input to its hexadecimal representation. The returned string is double the size of Inp...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void processImportsFiles(StringRef ModulePath, const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex, function_ref< void(const std::string &)> F)
Call F passing each of the files module ModulePath will import from.
cl::opt< std::optional< uint64_t >, false, remarks::HotnessThresholdParser > RemarksHotnessThreshold("lto-pass-remarks-hotness-threshold", cl::desc("Minimum profile count required for an " "optimization remark to be output." " Use 'auto' to apply the threshold from profile summary."), cl::value_desc("uint or 'auto'"), cl::init(0), cl::Hidden)
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
LLVM_ABI std::string computeLTOCacheKey(const lto::Config &Conf, const ModuleSummaryIndex &Index, StringRef ModuleID, const FunctionImporter::ImportMapTy &ImportList, const FunctionImporter::ExportSetTy &ExportList, const std::map< GlobalValue::GUID, GlobalValue::LinkageTypes > &ResolvedODR, const GVSummaryMapTy &DefinedGlobals, const DenseSet< GlobalValue::GUID > &CfiFunctionDefs={}, const DenseSet< GlobalValue::GUID > &CfiFunctionDecls={})
Computes a unique hash for the Module considering the current list of export/import and other global ...
Definition LTO.cpp:103
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
static cl::opt< bool > LTOKeepSymbolCopies("lto-keep-symbol-copies", cl::init(false), cl::Hidden, cl::desc("Keep copies of symbols in LTO indexing"))
LLVM_ABI bool UpgradeDebugInfo(Module &M)
Check the debug info version number, if it is out-dated, drop the debug info.
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
std::function< Expected< std::unique_ptr< CachedFileStream > >( unsigned Task, const Twine &ModuleName)> AddStreamFn
This type defines the callback to add a file that is generated on the fly.
LLVM_ABI void PrintStatisticsJSON(raw_ostream &OS)
Print statistics in JSON format.
LLVM_ABI void computeDeadSymbolsWithConstProp(ModuleSummaryIndex &Index, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols, function_ref< PrevailingType(GlobalValue::GUID)> isPrevailing, bool ImportEnabled)
Compute dead symbols and run constant propagation in combined index after that.
LLVM_ABI Error EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename, const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex)
Emit into OutputFilename the files module ModulePath will import from.
@ Keep
No function return thunk.
std::string itostr(int64_t X)
LLVM_ABI void updateVCallVisibilityInModule(Module &M, bool WholeProgramVisibilityEnabledInLTO, const DenseSet< GlobalValue::GUID > &DynamicExportSymbols, bool ValidateAllVtablesHaveTypeInfos, function_ref< bool(StringRef)> IsVisibleToRegularObj)
If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...
LLVM_ABI TimeTraceProfilerEntry * timeTraceProfilerBegin(StringRef Name, StringRef Detail)
Manually begin a time section, with the given Name and Detail.
LLVM_ABI void updateVCallVisibilityInIndex(ModuleSummaryIndex &Index, bool WholeProgramVisibilityEnabledInLTO, const DenseSet< GlobalValue::GUID > &DynamicExportSymbols, const DenseSet< GlobalValue::GUID > &VisibleToRegularObjSymbols)
If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...
Implement std::hash so that hash_code can be used in STL containers.
This type represents a file cache system that manages caching of files.
const std::string & getCacheDirectoryPath() const
A simple container for information about the supported runtime calls.
unsigned getNumAvailableLibcallImpls() const
bool isAvailable(RTLIB::LibcallImpl Impl) const
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl)
Get the libcall routine name for the specified libcall implementation.
Struct that holds a reference to a particular GUID in a global value summary.
std::optional< uint64_t > RemarksHotnessThreshold
The minimum hotness value a diagnostic needs in order to be included in optimization diagnostics.
std::optional< CodeModel::Model > CodeModel
bool CodeGenOnly
Disable entirely the optimizer, including importing for ThinLTO.
std::vector< std::string > MAttrs
std::vector< std::string > MllvmArgs
CodeGenOptLevel CGOptLevel
bool Dtlto
This flag is used as one of parameters to calculate cache entries and to ensure that in-process cache...
std::string DefaultTriple
Setting this field will replace unspecified target triples in input files with this triple.
std::string DwoDir
The directory to store .dwo files.
std::string RemarksFilename
Optimization remarks file path.
std::string OverrideTriple
Setting this field will replace target triples in input files with this triple.
std::string ProfileRemapping
Name remapping file for profile data.
bool TimeTraceEnabled
Time trace enabled.
std::string RemarksPasses
Optimization remarks pass filter.
std::string OptPipeline
If this field is set, the set of passes run in the middle-end optimizer will be the one specified by ...
unsigned TimeTraceGranularity
Time trace granularity.
bool RemarksWithHotness
Whether to emit optimization remarks with hotness informations.
std::optional< Reloc::Model > RelocModel
CodeGenFileType CGFileType
bool Freestanding
Flag to indicate that the optimizer should not assume builtins are present on the target.
std::string SampleProfile
Sample PGO profile path.
std::string RemarksFormat
The format used for serializing remarks (default: YAML).
The purpose of this struct is to only expose the symbol information that an LTO client should need in...
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.