[clang] 048239e - [Coroutines][6/6] Clang schedules new passes
Brian Gesiak via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 18 22:07:37 PST 2020
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; }
More information about the cfe-commits
mailing list