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