LLVM 19.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"
24#include "llvm/Config/config.h"
25#include "llvm/IR/Constants.h"
26#include "llvm/IR/DataLayout.h"
27#include "llvm/IR/DebugInfo.h"
31#include "llvm/IR/LLVMContext.h"
34#include "llvm/IR/Mangler.h"
35#include "llvm/IR/Module.h"
37#include "llvm/IR/Verifier.h"
38#include "llvm/LTO/LTO.h"
39#include "llvm/LTO/LTOBackend.h"
42#include "llvm/Linker/Linker.h"
43#include "llvm/MC/MCAsmInfo.h"
44#include "llvm/MC/MCContext.h"
59#include "llvm/Transforms/IPO.h"
64#include <optional>
65#include <system_error>
66using namespace llvm;
67
69 return PACKAGE_NAME " version " PACKAGE_VERSION;
70}
71
72namespace llvm {
74 "lto-discard-value-names",
75 cl::desc("Strip names from Value during LTO (other than GlobalValue)."),
76#ifdef NDEBUG
77 cl::init(true),
78#else
79 cl::init(false),
80#endif
82
84 "lto-pass-remarks-with-hotness",
85 cl::desc("With PGO, include profile count in optimization remarks"),
87
90 "lto-pass-remarks-hotness-threshold",
91 cl::desc("Minimum profile count required for an "
92 "optimization remark to be output."
93 " Use 'auto' to apply the threshold from profile summary."),
94 cl::value_desc("uint or 'auto'"), cl::init(0), cl::Hidden);
95
97 RemarksFilename("lto-pass-remarks-output",
98 cl::desc("Output filename for pass remarks"),
99 cl::value_desc("filename"));
100
102 RemarksPasses("lto-pass-remarks-filter",
103 cl::desc("Only record optimization remarks from passes whose "
104 "names match the given regular expression"),
105 cl::value_desc("regex"));
106
108 "lto-pass-remarks-format",
109 cl::desc("The format used for serializing remarks (default: YAML)"),
110 cl::value_desc("format"), cl::init("yaml"));
111
113 "lto-stats-file",
114 cl::desc("Save statistics to the specified file"),
115 cl::Hidden);
116
118 "lto-aix-system-assembler",
119 cl::desc("Path to a system assembler, picked up on AIX only"),
120 cl::value_desc("path"));
121
123 LTORunCSIRInstr("cs-profile-generate",
124 cl::desc("Perform context sensitive PGO instrumentation"));
125
127 LTOCSIRProfile("cs-profile-path",
128 cl::desc("Context sensitive profile file path"));
129} // namespace llvm
130
132 : Context(Context), MergedModule(new Module("ld-temp.o", Context)),
133 TheLinker(new Linker(*MergedModule)) {
136
137 Config.CodeModel = std::nullopt;
138 Config.StatsFile = LTOStatsFile;
141 };
142
145}
146
148
150 for (const StringRef &Undef : Mod->getAsmUndefinedRefs())
151 AsmUndefinedRefs.insert(Undef);
152}
153
155 assert(&Mod->getModule().getContext() == &Context &&
156 "Expected module in same context");
157
158 bool ret = TheLinker->linkInModule(Mod->takeModule());
160
161 // We've just changed the input, so let's make sure we verify it.
162 HasVerifiedInput = false;
163
164 return !ret;
165}
166
167void LTOCodeGenerator::setModule(std::unique_ptr<LTOModule> Mod) {
168 assert(&Mod->getModule().getContext() == &Context &&
169 "Expected module in same context");
170
171 AsmUndefinedRefs.clear();
172
173 MergedModule = Mod->takeModule();
174 TheLinker = std::make_unique<Linker>(*MergedModule);
176
177 // We've just changed the input, so let's make sure we verify it.
178 HasVerifiedInput = false;
179}
180
182 Config.Options = Options;
183}
184
186 switch (Debug) {
188 EmitDwarfDebugInfo = false;
189 return;
190
192 EmitDwarfDebugInfo = true;
193 return;
194 }
195 llvm_unreachable("Unknown debug format!");
196}
197
198void LTOCodeGenerator::setOptLevel(unsigned Level) {
199 Config.OptLevel = Level;
200 Config.PTO.LoopVectorization = Config.OptLevel > 1;
201 Config.PTO.SLPVectorization = Config.OptLevel > 1;
202 std::optional<CodeGenOptLevel> CGOptLevelOrNone =
204 assert(CGOptLevelOrNone && "Unknown optimization level!");
205 Config.CGOptLevel = *CGOptLevelOrNone;
206}
207
209 if (!determineTarget())
210 return false;
211
212 // We always run the verifier once on the merged module.
213 verifyMergedModuleOnce();
214
215 // mark which symbols can not be internalized
216 applyScopeRestrictions();
217
218 // create output file
219 std::error_code EC;
220 ToolOutputFile Out(Path, EC, sys::fs::OF_None);
221 if (EC) {
222 std::string ErrMsg = "could not open bitcode file for writing: ";
223 ErrMsg += Path.str() + ": " + EC.message();
224 emitError(ErrMsg);
225 return false;
226 }
227
228 // write bitcode to it
229 WriteBitcodeToFile(*MergedModule, Out.os(), ShouldEmbedUselists);
230 Out.os().close();
231
232 if (Out.os().has_error()) {
233 std::string ErrMsg = "could not write bitcode file: ";
234 ErrMsg += Path.str() + ": " + Out.os().error().message();
235 emitError(ErrMsg);
236 Out.os().clear_error();
237 return false;
238 }
239
240 Out.keep();
241 return true;
242}
243
244bool LTOCodeGenerator::useAIXSystemAssembler() {
245 const auto &Triple = TargetMach->getTargetTriple();
246 return Triple.isOSAIX() && Config.Options.DisableIntegratedAS;
247}
248
249bool LTOCodeGenerator::runAIXSystemAssembler(SmallString<128> &AssemblyFile) {
250 assert(useAIXSystemAssembler() &&
251 "Runing AIX system assembler when integrated assembler is available!");
252
253 // Set the system assembler path.
254 SmallString<256> AssemblerPath("/usr/bin/as");
255 if (!llvm::AIXSystemAssemblerPath.empty()) {
257 /* expand_tilde */ true)) {
258 emitError(
259 "Cannot find the assembler specified by lto-aix-system-assembler");
260 return false;
261 }
262 }
263
264 // Setup the LDR_CNTRL variable
265 std::string LDR_CNTRL_var = "LDR_CNTRL=MAXDATA32=0xA0000000@DSA";
266 if (std::optional<std::string> V = sys::Process::GetEnv("LDR_CNTRL"))
267 LDR_CNTRL_var += ("@" + *V);
268
269 // Prepare inputs for the assember.
270 const auto &Triple = TargetMach->getTargetTriple();
271 const char *Arch = Triple.isArch64Bit() ? "-a64" : "-a32";
272 std::string ObjectFileName(AssemblyFile);
273 ObjectFileName[ObjectFileName.size() - 1] = 'o';
275 "/bin/env", LDR_CNTRL_var,
276 AssemblerPath, Arch,
277 "-many", "-o",
278 ObjectFileName, AssemblyFile};
279
280 // Invoke the assembler.
281 int RC = sys::ExecuteAndWait(Args[0], Args);
282
283 // Handle errors.
284 if (RC < -1) {
285 emitError("LTO assembler exited abnormally");
286 return false;
287 }
288 if (RC < 0) {
289 emitError("Unable to invoke LTO assembler");
290 return false;
291 }
292 if (RC > 0) {
293 emitError("LTO assembler invocation returned non-zero");
294 return false;
295 }
296
297 // Cleanup.
298 remove(AssemblyFile.c_str());
299
300 // Fix the output file name.
301 AssemblyFile = ObjectFileName;
302
303 return true;
304}
305
306bool LTOCodeGenerator::compileOptimizedToFile(const char **Name) {
307 if (useAIXSystemAssembler())
309
310 // make unique temp output file to put generated code
312
313 auto AddStream =
314 [&](size_t Task,
315 const Twine &ModuleName) -> std::unique_ptr<CachedFileStream> {
317 Config.CGFileType == CodeGenFileType::AssemblyFile ? "s" : "o");
318
319 int FD;
320 std::error_code EC =
321 sys::fs::createTemporaryFile("lto-llvm", Extension, FD, Filename);
322 if (EC)
323 emitError(EC.message());
324
325 return std::make_unique<CachedFileStream>(
326 std::make_unique<llvm::raw_fd_ostream>(FD, true));
327 };
328
329 bool genResult = compileOptimized(AddStream, 1);
330
331 if (!genResult) {
332 sys::fs::remove(Twine(Filename));
333 return false;
334 }
335
336 // If statistics were requested, save them to the specified file or
337 // print them out after codegen.
338 if (StatsFile)
339 PrintStatisticsJSON(StatsFile->os());
340 else if (AreStatisticsEnabled())
342
343 if (useAIXSystemAssembler())
344 if (!runAIXSystemAssembler(Filename))
345 return false;
346
347 NativeObjectPath = Filename.c_str();
348 *Name = NativeObjectPath.c_str();
349 return true;
350}
351
352std::unique_ptr<MemoryBuffer>
354 const char *name;
355 if (!compileOptimizedToFile(&name))
356 return nullptr;
357
358 // read .o file into memory buffer
360 name, /*IsText=*/false, /*RequiresNullTerminator=*/false);
361 if (std::error_code EC = BufferOrErr.getError()) {
362 emitError(EC.message());
363 sys::fs::remove(NativeObjectPath);
364 return nullptr;
365 }
366
367 // remove temp files
368 sys::fs::remove(NativeObjectPath);
369
370 return std::move(*BufferOrErr);
371}
372
374 if (!optimize())
375 return false;
376
377 return compileOptimizedToFile(Name);
378}
379
380std::unique_ptr<MemoryBuffer> LTOCodeGenerator::compile() {
381 if (!optimize())
382 return nullptr;
383
384 return compileOptimized();
385}
386
387bool LTOCodeGenerator::determineTarget() {
388 if (TargetMach)
389 return true;
390
391 TripleStr = MergedModule->getTargetTriple();
392 if (TripleStr.empty()) {
393 TripleStr = sys::getDefaultTargetTriple();
394 MergedModule->setTargetTriple(TripleStr);
395 }
396 llvm::Triple Triple(TripleStr);
397
398 // create target machine from info for merged modules
399 std::string ErrMsg;
400 MArch = TargetRegistry::lookupTarget(TripleStr, ErrMsg);
401 if (!MArch) {
402 emitError(ErrMsg);
403 return false;
404 }
405
406 // Construct LTOModule, hand over ownership of module and target. Use MAttr as
407 // the default set of features.
408 SubtargetFeatures Features(join(Config.MAttrs, ""));
409 Features.getDefaultSubtargetFeatures(Triple);
410 FeatureStr = Features.getString();
411 if (Config.CPU.empty())
413
414 // If data-sections is not explicitly set or unset, set data-sections by
415 // default to match the behaviour of lld and gold plugin.
417 Config.Options.DataSections = true;
418
419 TargetMach = createTargetMachine();
420 assert(TargetMach && "Unable to create target machine");
421
422 return true;
423}
424
425std::unique_ptr<TargetMachine> LTOCodeGenerator::createTargetMachine() {
426 assert(MArch && "MArch is not set!");
427 return std::unique_ptr<TargetMachine>(MArch->createTargetMachine(
428 TripleStr, Config.CPU, FeatureStr, Config.Options, Config.RelocModel,
429 std::nullopt, Config.CGOptLevel));
430}
431
432// If a linkonce global is present in the MustPreserveSymbols, we need to make
433// sure we honor this. To force the compiler to not drop it, we add it to the
434// "llvm.compiler.used" global.
435void LTOCodeGenerator::preserveDiscardableGVs(
436 Module &TheModule,
438 std::vector<GlobalValue *> Used;
439 auto mayPreserveGlobal = [&](GlobalValue &GV) {
440 if (!GV.isDiscardableIfUnused() || GV.isDeclaration() ||
441 !mustPreserveGV(GV))
442 return;
443 if (GV.hasAvailableExternallyLinkage())
444 return emitWarning(
445 (Twine("Linker asked to preserve available_externally global: '") +
446 GV.getName() + "'").str());
447 if (GV.hasInternalLinkage())
448 return emitWarning((Twine("Linker asked to preserve internal global: '") +
449 GV.getName() + "'").str());
450 Used.push_back(&GV);
451 };
452 for (auto &GV : TheModule)
453 mayPreserveGlobal(GV);
454 for (auto &GV : TheModule.globals())
455 mayPreserveGlobal(GV);
456 for (auto &GV : TheModule.aliases())
457 mayPreserveGlobal(GV);
458
459 if (Used.empty())
460 return;
461
462 appendToCompilerUsed(TheModule, Used);
463}
464
465void LTOCodeGenerator::applyScopeRestrictions() {
466 if (ScopeRestrictionsDone)
467 return;
468
469 // Declare a callback for the internalize pass that will ask for every
470 // candidate GlobalValue if it can be internalized or not.
471 Mangler Mang;
472 SmallString<64> MangledName;
473 auto mustPreserveGV = [&](const GlobalValue &GV) -> bool {
474 // Unnamed globals can't be mangled, but they can't be preserved either.
475 if (!GV.hasName())
476 return false;
477
478 // Need to mangle the GV as the "MustPreserveSymbols" StringSet is filled
479 // with the linker supplied name, which on Darwin includes a leading
480 // underscore.
481 MangledName.clear();
482 MangledName.reserve(GV.getName().size() + 1);
483 Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
484 return MustPreserveSymbols.count(MangledName);
485 };
486
487 // Preserve linkonce value on linker request
488 preserveDiscardableGVs(*MergedModule, mustPreserveGV);
489
490 if (!ShouldInternalize)
491 return;
492
493 if (ShouldRestoreGlobalsLinkage) {
494 // Record the linkage type of non-local symbols so they can be restored
495 // prior
496 // to module splitting.
497 auto RecordLinkage = [&](const GlobalValue &GV) {
498 if (!GV.hasAvailableExternallyLinkage() && !GV.hasLocalLinkage() &&
499 GV.hasName())
500 ExternalSymbols.insert(std::make_pair(GV.getName(), GV.getLinkage()));
501 };
502 for (auto &GV : *MergedModule)
503 RecordLinkage(GV);
504 for (auto &GV : MergedModule->globals())
505 RecordLinkage(GV);
506 for (auto &GV : MergedModule->aliases())
507 RecordLinkage(GV);
508 }
509
510 // Update the llvm.compiler_used globals to force preserving libcalls and
511 // symbols referenced from asm
512 updateCompilerUsed(*MergedModule, *TargetMach, AsmUndefinedRefs);
513
514 internalizeModule(*MergedModule, mustPreserveGV);
515
516 ScopeRestrictionsDone = true;
517}
518
519/// Restore original linkage for symbols that may have been internalized
520void LTOCodeGenerator::restoreLinkageForExternals() {
521 if (!ShouldInternalize || !ShouldRestoreGlobalsLinkage)
522 return;
523
524 assert(ScopeRestrictionsDone &&
525 "Cannot externalize without internalization!");
526
527 if (ExternalSymbols.empty())
528 return;
529
530 auto externalize = [this](GlobalValue &GV) {
531 if (!GV.hasLocalLinkage() || !GV.hasName())
532 return;
533
534 auto I = ExternalSymbols.find(GV.getName());
535 if (I == ExternalSymbols.end())
536 return;
537
538 GV.setLinkage(I->second);
539 };
540
541 llvm::for_each(MergedModule->functions(), externalize);
542 llvm::for_each(MergedModule->globals(), externalize);
543 llvm::for_each(MergedModule->aliases(), externalize);
544}
545
546void LTOCodeGenerator::verifyMergedModuleOnce() {
547 // Only run on the first call.
548 if (HasVerifiedInput)
549 return;
550 HasVerifiedInput = true;
551
552 bool BrokenDebugInfo = false;
553 if (verifyModule(*MergedModule, &dbgs(), &BrokenDebugInfo))
554 report_fatal_error("Broken module found, compilation aborted!");
555 if (BrokenDebugInfo) {
556 emitWarning("Invalid debug info found, debug info will be stripped");
557 StripDebugInfo(*MergedModule);
558 }
559}
560
561void LTOCodeGenerator::finishOptimizationRemarks() {
562 if (DiagnosticOutputFile) {
563 DiagnosticOutputFile->keep();
564 // FIXME: LTOCodeGenerator dtor is not invoked on Darwin
565 DiagnosticOutputFile->os().flush();
566 }
567}
568
569/// Optimize merged modules using various IPO passes
571 if (!this->determineTarget())
572 return false;
573
574 // libLTO parses options late, so re-set them here.
576
577 auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
580 if (!DiagFileOrErr) {
581 errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
582 report_fatal_error("Can't get an output file for the remarks");
583 }
584 DiagnosticOutputFile = std::move(*DiagFileOrErr);
585
586 // Setup output file to emit statistics.
587 auto StatsFileOrErr = lto::setupStatsFile(LTOStatsFile);
588 if (!StatsFileOrErr) {
589 errs() << "Error: " << toString(StatsFileOrErr.takeError()) << "\n";
590 report_fatal_error("Can't get an output file for the statistics");
591 }
592 StatsFile = std::move(StatsFileOrErr.get());
593
594 // Currently there is no support for enabling whole program visibility via a
595 // linker option in the old LTO API, but this call allows it to be specified
596 // via the internal option. Must be done before WPD invoked via the optimizer
597 // pipeline run below.
598 updatePublicTypeTestCalls(*MergedModule,
599 /* WholeProgramVisibilityEnabledInLTO */ false);
601 *MergedModule,
602 /* WholeProgramVisibilityEnabledInLTO */ false,
603 // FIXME: These need linker information via a
604 // TBD new interface.
605 /*DynamicExportSymbols=*/{},
606 /*ValidateAllVtablesHaveTypeInfos=*/false,
607 /*IsVisibleToRegularObj=*/[](StringRef) { return true; });
608
609 // We always run the verifier once on the merged module, the `DisableVerify`
610 // parameter only applies to subsequent verify.
611 verifyMergedModuleOnce();
612
613 // Mark which symbols can not be internalized
614 this->applyScopeRestrictions();
615
616 // Add an appropriate DataLayout instance for this module...
617 MergedModule->setDataLayout(TargetMach->createDataLayout());
618
619 if (!SaveIRBeforeOptPath.empty()) {
620 std::error_code EC;
621 raw_fd_ostream OS(SaveIRBeforeOptPath, EC, sys::fs::OF_None);
622 if (EC)
623 report_fatal_error(Twine("Failed to open ") + SaveIRBeforeOptPath +
624 " to save optimized bitcode\n");
625 WriteBitcodeToFile(*MergedModule, OS,
626 /* ShouldPreserveUseListOrder */ true);
627 }
628
629 ModuleSummaryIndex CombinedIndex(false);
630 TargetMach = createTargetMachine();
631 if (!opt(Config, TargetMach.get(), 0, *MergedModule, /*IsThinLTO=*/false,
632 /*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr,
633 /*CmdArgs*/ std::vector<uint8_t>())) {
634 emitError("LTO middle-end optimizations failed");
635 return false;
636 }
637
638 return true;
639}
640
642 unsigned ParallelismLevel) {
643 if (!this->determineTarget())
644 return false;
645
646 // We always run the verifier once on the merged module. If it has already
647 // been called in optimize(), this call will return early.
648 verifyMergedModuleOnce();
649
650 // Re-externalize globals that may have been internalized to increase scope
651 // for splitting
652 restoreLinkageForExternals();
653
654 ModuleSummaryIndex CombinedIndex(false);
655
656 Config.CodeGenOnly = true;
657 Error Err = backend(Config, AddStream, ParallelismLevel, *MergedModule,
658 CombinedIndex);
659 assert(!Err && "unexpected code-generation failure");
660 (void)Err;
661
662 // If statistics were requested, save them to the specified file or
663 // print them out after codegen.
664 if (StatsFile)
665 PrintStatisticsJSON(StatsFile->os());
666 else if (AreStatisticsEnabled())
668
670
671 finishOptimizationRemarks();
672
673 return true;
674}
675
677 for (StringRef Option : Options)
678 CodegenOptions.push_back(Option.str());
679}
680
682 if (!CodegenOptions.empty())
683 llvm::parseCommandLineOptions(CodegenOptions);
684}
685
686void llvm::parseCommandLineOptions(std::vector<std::string> &Options) {
687 if (!Options.empty()) {
688 // ParseCommandLineOptions() expects argv[0] to be program name.
689 std::vector<const char *> CodegenArgv(1, "libLLVMLTO");
690 for (std::string &Arg : Options)
691 CodegenArgv.push_back(Arg.c_str());
692 cl::ParseCommandLineOptions(CodegenArgv.size(), CodegenArgv.data());
693 }
694}
695
697 // Map the LLVM internal diagnostic severity to the LTO diagnostic severity.
699 switch (DI.getSeverity()) {
700 case DS_Error:
701 Severity = LTO_DS_ERROR;
702 break;
703 case DS_Warning:
704 Severity = LTO_DS_WARNING;
705 break;
706 case DS_Remark:
707 Severity = LTO_DS_REMARK;
708 break;
709 case DS_Note:
710 Severity = LTO_DS_NOTE;
711 break;
712 }
713 // Create the string that will be reported to the external diagnostic handler.
714 std::string MsgStorage;
715 raw_string_ostream Stream(MsgStorage);
717 DI.print(DP);
718 Stream.flush();
719
720 // If this method has been called it means someone has set up an external
721 // diagnostic handler. Assert on that.
722 assert(DiagHandler && "Invalid diagnostic handler");
723 (*DiagHandler)(Severity, MsgStorage.c_str(), DiagContext);
724}
725
726namespace {
727struct LTODiagnosticHandler : public DiagnosticHandler {
728 LTOCodeGenerator *CodeGenerator;
729 LTODiagnosticHandler(LTOCodeGenerator *CodeGenPtr)
730 : CodeGenerator(CodeGenPtr) {}
731 bool handleDiagnostics(const DiagnosticInfo &DI) override {
732 CodeGenerator->DiagnosticHandler(DI);
733 return true;
734 }
735};
736}
737
738void
740 void *Ctxt) {
741 this->DiagHandler = DiagHandler;
742 this->DiagContext = Ctxt;
743 if (!DiagHandler)
744 return Context.setDiagnosticHandler(nullptr);
745 // Register the LTOCodeGenerator stub in the LLVMContext to forward the
746 // diagnostic to the external DiagHandler.
747 Context.setDiagnosticHandler(std::make_unique<LTODiagnosticHandler>(this),
748 true);
749}
750
751namespace {
752class LTODiagnosticInfo : public DiagnosticInfo {
753 const Twine &Msg;
754public:
755 LTODiagnosticInfo(const Twine &DiagMsg, DiagnosticSeverity Severity=DS_Error)
756 : DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {}
757 void print(DiagnosticPrinter &DP) const override { DP << Msg; }
758};
759}
760
761void LTOCodeGenerator::emitError(const std::string &ErrMsg) {
762 if (DiagHandler)
763 (*DiagHandler)(LTO_DS_ERROR, ErrMsg.c_str(), DiagContext);
764 else
765 Context.diagnose(LTODiagnosticInfo(ErrMsg));
766}
767
768void LTOCodeGenerator::emitWarning(const std::string &ErrMsg) {
769 if (DiagHandler)
770 (*DiagHandler)(LTO_DS_WARNING, ErrMsg.c_str(), DiagContext);
771 else
772 Context.diagnose(LTODiagnosticInfo(ErrMsg, DS_Warning));
773}
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)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
std::string Name
This file implements a simple parser to decode commandline option for remarks hotness threshold that ...
static LVOptions Options
Definition: LVOptions.cpp:25
#define I(x, y, z)
Definition: MD5.cpp:58
Module.h This file contains the declarations for the Module class.
bool Debug
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 ...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const char * name
Definition: SMEABIPass.cpp:50
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:1060
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:160
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
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).
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:22
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:120
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:65
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:676
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
bool empty() const
Definition: StringMap.h:103
iterator end()
Definition: StringMap.h:220
iterator find(StringRef Key)
Definition: StringMap.h:233
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
Definition: StringMap.h:276
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Definition: StringMap.h:308
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::pair< typename Base::iterator, bool > insert(StringRef key)
Definition: StringSet.h:38
Manages the enabling and disabling of subtarget specific features.
unsigned DataSections
Emit data into separate sections.
unsigned DisableIntegratedAS
Disable the integrated assembler.
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.
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:44
bool isOSAIX() const
Tests whether the OS is AIX.
Definition: Triple.h:710
bool isArch64Bit() const
Test whether the architecture is 64-bit.
Definition: Triple.cpp:1661
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
An efficient, type-erasing, non-owning reference to a callable.
PassManager manages ModulePassManagers.
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:460
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:562
std::error_code error() const
Definition: raw_ostream.h:556
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:573
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:661
static std::optional< std::string > GetEnv(StringRef name)
lto_debug_model
Definition: lto.h:79
lto_codegen_diagnostic_severity_t
Diagnostic severity.
Definition: lto.h:330
void(* lto_diagnostic_handler_t)(lto_codegen_diagnostic_severity_t severity, const char *diag, void *ctxt)
Diagnostic handler type.
Definition: lto.h:346
@ LTO_DEBUG_MODEL_DWARF
Definition: lto.h:81
@ LTO_DEBUG_MODEL_NONE
Definition: lto.h:80
@ LTO_DS_REMARK
Definition: lto.h:333
@ LTO_DS_WARNING
Definition: lto.h:332
@ LTO_DS_NOTE
Definition: lto.h:334
@ LTO_DS_ERROR
Definition: lto.h:331
#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:65
RecordLinkage
Definition: Record.h:48
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:443
std::optional< bool > getExplicitDataSections()
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
StringLiteral getThinLTODefaultCPU(const Triple &TheTriple)
Definition: LTO.cpp:1578
Expected< std::unique_ptr< ToolOutputFile > > setupStatsFile(StringRef StatsFilename)
Setups the output file for saving statistics.
Definition: LTO.cpp:1912
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:1887
std::error_code real_path(const Twine &path, SmallVectorImpl< char > &output, bool expand_tilde=false)
Collapse all .
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
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:864
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
std::string getDefaultTargetTriple()
getDefaultTargetTriple() - Return the default target triple the compiler has been configured to produ...
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:1715
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.
bool internalizeModule(Module &TheModule, std::function< bool(const GlobalValue &)> MustPreserveGV)
Helper function to internalize functions and variables in a Module.
Definition: Internalize.h:77
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:42
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...
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
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"))
void updatePublicTypeTestCalls(Module &M, bool WholeProgramVisibilityEnabledInLTO)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
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"))
void parseCommandLineOptions(std::vector< std::string > &Options)
A convenience function that calls cl::ParseCommandLineOptions on the given set of options.
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.
Definition: DebugInfo.cpp:591
@ Mod
The access may modify the value stored in memory.
void PrintStatistics()
Print statistics to the file returned by CreateInfoOutputFile().
Definition: Statistic.cpp:229
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)
cl::opt< std::string > LTOStatsFile("lto-stats-file", cl::desc("Save statistics to the specified file"), cl::Hidden)
Pass * createObjCARCContractPass()
void PrintStatisticsJSON(raw_ostream &OS)
Print statistics in JSON format.
Definition: Statistic.cpp:203
cl::opt< bool > LTORunCSIRInstr("cs-profile-generate", cl::desc("Perform context sensitive PGO instrumentation"))
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...
bool verifyModule(const Module &M, raw_ostream *OS=nullptr, bool *BrokenDebugInfo=nullptr)
Check a module for errors.
Definition: Verifier.cpp:7131
#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.
bool optimize()
Optimizes the merged module.
std::unique_ptr< MemoryBuffer > compile()
As with compile_to_file(), this function compiles the merged module into single output file.
void setModule(std::unique_ptr< LTOModule > M)
Set the destination module.
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...
void parseCodeGenDebugOptions()
Parse the options set in setCodeGenDebugOptions.
void setOptLevel(unsigned OptLevel)
void setAsmUndefinedRefs(struct LTOModule *)
void setDiagnosticHandler(lto_diagnostic_handler_t, void *)
void setFileType(CodeGenFileType FT)
Set the file type to be emitted (assembly or object code).
void setTargetOptions(const TargetOptions &Options)
void setCodeGenDebugOptions(ArrayRef< StringRef > Opts)
Pass options to the driver and optimization passes.
LTOCodeGenerator(LLVMContext &Context)
std::unique_ptr< MemoryBuffer > compileOptimized()
Compiles the merged optimized module into a single output file.
bool addModule(struct LTOModule *)
Merge given module.
void setDebugInfo(lto_debug_model)
bool writeMergedModules(StringRef Path)
Write the merged module to the file specified by the given path.
void DiagnosticHandler(const DiagnosticInfo &DI)
static const char * getVersionString()
C++ class which implements the opaque lto_module_t type.
Definition: LTOModule.h:38
static const Target * lookupTarget(StringRef Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.
std::string StatsFile
Statistics output file path.
Definition: Config.h:169
std::optional< CodeModel::Model > CodeModel
Definition: Config.h:56
std::function< void(legacy::PassManager &)> PreCodeGenPassesHook
For adding passes that run right before codegen.
Definition: Config.h:54
bool CodeGenOnly
Disable entirely the optimizer, including importing for ThinLTO.
Definition: Config.h:68
std::vector< std::string > MAttrs
Definition: Config.h:50
CodeGenOptLevel CGOptLevel
Definition: Config.h:57
PipelineTuningOptions PTO
Tunable parameters for passes in the default pipelines.
Definition: Config.h:193
std::string CPU
Definition: Config.h:48
TargetOptions Options
Definition: Config.h:49
bool RunCSIRInstr
Run PGO context sensitive IR instrumentation.
Definition: Config.h:71
unsigned OptLevel
Definition: Config.h:59
std::string CSIRProfile
Context Sensitive PGO profile path.
Definition: Config.h:116
std::optional< Reloc::Model > RelocModel
Definition: Config.h:55
CodeGenFileType CGFileType
Definition: Config.h:58