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