Author: Arthur Eubanks Date: 2020-11-04T22:27:16-08:00 New Revision: ae38540042668675dd16c642d850115f217ea59f
URL: https://github.com/llvm/llvm-project/commit/ae38540042668675dd16c642d850115f217ea59f DIFF: https://github.com/llvm/llvm-project/commit/ae38540042668675dd16c642d850115f217ea59f.diff LOG: [NewPM] Provide method to run all pipeline callbacks, used for -O0 Some targets may add required passes via TargetMachine::registerPassBuilderCallbacks(). We need to run those even under -O0. As an example, BPFTargetMachine adds BPFAbstractMemberAccessPass, a required pass. This also allows us to clean up BackendUtil.cpp (and out-of-tree Rust usage of the NPM) by allowing us to share added passes like coroutines and sanitizers between -O0 and other optimization levels. Tests are a continuation of those added in https://reviews.llvm.org/D89083. In order to prevent TargetMachines from adding unnecessary optimization passes at -O0, TargetMachine::registerPassBuilderCallbacks() will be changed to take an OptimizationLevel, but that will be done separately. Reviewed By: asbirlea Differential Revision: https://reviews.llvm.org/D89158 Added: clang/test/CodeGen/bpf-O0.c llvm/test/Other/new-pm-O0-ep-callbacks.ll Modified: clang/lib/CodeGen/BackendUtil.cpp llvm/include/llvm/Passes/PassBuilder.h llvm/lib/Passes/PassBuilder.cpp llvm/test/CodeGen/BPF/optnone-2.ll Removed: ################################################################################ diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 81ae79482d90..702982897c46 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -1015,6 +1015,9 @@ static PassBuilder::OptimizationLevel mapToLevel(const CodeGenOptions &Opts) { default: llvm_unreachable("Invalid optimization level!"); + case 0: + return PassBuilder::OptimizationLevel::O0; + case 1: return PassBuilder::OptimizationLevel::O1; @@ -1244,6 +1247,10 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( ModulePassManager MPM(CodeGenOpts.DebugPassManager); if (!CodeGenOpts.DisableLLVMPasses) { + // Map our optimization levels into one of the distinct levels used to + // configure the pipeline. + PassBuilder::OptimizationLevel Level = mapToLevel(CodeGenOpts); + bool IsThinLTO = CodeGenOpts.PrepareForThinLTO; bool IsLTO = CodeGenOpts.PrepareForLTO; @@ -1292,10 +1299,6 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( MPM.addPass(NameAnonGlobalPass()); } } else { - // Map our optimization levels into one of the distinct levels used to - // configure the pipeline. - PassBuilder::OptimizationLevel Level = mapToLevel(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 @@ -1433,6 +1436,8 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( } if (CodeGenOpts.OptimizationLevel == 0) { + PB.runRegisteredEPCallbacks(MPM, Level, CodeGenOpts.DebugPassManager); + // FIXME: the backends do not handle matrix intrinsics currently. Make // sure they are also lowered in O0. A lightweight version of the pass // should run in the backend pipeline on demand. diff --git a/clang/test/CodeGen/bpf-O0.c b/clang/test/CodeGen/bpf-O0.c new file mode 100644 index 000000000000..dddb5e0d2295 --- /dev/null +++ b/clang/test/CodeGen/bpf-O0.c @@ -0,0 +1,6 @@ +// RUN: %clang -O0 %s -target bpf -g -c -o /dev/null -fexperimental-new-pass-manager + +struct ss { + int a; +}; +int foo() { return __builtin_btf_type_id(0, 0) + __builtin_preserve_type_info(*(struct ss *)0, 0); } diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h index 31c4782eaba3..98af21b6276d 100644 --- a/llvm/include/llvm/Passes/PassBuilder.h +++ b/llvm/include/llvm/Passes/PassBuilder.h @@ -594,15 +594,20 @@ class PassBuilder { /// Register a callback for a default optimizer pipeline extension point /// /// This extension point allows adding optimizations at the very end of the - /// function optimization pipeline. A key diff erence between this and the - /// legacy PassManager's OptimizerLast callback is that this extension point - /// is not triggered at O0. Extensions to the O0 pipeline should append their - /// passes to the end of the overall pipeline. + /// function optimization pipeline. void registerOptimizerLastEPCallback( const std::function<void(ModulePassManager &, OptimizationLevel)> &C) { OptimizerLastEPCallbacks.push_back(C); } + /// Run all registered extension point callbacks + /// + /// This runs the registered callbacks in the order they would be run in a + /// typical build*Pipeline(). This allows for reusing register*EPCallback() + /// between O0 and O[123] pipelines. + void runRegisteredEPCallbacks(ModulePassManager &MPM, OptimizationLevel Level, + bool DebugLogging); + /// Register a callback for parsing an AliasAnalysis Name to populate /// the given AAManager \p AA void registerParseAACallback( diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 68bbb01d1fda..f1672c9f89cc 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -1658,6 +1658,49 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level, return MPM; } +void PassBuilder::runRegisteredEPCallbacks(ModulePassManager &MPM, + OptimizationLevel Level, + bool DebugLogging) { + assert(Level == OptimizationLevel::O0 && + "runRegisteredEPCallbacks should only be used with O0"); + for (auto &C : PipelineStartEPCallbacks) + C(MPM, Level); + if (!LateLoopOptimizationsEPCallbacks.empty()) { + LoopPassManager LPM(DebugLogging); + for (auto &C : LateLoopOptimizationsEPCallbacks) + C(LPM, Level); + MPM.addPass(createModuleToFunctionPassAdaptor( + createFunctionToLoopPassAdaptor(std::move(LPM)))); + } + if (!LoopOptimizerEndEPCallbacks.empty()) { + LoopPassManager LPM(DebugLogging); + for (auto &C : LoopOptimizerEndEPCallbacks) + C(LPM, Level); + MPM.addPass(createModuleToFunctionPassAdaptor( + createFunctionToLoopPassAdaptor(std::move(LPM)))); + } + if (!ScalarOptimizerLateEPCallbacks.empty()) { + FunctionPassManager FPM(DebugLogging); + for (auto &C : ScalarOptimizerLateEPCallbacks) + C(FPM, Level); + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); + } + if (!CGSCCOptimizerLateEPCallbacks.empty()) { + CGSCCPassManager CGPM(DebugLogging); + for (auto &C : CGSCCOptimizerLateEPCallbacks) + C(CGPM, Level); + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM))); + } + if (!VectorizerStartEPCallbacks.empty()) { + FunctionPassManager FPM(DebugLogging); + for (auto &C : VectorizerStartEPCallbacks) + C(FPM, Level); + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); + } + for (auto &C : OptimizerLastEPCallbacks) + C(MPM, Level); +} + AAManager PassBuilder::buildDefaultAAPipeline() { AAManager AA; @@ -2240,6 +2283,8 @@ Error PassBuilder::parseModulePass(ModulePassManager &MPM, MPM.addPass(createModuleToFunctionPassAdaptor(CoroCleanupPass())); } + runRegisteredEPCallbacks(MPM, L, DebugLogging); + // Do nothing else at all! return Error::success(); } diff --git a/llvm/test/CodeGen/BPF/optnone-2.ll b/llvm/test/CodeGen/BPF/optnone-2.ll index 82014bdaf2cc..16cbd67f0b6a 100644 --- a/llvm/test/CodeGen/BPF/optnone-2.ll +++ b/llvm/test/CodeGen/BPF/optnone-2.ll @@ -1,5 +1,5 @@ ; RUN: opt < %s -passes='default<O2>' | llc -march=bpfel -filetype=asm -o /dev/null - -; TODO: add -O0 once that's supported +; RUN: opt < %s -passes='default<O0>' | llc -march=bpfel -filetype=asm -o /dev/null - ; IR generated by ; $ cat /tmp/a.c diff --git a/llvm/test/Other/new-pm-O0-ep-callbacks.ll b/llvm/test/Other/new-pm-O0-ep-callbacks.ll new file mode 100644 index 000000000000..1645156c1b28 --- /dev/null +++ b/llvm/test/Other/new-pm-O0-ep-callbacks.ll @@ -0,0 +1,24 @@ +; RUN: opt -disable-output -debug-pass-manager -passes-ep-late-loop-optimizations=no-op-loop -passes='default<O0>' 2>&1 < %s | FileCheck %s +; RUN: opt -disable-output -debug-pass-manager -passes-ep-loop-optimizer-end=no-op-loop -passes='default<O0>' 2>&1 < %s | FileCheck %s +; RUN: opt -disable-output -debug-pass-manager -passes-ep-scalar-optimizer-late=no-op-function -passes='default<O0>' 2>&1 < %s | FileCheck %s +; RUN: opt -disable-output -debug-pass-manager -passes-ep-cgscc-optimizer-late=no-op-cgscc -passes='default<O0>' 2>&1 < %s | FileCheck %s +; RUN: opt -disable-output -debug-pass-manager -passes-ep-vectorizer-start=no-op-function -passes='default<O0>' 2>&1 < %s | FileCheck %s +; RUN: opt -disable-output -debug-pass-manager -passes-ep-pipeline-start=no-op-module -passes='default<O0>' 2>&1 < %s | FileCheck %s +; RUN: opt -disable-output -debug-pass-manager -passes-ep-optimizer-last=no-op-function -passes='default<O0>' 2>&1 < %s | FileCheck %s + +; CHECK: Running pass: NoOp + +declare void @bar() local_unnamed_addr + +define void @foo(i32 %n) local_unnamed_addr { +entry: + br label %loop +loop: + %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] + %iv.next = add i32 %iv, 1 + tail call void @bar() + %cmp = icmp eq i32 %iv, %n + br i1 %cmp, label %exit, label %loop +exit: + ret void +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits