diff options
author | Andrew Savonichev <andrew.savonichev@intel.com> | 2019-02-21 11:02:10 +0000 |
---|---|---|
committer | Andrew Savonichev <andrew.savonichev@intel.com> | 2019-02-21 11:02:10 +0000 |
commit | 43fceb27271f6cb83cbeda627f6228510cf4f2b8 (patch) | |
tree | beb4895fa8d8883eb7493dc9ce35e1cebf1b81af /clang/lib/CodeGen/CGOpenCLRuntime.cpp | |
parent | 6561a823d26f841cc539fe5cb0584c554a61b4c0 (diff) | |
download | bcm5719-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.cpp | 30 |
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"); |