summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGOpenCLRuntime.cpp
diff options
context:
space:
mode:
authorAndrew Savonichev <andrew.savonichev@intel.com>2019-02-21 11:02:10 +0000
committerAndrew Savonichev <andrew.savonichev@intel.com>2019-02-21 11:02:10 +0000
commit43fceb27271f6cb83cbeda627f6228510cf4f2b8 (patch)
treebeb4895fa8d8883eb7493dc9ce35e1cebf1b81af /clang/lib/CodeGen/CGOpenCLRuntime.cpp
parent6561a823d26f841cc539fe5cb0584c554a61b4c0 (diff)
downloadbcm5719-llvm-43fceb27271f6cb83cbeda627f6228510cf4f2b8.tar.gz
bcm5719-llvm-43fceb27271f6cb83cbeda627f6228510cf4f2b8.zip
[OpenCL] Simplify LLVM IR generated for OpenCL blocks
Summary: Emit direct call of block invoke functions when possible, i.e. in case the block is not passed as a function argument. Also doing some refactoring of `CodeGenFunction::EmitBlockCallExpr()` Reviewers: Anastasia, yaxunl, svenvh Reviewed By: Anastasia Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58388 llvm-svn: 354568
Diffstat (limited to 'clang/lib/CodeGen/CGOpenCLRuntime.cpp')
-rw-r--r--clang/lib/CodeGen/CGOpenCLRuntime.cpp30
1 files changed, 22 insertions, 8 deletions
diff --git a/clang/lib/CodeGen/CGOpenCLRuntime.cpp b/clang/lib/CodeGen/CGOpenCLRuntime.cpp
index 95732e93d5a..191a95c6299 100644
--- a/clang/lib/CodeGen/CGOpenCLRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenCLRuntime.cpp
@@ -122,6 +122,23 @@ llvm::PointerType *CGOpenCLRuntime::getGenericVoidPointerType() {
CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic));
}
+// Get the block literal from an expression derived from the block expression.
+// OpenCL v2.0 s6.12.5:
+// Block variable declarations are implicitly qualified with const. Therefore
+// all block variables must be initialized at declaration time and may not be
+// reassigned.
+static const BlockExpr *getBlockExpr(const Expr *E) {
+ const Expr *Prev = nullptr; // to make sure we do not stuck in infinite loop.
+ while(!isa<BlockExpr>(E) && E != Prev) {
+ Prev = E;
+ E = E->IgnoreCasts();
+ if (auto DR = dyn_cast<DeclRefExpr>(E)) {
+ E = cast<VarDecl>(DR->getDecl())->getInit();
+ }
+ }
+ return cast<BlockExpr>(E);
+}
+
/// Record emitted llvm invoke function and llvm block literal for the
/// corresponding block expression.
void CGOpenCLRuntime::recordBlockInfo(const BlockExpr *E,
@@ -136,20 +153,17 @@ void CGOpenCLRuntime::recordBlockInfo(const BlockExpr *E,
EnqueuedBlockMap[E].Kernel = nullptr;
}
+llvm::Function *CGOpenCLRuntime::getInvokeFunction(const Expr *E) {
+ return EnqueuedBlockMap[getBlockExpr(E)].InvokeFunc;
+}
+
CGOpenCLRuntime::EnqueuedBlockInfo
CGOpenCLRuntime::emitOpenCLEnqueuedBlock(CodeGenFunction &CGF, const Expr *E) {
CGF.EmitScalarExpr(E);
// The block literal may be assigned to a const variable. Chasing down
// to get the block literal.
- if (auto DR = dyn_cast<DeclRefExpr>(E)) {
- E = cast<VarDecl>(DR->getDecl())->getInit();
- }
- E = E->IgnoreImplicit();
- if (auto Cast = dyn_cast<CastExpr>(E)) {
- E = Cast->getSubExpr();
- }
- auto *Block = cast<BlockExpr>(E);
+ const BlockExpr *Block = getBlockExpr(E);
assert(EnqueuedBlockMap.find(Block) != EnqueuedBlockMap.end() &&
"Block expression not emitted");
OpenPOWER on IntegriCloud