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