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 @@ -53,7 +53,6 @@ #include "llvm/Support/raw_ostream.h" #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" diff --git a/llvm/bindings/go/llvm/transforms_coroutines.go b/llvm/bindings/go/llvm/transforms_coroutines.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/transforms_coroutines.go +++ /dev/null @@ -1,23 +0,0 @@ -//===- transforms_coroutines.go - Bindings for coroutines -----------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines bindings for the coroutines component. -// -//===----------------------------------------------------------------------===// - -package llvm - -/* -#include "llvm-c/Transforms/Coroutines.h" -*/ -import "C" - -func (pm PassManager) AddCoroEarlyPass() { C.LLVMAddCoroEarlyPass(pm.C) } -func (pm PassManager) AddCoroSplitPass() { C.LLVMAddCoroSplitPass(pm.C) } -func (pm PassManager) AddCoroElidePass() { C.LLVMAddCoroElidePass(pm.C) } -func (pm PassManager) AddCoroCleanupPass() { C.LLVMAddCoroCleanupPass(pm.C) } diff --git a/llvm/bindings/go/llvm/transforms_pmbuilder.go b/llvm/bindings/go/llvm/transforms_pmbuilder.go --- a/llvm/bindings/go/llvm/transforms_pmbuilder.go +++ b/llvm/bindings/go/llvm/transforms_pmbuilder.go @@ -14,7 +14,6 @@ /* #include "llvm-c/Transforms/PassManagerBuilder.h" -#include "llvm-c/Transforms/Coroutines.h" */ import "C" @@ -62,7 +61,3 @@ func (pmb PassManagerBuilder) UseInlinerWithThreshold(threshold uint) { C.LLVMPassManagerBuilderUseInlinerWithThreshold(pmb.C, C.uint(threshold)) } - -func (pmb PassManagerBuilder) AddCoroutinePassesToExtensionPoints() { - C.LLVMPassManagerBuilderAddCoroutinePassesToExtensionPoints(pmb.C); -} diff --git a/llvm/include/llvm-c/Transforms/Coroutines.h b/llvm/include/llvm-c/Transforms/Coroutines.h deleted file mode 100644 --- a/llvm/include/llvm-c/Transforms/Coroutines.h +++ /dev/null @@ -1,56 +0,0 @@ -/*===-- Coroutines.h - Coroutines Library C Interface -----------*- C++ -*-===*\ -|* *| -|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| -|* Exceptions. *| -|* See https://llvm.org/LICENSE.txt for license information. *| -|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| -|* *| -|*===----------------------------------------------------------------------===*| -|* *| -|* This header declares the C interface to libLLVMCoroutines.a, which *| -|* implements various scalar transformations of the LLVM IR. *| -|* *| -|* Many exotic languages can interoperate with C code but have a harder time *| -|* with C++ due to name mangling. So in addition to C, this interface enables *| -|* tools written in such languages. *| -|* *| -\*===----------------------------------------------------------------------===*/ - -#ifndef LLVM_C_TRANSFORMS_COROUTINES_H -#define LLVM_C_TRANSFORMS_COROUTINES_H - -#include "llvm-c/ExternC.h" -#include "llvm-c/Types.h" -#include "llvm-c/Transforms/PassManagerBuilder.h" - -LLVM_C_EXTERN_C_BEGIN - -/** - * @defgroup LLVMCTransformsCoroutines Coroutine transformations - * @ingroup LLVMCTransforms - * - * @{ - */ - -/** See llvm::createCoroEarlyLegacyPass function. */ -void LLVMAddCoroEarlyPass(LLVMPassManagerRef PM); - -/** See llvm::createCoroSplitLegacyPass function. */ -void LLVMAddCoroSplitPass(LLVMPassManagerRef PM); - -/** See llvm::createCoroElideLegacyPass function. */ -void LLVMAddCoroElidePass(LLVMPassManagerRef PM); - -/** See llvm::createCoroCleanupLegacyPass function. */ -void LLVMAddCoroCleanupPass(LLVMPassManagerRef PM); - -/** See llvm::addCoroutinePassesToExtensionPoints. */ -void LLVMPassManagerBuilderAddCoroutinePassesToExtensionPoints(LLVMPassManagerBuilderRef PMB); - -/** - * @} - */ - -LLVM_C_EXTERN_C_END - -#endif diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -48,9 +48,6 @@ /// Initialize all passes linked into the Analysis library. void initializeAnalysis(PassRegistry&); -/// Initialize all passes linked into the Coroutines library. -void initializeCoroutines(PassRegistry&); - /// Initialize all passes linked into the CodeGen library. void initializeCodeGen(PassRegistry&); diff --git a/llvm/include/llvm/Transforms/Coroutines.h b/llvm/include/llvm/Transforms/Coroutines.h deleted file mode 100644 --- a/llvm/include/llvm/Transforms/Coroutines.h +++ /dev/null @@ -1,37 +0,0 @@ -//===-- Coroutines.h - Coroutine Transformations ----------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// Declare accessor functions for coroutine lowering passes. -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TRANSFORMS_COROUTINES_H -#define LLVM_TRANSFORMS_COROUTINES_H - -namespace llvm { - -class Pass; -class PassManagerBuilder; - -/// Add all coroutine passes to appropriate extension points. -void addCoroutinePassesToExtensionPoints(PassManagerBuilder &Builder); - -/// Lower coroutine intrinsics that are not needed by later passes. -Pass *createCoroEarlyLegacyPass(); - -/// Split up coroutines into multiple functions driving their state machines. -Pass *createCoroSplitLegacyPass(bool IsOptimizing = false); - -/// Analyze coroutines use sites, devirtualize resume/destroy calls and elide -/// heap allocation for coroutine frame where possible. -Pass *createCoroElideLegacyPass(); - -/// Lower all remaining coroutine intrinsics. -Pass *createCoroCleanupLegacyPass(); - -} - -#endif 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 @@ -141,41 +141,3 @@ return PreservedAnalyses::none(); } - -namespace { - -struct CoroCleanupLegacy : FunctionPass { - static char ID; // Pass identification, replacement for typeid - - CoroCleanupLegacy() : FunctionPass(ID) { - initializeCoroCleanupLegacyPass(*PassRegistry::getPassRegistry()); - } - - std::unique_ptr L; - - // This pass has work to do only if we find intrinsics we are going to lower - // in the module. - bool doInitialization(Module &M) override { - if (declaresCoroCleanupIntrinsics(M)) - L = std::make_unique(M); - return false; - } - - bool runOnFunction(Function &F) override { - if (L) - return L->lowerRemainingCoroIntrinsics(F); - return false; - } - void getAnalysisUsage(AnalysisUsage &AU) const override { - if (!L) - AU.setPreservesAll(); - } - StringRef getPassName() const override { return "Coroutine Cleanup"; } -}; -} - -char CoroCleanupLegacy::ID = 0; -INITIALIZE_PASS(CoroCleanupLegacy, "coro-cleanup", - "Lower all coroutine related intrinsics", false, false) - -Pass *llvm::createCoroCleanupLegacyPass() { return new CoroCleanupLegacy(); } diff --git a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp --- a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp @@ -256,43 +256,3 @@ PA.preserveSet(); return PA; } - -namespace { - -struct CoroEarlyLegacy : public FunctionPass { - static char ID; // Pass identification, replacement for typeid. - CoroEarlyLegacy() : FunctionPass(ID) { - initializeCoroEarlyLegacyPass(*PassRegistry::getPassRegistry()); - } - - std::unique_ptr L; - - // This pass has work to do only if we find intrinsics we are going to lower - // in the module. - bool doInitialization(Module &M) override { - if (declaresCoroEarlyIntrinsics(M)) - L = std::make_unique(M); - return false; - } - - bool runOnFunction(Function &F) override { - if (!L) - return false; - - return L->lowerEarlyIntrinsics(F); - } - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.setPreservesCFG(); - } - StringRef getPassName() const override { - return "Lower early coroutine intrinsics"; - } -}; -} - -char CoroEarlyLegacy::ID = 0; -INITIALIZE_PASS(CoroEarlyLegacy, "coro-early", - "Lower early coroutine intrinsics", false, false) - -Pass *llvm::createCoroEarlyLegacyPass() { return new CoroEarlyLegacy(); } diff --git a/llvm/lib/Transforms/Coroutines/CoroElide.cpp b/llvm/lib/Transforms/Coroutines/CoroElide.cpp --- a/llvm/lib/Transforms/Coroutines/CoroElide.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroElide.cpp @@ -370,26 +370,6 @@ return true; } -// See if there are any coro.subfn.addr instructions referring to coro.devirt -// trigger, if so, replace them with a direct call to devirt trigger function. -static bool replaceDevirtTrigger(Function &F) { - SmallVector DevirtAddr; - for (auto &I : instructions(F)) - if (auto *SubFn = dyn_cast(&I)) - if (SubFn->getIndex() == CoroSubFnInst::RestartTrigger) - DevirtAddr.push_back(SubFn); - - if (DevirtAddr.empty()) - return false; - - Module &M = *F.getParent(); - Function *DevirtFn = M.getFunction(CORO_DEVIRT_TRIGGER_FN); - assert(DevirtFn && "coro.devirt.fn not found"); - replaceWithConstant(DevirtFn, DevirtAddr); - - return true; -} - static bool declaresCoroElideIntrinsics(Module &M) { return coro::declaresIntrinsics(M, {"llvm.coro.id", "llvm.coro.id.async"}); } @@ -415,62 +395,3 @@ return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all(); } - -namespace { -struct CoroElideLegacy : FunctionPass { - static char ID; - CoroElideLegacy() : FunctionPass(ID) { - initializeCoroElideLegacyPass(*PassRegistry::getPassRegistry()); - } - - std::unique_ptr L; - - bool doInitialization(Module &M) override { - if (declaresCoroElideIntrinsics(M)) - L = std::make_unique(M); - return false; - } - - bool runOnFunction(Function &F) override { - if (!L) - return false; - - bool Changed = false; - - if (F.hasFnAttribute(CORO_PRESPLIT_ATTR)) - Changed = replaceDevirtTrigger(F); - - L->CoroIds.clear(); - L->collectPostSplitCoroIds(&F); - // If we did not find any coro.id, there is nothing to do. - if (L->CoroIds.empty()) - return Changed; - - AAResults &AA = getAnalysis().getAAResults(); - DominatorTree &DT = getAnalysis().getDomTree(); - - for (auto *CII : L->CoroIds) - Changed |= L->processCoroId(CII, AA, DT); - - return Changed; - } - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); - AU.addRequired(); - } - StringRef getPassName() const override { return "Coroutine Elision"; } -}; -} - -char CoroElideLegacy::ID = 0; -INITIALIZE_PASS_BEGIN( - CoroElideLegacy, "coro-elide", - "Coroutine frame allocation elision and indirect calls replacement", false, - false) -INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) -INITIALIZE_PASS_END( - CoroElideLegacy, "coro-elide", - "Coroutine frame allocation elision and indirect calls replacement", false, - false) - -Pass *llvm::createCoroElideLegacyPass() { return new CoroElideLegacy(); } diff --git a/llvm/lib/Transforms/Coroutines/CoroInternal.h b/llvm/lib/Transforms/Coroutines/CoroInternal.h --- a/llvm/lib/Transforms/Coroutines/CoroInternal.h +++ b/llvm/lib/Transforms/Coroutines/CoroInternal.h @@ -13,7 +13,6 @@ #include "CoroInstr.h" #include "llvm/IR/IRBuilder.h" -#include "llvm/Transforms/Coroutines.h" namespace llvm { @@ -21,11 +20,6 @@ class CallGraphSCC; class PassRegistry; -void initializeCoroEarlyLegacyPass(PassRegistry &); -void initializeCoroSplitLegacyPass(PassRegistry &); -void initializeCoroElideLegacyPass(PassRegistry &); -void initializeCoroCleanupLegacyPass(PassRegistry &); - // CoroEarly pass marks every function that has coro.begin with a string // attribute "coroutine.presplit"="0". CoroSplit pass processes the coroutine // twice. First, it lets it go through complete IPO optimization pipeline as a @@ -54,8 +48,7 @@ bool declaresIntrinsics(const Module &M, const std::initializer_list); void replaceCoroFree(CoroIdInst *CoroId, bool Elide); -void updateCallGraph(Function &Caller, ArrayRef Funcs, - CallGraph &CG, CallGraphSCC &SCC); + /// Recover a dbg.declare prepared by the frontend and emit an alloca /// holding a pointer to the coroutine frame. void salvageDebugInfo( diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp --- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -1079,13 +1079,6 @@ return Cloner.getFunction(); } -/// Remove calls to llvm.coro.end in the original function. -static void removeCoroEnds(const coro::Shape &Shape, CallGraph *CG) { - for (auto End : Shape.CoroEnds) { - replaceCoroEnd(End, Shape, Shape.FramePtr, /*in resume*/ false, CG); - } -} - static void updateAsyncFuncPointerContextSize(coro::Shape &Shape) { assert(Shape.ABI == coro::ABI::Async); @@ -1957,20 +1950,6 @@ return Shape; } -static void -updateCallGraphAfterCoroutineSplit(Function &F, const coro::Shape &Shape, - const SmallVectorImpl &Clones, - CallGraph &CG, CallGraphSCC &SCC) { - if (!Shape.CoroBegin) - return; - - removeCoroEnds(Shape, &CG); - postSplitCleanup(F); - - // Update call graph and add the functions we created to the SCC. - coro::updateCallGraph(F, Clones, CG, SCC); -} - static void updateCallGraphAfterCoroutineSplit( LazyCallGraph::Node &N, const coro::Shape &Shape, const SmallVectorImpl &Clones, LazyCallGraph::SCC &C, @@ -2013,70 +1992,6 @@ updateCGAndAnalysisManagerForFunctionPass(CG, C, N, AM, UR, FAM); } -// When we see the coroutine the first time, we insert an indirect call to a -// devirt trigger function and mark the coroutine that it is now ready for -// split. -// Async lowering uses this after it has split the function to restart the -// pipeline. -static void prepareForSplit(Function &F, CallGraph &CG, - bool MarkForAsyncRestart = false) { - Module &M = *F.getParent(); - LLVMContext &Context = F.getContext(); -#ifndef NDEBUG - Function *DevirtFn = M.getFunction(CORO_DEVIRT_TRIGGER_FN); - assert(DevirtFn && "coro.devirt.trigger function not found"); -#endif - - F.addFnAttr(CORO_PRESPLIT_ATTR, MarkForAsyncRestart - ? ASYNC_RESTART_AFTER_SPLIT - : PREPARED_FOR_SPLIT); - - // Insert an indirect call sequence that will be devirtualized by CoroElide - // pass: - // %0 = call i8* @llvm.coro.subfn.addr(i8* null, i8 -1) - // %1 = bitcast i8* %0 to void(i8*)* - // call void %1(i8* null) - coro::LowererBase Lowerer(M); - Instruction *InsertPt = - MarkForAsyncRestart ? F.getEntryBlock().getFirstNonPHIOrDbgOrLifetime() - : F.getEntryBlock().getTerminator(); - auto *Null = ConstantPointerNull::get(Type::getInt8PtrTy(Context)); - auto *DevirtFnAddr = - Lowerer.makeSubFnCall(Null, CoroSubFnInst::RestartTrigger, InsertPt); - FunctionType *FnTy = FunctionType::get(Type::getVoidTy(Context), - {Type::getInt8PtrTy(Context)}, false); - auto *IndirectCall = CallInst::Create(FnTy, DevirtFnAddr, Null, "", InsertPt); - - // Update CG graph with an indirect call we just added. - CG[&F]->addCalledFunction(IndirectCall, CG.getCallsExternalNode()); -} - -// Make sure that there is a devirtualization trigger function that the -// coro-split pass uses to force a restart of the CGSCC pipeline. If the devirt -// trigger function is not found, we will create one and add it to the current -// SCC. -static void createDevirtTriggerFunc(CallGraph &CG, CallGraphSCC &SCC) { - Module &M = CG.getModule(); - if (M.getFunction(CORO_DEVIRT_TRIGGER_FN)) - return; - - LLVMContext &C = M.getContext(); - auto *FnTy = FunctionType::get(Type::getVoidTy(C), Type::getInt8PtrTy(C), - /*isVarArg=*/false); - Function *DevirtFn = - Function::Create(FnTy, GlobalValue::LinkageTypes::PrivateLinkage, - CORO_DEVIRT_TRIGGER_FN, &M); - DevirtFn->addFnAttr(Attribute::AlwaysInline); - auto *Entry = BasicBlock::Create(C, "entry", DevirtFn); - ReturnInst::Create(C, Entry); - - auto *Node = CG.getOrInsertFunction(DevirtFn); - - SmallVector Nodes(SCC.begin(), SCC.end()); - Nodes.push_back(Node); - SCC.initialize(Nodes); -} - /// Replace a call to llvm.coro.prepare.retcon. static void replacePrepare(CallInst *Prepare, LazyCallGraph &CG, LazyCallGraph::SCC &C) { @@ -2113,59 +2028,6 @@ Cast->eraseFromParent(); } } -/// Replace a call to llvm.coro.prepare.retcon. -static void replacePrepare(CallInst *Prepare, CallGraph &CG) { - auto CastFn = Prepare->getArgOperand(0); // as an i8* - auto Fn = CastFn->stripPointerCasts(); // as its original type - - // Find call graph nodes for the preparation. - CallGraphNode *PrepareUserNode = nullptr, *FnNode = nullptr; - if (auto ConcreteFn = dyn_cast(Fn)) { - PrepareUserNode = CG[Prepare->getFunction()]; - FnNode = CG[ConcreteFn]; - } - - // Attempt to peephole this pattern: - // %0 = bitcast [[TYPE]] @some_function to i8* - // %1 = call @llvm.coro.prepare.retcon(i8* %0) - // %2 = bitcast %1 to [[TYPE]] - // ==> - // %2 = @some_function - for (Use &U : llvm::make_early_inc_range(Prepare->uses())) { - // Look for bitcasts back to the original function type. - auto *Cast = dyn_cast(U.getUser()); - if (!Cast || Cast->getType() != Fn->getType()) continue; - - // Check whether the replacement will introduce new direct calls. - // If so, we'll need to update the call graph. - if (PrepareUserNode) { - for (auto &Use : Cast->uses()) { - if (auto *CB = dyn_cast(Use.getUser())) { - if (!CB->isCallee(&Use)) - continue; - PrepareUserNode->removeCallEdgeFor(*CB); - PrepareUserNode->addCalledFunction(CB, FnNode); - } - } - } - - // Replace and remove the cast. - Cast->replaceAllUsesWith(Fn); - Cast->eraseFromParent(); - } - - // Replace any remaining uses with the function as an i8*. - // This can never directly be a callee, so we don't need to update CG. - Prepare->replaceAllUsesWith(CastFn); - Prepare->eraseFromParent(); - - // Kill dead bitcasts. - while (auto *Cast = dyn_cast(CastFn)) { - if (!Cast->use_empty()) break; - CastFn = Cast->getOperand(0); - Cast->eraseFromParent(); - } -} static bool replaceAllPrepares(Function *PrepareFn, LazyCallGraph &CG, LazyCallGraph::SCC &C) { @@ -2180,30 +2042,6 @@ return Changed; } -/// Remove calls to llvm.coro.prepare.retcon, a barrier meant to prevent -/// IPO from operating on calls to a retcon coroutine before it's been -/// split. This is only safe to do after we've split all retcon -/// coroutines in the module. We can do that this in this pass because -/// this pass does promise to split all retcon coroutines (as opposed to -/// switch coroutines, which are lowered in multiple stages). -static bool replaceAllPrepares(Function *PrepareFn, CallGraph &CG) { - bool Changed = false; - for (Use &P : llvm::make_early_inc_range(PrepareFn->uses())) { - // Intrinsics can only be used in calls. - auto *Prepare = cast(P.getUser()); - replacePrepare(Prepare, CG); - Changed = true; - } - - return Changed; -} - -static bool declaresCoroSplitIntrinsics(const Module &M) { - return coro::declaresIntrinsics(M, {"llvm.coro.begin", - "llvm.coro.prepare.retcon", - "llvm.coro.prepare.async"}); -} - static void addPrepareFunction(const Module &M, SmallVectorImpl &Fns, StringRef Name) { @@ -2271,122 +2109,3 @@ return PreservedAnalyses::none(); } - -namespace { - -// We present a coroutine to LLVM as an ordinary function with suspension -// points marked up with intrinsics. We let the optimizer party on the coroutine -// as a single function for as long as possible. Shortly before the coroutine is -// eligible to be inlined into its callers, we split up the coroutine into parts -// corresponding to initial, resume and destroy invocations of the coroutine, -// add them to the current SCC and restart the IPO pipeline to optimize the -// coroutine subfunctions we extracted before proceeding to the caller of the -// coroutine. -struct CoroSplitLegacy : public CallGraphSCCPass { - static char ID; // Pass identification, replacement for typeid - - CoroSplitLegacy(bool OptimizeFrame = false) - : CallGraphSCCPass(ID), OptimizeFrame(OptimizeFrame) { - initializeCoroSplitLegacyPass(*PassRegistry::getPassRegistry()); - } - - bool Run = false; - bool OptimizeFrame; - - // A coroutine is identified by the presence of coro.begin intrinsic, if - // we don't have any, this pass has nothing to do. - bool doInitialization(CallGraph &CG) override { - Run = declaresCoroSplitIntrinsics(CG.getModule()); - return CallGraphSCCPass::doInitialization(CG); - } - - bool runOnSCC(CallGraphSCC &SCC) override { - if (!Run) - return false; - - // Check for uses of llvm.coro.prepare.retcon. - SmallVector PrepareFns; - auto &M = SCC.getCallGraph().getModule(); - addPrepareFunction(M, PrepareFns, "llvm.coro.prepare.retcon"); - addPrepareFunction(M, PrepareFns, "llvm.coro.prepare.async"); - - // Find coroutines for processing. - SmallVector Coroutines; - for (CallGraphNode *CGN : SCC) - if (auto *F = CGN->getFunction()) - if (F->hasFnAttribute(CORO_PRESPLIT_ATTR)) - Coroutines.push_back(F); - - if (Coroutines.empty() && PrepareFns.empty()) - return false; - - CallGraph &CG = getAnalysis().getCallGraph(); - - if (Coroutines.empty()) { - bool Changed = false; - for (auto *PrepareFn : PrepareFns) - Changed |= replaceAllPrepares(PrepareFn, CG); - return Changed; - } - - createDevirtTriggerFunc(CG, SCC); - - // Split all the coroutines. - for (Function *F : Coroutines) { - Attribute Attr = F->getFnAttribute(CORO_PRESPLIT_ATTR); - StringRef Value = Attr.getValueAsString(); - LLVM_DEBUG(dbgs() << "CoroSplit: Processing coroutine '" << F->getName() - << "' state: " << Value << "\n"); - // Async lowering marks coroutines to trigger a restart of the pipeline - // after it has split them. - if (Value == ASYNC_RESTART_AFTER_SPLIT) { - F->removeFnAttr(CORO_PRESPLIT_ATTR); - continue; - } - if (Value == UNPREPARED_FOR_SPLIT) { - prepareForSplit(*F, CG); - continue; - } - F->removeFnAttr(CORO_PRESPLIT_ATTR); - - SmallVector Clones; - const coro::Shape Shape = splitCoroutine(*F, Clones, OptimizeFrame); - updateCallGraphAfterCoroutineSplit(*F, Shape, Clones, CG, SCC); - if (Shape.ABI == coro::ABI::Async) { - // Restart SCC passes. - // Mark function for CoroElide pass. It will devirtualize causing a - // restart of the SCC pipeline. - prepareForSplit(*F, CG, true /*MarkForAsyncRestart*/); - } - } - - for (auto *PrepareFn : PrepareFns) - replaceAllPrepares(PrepareFn, CG); - - return true; - } - - void getAnalysisUsage(AnalysisUsage &AU) const override { - CallGraphSCCPass::getAnalysisUsage(AU); - } - - StringRef getPassName() const override { return "Coroutine Splitting"; } -}; - -} // end anonymous namespace - -char CoroSplitLegacy::ID = 0; - -INITIALIZE_PASS_BEGIN( - CoroSplitLegacy, "coro-split", - "Split coroutine into a set of functions driving its state machine", false, - false) -INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) -INITIALIZE_PASS_END( - CoroSplitLegacy, "coro-split", - "Split coroutine into a set of functions driving its state machine", false, - false) - -Pass *llvm::createCoroSplitLegacyPass(bool OptimizeFrame) { - return new CoroSplitLegacy(OptimizeFrame); -} 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 @@ -10,10 +10,8 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/Coroutines.h" #include "CoroInstr.h" #include "CoroInternal.h" -#include "llvm-c/Transforms/Coroutines.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Analysis/CallGraph.h" @@ -41,55 +39,6 @@ using namespace llvm; -void llvm::initializeCoroutines(PassRegistry &Registry) { - initializeCoroEarlyLegacyPass(Registry); - initializeCoroSplitLegacyPass(Registry); - initializeCoroElideLegacyPass(Registry); - initializeCoroCleanupLegacyPass(Registry); -} - -static void addCoroutineOpt0Passes(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - PM.add(createCoroSplitLegacyPass()); - PM.add(createCoroElideLegacyPass()); - - PM.add(createBarrierNoopPass()); - PM.add(createCoroCleanupLegacyPass()); -} - -static void addCoroutineEarlyPasses(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - PM.add(createCoroEarlyLegacyPass()); -} - -static void addCoroutineScalarOptimizerPasses(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - PM.add(createCoroElideLegacyPass()); -} - -static void addCoroutineSCCPasses(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - PM.add(createCoroSplitLegacyPass(Builder.OptLevel != 0)); -} - -static void addCoroutineOptimizerLastPasses(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { - PM.add(createCoroCleanupLegacyPass()); -} - -void llvm::addCoroutinePassesToExtensionPoints(PassManagerBuilder &Builder) { - Builder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, - addCoroutineEarlyPasses); - Builder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, - addCoroutineOpt0Passes); - Builder.addExtension(PassManagerBuilder::EP_CGSCCOptimizerLate, - addCoroutineSCCPasses); - Builder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, - addCoroutineScalarOptimizerPasses); - Builder.addExtension(PassManagerBuilder::EP_OptimizerLast, - addCoroutineOptimizerLastPasses); -} - // Construct the lowerer base class and initialize its members. coro::LowererBase::LowererBase(Module &M) : TheModule(M), Context(M.getContext()), @@ -202,46 +151,6 @@ } } -// FIXME: This code is stolen from CallGraph::addToCallGraph(Function *F), which -// happens to be private. It is better for this functionality exposed by the -// CallGraph. -static void buildCGN(CallGraph &CG, CallGraphNode *Node) { - Function *F = Node->getFunction(); - - // Look for calls by this function. - for (Instruction &I : instructions(F)) - if (auto *Call = dyn_cast(&I)) { - const Function *Callee = Call->getCalledFunction(); - if (!Callee || !Intrinsic::isLeaf(Callee->getIntrinsicID())) - // Indirect calls of intrinsics are not allowed so no need to check. - // We can be more precise here by using TargetArg returned by - // Intrinsic::isLeaf. - Node->addCalledFunction(Call, CG.getCallsExternalNode()); - else if (!Callee->isIntrinsic()) - Node->addCalledFunction(Call, CG.getOrInsertFunction(Callee)); - } -} - -// Rebuild CGN after we extracted parts of the code from ParentFunc into -// NewFuncs. Builds CGNs for the NewFuncs and adds them to the current SCC. -void coro::updateCallGraph(Function &ParentFunc, ArrayRef NewFuncs, - CallGraph &CG, CallGraphSCC &SCC) { - // Rebuild CGN from scratch for the ParentFunc - auto *ParentNode = CG[&ParentFunc]; - ParentNode->removeAllCalledFunctions(); - buildCGN(CG, ParentNode); - - SmallVector Nodes(SCC.begin(), SCC.end()); - - for (Function *F : NewFuncs) { - CallGraphNode *Callee = CG.getOrInsertFunction(F); - Nodes.push_back(Callee); - buildCGN(CG, Callee); - } - - SCC.initialize(Nodes); -} - static void clear(coro::Shape &Shape) { Shape.CoroBegin = nullptr; Shape.CoroEnds.clear(); @@ -746,25 +655,3 @@ "match the tail arguments", MustTailCallFunc); } - -void LLVMAddCoroEarlyPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createCoroEarlyLegacyPass()); -} - -void LLVMAddCoroSplitPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createCoroSplitLegacyPass()); -} - -void LLVMAddCoroElidePass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createCoroElideLegacyPass()); -} - -void LLVMAddCoroCleanupPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createCoroCleanupLegacyPass()); -} - -void -LLVMPassManagerBuilderAddCoroutinePassesToExtensionPoints(LLVMPassManagerBuilderRef PMB) { - PassManagerBuilder *Builder = unwrap(PMB); - addCoroutinePassesToExtensionPoints(*Builder); -} diff --git a/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-infinite-loop-bug.ll b/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-infinite-loop-bug.ll --- a/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-infinite-loop-bug.ll +++ b/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-infinite-loop-bug.ll @@ -1,5 +1,4 @@ -; RUN: opt < %s -enable-coroutines -passes='default' -S | FileCheck --check-prefixes=CHECK %s -; RUN: opt < %s -enable-coroutines -O0 -S | FileCheck --check-prefixes=CHECK %s +; RUN: opt < %s -O0 -S | FileCheck --check-prefixes=CHECK %s target datalayout = "p:64:64:64" diff --git a/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-start-bug.ll b/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-start-bug.ll --- a/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-start-bug.ll +++ b/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-start-bug.ll @@ -1,5 +1,4 @@ -; RUN: opt < %s -enable-coroutines -passes='default' -S | FileCheck --check-prefixes=CHECK %s -; RUN: opt < %s -enable-coroutines -O0 -S | FileCheck --check-prefixes=CHECK %s +; RUN: opt < %s -O0 -S | FileCheck --check-prefixes=CHECK %s target datalayout = "p:64:64:64" diff --git a/llvm/test/Transforms/Coroutines/coro-async-phi.ll b/llvm/test/Transforms/Coroutines/coro-async-phi.ll --- a/llvm/test/Transforms/Coroutines/coro-async-phi.ll +++ b/llvm/test/Transforms/Coroutines/coro-async-phi.ll @@ -1,5 +1,4 @@ -; RUN: opt < %s -enable-coroutines -O0 -S | FileCheck --check-prefixes=CHECK %s -; RUN: opt < %s -enable-coroutines -passes='default' -S | FileCheck --check-prefixes=CHECK %s +; RUN: opt < %s -O0 -S | FileCheck --check-prefixes=CHECK %s %swift.async_func_pointer = type <{ i32, i32 }> %swift.context = type { %swift.context*, void (%swift.context*)*, i64 } diff --git a/llvm/test/Transforms/Coroutines/coro-async-remat.ll b/llvm/test/Transforms/Coroutines/coro-async-remat.ll --- a/llvm/test/Transforms/Coroutines/coro-async-remat.ll +++ b/llvm/test/Transforms/Coroutines/coro-async-remat.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -enable-coroutines -O0 -S +; RUN: opt < %s -O0 -S %async_func_ptr = type <{ i32, i32 }> %Tsq = type <{}> diff --git a/llvm/test/Transforms/Coroutines/coro-async-unreachable.ll b/llvm/test/Transforms/Coroutines/coro-async-unreachable.ll --- a/llvm/test/Transforms/Coroutines/coro-async-unreachable.ll +++ b/llvm/test/Transforms/Coroutines/coro-async-unreachable.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -enable-coroutines -passes='default' -S | FileCheck --check-prefixes=CHECK %s +; RUN: opt < %s -passes='default' -S | FileCheck --check-prefixes=CHECK %s target datalayout = "p:64:64:64" diff --git a/llvm/test/Transforms/Coroutines/coro-async.ll b/llvm/test/Transforms/Coroutines/coro-async.ll --- a/llvm/test/Transforms/Coroutines/coro-async.ll +++ b/llvm/test/Transforms/Coroutines/coro-async.ll @@ -1,5 +1,5 @@ -; RUN: opt < %s -enable-coroutines -passes='default' -S | FileCheck --check-prefixes=CHECK %s -; RUN: opt < %s -enable-coroutines -O0 -S | FileCheck --check-prefixes=CHECK-O0 %s +; RUN: opt < %s -passes='default' -S | FileCheck --check-prefixes=CHECK %s +; RUN: opt < %s -O0 -S | FileCheck --check-prefixes=CHECK-O0 %s target datalayout = "p:64:64:64" %async.task = type { i64 } diff --git a/llvm/test/Transforms/Coroutines/coro-cleanup-lowering.ll b/llvm/test/Transforms/Coroutines/coro-cleanup-lowering.ll --- a/llvm/test/Transforms/Coroutines/coro-cleanup-lowering.ll +++ b/llvm/test/Transforms/Coroutines/coro-cleanup-lowering.ll @@ -1,5 +1,4 @@ ; Make sure that all library helper coro intrinsics are lowered. -; RUN: opt < %s -coro-cleanup -S | FileCheck %s ; RUN: opt < %s -passes=coro-cleanup -S | FileCheck %s ; CHECK-LABEL: @uses_library_support_coro_intrinsics( 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,5 @@ ; Make sure that all library helper coro intrinsics are lowered. -; RUN: opt < %s -passes='default' -enable-coroutines -S | FileCheck %s +; RUN: opt < %s -passes='default' -S | FileCheck %s ; CHECK-LABEL: @uses_library_support_coro_intrinsics( ; CHECK-NOT: @llvm.coro diff --git a/llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll b/llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll --- a/llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll +++ b/llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -passes='default' -enable-coroutines -S | FileCheck %s +; RUN: opt < %s -passes='default' -S | FileCheck %s ; Define a function 'f' that resembles the Clang frontend's output for the ; following C++ coroutine: diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-alloca-opaque-ptr.ll b/llvm/test/Transforms/Coroutines/coro-retcon-alloca-opaque-ptr.ll --- a/llvm/test/Transforms/Coroutines/coro-retcon-alloca-opaque-ptr.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-alloca-opaque-ptr.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -enable-coroutines -passes='default' -opaque-pointers=1 -S | FileCheck %s +; RUN: opt < %s -passes='default' -opaque-pointers=1 -S | FileCheck %s target datalayout = "p:64:64:64" diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll b/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll --- a/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -enable-coroutines -passes='default' -S | FileCheck %s +; RUN: opt < %s -passes='default' -S | FileCheck %s target datalayout = "p:64:64:64" diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll b/llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll --- a/llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -enable-coroutines -passes='default' -S | FileCheck %s +; RUN: opt < %s -passes='default' -S | FileCheck %s target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.12.0" diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll b/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll --- a/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -enable-coroutines -passes='default' -S | FileCheck %s +; RUN: opt < %s -passes='default' -S | FileCheck %s target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.12.0" diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-opaque-ptr.ll b/llvm/test/Transforms/Coroutines/coro-retcon-opaque-ptr.ll --- a/llvm/test/Transforms/Coroutines/coro-retcon-opaque-ptr.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-opaque-ptr.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -enable-coroutines -passes='default' -opaque-pointers -S | FileCheck %s +; RUN: opt < %s -passes='default' -opaque-pointers -S | FileCheck %s ; Same test as coro-retcon.ll, but with opaque pointers enabled. diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll b/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll --- a/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -enable-coroutines -passes='default' -aa-pipeline=default -S | FileCheck %s +; RUN: opt < %s -passes='default' -aa-pipeline=default -S | FileCheck %s define i8* @f(i8* %buffer, i32 %n) { ; CHECK-LABEL: @f( diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-value.ll b/llvm/test/Transforms/Coroutines/coro-retcon-value.ll --- a/llvm/test/Transforms/Coroutines/coro-retcon-value.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-value.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; First example from Doc/Coroutines.rst (two block loop) converted to retcon -; RUN: opt < %s -enable-coroutines -passes='default' -S | FileCheck %s +; RUN: opt < %s -passes='default' -S | FileCheck %s define {i8*, i32} @f(i8* %buffer, i32 %n) { ; CHECK-LABEL: @f( diff --git a/llvm/test/Transforms/Coroutines/coro-retcon.ll b/llvm/test/Transforms/Coroutines/coro-retcon.ll --- a/llvm/test/Transforms/Coroutines/coro-retcon.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; First example from Doc/Coroutines.rst (two block loop) converted to retcon -; RUN: opt < %s -enable-coroutines -passes='default' -S | FileCheck %s +; RUN: opt < %s -passes='default' -S | FileCheck %s define i8* @f(i8* %buffer, i32 %n) { ; CHECK-LABEL: @f( diff --git a/llvm/test/Transforms/Coroutines/coro-split-01.ll b/llvm/test/Transforms/Coroutines/coro-split-01.ll --- a/llvm/test/Transforms/Coroutines/coro-split-01.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-01.ll @@ -1,5 +1,5 @@ ; Tests that a coroutine is split, inlined into the caller and devirtualized. -; RUN: opt < %s -S -enable-coroutines -passes='default' | FileCheck %s +; RUN: opt < %s -S -passes='default' | FileCheck %s define i8* @f() "coroutine.presplit"="0" { entry: diff --git a/llvm/test/Transforms/Coroutines/coro-swifterror.ll b/llvm/test/Transforms/Coroutines/coro-swifterror.ll --- a/llvm/test/Transforms/Coroutines/coro-swifterror.ll +++ b/llvm/test/Transforms/Coroutines/coro-swifterror.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -enable-coroutines -passes='default' -S | FileCheck %s +; RUN: opt < %s -passes='default' -S | FileCheck %s target datalayout = "E-p:32:32" define i8* @f(i8* %buffer, i32 %n, i8** swifterror %errorslot) { diff --git a/llvm/test/Transforms/Coroutines/ex0.ll b/llvm/test/Transforms/Coroutines/ex0.ll --- a/llvm/test/Transforms/Coroutines/ex0.ll +++ b/llvm/test/Transforms/Coroutines/ex0.ll @@ -1,5 +1,5 @@ ; First example from Doc/Coroutines.rst (two block loop) -; RUN: opt < %s -enable-coroutines -aa-pipeline=basic-aa -passes='default' -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s +; RUN: opt < %s -aa-pipeline=basic-aa -passes='default' -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s define i8* @f(i32 %n) "coroutine.presplit"="0" { entry: diff --git a/llvm/test/Transforms/Coroutines/ex1.ll b/llvm/test/Transforms/Coroutines/ex1.ll --- a/llvm/test/Transforms/Coroutines/ex1.ll +++ b/llvm/test/Transforms/Coroutines/ex1.ll @@ -1,5 +1,5 @@ ; First example from Doc/Coroutines.rst (one block loop) -; RUN: opt < %s -aa-pipeline=basic-aa -passes='default' -enable-coroutines -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s +; RUN: opt < %s -aa-pipeline=basic-aa -passes='default' -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s define i8* @f(i32 %n) "coroutine.presplit"="0" { entry: diff --git a/llvm/test/Transforms/Coroutines/ex2.ll b/llvm/test/Transforms/Coroutines/ex2.ll --- a/llvm/test/Transforms/Coroutines/ex2.ll +++ b/llvm/test/Transforms/Coroutines/ex2.ll @@ -1,5 +1,5 @@ ; Second example from Doc/Coroutines.rst (custom alloc and free functions) -; RUN: opt < %s -passes='default' -enable-coroutines -S | FileCheck %s +; RUN: opt < %s -passes='default' -S | FileCheck %s define i8* @f(i32 %n) "coroutine.presplit"="0" { entry: diff --git a/llvm/test/Transforms/Coroutines/ex3.ll b/llvm/test/Transforms/Coroutines/ex3.ll --- a/llvm/test/Transforms/Coroutines/ex3.ll +++ b/llvm/test/Transforms/Coroutines/ex3.ll @@ -1,5 +1,5 @@ ; Third example from Doc/Coroutines.rst (two suspend points) -; RUN: opt < %s -aa-pipeline=basic-aa -passes='default' -enable-coroutines -S | FileCheck %s +; RUN: opt < %s -aa-pipeline=basic-aa -passes='default' -S | FileCheck %s define i8* @f(i32 %n) "coroutine.presplit"="0" { entry: diff --git a/llvm/test/Transforms/Coroutines/ex4.ll b/llvm/test/Transforms/Coroutines/ex4.ll --- a/llvm/test/Transforms/Coroutines/ex4.ll +++ b/llvm/test/Transforms/Coroutines/ex4.ll @@ -1,5 +1,5 @@ ; Fourth example from Doc/Coroutines.rst (coroutine promise) -; RUN: opt < %s -passes='default' -enable-coroutines -S | FileCheck %s +; RUN: opt < %s -passes='default' -S | FileCheck %s define i8* @f(i32 %n) "coroutine.presplit"="0" { entry: diff --git a/llvm/test/Transforms/Coroutines/ex5.ll b/llvm/test/Transforms/Coroutines/ex5.ll --- a/llvm/test/Transforms/Coroutines/ex5.ll +++ b/llvm/test/Transforms/Coroutines/ex5.ll @@ -1,5 +1,5 @@ ; Fifth example from Doc/Coroutines.rst (final suspend) -; RUN: opt < %s -aa-pipeline=basic-aa -passes='default' -enable-coroutines -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s +; RUN: opt < %s -aa-pipeline=basic-aa -passes='default' -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s define i8* @f(i32 %n) "coroutine.presplit"="0" { entry: diff --git a/llvm/test/Transforms/Coroutines/phi-coro-end.ll b/llvm/test/Transforms/Coroutines/phi-coro-end.ll --- a/llvm/test/Transforms/Coroutines/phi-coro-end.ll +++ b/llvm/test/Transforms/Coroutines/phi-coro-end.ll @@ -1,5 +1,5 @@ ; Verify that we correctly handle suspend when the coro.end block contains phi -; RUN: opt < %s -aa-pipeline=basic-aa -passes='default' -enable-coroutines -S | FileCheck %s +; RUN: opt < %s -aa-pipeline=basic-aa -passes='default' -S | FileCheck %s define i8* @f(i32 %n) "coroutine.presplit"="0" { entry: 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 @@ -1,8 +1,8 @@ ; REQUIRES: asserts ; The following tests use the new pass manager, and verify that the coroutine ; passes re-run the CGSCC pipeline. -; RUN: opt < %s -S -passes='default' -enable-coroutines -debug-only=coro-split 2>&1 | FileCheck --check-prefix=CHECK-NEWPM %s -; RUN: opt < %s -S -passes='default' -enable-coroutines -debug-only=coro-split 2>&1 | FileCheck --check-prefix=CHECK-NEWPM %s +; RUN: opt < %s -S -passes='default' -debug-only=coro-split 2>&1 | FileCheck --check-prefix=CHECK-NEWPM %s +; RUN: opt < %s -S -passes='default' -debug-only=coro-split 2>&1 | FileCheck --check-prefix=CHECK-NEWPM %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 @@ -1,13 +1,13 @@ ; Test that all coroutine passes run in the correct order at all optimization -; levels and -enable-coroutines adds coroutine passes to the pipeline. +; levels adds coroutine passes to the pipeline. ; -; RUN: opt < %s -disable-output -passes='default' -enable-coroutines \ +; RUN: opt < %s -disable-output -passes='default' \ ; RUN: -debug-pass-manager 2>&1 | FileCheck %s --check-prefixes=CHECK-ALL -; RUN: opt < %s -disable-output -passes='default' -enable-coroutines \ +; 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 -passes='default' -enable-coroutines \ +; 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 -passes='default' -enable-coroutines \ +; 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 \ diff --git a/llvm/tools/llvm-c-test/include-all.c b/llvm/tools/llvm-c-test/include-all.c --- a/llvm/tools/llvm-c-test/include-all.c +++ b/llvm/tools/llvm-c-test/include-all.c @@ -36,7 +36,6 @@ #include "llvm-c/Target.h" #include "llvm-c/TargetMachine.h" #include "llvm-c/Transforms/AggressiveInstCombine.h" -#include "llvm-c/Transforms/Coroutines.h" #include "llvm-c/Transforms/InstCombine.h" #include "llvm-c/Transforms/IPO.h" #include "llvm-c/Transforms/PassManagerBuilder.h" diff --git a/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp b/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp --- a/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp +++ b/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp @@ -191,7 +191,6 @@ PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); - initializeCoroutines(Registry); initializeScalarOpts(Registry); initializeObjCARCOpts(Registry); initializeVectorization(Registry); diff --git a/llvm/tools/opt/opt.cpp b/llvm/tools/opt/opt.cpp --- a/llvm/tools/opt/opt.cpp +++ b/llvm/tools/opt/opt.cpp @@ -52,7 +52,6 @@ #include "llvm/Support/ToolOutputFile.h" #include "llvm/Support/YAMLTraits.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Transforms/Coroutines.h" #include "llvm/Transforms/IPO/AlwaysInliner.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/IPO/WholeProgramDevirt.h" @@ -249,11 +248,6 @@ cl::desc("Discard names from Value (other than GlobalValue)."), cl::init(false), cl::Hidden); -static cl::opt Coroutines( - "enable-coroutines", - cl::desc("Enable coroutine passes."), - cl::init(false), cl::Hidden); - static cl::opt TimeTrace( "time-trace", cl::desc("Record time trace")); @@ -371,9 +365,6 @@ if (TM) TM->adjustPassManager(Builder); - if (Coroutines) - addCoroutinePassesToExtensionPoints(Builder); - switch (PGOKindFlag) { case InstrGen: Builder.EnablePGOInstrGen = true; @@ -539,7 +530,6 @@ // Initialize passes PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); - initializeCoroutines(Registry); initializeScalarOpts(Registry); initializeObjCARCOpts(Registry); initializeVectorization(Registry); diff --git a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel --- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel @@ -1381,10 +1381,7 @@ "lib/Transforms/Coroutines/*.cpp", "lib/Transforms/Coroutines/*.h", ]), - hdrs = [ - "include/llvm-c/Transforms/Coroutines.h", - "include/llvm/Transforms/Coroutines.h", - ] + glob(["include/llvm/Transforms/Coroutines/*.h"]), + hdrs = glob(["include/llvm/Transforms/Coroutines/*.h"]), copts = llvm_copts, deps = [ ":Analysis",