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