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