[clang] 7842e7e - [OPENMP50]Add codegen support for array shaping expression in depend

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 30 10:40:38 PDT 2020


Author: Alexey Bataev
Date: 2020-03-30T13:37:21-04:00
New Revision: 7842e7ebbf3b68ebe52592d51aaf7a20f94d047b

URL: https://github.com/llvm/llvm-project/commit/7842e7ebbf3b68ebe52592d51aaf7a20f94d047b
DIFF: https://github.com/llvm/llvm-project/commit/7842e7ebbf3b68ebe52592d51aaf7a20f94d047b.diff

LOG: [OPENMP50]Add codegen support for array shaping expression in depend
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.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 1bb001ced31a..4b913607c1db 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -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(

diff  --git a/clang/test/OpenMP/depobj_ast_print.cpp b/clang/test/OpenMP/depobj_ast_print.cpp
index 8b6586ca2b26..f3076646a25e 100644
--- a/clang/test/OpenMP/depobj_ast_print.cpp
+++ b/clang/test/OpenMP/depobj_ast_print.cpp
@@ -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){{$}}
 

diff  --git a/clang/test/OpenMP/depobj_codegen.cpp b/clang/test/OpenMP/depobj_codegen.cpp
index 61b97d0b8479..2c7509babc17 100644
--- a/clang/test/OpenMP/depobj_codegen.cpp
+++ b/clang/test/OpenMP/depobj_codegen.cpp
@@ -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]],

diff  --git a/clang/test/OpenMP/task_codegen.c b/clang/test/OpenMP/task_codegen.c
index d0bbe5670d69..9376c375d5a8 100644
--- a/clang/test/OpenMP/task_codegen.c
+++ b/clang/test/OpenMP/task_codegen.c
@@ -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
     {


        


More information about the cfe-commits mailing list