diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
| commit | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch) | |
| tree | 4adf86a776049cbf7f69a1929c4babcbbef925eb /llvm/lib/Transforms/Coroutines | |
| parent | 7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff) | |
Notes
Diffstat (limited to 'llvm/lib/Transforms/Coroutines')
| -rw-r--r-- | llvm/lib/Transforms/Coroutines/CoroCleanup.cpp | 12 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Coroutines/CoroEarly.cpp | 16 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Coroutines/CoroElide.cpp | 17 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Coroutines/CoroInternal.h | 11 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Coroutines/CoroSplit.cpp | 55 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Coroutines/Coroutines.cpp | 39 |
6 files changed, 84 insertions, 66 deletions
diff --git a/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp b/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp index c3e05577f044..c2dbd6f41642 100644 --- a/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp @@ -99,11 +99,11 @@ bool Lowerer::lowerRemainingCoroIntrinsics(Function &F) { namespace { -struct CoroCleanup : FunctionPass { +struct CoroCleanupLegacy : FunctionPass { static char ID; // Pass identification, replacement for typeid - CoroCleanup() : FunctionPass(ID) { - initializeCoroCleanupPass(*PassRegistry::getPassRegistry()); + CoroCleanupLegacy() : FunctionPass(ID) { + initializeCoroCleanupLegacyPass(*PassRegistry::getPassRegistry()); } std::unique_ptr<Lowerer> L; @@ -132,8 +132,8 @@ struct CoroCleanup : FunctionPass { }; } -char CoroCleanup::ID = 0; -INITIALIZE_PASS(CoroCleanup, "coro-cleanup", +char CoroCleanupLegacy::ID = 0; +INITIALIZE_PASS(CoroCleanupLegacy, "coro-cleanup", "Lower all coroutine related intrinsics", false, false) -Pass *llvm::createCoroCleanupPass() { return new CoroCleanup(); } +Pass *llvm::createCoroCleanupLegacyPass() { return new CoroCleanupLegacy(); } diff --git a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp index 55993d33ee4e..e73fb9eeb1e9 100644 --- a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp @@ -22,7 +22,7 @@ using namespace llvm; #define DEBUG_TYPE "coro-early" namespace { -// Created on demand if CoroEarly pass has work to do. +// Created on demand if the coro-early pass has work to do. class Lowerer : public coro::LowererBase { IRBuilder<> Builder; PointerType *const AnyResumeFnPtrTy; @@ -225,10 +225,10 @@ bool Lowerer::lowerEarlyIntrinsics(Function &F) { namespace { -struct CoroEarly : public FunctionPass { +struct CoroEarlyLegacy : public FunctionPass { static char ID; // Pass identification, replacement for typeid. - CoroEarly() : FunctionPass(ID) { - initializeCoroEarlyPass(*PassRegistry::getPassRegistry()); + CoroEarlyLegacy() : FunctionPass(ID) { + initializeCoroEarlyLegacyPass(*PassRegistry::getPassRegistry()); } std::unique_ptr<Lowerer> L; @@ -267,8 +267,8 @@ struct CoroEarly : public FunctionPass { }; } -char CoroEarly::ID = 0; -INITIALIZE_PASS(CoroEarly, "coro-early", "Lower early coroutine intrinsics", - false, false) +char CoroEarlyLegacy::ID = 0; +INITIALIZE_PASS(CoroEarlyLegacy, "coro-early", + "Lower early coroutine intrinsics", false, false) -Pass *llvm::createCoroEarlyPass() { return new CoroEarly(); } +Pass *llvm::createCoroEarlyLegacyPass() { return new CoroEarlyLegacy(); } diff --git a/llvm/lib/Transforms/Coroutines/CoroElide.cpp b/llvm/lib/Transforms/Coroutines/CoroElide.cpp index aca77119023b..23d22e23861a 100644 --- a/llvm/lib/Transforms/Coroutines/CoroElide.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroElide.cpp @@ -15,6 +15,7 @@ #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/InstIterator.h" +#include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/ErrorHandling.h" @@ -23,7 +24,7 @@ using namespace llvm; #define DEBUG_TYPE "coro-elide" namespace { -// Created on demand if CoroElide pass has work to do. +// Created on demand if the coro-elide pass has work to do. struct Lowerer : coro::LowererBase { SmallVector<CoroIdInst *, 4> CoroIds; SmallVector<CoroBeginInst *, 1> CoroBegins; @@ -276,10 +277,10 @@ static bool replaceDevirtTrigger(Function &F) { //===----------------------------------------------------------------------===// namespace { -struct CoroElide : FunctionPass { +struct CoroElideLegacy : FunctionPass { static char ID; - CoroElide() : FunctionPass(ID) { - initializeCoroElidePass(*PassRegistry::getPassRegistry()); + CoroElideLegacy() : FunctionPass(ID) { + initializeCoroElideLegacyPass(*PassRegistry::getPassRegistry()); } std::unique_ptr<Lowerer> L; @@ -329,15 +330,15 @@ struct CoroElide : FunctionPass { }; } -char CoroElide::ID = 0; +char CoroElideLegacy::ID = 0; INITIALIZE_PASS_BEGIN( - CoroElide, "coro-elide", + CoroElideLegacy, "coro-elide", "Coroutine frame allocation elision and indirect calls replacement", false, false) INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_END( - CoroElide, "coro-elide", + CoroElideLegacy, "coro-elide", "Coroutine frame allocation elision and indirect calls replacement", false, false) -Pass *llvm::createCoroElidePass() { return new CoroElide(); } +Pass *llvm::createCoroElideLegacyPass() { return new CoroElideLegacy(); } diff --git a/llvm/lib/Transforms/Coroutines/CoroInternal.h b/llvm/lib/Transforms/Coroutines/CoroInternal.h index c151474316f9..7eb35400c0d5 100644 --- a/llvm/lib/Transforms/Coroutines/CoroInternal.h +++ b/llvm/lib/Transforms/Coroutines/CoroInternal.h @@ -21,10 +21,10 @@ class CallGraph; class CallGraphSCC; class PassRegistry; -void initializeCoroEarlyPass(PassRegistry &); -void initializeCoroSplitPass(PassRegistry &); -void initializeCoroElidePass(PassRegistry &); -void initializeCoroCleanupPass(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 @@ -43,7 +43,8 @@ void initializeCoroCleanupPass(PassRegistry &); namespace coro { -bool declaresIntrinsics(Module &M, std::initializer_list<StringRef>); +bool declaresIntrinsics(const Module &M, + const std::initializer_list<StringRef>); void replaceAllCoroAllocs(CoroBeginInst *CB, bool Replacement); void replaceAllCoroFrees(CoroBeginInst *CB, Value *Replacement); void replaceCoroFree(CoroIdInst *CoroId, bool Elide); diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp index 04723cbde417..66cb3e74e53e 100644 --- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -27,7 +27,6 @@ #include "llvm/ADT/Twine.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/CallGraphSCCPass.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/IR/Argument.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" @@ -52,6 +51,7 @@ #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" #include "llvm/IR/Verifier.h" +#include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Debug.h" @@ -60,6 +60,7 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/ValueMapper.h" #include <cassert> #include <cstddef> @@ -157,8 +158,9 @@ private: } // end anonymous namespace -static void maybeFreeRetconStorage(IRBuilder<> &Builder, coro::Shape &Shape, - Value *FramePtr, CallGraph *CG) { +static void maybeFreeRetconStorage(IRBuilder<> &Builder, + const coro::Shape &Shape, Value *FramePtr, + CallGraph *CG) { assert(Shape.ABI == coro::ABI::Retcon || Shape.ABI == coro::ABI::RetconOnce); if (Shape.RetconLowering.IsFrameInlineInStorage) @@ -168,9 +170,9 @@ static void maybeFreeRetconStorage(IRBuilder<> &Builder, coro::Shape &Shape, } /// Replace a non-unwind call to llvm.coro.end. -static void replaceFallthroughCoroEnd(CoroEndInst *End, coro::Shape &Shape, - Value *FramePtr, bool InResume, - CallGraph *CG) { +static void replaceFallthroughCoroEnd(CoroEndInst *End, + const coro::Shape &Shape, Value *FramePtr, + bool InResume, CallGraph *CG) { // Start inserting right before the coro.end. IRBuilder<> Builder(End); @@ -218,7 +220,7 @@ static void replaceFallthroughCoroEnd(CoroEndInst *End, coro::Shape &Shape, } /// Replace an unwind call to llvm.coro.end. -static void replaceUnwindCoroEnd(CoroEndInst *End, coro::Shape &Shape, +static void replaceUnwindCoroEnd(CoroEndInst *End, const coro::Shape &Shape, Value *FramePtr, bool InResume, CallGraph *CG){ IRBuilder<> Builder(End); @@ -245,7 +247,7 @@ static void replaceUnwindCoroEnd(CoroEndInst *End, coro::Shape &Shape, } } -static void replaceCoroEnd(CoroEndInst *End, coro::Shape &Shape, +static void replaceCoroEnd(CoroEndInst *End, const coro::Shape &Shape, Value *FramePtr, bool InResume, CallGraph *CG) { if (End->isUnwind()) replaceUnwindCoroEnd(End, Shape, FramePtr, InResume, CG); @@ -781,7 +783,7 @@ static Function *createClone(Function &F, const Twine &Suffix, } /// Remove calls to llvm.coro.end in the original function. -static void removeCoroEnds(coro::Shape &Shape, CallGraph *CG) { +static void removeCoroEnds(const coro::Shape &Shape, CallGraph *CG) { for (auto End : Shape.CoroEnds) { replaceCoroEnd(End, Shape, Shape.FramePtr, /*in resume*/ false, CG); } @@ -906,17 +908,29 @@ scanPHIsAndUpdateValueMap(Instruction *Prev, BasicBlock *NewBlock, // values and select the correct case successor when possible. static bool simplifyTerminatorLeadingToRet(Instruction *InitialInst) { DenseMap<Value *, Value *> ResolvedValues; + BasicBlock *UnconditionalSucc = nullptr; Instruction *I = InitialInst; while (I->isTerminator()) { if (isa<ReturnInst>(I)) { - if (I != InitialInst) + if (I != InitialInst) { + // If InitialInst is an unconditional branch, + // remove PHI values that come from basic block of InitialInst + if (UnconditionalSucc) + for (PHINode &PN : UnconditionalSucc->phis()) { + int idx = PN.getBasicBlockIndex(InitialInst->getParent()); + if (idx != -1) + PN.removeIncomingValue(idx); + } ReplaceInstWithInst(InitialInst, I->clone()); + } return true; } if (auto *BR = dyn_cast<BranchInst>(I)) { if (BR->isUnconditional()) { BasicBlock *BB = BR->getSuccessor(0); + if (I == InitialInst) + UnconditionalSucc = BB; scanPHIsAndUpdateValueMap(I, BB, ResolvedValues); I = BB->getFirstNonPHIOrDbgOrLifetime(); continue; @@ -1407,9 +1421,10 @@ static void prepareForSplit(Function &F, CallGraph &CG) { CG[&F]->addCalledFunction(IndirectCall, CG.getCallsExternalNode()); } -// Make sure that there is a devirtualization trigger function that CoroSplit -// pass uses the force restart CGSCC pipeline. If devirt trigger function is not -// found, we will create one and add it to the current SCC. +// 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)) @@ -1512,11 +1527,11 @@ static bool replaceAllPrepares(Function *PrepareFn, CallGraph &CG) { namespace { -struct CoroSplit : public CallGraphSCCPass { +struct CoroSplitLegacy : public CallGraphSCCPass { static char ID; // Pass identification, replacement for typeid - CoroSplit() : CallGraphSCCPass(ID) { - initializeCoroSplitPass(*PassRegistry::getPassRegistry()); + CoroSplitLegacy() : CallGraphSCCPass(ID) { + initializeCoroSplitLegacyPass(*PassRegistry::getPassRegistry()); } bool Run = false; @@ -1586,16 +1601,16 @@ struct CoroSplit : public CallGraphSCCPass { } // end anonymous namespace -char CoroSplit::ID = 0; +char CoroSplitLegacy::ID = 0; INITIALIZE_PASS_BEGIN( - CoroSplit, "coro-split", + CoroSplitLegacy, "coro-split", "Split coroutine into a set of functions driving its state machine", false, false) INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) INITIALIZE_PASS_END( - CoroSplit, "coro-split", + CoroSplitLegacy, "coro-split", "Split coroutine into a set of functions driving its state machine", false, false) -Pass *llvm::createCoroSplitPass() { return new CoroSplit(); } +Pass *llvm::createCoroSplitLegacyPass() { return new CoroSplitLegacy(); } diff --git a/llvm/lib/Transforms/Coroutines/Coroutines.cpp b/llvm/lib/Transforms/Coroutines/Coroutines.cpp index f39483b27518..02d11af3303f 100644 --- a/llvm/lib/Transforms/Coroutines/Coroutines.cpp +++ b/llvm/lib/Transforms/Coroutines/Coroutines.cpp @@ -11,14 +11,13 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Coroutines.h" -#include "llvm-c/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" #include "llvm/Analysis/CallGraphSCCPass.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" @@ -31,10 +30,12 @@ #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" +#include "llvm/InitializePasses.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" +#include "llvm/Transforms/Utils/Local.h" #include <cassert> #include <cstddef> #include <utility> @@ -42,39 +43,39 @@ using namespace llvm; void llvm::initializeCoroutines(PassRegistry &Registry) { - initializeCoroEarlyPass(Registry); - initializeCoroSplitPass(Registry); - initializeCoroElidePass(Registry); - initializeCoroCleanupPass(Registry); + initializeCoroEarlyLegacyPass(Registry); + initializeCoroSplitLegacyPass(Registry); + initializeCoroElideLegacyPass(Registry); + initializeCoroCleanupLegacyPass(Registry); } static void addCoroutineOpt0Passes(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { - PM.add(createCoroSplitPass()); - PM.add(createCoroElidePass()); + PM.add(createCoroSplitLegacyPass()); + PM.add(createCoroElideLegacyPass()); PM.add(createBarrierNoopPass()); - PM.add(createCoroCleanupPass()); + PM.add(createCoroCleanupLegacyPass()); } static void addCoroutineEarlyPasses(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { - PM.add(createCoroEarlyPass()); + PM.add(createCoroEarlyLegacyPass()); } static void addCoroutineScalarOptimizerPasses(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { - PM.add(createCoroElidePass()); + PM.add(createCoroElideLegacyPass()); } static void addCoroutineSCCPasses(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { - PM.add(createCoroSplitPass()); + PM.add(createCoroSplitLegacyPass()); } static void addCoroutineOptimizerLastPasses(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { - PM.add(createCoroCleanupPass()); + PM.add(createCoroCleanupLegacyPass()); } void llvm::addCoroutinePassesToExtensionPoints(PassManagerBuilder &Builder) { @@ -150,8 +151,8 @@ static bool isCoroutineIntrinsicName(StringRef Name) { // Verifies if a module has named values listed. Also, in debug mode verifies // that names are intrinsic names. -bool coro::declaresIntrinsics(Module &M, - std::initializer_list<StringRef> List) { +bool coro::declaresIntrinsics(const Module &M, + const std::initializer_list<StringRef> List) { for (StringRef Name : List) { assert(isCoroutineIntrinsicName(Name) && "not a coroutine intrinsic"); if (M.getNamedValue(Name)) @@ -634,17 +635,17 @@ void AnyCoroIdRetconInst::checkWellFormed() const { } void LLVMAddCoroEarlyPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createCoroEarlyPass()); + unwrap(PM)->add(createCoroEarlyLegacyPass()); } void LLVMAddCoroSplitPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createCoroSplitPass()); + unwrap(PM)->add(createCoroSplitLegacyPass()); } void LLVMAddCoroElidePass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createCoroElidePass()); + unwrap(PM)->add(createCoroElideLegacyPass()); } void LLVMAddCoroCleanupPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createCoroCleanupPass()); + unwrap(PM)->add(createCoroCleanupLegacyPass()); } |
