diff --git a/llvm/include/llvm/Transforms/Coroutines.h b/llvm/include/llvm/Transforms/Coroutines.h --- a/llvm/include/llvm/Transforms/Coroutines.h +++ b/llvm/include/llvm/Transforms/Coroutines.h @@ -14,11 +14,15 @@ namespace llvm { class Pass; +class PassBuilder; class PassManagerBuilder; /// Add all coroutine passes to appropriate extension points. void addCoroutinePassesToExtensionPoints(PassManagerBuilder &Builder); +/// Register a callback to parse coroutines passes in a pass pipeline. +void registerCoroutinesPasses(PassBuilder &Builder); + /// Lower coroutine intrinsics that are not needed by later passes. Pass *createCoroEarlyLegacyPass(); diff --git a/llvm/lib/Transforms/Coroutines/Coroutines.cpp b/llvm/lib/Transforms/Coroutines/Coroutines.cpp --- a/llvm/lib/Transforms/Coroutines/Coroutines.cpp +++ b/llvm/lib/Transforms/Coroutines/Coroutines.cpp @@ -31,8 +31,13 @@ #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" #include "llvm/InitializePasses.h" +#include "llvm/Passes/PassBuilder.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Transforms/Coroutines/CoroCleanup.h" +#include "llvm/Transforms/Coroutines/CoroEarly.h" +#include "llvm/Transforms/Coroutines/CoroElide.h" +#include "llvm/Transforms/Coroutines/CoroSplit.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/Utils/Local.h" @@ -91,6 +96,22 @@ addCoroutineOptimizerLastPasses); } +void llvm::registerCoroutinesPasses(PassBuilder &Builder) { + Builder.registerPipelineParsingCallback( + [](StringRef Name, ModulePassManager &MPM, + ArrayRef) { + if (Name == "coroutines") { + MPM.addPass(createModuleToFunctionPassAdaptor(CoroEarlyPass())); + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CoroSplitPass())); + MPM.addPass(createModuleToFunctionPassAdaptor(CoroElidePass())); + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CoroSplitPass())); + MPM.addPass(createModuleToFunctionPassAdaptor(CoroCleanupPass())); + return true; + } + return false; + }); +} + // Construct the lowerer base class and initialize its members. coro::LowererBase::LowererBase(Module &M) : TheModule(M), Context(M.getContext()), diff --git a/llvm/test/Transforms/Coroutines/coro-cleanup.ll b/llvm/test/Transforms/Coroutines/coro-cleanup.ll --- a/llvm/test/Transforms/Coroutines/coro-cleanup.ll +++ b/llvm/test/Transforms/Coroutines/coro-cleanup.ll @@ -1,5 +1,6 @@ ; Make sure that all library helper coro intrinsics are lowered. ; RUN: opt < %s -O0 -enable-coroutines -S | FileCheck %s +; RUN: opt < %s -passes='coroutines' -S | FileCheck %s ; CHECK-LABEL: @uses_library_support_coro_intrinsics( ; CHECK-NOT: @llvm.coro diff --git a/llvm/test/Transforms/Coroutines/restart-trigger.ll b/llvm/test/Transforms/Coroutines/restart-trigger.ll --- a/llvm/test/Transforms/Coroutines/restart-trigger.ll +++ b/llvm/test/Transforms/Coroutines/restart-trigger.ll @@ -3,6 +3,7 @@ ; REQUIRES: asserts ; RUN: opt < %s -S -O0 -enable-coroutines -debug-only=coro-split 2>&1 | FileCheck %s ; RUN: opt < %s -S -O1 -enable-coroutines -debug-only=coro-split 2>&1 | FileCheck %s +; RUN: opt < %s -S -passes=coroutines -debug-only=coro-split 2>&1 | FileCheck %s ; CHECK: CoroSplit: Processing coroutine 'f' state: 0 ; CHECK-NEXT: CoroSplit: Processing coroutine 'f' state: 1 diff --git a/llvm/test/Transforms/Coroutines/smoketest.ll b/llvm/test/Transforms/Coroutines/smoketest.ll --- a/llvm/test/Transforms/Coroutines/smoketest.ll +++ b/llvm/test/Transforms/Coroutines/smoketest.ll @@ -9,6 +9,11 @@ ; RUN: -coro-early -coro-split -coro-elide -coro-cleanup 2>&1 | FileCheck %s ; RUN: opt < %s -disable-output -debug-pass=Arguments 2>&1 \ ; RUN: | FileCheck %s -check-prefix=NOCORO +; RUN: opt < %s -disable-output -passes=coroutines -debug-pass-manager 2>&1 \ +; RUN: | FileCheck %s -check-prefix=NEWPM +; RUN: opt < %s -disable-output \ +; RUN: -passes='coroutines,function(coro-early),cgscc(coro-split),function(coro-elide,coro-cleanup)' \ +; RUN: -debug-pass-manager 2>&1 | FileCheck %s -check-prefix=NEWPM ; CHECK: coro-early ; CHECK: coro-split @@ -20,6 +25,11 @@ ; NOCORO-NOT: coro-elide ; NOCORO-NOT: coro-cleanup +; NEWPM: CoroEarlyPass +; NEWPM: CoroSplitPass +; NEWPM: CoroElidePass +; NEWPM: CoroCleanupPass + define void @foo() { ret void } 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 @@ -32,6 +32,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/Coroutines.h" #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" #include "llvm/Transforms/Scalar/LoopPassManager.h" #include "llvm/Transforms/Utils/Debugify.h" @@ -290,6 +291,9 @@ return false; }); + // Register a callback that creates coroutines lowering passes as needed. + registerCoroutinesPasses(PB); + #ifdef LINK_POLLY_INTO_TOOLS polly::RegisterPollyPasses(PB); #endif