clang 21.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, CodeGenOptions &CGOpts,
210 llvm::Module *M,
212 : CI(CI), Diags(CI.getDiagnostics()), CodeGenOpts(CGOpts),
213 TargetOpts(CI.getTargetOpts()), LangOpts(CI.getLangOpts()),
214 TheModule(M), VFS(std::move(VFS)),
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 DiagnosticsEngine &Diags,
356 llvm::TargetOptions &Options) {
357 const auto &CodeGenOpts = CI.getCodeGenOpts();
358 const auto &TargetOpts = CI.getTargetOpts();
359 const auto &LangOpts = CI.getLangOpts();
360 const auto &HSOpts = CI.getHeaderSearchOpts();
361 switch (LangOpts.getThreadModel()) {
362 case LangOptions::ThreadModelKind::POSIX:
363 Options.ThreadModel = llvm::ThreadModel::POSIX;
364 break;
365 case LangOptions::ThreadModelKind::Single:
366 Options.ThreadModel = llvm::ThreadModel::Single;
367 break;
368 }
369
370 // Set float ABI type.
371 assert((CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp" ||
372 CodeGenOpts.FloatABI == "hard" || CodeGenOpts.FloatABI.empty()) &&
373 "Invalid Floating Point ABI!");
374 Options.FloatABIType =
375 llvm::StringSwitch<llvm::FloatABI::ABIType>(CodeGenOpts.FloatABI)
376 .Case("soft", llvm::FloatABI::Soft)
377 .Case("softfp", llvm::FloatABI::Soft)
378 .Case("hard", llvm::FloatABI::Hard)
379 .Default(llvm::FloatABI::Default);
380
381 // Set FP fusion mode.
382 switch (LangOpts.getDefaultFPContractMode()) {
383 case LangOptions::FPM_Off:
384 // Preserve any contraction performed by the front-end. (Strict performs
385 // splitting of the muladd intrinsic in the backend.)
386 Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
387 break;
388 case LangOptions::FPM_On:
389 case LangOptions::FPM_FastHonorPragmas:
390 Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
391 break;
392 case LangOptions::FPM_Fast:
393 Options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
394 break;
395 }
396
397 Options.BinutilsVersion =
398 llvm::TargetMachine::parseBinutilsVersion(CodeGenOpts.BinutilsVersion);
399 Options.UseInitArray = CodeGenOpts.UseInitArray;
400 Options.DisableIntegratedAS = CodeGenOpts.DisableIntegratedAS;
401
402 // Set EABI version.
403 Options.EABIVersion = TargetOpts.EABIVersion;
404
405 if (LangOpts.hasSjLjExceptions())
406 Options.ExceptionModel = llvm::ExceptionHandling::SjLj;
407 if (LangOpts.hasSEHExceptions())
408 Options.ExceptionModel = llvm::ExceptionHandling::WinEH;
409 if (LangOpts.hasDWARFExceptions())
410 Options.ExceptionModel = llvm::ExceptionHandling::DwarfCFI;
411 if (LangOpts.hasWasmExceptions())
412 Options.ExceptionModel = llvm::ExceptionHandling::Wasm;
413
414 Options.NoInfsFPMath = LangOpts.NoHonorInfs;
415 Options.NoNaNsFPMath = LangOpts.NoHonorNaNs;
416 Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
417 Options.UnsafeFPMath = LangOpts.AllowFPReassoc && LangOpts.AllowRecip &&
418 LangOpts.NoSignedZero && LangOpts.ApproxFunc &&
419 (LangOpts.getDefaultFPContractMode() ==
420 LangOptions::FPModeKind::FPM_Fast ||
421 LangOpts.getDefaultFPContractMode() ==
422 LangOptions::FPModeKind::FPM_FastHonorPragmas);
423 Options.ApproxFuncFPMath = LangOpts.ApproxFunc;
424
425 Options.BBAddrMap = CodeGenOpts.BBAddrMap;
426 Options.BBSections =
427 llvm::StringSwitch<llvm::BasicBlockSection>(CodeGenOpts.BBSections)
428 .Case("all", llvm::BasicBlockSection::All)
429 .StartsWith("list=", llvm::BasicBlockSection::List)
430 .Case("none", llvm::BasicBlockSection::None)
431 .Default(llvm::BasicBlockSection::None);
432
433 if (Options.BBSections == llvm::BasicBlockSection::List) {
434 ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
435 MemoryBuffer::getFile(CodeGenOpts.BBSections.substr(5));
436 if (!MBOrErr) {
437 Diags.Report(diag::err_fe_unable_to_load_basic_block_sections_file)
438 << MBOrErr.getError().message();
439 return false;
440 }
441 Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
442 }
443
444 Options.EnableMachineFunctionSplitter = CodeGenOpts.SplitMachineFunctions;
445 Options.FunctionSections = CodeGenOpts.FunctionSections;
446 Options.DataSections = CodeGenOpts.DataSections;
447 Options.IgnoreXCOFFVisibility = LangOpts.IgnoreXCOFFVisibility;
448 Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames;
449 Options.UniqueBasicBlockSectionNames =
450 CodeGenOpts.UniqueBasicBlockSectionNames;
451 Options.SeparateNamedSections = CodeGenOpts.SeparateNamedSections;
452 Options.TLSSize = CodeGenOpts.TLSSize;
453 Options.EnableTLSDESC = CodeGenOpts.EnableTLSDESC;
454 Options.EmulatedTLS = CodeGenOpts.EmulatedTLS;
455 Options.DebuggerTuning = CodeGenOpts.getDebuggerTuning();
456 Options.EmitStackSizeSection = CodeGenOpts.StackSizeSection;
457 Options.StackUsageOutput = CodeGenOpts.StackUsageOutput;
458 Options.EmitAddrsig = CodeGenOpts.Addrsig;
459 Options.ForceDwarfFrameSection = CodeGenOpts.ForceDwarfFrameSection;
460 Options.EmitCallSiteInfo = CodeGenOpts.EmitCallSiteInfo;
461 Options.EnableAIXExtendedAltivecABI = LangOpts.EnableAIXExtendedAltivecABI;
462 Options.XRayFunctionIndex = CodeGenOpts.XRayFunctionIndex;
463 Options.LoopAlignment = CodeGenOpts.LoopAlignment;
464 Options.DebugStrictDwarf = CodeGenOpts.DebugStrictDwarf;
465 Options.ObjectFilenameForDebug = CodeGenOpts.ObjectFilenameForDebug;
466 Options.Hotpatch = CodeGenOpts.HotPatch;
467 Options.JMCInstrument = CodeGenOpts.JMCInstrument;
468 Options.XCOFFReadOnlyPointers = CodeGenOpts.XCOFFReadOnlyPointers;
469
470 switch (CodeGenOpts.getSwiftAsyncFramePointer()) {
471 case CodeGenOptions::SwiftAsyncFramePointerKind::Auto:
472 Options.SwiftAsyncFramePointer =
473 SwiftAsyncFramePointerMode::DeploymentBased;
474 break;
475
476 case CodeGenOptions::SwiftAsyncFramePointerKind::Always:
477 Options.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Always;
478 break;
479
480 case CodeGenOptions::SwiftAsyncFramePointerKind::Never:
481 Options.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Never;
482 break;
483 }
484
485 Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile;
486 Options.MCOptions.EmitDwarfUnwind = CodeGenOpts.getEmitDwarfUnwind();
487 Options.MCOptions.EmitCompactUnwindNonCanonical =
488 CodeGenOpts.EmitCompactUnwindNonCanonical;
489 Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
490 Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
491 Options.MCOptions.MCUseDwarfDirectory =
492 CodeGenOpts.NoDwarfDirectoryAsm
493 ? llvm::MCTargetOptions::DisableDwarfDirectory
494 : llvm::MCTargetOptions::EnableDwarfDirectory;
495 Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack;
496 Options.MCOptions.MCIncrementalLinkerCompatible =
497 CodeGenOpts.IncrementalLinkerCompatible;
498 Options.MCOptions.MCFatalWarnings = CodeGenOpts.FatalWarnings;
499 Options.MCOptions.MCNoWarn = CodeGenOpts.NoWarn;
500 Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose;
501 Options.MCOptions.Dwarf64 = CodeGenOpts.Dwarf64;
502 Options.MCOptions.PreserveAsmComments = CodeGenOpts.PreserveAsmComments;
503 Options.MCOptions.Crel = CodeGenOpts.Crel;
504 Options.MCOptions.ImplicitMapSyms = CodeGenOpts.ImplicitMapSyms;
505 Options.MCOptions.X86RelaxRelocations = CodeGenOpts.X86RelaxRelocations;
506 Options.MCOptions.CompressDebugSections =
507 CodeGenOpts.getCompressDebugSections();
508 if (CodeGenOpts.OutputAsmVariant != 3) // 3 (default): not specified
509 Options.MCOptions.OutputAsmVariant = CodeGenOpts.OutputAsmVariant;
510 Options.MCOptions.ABIName = TargetOpts.ABI;
511 for (const auto &Entry : HSOpts.UserEntries)
512 if (!Entry.IsFramework &&
513 (Entry.Group == frontend::IncludeDirGroup::Quoted ||
514 Entry.Group == frontend::IncludeDirGroup::Angled ||
515 Entry.Group == frontend::IncludeDirGroup::System))
516 Options.MCOptions.IASSearchPaths.push_back(
517 Entry.IgnoreSysRoot ? Entry.Path : HSOpts.Sysroot + Entry.Path);
518 Options.MCOptions.Argv0 = CodeGenOpts.Argv0 ? CodeGenOpts.Argv0 : "";
519 Options.MCOptions.CommandlineArgs = flattenClangCommandLine(
520 CodeGenOpts.CommandLineArgs, CodeGenOpts.MainFileName);
521 Options.MCOptions.AsSecureLogFile = CodeGenOpts.AsSecureLogFile;
522 Options.MCOptions.PPCUseFullRegisterNames =
523 CodeGenOpts.PPCUseFullRegisterNames;
524 Options.MisExpect = CodeGenOpts.MisExpect;
525
526 return true;
527}
528
529static std::optional<GCOVOptions>
530getGCOVOptions(const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts) {
531 if (CodeGenOpts.CoverageNotesFile.empty() &&
532 CodeGenOpts.CoverageDataFile.empty())
533 return std::nullopt;
534 // Not using 'GCOVOptions::getDefault' allows us to avoid exiting if
535 // LLVM's -default-gcov-version flag is set to something invalid.
536 GCOVOptions Options;
537 Options.EmitNotes = !CodeGenOpts.CoverageNotesFile.empty();
538 Options.EmitData = !CodeGenOpts.CoverageDataFile.empty();
539 llvm::copy(CodeGenOpts.CoverageVersion, std::begin(Options.Version));
540 Options.NoRedZone = CodeGenOpts.DisableRedZone;
541 Options.Filter = CodeGenOpts.ProfileFilterFiles;
542 Options.Exclude = CodeGenOpts.ProfileExcludeFiles;
543 Options.Atomic = CodeGenOpts.AtomicProfileUpdate;
544 return Options;
545}
546
547static std::optional<InstrProfOptions>
549 const LangOptions &LangOpts) {
550 if (!CodeGenOpts.hasProfileClangInstr())
551 return std::nullopt;
552 InstrProfOptions Options;
553 Options.NoRedZone = CodeGenOpts.DisableRedZone;
554 Options.InstrProfileOutput = CodeGenOpts.InstrProfileOutput;
555 Options.Atomic = CodeGenOpts.AtomicProfileUpdate;
556 return Options;
557}
558
559static void setCommandLineOpts(const CodeGenOptions &CodeGenOpts) {
561 BackendArgs.push_back("clang"); // Fake program name.
562 if (!CodeGenOpts.DebugPass.empty()) {
563 BackendArgs.push_back("-debug-pass");
564 BackendArgs.push_back(CodeGenOpts.DebugPass.c_str());
565 }
566 if (!CodeGenOpts.LimitFloatPrecision.empty()) {
567 BackendArgs.push_back("-limit-float-precision");
568 BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str());
569 }
570 // Check for the default "clang" invocation that won't set any cl::opt values.
571 // Skip trying to parse the command line invocation to avoid the issues
572 // described below.
573 if (BackendArgs.size() == 1)
574 return;
575 BackendArgs.push_back(nullptr);
576 // FIXME: The command line parser below is not thread-safe and shares a global
577 // state, so this call might crash or overwrite the options of another Clang
578 // instance in the same process.
579 llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
580 BackendArgs.data());
581}
582
583void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
584 // Create the TargetMachine for generating code.
585 std::string Error;
586 std::string Triple = TheModule->getTargetTriple();
587 const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
588 if (!TheTarget) {
589 if (MustCreateTM)
590 Diags.Report(diag::err_fe_unable_to_create_target) << Error;
591 return;
592 }
593
594 std::optional<llvm::CodeModel::Model> CM = getCodeModel(CodeGenOpts);
595 std::string FeaturesStr =
596 llvm::join(TargetOpts.Features.begin(), TargetOpts.Features.end(), ",");
597 llvm::Reloc::Model RM = CodeGenOpts.RelocationModel;
598 std::optional<CodeGenOptLevel> OptLevelOrNone =
599 CodeGenOpt::getLevel(CodeGenOpts.OptimizationLevel);
600 assert(OptLevelOrNone && "Invalid optimization level!");
601 CodeGenOptLevel OptLevel = *OptLevelOrNone;
602
603 llvm::TargetOptions Options;
604 if (!initTargetOptions(CI, Diags, Options))
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(TypeSanitizerPass());
741
742 if (LangOpts.Sanitize.has(SanitizerKind::NumericalStability))
743 MPM.addPass(NumericalStabilitySanitizerPass());
744
745 if (LangOpts.Sanitize.has(SanitizerKind::Realtime))
746 MPM.addPass(RealtimeSanitizerPass());
747
748 auto ASanPass = [&](SanitizerMask Mask, bool CompileKernel) {
749 if (LangOpts.Sanitize.has(Mask)) {
750 bool UseGlobalGC = asanUseGlobalsGC(TargetTriple, CodeGenOpts);
751 bool UseOdrIndicator = CodeGenOpts.SanitizeAddressUseOdrIndicator;
752 llvm::AsanDtorKind DestructorKind =
753 CodeGenOpts.getSanitizeAddressDtor();
754 AddressSanitizerOptions Opts;
755 Opts.CompileKernel = CompileKernel;
756 Opts.Recover = CodeGenOpts.SanitizeRecover.has(Mask);
757 Opts.UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope;
758 Opts.UseAfterReturn = CodeGenOpts.getSanitizeAddressUseAfterReturn();
759 MPM.addPass(AddressSanitizerPass(Opts, UseGlobalGC, UseOdrIndicator,
760 DestructorKind));
761 }
762 };
763 ASanPass(SanitizerKind::Address, false);
764 ASanPass(SanitizerKind::KernelAddress, true);
765
766 auto HWASanPass = [&](SanitizerMask Mask, bool CompileKernel) {
767 if (LangOpts.Sanitize.has(Mask)) {
768 bool Recover = CodeGenOpts.SanitizeRecover.has(Mask);
769 MPM.addPass(HWAddressSanitizerPass(
770 {CompileKernel, Recover,
771 /*DisableOptimization=*/CodeGenOpts.OptimizationLevel == 0}));
772 }
773 };
774 HWASanPass(SanitizerKind::HWAddress, false);
775 HWASanPass(SanitizerKind::KernelHWAddress, true);
776
777 if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) {
778 MPM.addPass(DataFlowSanitizerPass(LangOpts.NoSanitizeFiles));
779 }
780 };
782 PB.registerOptimizerEarlyEPCallback(
783 [SanitizersCallback](ModulePassManager &MPM, OptimizationLevel Level,
784 ThinOrFullLTOPhase Phase) {
785 ModulePassManager NewMPM;
786 SanitizersCallback(NewMPM, Level, Phase);
787 if (!NewMPM.isEmpty()) {
788 // Sanitizers can abandon<GlobalsAA>.
789 NewMPM.addPass(RequireAnalysisPass<GlobalsAA, llvm::Module>());
790 MPM.addPass(std::move(NewMPM));
791 }
792 });
793 } else {
794 // LastEP does not need GlobalsAA.
795 PB.registerOptimizerLastEPCallback(SanitizersCallback);
796 }
797
798 // SanitizeSkipHotCutoffs: doubles with range [0, 1]
799 // Opts.cutoffs: unsigned ints with range [0, 1000000]
800 auto ScaledCutoffs = CodeGenOpts.SanitizeSkipHotCutoffs.getAllScaled(1000000);
801
802 // TODO: remove IsRequested()
803 if (LowerAllowCheckPass::IsRequested() || ScaledCutoffs.has_value()) {
804 // We want to call it after inline, which is about OptimizerEarlyEPCallback.
805 PB.registerOptimizerEarlyEPCallback(
806 [ScaledCutoffs](ModulePassManager &MPM, OptimizationLevel Level,
807 ThinOrFullLTOPhase Phase) {
808 LowerAllowCheckPass::Options Opts;
809 // TODO: after removing IsRequested(), make this unconditional
810 if (ScaledCutoffs.has_value())
811 Opts.cutoffs = ScaledCutoffs.value();
812 MPM.addPass(
813 createModuleToFunctionPassAdaptor(LowerAllowCheckPass(Opts)));
814 });
815 }
816}
817
818void EmitAssemblyHelper::RunOptimizationPipeline(
819 BackendAction Action, std::unique_ptr<raw_pwrite_stream> &OS,
820 std::unique_ptr<llvm::ToolOutputFile> &ThinLinkOS, BackendConsumer *BC) {
821 std::optional<PGOOptions> PGOOpt;
822
823 if (CodeGenOpts.hasProfileIRInstr())
824 // -fprofile-generate.
825 PGOOpt = PGOOptions(
826 CodeGenOpts.InstrProfileOutput.empty() ? getDefaultProfileGenName()
827 : CodeGenOpts.InstrProfileOutput,
828 "", "", CodeGenOpts.MemoryProfileUsePath, nullptr, PGOOptions::IRInstr,
829 PGOOptions::NoCSAction, ClPGOColdFuncAttr,
830 CodeGenOpts.DebugInfoForProfiling,
831 /*PseudoProbeForProfiling=*/false, CodeGenOpts.AtomicProfileUpdate);
832 else if (CodeGenOpts.hasProfileIRUse()) {
833 // -fprofile-use.
834 auto CSAction = CodeGenOpts.hasProfileCSIRUse() ? PGOOptions::CSIRUse
835 : PGOOptions::NoCSAction;
836 PGOOpt = PGOOptions(CodeGenOpts.ProfileInstrumentUsePath, "",
837 CodeGenOpts.ProfileRemappingFile,
838 CodeGenOpts.MemoryProfileUsePath, VFS,
839 PGOOptions::IRUse, CSAction, ClPGOColdFuncAttr,
840 CodeGenOpts.DebugInfoForProfiling);
841 } else if (!CodeGenOpts.SampleProfileFile.empty())
842 // -fprofile-sample-use
843 PGOOpt = PGOOptions(
844 CodeGenOpts.SampleProfileFile, "", CodeGenOpts.ProfileRemappingFile,
845 CodeGenOpts.MemoryProfileUsePath, VFS, PGOOptions::SampleUse,
846 PGOOptions::NoCSAction, ClPGOColdFuncAttr,
847 CodeGenOpts.DebugInfoForProfiling, CodeGenOpts.PseudoProbeForProfiling);
848 else if (!CodeGenOpts.MemoryProfileUsePath.empty())
849 // -fmemory-profile-use (without any of the above options)
850 PGOOpt = PGOOptions("", "", "", CodeGenOpts.MemoryProfileUsePath, VFS,
851 PGOOptions::NoAction, PGOOptions::NoCSAction,
852 ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling);
853 else if (CodeGenOpts.PseudoProbeForProfiling)
854 // -fpseudo-probe-for-profiling
855 PGOOpt =
856 PGOOptions("", "", "", /*MemoryProfile=*/"", nullptr,
857 PGOOptions::NoAction, PGOOptions::NoCSAction,
858 ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling, true);
859 else if (CodeGenOpts.DebugInfoForProfiling)
860 // -fdebug-info-for-profiling
861 PGOOpt = PGOOptions("", "", "", /*MemoryProfile=*/"", nullptr,
862 PGOOptions::NoAction, PGOOptions::NoCSAction,
863 ClPGOColdFuncAttr, true);
864
865 // Check to see if we want to generate a CS profile.
866 if (CodeGenOpts.hasProfileCSIRInstr()) {
867 assert(!CodeGenOpts.hasProfileCSIRUse() &&
868 "Cannot have both CSProfileUse pass and CSProfileGen pass at "
869 "the same time");
870 if (PGOOpt) {
871 assert(PGOOpt->Action != PGOOptions::IRInstr &&
872 PGOOpt->Action != PGOOptions::SampleUse &&
873 "Cannot run CSProfileGen pass with ProfileGen or SampleUse "
874 " pass");
875 PGOOpt->CSProfileGenFile = CodeGenOpts.InstrProfileOutput.empty()
876 ? getDefaultProfileGenName()
877 : CodeGenOpts.InstrProfileOutput;
878 PGOOpt->CSAction = PGOOptions::CSIRInstr;
879 } else
880 PGOOpt = PGOOptions("",
881 CodeGenOpts.InstrProfileOutput.empty()
882 ? getDefaultProfileGenName()
883 : CodeGenOpts.InstrProfileOutput,
884 "", /*MemoryProfile=*/"", nullptr,
885 PGOOptions::NoAction, PGOOptions::CSIRInstr,
886 ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling);
887 }
888 if (TM)
889 TM->setPGOOption(PGOOpt);
890
891 PipelineTuningOptions PTO;
892 PTO.LoopUnrolling = CodeGenOpts.UnrollLoops;
893 // For historical reasons, loop interleaving is set to mirror setting for loop
894 // unrolling.
895 PTO.LoopInterleaving = CodeGenOpts.UnrollLoops;
896 PTO.LoopVectorization = CodeGenOpts.VectorizeLoop;
897 PTO.SLPVectorization = CodeGenOpts.VectorizeSLP;
898 PTO.MergeFunctions = CodeGenOpts.MergeFunctions;
899 // Only enable CGProfilePass when using integrated assembler, since
900 // non-integrated assemblers don't recognize .cgprofile section.
901 PTO.CallGraphProfile = !CodeGenOpts.DisableIntegratedAS;
902 PTO.UnifiedLTO = CodeGenOpts.UnifiedLTO;
903
904 LoopAnalysisManager LAM;
905 FunctionAnalysisManager FAM;
906 CGSCCAnalysisManager CGAM;
907 ModuleAnalysisManager MAM;
908
909 bool DebugPassStructure = CodeGenOpts.DebugPass == "Structure";
910 PassInstrumentationCallbacks PIC;
911 PrintPassOptions PrintPassOpts;
912 PrintPassOpts.Indent = DebugPassStructure;
913 PrintPassOpts.SkipAnalyses = DebugPassStructure;
914 StandardInstrumentations SI(
915 TheModule->getContext(),
916 (CodeGenOpts.DebugPassManager || DebugPassStructure),
917 CodeGenOpts.VerifyEach, PrintPassOpts);
918 SI.registerCallbacks(PIC, &MAM);
919 PassBuilder PB(TM.get(), PTO, PGOOpt, &PIC);
920
921 // Handle the assignment tracking feature options.
922 switch (CodeGenOpts.getAssignmentTrackingMode()) {
923 case CodeGenOptions::AssignmentTrackingOpts::Forced:
924 PB.registerPipelineStartEPCallback(
925 [&](ModulePassManager &MPM, OptimizationLevel Level) {
926 MPM.addPass(AssignmentTrackingPass());
927 });
928 break;
929 case CodeGenOptions::AssignmentTrackingOpts::Enabled:
930 // Disable assignment tracking in LTO builds for now as the performance
931 // cost is too high. Disable for LLDB tuning due to llvm.org/PR43126.
932 if (!CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.PrepareForLTO &&
933 CodeGenOpts.getDebuggerTuning() != llvm::DebuggerKind::LLDB) {
934 PB.registerPipelineStartEPCallback(
935 [&](ModulePassManager &MPM, OptimizationLevel Level) {
936 // Only use assignment tracking if optimisations are enabled.
937 if (Level != OptimizationLevel::O0)
938 MPM.addPass(AssignmentTrackingPass());
939 });
940 }
941 break;
942 case CodeGenOptions::AssignmentTrackingOpts::Disabled:
943 break;
944 }
945
946 // Enable verify-debuginfo-preserve-each for new PM.
947 DebugifyEachInstrumentation Debugify;
948 DebugInfoPerPass DebugInfoBeforePass;
949 if (CodeGenOpts.EnableDIPreservationVerify) {
950 Debugify.setDebugifyMode(DebugifyMode::OriginalDebugInfo);
951 Debugify.setDebugInfoBeforePass(DebugInfoBeforePass);
952
953 if (!CodeGenOpts.DIBugsReportFilePath.empty())
954 Debugify.setOrigDIVerifyBugsReportFilePath(
955 CodeGenOpts.DIBugsReportFilePath);
956 Debugify.registerCallbacks(PIC, MAM);
957 }
958 // Attempt to load pass plugins and register their callbacks with PB.
959 for (auto &PluginFN : CodeGenOpts.PassPlugins) {
960 auto PassPlugin = PassPlugin::Load(PluginFN);
961 if (PassPlugin) {
962 PassPlugin->registerPassBuilderCallbacks(PB);
963 } else {
964 Diags.Report(diag::err_fe_unable_to_load_plugin)
965 << PluginFN << toString(PassPlugin.takeError());
966 }
967 }
968 for (const auto &PassCallback : CodeGenOpts.PassBuilderCallbacks)
969 PassCallback(PB);
970#define HANDLE_EXTENSION(Ext) \
971 get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
972#include "llvm/Support/Extension.def"
973
974 // Register the target library analysis directly and give it a customized
975 // preset TLI.
976 std::unique_ptr<TargetLibraryInfoImpl> TLII(
977 llvm::driver::createTLII(TargetTriple, CodeGenOpts.getVecLib()));
978 FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
979
980 // Register all the basic analyses with the managers.
981 PB.registerModuleAnalyses(MAM);
982 PB.registerCGSCCAnalyses(CGAM);
983 PB.registerFunctionAnalyses(FAM);
984 PB.registerLoopAnalyses(LAM);
985 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
986
987 ModulePassManager MPM;
988 // Add a verifier pass, before any other passes, to catch CodeGen issues.
989 if (CodeGenOpts.VerifyModule)
990 MPM.addPass(VerifierPass());
991
992 if (!CodeGenOpts.DisableLLVMPasses) {
993 // Map our optimization levels into one of the distinct levels used to
994 // configure the pipeline.
995 OptimizationLevel Level = mapToLevel(CodeGenOpts);
996
997 const bool PrepareForThinLTO = CodeGenOpts.PrepareForThinLTO;
998 const bool PrepareForLTO = CodeGenOpts.PrepareForLTO;
999
1000 if (LangOpts.ObjCAutoRefCount) {
1001 PB.registerPipelineStartEPCallback(
1002 [](ModulePassManager &MPM, OptimizationLevel Level) {
1003 if (Level != OptimizationLevel::O0)
1004 MPM.addPass(
1005 createModuleToFunctionPassAdaptor(ObjCARCExpandPass()));
1006 });
1007 PB.registerPipelineEarlySimplificationEPCallback(
1008 [](ModulePassManager &MPM, OptimizationLevel Level,
1009 ThinOrFullLTOPhase) {
1010 if (Level != OptimizationLevel::O0)
1011 MPM.addPass(ObjCARCAPElimPass());
1012 });
1013 PB.registerScalarOptimizerLateEPCallback(
1014 [](FunctionPassManager &FPM, OptimizationLevel Level) {
1015 if (Level != OptimizationLevel::O0)
1016 FPM.addPass(ObjCARCOptPass());
1017 });
1018 }
1019
1020 // If we reached here with a non-empty index file name, then the index
1021 // file was empty and we are not performing ThinLTO backend compilation
1022 // (used in testing in a distributed build environment).
1023 bool IsThinLTOPostLink = !CodeGenOpts.ThinLTOIndexFile.empty();
1024 // If so drop any the type test assume sequences inserted for whole program
1025 // vtables so that codegen doesn't complain.
1026 if (IsThinLTOPostLink)
1027 PB.registerPipelineStartEPCallback(
1028 [](ModulePassManager &MPM, OptimizationLevel Level) {
1029 MPM.addPass(LowerTypeTestsPass(
1030 /*ExportSummary=*/nullptr,
1031 /*ImportSummary=*/nullptr,
1032 /*DropTypeTests=*/lowertypetests::DropTestKind::Assume));
1033 });
1034
1035 // Register callbacks to schedule sanitizer passes at the appropriate part
1036 // of the pipeline.
1037 if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds))
1038 PB.registerScalarOptimizerLateEPCallback([this](FunctionPassManager &FPM,
1039 OptimizationLevel Level) {
1040 BoundsCheckingPass::Options Options;
1041 if (CodeGenOpts.SanitizeSkipHotCutoffs[SanitizerKind::SO_LocalBounds] ||
1043 static_assert(SanitizerKind::SO_LocalBounds <=
1044 std::numeric_limits<
1045 decltype(Options.GuardKind)::value_type>::max(),
1046 "Update type of llvm.allow.ubsan.check to represent "
1047 "SanitizerKind::SO_LocalBounds.");
1048 Options.GuardKind = SanitizerKind::SO_LocalBounds;
1049 }
1050 Options.Merge =
1051 CodeGenOpts.SanitizeMergeHandlers.has(SanitizerKind::LocalBounds);
1052 if (!CodeGenOpts.SanitizeTrap.has(SanitizerKind::LocalBounds)) {
1053 Options.Rt = {
1054 /*MinRuntime=*/static_cast<bool>(
1055 CodeGenOpts.SanitizeMinimalRuntime),
1056 /*MayReturn=*/
1057 CodeGenOpts.SanitizeRecover.has(SanitizerKind::LocalBounds),
1058 };
1059 }
1060 FPM.addPass(BoundsCheckingPass(Options));
1061 });
1062
1063 // Don't add sanitizers if we are here from ThinLTO PostLink. That already
1064 // done on PreLink stage.
1065 if (!IsThinLTOPostLink) {
1066 addSanitizers(TargetTriple, CodeGenOpts, LangOpts, PB);
1067 addKCFIPass(TargetTriple, LangOpts, PB);
1068 }
1069
1070 if (std::optional<GCOVOptions> Options =
1071 getGCOVOptions(CodeGenOpts, LangOpts))
1072 PB.registerPipelineStartEPCallback(
1073 [Options](ModulePassManager &MPM, OptimizationLevel Level) {
1074 MPM.addPass(GCOVProfilerPass(*Options));
1075 });
1076 if (std::optional<InstrProfOptions> Options =
1077 getInstrProfOptions(CodeGenOpts, LangOpts))
1078 PB.registerPipelineStartEPCallback(
1079 [Options](ModulePassManager &MPM, OptimizationLevel Level) {
1080 MPM.addPass(InstrProfilingLoweringPass(*Options, false));
1081 });
1082
1083 // TODO: Consider passing the MemoryProfileOutput to the pass builder via
1084 // the PGOOptions, and set this up there.
1085 if (!CodeGenOpts.MemoryProfileOutput.empty()) {
1086 PB.registerOptimizerLastEPCallback([](ModulePassManager &MPM,
1087 OptimizationLevel Level,
1088 ThinOrFullLTOPhase) {
1089 MPM.addPass(createModuleToFunctionPassAdaptor(MemProfilerPass()));
1090 MPM.addPass(ModuleMemProfilerPass());
1091 });
1092 }
1093
1094 if (CodeGenOpts.FatLTO) {
1095 MPM.addPass(PB.buildFatLTODefaultPipeline(
1096 Level, PrepareForThinLTO,
1097 PrepareForThinLTO || shouldEmitRegularLTOSummary()));
1098 } else if (PrepareForThinLTO) {
1099 MPM.addPass(PB.buildThinLTOPreLinkDefaultPipeline(Level));
1100 } else if (PrepareForLTO) {
1101 MPM.addPass(PB.buildLTOPreLinkDefaultPipeline(Level));
1102 } else {
1103 MPM.addPass(PB.buildPerModuleDefaultPipeline(Level));
1104 }
1105 }
1106
1107 // Link against bitcodes supplied via the -mlink-builtin-bitcode option
1108 if (CodeGenOpts.LinkBitcodePostopt)
1109 MPM.addPass(LinkInModulesPass(BC));
1110
1111 // Add a verifier pass if requested. We don't have to do this if the action
1112 // requires code generation because there will already be a verifier pass in
1113 // the code-generation pipeline.
1114 // Since we already added a verifier pass above, this
1115 // might even not run the analysis, if previous passes caused no changes.
1116 if (!actionRequiresCodeGen(Action) && CodeGenOpts.VerifyModule)
1117 MPM.addPass(VerifierPass());
1118
1119 if (Action == Backend_EmitBC || Action == Backend_EmitLL ||
1120 CodeGenOpts.FatLTO) {
1121 if (CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.DisableLLVMPasses) {
1122 if (!TheModule->getModuleFlag("EnableSplitLTOUnit"))
1123 TheModule->addModuleFlag(llvm::Module::Error, "EnableSplitLTOUnit",
1124 CodeGenOpts.EnableSplitLTOUnit);
1125 if (Action == Backend_EmitBC) {
1126 if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) {
1127 ThinLinkOS = openOutputFile(CodeGenOpts.ThinLinkBitcodeFile);
1128 if (!ThinLinkOS)
1129 return;
1130 }
1131 MPM.addPass(ThinLTOBitcodeWriterPass(
1132 *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr));
1133 } else if (Action == Backend_EmitLL) {
1134 MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,
1135 /*EmitLTOSummary=*/true));
1136 }
1137 } else {
1138 // Emit a module summary by default for Regular LTO except for ld64
1139 // targets
1140 bool EmitLTOSummary = shouldEmitRegularLTOSummary();
1141 if (EmitLTOSummary) {
1142 if (!TheModule->getModuleFlag("ThinLTO") && !CodeGenOpts.UnifiedLTO)
1143 TheModule->addModuleFlag(llvm::Module::Error, "ThinLTO", uint32_t(0));
1144 if (!TheModule->getModuleFlag("EnableSplitLTOUnit"))
1145 TheModule->addModuleFlag(llvm::Module::Error, "EnableSplitLTOUnit",
1146 uint32_t(1));
1147 }
1148 if (Action == Backend_EmitBC) {
1149 MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
1150 EmitLTOSummary));
1151 } else if (Action == Backend_EmitLL) {
1152 MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,
1153 EmitLTOSummary));
1154 }
1155 }
1156
1157 if (shouldEmitUnifiedLTOModueFlag())
1158 TheModule->addModuleFlag(llvm::Module::Error, "UnifiedLTO", uint32_t(1));
1159 }
1160
1161 // FIXME: This should eventually be replaced by a first-class driver option.
1162 // This should be done for both clang and flang simultaneously.
1163 // Print a textual, '-passes=' compatible, representation of pipeline if
1164 // requested.
1165 if (PrintPipelinePasses) {
1166 MPM.printPipeline(outs(), [&PIC](StringRef ClassName) {
1167 auto PassName = PIC.getPassNameForClassName(ClassName);
1168 return PassName.empty() ? ClassName : PassName;
1169 });
1170 outs() << "\n";
1171 return;
1172 }
1173
1174 if (LangOpts.HIPStdPar && !LangOpts.CUDAIsDevice &&
1175 LangOpts.HIPStdParInterposeAlloc)
1176 MPM.addPass(HipStdParAllocationInterpositionPass());
1177
1178 // Now that we have all of the passes ready, run them.
1179 {
1180 PrettyStackTraceString CrashInfo("Optimizer");
1181 llvm::TimeTraceScope TimeScope("Optimizer");
1182 Timer timer;
1183 if (CI.getCodeGenOpts().TimePasses) {
1184 timer.init("optimizer", "Optimizer", CI.getTimerGroup());
1185 CI.getFrontendTimer().yieldTo(timer);
1186 }
1187 MPM.run(*TheModule, MAM);
1188 if (CI.getCodeGenOpts().TimePasses)
1189 timer.yieldTo(CI.getFrontendTimer());
1190 }
1191}
1192
1193void EmitAssemblyHelper::RunCodegenPipeline(
1194 BackendAction Action, std::unique_ptr<raw_pwrite_stream> &OS,
1195 std::unique_ptr<llvm::ToolOutputFile> &DwoOS) {
1196 // We still use the legacy PM to run the codegen pipeline since the new PM
1197 // does not work with the codegen pipeline.
1198 // FIXME: make the new PM work with the codegen pipeline.
1199 legacy::PassManager CodeGenPasses;
1200
1201 // Append any output we need to the pass manager.
1202 switch (Action) {
1204 case Backend_EmitMCNull:
1205 case Backend_EmitObj:
1206 CodeGenPasses.add(
1207 createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
1208 if (!CodeGenOpts.SplitDwarfOutput.empty()) {
1209 DwoOS = openOutputFile(CodeGenOpts.SplitDwarfOutput);
1210 if (!DwoOS)
1211 return;
1212 }
1213 if (!AddEmitPasses(CodeGenPasses, Action, *OS,
1214 DwoOS ? &DwoOS->os() : nullptr))
1215 // FIXME: Should we handle this error differently?
1216 return;
1217 break;
1218 default:
1219 return;
1220 }
1221
1222 // If -print-pipeline-passes is requested, don't run the legacy pass manager.
1223 // FIXME: when codegen is switched to use the new pass manager, it should also
1224 // emit pass names here.
1225 if (PrintPipelinePasses) {
1226 return;
1227 }
1228
1229 {
1230 PrettyStackTraceString CrashInfo("Code generation");
1231 llvm::TimeTraceScope TimeScope("CodeGenPasses");
1232 Timer timer;
1233 if (CI.getCodeGenOpts().TimePasses) {
1234 timer.init("codegen", "Machine code generation", CI.getTimerGroup());
1235 CI.getFrontendTimer().yieldTo(timer);
1236 }
1237 CodeGenPasses.run(*TheModule);
1238 if (CI.getCodeGenOpts().TimePasses)
1239 timer.yieldTo(CI.getFrontendTimer());
1240 }
1241}
1242
1243void EmitAssemblyHelper::emitAssembly(BackendAction Action,
1244 std::unique_ptr<raw_pwrite_stream> OS,
1245 BackendConsumer *BC) {
1246 setCommandLineOpts(CodeGenOpts);
1247
1248 bool RequiresCodeGen = actionRequiresCodeGen(Action);
1249 CreateTargetMachine(RequiresCodeGen);
1250
1251 if (RequiresCodeGen && !TM)
1252 return;
1253 if (TM)
1254 TheModule->setDataLayout(TM->createDataLayout());
1255
1256 // Before executing passes, print the final values of the LLVM options.
1257 cl::PrintOptionValues();
1258
1259 std::unique_ptr<llvm::ToolOutputFile> ThinLinkOS, DwoOS;
1260 RunOptimizationPipeline(Action, OS, ThinLinkOS, BC);
1261 RunCodegenPipeline(Action, OS, DwoOS);
1262
1263 if (ThinLinkOS)
1264 ThinLinkOS->keep();
1265 if (DwoOS)
1266 DwoOS->keep();
1267}
1268
1269static void
1270runThinLTOBackend(CompilerInstance &CI, ModuleSummaryIndex *CombinedIndex,
1271 llvm::Module *M, std::unique_ptr<raw_pwrite_stream> OS,
1272 std::string SampleProfile, std::string ProfileRemapping,
1273 BackendAction Action) {
1274 DiagnosticsEngine &Diags = CI.getDiagnostics();
1275 const auto &CGOpts = CI.getCodeGenOpts();
1276 const auto &TOpts = CI.getTargetOpts();
1277 DenseMap<StringRef, DenseMap<GlobalValue::GUID, GlobalValueSummary *>>
1278 ModuleToDefinedGVSummaries;
1279 CombinedIndex->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
1280
1281 setCommandLineOpts(CGOpts);
1282
1283 // We can simply import the values mentioned in the combined index, since
1284 // we should only invoke this using the individual indexes written out
1285 // via a WriteIndexesThinBackend.
1286 FunctionImporter::ImportIDTable ImportIDs;
1287 FunctionImporter::ImportMapTy ImportList(ImportIDs);
1288 if (!lto::initImportList(*M, *CombinedIndex, ImportList))
1289 return;
1290
1291 auto AddStream = [&](size_t Task, const Twine &ModuleName) {
1292 return std::make_unique<CachedFileStream>(std::move(OS),
1293 CGOpts.ObjectFilenameForDebug);
1294 };
1295 lto::Config Conf;
1296 if (CGOpts.SaveTempsFilePrefix != "") {
1297 if (Error E = Conf.addSaveTemps(CGOpts.SaveTempsFilePrefix + ".",
1298 /* UseInputModulePath */ false)) {
1299 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
1300 errs() << "Error setting up ThinLTO save-temps: " << EIB.message()
1301 << '\n';
1302 });
1303 }
1304 }
1305 Conf.CPU = TOpts.CPU;
1306 Conf.CodeModel = getCodeModel(CGOpts);
1307 Conf.MAttrs = TOpts.Features;
1308 Conf.RelocModel = CGOpts.RelocationModel;
1309 std::optional<CodeGenOptLevel> OptLevelOrNone =
1310 CodeGenOpt::getLevel(CGOpts.OptimizationLevel);
1311 assert(OptLevelOrNone && "Invalid optimization level!");
1312 Conf.CGOptLevel = *OptLevelOrNone;
1313 Conf.OptLevel = CGOpts.OptimizationLevel;
1314 initTargetOptions(CI, Diags, Conf.Options);
1315 Conf.SampleProfile = std::move(SampleProfile);
1316 Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops;
1317 // For historical reasons, loop interleaving is set to mirror setting for loop
1318 // unrolling.
1319 Conf.PTO.LoopInterleaving = CGOpts.UnrollLoops;
1320 Conf.PTO.LoopVectorization = CGOpts.VectorizeLoop;
1321 Conf.PTO.SLPVectorization = CGOpts.VectorizeSLP;
1322 // Only enable CGProfilePass when using integrated assembler, since
1323 // non-integrated assemblers don't recognize .cgprofile section.
1324 Conf.PTO.CallGraphProfile = !CGOpts.DisableIntegratedAS;
1325
1326 // Context sensitive profile.
1327 if (CGOpts.hasProfileCSIRInstr()) {
1328 Conf.RunCSIRInstr = true;
1329 Conf.CSIRProfile = std::move(CGOpts.InstrProfileOutput);
1330 } else if (CGOpts.hasProfileCSIRUse()) {
1331 Conf.RunCSIRInstr = false;
1332 Conf.CSIRProfile = std::move(CGOpts.ProfileInstrumentUsePath);
1333 }
1334
1335 Conf.ProfileRemapping = std::move(ProfileRemapping);
1336 Conf.DebugPassManager = CGOpts.DebugPassManager;
1337 Conf.VerifyEach = CGOpts.VerifyEach;
1338 Conf.RemarksWithHotness = CGOpts.DiagnosticsWithHotness;
1339 Conf.RemarksFilename = CGOpts.OptRecordFile;
1340 Conf.RemarksPasses = CGOpts.OptRecordPasses;
1341 Conf.RemarksFormat = CGOpts.OptRecordFormat;
1342 Conf.SplitDwarfFile = CGOpts.SplitDwarfFile;
1343 Conf.SplitDwarfOutput = CGOpts.SplitDwarfOutput;
1344 switch (Action) {
1346 Conf.PreCodeGenModuleHook = [](size_t Task, const llvm::Module &Mod) {
1347 return false;
1348 };
1349 break;
1350 case Backend_EmitLL:
1351 Conf.PreCodeGenModuleHook = [&](size_t Task, const llvm::Module &Mod) {
1352 M->print(*OS, nullptr, CGOpts.EmitLLVMUseLists);
1353 return false;
1354 };
1355 break;
1356 case Backend_EmitBC:
1357 Conf.PreCodeGenModuleHook = [&](size_t Task, const llvm::Module &Mod) {
1358 WriteBitcodeToFile(*M, *OS, CGOpts.EmitLLVMUseLists);
1359 return false;
1360 };
1361 break;
1362 default:
1363 Conf.CGFileType = getCodeGenFileType(Action);
1364 break;
1365 }
1366 if (Error E =
1367 thinBackend(Conf, -1, AddStream, *M, *CombinedIndex, ImportList,
1368 ModuleToDefinedGVSummaries[M->getModuleIdentifier()],
1369 /*ModuleMap=*/nullptr, Conf.CodeGenOnly,
1370 /*IRAddStream=*/nullptr, CGOpts.CmdArgs)) {
1371 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
1372 errs() << "Error running ThinLTO backend: " << EIB.message() << '\n';
1373 });
1374 }
1375}
1376
1378 StringRef TDesc, llvm::Module *M,
1379 BackendAction Action,
1381 std::unique_ptr<raw_pwrite_stream> OS,
1382 BackendConsumer *BC) {
1383 llvm::TimeTraceScope TimeScope("Backend");
1384 DiagnosticsEngine &Diags = CI.getDiagnostics();
1385
1386 std::unique_ptr<llvm::Module> EmptyModule;
1387 if (!CGOpts.ThinLTOIndexFile.empty()) {
1388 // If we are performing a ThinLTO importing compile, load the function index
1389 // into memory and pass it into runThinLTOBackend, which will run the
1390 // function importer and invoke LTO passes.
1391 std::unique_ptr<ModuleSummaryIndex> CombinedIndex;
1392 if (Error E = llvm::getModuleSummaryIndexForFile(
1393 CGOpts.ThinLTOIndexFile,
1394 /*IgnoreEmptyThinLTOIndexFile*/ true)
1395 .moveInto(CombinedIndex)) {
1396 logAllUnhandledErrors(std::move(E), errs(),
1397 "Error loading index file '" +
1398 CGOpts.ThinLTOIndexFile + "': ");
1399 return;
1400 }
1401
1402 // A null CombinedIndex means we should skip ThinLTO compilation
1403 // (LLVM will optionally ignore empty index files, returning null instead
1404 // of an error).
1405 if (CombinedIndex) {
1406 if (!CombinedIndex->skipModuleByDistributedBackend()) {
1407 runThinLTOBackend(CI, CombinedIndex.get(), M, std::move(OS),
1409 Action);
1410 return;
1411 }
1412 // Distributed indexing detected that nothing from the module is needed
1413 // for the final linking. So we can skip the compilation. We sill need to
1414 // output an empty object file to make sure that a linker does not fail
1415 // trying to read it. Also for some features, like CFI, we must skip
1416 // the compilation as CombinedIndex does not contain all required
1417 // information.
1418 EmptyModule = std::make_unique<llvm::Module>("empty", M->getContext());
1419 EmptyModule->setTargetTriple(M->getTargetTriple());
1420 M = EmptyModule.get();
1421 }
1422 }
1423
1424 EmitAssemblyHelper AsmHelper(CI, CGOpts, M, VFS);
1425 AsmHelper.emitAssembly(Action, std::move(OS), BC);
1426
1427 // Verify clang's TargetInfo DataLayout against the LLVM TargetMachine's
1428 // DataLayout.
1429 if (AsmHelper.TM) {
1430 std::string DLDesc = M->getDataLayout().getStringRepresentation();
1431 if (DLDesc != TDesc) {
1432 unsigned DiagID = Diags.getCustomDiagID(
1433 DiagnosticsEngine::Error, "backend data layout '%0' does not match "
1434 "expected target description '%1'");
1435 Diags.Report(DiagID) << DLDesc << TDesc;
1436 }
1437 }
1438}
1439
1440// With -fembed-bitcode, save a copy of the llvm IR as data in the
1441// __LLVM,__bitcode section.
1442void clang::EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,
1443 llvm::MemoryBufferRef Buf) {
1444 if (CGOpts.getEmbedBitcode() == CodeGenOptions::Embed_Off)
1445 return;
1446 llvm::embedBitcodeInModule(
1447 *M, Buf, CGOpts.getEmbedBitcode() != CodeGenOptions::Embed_Marker,
1448 CGOpts.getEmbedBitcode() != CodeGenOptions::Embed_Bitcode,
1449 CGOpts.CmdArgs);
1450}
1451
1452void clang::EmbedObject(llvm::Module *M, const CodeGenOptions &CGOpts,
1453 DiagnosticsEngine &Diags) {
1454 if (CGOpts.OffloadObjects.empty())
1455 return;
1456
1457 for (StringRef OffloadObject : CGOpts.OffloadObjects) {
1458 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ObjectOrErr =
1459 llvm::MemoryBuffer::getFileOrSTDIN(OffloadObject);
1460 if (ObjectOrErr.getError()) {
1461 auto DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
1462 "could not open '%0' for embedding");
1463 Diags.Report(DiagID) << OffloadObject;
1464 return;
1465 }
1466
1467 llvm::embedBufferInModule(*M, **ObjectOrErr, ".llvm.offloading",
1468 Align(object::OffloadBinary::getAlignment()));
1469 }
1470}
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:1497
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Definition: Diagnostic.h:900
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:502
bool hasWasmExceptions() const
Definition: LangOptions.h:770
bool hasSjLjExceptions() const
Definition: LangOptions.h:758
SanitizerSet Sanitize
Set of enabled sanitizers.
Definition: LangOptions.h:508
bool hasDWARFExceptions() const
Definition: LangOptions.h:766
bool hasSEHExceptions() const
Definition: LangOptions.h:762
std::vector< std::string > NoSanitizeFiles
Paths to files specifying which objects (files, functions, variables) should not be instrumented.
Definition: LangOptions.h:514
std::optional< std::vector< unsigned > > getAllScaled(unsigned ScalingFactor) const
Definition: Sanitizers.cpp:48
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)
llvm::cl::opt< bool > ClSanitizeGuardChecks
void emitBackendOutput(CompilerInstance &CI, CodeGenOptions &CGOpts, 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: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:174