From b13b85818218aa17cee4c987cbf835208c06cf10 Mon Sep 17 00:00:00 2001 From: Arthur Eubanks Date: Tue, 21 Jul 2020 09:48:22 -0700 Subject: [PATCH] [NewPM] Support optnone under new pass manager OptNoneInstrumentation is part of StandardInstrumentations. It skips functions (or loops) that are marked optnone. The feature of skipping optional passes for optnone functions under NPM is gated on a -enable-npm-optnone flag. Currently it is by default false. That is because we still need to mark all required passes to be required. Otherwise optnone functions will start having incorrect semantics. After that is done in following changes, we can remove the flag and always enable this. Reviewed By: ychen Differential Revision: https://reviews.llvm.org/D83519 --- clang/lib/CodeGen/BackendUtil.cpp | 2 +- .../include/llvm/Passes/StandardInstrumentations.h | 16 ++++- llvm/lib/LTO/LTOBackend.cpp | 2 +- llvm/lib/Passes/StandardInstrumentations.cpp | 32 +++++++++ llvm/test/Feature/optnone-opt.ll | 81 ++++++++++++++-------- llvm/tools/opt/NewPMDriver.cpp | 2 +- 6 files changed, 104 insertions(+), 31 deletions(-) diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index dce0940..3405c48 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -1153,7 +1153,7 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( 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 index 3d3002e..bd8b886 100644 --- 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 @@ private: 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 index 0c395f9..ca29548 100644 --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -197,7 +197,7 @@ static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM, } 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 index 1e1a6b9..22a7103 100644 --- 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 PrintIRInstrumentation::registerCallbacks( } } +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 index 2741806..3af0ce8 100644 --- 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 @@ while.end: ; preds = %while.cond 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 index 47c9cfc..acaa575 100644 --- a/llvm/tools/opt/NewPMDriver.cpp +++ b/llvm/tools/opt/NewPMDriver.cpp @@ -261,7 +261,7 @@ bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM, } } PassInstrumentationCallbacks PIC; - StandardInstrumentations SI; + StandardInstrumentations SI(DebugPM); SI.registerCallbacks(PIC); PipelineTuningOptions PTO; -- 2.7.4