LLVM 17.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<CodeGenOpt::Level> 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();
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> {
317 StringRef Extension(Config.CGFileType == CGFT_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 // Set a default CPU for Darwin triples.
412 if (Config.CPU.empty() && Triple.isOSDarwin()) {
414 Config.CPU = "core2";
415 else if (Triple.getArch() == llvm::Triple::x86)
416 Config.CPU = "yonah";
417 else if (Triple.isArm64e())
418 Config.CPU = "apple-a12";
419 else if (Triple.getArch() == llvm::Triple::aarch64 ||
421 Config.CPU = "cyclone";
422 }
423
424 // If data-sections is not explicitly set or unset, set data-sections by
425 // default to match the behaviour of lld and gold plugin.
427 Config.Options.DataSections = true;
428
429 TargetMach = createTargetMachine();
430 assert(TargetMach && "Unable to create target machine");
431
432 return true;
433}
434
435std::unique_ptr<TargetMachine> LTOCodeGenerator::createTargetMachine() {
436 assert(MArch && "MArch is not set!");
437 return std::unique_ptr<TargetMachine>(MArch->createTargetMachine(
438 TripleStr, Config.CPU, FeatureStr, Config.Options, Config.RelocModel,
439 std::nullopt, Config.CGOptLevel));
440}
441
442// If a linkonce global is present in the MustPreserveSymbols, we need to make
443// sure we honor this. To force the compiler to not drop it, we add it to the
444// "llvm.compiler.used" global.
445void LTOCodeGenerator::preserveDiscardableGVs(
446 Module &TheModule,
448 std::vector<GlobalValue *> Used;
449 auto mayPreserveGlobal = [&](GlobalValue &GV) {
450 if (!GV.isDiscardableIfUnused() || GV.isDeclaration() ||
451 !mustPreserveGV(GV))
452 return;
453 if (GV.hasAvailableExternallyLinkage())
454 return emitWarning(
455 (Twine("Linker asked to preserve available_externally global: '") +
456 GV.getName() + "'").str());
457 if (GV.hasInternalLinkage())
458 return emitWarning((Twine("Linker asked to preserve internal global: '") +
459 GV.getName() + "'").str());
460 Used.push_back(&GV);
461 };
462 for (auto &GV : TheModule)
463 mayPreserveGlobal(GV);
464 for (auto &GV : TheModule.globals())
465 mayPreserveGlobal(GV);
466 for (auto &GV : TheModule.aliases())
467 mayPreserveGlobal(GV);
468
469 if (Used.empty())
470 return;
471
472 appendToCompilerUsed(TheModule, Used);
473}
474
475void LTOCodeGenerator::applyScopeRestrictions() {
476 if (ScopeRestrictionsDone)
477 return;
478
479 // Declare a callback for the internalize pass that will ask for every
480 // candidate GlobalValue if it can be internalized or not.
481 Mangler Mang;
482 SmallString<64> MangledName;
483 auto mustPreserveGV = [&](const GlobalValue &GV) -> bool {
484 // Unnamed globals can't be mangled, but they can't be preserved either.
485 if (!GV.hasName())
486 return false;
487
488 // Need to mangle the GV as the "MustPreserveSymbols" StringSet is filled
489 // with the linker supplied name, which on Darwin includes a leading
490 // underscore.
491 MangledName.clear();
492 MangledName.reserve(GV.getName().size() + 1);
493 Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
494 return MustPreserveSymbols.count(MangledName);
495 };
496
497 // Preserve linkonce value on linker request
498 preserveDiscardableGVs(*MergedModule, mustPreserveGV);
499
500 if (!ShouldInternalize)
501 return;
502
503 if (ShouldRestoreGlobalsLinkage) {
504 // Record the linkage type of non-local symbols so they can be restored
505 // prior
506 // to module splitting.
507 auto RecordLinkage = [&](const GlobalValue &GV) {
508 if (!GV.hasAvailableExternallyLinkage() && !GV.hasLocalLinkage() &&
509 GV.hasName())
510 ExternalSymbols.insert(std::make_pair(GV.getName(), GV.getLinkage()));
511 };
512 for (auto &GV : *MergedModule)
513 RecordLinkage(GV);
514 for (auto &GV : MergedModule->globals())
515 RecordLinkage(GV);
516 for (auto &GV : MergedModule->aliases())
517 RecordLinkage(GV);
518 }
519
520 // Update the llvm.compiler_used globals to force preserving libcalls and
521 // symbols referenced from asm
522 updateCompilerUsed(*MergedModule, *TargetMach, AsmUndefinedRefs);
523
524 internalizeModule(*MergedModule, mustPreserveGV);
525
526 ScopeRestrictionsDone = true;
527}
528
529/// Restore original linkage for symbols that may have been internalized
530void LTOCodeGenerator::restoreLinkageForExternals() {
531 if (!ShouldInternalize || !ShouldRestoreGlobalsLinkage)
532 return;
533
534 assert(ScopeRestrictionsDone &&
535 "Cannot externalize without internalization!");
536
537 if (ExternalSymbols.empty())
538 return;
539
540 auto externalize = [this](GlobalValue &GV) {
541 if (!GV.hasLocalLinkage() || !GV.hasName())
542 return;
543
544 auto I = ExternalSymbols.find(GV.getName());
545 if (I == ExternalSymbols.end())
546 return;
547
548 GV.setLinkage(I->second);
549 };
550
551 llvm::for_each(MergedModule->functions(), externalize);
552 llvm::for_each(MergedModule->globals(), externalize);
553 llvm::for_each(MergedModule->aliases(), externalize);
554}
555
556void LTOCodeGenerator::verifyMergedModuleOnce() {
557 // Only run on the first call.
558 if (HasVerifiedInput)
559 return;
560 HasVerifiedInput = true;
561
562 bool BrokenDebugInfo = false;
563 if (verifyModule(*MergedModule, &dbgs(), &BrokenDebugInfo))
564 report_fatal_error("Broken module found, compilation aborted!");
565 if (BrokenDebugInfo) {
566 emitWarning("Invalid debug info found, debug info will be stripped");
567 StripDebugInfo(*MergedModule);
568 }
569}
570
571void LTOCodeGenerator::finishOptimizationRemarks() {
572 if (DiagnosticOutputFile) {
573 DiagnosticOutputFile->keep();
574 // FIXME: LTOCodeGenerator dtor is not invoked on Darwin
575 DiagnosticOutputFile->os().flush();
576 }
577}
578
579/// Optimize merged modules using various IPO passes
581 if (!this->determineTarget())
582 return false;
583
584 auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
587 if (!DiagFileOrErr) {
588 errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
589 report_fatal_error("Can't get an output file for the remarks");
590 }
591 DiagnosticOutputFile = std::move(*DiagFileOrErr);
592
593 // Setup output file to emit statistics.
594 auto StatsFileOrErr = lto::setupStatsFile(LTOStatsFile);
595 if (!StatsFileOrErr) {
596 errs() << "Error: " << toString(StatsFileOrErr.takeError()) << "\n";
597 report_fatal_error("Can't get an output file for the statistics");
598 }
599 StatsFile = std::move(StatsFileOrErr.get());
600
601 // Currently there is no support for enabling whole program visibility via a
602 // linker option in the old LTO API, but this call allows it to be specified
603 // via the internal option. Must be done before WPD invoked via the optimizer
604 // pipeline run below.
605 updatePublicTypeTestCalls(*MergedModule,
606 /* WholeProgramVisibilityEnabledInLTO */ false);
607 updateVCallVisibilityInModule(*MergedModule,
608 /* WholeProgramVisibilityEnabledInLTO */ false,
609 // FIXME: This needs linker information via a
610 // TBD new interface.
611 /* DynamicExportSymbols */ {});
612
613 // We always run the verifier once on the merged module, the `DisableVerify`
614 // parameter only applies to subsequent verify.
615 verifyMergedModuleOnce();
616
617 // Mark which symbols can not be internalized
618 this->applyScopeRestrictions();
619
620 // Write LTOPostLink flag for passes that require all the modules.
621 MergedModule->addModuleFlag(Module::Error, "LTOPostLink", 1);
622
623 // Add an appropriate DataLayout instance for this module...
624 MergedModule->setDataLayout(TargetMach->createDataLayout());
625
626 if (!SaveIRBeforeOptPath.empty()) {
627 std::error_code EC;
628 raw_fd_ostream OS(SaveIRBeforeOptPath, EC, sys::fs::OF_None);
629 if (EC)
630 report_fatal_error(Twine("Failed to open ") + SaveIRBeforeOptPath +
631 " to save optimized bitcode\n");
632 WriteBitcodeToFile(*MergedModule, OS,
633 /* ShouldPreserveUseListOrder */ true);
634 }
635
636 ModuleSummaryIndex CombinedIndex(false);
637 TargetMach = createTargetMachine();
638 if (!opt(Config, TargetMach.get(), 0, *MergedModule, /*IsThinLTO=*/false,
639 /*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr,
640 /*CmdArgs*/ std::vector<uint8_t>())) {
641 emitError("LTO middle-end optimizations failed");
642 return false;
643 }
644
645 return true;
646}
647
649 unsigned ParallelismLevel) {
650 if (!this->determineTarget())
651 return false;
652
653 // We always run the verifier once on the merged module. If it has already
654 // been called in optimize(), this call will return early.
655 verifyMergedModuleOnce();
656
657 // Re-externalize globals that may have been internalized to increase scope
658 // for splitting
659 restoreLinkageForExternals();
660
661 ModuleSummaryIndex CombinedIndex(false);
662
663 Config.CodeGenOnly = true;
664 Error Err = backend(Config, AddStream, ParallelismLevel, *MergedModule,
665 CombinedIndex);
666 assert(!Err && "unexpected code-generation failure");
667 (void)Err;
668
669 // If statistics were requested, save them to the specified file or
670 // print them out after codegen.
671 if (StatsFile)
672 PrintStatisticsJSON(StatsFile->os());
673 else if (AreStatisticsEnabled())
675
677
678 finishOptimizationRemarks();
679
680 return true;
681}
682
684 for (StringRef Option : Options)
685 CodegenOptions.push_back(Option.str());
686}
687
689 if (!CodegenOptions.empty())
690 llvm::parseCommandLineOptions(CodegenOptions);
691}
692
693void llvm::parseCommandLineOptions(std::vector<std::string> &Options) {
694 if (!Options.empty()) {
695 // ParseCommandLineOptions() expects argv[0] to be program name.
696 std::vector<const char *> CodegenArgv(1, "libLLVMLTO");
697 for (std::string &Arg : Options)
698 CodegenArgv.push_back(Arg.c_str());
699 cl::ParseCommandLineOptions(CodegenArgv.size(), CodegenArgv.data());
700 }
701}
702
704 // Map the LLVM internal diagnostic severity to the LTO diagnostic severity.
706 switch (DI.getSeverity()) {
707 case DS_Error:
708 Severity = LTO_DS_ERROR;
709 break;
710 case DS_Warning:
711 Severity = LTO_DS_WARNING;
712 break;
713 case DS_Remark:
714 Severity = LTO_DS_REMARK;
715 break;
716 case DS_Note:
717 Severity = LTO_DS_NOTE;
718 break;
719 }
720 // Create the string that will be reported to the external diagnostic handler.
721 std::string MsgStorage;
722 raw_string_ostream Stream(MsgStorage);
724 DI.print(DP);
725 Stream.flush();
726
727 // If this method has been called it means someone has set up an external
728 // diagnostic handler. Assert on that.
729 assert(DiagHandler && "Invalid diagnostic handler");
730 (*DiagHandler)(Severity, MsgStorage.c_str(), DiagContext);
731}
732
733namespace {
734struct LTODiagnosticHandler : public DiagnosticHandler {
735 LTOCodeGenerator *CodeGenerator;
736 LTODiagnosticHandler(LTOCodeGenerator *CodeGenPtr)
737 : CodeGenerator(CodeGenPtr) {}
738 bool handleDiagnostics(const DiagnosticInfo &DI) override {
739 CodeGenerator->DiagnosticHandler(DI);
740 return true;
741 }
742};
743}
744
745void
747 void *Ctxt) {
748 this->DiagHandler = DiagHandler;
749 this->DiagContext = Ctxt;
750 if (!DiagHandler)
751 return Context.setDiagnosticHandler(nullptr);
752 // Register the LTOCodeGenerator stub in the LLVMContext to forward the
753 // diagnostic to the external DiagHandler.
754 Context.setDiagnosticHandler(std::make_unique<LTODiagnosticHandler>(this),
755 true);
756}
757
758namespace {
759class LTODiagnosticInfo : public DiagnosticInfo {
760 const Twine &Msg;
761public:
762 LTODiagnosticInfo(const Twine &DiagMsg, DiagnosticSeverity Severity=DS_Error)
763 : DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {}
764 void print(DiagnosticPrinter &DP) const override { DP << Msg; }
765};
766}
767
768void LTOCodeGenerator::emitError(const std::string &ErrMsg) {
769 if (DiagHandler)
770 (*DiagHandler)(LTO_DS_ERROR, ErrMsg.c_str(), DiagContext);
771 else
772 Context.diagnose(LTODiagnosticInfo(ErrMsg));
773}
774
775void LTOCodeGenerator::emitWarning(const std::string &ErrMsg) {
776 if (DiagHandler)
777 (*DiagHandler)(LTO_DS_WARNING, ErrMsg.c_str(), DiagContext);
778 else
779 Context.diagnose(LTODiagnosticInfo(ErrMsg, DS_Warning));
780}
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
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.
LLVMContext & Context
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:1080
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:156
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:119
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
@ Error
Emits an error if two values disagree, otherwise the resulting value is that of the operands.
Definition: Module.h:118
bool SLPVectorization
Tuning option to enable/disable slp loop vectorization, set based on opt level.
Definition: PassBuilder.h:56
bool LoopVectorization
Tuning option to enable/disable loop vectorization, set based on opt level.
Definition: PassBuilder.h:52
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
const char * c_str()
Definition: SmallString.h:264
void reserve(size_type N)
Definition: SmallVector.h:667
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
bool empty() const
Definition: StringMap.h:94
iterator end()
Definition: StringMap.h:204
iterator find(StringRef Key)
Definition: StringMap.h:217
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
Definition: StringMap.h:256
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Definition: StringMap.h:286
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:34
Manages the enabling and disabling of subtarget specific features.
unsigned DataSections
Emit data into separate sections.
TargetMachine * createTargetMachine(StringRef TT, StringRef CPU, StringRef Features, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM=std::nullopt, CodeGenOpt::Level OL=CodeGenOpt::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 isArm64e() const
Tests whether the target is the Apple "arm64e" AArch64 subarch.
Definition: Triple.h:959
@ aarch64_32
Definition: Triple.h:53
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition: Triple.h:356
bool isOSAIX() const
Tests whether the OS is AIX.
Definition: Triple.h:670
bool isArch64Bit() const
Test whether the architecture is 64-bit.
Definition: Triple.cpp:1464
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, or DriverKit).
Definition: Triple.h:519
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:454
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:545
std::error_code error() const
Definition: raw_ostream.h:539
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:556
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:642
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< Level > getLevel(IDType ID)
Get the Level identified by the integer ID.
Definition: CodeGen.h:66
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:445
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.
Expected< std::unique_ptr< ToolOutputFile > > setupStatsFile(StringRef StatsFilename)
Setups the output file for saving statistics.
Definition: LTO.cpp:1805
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:1780
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:1812
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:76
cl::opt< std::string > LTOCSIRProfile("cs-profile-path", cl::desc("Context sensitive profile file path"))
void updateVCallVisibilityInModule(Module &M, bool WholeProgramVisibilityEnabledInLTO, const DenseSet< GlobalValue::GUID > &DynamicExportSymbols)
If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...
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)
@ CGFT_AssemblyFile
Definition: CodeGen.h:85
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:145
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:533
@ 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"))
bool verifyModule(const Module &M, raw_ostream *OS=nullptr, bool *BrokenDebugInfo=nullptr)
Check a module for errors.
Definition: Verifier.cpp:6522
#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:165
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:70
std::vector< std::string > MAttrs
Definition: Config.h:50
PipelineTuningOptions PTO
Tunable parameters for passes in the default pipelines.
Definition: Config.h:189
std::string CPU
Definition: Config.h:48
TargetOptions Options
Definition: Config.h:49
CodeGenOpt::Level CGOptLevel
Definition: Config.h:57
bool RunCSIRInstr
Run PGO context sensitive IR instrumentation.
Definition: Config.h:73
unsigned OptLevel
Definition: Config.h:59
std::string CSIRProfile
Context Sensitive PGO profile path.
Definition: Config.h:112
std::optional< Reloc::Model > RelocModel
Definition: Config.h:55
CodeGenFileType CGFileType
Definition: Config.h:58