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 (C)

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 && I.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 (R.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 (M.getComdatSymbolTable().empty())

1012 for (GlobalValue &GV : M.global_values())

1014

1015

1016

1017 if (M.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 (I.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 (R.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 (C.PGOWarnMismatch) {

2411 Ops.push_back("-mllvm");

2412 Ops.push_back("-no-pgo-warn-mismatch");

2413 }

2414

2415

2416

2417 if (C.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.