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