diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp --- 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/PassManagerBuilder.h" @@ -1133,6 +1137,16 @@ if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) MPM.addPass(createModuleToFunctionPassAdaptor(BoundsCheckingPass())); + // For IR that makes use of coroutines intrinsics, coroutine passes must + // be run, even at -O0. + if (LangOpts.Coroutines) { + MPM.addPass(createModuleToFunctionPassAdaptor(CoroEarlyPass())); + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CoroSplitPass())); + MPM.addPass(createModuleToFunctionPassAdaptor(CoroElidePass())); + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CoroSplitPass())); + MPM.addPass(createModuleToFunctionPassAdaptor(CoroCleanupPass())); + } + // Lastly, add semantically necessary passes for LTO. if (IsLTO || IsThinLTO) { MPM.addPass(CanonicalizeAliasesPass()); @@ -1206,6 +1220,15 @@ MPM.addPass(InstrProfiling(*Options, false)); }); + if (LangOpts.Coroutines) + PB.registerPipelineStartEPCallback([](ModulePassManager &MPM) { + MPM.addPass(createModuleToFunctionPassAdaptor(CoroEarlyPass())); + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CoroSplitPass())); + MPM.addPass(createModuleToFunctionPassAdaptor(CoroElidePass())); + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CoroSplitPass())); + MPM.addPass(createModuleToFunctionPassAdaptor(CoroCleanupPass())); + }); + if (IsThinLTO) { MPM = PB.buildThinLTOPreLinkDefaultPipeline( Level, CodeGenOpts.DebugPassManager); diff --git a/clang/test/CodeGenCoroutines/coro-newpm-pipeline.cpp b/clang/test/CodeGenCoroutines/coro-newpm-pipeline.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenCoroutines/coro-newpm-pipeline.cpp @@ -0,0 +1,18 @@ +// 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 +// CHECK: Running pass:{{.*}}CoroSplitPass +// CHECK: Running pass:{{.*}}CoroElidePass +// CHECK: Running pass:{{.*}}CoroSplitPass +// CHECK: Running pass:{{.*}}CoroCleanupPass +// CHECK: Finished llvm::Module pass manager run. +void foo() {}