17#include "llvm/ADT/SmallSet.h"
18#include "llvm/ADT/StringExtras.h"
19#include "llvm/ADT/StringSwitch.h"
20#include "llvm/Analysis/AliasAnalysis.h"
21#include "llvm/Analysis/GlobalsModRef.h"
22#include "llvm/Analysis/TargetLibraryInfo.h"
23#include "llvm/Analysis/TargetTransformInfo.h"
24#include "llvm/Bitcode/BitcodeReader.h"
25#include "llvm/Bitcode/BitcodeWriter.h"
26#include "llvm/Bitcode/BitcodeWriterPass.h"
27#include "llvm/CodeGen/RegAllocRegistry.h"
28#include "llvm/CodeGen/SchedulerRegistry.h"
29#include "llvm/CodeGen/TargetSubtargetInfo.h"
30#include "llvm/IR/DataLayout.h"
31#include "llvm/IR/DebugInfo.h"
32#include "llvm/IR/LegacyPassManager.h"
33#include "llvm/IR/Module.h"
34#include "llvm/IR/ModuleSummaryIndex.h"
35#include "llvm/IR/PassManager.h"
36#include "llvm/IR/Verifier.h"
37#include "llvm/IRPrinter/IRPrintingPasses.h"
38#include "llvm/LTO/LTOBackend.h"
39#include "llvm/MC/MCAsmInfo.h"
40#include "llvm/MC/SubtargetFeature.h"
41#include "llvm/MC/TargetRegistry.h"
42#include "llvm/Object/OffloadBinary.h"
43#include "llvm/Passes/PassBuilder.h"
44#include "llvm/Passes/PassPlugin.h"
45#include "llvm/Passes/StandardInstrumentations.h"
46#include "llvm/Support/BuryPointer.h"
47#include "llvm/Support/CommandLine.h"
48#include "llvm/Support/MemoryBuffer.h"
49#include "llvm/Support/PrettyStackTrace.h"
50#include "llvm/Support/TimeProfiler.h"
51#include "llvm/Support/Timer.h"
52#include "llvm/Support/ToolOutputFile.h"
53#include "llvm/Support/VirtualFileSystem.h"
54#include "llvm/Support/raw_ostream.h"
55#include "llvm/Target/TargetMachine.h"
56#include "llvm/Target/TargetOptions.h"
57#include "llvm/TargetParser/Triple.h"
58#include "llvm/Transforms/IPO/LowerTypeTests.h"
59#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
60#include "llvm/Transforms/InstCombine/InstCombine.h"
61#include "llvm/Transforms/Instrumentation.h"
62#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
63#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
64#include "llvm/Transforms/Instrumentation/BoundsChecking.h"
65#include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h"
66#include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
67#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
68#include "llvm/Transforms/Instrumentation/InstrProfiling.h"
69#include "llvm/Transforms/Instrumentation/KCFI.h"
70#include "llvm/Transforms/Instrumentation/MemProfiler.h"
71#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
72#include "llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h"
73#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
74#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
75#include "llvm/Transforms/ObjCARC.h"
76#include "llvm/Transforms/Scalar/EarlyCSE.h"
77#include "llvm/Transforms/Scalar/GVN.h"
78#include "llvm/Transforms/Scalar/JumpThreading.h"
79#include "llvm/Transforms/Utils/Debugify.h"
80#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
81#include "llvm/Transforms/Utils/ModuleUtils.h"
87#define HANDLE_EXTENSION(Ext) \
88 llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
89#include "llvm/Support/Extension.def"
96 "sanitizer-early-opt-ep", cl::Optional,
97 cl::desc(
"Insert sanitizers on OptimizerEarlyEP."), cl::init(
false));
103std::string getDefaultProfileGenName() {
107class EmitAssemblyHelper {
116 Timer CodeGenerationTime;
118 std::unique_ptr<raw_pwrite_stream>
OS;
122 TargetIRAnalysis getTargetIRAnalysis()
const {
124 return TM->getTargetIRAnalysis();
126 return TargetIRAnalysis();
137 void CreateTargetMachine(
bool MustCreateTM);
142 bool AddEmitPasses(legacy::PassManager &CodeGenPasses,
BackendAction Action,
143 raw_pwrite_stream &OS, raw_pwrite_stream *DwoOS);
145 std::unique_ptr<llvm::ToolOutputFile> openOutputFile(StringRef Path) {
147 auto F = std::make_unique<llvm::ToolOutputFile>(Path, EC,
148 llvm::sys::fs::OF_None);
150 Diags.
Report(diag::err_fe_unable_to_open_output) << Path << EC.message();
158 std::unique_ptr<raw_pwrite_stream> &OS,
159 std::unique_ptr<llvm::ToolOutputFile> &ThinLinkOS);
161 std::unique_ptr<raw_pwrite_stream> &OS,
162 std::unique_ptr<llvm::ToolOutputFile> &DwoOS);
169 bool shouldEmitRegularLTOSummary()
const {
170 return CodeGenOpts.PrepareForLTO && !CodeGenOpts.DisableLLVMPasses &&
171 TargetTriple.getVendor() != llvm::Triple::Apple;
181 : Diags(_Diags), HSOpts(HeaderSearchOpts), CodeGenOpts(CGOpts),
182 TargetOpts(TOpts), LangOpts(LOpts), TheModule(M), VFS(
std::move(VFS)),
183 CodeGenerationTime(
"codegen",
"Code Generation Time"),
184 TargetTriple(TheModule->getTargetTriple()) {}
186 ~EmitAssemblyHelper() {
187 if (CodeGenOpts.DisableFree)
188 BuryPointer(std::move(TM));
191 std::unique_ptr<TargetMachine> TM;
195 std::unique_ptr<raw_pwrite_stream> OS);
199static SanitizerCoverageOptions
201 SanitizerCoverageOptions Opts;
203 static_cast<SanitizerCoverageOptions::Type
>(CGOpts.SanitizeCoverageType);
204 Opts.IndirectCalls = CGOpts.SanitizeCoverageIndirectCalls;
205 Opts.TraceBB = CGOpts.SanitizeCoverageTraceBB;
206 Opts.TraceCmp = CGOpts.SanitizeCoverageTraceCmp;
207 Opts.TraceDiv = CGOpts.SanitizeCoverageTraceDiv;
208 Opts.TraceGep = CGOpts.SanitizeCoverageTraceGep;
209 Opts.Use8bitCounters = CGOpts.SanitizeCoverage8bitCounters;
210 Opts.TracePC = CGOpts.SanitizeCoverageTracePC;
211 Opts.TracePCGuard = CGOpts.SanitizeCoverageTracePCGuard;
212 Opts.NoPrune = CGOpts.SanitizeCoverageNoPrune;
213 Opts.Inline8bitCounters = CGOpts.SanitizeCoverageInline8bitCounters;
214 Opts.InlineBoolFlag = CGOpts.SanitizeCoverageInlineBoolFlag;
215 Opts.PCTable = CGOpts.SanitizeCoveragePCTable;
216 Opts.StackDepth = CGOpts.SanitizeCoverageStackDepth;
217 Opts.TraceLoads = CGOpts.SanitizeCoverageTraceLoads;
218 Opts.TraceStores = CGOpts.SanitizeCoverageTraceStores;
219 Opts.CollectControlFlow = CGOpts.SanitizeCoverageControlFlow;
223static SanitizerBinaryMetadataOptions
225 SanitizerBinaryMetadataOptions Opts;
226 Opts.Covered = CGOpts.SanitizeBinaryMetadataCovered;
227 Opts.Atomics = CGOpts.SanitizeBinaryMetadataAtomics;
228 Opts.UAR = CGOpts.SanitizeBinaryMetadataUAR;
237 if (!CGOpts.SanitizeAddressGlobalsDeadStripping)
239 switch (T.getObjectFormat()) {
244 return !CGOpts.DisableIntegratedAS;
246 llvm::report_fatal_error(
"ASan not implemented for GOFF");
248 llvm::report_fatal_error(
"ASan not implemented for XCOFF.");
250 case Triple::DXContainer:
252 case Triple::UnknownObjectFormat:
258static TargetLibraryInfoImpl *
createTLII(llvm::Triple &TargetTriple,
260 TargetLibraryInfoImpl *TLII =
new TargetLibraryInfoImpl(TargetTriple);
262 switch (CodeGenOpts.getVecLib()) {
264 TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::Accelerate,
268 TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::LIBMVEC_X86,
272 TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::MASSV,
276 TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::SVML,
280 TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::SLEEFGNUABI,
284 TLII->addVectorizableFunctionsFromVecLib(
285 TargetLibraryInfoImpl::DarwinLibSystemM, TargetTriple);
293static std::optional<llvm::CodeModel::Model>
295 unsigned CodeModel = llvm::StringSwitch<unsigned>(CodeGenOpts.
CodeModel)
296 .Case(
"tiny", llvm::CodeModel::Tiny)
297 .Case(
"small", llvm::CodeModel::Small)
298 .Case(
"kernel", llvm::CodeModel::Kernel)
299 .Case(
"medium", llvm::CodeModel::Medium)
300 .Case(
"large", llvm::CodeModel::Large)
301 .Case(
"default", ~1u)
303 assert(CodeModel != ~0u &&
"invalid code model!");
304 if (CodeModel == ~1u)
306 return static_cast<llvm::CodeModel::Model
>(CodeModel);
311 return CGFT_ObjectFile;
316 return CGFT_AssemblyFile;
326 llvm::TargetOptions &Options,
331 switch (LangOpts.getThreadModel()) {
332 case LangOptions::ThreadModelKind::POSIX:
333 Options.ThreadModel = llvm::ThreadModel::POSIX;
335 case LangOptions::ThreadModelKind::Single:
336 Options.ThreadModel = llvm::ThreadModel::Single;
341 assert((CodeGenOpts.
FloatABI ==
"soft" || CodeGenOpts.
FloatABI ==
"softfp" ||
343 "Invalid Floating Point ABI!");
344 Options.FloatABIType =
345 llvm::StringSwitch<llvm::FloatABI::ABIType>(CodeGenOpts.
FloatABI)
346 .Case(
"soft", llvm::FloatABI::Soft)
347 .Case(
"softfp", llvm::FloatABI::Soft)
348 .Case(
"hard", llvm::FloatABI::Hard)
349 .Default(llvm::FloatABI::Default);
352 switch (LangOpts.getDefaultFPContractMode()) {
356 Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
360 Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
363 Options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
367 Options.BinutilsVersion =
368 llvm::TargetMachine::parseBinutilsVersion(CodeGenOpts.
BinutilsVersion);
369 Options.UseInitArray = CodeGenOpts.UseInitArray;
370 Options.DisableIntegratedAS = CodeGenOpts.DisableIntegratedAS;
371 Options.CompressDebugSections = CodeGenOpts.getCompressDebugSections();
372 Options.RelaxELFRelocations = CodeGenOpts.RelaxELFRelocations;
378 Options.ExceptionModel = llvm::ExceptionHandling::SjLj;
380 Options.ExceptionModel = llvm::ExceptionHandling::WinEH;
382 Options.ExceptionModel = llvm::ExceptionHandling::DwarfCFI;
384 Options.ExceptionModel = llvm::ExceptionHandling::Wasm;
386 Options.NoInfsFPMath = LangOpts.NoHonorInfs;
387 Options.NoNaNsFPMath = LangOpts.NoHonorNaNs;
388 Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
389 Options.UnsafeFPMath = LangOpts.AllowFPReassoc && LangOpts.AllowRecip &&
390 LangOpts.NoSignedZero && LangOpts.ApproxFunc &&
391 (LangOpts.getDefaultFPContractMode() ==
392 LangOptions::FPModeKind::FPM_Fast ||
393 LangOpts.getDefaultFPContractMode() ==
394 LangOptions::FPModeKind::FPM_FastHonorPragmas);
395 Options.ApproxFuncFPMath = LangOpts.ApproxFunc;
398 llvm::StringSwitch<llvm::BasicBlockSection>(CodeGenOpts.
BBSections)
399 .Case(
"all", llvm::BasicBlockSection::All)
400 .Case(
"labels", llvm::BasicBlockSection::Labels)
401 .StartsWith(
"list=", llvm::BasicBlockSection::List)
402 .Case(
"none", llvm::BasicBlockSection::None)
403 .Default(llvm::BasicBlockSection::None);
405 if (Options.BBSections == llvm::BasicBlockSection::List) {
406 ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
407 MemoryBuffer::getFile(CodeGenOpts.
BBSections.substr(5));
409 Diags.
Report(diag::err_fe_unable_to_load_basic_block_sections_file)
410 << MBOrErr.getError().message();
413 Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
416 Options.EnableMachineFunctionSplitter = CodeGenOpts.SplitMachineFunctions;
417 Options.FunctionSections = CodeGenOpts.FunctionSections;
418 Options.DataSections = CodeGenOpts.DataSections;
419 Options.IgnoreXCOFFVisibility = LangOpts.IgnoreXCOFFVisibility;
420 Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames;
421 Options.UniqueBasicBlockSectionNames =
422 CodeGenOpts.UniqueBasicBlockSectionNames;
423 Options.TLSSize = CodeGenOpts.TLSSize;
424 Options.EmulatedTLS = CodeGenOpts.EmulatedTLS;
425 Options.ExplicitEmulatedTLS =
true;
426 Options.DebuggerTuning = CodeGenOpts.getDebuggerTuning();
427 Options.EmitStackSizeSection = CodeGenOpts.StackSizeSection;
429 Options.EmitAddrsig = CodeGenOpts.Addrsig;
430 Options.ForceDwarfFrameSection = CodeGenOpts.ForceDwarfFrameSection;
431 Options.EmitCallSiteInfo = CodeGenOpts.EmitCallSiteInfo;
432 Options.EnableAIXExtendedAltivecABI = CodeGenOpts.EnableAIXExtendedAltivecABI;
433 Options.XRayOmitFunctionIndex = CodeGenOpts.XRayOmitFunctionIndex;
434 Options.LoopAlignment = CodeGenOpts.LoopAlignment;
435 Options.DebugStrictDwarf = CodeGenOpts.DebugStrictDwarf;
437 Options.Hotpatch = CodeGenOpts.HotPatch;
438 Options.JMCInstrument = CodeGenOpts.JMCInstrument;
440 switch (CodeGenOpts.getSwiftAsyncFramePointer()) {
441 case CodeGenOptions::SwiftAsyncFramePointerKind::Auto:
442 Options.SwiftAsyncFramePointer =
443 SwiftAsyncFramePointerMode::DeploymentBased;
446 case CodeGenOptions::SwiftAsyncFramePointerKind::Always:
447 Options.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Always;
450 case CodeGenOptions::SwiftAsyncFramePointerKind::Never:
451 Options.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Never;
456 Options.MCOptions.EmitDwarfUnwind = CodeGenOpts.getEmitDwarfUnwind();
457 Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
458 Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
459 Options.MCOptions.MCUseDwarfDirectory =
460 CodeGenOpts.NoDwarfDirectoryAsm
461 ? llvm::MCTargetOptions::DisableDwarfDirectory
462 : llvm::MCTargetOptions::EnableDwarfDirectory;
463 Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack;
464 Options.MCOptions.MCIncrementalLinkerCompatible =
465 CodeGenOpts.IncrementalLinkerCompatible;
466 Options.MCOptions.MCFatalWarnings = CodeGenOpts.FatalWarnings;
467 Options.MCOptions.MCNoWarn = CodeGenOpts.NoWarn;
468 Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose;
469 Options.MCOptions.Dwarf64 = CodeGenOpts.Dwarf64;
470 Options.MCOptions.PreserveAsmComments = CodeGenOpts.PreserveAsmComments;
471 Options.MCOptions.ABIName = TargetOpts.
ABI;
473 if (!Entry.IsFramework &&
474 (Entry.Group == frontend::IncludeDirGroup::Quoted ||
475 Entry.Group == frontend::IncludeDirGroup::Angled ||
476 Entry.Group == frontend::IncludeDirGroup::System))
477 Options.MCOptions.IASSearchPaths.push_back(
478 Entry.IgnoreSysRoot ? Entry.Path : HSOpts.
Sysroot + Entry.Path);
479 Options.MCOptions.Argv0 = CodeGenOpts.
Argv0;
482 Options.MisExpect = CodeGenOpts.MisExpect;
487static std::optional<GCOVOptions>
489 if (!CodeGenOpts.EmitGcovArcs && !CodeGenOpts.EmitGcovNotes)
494 Options.EmitNotes = CodeGenOpts.EmitGcovNotes;
495 Options.EmitData = CodeGenOpts.EmitGcovArcs;
497 Options.NoRedZone = CodeGenOpts.DisableRedZone;
500 Options.Atomic = CodeGenOpts.AtomicProfileUpdate;
504static std::optional<InstrProfOptions>
509 InstrProfOptions Options;
510 Options.NoRedZone = CodeGenOpts.DisableRedZone;
512 Options.Atomic = CodeGenOpts.AtomicProfileUpdate;
518 BackendArgs.push_back(
"clang");
520 BackendArgs.push_back(
"-debug-pass");
521 BackendArgs.push_back(CodeGenOpts.
DebugPass.c_str());
524 BackendArgs.push_back(
"-limit-float-precision");
530 if (BackendArgs.size() == 1)
532 BackendArgs.push_back(
nullptr);
536 llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
540void EmitAssemblyHelper::CreateTargetMachine(
bool MustCreateTM) {
543 std::string Triple = TheModule->getTargetTriple();
544 const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple,
Error);
547 Diags.
Report(diag::err_fe_unable_to_create_target) <<
Error;
551 std::optional<llvm::CodeModel::Model> CM =
getCodeModel(CodeGenOpts);
552 std::string FeaturesStr =
555 std::optional<CodeGenOpt::Level> OptLevelOrNone =
556 CodeGenOpt::getLevel(CodeGenOpts.OptimizationLevel);
557 assert(OptLevelOrNone &&
"Invalid optimization level!");
558 CodeGenOpt::Level OptLevel = *OptLevelOrNone;
560 llvm::TargetOptions Options;
564 TM.reset(TheTarget->createTargetMachine(Triple, TargetOpts.
CPU, FeaturesStr,
565 Options, RM, CM, OptLevel));
568bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses,
570 raw_pwrite_stream &
OS,
571 raw_pwrite_stream *DwoOS) {
573 std::unique_ptr<TargetLibraryInfoImpl> TLII(
575 CodeGenPasses.add(
new TargetLibraryInfoWrapperPass(*TLII));
584 if (CodeGenOpts.OptimizationLevel > 0)
585 CodeGenPasses.add(createObjCARCContractPass());
587 if (TM->addPassesToEmitFile(CodeGenPasses,
OS, DwoOS, CGFT,
588 !CodeGenOpts.VerifyModule)) {
589 Diags.
Report(diag::err_fe_unable_to_interface_with_target);
597 switch (Opts.OptimizationLevel) {
599 llvm_unreachable(
"Invalid optimization level!");
602 return OptimizationLevel::O0;
605 return OptimizationLevel::O1;
608 switch (Opts.OptimizeSize) {
610 llvm_unreachable(
"Invalid optimization level for size!");
613 return OptimizationLevel::O2;
616 return OptimizationLevel::Os;
619 return OptimizationLevel::Oz;
623 return OptimizationLevel::O3;
630 if (TargetTriple.getArch() == llvm::Triple::x86_64 ||
631 TargetTriple.isAArch64(64))
635 PB.registerOptimizerLastEPCallback(
636 [&](ModulePassManager &MPM, OptimizationLevel Level) {
637 if (Level == OptimizationLevel::O0 &&
639 MPM.addPass(createModuleToFunctionPassAdaptor(KCFIPass()));
644 PB.registerPeepholeEPCallback(
645 [&](FunctionPassManager &FPM, OptimizationLevel Level) {
646 if (Level != OptimizationLevel::O0 &&
648 FPM.addPass(KCFIPass());
655 auto SanitizersCallback = [&](ModulePassManager &MPM,
656 OptimizationLevel Level) {
659 MPM.addPass(SanitizerCoveragePass(
665 MPM.addPass(SanitizerBinaryMetadataPass(
670 auto MSanPass = [&](
SanitizerMask Mask,
bool CompileKernel) {
672 int TrackOrigins = CodeGenOpts.SanitizeMemoryTrackOrigins;
675 MemorySanitizerOptions options(TrackOrigins, Recover, CompileKernel,
676 CodeGenOpts.SanitizeMemoryParamRetval);
677 MPM.addPass(MemorySanitizerPass(options));
678 if (Level != OptimizationLevel::O0) {
683 MPM.addPass(RequireAnalysisPass<GlobalsAA, Module>());
684 FunctionPassManager FPM;
685 FPM.addPass(EarlyCSEPass(
true ));
686 FPM.addPass(InstCombinePass());
687 FPM.addPass(JumpThreadingPass());
688 FPM.addPass(GVNPass());
689 FPM.addPass(InstCombinePass());
690 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
694 MSanPass(SanitizerKind::Memory,
false);
695 MSanPass(SanitizerKind::KernelMemory,
true);
697 if (LangOpts.
Sanitize.
has(SanitizerKind::Thread)) {
698 MPM.addPass(ModuleThreadSanitizerPass());
699 MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
702 auto ASanPass = [&](
SanitizerMask Mask,
bool CompileKernel) {
705 bool UseOdrIndicator = CodeGenOpts.SanitizeAddressUseOdrIndicator;
706 llvm::AsanDtorKind DestructorKind =
707 CodeGenOpts.getSanitizeAddressDtor();
708 AddressSanitizerOptions Opts;
709 Opts.CompileKernel = CompileKernel;
711 Opts.UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope;
712 Opts.UseAfterReturn = CodeGenOpts.getSanitizeAddressUseAfterReturn();
713 MPM.addPass(AddressSanitizerPass(Opts, UseGlobalGC, UseOdrIndicator,
717 ASanPass(SanitizerKind::Address,
false);
718 ASanPass(SanitizerKind::KernelAddress,
true);
720 auto HWASanPass = [&](
SanitizerMask Mask,
bool CompileKernel) {
723 MPM.addPass(HWAddressSanitizerPass(
724 {CompileKernel, Recover,
725 CodeGenOpts.OptimizationLevel == 0}));
728 HWASanPass(SanitizerKind::HWAddress,
false);
729 HWASanPass(SanitizerKind::KernelHWAddress,
true);
731 if (LangOpts.
Sanitize.
has(SanitizerKind::DataFlow)) {
736 PB.registerOptimizerEarlyEPCallback(
737 [SanitizersCallback](ModulePassManager &MPM, OptimizationLevel Level) {
738 ModulePassManager NewMPM;
739 SanitizersCallback(NewMPM, Level);
740 if (!NewMPM.isEmpty()) {
742 NewMPM.addPass(RequireAnalysisPass<GlobalsAA, Module>());
743 MPM.addPass(std::move(NewMPM));
748 PB.registerOptimizerLastEPCallback(SanitizersCallback);
752void EmitAssemblyHelper::RunOptimizationPipeline(
754 std::unique_ptr<llvm::ToolOutputFile> &ThinLinkOS) {
755 std::optional<PGOOptions> PGOOpt;
762 "",
"",
nullptr, PGOOptions::IRInstr, PGOOptions::NoCSAction,
763 CodeGenOpts.DebugInfoForProfiling);
767 : PGOOptions::NoCSAction;
771 CSAction, CodeGenOpts.DebugInfoForProfiling);
776 VFS, PGOOptions::SampleUse, PGOOptions::NoCSAction,
777 CodeGenOpts.DebugInfoForProfiling, CodeGenOpts.PseudoProbeForProfiling);
778 else if (CodeGenOpts.PseudoProbeForProfiling)
780 PGOOpt = PGOOptions(
"",
"",
"",
nullptr, PGOOptions::NoAction,
781 PGOOptions::NoCSAction,
782 CodeGenOpts.DebugInfoForProfiling,
true);
783 else if (CodeGenOpts.DebugInfoForProfiling)
785 PGOOpt = PGOOptions(
"",
"",
"",
nullptr, PGOOptions::NoAction,
786 PGOOptions::NoCSAction,
true);
791 "Cannot have both CSProfileUse pass and CSProfileGen pass at "
794 assert(PGOOpt->Action != PGOOptions::IRInstr &&
795 PGOOpt->Action != PGOOptions::SampleUse &&
796 "Cannot run CSProfileGen pass with ProfileGen or SampleUse "
799 ? getDefaultProfileGenName()
800 : CodeGenOpts.InstrProfileOutput;
801 PGOOpt->CSAction = PGOOptions::CSIRInstr;
806 ? getDefaultProfileGenName()
808 "",
nullptr, PGOOptions::NoAction, PGOOptions::CSIRInstr,
809 CodeGenOpts.DebugInfoForProfiling);
812 TM->setPGOOption(PGOOpt);
814 PipelineTuningOptions PTO;
815 PTO.LoopUnrolling = CodeGenOpts.UnrollLoops;
818 PTO.LoopInterleaving = CodeGenOpts.UnrollLoops;
819 PTO.LoopVectorization = CodeGenOpts.VectorizeLoop;
820 PTO.SLPVectorization = CodeGenOpts.VectorizeSLP;
821 PTO.MergeFunctions = CodeGenOpts.MergeFunctions;
824 PTO.CallGraphProfile = !CodeGenOpts.DisableIntegratedAS;
826 LoopAnalysisManager LAM;
827 FunctionAnalysisManager FAM;
828 CGSCCAnalysisManager CGAM;
829 ModuleAnalysisManager MAM;
831 bool DebugPassStructure = CodeGenOpts.
DebugPass ==
"Structure";
832 PassInstrumentationCallbacks PIC;
833 PrintPassOptions PrintPassOpts;
834 PrintPassOpts.Indent = DebugPassStructure;
835 PrintPassOpts.SkipAnalyses = DebugPassStructure;
836 StandardInstrumentations SI(
837 TheModule->getContext(),
838 (CodeGenOpts.DebugPassManager || DebugPassStructure),
839 false, PrintPassOpts);
840 SI.registerCallbacks(PIC, &MAM);
841 PassBuilder PB(TM.get(), PTO, PGOOpt, &PIC);
843 if (CodeGenOpts.EnableAssignmentTracking) {
844 PB.registerPipelineStartEPCallback(
845 [&](ModulePassManager &MPM, OptimizationLevel Level) {
846 MPM.addPass(AssignmentTrackingPass());
851 DebugifyEachInstrumentation Debugify;
852 DebugInfoPerPass DebugInfoBeforePass;
853 if (CodeGenOpts.EnableDIPreservationVerify) {
854 Debugify.setDebugifyMode(DebugifyMode::OriginalDebugInfo);
855 Debugify.setDebugInfoBeforePass(DebugInfoBeforePass);
858 Debugify.setOrigDIVerifyBugsReportFilePath(
860 Debugify.registerCallbacks(PIC, MAM);
864 auto PassPlugin = PassPlugin::Load(PluginFN);
866 PassPlugin->registerPassBuilderCallbacks(PB);
868 Diags.
Report(diag::err_fe_unable_to_load_plugin)
869 << PluginFN <<
toString(PassPlugin.takeError());
872#define HANDLE_EXTENSION(Ext) \
873 get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
874#include "llvm/Support/Extension.def"
878 std::unique_ptr<TargetLibraryInfoImpl> TLII(
880 FAM.registerPass([&] {
return TargetLibraryAnalysis(*TLII); });
883 PB.registerModuleAnalyses(MAM);
884 PB.registerCGSCCAnalyses(CGAM);
885 PB.registerFunctionAnalyses(FAM);
886 PB.registerLoopAnalyses(LAM);
887 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
889 ModulePassManager MPM;
891 if (!CodeGenOpts.DisableLLVMPasses) {
896 bool IsThinLTO = CodeGenOpts.PrepareForThinLTO;
897 bool IsLTO = CodeGenOpts.PrepareForLTO;
899 if (LangOpts.ObjCAutoRefCount) {
900 PB.registerPipelineStartEPCallback(
901 [](ModulePassManager &MPM, OptimizationLevel Level) {
902 if (Level != OptimizationLevel::O0)
904 createModuleToFunctionPassAdaptor(ObjCARCExpandPass()));
906 PB.registerPipelineEarlySimplificationEPCallback(
907 [](ModulePassManager &MPM, OptimizationLevel Level) {
908 if (Level != OptimizationLevel::O0)
909 MPM.addPass(ObjCARCAPElimPass());
911 PB.registerScalarOptimizerLateEPCallback(
912 [](FunctionPassManager &FPM, OptimizationLevel Level) {
913 if (Level != OptimizationLevel::O0)
914 FPM.addPass(ObjCARCOptPass());
924 if (IsThinLTOPostLink)
925 PB.registerPipelineStartEPCallback(
926 [](ModulePassManager &MPM, OptimizationLevel Level) {
927 MPM.addPass(LowerTypeTestsPass(
nullptr,
932 if (CodeGenOpts.InstrumentFunctions ||
933 CodeGenOpts.InstrumentFunctionEntryBare ||
934 CodeGenOpts.InstrumentFunctionsAfterInlining ||
935 CodeGenOpts.InstrumentForProfiling) {
936 PB.registerPipelineStartEPCallback(
937 [](ModulePassManager &MPM, OptimizationLevel Level) {
938 MPM.addPass(createModuleToFunctionPassAdaptor(
939 EntryExitInstrumenterPass(
false)));
941 PB.registerOptimizerLastEPCallback(
942 [](ModulePassManager &MPM, OptimizationLevel Level) {
943 MPM.addPass(createModuleToFunctionPassAdaptor(
944 EntryExitInstrumenterPass(
true)));
950 if (LangOpts.
Sanitize.
has(SanitizerKind::LocalBounds))
951 PB.registerScalarOptimizerLateEPCallback(
952 [](FunctionPassManager &FPM, OptimizationLevel Level) {
953 FPM.addPass(BoundsCheckingPass());
958 if (!IsThinLTOPostLink) {
963 if (std::optional<GCOVOptions> Options =
965 PB.registerPipelineStartEPCallback(
966 [Options](ModulePassManager &MPM, OptimizationLevel Level) {
967 MPM.addPass(GCOVProfilerPass(*Options));
969 if (std::optional<InstrProfOptions> Options =
971 PB.registerPipelineStartEPCallback(
972 [Options](ModulePassManager &MPM, OptimizationLevel Level) {
973 MPM.addPass(InstrProfiling(*Options,
false));
977 MPM = PB.buildThinLTOPreLinkDefaultPipeline(Level);
979 MPM = PB.buildLTOPreLinkDefaultPipeline(Level);
981 MPM = PB.buildPerModuleDefaultPipeline(Level);
985 MPM.addPass(createModuleToFunctionPassAdaptor(MemProfilerPass()));
986 MPM.addPass(ModuleMemProfilerPass());
994 MPM.addPass(VerifierPass());
997 if (CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.DisableLLVMPasses) {
998 if (!TheModule->getModuleFlag(
"EnableSplitLTOUnit"))
999 TheModule->addModuleFlag(Module::Error,
"EnableSplitLTOUnit",
1000 CodeGenOpts.EnableSplitLTOUnit);
1007 MPM.addPass(ThinLTOBitcodeWriterPass(*
OS, ThinLinkOS ? &ThinLinkOS->os()
1010 MPM.addPass(PrintModulePass(*
OS,
"", CodeGenOpts.EmitLLVMUseLists,
1017 bool EmitLTOSummary = shouldEmitRegularLTOSummary();
1018 if (EmitLTOSummary) {
1019 if (!TheModule->getModuleFlag(
"ThinLTO"))
1020 TheModule->addModuleFlag(Module::Error,
"ThinLTO", uint32_t(0));
1021 if (!TheModule->getModuleFlag(
"EnableSplitLTOUnit"))
1022 TheModule->addModuleFlag(Module::Error,
"EnableSplitLTOUnit",
1026 MPM.addPass(BitcodeWriterPass(*
OS, CodeGenOpts.EmitLLVMUseLists,
1029 MPM.addPass(PrintModulePass(*
OS,
"", CodeGenOpts.EmitLLVMUseLists,
1036 PrettyStackTraceString CrashInfo(
"Optimizer");
1037 llvm::TimeTraceScope TimeScope(
"Optimizer");
1038 MPM.run(*TheModule, MAM);
1042void EmitAssemblyHelper::RunCodegenPipeline(
1044 std::unique_ptr<llvm::ToolOutputFile> &DwoOS) {
1048 legacy::PassManager CodeGenPasses;
1056 createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
1062 if (!AddEmitPasses(CodeGenPasses, Action, *
OS,
1063 DwoOS ? &DwoOS->os() :
nullptr))
1072 PrettyStackTraceString CrashInfo(
"Code generation");
1073 llvm::TimeTraceScope TimeScope(
"CodeGenPasses");
1074 CodeGenPasses.run(*TheModule);
1079 std::unique_ptr<raw_pwrite_stream>
OS) {
1080 TimeRegion Region(CodeGenOpts.TimePasses ? &CodeGenerationTime :
nullptr);
1084 CreateTargetMachine(RequiresCodeGen);
1086 if (RequiresCodeGen && !TM)
1089 TheModule->setDataLayout(TM->createDataLayout());
1092 cl::PrintOptionValues();
1094 std::unique_ptr<llvm::ToolOutputFile> ThinLinkOS, DwoOS;
1095 RunOptimizationPipeline(Action,
OS, ThinLinkOS);
1096 RunCodegenPipeline(Action,
OS, DwoOS);
1108 std::unique_ptr<raw_pwrite_stream>
OS, std::string SampleProfile,
1110 StringMap<DenseMap<GlobalValue::GUID, GlobalValueSummary *>>
1111 ModuleToDefinedGVSummaries;
1112 CombinedIndex->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
1119 FunctionImporter::ImportMapTy ImportList;
1120 if (!lto::initImportList(*M, *CombinedIndex, ImportList))
1123 auto AddStream = [&](
size_t Task,
const Twine &ModuleName) {
1124 return std::make_unique<CachedFileStream>(std::move(
OS),
1131 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
1132 errs() <<
"Error setting up ThinLTO save-temps: " << EIB.message()
1137 Conf.CPU = TOpts.
CPU;
1141 std::optional<CodeGenOpt::Level> OptLevelOrNone =
1142 CodeGenOpt::getLevel(CGOpts.OptimizationLevel);
1143 assert(OptLevelOrNone &&
"Invalid optimization level!");
1144 Conf.CGOptLevel = *OptLevelOrNone;
1145 Conf.OptLevel = CGOpts.OptimizationLevel;
1147 Conf.SampleProfile = std::move(SampleProfile);
1148 Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops;
1151 Conf.PTO.LoopInterleaving = CGOpts.UnrollLoops;
1152 Conf.PTO.LoopVectorization = CGOpts.VectorizeLoop;
1153 Conf.PTO.SLPVectorization = CGOpts.VectorizeSLP;
1156 Conf.PTO.CallGraphProfile = !CGOpts.DisableIntegratedAS;
1160 Conf.RunCSIRInstr =
true;
1163 Conf.RunCSIRInstr =
false;
1167 Conf.ProfileRemapping = std::move(ProfileRemapping);
1168 Conf.DebugPassManager = CGOpts.DebugPassManager;
1169 Conf.RemarksWithHotness = CGOpts.DiagnosticsWithHotness;
1177 Conf.PreCodeGenModuleHook = [](
size_t Task,
const Module &Mod) {
1182 Conf.PreCodeGenModuleHook = [&](
size_t Task,
const Module &Mod) {
1183 M->
print(*
OS,
nullptr, CGOpts.EmitLLVMUseLists);
1188 Conf.PreCodeGenModuleHook = [&](
size_t Task,
const Module &Mod) {
1189 WriteBitcodeToFile(*M, *
OS, CGOpts.EmitLLVMUseLists);
1198 thinBackend(Conf, -1, AddStream, *M, *CombinedIndex, ImportList,
1199 ModuleToDefinedGVSummaries[M->getModuleIdentifier()],
1201 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
1202 errs() <<
"Error running ThinLTO backend: " << EIB.message() <<
'\n';
1214 std::unique_ptr<raw_pwrite_stream>
OS) {
1216 llvm::TimeTraceScope TimeScope(
"Backend");
1218 std::unique_ptr<llvm::Module> EmptyModule;
1223 std::unique_ptr<ModuleSummaryIndex> CombinedIndex;
1224 if (
Error E = llvm::getModuleSummaryIndexForFile(
1227 .moveInto(CombinedIndex)) {
1228 logAllUnhandledErrors(std::move(E), errs(),
1229 "Error loading index file '" +
1237 if (CombinedIndex) {
1238 if (!CombinedIndex->skipModuleByDistributedBackend()) {
1250 EmptyModule = std::make_unique<llvm::Module>(
"empty", M->getContext());
1251 EmptyModule->setTargetTriple(M->getTargetTriple());
1252 M = EmptyModule.get();
1256 EmitAssemblyHelper AsmHelper(Diags, HeaderOpts, CGOpts, TOpts, LOpts, M, VFS);
1257 AsmHelper.EmitAssembly(Action, std::move(
OS));
1262 std::string DLDesc = M->getDataLayout().getStringRepresentation();
1263 if (DLDesc != TDesc) {
1266 "expected target description '%1'");
1267 Diags.
Report(DiagID) << DLDesc << TDesc;
1275 llvm::MemoryBufferRef Buf) {
1278 llvm::embedBitcodeInModule(
1290 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ObjectOrErr =
1291 llvm::MemoryBuffer::getFileOrSTDIN(OffloadObject);
1292 if (std::error_code EC = ObjectOrErr.getError()) {
1294 "could not open '%0' for embedding");
1295 Diags.
Report(DiagID) << OffloadObject;
1299 llvm::embedBufferInModule(*M, **ObjectOrErr,
".llvm.offloading",
1300 Align(object::OffloadBinary::getAlignment()));
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(DiagnosticsEngine &Diags, ModuleSummaryIndex *CombinedIndex, Module *M, const HeaderSearchOptions &HeaderOpts, const CodeGenOptions &CGOpts, const clang::TargetOptions &TOpts, const LangOptions &LOpts, 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(DiagnosticsEngine &Diags, llvm::TargetOptions &Options, const CodeGenOptions &CodeGenOpts, const clang::TargetOptions &TargetOpts, const LangOptions &LangOpts, const HeaderSearchOptions &HSOpts)
static TargetLibraryInfoImpl * createTLII(llvm::Triple &TargetTriple, 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::optional< InstrProfOptions > getInstrProfOptions(const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts)
static bool asanUseGlobalsGC(const Triple &T, const CodeGenOptions &CGOpts)
static void setCommandLineOpts(const CodeGenOptions &CodeGenOpts)
static CodeGenFileType getCodeGenFileType(BackendAction Action)
Defines the Diagnostic-related interfaces.
Defines the clang::LangOptions interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the clang::TargetOptions class.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
std::string OptRecordFile
The name of the file to which the backend should save YAML optimization records.
std::string InstrProfileOutput
Name of the profile file to use as output for -fprofile-instr-generate, -fprofile-generate,...
std::string BinutilsVersion
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 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.
std::string MemoryProfileOutput
Name of the profile file to use as output for with -fmemory-profile.
std::string LimitFloatPrecision
The float precision limit to use, if non-empty.
std::string CodeModel
The code model to use (-mcmodel).
std::vector< std::string > PassPlugins
List of dynamic shared object files to be loaded as pass plugins.
bool hasProfileClangInstr() const
Check if Clang profile instrumenation is on.
std::string StackUsageOutput
Name of the stack usage file (i.e., .su file) if user passes -fstack-usage.
std::string OptRecordPasses
The regex that filters the passes that should be saved to the optimization records.
std::vector< std::string > SanitizeCoverageAllowlistFiles
Path to allowlist file specifying which objects (files, functions) should exclusively be instrumented...
std::string SaveTempsFilePrefix
Prefix to use for -save-temps output.
std::vector< std::string > SanitizeCoverageIgnorelistFiles
Path to ignorelist file specifying which objects (files, functions) listed for instrumentation by san...
bool hasSanitizeCoverage() const
bool hasProfileIRInstr() const
Check if IR level profile instrumentation is on.
bool hasProfileCSIRUse() const
Check if CSIR profile use is on.
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.
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::vector< std::string > CommandLineArgs
std::string OptRecordFormat
The format used for serializing remarks (default: YAML)
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.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool hasWasmExceptions() const
bool hasSjLjExceptions() const
SanitizerSet Sanitize
Set of enabled sanitizers.
bool hasDWARFExceptions() const
bool hasSEHExceptions() const
std::vector< std::string > NoSanitizeFiles
Paths to files specifying which objects (files, functions, variables) should not be instrumented.
Describes a module or submodule.
void print(raw_ostream &OS, unsigned Indent=0, bool Dump=false) const
Print the module map for this module to the given stream.
Options for controlling the target.
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.
@ EmitAssembly
Emit a .s file.
void EmbedObject(llvm::Module *M, const CodeGenOptions &CGOpts, DiagnosticsEngine &Diags)
void EmitBackendOutput(DiagnosticsEngine &Diags, const HeaderSearchOptions &, const CodeGenOptions &CGOpts, const TargetOptions &TOpts, const LangOptions &LOpts, StringRef TDesc, llvm::Module *M, BackendAction Action, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, std::unique_ptr< raw_pwrite_stream > OS)
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::MemoryBufferRef Buf)
@ Backend_EmitAssembly
Emit native assembly files.
@ Backend_EmitLL
Emit human-readable LLVM assembly.
@ Backend_EmitBC
Emit LLVM bitcode files.
@ Backend_EmitObj
Emit native object files.
@ Backend_EmitMCNull
Run CodeGen, but don't emit anything.
@ Backend_EmitNothing
Don't emit anything (benchmarking mode)
YAML serialization mapping.
cl::opt< bool > DebugInfoCorrelate
static cl::opt< bool > ClSanitizeOnOptimizerEarlyEP("sanitizer-early-opt-ep", cl::Optional, cl::desc("Insert sanitizers on OptimizerEarlyEP."), cl::init(false))
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.