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