aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2018-11-08 15:47:39 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2018-11-08 15:47:39 +0000
commit837a4f70d294fda34ee47a3ca43a912ea1dff840 (patch)
tree6d0ec519ee90597ac097b812b818df8872863a3d
parent8bf07130276f736f15ff2bd346c604a17cd6cc85 (diff)
[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
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.cpp42
-rw-r--r--test/OpenMP/nvptx_lambda_capturing.cpp15
2 files changed, 40 insertions, 17 deletions
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<llvm::Value *, llvm::Value *> &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<llvm::Value *, llvm::Value *> &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<llvm::Value *, llvm::Value *> 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