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