LLVM: lib/LTO/LTO.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

27#include "llvm/Config/llvm-config.h"

52#include "llvm/Support/VCSRevision.h"

60

61#include

62#include

63

64using namespace llvm;

65using namespace lto;

66using namespace object;

67

68#define DEBUG_TYPE "lto"

69

71

74 cl::desc("Dump the SCCs in the ThinLTO index's callgraph"));

75

77

78namespace llvm {

79

82 cl::desc("Enable global value internalization in LTO"));

83

86 cl::desc("Keep copies of symbols in LTO indexing"));

87

88

89

91

92

94}

95

96

97

98

103 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,

107

108

109

110

112

113

114 Hasher.update(LLVM_VERSION_STRING);

115#ifdef LLVM_REVISION

116 Hasher.update(LLVM_REVISION);

117#endif

118

119

120 auto AddString = [&](StringRef Str) {

123 };

124 auto AddUnsigned = [&](unsigned I) {

128 };

129 auto AddUint64 = [&](uint64_t I) {

133 };

134 auto AddUint8 = [&](const uint8_t I) {

136 };

137 AddString(Conf.CPU);

138

139

140

141

146 for (auto &A : Conf.MAttrs)

147 AddString(A);

150 else

151 AddUnsigned(-1);

154 else

155 AddUnsigned(-1);

156 for (const auto &S : Conf.MllvmArgs)

157 AddString(S);

158 AddUnsigned(static_cast<int>(Conf.CGOptLevel));

159 AddUnsigned(static_cast<int>(Conf.CGFileType));

166 AddString(Conf.DwoDir);

167

168

169 auto ModHash = Index.getModuleHash(ModuleID);

171

172

173

174 std::vector<uint64_t> ExportsGUID;

175 ExportsGUID.reserve(ExportList.size());

176 for (const auto &VI : ExportList)

177 ExportsGUID.push_back(VI.getGUID());

178

179

181 for (auto GUID : ExportsGUID)

183

184

185

186 auto Comp = [&](const std::pair<StringRef, GlobalValue::GUID> &L,

187 const std::pair<StringRef, GlobalValue::GUID> &R) {

188 return std::make_pair(Index.getModule(L.first)->second, L.second) <

189 std::make_pair(Index.getModule(R.first)->second, R.second);

190 };

192

193

195 for (const auto &[FromModule, GUID, Type] : SortedImportList)

196 ++ModuleToNumImports[FromModule];

197

198 std::optional LastModule;

199 for (const auto &[FromModule, GUID, Type] : SortedImportList) {

200 if (LastModule != FromModule) {

201

202

203

204 LastModule = FromModule;

205 auto ModHash = Index.getModule(FromModule)->second;

207 AddUint64(ModuleToNumImports[FromModule]);

208 }

209 AddUint64(GUID);

210 AddUint8(Type);

211 }

212

213

214 for (auto &Entry : ResolvedODR) {

219 }

220

221

222

223 std::setGlobalValue::GUID UsedCfiDefs;

224 std::setGlobalValue::GUID UsedCfiDecls;

225

226

227 std::setGlobalValue::GUID UsedTypeIds;

228

230 if (CfiFunctionDefs.contains(ValueGUID))

231 UsedCfiDefs.insert(ValueGUID);

232 if (CfiFunctionDecls.contains(ValueGUID))

233 UsedCfiDecls.insert(ValueGUID);

234 };

235

237 if (!GS) return;

238 AddUnsigned(GS->getVisibility());

239 AddUnsigned(GS->isLive());

240 AddUnsigned(GS->canAutoHide());

241 for (const ValueInfo &VI : GS->refs()) {

242 AddUnsigned(VI.isDSOLocal(Index.withDSOLocalPropagation()));

243 AddUsedCfiGlobal(VI.getGUID());

244 }

245 if (auto *GVS = dyn_cast(GS)) {

246 AddUnsigned(GVS->maybeReadOnly());

247 AddUnsigned(GVS->maybeWriteOnly());

248 }

249 if (auto *FS = dyn_cast(GS)) {

250 for (auto &TT : FS->type_tests())

251 UsedTypeIds.insert(TT);

252 for (auto &TT : FS->type_test_assume_vcalls())

253 UsedTypeIds.insert(TT.GUID);

254 for (auto &TT : FS->type_checked_load_vcalls())

255 UsedTypeIds.insert(TT.GUID);

256 for (auto &TT : FS->type_test_assume_const_vcalls())

257 UsedTypeIds.insert(TT.VFunc.GUID);

258 for (auto &TT : FS->type_checked_load_const_vcalls())

259 UsedTypeIds.insert(TT.VFunc.GUID);

260 for (auto &ET : FS->calls()) {

261 AddUnsigned(ET.first.isDSOLocal(Index.withDSOLocalPropagation()));

262 AddUsedCfiGlobal(ET.first.getGUID());

263 }

264 }

265 };

266

267

268

269 for (auto &GS : DefinedGlobals) {

273 AddUsedCfiGlobal(GS.first);

274 AddUsedThings(GS.second);

275 }

276

277

278

279 for (const auto &[FromModule, GUID, Type] : SortedImportList) {

281 AddUsedThings(S);

282

283

284 if (auto *AS = dyn_cast_or_null(S))

285 AddUsedThings(AS->getBaseObject());

286 }

287

289 AddString(TId);

290

291 AddUnsigned(S.TTRes.TheKind);

292 AddUnsigned(S.TTRes.SizeM1BitWidth);

293

294 AddUint64(S.TTRes.AlignLog2);

295 AddUint64(S.TTRes.SizeM1);

296 AddUint64(S.TTRes.BitMask);

297 AddUint64(S.TTRes.InlineBits);

298

299 AddUint64(S.WPDRes.size());

300 for (auto &WPD : S.WPDRes) {

301 AddUnsigned(WPD.first);

302 AddUnsigned(WPD.second.TheKind);

303 AddString(WPD.second.SingleImplName);

304

305 AddUint64(WPD.second.ResByArg.size());

306 for (auto &ByArg : WPD.second.ResByArg) {

307 AddUint64(ByArg.first.size());

308 for (uint64_t Arg : ByArg.first)

309 AddUint64(Arg);

310 AddUnsigned(ByArg.second.TheKind);

311 AddUint64(ByArg.second.Info);

312 AddUnsigned(ByArg.second.Byte);

313 AddUnsigned(ByArg.second.Bit);

314 }

315 }

316 };

317

318

320 auto TidIter = Index.typeIds().equal_range(TId);

321 for (const auto &I : make_range(TidIter))

322 AddTypeIdSummary(I.second.first, I.second.second);

323 }

324

325 AddUnsigned(UsedCfiDefs.size());

326 for (auto &V : UsedCfiDefs)

327 AddUint64(V);

328

329 AddUnsigned(UsedCfiDecls.size());

330 for (auto &V : UsedCfiDecls)

331 AddUint64(V);

332

335 if (FileOrErr) {

336 Hasher.update(FileOrErr.get()->getBuffer());

337

340 if (FileOrErr)

341 Hasher.update(FileOrErr.get()->getBuffer());

342 }

343 }

344 }

345

346 return toHex(Hasher.result());

347}

348

352

353 auto AddString = [&](StringRef Str) {

356 };

357 AddString(Key);

358 AddString(ExtraID);

359

360 return toHex(Hasher.result());

361}

362

367 isPrevailing,

369 recordNewLinkage,

372 C.VisibilityScheme == Config::ELF ? VI.getELFVisibility()

374 for (auto &S : VI.getSummaryList()) {

376

377

380 continue;

381

382

383

384

385

386

387

388

389 if (isPrevailing(VI.getGUID(), S.get())) {

393

394

395

396

397

398

399

400

401

402 S->setCanAutoHide(VI.canAutoHide() &&

403 !GUIDPreservedSymbols.count(VI.getGUID()));

404 }

406 Visibility = S->getVisibility();

407 }

408

409 else if (!isa(S.get()) &&

410 !GlobalInvolvedWithAlias.count(S.get()))

412

413

414

415

417 S->setVisibility(Visibility);

418

419 if (S->linkage() != OriginalLinkage)

420 recordNewLinkage(S->modulePath(), VI.getGUID(), S->linkage());

421 }

422

424 for (auto &S : VI.getSummaryList()) {

428 continue;

429 S->setVisibility(Visibility);

430 }

431 }

432}

433

434

435

436

437

438

439

443 isPrevailing,

445 recordNewLinkage,

447

448

449

451 for (auto &I : Index)

452 for (auto &S : I.second.SummaryList)

453 if (auto AS = dyn_cast(S.get()))

454 GlobalInvolvedWithAlias.insert(&AS->getAliasee());

455

456 for (auto &I : Index)

458 GlobalInvolvedWithAlias, isPrevailing,

459 recordNewLinkage, GUIDPreservedSymbols);

460}

461

465 isPrevailing) {

466 auto ExternallyVisibleCopies =

468 [](const std::unique_ptr &Summary) {

469 return !GlobalValue::isLocalLinkage(Summary->linkage());

470 });

471

472 for (auto &S : VI.getSummaryList()) {

473

474

475 if (isExported(S->modulePath(), VI)) {

478 continue;

479 }

480

481

483 continue;

484

485

488 continue;

489 }

490

491

492

493

494

495

496

497

498

499

500

501

502

503

504

505

506

507

508

509

510

511

512

513

514

515

516

517

518

519

520

521

522

523

524

525

526

527

528

529

532 continue;

533

534 if (isPrevailing(VI.getGUID(), S.get()) && ExternallyVisibleCopies == 1)

536 }

537}

538

539

540

545 isPrevailing) {

546 for (auto &I : Index)

548 isPrevailing);

549}

550

551

553

555 std::unique_ptr File(new InputFile);

556

558 if (!FOrErr)

560

561 File->TargetTriple = FOrErr->TheReader.getTargetTriple();

562 File->SourceFileName = FOrErr->TheReader.getSourceFileName();

563 File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts();

564 File->DependentLibraries = FOrErr->TheReader.getDependentLibraries();

565 File->ComdatTable = FOrErr->TheReader.getComdatTable();

566

567 for (unsigned I = 0; I != FOrErr->Mods.size(); ++I) {

568 size_t Begin = File->Symbols.size();

570 FOrErr->TheReader.module_symbols(I))

571

572

574 File->Symbols.push_back(Sym);

575 File->ModuleSymIndices.push_back({Begin, File->Symbols.size()});

576 }

577

578 File->Mods = FOrErr->Mods;

579 File->Strtab = std::move(FOrErr->Strtab);

580 return std::move(File);

581}

582

584 return Mods[0].getModuleIdentifier();

585}

586

588 assert(Mods.size() == 1 && "Expect only one bitcode module");

589 return Mods[0];

590}

591

592LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel,

594 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),

595 Ctx(Conf), CombinedModule(std::make_unique<Module>("ld-temp.o", Ctx)),

596 Mover(std::make_unique<IRMover>(*CombinedModule)) {

598}

599

600LTO::ThinLTOState::ThinLTOState(ThinBackend BackendParam)

601 : Backend(std::move(BackendParam)), CombinedIndex( false) {

602 if (!Backend.isValid())

603 Backend =

605}

606

608 unsigned ParallelCodeGenParallelismLevel, LTOKind LTOMode)

610 RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),

611 ThinLTO(std::move(Backend)),

612 GlobalResolutions(

614 LTOMode(LTOMode) {

616 Alloc = std::make_unique();

617 GlobalResolutionSymbolSaver = std::make_uniquellvm::StringSaver(*Alloc);

618 }

619}

620

621

623

624

625

628 unsigned Partition, bool InSummary) {

629 auto *ResI = Res.begin();

630 auto *ResE = Res.end();

631 (void)ResE;

632 const Triple TT(RegularLTO.CombinedModule->getTargetTriple());

634 assert(ResI != ResE);

636

638

639 if (GlobalResolutionSymbolSaver && !GlobalResolutions->contains(SymbolName))

640 SymbolName = GlobalResolutionSymbolSaver->save(SymbolName);

641

642 auto &GlobalRes = (*GlobalResolutions)[SymbolName];

643 GlobalRes.UnnamedAddr &= Sym.isUnnamedAddr();

645 assert(!GlobalRes.Prevailing &&

646 "Multiple prevailing defs are not allowed");

647 GlobalRes.Prevailing = true;

648 GlobalRes.IRName = std::string(Sym.getIRName());

649 } else if (!GlobalRes.Prevailing && GlobalRes.IRName.empty()) {

650

651

652

653

654

655

656 GlobalRes.IRName = std::string(Sym.getIRName());

657 }

658

659

660

661

662

663

664

665

666

667

668

669

670 if (GlobalRes.IRName != Sym.getIRName()) {

671 GlobalRes.Partition = GlobalResolution::External;

672 GlobalRes.VisibleOutsideSummary = true;

673 }

674

675

676

677

678

680 (GlobalRes.Partition != GlobalResolution::Unknown &&

681 GlobalRes.Partition != Partition)) {

682 GlobalRes.Partition = GlobalResolution::External;

683 } else

684

685 GlobalRes.Partition = Partition;

686

687

688

689 GlobalRes.VisibleOutsideSummary |=

691

693 }

694}

695

696void LTO::releaseGlobalResolutionsMemory() {

697

698 GlobalResolutions.reset();

699

700 GlobalResolutionSymbolSaver.reset();

701 Alloc.reset();

702}

703

707 OS << Path << '\n';

708 auto ResI = Res.begin();

712

713 OS << "-r=" << Path << ',' << Sym.getName() << ',';

715 OS << 'p';

717 OS << 'l';

719 OS << 'x';

721 OS << 'r';

722 OS << '\n';

723 }

726}

727

730 assert(!CalledGetMaxTasks);

731

734

735 if (RegularLTO.CombinedModule->getTargetTriple().empty()) {

736 RegularLTO.CombinedModule->setTargetTriple(Input->getTargetTriple());

739 }

740

742 for (unsigned I = 0; I != Input->Mods.size(); ++I)

743 if (Error Err = addModule(*Input, I, ResI, Res.end()))

744 return Err;

745

748}

749

754 if (!LTOInfo)

756

757 if (EnableSplitLTOUnit) {

758

759

760

761 if (*EnableSplitLTOUnit != LTOInfo->EnableSplitLTOUnit)

762 ThinLTO.CombinedIndex.setPartiallySplitLTOUnits();

763 } else

764 EnableSplitLTOUnit = LTOInfo->EnableSplitLTOUnit;

765

767

769 !LTOInfo->UnifiedLTO)

770 return make_error(

771 "unified LTO compilation must use "

772 "compatible bitcode modules (use -funified-lto)",

774

775 if (LTOInfo->UnifiedLTO && LTOMode == LTOK_Default)

777

779

780 auto ModSyms = Input.module_symbols(ModI);

781 addModuleToGlobalRes(ModSyms, {ResI, ResE},

782 IsThinLTO ? ThinLTO.ModuleMap.size() + 1 : 0,

783 LTOInfo->HasSummary);

784

785 if (IsThinLTO)

786 return addThinLTO(BM, ModSyms, ResI, ResE);

787

788 RegularLTO.EmptyCombinedModule = false;

790 addRegularLTO(BM, ModSyms, ResI, ResE);

791 if (!ModOrErr)

793

794 if (!LTOInfo->HasSummary)

795 return linkRegularLTO(std::move(*ModOrErr), false);

796

797

798

800 return Err;

801 RegularLTO.ModsWithSummaries.push_back(std::move(*ModOrErr));

803}

804

805

806

807

808

809

810

811

812

813

814

815static void

817 std::set<const Comdat *> &NonPrevailingComdats) {

819 if (C)

820 return;

821

822 if (!NonPrevailingComdats.count(C))

823 return;

824

825

826

827

828

830

831 if (auto GO = dyn_cast(&GV))

832 GO->setComdat(nullptr);

833}

834

835

836

837

842 RegularLTOState::AddedModule Mod;

844 BM.getLazyModule(RegularLTO.Ctx, true,

845 false);

846 if (!MOrErr)

849 Mod.M = std::move(*MOrErr);

850

851 if (Error Err = M.materializeMetadata())

852 return std::move(Err);

853

854

855

856

857

859 if (NamedMDNode *CfiFunctionsMD = M.getNamedMetadata("cfi.functions"))

860 M.eraseNamedMetadata(CfiFunctionsMD);

861

863

866

868 if (GV.hasAppendingLinkage())

869 Mod.Keep.push_back(&GV);

870

872 for (auto &GA : M.aliases())

874 AliasedGlobals.insert(GO);

875

876

877

878

879

880

881

882

883 auto MsymI = SymTab.symbols().begin(), MsymE = SymTab.symbols().end();

884 auto Skip = [&]() {

885 while (MsymI != MsymE) {

889 return;

890 ++MsymI;

891 }

892 };

894

895 std::set<const Comdat *> NonPrevailingComdats;

898 assert(ResI != ResE);

900

901 assert(MsymI != MsymE);

904

905 if (GlobalValue *GV = dyn_cast_if_present<GlobalValue *>(Msym)) {

907 if (Sym.isUndefined())

908 continue;

909 Mod.Keep.push_back(GV);

910

911

912

915

920 } else if (isa(GV) &&

921 (GV->hasLinkOnceODRLinkage() || GV->hasWeakODRLinkage() ||

922 GV->hasAvailableExternallyLinkage()) &&

923 !AliasedGlobals.count(cast(GV))) {

924

925

926

927

928

929 Mod.Keep.push_back(GV);

931 if (GV->hasComdat())

932 NonPrevailingComdats.insert(GV->getComdat());

933 cast(GV)->setComdat(nullptr);

934 }

935

936

938 GV->setDSOLocal(true);

939 if (GV->hasDLLImportStorageClass())

941 DefaultStorageClass);

942 }

943 } else if (auto *AS =

944 dyn_cast_if_present<ModuleSymbolTable::AsmSymbol *>(Msym)) {

945

947 NonPrevailingAsmSymbols.insert(AS->first);

948 } else {

950 }

951

952

953

954

955 if (Sym.isCommon()) {

956

957

958 auto &CommonRes = RegularLTO.Commons[std::string(Sym.getIRName())];

959 CommonRes.Size = std::max(CommonRes.Size, Sym.getCommonSize());

960 if (uint32_t SymAlignValue = Sym.getCommonAlignment()) {

961 CommonRes.Alignment =

962 std::max(Align(SymAlignValue), CommonRes.Alignment);

963 }

964 CommonRes.Prevailing |= Res.Prevailing;

965 }

966 }

967

968 if (M.getComdatSymbolTable().empty())

971

972

973

974 if (M.getModuleInlineAsm().empty()) {

975 std::string NewIA = ".lto_discard";

976 if (!NonPrevailingAsmSymbols.empty()) {

977

980 if (!NonPrevailingAsmSymbols.count(Alias))

981 NonPrevailingAsmSymbols.erase(Name);

982 });

983 NewIA += " " + llvm::join(NonPrevailingAsmSymbols, ", ");

984 }

985 NewIA += "\n";

986 M.setModuleInlineAsm(NewIA + M.getModuleInlineAsm());

987 }

988

989 assert(MsymI == MsymE);

990 return std::move(Mod);

991}

992

993Error LTO::linkRegularLTO(RegularLTOState::AddedModule Mod,

994 bool LivenessFromIndex) {

995 std::vector<GlobalValue *> Keep;

997 if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->getGUID())) {

998 if (Function *F = dyn_cast(GV)) {

999 if (DiagnosticOutputFile) {

1000 if (Error Err = F->materialize())

1001 return Err;

1005 << " not added to the combined module ");

1006 }

1007 }

1008 continue;

1009 }

1010

1012 Keep.push_back(GV);

1013 continue;

1014 }

1015

1016

1017

1019 RegularLTO.CombinedModule->getNamedValue(GV->getName());

1021 continue;

1022

1023 Keep.push_back(GV);

1024 }

1025

1026 return RegularLTO.Mover->move(std::move(Mod.M), Keep, nullptr,

1027 false);

1028}

1029

1030

1036 assert(ResITmp != ResE);

1038

1039 if (Sym.getIRName().empty()) {

1044 }

1045 }

1046

1050 return ThinLTO.PrevailingModuleForGUID[GUID] ==

1051 BM.getModuleIdentifier();

1052 }))

1053 return Err;

1055

1057 assert(ResI != ResE);

1059

1060 if (Sym.getIRName().empty()) {

1064 assert(ThinLTO.PrevailingModuleForGUID[GUID] ==

1066

1067

1068

1069

1070

1072 if (auto S = ThinLTO.CombinedIndex.findSummaryInModule(

1075 }

1076

1077

1078

1080 if (auto S = ThinLTO.CombinedIndex.findSummaryInModule(

1082 S->setDSOLocal(true);

1083 }

1084 }

1085 }

1086 }

1087

1088 if (!ThinLTO.ModuleMap.insert({BM.getModuleIdentifier(), BM}).second)

1089 return make_error(

1090 "Expected at most one ThinLTO module per bitcode file",

1092

1094 if (!ThinLTO.ModulesToCompile)

1095 ThinLTO.ModulesToCompile = ModuleMapType();

1096

1097

1102 << " to compile\n");

1103 }

1104 }

1105 }

1106

1108}

1109

1111 CalledGetMaxTasks = true;

1112 auto ModuleCount = ThinLTO.ModulesToCompile ? ThinLTO.ModulesToCompile->size()

1113 : ThinLTO.ModuleMap.size();

1114 return RegularLTO.ParallelCodeGenParallelismLevel + ModuleCount;

1115}

1116

1117

1118

1119Error LTO::checkPartiallySplit() {

1120 if (!ThinLTO.CombinedIndex.partiallySplitLTOUnits())

1122

1123 const Module *Combined = RegularLTO.CombinedModule.get();

1126 Function *TypeCheckedLoadFunc =

1129 Combined, Intrinsic::type_checked_load_relative);

1130

1131

1132

1133 if ((TypeTestFunc && !TypeTestFunc->use_empty()) ||

1134 (TypeCheckedLoadFunc && !TypeCheckedLoadFunc->use_empty()) ||

1135 (TypeCheckedLoadRelativeFunc &&

1136 !TypeCheckedLoadRelativeFunc->use_empty()))

1137 return make_error(

1138 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",

1140

1141

1142

1143 for (auto &P : ThinLTO.CombinedIndex) {

1144 for (auto &S : P.second.SummaryList) {

1145 auto *FS = dyn_cast(S.get());

1146 if (!FS)

1147 continue;

1148 if (!FS->type_test_assume_vcalls().empty() ||

1149 !FS->type_checked_load_vcalls().empty() ||

1150 !FS->type_test_assume_const_vcalls().empty() ||

1151 !FS->type_checked_load_const_vcalls().empty() ||

1152 !FS->type_tests().empty())

1153 return make_error(

1154 "inconsistent LTO Unit splitting (recompile with -fsplit-lto-unit)",

1156 }

1157 }

1159}

1160

1162

1165 for (auto &Res : *GlobalResolutions) {

1166

1167

1168 if (Res.second.IRName.empty())

1169 continue;

1170

1173

1174 if (Res.second.VisibleOutsideSummary && Res.second.Prevailing)

1175 GUIDPreservedSymbols.insert(GUID);

1176

1178 DynamicExportSymbols.insert(GUID);

1179

1180 GUIDPrevailingResolutions[GUID] =

1182 }

1183

1185 auto It = GUIDPrevailingResolutions.find(G);

1186 if (It == GUIDPrevailingResolutions.end())

1188 return It->second;

1189 };

1191 isPrevailing, Conf.OptLevel > 0);

1192

1193

1195 if (!StatsFileOrErr)

1196 return StatsFileOrErr.takeError();

1197 std::unique_ptr StatsFile = std::move(StatsFileOrErr.get());

1198

1199

1200

1201

1202

1203

1205 ThinLTO.CombinedIndex.setWithSupportsHotColdNew();

1206

1207 Error Result = runRegularLTO(AddStream);

1208 if (!Result)

1209

1210

1211 Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols);

1212

1213 if (StatsFile)

1215

1216 return Result;

1217}

1218

1221 if (Index.withSupportsHotColdNew())

1222 return;

1223

1224

1225

1226

1227

1228

1229 for (auto &F : Mod) {

1230 for (auto &BB : F) {

1231 for (auto &I : BB) {

1232 auto *CI = dyn_cast(&I);

1233 if (!CI)

1234 continue;

1235 if (CI->hasFnAttr("memprof"))

1236 CI->removeFnAttr("memprof");

1237

1238

1239

1240

1241

1242

1243 CI->setMetadata(LLVMContext::MD_memprof, nullptr);

1244 CI->setMetadata(LLVMContext::MD_callsite, nullptr);

1245 }

1246 }

1247 }

1248}

1249

1251

1253 RegularLTO.CombinedModule->getContext(), Conf.RemarksFilename,

1257 if (!DiagFileOrErr)

1258 return DiagFileOrErr.takeError();

1259 DiagnosticOutputFile = std::move(*DiagFileOrErr);

1260

1261

1262

1263 for (auto &M : RegularLTO.ModsWithSummaries)

1264 if (Error Err = linkRegularLTO(std::move(M),

1265 true))

1266 return Err;

1267

1268

1269

1270

1271

1272 if (Error Err = checkPartiallySplit())

1273 return Err;

1274

1275

1276

1277 const DataLayout &DL = RegularLTO.CombinedModule->getDataLayout();

1278 for (auto &I : RegularLTO.Commons) {

1279 if (I.second.Prevailing)

1280

1281 continue;

1282 GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(I.first);

1283 if (OldGV && DL.getTypeAllocSize(OldGV->getValueType()) == I.second.Size) {

1284

1285

1287 continue;

1288 }

1291 auto *GV = new GlobalVariable(*RegularLTO.CombinedModule, Ty, false,

1294 GV->setAlignment(I.second.Alignment);

1295 if (OldGV) {

1299 } else {

1301 }

1302 }

1303

1305

1306 bool WholeProgramVisibilityEnabledInLTO =

1308

1309

1311

1312

1313

1314 auto IsVisibleToRegularObj = [&](StringRef name) {

1315 auto It = GlobalResolutions->find(name);

1316 return (It == GlobalResolutions->end() || It->second.VisibleOutsideSummary);

1317 };

1318

1319

1320

1322 *RegularLTO.CombinedModule, WholeProgramVisibilityEnabledInLTO,

1324 IsVisibleToRegularObj);

1326 WholeProgramVisibilityEnabledInLTO);

1327

1331

1333 for (const auto &R : *GlobalResolutions) {

1335 RegularLTO.CombinedModule->getNamedValue(R.second.IRName);

1336 if (R.second.isPrevailingIRSymbol())

1337 continue;

1338 if (R.second.Partition != 0 &&

1339 R.second.Partition != GlobalResolution::External)

1340 continue;

1341

1342

1343

1345 continue;

1346

1347

1348

1349

1350

1351

1352

1353

1354

1355

1359 continue;

1360

1365 }

1366

1370 }

1371

1374 backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,

1375 *RegularLTO.CombinedModule, ThinLTO.CombinedIndex))

1376 return Err;

1377 }

1378

1380}

1381

1386 [](const char *Name) { return Name; });

1387 return LibcallSymbols;

1388}

1389

1392 const std::string &NewModulePath) const {

1395

1396 std::error_code EC;

1398 ImportList, ModuleToSummariesForIndex,

1399 DeclarationSummaries);

1400

1403 if (EC)

1404 return createFileError("cannot open " + NewModulePath + ".thinlto.bc", EC);

1405

1407 &DeclarationSummaries);

1408

1411 ModulePath, NewModulePath + ".imports", ModuleToSummariesForIndex);

1412 if (ImportFilesError)

1413 return ImportFilesError;

1414 }

1416}

1417

1418namespace {

1420protected:

1425

1426 bool ShouldEmitIndexFiles;

1427

1428public:

1429 InProcessThinBackend(

1434 bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles)

1435 : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries,

1436 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),

1437 AddStream(std::move(AddStream)), Cache(std::move(Cache)),

1438 ShouldEmitIndexFiles(ShouldEmitIndexFiles) {

1440 CfiFunctionDefs.insert(

1443 CfiFunctionDecls.insert(

1445 }

1446

1447 virtual Error runThinLTOBackendThread(

1452 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,

1455 auto RunThinBackend = [&](AddStreamFn AddStream) {

1458 if (!MOrErr)

1460

1461 return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,

1462 ImportList, DefinedGlobals, &ModuleMap,

1464 };

1465

1467

1468 if (ShouldEmitIndexFiles) {

1469 if (auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))

1470 return E;

1471 }

1472

1475 [](uint32_t V) { return V == 0; }))

1476

1477

1478 return RunThinBackend(AddStream);

1479

1480

1482 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,

1483 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);

1486 return Err;

1487 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;

1488 if (CacheAddStream)

1489 return RunThinBackend(CacheAddStream);

1490

1492 }

1493

1498 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,

1501 assert(ModuleToDefinedGVSummaries.count(ModulePath));

1503 ModuleToDefinedGVSummaries.find(ModulePath)->second;

1504 BackendThreadPool.async(

1508 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>

1509 &ResolvedODR,

1514 "thin backend");

1515 Error E = runThinLTOBackendThread(

1516 AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList,

1517 ResolvedODR, DefinedGlobals, ModuleMap);

1518 if (E) {

1519 std::unique_lockstd::mutex L(ErrMu);

1520 if (Err)

1521 Err = joinErrors(std::move(*Err), std::move(E));

1522 else

1523 Err = std::move(E);

1524 }

1527 },

1528 BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList),

1529 std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap));

1530

1531 if (OnWrite)

1532 OnWrite(std::string(ModulePath));

1534 }

1535};

1536

1537

1538

1539

1540

1541

1542class FirstRoundThinBackend : public InProcessThinBackend {

1545

1546public:

1547 FirstRoundThinBackend(

1553 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,

1554 ModuleToDefinedGVSummaries, std::move(CGAddStream),

1555 std::move(CGCache), nullptr,

1556 false,

1557 false),

1558 IRAddStream(std::move(IRAddStream)), IRCache(std::move(IRCache)) {}

1559

1560 Error runThinLTOBackendThread(

1565 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,

1568 auto RunThinBackend = [&](AddStreamFn CGAddStream,

1572 if (!MOrErr)

1574

1575 return thinBackend(Conf, Task, CGAddStream, **MOrErr, CombinedIndex,

1576 ImportList, DefinedGlobals, &ModuleMap,

1578 };

1579

1581

1582

1583

1584 if (ShouldEmitIndexFiles) {

1585 if (auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))

1586 return E;

1587 }

1588

1590 "Both caches for CG and IR should have matching availability");

1593 [](uint32_t V) { return V == 0; }))

1594

1595

1596 return RunThinBackend(CGAddStream, IRAddStream);

1597

1598

1600 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,

1601 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);

1603 CGCache(Task, CGKey, ModuleID);

1605 return Err;

1606 AddStreamFn &CacheCGAddStream = *CacheCGAddStreamOrErr;

1607

1608

1611 IRCache(Task, IRKey, ModuleID);

1613 return Err;

1614 AddStreamFn &CacheIRAddStream = *CacheIRAddStreamOrErr;

1615

1616

1617

1618

1619

1620 if (CacheCGAddStream || CacheIRAddStream) {

1623 return RunThinBackend(CacheCGAddStream ? CacheCGAddStream : CGAddStream,

1624 CacheIRAddStream ? CacheIRAddStream : IRAddStream);

1625 }

1626

1628 }

1629};

1630

1631

1632

1633

1634

1635

1636class SecondRoundThinBackend : public InProcessThinBackend {

1637 std::unique_ptr<SmallVector> IRFiles;

1639

1640public:

1641 SecondRoundThinBackend(

1648 : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,

1649 ModuleToDefinedGVSummaries, std::move(AddStream),

1651 nullptr,

1652 false,

1653 false),

1654 IRFiles(std::move(IRFiles)), CombinedCGDataHash(CombinedCGDataHash) {}

1655

1656 virtual Error runThinLTOBackendThread(

1661 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,

1664 auto RunThinBackend = [&](AddStreamFn AddStream) {

1666 std::unique_ptr LoadedModule =

1668

1669 return thinBackend(Conf, Task, AddStream, *LoadedModule, CombinedIndex,

1670 ImportList, DefinedGlobals, &ModuleMap,

1671 true);

1672 };

1673

1677 [](uint32_t V) { return V == 0; }))

1678

1679

1680 return RunThinBackend(AddStream);

1681

1682

1683

1685 Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,

1686 DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);

1688 std::to_string(CombinedCGDataHash));

1691 return Err;

1692 AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;

1693

1694 if (CacheAddStream) {

1695 LLVM_DEBUG(dbgs() << "[SecondRound] Cache Miss for "

1697 return RunThinBackend(CacheAddStream);

1698 }

1699

1701 }

1702};

1703}

1704

1707 bool ShouldEmitIndexFiles,

1708 bool ShouldEmitImportsFiles) {

1709 auto Func =

1713 return std::make_unique(

1714 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,

1715 AddStream, Cache, OnWrite, ShouldEmitIndexFiles,

1716 ShouldEmitImportsFiles);

1717 };

1719}

1720

1723 return "";

1725 return "core2";

1727 return "yonah";

1729 return "apple-a12";

1732 return "cyclone";

1733 return "";

1734}

1735

1736

1737

1738

1741 if (OldPrefix.empty() && NewPrefix.empty())

1742 return std::string(Path);

1746 if (!ParentPath.empty()) {

1747

1749 llvm::errs() << "warning: could not create directory '" << ParentPath

1750 << "': " << EC.message() << '\n';

1751 }

1752 return std::string(NewPath);

1753}

1754

1755namespace {

1757 std::string OldPrefix, NewPrefix, NativeObjectPrefix;

1759

1760public:

1761 WriteIndexesThinBackend(

1765 std::string OldPrefix, std::string NewPrefix,

1766 std::string NativeObjectPrefix, bool ShouldEmitImportsFiles,

1768 : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries,

1769 OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),

1770 OldPrefix(OldPrefix), NewPrefix(NewPrefix),

1771 NativeObjectPrefix(NativeObjectPrefix),

1772 LinkedObjectsFile(LinkedObjectsFile) {}

1773

1778 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,

1781

1782

1783

1784

1785

1786 if (LinkedObjectsFile) {

1787 std::string ObjectPrefix =

1788 NativeObjectPrefix.empty() ? NewPrefix : NativeObjectPrefix;

1789 std::string LinkedObjectsFilePath =

1791 *LinkedObjectsFile << LinkedObjectsFilePath << '\n';

1792 }

1793

1794 BackendThreadPool.async(

1795 [this](const StringRef ModulePath,

1797 const std::string &OldPrefix, const std::string &NewPrefix) {

1798 std::string NewModulePath =

1800 auto E = emitFiles(ImportList, ModulePath, NewModulePath);

1801 if (E) {

1802 std::unique_lockstd::mutex L(ErrMu);

1803 if (Err)

1804 Err = joinErrors(std::move(*Err), std::move(E));

1805 else

1806 Err = std::move(E);

1807 return;

1808 }

1809 },

1810 ModulePath, ImportList, OldPrefix, NewPrefix);

1811

1812 if (OnWrite)

1813 OnWrite(std::string(ModulePath));

1815 }

1816

1817 bool isSensitiveToInputOrder() override {

1818

1819

1820 return true;

1821 }

1822};

1823}

1824

1827 std::string NewPrefix, std::string NativeObjectPrefix,

1828 bool ShouldEmitImportsFiles, raw_fd_ostream *LinkedObjectsFile,

1830 auto Func =

1834 return std::make_unique(

1835 Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,

1836 OldPrefix, NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,

1837 LinkedObjectsFile, OnWrite);

1838 };

1840}

1841

1845 ThinLTO.CombinedIndex.releaseTemporaryMemory();

1850 });

1851 if (ThinLTO.ModuleMap.empty())

1853

1854 if (ThinLTO.ModulesToCompile && ThinLTO.ModulesToCompile->empty()) {

1855 llvm::errs() << "warning: [ThinLTO] No module compiled\n";

1857 }

1858

1860 !Conf.CombinedIndexHook(ThinLTO.CombinedIndex, GUIDPreservedSymbols))

1862

1863

1864

1866 ThinLTO.ModuleMap.size());

1867 ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule(

1868 ModuleToDefinedGVSummaries);

1869

1870

1871

1872

1873

1874

1875

1876 for (auto &Mod : ThinLTO.ModuleMap)

1877 if (!ModuleToDefinedGVSummaries.count(Mod.first))

1879

1882 ThinLTO.ModuleMap.size());

1884

1886 ThinLTO.CombinedIndex.dumpSCCs(outs());

1887

1888 std::setGlobalValue::GUID ExportedGUIDs;

1889

1890 bool WholeProgramVisibilityEnabledInLTO =

1892

1893

1896 ThinLTO.CombinedIndex.setWithWholeProgramVisibility();

1897

1898

1899

1900

1902 if (WholeProgramVisibilityEnabledInLTO &&

1904

1905

1906 auto IsVisibleToRegularObj = [&](StringRef name) {

1907 auto It = GlobalResolutions->find(name);

1908 return (It == GlobalResolutions->end() ||

1909 It->second.VisibleOutsideSummary);

1910 };

1911

1913 VisibleToRegularObjSymbols,

1914 IsVisibleToRegularObj);

1915 }

1916

1917

1918

1920 ThinLTO.CombinedIndex, WholeProgramVisibilityEnabledInLTO,

1921 DynamicExportSymbols, VisibleToRegularObjSymbols);

1922

1923

1924

1925

1926 std::map<ValueInfo, std::vector> LocalWPDTargetsMap;

1928 LocalWPDTargetsMap);

1929

1931 return ThinLTO.PrevailingModuleForGUID[GUID] == S->modulePath();

1932 };

1935 ContextDisambiguation.run(ThinLTO.CombinedIndex, isPrevailing);

1936 }

1937

1938

1939

1940

1941

1942 for (auto &Res : *GlobalResolutions) {

1943

1944

1945 if (Res.second.Partition != GlobalResolution::External ||

1946 !Res.second.isPrevailingIRSymbol())

1947 continue;

1950

1951 if (ThinLTO.CombinedIndex.isGUIDLive(GUID))

1952 ExportedGUIDs.insert(GUID);

1953 }

1954

1955

1956

1957

1958

1959 releaseGlobalResolutionsMemory();

1960

1963 isPrevailing, ImportLists, ExportLists);

1964

1965

1966

1967 for (auto &Def : ThinLTO.CombinedIndex.cfiFunctionDefs())

1968 ExportedGUIDs.insert(

1970 for (auto &Decl : ThinLTO.CombinedIndex.cfiFunctionDecls())

1971 ExportedGUIDs.insert(

1973

1975 const auto &ExportList = ExportLists.find(ModuleIdentifier);

1976 return (ExportList != ExportLists.end() && ExportList->second.count(VI)) ||

1977 ExportedGUIDs.count(VI.getGUID());

1978 };

1979

1980

1981

1983 LocalWPDTargetsMap);

1984

1986 isPrevailing);

1987

1988 auto recordNewLinkage = [&](StringRef ModuleIdentifier,

1991 ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;

1992 };

1994 recordNewLinkage, GUIDPreservedSymbols);

1995

1997

1999

2002

2003 TimeTraceScopeExit.release();

2004

2005 auto &ModuleMap =

2006 ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;

2007

2009 auto ProcessOneModule = [&](int I) -> Error {

2010 auto &Mod = *(ModuleMap.begin() + I);

2011

2012

2013 return BackendProcess->start(

2014 RegularLTO.ParallelCodeGenParallelismLevel + I, Mod.second,

2015 ImportLists[Mod.first], ExportLists[Mod.first],

2016 ResolvedODR[Mod.first], ThinLTO.ModuleMap);

2017 };

2018

2019 if (BackendProcess->getThreadCount() == 1 ||

2020 BackendProcess->isSensitiveToInputOrder()) {

2021

2022

2023

2024

2025

2026 for (int I = 0, E = ModuleMap.size(); I != E; ++I)

2027 if (Error E = ProcessOneModule(I))

2028 return E;

2029 } else {

2030

2031

2032

2033

2034 std::vector<BitcodeModule *> ModulesVec;

2035 ModulesVec.reserve(ModuleMap.size());

2036 for (auto &Mod : ModuleMap)

2037 ModulesVec.push_back(&Mod.second);

2039 if (Error E = ProcessOneModule(I))

2040 return E;

2041 }

2042 return BackendProcess->wait();

2043 };

2044

2046 std::unique_ptr BackendProc =

2047 ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,

2048 AddStream, Cache);

2049 return RunBackends(BackendProc.get());

2050 }

2051

2052

2053

2054

2055

2056

2057 LLVM_DEBUG(dbgs() << "[TwoRounds] Initializing ThinLTO two-codegen rounds\n");

2058

2060 auto Parallelism = ThinLTO.Backend.getParallelism();

2061

2062

2064

2065

2066

2067

2068 LLVM_DEBUG(dbgs() << "[TwoRounds] Running the first round of codegen\n");

2069 auto FirstRoundLTO = std::make_unique(

2070 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,

2071 CG.AddStream, CG.Cache, IR.AddStream, IR.Cache);

2072 if (Error E = RunBackends(FirstRoundLTO.get()))

2073 return E;

2074

2075 LLVM_DEBUG(dbgs() << "[TwoRounds] Merging codegen data\n");

2077 if (Error E = CombinedHashOrErr.takeError())

2078 return E;

2079 auto CombinedHash = *CombinedHashOrErr;

2080 LLVM_DEBUG(dbgs() << "[TwoRounds] CGData hash: " << CombinedHash << "\n");

2081

2082

2083

2084 LLVM_DEBUG(dbgs() << "[TwoRounds] Running the second round of codegen\n");

2085 auto SecondRoundLTO = std::make_unique(

2086 Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,

2087 AddStream, Cache, IR.getResult(), CombinedHash);

2088 return RunBackends(SecondRoundLTO.get());

2089}

2090

2096

2097

2098 if (!Filename.empty() && Count != -1)

2099 Filename =

2100 (Twine(Filename) + ".thin." + llvm::utostr(Count) + "." + RemarksFormat)

2101 .str();

2102

2106 if (Error E = ResultOrErr.takeError())

2107 return std::move(E);

2108

2109 if (*ResultOrErr)

2110 (*ResultOrErr)->keep();

2111

2112 return ResultOrErr;

2113}

2114

2117

2118 if (StatsFilename.empty())

2119 return nullptr;

2120

2122 std::error_code EC;

2123 auto StatsFile =

2124 std::make_unique(StatsFilename, EC, sys::fs::OF_None);

2125 if (EC)

2127

2128 StatsFile->keep();

2129 return std::move(StatsFile);

2130}

2131

2132

2133

2134

2136 auto Seq = llvm::seq(0, R.size());

2137 std::vector ModulesOrdering(Seq.begin(), Seq.end());

2138 llvm::sort(ModulesOrdering, [&](int LeftIndex, int RightIndex) {

2139 auto LSize = R[LeftIndex]->getBuffer().size();

2140 auto RSize = R[RightIndex]->getBuffer().size();

2141 return LSize > RSize;

2142 });

2143 return ModulesOrdering;

2144}

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

cl::opt< bool > CodeGenDataThinLTOTwoRounds("codegen-data-thinlto-two-rounds", cl::init(false), cl::Hidden, cl::desc("Enable two-round ThinLTO code generation. The first round " "emits codegen data, while the second round uses the emitted " "codegen data for further optimizations."))

static void writeToResolutionFile(raw_ostream &OS, InputFile *Input, ArrayRef< SymbolResolution > Res)

static void thinLTOResolvePrevailingGUID(const Config &C, ValueInfo VI, DenseSet< GlobalValueSummary * > &GlobalInvolvedWithAlias, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, function_ref< void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> recordNewLinkage, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols)

static void handleNonPrevailingComdat(GlobalValue &GV, std::set< const Comdat * > &NonPrevailingComdats)

cl::opt< bool > CodeGenDataThinLTOTwoRounds

static cl::opt< bool > DumpThinCGSCCs("dump-thin-cg-sccs", cl::init(false), cl::Hidden, cl::desc("Dump the SCCs in the ThinLTO index's callgraph"))

static void thinLTOInternalizeAndPromoteGUID(ValueInfo VI, function_ref< bool(StringRef, ValueInfo)> isExported, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)

cl::opt< bool > UseNewDbgInfoFormat

Legalize the Machine IR a function s Machine IR

llvm:🆑:opt< bool > UseNewDbgInfoFormat

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...

This file defines the SmallSet class.

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

This pass exposes codegen information to IR-level passes.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

static ArrayType * get(Type *ElementType, uint64_t NumElements)

This static method is the primary way to construct an ArrayType.

Represents a module in a bitcode file.

StringRef getModuleIdentifier() const

Error readSummary(ModuleSummaryIndex &CombinedIndex, StringRef ModulePath, std::function< bool(GlobalValue::GUID)> IsPrevailing=nullptr)

Parse the specified bitcode buffer and merge its module summary index into CombinedIndex.

Expected< std::unique_ptr< Module > > parseModule(LLVMContext &Context, ParserCallbacks Callbacks={})

Read the entire bitcode module and return it.

Expected< std::unique_ptr< Module > > getLazyModule(LLVMContext &Context, bool ShouldLazyLoadMetadata, bool IsImporting, ParserCallbacks Callbacks={})

Read the bitcode module and prepare for lazy deserialization of function bodies.

static ConstantAggregateZero * get(Type *Ty)

A parsed version of the target data layout string in and methods for querying it.

iterator find(const_arg_type_t< KeyT > Val)

std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)

size_type count(const_arg_type_t< KeyT > Val) const

Return 1 if the specified key is in the map, 0 otherwise.

Implements a dense probed hash-table based set.

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

Error takeError()

Take ownership of the stored error.

The map maintains the list of imports.

void setAlignment(Align Align)

Sets the alignment attribute of the GlobalObject.

Function and variable summary information to aid decisions and implementation of importing.

static bool isAppendingLinkage(LinkageTypes Linkage)

static bool isExternalWeakLinkage(LinkageTypes Linkage)

static bool isLocalLinkage(LinkageTypes Linkage)

bool isDeclaration() const

Return true if the primary definition of this global value is outside of the current translation unit...

void setUnnamedAddr(UnnamedAddr Val)

bool hasLocalLinkage() const

static StringRef dropLLVMManglingEscape(StringRef Name)

If the given string begins with the GlobalValue name mangling escape character '\1',...

const Comdat * getComdat() const

static bool isLinkOnceLinkage(LinkageTypes Linkage)

static GUID getGUID(StringRef GlobalName)

Return a 64-bit global unique ID constructed from global value name (i.e.

void setLinkage(LinkageTypes LT)

DLLStorageClassTypes

Storage classes of global values for PE targets.

GUID getGUID() const

Return a 64-bit global unique ID constructed from global value name (i.e.

const GlobalObject * getAliaseeObject() const

static bool isExternalLinkage(LinkageTypes Linkage)

VisibilityTypes

An enumeration for the kinds of visibility of global values.

@ DefaultVisibility

The GV is visible.

static LinkageTypes getWeakLinkage(bool ODR)

bool isWeakForLinker() const

bool hasAppendingLinkage() const

bool hasAvailableExternallyLinkage() const

std::string getGlobalIdentifier() const

Return the modified name for this global value suitable to be used as the key for a global lookup (e....

LinkageTypes

An enumeration for the kinds of linkage for global values.

@ CommonLinkage

Tentative definitions.

@ InternalLinkage

Rename collisions when linking (static functions).

@ ExternalLinkage

Externally visible function.

@ WeakAnyLinkage

Keep one copy of named function when linking (weak)

@ AvailableExternallyLinkage

Available for inspection, not emission.

DLLStorageClassTypes getDLLStorageClass() const

Type * getValueType() const

static bool isLinkOnceODRLinkage(LinkageTypes Linkage)

void eraseFromParent()

eraseFromParent - This method unlinks 'this' from the containing module and deletes it.

This is an important class for using LLVM in a threaded context.

This class implements a map that also provides access to all stored values in a deterministic order.

PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)

static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)

Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...

Class to hold module path string table and global value map, and encapsulate methods for operating on...

const ModuleHash & getModuleHash(const StringRef ModPath) const

Get the module SHA1 hash recorded for the given module path.

const StringMap< ModuleHash > & modulePaths() const

Table of modules, containing module hash and id.

std::set< std::string, std::less<> > & cfiFunctionDefs()

std::set< std::string, std::less<> > & cfiFunctionDecls()

void addModule(Module *M)

static void CollectAsmSymvers(const Module &M, function_ref< void(StringRef, StringRef)> AsmSymver)

Parse inline ASM and collect the symvers directives that are defined in the current module.

uint32_t getSymbolFlags(Symbol S) const

ArrayRef< Symbol > symbols() const

A Module instance is used to store all the information related to an LLVM module.

A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...

A class that wrap the SHA1 algorithm.

void update(ArrayRef< uint8_t > Data)

Digest more data.

std::array< uint8_t, 20 > result()

Return the current raw 160-bits SHA1 for the digested data since the last call to init().

SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...

size_type count(const T &V) const

count - Return 1 if the element is in the set, 0 otherwise.

std::pair< const_iterator, bool > insert(const T &V)

insert - Insert an element into the set if it isn't already there.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

StringRef str() const

Explicit conversion to StringRef.

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...

StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...

size_type count(StringRef Key) const

count - Return 1 if the element is in the map, 0 otherwise.

StringRef - Represent a constant reference to a string, i.e.

constexpr bool empty() const

empty - Check if the string is empty.

bool contains(StringRef Other) const

Return true if the given string is a substring of *this, and false otherwise.

MCTargetOptions MCOptions

Machine level options.

DebuggerKind DebuggerTuning

Which debugger to tune for.

unsigned FunctionSections

Emit functions into separate sections.

unsigned DataSections

Emit data into separate sections.

This tells how a thread pool will be used.

Triple - Helper class for working with autoconf configuration names.

bool isArm64e() const

Tests whether the target is the Apple "arm64e" AArch64 subarch.

ArchType getArch() const

Get the parsed architecture type of this triple.

bool isOSDarwin() const

Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, XROS, or DriverKit).

bool isOSBinFormatELF() const

Tests whether the OS uses the ELF binary format.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

The instances of the Type class are immutable: once they are created, they are never changed.

static IntegerType * getInt8Ty(LLVMContext &C)

void setName(const Twine &Name)

Change the name of the value.

void replaceAllUsesWith(Value *V)

Change all uses of this to point to a new Value.

StringRef getName() const

Return a constant reference to the value's name.

void takeName(Value *V)

Transfer the name from V to this value.

std::pair< iterator, bool > insert(const ValueT &V)

iterator find(const_arg_type_t< ValueT > V)

bool contains(const_arg_type_t< ValueT > V) const

Check if the set contains the given element.

size_type count(const_arg_type_t< ValueT > V) const

Return 1 if the specified key is in the set, 0 otherwise.

An efficient, type-erasing, non-owning reference to a callable.

Ephemeral symbols produced by Reader::symbols() and Reader::module_symbols().

static Expected< std::unique_ptr< InputFile > > create(MemoryBufferRef Object)

Create an InputFile.

ArrayRef< Symbol > symbols() const

A range over the symbols in this InputFile.

StringRef getName() const

Returns the path to the InputFile.

BitcodeModule & getSingleBitcodeModule()

LTO(Config Conf, ThinBackend Backend={}, unsigned ParallelCodeGenParallelismLevel=1, LTOKind LTOMode=LTOK_Default)

Create an LTO object.

Error add(std::unique_ptr< InputFile > Obj, ArrayRef< SymbolResolution > Res)

Add an input file to the LTO link, using the provided symbol resolutions.

static SmallVector< const char * > getRuntimeLibcallSymbols(const Triple &TT)

Static method that returns a list of libcall symbols that can be generated by LTO but might not be vi...

LTOKind

Unified LTO modes.

@ LTOK_UnifiedRegular

Regular LTO, with Unified LTO enabled.

@ LTOK_Default

Any LTO mode without Unified LTO. The default mode.

@ LTOK_UnifiedThin

ThinLTO, with Unified LTO enabled.

unsigned getMaxTasks() const

Returns an upper bound on the number of tasks that the client may expect.

Error run(AddStreamFn AddStream, FileCache Cache={})

Runs the LTO pipeline.

This class defines the interface to the ThinLTO backend.

Error emitFiles(const FunctionImporter::ImportMapTy &ImportList, llvm::StringRef ModulePath, const std::string &NewModulePath) const

bool ShouldEmitImportsFiles

const DenseMap< StringRef, GVSummaryMapTy > & ModuleToDefinedGVSummaries

ModuleSummaryIndex & CombinedIndex

A raw_ostream that writes to a file descriptor.

This class implements an extremely fast bulk output stream that can only output to a stream.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ C

The default llvm calling convention, compatible with C.

Function * getDeclarationIfExists(Module *M, ID id, ArrayRef< Type * > Tys, FunctionType *FT=nullptr)

This version supports overloaded intrinsics.

Expected< stable_hash > mergeCodeGenData(ArrayRef< StringRef > ObjectFiles)

Merge the codegen data from the scratch objects ObjectFiles from the first codegen round.

std::unique_ptr< Module > loadModuleForTwoRounds(BitcodeModule &OrigModule, unsigned Task, LLVMContext &Context, ArrayRef< StringRef > IRFiles)

Load the optimized bitcode module for the second codegen round.

initializer< Ty > init(const Ty &Val)

ThinBackend createInProcessThinBackend(ThreadPoolStrategy Parallelism, IndexWriteCallback OnWrite=nullptr, bool ShouldEmitIndexFiles=false, bool ShouldEmitImportsFiles=false)

This ThinBackend runs the individual backend jobs in-process.

std::string getThinLTOOutputFile(StringRef Path, StringRef OldPrefix, StringRef NewPrefix)

Given the original Path to an output file, replace any path prefix matching OldPrefix with NewPrefix.

std::function< void(const std::string &)> IndexWriteCallback

StringLiteral getThinLTODefaultCPU(const Triple &TheTriple)

Expected< std::unique_ptr< ToolOutputFile > > setupStatsFile(StringRef StatsFilename)

Setups the output file for saving statistics.

Error backend(const Config &C, AddStreamFn AddStream, unsigned ParallelCodeGenParallelismLevel, Module &M, ModuleSummaryIndex &CombinedIndex)

Runs a regular LTO backend.

ThinBackend createWriteIndexesThinBackend(ThreadPoolStrategy Parallelism, std::string OldPrefix, std::string NewPrefix, std::string NativeObjectPrefix, bool ShouldEmitImportsFiles, raw_fd_ostream *LinkedObjectsFile, IndexWriteCallback OnWrite)

This ThinBackend writes individual module indexes to files, instead of running the individual backend...

Error finalizeOptimizationRemarks(std::unique_ptr< ToolOutputFile > DiagOutputFile)

std::vector< int > generateModulesOrdering(ArrayRef< BitcodeModule * > R)

Produces a container ordering for optimal multi-threaded processing.

Expected< std::unique_ptr< ToolOutputFile > > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::optional< uint64_t > RemarksHotnessThreshold=0, int Count=-1)

Setup optimization remarks.

Error thinBackend(const Config &C, unsigned Task, AddStreamFn AddStream, Module &M, const ModuleSummaryIndex &CombinedIndex, const FunctionImporter::ImportMapTy &ImportList, const GVSummaryMapTy &DefinedGlobals, MapVector< StringRef, BitcodeModule > *ModuleMap, bool CodeGenOnly, AddStreamFn IRAddStream=nullptr, const std::vector< uint8_t > &CmdArgs=std::vector< uint8_t >())

Runs a ThinLTO backend.

void updateMemProfAttributes(Module &Mod, const ModuleSummaryIndex &Index)

Updates MemProf attributes (and metadata) based on whether the index has recorded that we are linking...

Expected< IRSymtabFile > readIRSymtab(MemoryBufferRef MBRef)

Reads a bitcode file, creating its irsymtab if necessary.

void write64le(void *P, uint64_t V)

void write32le(void *P, uint32_t V)

std::error_code create_directories(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)

Create all the non-existent directories in path.

StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)

Get parent path.

bool replace_path_prefix(SmallVectorImpl< char > &Path, StringRef OldPrefix, StringRef NewPrefix, Style style=Style::native)

Replace matching path prefix with another path.

This is an optimization pass for GlobalISel generic memory operations.

ThreadPoolStrategy heavyweight_hardware_concurrency(unsigned ThreadCount=0)

Returns a thread strategy for tasks requiring significant memory or other resources.

cl::opt< std::string > RemarksFormat("lto-pass-remarks-format", cl::desc("The format used for serializing remarks (default: YAML)"), cl::value_desc("format"), cl::init("yaml"))

bool all_of(R &&range, UnaryPredicate P)

Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.

Error createFileError(const Twine &F, Error E)

Concatenate a source file path and/or name with an Error.

auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)

Get the size of a range.

detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)

void generateParamAccessSummary(ModuleSummaryIndex &Index)

cl::opt< std::string > RemarksPasses("lto-pass-remarks-filter", cl::desc("Only record optimization remarks from passes whose " "names match the given regular expression"), cl::value_desc("regex"))

std::error_code inconvertibleErrorCode()

The value returned by this function can be returned from convertToErrorCode for Error values where no...

raw_fd_ostream & outs()

This returns a reference to a raw_fd_ostream for standard output.

std::function< Expected< std::unique_ptr< CachedFileStream > >(unsigned Task, const Twine &ModuleName)> AddStreamFn

This type defines the callback to add a file that is generated on the fly.

iterator_range< T > make_range(T x, T y)

Convenience function for iterating over sub-ranges.

bool thinLTOPropagateFunctionAttrs(ModuleSummaryIndex &Index, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)

Propagate function attributes for function summaries along the index's callgraph during thinlink.

OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P)

Provide wrappers to std::copy_if which take ranges instead of having to pass begin/end explicitly.

bool hasWholeProgramVisibility(bool WholeProgramVisibilityEnabledInLTO)

void writeIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out, const ModuleToSummariesForIndexTy *ModuleToSummariesForIndex=nullptr, const GVSummaryPtrSet *DecSummaries=nullptr)

Write the specified module summary index to the given raw output stream, where it will be written in ...

void ComputeCrossModuleImport(const ModuleSummaryIndex &Index, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, FunctionImporter::ImportListsTy &ImportLists, DenseMap< StringRef, FunctionImporter::ExportSetTy > &ExportLists)

Compute all the imports and exports for every module in the Index.

void EnableStatistics(bool DoPrintOnExit=true)

Enable the collection and printing of statistics.

void thinLTOInternalizeAndPromoteInIndex(ModuleSummaryIndex &Index, function_ref< bool(StringRef, ValueInfo)> isExported, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)

Update the linkages in the given Index to mark exported values as external and non-exported values as...

void timeTraceProfilerInitialize(unsigned TimeTraceGranularity, StringRef ProcName, bool TimeTraceVerbose=false)

Initialize the time trace profiler.

void timeTraceProfilerFinishThread()

Finish a time trace profiler running on a worker thread.

std::string recomputeLTOCacheKey(const std::string &Key, StringRef ExtraID)

Recomputes the LTO cache key for a given key with an extra identifier.

Error joinErrors(Error E1, Error E2)

Concatenate errors.

void updatePublicTypeTestCalls(Module &M, bool WholeProgramVisibilityEnabledInLTO)

void getVisibleToRegularObjVtableGUIDs(ModuleSummaryIndex &Index, DenseSet< GlobalValue::GUID > &VisibleToRegularObjSymbols, function_ref< bool(StringRef)> IsVisibleToRegularObj)

Based on typeID string, get all associated vtable GUIDS that are visible to regular objects.

void sort(IteratorTy Start, IteratorTy End)

bool timeTraceProfilerEnabled()

Is the time trace profiler enabled, i.e. initialized?

raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

Expected< std::unique_ptr< ToolOutputFile > > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::optional< uint64_t > RemarksHotnessThreshold=0)

Setup optimization remarks that output to a file.

cl::opt< bool > EnableLTOInternalization

Enable global value internalization in LTO.

cl::opt< bool > RemarksWithHotness("lto-pass-remarks-with-hotness", cl::desc("With PGO, include profile count in optimization remarks"), cl::Hidden)

void timeTraceProfilerEnd()

Manually end the last time section.

cl::opt< std::string > RemarksFilename("lto-pass-remarks-output", cl::desc("Output filename for pass remarks"), cl::value_desc("filename"))

cl::opt< bool > SupportsHotColdNew

Indicate we are linking with an allocator that supports hot/cold operator new interfaces.

void updateIndexWPDForExports(ModuleSummaryIndex &Summary, function_ref< bool(StringRef, ValueInfo)> isExported, std::map< ValueInfo, std::vector< VTableSlotSummary > > &LocalWPDTargetsMap)

Call after cross-module importing to update the recorded single impl devirt target names for any loca...

void thinLTOResolvePrevailingInIndex(const lto::Config &C, ModuleSummaryIndex &Index, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, function_ref< void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> recordNewLinkage, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols)

Resolve linkage for prevailing symbols in the Index.

raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

@ Mod

The access may modify the value stored in memory.

cl::opt< bool > EnableMemProfContextDisambiguation

Enable MemProf context disambiguation for thin link.

void runWholeProgramDevirtOnIndex(ModuleSummaryIndex &Summary, std::set< GlobalValue::GUID > &ExportedGUIDs, std::map< ValueInfo, std::vector< VTableSlotSummary > > &LocalWPDTargetsMap)

Perform index-based whole program devirtualization on the Summary index.

std::unordered_set< GlobalValueSummary * > GVSummaryPtrSet

A set of global value summary pointers.

void gatherImportedSummariesForModule(StringRef ModulePath, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, const FunctionImporter::ImportMapTy &ImportList, ModuleToSummariesForIndexTy &ModuleToSummariesForIndex, GVSummaryPtrSet &DecSummaries)

Compute the set of summaries needed for a ThinLTO backend compilation of ModulePath.

std::map< std::string, GVSummaryMapTy, std::less<> > ModuleToSummariesForIndexTy

Map of a module name to the GUIDs and summaries we will import from that module.

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

auto count_if(R &&Range, UnaryPredicate P)

Wrapper function around std::count_if to count the number of times an element satisfying a given pred...

cl::opt< std::optional< uint64_t >, false, remarks::HotnessThresholdParser > RemarksHotnessThreshold("lto-pass-remarks-hotness-threshold", cl::desc("Minimum profile count required for an " "optimization remark to be output." " Use 'auto' to apply the threshold from profile summary."), cl::value_desc("uint or 'auto'"), cl::init(0), cl::Hidden)

std::string computeLTOCacheKey(const lto::Config &Conf, const ModuleSummaryIndex &Index, StringRef ModuleID, const FunctionImporter::ImportMapTy &ImportList, const FunctionImporter::ExportSetTy &ExportList, const std::map< GlobalValue::GUID, GlobalValue::LinkageTypes > &ResolvedODR, const GVSummaryMapTy &DefinedGlobals, const DenseSet< GlobalValue::GUID > &CfiFunctionDefs={}, const DenseSet< GlobalValue::GUID > &CfiFunctionDecls={})

Computes a unique hash for the Module considering the current list of export/import and other global ...

Error errorCodeToError(std::error_code EC)

Helper for converting an std::error_code to a Error.

static cl::opt< bool > LTOKeepSymbolCopies("lto-keep-symbol-copies", cl::init(false), cl::Hidden, cl::desc("Keep copies of symbols in LTO indexing"))

bool UpgradeDebugInfo(Module &M)

Check the debug info version number, if it is out-dated, drop the debug info.

void PrintStatisticsJSON(raw_ostream &OS)

Print statistics in JSON format.

void computeDeadSymbolsWithConstProp(ModuleSummaryIndex &Index, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols, function_ref< PrevailingType(GlobalValue::GUID)> isPrevailing, bool ImportEnabled)

Compute dead symbols and run constant propagation in combined index after that.

Error EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename, const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex)

Emit into OutputFilename the files module ModulePath will import from.

@ Keep

No function return thunk.

void updateVCallVisibilityInModule(Module &M, bool WholeProgramVisibilityEnabledInLTO, const DenseSet< GlobalValue::GUID > &DynamicExportSymbols, bool ValidateAllVtablesHaveTypeInfos, function_ref< bool(StringRef)> IsVisibleToRegularObj)

If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...

TimeTraceProfilerEntry * timeTraceProfilerBegin(StringRef Name, StringRef Detail)

Manually begin a time section, with the given Name and Detail.

void updateVCallVisibilityInIndex(ModuleSummaryIndex &Index, bool WholeProgramVisibilityEnabledInLTO, const DenseSet< GlobalValue::GUID > &DynamicExportSymbols, const DenseSet< GlobalValue::GUID > &VisibleToRegularObjSymbols)

If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...

Implement std::hash so that hash_code can be used in STL containers.

This struct is a compact representation of a valid (non-zero power of two) alignment.

Used in the streaming interface as the general argument type.

This type represents a file cache system that manages caching of files.

A simple container for information about the supported runtime calls.

iterator_range< const char ** > getLibcallNames()

Struct that holds a reference to a particular GUID in a global value summary.

bool isFormatSpecific() const

bool HasWholeProgramVisibility

Asserts whether we can assume whole program visibility during the LTO link.

bool ValidateAllVtablesHaveTypeInfos

We're validating that all native vtables have corresponding type infos.

bool KeepSymbolNameCopies

If true, the LTO instance creates copies of the symbol names for LTO::run.

std::optional< uint64_t > RemarksHotnessThreshold

The minimum hotness value a diagnostic needs in order to be included in optimization diagnostics.

std::string StatsFile

Statistics output file path.

ModuleHookFn PreOptModuleHook

This module hook is called after linking (regular LTO) or loading (ThinLTO) the module,...

CombinedIndexHookFn CombinedIndexHook

std::optional< CodeModel::Model > CodeModel

bool CodeGenOnly

Disable entirely the optimizer, including importing for ThinLTO.

std::vector< std::string > MAttrs

std::vector< std::string > MllvmArgs

std::vector< std::string > ThinLTOModulesToCompile

Specific thinLTO modules to compile.

CodeGenOptLevel CGOptLevel

std::unique_ptr< raw_ostream > ResolutionFile

If this field is set, LTO will write input file paths and symbol resolutions here in llvm-lto2 comman...

std::string DefaultTriple

Setting this field will replace unspecified target triples in input files with this triple.

bool AlwaysEmitRegularLTOObj

Always emit a Regular LTO object even when it is empty because no Regular LTO modules were linked.

std::string DwoDir

The directory to store .dwo files.

std::string RemarksFilename

Optimization remarks file path.

VisScheme VisibilityScheme

Allows non-imported definitions to get the potentially more constraining visibility from the prevaili...

std::string OverrideTriple

Setting this field will replace target triples in input files with this triple.

std::string ProfileRemapping

Name remapping file for profile data.

bool AllVtablesHaveTypeInfos

If all native vtables have corresponding type infos, allow usage of RTTI to block devirtualization on...

bool TimeTraceEnabled

Time trace enabled.

std::string RemarksPasses

Optimization remarks pass filter.

std::string OptPipeline

If this field is set, the set of passes run in the middle-end optimizer will be the one specified by ...

ModuleHookFn PostInternalizeModuleHook

This hook is called after internalizing the module.

unsigned TimeTraceGranularity

Time trace granularity.

bool RemarksWithHotness

Whether to emit optimization remarks with hotness informations.

std::optional< Reloc::Model > RelocModel

CodeGenFileType CGFileType

bool Freestanding

Flag to indicate that the optimizer should not assume builtins are present on the target.

std::string SampleProfile

Sample PGO profile path.

std::string RemarksFormat

The format used for serializing remarks (default: YAML).

The purpose of this struct is to only expose the symbol information that an LTO client should need in...

A derived class of LLVMContext that initializes itself according to a given Config object.

The resolution for a symbol.

unsigned FinalDefinitionInLinkageUnit

The definition of this symbol is unpreemptable at runtime and is known to be in this linkage unit.

unsigned ExportDynamic

The symbol was exported dynamically, and therefore could be referenced by a shared library not visibl...

unsigned Prevailing

The linker has chosen this definition of the symbol.

unsigned LinkerRedefined

Linker redefined version of the symbol which appeared in -wrap or -defsym linker option.

unsigned VisibleToRegularObj

The definition of this symbol is visible outside of the LTO unit.

This type defines the behavior following the thin-link phase during ThinLTO.