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/ScopeExit.h"
20#include "llvm/ADT/StringExtras.h"
21#include "llvm/ADT/StringSwitch.h"
22#include "llvm/Analysis/GlobalsModRef.h"
23#include "llvm/Analysis/TargetLibraryInfo.h"
24#include "llvm/Analysis/TargetTransformInfo.h"
25#include "llvm/Bitcode/BitcodeReader.h"
26#include "llvm/Bitcode/BitcodeWriter.h"
27#include "llvm/Bitcode/BitcodeWriterPass.h"
28#include "llvm/CodeGen/TargetSubtargetInfo.h"
29#include "llvm/Frontend/Driver/CodeGenOptions.h"
30#include "llvm/IR/DataLayout.h"
31#include "llvm/IR/DebugInfo.h"
32#include "llvm/IR/LegacyPassManager.h"
33#include "llvm/IR/Module.h"
34#include "llvm/IR/ModuleSummaryIndex.h"
35#include "llvm/IR/PassManager.h"
36#include "llvm/IR/Verifier.h"
37#include "llvm/IRPrinter/IRPrintingPasses.h"
38#include "llvm/LTO/LTOBackend.h"
39#include "llvm/MC/TargetRegistry.h"
40#include "llvm/Object/OffloadBinary.h"
41#include "llvm/Passes/PassBuilder.h"
42#include "llvm/Passes/PassPlugin.h"
43#include "llvm/Passes/StandardInstrumentations.h"
44#include "llvm/ProfileData/InstrProfCorrelator.h"
45#include "llvm/Support/BuryPointer.h"
46#include "llvm/Support/CommandLine.h"
47#include "llvm/Support/MemoryBuffer.h"
48#include "llvm/Support/PrettyStackTrace.h"
49#include "llvm/Support/Program.h"
50#include "llvm/Support/TimeProfiler.h"
51#include "llvm/Support/Timer.h"
52#include "llvm/Support/ToolOutputFile.h"
53#include "llvm/Support/VirtualFileSystem.h"
54#include "llvm/Support/raw_ostream.h"
55#include "llvm/Target/TargetMachine.h"
56#include "llvm/Target/TargetOptions.h"
57#include "llvm/TargetParser/SubtargetFeature.h"
58#include "llvm/TargetParser/Triple.h"
59#include "llvm/Transforms/HipStdPar/HipStdPar.h"
60#include "llvm/Transforms/IPO/EmbedBitcodePass.h"
61#include "llvm/Transforms/IPO/LowerTypeTests.h"
62#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
63#include "llvm/Transforms/InstCombine/InstCombine.h"
64#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
65#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
66#include "llvm/Transforms/Instrumentation/BoundsChecking.h"
67#include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h"
68#include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
69#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
70#include "llvm/Transforms/Instrumentation/InstrProfiling.h"
71#include "llvm/Transforms/Instrumentation/KCFI.h"
72#include "llvm/Transforms/Instrumentation/LowerAllowCheckPass.h"
73#include "llvm/Transforms/Instrumentation/MemProfiler.h"
74#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
75#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
76#include "llvm/Transforms/Instrumentation/PGOInstrumentation.h"
77#include "llvm/Transforms/Instrumentation/RealtimeSanitizer.h"
78#include "llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h"
79#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
80#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
81#include "llvm/Transforms/Instrumentation/TypeSanitizer.h"
82#include "llvm/Transforms/ObjCARC.h"
83#include "llvm/Transforms/Scalar/EarlyCSE.h"
84#include "llvm/Transforms/Scalar/GVN.h"
85#include "llvm/Transforms/Scalar/JumpThreading.h"
86#include "llvm/Transforms/Utils/Debugify.h"
87#include "llvm/Transforms/Utils/ModuleUtils.h"
88#include <limits>
89#include <memory>
90#include <optional>
91using namespace clang;
92using namespace llvm;
93
94#define HANDLE_EXTENSION(Ext) \
95 llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
96#include "llvm/Support/Extension.def"
97
98namespace llvm {
99extern cl::opt<bool> PrintPipelinePasses;
100
101// Experiment to move sanitizers earlier.
102static cl::opt<bool> ClSanitizeOnOptimizerEarlyEP(
103 "sanitizer-early-opt-ep", cl::Optional,
104 cl::desc("Insert sanitizers on OptimizerEarlyEP."));
105
106// Experiment to mark cold functions as optsize/minsize/optnone.
107// TODO: remove once this is exposed as a proper driver flag.
108static cl::opt<PGOOptions::ColdFuncOpt> ClPGOColdFuncAttr(
109 "pgo-cold-func-opt", cl::init(PGOOptions::ColdFuncOpt::Default), cl::Hidden,
110 cl::desc(
111 "Function attribute to apply to cold functions as determined by PGO"),
112 cl::values(clEnumValN(PGOOptions::ColdFuncOpt::Default, "default",
113 "Default (no attribute)"),
114 clEnumValN(PGOOptions::ColdFuncOpt::OptSize, "optsize",
115 "Mark cold functions with optsize."),
116 clEnumValN(PGOOptions::ColdFuncOpt::MinSize, "minsize",
117 "Mark cold functions with minsize."),
118 clEnumValN(PGOOptions::ColdFuncOpt::OptNone, "optnone",
119 "Mark cold functions with optnone.")));
120
121extern cl::opt<InstrProfCorrelator::ProfCorrelatorKind> ProfileCorrelate;
122} // namespace llvm
123namespace clang {
124extern llvm::cl::opt<bool> ClSanitizeGuardChecks;
125}
126
127namespace {
128
129// Default filename used for profile generation.
130std::string getDefaultProfileGenName() {
131 return DebugInfoCorrelate || ProfileCorrelate != InstrProfCorrelator::NONE
132 ? "default_%m.proflite"
133 : "default_%m.profraw";
134}
135
136class EmitAssemblyHelper {
138 DiagnosticsEngine &Diags;
139 const CodeGenOptions &CodeGenOpts;
140 const clang::TargetOptions &TargetOpts;
141 const LangOptions &LangOpts;
142 llvm::Module *TheModule;
144
145 std::unique_ptr<raw_pwrite_stream> OS;
146
147 Triple TargetTriple;
148
149 TargetIRAnalysis getTargetIRAnalysis() const {
150 if (TM)
151 return TM->getTargetIRAnalysis();
152
153 return TargetIRAnalysis();
154 }
155
156 /// Generates the TargetMachine.
157 /// Leaves TM unchanged if it is unable to create the target machine.
158 /// Some of our clang tests specify triples which are not built
159 /// into clang. This is okay because these tests check the generated
160 /// IR, and they require DataLayout which depends on the triple.
161 /// In this case, we allow this method to fail and not report an error.
162 /// When MustCreateTM is used, we print an error if we are unable to load
163 /// the requested target.
164 void CreateTargetMachine(bool MustCreateTM);
165
166 /// Add passes necessary to emit assembly or LLVM IR.
167 ///
168 /// \return True on success.
169 bool AddEmitPasses(legacy::PassManager &CodeGenPasses, BackendAction Action,
170 raw_pwrite_stream &OS, raw_pwrite_stream *DwoOS);
171
172 std::unique_ptr<llvm::ToolOutputFile> openOutputFile(StringRef Path) {
173 std::error_code EC;
174 auto F = std::make_unique<llvm::ToolOutputFile>(Path, EC,
175 llvm::sys::fs::OF_None);
176 if (EC) {
177 Diags.Report(diag::err_fe_unable_to_open_output) << Path << EC.message();
178 F.reset();
179 }
180 return F;
181 }
182
183 void RunOptimizationPipeline(
184 BackendAction Action, std::unique_ptr<raw_pwrite_stream> &OS,
185 std::unique_ptr<llvm::ToolOutputFile> &ThinLinkOS, BackendConsumer *BC);
186 void RunCodegenPipeline(BackendAction Action,
187 std::unique_ptr<raw_pwrite_stream> &OS,
188 std::unique_ptr<llvm::ToolOutputFile> &DwoOS);
189
190 /// Check whether we should emit a module summary for regular LTO.
191 /// The module summary should be emitted by default for regular LTO
192 /// except for ld64 targets.
193 ///
194 /// \return True if the module summary should be emitted.
195 bool shouldEmitRegularLTOSummary() const {
196 return CodeGenOpts.PrepareForLTO && !CodeGenOpts.DisableLLVMPasses &&
197 TargetTriple.getVendor() != llvm::Triple::Apple;
198 }
199
200 /// Check whether we should emit a flag for UnifiedLTO.
201 /// The UnifiedLTO module flag should be set when UnifiedLTO is enabled for
202 /// ThinLTO or Full LTO with module summaries.
203 bool shouldEmitUnifiedLTOModueFlag() const {
204 return CodeGenOpts.UnifiedLTO &&
205 (CodeGenOpts.PrepareForThinLTO || shouldEmitRegularLTOSummary());
206 }
207
208public:
209 EmitAssemblyHelper(CompilerInstance &CI, llvm::Module *M,
211 : CI(CI), Diags(CI.getDiagnostics()), CodeGenOpts(CI.getCodeGenOpts()),
212 TargetOpts(CI.getTargetOpts()), LangOpts(CI.getLangOpts()),
213 TheModule(M), VFS(std::move(VFS)),
214 TargetTriple(TheModule->getTargetTriple()) {}
215
216 ~EmitAssemblyHelper() {
217 if (CodeGenOpts.DisableFree)
218 BuryPointer(std::move(TM));
219 }
220
221 std::unique_ptr<TargetMachine> TM;
222
223 // Emit output using the new pass manager for the optimization pipeline.
224 void emitAssembly(BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS,
225 BackendConsumer *BC);
226};
227} // namespace
228
229static SanitizerCoverageOptions
231 SanitizerCoverageOptions Opts;
232 Opts.CoverageType =
233 static_cast<SanitizerCoverageOptions::Type>(CGOpts.SanitizeCoverageType);
234 Opts.IndirectCalls = CGOpts.SanitizeCoverageIndirectCalls;
235 Opts.TraceBB = CGOpts.SanitizeCoverageTraceBB;
236 Opts.TraceCmp = CGOpts.SanitizeCoverageTraceCmp;
237 Opts.TraceDiv = CGOpts.SanitizeCoverageTraceDiv;
238 Opts.TraceGep = CGOpts.SanitizeCoverageTraceGep;
239 Opts.Use8bitCounters = CGOpts.SanitizeCoverage8bitCounters;
240 Opts.TracePC = CGOpts.SanitizeCoverageTracePC;
241 Opts.TracePCGuard = CGOpts.SanitizeCoverageTracePCGuard;
242 Opts.NoPrune = CGOpts.SanitizeCoverageNoPrune;
243 Opts.Inline8bitCounters = CGOpts.SanitizeCoverageInline8bitCounters;
244 Opts.InlineBoolFlag = CGOpts.SanitizeCoverageInlineBoolFlag;
245 Opts.PCTable = CGOpts.SanitizeCoveragePCTable;
246 Opts.StackDepth = CGOpts.SanitizeCoverageStackDepth;
247 Opts.TraceLoads = CGOpts.SanitizeCoverageTraceLoads;
248 Opts.TraceStores = CGOpts.SanitizeCoverageTraceStores;
249 Opts.CollectControlFlow = CGOpts.SanitizeCoverageControlFlow;
250 return Opts;
251}
252
253static SanitizerBinaryMetadataOptions
255 SanitizerBinaryMetadataOptions Opts;
256 Opts.Covered = CGOpts.SanitizeBinaryMetadataCovered;
257 Opts.Atomics = CGOpts.SanitizeBinaryMetadataAtomics;
258 Opts.UAR = CGOpts.SanitizeBinaryMetadataUAR;
259 return Opts;
260}
261
262// Check if ASan should use GC-friendly instrumentation for globals.
263// First of all, there is no point if -fdata-sections is off (expect for MachO,
264// where this is not a factor). Also, on ELF this feature requires an assembler
265// extension that only works with -integrated-as at the moment.
266static bool asanUseGlobalsGC(const Triple &T, const CodeGenOptions &CGOpts) {
267 if (!CGOpts.SanitizeAddressGlobalsDeadStripping)
268 return false;
269 switch (T.getObjectFormat()) {
270 case Triple::MachO:
271 case Triple::COFF:
272 return true;
273 case Triple::ELF:
274 return !CGOpts.DisableIntegratedAS;
275 case Triple::GOFF:
276 llvm::report_fatal_error("ASan not implemented for GOFF");
277 case Triple::XCOFF:
278 llvm::report_fatal_error("ASan not implemented for XCOFF.");
279 case Triple::Wasm:
280 case Triple::DXContainer:
281 case Triple::SPIRV:
282 case Triple::UnknownObjectFormat:
283 break;
284 }
285 return false;
286}
287
288static std::optional<llvm::CodeModel::Model>
289getCodeModel(const CodeGenOptions &CodeGenOpts) {
290 unsigned CodeModel = llvm::StringSwitch<unsigned>(CodeGenOpts.CodeModel)
291 .Case("tiny", llvm::CodeModel::Tiny)
292 .Case("small", llvm::CodeModel::Small)
293 .Case("kernel", llvm::CodeModel::Kernel)
294 .Case("medium", llvm::CodeModel::Medium)
295 .Case("large", llvm::CodeModel::Large)
296 .Case("default", ~1u)
297 .Default(~0u);
298 assert(CodeModel != ~0u && "invalid code model!");
299 if (CodeModel == ~1u)
300 return std::nullopt;
301 return static_cast<llvm::CodeModel::Model>(CodeModel);
302}
303
304static CodeGenFileType getCodeGenFileType(BackendAction Action) {
305 if (Action == Backend_EmitObj)
306 return CodeGenFileType::ObjectFile;
307 else if (Action == Backend_EmitMCNull)
308 return CodeGenFileType::Null;
309 else {
310 assert(Action == Backend_EmitAssembly && "Invalid action!");
311 return CodeGenFileType::AssemblyFile;
312 }
313}
314
316 return Action != Backend_EmitNothing && Action != Backend_EmitBC &&
317 Action != Backend_EmitLL;
318}
319
321 StringRef MainFilename) {
322 if (Args.empty())
323 return std::string{};
324
325 std::string FlatCmdLine;
326 raw_string_ostream OS(FlatCmdLine);
327 bool PrintedOneArg = false;
328 if (!StringRef(Args[0]).contains("-cc1")) {
329 llvm::sys::printArg(OS, "-cc1", /*Quote=*/true);
330 PrintedOneArg = true;
331 }
332 for (unsigned i = 0; i < Args.size(); i++) {
333 StringRef Arg = Args[i];
334 if (Arg.empty())
335 continue;
336 if (Arg == "-main-file-name" || Arg == "-o") {
337 i++; // Skip this argument and next one.
338 continue;
339 }
340 if (Arg.starts_with("-object-file-name") || Arg == MainFilename)
341 continue;
342 // Skip fmessage-length for reproducibility.
343 if (Arg.starts_with("-fmessage-length"))
344 continue;
345 if (PrintedOneArg)
346 OS << " ";
347 llvm::sys::printArg(OS, Arg, /*Quote=*/true);
348 PrintedOneArg = true;
349 }
350 return FlatCmdLine;
351}
352
354 DiagnosticsEngine &Diags,
355 llvm::TargetOptions &Options) {
356 const auto &CodeGenOpts = CI.getCodeGenOpts();
357 const auto &TargetOpts = CI.getTargetOpts();
358 const auto &LangOpts = CI.getLangOpts();
359 const auto &HSOpts = CI.getHeaderSearchOpts();
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(CI, Diags, Options))
604 return;
605 TM.reset(TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr,
606 Options, RM, CM, OptLevel));
607 TM->setLargeDataThreshold(CodeGenOpts.LargeDataThreshold);
608}
609
610bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses,
611 BackendAction Action,
612 raw_pwrite_stream &OS,
613 raw_pwrite_stream *DwoOS) {
614 // Add LibraryInfo.
615 std::unique_ptr<TargetLibraryInfoImpl> TLII(
616 llvm::driver::createTLII(TargetTriple, CodeGenOpts.getVecLib()));
617 CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII));
618
619 // Normal mode, emit a .s or .o file by running the code generator. Note,
620 // this also adds codegenerator level optimization passes.
621 CodeGenFileType CGFT = getCodeGenFileType(Action);
622
623 if (TM->addPassesToEmitFile(CodeGenPasses, OS, DwoOS, CGFT,
624 /*DisableVerify=*/!CodeGenOpts.VerifyModule)) {
625 Diags.Report(diag::err_fe_unable_to_interface_with_target);
626 return false;
627 }
628
629 return true;
630}
631
632static OptimizationLevel mapToLevel(const CodeGenOptions &Opts) {
633 switch (Opts.OptimizationLevel) {
634 default:
635 llvm_unreachable("Invalid optimization level!");
636
637 case 0:
638 return OptimizationLevel::O0;
639
640 case 1:
641 return OptimizationLevel::O1;
642
643 case 2:
644 switch (Opts.OptimizeSize) {
645 default:
646 llvm_unreachable("Invalid optimization level for size!");
647
648 case 0:
649 return OptimizationLevel::O2;
650
651 case 1:
652 return OptimizationLevel::Os;
653
654 case 2:
655 return OptimizationLevel::Oz;
656 }
657
658 case 3:
659 return OptimizationLevel::O3;
660 }
661}
662
663static void addKCFIPass(const Triple &TargetTriple, const LangOptions &LangOpts,
664 PassBuilder &PB) {
665 // If the back-end supports KCFI operand bundle lowering, skip KCFIPass.
666 if (TargetTriple.getArch() == llvm::Triple::x86_64 ||
667 TargetTriple.isAArch64(64) || TargetTriple.isRISCV())
668 return;
669
670 // Ensure we lower KCFI operand bundles with -O0.
671 PB.registerOptimizerLastEPCallback(
672 [&](ModulePassManager &MPM, OptimizationLevel Level, ThinOrFullLTOPhase) {
673 if (Level == OptimizationLevel::O0 &&
674 LangOpts.Sanitize.has(SanitizerKind::KCFI))
675 MPM.addPass(createModuleToFunctionPassAdaptor(KCFIPass()));
676 });
677
678 // When optimizations are requested, run KCIFPass after InstCombine to
679 // avoid unnecessary checks.
680 PB.registerPeepholeEPCallback(
681 [&](FunctionPassManager &FPM, OptimizationLevel Level) {
682 if (Level != OptimizationLevel::O0 &&
683 LangOpts.Sanitize.has(SanitizerKind::KCFI))
684 FPM.addPass(KCFIPass());
685 });
686}
687
688static void addSanitizers(const Triple &TargetTriple,
689 const CodeGenOptions &CodeGenOpts,
690 const LangOptions &LangOpts, PassBuilder &PB) {
691 auto SanitizersCallback = [&](ModulePassManager &MPM, OptimizationLevel Level,
692 ThinOrFullLTOPhase) {
693 if (CodeGenOpts.hasSanitizeCoverage()) {
694 auto SancovOpts = getSancovOptsFromCGOpts(CodeGenOpts);
695 MPM.addPass(SanitizerCoveragePass(
696 SancovOpts, CodeGenOpts.SanitizeCoverageAllowlistFiles,
698 }
699
700 if (CodeGenOpts.hasSanitizeBinaryMetadata()) {
701 MPM.addPass(SanitizerBinaryMetadataPass(
704 }
705
706 auto MSanPass = [&](SanitizerMask Mask, bool CompileKernel) {
707 if (LangOpts.Sanitize.has(Mask)) {
708 int TrackOrigins = CodeGenOpts.SanitizeMemoryTrackOrigins;
709 bool Recover = CodeGenOpts.SanitizeRecover.has(Mask);
710
711 MemorySanitizerOptions options(TrackOrigins, Recover, CompileKernel,
712 CodeGenOpts.SanitizeMemoryParamRetval);
713 MPM.addPass(MemorySanitizerPass(options));
714 if (Level != OptimizationLevel::O0) {
715 // MemorySanitizer inserts complex instrumentation that mostly follows
716 // the logic of the original code, but operates on "shadow" values. It
717 // can benefit from re-running some general purpose optimization
718 // passes.
719 MPM.addPass(RequireAnalysisPass<GlobalsAA, llvm::Module>());
720 FunctionPassManager FPM;
721 FPM.addPass(EarlyCSEPass(true /* Enable mem-ssa. */));
722 FPM.addPass(InstCombinePass());
723 FPM.addPass(JumpThreadingPass());
724 FPM.addPass(GVNPass());
725 FPM.addPass(InstCombinePass());
726 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
727 }
728 }
729 };
730 MSanPass(SanitizerKind::Memory, false);
731 MSanPass(SanitizerKind::KernelMemory, true);
732
733 if (LangOpts.Sanitize.has(SanitizerKind::Thread)) {
734 MPM.addPass(ModuleThreadSanitizerPass());
735 MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
736 }
737
738 if (LangOpts.Sanitize.has(SanitizerKind::Type))
739 MPM.addPass(TypeSanitizerPass());
740
741 if (LangOpts.Sanitize.has(SanitizerKind::NumericalStability))
742 MPM.addPass(NumericalStabilitySanitizerPass());
743
744 if (LangOpts.Sanitize.has(SanitizerKind::Realtime))
745 MPM.addPass(RealtimeSanitizerPass());
746
747 auto ASanPass = [&](SanitizerMask Mask, bool CompileKernel) {
748 if (LangOpts.Sanitize.has(Mask)) {
749 bool UseGlobalGC = asanUseGlobalsGC(TargetTriple, CodeGenOpts);
750 bool UseOdrIndicator = CodeGenOpts.SanitizeAddressUseOdrIndicator;
751 llvm::AsanDtorKind DestructorKind =
752 CodeGenOpts.getSanitizeAddressDtor();
753 AddressSanitizerOptions Opts;
754 Opts.CompileKernel = CompileKernel;
755 Opts.Recover = CodeGenOpts.SanitizeRecover.has(Mask);
756 Opts.UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope;
757 Opts.UseAfterReturn = CodeGenOpts.getSanitizeAddressUseAfterReturn();
758 MPM.addPass(AddressSanitizerPass(Opts, UseGlobalGC, UseOdrIndicator,
759 DestructorKind));
760 }
761 };
762 ASanPass(SanitizerKind::Address, false);
763 ASanPass(SanitizerKind::KernelAddress, true);
764
765 auto HWASanPass = [&](SanitizerMask Mask, bool CompileKernel) {
766 if (LangOpts.Sanitize.has(Mask)) {
767 bool Recover = CodeGenOpts.SanitizeRecover.has(Mask);
768 MPM.addPass(HWAddressSanitizerPass(
769 {CompileKernel, Recover,
770 /*DisableOptimization=*/CodeGenOpts.OptimizationLevel == 0}));
771 }
772 };
773 HWASanPass(SanitizerKind::HWAddress, false);
774 HWASanPass(SanitizerKind::KernelHWAddress, true);
775
776 if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) {
777 MPM.addPass(DataFlowSanitizerPass(LangOpts.NoSanitizeFiles));
778 }
779 };
781 PB.registerOptimizerEarlyEPCallback(
782 [SanitizersCallback](ModulePassManager &MPM, OptimizationLevel Level,
783 ThinOrFullLTOPhase Phase) {
784 ModulePassManager NewMPM;
785 SanitizersCallback(NewMPM, Level, Phase);
786 if (!NewMPM.isEmpty()) {
787 // Sanitizers can abandon<GlobalsAA>.
788 NewMPM.addPass(RequireAnalysisPass<GlobalsAA, llvm::Module>());
789 MPM.addPass(std::move(NewMPM));
790 }
791 });
792 } else {
793 // LastEP does not need GlobalsAA.
794 PB.registerOptimizerLastEPCallback(SanitizersCallback);
795 }
796
797 if (LowerAllowCheckPass::IsRequested()) {
798 // We want to call it after inline, which is about OptimizerEarlyEPCallback.
799 PB.registerOptimizerEarlyEPCallback([&](ModulePassManager &MPM,
800 OptimizationLevel Level,
801 ThinOrFullLTOPhase Phase) {
802 LowerAllowCheckPass::Options Opts;
803 MPM.addPass(createModuleToFunctionPassAdaptor(LowerAllowCheckPass(Opts)));
804 });
805 }
806}
807
808void EmitAssemblyHelper::RunOptimizationPipeline(
809 BackendAction Action, std::unique_ptr<raw_pwrite_stream> &OS,
810 std::unique_ptr<llvm::ToolOutputFile> &ThinLinkOS, BackendConsumer *BC) {
811 std::optional<PGOOptions> PGOOpt;
812
813 if (CodeGenOpts.hasProfileIRInstr())
814 // -fprofile-generate.
815 PGOOpt = PGOOptions(
816 CodeGenOpts.InstrProfileOutput.empty() ? getDefaultProfileGenName()
817 : CodeGenOpts.InstrProfileOutput,
818 "", "", CodeGenOpts.MemoryProfileUsePath, nullptr, PGOOptions::IRInstr,
819 PGOOptions::NoCSAction, ClPGOColdFuncAttr,
820 CodeGenOpts.DebugInfoForProfiling,
821 /*PseudoProbeForProfiling=*/false, CodeGenOpts.AtomicProfileUpdate);
822 else if (CodeGenOpts.hasProfileIRUse()) {
823 // -fprofile-use.
824 auto CSAction = CodeGenOpts.hasProfileCSIRUse() ? PGOOptions::CSIRUse
825 : PGOOptions::NoCSAction;
826 PGOOpt = PGOOptions(CodeGenOpts.ProfileInstrumentUsePath, "",
827 CodeGenOpts.ProfileRemappingFile,
828 CodeGenOpts.MemoryProfileUsePath, VFS,
829 PGOOptions::IRUse, CSAction, ClPGOColdFuncAttr,
830 CodeGenOpts.DebugInfoForProfiling);
831 } else if (!CodeGenOpts.SampleProfileFile.empty())
832 // -fprofile-sample-use
833 PGOOpt = PGOOptions(
834 CodeGenOpts.SampleProfileFile, "", CodeGenOpts.ProfileRemappingFile,
835 CodeGenOpts.MemoryProfileUsePath, VFS, PGOOptions::SampleUse,
836 PGOOptions::NoCSAction, ClPGOColdFuncAttr,
837 CodeGenOpts.DebugInfoForProfiling, CodeGenOpts.PseudoProbeForProfiling);
838 else if (!CodeGenOpts.MemoryProfileUsePath.empty())
839 // -fmemory-profile-use (without any of the above options)
840 PGOOpt = PGOOptions("", "", "", CodeGenOpts.MemoryProfileUsePath, VFS,
841 PGOOptions::NoAction, PGOOptions::NoCSAction,
842 ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling);
843 else if (CodeGenOpts.PseudoProbeForProfiling)
844 // -fpseudo-probe-for-profiling
845 PGOOpt =
846 PGOOptions("", "", "", /*MemoryProfile=*/"", nullptr,
847 PGOOptions::NoAction, PGOOptions::NoCSAction,
848 ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling, true);
849 else if (CodeGenOpts.DebugInfoForProfiling)
850 // -fdebug-info-for-profiling
851 PGOOpt = PGOOptions("", "", "", /*MemoryProfile=*/"", nullptr,
852 PGOOptions::NoAction, PGOOptions::NoCSAction,
853 ClPGOColdFuncAttr, true);
854
855 // Check to see if we want to generate a CS profile.
856 if (CodeGenOpts.hasProfileCSIRInstr()) {
857 assert(!CodeGenOpts.hasProfileCSIRUse() &&
858 "Cannot have both CSProfileUse pass and CSProfileGen pass at "
859 "the same time");
860 if (PGOOpt) {
861 assert(PGOOpt->Action != PGOOptions::IRInstr &&
862 PGOOpt->Action != PGOOptions::SampleUse &&
863 "Cannot run CSProfileGen pass with ProfileGen or SampleUse "
864 " pass");
865 PGOOpt->CSProfileGenFile = CodeGenOpts.InstrProfileOutput.empty()
866 ? getDefaultProfileGenName()
867 : CodeGenOpts.InstrProfileOutput;
868 PGOOpt->CSAction = PGOOptions::CSIRInstr;
869 } else
870 PGOOpt = PGOOptions("",
871 CodeGenOpts.InstrProfileOutput.empty()
872 ? getDefaultProfileGenName()
873 : CodeGenOpts.InstrProfileOutput,
874 "", /*MemoryProfile=*/"", nullptr,
875 PGOOptions::NoAction, PGOOptions::CSIRInstr,
876 ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling);
877 }
878 if (TM)
879 TM->setPGOOption(PGOOpt);
880
881 PipelineTuningOptions PTO;
882 PTO.LoopUnrolling = CodeGenOpts.UnrollLoops;
883 // For historical reasons, loop interleaving is set to mirror setting for loop
884 // unrolling.
885 PTO.LoopInterleaving = CodeGenOpts.UnrollLoops;
886 PTO.LoopVectorization = CodeGenOpts.VectorizeLoop;
887 PTO.SLPVectorization = CodeGenOpts.VectorizeSLP;
888 PTO.MergeFunctions = CodeGenOpts.MergeFunctions;
889 // Only enable CGProfilePass when using integrated assembler, since
890 // non-integrated assemblers don't recognize .cgprofile section.
891 PTO.CallGraphProfile = !CodeGenOpts.DisableIntegratedAS;
892 PTO.UnifiedLTO = CodeGenOpts.UnifiedLTO;
893
894 LoopAnalysisManager LAM;
895 FunctionAnalysisManager FAM;
896 CGSCCAnalysisManager CGAM;
897 ModuleAnalysisManager MAM;
898
899 bool DebugPassStructure = CodeGenOpts.DebugPass == "Structure";
900 PassInstrumentationCallbacks PIC;
901 PrintPassOptions PrintPassOpts;
902 PrintPassOpts.Indent = DebugPassStructure;
903 PrintPassOpts.SkipAnalyses = DebugPassStructure;
904 StandardInstrumentations SI(
905 TheModule->getContext(),
906 (CodeGenOpts.DebugPassManager || DebugPassStructure),
907 CodeGenOpts.VerifyEach, PrintPassOpts);
908 SI.registerCallbacks(PIC, &MAM);
909 PassBuilder PB(TM.get(), PTO, PGOOpt, &PIC);
910
911 // Handle the assignment tracking feature options.
912 switch (CodeGenOpts.getAssignmentTrackingMode()) {
913 case CodeGenOptions::AssignmentTrackingOpts::Forced:
914 PB.registerPipelineStartEPCallback(
915 [&](ModulePassManager &MPM, OptimizationLevel Level) {
916 MPM.addPass(AssignmentTrackingPass());
917 });
918 break;
919 case CodeGenOptions::AssignmentTrackingOpts::Enabled:
920 // Disable assignment tracking in LTO builds for now as the performance
921 // cost is too high. Disable for LLDB tuning due to llvm.org/PR43126.
922 if (!CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.PrepareForLTO &&
923 CodeGenOpts.getDebuggerTuning() != llvm::DebuggerKind::LLDB) {
924 PB.registerPipelineStartEPCallback(
925 [&](ModulePassManager &MPM, OptimizationLevel Level) {
926 // Only use assignment tracking if optimisations are enabled.
927 if (Level != OptimizationLevel::O0)
928 MPM.addPass(AssignmentTrackingPass());
929 });
930 }
931 break;
932 case CodeGenOptions::AssignmentTrackingOpts::Disabled:
933 break;
934 }
935
936 // Enable verify-debuginfo-preserve-each for new PM.
937 DebugifyEachInstrumentation Debugify;
938 DebugInfoPerPass DebugInfoBeforePass;
939 if (CodeGenOpts.EnableDIPreservationVerify) {
940 Debugify.setDebugifyMode(DebugifyMode::OriginalDebugInfo);
941 Debugify.setDebugInfoBeforePass(DebugInfoBeforePass);
942
943 if (!CodeGenOpts.DIBugsReportFilePath.empty())
944 Debugify.setOrigDIVerifyBugsReportFilePath(
945 CodeGenOpts.DIBugsReportFilePath);
946 Debugify.registerCallbacks(PIC, MAM);
947 }
948 // Attempt to load pass plugins and register their callbacks with PB.
949 for (auto &PluginFN : CodeGenOpts.PassPlugins) {
950 auto PassPlugin = PassPlugin::Load(PluginFN);
951 if (PassPlugin) {
952 PassPlugin->registerPassBuilderCallbacks(PB);
953 } else {
954 Diags.Report(diag::err_fe_unable_to_load_plugin)
955 << PluginFN << toString(PassPlugin.takeError());
956 }
957 }
958 for (const auto &PassCallback : CodeGenOpts.PassBuilderCallbacks)
959 PassCallback(PB);
960#define HANDLE_EXTENSION(Ext) \
961 get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
962#include "llvm/Support/Extension.def"
963
964 // Register the target library analysis directly and give it a customized
965 // preset TLI.
966 std::unique_ptr<TargetLibraryInfoImpl> TLII(
967 llvm::driver::createTLII(TargetTriple, CodeGenOpts.getVecLib()));
968 FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
969
970 // Register all the basic analyses with the managers.
971 PB.registerModuleAnalyses(MAM);
972 PB.registerCGSCCAnalyses(CGAM);
973 PB.registerFunctionAnalyses(FAM);
974 PB.registerLoopAnalyses(LAM);
975 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
976
977 ModulePassManager MPM;
978 // Add a verifier pass, before any other passes, to catch CodeGen issues.
979 if (CodeGenOpts.VerifyModule)
980 MPM.addPass(VerifierPass());
981
982 if (!CodeGenOpts.DisableLLVMPasses) {
983 // Map our optimization levels into one of the distinct levels used to
984 // configure the pipeline.
985 OptimizationLevel Level = mapToLevel(CodeGenOpts);
986
987 const bool PrepareForThinLTO = CodeGenOpts.PrepareForThinLTO;
988 const bool PrepareForLTO = CodeGenOpts.PrepareForLTO;
989
990 if (LangOpts.ObjCAutoRefCount) {
991 PB.registerPipelineStartEPCallback(
992 [](ModulePassManager &MPM, OptimizationLevel Level) {
993 if (Level != OptimizationLevel::O0)
994 MPM.addPass(
995 createModuleToFunctionPassAdaptor(ObjCARCExpandPass()));
996 });
997 PB.registerPipelineEarlySimplificationEPCallback(
998 [](ModulePassManager &MPM, OptimizationLevel Level,
999 ThinOrFullLTOPhase) {
1000 if (Level != OptimizationLevel::O0)
1001 MPM.addPass(ObjCARCAPElimPass());
1002 });
1003 PB.registerScalarOptimizerLateEPCallback(
1004 [](FunctionPassManager &FPM, OptimizationLevel Level) {
1005 if (Level != OptimizationLevel::O0)
1006 FPM.addPass(ObjCARCOptPass());
1007 });
1008 }
1009
1010 // If we reached here with a non-empty index file name, then the index
1011 // file was empty and we are not performing ThinLTO backend compilation
1012 // (used in testing in a distributed build environment).
1013 bool IsThinLTOPostLink = !CodeGenOpts.ThinLTOIndexFile.empty();
1014 // If so drop any the type test assume sequences inserted for whole program
1015 // vtables so that codegen doesn't complain.
1016 if (IsThinLTOPostLink)
1017 PB.registerPipelineStartEPCallback(
1018 [](ModulePassManager &MPM, OptimizationLevel Level) {
1019 MPM.addPass(LowerTypeTestsPass(
1020 /*ExportSummary=*/nullptr,
1021 /*ImportSummary=*/nullptr,
1022 /*DropTypeTests=*/lowertypetests::DropTestKind::Assume));
1023 });
1024
1025 // Register callbacks to schedule sanitizer passes at the appropriate part
1026 // of the pipeline.
1027 if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds))
1028 PB.registerScalarOptimizerLateEPCallback([this](FunctionPassManager &FPM,
1029 OptimizationLevel Level) {
1030 BoundsCheckingPass::Options Options;
1031 if (CodeGenOpts.SanitizeSkipHotCutoffs[SanitizerKind::SO_LocalBounds] ||
1033 static_assert(SanitizerKind::SO_LocalBounds <=
1034 std::numeric_limits<
1035 decltype(Options.GuardKind)::value_type>::max(),
1036 "Update type of llvm.allow.ubsan.check to represent "
1037 "SanitizerKind::SO_LocalBounds.");
1038 Options.GuardKind = SanitizerKind::SO_LocalBounds;
1039 }
1040 Options.Merge =
1041 CodeGenOpts.SanitizeMergeHandlers.has(SanitizerKind::LocalBounds);
1042 if (!CodeGenOpts.SanitizeTrap.has(SanitizerKind::LocalBounds)) {
1043 Options.Rt = {
1044 /*MinRuntime=*/static_cast<bool>(
1045 CodeGenOpts.SanitizeMinimalRuntime),
1046 /*MayReturn=*/
1047 CodeGenOpts.SanitizeRecover.has(SanitizerKind::LocalBounds),
1048 };
1049 }
1050 FPM.addPass(BoundsCheckingPass(Options));
1051 });
1052
1053 // Don't add sanitizers if we are here from ThinLTO PostLink. That already
1054 // done on PreLink stage.
1055 if (!IsThinLTOPostLink) {
1056 addSanitizers(TargetTriple, CodeGenOpts, LangOpts, PB);
1057 addKCFIPass(TargetTriple, LangOpts, PB);
1058 }
1059
1060 if (std::optional<GCOVOptions> Options =
1061 getGCOVOptions(CodeGenOpts, LangOpts))
1062 PB.registerPipelineStartEPCallback(
1063 [Options](ModulePassManager &MPM, OptimizationLevel Level) {
1064 MPM.addPass(GCOVProfilerPass(*Options));
1065 });
1066 if (std::optional<InstrProfOptions> Options =
1067 getInstrProfOptions(CodeGenOpts, LangOpts))
1068 PB.registerPipelineStartEPCallback(
1069 [Options](ModulePassManager &MPM, OptimizationLevel Level) {
1070 MPM.addPass(InstrProfilingLoweringPass(*Options, false));
1071 });
1072
1073 // TODO: Consider passing the MemoryProfileOutput to the pass builder via
1074 // the PGOOptions, and set this up there.
1075 if (!CodeGenOpts.MemoryProfileOutput.empty()) {
1076 PB.registerOptimizerLastEPCallback([](ModulePassManager &MPM,
1077 OptimizationLevel Level,
1078 ThinOrFullLTOPhase) {
1079 MPM.addPass(createModuleToFunctionPassAdaptor(MemProfilerPass()));
1080 MPM.addPass(ModuleMemProfilerPass());
1081 });
1082 }
1083
1084 if (CodeGenOpts.FatLTO) {
1085 MPM.addPass(PB.buildFatLTODefaultPipeline(
1086 Level, PrepareForThinLTO,
1087 PrepareForThinLTO || shouldEmitRegularLTOSummary()));
1088 } else if (PrepareForThinLTO) {
1089 MPM.addPass(PB.buildThinLTOPreLinkDefaultPipeline(Level));
1090 } else if (PrepareForLTO) {
1091 MPM.addPass(PB.buildLTOPreLinkDefaultPipeline(Level));
1092 } else {
1093 MPM.addPass(PB.buildPerModuleDefaultPipeline(Level));
1094 }
1095 }
1096
1097 // Link against bitcodes supplied via the -mlink-builtin-bitcode option
1098 if (CodeGenOpts.LinkBitcodePostopt)
1099 MPM.addPass(LinkInModulesPass(BC));
1100
1101 // Add a verifier pass if requested. We don't have to do this if the action
1102 // requires code generation because there will already be a verifier pass in
1103 // the code-generation pipeline.
1104 // Since we already added a verifier pass above, this
1105 // might even not run the analysis, if previous passes caused no changes.
1106 if (!actionRequiresCodeGen(Action) && CodeGenOpts.VerifyModule)
1107 MPM.addPass(VerifierPass());
1108
1109 if (Action == Backend_EmitBC || Action == Backend_EmitLL ||
1110 CodeGenOpts.FatLTO) {
1111 if (CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.DisableLLVMPasses) {
1112 if (!TheModule->getModuleFlag("EnableSplitLTOUnit"))
1113 TheModule->addModuleFlag(llvm::Module::Error, "EnableSplitLTOUnit",
1114 CodeGenOpts.EnableSplitLTOUnit);
1115 if (Action == Backend_EmitBC) {
1116 if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) {
1117 ThinLinkOS = openOutputFile(CodeGenOpts.ThinLinkBitcodeFile);
1118 if (!ThinLinkOS)
1119 return;
1120 }
1121 MPM.addPass(ThinLTOBitcodeWriterPass(
1122 *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr));
1123 } else if (Action == Backend_EmitLL) {
1124 MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,
1125 /*EmitLTOSummary=*/true));
1126 }
1127 } else {
1128 // Emit a module summary by default for Regular LTO except for ld64
1129 // targets
1130 bool EmitLTOSummary = shouldEmitRegularLTOSummary();
1131 if (EmitLTOSummary) {
1132 if (!TheModule->getModuleFlag("ThinLTO") && !CodeGenOpts.UnifiedLTO)
1133 TheModule->addModuleFlag(llvm::Module::Error, "ThinLTO", uint32_t(0));
1134 if (!TheModule->getModuleFlag("EnableSplitLTOUnit"))
1135 TheModule->addModuleFlag(llvm::Module::Error, "EnableSplitLTOUnit",
1136 uint32_t(1));
1137 }
1138 if (Action == Backend_EmitBC) {
1139 MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
1140 EmitLTOSummary));
1141 } else if (Action == Backend_EmitLL) {
1142 MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,
1143 EmitLTOSummary));
1144 }
1145 }
1146
1147 if (shouldEmitUnifiedLTOModueFlag())
1148 TheModule->addModuleFlag(llvm::Module::Error, "UnifiedLTO", uint32_t(1));
1149 }
1150
1151 // FIXME: This should eventually be replaced by a first-class driver option.
1152 // This should be done for both clang and flang simultaneously.
1153 // Print a textual, '-passes=' compatible, representation of pipeline if
1154 // requested.
1155 if (PrintPipelinePasses) {
1156 MPM.printPipeline(outs(), [&PIC](StringRef ClassName) {
1157 auto PassName = PIC.getPassNameForClassName(ClassName);
1158 return PassName.empty() ? ClassName : PassName;
1159 });
1160 outs() << "\n";
1161 return;
1162 }
1163
1164 if (LangOpts.HIPStdPar && !LangOpts.CUDAIsDevice &&
1165 LangOpts.HIPStdParInterposeAlloc)
1166 MPM.addPass(HipStdParAllocationInterpositionPass());
1167
1168 // Now that we have all of the passes ready, run them.
1169 {
1170 PrettyStackTraceString CrashInfo("Optimizer");
1171 llvm::TimeTraceScope TimeScope("Optimizer");
1172 Timer timer;
1173 if (CI.getCodeGenOpts().TimePasses) {
1174 timer.init("optimizer", "Optimizer", CI.getTimerGroup());
1175 CI.getFrontendTimer().yieldTo(timer);
1176 }
1177 MPM.run(*TheModule, MAM);
1178 if (CI.getCodeGenOpts().TimePasses)
1179 timer.yieldTo(CI.getFrontendTimer());
1180 }
1181}
1182
1183void EmitAssemblyHelper::RunCodegenPipeline(
1184 BackendAction Action, std::unique_ptr<raw_pwrite_stream> &OS,
1185 std::unique_ptr<llvm::ToolOutputFile> &DwoOS) {
1186 // We still use the legacy PM to run the codegen pipeline since the new PM
1187 // does not work with the codegen pipeline.
1188 // FIXME: make the new PM work with the codegen pipeline.
1189 legacy::PassManager CodeGenPasses;
1190
1191 // Append any output we need to the pass manager.
1192 switch (Action) {
1194 case Backend_EmitMCNull:
1195 case Backend_EmitObj:
1196 CodeGenPasses.add(
1197 createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
1198 if (!CodeGenOpts.SplitDwarfOutput.empty()) {
1199 DwoOS = openOutputFile(CodeGenOpts.SplitDwarfOutput);
1200 if (!DwoOS)
1201 return;
1202 }
1203 if (!AddEmitPasses(CodeGenPasses, Action, *OS,
1204 DwoOS ? &DwoOS->os() : nullptr))
1205 // FIXME: Should we handle this error differently?
1206 return;
1207 break;
1208 default:
1209 return;
1210 }
1211
1212 // If -print-pipeline-passes is requested, don't run the legacy pass manager.
1213 // FIXME: when codegen is switched to use the new pass manager, it should also
1214 // emit pass names here.
1215 if (PrintPipelinePasses) {
1216 return;
1217 }
1218
1219 {
1220 PrettyStackTraceString CrashInfo("Code generation");
1221 llvm::TimeTraceScope TimeScope("CodeGenPasses");
1222 Timer timer;
1223 if (CI.getCodeGenOpts().TimePasses) {
1224 timer.init("codegen", "Machine code generation", CI.getTimerGroup());
1225 CI.getFrontendTimer().yieldTo(timer);
1226 }
1227 CodeGenPasses.run(*TheModule);
1228 if (CI.getCodeGenOpts().TimePasses)
1229 timer.yieldTo(CI.getFrontendTimer());
1230 }
1231}
1232
1233void EmitAssemblyHelper::emitAssembly(BackendAction Action,
1234 std::unique_ptr<raw_pwrite_stream> OS,
1235 BackendConsumer *BC) {
1236 setCommandLineOpts(CodeGenOpts);
1237
1238 bool RequiresCodeGen = actionRequiresCodeGen(Action);
1239 CreateTargetMachine(RequiresCodeGen);
1240
1241 if (RequiresCodeGen && !TM)
1242 return;
1243 if (TM)
1244 TheModule->setDataLayout(TM->createDataLayout());
1245
1246 // Before executing passes, print the final values of the LLVM options.
1247 cl::PrintOptionValues();
1248
1249 std::unique_ptr<llvm::ToolOutputFile> ThinLinkOS, DwoOS;
1250 RunOptimizationPipeline(Action, OS, ThinLinkOS, BC);
1251 RunCodegenPipeline(Action, OS, DwoOS);
1252
1253 if (ThinLinkOS)
1254 ThinLinkOS->keep();
1255 if (DwoOS)
1256 DwoOS->keep();
1257}
1258
1259static void
1260runThinLTOBackend(CompilerInstance &CI, ModuleSummaryIndex *CombinedIndex,
1261 llvm::Module *M, std::unique_ptr<raw_pwrite_stream> OS,
1262 std::string SampleProfile, std::string ProfileRemapping,
1263 BackendAction Action) {
1264 DiagnosticsEngine &Diags = CI.getDiagnostics();
1265 const auto &CGOpts = CI.getCodeGenOpts();
1266 const auto &TOpts = CI.getTargetOpts();
1267 DenseMap<StringRef, DenseMap<GlobalValue::GUID, GlobalValueSummary *>>
1268 ModuleToDefinedGVSummaries;
1269 CombinedIndex->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
1270
1271 setCommandLineOpts(CGOpts);
1272
1273 // We can simply import the values mentioned in the combined index, since
1274 // we should only invoke this using the individual indexes written out
1275 // via a WriteIndexesThinBackend.
1276 FunctionImporter::ImportIDTable ImportIDs;
1277 FunctionImporter::ImportMapTy ImportList(ImportIDs);
1278 if (!lto::initImportList(*M, *CombinedIndex, ImportList))
1279 return;
1280
1281 auto AddStream = [&](size_t Task, const Twine &ModuleName) {
1282 return std::make_unique<CachedFileStream>(std::move(OS),
1283 CGOpts.ObjectFilenameForDebug);
1284 };
1285 lto::Config Conf;
1286 if (CGOpts.SaveTempsFilePrefix != "") {
1287 if (Error E = Conf.addSaveTemps(CGOpts.SaveTempsFilePrefix + ".",
1288 /* UseInputModulePath */ false)) {
1289 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
1290 errs() << "Error setting up ThinLTO save-temps: " << EIB.message()
1291 << '\n';
1292 });
1293 }
1294 }
1295 Conf.CPU = TOpts.CPU;
1296 Conf.CodeModel = getCodeModel(CGOpts);
1297 Conf.MAttrs = TOpts.Features;
1298 Conf.RelocModel = CGOpts.RelocationModel;
1299 std::optional<CodeGenOptLevel> OptLevelOrNone =
1300 CodeGenOpt::getLevel(CGOpts.OptimizationLevel);
1301 assert(OptLevelOrNone && "Invalid optimization level!");
1302 Conf.CGOptLevel = *OptLevelOrNone;
1303 Conf.OptLevel = CGOpts.OptimizationLevel;
1304 initTargetOptions(CI, Diags, Conf.Options);
1305 Conf.SampleProfile = std::move(SampleProfile);
1306 Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops;
1307 // For historical reasons, loop interleaving is set to mirror setting for loop
1308 // unrolling.
1309 Conf.PTO.LoopInterleaving = CGOpts.UnrollLoops;
1310 Conf.PTO.LoopVectorization = CGOpts.VectorizeLoop;
1311 Conf.PTO.SLPVectorization = CGOpts.VectorizeSLP;
1312 // Only enable CGProfilePass when using integrated assembler, since
1313 // non-integrated assemblers don't recognize .cgprofile section.
1314 Conf.PTO.CallGraphProfile = !CGOpts.DisableIntegratedAS;
1315
1316 // Context sensitive profile.
1317 if (CGOpts.hasProfileCSIRInstr()) {
1318 Conf.RunCSIRInstr = true;
1319 Conf.CSIRProfile = std::move(CGOpts.InstrProfileOutput);
1320 } else if (CGOpts.hasProfileCSIRUse()) {
1321 Conf.RunCSIRInstr = false;
1322 Conf.CSIRProfile = std::move(CGOpts.ProfileInstrumentUsePath);
1323 }
1324
1325 Conf.ProfileRemapping = std::move(ProfileRemapping);
1326 Conf.DebugPassManager = CGOpts.DebugPassManager;
1327 Conf.VerifyEach = CGOpts.VerifyEach;
1328 Conf.RemarksWithHotness = CGOpts.DiagnosticsWithHotness;
1329 Conf.RemarksFilename = CGOpts.OptRecordFile;
1330 Conf.RemarksPasses = CGOpts.OptRecordPasses;
1331 Conf.RemarksFormat = CGOpts.OptRecordFormat;
1332 Conf.SplitDwarfFile = CGOpts.SplitDwarfFile;
1333 Conf.SplitDwarfOutput = CGOpts.SplitDwarfOutput;
1334 switch (Action) {
1336 Conf.PreCodeGenModuleHook = [](size_t Task, const llvm::Module &Mod) {
1337 return false;
1338 };
1339 break;
1340 case Backend_EmitLL:
1341 Conf.PreCodeGenModuleHook = [&](size_t Task, const llvm::Module &Mod) {
1342 M->print(*OS, nullptr, CGOpts.EmitLLVMUseLists);
1343 return false;
1344 };
1345 break;
1346 case Backend_EmitBC:
1347 Conf.PreCodeGenModuleHook = [&](size_t Task, const llvm::Module &Mod) {
1348 WriteBitcodeToFile(*M, *OS, CGOpts.EmitLLVMUseLists);
1349 return false;
1350 };
1351 break;
1352 default:
1353 Conf.CGFileType = getCodeGenFileType(Action);
1354 break;
1355 }
1356 if (Error E =
1357 thinBackend(Conf, -1, AddStream, *M, *CombinedIndex, ImportList,
1358 ModuleToDefinedGVSummaries[M->getModuleIdentifier()],
1359 /*ModuleMap=*/nullptr, Conf.CodeGenOnly,
1360 /*IRAddStream=*/nullptr, CGOpts.CmdArgs)) {
1361 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
1362 errs() << "Error running ThinLTO backend: " << EIB.message() << '\n';
1363 });
1364 }
1365}
1366
1368 llvm::Module *M, BackendAction Action,
1370 std::unique_ptr<raw_pwrite_stream> OS,
1371 BackendConsumer *BC) {
1372 llvm::TimeTraceScope TimeScope("Backend");
1373 DiagnosticsEngine &Diags = CI.getDiagnostics();
1374 const auto &CGOpts = CI.getCodeGenOpts();
1375
1376 std::unique_ptr<llvm::Module> EmptyModule;
1377 if (!CGOpts.ThinLTOIndexFile.empty()) {
1378 // If we are performing a ThinLTO importing compile, load the function index
1379 // into memory and pass it into runThinLTOBackend, which will run the
1380 // function importer and invoke LTO passes.
1381 std::unique_ptr<ModuleSummaryIndex> CombinedIndex;
1382 if (Error E = llvm::getModuleSummaryIndexForFile(
1383 CGOpts.ThinLTOIndexFile,
1384 /*IgnoreEmptyThinLTOIndexFile*/ true)
1385 .moveInto(CombinedIndex)) {
1386 logAllUnhandledErrors(std::move(E), errs(),
1387 "Error loading index file '" +
1388 CGOpts.ThinLTOIndexFile + "': ");
1389 return;
1390 }
1391
1392 // A null CombinedIndex means we should skip ThinLTO compilation
1393 // (LLVM will optionally ignore empty index files, returning null instead
1394 // of an error).
1395 if (CombinedIndex) {
1396 if (!CombinedIndex->skipModuleByDistributedBackend()) {
1397 runThinLTOBackend(CI, CombinedIndex.get(), M, std::move(OS),
1398 CGOpts.SampleProfileFile, CGOpts.ProfileRemappingFile,
1399 Action);
1400 return;
1401 }
1402 // Distributed indexing detected that nothing from the module is needed
1403 // for the final linking. So we can skip the compilation. We sill need to
1404 // output an empty object file to make sure that a linker does not fail
1405 // trying to read it. Also for some features, like CFI, we must skip
1406 // the compilation as CombinedIndex does not contain all required
1407 // information.
1408 EmptyModule = std::make_unique<llvm::Module>("empty", M->getContext());
1409 EmptyModule->setTargetTriple(M->getTargetTriple());
1410 M = EmptyModule.get();
1411 }
1412 }
1413
1414 EmitAssemblyHelper AsmHelper(CI, M, VFS);
1415 AsmHelper.emitAssembly(Action, std::move(OS), BC);
1416
1417 // Verify clang's TargetInfo DataLayout against the LLVM TargetMachine's
1418 // DataLayout.
1419 if (AsmHelper.TM) {
1420 std::string DLDesc = M->getDataLayout().getStringRepresentation();
1421 if (DLDesc != TDesc) {
1422 unsigned DiagID = Diags.getCustomDiagID(
1423 DiagnosticsEngine::Error, "backend data layout '%0' does not match "
1424 "expected target description '%1'");
1425 Diags.Report(DiagID) << DLDesc << TDesc;
1426 }
1427 }
1428}
1429
1430// With -fembed-bitcode, save a copy of the llvm IR as data in the
1431// __LLVM,__bitcode section.
1432void clang::EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,
1433 llvm::MemoryBufferRef Buf) {
1434 if (CGOpts.getEmbedBitcode() == CodeGenOptions::Embed_Off)
1435 return;
1436 llvm::embedBitcodeInModule(
1437 *M, Buf, CGOpts.getEmbedBitcode() != CodeGenOptions::Embed_Marker,
1438 CGOpts.getEmbedBitcode() != CodeGenOptions::Embed_Bitcode,
1439 CGOpts.CmdArgs);
1440}
1441
1442void clang::EmbedObject(llvm::Module *M, const CodeGenOptions &CGOpts,
1443 DiagnosticsEngine &Diags) {
1444 if (CGOpts.OffloadObjects.empty())
1445 return;
1446
1447 for (StringRef OffloadObject : CGOpts.OffloadObjects) {
1448 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ObjectOrErr =
1449 llvm::MemoryBuffer::getFileOrSTDIN(OffloadObject);
1450 if (ObjectOrErr.getError()) {
1451 auto DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
1452 "could not open '%0' for embedding");
1453 Diags.Report(DiagID) << OffloadObject;
1454 return;
1455 }
1456
1457 llvm::embedBufferInModule(*M, **ObjectOrErr, ".llvm.offloading",
1458 Align(object::OffloadBinary::getAlignment()));
1459 }
1460}
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 void runThinLTOBackend(CompilerInstance &CI, ModuleSummaryIndex *CombinedIndex, llvm::Module *M, std::unique_ptr< raw_pwrite_stream > OS, std::string SampleProfile, std::string ProfileRemapping, BackendAction Action)
static SanitizerBinaryMetadataOptions getSanitizerBinaryMetadataOptions(const CodeGenOptions &CGOpts)
static std::optional< GCOVOptions > getGCOVOptions(const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts)
static bool initTargetOptions(const CompilerInstance &CI, DiagnosticsEngine &Diags, llvm::TargetOptions &Options)
static void addKCFIPass(const Triple &TargetTriple, const LangOptions &LangOpts, PassBuilder &PB)
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 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::vector< std::string > SanitizeCoverageAllowlistFiles
Path to allowlist file specifying which objects (files, functions) should exclusively be instrumented...
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.
SanitizerMaskCutoffs SanitizeSkipHotCutoffs
Set of thresholds in a range [0.0, 1.0]: the top hottest code responsible for the given fraction of P...
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::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.
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
llvm::TimerGroup & getTimerGroup() const
llvm::Timer & getFrontendTimer() const
TargetOptions & getTargetOpts()
HeaderSearchOptions & getHeaderSearchOpts()
LangOptions & getLangOpts()
CodeGenOptions & getCodeGenOpts()
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
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...
@ 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(CompilerInstance &CI, StringRef TDesc, llvm::Module *M, BackendAction Action, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, std::unique_ptr< raw_pwrite_stream > OS, BackendConsumer *BC=nullptr)
llvm::cl::opt< bool > ClSanitizeGuardChecks
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
BackendAction
Definition: BackendUtil.h:33
@ Backend_EmitAssembly
Emit native assembly files.
Definition: BackendUtil.h:34
@ Backend_EmitLL
Emit human-readable LLVM assembly.
Definition: BackendUtil.h:36
@ Backend_EmitBC
Emit LLVM bitcode files.
Definition: BackendUtil.h:35
@ Backend_EmitObj
Emit native object files.
Definition: BackendUtil.h:39
@ Backend_EmitMCNull
Run CodeGen, but don't emit anything.
Definition: BackendUtil.h:38
@ Backend_EmitNothing
Don't emit anything (benchmarking mode)
Definition: BackendUtil.h:37
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:169