[OpenCL] Blocks are allowed to capture arrays

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

[OpenCL] Blocks are allowed to capture arrays

Simon Dardis via cfe-dev



I'm working on the following patch: https://reviews.llvm.org/D26794

In the beginning of the work it was a bug in spec: https://cvs.khronos.org/bugzilla/show_bug.cgi?id=15659 and it was fixed in rev. 39 (example 5, chapter 6.12.5): https://cvs.khronos.org/svn/repos/OpenCL/trunk/Khronos/specs/opencl20-openclc-rev39.pdf


After these changes in specification, block capture semantics follows regular C argument passing convention, i.e. arrays are captured by reference (decayed to pointers) and structs are captured by value. But in current implementation array will be captured by value in both cases.


I added new check in function EmitBlockLiteral in file CGBlocks.cpp where I check if type is array, I do some operations for keeping reference to initial array. I think that the code in this check should work correctly (I saw how it works for cpp lambdas). But I cannot check it because type of captured variable in block is [4 x i32]. For keeping reference I expect that it should be [4 x i32]* or i8*.

I tried to get the pointer on array by two different ways:

1.       I extended an if statement in file SemaExpr.cpp in function: captureInBlock. In the following statement I added OpenCL check:


if (HasBlocksAttr || CaptureType->isReferenceType() ||

   (S.getLangOpts().OpenMP && S.IsOpenMPCapturedDecl(Var)) ||

   (S.getLangOpts().OpenCL && CaptureType->isArrayType())) {

  // Block capture by reference does not change the capture or // declaration reference types.

ByRef = true;          


And also, in the same file in function ActOnBlockStmtExpr. I added check if captured value is reference capture:


BlockDecl::Capture NewCap(Cap.getVariable(), Cap.isBlockCapture() || Cap.isReferenceCapture(),

                                             Cap.isNested(), Cap.getInitExpr());


I thought that it will get me a reference to the array. But it doesn't work and fails when I try to get llvm ir with the following assert: "clang: ./llvm/include/llvm/IR/Instructions.h:832: llvm::Type* llvm::checkGEPType(llvm::Type*): Assertion `Ty && "Invalid GetElementPtrInst indices for type!"' failed."

And in the AST I have capturing variable in block by reference:


`-BlockDecl 0xa14cd00 <col:17, col:35> col:17

  |-capture byref Var 0xa14cab0 'arr' 'int [4]'

  `-CompoundStmt 0xa171b58 <col:20, col:35>

    `-ReturnStmt 0xa171b40 <col:21, col:33>

      `-ImplicitCastExpr 0xa171b28 <col:28, col:33> 'int' <LValueToRValue>

        `-ArraySubscriptExpr 0xa171b00 <col:28, col:33> 'int' lvalue

          |-ImplicitCastExpr 0xa171ae8 <col:28> 'int *' <ArrayToPointerDecay>

          | `-DeclRefExpr 0xa171a70 <col:28> 'int [4]' lvalue Var 0xa14cab0 'arr' 'int [4]'

          `-IntegerLiteral 0xa171a98 <col:32> 'int' 1


2.       Also, I tried to set capture type to a reference on the array. In file SemaExpr.cpp in function tryCaptureVariable after a loop: "} while (!VarDC->Equals(DC));", I added the following lines:\


if (getLangOpts().OpenCL && CaptureType.getTypePtr()->isArrayType()) {

  CaptureType = Context.getLValueReferenceType(CaptureType);



But nothing interesting has happen. No changes in AST or llvm ir.


Could you please help me? What is the better way to get the pointer on array?


Best regards,



Joint Stock Company Intel A/O
Registered legal address: Krylatsky Hills Business Park,
17 Krylatskaya Str., Bldg 4, Moscow 121614,
Russian Federation

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.

cfe-dev mailing list
[hidden email]