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