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