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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits