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