[OPENMP]Fix PR45911: Data sharing and lambda capture.
authorAlexey Bataev <a.bataev@hotmail.com>
Thu, 14 May 2020 20:37:30 +0000 (16:37 -0400)
committerAlexey Bataev <a.bataev@hotmail.com>
Wed, 20 May 2020 19:01:02 +0000 (15:01 -0400)
Summary:
No need to generate inlined OpenMP region for variables captured in
lambdas or block decls, only for implicitly captured variables in the
OpenMP region.

Reviewers: jdoerfert

Subscribers: yaxunl, guansong, cfe-commits, caomhin

Tags: #clang

Differential Revision: https://reviews.llvm.org/D79966

clang/lib/CodeGen/CGOpenMPRuntime.cpp
clang/test/OpenMP/task_firstprivate_codegen.cpp

index 549d864..6a724ca 100644 (file)
@@ -4836,11 +4836,16 @@ static void emitPrivatesInit(CodeGenFunction &CGF,
                       C.getDeclAlign(OriginalVD)),
               SharedRefLValue.getType(), LValueBaseInfo(AlignmentSource::Decl),
               SharedRefLValue.getTBAAInfo());
+        } else if (CGF.LambdaCaptureFields.count(
+                       Pair.second.Original->getCanonicalDecl()) > 0 ||
+                   dyn_cast_or_null<BlockDecl>(CGF.CurCodeDecl)) {
+          SharedRefLValue = CGF.EmitLValue(Pair.second.OriginalRef);
         } else {
+          // Processing for implicitly captured variables.
           InlinedOpenMPRegionRAII Region(
               CGF, [](CodeGenFunction &, PrePostActionTy &) {}, OMPD_unknown,
               /*HasCancel=*/false);
-          SharedRefLValue =  CGF.EmitLValue(Pair.second.OriginalRef);
+          SharedRefLValue = CGF.EmitLValue(Pair.second.OriginalRef);
         }
         if (Type->isArrayType()) {
           // Initialize firstprivate array.
index 079c342..d5d495e 100644 (file)
@@ -56,6 +56,7 @@ T tmain() {
 
 int main() {
   static int sivar;
+  float local = 0;
 #ifdef LAMBDA
   // LAMBDA: [[G:@.+]] = global double
   // LAMBDA: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0,
@@ -73,9 +74,12 @@ int main() {
 // LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR]],
 // LAMBDA: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]]
 
+// LAMBDA: [[LOCAL_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+// LAMBDA: store float %{{.+}}, float* [[LOCAL_PRIVATE_ADDR]]
+
 // LAMBDA: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]])
 // LAMBDA: ret
-#pragma omp task firstprivate(g, sivar)
+#pragma omp task firstprivate(g, sivar, local)
   {
     // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG_PTR:%.+]])
     // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
@@ -115,9 +119,13 @@ int main() {
   // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1
   // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR]],
   // BLOCKS: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]],
+
+  // BLOCKS: [[LOCAL_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2
+  // BLOCKS: store float %{{.+}}, float* [[LOCAL_PRIVATE_ADDR]]
+
   // BLOCKS: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]])
   // BLOCKS: ret
-#pragma omp task firstprivate(g, sivar)
+#pragma omp task firstprivate(g, sivar, local)
   {
     // BLOCKS: define {{.+}} void {{@.+}}(i8*
     // BLOCKS-NOT: [[G]]{{[[^:word:]]}}