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