diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -1153,7 +1153,7 @@ PTO.Coroutines = LangOpts.Coroutines; PassInstrumentationCallbacks PIC; - StandardInstrumentations SI; + StandardInstrumentations SI(CodeGenOpts.DebugPassManager); SI.registerCallbacks(PIC); PassBuilder PB(TM.get(), PTO, PGOOpt, &PIC); diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h --- a/llvm/include/llvm/Passes/StandardInstrumentations.h +++ b/llvm/include/llvm/Passes/StandardInstrumentations.h @@ -16,6 +16,7 @@ #define LLVM_PASSES_STANDARDINSTRUMENTATIONS_H #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/IR/PassInstrumentation.h" #include "llvm/IR/PassTimingInfo.h" @@ -53,14 +54,27 @@ bool StoreModuleDesc = false; }; +class OptNoneInstrumentation { +public: + OptNoneInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {} + void registerCallbacks(PassInstrumentationCallbacks &PIC); + +private: + bool skip(StringRef PassID, Any IR); + + bool DebugLogging; +}; + /// This class provides an interface to register all the standard pass /// instrumentations and manages their state (if any). class StandardInstrumentations { PrintIRInstrumentation PrintIR; TimePassesHandler TimePasses; + OptNoneInstrumentation OptNone; public: - StandardInstrumentations() = default; + StandardInstrumentations(bool DebugLogging) + : PrintIR(), TimePasses(), OptNone(DebugLogging) {} void registerCallbacks(PassInstrumentationCallbacks &PIC); diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -197,7 +197,7 @@ } PassInstrumentationCallbacks PIC; - StandardInstrumentations SI; + StandardInstrumentations SI(Conf.DebugPassManager); SI.registerCallbacks(PIC); PassBuilder PB(TM, Conf.PTO, PGOOpt, &PIC); AAManager AA; diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp --- a/llvm/lib/Passes/StandardInstrumentations.cpp +++ b/llvm/lib/Passes/StandardInstrumentations.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Passes/StandardInstrumentations.h" +#include "llvm/ADT/Any.h" #include "llvm/ADT/Optional.h" #include "llvm/Analysis/CallGraphSCCPass.h" #include "llvm/Analysis/LazyCallGraph.h" @@ -21,12 +22,19 @@ #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/Module.h" #include "llvm/IR/PassInstrumentation.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; +// TODO: remove once all required passes are marked as such. +static cl::opt + EnableOptnone("enable-npm-optnone", cl::init(false), + cl::desc("Enable skipping optional passes optnone functions " + "under new pass manager")); + namespace { /// Extracting Module out of \p IR unit. Also fills a textual description @@ -243,8 +251,32 @@ } } +void OptNoneInstrumentation::registerCallbacks( + PassInstrumentationCallbacks &PIC) { + PIC.registerBeforePassCallback( + [this](StringRef P, Any IR) { return this->skip(P, IR); }); +} + +bool OptNoneInstrumentation::skip(StringRef PassID, Any IR) { + if (!EnableOptnone) + return true; + const Function *F = nullptr; + if (any_isa(IR)) { + F = any_cast(IR); + } else if (any_isa(IR)) { + F = any_cast(IR)->getHeader()->getParent(); + } + if (F && F->hasOptNone()) { + if (DebugLogging) + dbgs() << "Skipping pass: " << PassID << " (optnone)\n"; + return false; + } + return true; +} + void StandardInstrumentations::registerCallbacks( PassInstrumentationCallbacks &PIC) { PrintIR.registerCallbacks(PIC); TimePasses.registerCallbacks(PIC); + OptNone.registerCallbacks(PIC); } diff --git a/llvm/test/Feature/optnone-opt.ll b/llvm/test/Feature/optnone-opt.ll --- a/llvm/test/Feature/optnone-opt.ll +++ b/llvm/test/Feature/optnone-opt.ll @@ -1,9 +1,15 @@ -; RUN: opt -S -debug %s 2>&1 | FileCheck %s --check-prefix=OPT-O0 -; RUN: opt -O1 -S -debug %s 2>&1 | FileCheck %s --check-prefix=OPT-O1 -; RUN: opt -O2 -S -debug %s 2>&1 | FileCheck %s --check-prefix=OPT-O1 --check-prefix=OPT-O2O3 -; RUN: opt -O3 -S -debug %s 2>&1 | FileCheck %s --check-prefix=OPT-O1 --check-prefix=OPT-O2O3 -; RUN: opt -dce -die -gvn-hoist -loweratomic -S -debug %s 2>&1 | FileCheck %s --check-prefix=OPT-MORE -; RUN: opt -indvars -licm -loop-deletion -loop-extract -loop-idiom -loop-instsimplify -loop-reduce -loop-reroll -loop-rotate -loop-unroll -loop-unswitch -S -debug %s 2>&1 | FileCheck %s --check-prefix=OPT-LOOP +; RUN: opt -S -debug -enable-new-pm=0 %s 2>&1 | FileCheck %s --check-prefix=O0 +; RUN: opt -O1 -S -debug -enable-new-pm=0 %s 2>&1 | FileCheck %s --check-prefix=O1 +; RUN: opt -O2 -S -debug -enable-new-pm=0 %s 2>&1 | FileCheck %s --check-prefix=O1 --check-prefix=O2O3 +; RUN: opt -O3 -S -debug -enable-new-pm=0 %s 2>&1 | FileCheck %s --check-prefix=O1 --check-prefix=O2O3 +; RUN: opt -dce -die -gvn-hoist -loweratomic -S -debug -enable-new-pm=0 %s 2>&1 | FileCheck %s --check-prefix=MORE +; RUN: opt -indvars -licm -loop-deletion -loop-extract -loop-idiom -loop-instsimplify -loop-reduce -loop-reroll -loop-rotate -loop-unroll -loop-unswitch -enable-new-pm=0 -S -debug %s 2>&1 | FileCheck %s --check-prefix=LOOP +; RUN: opt -enable-npm-optnone -S -debug-pass-manager -enable-new-pm %s 2>&1 | FileCheck %s --check-prefix=NPM-O0 +; RUN: opt -enable-npm-optnone -O1 -S -debug-pass-manager -enable-new-pm %s 2>&1 | FileCheck %s --check-prefix=NPM-O1 +; RUN: opt -enable-npm-optnone -O2 -S -debug-pass-manager -enable-new-pm %s 2>&1 | FileCheck %s --check-prefix=NPM-O1 --check-prefix=NPM-O2O3 +; RUN: opt -enable-npm-optnone -O3 -S -debug-pass-manager -enable-new-pm %s 2>&1 | FileCheck %s --check-prefix=NPM-O1 --check-prefix=NPM-O2O3 +; RUN: opt -enable-npm-optnone -dce -gvn-hoist -loweratomic -S -debug-pass-manager -enable-new-pm %s 2>&1 | FileCheck %s --check-prefix=NPM-MORE +; RUN: opt -enable-npm-optnone -indvars -licm -loop-deletion -loop-idiom -loop-instsimplify -loop-reduce -loop-unroll -simple-loop-unswitch -S -debug-pass-manager -enable-new-pm %s 2>&1 | FileCheck %s --check-prefix=NPM-LOOP ; REQUIRES: asserts @@ -34,32 +40,53 @@ attributes #0 = { optnone noinline } ; Nothing that runs at -O0 gets skipped. -; OPT-O0-NOT: Skipping pass +; O0-NOT: Skipping pass +; NPM-O0-NOT: Skipping pass ; IR passes run at -O1 and higher. -; OPT-O1-DAG: Skipping pass 'Aggressive Dead Code Elimination' -; OPT-O1-DAG: Skipping pass 'Combine redundant instructions' -; OPT-O1-DAG: Skipping pass 'Early CSE' -; OPT-O1-DAG: Skipping pass 'Reassociate expressions' -; OPT-O1-DAG: Skipping pass 'Simplify the CFG' -; OPT-O1-DAG: Skipping pass 'Sparse Conditional Constant Propagation' +; O1-DAG: Skipping pass 'Aggressive Dead Code Elimination' +; O1-DAG: Skipping pass 'Combine redundant instructions' +; O1-DAG: Skipping pass 'Early CSE' +; O1-DAG: Skipping pass 'Reassociate expressions' +; O1-DAG: Skipping pass 'Simplify the CFG' +; O1-DAG: Skipping pass 'Sparse Conditional Constant Propagation' +; NPM-O1-DAG: Skipping pass: SimplifyCFGPass +; NPM-O1-DAG: Skipping pass: SROA +; NPM-O1-DAG: Skipping pass: EarlyCSEPass +; NPM-O1-DAG: Skipping pass: LowerExpectIntrinsicPass +; NPM-O1-DAG: Skipping pass: PromotePass +; NPM-O1-DAG: Skipping pass: InstCombinePass ; Additional IR passes run at -O2 and higher. -; OPT-O2O3-DAG: Skipping pass 'Global Value Numbering' -; OPT-O2O3-DAG: Skipping pass 'SLP Vectorizer' +; O2O3-DAG: Skipping pass 'Global Value Numbering' +; O2O3-DAG: Skipping pass 'SLP Vectorizer' +; NPM-O2O3-DAG: Skipping pass: GVN +; NPM-O2O3-DAG: Skipping pass: SLPVectorizerPass ; Additional IR passes that opt doesn't turn on by default. -; OPT-MORE-DAG: Skipping pass 'Dead Code Elimination' -; OPT-MORE-DAG: Skipping pass 'Dead Instruction Elimination' +; MORE-DAG: Skipping pass 'Dead Code Elimination' +; MORE-DAG: Skipping pass 'Dead Instruction Elimination' +; NPM-MORE-DAG: Skipping pass: GVNHoistPass +; NPM-MORE-DAG: Skipping pass: LowerAtomicPass ; Loop IR passes that opt doesn't turn on by default. -; OPT-LOOP-DAG: Skipping pass 'Delete dead loops' -; OPT-LOOP-DAG: Skipping pass 'Induction Variable Simplification' -; OPT-LOOP-DAG: Skipping pass 'Loop Invariant Code Motion' -; OPT-LOOP-DAG: Skipping pass 'Loop Strength Reduction' -; OPT-LOOP-DAG: Skipping pass 'Recognize loop idioms' -; OPT-LOOP-DAG: Skipping pass 'Reroll loops' -; OPT-LOOP-DAG: Skipping pass 'Rotate Loops' -; OPT-LOOP-DAG: Skipping pass 'Simplify instructions in loops' -; OPT-LOOP-DAG: Skipping pass 'Unroll loops' -; OPT-LOOP-DAG: Skipping pass 'Unswitch loops' +; LOOP-DAG: Skipping pass 'Delete dead loops' +; LOOP-DAG: Skipping pass 'Induction Variable Simplification' +; LOOP-DAG: Skipping pass 'Loop Invariant Code Motion' +; LOOP-DAG: Skipping pass 'Loop Strength Reduction' +; LOOP-DAG: Skipping pass 'Recognize loop idioms' +; LOOP-DAG: Skipping pass 'Reroll loops' +; LOOP-DAG: Skipping pass 'Rotate Loops' +; LOOP-DAG: Skipping pass 'Simplify instructions in loops' +; LOOP-DAG: Skipping pass 'Unroll loops' +; LOOP-DAG: Skipping pass 'Unswitch loops' +; NPM-LOOP-DAG: Skipping pass: LoopSimplifyPass +; NPM-LOOP-DAG: Skipping pass: LCSSAPass +; NPM-LOOP-DAG: Skipping pass: IndVarSimplifyPass +; NPM-LOOP-DAG: Skipping pass: SimpleLoopUnswitchPass +; NPM-LOOP-DAG: Skipping pass: LoopUnrollPass +; NPM-LOOP-DAG: Skipping pass: LoopStrengthReducePass +; NPM-LOOP-DAG: Skipping pass: LoopDeletionPass +; NPM-LOOP-DAG: Skipping pass: LICMPass +; NPM-LOOP-DAG: Skipping pass: LoopIdiomRecognizePass +; NPM-LOOP-DAG: Skipping pass: LoopInstSimplifyPass diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp --- a/llvm/tools/opt/NewPMDriver.cpp +++ b/llvm/tools/opt/NewPMDriver.cpp @@ -261,7 +261,7 @@ } } PassInstrumentationCallbacks PIC; - StandardInstrumentations SI; + StandardInstrumentations SI(DebugPM); SI.registerCallbacks(PIC); PipelineTuningOptions PTO;