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