cchen updated this revision to Diff 234157.
cchen added a comment.

Apply @ABataev's patch, add some code to support the patch and some tests


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D71475/new/

https://reviews.llvm.org/D71475

Files:
  clang/lib/Sema/SemaOpenMP.cpp
  clang/test/OpenMP/parallel_for_ast_print.cpp
  clang/test/OpenMP/parallel_for_linear_codegen.cpp
  clang/test/OpenMP/target_simd_ast_print.cpp

Index: clang/test/OpenMP/target_simd_ast_print.cpp
===================================================================
--- clang/test/OpenMP/target_simd_ast_print.cpp
+++ clang/test/OpenMP/target_simd_ast_print.cpp
@@ -187,6 +187,10 @@
   // CHECK-NEXT: for (T i = 0; i < N; ++i) {
   // CHECK-NEXT: }
 
+#pragma omp target simd linear (i: b + 1)
+  // CHECK: #pragma omp target simd linear(i: b + 1)
+  for (T j = 16; j < 64; j++)
+    i += 4;
   return T();
 }
 
@@ -307,6 +311,10 @@
   // CHECK: #pragma omp target simd is_device_ptr(p)
   // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
   // CHECK-NEXT: }
+#pragma omp target simd linear (i: b + 1)
+  // CHECK: #pragma omp target simd linear(i: b + 1)
+  for (int j = 16; j < 64; j++)
+    i += 4;
 
   return (tmain<int, 5>(argc, &argc));
 }
Index: clang/test/OpenMP/parallel_for_linear_codegen.cpp
===================================================================
--- clang/test/OpenMP/parallel_for_linear_codegen.cpp
+++ clang/test/OpenMP/parallel_for_linear_codegen.cpp
@@ -28,6 +28,8 @@
 float f;
 char cnt;
 
+int a[100];
+
 // CHECK: [[S_FLOAT_TY:%.+]] = type { float }
 // CHECK: [[S_INT_TY:%.+]] = type { i32 }
 // CHECK-DAG: [[F:@.+]] = global float 0.0
@@ -255,3 +257,39 @@
 // CHECK: ret void
 #endif
 
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s -check-prefix=CK1
+// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
+
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp-simd -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
+// RUN: %clang_cc1 -DCK1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
+// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
+#ifdef CK1
+
+// CK1: foo
+int foo (int i, int k)
+{
+#pragma omp parallel for linear (i: k + 1)
+  for (int j = 16; j < 64; j++)
+  {
+    a[i] = j;
+    i += 4;
+  }
+  return i;
+}
+// CK1: define internal void [[OUTLINE:@.+]](i32* noalias [[GTID:%.+]], i32* noalias [[BTID:%.+]], i32* dereferenceable(4) [[I_VAR:%.+]], i32* dereferenceable(4) [[K_VAR:%.+]])
+// CK1: [[GTID_ADDR:%.+]] = alloca i32*
+// CK1: [[BTID_ADDR:%.+]] = alloca i32*
+// CK1: [[I_ADDR:%.+]] = alloca i32*
+// CK1: [[K_ADDR:%.+]] = alloca i32*
+// CK1: store i32* [[GTID]], i32** [[GTID_ADDR]]
+// CK1: store i32* [[BTID]], i32** [[BTID_ADDR]]
+// CK1: store i32* [[I_VAR:%.+]], i32** [[I_ADDR]]
+// CK1: store i32* [[K_VAR:%.+]], i32** [[K_ADDR]]
+// CK1: [[ZERO:%.+]] = load i32*, i32** [[I_ADDR]]
+// CK1: [[ONE:%.+]] = load i32*, i32** [[K_ADDR]]
+// CK1: [[TWO:%.+]] = load i32, i32* [[ZERO]]
+// CK1: store i32 [[TWO]], i32* [[LINEAR_START:%.+]]
+// CK1: [[THREE:%.+]] = load i32, i32* [[ONE]]
+// CK1: [[ADD:%.+]] = add nsw i32 [[THREE]]
+// CK1: store i32 [[ADD]], i32* [[LINEAR_STEP:%.+]]
+#endif
Index: clang/test/OpenMP/parallel_for_ast_print.cpp
===================================================================
--- clang/test/OpenMP/parallel_for_ast_print.cpp
+++ clang/test/OpenMP/parallel_for_ast_print.cpp
@@ -100,6 +100,11 @@
   // CHECK-NEXT: for (int j = 0; j < 2; ++j)
   // CHECK-NEXT: for (int j = 0; j < 2; ++j)
   // CHECK-NEXT: foo();
+
+  T i;
+#pragma omp parallel for linear (i: b + 1)
+  for (T j = 16; j < 64; j++)
+    b += 4;
   return T();
 }
 
@@ -146,6 +151,11 @@
  // CHECK-NEXT: for (int i = 0; i < 10; ++i)
   // CHECK-NEXT: for (int j = 0; j < 10; ++j)
   // CHECK-NEXT: foo();
+
+  int i;
+#pragma omp parallel for linear (i: b + 1)
+  for (int j = 16; j < 64; j++)
+    b += 4;
   return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
 }
 
Index: clang/lib/Sema/SemaOpenMP.cpp
===================================================================
--- clang/lib/Sema/SemaOpenMP.cpp
+++ clang/lib/Sema/SemaOpenMP.cpp
@@ -1124,7 +1124,8 @@
   } else {
     DSAInfo &Data = getTopOfStack().SharingMap[D];
     assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
-           (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
+           (A == OMPC_firstprivate && (Data.Attributes == OMPC_lastprivate ||
+                                       Data.Attributes == OMPC_linear)) ||
            (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
            (isLoopControlVariable(D).first && A == OMPC_private));
     if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
@@ -3829,6 +3830,9 @@
           MarkDeclarationsReferencedInExpr(E);
         }
       }
+      if (auto *LC = dyn_cast<OMPLinearClause>(Clause))
+        if (Expr *E = LC->getStep())
+          MarkDeclarationsReferencedInExpr(E);
       DSAStack->setForceVarCapturing(/*V=*/false);
     } else if (CaptureRegions.size() > 1 ||
                CaptureRegions.back() != OMPD_unknown) {
@@ -4404,6 +4408,37 @@
   }
 }
 
+namespace {
+class LinearStepVarChecker : public StmtVisitor<LinearStepVarChecker, bool> {
+  llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
+  DSAStackTy *Stack;
+public:
+  bool VisitDeclRefExpr(DeclRefExpr *E) {
+    if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
+      DSAStackTy::DSAVarData DVar =
+          Stack->getTopDSA(E->getDecl(), /*FromParent=*/false);
+      if (DVar.CKind != OMPC_shared && DVar.CKind != OMPC_private &&
+          DVar.CKind != OMPC_firstprivate && DVar.CKind != OMPC_lastprivate)
+        ImplicitFirstprivate.push_back(cast<Expr>(E));
+      return true;
+    }
+    return false;
+  }
+  bool VisitStmt(Stmt *S) {
+    for (Stmt *Child : S->children()) {
+      if (Child && Visit(Child))
+        return true;
+    }
+    return false;
+  }
+  ArrayRef<Expr *> getImplicitFirstprivate() const {
+    return ImplicitFirstprivate;
+  }
+
+  explicit LinearStepVarChecker(DSAStackTy *S) : Stack(S) {}
+};
+} // namespace
+
 StmtResult Sema::ActOnOpenMPExecutableDirective(
     OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
     OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
@@ -4460,6 +4495,17 @@
         for (Expr *E : IRC->taskgroup_descriptors())
           if (E)
             ImplicitFirstprivates.emplace_back(E);
+      } else if (auto *LC = dyn_cast<OMPLinearClause>(C)) {
+        Expr *E = LC->getStep();
+        if (E) {
+          LinearStepVarChecker LSVChecker(DSAStack);
+          LSVChecker.Visit(E);
+          ArrayRef<Expr *> LinearVars = LSVChecker.getImplicitFirstprivate();
+          ImplicitFirstprivates.insert(
+              ImplicitFirstprivates.end(),
+              std::make_move_iterator(LinearVars.begin()),
+              std::make_move_iterator(LinearVars.end()));
+        }
       }
     }
     if (!ImplicitFirstprivates.empty()) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to