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,9 +14,15 @@ namespace llvm { class Pass; +class PassBuilder; class PassManagerBuilder; -/// Add all coroutine passes to appropriate extension points. +/// Register a callback to parse coroutines passes in a pass pipeline. +void registerCoroutinePipelineParsingCallback(PassBuilder &Builder, + bool DebugLogging = false); + +/// Add all coroutine passes to appropriate extension points using the legacy +/// pass manager. void addCoroutinePassesToExtensionPoints(PassManagerBuilder &Builder); /// Lower coroutine intrinsics that are not needed by later passes. 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" @@ -49,6 +54,26 @@ initializeCoroCleanupLegacyPass(Registry); } +void llvm::registerCoroutinePipelineParsingCallback(PassBuilder &Builder, + bool DebugLogging) { + Builder.registerPipelineParsingCallback( + [=](StringRef Name, ModulePassManager &MPM, + ArrayRef) { + if (Name == "coroutines") { + MPM.addPass(createModuleToFunctionPassAdaptor(CoroEarlyPass())); + + CGSCCPassManager CGPM(DebugLogging); + CGPM.addPass(CoroSplitPass()); + CGPM.addPass(createCGSCCToFunctionPassAdaptor(CoroElidePass())); + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM))); + + MPM.addPass(createModuleToFunctionPassAdaptor(CoroCleanupPass())); + return true; + } + return false; + }); +} + static void addCoroutineOpt0Passes(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { PM.add(createCoroSplitLegacyPass()); 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 @@ -4,6 +4,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" @@ -292,6 +293,9 @@ get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB); #include "llvm/Support/Extension.def" + // Register a callback that creates coroutines lowering passes as needed. + registerCoroutinePipelineParsingCallback(PB, DebugPM); + // Specially handle the alias analysis manager so that we can register // a custom pipeline of AA passes with it. AAManager AA;