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

1

2

3

4

5

6

7

8

9

10

11

12

13

16

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

61

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

63#include <unistd.h>

64#else

65#include <io.h>

66#endif

67

68using namespace llvm;

70

71#define DEBUG_TYPE "thinlto"

72

73namespace llvm {

74

82}

83

84

85

86

88

89

92 if (TempDir.empty())

93 return;

94

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

96 std::error_code EC;

98 if (EC)

100 " to save optimized bitcode\n");

101 WriteBitcodeToFile(TheModule, OS, true);

102}

103

105 ArrayRef<std::unique_ptr> GVSummaryList) {

106

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

109 auto Linkage = Summary->linkage();

112 });

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

114 return StrongDefForLinker->get();

115

116

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

119 auto Linkage = Summary->linkage();

121 });

122

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

124 return nullptr;

125 return FirstDefForLinker->get();

126}

127

128

129

130

134 auto HasMultipleCopies =

136 return GVSummaryList.size() > 1;

137 };

138

139 for (auto &I : Index) {

140 if (HasMultipleCopies(I.second.getSummaryList()))

141 PrevailingCopy[I.first] =

143 }

144}

145

149 for (auto &M : Modules) {

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

152 "Expect unique Buffer Identifier");

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

154 }

155 return ModuleMap;

156}

157

159 bool ClearDSOLocalOnDeclarations) {

161}

162

163namespace {

165 const Twine &Msg;

166public:

169 : DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {}

170 void print(DiagnosticPrinter &DP) const override { DP << Msg; }

171};

172}

173

174

176 bool BrokenDebugInfo = false;

179 if (BrokenDebugInfo) {

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

183 }

184}

185

188 bool Lazy,

189 bool IsImporting) {

190 auto &Mod = Input->getSingleBitcodeModule();

193 Lazy ? Mod.getLazyModule(Context,

194 true, IsImporting)

195 : Mod.parseModule(Context);

196 if (!ModuleOrErr) {

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

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

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

201 });

203 }

204 if (!Lazy)

206 return std::move(*ModuleOrErr);

207}

208

209static void

213 bool ClearDSOLocalOnDeclarations) {

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

215 auto &Input = ModuleMap[Identifier];

217 true, true);

218 };

219

220 FunctionImporter Importer(Index, Loader, ClearDSOLocalOnDeclarations);

222 if (!Result) {

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

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

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

227 });

229 }

230

232}

233

235 unsigned OptLevel, bool Freestanding,

237 std::optional PGOOpt;

242

245 SI.registerCallbacks(PIC, &MAM);

250

251 std::unique_ptr TLII(

253 if (Freestanding)

254 TLII->disableAllFunctions();

256

257

258 PB.registerModuleAnalyses(MAM);

259 PB.registerCGSCCAnalyses(CGAM);

260 PB.registerFunctionAnalyses(FAM);

261 PB.registerLoopAnalyses(LAM);

263

265

267

268 switch (OptLevel) {

269 default:

271 case 0:

273 break;

274 case 1:

276 break;

277 case 2:

279 break;

280 case 3:

282 break;

283 }

284

285 MPM.addPass(PB.buildThinLTODefaultPipeline(OL, Index));

286

287 MPM.run(TheModule, MAM);

288}

289

290static void

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

294 if (Sym.isUsed())

295 PreservedGUID.insert(

297 }

298}

299

300

303 const Triple &TheTriple,

305

306

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

308 if (PreservedSymbols.count(Sym.getName()) && !Sym.getIRName().empty())

312 }

313}

314

318 const Triple &TheTriple) {

321 GUIDPreservedSymbols);

322 return GUIDPreservedSymbols;

323}

324

328

329

330 {

333

334

336 true))

338

339

340 PM.run(TheModule);

341 }

342 return std::make_unique(

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

344}

345

346namespace {

347

348class ModuleCacheEntry {

349 SmallString<128> EntryPath;

350

351public:

352

353

354

355 ModuleCacheEntry(

356 StringRef CachePath, const ModuleSummaryIndex &Index, StringRef ModuleID,

357 const FunctionImporter::ImportMapTy &ImportList,

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

360 const GVSummaryMapTy &DefinedGVSummaries, unsigned OptLevel,

361 bool Freestanding, const TargetMachineBuilder &TMBuilder) {

362 if (CachePath.empty())

363 return;

364

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

366

367 return;

368

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

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

371

372 return;

373

374 llvm::lto::Config Conf;

377 Conf.CPU = TMBuilder.MCpu;

382 std::string Key =

384 ResolvedODR, DefinedGVSummaries);

385

386

387

389 }

390

391

392 StringRef getEntryPath() { return EntryPath; }

393

394

395 ErrorOr<std::unique_ptr> tryLoadingBuffer() {

396 if (EntryPath.empty())

397 return std::error_code();

398 SmallString<64> ResultPath;

401 if (!FDOrErr)

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

406 return MBOrErr;

407 }

408

409

410 void write(const MemoryBuffer &OutputBuffer) {

411 if (EntryPath.empty())

412 return;

413

415 EntryPath, [&OutputBuffer](llvm::raw_ostream &OS) -> llvm::Error {

418 }))

420 EntryPath,

422 }

423};

424}

425

426static std::unique_ptr

434 bool DisableCodeGen, StringRef SaveTempsDir,

435 bool Freestanding, unsigned OptLevel, unsigned count,

436 bool DebugPassManager) {

437

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

439

440

441

442 bool ClearDSOLocalOnDeclarations =

446

447 if (!SingleModule) {

448 promoteModule(TheModule, Index, ClearDSOLocalOnDeclarations);

449

450

452

453

455 }

456

457

458

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

460

462 }

463

464

466

467 if (!SingleModule)

469 ClearDSOLocalOnDeclarations);

470

471

472

473

475 false);

476

477

479

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

481 &Index);

482

484

485 if (DisableCodeGen) {

486

488 {

493 }

494 return std::make_unique(

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

496 }

497

499}

500

501

502

503

504

505

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

509 &ResolvedODR,

512 &PrevailingCopy) {

513

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

516

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

518 return true;

519 return Prevailing->second == S;

520 };

521

522 auto recordNewLinkage = [&](StringRef ModuleIdentifier,

525 ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;

526 };

527

528

531 GUIDPreservedSymbols);

532}

533

534

536 const Triple &TheTriple) {

537 if (TMBuilder.MCpu.empty())

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

540}

541

544

546 if (!InputOrError)

548 toString(InputOrError.takeError()));

549

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

551 Triple TheTriple(TripleStr);

552

553 if (Modules.empty())

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

556 if (!TMBuilder.TheTriple.isCompatibleWith(TheTriple))

558 "supported");

560 }

561

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

563}

564

566 PreservedSymbols.insert(Name);

567}

568

570

571

572

573 PreservedSymbols.insert(Name);

574}

575

576

578 std::string ErrMsg;

580 if (!TheTarget) {

582 }

583

584

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

588

589 std::unique_ptr TM(

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

593

594 return TM;

595}

596

597

598

599

600

602 std::unique_ptr CombinedIndex =

603 std::make_unique(false);

604 for (auto &Mod : Modules) {

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

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

607

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

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

611 return nullptr;

612 }

613 }

614 return CombinedIndex;

615}

616

617namespace {

618struct IsExported {

621

622 IsExported(

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

626

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

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

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

631 }

632};

633

634struct IsPrevailing {

635 const DenseMap<GlobalValue::GUID, const GlobalValueSummary *> &PrevailingCopy;

636 IsPrevailing(const DenseMap<GlobalValue::GUID, const GlobalValueSummary *>

637 &PrevailingCopy)

638 : PrevailingCopy(PrevailingCopy) {}

639

640 bool operator()(GlobalValue::GUID GUID, const GlobalValueSummary *S) const {

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

642

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

644 return true;

645 return Prevailing->second == S;

646 };

647};

648}

649

653

654

655

658 };

660 true);

661}

662

663

664

665

666

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

671

672

674 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);

675

676

679

680

682

683

685

686

689

690

694 IsPrevailing(PrevailingCopy), ImportLists,

695 ExportLists);

696

697

700 PrevailingCopy);

701

703 ModuleToDefinedGVSummaries[ModuleIdentifier],

704 false);

705

706

707

709 Index, IsExported(ExportLists, GUIDPreservedSymbols),

710 IsPrevailing(PrevailingCopy));

711

712

713 promoteModule(TheModule, Index, false);

714}

715

716

717

718

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

724

725

727 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);

728

729

732

734

735

737

738

741

742

746 IsPrevailing(PrevailingCopy), ImportLists,

747 ExportLists);

749

750

752 false);

753}

754

755

756

757

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

764

765

767 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);

768

769

772

774

775

777

778

781

782

786 IsPrevailing(PrevailingCopy), ImportLists,

787 ExportLists);

788

790 ModuleIdentifier, ModuleToDefinedGVSummaries,

791 ImportLists[ModuleIdentifier], ModuleToSummariesForIndex, DecSummaries);

792}

793

794

795

796

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

802

803

805 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);

806

807

810

812

813

815

816

819

820

824 IsPrevailing(PrevailingCopy), ImportLists,

825 ExportLists);

826

827

828

829

833 ModuleIdentifier, ModuleToDefinedGVSummaries,

834 ImportLists[ModuleIdentifier], ModuleToSummariesForIndex, DecSummaries);

835

837 ModuleToSummariesForIndex))

839 " to save imports lists\n");

840}

841

842

843

844

845

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

852

853

854 auto GUIDPreservedSymbols =

856

858

859

861 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);

862

863

865

866

869

870

874 IsPrevailing(PrevailingCopy), ImportLists,

875 ExportLists);

876 auto &ExportList = ExportLists[ModuleIdentifier];

877

878

879

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

881 return;

882

883

886 PrevailingCopy);

887

888

889

891 Index, IsExported(ExportLists, GUIDPreservedSymbols),

892 IsPrevailing(PrevailingCopy));

893

894

895 promoteModule(TheModule, Index, false);

896

897

899 ModuleToDefinedGVSummaries[ModuleIdentifier],

900 false);

901

903 ModuleToDefinedGVSummaries[ModuleIdentifier]);

904}

905

906

907

908

911

912

913 optimizeModule(TheModule, *TMBuilder.create(), OptLevel, Freestanding,

914 DebugPassManager, nullptr);

915}

916

917

918

919

920std::string

923 auto ArchName = TMBuilder.TheTriple.getArchName();

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

927 OutputPath.c_str();

930

931

932 if (!CacheEntryPath.empty()) {

933

935 if (!Err)

936 return std::string(OutputPath);

937

939 if (!Err)

940 return std::string(OutputPath);

941

942

943

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

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

946 }

947

948 std::error_code Err;

950 if (Err)

953 return std::string(OutputPath);

954}

955

956

962 });

963

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

965 if (SavedObjectsDirectoryPath.empty())

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

967 else {

969 bool IsDir;

971 if (!IsDir)

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

974 }

975

976 if (CodeGenOnly) {

977

980 for (auto &Mod : Modules) {

984

985

987 false);

988

989

991 if (SavedObjectsDirectoryPath.empty())

993 else

994 ProducedBinaryFiles[count] =

997 }

998

999 return;

1000 }

1001

1002

1004

1005

1006 if (!SaveTempsDir.empty()) {

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

1008 std::error_code EC;

1010 if (EC)

1012 " to save optimized bitcode\n");

1014 }

1015

1016

1017

1019 auto ModuleCount = Modules.size();

1020

1021

1023 Index->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);

1024

1025

1026

1028 for (const auto &M : Modules)

1030 GUIDPreservedSymbols);

1031

1032

1033 for (const auto &M : Modules)

1035

1036

1038

1039

1040

1041

1043 Index->setWithWholeProgramVisibility();

1044

1045

1047 false,

1048

1049

1050 {},

1051 {});

1052

1053

1054

1055

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

1057 std::setGlobalValue::GUID ExportedGUIDs;

1059 GUIDPreservedSymbols.insert_range(ExportedGUIDs);

1060

1061

1064

1065

1066

1070 IsPrevailing(PrevailingCopy), ImportLists,

1071 ExportLists);

1072

1073

1074

1075

1076

1078

1079

1080

1082 PrevailingCopy);

1083

1084

1085

1086

1088 IsExported(ExportLists, GUIDPreservedSymbols),

1089 LocalWPDTargetsMap);

1091 *Index, IsExported(ExportLists, GUIDPreservedSymbols),

1092 IsPrevailing(PrevailingCopy));

1093

1095

1096

1097

1098

1099 for (auto &Module : Modules) {

1101 ExportLists[ModuleIdentifier];

1102 ImportLists[ModuleIdentifier];

1103 ResolvedODR[ModuleIdentifier];

1104 ModuleToDefinedGVSummaries[ModuleIdentifier];

1105 }

1106

1107 std::vector<BitcodeModule *> ModulesVec;

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

1109 for (auto &Mod : Modules)

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

1112

1115

1116 TimeTraceScopeExit.release();

1117

1118

1119 {

1121 for (auto IndexCount : ModulesOrdering) {

1122 auto &Mod = Modules[IndexCount];

1124 auto ModuleIdentifier = Mod->getName();

1125 auto &ExportList = ExportLists[ModuleIdentifier];

1126

1127 auto &DefinedGVSummaries = ModuleToDefinedGVSummaries[ModuleIdentifier];

1128

1129

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

1131 ImportLists[ModuleIdentifier], ExportList,

1132 ResolvedODR[ModuleIdentifier],

1133 DefinedGVSummaries, OptLevel, Freestanding,

1134 TMBuilder);

1135 auto CacheEntryPath = CacheEntry.getEntryPath();

1136

1137 {

1138 auto ErrOrBuffer = CacheEntry.tryLoadingBuffer();

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

1140 << " '" << CacheEntryPath << "' for buffer "

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

1142

1143 if (ErrOrBuffer) {

1144

1145 if (SavedObjectsDirectoryPath.empty())

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

1147 else

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

1150 return;

1151 }

1152 }

1153

1156 Context.enableDebugTypeODRUniquing();

1160 if (!DiagFileOrErr) {

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

1163 "remarks");

1164 }

1165

1166

1168 false);

1169

1170

1172

1173 auto &ImportList = ImportLists[ModuleIdentifier];

1174

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

1177 ExportList, GUIDPreservedSymbols,

1178 ModuleToDefinedGVSummaries[ModuleIdentifier], CacheOptions,

1179 DisableCodeGen, SaveTempsDir, Freestanding, OptLevel, count,

1180 DebugPassManager);

1181

1182

1184

1185 if (SavedObjectsDirectoryPath.empty()) {

1186

1187 if (!CacheEntryPath.empty()) {

1188

1189

1190

1191

1192

1193

1194 auto ReloadedBufferOrErr = CacheEntry.tryLoadingBuffer();

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

1196

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

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

1199 } else {

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

1201 }

1202 }

1204 return;

1205 }

1208 }, IndexCount);

1209 }

1210 }

1211

1212 pruneCache(CacheOptions.Path, CacheOptions.Policy, ProducedBinaries);

1213

1214

1218}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

This file provides a bitcode writing pass.

#define LLVM_LIFETIME_BOUND

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

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

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)

Definition ThinLTOCodeGenerator.cpp:210

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

Definition ThinLTOCodeGenerator.cpp:650

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

Definition ThinLTOCodeGenerator.cpp:147

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

Definition ThinLTOCodeGenerator.cpp:535

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.

Definition ThinLTOCodeGenerator.cpp:506

static const GlobalValueSummary * getFirstDefinitionForLinker(ArrayRef< std::unique_ptr< GlobalValueSummary > > GVSummaryList)

Definition ThinLTOCodeGenerator.cpp:104

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

Definition ThinLTOCodeGenerator.cpp:131

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

Definition ThinLTOCodeGenerator.cpp:90

static void verifyLoadedModule(Module &TheModule)

Verify the module and strip broken debug info.

Definition ThinLTOCodeGenerator.cpp:175

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

Definition ThinLTOCodeGenerator.cpp:291

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)

Definition ThinLTOCodeGenerator.cpp:427

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

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

Definition ThinLTOCodeGenerator.cpp:325

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

Definition ThinLTOCodeGenerator.cpp:234

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

Definition ThinLTOCodeGenerator.cpp:301

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

Definition ThinLTOCodeGenerator.cpp:186

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

Definition ThinLTOCodeGenerator.cpp:158

The Input class is used to parse a yaml document into in-memory structs and vectors.

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

iterator find(const_arg_type_t< KeyT > Val)

Implements a dense probed hash-table based set.

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

Base class for error info classes.

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

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

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

DenseSet< ValueInfo > ExportSetTy

The set contains an entry for every global value that the module exports.

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

static LLVM_ABI GUID getGUIDAssumingExternalLinkage(StringRef GlobalName)

Return a 64-bit global unique ID constructed from the name of a global symbol.

uint64_t GUID

Declare a type to represent a global unique identifier for a global value.

static bool isAvailableExternallyLinkage(LinkageTypes Linkage)

static LLVM_ABI std::string getGlobalIdentifier(StringRef Name, GlobalValue::LinkageTypes Linkage, StringRef FileName)

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

bool isWeakForLinker() const

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.

LLVM_ABI void diagnose(const DiagnosticInfo &DI)

Report a message to the currently installed diagnostic handler.

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

const Triple & getTargetTriple() const

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

LLVMContext & getContext() const

Get the global data context.

StringRef getName() const

Get a short "name" for the module.

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 LLVM_ABI const OptimizationLevel O3

Optimize for fast execution as much as possible.

static LLVM_ABI const OptimizationLevel O0

Disable as many optimizations as possible.

static LLVM_ABI const OptimizationLevel O2

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

static LLVM_ABI const OptimizationLevel O1

Optimize quickly without destroying debuggability.

This class provides access to building LLVM's passes.

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

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

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.

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.

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

Manages the enabling and disabling of subtarget specific features.

LLVM_ABI void getDefaultSubtargetFeatures(const Triple &Triple)

Adds the default features for the specified target triple.

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

virtual bool addPassesToEmitFile(PassManagerBase &, raw_pwrite_stream &, raw_pwrite_stream *, CodeGenFileType, bool=true, MachineModuleInfoWrapperPass *MMIWP=nullptr)

Add passes to the specified pass manager to get the specified file emitted.

const Triple & getTargetTriple() const

Reloc::Model getRelocationModel() const

Returns the code generation relocation model.

Target - Wrapper for Target specific information.

TargetMachine * createTargetMachine(const Triple &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.

LLVM_ABI void preserveSymbol(StringRef Name)

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

Definition ThinLTOCodeGenerator.cpp:565

LLVM_ABI void run()

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

Definition ThinLTOCodeGenerator.cpp:957

LLVM_ABI void crossReferenceSymbol(StringRef Name)

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

Definition ThinLTOCodeGenerator.cpp:569

LLVM_ABI void addModule(StringRef Identifier, StringRef Data)

Add given module to the code generator.

Definition ThinLTOCodeGenerator.cpp:542

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

Asynchronous submission of a task to the pool.

Triple - Helper class for working with autoconf configuration names.

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

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

void insert_range(Range &&R)

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 LLVM_ABI Expected< std::unique_ptr< InputFile > > create(MemoryBufferRef Object)

Create an InputFile.

A raw_ostream that writes to a file descriptor.

A raw_ostream that writes to an SmallVector or SmallString.

LLVM_ABI void optimize(Module &Module)

Perform post-importing ThinLTO optimizations.

Definition ThinLTOCodeGenerator.cpp:909

LLVM_ABI std::unique_ptr< ModuleSummaryIndex > linkCombinedIndex()

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

Definition ThinLTOCodeGenerator.cpp:601

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

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

Definition ThinLTOCodeGenerator.cpp:719

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

Compute and emit the imported files for module at ModulePath.

Definition ThinLTOCodeGenerator.cpp:797

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

Perform internalization.

Definition ThinLTOCodeGenerator.cpp:846

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

Definition ThinLTOCodeGenerator.cpp:758

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

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

Definition ThinLTOCodeGenerator.cpp:667

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

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

Definition ThinLTOCodeGenerator.cpp:921

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.

ThinLTOCodeGeneratorImpl - Namespace used for ThinLTOCodeGenerator implementation details.

initializer< Ty > init(const Ty &Val)

LLVM_ABI StringLiteral getThinLTODefaultCPU(const Triple &TheTriple)

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

Setup optimization remarks.

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

Produces a container ordering for optimal multi-threaded processing.

LLVM_ABI std::error_code closeFile(file_t &F)

Close the file object.

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

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

LLVM_ABI bool exists(const basic_file_status &status)

Does file exist?

@ OF_UpdateAtime

Force files Atime to be updated on access.

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

Remove path.

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

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

Create all the non-existent directories in path.

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

Copy the contents of From to To.

LLVM_ABI bool is_directory(const basic_file_status &status)

Does status represent a directory?

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

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

Definition ThinLTOCodeGenerator.cpp:81

bool all_of(R &&range, UnaryPredicate P)

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

Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)

std::unordered_set< GlobalValueSummary * > GVSummaryPtrSet

A set of global value summary pointers.

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

Definition ThinLTOCodeGenerator.cpp:75

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

Definition ThinLTOCodeGenerator.cpp:77

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)

DenseMap< GlobalValue::GUID, GlobalValueSummary * > GVSummaryMapTy

Map of global value GUID to its summary, used to identify values defined in a particular module,...

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

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

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

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

LLVM_ABI void reportAndResetTimings(raw_ostream *OutStream=nullptr)

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

LLVM_ABI bool hasWholeProgramVisibility(bool WholeProgramVisibilityEnabledInLTO)

AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager

The CGSCC analysis manager.

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

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

AnalysisManager< Loop, LoopStandardAnalysisResults & > LoopAnalysisManager

The loop analysis manager.

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

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

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

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

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

LLVM_ABI void updatePublicTypeTestCalls(Module &M, bool WholeProgramVisibilityEnabledInLTO)

PassManager< Module > ModulePassManager

Convenience typedef for a pass manager over modules.

bool timeTraceProfilerEnabled()

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

LLVM_ABI raw_ostream & dbgs()

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

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

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

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

LLVM_ABI bool AreStatisticsEnabled()

Check if statistics are enabled.

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

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

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

Definition ThinLTOCodeGenerator.cpp:78

LLVM_ABI void timeTraceProfilerEnd()

Manually end the last time section.

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

Definition ThinLTOCodeGenerator.cpp:76

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

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

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

Resolve linkage for prevailing symbols in the Index.

LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

LLVM_ABI bool StripDebugInfo(Module &M)

Strip debug info in the module if it exists.

@ Mod

The access may modify the value stored in memory.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

LLVM_ABI void PrintStatistics()

Print statistics to the file returned by CreateInfoOutputFile().

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

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

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

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

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

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

SingleThreadExecutor DefaultThreadPool

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

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

std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)

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)

Definition ThinLTOCodeGenerator.cpp:80

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

auto find_if(R &&Range, UnaryPredicate P)

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

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

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

AnalysisManager< Function > FunctionAnalysisManager

Convenience typedef for the Function analysis manager.

LLVM_ABI std::error_code errorToErrorCode(Error Err)

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

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

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

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

Emit into OutputFilename the files module ModulePath will import from.

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

Check a module for errors.

AnalysisManager< Module > ModuleAnalysisManager

Convenience typedef for the Module analysis manager.

LLVM_ABI TimeTraceProfilerEntry * timeTraceProfilerBegin(StringRef Name, StringRef Detail)

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

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

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

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

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

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

lookupTarget - Lookup a target based on a target triple.

Helper to gather options relevant to the target machine creation.

LLVM_ABI std::unique_ptr< TargetMachine > create() const

Definition ThinLTOCodeGenerator.cpp:577

std::optional< Reloc::Model > RelocModel

CodeGenOptLevel CGOptLevel

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.