Author: Chuanqi Xu Date: 2022-04-21T10:59:11+08:00 New Revision: 483efc9ad04dccd9f2163c84c2b6198ebb7049a6
URL: https://github.com/llvm/llvm-project/commit/483efc9ad04dccd9f2163c84c2b6198ebb7049a6 DIFF: https://github.com/llvm/llvm-project/commit/483efc9ad04dccd9f2163c84c2b6198ebb7049a6.diff LOG: [Pipelines] Remove Legacy Passes in Coroutines The legacy passes are deprecated now and would be removed in near future. This patch tries to remove legacy passes in coroutines. Reviewed By: aeubanks Differential Revision: https://reviews.llvm.org/D123918 Added: Modified: clang/lib/CodeGen/BackendUtil.cpp llvm/bindings/go/llvm/transforms_pmbuilder.go llvm/include/llvm/InitializePasses.h llvm/lib/Transforms/Coroutines/CoroCleanup.cpp llvm/lib/Transforms/Coroutines/CoroEarly.cpp llvm/lib/Transforms/Coroutines/CoroElide.cpp llvm/lib/Transforms/Coroutines/CoroInternal.h llvm/lib/Transforms/Coroutines/CoroSplit.cpp llvm/lib/Transforms/Coroutines/Coroutines.cpp llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-infinite-loop-bug.ll llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-start-bug.ll llvm/test/Transforms/Coroutines/coro-async-phi.ll llvm/test/Transforms/Coroutines/coro-async-remat.ll llvm/test/Transforms/Coroutines/coro-async-unreachable.ll llvm/test/Transforms/Coroutines/coro-async.ll llvm/test/Transforms/Coroutines/coro-cleanup-lowering.ll llvm/test/Transforms/Coroutines/coro-cleanup.ll llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll llvm/test/Transforms/Coroutines/coro-retcon-alloca-opaque-ptr.ll llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll llvm/test/Transforms/Coroutines/coro-retcon-opaque-ptr.ll llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll llvm/test/Transforms/Coroutines/coro-retcon-value.ll llvm/test/Transforms/Coroutines/coro-retcon.ll llvm/test/Transforms/Coroutines/coro-split-01.ll llvm/test/Transforms/Coroutines/coro-swifterror.ll llvm/test/Transforms/Coroutines/ex0.ll llvm/test/Transforms/Coroutines/ex1.ll llvm/test/Transforms/Coroutines/ex2.ll llvm/test/Transforms/Coroutines/ex3.ll llvm/test/Transforms/Coroutines/ex4.ll llvm/test/Transforms/Coroutines/ex5.ll llvm/test/Transforms/Coroutines/phi-coro-end.ll llvm/test/Transforms/Coroutines/restart-trigger.ll llvm/test/Transforms/Coroutines/smoketest.ll llvm/tools/llvm-c-test/include-all.c llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp llvm/tools/opt/opt.cpp utils/bazel/llvm-project-overlay/llvm/BUILD.bazel Removed: llvm/bindings/go/llvm/transforms_coroutines.go llvm/include/llvm-c/Transforms/Coroutines.h llvm/include/llvm/Transforms/Coroutines.h ################################################################################ diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index e1cdfaeccc48b..ed7bd8f838ee0 100644 --- 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 index c18c3fe936c1e..0000000000000 --- 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 index 383f7bb3ae7ba..2c902a140dc43 100644 --- a/llvm/bindings/go/llvm/transforms_pmbuilder.go +++ b/llvm/bindings/go/llvm/transforms_pmbuilder.go @@ -14,7 +14,6 @@ package llvm /* #include "llvm-c/Transforms/PassManagerBuilder.h" -#include "llvm-c/Transforms/Coroutines.h" */ import "C" @@ -62,7 +61,3 @@ func (pmb PassManagerBuilder) SetDisableSimplifyLibCalls(val bool) { 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 index 03b6822033c92..0000000000000 --- 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 index f5ae1b4f15401..e5d6b8304c4ab 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -48,9 +48,6 @@ void initializeInstrumentation(PassRegistry&); /// 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 index f68ef705fdef3..0000000000000 --- 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 index 67f8828e4c75a..0883022213c59 100644 --- a/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp @@ -141,41 +141,3 @@ PreservedAnalyses CoroCleanupPass::run(Function &F, return PreservedAnalyses::none(); } - -namespace { - -struct CoroCleanupLegacy : FunctionPass { - static char ID; // Pass identification, replacement for typeid - - CoroCleanupLegacy() : FunctionPass(ID) { - initializeCoroCleanupLegacyPass(*PassRegistry::getPassRegistry()); - } - - std::unique_ptr<Lowerer> 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<Lowerer>(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 index 9fb7c63a62b71..a3f3ccc633f74 100644 --- a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp @@ -256,43 +256,3 @@ PreservedAnalyses CoroEarlyPass::run(Module &M, ModuleAnalysisManager &) { PA.preserveSet<CFGAnalyses>(); return PA; } - -namespace { - -struct CoroEarlyLegacy : public FunctionPass { - static char ID; // Pass identification, replacement for typeid. - CoroEarlyLegacy() : FunctionPass(ID) { - initializeCoroEarlyLegacyPass(*PassRegistry::getPassRegistry()); - } - - std::unique_ptr<Lowerer> 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<Lowerer>(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 index 1e37f8c8e795e..c70e25fd56f46 100644 --- a/llvm/lib/Transforms/Coroutines/CoroElide.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroElide.cpp @@ -370,26 +370,6 @@ bool Lowerer::processCoroId(CoroIdInst *CoroId, AAResults &AA, 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<CoroSubFnInst *, 1> DevirtAddr; - for (auto &I : instructions(F)) - if (auto *SubFn = dyn_cast<CoroSubFnInst>(&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 @@ PreservedAnalyses CoroElidePass::run(Function &F, FunctionAnalysisManager &AM) { return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all(); } - -namespace { -struct CoroElideLegacy : FunctionPass { - static char ID; - CoroElideLegacy() : FunctionPass(ID) { - initializeCoroElideLegacyPass(*PassRegistry::getPassRegistry()); - } - - std::unique_ptr<Lowerer> L; - - bool doInitialization(Module &M) override { - if (declaresCoroElideIntrinsics(M)) - L = std::make_unique<Lowerer>(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<AAResultsWrapperPass>().getAAResults(); - DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree(); - - for (auto *CII : L->CoroIds) - Changed |= L->processCoroId(CII, AA, DT); - - return Changed; - } - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired<AAResultsWrapperPass>(); - AU.addRequired<DominatorTreeWrapperPass>(); - } - 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 index 36d2094ae2c81..32e68cd498cbf 100644 --- 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 CallGraph; 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 declaresAnyIntrinsic(const Module &M); bool declaresIntrinsics(const Module &M, const std::initializer_list<StringRef>); void replaceCoroFree(CoroIdInst *CoroId, bool Elide); -void updateCallGraph(Function &Caller, ArrayRef<Function *> 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 index 9ac2569490632..3e62821ba0168 100644 --- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -1079,13 +1079,6 @@ static Function *createClone(Function &F, const Twine &Suffix, 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 @@ static coro::Shape splitCoroutine(Function &F, return Shape; } -static void -updateCallGraphAfterCoroutineSplit(Function &F, const coro::Shape &Shape, - const SmallVectorImpl<Function *> &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<Function *> &Clones, LazyCallGraph::SCC &C, @@ -2013,70 +1992,6 @@ static void updateCallGraphAfterCoroutineSplit( 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<CallGraphNode *, 8> 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 @@ static void replacePrepare(CallInst *Prepare, LazyCallGraph &CG, 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<Function>(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<BitCastInst>(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<CallBase>(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<BitCastInst>(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 @@ static bool replaceAllPrepares(Function *PrepareFn, LazyCallGraph &CG, 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<CallInst>(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<Function *> &Fns, StringRef Name) { @@ -2271,122 +2109,3 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C, 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<Function *, 2> 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<Function *, 4> 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<CallGraphWrapperPass>().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<Function *, 4> 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 index dcb8062363dd0..2a24e3cc1aeb0 100644 --- 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 @@ void coro::replaceCoroFree(CoroIdInst *CoroId, bool Elide) { } } -// 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<CallBase>(&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<Function *> NewFuncs, - CallGraph &CG, CallGraphSCC &SCC) { - // Rebuild CGN from scratch for the ParentFunc - auto *ParentNode = CG[&ParentFunc]; - ParentNode->removeAllCalledFunctions(); - buildCGN(CG, ParentNode); - - SmallVector<CallGraphNode *, 8> 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 @@ void CoroAsyncEndInst::checkWellFormed() const { "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 index 905fcb569b545..467af68d278c7 100644 --- 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<O0>' -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 index bcfaaa6ab6d48..8cc8aa68e3777 100644 --- 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<O0>' -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 index 1bafa3499d456..c521601005aff 100644 --- 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<O0>' -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 index 39441f0ec7b79..60c045464093a 100644 --- 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 index 4670eea92b57b..d70820e43215c 100644 --- 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<O2>' -S | FileCheck --check-prefixes=CHECK %s +; RUN: opt < %s -passes='default<O2>' -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 index dac07bab0f6ed..7290741bee799 100644 --- 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<O2>' -S | FileCheck --check-prefixes=CHECK %s -; RUN: opt < %s -enable-coroutines -O0 -S | FileCheck --check-prefixes=CHECK-O0 %s +; RUN: opt < %s -passes='default<O2>' -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 index baf76a2a81971..e2e03efc3368c 100644 --- 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 index b6ff99822e674..fb35b02982a14 100644 --- 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<O0>' -enable-coroutines -S | FileCheck %s +; RUN: opt < %s -passes='default<O0>' -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 index cc9da24052e34..8bf9a1b1b6118 100644 --- 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<O0>' -enable-coroutines -S | FileCheck %s +; RUN: opt < %s -passes='default<O0>' -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 index 53a04264c788a..427d95eceeac4 100644 --- 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<O2>' -opaque-pointers=1 -S | FileCheck %s +; RUN: opt < %s -passes='default<O2>' -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 index be8df510ecfa2..e3f2800c37ad5 100644 --- 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<O2>' -S | FileCheck %s +; RUN: opt < %s -passes='default<O2>' -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 index c50463955595e..1486123902a5a 100644 --- 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<O0>' -S | FileCheck %s +; RUN: opt < %s -passes='default<O0>' -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 index 7a164a5f82af5..b780d7ed5a44b 100644 --- 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<O2>' -S | FileCheck %s +; RUN: opt < %s -passes='default<O2>' -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 index bdbfd1f17ef03..c7684d9107bb7 100644 --- 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<O2>' -opaque-pointers -S | FileCheck %s +; RUN: opt < %s -passes='default<O2>' -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 index 1981f75ed5460..3eda7b64a33ba 100644 --- 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<O2>' -aa-pipeline=default -S | FileCheck %s +; RUN: opt < %s -passes='default<O2>' -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 index 36cc659ff44da..c8a95ed82bdb7 100644 --- 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<O2>' -S | FileCheck %s +; RUN: opt < %s -passes='default<O2>' -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 index 7445ba8c1117d..6968de442f12e 100644 --- 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<O2>' -S | FileCheck %s +; RUN: opt < %s -passes='default<O2>' -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 index d95759bade322..da7b9673a1662 100644 --- 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<O2>' | FileCheck %s +; RUN: opt < %s -S -passes='default<O2>' | 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 index f19b003564912..9936014b5db03 100644 --- 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<O2>' -S | FileCheck %s +; RUN: opt < %s -passes='default<O2>' -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 index 898c636e03e37..fa7323ea8b022 100644 --- 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<O2>' -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s +; RUN: opt < %s -aa-pipeline=basic-aa -passes='default<O2>' -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 index 4269f07ea8bfa..df583dab6bf09 100644 --- 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<O2>' -enable-coroutines -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s +; RUN: opt < %s -aa-pipeline=basic-aa -passes='default<O2>' -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 index 1eea51be8ae6e..b469bc76a1821 100644 --- 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<O2>' -enable-coroutines -S | FileCheck %s +; RUN: opt < %s -passes='default<O2>' -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 index 5fda7594878b3..f0d5e58ee42cf 100644 --- 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<O2>' -enable-coroutines -S | FileCheck %s +; RUN: opt < %s -aa-pipeline=basic-aa -passes='default<O2>' -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 index e2970a3aab4f4..12ddf50c99e68 100644 --- 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<O2>' -enable-coroutines -S | FileCheck %s +; RUN: opt < %s -passes='default<O2>' -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 index d3d09a91333c9..dff50846846df 100644 --- 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<O2>' -enable-coroutines -preserve-alignment-assumptions-during-inlining=false -S | FileCheck %s +; RUN: opt < %s -aa-pipeline=basic-aa -passes='default<O2>' -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 index 7fe13a0d631d3..bc9cdf0b719b3 100644 --- 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<O2>' -enable-coroutines -S | FileCheck %s +; RUN: opt < %s -aa-pipeline=basic-aa -passes='default<O2>' -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 index 3538f5f337865..780bc55b751b5 100644 --- 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<O0>' -enable-coroutines -debug-only=coro-split 2>&1 | FileCheck --check-prefix=CHECK-NEWPM %s -; RUN: opt < %s -S -passes='default<O1>' -enable-coroutines -debug-only=coro-split 2>&1 | FileCheck --check-prefix=CHECK-NEWPM %s +; RUN: opt < %s -S -passes='default<O0>' -debug-only=coro-split 2>&1 | FileCheck --check-prefix=CHECK-NEWPM %s +; RUN: opt < %s -S -passes='default<O1>' -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 index f55c8385e300f..240ffd290c844 100644 --- 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<O0>' -enable-coroutines \ +; RUN: opt < %s -disable-output -passes='default<O0>' \ ; RUN: -debug-pass-manager 2>&1 | FileCheck %s --check-prefixes=CHECK-ALL -; RUN: opt < %s -disable-output -passes='default<O1>' -enable-coroutines \ +; RUN: opt < %s -disable-output -passes='default<O1>' \ ; RUN: -debug-pass-manager 2>&1 | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-OPT -; RUN: opt < %s -disable-output -passes='default<O2>' -enable-coroutines \ +; RUN: opt < %s -disable-output -passes='default<O2>' \ ; RUN: -debug-pass-manager 2>&1 | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-OPT -; RUN: opt < %s -disable-output -passes='default<O3>' -enable-coroutines \ +; RUN: opt < %s -disable-output -passes='default<O3>' \ ; 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 index 27b11fb7e0f65..144393ad3c509 100644 --- 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 index 265c8ac47fb6d..74b898bdbdfb8 100644 --- a/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp +++ b/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp @@ -191,7 +191,6 @@ extern "C" LLVM_ATTRIBUTE_USED int LLVMFuzzerInitialize( 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 index 3136ddb878fea..2b3b392171846 100644 --- 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 @@ static cl::opt<bool> DiscardValueNames( cl::desc("Discard names from Value (other than GlobalValue)."), cl::init(false), cl::Hidden); -static cl::opt<bool> Coroutines( - "enable-coroutines", - cl::desc("Enable coroutine passes."), - cl::init(false), cl::Hidden); - static cl::opt<bool> TimeTrace( "time-trace", cl::desc("Record time trace")); @@ -371,9 +365,6 @@ static void AddOptimizationPasses(legacy::PassManagerBase &MPM, if (TM) TM->adjustPassManager(Builder); - if (Coroutines) - addCoroutinePassesToExtensionPoints(Builder); - switch (PGOKindFlag) { case InstrGen: Builder.EnablePGOInstrGen = true; @@ -539,7 +530,6 @@ int main(int argc, char **argv) { // 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 index 083e24acff373..f10c76990dac0 100644 --- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel @@ -1381,10 +1381,7 @@ cc_library( "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", _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits