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