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