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", cl::Optional,
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 switch (LangOpts.getThreadModel()) {
384 Options.ThreadModel = llvm::ThreadModel::POSIX;
385 break;
387 Options.ThreadModel = llvm::ThreadModel::Single;
388 break;
389 }
390
391 // Set FP fusion mode.
392 switch (LangOpts.getDefaultFPContractMode()) {
394 // Preserve any contraction performed by the front-end. (Strict performs
395 // splitting of the muladd intrinsic in the backend.)
396 Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
397 break;
400 Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
401 break;
403 Options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
404 break;
405 }
406
407 Options.MCOptions.BinutilsVersion =
408 llvm::MCTargetOptions::parseBinutilsVersion(CodeGenOpts.BinutilsVersion);
409 Options.UseInitArray = CodeGenOpts.UseInitArray;
410 Options.MCOptions.DisableIntegratedAS = CodeGenOpts.DisableIntegratedAS;
411
412 // Set EABI version.
413 Options.EABIVersion = TargetOpts.EABIVersion;
414
415 if (CodeGenOpts.hasSjLjExceptions())
416 Options.ExceptionModel = llvm::ExceptionHandling::SjLj;
417 if (CodeGenOpts.hasSEHExceptions())
418 Options.ExceptionModel = llvm::ExceptionHandling::WinEH;
419 if (CodeGenOpts.hasDWARFExceptions())
420 Options.ExceptionModel = llvm::ExceptionHandling::DwarfCFI;
421 if (CodeGenOpts.hasWasmExceptions())
422 Options.ExceptionModel = llvm::ExceptionHandling::Wasm;
423
424 Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
425
426 Options.BBAddrMap = CodeGenOpts.BBAddrMap;
427 Options.BBSections =
428 llvm::StringSwitch<llvm::BasicBlockSection>(CodeGenOpts.BBSections)
429 .Case("all", llvm::BasicBlockSection::All)
430 .StartsWith("list=", llvm::BasicBlockSection::List)
431 .Case("none", llvm::BasicBlockSection::None)
432 .Default(llvm::BasicBlockSection::None);
433
434 if (Options.BBSections == llvm::BasicBlockSection::List) {
435 ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
436 CI.getVirtualFileSystem().getBufferForFile(
437 CodeGenOpts.BBSections.substr(5));
438 if (!MBOrErr) {
439 Diags.Report(diag::err_fe_unable_to_load_basic_block_sections_file)
440 << MBOrErr.getError().message();
441 return false;
442 }
443 Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
444 }
445
446 Options.EnableMachineFunctionSplitter = CodeGenOpts.SplitMachineFunctions;
447 Options.EnableStaticDataPartitioning =
448 CodeGenOpts.PartitionStaticDataSections;
449 Options.FunctionSections = CodeGenOpts.FunctionSections;
450 Options.DataSections = CodeGenOpts.DataSections;
451 Options.IgnoreXCOFFVisibility = LangOpts.IgnoreXCOFFVisibility;
452 Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames;
453 Options.UniqueBasicBlockSectionNames =
454 CodeGenOpts.UniqueBasicBlockSectionNames;
455 Options.SeparateNamedSections = CodeGenOpts.SeparateNamedSections;
456 Options.TLSSize = CodeGenOpts.TLSSize;
457 Options.EnableTLSDESC = CodeGenOpts.EnableTLSDESC;
458 Options.EmulatedTLS = CodeGenOpts.EmulatedTLS;
459 Options.DebuggerTuning = CodeGenOpts.getDebuggerTuning();
460 Options.EmitStackSizeSection = CodeGenOpts.StackSizeSection;
461 Options.StackUsageFile = CodeGenOpts.StackUsageFile;
462 Options.EmitAddrsig = CodeGenOpts.Addrsig;
463 Options.ForceDwarfFrameSection = CodeGenOpts.ForceDwarfFrameSection;
464 Options.EmitCallGraphSection = CodeGenOpts.CallGraphSection;
465 Options.EmitCallSiteInfo = CodeGenOpts.EmitCallSiteInfo;
466 Options.EnableAIXExtendedAltivecABI = LangOpts.EnableAIXExtendedAltivecABI;
467 Options.XRayFunctionIndex = CodeGenOpts.XRayFunctionIndex;
468 Options.LoopAlignment = CodeGenOpts.LoopAlignment;
469 Options.DebugStrictDwarf = CodeGenOpts.DebugStrictDwarf;
470 Options.ObjectFilenameForDebug =
471 CodeGenOpts.remapDebugPathPrefix(CodeGenOpts.ObjectFilenameForDebug);
472 Options.Hotpatch = CodeGenOpts.HotPatch;
473 Options.JMCInstrument = CodeGenOpts.JMCInstrument;
474 Options.XCOFFReadOnlyPointers = CodeGenOpts.XCOFFReadOnlyPointers;
475 Options.VecLib =
476 convertDriverVectorLibraryToVectorLibrary(CodeGenOpts.getVecLib());
477
478 switch (CodeGenOpts.getSwiftAsyncFramePointer()) {
480 Options.SwiftAsyncFramePointer =
481 SwiftAsyncFramePointerMode::DeploymentBased;
482 break;
483
485 Options.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Always;
486 break;
487
489 Options.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Never;
490 break;
491 }
492
493 Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile;
494 Options.MCOptions.EmitDwarfUnwind = CodeGenOpts.getEmitDwarfUnwind();
495 Options.MCOptions.EmitCompactUnwindNonCanonical =
496 CodeGenOpts.EmitCompactUnwindNonCanonical;
497 Options.MCOptions.EmitSFrameUnwind = CodeGenOpts.EmitSFrameUnwind;
498 Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
499 Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
500 Options.MCOptions.MCUseDwarfDirectory =
501 CodeGenOpts.NoDwarfDirectoryAsm
502 ? llvm::MCTargetOptions::DisableDwarfDirectory
503 : llvm::MCTargetOptions::EnableDwarfDirectory;
504 Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack;
505 Options.MCOptions.MCIncrementalLinkerCompatible =
506 CodeGenOpts.IncrementalLinkerCompatible;
507 Options.MCOptions.MCFatalWarnings = CodeGenOpts.FatalWarnings;
508 Options.MCOptions.MCNoWarn = CodeGenOpts.NoWarn;
509 Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose;
510 Options.MCOptions.Dwarf64 = CodeGenOpts.Dwarf64;
511 Options.MCOptions.PreserveAsmComments = CodeGenOpts.PreserveAsmComments;
512 Options.MCOptions.Crel = CodeGenOpts.Crel;
513 Options.MCOptions.RelocSectionSym = CodeGenOpts.getRelocSectionSym();
514 Options.MCOptions.ImplicitMapSyms = CodeGenOpts.ImplicitMapSyms;
515 Options.MCOptions.X86RelaxRelocations = CodeGenOpts.X86RelaxRelocations;
516 Options.MCOptions.CompressDebugSections =
517 CodeGenOpts.getCompressDebugSections();
518 if (CodeGenOpts.OutputAsmVariant != 3) // 3 (default): not specified
519 Options.MCOptions.OutputAsmVariant = CodeGenOpts.OutputAsmVariant;
520 Options.MCOptions.ABIName = TargetOpts.ABI;
521 for (const auto &Entry : HSOpts.UserEntries)
522 if (!Entry.IsFramework &&
523 (Entry.Group == frontend::IncludeDirGroup::Quoted ||
524 Entry.Group == frontend::IncludeDirGroup::Angled ||
525 Entry.Group == frontend::IncludeDirGroup::System))
526 Options.MCOptions.IASSearchPaths.push_back(
527 Entry.IgnoreSysRoot ? Entry.Path : HSOpts.Sysroot + Entry.Path);
528 Options.MCOptions.Argv0 = CodeGenOpts.Argv0 ? CodeGenOpts.Argv0 : "";
529 // Pass the resolved frontend inputs so flattenClangCommandLine can strip
530 // the cc1 source positional even when the driver received an absolute path
531 // (which won't match CodeGenOpts.MainFileName, that's just the basename).
532 SmallVector<StringRef, 1> InputFiles;
533 for (const auto &Input : CI.getFrontendOpts().Inputs)
534 if (Input.isFile())
535 InputFiles.push_back(Input.getFile());
536 Options.MCOptions.CommandlineArgs = flattenClangCommandLine(
537 CodeGenOpts.CommandLineArgs, CodeGenOpts.MainFileName, InputFiles);
538 Options.MCOptions.AsSecureLogFile = CodeGenOpts.AsSecureLogFile;
539 Options.MCOptions.PPCUseFullRegisterNames =
540 CodeGenOpts.PPCUseFullRegisterNames;
541 Options.MisExpect = CodeGenOpts.MisExpect;
542
543 return true;
544}
545
546static std::optional<GCOVOptions>
547getGCOVOptions(const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts) {
548 if (CodeGenOpts.CoverageNotesFile.empty() &&
549 CodeGenOpts.CoverageDataFile.empty())
550 return std::nullopt;
551 // Not using 'GCOVOptions::getDefault' allows us to avoid exiting if
552 // LLVM's -default-gcov-version flag is set to something invalid.
553 GCOVOptions Options;
554 Options.EmitNotes = !CodeGenOpts.CoverageNotesFile.empty();
555 Options.EmitData = !CodeGenOpts.CoverageDataFile.empty();
556 llvm::copy(CodeGenOpts.CoverageVersion, std::begin(Options.Version));
557 Options.NoRedZone = CodeGenOpts.DisableRedZone;
558 Options.Filter = CodeGenOpts.ProfileFilterFiles;
559 Options.Exclude = CodeGenOpts.ProfileExcludeFiles;
560 Options.Atomic = CodeGenOpts.AtomicProfileUpdate;
561 return Options;
562}
563
564static std::optional<InstrProfOptions>
566 const LangOptions &LangOpts) {
567 if (!CodeGenOpts.hasProfileClangInstr())
568 return std::nullopt;
569 InstrProfOptions Options;
570 Options.NoRedZone = CodeGenOpts.DisableRedZone;
571 Options.InstrProfileOutput = CodeGenOpts.ContinuousProfileSync
572 ? ("%c" + CodeGenOpts.InstrProfileOutput)
573 : CodeGenOpts.InstrProfileOutput;
574 Options.Atomic = CodeGenOpts.AtomicProfileUpdate;
575 return Options;
576}
577
578static void setCommandLineOpts(const CodeGenOptions &CodeGenOpts,
579 vfs::FileSystem &VFS) {
581 BackendArgs.push_back("clang"); // Fake program name.
582 if (!CodeGenOpts.DebugPass.empty()) {
583 BackendArgs.push_back("-debug-pass");
584 BackendArgs.push_back(CodeGenOpts.DebugPass.c_str());
585 }
586 if (!CodeGenOpts.LimitFloatPrecision.empty()) {
587 BackendArgs.push_back("-limit-float-precision");
588 BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str());
589 }
590
591 // Check for the default "clang" invocation that won't set any cl::opt values.
592 // Skip trying to parse the command line invocation to avoid the issues
593 // described below.
594 if (BackendArgs.size() == 1)
595 return;
596 BackendArgs.push_back(nullptr);
597 // FIXME: The command line parser below is not thread-safe and shares a global
598 // state, so this call might crash or overwrite the options of another Clang
599 // instance in the same process.
600 llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1, BackendArgs.data(),
601 /*Overview=*/"", /*Errs=*/nullptr,
602 /*VFS=*/&VFS);
603}
604
605void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
606 // Create the TargetMachine for generating code.
607 std::string Error;
608 const llvm::Triple &Triple = TheModule->getTargetTriple();
609 const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
610 if (!TheTarget) {
611 if (MustCreateTM)
612 Diags.Report(diag::err_fe_unable_to_create_target) << Error;
613 return;
614 }
615
616 std::optional<llvm::CodeModel::Model> CM = getCodeModel(CodeGenOpts);
617 std::string FeaturesStr =
618 llvm::join(TargetOpts.Features.begin(), TargetOpts.Features.end(), ",");
619 llvm::Reloc::Model RM = CodeGenOpts.RelocationModel;
620 std::optional<CodeGenOptLevel> OptLevelOrNone =
621 CodeGenOpt::getLevel(CodeGenOpts.OptimizationLevel);
622 assert(OptLevelOrNone && "Invalid optimization level!");
623 CodeGenOptLevel OptLevel = *OptLevelOrNone;
624
625 llvm::TargetOptions Options;
626 if (!initTargetOptions(CI, Diags, Options))
627 return;
628 TM.reset(TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr,
629 Options, RM, CM, OptLevel));
630 if (TM)
631 TM->setLargeDataThreshold(CodeGenOpts.LargeDataThreshold);
632}
633
634static OptimizationLevel mapToLevel(const CodeGenOptions &Opts) {
635 switch (Opts.OptimizationLevel) {
636 default:
637 llvm_unreachable("Invalid optimization level!");
638
639 case 0:
640 return OptimizationLevel::O0;
641
642 case 1:
643 return OptimizationLevel::O1;
644
645 case 2:
646 return OptimizationLevel::O2;
647
648 case 3:
649 return OptimizationLevel::O3;
650 }
651}
652
653static void addKCFIPass(const Triple &TargetTriple, const LangOptions &LangOpts,
654 PassBuilder &PB) {
655 // If the back-end supports KCFI operand bundle lowering, skip KCFIPass.
656 if (TargetTriple.getArch() == llvm::Triple::x86_64 ||
657 TargetTriple.isAArch64(64) || TargetTriple.isRISCV() ||
658 TargetTriple.isARM() || TargetTriple.isThumb() ||
659 TargetTriple.getArch() == llvm::Triple::hexagon)
660 return;
661
662 // Ensure we lower KCFI operand bundles with -O0.
663 PB.registerOptimizerLastEPCallback(
664 [&](ModulePassManager &MPM, OptimizationLevel Level, ThinOrFullLTOPhase) {
665 if (Level == OptimizationLevel::O0 &&
666 LangOpts.Sanitize.has(SanitizerKind::KCFI))
667 MPM.addPass(createModuleToFunctionPassAdaptor(KCFIPass()));
668 });
669
670 // When optimizations are requested, run KCIFPass after InstCombine to
671 // avoid unnecessary checks.
672 PB.registerPeepholeEPCallback(
673 [&](FunctionPassManager &FPM, OptimizationLevel Level) {
674 if (Level != OptimizationLevel::O0 &&
675 LangOpts.Sanitize.has(SanitizerKind::KCFI))
676 FPM.addPass(KCFIPass());
677 });
678}
679
680static void addSanitizers(const Triple &TargetTriple,
681 const CodeGenOptions &CodeGenOpts,
682 const LangOptions &LangOpts, PassBuilder &PB) {
683 auto SanitizersCallback = [&](ModulePassManager &MPM, OptimizationLevel Level,
684 ThinOrFullLTOPhase) {
685 if (CodeGenOpts.hasSanitizeCoverage()) {
686 auto SancovOpts = getSancovOptsFromCGOpts(CodeGenOpts);
687 MPM.addPass(
688 SanitizerCoveragePass(SancovOpts, PB.getVirtualFileSystemPtr(),
691 }
692
693 if (CodeGenOpts.hasSanitizeBinaryMetadata()) {
694 MPM.addPass(SanitizerBinaryMetadataPass(
696 PB.getVirtualFileSystemPtr(),
698 }
699
700 auto MSanPass = [&](SanitizerMask Mask, bool CompileKernel) {
701 if (LangOpts.Sanitize.has(Mask)) {
702 int TrackOrigins = CodeGenOpts.SanitizeMemoryTrackOrigins;
703 bool Recover = CodeGenOpts.SanitizeRecover.has(Mask);
704
705 MemorySanitizerOptions options(TrackOrigins, Recover, CompileKernel,
706 CodeGenOpts.SanitizeMemoryParamRetval);
707 MPM.addPass(MemorySanitizerPass(options));
708 if (Level != OptimizationLevel::O0) {
709 // MemorySanitizer inserts complex instrumentation that mostly follows
710 // the logic of the original code, but operates on "shadow" values. It
711 // can benefit from re-running some general purpose optimization
712 // passes.
713 MPM.addPass(RequireAnalysisPass<GlobalsAA, llvm::Module>());
714 FunctionPassManager FPM;
715 FPM.addPass(EarlyCSEPass(true /* Enable mem-ssa. */));
716 FPM.addPass(InstCombinePass());
717 FPM.addPass(JumpThreadingPass());
718 FPM.addPass(GVNPass());
719 FPM.addPass(InstCombinePass());
720 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
721 }
722 }
723 };
724 MSanPass(SanitizerKind::Memory, false);
725 MSanPass(SanitizerKind::KernelMemory, true);
726
727 if (LangOpts.Sanitize.has(SanitizerKind::Thread)) {
728 MPM.addPass(ModuleThreadSanitizerPass());
729 MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
730 }
731
732 if (LangOpts.Sanitize.has(SanitizerKind::Type))
733 MPM.addPass(TypeSanitizerPass());
734
735 if (LangOpts.Sanitize.has(SanitizerKind::NumericalStability))
736 MPM.addPass(NumericalStabilitySanitizerPass());
737
738 if (LangOpts.Sanitize.has(SanitizerKind::Realtime))
739 MPM.addPass(RealtimeSanitizerPass());
740
741 auto ASanPass = [&](SanitizerMask Mask, bool CompileKernel) {
742 if (LangOpts.Sanitize.has(Mask)) {
743 bool UseGlobalGC = asanUseGlobalsGC(TargetTriple, CodeGenOpts);
744 bool UseOdrIndicator = CodeGenOpts.SanitizeAddressUseOdrIndicator;
745 llvm::AsanDtorKind DestructorKind =
746 CodeGenOpts.getSanitizeAddressDtor();
747 AddressSanitizerOptions Opts;
748 Opts.CompileKernel = CompileKernel;
749 Opts.Recover = CodeGenOpts.SanitizeRecover.has(Mask);
750 Opts.UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope;
751 Opts.UseAfterReturn = CodeGenOpts.getSanitizeAddressUseAfterReturn();
752 MPM.addPass(AddressSanitizerPass(Opts, UseGlobalGC, UseOdrIndicator,
753 DestructorKind));
754 }
755 };
756 ASanPass(SanitizerKind::Address, false);
757 ASanPass(SanitizerKind::KernelAddress, true);
758
759 auto HWASanPass = [&](SanitizerMask Mask, bool CompileKernel) {
760 if (LangOpts.Sanitize.has(Mask)) {
761 bool Recover = CodeGenOpts.SanitizeRecover.has(Mask);
762 MPM.addPass(HWAddressSanitizerPass(
763 {CompileKernel, Recover,
764 /*DisableOptimization=*/CodeGenOpts.OptimizationLevel == 0}));
765 }
766 };
767 HWASanPass(SanitizerKind::HWAddress, false);
768 HWASanPass(SanitizerKind::KernelHWAddress, true);
769
770 if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) {
771 MPM.addPass(DataFlowSanitizerPass(LangOpts.NoSanitizeFiles,
772 PB.getVirtualFileSystemPtr()));
773 }
774 };
776 PB.registerOptimizerEarlyEPCallback(
777 [SanitizersCallback](ModulePassManager &MPM, OptimizationLevel Level,
778 ThinOrFullLTOPhase Phase) {
779 ModulePassManager NewMPM;
780 SanitizersCallback(NewMPM, Level, Phase);
781 if (!NewMPM.isEmpty()) {
782 // Sanitizers can abandon<GlobalsAA>.
783 NewMPM.addPass(RequireAnalysisPass<GlobalsAA, llvm::Module>());
784 MPM.addPass(std::move(NewMPM));
785 }
786 });
787 } else {
788 // LastEP does not need GlobalsAA.
789 PB.registerOptimizerLastEPCallback(SanitizersCallback);
790 }
791}
792
794 const LangOptions &LangOpts, PassBuilder &PB) {
795 // SanitizeSkipHotCutoffs: doubles with range [0, 1]
796 // Opts.cutoffs: unsigned ints with range [0, 1000000]
797 auto ScaledCutoffs = CodeGenOpts.SanitizeSkipHotCutoffs.getAllScaled(1000000);
798 uint64_t AllowRuntimeCheckSkipHotCutoff =
799 CodeGenOpts.AllowRuntimeCheckSkipHotCutoff.value_or(0.0) * 1000000;
800 // Only register the pass if one of the relevant sanitizers is enabled.
801 // This avoids pipeline overhead for builds that do not use these sanitizers.
802 bool LowerAllowSanitize = LangOpts.Sanitize.hasOneOf(
803 SanitizerKind::Address | SanitizerKind::KernelAddress |
804 SanitizerKind::Thread | SanitizerKind::Memory |
805 SanitizerKind::KernelMemory | SanitizerKind::HWAddress |
806 SanitizerKind::KernelHWAddress);
807
808 // TODO: remove IsRequested()
809 if (LowerAllowCheckPass::IsRequested() || ScaledCutoffs.has_value() ||
810 CodeGenOpts.AllowRuntimeCheckSkipHotCutoff.has_value() ||
811 LowerAllowSanitize) {
812 // We want to call it after inline, which is about OptimizerEarlyEPCallback.
813 PB.registerOptimizerEarlyEPCallback(
814 [ScaledCutoffs, AllowRuntimeCheckSkipHotCutoff](
815 ModulePassManager &MPM, OptimizationLevel Level,
816 ThinOrFullLTOPhase Phase) {
817 LowerAllowCheckPass::Options Opts;
818 // TODO: after removing IsRequested(), make this unconditional
819 if (ScaledCutoffs.has_value())
820 Opts.cutoffs = ScaledCutoffs.value();
821 Opts.runtime_check = AllowRuntimeCheckSkipHotCutoff;
822 MPM.addPass(
823 createModuleToFunctionPassAdaptor(LowerAllowCheckPass(Opts)));
824 });
825 }
826}
827
828void EmitAssemblyHelper::RunOptimizationPipeline(
829 BackendAction Action, std::unique_ptr<raw_pwrite_stream> &OS,
830 std::unique_ptr<llvm::ToolOutputFile> &ThinLinkOS, BackendConsumer *BC) {
831 std::optional<PGOOptions> PGOOpt;
832
833 if (CodeGenOpts.hasProfileIRInstr())
834 // -fprofile-generate.
835 PGOOpt = PGOOptions(getProfileGenName(CodeGenOpts), "", "",
836 CodeGenOpts.MemoryProfileUsePath, PGOOptions::IRInstr,
837 PGOOptions::NoCSAction, ClPGOColdFuncAttr,
838 CodeGenOpts.DebugInfoForProfiling,
839 /*PseudoProbeForProfiling=*/false,
840 CodeGenOpts.AtomicProfileUpdate);
841 else if (CodeGenOpts.hasProfileIRUse()) {
842 // -fprofile-use.
843 auto CSAction = CodeGenOpts.hasProfileCSIRUse() ? PGOOptions::CSIRUse
844 : PGOOptions::NoCSAction;
845 PGOOpt = PGOOptions(CodeGenOpts.ProfileInstrumentUsePath, "",
846 CodeGenOpts.ProfileRemappingFile,
847 CodeGenOpts.MemoryProfileUsePath, PGOOptions::IRUse,
848 CSAction, ClPGOColdFuncAttr,
849 CodeGenOpts.DebugInfoForProfiling);
850 } else if (!CodeGenOpts.SampleProfileFile.empty())
851 // -fprofile-sample-use
852 PGOOpt = PGOOptions(
853 CodeGenOpts.SampleProfileFile, "", CodeGenOpts.ProfileRemappingFile,
854 CodeGenOpts.MemoryProfileUsePath, PGOOptions::SampleUse,
855 PGOOptions::NoCSAction, ClPGOColdFuncAttr,
856 CodeGenOpts.DebugInfoForProfiling, CodeGenOpts.PseudoProbeForProfiling);
857 else if (!CodeGenOpts.MemoryProfileUsePath.empty())
858 // -fmemory-profile-use (without any of the above options)
859 PGOOpt = PGOOptions("", "", "", CodeGenOpts.MemoryProfileUsePath,
860 PGOOptions::NoAction, PGOOptions::NoCSAction,
861 ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling);
862 else if (CodeGenOpts.PseudoProbeForProfiling)
863 // -fpseudo-probe-for-profiling
864 PGOOpt = PGOOptions("", "", "", /*MemoryProfile=*/"", PGOOptions::NoAction,
865 PGOOptions::NoCSAction, ClPGOColdFuncAttr,
866 CodeGenOpts.DebugInfoForProfiling, true);
867 else if (CodeGenOpts.DebugInfoForProfiling)
868 // -fdebug-info-for-profiling
869 PGOOpt = PGOOptions("", "", "", /*MemoryProfile=*/"", PGOOptions::NoAction,
870 PGOOptions::NoCSAction, ClPGOColdFuncAttr, true);
871
872 // Check to see if we want to generate a CS profile.
873 if (CodeGenOpts.hasProfileCSIRInstr()) {
874 assert(!CodeGenOpts.hasProfileCSIRUse() &&
875 "Cannot have both CSProfileUse pass and CSProfileGen pass at "
876 "the same time");
877 if (PGOOpt) {
878 assert(PGOOpt->Action != PGOOptions::IRInstr &&
879 PGOOpt->Action != PGOOptions::SampleUse &&
880 "Cannot run CSProfileGen pass with ProfileGen or SampleUse "
881 " pass");
882 PGOOpt->CSProfileGenFile = getProfileGenName(CodeGenOpts);
883 PGOOpt->CSAction = PGOOptions::CSIRInstr;
884 } else
885 PGOOpt = PGOOptions("", getProfileGenName(CodeGenOpts), "",
886 /*MemoryProfile=*/"", PGOOptions::NoAction,
887 PGOOptions::CSIRInstr, ClPGOColdFuncAttr,
888 CodeGenOpts.DebugInfoForProfiling);
889 }
890 if (TM)
891 TM->setPGOOption(PGOOpt);
892
893 PipelineTuningOptions PTO;
894 PTO.LoopUnrolling = CodeGenOpts.UnrollLoops;
895 PTO.LoopInterchange = CodeGenOpts.InterchangeLoops;
896 PTO.LoopFusion = CodeGenOpts.FuseLoops;
897 // For historical reasons, loop interleaving is set to mirror setting for loop
898 // unrolling.
899 PTO.LoopInterleaving = CodeGenOpts.UnrollLoops;
900 PTO.LoopVectorization = CodeGenOpts.VectorizeLoop;
901 PTO.SLPVectorization = CodeGenOpts.VectorizeSLP;
902 PTO.MergeFunctions = CodeGenOpts.MergeFunctions;
903 // Only enable CGProfilePass when using integrated assembler, since
904 // non-integrated assemblers don't recognize .cgprofile section.
905 PTO.CallGraphProfile = !CodeGenOpts.DisableIntegratedAS;
906 PTO.UnifiedLTO = CodeGenOpts.UnifiedLTO;
907 PTO.DevirtualizeSpeculatively = CodeGenOpts.DevirtualizeSpeculatively;
908
909 LoopAnalysisManager LAM;
910 FunctionAnalysisManager FAM;
911 CGSCCAnalysisManager CGAM;
912 ModuleAnalysisManager MAM;
913
914 bool DebugPassStructure = CodeGenOpts.DebugPass == "Structure";
915 PassInstrumentationCallbacks PIC;
916 PrintPassOptions PrintPassOpts;
917 PrintPassOpts.Indent = DebugPassStructure;
918 PrintPassOpts.SkipAnalyses = DebugPassStructure;
919 StandardInstrumentations SI(
920 TheModule->getContext(),
921 (CodeGenOpts.DebugPassManager || DebugPassStructure),
922 CodeGenOpts.VerifyEach, PrintPassOpts);
923 SI.registerCallbacks(PIC, &MAM);
924 PassBuilder PB(TM.get(), PTO, PGOOpt, &PIC, CI.getVirtualFileSystemPtr());
925
926 // Handle the assignment tracking feature options.
927 switch (CodeGenOpts.getAssignmentTrackingMode()) {
928 case CodeGenOptions::AssignmentTrackingOpts::Forced:
929 PB.registerPipelineStartEPCallback(
930 [&](ModulePassManager &MPM, OptimizationLevel Level) {
931 MPM.addPass(AssignmentTrackingPass());
932 });
933 break;
934 case CodeGenOptions::AssignmentTrackingOpts::Enabled:
935 // Disable assignment tracking in LTO builds for now as the performance
936 // cost is too high. Disable for LLDB tuning due to llvm.org/PR43126.
937 if (!CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.PrepareForLTO &&
938 CodeGenOpts.getDebuggerTuning() != llvm::DebuggerKind::LLDB) {
939 PB.registerPipelineStartEPCallback(
940 [&](ModulePassManager &MPM, OptimizationLevel Level) {
941 // Only use assignment tracking if optimisations are enabled.
942 if (Level != OptimizationLevel::O0)
943 MPM.addPass(AssignmentTrackingPass());
944 });
945 }
946 break;
947 case CodeGenOptions::AssignmentTrackingOpts::Disabled:
948 break;
949 }
950
951 // Enable verify-debuginfo-preserve-each for new PM.
952 DebugifyEachInstrumentation Debugify;
953 DebugInfoPerPass DebugInfoBeforePass;
954 if (CodeGenOpts.EnableDIPreservationVerify) {
955 Debugify.setDebugifyMode(DebugifyMode::OriginalDebugInfo);
956 Debugify.setDebugInfoBeforePass(DebugInfoBeforePass);
957
958 if (!CodeGenOpts.DIBugsReportFilePath.empty())
959 Debugify.setOrigDIVerifyBugsReportFilePath(
960 CodeGenOpts.DIBugsReportFilePath);
961 Debugify.registerCallbacks(PIC, MAM);
962
963#if LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
964 // If we're using debug location coverage tracking, mark all the
965 // instructions coming out of the frontend without a DebugLoc as being
966 // compiler-generated, to prevent both those instructions and new
967 // instructions that inherit their location from being treated as
968 // incorrectly empty locations.
969 for (Function &F : *TheModule) {
970 if (!F.getSubprogram())
971 continue;
972 for (BasicBlock &BB : F)
973 for (Instruction &I : BB)
974 if (!I.getDebugLoc())
975 I.setDebugLoc(DebugLoc::getCompilerGenerated());
976 }
977#endif
978 }
979 // Register plugin callbacks with PB.
980 for (const std::unique_ptr<PassPlugin> &Plugin : CI.getPassPlugins())
981 Plugin->registerPassBuilderCallbacks(PB);
982 for (const auto &PassCallback : CodeGenOpts.PassBuilderCallbacks)
983 PassCallback(PB);
984#define HANDLE_EXTENSION(Ext) \
985 get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
986#include "llvm/Support/Extension.def"
987
988 // Register the target library analysis directly and give it a customized
989 // preset TLI.
990 std::unique_ptr<TargetLibraryInfoImpl> TLII(
991 llvm::driver::createTLII(TargetTriple, CodeGenOpts.getVecLib()));
992 FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
993
994 // Register all the basic analyses with the managers.
995 PB.registerModuleAnalyses(MAM);
996 PB.registerCGSCCAnalyses(CGAM);
997 PB.registerFunctionAnalyses(FAM);
998 PB.registerLoopAnalyses(LAM);
999 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
1000
1001 ModulePassManager MPM;
1002 // Add a verifier pass, before any other passes, to catch CodeGen issues.
1003 if (CodeGenOpts.VerifyModule)
1004 MPM.addPass(VerifierPass());
1005
1006 if (!CodeGenOpts.DisableLLVMPasses) {
1007 // Map our optimization levels into one of the distinct levels used to
1008 // configure the pipeline.
1009 OptimizationLevel Level = mapToLevel(CodeGenOpts);
1010
1011 const bool PrepareForThinLTO = CodeGenOpts.PrepareForThinLTO;
1012 const bool PrepareForLTO = CodeGenOpts.PrepareForLTO;
1013
1014 if (LangOpts.ObjCAutoRefCount) {
1015 PB.registerPipelineStartEPCallback(
1016 [](ModulePassManager &MPM, OptimizationLevel Level) {
1017 if (Level != OptimizationLevel::O0)
1018 MPM.addPass(
1019 createModuleToFunctionPassAdaptor(ObjCARCExpandPass()));
1020 });
1021 PB.registerScalarOptimizerLateEPCallback(
1022 [](FunctionPassManager &FPM, OptimizationLevel Level) {
1023 if (Level != OptimizationLevel::O0)
1024 FPM.addPass(ObjCARCOptPass());
1025 });
1026 }
1027
1028 // If we reached here with a non-empty index file name, then the index
1029 // file was empty and we are not performing ThinLTO backend compilation
1030 // (used in testing in a distributed build environment).
1031 bool IsThinLTOPostLink = !CodeGenOpts.ThinLTOIndexFile.empty();
1032 // If so drop any the type test assume sequences inserted for whole program
1033 // vtables so that codegen doesn't complain.
1034 if (IsThinLTOPostLink)
1035 PB.registerPipelineStartEPCallback(
1036 [](ModulePassManager &MPM, OptimizationLevel Level) {
1037 MPM.addPass(DropTypeTestsPass());
1038 });
1039
1040 // Register callbacks to schedule sanitizer passes at the appropriate part
1041 // of the pipeline.
1042 if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds))
1043 PB.registerScalarOptimizerLateEPCallback([this](FunctionPassManager &FPM,
1044 OptimizationLevel Level) {
1045 BoundsCheckingPass::Options Options;
1046 if (CodeGenOpts.SanitizeSkipHotCutoffs[SanitizerKind::SO_LocalBounds] ||
1048 static_assert(SanitizerKind::SO_LocalBounds <=
1049 std::numeric_limits<
1050 decltype(Options.GuardKind)::value_type>::max(),
1051 "Update type of llvm.allow.ubsan.check to represent "
1052 "SanitizerKind::SO_LocalBounds.");
1053 Options.GuardKind = SanitizerKind::SO_LocalBounds;
1054 }
1055 Options.Merge =
1056 CodeGenOpts.SanitizeMergeHandlers.has(SanitizerKind::LocalBounds);
1057 if (!CodeGenOpts.SanitizeTrap.has(SanitizerKind::LocalBounds)) {
1058 Options.Rt = {
1059 /*MinRuntime=*/static_cast<bool>(
1060 CodeGenOpts.SanitizeMinimalRuntime),
1061 /*MayReturn=*/
1062 CodeGenOpts.SanitizeRecover.has(SanitizerKind::LocalBounds),
1063 /*HandlerPreserveAllRegs=*/
1064 static_cast<bool>(CodeGenOpts.SanitizeHandlerPreserveAllRegs),
1065 };
1066 }
1067 FPM.addPass(BoundsCheckingPass(Options));
1068 });
1069
1070 if (!IsThinLTOPostLink) {
1071 // Most sanitizers only run during PreLink stage.
1072 addSanitizers(TargetTriple, CodeGenOpts, LangOpts, PB);
1073 addKCFIPass(TargetTriple, LangOpts, PB);
1074 addLowerAllowCheckPass(CodeGenOpts, LangOpts, PB);
1075
1076 PB.registerPipelineStartEPCallback(
1077 [&](ModulePassManager &MPM, OptimizationLevel Level) {
1078 if (Level == OptimizationLevel::O0 &&
1079 LangOpts.Sanitize.has(SanitizerKind::AllocToken)) {
1080 // With the default O0 pipeline, LibFunc attrs are not inferred,
1081 // so we insert it here because we need it for accurate memory
1082 // allocation function detection with -fsanitize=alloc-token.
1083 // Note: This could also be added to the default O0 pipeline, but
1084 // has a non-trivial effect on generated IR size (attributes).
1085 MPM.addPass(InferFunctionAttrsPass());
1086 }
1087 });
1088 }
1089
1090 if (std::optional<GCOVOptions> Options =
1091 getGCOVOptions(CodeGenOpts, LangOpts))
1092 PB.registerPipelineStartEPCallback(
1093 [this, Options](ModulePassManager &MPM, OptimizationLevel Level) {
1094 MPM.addPass(
1095 GCOVProfilerPass(*Options, CI.getVirtualFileSystemPtr()));
1096 });
1097 if (std::optional<InstrProfOptions> Options =
1098 getInstrProfOptions(CodeGenOpts, LangOpts))
1099 PB.registerPipelineStartEPCallback(
1100 [Options](ModulePassManager &MPM, OptimizationLevel Level) {
1101 MPM.addPass(InstrProfilingLoweringPass(*Options, false));
1102 });
1103
1104 // TODO: Consider passing the MemoryProfileOutput to the pass builder via
1105 // the PGOOptions, and set this up there.
1106 if (!CodeGenOpts.MemoryProfileOutput.empty()) {
1107 PB.registerOptimizerLastEPCallback([](ModulePassManager &MPM,
1108 OptimizationLevel Level,
1109 ThinOrFullLTOPhase) {
1110 MPM.addPass(createModuleToFunctionPassAdaptor(MemProfilerPass()));
1111 MPM.addPass(ModuleMemProfilerPass());
1112 });
1113 }
1114
1115 if (CodeGenOpts.FatLTO) {
1116 MPM.addPass(PB.buildFatLTODefaultPipeline(
1117 Level, PrepareForThinLTO,
1118 PrepareForThinLTO || shouldEmitRegularLTOSummary(),
1119 CodeGenOpts.VerifyModule));
1120 } else if (PrepareForThinLTO) {
1121 MPM.addPass(PB.buildThinLTOPreLinkDefaultPipeline(Level));
1122 } else if (PrepareForLTO) {
1123 MPM.addPass(PB.buildLTOPreLinkDefaultPipeline(Level));
1124 } else {
1125 MPM.addPass(PB.buildPerModuleDefaultPipeline(Level));
1126 }
1127 }
1128
1129 // Link against bitcodes supplied via the -mlink-builtin-bitcode option
1130 if (CodeGenOpts.LinkBitcodePostopt) {
1131 MPM.addPass(LinkInModulesPass(BC));
1132 MPM.addPass(AssignGUIDPass());
1133 }
1134
1135 if (LangOpts.HIPStdPar && !LangOpts.CUDAIsDevice &&
1136 LangOpts.HIPStdParInterposeAlloc)
1137 MPM.addPass(HipStdParAllocationInterpositionPass());
1138
1139 // Add a verifier pass if requested. We don't have to do this if the action
1140 // requires code generation because there will already be a verifier pass in
1141 // the code-generation pipeline.
1142 // Since we already added a verifier pass above, this
1143 // might even not run the analysis, if previous passes caused no changes.
1144 if (!actionRequiresCodeGen(Action) && CodeGenOpts.VerifyModule)
1145 MPM.addPass(VerifierPass());
1146
1147 if (Action == Backend_EmitBC || Action == Backend_EmitLL ||
1148 CodeGenOpts.FatLTO) {
1149 if (CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.DisableLLVMPasses) {
1150 if (!TheModule->getModuleFlag("EnableSplitLTOUnit"))
1151 TheModule->addModuleFlag(llvm::Module::Error, "EnableSplitLTOUnit",
1152 CodeGenOpts.EnableSplitLTOUnit);
1153 if (Action == Backend_EmitBC) {
1154 if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) {
1155 ThinLinkOS = openOutputFile(CodeGenOpts.ThinLinkBitcodeFile);
1156 if (!ThinLinkOS)
1157 return;
1158 }
1159 MPM.addPass(ThinLTOBitcodeWriterPass(
1160 *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr));
1161 } else if (Action == Backend_EmitLL) {
1162 MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,
1163 /*EmitLTOSummary=*/true,
1164 /*ShouldRenumberMetadata=*/true));
1165 }
1166 } else {
1167 // Emit a module summary by default for Regular LTO except for ld64
1168 // targets
1169 bool EmitLTOSummary = shouldEmitRegularLTOSummary();
1170 if (EmitLTOSummary) {
1171 if (!TheModule->getModuleFlag("ThinLTO") && !CodeGenOpts.UnifiedLTO)
1172 TheModule->addModuleFlag(llvm::Module::Error, "ThinLTO", uint32_t(0));
1173 if (!TheModule->getModuleFlag("EnableSplitLTOUnit"))
1174 TheModule->addModuleFlag(llvm::Module::Error, "EnableSplitLTOUnit",
1175 uint32_t(1));
1176 }
1177 if (Action == Backend_EmitBC) {
1178 MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
1179 EmitLTOSummary));
1180 } else if (Action == Backend_EmitLL) {
1181 MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,
1182 EmitLTOSummary,
1183 /*ShouldRenumberMetadata=*/true));
1184 }
1185 }
1186
1187 if (shouldEmitUnifiedLTOModueFlag() &&
1188 !TheModule->getModuleFlag("UnifiedLTO"))
1189 TheModule->addModuleFlag(llvm::Module::Error, "UnifiedLTO", uint32_t(1));
1190 }
1191
1192 // FIXME: This should eventually be replaced by a first-class driver option.
1193 // This should be done for both clang and flang simultaneously.
1194 // Print a textual, '-passes=' compatible, representation of pipeline if
1195 // requested.
1196 if (PrintPipelinePasses) {
1197 MPM.printPipeline(outs(), [&PIC](StringRef ClassName) {
1198 auto PassName = PIC.getPassNameForClassName(ClassName);
1199 return PassName.empty() ? ClassName : PassName;
1200 });
1201 outs() << "\n";
1202 return;
1203 }
1204
1205 // Now that we have all of the passes ready, run them.
1206 {
1207 PrettyStackTraceString CrashInfo("Optimizer");
1208 llvm::TimeTraceScope TimeScope("Optimizer");
1209 Timer timer;
1210 if (CI.getCodeGenOpts().TimePasses) {
1211 timer.init("optimizer", "Optimizer", CI.getTimerGroup());
1212 CI.getFrontendTimer().yieldTo(timer);
1213 }
1214 MPM.run(*TheModule, MAM);
1215 if (CI.getCodeGenOpts().TimePasses)
1216 timer.yieldTo(CI.getFrontendTimer());
1217 }
1218}
1219
1220void EmitAssemblyHelper::RunCodegenPipeline(
1221 BackendAction Action, std::unique_ptr<raw_pwrite_stream> &OS,
1222 std::unique_ptr<llvm::ToolOutputFile> &DwoOS) {
1223 if (!actionRequiresCodeGen(Action))
1224 return;
1225
1226 // Normal mode, emit a .s or .o file by running the code generator. Note,
1227 // this also adds codegenerator level optimization passes.
1228 CodeGenFileType CGFT = getCodeGenFileType(Action);
1229
1230 // Invoke pre-codegen callback from plugin, which might want to take over the
1231 // entire code generation itself.
1232 for (const std::unique_ptr<llvm::PassPlugin> &Plugin : CI.getPassPlugins()) {
1233 if (Plugin->invokePreCodeGenCallback(*TheModule, *TM, CGFT, *OS))
1234 return;
1235 }
1236
1237 if (!CodeGenOpts.SplitDwarfOutput.empty()) {
1238 DwoOS = openOutputFile(CodeGenOpts.SplitDwarfOutput);
1239 if (!DwoOS)
1240 return;
1241 }
1242
1243 TimeCodegenPasses([&]() {
1244 Error CodeGenError = runCodeGenPipeline(
1245 *TM, *TheModule, *OS, DwoOS, CGFT, PrintPipelinePasses.has_value(),
1246 !CodeGenOpts.VerifyModule, CI.getVirtualFileSystemPtr());
1247 if (CodeGenError)
1248 Diags.Report(diag::err_fe_unable_to_interface_with_target);
1249 });
1250}
1251
1252void EmitAssemblyHelper::TimeCodegenPasses(
1253 llvm::function_ref<void()> RunPasses) {
1254 PrettyStackTraceString CrashInfo("Code generation");
1255 llvm::TimeTraceScope TimeScope("CodeGenPasses");
1256 Timer timer;
1257 if (CI.getCodeGenOpts().TimePasses) {
1258 timer.init("codegen", "Machine code generation", CI.getTimerGroup());
1259 CI.getFrontendTimer().yieldTo(timer);
1260 }
1261 RunPasses();
1262 if (CI.getCodeGenOpts().TimePasses)
1263 timer.yieldTo(CI.getFrontendTimer());
1264}
1265
1266void EmitAssemblyHelper::emitAssembly(BackendAction Action,
1267 std::unique_ptr<raw_pwrite_stream> OS,
1268 BackendConsumer *BC) {
1269 setCommandLineOpts(CodeGenOpts, CI.getVirtualFileSystem());
1270
1271 bool RequiresCodeGen = actionRequiresCodeGen(Action);
1272 CreateTargetMachine(RequiresCodeGen);
1273
1274 if (RequiresCodeGen && !TM)
1275 return;
1276 if (TM)
1277 TheModule->setDataLayout(TM->createDataLayout());
1278
1279 // Before executing passes, print the final values of the LLVM options.
1280 cl::PrintOptionValues();
1281
1282 std::unique_ptr<llvm::ToolOutputFile> ThinLinkOS, DwoOS;
1283 RunOptimizationPipeline(Action, OS, ThinLinkOS, BC);
1284 RunCodegenPipeline(Action, OS, DwoOS);
1285
1286 if (ThinLinkOS)
1287 ThinLinkOS->keep();
1288 if (DwoOS)
1289 DwoOS->keep();
1290}
1291
1292static void
1293runThinLTOBackend(CompilerInstance &CI, ModuleSummaryIndex *CombinedIndex,
1294 llvm::Module *M, std::unique_ptr<raw_pwrite_stream> OS,
1295 std::string SampleProfile, std::string ProfileRemapping,
1296 BackendAction Action) {
1297 DiagnosticsEngine &Diags = CI.getDiagnostics();
1298 const auto &CGOpts = CI.getCodeGenOpts();
1299 const auto &TOpts = CI.getTargetOpts();
1300 DenseMap<StringRef, DenseMap<GlobalValue::GUID, GlobalValueSummary *>>
1301 ModuleToDefinedGVSummaries;
1302 CombinedIndex->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
1303
1305
1306 // We can simply import the values mentioned in the combined index, since
1307 // we should only invoke this using the individual indexes written out
1308 // via a WriteIndexesThinBackend.
1309 FunctionImporter::ImportIDTable ImportIDs;
1310 FunctionImporter::ImportMapTy ImportList(ImportIDs);
1311 if (!lto::initImportList(*M, *CombinedIndex, ImportList))
1312 return;
1313
1314 auto AddStream = [&](size_t Task, const Twine &ModuleName) {
1315 return std::make_unique<CachedFileStream>(std::move(OS),
1316 CGOpts.ObjectFilenameForDebug);
1317 };
1318 lto::Config Conf;
1319 if (CGOpts.SaveTempsFilePrefix != "") {
1320 if (Error E = Conf.addSaveTemps(CGOpts.SaveTempsFilePrefix + ".",
1321 /* UseInputModulePath */ false)) {
1322 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
1323 errs() << "Error setting up ThinLTO save-temps: " << EIB.message()
1324 << '\n';
1325 });
1326 }
1327 }
1328 Conf.CPU = TOpts.CPU;
1329 Conf.CodeModel = getCodeModel(CGOpts);
1330 Conf.MAttrs = TOpts.Features;
1331 Conf.RelocModel = CGOpts.RelocationModel;
1332 std::optional<CodeGenOptLevel> OptLevelOrNone =
1333 CodeGenOpt::getLevel(CGOpts.OptimizationLevel);
1334 assert(OptLevelOrNone && "Invalid optimization level!");
1335 Conf.CGOptLevel = *OptLevelOrNone;
1336 Conf.OptLevel = CGOpts.OptimizationLevel;
1337 initTargetOptions(CI, Diags, Conf.Options);
1338 Conf.SampleProfile = std::move(SampleProfile);
1339 Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops;
1340 Conf.PTO.LoopInterchange = CGOpts.InterchangeLoops;
1341 Conf.PTO.LoopFusion = CGOpts.FuseLoops;
1342 // For historical reasons, loop interleaving is set to mirror setting for loop
1343 // unrolling.
1344 Conf.PTO.LoopInterleaving = CGOpts.UnrollLoops;
1345 Conf.PTO.LoopVectorization = CGOpts.VectorizeLoop;
1346 Conf.PTO.SLPVectorization = CGOpts.VectorizeSLP;
1347 // Only enable CGProfilePass when using integrated assembler, since
1348 // non-integrated assemblers don't recognize .cgprofile section.
1349 Conf.PTO.CallGraphProfile = !CGOpts.DisableIntegratedAS;
1350
1351 // Context sensitive profile.
1352 if (CGOpts.hasProfileCSIRInstr()) {
1353 Conf.RunCSIRInstr = true;
1354 Conf.CSIRProfile = getProfileGenName(CGOpts);
1355 } else if (CGOpts.hasProfileCSIRUse()) {
1356 Conf.RunCSIRInstr = false;
1357 Conf.CSIRProfile = std::move(CGOpts.ProfileInstrumentUsePath);
1358 }
1359
1360 Conf.ProfileRemapping = std::move(ProfileRemapping);
1361 Conf.DebugPassManager = CGOpts.DebugPassManager;
1362 Conf.VerifyEach = CGOpts.VerifyEach;
1363 Conf.RemarksWithHotness = CGOpts.DiagnosticsWithHotness;
1364 Conf.RemarksFilename = CGOpts.OptRecordFile;
1365 Conf.RemarksPasses = CGOpts.OptRecordPasses;
1366 Conf.RemarksFormat = CGOpts.OptRecordFormat;
1367 Conf.SplitDwarfFile = CGOpts.SplitDwarfFile;
1368 Conf.SplitDwarfOutput = CGOpts.SplitDwarfOutput;
1369 for (auto &Plugin : CI.getPassPlugins())
1370 Conf.LoadedPassPlugins.push_back(Plugin.get());
1371 switch (Action) {
1373 Conf.PreCodeGenModuleHook = [](size_t Task, const llvm::Module &Mod) {
1374 return false;
1375 };
1376 break;
1377 case Backend_EmitLL:
1378 Conf.PreCodeGenModuleHook = [&](size_t Task, const llvm::Module &Mod) {
1379 M->renumberMetadataForAssembly();
1380 M->print(*OS, nullptr, CGOpts.EmitLLVMUseLists);
1381 return false;
1382 };
1383 break;
1384 case Backend_EmitBC:
1385 Conf.PreCodeGenModuleHook = [&](size_t Task, const llvm::Module &Mod) {
1386 WriteBitcodeToFile(*M, *OS, CGOpts.EmitLLVMUseLists);
1387 return false;
1388 };
1389 break;
1390 default:
1391 Conf.CGFileType = getCodeGenFileType(Action);
1392 break;
1393 }
1394
1395 // FIXME: Both ExecuteAction and thinBackend set up optimization remarks for
1396 // the same context.
1397 // FIXME: This does not yet set the list of bitcode libfuncs that it isn't
1398 // safe to call. This precludes bitcode libc in distributed ThinLTO.
1399 finalizeLLVMOptimizationRemarks(M->getContext());
1400 if (Error E = thinBackend(
1401 Conf, -1, AddStream, *M, *CombinedIndex, ImportList,
1402 ModuleToDefinedGVSummaries[M->getModuleIdentifier()],
1403 /*ModuleMap=*/nullptr, Conf.CodeGenOnly, /*BitcodeLibFuncs=*/{},
1404 /*IRAddStream=*/nullptr, CGOpts.CmdArgs)) {
1405 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
1406 errs() << "Error running ThinLTO backend: " << EIB.message() << '\n';
1407 });
1408 }
1409}
1410
1412 CompilerInstance &CI, CodeGenOptions &CGOpts, llvm::Module *M,
1414 /// Helper for saving the module(s) at various dyndbg stages.
1415 auto SaveModule = [&](StringRef Name, llvm::Module &M) {
1416 if (CGOpts.SaveDynDbgTempsFilePrefix == "")
1417 return;
1418 std::error_code EC;
1419 std::string Path =
1420 Twine(CGOpts.SaveDynDbgTempsFilePrefix + "." + Name + ".ll").str();
1421 raw_fd_ostream OS(Path, EC, sys::fs::OpenFlags::OF_None);
1422 if (EC) {
1423 // Copy -save-temps behaviour: this is a debugging option so we simply
1424 // exit if there's an issue.
1425 errs() << "failed to open " << Path << ": " << EC.message() << '\n';
1426 errs().flush();
1427 exit(1);
1428 }
1429 M.print(OS, nullptr);
1430 };
1431
1432 // Compute a hash suffix for promoting static globals (once per TU).
1433 std::string PromotionSuffix;
1434 {
1435 // LLVM's hash/hash_combine is not guaranteed to be stable.
1436 MD5 Hash;
1437 // Include args in the hash else preprocessor definitions used to alter
1438 // the same source file compiled twice won't generate unique hashes.
1439 Hash.update(CGOpts.CmdArgs);
1440 for (auto *CU : M->debug_compile_units()) {
1441 if (CU->getDirectory().size() > 0)
1442 Hash.update(CU->getDirectory());
1443
1444 Hash.update(CU->getFilename());
1445 }
1446
1447 MD5::MD5Result Result;
1448 Hash.final(Result);
1449 PromotionSuffix = ".dyndbg." + utohexstr(Result.low());
1450 }
1451
1452 SaveModule("dyndbg.0.input", *M);
1453 // Modify M as needed and create an "unoptimized" clone.
1454 auto UnoptM = prepareForDynamicDebugging(M, PromotionSuffix);
1455 SaveModule("dyndbg.1.inner", *UnoptM);
1456
1457 if (!CGOpts.DiscardDynamicDebuggingDebugModule) {
1458 CodeGenOptions UnoptOpts = CGOpts;
1459 UnoptOpts.OptimizationLevel = 0;
1460 UnoptOpts.OptimizeSize = 0;
1461 EmitAssemblyHelper AsmHelper(CI, UnoptOpts, UnoptM.get(), VFS);
1462
1463 // Create a buffer and ostream for the inner ELF.
1464 SmallVector<char, 0> UnoptBuf;
1465 std::unique_ptr<llvm::raw_pwrite_stream> UnoptOS =
1466 std::make_unique<llvm::raw_svector_ostream>(UnoptBuf);
1467
1468 // Always run the full codegen pipeline (Backend_EmitObj). This causes
1469 // assertion failures if there's no registered backend which is why we
1470 // disable the feature if that's the case (see
1471 // warn_dyndbg_unable_to_create_target above).
1472 AsmHelper.emitAssembly(Backend_EmitObj, std::move(UnoptOS), BC);
1473 assert(!UnoptBuf.empty() && "Expected emitAssembly to fill UnoptBuf");
1474
1475 // Inject the inner ELF into the outer module.
1476 StringRef SR(UnoptBuf.data(), UnoptBuf.size());
1477 std::unique_ptr<MemoryBuffer> Buf =
1478 MemoryBuffer::getMemBuffer(SR, "", false);
1479
1480 GlobalVariable *EmbeddedGV =
1481 llvm::embedBufferInModule(*M, *Buf, ".debug_llvm_dyndbg", Align(8),
1482 /*SectionExclude*/ false);
1483 // Add ELF section properties metadata.
1484 auto &C = M->getContext();
1485 auto getU32Metadata = [&C](unsigned Val) {
1486 return ConstantAsMetadata::get(ConstantInt::get(C, APInt(32, Val)));
1487 };
1488 EmbeddedGV->addMetadata(
1489 LLVMContext::MD_elf_section_properties,
1490 *MDTuple::get(C, {/*sh_type*/ getU32Metadata(ELF::SHT_LLVM_DYNDBG_ELF),
1491 /*sh_entsize*/ getU32Metadata(0)}));
1492 }
1493 SaveModule("dyndbg.2.outer", *M);
1494}
1495
1497 StringRef TDesc, llvm::Module *M,
1498 BackendAction Action,
1500 std::unique_ptr<raw_pwrite_stream> OS,
1501 BackendConsumer *BC) {
1502 llvm::TimeTraceScope TimeScope("Backend");
1503 DiagnosticsEngine &Diags = CI.getDiagnostics();
1504
1505 std::unique_ptr<llvm::Module> EmptyModule;
1506 if (!CGOpts.ThinLTOIndexFile.empty()) {
1507 // FIXME(sandboxing): Figure out how to support distributed indexing.
1508 auto BypassSandbox = sys::sandbox::scopedDisable();
1509 // If we are performing a ThinLTO importing compile, load the function index
1510 // into memory and pass it into runThinLTOBackend, which will run the
1511 // function importer and invoke LTO passes.
1512 std::unique_ptr<ModuleSummaryIndex> CombinedIndex;
1513 if (Error E = llvm::getModuleSummaryIndexForFile(
1514 CGOpts.ThinLTOIndexFile,
1515 /*IgnoreEmptyThinLTOIndexFile*/ true)
1516 .moveInto(CombinedIndex)) {
1517 logAllUnhandledErrors(std::move(E), errs(),
1518 "Error loading index file '" +
1519 CGOpts.ThinLTOIndexFile + "': ");
1520 return;
1521 }
1522
1523 // A null CombinedIndex means we should skip ThinLTO compilation
1524 // (LLVM will optionally ignore empty index files, returning null instead
1525 // of an error).
1526 if (CombinedIndex) {
1527 if (!CombinedIndex->skipModuleByDistributedBackend()) {
1528 runThinLTOBackend(CI, CombinedIndex.get(), M, std::move(OS),
1530 Action);
1531 return;
1532 }
1533 // Distributed indexing detected that nothing from the module is needed
1534 // for the final linking. So we can skip the compilation. We sill need to
1535 // output an empty object file to make sure that a linker does not fail
1536 // trying to read it. Also for some features, like CFI, we must skip
1537 // the compilation as CombinedIndex does not contain all required
1538 // information.
1539 EmptyModule = std::make_unique<llvm::Module>("empty", M->getContext());
1540 EmptyModule->setTargetTriple(M->getTargetTriple());
1541 M = EmptyModule.get();
1542 }
1543 }
1544
1545 bool EnableDynamicDebugging = CGOpts.DynamicDebugging;
1546 if (EnableDynamicDebugging) {
1547 // Disable dyndbg if the target isn't available as we're compiling to the
1548 // inner module (unless we're discarding it for debugging/testing).
1549 std::string Error;
1550 const llvm::Target *TheTarget =
1551 TargetRegistry::lookupTarget(M->getTargetTriple(), Error);
1552 if (!TheTarget && !CGOpts.DiscardDynamicDebuggingDebugModule) {
1553 Diags.Report(diag::warn_dyndbg_unable_to_create_target) << Error;
1554 EnableDynamicDebugging = false;
1555 }
1556
1557 // Instrumentation causes issues (parts of LLVM expect certain globals to
1558 // have initializers). Intrinsics may already have been added to IR by now,
1559 // so we can't just turn it off for the inner module (we'd have to strip
1560 // them out / not clone them). TODO: Support instrumentation.
1561 if (CGOpts.getProfileInstr() != driver::ProfileInstrKind::ProfileNone) {
1562 Diags.Report(diag::err_dyndbg_no_instrumentation);
1563 EnableDynamicDebugging = false;
1564 }
1565 }
1566 if (EnableDynamicDebugging)
1567 createAndEmbedModuleForDynamicDebugging(CI, CGOpts, M, VFS, BC);
1568
1569 EmitAssemblyHelper AsmHelper(CI, CGOpts, M, VFS);
1570 AsmHelper.emitAssembly(Action, std::move(OS), BC);
1571
1572 // Verify clang's TargetInfo DataLayout against the LLVM TargetMachine's
1573 // DataLayout.
1574 if (AsmHelper.TM) {
1575 std::string DLDesc = M->getDataLayout().getStringRepresentation();
1576 if (DLDesc != TDesc) {
1577 Diags.Report(diag::err_data_layout_mismatch) << DLDesc << TDesc;
1578 }
1579 }
1580}
1581
1582// With -fembed-bitcode, save a copy of the llvm IR as data in the
1583// __LLVM,__bitcode section.
1584void clang::EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,
1585 llvm::MemoryBufferRef Buf) {
1586 if (CGOpts.getEmbedBitcode() == CodeGenOptions::Embed_Off)
1587 return;
1588 llvm::embedBitcodeInModule(
1589 *M, Buf, CGOpts.getEmbedBitcode() != CodeGenOptions::Embed_Marker,
1590 CGOpts.getEmbedBitcode() != CodeGenOptions::Embed_Bitcode,
1591 CGOpts.CmdArgs);
1592}
1593
1594void clang::EmbedObject(llvm::Module *M, const CodeGenOptions &CGOpts,
1595 llvm::vfs::FileSystem &VFS, DiagnosticsEngine &Diags) {
1596 if (CGOpts.OffloadObjects.empty())
1597 return;
1598
1599 for (StringRef OffloadObject : CGOpts.OffloadObjects) {
1600 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ObjectOrErr =
1601 VFS.getBufferForFile(OffloadObject);
1602 if (ObjectOrErr.getError()) {
1603 Diags.Report(diag::err_failed_to_open_for_embedding) << OffloadObject;
1604 return;
1605 }
1606
1607 llvm::embedBufferInModule(*M, **ObjectOrErr, ".llvm.offloading",
1608 Align(object::OffloadBinary::getAlignment()));
1609 }
1610}
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 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:234
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
SmallVector< FrontendInputFile, 0 > Inputs
The input files and their types.
@ Single
Single Threaded Environment.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
SanitizerSet Sanitize
Set of enabled sanitizers.
std::vector< std::string > NoSanitizeFiles
Paths to files specifying which objects (files, functions, variables) should not be instrumented.
std::optional< std::vector< unsigned > > getAllScaled(unsigned ScalingFactor) const
std::vector< std::string > Features
The list of target specific features to enable or disable – this should be a list of strings starting...
std::string ABI
If given, the name of the target ABI to use.
std::string CPU
If given, the name of the target CPU to generate code for.
llvm::EABI EABIVersion
The EABI version to use.
@ Angled
Paths for '#include <>' added by '-I'.
@ System
Like Angled, but marks system directories.
@ Quoted
'#include ""' paths, added by 'gcc -iquote'.
Top level wrappers for InstallAPI frontend operations.
@ Default
Set to the current date and time.
const FunctionProtoType * T
llvm::cl::opt< bool > ClSanitizeGuardChecks
void emitBackendOutput(CompilerInstance &CI, CodeGenOptions &CGOpts, StringRef TDesc, llvm::Module *M, BackendAction Action, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, std::unique_ptr< raw_pwrite_stream > OS, BackendConsumer *BC=nullptr)
void EmbedObject(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::vfs::FileSystem &VFS, DiagnosticsEngine &Diags)
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
BackendAction
Definition BackendUtil.h:33
@ Backend_EmitAssembly
Emit native assembly files.
Definition BackendUtil.h:34
@ Backend_EmitLL
Emit human-readable LLVM assembly.
Definition BackendUtil.h:36
@ Backend_EmitBC
Emit LLVM bitcode files.
Definition BackendUtil.h:35
@ Backend_EmitObj
Emit native object files.
Definition BackendUtil.h:39
@ Backend_EmitMCNull
Run CodeGen, but don't emit anything.
Definition BackendUtil.h:38
@ Backend_EmitNothing
Don't emit anything (benchmarking mode)
Definition BackendUtil.h:37
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
LLVM_ABI cl::opt< InstrProfCorrelator::ProfCorrelatorKind > ProfileCorrelate
static cl::opt< PGOOptions::ColdFuncOpt > ClPGOColdFuncAttr("pgo-cold-func-opt", cl::init(PGOOptions::ColdFuncOpt::Default), cl::Hidden, cl::desc("Function attribute to apply to cold functions as determined by PGO"), cl::values(clEnumValN(PGOOptions::ColdFuncOpt::Default, "default", "Default (no attribute)"), clEnumValN(PGOOptions::ColdFuncOpt::OptSize, "optsize", "Mark cold functions with optsize."), clEnumValN(PGOOptions::ColdFuncOpt::MinSize, "minsize", "Mark cold functions with minsize."), clEnumValN(PGOOptions::ColdFuncOpt::OptNone, "optnone", "Mark cold functions with optnone.")))
static cl::opt< bool > ClSanitizeOnOptimizerEarlyEP("sanitizer-early-opt-ep", cl::Optional, cl::desc("Insert sanitizers on OptimizerEarlyEP."))
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
Definition Sanitizers.h:174
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.
Definition Sanitizers.h:184