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