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