xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/CodeGen/BackendUtil.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg //===--- BackendUtil.cpp - LLVM Backend Utilities -------------------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg 
97330f729Sjoerg #include "clang/CodeGen/BackendUtil.h"
107330f729Sjoerg #include "clang/Basic/CodeGenOptions.h"
117330f729Sjoerg #include "clang/Basic/Diagnostic.h"
127330f729Sjoerg #include "clang/Basic/LangOptions.h"
137330f729Sjoerg #include "clang/Basic/TargetOptions.h"
147330f729Sjoerg #include "clang/Frontend/FrontendDiagnostic.h"
157330f729Sjoerg #include "clang/Frontend/Utils.h"
167330f729Sjoerg #include "clang/Lex/HeaderSearchOptions.h"
177330f729Sjoerg #include "llvm/ADT/SmallSet.h"
187330f729Sjoerg #include "llvm/ADT/StringExtras.h"
197330f729Sjoerg #include "llvm/ADT/StringSwitch.h"
207330f729Sjoerg #include "llvm/ADT/Triple.h"
21*e038c9c4Sjoerg #include "llvm/Analysis/AliasAnalysis.h"
22*e038c9c4Sjoerg #include "llvm/Analysis/StackSafetyAnalysis.h"
237330f729Sjoerg #include "llvm/Analysis/TargetLibraryInfo.h"
247330f729Sjoerg #include "llvm/Analysis/TargetTransformInfo.h"
257330f729Sjoerg #include "llvm/Bitcode/BitcodeReader.h"
267330f729Sjoerg #include "llvm/Bitcode/BitcodeWriter.h"
277330f729Sjoerg #include "llvm/Bitcode/BitcodeWriterPass.h"
287330f729Sjoerg #include "llvm/CodeGen/RegAllocRegistry.h"
297330f729Sjoerg #include "llvm/CodeGen/SchedulerRegistry.h"
307330f729Sjoerg #include "llvm/CodeGen/TargetSubtargetInfo.h"
317330f729Sjoerg #include "llvm/IR/DataLayout.h"
327330f729Sjoerg #include "llvm/IR/IRPrintingPasses.h"
337330f729Sjoerg #include "llvm/IR/LegacyPassManager.h"
347330f729Sjoerg #include "llvm/IR/Module.h"
357330f729Sjoerg #include "llvm/IR/ModuleSummaryIndex.h"
36*e038c9c4Sjoerg #include "llvm/IR/PassManager.h"
377330f729Sjoerg #include "llvm/IR/Verifier.h"
387330f729Sjoerg #include "llvm/LTO/LTOBackend.h"
397330f729Sjoerg #include "llvm/MC/MCAsmInfo.h"
407330f729Sjoerg #include "llvm/MC/SubtargetFeature.h"
417330f729Sjoerg #include "llvm/Passes/PassBuilder.h"
427330f729Sjoerg #include "llvm/Passes/PassPlugin.h"
437330f729Sjoerg #include "llvm/Passes/StandardInstrumentations.h"
447330f729Sjoerg #include "llvm/Support/BuryPointer.h"
457330f729Sjoerg #include "llvm/Support/CommandLine.h"
467330f729Sjoerg #include "llvm/Support/MemoryBuffer.h"
477330f729Sjoerg #include "llvm/Support/PrettyStackTrace.h"
487330f729Sjoerg #include "llvm/Support/TargetRegistry.h"
497330f729Sjoerg #include "llvm/Support/TimeProfiler.h"
507330f729Sjoerg #include "llvm/Support/Timer.h"
51*e038c9c4Sjoerg #include "llvm/Support/ToolOutputFile.h"
527330f729Sjoerg #include "llvm/Support/raw_ostream.h"
537330f729Sjoerg #include "llvm/Target/TargetMachine.h"
547330f729Sjoerg #include "llvm/Target/TargetOptions.h"
557330f729Sjoerg #include "llvm/Transforms/Coroutines.h"
56*e038c9c4Sjoerg #include "llvm/Transforms/Coroutines/CoroCleanup.h"
57*e038c9c4Sjoerg #include "llvm/Transforms/Coroutines/CoroEarly.h"
58*e038c9c4Sjoerg #include "llvm/Transforms/Coroutines/CoroElide.h"
59*e038c9c4Sjoerg #include "llvm/Transforms/Coroutines/CoroSplit.h"
607330f729Sjoerg #include "llvm/Transforms/IPO.h"
617330f729Sjoerg #include "llvm/Transforms/IPO/AlwaysInliner.h"
62*e038c9c4Sjoerg #include "llvm/Transforms/IPO/LowerTypeTests.h"
637330f729Sjoerg #include "llvm/Transforms/IPO/PassManagerBuilder.h"
647330f729Sjoerg #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
657330f729Sjoerg #include "llvm/Transforms/InstCombine/InstCombine.h"
667330f729Sjoerg #include "llvm/Transforms/Instrumentation.h"
677330f729Sjoerg #include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
687330f729Sjoerg #include "llvm/Transforms/Instrumentation/BoundsChecking.h"
69*e038c9c4Sjoerg #include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h"
707330f729Sjoerg #include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
717330f729Sjoerg #include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
727330f729Sjoerg #include "llvm/Transforms/Instrumentation/InstrProfiling.h"
73*e038c9c4Sjoerg #include "llvm/Transforms/Instrumentation/MemProfiler.h"
747330f729Sjoerg #include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
757330f729Sjoerg #include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
767330f729Sjoerg #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
777330f729Sjoerg #include "llvm/Transforms/ObjCARC.h"
787330f729Sjoerg #include "llvm/Transforms/Scalar.h"
79*e038c9c4Sjoerg #include "llvm/Transforms/Scalar/EarlyCSE.h"
807330f729Sjoerg #include "llvm/Transforms/Scalar/GVN.h"
81*e038c9c4Sjoerg #include "llvm/Transforms/Scalar/LowerMatrixIntrinsics.h"
827330f729Sjoerg #include "llvm/Transforms/Utils.h"
837330f729Sjoerg #include "llvm/Transforms/Utils/CanonicalizeAliases.h"
84*e038c9c4Sjoerg #include "llvm/Transforms/Utils/Debugify.h"
857330f729Sjoerg #include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
867330f729Sjoerg #include "llvm/Transforms/Utils/NameAnonGlobals.h"
877330f729Sjoerg #include "llvm/Transforms/Utils/SymbolRewriter.h"
887330f729Sjoerg #include <memory>
897330f729Sjoerg using namespace clang;
907330f729Sjoerg using namespace llvm;
917330f729Sjoerg 
92*e038c9c4Sjoerg #define HANDLE_EXTENSION(Ext)                                                  \
93*e038c9c4Sjoerg   llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
94*e038c9c4Sjoerg #include "llvm/Support/Extension.def"
95*e038c9c4Sjoerg 
967330f729Sjoerg namespace {
977330f729Sjoerg 
987330f729Sjoerg // Default filename used for profile generation.
997330f729Sjoerg static constexpr StringLiteral DefaultProfileGenName = "default_%m.profraw";
1007330f729Sjoerg 
1017330f729Sjoerg class EmitAssemblyHelper {
1027330f729Sjoerg   DiagnosticsEngine &Diags;
1037330f729Sjoerg   const HeaderSearchOptions &HSOpts;
1047330f729Sjoerg   const CodeGenOptions &CodeGenOpts;
1057330f729Sjoerg   const clang::TargetOptions &TargetOpts;
1067330f729Sjoerg   const LangOptions &LangOpts;
1077330f729Sjoerg   Module *TheModule;
1087330f729Sjoerg 
1097330f729Sjoerg   Timer CodeGenerationTime;
1107330f729Sjoerg 
1117330f729Sjoerg   std::unique_ptr<raw_pwrite_stream> OS;
1127330f729Sjoerg 
getTargetIRAnalysis() const1137330f729Sjoerg   TargetIRAnalysis getTargetIRAnalysis() const {
1147330f729Sjoerg     if (TM)
1157330f729Sjoerg       return TM->getTargetIRAnalysis();
1167330f729Sjoerg 
1177330f729Sjoerg     return TargetIRAnalysis();
1187330f729Sjoerg   }
1197330f729Sjoerg 
1207330f729Sjoerg   void CreatePasses(legacy::PassManager &MPM, legacy::FunctionPassManager &FPM);
1217330f729Sjoerg 
1227330f729Sjoerg   /// Generates the TargetMachine.
1237330f729Sjoerg   /// Leaves TM unchanged if it is unable to create the target machine.
1247330f729Sjoerg   /// Some of our clang tests specify triples which are not built
1257330f729Sjoerg   /// into clang. This is okay because these tests check the generated
1267330f729Sjoerg   /// IR, and they require DataLayout which depends on the triple.
1277330f729Sjoerg   /// In this case, we allow this method to fail and not report an error.
1287330f729Sjoerg   /// When MustCreateTM is used, we print an error if we are unable to load
1297330f729Sjoerg   /// the requested target.
1307330f729Sjoerg   void CreateTargetMachine(bool MustCreateTM);
1317330f729Sjoerg 
1327330f729Sjoerg   /// Add passes necessary to emit assembly or LLVM IR.
1337330f729Sjoerg   ///
1347330f729Sjoerg   /// \return True on success.
1357330f729Sjoerg   bool AddEmitPasses(legacy::PassManager &CodeGenPasses, BackendAction Action,
1367330f729Sjoerg                      raw_pwrite_stream &OS, raw_pwrite_stream *DwoOS);
1377330f729Sjoerg 
openOutputFile(StringRef Path)1387330f729Sjoerg   std::unique_ptr<llvm::ToolOutputFile> openOutputFile(StringRef Path) {
1397330f729Sjoerg     std::error_code EC;
1407330f729Sjoerg     auto F = std::make_unique<llvm::ToolOutputFile>(Path, EC,
1417330f729Sjoerg                                                      llvm::sys::fs::OF_None);
1427330f729Sjoerg     if (EC) {
1437330f729Sjoerg       Diags.Report(diag::err_fe_unable_to_open_output) << Path << EC.message();
1447330f729Sjoerg       F.reset();
1457330f729Sjoerg     }
1467330f729Sjoerg     return F;
1477330f729Sjoerg   }
1487330f729Sjoerg 
1497330f729Sjoerg public:
EmitAssemblyHelper(DiagnosticsEngine & _Diags,const HeaderSearchOptions & HeaderSearchOpts,const CodeGenOptions & CGOpts,const clang::TargetOptions & TOpts,const LangOptions & LOpts,Module * M)1507330f729Sjoerg   EmitAssemblyHelper(DiagnosticsEngine &_Diags,
1517330f729Sjoerg                      const HeaderSearchOptions &HeaderSearchOpts,
1527330f729Sjoerg                      const CodeGenOptions &CGOpts,
1537330f729Sjoerg                      const clang::TargetOptions &TOpts,
1547330f729Sjoerg                      const LangOptions &LOpts, Module *M)
1557330f729Sjoerg       : Diags(_Diags), HSOpts(HeaderSearchOpts), CodeGenOpts(CGOpts),
1567330f729Sjoerg         TargetOpts(TOpts), LangOpts(LOpts), TheModule(M),
1577330f729Sjoerg         CodeGenerationTime("codegen", "Code Generation Time") {}
1587330f729Sjoerg 
~EmitAssemblyHelper()1597330f729Sjoerg   ~EmitAssemblyHelper() {
1607330f729Sjoerg     if (CodeGenOpts.DisableFree)
1617330f729Sjoerg       BuryPointer(std::move(TM));
1627330f729Sjoerg   }
1637330f729Sjoerg 
1647330f729Sjoerg   std::unique_ptr<TargetMachine> TM;
1657330f729Sjoerg 
1667330f729Sjoerg   void EmitAssembly(BackendAction Action,
1677330f729Sjoerg                     std::unique_ptr<raw_pwrite_stream> OS);
1687330f729Sjoerg 
1697330f729Sjoerg   void EmitAssemblyWithNewPassManager(BackendAction Action,
1707330f729Sjoerg                                       std::unique_ptr<raw_pwrite_stream> OS);
1717330f729Sjoerg };
1727330f729Sjoerg 
1737330f729Sjoerg // We need this wrapper to access LangOpts and CGOpts from extension functions
1747330f729Sjoerg // that we add to the PassManagerBuilder.
1757330f729Sjoerg class PassManagerBuilderWrapper : public PassManagerBuilder {
1767330f729Sjoerg public:
PassManagerBuilderWrapper(const Triple & TargetTriple,const CodeGenOptions & CGOpts,const LangOptions & LangOpts)1777330f729Sjoerg   PassManagerBuilderWrapper(const Triple &TargetTriple,
1787330f729Sjoerg                             const CodeGenOptions &CGOpts,
1797330f729Sjoerg                             const LangOptions &LangOpts)
1807330f729Sjoerg       : PassManagerBuilder(), TargetTriple(TargetTriple), CGOpts(CGOpts),
1817330f729Sjoerg         LangOpts(LangOpts) {}
getTargetTriple() const1827330f729Sjoerg   const Triple &getTargetTriple() const { return TargetTriple; }
getCGOpts() const1837330f729Sjoerg   const CodeGenOptions &getCGOpts() const { return CGOpts; }
getLangOpts() const1847330f729Sjoerg   const LangOptions &getLangOpts() const { return LangOpts; }
1857330f729Sjoerg 
1867330f729Sjoerg private:
1877330f729Sjoerg   const Triple &TargetTriple;
1887330f729Sjoerg   const CodeGenOptions &CGOpts;
1897330f729Sjoerg   const LangOptions &LangOpts;
1907330f729Sjoerg };
1917330f729Sjoerg }
1927330f729Sjoerg 
addObjCARCAPElimPass(const PassManagerBuilder & Builder,PassManagerBase & PM)1937330f729Sjoerg static void addObjCARCAPElimPass(const PassManagerBuilder &Builder, PassManagerBase &PM) {
1947330f729Sjoerg   if (Builder.OptLevel > 0)
1957330f729Sjoerg     PM.add(createObjCARCAPElimPass());
1967330f729Sjoerg }
1977330f729Sjoerg 
addObjCARCExpandPass(const PassManagerBuilder & Builder,PassManagerBase & PM)1987330f729Sjoerg static void addObjCARCExpandPass(const PassManagerBuilder &Builder, PassManagerBase &PM) {
1997330f729Sjoerg   if (Builder.OptLevel > 0)
2007330f729Sjoerg     PM.add(createObjCARCExpandPass());
2017330f729Sjoerg }
2027330f729Sjoerg 
addObjCARCOptPass(const PassManagerBuilder & Builder,PassManagerBase & PM)2037330f729Sjoerg static void addObjCARCOptPass(const PassManagerBuilder &Builder, PassManagerBase &PM) {
2047330f729Sjoerg   if (Builder.OptLevel > 0)
2057330f729Sjoerg     PM.add(createObjCARCOptPass());
2067330f729Sjoerg }
2077330f729Sjoerg 
addAddDiscriminatorsPass(const PassManagerBuilder & Builder,legacy::PassManagerBase & PM)2087330f729Sjoerg static void addAddDiscriminatorsPass(const PassManagerBuilder &Builder,
2097330f729Sjoerg                                      legacy::PassManagerBase &PM) {
2107330f729Sjoerg   PM.add(createAddDiscriminatorsPass());
2117330f729Sjoerg }
2127330f729Sjoerg 
addBoundsCheckingPass(const PassManagerBuilder & Builder,legacy::PassManagerBase & PM)2137330f729Sjoerg static void addBoundsCheckingPass(const PassManagerBuilder &Builder,
2147330f729Sjoerg                                   legacy::PassManagerBase &PM) {
2157330f729Sjoerg   PM.add(createBoundsCheckingLegacyPass());
2167330f729Sjoerg }
2177330f729Sjoerg 
2187330f729Sjoerg static SanitizerCoverageOptions
getSancovOptsFromCGOpts(const CodeGenOptions & CGOpts)2197330f729Sjoerg getSancovOptsFromCGOpts(const CodeGenOptions &CGOpts) {
2207330f729Sjoerg   SanitizerCoverageOptions Opts;
2217330f729Sjoerg   Opts.CoverageType =
2227330f729Sjoerg       static_cast<SanitizerCoverageOptions::Type>(CGOpts.SanitizeCoverageType);
2237330f729Sjoerg   Opts.IndirectCalls = CGOpts.SanitizeCoverageIndirectCalls;
2247330f729Sjoerg   Opts.TraceBB = CGOpts.SanitizeCoverageTraceBB;
2257330f729Sjoerg   Opts.TraceCmp = CGOpts.SanitizeCoverageTraceCmp;
2267330f729Sjoerg   Opts.TraceDiv = CGOpts.SanitizeCoverageTraceDiv;
2277330f729Sjoerg   Opts.TraceGep = CGOpts.SanitizeCoverageTraceGep;
2287330f729Sjoerg   Opts.Use8bitCounters = CGOpts.SanitizeCoverage8bitCounters;
2297330f729Sjoerg   Opts.TracePC = CGOpts.SanitizeCoverageTracePC;
2307330f729Sjoerg   Opts.TracePCGuard = CGOpts.SanitizeCoverageTracePCGuard;
2317330f729Sjoerg   Opts.NoPrune = CGOpts.SanitizeCoverageNoPrune;
2327330f729Sjoerg   Opts.Inline8bitCounters = CGOpts.SanitizeCoverageInline8bitCounters;
233*e038c9c4Sjoerg   Opts.InlineBoolFlag = CGOpts.SanitizeCoverageInlineBoolFlag;
2347330f729Sjoerg   Opts.PCTable = CGOpts.SanitizeCoveragePCTable;
2357330f729Sjoerg   Opts.StackDepth = CGOpts.SanitizeCoverageStackDepth;
2367330f729Sjoerg   return Opts;
2377330f729Sjoerg }
2387330f729Sjoerg 
addSanitizerCoveragePass(const PassManagerBuilder & Builder,legacy::PassManagerBase & PM)2397330f729Sjoerg static void addSanitizerCoveragePass(const PassManagerBuilder &Builder,
2407330f729Sjoerg                                      legacy::PassManagerBase &PM) {
2417330f729Sjoerg   const PassManagerBuilderWrapper &BuilderWrapper =
2427330f729Sjoerg       static_cast<const PassManagerBuilderWrapper &>(Builder);
2437330f729Sjoerg   const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
2447330f729Sjoerg   auto Opts = getSancovOptsFromCGOpts(CGOpts);
245*e038c9c4Sjoerg   PM.add(createModuleSanitizerCoverageLegacyPassPass(
246*e038c9c4Sjoerg       Opts, CGOpts.SanitizeCoverageAllowlistFiles,
247*e038c9c4Sjoerg       CGOpts.SanitizeCoverageIgnorelistFiles));
2487330f729Sjoerg }
2497330f729Sjoerg 
2507330f729Sjoerg // Check if ASan should use GC-friendly instrumentation for globals.
2517330f729Sjoerg // First of all, there is no point if -fdata-sections is off (expect for MachO,
2527330f729Sjoerg // where this is not a factor). Also, on ELF this feature requires an assembler
2537330f729Sjoerg // extension that only works with -integrated-as at the moment.
asanUseGlobalsGC(const Triple & T,const CodeGenOptions & CGOpts)2547330f729Sjoerg static bool asanUseGlobalsGC(const Triple &T, const CodeGenOptions &CGOpts) {
2557330f729Sjoerg   if (!CGOpts.SanitizeAddressGlobalsDeadStripping)
2567330f729Sjoerg     return false;
2577330f729Sjoerg   switch (T.getObjectFormat()) {
2587330f729Sjoerg   case Triple::MachO:
2597330f729Sjoerg   case Triple::COFF:
2607330f729Sjoerg     return true;
2617330f729Sjoerg   case Triple::ELF:
2627330f729Sjoerg     return CGOpts.DataSections && !CGOpts.DisableIntegratedAS;
263*e038c9c4Sjoerg   case Triple::GOFF:
264*e038c9c4Sjoerg     llvm::report_fatal_error("ASan not implemented for GOFF");
2657330f729Sjoerg   case Triple::XCOFF:
2667330f729Sjoerg     llvm::report_fatal_error("ASan not implemented for XCOFF.");
2677330f729Sjoerg   case Triple::Wasm:
2687330f729Sjoerg   case Triple::UnknownObjectFormat:
2697330f729Sjoerg     break;
2707330f729Sjoerg   }
2717330f729Sjoerg   return false;
2727330f729Sjoerg }
2737330f729Sjoerg 
addMemProfilerPasses(const PassManagerBuilder & Builder,legacy::PassManagerBase & PM)274*e038c9c4Sjoerg static void addMemProfilerPasses(const PassManagerBuilder &Builder,
275*e038c9c4Sjoerg                                  legacy::PassManagerBase &PM) {
276*e038c9c4Sjoerg   PM.add(createMemProfilerFunctionPass());
277*e038c9c4Sjoerg   PM.add(createModuleMemProfilerLegacyPassPass());
278*e038c9c4Sjoerg }
279*e038c9c4Sjoerg 
addAddressSanitizerPasses(const PassManagerBuilder & Builder,legacy::PassManagerBase & PM)2807330f729Sjoerg static void addAddressSanitizerPasses(const PassManagerBuilder &Builder,
2817330f729Sjoerg                                       legacy::PassManagerBase &PM) {
2827330f729Sjoerg   const PassManagerBuilderWrapper &BuilderWrapper =
2837330f729Sjoerg       static_cast<const PassManagerBuilderWrapper&>(Builder);
2847330f729Sjoerg   const Triple &T = BuilderWrapper.getTargetTriple();
2857330f729Sjoerg   const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
2867330f729Sjoerg   bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::Address);
2877330f729Sjoerg   bool UseAfterScope = CGOpts.SanitizeAddressUseAfterScope;
2887330f729Sjoerg   bool UseOdrIndicator = CGOpts.SanitizeAddressUseOdrIndicator;
2897330f729Sjoerg   bool UseGlobalsGC = asanUseGlobalsGC(T, CGOpts);
290*e038c9c4Sjoerg   llvm::AsanDtorKind DestructorKind = CGOpts.getSanitizeAddressDtor();
2917330f729Sjoerg   PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/ false, Recover,
2927330f729Sjoerg                                             UseAfterScope));
2937330f729Sjoerg   PM.add(createModuleAddressSanitizerLegacyPassPass(
294*e038c9c4Sjoerg       /*CompileKernel*/ false, Recover, UseGlobalsGC, UseOdrIndicator,
295*e038c9c4Sjoerg       DestructorKind));
2967330f729Sjoerg }
2977330f729Sjoerg 
addKernelAddressSanitizerPasses(const PassManagerBuilder & Builder,legacy::PassManagerBase & PM)2987330f729Sjoerg static void addKernelAddressSanitizerPasses(const PassManagerBuilder &Builder,
2997330f729Sjoerg                                             legacy::PassManagerBase &PM) {
3007330f729Sjoerg   PM.add(createAddressSanitizerFunctionPass(
3017330f729Sjoerg       /*CompileKernel*/ true, /*Recover*/ true, /*UseAfterScope*/ false));
3027330f729Sjoerg   PM.add(createModuleAddressSanitizerLegacyPassPass(
3037330f729Sjoerg       /*CompileKernel*/ true, /*Recover*/ true, /*UseGlobalsGC*/ true,
3047330f729Sjoerg       /*UseOdrIndicator*/ false));
3057330f729Sjoerg }
3067330f729Sjoerg 
addHWAddressSanitizerPasses(const PassManagerBuilder & Builder,legacy::PassManagerBase & PM)3077330f729Sjoerg static void addHWAddressSanitizerPasses(const PassManagerBuilder &Builder,
3087330f729Sjoerg                                             legacy::PassManagerBase &PM) {
3097330f729Sjoerg   const PassManagerBuilderWrapper &BuilderWrapper =
3107330f729Sjoerg       static_cast<const PassManagerBuilderWrapper &>(Builder);
3117330f729Sjoerg   const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
3127330f729Sjoerg   bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::HWAddress);
3137330f729Sjoerg   PM.add(
3147330f729Sjoerg       createHWAddressSanitizerLegacyPassPass(/*CompileKernel*/ false, Recover));
3157330f729Sjoerg }
3167330f729Sjoerg 
addKernelHWAddressSanitizerPasses(const PassManagerBuilder & Builder,legacy::PassManagerBase & PM)3177330f729Sjoerg static void addKernelHWAddressSanitizerPasses(const PassManagerBuilder &Builder,
3187330f729Sjoerg                                             legacy::PassManagerBase &PM) {
3197330f729Sjoerg   PM.add(createHWAddressSanitizerLegacyPassPass(
3207330f729Sjoerg       /*CompileKernel*/ true, /*Recover*/ true));
3217330f729Sjoerg }
3227330f729Sjoerg 
addGeneralOptsForMemorySanitizer(const PassManagerBuilder & Builder,legacy::PassManagerBase & PM,bool CompileKernel)3237330f729Sjoerg static void addGeneralOptsForMemorySanitizer(const PassManagerBuilder &Builder,
3247330f729Sjoerg                                              legacy::PassManagerBase &PM,
3257330f729Sjoerg                                              bool CompileKernel) {
3267330f729Sjoerg   const PassManagerBuilderWrapper &BuilderWrapper =
3277330f729Sjoerg       static_cast<const PassManagerBuilderWrapper&>(Builder);
3287330f729Sjoerg   const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
3297330f729Sjoerg   int TrackOrigins = CGOpts.SanitizeMemoryTrackOrigins;
3307330f729Sjoerg   bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::Memory);
3317330f729Sjoerg   PM.add(createMemorySanitizerLegacyPassPass(
3327330f729Sjoerg       MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel}));
3337330f729Sjoerg 
3347330f729Sjoerg   // MemorySanitizer inserts complex instrumentation that mostly follows
3357330f729Sjoerg   // the logic of the original code, but operates on "shadow" values.
3367330f729Sjoerg   // It can benefit from re-running some general purpose optimization passes.
3377330f729Sjoerg   if (Builder.OptLevel > 0) {
3387330f729Sjoerg     PM.add(createEarlyCSEPass());
3397330f729Sjoerg     PM.add(createReassociatePass());
3407330f729Sjoerg     PM.add(createLICMPass());
3417330f729Sjoerg     PM.add(createGVNPass());
3427330f729Sjoerg     PM.add(createInstructionCombiningPass());
3437330f729Sjoerg     PM.add(createDeadStoreEliminationPass());
3447330f729Sjoerg   }
3457330f729Sjoerg }
3467330f729Sjoerg 
addMemorySanitizerPass(const PassManagerBuilder & Builder,legacy::PassManagerBase & PM)3477330f729Sjoerg static void addMemorySanitizerPass(const PassManagerBuilder &Builder,
3487330f729Sjoerg                                    legacy::PassManagerBase &PM) {
3497330f729Sjoerg   addGeneralOptsForMemorySanitizer(Builder, PM, /*CompileKernel*/ false);
3507330f729Sjoerg }
3517330f729Sjoerg 
addKernelMemorySanitizerPass(const PassManagerBuilder & Builder,legacy::PassManagerBase & PM)3527330f729Sjoerg static void addKernelMemorySanitizerPass(const PassManagerBuilder &Builder,
3537330f729Sjoerg                                          legacy::PassManagerBase &PM) {
3547330f729Sjoerg   addGeneralOptsForMemorySanitizer(Builder, PM, /*CompileKernel*/ true);
3557330f729Sjoerg }
3567330f729Sjoerg 
addThreadSanitizerPass(const PassManagerBuilder & Builder,legacy::PassManagerBase & PM)3577330f729Sjoerg static void addThreadSanitizerPass(const PassManagerBuilder &Builder,
3587330f729Sjoerg                                    legacy::PassManagerBase &PM) {
3597330f729Sjoerg   PM.add(createThreadSanitizerLegacyPassPass());
3607330f729Sjoerg }
3617330f729Sjoerg 
addDataFlowSanitizerPass(const PassManagerBuilder & Builder,legacy::PassManagerBase & PM)3627330f729Sjoerg static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder,
3637330f729Sjoerg                                      legacy::PassManagerBase &PM) {
3647330f729Sjoerg   const PassManagerBuilderWrapper &BuilderWrapper =
3657330f729Sjoerg       static_cast<const PassManagerBuilderWrapper&>(Builder);
3667330f729Sjoerg   const LangOptions &LangOpts = BuilderWrapper.getLangOpts();
367*e038c9c4Sjoerg   PM.add(createDataFlowSanitizerLegacyPassPass(LangOpts.NoSanitizeFiles));
368*e038c9c4Sjoerg }
369*e038c9c4Sjoerg 
addEntryExitInstrumentationPass(const PassManagerBuilder & Builder,legacy::PassManagerBase & PM)370*e038c9c4Sjoerg static void addEntryExitInstrumentationPass(const PassManagerBuilder &Builder,
371*e038c9c4Sjoerg                                             legacy::PassManagerBase &PM) {
372*e038c9c4Sjoerg   PM.add(createEntryExitInstrumenterPass());
373*e038c9c4Sjoerg }
374*e038c9c4Sjoerg 
375*e038c9c4Sjoerg static void
addPostInlineEntryExitInstrumentationPass(const PassManagerBuilder & Builder,legacy::PassManagerBase & PM)376*e038c9c4Sjoerg addPostInlineEntryExitInstrumentationPass(const PassManagerBuilder &Builder,
377*e038c9c4Sjoerg                                           legacy::PassManagerBase &PM) {
378*e038c9c4Sjoerg   PM.add(createPostInlineEntryExitInstrumenterPass());
3797330f729Sjoerg }
3807330f729Sjoerg 
createTLII(llvm::Triple & TargetTriple,const CodeGenOptions & CodeGenOpts)3817330f729Sjoerg static TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple,
3827330f729Sjoerg                                          const CodeGenOptions &CodeGenOpts) {
3837330f729Sjoerg   TargetLibraryInfoImpl *TLII = new TargetLibraryInfoImpl(TargetTriple);
3847330f729Sjoerg 
3857330f729Sjoerg   switch (CodeGenOpts.getVecLib()) {
3867330f729Sjoerg   case CodeGenOptions::Accelerate:
3877330f729Sjoerg     TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::Accelerate);
3887330f729Sjoerg     break;
389*e038c9c4Sjoerg   case CodeGenOptions::LIBMVEC:
390*e038c9c4Sjoerg     switch(TargetTriple.getArch()) {
391*e038c9c4Sjoerg       default:
392*e038c9c4Sjoerg         break;
393*e038c9c4Sjoerg       case llvm::Triple::x86_64:
394*e038c9c4Sjoerg         TLII->addVectorizableFunctionsFromVecLib
395*e038c9c4Sjoerg                 (TargetLibraryInfoImpl::LIBMVEC_X86);
396*e038c9c4Sjoerg         break;
397*e038c9c4Sjoerg     }
398*e038c9c4Sjoerg     break;
3997330f729Sjoerg   case CodeGenOptions::MASSV:
4007330f729Sjoerg     TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::MASSV);
4017330f729Sjoerg     break;
4027330f729Sjoerg   case CodeGenOptions::SVML:
4037330f729Sjoerg     TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::SVML);
4047330f729Sjoerg     break;
405*e038c9c4Sjoerg   case CodeGenOptions::Darwin_libsystem_m:
406*e038c9c4Sjoerg     TLII->addVectorizableFunctionsFromVecLib(
407*e038c9c4Sjoerg         TargetLibraryInfoImpl::DarwinLibSystemM);
408*e038c9c4Sjoerg     break;
4097330f729Sjoerg   default:
4107330f729Sjoerg     break;
4117330f729Sjoerg   }
4127330f729Sjoerg   return TLII;
4137330f729Sjoerg }
4147330f729Sjoerg 
addSymbolRewriterPass(const CodeGenOptions & Opts,legacy::PassManager * MPM)4157330f729Sjoerg static void addSymbolRewriterPass(const CodeGenOptions &Opts,
4167330f729Sjoerg                                   legacy::PassManager *MPM) {
4177330f729Sjoerg   llvm::SymbolRewriter::RewriteDescriptorList DL;
4187330f729Sjoerg 
4197330f729Sjoerg   llvm::SymbolRewriter::RewriteMapParser MapParser;
4207330f729Sjoerg   for (const auto &MapFile : Opts.RewriteMapFiles)
4217330f729Sjoerg     MapParser.parse(MapFile, &DL);
4227330f729Sjoerg 
4237330f729Sjoerg   MPM->add(createRewriteSymbolsPass(DL));
4247330f729Sjoerg }
4257330f729Sjoerg 
getCGOptLevel(const CodeGenOptions & CodeGenOpts)4267330f729Sjoerg static CodeGenOpt::Level getCGOptLevel(const CodeGenOptions &CodeGenOpts) {
4277330f729Sjoerg   switch (CodeGenOpts.OptimizationLevel) {
4287330f729Sjoerg   default:
4297330f729Sjoerg     llvm_unreachable("Invalid optimization level!");
4307330f729Sjoerg   case 0:
4317330f729Sjoerg     return CodeGenOpt::None;
4327330f729Sjoerg   case 1:
4337330f729Sjoerg     return CodeGenOpt::Less;
4347330f729Sjoerg   case 2:
4357330f729Sjoerg     return CodeGenOpt::Default; // O2/Os/Oz
4367330f729Sjoerg   case 3:
4377330f729Sjoerg     return CodeGenOpt::Aggressive;
4387330f729Sjoerg   }
4397330f729Sjoerg }
4407330f729Sjoerg 
4417330f729Sjoerg static Optional<llvm::CodeModel::Model>
getCodeModel(const CodeGenOptions & CodeGenOpts)4427330f729Sjoerg getCodeModel(const CodeGenOptions &CodeGenOpts) {
4437330f729Sjoerg   unsigned CodeModel = llvm::StringSwitch<unsigned>(CodeGenOpts.CodeModel)
4447330f729Sjoerg                            .Case("tiny", llvm::CodeModel::Tiny)
4457330f729Sjoerg                            .Case("small", llvm::CodeModel::Small)
4467330f729Sjoerg                            .Case("kernel", llvm::CodeModel::Kernel)
4477330f729Sjoerg                            .Case("medium", llvm::CodeModel::Medium)
4487330f729Sjoerg                            .Case("large", llvm::CodeModel::Large)
4497330f729Sjoerg                            .Case("default", ~1u)
4507330f729Sjoerg                            .Default(~0u);
4517330f729Sjoerg   assert(CodeModel != ~0u && "invalid code model!");
4527330f729Sjoerg   if (CodeModel == ~1u)
4537330f729Sjoerg     return None;
4547330f729Sjoerg   return static_cast<llvm::CodeModel::Model>(CodeModel);
4557330f729Sjoerg }
4567330f729Sjoerg 
getCodeGenFileType(BackendAction Action)457*e038c9c4Sjoerg static CodeGenFileType getCodeGenFileType(BackendAction Action) {
4587330f729Sjoerg   if (Action == Backend_EmitObj)
459*e038c9c4Sjoerg     return CGFT_ObjectFile;
4607330f729Sjoerg   else if (Action == Backend_EmitMCNull)
461*e038c9c4Sjoerg     return CGFT_Null;
4627330f729Sjoerg   else {
4637330f729Sjoerg     assert(Action == Backend_EmitAssembly && "Invalid action!");
464*e038c9c4Sjoerg     return CGFT_AssemblyFile;
4657330f729Sjoerg   }
4667330f729Sjoerg }
4677330f729Sjoerg 
initTargetOptions(DiagnosticsEngine & Diags,llvm::TargetOptions & Options,const CodeGenOptions & CodeGenOpts,const clang::TargetOptions & TargetOpts,const LangOptions & LangOpts,const HeaderSearchOptions & HSOpts)468*e038c9c4Sjoerg static bool initTargetOptions(DiagnosticsEngine &Diags,
469*e038c9c4Sjoerg                               llvm::TargetOptions &Options,
4707330f729Sjoerg                               const CodeGenOptions &CodeGenOpts,
4717330f729Sjoerg                               const clang::TargetOptions &TargetOpts,
4727330f729Sjoerg                               const LangOptions &LangOpts,
4737330f729Sjoerg                               const HeaderSearchOptions &HSOpts) {
474*e038c9c4Sjoerg   switch (LangOpts.getThreadModel()) {
475*e038c9c4Sjoerg   case LangOptions::ThreadModelKind::POSIX:
476*e038c9c4Sjoerg     Options.ThreadModel = llvm::ThreadModel::POSIX;
477*e038c9c4Sjoerg     break;
478*e038c9c4Sjoerg   case LangOptions::ThreadModelKind::Single:
479*e038c9c4Sjoerg     Options.ThreadModel = llvm::ThreadModel::Single;
480*e038c9c4Sjoerg     break;
481*e038c9c4Sjoerg   }
4827330f729Sjoerg 
4837330f729Sjoerg   // Set float ABI type.
4847330f729Sjoerg   assert((CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp" ||
4857330f729Sjoerg           CodeGenOpts.FloatABI == "hard" || CodeGenOpts.FloatABI.empty()) &&
4867330f729Sjoerg          "Invalid Floating Point ABI!");
4877330f729Sjoerg   Options.FloatABIType =
4887330f729Sjoerg       llvm::StringSwitch<llvm::FloatABI::ABIType>(CodeGenOpts.FloatABI)
4897330f729Sjoerg           .Case("soft", llvm::FloatABI::Soft)
4907330f729Sjoerg           .Case("softfp", llvm::FloatABI::Soft)
4917330f729Sjoerg           .Case("hard", llvm::FloatABI::Hard)
4927330f729Sjoerg           .Default(llvm::FloatABI::Default);
4937330f729Sjoerg 
4947330f729Sjoerg   // Set FP fusion mode.
4957330f729Sjoerg   switch (LangOpts.getDefaultFPContractMode()) {
496*e038c9c4Sjoerg   case LangOptions::FPM_Off:
4977330f729Sjoerg     // Preserve any contraction performed by the front-end.  (Strict performs
4987330f729Sjoerg     // splitting of the muladd intrinsic in the backend.)
4997330f729Sjoerg     Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
5007330f729Sjoerg     break;
501*e038c9c4Sjoerg   case LangOptions::FPM_On:
502*e038c9c4Sjoerg   case LangOptions::FPM_FastHonorPragmas:
5037330f729Sjoerg     Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
5047330f729Sjoerg     break;
505*e038c9c4Sjoerg   case LangOptions::FPM_Fast:
5067330f729Sjoerg     Options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
5077330f729Sjoerg     break;
5087330f729Sjoerg   }
5097330f729Sjoerg 
510*e038c9c4Sjoerg   Options.BinutilsVersion =
511*e038c9c4Sjoerg       llvm::TargetMachine::parseBinutilsVersion(CodeGenOpts.BinutilsVersion);
5127330f729Sjoerg   Options.UseInitArray = CodeGenOpts.UseInitArray;
5137330f729Sjoerg   Options.DisableIntegratedAS = CodeGenOpts.DisableIntegratedAS;
5147330f729Sjoerg   Options.CompressDebugSections = CodeGenOpts.getCompressDebugSections();
5157330f729Sjoerg   Options.RelaxELFRelocations = CodeGenOpts.RelaxELFRelocations;
5167330f729Sjoerg 
5177330f729Sjoerg   // Set EABI version.
5187330f729Sjoerg   Options.EABIVersion = TargetOpts.EABIVersion;
5197330f729Sjoerg 
520*e038c9c4Sjoerg   if (LangOpts.hasSjLjExceptions())
5217330f729Sjoerg     Options.ExceptionModel = llvm::ExceptionHandling::SjLj;
522*e038c9c4Sjoerg   if (LangOpts.hasSEHExceptions())
5237330f729Sjoerg     Options.ExceptionModel = llvm::ExceptionHandling::WinEH;
524*e038c9c4Sjoerg   if (LangOpts.hasDWARFExceptions())
5257330f729Sjoerg     Options.ExceptionModel = llvm::ExceptionHandling::DwarfCFI;
526*e038c9c4Sjoerg   if (LangOpts.hasWasmExceptions())
5277330f729Sjoerg     Options.ExceptionModel = llvm::ExceptionHandling::Wasm;
5287330f729Sjoerg 
529*e038c9c4Sjoerg   Options.NoInfsFPMath = LangOpts.NoHonorInfs;
530*e038c9c4Sjoerg   Options.NoNaNsFPMath = LangOpts.NoHonorNaNs;
5317330f729Sjoerg   Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
532*e038c9c4Sjoerg   Options.UnsafeFPMath = LangOpts.UnsafeFPMath;
5337330f729Sjoerg   Options.StackAlignmentOverride = CodeGenOpts.StackAlignment;
534*e038c9c4Sjoerg 
535*e038c9c4Sjoerg   Options.BBSections =
536*e038c9c4Sjoerg       llvm::StringSwitch<llvm::BasicBlockSection>(CodeGenOpts.BBSections)
537*e038c9c4Sjoerg           .Case("all", llvm::BasicBlockSection::All)
538*e038c9c4Sjoerg           .Case("labels", llvm::BasicBlockSection::Labels)
539*e038c9c4Sjoerg           .StartsWith("list=", llvm::BasicBlockSection::List)
540*e038c9c4Sjoerg           .Case("none", llvm::BasicBlockSection::None)
541*e038c9c4Sjoerg           .Default(llvm::BasicBlockSection::None);
542*e038c9c4Sjoerg 
543*e038c9c4Sjoerg   if (Options.BBSections == llvm::BasicBlockSection::List) {
544*e038c9c4Sjoerg     ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
545*e038c9c4Sjoerg         MemoryBuffer::getFile(CodeGenOpts.BBSections.substr(5));
546*e038c9c4Sjoerg     if (!MBOrErr) {
547*e038c9c4Sjoerg       Diags.Report(diag::err_fe_unable_to_load_basic_block_sections_file)
548*e038c9c4Sjoerg           << MBOrErr.getError().message();
549*e038c9c4Sjoerg       return false;
550*e038c9c4Sjoerg     }
551*e038c9c4Sjoerg     Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
552*e038c9c4Sjoerg   }
553*e038c9c4Sjoerg 
554*e038c9c4Sjoerg   Options.EnableMachineFunctionSplitter = CodeGenOpts.SplitMachineFunctions;
5557330f729Sjoerg   Options.FunctionSections = CodeGenOpts.FunctionSections;
5567330f729Sjoerg   Options.DataSections = CodeGenOpts.DataSections;
557*e038c9c4Sjoerg   Options.IgnoreXCOFFVisibility = LangOpts.IgnoreXCOFFVisibility;
5587330f729Sjoerg   Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames;
559*e038c9c4Sjoerg   Options.UniqueBasicBlockSectionNames =
560*e038c9c4Sjoerg       CodeGenOpts.UniqueBasicBlockSectionNames;
561*e038c9c4Sjoerg   Options.TLSSize = CodeGenOpts.TLSSize;
5627330f729Sjoerg   Options.EmulatedTLS = CodeGenOpts.EmulatedTLS;
5637330f729Sjoerg   Options.ExplicitEmulatedTLS = CodeGenOpts.ExplicitEmulatedTLS;
5647330f729Sjoerg   Options.DebuggerTuning = CodeGenOpts.getDebuggerTuning();
5657330f729Sjoerg   Options.EmitStackSizeSection = CodeGenOpts.StackSizeSection;
566*e038c9c4Sjoerg   Options.StackUsageOutput = CodeGenOpts.StackUsageOutput;
5677330f729Sjoerg   Options.EmitAddrsig = CodeGenOpts.Addrsig;
568*e038c9c4Sjoerg   Options.ForceDwarfFrameSection = CodeGenOpts.ForceDwarfFrameSection;
569*e038c9c4Sjoerg   Options.EmitCallSiteInfo = CodeGenOpts.EmitCallSiteInfo;
570*e038c9c4Sjoerg   Options.EnableAIXExtendedAltivecABI = CodeGenOpts.EnableAIXExtendedAltivecABI;
571*e038c9c4Sjoerg   Options.PseudoProbeForProfiling = CodeGenOpts.PseudoProbeForProfiling;
572*e038c9c4Sjoerg   Options.ValueTrackingVariableLocations =
573*e038c9c4Sjoerg       CodeGenOpts.ValueTrackingVariableLocations;
574*e038c9c4Sjoerg   Options.XRayOmitFunctionIndex = CodeGenOpts.XRayOmitFunctionIndex;
5757330f729Sjoerg 
5767330f729Sjoerg   Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile;
5777330f729Sjoerg   Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
5787330f729Sjoerg   Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
5797330f729Sjoerg   Options.MCOptions.MCUseDwarfDirectory = !CodeGenOpts.NoDwarfDirectoryAsm;
5807330f729Sjoerg   Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack;
5817330f729Sjoerg   Options.MCOptions.MCIncrementalLinkerCompatible =
5827330f729Sjoerg       CodeGenOpts.IncrementalLinkerCompatible;
5837330f729Sjoerg   Options.MCOptions.MCFatalWarnings = CodeGenOpts.FatalWarnings;
5847330f729Sjoerg   Options.MCOptions.MCNoWarn = CodeGenOpts.NoWarn;
5857330f729Sjoerg   Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose;
586*e038c9c4Sjoerg   Options.MCOptions.Dwarf64 = CodeGenOpts.Dwarf64;
5877330f729Sjoerg   Options.MCOptions.PreserveAsmComments = CodeGenOpts.PreserveAsmComments;
5887330f729Sjoerg   Options.MCOptions.ABIName = TargetOpts.ABI;
5897330f729Sjoerg   for (const auto &Entry : HSOpts.UserEntries)
5907330f729Sjoerg     if (!Entry.IsFramework &&
5917330f729Sjoerg         (Entry.Group == frontend::IncludeDirGroup::Quoted ||
5927330f729Sjoerg          Entry.Group == frontend::IncludeDirGroup::Angled ||
5937330f729Sjoerg          Entry.Group == frontend::IncludeDirGroup::System))
5947330f729Sjoerg       Options.MCOptions.IASSearchPaths.push_back(
5957330f729Sjoerg           Entry.IgnoreSysRoot ? Entry.Path : HSOpts.Sysroot + Entry.Path);
596*e038c9c4Sjoerg   Options.MCOptions.Argv0 = CodeGenOpts.Argv0;
597*e038c9c4Sjoerg   Options.MCOptions.CommandLineArgs = CodeGenOpts.CommandLineArgs;
598*e038c9c4Sjoerg   Options.DebugStrictDwarf = CodeGenOpts.DebugStrictDwarf;
599*e038c9c4Sjoerg 
600*e038c9c4Sjoerg   return true;
6017330f729Sjoerg }
602*e038c9c4Sjoerg 
getGCOVOptions(const CodeGenOptions & CodeGenOpts,const LangOptions & LangOpts)603*e038c9c4Sjoerg static Optional<GCOVOptions> getGCOVOptions(const CodeGenOptions &CodeGenOpts,
604*e038c9c4Sjoerg                                             const LangOptions &LangOpts) {
6057330f729Sjoerg   if (!CodeGenOpts.EmitGcovArcs && !CodeGenOpts.EmitGcovNotes)
6067330f729Sjoerg     return None;
6077330f729Sjoerg   // Not using 'GCOVOptions::getDefault' allows us to avoid exiting if
6087330f729Sjoerg   // LLVM's -default-gcov-version flag is set to something invalid.
6097330f729Sjoerg   GCOVOptions Options;
6107330f729Sjoerg   Options.EmitNotes = CodeGenOpts.EmitGcovNotes;
6117330f729Sjoerg   Options.EmitData = CodeGenOpts.EmitGcovArcs;
6127330f729Sjoerg   llvm::copy(CodeGenOpts.CoverageVersion, std::begin(Options.Version));
6137330f729Sjoerg   Options.NoRedZone = CodeGenOpts.DisableRedZone;
6147330f729Sjoerg   Options.Filter = CodeGenOpts.ProfileFilterFiles;
6157330f729Sjoerg   Options.Exclude = CodeGenOpts.ProfileExcludeFiles;
616*e038c9c4Sjoerg   Options.Atomic = CodeGenOpts.AtomicProfileUpdate;
6177330f729Sjoerg   return Options;
6187330f729Sjoerg }
6197330f729Sjoerg 
6207330f729Sjoerg static Optional<InstrProfOptions>
getInstrProfOptions(const CodeGenOptions & CodeGenOpts,const LangOptions & LangOpts)6217330f729Sjoerg getInstrProfOptions(const CodeGenOptions &CodeGenOpts,
6227330f729Sjoerg                     const LangOptions &LangOpts) {
6237330f729Sjoerg   if (!CodeGenOpts.hasProfileClangInstr())
6247330f729Sjoerg     return None;
6257330f729Sjoerg   InstrProfOptions Options;
6267330f729Sjoerg   Options.NoRedZone = CodeGenOpts.DisableRedZone;
6277330f729Sjoerg   Options.InstrProfileOutput = CodeGenOpts.InstrProfileOutput;
628*e038c9c4Sjoerg   Options.Atomic = CodeGenOpts.AtomicProfileUpdate;
6297330f729Sjoerg   return Options;
6307330f729Sjoerg }
6317330f729Sjoerg 
CreatePasses(legacy::PassManager & MPM,legacy::FunctionPassManager & FPM)6327330f729Sjoerg void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
6337330f729Sjoerg                                       legacy::FunctionPassManager &FPM) {
6347330f729Sjoerg   // Handle disabling of all LLVM passes, where we want to preserve the
6357330f729Sjoerg   // internal module before any optimization.
6367330f729Sjoerg   if (CodeGenOpts.DisableLLVMPasses)
6377330f729Sjoerg     return;
6387330f729Sjoerg 
6397330f729Sjoerg   // Figure out TargetLibraryInfo.  This needs to be added to MPM and FPM
6407330f729Sjoerg   // manually (and not via PMBuilder), since some passes (eg. InstrProfiling)
6417330f729Sjoerg   // are inserted before PMBuilder ones - they'd get the default-constructed
6427330f729Sjoerg   // TLI with an unknown target otherwise.
6437330f729Sjoerg   Triple TargetTriple(TheModule->getTargetTriple());
6447330f729Sjoerg   std::unique_ptr<TargetLibraryInfoImpl> TLII(
6457330f729Sjoerg       createTLII(TargetTriple, CodeGenOpts));
6467330f729Sjoerg 
647*e038c9c4Sjoerg   // If we reached here with a non-empty index file name, then the index file
648*e038c9c4Sjoerg   // was empty and we are not performing ThinLTO backend compilation (used in
649*e038c9c4Sjoerg   // testing in a distributed build environment). Drop any the type test
650*e038c9c4Sjoerg   // assume sequences inserted for whole program vtables so that codegen doesn't
651*e038c9c4Sjoerg   // complain.
652*e038c9c4Sjoerg   if (!CodeGenOpts.ThinLTOIndexFile.empty())
653*e038c9c4Sjoerg     MPM.add(createLowerTypeTestsPass(/*ExportSummary=*/nullptr,
654*e038c9c4Sjoerg                                      /*ImportSummary=*/nullptr,
655*e038c9c4Sjoerg                                      /*DropTypeTests=*/true));
656*e038c9c4Sjoerg 
6577330f729Sjoerg   PassManagerBuilderWrapper PMBuilder(TargetTriple, CodeGenOpts, LangOpts);
6587330f729Sjoerg 
6597330f729Sjoerg   // At O0 and O1 we only run the always inliner which is more efficient. At
6607330f729Sjoerg   // higher optimization levels we run the normal inliner.
6617330f729Sjoerg   if (CodeGenOpts.OptimizationLevel <= 1) {
662*e038c9c4Sjoerg     bool InsertLifetimeIntrinsics = ((CodeGenOpts.OptimizationLevel != 0 &&
663*e038c9c4Sjoerg                                       !CodeGenOpts.DisableLifetimeMarkers) ||
664*e038c9c4Sjoerg                                      LangOpts.Coroutines);
6657330f729Sjoerg     PMBuilder.Inliner = createAlwaysInlinerLegacyPass(InsertLifetimeIntrinsics);
6667330f729Sjoerg   } else {
6677330f729Sjoerg     // We do not want to inline hot callsites for SamplePGO module-summary build
6687330f729Sjoerg     // because profile annotation will happen again in ThinLTO backend, and we
6697330f729Sjoerg     // want the IR of the hot path to match the profile.
6707330f729Sjoerg     PMBuilder.Inliner = createFunctionInliningPass(
6717330f729Sjoerg         CodeGenOpts.OptimizationLevel, CodeGenOpts.OptimizeSize,
6727330f729Sjoerg         (!CodeGenOpts.SampleProfileFile.empty() &&
6737330f729Sjoerg          CodeGenOpts.PrepareForThinLTO));
6747330f729Sjoerg   }
6757330f729Sjoerg 
6767330f729Sjoerg   PMBuilder.OptLevel = CodeGenOpts.OptimizationLevel;
6777330f729Sjoerg   PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize;
6787330f729Sjoerg   PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP;
6797330f729Sjoerg   PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop;
680*e038c9c4Sjoerg   // Only enable CGProfilePass when using integrated assembler, since
681*e038c9c4Sjoerg   // non-integrated assemblers don't recognize .cgprofile section.
682*e038c9c4Sjoerg   PMBuilder.CallGraphProfile = !CodeGenOpts.DisableIntegratedAS;
6837330f729Sjoerg 
6847330f729Sjoerg   PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;
6857330f729Sjoerg   // Loop interleaving in the loop vectorizer has historically been set to be
6867330f729Sjoerg   // enabled when loop unrolling is enabled.
6877330f729Sjoerg   PMBuilder.LoopsInterleaved = CodeGenOpts.UnrollLoops;
6887330f729Sjoerg   PMBuilder.MergeFunctions = CodeGenOpts.MergeFunctions;
6897330f729Sjoerg   PMBuilder.PrepareForThinLTO = CodeGenOpts.PrepareForThinLTO;
6907330f729Sjoerg   PMBuilder.PrepareForLTO = CodeGenOpts.PrepareForLTO;
6917330f729Sjoerg   PMBuilder.RerollLoops = CodeGenOpts.RerollLoops;
6927330f729Sjoerg 
6937330f729Sjoerg   MPM.add(new TargetLibraryInfoWrapperPass(*TLII));
6947330f729Sjoerg 
6957330f729Sjoerg   if (TM)
6967330f729Sjoerg     TM->adjustPassManager(PMBuilder);
6977330f729Sjoerg 
6987330f729Sjoerg   if (CodeGenOpts.DebugInfoForProfiling ||
6997330f729Sjoerg       !CodeGenOpts.SampleProfileFile.empty())
7007330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
7017330f729Sjoerg                            addAddDiscriminatorsPass);
7027330f729Sjoerg 
7037330f729Sjoerg   // In ObjC ARC mode, add the main ARC optimization passes.
7047330f729Sjoerg   if (LangOpts.ObjCAutoRefCount) {
7057330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
7067330f729Sjoerg                            addObjCARCExpandPass);
7077330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly,
7087330f729Sjoerg                            addObjCARCAPElimPass);
7097330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
7107330f729Sjoerg                            addObjCARCOptPass);
7117330f729Sjoerg   }
7127330f729Sjoerg 
7137330f729Sjoerg   if (LangOpts.Coroutines)
7147330f729Sjoerg     addCoroutinePassesToExtensionPoints(PMBuilder);
7157330f729Sjoerg 
716*e038c9c4Sjoerg   if (!CodeGenOpts.MemoryProfileOutput.empty()) {
717*e038c9c4Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
718*e038c9c4Sjoerg                            addMemProfilerPasses);
719*e038c9c4Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
720*e038c9c4Sjoerg                            addMemProfilerPasses);
721*e038c9c4Sjoerg   }
722*e038c9c4Sjoerg 
7237330f729Sjoerg   if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) {
7247330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
7257330f729Sjoerg                            addBoundsCheckingPass);
7267330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
7277330f729Sjoerg                            addBoundsCheckingPass);
7287330f729Sjoerg   }
7297330f729Sjoerg 
7307330f729Sjoerg   if (CodeGenOpts.SanitizeCoverageType ||
7317330f729Sjoerg       CodeGenOpts.SanitizeCoverageIndirectCalls ||
7327330f729Sjoerg       CodeGenOpts.SanitizeCoverageTraceCmp) {
7337330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
7347330f729Sjoerg                            addSanitizerCoveragePass);
7357330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
7367330f729Sjoerg                            addSanitizerCoveragePass);
7377330f729Sjoerg   }
7387330f729Sjoerg 
7397330f729Sjoerg   if (LangOpts.Sanitize.has(SanitizerKind::Address)) {
7407330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
7417330f729Sjoerg                            addAddressSanitizerPasses);
7427330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
7437330f729Sjoerg                            addAddressSanitizerPasses);
7447330f729Sjoerg   }
7457330f729Sjoerg 
7467330f729Sjoerg   if (LangOpts.Sanitize.has(SanitizerKind::KernelAddress)) {
7477330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
7487330f729Sjoerg                            addKernelAddressSanitizerPasses);
7497330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
7507330f729Sjoerg                            addKernelAddressSanitizerPasses);
7517330f729Sjoerg   }
7527330f729Sjoerg 
7537330f729Sjoerg   if (LangOpts.Sanitize.has(SanitizerKind::HWAddress)) {
7547330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
7557330f729Sjoerg                            addHWAddressSanitizerPasses);
7567330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
7577330f729Sjoerg                            addHWAddressSanitizerPasses);
7587330f729Sjoerg   }
7597330f729Sjoerg 
7607330f729Sjoerg   if (LangOpts.Sanitize.has(SanitizerKind::KernelHWAddress)) {
7617330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
7627330f729Sjoerg                            addKernelHWAddressSanitizerPasses);
7637330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
7647330f729Sjoerg                            addKernelHWAddressSanitizerPasses);
7657330f729Sjoerg   }
7667330f729Sjoerg 
7677330f729Sjoerg   if (LangOpts.Sanitize.has(SanitizerKind::Memory)) {
7687330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
7697330f729Sjoerg                            addMemorySanitizerPass);
7707330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
7717330f729Sjoerg                            addMemorySanitizerPass);
7727330f729Sjoerg   }
7737330f729Sjoerg 
7747330f729Sjoerg   if (LangOpts.Sanitize.has(SanitizerKind::KernelMemory)) {
7757330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
7767330f729Sjoerg                            addKernelMemorySanitizerPass);
7777330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
7787330f729Sjoerg                            addKernelMemorySanitizerPass);
7797330f729Sjoerg   }
7807330f729Sjoerg 
7817330f729Sjoerg   if (LangOpts.Sanitize.has(SanitizerKind::Thread)) {
7827330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
7837330f729Sjoerg                            addThreadSanitizerPass);
7847330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
7857330f729Sjoerg                            addThreadSanitizerPass);
7867330f729Sjoerg   }
7877330f729Sjoerg 
7887330f729Sjoerg   if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) {
7897330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
7907330f729Sjoerg                            addDataFlowSanitizerPass);
7917330f729Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
7927330f729Sjoerg                            addDataFlowSanitizerPass);
7937330f729Sjoerg   }
7947330f729Sjoerg 
795*e038c9c4Sjoerg   if (CodeGenOpts.InstrumentFunctions ||
796*e038c9c4Sjoerg       CodeGenOpts.InstrumentFunctionEntryBare ||
797*e038c9c4Sjoerg       CodeGenOpts.InstrumentFunctionsAfterInlining ||
798*e038c9c4Sjoerg       CodeGenOpts.InstrumentForProfiling) {
799*e038c9c4Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
800*e038c9c4Sjoerg                            addEntryExitInstrumentationPass);
801*e038c9c4Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
802*e038c9c4Sjoerg                            addEntryExitInstrumentationPass);
803*e038c9c4Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
804*e038c9c4Sjoerg                            addPostInlineEntryExitInstrumentationPass);
805*e038c9c4Sjoerg     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
806*e038c9c4Sjoerg                            addPostInlineEntryExitInstrumentationPass);
807*e038c9c4Sjoerg   }
808*e038c9c4Sjoerg 
8097330f729Sjoerg   // Set up the per-function pass manager.
8107330f729Sjoerg   FPM.add(new TargetLibraryInfoWrapperPass(*TLII));
8117330f729Sjoerg   if (CodeGenOpts.VerifyModule)
8127330f729Sjoerg     FPM.add(createVerifierPass());
8137330f729Sjoerg 
8147330f729Sjoerg   // Set up the per-module pass manager.
8157330f729Sjoerg   if (!CodeGenOpts.RewriteMapFiles.empty())
8167330f729Sjoerg     addSymbolRewriterPass(CodeGenOpts, &MPM);
8177330f729Sjoerg 
818*e038c9c4Sjoerg   if (Optional<GCOVOptions> Options = getGCOVOptions(CodeGenOpts, LangOpts)) {
8197330f729Sjoerg     MPM.add(createGCOVProfilerPass(*Options));
8207330f729Sjoerg     if (CodeGenOpts.getDebugInfo() == codegenoptions::NoDebugInfo)
8217330f729Sjoerg       MPM.add(createStripSymbolsPass(true));
8227330f729Sjoerg   }
8237330f729Sjoerg 
8247330f729Sjoerg   if (Optional<InstrProfOptions> Options =
8257330f729Sjoerg           getInstrProfOptions(CodeGenOpts, LangOpts))
8267330f729Sjoerg     MPM.add(createInstrProfilingLegacyPass(*Options, false));
8277330f729Sjoerg 
8287330f729Sjoerg   bool hasIRInstr = false;
8297330f729Sjoerg   if (CodeGenOpts.hasProfileIRInstr()) {
8307330f729Sjoerg     PMBuilder.EnablePGOInstrGen = true;
8317330f729Sjoerg     hasIRInstr = true;
8327330f729Sjoerg   }
8337330f729Sjoerg   if (CodeGenOpts.hasProfileCSIRInstr()) {
8347330f729Sjoerg     assert(!CodeGenOpts.hasProfileCSIRUse() &&
8357330f729Sjoerg            "Cannot have both CSProfileUse pass and CSProfileGen pass at the "
8367330f729Sjoerg            "same time");
8377330f729Sjoerg     assert(!hasIRInstr &&
8387330f729Sjoerg            "Cannot have both ProfileGen pass and CSProfileGen pass at the "
8397330f729Sjoerg            "same time");
8407330f729Sjoerg     PMBuilder.EnablePGOCSInstrGen = true;
8417330f729Sjoerg     hasIRInstr = true;
8427330f729Sjoerg   }
8437330f729Sjoerg   if (hasIRInstr) {
8447330f729Sjoerg     if (!CodeGenOpts.InstrProfileOutput.empty())
8457330f729Sjoerg       PMBuilder.PGOInstrGen = CodeGenOpts.InstrProfileOutput;
8467330f729Sjoerg     else
847*e038c9c4Sjoerg       PMBuilder.PGOInstrGen = std::string(DefaultProfileGenName);
8487330f729Sjoerg   }
8497330f729Sjoerg   if (CodeGenOpts.hasProfileIRUse()) {
8507330f729Sjoerg     PMBuilder.PGOInstrUse = CodeGenOpts.ProfileInstrumentUsePath;
8517330f729Sjoerg     PMBuilder.EnablePGOCSInstrUse = CodeGenOpts.hasProfileCSIRUse();
8527330f729Sjoerg   }
8537330f729Sjoerg 
8547330f729Sjoerg   if (!CodeGenOpts.SampleProfileFile.empty())
8557330f729Sjoerg     PMBuilder.PGOSampleUse = CodeGenOpts.SampleProfileFile;
8567330f729Sjoerg 
8577330f729Sjoerg   PMBuilder.populateFunctionPassManager(FPM);
8587330f729Sjoerg   PMBuilder.populateModulePassManager(MPM);
8597330f729Sjoerg }
8607330f729Sjoerg 
setCommandLineOpts(const CodeGenOptions & CodeGenOpts)8617330f729Sjoerg static void setCommandLineOpts(const CodeGenOptions &CodeGenOpts) {
8627330f729Sjoerg   SmallVector<const char *, 16> BackendArgs;
8637330f729Sjoerg   BackendArgs.push_back("clang"); // Fake program name.
8647330f729Sjoerg   if (!CodeGenOpts.DebugPass.empty()) {
8657330f729Sjoerg     BackendArgs.push_back("-debug-pass");
8667330f729Sjoerg     BackendArgs.push_back(CodeGenOpts.DebugPass.c_str());
8677330f729Sjoerg   }
8687330f729Sjoerg   if (!CodeGenOpts.LimitFloatPrecision.empty()) {
8697330f729Sjoerg     BackendArgs.push_back("-limit-float-precision");
8707330f729Sjoerg     BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str());
8717330f729Sjoerg   }
872*e038c9c4Sjoerg   // Check for the default "clang" invocation that won't set any cl::opt values.
873*e038c9c4Sjoerg   // Skip trying to parse the command line invocation to avoid the issues
874*e038c9c4Sjoerg   // described below.
875*e038c9c4Sjoerg   if (BackendArgs.size() == 1)
876*e038c9c4Sjoerg     return;
8777330f729Sjoerg   BackendArgs.push_back(nullptr);
878*e038c9c4Sjoerg   // FIXME: The command line parser below is not thread-safe and shares a global
879*e038c9c4Sjoerg   // state, so this call might crash or overwrite the options of another Clang
880*e038c9c4Sjoerg   // instance in the same process.
8817330f729Sjoerg   llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
8827330f729Sjoerg                                     BackendArgs.data());
8837330f729Sjoerg }
8847330f729Sjoerg 
CreateTargetMachine(bool MustCreateTM)8857330f729Sjoerg void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
8867330f729Sjoerg   // Create the TargetMachine for generating code.
8877330f729Sjoerg   std::string Error;
8887330f729Sjoerg   std::string Triple = TheModule->getTargetTriple();
8897330f729Sjoerg   const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
8907330f729Sjoerg   if (!TheTarget) {
8917330f729Sjoerg     if (MustCreateTM)
8927330f729Sjoerg       Diags.Report(diag::err_fe_unable_to_create_target) << Error;
8937330f729Sjoerg     return;
8947330f729Sjoerg   }
8957330f729Sjoerg 
8967330f729Sjoerg   Optional<llvm::CodeModel::Model> CM = getCodeModel(CodeGenOpts);
8977330f729Sjoerg   std::string FeaturesStr =
8987330f729Sjoerg       llvm::join(TargetOpts.Features.begin(), TargetOpts.Features.end(), ",");
8997330f729Sjoerg   llvm::Reloc::Model RM = CodeGenOpts.RelocationModel;
9007330f729Sjoerg   CodeGenOpt::Level OptLevel = getCGOptLevel(CodeGenOpts);
9017330f729Sjoerg 
9027330f729Sjoerg   llvm::TargetOptions Options;
903*e038c9c4Sjoerg   if (!initTargetOptions(Diags, Options, CodeGenOpts, TargetOpts, LangOpts,
904*e038c9c4Sjoerg                          HSOpts))
905*e038c9c4Sjoerg     return;
9067330f729Sjoerg   TM.reset(TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr,
9077330f729Sjoerg                                           Options, RM, CM, OptLevel));
9087330f729Sjoerg }
9097330f729Sjoerg 
AddEmitPasses(legacy::PassManager & CodeGenPasses,BackendAction Action,raw_pwrite_stream & OS,raw_pwrite_stream * DwoOS)9107330f729Sjoerg bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses,
9117330f729Sjoerg                                        BackendAction Action,
9127330f729Sjoerg                                        raw_pwrite_stream &OS,
9137330f729Sjoerg                                        raw_pwrite_stream *DwoOS) {
9147330f729Sjoerg   // Add LibraryInfo.
9157330f729Sjoerg   llvm::Triple TargetTriple(TheModule->getTargetTriple());
9167330f729Sjoerg   std::unique_ptr<TargetLibraryInfoImpl> TLII(
9177330f729Sjoerg       createTLII(TargetTriple, CodeGenOpts));
9187330f729Sjoerg   CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII));
9197330f729Sjoerg 
9207330f729Sjoerg   // Normal mode, emit a .s or .o file by running the code generator. Note,
9217330f729Sjoerg   // this also adds codegenerator level optimization passes.
922*e038c9c4Sjoerg   CodeGenFileType CGFT = getCodeGenFileType(Action);
9237330f729Sjoerg 
9247330f729Sjoerg   // Add ObjC ARC final-cleanup optimizations. This is done as part of the
9257330f729Sjoerg   // "codegen" passes so that it isn't run multiple times when there is
9267330f729Sjoerg   // inlining happening.
9277330f729Sjoerg   if (CodeGenOpts.OptimizationLevel > 0)
9287330f729Sjoerg     CodeGenPasses.add(createObjCARCContractPass());
9297330f729Sjoerg 
9307330f729Sjoerg   if (TM->addPassesToEmitFile(CodeGenPasses, OS, DwoOS, CGFT,
9317330f729Sjoerg                               /*DisableVerify=*/!CodeGenOpts.VerifyModule)) {
9327330f729Sjoerg     Diags.Report(diag::err_fe_unable_to_interface_with_target);
9337330f729Sjoerg     return false;
9347330f729Sjoerg   }
9357330f729Sjoerg 
9367330f729Sjoerg   return true;
9377330f729Sjoerg }
9387330f729Sjoerg 
EmitAssembly(BackendAction Action,std::unique_ptr<raw_pwrite_stream> OS)9397330f729Sjoerg void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
9407330f729Sjoerg                                       std::unique_ptr<raw_pwrite_stream> OS) {
941*e038c9c4Sjoerg   TimeRegion Region(CodeGenOpts.TimePasses ? &CodeGenerationTime : nullptr);
9427330f729Sjoerg 
9437330f729Sjoerg   setCommandLineOpts(CodeGenOpts);
9447330f729Sjoerg 
9457330f729Sjoerg   bool UsesCodeGen = (Action != Backend_EmitNothing &&
9467330f729Sjoerg                       Action != Backend_EmitBC &&
9477330f729Sjoerg                       Action != Backend_EmitLL);
9487330f729Sjoerg   CreateTargetMachine(UsesCodeGen);
9497330f729Sjoerg 
9507330f729Sjoerg   if (UsesCodeGen && !TM)
9517330f729Sjoerg     return;
9527330f729Sjoerg   if (TM)
9537330f729Sjoerg     TheModule->setDataLayout(TM->createDataLayout());
9547330f729Sjoerg 
955*e038c9c4Sjoerg   DebugifyCustomPassManager PerModulePasses;
956*e038c9c4Sjoerg   DebugInfoPerPassMap DIPreservationMap;
957*e038c9c4Sjoerg   if (CodeGenOpts.EnableDIPreservationVerify) {
958*e038c9c4Sjoerg     PerModulePasses.setDebugifyMode(DebugifyMode::OriginalDebugInfo);
959*e038c9c4Sjoerg     PerModulePasses.setDIPreservationMap(DIPreservationMap);
960*e038c9c4Sjoerg 
961*e038c9c4Sjoerg     if (!CodeGenOpts.DIBugsReportFilePath.empty())
962*e038c9c4Sjoerg       PerModulePasses.setOrigDIVerifyBugsReportFilePath(
963*e038c9c4Sjoerg           CodeGenOpts.DIBugsReportFilePath);
964*e038c9c4Sjoerg   }
9657330f729Sjoerg   PerModulePasses.add(
9667330f729Sjoerg       createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
9677330f729Sjoerg 
9687330f729Sjoerg   legacy::FunctionPassManager PerFunctionPasses(TheModule);
9697330f729Sjoerg   PerFunctionPasses.add(
9707330f729Sjoerg       createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
9717330f729Sjoerg 
9727330f729Sjoerg   CreatePasses(PerModulePasses, PerFunctionPasses);
9737330f729Sjoerg 
9747330f729Sjoerg   legacy::PassManager CodeGenPasses;
9757330f729Sjoerg   CodeGenPasses.add(
9767330f729Sjoerg       createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
9777330f729Sjoerg 
9787330f729Sjoerg   std::unique_ptr<llvm::ToolOutputFile> ThinLinkOS, DwoOS;
9797330f729Sjoerg 
9807330f729Sjoerg   switch (Action) {
9817330f729Sjoerg   case Backend_EmitNothing:
9827330f729Sjoerg     break;
9837330f729Sjoerg 
9847330f729Sjoerg   case Backend_EmitBC:
9857330f729Sjoerg     if (CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.DisableLLVMPasses) {
9867330f729Sjoerg       if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) {
9877330f729Sjoerg         ThinLinkOS = openOutputFile(CodeGenOpts.ThinLinkBitcodeFile);
9887330f729Sjoerg         if (!ThinLinkOS)
9897330f729Sjoerg           return;
9907330f729Sjoerg       }
9917330f729Sjoerg       TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit",
9927330f729Sjoerg                                CodeGenOpts.EnableSplitLTOUnit);
9937330f729Sjoerg       PerModulePasses.add(createWriteThinLTOBitcodePass(
9947330f729Sjoerg           *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr));
9957330f729Sjoerg     } else {
9967330f729Sjoerg       // Emit a module summary by default for Regular LTO except for ld64
9977330f729Sjoerg       // targets
9987330f729Sjoerg       bool EmitLTOSummary =
9997330f729Sjoerg           (CodeGenOpts.PrepareForLTO &&
10007330f729Sjoerg            !CodeGenOpts.DisableLLVMPasses &&
10017330f729Sjoerg            llvm::Triple(TheModule->getTargetTriple()).getVendor() !=
10027330f729Sjoerg                llvm::Triple::Apple);
10037330f729Sjoerg       if (EmitLTOSummary) {
10047330f729Sjoerg         if (!TheModule->getModuleFlag("ThinLTO"))
10057330f729Sjoerg           TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0));
10067330f729Sjoerg         TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit",
10077330f729Sjoerg                                  uint32_t(1));
10087330f729Sjoerg       }
10097330f729Sjoerg 
10107330f729Sjoerg       PerModulePasses.add(createBitcodeWriterPass(
10117330f729Sjoerg           *OS, CodeGenOpts.EmitLLVMUseLists, EmitLTOSummary));
10127330f729Sjoerg     }
10137330f729Sjoerg     break;
10147330f729Sjoerg 
10157330f729Sjoerg   case Backend_EmitLL:
10167330f729Sjoerg     PerModulePasses.add(
10177330f729Sjoerg         createPrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists));
10187330f729Sjoerg     break;
10197330f729Sjoerg 
10207330f729Sjoerg   default:
10217330f729Sjoerg     if (!CodeGenOpts.SplitDwarfOutput.empty()) {
10227330f729Sjoerg       DwoOS = openOutputFile(CodeGenOpts.SplitDwarfOutput);
10237330f729Sjoerg       if (!DwoOS)
10247330f729Sjoerg         return;
10257330f729Sjoerg     }
10267330f729Sjoerg     if (!AddEmitPasses(CodeGenPasses, Action, *OS,
10277330f729Sjoerg                        DwoOS ? &DwoOS->os() : nullptr))
10287330f729Sjoerg       return;
10297330f729Sjoerg   }
10307330f729Sjoerg 
10317330f729Sjoerg   // Before executing passes, print the final values of the LLVM options.
10327330f729Sjoerg   cl::PrintOptionValues();
10337330f729Sjoerg 
10347330f729Sjoerg   // Run passes. For now we do all passes at once, but eventually we
10357330f729Sjoerg   // would like to have the option of streaming code generation.
10367330f729Sjoerg 
10377330f729Sjoerg   {
10387330f729Sjoerg     PrettyStackTraceString CrashInfo("Per-function optimization");
1039*e038c9c4Sjoerg     llvm::TimeTraceScope TimeScope("PerFunctionPasses");
10407330f729Sjoerg 
10417330f729Sjoerg     PerFunctionPasses.doInitialization();
10427330f729Sjoerg     for (Function &F : *TheModule)
10437330f729Sjoerg       if (!F.isDeclaration())
10447330f729Sjoerg         PerFunctionPasses.run(F);
10457330f729Sjoerg     PerFunctionPasses.doFinalization();
10467330f729Sjoerg   }
10477330f729Sjoerg 
10487330f729Sjoerg   {
10497330f729Sjoerg     PrettyStackTraceString CrashInfo("Per-module optimization passes");
1050*e038c9c4Sjoerg     llvm::TimeTraceScope TimeScope("PerModulePasses");
10517330f729Sjoerg     PerModulePasses.run(*TheModule);
10527330f729Sjoerg   }
10537330f729Sjoerg 
10547330f729Sjoerg   {
10557330f729Sjoerg     PrettyStackTraceString CrashInfo("Code generation");
1056*e038c9c4Sjoerg     llvm::TimeTraceScope TimeScope("CodeGenPasses");
10577330f729Sjoerg     CodeGenPasses.run(*TheModule);
10587330f729Sjoerg   }
10597330f729Sjoerg 
10607330f729Sjoerg   if (ThinLinkOS)
10617330f729Sjoerg     ThinLinkOS->keep();
10627330f729Sjoerg   if (DwoOS)
10637330f729Sjoerg     DwoOS->keep();
10647330f729Sjoerg }
10657330f729Sjoerg 
mapToLevel(const CodeGenOptions & Opts)10667330f729Sjoerg static PassBuilder::OptimizationLevel mapToLevel(const CodeGenOptions &Opts) {
10677330f729Sjoerg   switch (Opts.OptimizationLevel) {
10687330f729Sjoerg   default:
10697330f729Sjoerg     llvm_unreachable("Invalid optimization level!");
10707330f729Sjoerg 
1071*e038c9c4Sjoerg   case 0:
1072*e038c9c4Sjoerg     return PassBuilder::OptimizationLevel::O0;
1073*e038c9c4Sjoerg 
10747330f729Sjoerg   case 1:
1075*e038c9c4Sjoerg     return PassBuilder::OptimizationLevel::O1;
10767330f729Sjoerg 
10777330f729Sjoerg   case 2:
10787330f729Sjoerg     switch (Opts.OptimizeSize) {
10797330f729Sjoerg     default:
10807330f729Sjoerg       llvm_unreachable("Invalid optimization level for size!");
10817330f729Sjoerg 
10827330f729Sjoerg     case 0:
1083*e038c9c4Sjoerg       return PassBuilder::OptimizationLevel::O2;
10847330f729Sjoerg 
10857330f729Sjoerg     case 1:
1086*e038c9c4Sjoerg       return PassBuilder::OptimizationLevel::Os;
10877330f729Sjoerg 
10887330f729Sjoerg     case 2:
1089*e038c9c4Sjoerg       return PassBuilder::OptimizationLevel::Oz;
10907330f729Sjoerg     }
10917330f729Sjoerg 
10927330f729Sjoerg   case 3:
1093*e038c9c4Sjoerg     return PassBuilder::OptimizationLevel::O3;
10947330f729Sjoerg   }
10957330f729Sjoerg }
10967330f729Sjoerg 
addSanitizers(const Triple & TargetTriple,const CodeGenOptions & CodeGenOpts,const LangOptions & LangOpts,PassBuilder & PB)1097*e038c9c4Sjoerg static void addSanitizers(const Triple &TargetTriple,
1098*e038c9c4Sjoerg                           const CodeGenOptions &CodeGenOpts,
1099*e038c9c4Sjoerg                           const LangOptions &LangOpts, PassBuilder &PB) {
1100*e038c9c4Sjoerg   PB.registerOptimizerLastEPCallback([&](ModulePassManager &MPM,
1101*e038c9c4Sjoerg                                          PassBuilder::OptimizationLevel Level) {
1102*e038c9c4Sjoerg     if (CodeGenOpts.SanitizeCoverageType ||
1103*e038c9c4Sjoerg         CodeGenOpts.SanitizeCoverageIndirectCalls ||
1104*e038c9c4Sjoerg         CodeGenOpts.SanitizeCoverageTraceCmp) {
1105*e038c9c4Sjoerg       auto SancovOpts = getSancovOptsFromCGOpts(CodeGenOpts);
1106*e038c9c4Sjoerg       MPM.addPass(ModuleSanitizerCoveragePass(
1107*e038c9c4Sjoerg           SancovOpts, CodeGenOpts.SanitizeCoverageAllowlistFiles,
1108*e038c9c4Sjoerg           CodeGenOpts.SanitizeCoverageIgnorelistFiles));
1109*e038c9c4Sjoerg     }
1110*e038c9c4Sjoerg 
1111*e038c9c4Sjoerg     auto MSanPass = [&](SanitizerMask Mask, bool CompileKernel) {
1112*e038c9c4Sjoerg       if (LangOpts.Sanitize.has(Mask)) {
1113*e038c9c4Sjoerg         int TrackOrigins = CodeGenOpts.SanitizeMemoryTrackOrigins;
11147330f729Sjoerg         bool Recover = CodeGenOpts.SanitizeRecover.has(Mask);
1115*e038c9c4Sjoerg 
11167330f729Sjoerg         MPM.addPass(
1117*e038c9c4Sjoerg             MemorySanitizerPass({TrackOrigins, Recover, CompileKernel}));
1118*e038c9c4Sjoerg         FunctionPassManager FPM;
1119*e038c9c4Sjoerg         FPM.addPass(
1120*e038c9c4Sjoerg             MemorySanitizerPass({TrackOrigins, Recover, CompileKernel}));
1121*e038c9c4Sjoerg         if (Level != PassBuilder::OptimizationLevel::O0) {
1122*e038c9c4Sjoerg           // MemorySanitizer inserts complex instrumentation that mostly
1123*e038c9c4Sjoerg           // follows the logic of the original code, but operates on
1124*e038c9c4Sjoerg           // "shadow" values. It can benefit from re-running some
1125*e038c9c4Sjoerg           // general purpose optimization passes.
1126*e038c9c4Sjoerg           FPM.addPass(EarlyCSEPass());
1127*e038c9c4Sjoerg           // TODO: Consider add more passes like in
1128*e038c9c4Sjoerg           // addGeneralOptsForMemorySanitizer. EarlyCSEPass makes visible
1129*e038c9c4Sjoerg           // difference on size. It's not clear if the rest is still
1130*e038c9c4Sjoerg           // usefull. InstCombinePass breakes
1131*e038c9c4Sjoerg           // compiler-rt/test/msan/select_origin.cpp.
1132*e038c9c4Sjoerg         }
1133*e038c9c4Sjoerg         MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
1134*e038c9c4Sjoerg       }
11357330f729Sjoerg     };
1136*e038c9c4Sjoerg     MSanPass(SanitizerKind::Memory, false);
1137*e038c9c4Sjoerg     MSanPass(SanitizerKind::KernelMemory, true);
11387330f729Sjoerg 
11397330f729Sjoerg     if (LangOpts.Sanitize.has(SanitizerKind::Thread)) {
11407330f729Sjoerg       MPM.addPass(ThreadSanitizerPass());
11417330f729Sjoerg       MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
11427330f729Sjoerg     }
1143*e038c9c4Sjoerg 
1144*e038c9c4Sjoerg     auto ASanPass = [&](SanitizerMask Mask, bool CompileKernel) {
1145*e038c9c4Sjoerg       if (LangOpts.Sanitize.has(Mask)) {
1146*e038c9c4Sjoerg         bool Recover = CodeGenOpts.SanitizeRecover.has(Mask);
1147*e038c9c4Sjoerg         bool UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope;
1148*e038c9c4Sjoerg         bool ModuleUseAfterScope = asanUseGlobalsGC(TargetTriple, CodeGenOpts);
1149*e038c9c4Sjoerg         bool UseOdrIndicator = CodeGenOpts.SanitizeAddressUseOdrIndicator;
1150*e038c9c4Sjoerg         llvm::AsanDtorKind DestructorKind =
1151*e038c9c4Sjoerg             CodeGenOpts.getSanitizeAddressDtor();
1152*e038c9c4Sjoerg         MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
1153*e038c9c4Sjoerg         MPM.addPass(ModuleAddressSanitizerPass(
1154*e038c9c4Sjoerg             CompileKernel, Recover, ModuleUseAfterScope, UseOdrIndicator,
1155*e038c9c4Sjoerg             DestructorKind));
1156*e038c9c4Sjoerg         MPM.addPass(createModuleToFunctionPassAdaptor(
1157*e038c9c4Sjoerg             AddressSanitizerPass(CompileKernel, Recover, UseAfterScope)));
1158*e038c9c4Sjoerg       }
1159*e038c9c4Sjoerg     };
1160*e038c9c4Sjoerg     ASanPass(SanitizerKind::Address, false);
1161*e038c9c4Sjoerg     ASanPass(SanitizerKind::KernelAddress, true);
1162*e038c9c4Sjoerg 
1163*e038c9c4Sjoerg     auto HWASanPass = [&](SanitizerMask Mask, bool CompileKernel) {
1164*e038c9c4Sjoerg       if (LangOpts.Sanitize.has(Mask)) {
1165*e038c9c4Sjoerg         bool Recover = CodeGenOpts.SanitizeRecover.has(Mask);
1166*e038c9c4Sjoerg         MPM.addPass(HWAddressSanitizerPass(CompileKernel, Recover));
1167*e038c9c4Sjoerg       }
1168*e038c9c4Sjoerg     };
1169*e038c9c4Sjoerg     HWASanPass(SanitizerKind::HWAddress, false);
1170*e038c9c4Sjoerg     HWASanPass(SanitizerKind::KernelHWAddress, true);
1171*e038c9c4Sjoerg 
1172*e038c9c4Sjoerg     if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) {
1173*e038c9c4Sjoerg       MPM.addPass(DataFlowSanitizerPass(LangOpts.NoSanitizeFiles));
1174*e038c9c4Sjoerg     }
1175*e038c9c4Sjoerg   });
11767330f729Sjoerg }
11777330f729Sjoerg 
11787330f729Sjoerg /// A clean version of `EmitAssembly` that uses the new pass manager.
11797330f729Sjoerg ///
11807330f729Sjoerg /// Not all features are currently supported in this system, but where
11817330f729Sjoerg /// necessary it falls back to the legacy pass manager to at least provide
11827330f729Sjoerg /// basic functionality.
11837330f729Sjoerg ///
11847330f729Sjoerg /// This API is planned to have its functionality finished and then to replace
11857330f729Sjoerg /// `EmitAssembly` at some point in the future when the default switches.
EmitAssemblyWithNewPassManager(BackendAction Action,std::unique_ptr<raw_pwrite_stream> OS)11867330f729Sjoerg void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
11877330f729Sjoerg     BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS) {
1188*e038c9c4Sjoerg   TimeRegion Region(CodeGenOpts.TimePasses ? &CodeGenerationTime : nullptr);
11897330f729Sjoerg   setCommandLineOpts(CodeGenOpts);
11907330f729Sjoerg 
11917330f729Sjoerg   bool RequiresCodeGen = (Action != Backend_EmitNothing &&
11927330f729Sjoerg                           Action != Backend_EmitBC &&
11937330f729Sjoerg                           Action != Backend_EmitLL);
11947330f729Sjoerg   CreateTargetMachine(RequiresCodeGen);
11957330f729Sjoerg 
11967330f729Sjoerg   if (RequiresCodeGen && !TM)
11977330f729Sjoerg     return;
11987330f729Sjoerg   if (TM)
11997330f729Sjoerg     TheModule->setDataLayout(TM->createDataLayout());
12007330f729Sjoerg 
12017330f729Sjoerg   Optional<PGOOptions> PGOOpt;
12027330f729Sjoerg 
12037330f729Sjoerg   if (CodeGenOpts.hasProfileIRInstr())
12047330f729Sjoerg     // -fprofile-generate.
12057330f729Sjoerg     PGOOpt = PGOOptions(CodeGenOpts.InstrProfileOutput.empty()
1206*e038c9c4Sjoerg                             ? std::string(DefaultProfileGenName)
12077330f729Sjoerg                             : CodeGenOpts.InstrProfileOutput,
12087330f729Sjoerg                         "", "", PGOOptions::IRInstr, PGOOptions::NoCSAction,
12097330f729Sjoerg                         CodeGenOpts.DebugInfoForProfiling);
12107330f729Sjoerg   else if (CodeGenOpts.hasProfileIRUse()) {
12117330f729Sjoerg     // -fprofile-use.
12127330f729Sjoerg     auto CSAction = CodeGenOpts.hasProfileCSIRUse() ? PGOOptions::CSIRUse
12137330f729Sjoerg                                                     : PGOOptions::NoCSAction;
12147330f729Sjoerg     PGOOpt = PGOOptions(CodeGenOpts.ProfileInstrumentUsePath, "",
12157330f729Sjoerg                         CodeGenOpts.ProfileRemappingFile, PGOOptions::IRUse,
12167330f729Sjoerg                         CSAction, CodeGenOpts.DebugInfoForProfiling);
12177330f729Sjoerg   } else if (!CodeGenOpts.SampleProfileFile.empty())
12187330f729Sjoerg     // -fprofile-sample-use
1219*e038c9c4Sjoerg     PGOOpt = PGOOptions(
1220*e038c9c4Sjoerg         CodeGenOpts.SampleProfileFile, "", CodeGenOpts.ProfileRemappingFile,
1221*e038c9c4Sjoerg         PGOOptions::SampleUse, PGOOptions::NoCSAction,
1222*e038c9c4Sjoerg         CodeGenOpts.DebugInfoForProfiling, CodeGenOpts.PseudoProbeForProfiling);
1223*e038c9c4Sjoerg   else if (CodeGenOpts.PseudoProbeForProfiling)
1224*e038c9c4Sjoerg     // -fpseudo-probe-for-profiling
12257330f729Sjoerg     PGOOpt =
1226*e038c9c4Sjoerg         PGOOptions("", "", "", PGOOptions::NoAction, PGOOptions::NoCSAction,
1227*e038c9c4Sjoerg                    CodeGenOpts.DebugInfoForProfiling, true);
12287330f729Sjoerg   else if (CodeGenOpts.DebugInfoForProfiling)
12297330f729Sjoerg     // -fdebug-info-for-profiling
12307330f729Sjoerg     PGOOpt = PGOOptions("", "", "", PGOOptions::NoAction,
12317330f729Sjoerg                         PGOOptions::NoCSAction, true);
12327330f729Sjoerg 
12337330f729Sjoerg   // Check to see if we want to generate a CS profile.
12347330f729Sjoerg   if (CodeGenOpts.hasProfileCSIRInstr()) {
12357330f729Sjoerg     assert(!CodeGenOpts.hasProfileCSIRUse() &&
12367330f729Sjoerg            "Cannot have both CSProfileUse pass and CSProfileGen pass at "
12377330f729Sjoerg            "the same time");
12387330f729Sjoerg     if (PGOOpt.hasValue()) {
12397330f729Sjoerg       assert(PGOOpt->Action != PGOOptions::IRInstr &&
12407330f729Sjoerg              PGOOpt->Action != PGOOptions::SampleUse &&
12417330f729Sjoerg              "Cannot run CSProfileGen pass with ProfileGen or SampleUse "
12427330f729Sjoerg              " pass");
12437330f729Sjoerg       PGOOpt->CSProfileGenFile = CodeGenOpts.InstrProfileOutput.empty()
1244*e038c9c4Sjoerg                                      ? std::string(DefaultProfileGenName)
12457330f729Sjoerg                                      : CodeGenOpts.InstrProfileOutput;
12467330f729Sjoerg       PGOOpt->CSAction = PGOOptions::CSIRInstr;
12477330f729Sjoerg     } else
12487330f729Sjoerg       PGOOpt = PGOOptions("",
12497330f729Sjoerg                           CodeGenOpts.InstrProfileOutput.empty()
1250*e038c9c4Sjoerg                               ? std::string(DefaultProfileGenName)
12517330f729Sjoerg                               : CodeGenOpts.InstrProfileOutput,
12527330f729Sjoerg                           "", PGOOptions::NoAction, PGOOptions::CSIRInstr,
12537330f729Sjoerg                           CodeGenOpts.DebugInfoForProfiling);
12547330f729Sjoerg   }
12557330f729Sjoerg 
12567330f729Sjoerg   PipelineTuningOptions PTO;
12577330f729Sjoerg   PTO.LoopUnrolling = CodeGenOpts.UnrollLoops;
12587330f729Sjoerg   // For historical reasons, loop interleaving is set to mirror setting for loop
12597330f729Sjoerg   // unrolling.
12607330f729Sjoerg   PTO.LoopInterleaving = CodeGenOpts.UnrollLoops;
12617330f729Sjoerg   PTO.LoopVectorization = CodeGenOpts.VectorizeLoop;
12627330f729Sjoerg   PTO.SLPVectorization = CodeGenOpts.VectorizeSLP;
1263*e038c9c4Sjoerg   PTO.MergeFunctions = CodeGenOpts.MergeFunctions;
1264*e038c9c4Sjoerg   // Only enable CGProfilePass when using integrated assembler, since
1265*e038c9c4Sjoerg   // non-integrated assemblers don't recognize .cgprofile section.
1266*e038c9c4Sjoerg   PTO.CallGraphProfile = !CodeGenOpts.DisableIntegratedAS;
1267*e038c9c4Sjoerg   PTO.Coroutines = LangOpts.Coroutines;
12687330f729Sjoerg 
1269*e038c9c4Sjoerg   LoopAnalysisManager LAM;
1270*e038c9c4Sjoerg   FunctionAnalysisManager FAM;
1271*e038c9c4Sjoerg   CGSCCAnalysisManager CGAM;
1272*e038c9c4Sjoerg   ModuleAnalysisManager MAM;
1273*e038c9c4Sjoerg 
1274*e038c9c4Sjoerg   bool DebugPassStructure = CodeGenOpts.DebugPass == "Structure";
12757330f729Sjoerg   PassInstrumentationCallbacks PIC;
1276*e038c9c4Sjoerg   PrintPassOptions PrintPassOpts;
1277*e038c9c4Sjoerg   PrintPassOpts.Indent = DebugPassStructure;
1278*e038c9c4Sjoerg   PrintPassOpts.SkipAnalyses = DebugPassStructure;
1279*e038c9c4Sjoerg   StandardInstrumentations SI(CodeGenOpts.DebugPassManager ||
1280*e038c9c4Sjoerg                                   DebugPassStructure,
1281*e038c9c4Sjoerg                               /*VerifyEach*/ false, PrintPassOpts);
1282*e038c9c4Sjoerg   SI.registerCallbacks(PIC, &FAM);
12837330f729Sjoerg   PassBuilder PB(TM.get(), PTO, PGOOpt, &PIC);
12847330f729Sjoerg 
12857330f729Sjoerg   // Attempt to load pass plugins and register their callbacks with PB.
12867330f729Sjoerg   for (auto &PluginFN : CodeGenOpts.PassPlugins) {
12877330f729Sjoerg     auto PassPlugin = PassPlugin::Load(PluginFN);
12887330f729Sjoerg     if (PassPlugin) {
12897330f729Sjoerg       PassPlugin->registerPassBuilderCallbacks(PB);
12907330f729Sjoerg     } else {
12917330f729Sjoerg       Diags.Report(diag::err_fe_unable_to_load_plugin)
12927330f729Sjoerg           << PluginFN << toString(PassPlugin.takeError());
12937330f729Sjoerg     }
12947330f729Sjoerg   }
1295*e038c9c4Sjoerg #define HANDLE_EXTENSION(Ext)                                                  \
1296*e038c9c4Sjoerg   get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
1297*e038c9c4Sjoerg #include "llvm/Support/Extension.def"
12987330f729Sjoerg 
12997330f729Sjoerg   // Register the AA manager first so that our version is the one used.
13007330f729Sjoerg   FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); });
13017330f729Sjoerg 
13027330f729Sjoerg   // Register the target library analysis directly and give it a customized
13037330f729Sjoerg   // preset TLI.
13047330f729Sjoerg   Triple TargetTriple(TheModule->getTargetTriple());
13057330f729Sjoerg   std::unique_ptr<TargetLibraryInfoImpl> TLII(
13067330f729Sjoerg       createTLII(TargetTriple, CodeGenOpts));
13077330f729Sjoerg   FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
13087330f729Sjoerg 
13097330f729Sjoerg   // Register all the basic analyses with the managers.
13107330f729Sjoerg   PB.registerModuleAnalyses(MAM);
13117330f729Sjoerg   PB.registerCGSCCAnalyses(CGAM);
13127330f729Sjoerg   PB.registerFunctionAnalyses(FAM);
13137330f729Sjoerg   PB.registerLoopAnalyses(LAM);
13147330f729Sjoerg   PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
13157330f729Sjoerg 
1316*e038c9c4Sjoerg   ModulePassManager MPM;
13177330f729Sjoerg 
13187330f729Sjoerg   if (!CodeGenOpts.DisableLLVMPasses) {
13197330f729Sjoerg     // Map our optimization levels into one of the distinct levels used to
13207330f729Sjoerg     // configure the pipeline.
13217330f729Sjoerg     PassBuilder::OptimizationLevel Level = mapToLevel(CodeGenOpts);
13227330f729Sjoerg 
1323*e038c9c4Sjoerg     bool IsThinLTO = CodeGenOpts.PrepareForThinLTO;
1324*e038c9c4Sjoerg     bool IsLTO = CodeGenOpts.PrepareForLTO;
1325*e038c9c4Sjoerg 
1326*e038c9c4Sjoerg     if (LangOpts.ObjCAutoRefCount) {
1327*e038c9c4Sjoerg       PB.registerPipelineStartEPCallback(
1328*e038c9c4Sjoerg           [](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
1329*e038c9c4Sjoerg             if (Level != PassBuilder::OptimizationLevel::O0)
1330*e038c9c4Sjoerg               MPM.addPass(
1331*e038c9c4Sjoerg                   createModuleToFunctionPassAdaptor(ObjCARCExpandPass()));
1332*e038c9c4Sjoerg           });
1333*e038c9c4Sjoerg       PB.registerPipelineEarlySimplificationEPCallback(
1334*e038c9c4Sjoerg           [](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
1335*e038c9c4Sjoerg             if (Level != PassBuilder::OptimizationLevel::O0)
1336*e038c9c4Sjoerg               MPM.addPass(ObjCARCAPElimPass());
1337*e038c9c4Sjoerg           });
1338*e038c9c4Sjoerg       PB.registerScalarOptimizerLateEPCallback(
1339*e038c9c4Sjoerg           [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
1340*e038c9c4Sjoerg             if (Level != PassBuilder::OptimizationLevel::O0)
1341*e038c9c4Sjoerg               FPM.addPass(ObjCARCOptPass());
1342*e038c9c4Sjoerg           });
1343*e038c9c4Sjoerg     }
1344*e038c9c4Sjoerg 
1345*e038c9c4Sjoerg     // If we reached here with a non-empty index file name, then the index
1346*e038c9c4Sjoerg     // file was empty and we are not performing ThinLTO backend compilation
1347*e038c9c4Sjoerg     // (used in testing in a distributed build environment).
1348*e038c9c4Sjoerg     bool IsThinLTOPostLink = !CodeGenOpts.ThinLTOIndexFile.empty();
1349*e038c9c4Sjoerg     // If so drop any the type test assume sequences inserted for whole program
1350*e038c9c4Sjoerg     // vtables so that codegen doesn't complain.
1351*e038c9c4Sjoerg     if (IsThinLTOPostLink)
1352*e038c9c4Sjoerg       PB.registerPipelineStartEPCallback(
1353*e038c9c4Sjoerg           [](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
1354*e038c9c4Sjoerg             MPM.addPass(LowerTypeTestsPass(/*ExportSummary=*/nullptr,
1355*e038c9c4Sjoerg                                            /*ImportSummary=*/nullptr,
1356*e038c9c4Sjoerg                                            /*DropTypeTests=*/true));
1357*e038c9c4Sjoerg           });
1358*e038c9c4Sjoerg 
1359*e038c9c4Sjoerg     if (CodeGenOpts.InstrumentFunctions ||
1360*e038c9c4Sjoerg         CodeGenOpts.InstrumentFunctionEntryBare ||
1361*e038c9c4Sjoerg         CodeGenOpts.InstrumentFunctionsAfterInlining ||
1362*e038c9c4Sjoerg         CodeGenOpts.InstrumentForProfiling) {
1363*e038c9c4Sjoerg       PB.registerPipelineStartEPCallback(
1364*e038c9c4Sjoerg           [](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
13657330f729Sjoerg             MPM.addPass(createModuleToFunctionPassAdaptor(
13667330f729Sjoerg                 EntryExitInstrumenterPass(/*PostInlining=*/false)));
13677330f729Sjoerg           });
1368*e038c9c4Sjoerg       PB.registerOptimizerLastEPCallback(
1369*e038c9c4Sjoerg           [](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
1370*e038c9c4Sjoerg             MPM.addPass(createModuleToFunctionPassAdaptor(
1371*e038c9c4Sjoerg                 EntryExitInstrumenterPass(/*PostInlining=*/true)));
1372*e038c9c4Sjoerg           });
1373*e038c9c4Sjoerg     }
13747330f729Sjoerg 
1375*e038c9c4Sjoerg     // Register callbacks to schedule sanitizer passes at the appropriate part
1376*e038c9c4Sjoerg     // of the pipeline.
13777330f729Sjoerg     if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds))
13787330f729Sjoerg       PB.registerScalarOptimizerLateEPCallback(
13797330f729Sjoerg           [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
13807330f729Sjoerg             FPM.addPass(BoundsCheckingPass());
13817330f729Sjoerg           });
1382*e038c9c4Sjoerg 
1383*e038c9c4Sjoerg     // Don't add sanitizers if we are here from ThinLTO PostLink. That already
1384*e038c9c4Sjoerg     // done on PreLink stage.
1385*e038c9c4Sjoerg     if (!IsThinLTOPostLink)
1386*e038c9c4Sjoerg       addSanitizers(TargetTriple, CodeGenOpts, LangOpts, PB);
1387*e038c9c4Sjoerg 
1388*e038c9c4Sjoerg     if (Optional<GCOVOptions> Options = getGCOVOptions(CodeGenOpts, LangOpts))
13897330f729Sjoerg       PB.registerPipelineStartEPCallback(
1390*e038c9c4Sjoerg           [Options](ModulePassManager &MPM,
13917330f729Sjoerg                     PassBuilder::OptimizationLevel Level) {
13927330f729Sjoerg             MPM.addPass(GCOVProfilerPass(*Options));
13937330f729Sjoerg           });
13947330f729Sjoerg     if (Optional<InstrProfOptions> Options =
13957330f729Sjoerg             getInstrProfOptions(CodeGenOpts, LangOpts))
1396*e038c9c4Sjoerg       PB.registerPipelineStartEPCallback(
1397*e038c9c4Sjoerg           [Options](ModulePassManager &MPM,
1398*e038c9c4Sjoerg                     PassBuilder::OptimizationLevel Level) {
13997330f729Sjoerg             MPM.addPass(InstrProfiling(*Options, false));
14007330f729Sjoerg           });
14017330f729Sjoerg 
14027330f729Sjoerg     if (CodeGenOpts.OptimizationLevel == 0) {
1403*e038c9c4Sjoerg       MPM = PB.buildO0DefaultPipeline(Level, IsLTO || IsThinLTO);
1404*e038c9c4Sjoerg     } else if (IsThinLTO) {
1405*e038c9c4Sjoerg       MPM = PB.buildThinLTOPreLinkDefaultPipeline(Level);
1406*e038c9c4Sjoerg     } else if (IsLTO) {
1407*e038c9c4Sjoerg       MPM = PB.buildLTOPreLinkDefaultPipeline(Level);
1408*e038c9c4Sjoerg     } else {
1409*e038c9c4Sjoerg       MPM = PB.buildPerModuleDefaultPipeline(Level);
1410*e038c9c4Sjoerg     }
1411*e038c9c4Sjoerg 
1412*e038c9c4Sjoerg     if (!CodeGenOpts.MemoryProfileOutput.empty()) {
1413*e038c9c4Sjoerg       MPM.addPass(createModuleToFunctionPassAdaptor(MemProfilerPass()));
1414*e038c9c4Sjoerg       MPM.addPass(ModuleMemProfilerPass());
14157330f729Sjoerg     }
14167330f729Sjoerg   }
14177330f729Sjoerg 
14187330f729Sjoerg   // FIXME: We still use the legacy pass manager to do code generation. We
14197330f729Sjoerg   // create that pass manager here and use it as needed below.
14207330f729Sjoerg   legacy::PassManager CodeGenPasses;
14217330f729Sjoerg   bool NeedCodeGen = false;
14227330f729Sjoerg   std::unique_ptr<llvm::ToolOutputFile> ThinLinkOS, DwoOS;
14237330f729Sjoerg 
14247330f729Sjoerg   // Append any output we need to the pass manager.
14257330f729Sjoerg   switch (Action) {
14267330f729Sjoerg   case Backend_EmitNothing:
14277330f729Sjoerg     break;
14287330f729Sjoerg 
14297330f729Sjoerg   case Backend_EmitBC:
14307330f729Sjoerg     if (CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.DisableLLVMPasses) {
14317330f729Sjoerg       if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) {
14327330f729Sjoerg         ThinLinkOS = openOutputFile(CodeGenOpts.ThinLinkBitcodeFile);
14337330f729Sjoerg         if (!ThinLinkOS)
14347330f729Sjoerg           return;
14357330f729Sjoerg       }
14367330f729Sjoerg       TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit",
14377330f729Sjoerg                                CodeGenOpts.EnableSplitLTOUnit);
14387330f729Sjoerg       MPM.addPass(ThinLTOBitcodeWriterPass(*OS, ThinLinkOS ? &ThinLinkOS->os()
14397330f729Sjoerg                                                            : nullptr));
14407330f729Sjoerg     } else {
14417330f729Sjoerg       // Emit a module summary by default for Regular LTO except for ld64
14427330f729Sjoerg       // targets
14437330f729Sjoerg       bool EmitLTOSummary =
14447330f729Sjoerg           (CodeGenOpts.PrepareForLTO &&
14457330f729Sjoerg            !CodeGenOpts.DisableLLVMPasses &&
14467330f729Sjoerg            llvm::Triple(TheModule->getTargetTriple()).getVendor() !=
14477330f729Sjoerg                llvm::Triple::Apple);
14487330f729Sjoerg       if (EmitLTOSummary) {
14497330f729Sjoerg         if (!TheModule->getModuleFlag("ThinLTO"))
14507330f729Sjoerg           TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0));
14517330f729Sjoerg         TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit",
14527330f729Sjoerg                                  uint32_t(1));
14537330f729Sjoerg       }
14547330f729Sjoerg       MPM.addPass(
14557330f729Sjoerg           BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists, EmitLTOSummary));
14567330f729Sjoerg     }
14577330f729Sjoerg     break;
14587330f729Sjoerg 
14597330f729Sjoerg   case Backend_EmitLL:
14607330f729Sjoerg     MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists));
14617330f729Sjoerg     break;
14627330f729Sjoerg 
14637330f729Sjoerg   case Backend_EmitAssembly:
14647330f729Sjoerg   case Backend_EmitMCNull:
14657330f729Sjoerg   case Backend_EmitObj:
14667330f729Sjoerg     NeedCodeGen = true;
14677330f729Sjoerg     CodeGenPasses.add(
14687330f729Sjoerg         createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
14697330f729Sjoerg     if (!CodeGenOpts.SplitDwarfOutput.empty()) {
14707330f729Sjoerg       DwoOS = openOutputFile(CodeGenOpts.SplitDwarfOutput);
14717330f729Sjoerg       if (!DwoOS)
14727330f729Sjoerg         return;
14737330f729Sjoerg     }
14747330f729Sjoerg     if (!AddEmitPasses(CodeGenPasses, Action, *OS,
14757330f729Sjoerg                        DwoOS ? &DwoOS->os() : nullptr))
14767330f729Sjoerg       // FIXME: Should we handle this error differently?
14777330f729Sjoerg       return;
14787330f729Sjoerg     break;
14797330f729Sjoerg   }
14807330f729Sjoerg 
14817330f729Sjoerg   // Before executing passes, print the final values of the LLVM options.
14827330f729Sjoerg   cl::PrintOptionValues();
14837330f729Sjoerg 
14847330f729Sjoerg   // Now that we have all of the passes ready, run them.
14857330f729Sjoerg   {
14867330f729Sjoerg     PrettyStackTraceString CrashInfo("Optimizer");
14877330f729Sjoerg     MPM.run(*TheModule, MAM);
14887330f729Sjoerg   }
14897330f729Sjoerg 
14907330f729Sjoerg   // Now if needed, run the legacy PM for codegen.
14917330f729Sjoerg   if (NeedCodeGen) {
14927330f729Sjoerg     PrettyStackTraceString CrashInfo("Code generation");
14937330f729Sjoerg     CodeGenPasses.run(*TheModule);
14947330f729Sjoerg   }
14957330f729Sjoerg 
14967330f729Sjoerg   if (ThinLinkOS)
14977330f729Sjoerg     ThinLinkOS->keep();
14987330f729Sjoerg   if (DwoOS)
14997330f729Sjoerg     DwoOS->keep();
15007330f729Sjoerg }
15017330f729Sjoerg 
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)1502*e038c9c4Sjoerg static void runThinLTOBackend(
1503*e038c9c4Sjoerg     DiagnosticsEngine &Diags, ModuleSummaryIndex *CombinedIndex, Module *M,
1504*e038c9c4Sjoerg     const HeaderSearchOptions &HeaderOpts, const CodeGenOptions &CGOpts,
1505*e038c9c4Sjoerg     const clang::TargetOptions &TOpts, const LangOptions &LOpts,
1506*e038c9c4Sjoerg     std::unique_ptr<raw_pwrite_stream> OS, std::string SampleProfile,
1507*e038c9c4Sjoerg     std::string ProfileRemapping, BackendAction Action) {
15087330f729Sjoerg   StringMap<DenseMap<GlobalValue::GUID, GlobalValueSummary *>>
15097330f729Sjoerg       ModuleToDefinedGVSummaries;
15107330f729Sjoerg   CombinedIndex->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
15117330f729Sjoerg 
15127330f729Sjoerg   setCommandLineOpts(CGOpts);
15137330f729Sjoerg 
15147330f729Sjoerg   // We can simply import the values mentioned in the combined index, since
15157330f729Sjoerg   // we should only invoke this using the individual indexes written out
15167330f729Sjoerg   // via a WriteIndexesThinBackend.
15177330f729Sjoerg   FunctionImporter::ImportMapTy ImportList;
1518*e038c9c4Sjoerg   if (!lto::initImportList(*M, *CombinedIndex, ImportList))
15197330f729Sjoerg     return;
15207330f729Sjoerg 
15217330f729Sjoerg   auto AddStream = [&](size_t Task) {
15227330f729Sjoerg     return std::make_unique<lto::NativeObjectStream>(std::move(OS));
15237330f729Sjoerg   };
15247330f729Sjoerg   lto::Config Conf;
15257330f729Sjoerg   if (CGOpts.SaveTempsFilePrefix != "") {
15267330f729Sjoerg     if (Error E = Conf.addSaveTemps(CGOpts.SaveTempsFilePrefix + ".",
15277330f729Sjoerg                                     /* UseInputModulePath */ false)) {
15287330f729Sjoerg       handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
15297330f729Sjoerg         errs() << "Error setting up ThinLTO save-temps: " << EIB.message()
15307330f729Sjoerg                << '\n';
15317330f729Sjoerg       });
15327330f729Sjoerg     }
15337330f729Sjoerg   }
15347330f729Sjoerg   Conf.CPU = TOpts.CPU;
15357330f729Sjoerg   Conf.CodeModel = getCodeModel(CGOpts);
15367330f729Sjoerg   Conf.MAttrs = TOpts.Features;
15377330f729Sjoerg   Conf.RelocModel = CGOpts.RelocationModel;
15387330f729Sjoerg   Conf.CGOptLevel = getCGOptLevel(CGOpts);
15397330f729Sjoerg   Conf.OptLevel = CGOpts.OptimizationLevel;
1540*e038c9c4Sjoerg   initTargetOptions(Diags, Conf.Options, CGOpts, TOpts, LOpts, HeaderOpts);
15417330f729Sjoerg   Conf.SampleProfile = std::move(SampleProfile);
1542*e038c9c4Sjoerg   Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops;
1543*e038c9c4Sjoerg   // For historical reasons, loop interleaving is set to mirror setting for loop
1544*e038c9c4Sjoerg   // unrolling.
1545*e038c9c4Sjoerg   Conf.PTO.LoopInterleaving = CGOpts.UnrollLoops;
1546*e038c9c4Sjoerg   Conf.PTO.LoopVectorization = CGOpts.VectorizeLoop;
1547*e038c9c4Sjoerg   Conf.PTO.SLPVectorization = CGOpts.VectorizeSLP;
1548*e038c9c4Sjoerg   // Only enable CGProfilePass when using integrated assembler, since
1549*e038c9c4Sjoerg   // non-integrated assemblers don't recognize .cgprofile section.
1550*e038c9c4Sjoerg   Conf.PTO.CallGraphProfile = !CGOpts.DisableIntegratedAS;
15517330f729Sjoerg 
15527330f729Sjoerg   // Context sensitive profile.
15537330f729Sjoerg   if (CGOpts.hasProfileCSIRInstr()) {
15547330f729Sjoerg     Conf.RunCSIRInstr = true;
15557330f729Sjoerg     Conf.CSIRProfile = std::move(CGOpts.InstrProfileOutput);
15567330f729Sjoerg   } else if (CGOpts.hasProfileCSIRUse()) {
15577330f729Sjoerg     Conf.RunCSIRInstr = false;
15587330f729Sjoerg     Conf.CSIRProfile = std::move(CGOpts.ProfileInstrumentUsePath);
15597330f729Sjoerg   }
15607330f729Sjoerg 
15617330f729Sjoerg   Conf.ProfileRemapping = std::move(ProfileRemapping);
1562*e038c9c4Sjoerg   Conf.UseNewPM = !CGOpts.LegacyPassManager;
15637330f729Sjoerg   Conf.DebugPassManager = CGOpts.DebugPassManager;
15647330f729Sjoerg   Conf.RemarksWithHotness = CGOpts.DiagnosticsWithHotness;
15657330f729Sjoerg   Conf.RemarksFilename = CGOpts.OptRecordFile;
15667330f729Sjoerg   Conf.RemarksPasses = CGOpts.OptRecordPasses;
15677330f729Sjoerg   Conf.RemarksFormat = CGOpts.OptRecordFormat;
15687330f729Sjoerg   Conf.SplitDwarfFile = CGOpts.SplitDwarfFile;
15697330f729Sjoerg   Conf.SplitDwarfOutput = CGOpts.SplitDwarfOutput;
15707330f729Sjoerg   switch (Action) {
15717330f729Sjoerg   case Backend_EmitNothing:
15727330f729Sjoerg     Conf.PreCodeGenModuleHook = [](size_t Task, const Module &Mod) {
15737330f729Sjoerg       return false;
15747330f729Sjoerg     };
15757330f729Sjoerg     break;
15767330f729Sjoerg   case Backend_EmitLL:
15777330f729Sjoerg     Conf.PreCodeGenModuleHook = [&](size_t Task, const Module &Mod) {
15787330f729Sjoerg       M->print(*OS, nullptr, CGOpts.EmitLLVMUseLists);
15797330f729Sjoerg       return false;
15807330f729Sjoerg     };
15817330f729Sjoerg     break;
15827330f729Sjoerg   case Backend_EmitBC:
15837330f729Sjoerg     Conf.PreCodeGenModuleHook = [&](size_t Task, const Module &Mod) {
15847330f729Sjoerg       WriteBitcodeToFile(*M, *OS, CGOpts.EmitLLVMUseLists);
15857330f729Sjoerg       return false;
15867330f729Sjoerg     };
15877330f729Sjoerg     break;
15887330f729Sjoerg   default:
15897330f729Sjoerg     Conf.CGFileType = getCodeGenFileType(Action);
15907330f729Sjoerg     break;
15917330f729Sjoerg   }
1592*e038c9c4Sjoerg   if (Error E =
1593*e038c9c4Sjoerg           thinBackend(Conf, -1, AddStream, *M, *CombinedIndex, ImportList,
1594*e038c9c4Sjoerg                       ModuleToDefinedGVSummaries[M->getModuleIdentifier()],
1595*e038c9c4Sjoerg                       /* ModuleMap */ nullptr, CGOpts.CmdArgs)) {
15967330f729Sjoerg     handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
15977330f729Sjoerg       errs() << "Error running ThinLTO backend: " << EIB.message() << '\n';
15987330f729Sjoerg     });
15997330f729Sjoerg   }
16007330f729Sjoerg }
16017330f729Sjoerg 
EmitBackendOutput(DiagnosticsEngine & Diags,const HeaderSearchOptions & HeaderOpts,const CodeGenOptions & CGOpts,const clang::TargetOptions & TOpts,const LangOptions & LOpts,StringRef TDesc,Module * M,BackendAction Action,std::unique_ptr<raw_pwrite_stream> OS)16027330f729Sjoerg void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
16037330f729Sjoerg                               const HeaderSearchOptions &HeaderOpts,
16047330f729Sjoerg                               const CodeGenOptions &CGOpts,
16057330f729Sjoerg                               const clang::TargetOptions &TOpts,
16067330f729Sjoerg                               const LangOptions &LOpts,
1607*e038c9c4Sjoerg                               StringRef TDesc, Module *M,
16087330f729Sjoerg                               BackendAction Action,
16097330f729Sjoerg                               std::unique_ptr<raw_pwrite_stream> OS) {
16107330f729Sjoerg 
1611*e038c9c4Sjoerg   llvm::TimeTraceScope TimeScope("Backend");
16127330f729Sjoerg 
16137330f729Sjoerg   std::unique_ptr<llvm::Module> EmptyModule;
16147330f729Sjoerg   if (!CGOpts.ThinLTOIndexFile.empty()) {
16157330f729Sjoerg     // If we are performing a ThinLTO importing compile, load the function index
16167330f729Sjoerg     // into memory and pass it into runThinLTOBackend, which will run the
16177330f729Sjoerg     // function importer and invoke LTO passes.
16187330f729Sjoerg     Expected<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
16197330f729Sjoerg         llvm::getModuleSummaryIndexForFile(CGOpts.ThinLTOIndexFile,
16207330f729Sjoerg                                            /*IgnoreEmptyThinLTOIndexFile*/true);
16217330f729Sjoerg     if (!IndexOrErr) {
16227330f729Sjoerg       logAllUnhandledErrors(IndexOrErr.takeError(), errs(),
16237330f729Sjoerg                             "Error loading index file '" +
16247330f729Sjoerg                             CGOpts.ThinLTOIndexFile + "': ");
16257330f729Sjoerg       return;
16267330f729Sjoerg     }
16277330f729Sjoerg     std::unique_ptr<ModuleSummaryIndex> CombinedIndex = std::move(*IndexOrErr);
16287330f729Sjoerg     // A null CombinedIndex means we should skip ThinLTO compilation
16297330f729Sjoerg     // (LLVM will optionally ignore empty index files, returning null instead
16307330f729Sjoerg     // of an error).
16317330f729Sjoerg     if (CombinedIndex) {
16327330f729Sjoerg       if (!CombinedIndex->skipModuleByDistributedBackend()) {
1633*e038c9c4Sjoerg         runThinLTOBackend(Diags, CombinedIndex.get(), M, HeaderOpts, CGOpts,
1634*e038c9c4Sjoerg                           TOpts, LOpts, std::move(OS), CGOpts.SampleProfileFile,
16357330f729Sjoerg                           CGOpts.ProfileRemappingFile, Action);
16367330f729Sjoerg         return;
16377330f729Sjoerg       }
16387330f729Sjoerg       // Distributed indexing detected that nothing from the module is needed
16397330f729Sjoerg       // for the final linking. So we can skip the compilation. We sill need to
16407330f729Sjoerg       // output an empty object file to make sure that a linker does not fail
16417330f729Sjoerg       // trying to read it. Also for some features, like CFI, we must skip
16427330f729Sjoerg       // the compilation as CombinedIndex does not contain all required
16437330f729Sjoerg       // information.
16447330f729Sjoerg       EmptyModule = std::make_unique<llvm::Module>("empty", M->getContext());
16457330f729Sjoerg       EmptyModule->setTargetTriple(M->getTargetTriple());
16467330f729Sjoerg       M = EmptyModule.get();
16477330f729Sjoerg     }
16487330f729Sjoerg   }
16497330f729Sjoerg 
16507330f729Sjoerg   EmitAssemblyHelper AsmHelper(Diags, HeaderOpts, CGOpts, TOpts, LOpts, M);
16517330f729Sjoerg 
1652*e038c9c4Sjoerg   if (!CGOpts.LegacyPassManager)
16537330f729Sjoerg     AsmHelper.EmitAssemblyWithNewPassManager(Action, std::move(OS));
16547330f729Sjoerg   else
16557330f729Sjoerg     AsmHelper.EmitAssembly(Action, std::move(OS));
16567330f729Sjoerg 
16577330f729Sjoerg   // Verify clang's TargetInfo DataLayout against the LLVM TargetMachine's
16587330f729Sjoerg   // DataLayout.
16597330f729Sjoerg   if (AsmHelper.TM) {
16607330f729Sjoerg     std::string DLDesc = M->getDataLayout().getStringRepresentation();
1661*e038c9c4Sjoerg     if (DLDesc != TDesc) {
16627330f729Sjoerg       unsigned DiagID = Diags.getCustomDiagID(
16637330f729Sjoerg           DiagnosticsEngine::Error, "backend data layout '%0' does not match "
16647330f729Sjoerg                                     "expected target description '%1'");
1665*e038c9c4Sjoerg       Diags.Report(DiagID) << DLDesc << TDesc;
16667330f729Sjoerg     }
16677330f729Sjoerg   }
16687330f729Sjoerg }
16697330f729Sjoerg 
16707330f729Sjoerg // With -fembed-bitcode, save a copy of the llvm IR as data in the
16717330f729Sjoerg // __LLVM,__bitcode section.
EmbedBitcode(llvm::Module * M,const CodeGenOptions & CGOpts,llvm::MemoryBufferRef Buf)16727330f729Sjoerg void clang::EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,
16737330f729Sjoerg                          llvm::MemoryBufferRef Buf) {
16747330f729Sjoerg   if (CGOpts.getEmbedBitcode() == CodeGenOptions::Embed_Off)
16757330f729Sjoerg     return;
1676*e038c9c4Sjoerg   llvm::EmbedBitcodeInModule(
1677*e038c9c4Sjoerg       *M, Buf, CGOpts.getEmbedBitcode() != CodeGenOptions::Embed_Marker,
1678*e038c9c4Sjoerg       CGOpts.getEmbedBitcode() != CodeGenOptions::Embed_Bitcode,
1679*e038c9c4Sjoerg       CGOpts.CmdArgs);
16807330f729Sjoerg }
1681