clang 20.0.0git
BackendUtil.cpp
Go to the documentation of this file.
1//===--- BackendUtil.cpp - LLVM Backend Utilities -------------------------===//
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
10#include "BackendConsumer.h"
11#include "LinkInModulesPass.h"
19#include "llvm/ADT/StringExtras.h"
20#include "llvm/ADT/StringSwitch.h"
21#include "llvm/Analysis/GlobalsModRef.h"
22#include "llvm/Analysis/TargetLibraryInfo.h"
23#include "llvm/Analysis/TargetTransformInfo.h"
24#include "llvm/Bitcode/BitcodeReader.h"
25#include "llvm/Bitcode/BitcodeWriter.h"
26#include "llvm/Bitcode/BitcodeWriterPass.h"
27#include "llvm/CodeGen/TargetSubtargetInfo.h"
28#include "llvm/Frontend/Driver/CodeGenOptions.h"
29#include "llvm/IR/DataLayout.h"
30#include "llvm/IR/DebugInfo.h"
31#include "llvm/IR/LegacyPassManager.h"
32#include "llvm/IR/Module.h"
33#include "llvm/IR/ModuleSummaryIndex.h"
34#include "llvm/IR/PassManager.h"
35#include "llvm/IR/Verifier.h"
36#include "llvm/IRPrinter/IRPrintingPasses.h"
37#include "llvm/LTO/LTOBackend.h"
38#include "llvm/MC/TargetRegistry.h"
39#include "llvm/Object/OffloadBinary.h"
40#include "llvm/Passes/PassBuilder.h"
41#include "llvm/Passes/PassPlugin.h"
42#include "llvm/Passes/StandardInstrumentations.h"
43#include "llvm/ProfileData/InstrProfCorrelator.h"
44#include "llvm/Support/BuryPointer.h"
45#include "llvm/Support/CommandLine.h"
46#include "llvm/Support/MemoryBuffer.h"
47#include "llvm/Support/PrettyStackTrace.h"
48#include "llvm/Support/Program.h"
49#include "llvm/Support/TimeProfiler.h"
50#include "llvm/Support/Timer.h"
51#include "llvm/Support/ToolOutputFile.h"
52#include "llvm/Support/VirtualFileSystem.h"
53#include "llvm/Support/raw_ostream.h"
54#include "llvm/Target/TargetMachine.h"
55#include "llvm/Target/TargetOptions.h"
56#include "llvm/TargetParser/SubtargetFeature.h"
57#include "llvm/TargetParser/Triple.h"
58#include "llvm/Transforms/HipStdPar/HipStdPar.h"
59#include "llvm/Transforms/IPO/EmbedBitcodePass.h"
60#include "llvm/Transforms/IPO/LowerTypeTests.h"
61#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
62#include "llvm/Transforms/InstCombine/InstCombine.h"
63#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
64#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
65#include "llvm/Transforms/Instrumentation/BoundsChecking.h"
66#include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h"
67#include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
68#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
69#include "llvm/Transforms/Instrumentation/InstrProfiling.h"
70#include "llvm/Transforms/Instrumentation/KCFI.h"
71#include "llvm/Transforms/Instrumentation/LowerAllowCheckPass.h"
72#include "llvm/Transforms/Instrumentation/MemProfiler.h"
73#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
74#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
75#include "llvm/Transforms/Instrumentation/PGOInstrumentation.h"
76#include "llvm/Transforms/Instrumentation/RealtimeSanitizer.h"
77#include "llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h"
78#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
79#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
80#include "llvm/Transforms/Instrumentation/TypeSanitizer.h"
81#include "llvm/Transforms/ObjCARC.h"
82#include "llvm/Transforms/Scalar/EarlyCSE.h"
83#include "llvm/Transforms/Scalar/GVN.h"
84#include "llvm/Transforms/Scalar/JumpThreading.h"
85#include "llvm/Transforms/Utils/Debugify.h"
86#include "llvm/Transforms/Utils/ModuleUtils.h"
87#include <memory>
88#include <optional>
89using namespace clang;
90using namespace llvm;
91
92#define HANDLE_EXTENSION(Ext) \
93 llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
94#include "llvm/Support/Extension.def"
95
96namespace llvm {
97extern cl::opt<bool> PrintPipelinePasses;
98
99// Experiment to move sanitizers earlier.
100static cl::opt<bool> ClSanitizeOnOptimizerEarlyEP(
101 "sanitizer-early-opt-ep", cl::Optional,
102 cl::desc("Insert sanitizers on OptimizerEarlyEP."));
103
104// Experiment to mark cold functions as optsize/minsize/optnone.
105// TODO: remove once this is exposed as a proper driver flag.
106static cl::opt<PGOOptions::ColdFuncOpt> ClPGOColdFuncAttr(
107 "pgo-cold-func-opt", cl::init(PGOOptions::ColdFuncOpt::Default), cl::Hidden,
108 cl::desc(
109 "Function attribute to apply to cold functions as determined by PGO"),
110 cl::values(clEnumValN(PGOOptions::ColdFuncOpt::Default, "default",
111 "Default (no attribute)"),
112 clEnumValN(PGOOptions::ColdFuncOpt::OptSize, "optsize",
113 "Mark cold functions with optsize."),
114 clEnumValN(PGOOptions::ColdFuncOpt::MinSize, "minsize",
115 "Mark cold functions with minsize."),
116 clEnumValN(PGOOptions::ColdFuncOpt::OptNone, "optnone",
117 "Mark cold functions with optnone.")));
118
119extern cl::opt<InstrProfCorrelator::ProfCorrelatorKind> ProfileCorrelate;
120} // namespace llvm
121
122namespace {
123
124// Default filename used for profile generation.
125std::string getDefaultProfileGenName() {
126 return DebugInfoCorrelate || ProfileCorrelate != InstrProfCorrelator::NONE
127 ? "default_%m.proflite"
128 : "default_%m.profraw";
129}
130
131class EmitAssemblyHelper {
132 DiagnosticsEngine &Diags;
133 const HeaderSearchOptions &HSOpts;
134 const CodeGenOptions &CodeGenOpts;
135 const clang::TargetOptions &TargetOpts;
136 const LangOptions &LangOpts;
137 llvm::Module *TheModule;
139
140 Timer CodeGenerationTime;
141
142 std::unique_ptr<raw_pwrite_stream> OS;
143
144 Triple TargetTriple;
145
146 TargetIRAnalysis getTargetIRAnalysis() const {
147 if (TM)
148 return TM->getTargetIRAnalysis();
149
150 return TargetIRAnalysis();
151 }
152
153 /// Generates the TargetMachine.
154 /// Leaves TM unchanged if it is unable to create the target machine.
155 /// Some of our clang tests specify triples which are not built
156 /// into clang. This is okay because these tests check the generated
157 /// IR, and they require DataLayout which depends on the triple.
158 /// In this case, we allow this method to fail and not report an error.
159 /// When MustCreateTM is used, we print an error if we are unable to load
160 /// the requested target.
161 void CreateTargetMachine(bool MustCreateTM);
162
163 /// Add passes necessary to emit assembly or LLVM IR.
164 ///
165 /// \return True on success.
166 bool AddEmitPasses(legacy::PassManager &CodeGenPasses, BackendAction Action,
167 raw_pwrite_stream &OS, raw_pwrite_stream *DwoOS);
168
169 std::unique_ptr<llvm::ToolOutputFile> openOutputFile(StringRef Path) {
170 std::error_code EC;
171 auto F = std::make_unique<llvm::ToolOutputFile>(Path, EC,
172 llvm::sys::fs::OF_None);
173 if (EC) {
174 Diags.Report(diag::err_fe_unable_to_open_output) << Path << EC.message();
175 F.reset();
176 }
177 return F;
178 }
179
180 void RunOptimizationPipeline(
181 BackendAction Action, std::unique_ptr<raw_pwrite_stream> &OS,
182 std::unique_ptr<llvm::ToolOutputFile> &ThinLinkOS, BackendConsumer *BC);
183 void RunCodegenPipeline(BackendAction Action,
184 std::unique_ptr<raw_pwrite_stream> &OS,
185 std::unique_ptr<llvm::ToolOutputFile> &DwoOS);
186
187 /// Check whether we should emit a module summary for regular LTO.
188 /// The module summary should be emitted by default for regular LTO
189 /// except for ld64 targets.
190 ///
191 /// \return True if the module summary should be emitted.
192 bool shouldEmitRegularLTOSummary() const {
193 return CodeGenOpts.PrepareForLTO && !CodeGenOpts.DisableLLVMPasses &&
194 TargetTriple.getVendor() != llvm::Triple::Apple;
195 }
196
197 /// Check whether we should emit a flag for UnifiedLTO.
198 /// The UnifiedLTO module flag should be set when UnifiedLTO is enabled for
199 /// ThinLTO or Full LTO with module summaries.
200 bool shouldEmitUnifiedLTOModueFlag() const {
201 return CodeGenOpts.UnifiedLTO &&
202 (CodeGenOpts.PrepareForThinLTO || shouldEmitRegularLTOSummary());
203 }
204
205public:
206 EmitAssemblyHelper(DiagnosticsEngine &_Diags,
207 const HeaderSearchOptions &HeaderSearchOpts,
208 const CodeGenOptions &CGOpts,
209 const clang::TargetOptions &TOpts,
210 const LangOptions &LOpts, llvm::Module *M,
212 : Diags(_Diags), HSOpts(HeaderSearchOpts), CodeGenOpts(CGOpts),
213 TargetOpts(TOpts), LangOpts(LOpts), TheModule(M), VFS(std::move(VFS)),
214 CodeGenerationTime("codegen", "Code Generation Time"),
215 TargetTriple(TheModule->getTargetTriple()) {}
216
217 ~EmitAssemblyHelper() {
218 if (CodeGenOpts.DisableFree)
219 BuryPointer(std::move(TM));
220 }
221
222 std::unique_ptr<TargetMachine> TM;
223
224 // Emit output using the new pass manager for the optimization pipeline.
225 void EmitAssembly(BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS,
226 BackendConsumer *BC);
227};
228} // namespace
229
230static SanitizerCoverageOptions
232 SanitizerCoverageOptions Opts;
233 Opts.CoverageType =
234 static_cast<SanitizerCoverageOptions::Type>(CGOpts.SanitizeCoverageType);
235 Opts.IndirectCalls = CGOpts.SanitizeCoverageIndirectCalls;
236 Opts.TraceBB = CGOpts.SanitizeCoverageTraceBB;
237 Opts.TraceCmp = CGOpts.SanitizeCoverageTraceCmp;
238 Opts.TraceDiv = CGOpts.SanitizeCoverageTraceDiv;
239 Opts.TraceGep = CGOpts.SanitizeCoverageTraceGep;
240 Opts.Use8bitCounters = CGOpts.SanitizeCoverage8bitCounters;
241 Opts.TracePC = CGOpts.SanitizeCoverageTracePC;
242 Opts.TracePCGuard = CGOpts.SanitizeCoverageTracePCGuard;
243 Opts.NoPrune = CGOpts.SanitizeCoverageNoPrune;
244 Opts.Inline8bitCounters = CGOpts.SanitizeCoverageInline8bitCounters;
245 Opts.InlineBoolFlag = CGOpts.SanitizeCoverageInlineBoolFlag;
246 Opts.PCTable = CGOpts.SanitizeCoveragePCTable;
247 Opts.StackDepth = CGOpts.SanitizeCoverageStackDepth;
248 Opts.TraceLoads = CGOpts.SanitizeCoverageTraceLoads;
249 Opts.TraceStores = CGOpts.SanitizeCoverageTraceStores;
250 Opts.CollectControlFlow = CGOpts.SanitizeCoverageControlFlow;
251 return Opts;
252}
253
254static SanitizerBinaryMetadataOptions
256 SanitizerBinaryMetadataOptions Opts;
257 Opts.Covered = CGOpts.SanitizeBinaryMetadataCovered;
258 Opts.Atomics = CGOpts.SanitizeBinaryMetadataAtomics;
259 Opts.UAR = CGOpts.SanitizeBinaryMetadataUAR;
260 return Opts;
261}
262
263// Check if ASan should use GC-friendly instrumentation for globals.
264// First of all, there is no point if -fdata-sections is off (expect for MachO,
265// where this is not a factor). Also, on ELF this feature requires an assembler
266// extension that only works with -integrated-as at the moment.
267static bool asanUseGlobalsGC(const Triple &T, const CodeGenOptions &CGOpts) {
268 if (!CGOpts.SanitizeAddressGlobalsDeadStripping)
269 return false;
270 switch (T.getObjectFormat()) {
271 case Triple::MachO:
272 case Triple::COFF:
273 return true;
274 case Triple::ELF:
275 return !CGOpts.DisableIntegratedAS;
276 case Triple::GOFF:
277 llvm::report_fatal_error("ASan not implemented for GOFF");
278 case Triple::XCOFF:
279 llvm::report_fatal_error("ASan not implemented for XCOFF.");
280 case Triple::Wasm:
281 case Triple::DXContainer:
282 case Triple::SPIRV:
283 case Triple::UnknownObjectFormat:
284 break;
285 }
286 return false;
287}
288
289static std::optional<llvm::CodeModel::Model>
290getCodeModel(const CodeGenOptions &CodeGenOpts) {
291 unsigned CodeModel = llvm::StringSwitch<unsigned>(CodeGenOpts.CodeModel)
292 .Case("tiny", llvm::CodeModel::Tiny)
293 .Case("small", llvm::CodeModel::Small)
294 .Case("kernel", llvm::CodeModel::Kernel)
295 .Case("medium", llvm::CodeModel::Medium)
296 .Case("large", llvm::CodeModel::Large)
297 .Case("default", ~1u)
298 .Default(~0u);
299 assert(CodeModel != ~0u && "invalid code model!");
300 if (CodeModel == ~1u)
301 return std::nullopt;
302 return static_cast<llvm::CodeModel::Model>(CodeModel);
303}
304
305static CodeGenFileType getCodeGenFileType(BackendAction Action) {
306 if (Action == Backend_EmitObj)
307 return CodeGenFileType::ObjectFile;
308 else if (Action == Backend_EmitMCNull)
309 return CodeGenFileType::Null;
310 else {
311 assert(Action == Backend_EmitAssembly && "Invalid action!");
312 return CodeGenFileType::AssemblyFile;
313 }
314}
315
317 return Action != Backend_EmitNothing && Action != Backend_EmitBC &&
318 Action != Backend_EmitLL;
319}
320
322 StringRef MainFilename) {
323 if (Args.empty())
324 return std::string{};
325
326 std::string FlatCmdLine;
327 raw_string_ostream OS(FlatCmdLine);
328 bool PrintedOneArg = false;
329 if (!StringRef(Args[0]).contains("-cc1")) {
330 llvm::sys::printArg(OS, "-cc1", /*Quote=*/true);
331 PrintedOneArg = true;
332 }
333 for (unsigned i = 0; i < Args.size(); i++) {
334 StringRef Arg = Args[i];
335 if (Arg.empty())
336 continue;
337 if (Arg == "-main-file-name" || Arg == "-o") {
338 i++; // Skip this argument and next one.
339 continue;
340 }
341 if (Arg.starts_with("-object-file-name") || Arg == MainFilename)
342 continue;
343 // Skip fmessage-length for reproducibility.
344 if (Arg.starts_with("-fmessage-length"))
345 continue;
346 if (PrintedOneArg)
347 OS << " ";
348 llvm::sys::printArg(OS, Arg, /*Quote=*/true);
349 PrintedOneArg = true;
350 }
351 return FlatCmdLine;
352}
353
355 llvm::TargetOptions &Options,
356 const CodeGenOptions &CodeGenOpts,
357 const clang::TargetOptions &TargetOpts,
358 const LangOptions &LangOpts,
359 const HeaderSearchOptions &HSOpts) {
360 switch (LangOpts.getThreadModel()) {
361 case LangOptions::ThreadModelKind::POSIX:
362 Options.ThreadModel = llvm::ThreadModel::POSIX;
363 break;
364 case LangOptions::ThreadModelKind::Single:
365 Options.ThreadModel = llvm::ThreadModel::Single;
366 break;
367 }
368
369 // Set float ABI type.
370 assert((CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp" ||
371 CodeGenOpts.FloatABI == "hard" || CodeGenOpts.FloatABI.empty()) &&
372 "Invalid Floating Point ABI!");
373 Options.FloatABIType =
374 llvm::StringSwitch<llvm::FloatABI::ABIType>(CodeGenOpts.FloatABI)
375 .Case("soft", llvm::FloatABI::Soft)
376 .Case("softfp", llvm::FloatABI::Soft)
377 .Case("hard", llvm::FloatABI::Hard)
378 .Default(llvm::FloatABI::Default);
379
380 // Set FP fusion mode.
381 switch (LangOpts.getDefaultFPContractMode()) {
382 case LangOptions::FPM_Off:
383 // Preserve any contraction performed by the front-end. (Strict performs
384 // splitting of the muladd intrinsic in the backend.)
385 Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
386 break;
387 case LangOptions::FPM_On:
388 case LangOptions::FPM_FastHonorPragmas:
389 Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
390 break;
391 case LangOptions::FPM_Fast:
392 Options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
393 break;
394 }
395
396 Options.BinutilsVersion =
397 llvm::TargetMachine::parseBinutilsVersion(CodeGenOpts.BinutilsVersion);
398 Options.UseInitArray = CodeGenOpts.UseInitArray;
399 Options.DisableIntegratedAS = CodeGenOpts.DisableIntegratedAS;
400
401 // Set EABI version.
402 Options.EABIVersion = TargetOpts.EABIVersion;
403
404 if (LangOpts.hasSjLjExceptions())
405 Options.ExceptionModel = llvm::ExceptionHandling::SjLj;
406 if (LangOpts.hasSEHExceptions())
407 Options.ExceptionModel = llvm::ExceptionHandling::WinEH;
408 if (LangOpts.hasDWARFExceptions())
409 Options.ExceptionModel = llvm::ExceptionHandling::DwarfCFI;
410 if (LangOpts.hasWasmExceptions())
411 Options.ExceptionModel = llvm::ExceptionHandling::Wasm;
412
413 Options.NoInfsFPMath = LangOpts.NoHonorInfs;
414 Options.NoNaNsFPMath = LangOpts.NoHonorNaNs;
415 Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
416 Options.UnsafeFPMath = LangOpts.AllowFPReassoc && LangOpts.AllowRecip &&
417 LangOpts.NoSignedZero && LangOpts.ApproxFunc &&
418 (LangOpts.getDefaultFPContractMode() ==
419 LangOptions::FPModeKind::FPM_Fast ||
420 LangOpts.getDefaultFPContractMode() ==
421 LangOptions::FPModeKind::FPM_FastHonorPragmas);
422 Options.ApproxFuncFPMath = LangOpts.ApproxFunc;
423
424 Options.BBAddrMap = CodeGenOpts.BBAddrMap;
425 Options.BBSections =
426 llvm::StringSwitch<llvm::BasicBlockSection>(CodeGenOpts.BBSections)
427 .Case("all", llvm::BasicBlockSection::All)
428 .StartsWith("list=", llvm::BasicBlockSection::List)
429 .Case("none", llvm::BasicBlockSection::None)
430 .Default(llvm::BasicBlockSection::None);
431
432 if (Options.BBSections == llvm::BasicBlockSection::List) {
433 ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
434 MemoryBuffer::getFile(CodeGenOpts.BBSections.substr(5));
435 if (!MBOrErr) {
436 Diags.Report(diag::err_fe_unable_to_load_basic_block_sections_file)
437 << MBOrErr.getError().message();
438 return false;
439 }
440 Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
441 }
442
443 Options.EnableMachineFunctionSplitter = CodeGenOpts.SplitMachineFunctions;
444 Options.FunctionSections = CodeGenOpts.FunctionSections;
445 Options.DataSections = CodeGenOpts.DataSections;
446 Options.IgnoreXCOFFVisibility = LangOpts.IgnoreXCOFFVisibility;
447 Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames;
448 Options.UniqueBasicBlockSectionNames =
449 CodeGenOpts.UniqueBasicBlockSectionNames;
450 Options.SeparateNamedSections = CodeGenOpts.SeparateNamedSections;
451 Options.TLSSize = CodeGenOpts.TLSSize;
452 Options.EnableTLSDESC = CodeGenOpts.EnableTLSDESC;
453 Options.EmulatedTLS = CodeGenOpts.EmulatedTLS;
454 Options.DebuggerTuning = CodeGenOpts.getDebuggerTuning();
455 Options.EmitStackSizeSection = CodeGenOpts.StackSizeSection;
456 Options.StackUsageOutput = CodeGenOpts.StackUsageOutput;
457 Options.EmitAddrsig = CodeGenOpts.Addrsig;
458 Options.ForceDwarfFrameSection = CodeGenOpts.ForceDwarfFrameSection;
459 Options.EmitCallSiteInfo = CodeGenOpts.EmitCallSiteInfo;
460 Options.EnableAIXExtendedAltivecABI = LangOpts.EnableAIXExtendedAltivecABI;
461 Options.XRayFunctionIndex = CodeGenOpts.XRayFunctionIndex;
462 Options.LoopAlignment = CodeGenOpts.LoopAlignment;
463 Options.DebugStrictDwarf = CodeGenOpts.DebugStrictDwarf;
464 Options.ObjectFilenameForDebug = CodeGenOpts.ObjectFilenameForDebug;
465 Options.Hotpatch = CodeGenOpts.HotPatch;
466 Options.JMCInstrument = CodeGenOpts.JMCInstrument;
467 Options.XCOFFReadOnlyPointers = CodeGenOpts.XCOFFReadOnlyPointers;
468
469 switch (CodeGenOpts.getSwiftAsyncFramePointer()) {
470 case CodeGenOptions::SwiftAsyncFramePointerKind::Auto:
471 Options.SwiftAsyncFramePointer =
472 SwiftAsyncFramePointerMode::DeploymentBased;
473 break;
474
475 case CodeGenOptions::SwiftAsyncFramePointerKind::Always:
476 Options.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Always;
477 break;
478
479 case CodeGenOptions::SwiftAsyncFramePointerKind::Never:
480 Options.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Never;
481 break;
482 }
483
484 Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile;
485 Options.MCOptions.EmitDwarfUnwind = CodeGenOpts.getEmitDwarfUnwind();
486 Options.MCOptions.EmitCompactUnwindNonCanonical =
487 CodeGenOpts.EmitCompactUnwindNonCanonical;
488 Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
489 Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
490 Options.MCOptions.MCUseDwarfDirectory =
491 CodeGenOpts.NoDwarfDirectoryAsm
492 ? llvm::MCTargetOptions::DisableDwarfDirectory
493 : llvm::MCTargetOptions::EnableDwarfDirectory;
494 Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack;
495 Options.MCOptions.MCIncrementalLinkerCompatible =
496 CodeGenOpts.IncrementalLinkerCompatible;
497 Options.MCOptions.MCFatalWarnings = CodeGenOpts.FatalWarnings;
498 Options.MCOptions.MCNoWarn = CodeGenOpts.NoWarn;
499 Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose;
500 Options.MCOptions.Dwarf64 = CodeGenOpts.Dwarf64;
501 Options.MCOptions.PreserveAsmComments = CodeGenOpts.PreserveAsmComments;
502 Options.MCOptions.Crel = CodeGenOpts.Crel;
503 Options.MCOptions.ImplicitMapSyms = CodeGenOpts.ImplicitMapSyms;
504 Options.MCOptions.X86RelaxRelocations = CodeGenOpts.X86RelaxRelocations;
505 Options.MCOptions.CompressDebugSections =
506 CodeGenOpts.getCompressDebugSections();
507 if (CodeGenOpts.OutputAsmVariant != 3) // 3 (default): not specified
508 Options.MCOptions.OutputAsmVariant = CodeGenOpts.OutputAsmVariant;
509 Options.MCOptions.ABIName = TargetOpts.ABI;
510 for (const auto &Entry : HSOpts.UserEntries)
511 if (!Entry.IsFramework &&
512 (Entry.Group == frontend::IncludeDirGroup::Quoted ||
513 Entry.Group == frontend::IncludeDirGroup::Angled ||
514 Entry.Group == frontend::IncludeDirGroup::System))
515 Options.MCOptions.IASSearchPaths.push_back(
516 Entry.IgnoreSysRoot ? Entry.Path : HSOpts.Sysroot + Entry.Path);
517 Options.MCOptions.Argv0 = CodeGenOpts.Argv0 ? CodeGenOpts.Argv0 : "";
518 Options.MCOptions.CommandlineArgs = flattenClangCommandLine(
519 CodeGenOpts.CommandLineArgs, CodeGenOpts.MainFileName);
520 Options.MCOptions.AsSecureLogFile = CodeGenOpts.AsSecureLogFile;
521 Options.MCOptions.PPCUseFullRegisterNames =
522 CodeGenOpts.PPCUseFullRegisterNames;
523 Options.MisExpect = CodeGenOpts.MisExpect;
524
525 return true;
526}
527
528static std::optional<GCOVOptions>
529getGCOVOptions(const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts) {
530 if (CodeGenOpts.CoverageNotesFile.empty() &&
531 CodeGenOpts.CoverageDataFile.empty())
532 return std::nullopt;
533 // Not using 'GCOVOptions::getDefault' allows us to avoid exiting if
534 // LLVM's -default-gcov-version flag is set to something invalid.
535 GCOVOptions Options;
536 Options.EmitNotes = !CodeGenOpts.CoverageNotesFile.empty();
537 Options.EmitData = !CodeGenOpts.CoverageDataFile.empty();
538 llvm::copy(CodeGenOpts.CoverageVersion, std::begin(Options.Version));
539 Options.NoRedZone = CodeGenOpts.DisableRedZone;
540 Options.Filter = CodeGenOpts.ProfileFilterFiles;
541 Options.Exclude = CodeGenOpts.ProfileExcludeFiles;
542 Options.Atomic = CodeGenOpts.AtomicProfileUpdate;
543 return Options;
544}
545
546static std::optional<InstrProfOptions>
548 const LangOptions &LangOpts) {
549 if (!CodeGenOpts.hasProfileClangInstr())
550 return std::nullopt;
551 InstrProfOptions Options;
552 Options.NoRedZone = CodeGenOpts.DisableRedZone;
553 Options.InstrProfileOutput = CodeGenOpts.InstrProfileOutput;
554 Options.Atomic = CodeGenOpts.AtomicProfileUpdate;
555 return Options;
556}
557
558static void setCommandLineOpts(const CodeGenOptions &CodeGenOpts) {
560 BackendArgs.push_back("clang"); // Fake program name.
561 if (!CodeGenOpts.DebugPass.empty()) {
562 BackendArgs.push_back("-debug-pass");
563 BackendArgs.push_back(CodeGenOpts.DebugPass.c_str());
564 }
565 if (!CodeGenOpts.LimitFloatPrecision.empty()) {
566 BackendArgs.push_back("-limit-float-precision");
567 BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str());
568 }
569 // Check for the default "clang" invocation that won't set any cl::opt values.
570 // Skip trying to parse the command line invocation to avoid the issues
571 // described below.
572 if (BackendArgs.size() == 1)
573 return;
574 BackendArgs.push_back(nullptr);
575 // FIXME: The command line parser below is not thread-safe and shares a global
576 // state, so this call might crash or overwrite the options of another Clang
577 // instance in the same process.
578 llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
579 BackendArgs.data());
580}
581
582void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
583 // Create the TargetMachine for generating code.
584 std::string Error;
585 std::string Triple = TheModule->getTargetTriple();
586 const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
587 if (!TheTarget) {
588 if (MustCreateTM)
589 Diags.Report(diag::err_fe_unable_to_create_target) << Error;
590 return;
591 }
592
593 std::optional<llvm::CodeModel::Model> CM = getCodeModel(CodeGenOpts);
594 std::string FeaturesStr =
595 llvm::join(TargetOpts.Features.begin(), TargetOpts.Features.end(), ",");
596 llvm::Reloc::Model RM = CodeGenOpts.RelocationModel;
597 std::optional<CodeGenOptLevel> OptLevelOrNone =
598 CodeGenOpt::getLevel(CodeGenOpts.OptimizationLevel);
599 assert(OptLevelOrNone && "Invalid optimization level!");
600 CodeGenOptLevel OptLevel = *OptLevelOrNone;
601
602 llvm::TargetOptions Options;
603 if (!initTargetOptions(Diags, Options, CodeGenOpts, TargetOpts, LangOpts,
604 HSOpts))
605 return;
606 TM.reset(TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr,
607 Options, RM, CM, OptLevel));
608 TM->setLargeDataThreshold(CodeGenOpts.LargeDataThreshold);
609}
610
611bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses,
612 BackendAction Action,
613 raw_pwrite_stream &OS,
614 raw_pwrite_stream *DwoOS) {
615 // Add LibraryInfo.
616 std::unique_ptr<TargetLibraryInfoImpl> TLII(
617 llvm::driver::createTLII(TargetTriple, CodeGenOpts.getVecLib()));
618 CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII));
619
620 // Normal mode, emit a .s or .o file by running the code generator. Note,
621 // this also adds codegenerator level optimization passes.
622 CodeGenFileType CGFT = getCodeGenFileType(Action);
623
624 if (TM->addPassesToEmitFile(CodeGenPasses, OS, DwoOS, CGFT,
625 /*DisableVerify=*/!CodeGenOpts.VerifyModule)) {
626 Diags.Report(diag::err_fe_unable_to_interface_with_target);
627 return false;
628 }
629
630 return true;
631}
632
633static OptimizationLevel mapToLevel(const CodeGenOptions &Opts) {
634 switch (Opts.OptimizationLevel) {
635 default:
636 llvm_unreachable("Invalid optimization level!");
637
638 case 0:
639 return OptimizationLevel::O0;
640
641 case 1:
642 return OptimizationLevel::O1;
643
644 case 2:
645 switch (Opts.OptimizeSize) {
646 default:
647 llvm_unreachable("Invalid optimization level for size!");
648
649 case 0:
650 return OptimizationLevel::O2;
651
652 case 1:
653 return OptimizationLevel::Os;
654
655 case 2:
656 return OptimizationLevel::Oz;
657 }
658
659 case 3:
660 return OptimizationLevel::O3;
661 }
662}
663
664static void addKCFIPass(const Triple &TargetTriple, const LangOptions &LangOpts,
665 PassBuilder &PB) {
666 // If the back-end supports KCFI operand bundle lowering, skip KCFIPass.
667 if (TargetTriple.getArch() == llvm::Triple::x86_64 ||
668 TargetTriple.isAArch64(64) || TargetTriple.isRISCV())
669 return;
670
671 // Ensure we lower KCFI operand bundles with -O0.
672 PB.registerOptimizerLastEPCallback(
673 [&](ModulePassManager &MPM, OptimizationLevel Level, ThinOrFullLTOPhase) {
674 if (Level == OptimizationLevel::O0 &&
675 LangOpts.Sanitize.has(SanitizerKind::KCFI))
676 MPM.addPass(createModuleToFunctionPassAdaptor(KCFIPass()));
677 });
678
679 // When optimizations are requested, run KCIFPass after InstCombine to
680 // avoid unnecessary checks.
681 PB.registerPeepholeEPCallback(
682 [&](FunctionPassManager &FPM, OptimizationLevel Level) {
683 if (Level != OptimizationLevel::O0 &&
684 LangOpts.Sanitize.has(SanitizerKind::KCFI))
685 FPM.addPass(KCFIPass());
686 });
687}
688
689static void addSanitizers(const Triple &TargetTriple,
690 const CodeGenOptions &CodeGenOpts,
691 const LangOptions &LangOpts, PassBuilder &PB) {
692 auto SanitizersCallback = [&](ModulePassManager &MPM, OptimizationLevel Level,
693 ThinOrFullLTOPhase) {
694 if (CodeGenOpts.hasSanitizeCoverage()) {
695 auto SancovOpts = getSancovOptsFromCGOpts(CodeGenOpts);
696 MPM.addPass(SanitizerCoveragePass(
697 SancovOpts, CodeGenOpts.SanitizeCoverageAllowlistFiles,
699 }
700
701 if (CodeGenOpts.hasSanitizeBinaryMetadata()) {
702 MPM.addPass(SanitizerBinaryMetadataPass(
705 }
706
707 auto MSanPass = [&](SanitizerMask Mask, bool CompileKernel) {
708 if (LangOpts.Sanitize.has(Mask)) {
709 int TrackOrigins = CodeGenOpts.SanitizeMemoryTrackOrigins;
710 bool Recover = CodeGenOpts.SanitizeRecover.has(Mask);
711
712 MemorySanitizerOptions options(TrackOrigins, Recover, CompileKernel,
713 CodeGenOpts.SanitizeMemoryParamRetval);
714 MPM.addPass(MemorySanitizerPass(options));
715 if (Level != OptimizationLevel::O0) {
716 // MemorySanitizer inserts complex instrumentation that mostly follows
717 // the logic of the original code, but operates on "shadow" values. It
718 // can benefit from re-running some general purpose optimization
719 // passes.
720 MPM.addPass(RequireAnalysisPass<GlobalsAA, llvm::Module>());
721 FunctionPassManager FPM;
722 FPM.addPass(EarlyCSEPass(true /* Enable mem-ssa. */));
723 FPM.addPass(InstCombinePass());
724 FPM.addPass(JumpThreadingPass());
725 FPM.addPass(GVNPass());
726 FPM.addPass(InstCombinePass());
727 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
728 }
729 }
730 };
731 MSanPass(SanitizerKind::Memory, false);
732 MSanPass(SanitizerKind::KernelMemory, true);
733
734 if (LangOpts.Sanitize.has(SanitizerKind::Thread)) {
735 MPM.addPass(ModuleThreadSanitizerPass());
736 MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
737 }
738
739 if (LangOpts.Sanitize.has(SanitizerKind::Type)) {
740 MPM.addPass(ModuleTypeSanitizerPass());
741 MPM.addPass(createModuleToFunctionPassAdaptor(TypeSanitizerPass()));
742 }
743
744 if (LangOpts.Sanitize.has(SanitizerKind::NumericalStability))
745 MPM.addPass(NumericalStabilitySanitizerPass());
746
747 if (LangOpts.Sanitize.has(SanitizerKind::Realtime))
748 MPM.addPass(RealtimeSanitizerPass());
749
750 auto ASanPass = [&](SanitizerMask Mask, bool CompileKernel) {
751 if (LangOpts.Sanitize.has(Mask)) {
752 bool UseGlobalGC = asanUseGlobalsGC(TargetTriple, CodeGenOpts);
753 bool UseOdrIndicator = CodeGenOpts.SanitizeAddressUseOdrIndicator;
754 llvm::AsanDtorKind DestructorKind =
755 CodeGenOpts.getSanitizeAddressDtor();
756 AddressSanitizerOptions Opts;
757 Opts.CompileKernel = CompileKernel;
758 Opts.Recover = CodeGenOpts.SanitizeRecover.has(Mask);
759 Opts.UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope;
760 Opts.UseAfterReturn = CodeGenOpts.getSanitizeAddressUseAfterReturn();
761 MPM.addPass(AddressSanitizerPass(Opts, UseGlobalGC, UseOdrIndicator,
762 DestructorKind));
763 }
764 };
765 ASanPass(SanitizerKind::Address, false);
766 ASanPass(SanitizerKind::KernelAddress, true);
767
768 auto HWASanPass = [&](SanitizerMask Mask, bool CompileKernel) {
769 if (LangOpts.Sanitize.has(Mask)) {
770 bool Recover = CodeGenOpts.SanitizeRecover.has(Mask);
771 MPM.addPass(HWAddressSanitizerPass(
772 {CompileKernel, Recover,
773 /*DisableOptimization=*/CodeGenOpts.OptimizationLevel == 0}));
774 }
775 };
776 HWASanPass(SanitizerKind::HWAddress, false);
777 HWASanPass(SanitizerKind::KernelHWAddress, true);
778
779 if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) {
780 MPM.addPass(DataFlowSanitizerPass(LangOpts.NoSanitizeFiles));
781 }
782 };
784 PB.registerOptimizerEarlyEPCallback(
785 [SanitizersCallback](ModulePassManager &MPM, OptimizationLevel Level,
786 ThinOrFullLTOPhase Phase) {
787 ModulePassManager NewMPM;
788 SanitizersCallback(NewMPM, Level, Phase);
789 if (!NewMPM.isEmpty()) {
790 // Sanitizers can abandon<GlobalsAA>.
791 NewMPM.addPass(RequireAnalysisPass<GlobalsAA, llvm::Module>());
792 MPM.addPass(std::move(NewMPM));
793 }
794 });
795 } else {
796 // LastEP does not need GlobalsAA.
797 PB.registerOptimizerLastEPCallback(SanitizersCallback);
798 }
799
800 if (LowerAllowCheckPass::IsRequested()) {
801 // We want to call it after inline, which is about OptimizerEarlyEPCallback.
802 PB.registerOptimizerEarlyEPCallback([](ModulePassManager &MPM,
803 OptimizationLevel Level,
804 ThinOrFullLTOPhase Phase) {
805 MPM.addPass(createModuleToFunctionPassAdaptor(LowerAllowCheckPass()));
806 });
807 }
808}
809
810void EmitAssemblyHelper::RunOptimizationPipeline(
811 BackendAction Action, std::unique_ptr<raw_pwrite_stream> &OS,
812 std::unique_ptr<llvm::ToolOutputFile> &ThinLinkOS, BackendConsumer *BC) {
813 std::optional<PGOOptions> PGOOpt;
814
815 if (CodeGenOpts.hasProfileIRInstr())
816 // -fprofile-generate.
817 PGOOpt = PGOOptions(
818 CodeGenOpts.InstrProfileOutput.empty() ? getDefaultProfileGenName()
819 : CodeGenOpts.InstrProfileOutput,
820 "", "", CodeGenOpts.MemoryProfileUsePath, nullptr, PGOOptions::IRInstr,
821 PGOOptions::NoCSAction, ClPGOColdFuncAttr,
822 CodeGenOpts.DebugInfoForProfiling,
823 /*PseudoProbeForProfiling=*/false, CodeGenOpts.AtomicProfileUpdate);
824 else if (CodeGenOpts.hasProfileIRUse()) {
825 // -fprofile-use.
826 auto CSAction = CodeGenOpts.hasProfileCSIRUse() ? PGOOptions::CSIRUse
827 : PGOOptions::NoCSAction;
828 PGOOpt = PGOOptions(CodeGenOpts.ProfileInstrumentUsePath, "",
829 CodeGenOpts.ProfileRemappingFile,
830 CodeGenOpts.MemoryProfileUsePath, VFS,
831 PGOOptions::IRUse, CSAction, ClPGOColdFuncAttr,
832 CodeGenOpts.DebugInfoForProfiling);
833 } else if (!CodeGenOpts.SampleProfileFile.empty())
834 // -fprofile-sample-use
835 PGOOpt = PGOOptions(
836 CodeGenOpts.SampleProfileFile, "", CodeGenOpts.ProfileRemappingFile,
837 CodeGenOpts.MemoryProfileUsePath, VFS, PGOOptions::SampleUse,
838 PGOOptions::NoCSAction, ClPGOColdFuncAttr,
839 CodeGenOpts.DebugInfoForProfiling, CodeGenOpts.PseudoProbeForProfiling);
840 else if (!CodeGenOpts.MemoryProfileUsePath.empty())
841 // -fmemory-profile-use (without any of the above options)
842 PGOOpt = PGOOptions("", "", "", CodeGenOpts.MemoryProfileUsePath, VFS,
843 PGOOptions::NoAction, PGOOptions::NoCSAction,
844 ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling);
845 else if (CodeGenOpts.PseudoProbeForProfiling)
846 // -fpseudo-probe-for-profiling
847 PGOOpt =
848 PGOOptions("", "", "", /*MemoryProfile=*/"", nullptr,
849 PGOOptions::NoAction, PGOOptions::NoCSAction,
850 ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling, true);
851 else if (CodeGenOpts.DebugInfoForProfiling)
852 // -fdebug-info-for-profiling
853 PGOOpt = PGOOptions("", "", "", /*MemoryProfile=*/"", nullptr,
854 PGOOptions::NoAction, PGOOptions::NoCSAction,
855 ClPGOColdFuncAttr, true);
856
857 // Check to see if we want to generate a CS profile.
858 if (CodeGenOpts.hasProfileCSIRInstr()) {
859 assert(!CodeGenOpts.hasProfileCSIRUse() &&
860 "Cannot have both CSProfileUse pass and CSProfileGen pass at "
861 "the same time");
862 if (PGOOpt) {
863 assert(PGOOpt->Action != PGOOptions::IRInstr &&
864 PGOOpt->Action != PGOOptions::SampleUse &&
865 "Cannot run CSProfileGen pass with ProfileGen or SampleUse "
866 " pass");
867 PGOOpt->CSProfileGenFile = CodeGenOpts.InstrProfileOutput.empty()
868 ? getDefaultProfileGenName()
869 : CodeGenOpts.InstrProfileOutput;
870 PGOOpt->CSAction = PGOOptions::CSIRInstr;
871 } else
872 PGOOpt = PGOOptions("",
873 CodeGenOpts.InstrProfileOutput.empty()
874 ? getDefaultProfileGenName()
875 : CodeGenOpts.InstrProfileOutput,
876 "", /*MemoryProfile=*/"", nullptr,
877 PGOOptions::NoAction, PGOOptions::CSIRInstr,
878 ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling);
879 }
880 if (TM)
881 TM->setPGOOption(PGOOpt);
882
883 PipelineTuningOptions PTO;
884 PTO.LoopUnrolling = CodeGenOpts.UnrollLoops;
885 // For historical reasons, loop interleaving is set to mirror setting for loop
886 // unrolling.
887 PTO.LoopInterleaving = CodeGenOpts.UnrollLoops;
888 PTO.LoopVectorization = CodeGenOpts.VectorizeLoop;
889 PTO.SLPVectorization = CodeGenOpts.VectorizeSLP;
890 PTO.MergeFunctions = CodeGenOpts.MergeFunctions;
891 // Only enable CGProfilePass when using integrated assembler, since
892 // non-integrated assemblers don't recognize .cgprofile section.
893 PTO.CallGraphProfile = !CodeGenOpts.DisableIntegratedAS;
894 PTO.UnifiedLTO = CodeGenOpts.UnifiedLTO;
895
896 LoopAnalysisManager LAM;
897 FunctionAnalysisManager FAM;
898 CGSCCAnalysisManager CGAM;
899 ModuleAnalysisManager MAM;
900
901 bool DebugPassStructure = CodeGenOpts.DebugPass == "Structure";
902 PassInstrumentationCallbacks PIC;
903 PrintPassOptions PrintPassOpts;
904 PrintPassOpts.Indent = DebugPassStructure;
905 PrintPassOpts.SkipAnalyses = DebugPassStructure;
906 StandardInstrumentations SI(
907 TheModule->getContext(),
908 (CodeGenOpts.DebugPassManager || DebugPassStructure),
909 CodeGenOpts.VerifyEach, PrintPassOpts);
910 SI.registerCallbacks(PIC, &MAM);
911 PassBuilder PB(TM.get(), PTO, PGOOpt, &PIC);
912
913 // Handle the assignment tracking feature options.
914 switch (CodeGenOpts.getAssignmentTrackingMode()) {
915 case CodeGenOptions::AssignmentTrackingOpts::Forced:
916 PB.registerPipelineStartEPCallback(
917 [&](ModulePassManager &MPM, OptimizationLevel Level) {
918 MPM.addPass(AssignmentTrackingPass());
919 });
920 break;
921 case CodeGenOptions::AssignmentTrackingOpts::Enabled:
922 // Disable assignment tracking in LTO builds for now as the performance
923 // cost is too high. Disable for LLDB tuning due to llvm.org/PR43126.
924 if (!CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.PrepareForLTO &&
925 CodeGenOpts.getDebuggerTuning() != llvm::DebuggerKind::LLDB) {
926 PB.registerPipelineStartEPCallback(
927 [&](ModulePassManager &MPM, OptimizationLevel Level) {
928 // Only use assignment tracking if optimisations are enabled.
929 if (Level != OptimizationLevel::O0)
930 MPM.addPass(AssignmentTrackingPass());
931 });
932 }
933 break;
934 case CodeGenOptions::AssignmentTrackingOpts::Disabled:
935 break;
936 }
937
938 // Enable verify-debuginfo-preserve-each for new PM.
939 DebugifyEachInstrumentation Debugify;
940 DebugInfoPerPass DebugInfoBeforePass;
941 if (CodeGenOpts.EnableDIPreservationVerify) {
942 Debugify.setDebugifyMode(DebugifyMode::OriginalDebugInfo);
943 Debugify.setDebugInfoBeforePass(DebugInfoBeforePass);
944
945 if (!CodeGenOpts.DIBugsReportFilePath.empty())
946 Debugify.setOrigDIVerifyBugsReportFilePath(
947 CodeGenOpts.DIBugsReportFilePath);
948 Debugify.registerCallbacks(PIC, MAM);
949 }
950 // Attempt to load pass plugins and register their callbacks with PB.
951 for (auto &PluginFN : CodeGenOpts.PassPlugins) {
952 auto PassPlugin = PassPlugin::Load(PluginFN);
953 if (PassPlugin) {
954 PassPlugin->registerPassBuilderCallbacks(PB);
955 } else {
956 Diags.Report(diag::err_fe_unable_to_load_plugin)
957 << PluginFN << toString(PassPlugin.takeError());
958 }
959 }
960 for (const auto &PassCallback : CodeGenOpts.PassBuilderCallbacks)
961 PassCallback(PB);
962#define HANDLE_EXTENSION(Ext) \
963 get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
964#include "llvm/Support/Extension.def"
965
966 // Register the target library analysis directly and give it a customized
967 // preset TLI.
968 std::unique_ptr<TargetLibraryInfoImpl> TLII(
969 llvm::driver::createTLII(TargetTriple, CodeGenOpts.getVecLib()));
970 FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
971
972 // Register all the basic analyses with the managers.
973 PB.registerModuleAnalyses(MAM);
974 PB.registerCGSCCAnalyses(CGAM);
975 PB.registerFunctionAnalyses(FAM);
976 PB.registerLoopAnalyses(LAM);
977 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
978
979 ModulePassManager MPM;
980 // Add a verifier pass, before any other passes, to catch CodeGen issues.
981 if (CodeGenOpts.VerifyModule)
982 MPM.addPass(VerifierPass());
983
984 if (!CodeGenOpts.DisableLLVMPasses) {
985 // Map our optimization levels into one of the distinct levels used to
986 // configure the pipeline.
987 OptimizationLevel Level = mapToLevel(CodeGenOpts);
988
989 const bool PrepareForThinLTO = CodeGenOpts.PrepareForThinLTO;
990 const bool PrepareForLTO = CodeGenOpts.PrepareForLTO;
991
992 if (LangOpts.ObjCAutoRefCount) {
993 PB.registerPipelineStartEPCallback(
994 [](ModulePassManager &MPM, OptimizationLevel Level) {
995 if (Level != OptimizationLevel::O0)
996 MPM.addPass(
997 createModuleToFunctionPassAdaptor(ObjCARCExpandPass()));
998 });
999 PB.registerPipelineEarlySimplificationEPCallback(
1000 [](ModulePassManager &MPM, OptimizationLevel Level,
1001 ThinOrFullLTOPhase) {
1002 if (Level != OptimizationLevel::O0)
1003 MPM.addPass(ObjCARCAPElimPass());
1004 });
1005 PB.registerScalarOptimizerLateEPCallback(
1006 [](FunctionPassManager &FPM, OptimizationLevel Level) {
1007 if (Level != OptimizationLevel::O0)
1008 FPM.addPass(ObjCARCOptPass());
1009 });
1010 }
1011
1012 // If we reached here with a non-empty index file name, then the index
1013 // file was empty and we are not performing ThinLTO backend compilation
1014 // (used in testing in a distributed build environment).
1015 bool IsThinLTOPostLink = !CodeGenOpts.ThinLTOIndexFile.empty();
1016 // If so drop any the type test assume sequences inserted for whole program
1017 // vtables so that codegen doesn't complain.
1018 if (IsThinLTOPostLink)
1019 PB.registerPipelineStartEPCallback(
1020 [](ModulePassManager &MPM, OptimizationLevel Level) {
1021 MPM.addPass(LowerTypeTestsPass(
1022 /*ExportSummary=*/nullptr,
1023 /*ImportSummary=*/nullptr,
1024 /*DropTypeTests=*/lowertypetests::DropTestKind::Assume));
1025 });
1026
1027 // Register callbacks to schedule sanitizer passes at the appropriate part
1028 // of the pipeline.
1029 if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds))
1030 PB.registerScalarOptimizerLateEPCallback(
1031 [this](FunctionPassManager &FPM, OptimizationLevel Level) {
1032 BoundsCheckingPass::ReportingMode Mode;
1033 bool Merge = CodeGenOpts.SanitizeMergeHandlers.has(
1034 SanitizerKind::LocalBounds);
1035
1036 if (CodeGenOpts.SanitizeTrap.has(SanitizerKind::LocalBounds)) {
1037 Mode = BoundsCheckingPass::ReportingMode::Trap;
1038 } else if (CodeGenOpts.SanitizeMinimalRuntime) {
1039 Mode = CodeGenOpts.SanitizeRecover.has(SanitizerKind::LocalBounds)
1040 ? BoundsCheckingPass::ReportingMode::MinRuntime
1041 : BoundsCheckingPass::ReportingMode::MinRuntimeAbort;
1042 } else {
1043 Mode = CodeGenOpts.SanitizeRecover.has(SanitizerKind::LocalBounds)
1044 ? BoundsCheckingPass::ReportingMode::FullRuntime
1045 : BoundsCheckingPass::ReportingMode::FullRuntimeAbort;
1046 }
1047 BoundsCheckingPass::BoundsCheckingOptions Options(Mode, Merge);
1048 FPM.addPass(BoundsCheckingPass(Options));
1049 });
1050
1051 // Don't add sanitizers if we are here from ThinLTO PostLink. That already
1052 // done on PreLink stage.
1053 if (!IsThinLTOPostLink) {
1054 addSanitizers(TargetTriple, CodeGenOpts, LangOpts, PB);
1055 addKCFIPass(TargetTriple, LangOpts, PB);
1056 }
1057
1058 if (std::optional<GCOVOptions> Options =
1059 getGCOVOptions(CodeGenOpts, LangOpts))
1060 PB.registerPipelineStartEPCallback(
1061 [Options](ModulePassManager &MPM, OptimizationLevel Level) {
1062 MPM.addPass(GCOVProfilerPass(*Options));
1063 });
1064 if (std::optional<InstrProfOptions> Options =
1065 getInstrProfOptions(CodeGenOpts, LangOpts))
1066 PB.registerPipelineStartEPCallback(
1067 [Options](ModulePassManager &MPM, OptimizationLevel Level) {
1068 MPM.addPass(InstrProfilingLoweringPass(*Options, false));
1069 });
1070
1071 // TODO: Consider passing the MemoryProfileOutput to the pass builder via
1072 // the PGOOptions, and set this up there.
1073 if (!CodeGenOpts.MemoryProfileOutput.empty()) {
1074 PB.registerOptimizerLastEPCallback([](ModulePassManager &MPM,
1075 OptimizationLevel Level,
1076 ThinOrFullLTOPhase) {
1077 MPM.addPass(createModuleToFunctionPassAdaptor(MemProfilerPass()));
1078 MPM.addPass(ModuleMemProfilerPass());
1079 });
1080 }
1081
1082 if (CodeGenOpts.FatLTO) {
1083 MPM.addPass(PB.buildFatLTODefaultPipeline(
1084 Level, PrepareForThinLTO,
1085 PrepareForThinLTO || shouldEmitRegularLTOSummary()));
1086 } else if (PrepareForThinLTO) {
1087 MPM.addPass(PB.buildThinLTOPreLinkDefaultPipeline(Level));
1088 } else if (PrepareForLTO) {
1089 MPM.addPass(PB.buildLTOPreLinkDefaultPipeline(Level));
1090 } else {
1091 MPM.addPass(PB.buildPerModuleDefaultPipeline(Level));
1092 }
1093 }
1094
1095 // Link against bitcodes supplied via the -mlink-builtin-bitcode option
1096 if (CodeGenOpts.LinkBitcodePostopt)
1097 MPM.addPass(LinkInModulesPass(BC));
1098
1099 // Add a verifier pass if requested. We don't have to do this if the action
1100 // requires code generation because there will already be a verifier pass in
1101 // the code-generation pipeline.
1102 // Since we already added a verifier pass above, this
1103 // might even not run the analysis, if previous passes caused no changes.
1104 if (!actionRequiresCodeGen(Action) && CodeGenOpts.VerifyModule)
1105 MPM.addPass(VerifierPass());
1106
1107 if (Action == Backend_EmitBC || Action == Backend_EmitLL ||
1108 CodeGenOpts.FatLTO) {
1109 if (CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.DisableLLVMPasses) {
1110 if (!TheModule->getModuleFlag("EnableSplitLTOUnit"))
1111 TheModule->addModuleFlag(llvm::Module::Error, "EnableSplitLTOUnit",
1112 CodeGenOpts.EnableSplitLTOUnit);
1113 if (Action == Backend_EmitBC) {
1114 if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) {
1115 ThinLinkOS = openOutputFile(CodeGenOpts.ThinLinkBitcodeFile);
1116 if (!ThinLinkOS)
1117 return;
1118 }
1119 MPM.addPass(ThinLTOBitcodeWriterPass(
1120 *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr));
1121 } else if (Action == Backend_EmitLL) {
1122 MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,
1123 /*EmitLTOSummary=*/true));
1124 }
1125 } else {
1126 // Emit a module summary by default for Regular LTO except for ld64
1127 // targets
1128 bool EmitLTOSummary = shouldEmitRegularLTOSummary();
1129 if (EmitLTOSummary) {
1130 if (!TheModule->getModuleFlag("ThinLTO") && !CodeGenOpts.UnifiedLTO)
1131 TheModule->addModuleFlag(llvm::Module::Error, "ThinLTO", uint32_t(0));
1132 if (!TheModule->getModuleFlag("EnableSplitLTOUnit"))
1133 TheModule->addModuleFlag(llvm::Module::Error, "EnableSplitLTOUnit",
1134 uint32_t(1));
1135 }
1136 if (Action == Backend_EmitBC) {
1137 MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
1138 EmitLTOSummary));
1139 } else if (Action == Backend_EmitLL) {
1140 MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,
1141 EmitLTOSummary));
1142 }
1143 }
1144
1145 if (shouldEmitUnifiedLTOModueFlag())
1146 TheModule->addModuleFlag(llvm::Module::Error, "UnifiedLTO", uint32_t(1));
1147 }
1148
1149 // FIXME: This should eventually be replaced by a first-class driver option.
1150 // This should be done for both clang and flang simultaneously.
1151 // Print a textual, '-passes=' compatible, representation of pipeline if
1152 // requested.
1153 if (PrintPipelinePasses) {
1154 MPM.printPipeline(outs(), [&PIC](StringRef ClassName) {
1155 auto PassName = PIC.getPassNameForClassName(ClassName);
1156 return PassName.empty() ? ClassName : PassName;
1157 });
1158 outs() << "\n";
1159 return;
1160 }
1161
1162 if (LangOpts.HIPStdPar && !LangOpts.CUDAIsDevice &&
1163 LangOpts.HIPStdParInterposeAlloc)
1164 MPM.addPass(HipStdParAllocationInterpositionPass());
1165
1166 // Now that we have all of the passes ready, run them.
1167 {
1168 PrettyStackTraceString CrashInfo("Optimizer");
1169 llvm::TimeTraceScope TimeScope("Optimizer");
1170 MPM.run(*TheModule, MAM);
1171 }
1172}
1173
1174void EmitAssemblyHelper::RunCodegenPipeline(
1175 BackendAction Action, std::unique_ptr<raw_pwrite_stream> &OS,
1176 std::unique_ptr<llvm::ToolOutputFile> &DwoOS) {
1177 // We still use the legacy PM to run the codegen pipeline since the new PM
1178 // does not work with the codegen pipeline.
1179 // FIXME: make the new PM work with the codegen pipeline.
1180 legacy::PassManager CodeGenPasses;
1181
1182 // Append any output we need to the pass manager.
1183 switch (Action) {
1185 case Backend_EmitMCNull:
1186 case Backend_EmitObj:
1187 CodeGenPasses.add(
1188 createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
1189 if (!CodeGenOpts.SplitDwarfOutput.empty()) {
1190 DwoOS = openOutputFile(CodeGenOpts.SplitDwarfOutput);
1191 if (!DwoOS)
1192 return;
1193 }
1194 if (!AddEmitPasses(CodeGenPasses, Action, *OS,
1195 DwoOS ? &DwoOS->os() : nullptr))
1196 // FIXME: Should we handle this error differently?
1197 return;
1198 break;
1199 default:
1200 return;
1201 }
1202
1203 // If -print-pipeline-passes is requested, don't run the legacy pass manager.
1204 // FIXME: when codegen is switched to use the new pass manager, it should also
1205 // emit pass names here.
1206 if (PrintPipelinePasses) {
1207 return;
1208 }
1209
1210 {
1211 PrettyStackTraceString CrashInfo("Code generation");
1212 llvm::TimeTraceScope TimeScope("CodeGenPasses");
1213 CodeGenPasses.run(*TheModule);
1214 }
1215}
1216
1217void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
1218 std::unique_ptr<raw_pwrite_stream> OS,
1219 BackendConsumer *BC) {
1220 TimeRegion Region(CodeGenOpts.TimePasses ? &CodeGenerationTime : nullptr);
1221 setCommandLineOpts(CodeGenOpts);
1222
1223 bool RequiresCodeGen = actionRequiresCodeGen(Action);
1224 CreateTargetMachine(RequiresCodeGen);
1225
1226 if (RequiresCodeGen && !TM)
1227 return;
1228 if (TM)
1229 TheModule->setDataLayout(TM->createDataLayout());
1230
1231 // Before executing passes, print the final values of the LLVM options.
1232 cl::PrintOptionValues();
1233
1234 std::unique_ptr<llvm::ToolOutputFile> ThinLinkOS, DwoOS;
1235 RunOptimizationPipeline(Action, OS, ThinLinkOS, BC);
1236 RunCodegenPipeline(Action, OS, DwoOS);
1237
1238 if (ThinLinkOS)
1239 ThinLinkOS->keep();
1240 if (DwoOS)
1241 DwoOS->keep();
1242}
1243
1245 DiagnosticsEngine &Diags, ModuleSummaryIndex *CombinedIndex,
1246 llvm::Module *M, const HeaderSearchOptions &HeaderOpts,
1247 const CodeGenOptions &CGOpts, const clang::TargetOptions &TOpts,
1248 const LangOptions &LOpts, std::unique_ptr<raw_pwrite_stream> OS,
1249 std::string SampleProfile, std::string ProfileRemapping,
1250 BackendAction Action) {
1251 DenseMap<StringRef, DenseMap<GlobalValue::GUID, GlobalValueSummary *>>
1252 ModuleToDefinedGVSummaries;
1253 CombinedIndex->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
1254
1255 setCommandLineOpts(CGOpts);
1256
1257 // We can simply import the values mentioned in the combined index, since
1258 // we should only invoke this using the individual indexes written out
1259 // via a WriteIndexesThinBackend.
1260 FunctionImporter::ImportIDTable ImportIDs;
1261 FunctionImporter::ImportMapTy ImportList(ImportIDs);
1262 if (!lto::initImportList(*M, *CombinedIndex, ImportList))
1263 return;
1264
1265 auto AddStream = [&](size_t Task, const Twine &ModuleName) {
1266 return std::make_unique<CachedFileStream>(std::move(OS),
1267 CGOpts.ObjectFilenameForDebug);
1268 };
1269 lto::Config Conf;
1270 if (CGOpts.SaveTempsFilePrefix != "") {
1271 if (Error E = Conf.addSaveTemps(CGOpts.SaveTempsFilePrefix + ".",
1272 /* UseInputModulePath */ false)) {
1273 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
1274 errs() << "Error setting up ThinLTO save-temps: " << EIB.message()
1275 << '\n';
1276 });
1277 }
1278 }
1279 Conf.CPU = TOpts.CPU;
1280 Conf.CodeModel = getCodeModel(CGOpts);
1281 Conf.MAttrs = TOpts.Features;
1282 Conf.RelocModel = CGOpts.RelocationModel;
1283 std::optional<CodeGenOptLevel> OptLevelOrNone =
1284 CodeGenOpt::getLevel(CGOpts.OptimizationLevel);
1285 assert(OptLevelOrNone && "Invalid optimization level!");
1286 Conf.CGOptLevel = *OptLevelOrNone;
1287 Conf.OptLevel = CGOpts.OptimizationLevel;
1288 initTargetOptions(Diags, Conf.Options, CGOpts, TOpts, LOpts, HeaderOpts);
1289 Conf.SampleProfile = std::move(SampleProfile);
1290 Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops;
1291 // For historical reasons, loop interleaving is set to mirror setting for loop
1292 // unrolling.
1293 Conf.PTO.LoopInterleaving = CGOpts.UnrollLoops;
1294 Conf.PTO.LoopVectorization = CGOpts.VectorizeLoop;
1295 Conf.PTO.SLPVectorization = CGOpts.VectorizeSLP;
1296 // Only enable CGProfilePass when using integrated assembler, since
1297 // non-integrated assemblers don't recognize .cgprofile section.
1298 Conf.PTO.CallGraphProfile = !CGOpts.DisableIntegratedAS;
1299
1300 // Context sensitive profile.
1301 if (CGOpts.hasProfileCSIRInstr()) {
1302 Conf.RunCSIRInstr = true;
1303 Conf.CSIRProfile = std::move(CGOpts.InstrProfileOutput);
1304 } else if (CGOpts.hasProfileCSIRUse()) {
1305 Conf.RunCSIRInstr = false;
1306 Conf.CSIRProfile = std::move(CGOpts.ProfileInstrumentUsePath);
1307 }
1308
1309 Conf.ProfileRemapping = std::move(ProfileRemapping);
1310 Conf.DebugPassManager = CGOpts.DebugPassManager;
1311 Conf.VerifyEach = CGOpts.VerifyEach;
1312 Conf.RemarksWithHotness = CGOpts.DiagnosticsWithHotness;
1313 Conf.RemarksFilename = CGOpts.OptRecordFile;
1314 Conf.RemarksPasses = CGOpts.OptRecordPasses;
1315 Conf.RemarksFormat = CGOpts.OptRecordFormat;
1316 Conf.SplitDwarfFile = CGOpts.SplitDwarfFile;
1317 Conf.SplitDwarfOutput = CGOpts.SplitDwarfOutput;
1318 switch (Action) {
1320 Conf.PreCodeGenModuleHook = [](size_t Task, const llvm::Module &Mod) {
1321 return false;
1322 };
1323 break;
1324 case Backend_EmitLL:
1325 Conf.PreCodeGenModuleHook = [&](size_t Task, const llvm::Module &Mod) {
1326 M->print(*OS, nullptr, CGOpts.EmitLLVMUseLists);
1327 return false;
1328 };
1329 break;
1330 case Backend_EmitBC:
1331 Conf.PreCodeGenModuleHook = [&](size_t Task, const llvm::Module &Mod) {
1332 WriteBitcodeToFile(*M, *OS, CGOpts.EmitLLVMUseLists);
1333 return false;
1334 };
1335 break;
1336 default:
1337 Conf.CGFileType = getCodeGenFileType(Action);
1338 break;
1339 }
1340 if (Error E =
1341 thinBackend(Conf, -1, AddStream, *M, *CombinedIndex, ImportList,
1342 ModuleToDefinedGVSummaries[M->getModuleIdentifier()],
1343 /*ModuleMap=*/nullptr, Conf.CodeGenOnly,
1344 /*IRAddStream=*/nullptr, CGOpts.CmdArgs)) {
1345 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
1346 errs() << "Error running ThinLTO backend: " << EIB.message() << '\n';
1347 });
1348 }
1349}
1350
1352 DiagnosticsEngine &Diags, const HeaderSearchOptions &HeaderOpts,
1353 const CodeGenOptions &CGOpts, const clang::TargetOptions &TOpts,
1354 const LangOptions &LOpts, StringRef TDesc, llvm::Module *M,
1356 std::unique_ptr<raw_pwrite_stream> OS, BackendConsumer *BC) {
1357
1358 llvm::TimeTraceScope TimeScope("Backend");
1359
1360 std::unique_ptr<llvm::Module> EmptyModule;
1361 if (!CGOpts.ThinLTOIndexFile.empty()) {
1362 // If we are performing a ThinLTO importing compile, load the function index
1363 // into memory and pass it into runThinLTOBackend, which will run the
1364 // function importer and invoke LTO passes.
1365 std::unique_ptr<ModuleSummaryIndex> CombinedIndex;
1366 if (Error E = llvm::getModuleSummaryIndexForFile(
1367 CGOpts.ThinLTOIndexFile,
1368 /*IgnoreEmptyThinLTOIndexFile*/ true)
1369 .moveInto(CombinedIndex)) {
1370 logAllUnhandledErrors(std::move(E), errs(),
1371 "Error loading index file '" +
1372 CGOpts.ThinLTOIndexFile + "': ");
1373 return;
1374 }
1375
1376 // A null CombinedIndex means we should skip ThinLTO compilation
1377 // (LLVM will optionally ignore empty index files, returning null instead
1378 // of an error).
1379 if (CombinedIndex) {
1380 if (!CombinedIndex->skipModuleByDistributedBackend()) {
1381 runThinLTOBackend(Diags, CombinedIndex.get(), M, HeaderOpts, CGOpts,
1382 TOpts, LOpts, std::move(OS), CGOpts.SampleProfileFile,
1383 CGOpts.ProfileRemappingFile, Action);
1384 return;
1385 }
1386 // Distributed indexing detected that nothing from the module is needed
1387 // for the final linking. So we can skip the compilation. We sill need to
1388 // output an empty object file to make sure that a linker does not fail
1389 // trying to read it. Also for some features, like CFI, we must skip
1390 // the compilation as CombinedIndex does not contain all required
1391 // information.
1392 EmptyModule = std::make_unique<llvm::Module>("empty", M->getContext());
1393 EmptyModule->setTargetTriple(M->getTargetTriple());
1394 M = EmptyModule.get();
1395 }
1396 }
1397
1398 EmitAssemblyHelper AsmHelper(Diags, HeaderOpts, CGOpts, TOpts, LOpts, M, VFS);
1399 AsmHelper.EmitAssembly(Action, std::move(OS), BC);
1400
1401 // Verify clang's TargetInfo DataLayout against the LLVM TargetMachine's
1402 // DataLayout.
1403 if (AsmHelper.TM) {
1404 std::string DLDesc = M->getDataLayout().getStringRepresentation();
1405 if (DLDesc != TDesc) {
1406 unsigned DiagID = Diags.getCustomDiagID(
1407 DiagnosticsEngine::Error, "backend data layout '%0' does not match "
1408 "expected target description '%1'");
1409 Diags.Report(DiagID) << DLDesc << TDesc;
1410 }
1411 }
1412}
1413
1414// With -fembed-bitcode, save a copy of the llvm IR as data in the
1415// __LLVM,__bitcode section.
1416void clang::EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,
1417 llvm::MemoryBufferRef Buf) {
1418 if (CGOpts.getEmbedBitcode() == CodeGenOptions::Embed_Off)
1419 return;
1420 llvm::embedBitcodeInModule(
1421 *M, Buf, CGOpts.getEmbedBitcode() != CodeGenOptions::Embed_Marker,
1422 CGOpts.getEmbedBitcode() != CodeGenOptions::Embed_Bitcode,
1423 CGOpts.CmdArgs);
1424}
1425
1426void clang::EmbedObject(llvm::Module *M, const CodeGenOptions &CGOpts,
1427 DiagnosticsEngine &Diags) {
1428 if (CGOpts.OffloadObjects.empty())
1429 return;
1430
1431 for (StringRef OffloadObject : CGOpts.OffloadObjects) {
1432 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ObjectOrErr =
1433 llvm::MemoryBuffer::getFileOrSTDIN(OffloadObject);
1434 if (ObjectOrErr.getError()) {
1435 auto DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
1436 "could not open '%0' for embedding");
1437 Diags.Report(DiagID) << OffloadObject;
1438 return;
1439 }
1440
1441 llvm::embedBufferInModule(*M, **ObjectOrErr, ".llvm.offloading",
1442 Align(object::OffloadBinary::getAlignment()));
1443 }
1444}
static bool actionRequiresCodeGen(BackendAction Action)
static void addSanitizers(const Triple &TargetTriple, const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts, PassBuilder &PB)
static std::optional< llvm::CodeModel::Model > getCodeModel(const CodeGenOptions &CodeGenOpts)
static SanitizerBinaryMetadataOptions getSanitizerBinaryMetadataOptions(const CodeGenOptions &CGOpts)
static std::optional< GCOVOptions > getGCOVOptions(const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts)
static bool initTargetOptions(DiagnosticsEngine &Diags, llvm::TargetOptions &Options, const CodeGenOptions &CodeGenOpts, const clang::TargetOptions &TargetOpts, const LangOptions &LangOpts, const HeaderSearchOptions &HSOpts)
static void addKCFIPass(const Triple &TargetTriple, const LangOptions &LangOpts, PassBuilder &PB)
static void runThinLTOBackend(DiagnosticsEngine &Diags, ModuleSummaryIndex *CombinedIndex, llvm::Module *M, const HeaderSearchOptions &HeaderOpts, const CodeGenOptions &CGOpts, const clang::TargetOptions &TOpts, const LangOptions &LOpts, std::unique_ptr< raw_pwrite_stream > OS, std::string SampleProfile, std::string ProfileRemapping, BackendAction Action)
static SanitizerCoverageOptions getSancovOptsFromCGOpts(const CodeGenOptions &CGOpts)
static OptimizationLevel mapToLevel(const CodeGenOptions &Opts)
static std::optional< InstrProfOptions > getInstrProfOptions(const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts)
static bool asanUseGlobalsGC(const Triple &T, const CodeGenOptions &CGOpts)
static void setCommandLineOpts(const CodeGenOptions &CodeGenOpts)
static CodeGenFileType getCodeGenFileType(BackendAction Action)
static std::string flattenClangCommandLine(ArrayRef< std::string > Args, StringRef MainFilename)
Defines the Diagnostic-related interfaces.
IndirectLocalPath & Path
Expr * E
Defines the clang::LangOptions interface.
This file provides a pass to link in Modules from a provided BackendConsumer.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static bool contains(const std::set< tok::TokenKind > &Terminators, const Token &Tok)
Definition: SourceCode.cpp:201
Defines the clang::TargetOptions class.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
SanitizerSet SanitizeMergeHandlers
Set of sanitizer checks that can merge handlers (smaller code size at the expense of debuggability).
std::string OptRecordFile
The name of the file to which the backend should save YAML optimization records.
std::string InstrProfileOutput
Name of the profile file to use as output for -fprofile-instr-generate, -fprofile-generate,...
std::string BinutilsVersion
bool hasProfileIRUse() const
Check if IR level profile use is on.
char CoverageVersion[4]
The version string to put into coverage files.
std::string FloatABI
The ABI to use for passing floating point arguments.
std::string ThinLinkBitcodeFile
Name of a file that can optionally be written with minimized bitcode to be used as input for the Thin...
bool hasProfileCSIRInstr() const
Check if CS IR level profile instrumentation is on.
std::string DebugPass
Enable additional debugging information.
llvm::Reloc::Model RelocationModel
The name of the relocation model to use.
std::string CoverageNotesFile
The filename with path we use for coverage notes files.
std::string ProfileInstrumentUsePath
Name of the profile file to use as input for -fprofile-instr-use.
std::string SampleProfileFile
Name of the profile file to use with -fprofile-sample-use.
uint64_t LargeDataThreshold
The code model-specific large data threshold to use (-mlarge-data-threshold).
std::string MemoryProfileOutput
Name of the profile file to use as output for with -fmemory-profile.
std::vector< std::function< void(llvm::PassBuilder &)> > PassBuilderCallbacks
List of pass builder callbacks.
std::string LimitFloatPrecision
The float precision limit to use, if non-empty.
std::string CodeModel
The code model to use (-mcmodel).
std::string CoverageDataFile
The filename with path we use for coverage data files.
std::vector< std::string > PassPlugins
List of dynamic shared object files to be loaded as pass plugins.
bool hasProfileClangInstr() const
Check if Clang profile instrumenation is on.
std::string StackUsageOutput
Name of the stack usage file (i.e., .su file) if user passes -fstack-usage.
std::string OptRecordPasses
The regex that filters the passes that should be saved to the optimization records.
std::vector< std::string > SanitizeCoverageAllowlistFiles
Path to allowlist file specifying which objects (files, functions) should exclusively be instrumented...
std::string SaveTempsFilePrefix
Prefix to use for -save-temps output.
std::vector< std::string > SanitizeCoverageIgnorelistFiles
Path to ignorelist file specifying which objects (files, functions) listed for instrumentation by san...
bool hasSanitizeCoverage() const
std::string MainFileName
The user provided name for the "main file", if non-empty.
bool hasProfileIRInstr() const
Check if IR level profile instrumentation is on.
bool hasProfileCSIRUse() const
Check if CSIR profile use is on.
SanitizerSet SanitizeTrap
Set of sanitizer checks that trap rather than diagnose.
std::vector< std::string > SanitizeMetadataIgnorelistFiles
Path to ignorelist file specifying which objects (files, functions) listed for instrumentation by san...
SanitizerSet SanitizeRecover
Set of sanitizer checks that are non-fatal (i.e.
std::string ProfileExcludeFiles
Regexes separated by a semi-colon to filter the files to not instrument.
std::string AsSecureLogFile
The name of a file to use with .secure_log_unique directives.
std::string ProfileRemappingFile
Name of the profile remapping file to apply to the profile data supplied by -fprofile-sample-use or -...
bool hasSanitizeBinaryMetadata() const
std::string ThinLTOIndexFile
Name of the function summary index file to use for ThinLTO function importing.
const char * Argv0
Executable and command-line used to create a given CompilerInvocation.
std::string SplitDwarfFile
The name for the split debug info file used for the DW_AT_[GNU_]dwo_name attribute in the skeleton CU...
std::vector< uint8_t > CmdArgs
List of backend command-line options for -fembed-bitcode.
std::vector< std::string > CommandLineArgs
std::string MemoryProfileUsePath
Name of the profile file to use as input for -fmemory-profile-use.
std::string OptRecordFormat
The format used for serializing remarks (default: YAML)
std::vector< std::string > OffloadObjects
List of filenames passed in using the -fembed-offload-object option.
std::string ProfileFilterFiles
Regexes separated by a semi-colon to filter the files to instrument.
std::string ObjectFilenameForDebug
Output filename used in the COFF debug information.
std::string SplitDwarfOutput
Output filename for the split debug info, not used in the skeleton CU.
std::string DIBugsReportFilePath
The file to use for dumping bug report by Debugify for original debug info.
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:231
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1493
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Definition: Diagnostic.h:896
HeaderSearchOptions - Helper class for storing options related to the initialization of the HeaderSea...
std::string Sysroot
If non-empty, the directory to use as a "virtual system root" for include paths.
std::vector< Entry > UserEntries
User specified include entries.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:499
bool hasWasmExceptions() const
Definition: LangOptions.h:767
bool hasSjLjExceptions() const
Definition: LangOptions.h:755
SanitizerSet Sanitize
Set of enabled sanitizers.
Definition: LangOptions.h:505
bool hasDWARFExceptions() const
Definition: LangOptions.h:763
bool hasSEHExceptions() const
Definition: LangOptions.h:759
std::vector< std::string > NoSanitizeFiles
Paths to files specifying which objects (files, functions, variables) should not be instrumented.
Definition: LangOptions.h:511
Options for controlling the target.
Definition: TargetOptions.h:26
std::vector< std::string > Features
The list of target specific features to enable or disable – this should be a list of strings starting...
Definition: TargetOptions.h:58
std::string ABI
If given, the name of the target ABI to use.
Definition: TargetOptions.h:45
std::string CPU
If given, the name of the target CPU to generate code for.
Definition: TargetOptions.h:36
llvm::EABI EABIVersion
The EABI version to use.
Definition: TargetOptions.h:48
Create and return a pass that links in Moduels from a provided BackendConsumer to a given primary Mod...
@ EmitAssembly
Emit a .s file.
@ VFS
Remove unused -ivfsoverlay arguments.
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
void EmbedObject(llvm::Module *M, const CodeGenOptions &CGOpts, DiagnosticsEngine &Diags)
void EmitBackendOutput(DiagnosticsEngine &Diags, const HeaderSearchOptions &, const CodeGenOptions &CGOpts, const TargetOptions &TOpts, const LangOptions &LOpts, StringRef TDesc, llvm::Module *M, BackendAction Action, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, std::unique_ptr< raw_pwrite_stream > OS, BackendConsumer *BC=nullptr)
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
BackendAction
Definition: BackendUtil.h:35
@ Backend_EmitAssembly
Emit native assembly files.
Definition: BackendUtil.h:36
@ Backend_EmitLL
Emit human-readable LLVM assembly.
Definition: BackendUtil.h:38
@ Backend_EmitBC
Emit LLVM bitcode files.
Definition: BackendUtil.h:37
@ Backend_EmitObj
Emit native object files.
Definition: BackendUtil.h:41
@ Backend_EmitMCNull
Run CodeGen, but don't emit anything.
Definition: BackendUtil.h:40
@ Backend_EmitNothing
Don't emit anything (benchmarking mode)
Definition: BackendUtil.h:39
const FunctionProtoType * T
unsigned int uint32_t
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
cl::opt< bool > PrintPipelinePasses
cl::opt< InstrProfCorrelator::ProfCorrelatorKind > ProfileCorrelate
static cl::opt< PGOOptions::ColdFuncOpt > ClPGOColdFuncAttr("pgo-cold-func-opt", cl::init(PGOOptions::ColdFuncOpt::Default), cl::Hidden, cl::desc("Function attribute to apply to cold functions as determined by PGO"), cl::values(clEnumValN(PGOOptions::ColdFuncOpt::Default, "default", "Default (no attribute)"), clEnumValN(PGOOptions::ColdFuncOpt::OptSize, "optsize", "Mark cold functions with optsize."), clEnumValN(PGOOptions::ColdFuncOpt::MinSize, "minsize", "Mark cold functions with minsize."), clEnumValN(PGOOptions::ColdFuncOpt::OptNone, "optnone", "Mark cold functions with optnone.")))
static cl::opt< bool > ClSanitizeOnOptimizerEarlyEP("sanitizer-early-opt-ep", cl::Optional, cl::desc("Insert sanitizers on OptimizerEarlyEP."))
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
Definition: Sanitizers.h:159