diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp | 631 |
1 files changed, 38 insertions, 593 deletions
diff --git a/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp b/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp index a4d330c0ba93..eb40e446057f 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/BackendUtil.cpp @@ -39,6 +39,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/SubtargetFeature.h" #include "llvm/MC/TargetRegistry.h" +#include "llvm/Object/OffloadBinary.h" #include "llvm/Passes/PassBuilder.h" #include "llvm/Passes/PassPlugin.h" #include "llvm/Passes/StandardInstrumentations.h" @@ -52,7 +53,6 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Transforms/Coroutines.h" #include "llvm/Transforms/Coroutines/CoroCleanup.h" #include "llvm/Transforms/Coroutines/CoroEarly.h" #include "llvm/Transforms/Coroutines/CoroElide.h" @@ -60,7 +60,6 @@ #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO/AlwaysInliner.h" #include "llvm/Transforms/IPO/LowerTypeTests.h" -#include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" #include "llvm/Transforms/InstCombine/InstCombine.h" #include "llvm/Transforms/Instrumentation.h" @@ -118,6 +117,8 @@ class EmitAssemblyHelper { std::unique_ptr<raw_pwrite_stream> OS; + Triple TargetTriple; + TargetIRAnalysis getTargetIRAnalysis() const { if (TM) return TM->getTargetIRAnalysis(); @@ -125,8 +126,6 @@ class EmitAssemblyHelper { return TargetIRAnalysis(); } - void CreatePasses(legacy::PassManager &MPM, legacy::FunctionPassManager &FPM); - /// Generates the TargetMachine. /// Leaves TM unchanged if it is unable to create the target machine. /// Some of our clang tests specify triples which are not built @@ -162,6 +161,16 @@ class EmitAssemblyHelper { std::unique_ptr<raw_pwrite_stream> &OS, std::unique_ptr<llvm::ToolOutputFile> &DwoOS); + /// Check whether we should emit a module summary for regular LTO. + /// The module summary should be emitted by default for regular LTO + /// except for ld64 targets. + /// + /// \return True if the module summary should be emitted. + bool shouldEmitRegularLTOSummary() const { + return CodeGenOpts.PrepareForLTO && !CodeGenOpts.DisableLLVMPasses && + TargetTriple.getVendor() != llvm::Triple::Apple; + } + public: EmitAssemblyHelper(DiagnosticsEngine &_Diags, const HeaderSearchOptions &HeaderSearchOpts, @@ -170,7 +179,8 @@ public: const LangOptions &LOpts, Module *M) : Diags(_Diags), HSOpts(HeaderSearchOpts), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts), TheModule(M), - CodeGenerationTime("codegen", "Code Generation Time") {} + CodeGenerationTime("codegen", "Code Generation Time"), + TargetTriple(TheModule->getTargetTriple()) {} ~EmitAssemblyHelper() { if (CodeGenOpts.DisableFree) @@ -179,60 +189,10 @@ public: std::unique_ptr<TargetMachine> TM; - // Emit output using the legacy pass manager for the optimization pipeline. - // This will be removed soon when using the legacy pass manager for the - // optimization pipeline is no longer supported. - void EmitAssemblyWithLegacyPassManager(BackendAction Action, - std::unique_ptr<raw_pwrite_stream> OS); - - // Emit output using the new pass manager for the optimization pipeline. This - // is the default. + // Emit output using the new pass manager for the optimization pipeline. void EmitAssembly(BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS); }; - -// We need this wrapper to access LangOpts and CGOpts from extension functions -// that we add to the PassManagerBuilder. -class PassManagerBuilderWrapper : public PassManagerBuilder { -public: - PassManagerBuilderWrapper(const Triple &TargetTriple, - const CodeGenOptions &CGOpts, - const LangOptions &LangOpts) - : TargetTriple(TargetTriple), CGOpts(CGOpts), LangOpts(LangOpts) {} - const Triple &getTargetTriple() const { return TargetTriple; } - const CodeGenOptions &getCGOpts() const { return CGOpts; } - const LangOptions &getLangOpts() const { return LangOpts; } - -private: - const Triple &TargetTriple; - const CodeGenOptions &CGOpts; - const LangOptions &LangOpts; -}; -} - -static void addObjCARCAPElimPass(const PassManagerBuilder &Builder, PassManagerBase &PM) { - if (Builder.OptLevel > 0) - PM.add(createObjCARCAPElimPass()); -} - -static void addObjCARCExpandPass(const PassManagerBuilder &Builder, PassManagerBase &PM) { - if (Builder.OptLevel > 0) - PM.add(createObjCARCExpandPass()); -} - -static void addObjCARCOptPass(const PassManagerBuilder &Builder, PassManagerBase &PM) { - if (Builder.OptLevel > 0) - PM.add(createObjCARCOptPass()); -} - -static void addAddDiscriminatorsPass(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - PM.add(createAddDiscriminatorsPass()); -} - -static void addBoundsCheckingPass(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - PM.add(createBoundsCheckingLegacyPass()); } static SanitizerCoverageOptions @@ -258,17 +218,6 @@ getSancovOptsFromCGOpts(const CodeGenOptions &CGOpts) { return Opts; } -static void addSanitizerCoveragePass(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - const PassManagerBuilderWrapper &BuilderWrapper = - static_cast<const PassManagerBuilderWrapper &>(Builder); - const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); - auto Opts = getSancovOptsFromCGOpts(CGOpts); - PM.add(createModuleSanitizerCoverageLegacyPassPass( - Opts, CGOpts.SanitizeCoverageAllowlistFiles, - CGOpts.SanitizeCoverageIgnorelistFiles)); -} - // Check if ASan should use GC-friendly instrumentation for globals. // First of all, there is no point if -fdata-sections is off (expect for MachO, // where this is not a factor). Also, on ELF this feature requires an assembler @@ -281,134 +230,20 @@ static bool asanUseGlobalsGC(const Triple &T, const CodeGenOptions &CGOpts) { case Triple::COFF: return true; case Triple::ELF: - return CGOpts.DataSections && !CGOpts.DisableIntegratedAS; + return !CGOpts.DisableIntegratedAS; case Triple::GOFF: llvm::report_fatal_error("ASan not implemented for GOFF"); case Triple::XCOFF: llvm::report_fatal_error("ASan not implemented for XCOFF."); case Triple::Wasm: + case Triple::DXContainer: + case Triple::SPIRV: case Triple::UnknownObjectFormat: break; } return false; } -static void addMemProfilerPasses(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - PM.add(createMemProfilerFunctionPass()); - PM.add(createModuleMemProfilerLegacyPassPass()); -} - -static void addAddressSanitizerPasses(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - const PassManagerBuilderWrapper &BuilderWrapper = - static_cast<const PassManagerBuilderWrapper&>(Builder); - const Triple &T = BuilderWrapper.getTargetTriple(); - const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); - bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::Address); - bool UseAfterScope = CGOpts.SanitizeAddressUseAfterScope; - bool UseOdrIndicator = CGOpts.SanitizeAddressUseOdrIndicator; - bool UseGlobalsGC = asanUseGlobalsGC(T, CGOpts); - llvm::AsanDtorKind DestructorKind = CGOpts.getSanitizeAddressDtor(); - llvm::AsanDetectStackUseAfterReturnMode UseAfterReturn = - CGOpts.getSanitizeAddressUseAfterReturn(); - PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/ false, Recover, - UseAfterScope, UseAfterReturn)); - PM.add(createModuleAddressSanitizerLegacyPassPass( - /*CompileKernel*/ false, Recover, UseGlobalsGC, UseOdrIndicator, - DestructorKind)); -} - -static void addKernelAddressSanitizerPasses(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - PM.add(createAddressSanitizerFunctionPass( - /*CompileKernel*/ true, /*Recover*/ true, /*UseAfterScope*/ false, - /*UseAfterReturn*/ llvm::AsanDetectStackUseAfterReturnMode::Never)); - PM.add(createModuleAddressSanitizerLegacyPassPass( - /*CompileKernel*/ true, /*Recover*/ true, /*UseGlobalsGC*/ true, - /*UseOdrIndicator*/ false)); -} - -static void addHWAddressSanitizerPasses(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - const PassManagerBuilderWrapper &BuilderWrapper = - static_cast<const PassManagerBuilderWrapper &>(Builder); - const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); - bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::HWAddress); - PM.add(createHWAddressSanitizerLegacyPassPass( - /*CompileKernel*/ false, Recover, - /*DisableOptimization*/ CGOpts.OptimizationLevel == 0)); -} - -static void addKernelHWAddressSanitizerPasses(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - const PassManagerBuilderWrapper &BuilderWrapper = - static_cast<const PassManagerBuilderWrapper &>(Builder); - const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); - PM.add(createHWAddressSanitizerLegacyPassPass( - /*CompileKernel*/ true, /*Recover*/ true, - /*DisableOptimization*/ CGOpts.OptimizationLevel == 0)); -} - -static void addGeneralOptsForMemorySanitizer(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM, - bool CompileKernel) { - const PassManagerBuilderWrapper &BuilderWrapper = - static_cast<const PassManagerBuilderWrapper&>(Builder); - const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); - int TrackOrigins = CGOpts.SanitizeMemoryTrackOrigins; - bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::Memory); - PM.add(createMemorySanitizerLegacyPassPass( - MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel, - CGOpts.SanitizeMemoryParamRetval != 0})); - - // MemorySanitizer inserts complex instrumentation that mostly follows - // the logic of the original code, but operates on "shadow" values. - // It can benefit from re-running some general purpose optimization passes. - if (Builder.OptLevel > 0) { - PM.add(createEarlyCSEPass()); - PM.add(createReassociatePass()); - PM.add(createLICMPass()); - PM.add(createGVNPass()); - PM.add(createInstructionCombiningPass()); - PM.add(createDeadStoreEliminationPass()); - } -} - -static void addMemorySanitizerPass(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - addGeneralOptsForMemorySanitizer(Builder, PM, /*CompileKernel*/ false); -} - -static void addKernelMemorySanitizerPass(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - addGeneralOptsForMemorySanitizer(Builder, PM, /*CompileKernel*/ true); -} - -static void addThreadSanitizerPass(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - PM.add(createThreadSanitizerLegacyPassPass()); -} - -static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - const PassManagerBuilderWrapper &BuilderWrapper = - static_cast<const PassManagerBuilderWrapper&>(Builder); - const LangOptions &LangOpts = BuilderWrapper.getLangOpts(); - PM.add(createDataFlowSanitizerLegacyPassPass(LangOpts.NoSanitizeFiles)); -} - -static void addEntryExitInstrumentationPass(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - PM.add(createEntryExitInstrumenterPass()); -} - -static void -addPostInlineEntryExitInstrumentationPass(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - PM.add(createPostInlineEntryExitInstrumenterPass()); -} - static TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple, const CodeGenOptions &CodeGenOpts) { TargetLibraryInfoImpl *TLII = new TargetLibraryInfoImpl(TargetTriple); @@ -443,17 +278,6 @@ static TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple, return TLII; } -static void addSymbolRewriterPass(const CodeGenOptions &Opts, - legacy::PassManager *MPM) { - llvm::SymbolRewriter::RewriteDescriptorList DL; - - llvm::SymbolRewriter::RewriteMapParser MapParser; - for (const auto &MapFile : Opts.RewriteMapFiles) - MapParser.parse(MapFile, &DL); - - MPM->add(createRewriteSymbolsPass(DL)); -} - static CodeGenOpt::Level getCGOptLevel(const CodeGenOptions &CodeGenOpts) { switch (CodeGenOpts.OptimizationLevel) { default: @@ -546,6 +370,8 @@ static bool initTargetOptions(DiagnosticsEngine &Diags, Options.BinutilsVersion = llvm::TargetMachine::parseBinutilsVersion(CodeGenOpts.BinutilsVersion); Options.UseInitArray = CodeGenOpts.UseInitArray; + Options.LowerGlobalDtorsViaCxaAtExit = + CodeGenOpts.RegisterGlobalDtorsWithAtExit; Options.DisableIntegratedAS = CodeGenOpts.DisableIntegratedAS; Options.CompressDebugSections = CodeGenOpts.getCompressDebugSections(); Options.RelaxELFRelocations = CodeGenOpts.RelaxELFRelocations; @@ -606,6 +432,10 @@ static bool initTargetOptions(DiagnosticsEngine &Diags, Options.EnableAIXExtendedAltivecABI = CodeGenOpts.EnableAIXExtendedAltivecABI; Options.XRayOmitFunctionIndex = CodeGenOpts.XRayOmitFunctionIndex; Options.LoopAlignment = CodeGenOpts.LoopAlignment; + Options.DebugStrictDwarf = CodeGenOpts.DebugStrictDwarf; + Options.ObjectFilenameForDebug = CodeGenOpts.ObjectFilenameForDebug; + Options.Hotpatch = CodeGenOpts.HotPatch; + Options.JMCInstrument = CodeGenOpts.JMCInstrument; switch (CodeGenOpts.getSwiftAsyncFramePointer()) { case CodeGenOptions::SwiftAsyncFramePointerKind::Auto: @@ -623,9 +453,13 @@ static bool initTargetOptions(DiagnosticsEngine &Diags, } Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile; + Options.MCOptions.EmitDwarfUnwind = CodeGenOpts.getEmitDwarfUnwind(); Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll; Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels; - Options.MCOptions.MCUseDwarfDirectory = !CodeGenOpts.NoDwarfDirectoryAsm; + Options.MCOptions.MCUseDwarfDirectory = + CodeGenOpts.NoDwarfDirectoryAsm + ? llvm::MCTargetOptions::DisableDwarfDirectory + : llvm::MCTargetOptions::EnableDwarfDirectory; Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack; Options.MCOptions.MCIncrementalLinkerCompatible = CodeGenOpts.IncrementalLinkerCompatible; @@ -644,9 +478,7 @@ static bool initTargetOptions(DiagnosticsEngine &Diags, Entry.IgnoreSysRoot ? Entry.Path : HSOpts.Sysroot + Entry.Path); Options.MCOptions.Argv0 = CodeGenOpts.Argv0; Options.MCOptions.CommandLineArgs = CodeGenOpts.CommandLineArgs; - Options.DebugStrictDwarf = CodeGenOpts.DebugStrictDwarf; - Options.ObjectFilenameForDebug = CodeGenOpts.ObjectFilenameForDebug; - Options.Hotpatch = CodeGenOpts.HotPatch; + Options.MisExpect = CodeGenOpts.MisExpect; return true; } @@ -680,233 +512,6 @@ getInstrProfOptions(const CodeGenOptions &CodeGenOpts, return Options; } -void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM, - legacy::FunctionPassManager &FPM) { - // Handle disabling of all LLVM passes, where we want to preserve the - // internal module before any optimization. - if (CodeGenOpts.DisableLLVMPasses) - return; - - // Figure out TargetLibraryInfo. This needs to be added to MPM and FPM - // manually (and not via PMBuilder), since some passes (eg. InstrProfiling) - // are inserted before PMBuilder ones - they'd get the default-constructed - // TLI with an unknown target otherwise. - Triple TargetTriple(TheModule->getTargetTriple()); - std::unique_ptr<TargetLibraryInfoImpl> TLII( - createTLII(TargetTriple, CodeGenOpts)); - - // If we reached here with a non-empty index file name, then the index file - // was empty and we are not performing ThinLTO backend compilation (used in - // testing in a distributed build environment). Drop any the type test - // assume sequences inserted for whole program vtables so that codegen doesn't - // complain. - if (!CodeGenOpts.ThinLTOIndexFile.empty()) - MPM.add(createLowerTypeTestsPass(/*ExportSummary=*/nullptr, - /*ImportSummary=*/nullptr, - /*DropTypeTests=*/true)); - - PassManagerBuilderWrapper PMBuilder(TargetTriple, CodeGenOpts, LangOpts); - - // At O0 and O1 we only run the always inliner which is more efficient. At - // higher optimization levels we run the normal inliner. - if (CodeGenOpts.OptimizationLevel <= 1) { - bool InsertLifetimeIntrinsics = ((CodeGenOpts.OptimizationLevel != 0 && - !CodeGenOpts.DisableLifetimeMarkers) || - LangOpts.Coroutines); - PMBuilder.Inliner = createAlwaysInlinerLegacyPass(InsertLifetimeIntrinsics); - } else { - // We do not want to inline hot callsites for SamplePGO module-summary build - // because profile annotation will happen again in ThinLTO backend, and we - // want the IR of the hot path to match the profile. - PMBuilder.Inliner = createFunctionInliningPass( - CodeGenOpts.OptimizationLevel, CodeGenOpts.OptimizeSize, - (!CodeGenOpts.SampleProfileFile.empty() && - CodeGenOpts.PrepareForThinLTO)); - } - - PMBuilder.OptLevel = CodeGenOpts.OptimizationLevel; - PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize; - PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP; - PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop; - // Only enable CGProfilePass when using integrated assembler, since - // non-integrated assemblers don't recognize .cgprofile section. - PMBuilder.CallGraphProfile = !CodeGenOpts.DisableIntegratedAS; - - PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops; - // Loop interleaving in the loop vectorizer has historically been set to be - // enabled when loop unrolling is enabled. - PMBuilder.LoopsInterleaved = CodeGenOpts.UnrollLoops; - PMBuilder.MergeFunctions = CodeGenOpts.MergeFunctions; - PMBuilder.PrepareForThinLTO = CodeGenOpts.PrepareForThinLTO; - PMBuilder.PrepareForLTO = CodeGenOpts.PrepareForLTO; - PMBuilder.RerollLoops = CodeGenOpts.RerollLoops; - - MPM.add(new TargetLibraryInfoWrapperPass(*TLII)); - - if (TM) - TM->adjustPassManager(PMBuilder); - - if (CodeGenOpts.DebugInfoForProfiling || - !CodeGenOpts.SampleProfileFile.empty()) - PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, - addAddDiscriminatorsPass); - - // In ObjC ARC mode, add the main ARC optimization passes. - if (LangOpts.ObjCAutoRefCount) { - PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, - addObjCARCExpandPass); - PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly, - addObjCARCAPElimPass); - PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, - addObjCARCOptPass); - } - - if (LangOpts.Coroutines) - addCoroutinePassesToExtensionPoints(PMBuilder); - - if (!CodeGenOpts.MemoryProfileOutput.empty()) { - PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, - addMemProfilerPasses); - PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, - addMemProfilerPasses); - } - - if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) { - PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, - addBoundsCheckingPass); - PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, - addBoundsCheckingPass); - } - - if (CodeGenOpts.hasSanitizeCoverage()) { - PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, - addSanitizerCoveragePass); - PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, - addSanitizerCoveragePass); - } - - if (LangOpts.Sanitize.has(SanitizerKind::Address)) { - PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, - addAddressSanitizerPasses); - PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, - addAddressSanitizerPasses); - } - - if (LangOpts.Sanitize.has(SanitizerKind::KernelAddress)) { - PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, - addKernelAddressSanitizerPasses); - PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, - addKernelAddressSanitizerPasses); - } - - if (LangOpts.Sanitize.has(SanitizerKind::HWAddress)) { - PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, - addHWAddressSanitizerPasses); - PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, - addHWAddressSanitizerPasses); - } - - if (LangOpts.Sanitize.has(SanitizerKind::KernelHWAddress)) { - PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, - addKernelHWAddressSanitizerPasses); - PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, - addKernelHWAddressSanitizerPasses); - } - - if (LangOpts.Sanitize.has(SanitizerKind::Memory)) { - PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, - addMemorySanitizerPass); - PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, - addMemorySanitizerPass); - } - - if (LangOpts.Sanitize.has(SanitizerKind::KernelMemory)) { - PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, - addKernelMemorySanitizerPass); - PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, - addKernelMemorySanitizerPass); - } - - if (LangOpts.Sanitize.has(SanitizerKind::Thread)) { - PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, - addThreadSanitizerPass); - PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, - addThreadSanitizerPass); - } - - if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) { - PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, - addDataFlowSanitizerPass); - PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, - addDataFlowSanitizerPass); - } - - if (CodeGenOpts.InstrumentFunctions || - CodeGenOpts.InstrumentFunctionEntryBare || - CodeGenOpts.InstrumentFunctionsAfterInlining || - CodeGenOpts.InstrumentForProfiling) { - PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, - addEntryExitInstrumentationPass); - PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, - addEntryExitInstrumentationPass); - PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, - addPostInlineEntryExitInstrumentationPass); - PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, - addPostInlineEntryExitInstrumentationPass); - } - - // Set up the per-function pass manager. - FPM.add(new TargetLibraryInfoWrapperPass(*TLII)); - if (CodeGenOpts.VerifyModule) - FPM.add(createVerifierPass()); - - // Set up the per-module pass manager. - if (!CodeGenOpts.RewriteMapFiles.empty()) - addSymbolRewriterPass(CodeGenOpts, &MPM); - - if (Optional<GCOVOptions> Options = getGCOVOptions(CodeGenOpts, LangOpts)) { - MPM.add(createGCOVProfilerPass(*Options)); - if (CodeGenOpts.getDebugInfo() == codegenoptions::NoDebugInfo) - MPM.add(createStripSymbolsPass(true)); - } - - if (Optional<InstrProfOptions> Options = - getInstrProfOptions(CodeGenOpts, LangOpts)) - MPM.add(createInstrProfilingLegacyPass(*Options, false)); - - bool hasIRInstr = false; - if (CodeGenOpts.hasProfileIRInstr()) { - PMBuilder.EnablePGOInstrGen = true; - hasIRInstr = true; - } - if (CodeGenOpts.hasProfileCSIRInstr()) { - assert(!CodeGenOpts.hasProfileCSIRUse() && - "Cannot have both CSProfileUse pass and CSProfileGen pass at the " - "same time"); - assert(!hasIRInstr && - "Cannot have both ProfileGen pass and CSProfileGen pass at the " - "same time"); - PMBuilder.EnablePGOCSInstrGen = true; - hasIRInstr = true; - } - if (hasIRInstr) { - if (!CodeGenOpts.InstrProfileOutput.empty()) - PMBuilder.PGOInstrGen = CodeGenOpts.InstrProfileOutput; - else - PMBuilder.PGOInstrGen = getDefaultProfileGenName(); - } - if (CodeGenOpts.hasProfileIRUse()) { - PMBuilder.PGOInstrUse = CodeGenOpts.ProfileInstrumentUsePath; - PMBuilder.EnablePGOCSInstrUse = CodeGenOpts.hasProfileCSIRUse(); - } - - if (!CodeGenOpts.SampleProfileFile.empty()) - PMBuilder.PGOSampleUse = CodeGenOpts.SampleProfileFile; - - PMBuilder.populateFunctionPassManager(FPM); - PMBuilder.populateModulePassManager(MPM); -} - static void setCommandLineOpts(const CodeGenOptions &CodeGenOpts) { SmallVector<const char *, 16> BackendArgs; BackendArgs.push_back("clang"); // Fake program name. @@ -961,7 +566,6 @@ bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses, raw_pwrite_stream &OS, raw_pwrite_stream *DwoOS) { // Add LibraryInfo. - llvm::Triple TargetTriple(TheModule->getTargetTriple()); std::unique_ptr<TargetLibraryInfoImpl> TLII( createTLII(TargetTriple, CodeGenOpts)); CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII)); @@ -985,139 +589,6 @@ bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses, return true; } -void EmitAssemblyHelper::EmitAssemblyWithLegacyPassManager( - BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS) { - TimeRegion Region(CodeGenOpts.TimePasses ? &CodeGenerationTime : nullptr); - - setCommandLineOpts(CodeGenOpts); - - bool UsesCodeGen = actionRequiresCodeGen(Action); - CreateTargetMachine(UsesCodeGen); - - if (UsesCodeGen && !TM) - return; - if (TM) - TheModule->setDataLayout(TM->createDataLayout()); - - DebugifyCustomPassManager PerModulePasses; - DebugInfoPerPassMap DIPreservationMap; - if (CodeGenOpts.EnableDIPreservationVerify) { - PerModulePasses.setDebugifyMode(DebugifyMode::OriginalDebugInfo); - PerModulePasses.setDIPreservationMap(DIPreservationMap); - - if (!CodeGenOpts.DIBugsReportFilePath.empty()) - PerModulePasses.setOrigDIVerifyBugsReportFilePath( - CodeGenOpts.DIBugsReportFilePath); - } - PerModulePasses.add( - createTargetTransformInfoWrapperPass(getTargetIRAnalysis())); - - legacy::FunctionPassManager PerFunctionPasses(TheModule); - PerFunctionPasses.add( - createTargetTransformInfoWrapperPass(getTargetIRAnalysis())); - - CreatePasses(PerModulePasses, PerFunctionPasses); - - // Add a verifier pass if requested. We don't have to do this if the action - // requires code generation because there will already be a verifier pass in - // the code-generation pipeline. - if (!UsesCodeGen && CodeGenOpts.VerifyModule) - PerModulePasses.add(createVerifierPass()); - - legacy::PassManager CodeGenPasses; - CodeGenPasses.add( - createTargetTransformInfoWrapperPass(getTargetIRAnalysis())); - - std::unique_ptr<llvm::ToolOutputFile> ThinLinkOS, DwoOS; - - switch (Action) { - case Backend_EmitNothing: - break; - - case Backend_EmitBC: - if (CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.DisableLLVMPasses) { - if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) { - ThinLinkOS = openOutputFile(CodeGenOpts.ThinLinkBitcodeFile); - if (!ThinLinkOS) - return; - } - if (!TheModule->getModuleFlag("EnableSplitLTOUnit")) - TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit", - CodeGenOpts.EnableSplitLTOUnit); - PerModulePasses.add(createWriteThinLTOBitcodePass( - *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr)); - } else { - // Emit a module summary by default for Regular LTO except for ld64 - // targets - bool EmitLTOSummary = - (CodeGenOpts.PrepareForLTO && - !CodeGenOpts.DisableLLVMPasses && - llvm::Triple(TheModule->getTargetTriple()).getVendor() != - llvm::Triple::Apple); - if (EmitLTOSummary) { - if (!TheModule->getModuleFlag("ThinLTO")) - TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0)); - if (!TheModule->getModuleFlag("EnableSplitLTOUnit")) - TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit", - uint32_t(1)); - } - - PerModulePasses.add(createBitcodeWriterPass( - *OS, CodeGenOpts.EmitLLVMUseLists, EmitLTOSummary)); - } - break; - - case Backend_EmitLL: - PerModulePasses.add( - createPrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists)); - break; - - default: - if (!CodeGenOpts.SplitDwarfOutput.empty()) { - DwoOS = openOutputFile(CodeGenOpts.SplitDwarfOutput); - if (!DwoOS) - return; - } - if (!AddEmitPasses(CodeGenPasses, Action, *OS, - DwoOS ? &DwoOS->os() : nullptr)) - return; - } - - // Before executing passes, print the final values of the LLVM options. - cl::PrintOptionValues(); - - // Run passes. For now we do all passes at once, but eventually we - // would like to have the option of streaming code generation. - - { - PrettyStackTraceString CrashInfo("Per-function optimization"); - llvm::TimeTraceScope TimeScope("PerFunctionPasses"); - - PerFunctionPasses.doInitialization(); - for (Function &F : *TheModule) - if (!F.isDeclaration()) - PerFunctionPasses.run(F); - PerFunctionPasses.doFinalization(); - } - - { - PrettyStackTraceString CrashInfo("Per-module optimization passes"); - llvm::TimeTraceScope TimeScope("PerModulePasses"); - PerModulePasses.run(*TheModule); - } - - { - PrettyStackTraceString CrashInfo("Code generation"); - llvm::TimeTraceScope TimeScope("CodeGenPasses"); - CodeGenPasses.run(*TheModule); - } - - if (ThinLinkOS) - ThinLinkOS->keep(); - if (DwoOS) - DwoOS->keep(); -} - static OptimizationLevel mapToLevel(const CodeGenOptions &Opts) { switch (Opts.OptimizationLevel) { default: @@ -1205,7 +676,6 @@ static void addSanitizers(const Triple &TargetTriple, Opts.Recover = CodeGenOpts.SanitizeRecover.has(Mask); Opts.UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope; Opts.UseAfterReturn = CodeGenOpts.getSanitizeAddressUseAfterReturn(); - MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>()); MPM.addPass(ModuleAddressSanitizerPass( Opts, UseGlobalGC, UseOdrIndicator, DestructorKind)); } @@ -1270,7 +740,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline( assert(!CodeGenOpts.hasProfileCSIRUse() && "Cannot have both CSProfileUse pass and CSProfileGen pass at " "the same time"); - if (PGOOpt.hasValue()) { + if (PGOOpt) { assert(PGOOpt->Action != PGOOptions::IRInstr && PGOOpt->Action != PGOOptions::SampleUse && "Cannot run CSProfileGen pass with ProfileGen or SampleUse " @@ -1334,7 +804,6 @@ void EmitAssemblyHelper::RunOptimizationPipeline( // Register the target library analysis directly and give it a customized // preset TLI. - Triple TargetTriple(TheModule->getTargetTriple()); std::unique_ptr<TargetLibraryInfoImpl> TLII( createTLII(TargetTriple, CodeGenOpts)); FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); }); @@ -1468,10 +937,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline( } else { // Emit a module summary by default for Regular LTO except for ld64 // targets - bool EmitLTOSummary = - (CodeGenOpts.PrepareForLTO && !CodeGenOpts.DisableLLVMPasses && - llvm::Triple(TheModule->getTargetTriple()).getVendor() != - llvm::Triple::Apple); + bool EmitLTOSummary = shouldEmitRegularLTOSummary(); if (EmitLTOSummary) { if (!TheModule->getModuleFlag("ThinLTO")) TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0)); @@ -1536,14 +1002,6 @@ void EmitAssemblyHelper::RunCodegenPipeline( } } -/// A clean version of `EmitAssembly` that uses the new pass manager. -/// -/// Not all features are currently supported in this system, but where -/// necessary it falls back to the legacy pass manager to at least provide -/// basic functionality. -/// -/// This API is planned to have its functionality finished and then to replace -/// `EmitAssembly` at some point in the future when the default switches. void EmitAssemblyHelper::EmitAssembly(BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS) { TimeRegion Region(CodeGenOpts.TimePasses ? &CodeGenerationTime : nullptr); @@ -1631,7 +1089,6 @@ static void runThinLTOBackend( } Conf.ProfileRemapping = std::move(ProfileRemapping); - Conf.UseNewPM = !CGOpts.LegacyPassManager; Conf.DebugPassManager = CGOpts.DebugPassManager; Conf.RemarksWithHotness = CGOpts.DiagnosticsWithHotness; Conf.RemarksFilename = CGOpts.OptRecordFile; @@ -1721,11 +1178,7 @@ void clang::EmitBackendOutput(DiagnosticsEngine &Diags, } EmitAssemblyHelper AsmHelper(Diags, HeaderOpts, CGOpts, TOpts, LOpts, M); - - if (CGOpts.LegacyPassManager) - AsmHelper.EmitAssemblyWithLegacyPassManager(Action, std::move(OS)); - else - AsmHelper.EmitAssembly(Action, std::move(OS)); + AsmHelper.EmitAssembly(Action, std::move(OS)); // Verify clang's TargetInfo DataLayout against the LLVM TargetMachine's // DataLayout. @@ -1758,24 +1211,16 @@ void clang::EmbedObject(llvm::Module *M, const CodeGenOptions &CGOpts, return; for (StringRef OffloadObject : CGOpts.OffloadObjects) { - if (OffloadObject.count(',') != 1) { - Diags.Report(Diags.getCustomDiagID( - DiagnosticsEngine::Error, "Invalid string pair for embedding '%0'")) - << OffloadObject; - return; - } - auto FilenameAndSection = OffloadObject.split(','); llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ObjectOrErr = - llvm::MemoryBuffer::getFileOrSTDIN(std::get<0>(FilenameAndSection)); + llvm::MemoryBuffer::getFileOrSTDIN(OffloadObject); if (std::error_code EC = ObjectOrErr.getError()) { auto DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "could not open '%0' for embedding"); - Diags.Report(DiagID) << std::get<0>(FilenameAndSection); + Diags.Report(DiagID) << OffloadObject; return; } - SmallString<128> SectionName( - {".llvm.offloading.", std::get<1>(FilenameAndSection)}); - llvm::embedBufferInModule(*M, **ObjectOrErr, SectionName); + llvm::embedBufferInModule(*M, **ObjectOrErr, ".llvm.offloading", + Align(object::OffloadBinary::getAlignment())); } } |