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