From 3c676e3891b962b859e7613781419ee0dacce7dd Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Tue, 12 Nov 2019 11:19:26 -0500 Subject: [PATCH] [OPENMP]Use copy constructors instead of assignment operators in declare reduction initializers. Better to use copy constructor at the initialization of the declare reduction construct rather than assignment operator. --- clang/lib/Parse/ParseOpenMP.cpp | 13 +++---- .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 7 +++- clang/test/AST/dump.cpp | 12 +++---- .../OpenMP/declare_reduction_messages.cpp | 2 +- .../test/OpenMP/for_reduction_codegen_UDR.cpp | 36 ++++++++++++++++--- 5 files changed, 48 insertions(+), 22 deletions(-) diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 8430e72d3c88..49ba52897fe6 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -368,14 +368,8 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) { // Check if initializer is omp_priv or something else. if (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr("omp_priv")) { - if (Actions.getLangOpts().CPlusPlus) { - InitializerResult = Actions.ActOnFinishFullExpr( - ParseAssignmentExpression().get(), D->getLocation(), - /*DiscardedValue*/ false); - } else { - ConsumeToken(); - ParseOpenMPReductionInitializerForDecl(OmpPrivParm); - } + ConsumeToken(); + ParseOpenMPReductionInitializerForDecl(OmpPrivParm); } else { InitializerResult = Actions.ActOnFinishFullExpr( ParseAssignmentExpression().get(), D->getLocation(), @@ -419,7 +413,8 @@ void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) { return; } - ExprResult Init(ParseInitializer()); + PreferredType.enterVariableInit(Tok.getLocation(), OmpPrivParm); + ExprResult Init = ParseAssignmentExpression(); if (Init.isInvalid()) { SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index cd8b95231aad..600265e2d852 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3118,7 +3118,12 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl( SubstInitializer = SemaRef.SubstExpr(D->getInitializer(), TemplateArgs).get(); } else { - IsCorrect = IsCorrect && OmpPrivParm->hasInit(); + auto *OldPrivParm = + cast(cast(D->getInitPriv())->getDecl()); + IsCorrect = IsCorrect && OldPrivParm->hasInit(); + if (IsCorrect) + SemaRef.InstantiateVariableInitializer(OmpPrivParm, OldPrivParm, + TemplateArgs); } SemaRef.ActOnOpenMPDeclareReductionInitializerEnd( NewDRD, SubstInitializer, OmpPrivParm); diff --git a/clang/test/AST/dump.cpp b/clang/test/AST/dump.cpp index 641abc5ea646..4d271514349f 100644 --- a/clang/test/AST/dump.cpp +++ b/clang/test/AST/dump.cpp @@ -33,13 +33,11 @@ int ga, gb; // CHECK-NEXT: | | |-DeclRefExpr {{.+}} 'float' lvalue Var {{.+}} 'omp_out' 'float' // CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} 'float' // CHECK-NEXT: | | `-DeclRefExpr {{.+}} 'float' lvalue Var {{.+}} 'omp_in' 'float' -// CHECK-NEXT: | |-BinaryOperator {{.+}} 'float' lvalue '=' -// CHECK-NEXT: | | |-DeclRefExpr {{.+}} 'float' lvalue Var {{.+}} 'omp_priv' 'float' -// CHECK-NEXT: | | `-BinaryOperator {{.+}} 'float' '+' -// CHECK-NEXT: | | |-ImplicitCastExpr {{.+}} 'float' -// CHECK-NEXT: | | | `-DeclRefExpr {{.+}} 'float' lvalue Var {{.+}} 'omp_orig' 'float' -// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} 'float' -// CHECK-NEXT: | | `-IntegerLiteral {{.+}} 'int' 15 +// CHECK-NEXT: | |-BinaryOperator {{.+}} 'float' '+' +// CHECK-NEXT: | | |-ImplicitCastExpr {{.+}} 'float' +// CHECK-NEXT: | | | `-DeclRefExpr {{.+}} 'float' lvalue Var {{.+}} 'omp_orig' 'float' +// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} 'float' +// CHECK-NEXT: | | `-IntegerLiteral {{.+}} 'int' 15 struct S { int a, b; diff --git a/clang/test/OpenMP/declare_reduction_messages.cpp b/clang/test/OpenMP/declare_reduction_messages.cpp index a674af7151da..1fc5ec6e683f 100644 --- a/clang/test/OpenMP/declare_reduction_messages.cpp +++ b/clang/test/OpenMP/declare_reduction_messages.cpp @@ -142,7 +142,7 @@ int main() { #if __cplusplus == 201103L struct A { A() {} - A& operator=(A&&) = default; + A(const A &) = default; }; int A_TEST() { diff --git a/clang/test/OpenMP/for_reduction_codegen_UDR.cpp b/clang/test/OpenMP/for_reduction_codegen_UDR.cpp index c7384f6eb13a..f3816de5f5bf 100644 --- a/clang/test/OpenMP/for_reduction_codegen_UDR.cpp +++ b/clang/test/OpenMP/for_reduction_codegen_UDR.cpp @@ -56,6 +56,34 @@ void init_plus(BaseS1&, const BaseS1&); // CHECK-DAG: [[REDUCTION_LOC:@.+]] = private unnamed_addr global %struct.ident_t { i32 0, i32 18, i32 0, i32 0, i8* // CHECK-DAG: [[REDUCTION_LOCK:@.+]] = common global [8 x i32] zeroinitializer +#pragma omp declare reduction(operator* : S : omp_out.f = 17 * omp_in.f) initializer(omp_priv = S()) +// CHECK-LABEL: bazz +void bazz() { + S s; +// CHECK: [[S_ADDR:%.+]] = alloca [[S_INT_TY]], +// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[S_ADDR]]) +// CHECK: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @{{.+}}, i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[S_INT_TY]]*)* [[BAZZ_OUTLINE:@.+]] to void (i32*, i32*, ...)*), [[S_INT_TY]]* [[S_ADDR]]) +// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* +// CHECK: ret void +#pragma omp parallel +#pragma omp simd reduction(*: s) + for (int I = 0; I < 10; ++I) + ; +} + +// CHECK: define internal void [[BAZZ_OUTLINE]](i32* {{.+}}, i32* {{.+}}, [[S_INT_TY]]* {{.+}}) +// CHECK: [[S_PRIV_ADDR:%.+]] = alloca [[S_INT_TY]], +// CHECK: call void [[BAZZ_INIT:@.+]]([[S_INT_TY]]* [[S_PRIV_ADDR]], [[S_INT_TY]]* [[S_ORIG_ADDR:%.+]]) +// CHECK: call void @{{.+}}([[S_INT_TY]]* [[S_ORIG_ADDR]], [[S_INT_TY]]* [[S_PRIV_ADDR]]) +// CHECK-NEXT: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[S_PRIV_ADDR]]) +// CHECK-NEXT: ret void + +// CHECK: define internal void [[BAZZ_INIT]]([[S_INT_TY]]* {{.*}}[[S_PRIV_ADDR:%.+]], [[S_INT_TY]]* {{.*}}[[S_ORIG_ADDR:%.+]]) +// CHECK: store [[S_INT_TY]]* [[S_PRIV_ADDR]], [[S_INT_TY]]** [[S_PRIV_ADDR_REF:%.+]], +// CHECK: [[S_PRIV_ADDR:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[S_PRIV_ADDR_REF]], +// CHECK: call void [[S_INT_TY_CONSTR]]([[S_INT_TY]]* [[S_PRIV_ADDR]]) +// CHECK-NEXT: ret void + #pragma omp declare reduction(operator&& : int : omp_out = 111 & omp_in) template T tmain() { @@ -828,7 +856,7 @@ int main() { // CHECK: store [4 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]], // CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]], // CHECK: [[VAR3_VOID_PTR:%.+]] = call i8* @__kmpc_alloc(i32 [[GTID:%.+]], i64 48, i8* inttoptr (i64 6 to i8*)) -// CHECK: [[VAR3_PRIV:%.+]] = bitcast i8* [[VAR3_VOID_PTR]] to [4 x %struct.S]* +// CHECK: [[VAR3_PRIV:%.+]] = bitcast i8* [[VAR3_VOID_PTR]] to [4 x [[S_FLOAT_TY]]]* // CHECK: getelementptr inbounds [4 x [[S_FLOAT_TY]]], [4 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], i32 0, i32 0 // CHECK: bitcast [4 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]* // CHECK: getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 4 @@ -839,13 +867,13 @@ int main() { // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT_42]]() // CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], -// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) +// CHECK: call {{.*}} [[S_INT_TY_CONSTR]]([[S_INT_TY]]* [[TEST]]) // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32*, [[S_INT_TY]]*, [[S_INT_TY]]*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*)* [[TMAIN_MICROTASK:@.+]] to void // Not interested in this one: // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [42 x [[S_INT_TY]]]*, [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK2:@.+]] to void -// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* -// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* +// CHECK: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* +// CHECK: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* // CHECK: ret // // CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [[S_INT_TY]]* dereferenceable(12) %{{.+}}, [[S_INT_TY]]* dereferenceable(12) %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(24) %{{.+}})