From: Alexey Bataev Date: Thu, 8 Nov 2018 15:47:39 +0000 (+0000) Subject: [OPENMP]Make lambda mapping follow reqs for PTR_AND_OBJ mapping. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=837a4f70d294fda34ee47a3ca43a912ea1dff840;p=clang [OPENMP]Make lambda mapping follow reqs for PTR_AND_OBJ mapping. The base pointer for the lambda mapping must point to the lambda capture placement and pointer must point to the captured variable itself. Patch fixes this problem. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@346408 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp index 2854744a96..831412bce6 100644 --- a/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/lib/CodeGen/CGOpenMPRuntime.cpp @@ -7550,11 +7550,11 @@ public: } /// Emit capture info for lambdas for variables captured by reference. - void generateInfoForLambdaCaptures(const ValueDecl *VD, llvm::Value *Arg, - MapBaseValuesArrayTy &BasePointers, - MapValuesArrayTy &Pointers, - MapValuesArrayTy &Sizes, - MapFlagsArrayTy &Types) const { + void generateInfoForLambdaCaptures( + const ValueDecl *VD, llvm::Value *Arg, MapBaseValuesArrayTy &BasePointers, + MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes, + MapFlagsArrayTy &Types, + llvm::DenseMap &LambdaPointers) const { const auto *RD = VD->getType() .getCanonicalType() .getNonReferenceType() @@ -7570,8 +7570,10 @@ public: if (ThisCapture) { LValue ThisLVal = CGF.EmitLValueForFieldInitialization(VDLVal, ThisCapture); - BasePointers.push_back(VDLVal.getPointer()); - Pointers.push_back(ThisLVal.getPointer()); + LValue ThisLValVal = CGF.EmitLValueForField(VDLVal, ThisCapture); + LambdaPointers.try_emplace(ThisLVal.getPointer(), VDLVal.getPointer()); + BasePointers.push_back(ThisLVal.getPointer()); + Pointers.push_back(ThisLValVal.getPointer()); Sizes.push_back(CGF.getTypeSize(CGF.getContext().VoidPtrTy)); Types.push_back(OMP_MAP_PTR_AND_OBJ | OMP_MAP_LITERAL | OMP_MAP_MEMBER_OF | OMP_MAP_IMPLICIT); @@ -7583,8 +7585,10 @@ public: auto It = Captures.find(VD); assert(It != Captures.end() && "Found lambda capture without field."); LValue VarLVal = CGF.EmitLValueForFieldInitialization(VDLVal, It->second); - BasePointers.push_back(VDLVal.getPointer()); - Pointers.push_back(VarLVal.getPointer()); + LValue VarLValVal = CGF.EmitLValueForField(VDLVal, It->second); + LambdaPointers.try_emplace(VarLVal.getPointer(), VDLVal.getPointer()); + BasePointers.push_back(VarLVal.getPointer()); + Pointers.push_back(VarLValVal.getPointer()); Sizes.push_back(CGF.getTypeSize( VD->getType().getCanonicalType().getNonReferenceType())); Types.push_back(OMP_MAP_PTR_AND_OBJ | OMP_MAP_LITERAL | @@ -7593,15 +7597,17 @@ public: } /// Set correct indices for lambdas captures. - void adjustMemberOfForLambdaCaptures(MapBaseValuesArrayTy &BasePointers, - MapValuesArrayTy &Pointers, - MapFlagsArrayTy &Types) const { + void adjustMemberOfForLambdaCaptures( + const llvm::DenseMap &LambdaPointers, + MapBaseValuesArrayTy &BasePointers, MapValuesArrayTy &Pointers, + MapFlagsArrayTy &Types) const { for (unsigned I = 0, E = Types.size(); I < E; ++I) { // Set correct member_of idx for all implicit lambda captures. if (Types[I] != (OMP_MAP_PTR_AND_OBJ | OMP_MAP_LITERAL | OMP_MAP_MEMBER_OF | OMP_MAP_IMPLICIT)) continue; - llvm::Value *BasePtr = *BasePointers[I]; + llvm::Value *BasePtr = LambdaPointers.lookup(*BasePointers[I]); + assert(BasePtr && "Unable to find base lambda address."); int TgtIdx = -1; for (unsigned J = I; J > 0; --J) { unsigned Idx = J - 1; @@ -8191,6 +8197,7 @@ void CGOpenMPRuntime::emitTargetCall(CodeGenFunction &CGF, // Get mappable expression information. MappableExprsHandler MEHandler(D, CGF); + llvm::DenseMap LambdaPointers; auto RI = CS.getCapturedRecordDecl()->field_begin(); auto CV = CapturedVars.begin(); @@ -8223,9 +8230,9 @@ void CGOpenMPRuntime::emitTargetCall(CodeGenFunction &CGF, // Generate correct mapping for variables captured by reference in // lambdas. if (CI->capturesVariable()) - MEHandler.generateInfoForLambdaCaptures(CI->getCapturedVar(), *CV, - CurBasePointers, CurPointers, - CurSizes, CurMapTypes); + MEHandler.generateInfoForLambdaCaptures( + CI->getCapturedVar(), *CV, CurBasePointers, CurPointers, CurSizes, + CurMapTypes, LambdaPointers); } // We expect to have at least an element of information for this capture. assert(!CurBasePointers.empty() && @@ -8248,7 +8255,8 @@ void CGOpenMPRuntime::emitTargetCall(CodeGenFunction &CGF, MapTypes.append(CurMapTypes.begin(), CurMapTypes.end()); } // Adjust MEMBER_OF flags for the lambdas captures. - MEHandler.adjustMemberOfForLambdaCaptures(BasePointers, Pointers, MapTypes); + MEHandler.adjustMemberOfForLambdaCaptures(LambdaPointers, BasePointers, + Pointers, MapTypes); // Map other list items in the map clause which are not captured variables // but "declare target link" global variables. MEHandler.generateInfoForDeclareTargetLink(BasePointers, Pointers, Sizes, diff --git a/test/OpenMP/nvptx_lambda_capturing.cpp b/test/OpenMP/nvptx_lambda_capturing.cpp index e041d5b2b7..481d4ad745 100644 --- a/test/OpenMP/nvptx_lambda_capturing.cpp +++ b/test/OpenMP/nvptx_lambda_capturing.cpp @@ -129,4 +129,19 @@ int main(int argc, char **argv) { return argc + s.foo(); } + +// HOST-LABEL: @main + +// HOST-DAG: call i32 @__tgt_target(i64 -1, i8* @{{.+}}, i32 11, i8** [[BASES:%.+]], i8** [[PTRS:%.+]], +// HOST-DAG: [[BASES:%.+]] = getelementptr inbounds [11 x i8*], [11 x i8*]* [[BASE_PTR:%.+]], i32 0, i32 0 +// HOST-DAG: [[PTRS:%.+]] = getelementptr inbounds [11 x i8*], [11 x i8*]* [[PTR_PTR:%.+]], i32 0, i32 0 +// HOST-DAG: [[BASE_REF:%.+]] = getelementptr inbounds [11 x i8*], [11 x i8*]* [[BASE_PTR]], i32 0, i32 5 +// HOST-DAG: [[BASE_REF_CAST:%.+]] = bitcast i8** [[BASE_REF]] to i32*** +// HOST-DAG: store i32** [[BASE:%.+]], i32*** [[BASE_REF_CAST]], +// HOST-DAG: [[BASE]] = getelementptr inbounds [[LAMBDA:%.+]], [[LAMBDA]]* [[LAMBDA_ADDR:%.+]], i32 0, i32 0 +// HOST-DAG: [[PTR_REF:%.+]] = getelementptr inbounds [11 x i8*], [11 x i8*]* [[PTR_PTR]], i32 0, i32 5 +// HOST-DAG: [[PTR_REF_CAST:%.+]] = bitcast i8** [[PTR_REF]] to i32** +// HOST-DAG: store i32* [[PTR:%.+]], i32** [[PTR_REF_CAST]], +// HOST-DAG: [[PTR]] = load i32*, i32** [[PTR_REF:%.+]], +// HOST-DAG: [[PTR_REF]] = getelementptr inbounds [[LAMBDA]], [[LAMBDA]]* [[LAMBDA_ADDR]], i32 0, i32 0 #endif // HEADER