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