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