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

1

2

3

4

5

6

7

8

9

10

11

12

13

16

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

63

64#include

65

66#if !defined(_MSC_VER) && !defined(__MINGW32__)

67#include <unistd.h>

68#else

69#include <io.h>

70#endif

71

72using namespace llvm;

73using namespace ThinLTOCodeGeneratorImpl;

74

75#define DEBUG_TYPE "thinlto"

76

77namespace llvm {

78

86}

87

88

89

90

92

93

96 if (TempDir.empty())

97 return;

98

99 std::string SaveTempPath = (TempDir + llvm::Twine(count) + Suffix).str();

100 std::error_code EC;

102 if (EC)

104 " to save optimized bitcode\n");

106}

107

110

112 GVSummaryList, [](const std::unique_ptr &Summary) {

113 auto Linkage = Summary->linkage();

116 });

117 if (StrongDefForLinker != GVSummaryList.end())

118 return StrongDefForLinker->get();

119

120

122 GVSummaryList, [](const std::unique_ptr &Summary) {

123 auto Linkage = Summary->linkage();

125 });

126

127 if (FirstDefForLinker == GVSummaryList.end())

128 return nullptr;

129 return FirstDefForLinker->get();

130}

131

132

133

134

139 return GVSummaryList.size() > 1;

140 };

141

142 for (auto &I : Index) {

143 if (HasMultipleCopies(I.second.SummaryList))

144 PrevailingCopy[I.first] =

146 }

147}

148

152 for (auto &M : Modules) {

153 LLVM_DEBUG(dbgs() << "Adding module " << M->getName() << " to ModuleMap\n");

155 "Expect unique Buffer Identifier");

156 ModuleMap[M->getName()] = M.get();

157 }

158 return ModuleMap;

159}

160

162 bool ClearDSOLocalOnDeclarations) {

164}

165

166namespace {

168 const Twine &Msg;

169public:

170 ThinLTODiagnosticInfo(const Twine &DiagMsg,

174};

175}

176

177

179 bool BrokenDebugInfo = false;

182 if (BrokenDebugInfo) {

184 "Invalid debug info found, debug info will be stripped", DS_Warning));

186 }

187}

188

191 bool Lazy,

192 bool IsImporting) {

196 Lazy ? Mod.getLazyModule(Context,

197 true, IsImporting)

198 : Mod.parseModule(Context);

199 if (!ModuleOrErr) {

201 SMDiagnostic Err = SMDiagnostic(Mod.getModuleIdentifier(),

202 SourceMgr::DK_Error, EIB.message());

203 Err.print("ThinLTO", errs());

204 });

206 }

207 if (!Lazy)

209 return std::move(*ModuleOrErr);

210}

211

212static void

216 bool ClearDSOLocalOnDeclarations) {

217 auto Loader = [&](StringRef Identifier) {

218 auto &Input = ModuleMap[Identifier];

220 true, true);

221 };

222

223 FunctionImporter Importer(Index, Loader, ClearDSOLocalOnDeclarations);

225 if (!Result) {

227 SMDiagnostic Err = SMDiagnostic(TheModule.getModuleIdentifier(),

228 SourceMgr::DK_Error, EIB.message());

229 Err.print("ThinLTO", errs());

230 });

232 }

233

235}

236

238 unsigned OptLevel, bool Freestanding,

240 std::optional PGOOpt;

245

248 SI.registerCallbacks(PIC, &MAM);

253

254 std::unique_ptr TLII(

256 if (Freestanding)

257 TLII->disableAllFunctions();

259

260

266

268

270

271 switch (OptLevel) {

272 default:

274 case 0:

276 break;

277 case 1:

279 break;

280 case 2:

282 break;

283 case 3:

285 break;

286 }

287

289

290 MPM.run(TheModule, MAM);

291}

292

293static void

296 for (const auto &Sym : File.symbols()) {

297 if (Sym.isUsed())

299 }

300}

301

302

305 const Triple &TheTriple,

307

308

309 for (const auto &Sym : File.symbols()) {

313 }

314}

315

319 const Triple &TheTriple) {

322 GUIDPreservedSymbols);

323 return GUIDPreservedSymbols;

324}

325

329

330

331 {

334

335

336 if (TM.addPassesToEmitFile(PM, OS, nullptr, CodeGenFileType::ObjectFile,

337 true))

339

340

341 PM.run(TheModule);

342 }

343 return std::make_unique(

344 std::move(OutputBuffer), false);

345}

346

347namespace {

348

349class ModuleCacheEntry {

351

352public:

353

354

355

356 ModuleCacheEntry(

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

361 const GVSummaryMapTy &DefinedGVSummaries, unsigned OptLevel,

363 if (CachePath.empty())

364 return;

365

366 if (Index.modulePaths().count(ModuleID))

367

368 return;

369

370 if (all_of(Index.getModuleHash(ModuleID),

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

372

373 return;

374

378 Conf.CPU = TMBuilder.MCpu;

383 std::string Key =

385 ResolvedODR, DefinedGVSummaries);

386

387

388

390 }

391

392

393 StringRef getEntryPath() { return EntryPath; }

394

395

397 if (EntryPath.empty())

398 return std::error_code();

402 if (!FDOrErr)

405 *FDOrErr, EntryPath, -1, false);

407 return MBOrErr;

408 }

409

410

412 if (EntryPath.empty())

413 return;

414

419 }))

421 EntryPath,

423 }

424};

425}

426

427static std::unique_ptr

435 bool DisableCodeGen, StringRef SaveTempsDir,

436 bool Freestanding, unsigned OptLevel, unsigned count,

437 bool DebugPassManager) {

438

439 bool SingleModule = (ModuleMap.size() == 1);

440

441

442

443 bool ClearDSOLocalOnDeclarations =

444 TM.getTargetTriple().isOSBinFormatELF() &&

447

448 if (!SingleModule) {

449 promoteModule(TheModule, Index, ClearDSOLocalOnDeclarations);

450

451

453

454

456 }

457

458

459

460 if (!ExportList.empty() || !GUIDPreservedSymbols.empty()) {

461

463 }

464

465

467

468 if (!SingleModule)

470 ClearDSOLocalOnDeclarations);

471

472

473

474

476 false);

477

478

480

481 optimizeModule(TheModule, TM, OptLevel, Freestanding, DebugPassManager,

482 &Index);

483

485

486 if (DisableCodeGen) {

487

489 {

494 }

495 return std::make_unique(

496 std::move(OutputBuffer), false);

497 }

498

500}

501

502

503

504

505

506

509 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>>

510 &ResolvedODR,

513 &PrevailingCopy) {

514

516 const auto &Prevailing = PrevailingCopy.find(GUID);

517

518 if (Prevailing == PrevailingCopy.end())

519 return true;

520 return Prevailing->second == S;

521 };

522

523 auto recordNewLinkage = [&](StringRef ModuleIdentifier,

526 ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;

527 };

528

529

532 GUIDPreservedSymbols);

533}

534

535

537 const Triple &TheTriple) {

538 if (TMBuilder.MCpu.empty())

540 TMBuilder.TheTriple = std::move(TheTriple);

541}

542

545

547 if (!InputOrError)

549 toString(InputOrError.takeError()));

550

551 auto TripleStr = (*InputOrError)->getTargetTriple();

552 Triple TheTriple(TripleStr);

553

554 if (Modules.empty())

556 else if (TMBuilder.TheTriple != TheTriple) {

559 "supported");

561 }

562

563 Modules.emplace_back(std::move(*InputOrError));

564}

565

568}

569

571

572

573

575}

576

577

579 std::string ErrMsg;

580 const Target *TheTarget =

582 if (!TheTarget) {

584 }

585

586

589 std::string FeatureStr = Features.getString();

590

591 std::unique_ptr TM(

593 RelocModel, std::nullopt, CGOptLevel));

594 assert(TM && "Cannot create target machine");

595

596 return TM;

597}

598

599

600

601

602

604 std::unique_ptr CombinedIndex =

605 std::make_unique(false);

606 for (auto &Mod : Modules) {

607 auto &M = Mod->getSingleBitcodeModule();

608 if (Error Err = M.readSummary(*CombinedIndex, Mod->getName())) {

609

611 std::move(Err), errs(),

612 "error: can't create module summary index for buffer: ");

613 return nullptr;

614 }

615 }

616 return CombinedIndex;

617}

618

619namespace {

620struct IsExported {

623

624 IsExported(

627 : ExportLists(ExportLists), GUIDPreservedSymbols(GUIDPreservedSymbols) {}

628

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

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

632 GUIDPreservedSymbols.count(VI.getGUID());

633 }

634};

635

636struct IsPrevailing {

639 &PrevailingCopy)

640 : PrevailingCopy(PrevailingCopy) {}

641

643 const auto &Prevailing = PrevailingCopy.find(GUID);

644

645 if (Prevailing == PrevailingCopy.end())

646 return true;

647 return Prevailing->second == S;

648 };

649};

650}

651

655

656

657

660 };

662 true);

663}

664

665

666

667

668

671 auto ModuleCount = Index.modulePaths().size();

673

674

676 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);

677

678

681

682

684

685

687

688

691

692

696 IsPrevailing(PrevailingCopy), ImportLists,

697 ExportLists);

698

699

702 PrevailingCopy);

703

705 ModuleToDefinedGVSummaries[ModuleIdentifier],

706 false);

707

708

709

711 Index, IsExported(ExportLists, GUIDPreservedSymbols),

712 IsPrevailing(PrevailingCopy));

713

714

715 promoteModule(TheModule, Index, false);

716}

717

718

719

720

725 auto ModuleCount = Index.modulePaths().size();

726

727

729 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);

730

731

734

736

737

739

740

743

744

748 IsPrevailing(PrevailingCopy), ImportLists,

749 ExportLists);

751

752

754 false);

755}

756

757

758

759

764 auto ModuleCount = Index.modulePaths().size();

766

767

769 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);

770

771

774

776

777

779

780

783

784

788 IsPrevailing(PrevailingCopy), ImportLists,

789 ExportLists);

790

792 ModuleIdentifier, ModuleToDefinedGVSummaries,

793 ImportLists[ModuleIdentifier], ModuleToSummariesForIndex, DecSummaries);

794}

795

796

797

798

802 auto ModuleCount = Index.modulePaths().size();

804

805

807 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);

808

809

812

814

815

817

818

821

822

826 IsPrevailing(PrevailingCopy), ImportLists,

827 ExportLists);

828

829

830

831

835 ModuleIdentifier, ModuleToDefinedGVSummaries,

836 ImportLists[ModuleIdentifier], ModuleToSummariesForIndex, DecSummaries);

837

839 ModuleToSummariesForIndex))

841 " to save imports lists\n");

842}

843

844

845

846

847

852 auto ModuleCount = Index.modulePaths().size();

854

855

856 auto GUIDPreservedSymbols =

858

860

861

863 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);

864

865

867

868

871

872

876 IsPrevailing(PrevailingCopy), ImportLists,

877 ExportLists);

878 auto &ExportList = ExportLists[ModuleIdentifier];

879

880

881

882 if (ExportList.empty() && GUIDPreservedSymbols.empty())

883 return;

884

885

888 PrevailingCopy);

889

890

891

893 Index, IsExported(ExportLists, GUIDPreservedSymbols),

894 IsPrevailing(PrevailingCopy));

895

896

897 promoteModule(TheModule, Index, false);

898

899

901 ModuleToDefinedGVSummaries[ModuleIdentifier],

902 false);

903

905 ModuleToDefinedGVSummaries[ModuleIdentifier]);

906}

907

908

909

910

913

914

916 DebugPassManager, nullptr);

917}

918

919

920

921

922std::string

928 Twine(count) + "." + ArchName + ".thinlto.o");

929 OutputPath.c_str();

932

933

934 if (!CacheEntryPath.empty()) {

935

937 if (!Err)

938 return std::string(OutputPath);

939

941 if (!Err)

942 return std::string(OutputPath);

943

944

945

946 errs() << "remark: can't link or copy from cached entry '" << CacheEntryPath

947 << "' to '" << OutputPath << "'\n";

948 }

949

950 std::error_code Err;

952 if (Err)

955 return std::string(OutputPath);

956}

957

958

964 });

965

966 assert(ProducedBinaries.empty() && "The generator should not be reused");

967 if (SavedObjectsDirectoryPath.empty())

968 ProducedBinaries.resize(Modules.size());

969 else {

971 bool IsDir;

973 if (!IsDir)

975 ProducedBinaryFiles.resize(Modules.size());

976 }

977

978 if (CodeGenOnly) {

979

982 for (auto &Mod : Modules) {

986

987

989 false);

990

991

993 if (SavedObjectsDirectoryPath.empty())

994 ProducedBinaries[count] = std::move(OutputBuffer);

995 else

996 ProducedBinaryFiles[count] =

999 }

1000

1001 return;

1002 }

1003

1004

1006

1007

1008 if (!SaveTempsDir.empty()) {

1009 auto SaveTempPath = SaveTempsDir + "index.bc";

1010 std::error_code EC;

1012 if (EC)

1014 " to save optimized bitcode\n");

1016 }

1017

1018

1019

1021 auto ModuleCount = Modules.size();

1022

1023

1025 Index->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);

1026

1027

1028

1030 for (const auto &M : Modules)

1032 GUIDPreservedSymbols);

1033

1034

1035 for (const auto &M : Modules)

1037

1038

1040

1041

1042

1043

1045 Index->setWithWholeProgramVisibility();

1046

1047

1049 false,

1050

1051

1052 {},

1053 {});

1054

1055

1056

1057

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

1059 std::setGlobalValue::GUID ExportedGUIDs;

1061 for (auto GUID : ExportedGUIDs)

1062 GUIDPreservedSymbols.insert(GUID);

1063

1064

1067

1068

1069

1073 IsPrevailing(PrevailingCopy), ImportLists,

1074 ExportLists);

1075

1076

1077

1078

1079

1081

1082

1083

1085 PrevailingCopy);

1086

1087

1088

1089

1091 IsExported(ExportLists, GUIDPreservedSymbols),

1092 LocalWPDTargetsMap);

1094 *Index, IsExported(ExportLists, GUIDPreservedSymbols),

1095 IsPrevailing(PrevailingCopy));

1096

1098

1099

1100

1101

1102 for (auto &Module : Modules) {

1104 ExportLists[ModuleIdentifier];

1105 ImportLists[ModuleIdentifier];

1106 ResolvedODR[ModuleIdentifier];

1107 ModuleToDefinedGVSummaries[ModuleIdentifier];

1108 }

1109

1110 std::vector<BitcodeModule *> ModulesVec;

1111 ModulesVec.reserve(Modules.size());

1112 for (auto &Mod : Modules)

1113 ModulesVec.push_back(&Mod->getSingleBitcodeModule());

1115

1118

1119 TimeTraceScopeExit.release();

1120

1121

1122 {

1124 for (auto IndexCount : ModulesOrdering) {

1125 auto &Mod = Modules[IndexCount];

1127 auto ModuleIdentifier = Mod->getName();

1128 auto &ExportList = ExportLists[ModuleIdentifier];

1129

1130 auto &DefinedGVSummaries = ModuleToDefinedGVSummaries[ModuleIdentifier];

1131

1132

1133 ModuleCacheEntry CacheEntry(CacheOptions.Path, *Index, ModuleIdentifier,

1134 ImportLists[ModuleIdentifier], ExportList,

1135 ResolvedODR[ModuleIdentifier],

1136 DefinedGVSummaries, OptLevel, Freestanding,

1137 TMBuilder);

1138 auto CacheEntryPath = CacheEntry.getEntryPath();

1139

1140 {

1141 auto ErrOrBuffer = CacheEntry.tryLoadingBuffer();

1142 LLVM_DEBUG(dbgs() << "Cache " << (ErrOrBuffer ? "hit" : "miss")

1143 << " '" << CacheEntryPath << "' for buffer "

1144 << count << " " << ModuleIdentifier << "\n");

1145

1146 if (ErrOrBuffer) {

1147

1148 if (SavedObjectsDirectoryPath.empty())

1149 ProducedBinaries[count] = std::move(ErrOrBuffer.get());

1150 else

1152 count, CacheEntryPath, *ErrOrBuffer.get());

1153 return;

1154 }

1155 }

1156

1163 if (!DiagFileOrErr) {

1164 errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";

1166 "remarks");

1167 }

1168

1169

1171 false);

1172

1173

1175

1176 auto &ImportList = ImportLists[ModuleIdentifier];

1177

1179 *TheModule, *Index, ModuleMap, *TMBuilder.create(), ImportList,

1180 ExportList, GUIDPreservedSymbols,

1181 ModuleToDefinedGVSummaries[ModuleIdentifier], CacheOptions,

1182 DisableCodeGen, SaveTempsDir, Freestanding, OptLevel, count,

1183 DebugPassManager);

1184

1185

1186 CacheEntry.write(*OutputBuffer);

1187

1188 if (SavedObjectsDirectoryPath.empty()) {

1189

1190 if (!CacheEntryPath.empty()) {

1191

1192

1193

1194

1195

1196

1197 auto ReloadedBufferOrErr = CacheEntry.tryLoadingBuffer();

1198 if (auto EC = ReloadedBufferOrErr.getError()) {

1199

1200 errs() << "remark: can't reload cached file '" << CacheEntryPath

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

1202 } else {

1203 OutputBuffer = std::move(*ReloadedBufferOrErr);

1204 }

1205 }

1206 ProducedBinaries[count] = std::move(OutputBuffer);

1207 return;

1208 }

1210 count, CacheEntryPath, *OutputBuffer);

1211 }, IndexCount);

1212 }

1213 }

1214

1216

1217

1221}

This file provides a bitcode writing pass.

Provides passes for computing function attributes based on interprocedural analyses.

This file implements a simple parser to decode commandline option for remarks hotness threshold that ...

static const char * PreservedSymbols[]

This is the interface to build a ModuleSummaryIndex for a module.

CGSCCAnalysisManager CGAM

if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod

FunctionAnalysisManager FAM

ModuleAnalysisManager MAM

PassInstrumentationCallbacks PIC

PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)

This header defines classes/functions to handle pass execution timing information with interfaces for...

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 header defines a class that provides bookkeeping for all standard (i.e in-tree) pass instrumenta...

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

static void crossImportIntoModule(Module &TheModule, const ModuleSummaryIndex &Index, StringMap< lto::InputFile * > &ModuleMap, const FunctionImporter::ImportMapTy &ImportList, bool ClearDSOLocalOnDeclarations)

static void computeDeadSymbolsInIndex(ModuleSummaryIndex &Index, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols)

static StringMap< lto::InputFile * > generateModuleMap(std::vector< std::unique_ptr< lto::InputFile > > &Modules)

static void initTMBuilder(TargetMachineBuilder &TMBuilder, const Triple &TheTriple)

static void resolvePrevailingInIndex(ModuleSummaryIndex &Index, StringMap< std::map< GlobalValue::GUID, GlobalValue::LinkageTypes > > &ResolvedODR, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols, const DenseMap< GlobalValue::GUID, const GlobalValueSummary * > &PrevailingCopy)

Resolve prevailing symbols.

static void computePrevailingCopies(const ModuleSummaryIndex &Index, DenseMap< GlobalValue::GUID, const GlobalValueSummary * > &PrevailingCopy)

static void saveTempBitcode(const Module &TheModule, StringRef TempDir, unsigned count, StringRef Suffix)

static void verifyLoadedModule(Module &TheModule)

Verify the module and strip broken debug info.

static void addUsedSymbolToPreservedGUID(const lto::InputFile &File, DenseSet< GlobalValue::GUID > &PreservedGUID)

static std::unique_ptr< MemoryBuffer > ProcessThinLTOModule(Module &TheModule, ModuleSummaryIndex &Index, StringMap< lto::InputFile * > &ModuleMap, TargetMachine &TM, const FunctionImporter::ImportMapTy &ImportList, const FunctionImporter::ExportSetTy &ExportList, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols, const GVSummaryMapTy &DefinedGlobals, const ThinLTOCodeGenerator::CachingOptions &CacheOptions, bool DisableCodeGen, StringRef SaveTempsDir, bool Freestanding, unsigned OptLevel, unsigned count, bool DebugPassManager)

static cl::opt< int > ThreadCount("threads", cl::init(0))

static std::unique_ptr< MemoryBuffer > codegenModule(Module &TheModule, TargetMachine &TM)

static void optimizeModule(Module &TheModule, TargetMachine &TM, unsigned OptLevel, bool Freestanding, bool DebugPassManager, ModuleSummaryIndex *Index)

static void computeGUIDPreservedSymbols(const lto::InputFile &File, const StringSet<> &PreservedSymbols, const Triple &TheTriple, DenseSet< GlobalValue::GUID > &GUIDs)

static std::unique_ptr< Module > loadModuleFromInput(lto::InputFile *Input, LLVMContext &Context, bool Lazy, bool IsImporting)

static const GlobalValueSummary * getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList)

static void promoteModule(Module &TheModule, const ModuleSummaryIndex &Index, bool ClearDSOLocalOnDeclarations)

A container for analyses that lazily runs them and caches their results.

bool registerPass(PassBuilderT &&PassBuilder)

Register an analysis pass with the manager.

iterator find(const_arg_type_t< KeyT > Val)

void reserve(size_type NumEntries)

Grow the densemap so that it can contain at least NumEntries items before resizing again.

Implements a dense probed hash-table based set.

This is the base abstract class for diagnostic reporting in the backend.

virtual void print(DiagnosticPrinter &DP) const =0

Print using the given DP a user-friendly message.

Interface for custom diagnostic printing.

Base class for error info classes.

Represents either an error or a value T.

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.

reference get()

Returns a reference to the stored T value.

The map maintains the list of imports.

The function importer is automatically importing function from other modules based on the provided su...

Expected< bool > importFunctions(Module &M, const ImportMapTy &ImportList)

Import functions in Module M based on the supplied import list.

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

static bool isAvailableExternallyLinkage(LinkageTypes Linkage)

GUID getGUID() const

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

bool isWeakForLinker() 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.

@ ExternalLinkage

Externally visible function.

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

void enableDebugTypeODRUniquing()

void diagnose(const DiagnosticInfo &DI)

Report a message to the currently installed diagnostic handler.

void setDiscardValueNames(bool Discard)

Set the Context runtime configuration to discard all value name (but GlobalValue).

This interface provides simple read-only access to a block of memory, and provides simple methods for...

static ErrorOr< std::unique_ptr< MemoryBuffer > > getOpenFile(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)

Given an already-open file descriptor, read the file and return a MemoryBuffer.

StringRef getBuffer() const

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

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

LLVMContext & getContext() const

Get the global data context.

StringRef getName() const

Get a short "name" for the module.

const std::string & getTargetTriple() const

Get the target triple which is a string describing the target host.

const std::string & getModuleIdentifier() const

Get the module identifier which is, essentially, the name of the module.

PIELevel::Level getPIELevel() const

Returns the PIE level (small or large model)

static const OptimizationLevel O3

Optimize for fast execution as much as possible.

static const OptimizationLevel O0

Disable as many optimizations as possible.

static const OptimizationLevel O2

Optimize for fast execution as much as possible without triggering significant incremental compile ti...

static const OptimizationLevel O1

Optimize quickly without destroying debuggability.

This class provides access to building LLVM's passes.

void registerLoopAnalyses(LoopAnalysisManager &LAM)

Registers all available loop analysis passes.

void crossRegisterProxies(LoopAnalysisManager &LAM, FunctionAnalysisManager &FAM, CGSCCAnalysisManager &CGAM, ModuleAnalysisManager &MAM, MachineFunctionAnalysisManager *MFAM=nullptr)

Cross register the analysis managers through their proxies.

ModulePassManager buildThinLTODefaultPipeline(OptimizationLevel Level, const ModuleSummaryIndex *ImportSummary)

Build a ThinLTO default optimization pipeline to a pass manager.

void registerModuleAnalyses(ModuleAnalysisManager &MAM)

Registers all available module analysis passes.

void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM)

Registers all available CGSCC analysis passes.

void registerFunctionAnalyses(FunctionAnalysisManager &FAM)

Registers all available function analysis passes.

LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)

PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs)

Run all of the passes in this manager over the given unit of IR.

Tunable parameters for passes in the default pipelines.

bool SLPVectorization

Tuning option to enable/disable slp loop vectorization, set based on opt level.

bool LoopVectorization

Tuning option to enable/disable loop vectorization, set based on opt level.

Analysis providing profile information.

Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...

A non-threaded implementation.

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

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

This class provides an interface to register all the standard pass instrumentations and manages their...

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

bool contains(StringRef Key) const

contains - Return true if the element is in the map, false otherwise.

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

constexpr bool empty() const

empty - Check if the string is empty.

StringSet - A wrapper for StringMap that provides set-like functionality.

std::pair< typename Base::iterator, bool > insert(StringRef key)

Manages the enabling and disabling of subtarget specific features.

void getDefaultSubtargetFeatures(const Triple &Triple)

Adds the default features for the specified target triple.

std::string getString() const

Returns features as a string.

Analysis pass providing the TargetLibraryInfo.

Implementation of the target library information.

Primary interface to the complete machine description for the target machine.

Target - Wrapper for Target specific information.

TargetMachine * createTargetMachine(StringRef TT, StringRef CPU, StringRef Features, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM=std::nullopt, CodeGenOptLevel OL=CodeGenOptLevel::Default, bool JIT=false) const

createTargetMachine - Create a target specific machine implementation for the specified Triple.

void preserveSymbol(StringRef Name)

Adds to a list of all global symbols that must exist in the final generated code.

void run()

Process all the modules that were added to the code generator in parallel.

void crossReferenceSymbol(StringRef Name)

Adds to a list of all global symbols that are cross-referenced between ThinLTO files.

void addModule(StringRef Identifier, StringRef Data)

Add given module to the code generator.

auto async(Function &&F, Args &&...ArgList)

Asynchronous submission of a task to the pool.

Triple - Helper class for working with autoconf configuration names.

std::string merge(const Triple &Other) const

Merge target triples.

StringRef getArchName() const

Get the architecture (first) component of the triple.

bool isCompatibleWith(const Triple &Other) const

Test whether target triples are compatible.

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

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

size_type count(const_arg_type_t< ValueT > V) const

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

PassManager manages ModulePassManagers.

bool run(Module &M)

run - Execute all of the passes scheduled for execution.

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

Create an InputFile.

BitcodeModule & getSingleBitcodeModule()

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.

A raw_ostream that writes to an SmallVector or SmallString.

void optimize(Module &Module)

Perform post-importing ThinLTO optimizations.

std::unique_ptr< ModuleSummaryIndex > linkCombinedIndex()

Produce the combined summary index from all the bitcode files: "thin-link".

void crossModuleImport(Module &Module, ModuleSummaryIndex &Index, const lto::InputFile &File)

Perform cross-module importing for the module identified by ModuleIdentifier.

void emitImports(Module &Module, StringRef OutputName, ModuleSummaryIndex &Index, const lto::InputFile &File)

Compute and emit the imported files for module at ModulePath.

void internalize(Module &Module, ModuleSummaryIndex &Index, const lto::InputFile &File)

Perform internalization.

void gatherImportedSummariesForModule(Module &Module, ModuleSummaryIndex &Index, ModuleToSummariesForIndexTy &ModuleToSummariesForIndex, GVSummaryPtrSet &DecSummaries, const lto::InputFile &File)

Compute the list of summaries and the subset of declaration summaries needed for importing into modul...

void promote(Module &Module, ModuleSummaryIndex &Index, const lto::InputFile &File)

Perform promotion and renaming of exported internal functions, and additionally resolve weak and link...

std::string writeGeneratedObject(int count, StringRef CacheEntryPath, const MemoryBuffer &OutputBuffer)

Write temporary object file to SavedObjectDirectoryPath, write symlink to Cache directory if needed.

Interfaces for registering analysis passes, producing common pass manager configurations,...

#define llvm_unreachable(msg)

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

initializer< Ty > init(const Ty &Val)

StringLiteral getThinLTODefaultCPU(const Triple &TheTriple)

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.

std::error_code closeFile(file_t &F)

Close the file object.

bool exists(const basic_file_status &status)

Does file exist?

@ OF_UpdateAtime

Force files Atime to be updated on access.

std::error_code create_hard_link(const Twine &to, const Twine &from)

Create a hard link from from to to, or return an error.

std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)

Remove path.

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.

std::error_code copy_file(const Twine &From, const Twine &To)

Copy the contents of From to To.

Expected< file_t > openNativeFileForRead(const Twine &Name, OpenFlags Flags=OF_None, SmallVectorImpl< char > *RealPath=nullptr)

Opens the file with the given name in a read-only mode, returning its open file descriptor.

bool is_directory(const basic_file_status &status)

Does status represent a directory?

void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")

Append to 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.

void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})

Log all errors (if any) in E to OS.

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.

cl::opt< bool > LTODiscardValueNames("lto-discard-value-names", cl::desc("Strip names from Value during LTO (other than GlobalValue)."), cl::init(false), cl::Hidden)

void WriteBitcodeToFile(const Module &M, raw_ostream &Out, bool ShouldPreserveUseListOrder=false, const ModuleSummaryIndex *Index=nullptr, bool GenerateHash=false, ModuleHash *ModHash=nullptr)

Write the specified module to the specified raw output stream.

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

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"))

void handleAllErrors(Error E, HandlerTs &&... Handlers)

Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...

SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)

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.

void renameModuleForThinLTO(Module &M, const ModuleSummaryIndex &Index, bool ClearDSOLocalOnDeclarations, SetVector< GlobalValue * > *GlobalsToImport=nullptr)

Perform in-place global value handling on the given Module for exported local functions renamed and p...

ModuleSummaryIndex buildModuleSummaryIndex(const Module &M, std::function< BlockFrequencyInfo *(const Function &F)> GetBFICallback, ProfileSummaryInfo *PSI, std::function< const StackSafetyInfo *(const Function &F)> GetSSICallback=[](const Function &F) -> const StackSafetyInfo *{ return nullptr;})

Direct function to compute a ModuleSummaryIndex from a given module.

void reportAndResetTimings(raw_ostream *OutStream=nullptr)

If -time-passes has been specified, report the timings immediately and then reset the timers to zero.

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 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...

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

void updatePublicTypeTestCalls(Module &M, bool WholeProgramVisibilityEnabledInLTO)

Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue)

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.

void report_fatal_error(Error Err, bool gen_crash_diag=true)

Report a serious error, calling any installed error handler.

Error writeToOutput(StringRef OutputFileName, std::function< Error(raw_ostream &)> Write)

This helper creates an output stream and then passes it to Write.

bool AreStatisticsEnabled()

Check if statistics are enabled.

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"))

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.

std::vector< std::unique_ptr< GlobalValueSummary > > GlobalValueSummaryList

raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

bool StripDebugInfo(Module &M)

Strip debug info in the module if it exists.

@ Mod

The access may modify the value stored in memory.

void PrintStatistics()

Print statistics to the file returned by CreateInfoOutputFile().

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.

bool pruneCache(StringRef Path, CachePruningPolicy Policy, const std::vector< std::unique_ptr< MemoryBuffer > > &Files={})

Peform pruning using the supplied policy, returns true if pruning occurred, i.e.

void thinLTOInternalizeModule(Module &TheModule, const GVSummaryMapTy &DefinedGlobals)

Internalize TheModule based on the information recorded in the summaries during global summary-based ...

std::unordered_set< GlobalValueSummary * > GVSummaryPtrSet

A set of global value summary pointers.

auto count(R &&Range, const E &Element)

Wrapper function around std::count to count the number of times an element Element occurs in the give...

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.

DiagnosticSeverity

Defines the different supported severity of a diagnostic.

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)

auto find_if(R &&Range, UnaryPredicate P)

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

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 ...

const char * toString(DWARFSectionKind Kind)

std::error_code errorToErrorCode(Error Err)

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

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.

bool verifyModule(const Module &M, raw_ostream *OS=nullptr, bool *BrokenDebugInfo=nullptr)

Check a module for errors.

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...

void thinLTOFinalizeInModule(Module &TheModule, const GVSummaryMapTy &DefinedGlobals, bool PropagateAttrs)

Based on the information recorded in the summaries during global summary-based analysis:

This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...

static const Target * lookupTarget(StringRef Triple, std::string &Error)

lookupTarget - Lookup a target based on a target triple.

Helper to gather options relevant to the target machine creation.

std::unique_ptr< TargetMachine > create() const

std::optional< Reloc::Model > RelocModel

CodeGenOptLevel CGOptLevel

CachePruningPolicy Policy

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

std::vector< std::string > MAttrs

CodeGenOptLevel CGOptLevel

std::optional< Reloc::Model > RelocModel

bool Freestanding

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