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