[OPENMP50]Add codegen support for array shaping expression in depend
authorAlexey Bataev <a.bataev@hotmail.com>
Mon, 30 Mar 2020 16:48:44 +0000 (12:48 -0400)
committerAlexey Bataev <a.bataev@hotmail.com>
Mon, 30 Mar 2020 17:37:21 +0000 (13:37 -0400)
clauses.

Implemented codegen for array shaping operation in depend clauses. The
begin of the expression is the pointer itself, while the size of the
dependence data is the mukltiplacation of all dimensions in the array
shaping expression.

clang/lib/CodeGen/CGOpenMPRuntime.cpp
clang/test/OpenMP/depobj_ast_print.cpp
clang/test/OpenMP/depobj_codegen.cpp
clang/test/OpenMP/task_codegen.c

index 1bb001c..4b91360 100644 (file)
@@ -5363,11 +5363,29 @@ std::pair<llvm::Value *, Address> CGOpenMPRuntime::emitDependClause(
       if (Dependencies[I].first == OMPC_DEPEND_depobj)
         continue;
       const Expr *E = Dependencies[I].second;
-      LValue Addr = CGF.EmitLValue(E);
+      const auto *OASE = dyn_cast<OMPArrayShapingExpr>(E);
+      LValue Addr;
+      if (OASE) {
+        const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
+        Addr =
+            CGF.EmitLoadOfPointerLValue(CGF.EmitLValue(Base).getAddress(CGF),
+                                        Base->getType()->castAs<PointerType>());
+      } else {
+        Addr = CGF.EmitLValue(E);
+      }
       llvm::Value *Size;
       QualType Ty = E->getType();
-      if (const auto *ASE =
-              dyn_cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts())) {
+      if (OASE) {
+        Size = llvm::ConstantInt::get(CGF.SizeTy,/*V=*/1);
+        for (const Expr *SE : OASE->getDimensions()) {
+           llvm::Value *Sz = CGF.EmitScalarExpr(SE);
+           Sz = CGF.EmitScalarConversion(Sz, SE->getType(),
+                                    CGF.getContext().getSizeType(),
+                                    SE->getExprLoc());
+           Size = CGF.Builder.CreateNUWMul(Size, Sz);
+        }
+      } else if (const auto *ASE =
+                     dyn_cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts())) {
         LValue UpAddrLVal =
             CGF.EmitOMPArraySectionExpr(ASE, /*IsLowerBound=*/false);
         llvm::Value *UpAddr = CGF.Builder.CreateConstGEP1_32(
index 8b6586c..f307664 100644 (file)
@@ -17,17 +17,20 @@ void foo() {}
 template <class T>
 T tmain(T argc) {
   static T a;
-#pragma omp depobj(a) depend(in:argc)
+  int *b;
+#pragma omp depobj(a) depend(in:argc, ([4][*b][4])b)
 #pragma omp depobj(argc) destroy
 #pragma omp depobj(argc) update(inout)
   return argc;
 }
 // CHECK:      static T a;
-// CHECK-NEXT: #pragma omp depobj (a) depend(in : argc){{$}}
+// CHECK-NEXT: int *b;
+// CHECK-NEXT: #pragma omp depobj (a) depend(in : argc,([4][*b][4])b){{$}}
 // CHECK-NEXT: #pragma omp depobj (argc) destroy{{$}}
 // CHECK-NEXT: #pragma omp depobj (argc) update(inout){{$}}
 // CHECK:      static void *a;
-// CHECK-NEXT: #pragma omp depobj (a) depend(in : argc){{$}}
+// CHECK-NEXT: int *b;
+// CHECK-NEXT: #pragma omp depobj (a) depend(in : argc,([4][*b][4])b){{$}}
 // CHECK-NEXT: #pragma omp depobj (argc) destroy{{$}}
 // CHECK-NEXT: #pragma omp depobj (argc) update(inout){{$}}
 
index 61b97d0..2c7509b 100644 (file)
@@ -22,7 +22,7 @@ template <class T>
 T tmain(T argc) {
   static T a;
   void *argv;
-#pragma omp depobj(a) depend(in:argv)
+#pragma omp depobj(a) depend(in:argv, ([3][*(int*)argv][4])argv)
 #pragma omp depobj(argc) destroy
 #pragma omp depobj(argc) update(inout)
   return argc;
@@ -87,19 +87,30 @@ int main(int argc, char **argv) {
 // CHECK-LABEL: tmain
 // CHECK: [[ARGC_ADDR:%.+]] = alloca i8*,
 // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(
-// CHECK: [[DEP_ADDR_VOID:%.+]] = call i8* @__kmpc_alloc(i32 [[GTID]], i64 48, i8* null)
-// CHECK: [[DEP_ADDR:%.+]] = bitcast i8* [[DEP_ADDR_VOID]] to [2 x %struct.kmp_depend_info]*
-// CHECK: [[BASE_ADDR:%.+]] = getelementptr inbounds [2 x %struct.kmp_depend_info], [2 x %struct.kmp_depend_info]* [[DEP_ADDR]], i{{.+}} 0, i{{.+}} 0
+// CHECK: [[DEP_ADDR_VOID:%.+]] = call i8* @__kmpc_alloc(i32 [[GTID]], i64 72, i8* null)
+// CHECK: [[DEP_ADDR:%.+]] = bitcast i8* [[DEP_ADDR_VOID]] to [3 x %struct.kmp_depend_info]*
+// CHECK: [[BASE_ADDR:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* [[DEP_ADDR]], i{{.+}} 0, i{{.+}} 0
 // CHECK: [[SZ_BASE:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[BASE_ADDR]], i{{.+}} 0, i{{.+}} 0
-// CHECK: store i64 1, i64* [[SZ_BASE]],
-// CHECK: [[BASE_ADDR:%.+]] = getelementptr inbounds [2 x %struct.kmp_depend_info], [2 x %struct.kmp_depend_info]* [[DEP_ADDR]], i{{.+}} 0, i{{.+}} 1
+// CHECK: store i64 2, i64* [[SZ_BASE]],
+// CHECK: [[BASE_ADDR:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* [[DEP_ADDR]], i{{.+}} 0, i{{.+}} 1
 // CHECK: [[ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[BASE_ADDR]], i{{.+}} 0, i{{.+}} 0
 // CHECK: store i64 %{{.+}}, i64* [[ADDR]],
 // CHECK: [[SZ_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[BASE_ADDR]], i{{.+}} 0, i{{.+}} 1
 // CHECK: store i64 8, i64* [[SZ_ADDR]],
 // CHECK: [[FLAGS_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[BASE_ADDR]], i{{.+}} 0, i{{.+}} 2
 // CHECK: store i8 1, i8* [[FLAGS_ADDR]],
-// CHECK: [[BASE_ADDR:%.+]] = getelementptr inbounds [2 x %struct.kmp_depend_info], [2 x %struct.kmp_depend_info]* [[DEP_ADDR]], i{{.+}} 0, i{{.+}} 1
+// CHECK: [[SHAPE_ADDR:%.+]] = load i8*, i8** [[ARGV_ADDR:%.+]],
+// CHECK: [[SZ1:%.+]] = mul nuw i64 3, %{{.+}}
+// CHECK: [[SZ:%.+]] = mul nuw i64 [[SZ1]], 4
+// CHECK: [[BASE_ADDR:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* [[DEP_ADDR]], i{{.+}} 0, i{{.+}} 2
+// CHECK: [[ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[BASE_ADDR]], i{{.+}} 0, i{{.+}} 0
+// CHECK: [[SHAPE:%.+]] = ptrtoint i8* [[SHAPE_ADDR]] to i64
+// CHECK: store i64 [[SHAPE]], i64* [[ADDR]],
+// CHECK: [[SZ_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[BASE_ADDR]], i{{.+}} 0, i{{.+}} 1
+// CHECK: store i64 [[SZ]], i64* [[SZ_ADDR]],
+// CHECK: [[FLAGS_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[BASE_ADDR]], i{{.+}} 0, i{{.+}} 2
+// CHECK: store i8 1, i8* [[FLAGS_ADDR]],
+// CHECK: [[BASE_ADDR:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* [[DEP_ADDR]], i{{.+}} 0, i{{.+}} 1
 // CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[BASE_ADDR]] to i8*
 // CHECK: store i8* [[DEP]], i8** [[TMAIN_A]],
 // CHECK: [[ARGC:%.+]] = load i8*, i8** [[ARGC_ADDR]],
index d0bbe56..9376c37 100644 (file)
@@ -19,7 +19,7 @@ void foo();
 int main() {
   omp_depend_t d, x;
   omp_event_handle_t evt;
-  int a;
+  int a, *b;
   // CHECK: [[D_ADDR:%.+]] = alloca i8*,
   // CHECK: [[X_ADDR:%.+]] = alloca i8*,
   // CHECK: [[EVT_ADDR:%.+]] = alloca i64,
@@ -42,7 +42,7 @@ int main() {
   // CHECK: [[X_DEP_BASE_SIZE:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[X_DEP_BASE]], i{{.+}} 0, i{{.+}} 0
   // CHECK: [[SIZE2:%.+]] = load i64, i64* [[X_DEP_BASE_SIZE]],
   // CHECK: [[SIZE3:%.+]] = add nuw i64 [[SIZE]], [[SIZE2]]
-  // CHECK: [[SIZE:%.+]] = add nuw i64 [[SIZE3]], 1
+  // CHECK: [[SIZE:%.+]] = add nuw i64 [[SIZE3]], 2
   // CHECK: [[SIZE32:%.+]] = trunc i64 [[SIZE]] to i32
   // CHECK: [[SIZE64:%.+]] = zext i32 [[SIZE32]] to i64
   // CHECK: [[SV:%.+]] = call i8* @llvm.stacksave()
@@ -56,11 +56,26 @@ int main() {
   // CHECK: store i64 4, i64* [[SIZE_ADDR]],
   // CHECK: [[FLAGS_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA0]], i{{.+}} 0, i{{.+}} 2
   // CHECK: store i8 1, i8* [[FLAGS_ADDR]],
-  // CHECK: [[VLA_D:%.+]] = getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA]], i64 1
+  // CHECK: [[B_ADDR:%.+]] = load i32*, i32** %{{.+}},
+  // CHECK: [[A:%.+]] = load i32, i32* [[A_ADDR]],
+  // CHECK: [[A_CAST:%.+]] = sext i32 [[A]] to i64
+  // CHECK: [[SZ1:%.+]] = mul nuw i64 3, [[A_CAST]]
+  // CHECK: [[A:%.+]] = load i32, i32* [[A_ADDR]],
+  // CHECK: [[A_CAST:%.+]] = sext i32 [[A]] to i64
+  // CHECK: [[SZ:%.+]] = mul nuw i64 [[SZ1]], [[A_CAST]]
+  // CHECK: [[VLA1:%.+]] = getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA]], i64 1
+  // CHECK: [[BASE_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA1]], i{{.+}} 0, i{{.+}} 0
+  // CHECK: [[B_ADDR_CAST:%.+]] = ptrtoint i32* [[B_ADDR]] to i64
+  // CHECK: store i64 [[B_ADDR_CAST]], i64* [[BASE_ADDR]],
+  // CHECK: [[SIZE_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA1]], i{{.+}} 0, i{{.+}} 1
+  // CHECK: store i64 [[SZ]], i64* [[SIZE_ADDR]],
+  // CHECK: [[FLAGS_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA1]], i{{.+}} 0, i{{.+}} 2
+  // CHECK: store i8 1, i8* [[FLAGS_ADDR]],
+  // CHECK: [[VLA_D:%.+]] = getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA]], i64 2
   // CHECK: [[D_SIZE:%.+]] = mul nuw i64 24, [[SIZE1]]
   // CHECK: [[DEST:%.+]] = bitcast %struct.kmp_depend_info* [[VLA_D]] to i8*
   // CHECK: [[SRC:%.+]] = bitcast %struct.kmp_depend_info* [[D_DEP]] to i8*
-  // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[DEST]], i8* align 8 [[SRC]], i64 [[D_SIZE]], i1 false)
+  // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align {{.+}} [[DEST]], i8* align {{.+}} [[SRC]], i64 [[D_SIZE]], i1 false)
   // CHECK: [[VLA_X:%.+]] = getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA_D]], i64 [[SIZE1]]
   // CHECK: [[X_SIZE:%.+]] = mul nuw i64 24, [[SIZE2]]
   // CHECK: [[DEST:%.+]] = bitcast %struct.kmp_depend_info* [[VLA_X]] to i8*
@@ -70,7 +85,7 @@ int main() {
   // CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* @{{.+}}, i32 [[GTID]], i8* [[ALLOC]], i32 [[SIZE32]], i8* [[BC]], i32 0, i8* null)
   // CHECK: [[SV:%.+]] = load i8*, i8** [[SV_ADDR]],
   // CHECK: call void @llvm.stackrestore(i8* [[SV]])
-#pragma omp task depend(in: a) depend(depobj: d, x) detach(evt)
+#pragma omp task depend(in: a, ([3][a][a])b) depend(depobj: d, x) detach(evt)
   {
 #pragma omp taskgroup
     {