LLVM 22.0.0git
LTOCodeGenerator.cpp
Go to the documentation of this file.
1//===-LTOCodeGenerator.cpp - LLVM Link Time Optimizer ---------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the Link Time Optimization library. This library is
10// intended to be used by linker to optimize code at link time.
11//
12//===----------------------------------------------------------------------===//
13
15
16#include "llvm/ADT/Statistic.h"
23#include "llvm/Config/config.h"
24#include "llvm/IR/DataLayout.h"
25#include "llvm/IR/DebugInfo.h"
29#include "llvm/IR/LLVMContext.h"
32#include "llvm/IR/Mangler.h"
33#include "llvm/IR/Module.h"
35#include "llvm/IR/Verifier.h"
36#include "llvm/LTO/LTO.h"
37#include "llvm/LTO/LTOBackend.h"
40#include "llvm/Linker/Linker.h"
53#include "llvm/Transforms/IPO.h"
57#include <optional>
58#include <system_error>
59using namespace llvm;
60
62 return PACKAGE_NAME " version " PACKAGE_VERSION;
63}
64
65namespace llvm {
67 "lto-discard-value-names",
68 cl::desc("Strip names from Value during LTO (other than GlobalValue)."),
69#ifdef NDEBUG
70 cl::init(true),
71#else
72 cl::init(false),
73#endif
75
77 "lto-pass-remarks-with-hotness",
78 cl::desc("With PGO, include profile count in optimization remarks"),
80
83 "lto-pass-remarks-hotness-threshold",
84 cl::desc("Minimum profile count required for an "
85 "optimization remark to be output."
86 " Use 'auto' to apply the threshold from profile summary."),
87 cl::value_desc("uint or 'auto'"), cl::init(0), cl::Hidden);
88
90 RemarksFilename("lto-pass-remarks-output",
91 cl::desc("Output filename for pass remarks"),
92 cl::value_desc("filename"));
93
95 RemarksPasses("lto-pass-remarks-filter",
96 cl::desc("Only record optimization remarks from passes whose "
97 "names match the given regular expression"),
98 cl::value_desc("regex"));
99
101 "lto-pass-remarks-format",
102 cl::desc("The format used for serializing remarks (default: YAML)"),
103 cl::value_desc("format"), cl::init("yaml"));
104
106 LTOStatsFile("lto-stats-file",
107 cl::desc("Save statistics to the specified file"), cl::Hidden);
108
110 "lto-aix-system-assembler",
111 cl::desc("Path to a system assembler, picked up on AIX only"),
112 cl::value_desc("path"));
113
114static cl::opt<bool>
115 LTORunCSIRInstr("cs-profile-generate",
116 cl::desc("Perform context sensitive PGO instrumentation"));
117
119 LTOCSIRProfile("cs-profile-path",
120 cl::desc("Context sensitive profile file path"));
121} // namespace llvm
122
124 : Context(Context), MergedModule(new Module("ld-temp.o", Context)),
125 TheLinker(new Linker(*MergedModule)) {
126 Context.setDiscardValueNames(LTODiscardValueNames);
127 Context.enableDebugTypeODRUniquing();
128
129 Config.CodeModel = std::nullopt;
130 Config.StatsFile = LTOStatsFile;
133}
134
136
138 AsmUndefinedRefs.insert_range(Mod->getAsmUndefinedRefs());
139}
140
142 assert(&Mod->getModule().getContext() == &Context &&
143 "Expected module in same context");
144
145 bool ret = TheLinker->linkInModule(Mod->takeModule());
147
148 // We've just changed the input, so let's make sure we verify it.
149 HasVerifiedInput = false;
150
151 return !ret;
152}
153
154void LTOCodeGenerator::setModule(std::unique_ptr<LTOModule> Mod) {
155 assert(&Mod->getModule().getContext() == &Context &&
156 "Expected module in same context");
157
158 AsmUndefinedRefs.clear();
159
160 MergedModule = Mod->takeModule();
161 TheLinker = std::make_unique<Linker>(*MergedModule);
163
164 // We've just changed the input, so let's make sure we verify it.
165 HasVerifiedInput = false;
166}
167
169 Config.Options = Options;
170}
171
173 switch (Debug) {
175 EmitDwarfDebugInfo = false;
176 return;
177
179 EmitDwarfDebugInfo = true;
180 return;
181 }
182 llvm_unreachable("Unknown debug format!");
183}
184
185void LTOCodeGenerator::setOptLevel(unsigned Level) {
186 Config.OptLevel = Level;
187 Config.PTO.LoopVectorization = Config.OptLevel > 1;
188 Config.PTO.SLPVectorization = Config.OptLevel > 1;
189 std::optional<CodeGenOptLevel> CGOptLevelOrNone =
191 assert(CGOptLevelOrNone && "Unknown optimization level!");
192 Config.CGOptLevel = *CGOptLevelOrNone;
193}
194
196 if (!determineTarget())
197 return false;
198
199 // We always run the verifier once on the merged module.
200 verifyMergedModuleOnce();
201
202 // mark which symbols can not be internalized
203 applyScopeRestrictions();
204
205 // create output file
206 std::error_code EC;
207 ToolOutputFile Out(Path, EC, sys::fs::OF_None);
208 if (EC) {
209 std::string ErrMsg = "could not open bitcode file for writing: ";
210 ErrMsg += Path.str() + ": " + EC.message();
211 emitError(ErrMsg);
212 return false;
213 }
214
215 // write bitcode to it
216 WriteBitcodeToFile(*MergedModule, Out.os(), ShouldEmbedUselists);
217 Out.os().close();
218
219 if (Out.os().has_error()) {
220 std::string ErrMsg = "could not write bitcode file: ";
221 ErrMsg += Path.str() + ": " + Out.os().error().message();
222 emitError(ErrMsg);
223 Out.os().clear_error();
224 return false;
225 }
226
227 Out.keep();
228 return true;
229}
230
231bool LTOCodeGenerator::useAIXSystemAssembler() {
232 const auto &Triple = TargetMach->getTargetTriple();
233 return Triple.isOSAIX() && Config.Options.DisableIntegratedAS;
234}
235
236bool LTOCodeGenerator::runAIXSystemAssembler(SmallString<128> &AssemblyFile) {
237 assert(useAIXSystemAssembler() &&
238 "Runing AIX system assembler when integrated assembler is available!");
239
240 // Set the system assembler path.
241 SmallString<256> AssemblerPath("/usr/bin/as");
242 if (!llvm::AIXSystemAssemblerPath.empty()) {
244 /* expand_tilde */ true)) {
245 emitError(
246 "Cannot find the assembler specified by lto-aix-system-assembler");
247 return false;
248 }
249 }
250
251 // Setup the LDR_CNTRL variable
252 std::string LDR_CNTRL_var = "LDR_CNTRL=MAXDATA32=0xA0000000@DSA";
253 if (std::optional<std::string> V = sys::Process::GetEnv("LDR_CNTRL"))
254 LDR_CNTRL_var += ("@" + *V);
255
256 // Prepare inputs for the assember.
257 const auto &Triple = TargetMach->getTargetTriple();
258 const char *Arch = Triple.isArch64Bit() ? "-a64" : "-a32";
259 std::string ObjectFileName(AssemblyFile);
260 ObjectFileName[ObjectFileName.size() - 1] = 'o';
262 "/bin/env", LDR_CNTRL_var,
263 AssemblerPath, Arch,
264 "-many", "-o",
265 ObjectFileName, AssemblyFile};
266
267 // Invoke the assembler.
268 int RC = sys::ExecuteAndWait(Args[0], Args);
269
270 // Handle errors.
271 if (RC < -1) {
272 emitError("LTO assembler exited abnormally");
273 return false;
274 }
275 if (RC < 0) {
276 emitError("Unable to invoke LTO assembler");
277 return false;
278 }
279 if (RC > 0) {
280 emitError("LTO assembler invocation returned non-zero");
281 return false;
282 }
283
284 // Cleanup.
285 remove(AssemblyFile.c_str());
286
287 // Fix the output file name.
288 AssemblyFile = ObjectFileName;
289
290 return true;
291}
292
293bool LTOCodeGenerator::compileOptimizedToFile(const char **Name) {
294 if (useAIXSystemAssembler())
296
297 // make unique temp output file to put generated code
299
300 auto AddStream =
301 [&](size_t Task,
302 const Twine &ModuleName) -> std::unique_ptr<CachedFileStream> {
304 Config.CGFileType == CodeGenFileType::AssemblyFile ? "s" : "o");
305
306 int FD;
307 std::error_code EC =
308 sys::fs::createTemporaryFile("lto-llvm", Extension, FD, Filename);
309 if (EC)
310 emitError(EC.message());
311
312 return std::make_unique<CachedFileStream>(
313 std::make_unique<llvm::raw_fd_ostream>(FD, true));
314 };
315
316 bool genResult = compileOptimized(AddStream, 1);
317
318 if (!genResult) {
319 sys::fs::remove(Twine(Filename));
320 return false;
321 }
322
323 // If statistics were requested, save them to the specified file or
324 // print them out after codegen.
325 if (StatsFile)
326 PrintStatisticsJSON(StatsFile->os());
327 else if (AreStatisticsEnabled())
329
330 if (useAIXSystemAssembler())
331 if (!runAIXSystemAssembler(Filename))
332 return false;
333
334 NativeObjectPath = Filename.c_str();
335 *Name = NativeObjectPath.c_str();
336 return true;
337}
338
339std::unique_ptr<MemoryBuffer>
341 const char *name;
342 if (!compileOptimizedToFile(&name))
343 return nullptr;
344
345 // read .o file into memory buffer
347 name, /*IsText=*/false, /*RequiresNullTerminator=*/false);
348 if (std::error_code EC = BufferOrErr.getError()) {
349 emitError(EC.message());
350 sys::fs::remove(NativeObjectPath);
351 return nullptr;
352 }
353
354 // remove temp files
355 sys::fs::remove(NativeObjectPath);
356
357 return std::move(*BufferOrErr);
358}
359
361 if (!optimize())
362 return false;
363
364 return compileOptimizedToFile(Name);
365}
366
367std::unique_ptr<MemoryBuffer> LTOCodeGenerator::compile() {
368 if (!optimize())
369 return nullptr;
370
371 return compileOptimized();
372}
373
374bool LTOCodeGenerator::determineTarget() {
375 if (TargetMach)
376 return true;
377
378 TripleStr = MergedModule->getTargetTriple().str();
379 llvm::Triple Triple(TripleStr);
380 if (TripleStr.empty()) {
381 TripleStr = sys::getDefaultTargetTriple();
382 MergedModule->setTargetTriple(Triple);
383 }
384
385 // create target machine from info for merged modules
386 std::string ErrMsg;
387 MArch = TargetRegistry::lookupTarget(TripleStr, ErrMsg);
388 if (!MArch) {
389 emitError(ErrMsg);
390 return false;
391 }
392
393 // Construct LTOModule, hand over ownership of module and target. Use MAttr as
394 // the default set of features.
395 SubtargetFeatures Features(join(Config.MAttrs, ""));
396 Features.getDefaultSubtargetFeatures(Triple);
397 FeatureStr = Features.getString();
398 if (Config.CPU.empty())
400
401 // If data-sections is not explicitly set or unset, set data-sections by
402 // default to match the behaviour of lld and gold plugin.
404 Config.Options.DataSections = true;
405
406 TargetMach = createTargetMachine();
407 assert(TargetMach && "Unable to create target machine");
408
409 return true;
410}
411
412std::unique_ptr<TargetMachine> LTOCodeGenerator::createTargetMachine() {
413 assert(MArch && "MArch is not set!");
414 return std::unique_ptr<TargetMachine>(MArch->createTargetMachine(
415 Triple(TripleStr), Config.CPU, FeatureStr, Config.Options,
416 Config.RelocModel, std::nullopt, Config.CGOptLevel));
417}
418
419// If a linkonce global is present in the MustPreserveSymbols, we need to make
420// sure we honor this. To force the compiler to not drop it, we add it to the
421// "llvm.compiler.used" global.
422void LTOCodeGenerator::preserveDiscardableGVs(
423 Module &TheModule,
425 std::vector<GlobalValue *> Used;
426 auto mayPreserveGlobal = [&](GlobalValue &GV) {
427 if (!GV.isDiscardableIfUnused() || GV.isDeclaration() ||
428 !mustPreserveGV(GV))
429 return;
430 if (GV.hasAvailableExternallyLinkage())
431 return emitWarning(
432 (Twine("Linker asked to preserve available_externally global: '") +
433 GV.getName() + "'").str());
434 if (GV.hasInternalLinkage())
435 return emitWarning((Twine("Linker asked to preserve internal global: '") +
436 GV.getName() + "'").str());
437 Used.push_back(&GV);
438 };
439 for (auto &GV : TheModule)
440 mayPreserveGlobal(GV);
441 for (auto &GV : TheModule.globals())
442 mayPreserveGlobal(GV);
443 for (auto &GV : TheModule.aliases())
444 mayPreserveGlobal(GV);
445
446 if (Used.empty())
447 return;
448
449 appendToCompilerUsed(TheModule, Used);
450}
451
452void LTOCodeGenerator::applyScopeRestrictions() {
453 if (ScopeRestrictionsDone)
454 return;
455
456 // Declare a callback for the internalize pass that will ask for every
457 // candidate GlobalValue if it can be internalized or not.
458 Mangler Mang;
459 SmallString<64> MangledName;
460 auto mustPreserveGV = [&](const GlobalValue &GV) -> bool {
461 // Unnamed globals can't be mangled, but they can't be preserved either.
462 if (!GV.hasName())
463 return false;
464
465 // Need to mangle the GV as the "MustPreserveSymbols" StringSet is filled
466 // with the linker supplied name, which on Darwin includes a leading
467 // underscore.
468 MangledName.clear();
469 MangledName.reserve(GV.getName().size() + 1);
470 Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
471 return MustPreserveSymbols.count(MangledName);
472 };
473
474 // Preserve linkonce value on linker request
475 preserveDiscardableGVs(*MergedModule, mustPreserveGV);
476
477 if (!ShouldInternalize)
478 return;
479
480 if (ShouldRestoreGlobalsLinkage) {
481 // Record the linkage type of non-local symbols so they can be restored
482 // prior
483 // to module splitting.
484 auto RecordLinkage = [&](const GlobalValue &GV) {
485 if (!GV.hasAvailableExternallyLinkage() && !GV.hasLocalLinkage() &&
486 GV.hasName())
487 ExternalSymbols.insert(std::make_pair(GV.getName(), GV.getLinkage()));
488 };
489 for (auto &GV : *MergedModule)
490 RecordLinkage(GV);
491 for (auto &GV : MergedModule->globals())
492 RecordLinkage(GV);
493 for (auto &GV : MergedModule->aliases())
494 RecordLinkage(GV);
495 }
496
497 // Update the llvm.compiler_used globals to force preserving libcalls and
498 // symbols referenced from asm
499 updateCompilerUsed(*MergedModule, *TargetMach, AsmUndefinedRefs);
500
501 internalizeModule(*MergedModule, mustPreserveGV);
502
503 ScopeRestrictionsDone = true;
504}
505
506/// Restore original linkage for symbols that may have been internalized
507void LTOCodeGenerator::restoreLinkageForExternals() {
508 if (!ShouldInternalize || !ShouldRestoreGlobalsLinkage)
509 return;
510
511 assert(ScopeRestrictionsDone &&
512 "Cannot externalize without internalization!");
513
514 if (ExternalSymbols.empty())
515 return;
516
517 auto externalize = [this](GlobalValue &GV) {
518 if (!GV.hasLocalLinkage() || !GV.hasName())
519 return;
520
521 auto I = ExternalSymbols.find(GV.getName());
522 if (I == ExternalSymbols.end())
523 return;
524
525 GV.setLinkage(I->second);
526 };
527
528 llvm::for_each(MergedModule->functions(), externalize);
529 llvm::for_each(MergedModule->globals(), externalize);
530 llvm::for_each(MergedModule->aliases(), externalize);
531}
532
533void LTOCodeGenerator::verifyMergedModuleOnce() {
534 // Only run on the first call.
535 if (HasVerifiedInput)
536 return;
537 HasVerifiedInput = true;
538
539 bool BrokenDebugInfo = false;
540 if (verifyModule(*MergedModule, &dbgs(), &BrokenDebugInfo))
541 report_fatal_error("Broken module found, compilation aborted!");
542 if (BrokenDebugInfo) {
543 emitWarning("Invalid debug info found, debug info will be stripped");
544 StripDebugInfo(*MergedModule);
545 }
546}
547
548void LTOCodeGenerator::finishOptimizationRemarks() {
549 if (DiagnosticOutputFile) {
550 DiagnosticOutputFile->keep();
551 // FIXME: LTOCodeGenerator dtor is not invoked on Darwin
552 DiagnosticOutputFile->os().flush();
553 }
554}
555
556/// Optimize merged modules using various IPO passes
558 if (!this->determineTarget())
559 return false;
560
561 // libLTO parses options late, so re-set them here.
563
564 auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
567 if (!DiagFileOrErr) {
568 errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
569 report_fatal_error("Can't get an output file for the remarks");
570 }
571 DiagnosticOutputFile = std::move(*DiagFileOrErr);
572
573 // Setup output file to emit statistics.
574 auto StatsFileOrErr = lto::setupStatsFile(LTOStatsFile);
575 if (!StatsFileOrErr) {
576 errs() << "Error: " << toString(StatsFileOrErr.takeError()) << "\n";
577 report_fatal_error("Can't get an output file for the statistics");
578 }
579 StatsFile = std::move(StatsFileOrErr.get());
580
581 // Currently there is no support for enabling whole program visibility via a
582 // linker option in the old LTO API, but this call allows it to be specified
583 // via the internal option. Must be done before WPD invoked via the optimizer
584 // pipeline run below.
585 updatePublicTypeTestCalls(*MergedModule,
586 /* WholeProgramVisibilityEnabledInLTO */ false);
588 *MergedModule,
589 /* WholeProgramVisibilityEnabledInLTO */ false,
590 // FIXME: These need linker information via a
591 // TBD new interface.
592 /*DynamicExportSymbols=*/{},
593 /*ValidateAllVtablesHaveTypeInfos=*/false,
594 /*IsVisibleToRegularObj=*/[](StringRef) { return true; });
595
596 // We always run the verifier once on the merged module, the `DisableVerify`
597 // parameter only applies to subsequent verify.
598 verifyMergedModuleOnce();
599
600 // Mark which symbols can not be internalized
601 this->applyScopeRestrictions();
602
603 // Add an appropriate DataLayout instance for this module...
604 MergedModule->setDataLayout(TargetMach->createDataLayout());
605
606 if (!SaveIRBeforeOptPath.empty()) {
607 std::error_code EC;
608 raw_fd_ostream OS(SaveIRBeforeOptPath, EC, sys::fs::OF_None);
609 if (EC)
610 report_fatal_error(Twine("Failed to open ") + SaveIRBeforeOptPath +
611 " to save optimized bitcode\n");
612 WriteBitcodeToFile(*MergedModule, OS,
613 /* ShouldPreserveUseListOrder */ true);
614 }
615
616 ModuleSummaryIndex CombinedIndex(false);
617 TargetMach = createTargetMachine();
618 if (!opt(Config, TargetMach.get(), 0, *MergedModule, /*IsThinLTO=*/false,
619 /*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr,
620 /*CmdArgs*/ std::vector<uint8_t>())) {
621 emitError("LTO middle-end optimizations failed");
622 return false;
623 }
624
625 return true;
626}
627
629 unsigned ParallelismLevel) {
630 if (!this->determineTarget())
631 return false;
632
633 // We always run the verifier once on the merged module. If it has already
634 // been called in optimize(), this call will return early.
635 verifyMergedModuleOnce();
636
637 // Re-externalize globals that may have been internalized to increase scope
638 // for splitting
639 restoreLinkageForExternals();
640
641 ModuleSummaryIndex CombinedIndex(false);
642
643 Config.CodeGenOnly = true;
644 Error Err = backend(Config, AddStream, ParallelismLevel, *MergedModule,
645 CombinedIndex);
646 assert(!Err && "unexpected code-generation failure");
647 (void)Err;
648
649 // If statistics were requested, save them to the specified file or
650 // print them out after codegen.
651 if (StatsFile)
652 PrintStatisticsJSON(StatsFile->os());
653 else if (AreStatisticsEnabled())
655
657
658 finishOptimizationRemarks();
659
660 return true;
661}
662
664 for (StringRef Option : Options)
665 CodegenOptions.push_back(Option.str());
666}
667
669 if (!CodegenOptions.empty())
670 llvm::parseCommandLineOptions(CodegenOptions);
671}
672
673void llvm::parseCommandLineOptions(std::vector<std::string> &Options) {
674 if (!Options.empty()) {
675 // ParseCommandLineOptions() expects argv[0] to be program name.
676 std::vector<const char *> CodegenArgv(1, "libLLVMLTO");
677 for (std::string &Arg : Options)
678 CodegenArgv.push_back(Arg.c_str());
679 cl::ParseCommandLineOptions(CodegenArgv.size(), CodegenArgv.data());
680 }
681}
682
684 // Map the LLVM internal diagnostic severity to the LTO diagnostic severity.
686 switch (DI.getSeverity()) {
687 case DS_Error:
688 Severity = LTO_DS_ERROR;
689 break;
690 case DS_Warning:
691 Severity = LTO_DS_WARNING;
692 break;
693 case DS_Remark:
694 Severity = LTO_DS_REMARK;
695 break;
696 case DS_Note:
697 Severity = LTO_DS_NOTE;
698 break;
699 }
700 // Create the string that will be reported to the external diagnostic handler.
701 std::string MsgStorage;
702 raw_string_ostream Stream(MsgStorage);
704 DI.print(DP);
705 Stream.flush();
706
707 // If this method has been called it means someone has set up an external
708 // diagnostic handler. Assert on that.
709 assert(DiagHandler && "Invalid diagnostic handler");
710 (*DiagHandler)(Severity, MsgStorage.c_str(), DiagContext);
711}
712
713namespace {
714struct LTODiagnosticHandler : public DiagnosticHandler {
715 LTOCodeGenerator *CodeGenerator;
716 LTODiagnosticHandler(LTOCodeGenerator *CodeGenPtr)
717 : CodeGenerator(CodeGenPtr) {}
718 bool handleDiagnostics(const DiagnosticInfo &DI) override {
719 CodeGenerator->DiagnosticHandler(DI);
720 return true;
721 }
722};
723}
724
725void
727 void *Ctxt) {
728 this->DiagHandler = DiagHandler;
729 this->DiagContext = Ctxt;
730 if (!DiagHandler)
731 return Context.setDiagnosticHandler(nullptr);
732 // Register the LTOCodeGenerator stub in the LLVMContext to forward the
733 // diagnostic to the external DiagHandler.
734 Context.setDiagnosticHandler(std::make_unique<LTODiagnosticHandler>(this),
735 true);
736}
737
738namespace {
739class LTODiagnosticInfo : public DiagnosticInfo {
740 const Twine &Msg;
741public:
742 LTODiagnosticInfo(const Twine &DiagMsg LLVM_LIFETIME_BOUND,
743 DiagnosticSeverity Severity = DS_Error)
744 : DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {}
745 void print(DiagnosticPrinter &DP) const override { DP << Msg; }
746};
747}
748
749void LTOCodeGenerator::emitError(const std::string &ErrMsg) {
750 if (DiagHandler)
751 (*DiagHandler)(LTO_DS_ERROR, ErrMsg.c_str(), DiagContext);
752 else
753 Context.diagnose(LTODiagnosticInfo(ErrMsg));
754}
755
756void LTOCodeGenerator::emitWarning(const std::string &ErrMsg) {
757 if (DiagHandler)
758 (*DiagHandler)(LTO_DS_WARNING, ErrMsg.c_str(), DiagContext);
759 else
760 Context.diagnose(LTODiagnosticInfo(ErrMsg, DS_Warning));
761}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool mustPreserveGV(const GlobalValue &GV)
Predicate for Internalize pass.
arm prera ldst opt
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
#define LLVM_LIFETIME_BOUND
Definition: Compiler.h:435
static ManagedStatic< cl::opt< bool, true >, CreateDebug > Debug
Definition: Debug.cpp:147
std::string Name
This file implements a simple parser to decode commandline option for remarks hotness threshold that ...
Module.h This file contains the declarations for the Module class.
static LVOptions Options
Definition: LVOptions.cpp:25
#define I(x, y, z)
Definition: MD5.cpp:58
This header defines classes/functions to handle pass execution timing information with interfaces for...
Provides a library for accessing information about this process and other processes on the operating ...
static const char * name
Definition: SMEABIPass.cpp:52
raw_pwrite_stream & OS
static void externalize(GlobalValue *GV)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
This file contains some functions that are useful when dealing with strings.
This pass exposes codegen information to IR-level passes.
static void DiagHandler(const SMDiagnostic &Diag, void *Context)
Definition: TextStub.cpp:1059
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
This is the base abstract class for diagnostic reporting in the backend.
DiagnosticSeverity getSeverity() const
virtual void print(DiagnosticPrinter &DP) const =0
Print using the given DP a user-friendly message.
Basic diagnostic printer that uses an underlying raw_ostream.
Interface for custom diagnostic printing.
Represents either an error or a value T.
Definition: ErrorOr.h:56
std::error_code getError() const
Definition: ErrorOr.h:152
Lightweight error class with error context and mandatory checking.
Definition: Error.h:159
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
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).
LLVM_ABI void setDiagnosticHandler(std::unique_ptr< DiagnosticHandler > &&DH, bool RespectFilters=false)
setDiagnosticHandler - This method sets unique_ptr to object of DiagnosticHandler to provide custom d...
This class provides the core functionality of linking in LLVM.
Definition: Linker.h:23
LLVM_ABI void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable's name.
Definition: Mangler.cpp:121
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...
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
bool SLPVectorization
Tuning option to enable/disable slp loop vectorization, set based on opt level.
Definition: PassBuilder.h:59
bool LoopVectorization
Tuning option to enable/disable loop vectorization, set based on opt level.
Definition: PassBuilder.h:55
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
void reserve(size_type N)
Definition: SmallVector.h:664
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
bool empty() const
Definition: StringMap.h:108
iterator end()
Definition: StringMap.h:224
iterator find(StringRef Key)
Definition: StringMap.h:237
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
Definition: StringMap.h:280
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Definition: StringMap.h:312
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
void insert_range(Range &&R)
Definition: StringSet.h:49
Manages the enabling and disabling of subtarget specific features.
unsigned DataSections
Emit data into separate sections.
unsigned DisableIntegratedAS
Disable the integrated assembler.
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.
This class contains a raw_fd_ostream and adds a few extra features commonly needed for compiler-like ...
void keep()
Indicate that the tool's job wrt this output file has been successful and the file should not be dele...
raw_fd_ostream & os()
Return the contained raw_fd_ostream.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:47
bool isOSAIX() const
Tests whether the OS is AIX.
Definition: Triple.h:757
LLVM_ABI bool isArch64Bit() const
Test whether the architecture is 64-bit.
Definition: Triple.cpp:1771
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:82
An efficient, type-erasing, non-owning reference to a callable.
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:461
bool has_error() const
Return the value of the flag in this raw_fd_ostream indicating whether an output error has been encou...
Definition: raw_ostream.h:563
std::error_code error() const
Definition: raw_ostream.h:557
void close()
Manually flush the stream and close the file.
void clear_error()
Set the flag read by has_error() to false.
Definition: raw_ostream.h:574
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:662
static LLVM_ABI std::optional< std::string > GetEnv(StringRef name)
lto_debug_model
Definition: lto.h:79
lto_codegen_diagnostic_severity_t
Diagnostic severity.
Definition: lto.h:345
void(* lto_diagnostic_handler_t)(lto_codegen_diagnostic_severity_t severity, const char *diag, void *ctxt)
Diagnostic handler type.
Definition: lto.h:361
@ LTO_DEBUG_MODEL_DWARF
Definition: lto.h:81
@ LTO_DEBUG_MODEL_NONE
Definition: lto.h:80
@ LTO_DS_REMARK
Definition: lto.h:348
@ LTO_DS_WARNING
Definition: lto.h:347
@ LTO_DS_NOTE
Definition: lto.h:349
@ LTO_DS_ERROR
Definition: lto.h:346
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
std::optional< CodeGenOptLevel > getLevel(int OL)
Get the Level identified by the integer OL.
Definition: CodeGen.h:93
RecordLinkage
Definition: Record.h:49
LLVM_ABI bool ParseCommandLineOptions(int argc, const char *const *argv, StringRef Overview="", raw_ostream *Errs=nullptr, const char *EnvVar=nullptr, bool LongOptionsUseDoubleDash=false)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:444
LLVM_ABI std::optional< bool > getExplicitDataSections()
LLVM_ABI StringLiteral getThinLTODefaultCPU(const Triple &TheTriple)
Definition: LTO.cpp:1795
LLVM_ABI Expected< std::unique_ptr< ToolOutputFile > > setupStatsFile(StringRef StatsFilename)
Setups the output file for saving statistics.
Definition: LTO.cpp:2192
LLVM_ABI 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.
Definition: LTO.cpp:2167
LLVM_ABI std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
LLVM_ABI std::error_code real_path(const Twine &path, SmallVectorImpl< char > &output, bool expand_tilde=false)
Collapse all .
LLVM_ABI std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD, SmallVectorImpl< char > &ResultPath, OpenFlags Flags=OF_None)
Create a file in the system temporary directory.
Definition: Path.cpp:863
LLVM_ABI std::string getDefaultTargetTriple()
getDefaultTargetTriple() - Return the default target triple the compiler has been configured to produ...
LLVM_ABI int ExecuteAndWait(StringRef Program, ArrayRef< StringRef > Args, std::optional< ArrayRef< StringRef > > Env=std::nullopt, ArrayRef< std::optional< StringRef > > Redirects={}, unsigned SecondsToWait=0, unsigned MemoryLimit=0, std::string *ErrMsg=nullptr, bool *ExecutionFailed=nullptr, std::optional< ProcessStatistics > *ProcStat=nullptr, BitVector *AffinityMask=nullptr)
This function executes the program using the arguments provided.
Definition: Program.cpp:32
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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"))
UnaryFunction for_each(R &&Range, UnaryFunction F)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1737
cl::opt< bool > LTODiscardValueNames("lto-discard-value-names", cl::desc("Strip names from Value during LTO (other than GlobalValue)."), cl::init(false), cl::Hidden)
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.
bool internalizeModule(Module &TheModule, std::function< bool(const GlobalValue &)> MustPreserveGV)
Helper function to internalize functions and variables in a Module.
Definition: Internalize.h:78
static cl::opt< std::string > LTOCSIRProfile("cs-profile-path", cl::desc("Context sensitive profile file path"))
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::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.
Definition: Caching.h:60
void updateCompilerUsed(Module &TheModule, const TargetMachine &TM, const StringSet<> &AsmUndefinedRefs)
Find all globals in TheModule that are referenced in AsmUndefinedRefs, as well as the user-supplied f...
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.
@ DK_Linker
static cl::opt< std::string > AIXSystemAssemblerPath("lto-aix-system-assembler", cl::desc("Path to a system assembler, picked up on AIX only"), cl::value_desc("path"))
LLVM_ABI void updatePublicTypeTestCalls(Module &M, bool WholeProgramVisibilityEnabledInLTO)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition: Error.cpp:167
LLVM_ABI bool AreStatisticsEnabled()
Check if statistics are enabled.
Definition: Statistic.cpp:139
cl::opt< bool > RemarksWithHotness("lto-pass-remarks-with-hotness", cl::desc("With PGO, include profile count in optimization remarks"), cl::Hidden)
cl::opt< std::string > RemarksFilename("lto-pass-remarks-output", cl::desc("Output filename for pass remarks"), cl::value_desc("filename"))
LLVM_ABI void parseCommandLineOptions(std::vector< std::string > &Options)
A convenience function that calls cl::ParseCommandLineOptions on the given set of options.
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.
Definition: DebugInfo.cpp:565
@ Mod
The access may modify the value stored in memory.
LLVM_ABI void PrintStatistics()
Print statistics to the file returned by CreateInfoOutputFile().
Definition: Statistic.cpp:229
LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
DiagnosticSeverity
Defines the different supported severity of a diagnostic.
@ DS_Remark
@ DS_Warning
@ DS_Error
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)
const char * toString(DWARFSectionKind Kind)
static cl::opt< std::string > LTOStatsFile("lto-stats-file", cl::desc("Save statistics to the specified file"), cl::Hidden)
LLVM_ABI void PrintStatisticsJSON(raw_ostream &OS)
Print statistics in JSON format.
Definition: Statistic.cpp:203
static cl::opt< bool > LTORunCSIRInstr("cs-profile-generate", cl::desc("Perform context sensitive PGO instrumentation"))
LLVM_ABI void updateVCallVisibilityInModule(Module &M, bool WholeProgramVisibilityEnabledInLTO, const DenseSet< GlobalValue::GUID > &DynamicExportSymbols, bool ValidateAllVtablesHaveTypeInfos, function_ref< bool(StringRef)> IsVisibleToRegularObj)
If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...
LLVM_ABI bool verifyModule(const Module &M, raw_ostream *OS=nullptr, bool *BrokenDebugInfo=nullptr)
Check a module for errors.
Definition: Verifier.cpp:7513
#define NDEBUG
Definition: regutils.h:48
This is the base class for diagnostic handling in LLVM.
C++ class which implements the opaque lto_code_gen_t type.
LLVM_ABI bool optimize()
Optimizes the merged module.
LLVM_ABI std::unique_ptr< MemoryBuffer > compile()
As with compile_to_file(), this function compiles the merged module into single output file.
LLVM_ABI void setModule(std::unique_ptr< LTOModule > M)
Set the destination module.
LLVM_ABI bool compile_to_file(const char **Name)
Compile the merged module into a single output file; the path to output file is returned to the calle...
LLVM_ABI void parseCodeGenDebugOptions()
Parse the options set in setCodeGenDebugOptions.
LLVM_ABI void setOptLevel(unsigned OptLevel)
LLVM_ABI void setAsmUndefinedRefs(struct LTOModule *)
LLVM_ABI void setDiagnosticHandler(lto_diagnostic_handler_t, void *)
void setFileType(CodeGenFileType FT)
Set the file type to be emitted (assembly or object code).
LLVM_ABI void setTargetOptions(const TargetOptions &Options)
LLVM_ABI void setCodeGenDebugOptions(ArrayRef< StringRef > Opts)
Pass options to the driver and optimization passes.
LLVM_ABI LTOCodeGenerator(LLVMContext &Context)
LLVM_ABI std::unique_ptr< MemoryBuffer > compileOptimized()
Compiles the merged optimized module into a single output file.
LLVM_ABI bool addModule(struct LTOModule *)
Merge given module.
LLVM_ABI void setDebugInfo(lto_debug_model)
LLVM_ABI ~LTOCodeGenerator()
LLVM_ABI bool writeMergedModules(StringRef Path)
Write the merged module to the file specified by the given path.
LLVM_ABI void DiagnosticHandler(const DiagnosticInfo &DI)
static LLVM_ABI const char * getVersionString()
C++ class which implements the opaque lto_module_t type.
Definition: LTOModule.h:39
static const Target * lookupTarget(StringRef TripleStr, std::string &Error)
lookupTarget - Lookup a target based on a target triple.
std::string StatsFile
Statistics output file path.
Definition: Config.h:175
std::optional< CodeModel::Model > CodeModel
Definition: Config.h:57
bool CodeGenOnly
Disable entirely the optimizer, including importing for ThinLTO.
Definition: Config.h:69
std::vector< std::string > MAttrs
Definition: Config.h:51
CodeGenOptLevel CGOptLevel
Definition: Config.h:58
PipelineTuningOptions PTO
Tunable parameters for passes in the default pipelines.
Definition: Config.h:199
std::string CPU
Definition: Config.h:49
TargetOptions Options
Definition: Config.h:50
bool RunCSIRInstr
Run PGO context sensitive IR instrumentation.
Definition: Config.h:72
unsigned OptLevel
Definition: Config.h:60
std::string CSIRProfile
Context Sensitive PGO profile path.
Definition: Config.h:122
std::optional< Reloc::Model > RelocModel
Definition: Config.h:56
CodeGenFileType CGFileType
Definition: Config.h:59