diff options
author | Gor Nishanov <GorNishanov@gmail.com> | 2016-09-30 18:41:35 +0000 |
---|---|---|
committer | Gor Nishanov <GorNishanov@gmail.com> | 2016-09-30 18:41:35 +0000 |
commit | 768de2c604792ae9f43e664540580e39c3a9cba1 (patch) | |
tree | fdd23cacb4c9dbfc9271b2ae8c77cb05342f283b /llvm/lib/Transforms/Coroutines | |
parent | b43712a513b23d4a5307e96bb28d2ffe37862ba8 (diff) | |
download | bcm5719-llvm-768de2c604792ae9f43e664540580e39c3a9cba1.tar.gz bcm5719-llvm-768de2c604792ae9f43e664540580e39c3a9cba1.zip |
[Coroutines] Part 15a: Lower coro.subfn.addr in CoroCleanup
Summary: Not all coro.subfn.addr intrinsics can be eliminated in CoroElide through devirtualization. Those that remain need to be lowered in CoroCleanup.
Reviewers: majnemer
Subscribers: llvm-commits, mehdi_amini
Differential Revision: https://reviews.llvm.org/D24412
llvm-svn: 282897
Diffstat (limited to 'llvm/lib/Transforms/Coroutines')
-rw-r--r-- | llvm/lib/Transforms/Coroutines/CoroCleanup.cpp | 27 | ||||
-rw-r--r-- | llvm/lib/Transforms/Coroutines/Coroutines.cpp | 2 |
2 files changed, 26 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp b/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp index 6f11efa0847..a97db6fde45 100644 --- a/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp @@ -10,6 +10,7 @@ //===----------------------------------------------------------------------===// #include "CoroInternal.h" +#include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstIterator.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/Pass.h" @@ -22,7 +23,8 @@ using namespace llvm; namespace { // Created on demand if CoroCleanup pass has work to do. struct Lowerer : coro::LowererBase { - Lowerer(Module &M) : LowererBase(M) {} + IRBuilder<> Builder; + Lowerer(Module &M) : LowererBase(M), Builder(Context) {} bool lowerRemainingCoroIntrinsics(Function &F); }; } @@ -36,6 +38,23 @@ static void simplifyCFG(Function &F) { FPM.doFinalization(); } +static void lowerSubFn(IRBuilder<> &Builder, CoroSubFnInst *SubFn) { + Builder.SetInsertPoint(SubFn); + Value *FrameRaw = SubFn->getFrame(); + int Index = SubFn->getIndex(); + + auto *FrameTy = StructType::get( + SubFn->getContext(), {Builder.getInt8PtrTy(), Builder.getInt8PtrTy()}); + PointerType *FramePtrTy = FrameTy->getPointerTo(); + + Builder.SetInsertPoint(SubFn); + auto *FramePtr = Builder.CreateBitCast(FrameRaw, FramePtrTy); + auto *Gep = Builder.CreateConstInBoundsGEP2_32(FrameTy, FramePtr, 0, Index); + auto *Load = Builder.CreateLoad(Gep); + + SubFn->replaceAllUsesWith(Load); +} + bool Lowerer::lowerRemainingCoroIntrinsics(Function &F) { bool Changed = false; @@ -57,6 +76,9 @@ bool Lowerer::lowerRemainingCoroIntrinsics(Function &F) { case Intrinsic::coro_id: II->replaceAllUsesWith(ConstantTokenNone::get(Context)); break; + case Intrinsic::coro_subfn_addr: + lowerSubFn(Builder, cast<CoroSubFnInst>(II)); + break; } II->eraseFromParent(); Changed = true; @@ -87,7 +109,8 @@ struct CoroCleanup : FunctionPass { // in the module. bool doInitialization(Module &M) override { if (coro::declaresIntrinsics(M, {"llvm.coro.alloc", "llvm.coro.begin", - "llvm.coro.free", "llvm.coro.id"})) + "llvm.coro.subfn.addr", "llvm.coro.free", + "llvm.coro.id"})) L = llvm::make_unique<Lowerer>(M); return false; } diff --git a/llvm/lib/Transforms/Coroutines/Coroutines.cpp b/llvm/lib/Transforms/Coroutines/Coroutines.cpp index 7e643006ffd..877ec34b4d3 100644 --- a/llvm/lib/Transforms/Coroutines/Coroutines.cpp +++ b/llvm/lib/Transforms/Coroutines/Coroutines.cpp @@ -107,7 +107,7 @@ static bool isCoroutineIntrinsicName(StringRef Name) { "llvm.coro.done", "llvm.coro.end", "llvm.coro.frame", "llvm.coro.free", "llvm.coro.id", "llvm.coro.param", "llvm.coro.promise", "llvm.coro.resume", "llvm.coro.save", - "llvm.coro.size", "llvm.coro.suspend", + "llvm.coro.size", "llvm.coro.subfn.addr", "llvm.coro.suspend", }; return Intrinsic::lookupLLVMIntrinsicByName(CoroIntrinsics, Name) != -1; } |