diff --git a/llvm/include/llvm/Transforms/Coroutines/CoroCleanup.h b/llvm/include/llvm/Transforms/Coroutines/CoroCleanup.h --- a/llvm/include/llvm/Transforms/Coroutines/CoroCleanup.h +++ b/llvm/include/llvm/Transforms/Coroutines/CoroCleanup.h @@ -18,10 +18,10 @@ namespace llvm { -class Function; +class Module; struct CoroCleanupPass : PassInfoMixin { - PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); static bool isRequired() { return true; } }; } // end namespace llvm diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp --- a/llvm/lib/Passes/PassBuilderPipelines.cpp +++ b/llvm/lib/Passes/PassBuilderPipelines.cpp @@ -989,7 +989,7 @@ else MPM.addPass(buildInlinerPipeline(Level, Phase)); - MPM.addPass(createModuleToFunctionPassAdaptor(CoroCleanupPass())); + MPM.addPass(CoroCleanupPass()); if (EnableMemProfiler && Phase != ThinOrFullLTOPhase::ThinLTOPreLink) { MPM.addPass(createModuleToFunctionPassAdaptor(MemProfilerPass())); @@ -1836,7 +1836,7 @@ CGSCCPassManager CGPM; CGPM.addPass(CoroSplitPass()); CoroPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM))); - CoroPM.addPass(createModuleToFunctionPassAdaptor(CoroCleanupPass())); + CoroPM.addPass(CoroCleanupPass()); CoroPM.addPass(GlobalDCEPass()); MPM.addPass(CoroConditionalWrapper(std::move(CoroPM))); diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -51,6 +51,7 @@ MODULE_PASS("check-debugify", NewPMCheckDebugifyPass()) MODULE_PASS("constmerge", ConstantMergePass()) MODULE_PASS("coro-early", CoroEarlyPass()) +MODULE_PASS("coro-cleanup", CoroCleanupPass()) MODULE_PASS("cross-dso-cfi", CrossDSOCFIPass()) MODULE_PASS("deadargelim", DeadArgumentEliminationPass()) MODULE_PASS("debugify", NewPMDebugifyPass()) @@ -253,7 +254,6 @@ FUNCTION_PASS("constraint-elimination", ConstraintEliminationPass()) FUNCTION_PASS("chr", ControlHeightReductionPass()) FUNCTION_PASS("coro-elide", CoroElidePass()) -FUNCTION_PASS("coro-cleanup", CoroCleanupPass()) FUNCTION_PASS("correlated-propagation", CorrelatedValuePropagationPass()) FUNCTION_PASS("dce", DCEPass()) FUNCTION_PASS("dfa-jump-threading", DFAJumpThreadingPass()) diff --git a/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp b/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp --- a/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp @@ -23,7 +23,7 @@ struct Lowerer : coro::LowererBase { IRBuilder<> Builder; Lowerer(Module &M) : LowererBase(M), Builder(Context) {} - bool lowerRemainingCoroIntrinsics(Function &F); + void lower(Function &F); }; } @@ -53,9 +53,7 @@ SubFn->replaceAllUsesWith(Load); } -bool Lowerer::lowerRemainingCoroIntrinsics(Function &F) { - bool Changed = false; - +void Lowerer::lower(Function &F) { bool IsPrivateAndUnprocessed = F.hasFnAttribute(CORO_PRESPLIT_ATTR) && F.hasLocalLinkage(); @@ -112,16 +110,11 @@ break; } II->eraseFromParent(); - Changed = true; } } - if (Changed) { - // After replacement were made we can cleanup the function body a little. - simplifyCFG(F); - } - - return Changed; + // After replacement were made we can cleanup the function body a little. + simplifyCFG(F); } static bool declaresCoroCleanupIntrinsics(const Module &M) { @@ -132,12 +125,14 @@ "llvm.coro.async.resume"}); } -PreservedAnalyses CoroCleanupPass::run(Function &F, - FunctionAnalysisManager &AM) { - auto &M = *F.getParent(); - if (!declaresCoroCleanupIntrinsics(M) || - !Lowerer(M).lowerRemainingCoroIntrinsics(F)) +PreservedAnalyses CoroCleanupPass::run(Module &M, + ModuleAnalysisManager &MAM) { + if (!declaresCoroCleanupIntrinsics(M)) return PreservedAnalyses::all(); + Lowerer L(M); + for (auto &F : M) + L.lower(F); + return PreservedAnalyses::none(); } 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 @@ -10,7 +10,7 @@ ; RUN: opt < %s -disable-output -passes='default' \ ; RUN: -debug-pass-manager 2>&1 | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-OPT ; RUN: opt < %s -disable-output -debug-pass-manager \ -; RUN: -passes='module(coro-early),function(coro-elide),cgscc(coro-split),function(coro-cleanup)' 2>&1 \ +; RUN: -passes='module(coro-early),function(coro-elide),cgscc(coro-split),module(coro-cleanup)' 2>&1 \ ; RUN: | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-OPT ; note that we run CoroElidePass before CoroSplitPass. This is because CoroElidePass is part of