summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Coroutines
diff options
context:
space:
mode:
authorGor Nishanov <GorNishanov@gmail.com>2016-09-30 18:41:35 +0000
committerGor Nishanov <GorNishanov@gmail.com>2016-09-30 18:41:35 +0000
commit768de2c604792ae9f43e664540580e39c3a9cba1 (patch)
treefdd23cacb4c9dbfc9271b2ae8c77cb05342f283b /llvm/lib/Transforms/Coroutines
parentb43712a513b23d4a5307e96bb28d2ffe37862ba8 (diff)
downloadbcm5719-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.cpp27
-rw-r--r--llvm/lib/Transforms/Coroutines/Coroutines.cpp2
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;
}
OpenPOWER on IntegriCloud