Author: Brian Gesiak Date: 2020-02-19T01:03:28-05:00 New Revision: 048239e46e490d441f21f3e26073ec38f19e8a10
URL: https://github.com/llvm/llvm-project/commit/048239e46e490d441f21f3e26073ec38f19e8a10 DIFF: https://github.com/llvm/llvm-project/commit/048239e46e490d441f21f3e26073ec38f19e8a10.diff LOG: [Coroutines][6/6] Clang schedules new passes Summary: Depends on https://reviews.llvm.org/D71902. The last in a series of six patches that ports the LLVM coroutines passes to the new pass manager infrastructure. This patch has Clang schedule the new coroutines passes when the `-fexperimental-new-pass-manager` option is used. With this and the previous 5 patches, Clang is capable of building and successfully running the test suite of large coroutines projects such as https://github.com/lewissbaker/cppcoro with `ENABLE_EXPERIMENTAL_NEW_PASS_MANAGER=On`. Reviewers: GorNishanov, lewissbaker, chandlerc, junparser Subscribers: EricWF, cfe-commits, llvm-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D71903 Added: clang/test/CodeGenCoroutines/coro-newpm-pipeline.cpp Modified: clang/lib/CodeGen/BackendUtil.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 6c71cf793c0f..b244fd499fb0 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -49,6 +49,10 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Transforms/Coroutines.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/AlwaysInliner.h" #include "llvm/Transforms/IPO/LowerTypeTests.h" @@ -957,6 +961,22 @@ static PassBuilder::OptimizationLevel mapToLevel(const CodeGenOptions &Opts) { } } +static void addCoroutinePassesAtO0(ModulePassManager &MPM, + const LangOptions &LangOpts, + const CodeGenOptions &CodeGenOpts) { + if (!LangOpts.Coroutines) + return; + + MPM.addPass(createModuleToFunctionPassAdaptor(CoroEarlyPass())); + + CGSCCPassManager CGPM(CodeGenOpts.DebugPassManager); + CGPM.addPass(CoroSplitPass()); + CGPM.addPass(createCGSCCToFunctionPassAdaptor(CoroElidePass())); + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM))); + + MPM.addPass(createModuleToFunctionPassAdaptor(CoroCleanupPass())); +} + static void addSanitizersAtO0(ModulePassManager &MPM, const Triple &TargetTriple, const LangOptions &LangOpts, @@ -1076,6 +1096,7 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( PTO.LoopInterleaving = CodeGenOpts.UnrollLoops; PTO.LoopVectorization = CodeGenOpts.VectorizeLoop; PTO.SLPVectorization = CodeGenOpts.VectorizeSLP; + PTO.Coroutines = LangOpts.Coroutines; PassInstrumentationCallbacks PIC; StandardInstrumentations SI; @@ -1279,6 +1300,7 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( } if (CodeGenOpts.OptimizationLevel == 0) { + addCoroutinePassesAtO0(MPM, LangOpts, CodeGenOpts); addSanitizersAtO0(MPM, TargetTriple, LangOpts, CodeGenOpts); } } diff --git a/clang/test/CodeGenCoroutines/coro-newpm-pipeline.cpp b/clang/test/CodeGenCoroutines/coro-newpm-pipeline.cpp new file mode 100644 index 000000000000..aed2cf13f892 --- /dev/null +++ b/clang/test/CodeGenCoroutines/coro-newpm-pipeline.cpp @@ -0,0 +1,57 @@ +// Tests that coroutine passes are added to and run by the new pass manager +// pipeline, at -O0 and above. + +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null \ +// RUN: -fexperimental-new-pass-manager -fdebug-pass-manager -fcoroutines-ts \ +// RUN: -O0 %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -o /dev/null \ +// RUN: -fexperimental-new-pass-manager -fdebug-pass-manager -fcoroutines-ts \ +// RUN: -O1 %s 2>&1 | FileCheck %s +// +// CHECK: Starting llvm::Module pass manager run. +// CHECK: Running pass:{{.*}}CoroEarlyPass +// +// The first coro-split pass enqueues a second run of the entire CGSCC pipeline. +// CHECK: Starting CGSCC pass manager run. +// CHECK: Running pass: CoroSplitPass on (_Z3foov) +// CHECK: Running pass:{{.*}}CoroElidePass{{.*}} on (_Z3foov) +// CHECK: Finished CGSCC pass manager run. +// +// The second coro-split pass splits coroutine 'foo' into funclets +// 'foo.resume', 'foo.destroy', and 'foo.cleanup'. +// CHECK: Starting CGSCC pass manager run. +// CHECK: Running pass: CoroSplitPass on (_Z3foov) +// CHECK: Running pass:{{.*}}CoroElidePass{{.*}} on (_Z3foov) +// CHECK: Finished CGSCC pass manager run. +// +// CHECK: Running pass:{{.*}}CoroCleanupPass +// CHECK: Finished llvm::Module pass manager run. + +namespace std { +namespace experimental { + +struct handle {}; + +struct awaitable { + bool await_ready() { return true; } + void await_suspend(handle) {} + bool await_resume() { return true; } +}; + +template <typename T> struct coroutine_handle { + static handle from_address(void *address) { return {}; } +}; + +template <typename T = void> struct coroutine_traits { + struct promise_type { + awaitable initial_suspend() { return {}; } + awaitable final_suspend() { return {}; } + void return_void() {} + T get_return_object() { return T(); } + void unhandled_exception() {} + }; +}; +} // namespace experimental +} // namespace std + +void foo() { co_return; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits