On 7/20/20 9:12 PM, Jakub Jelinek wrote:
I don't like this global variable.
Can you please instead stick it into struct nesting_info and make sure it is
cleared where it is allocated?

Done. The existing code uses
   struct nesting_info *info = XCNEW (struct nesting_info);
in create_nesting_tree; hence, the clearing is already done.

Tobias

-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander 
Walter
OpenMP: Fix tmp-var handling with tree-nested.c [PR93553]

gcc/ChangeLog:

	PR fortran/93553
	* tree-nested.c (struct nesting_info): Add omp_new_clauses.
	(convert_nonlocal_reference_op): Add init_tmp_var/init_tmp_var
	vars to omp_new_clauses.
	(convert_nonlocal_omp_clauses, convert_local_omp_clauses): Add
	those as 'private' to the OpenMP clause.

libgomp/ChangeLog:

	PR fortran/93553
	* testsuite/libgomp.fortran/pr93553.f90: New test.

 gcc/tree-nested.c                             | 35 +++++++++++++++++++++++++++
 libgomp/testsuite/libgomp.fortran/pr93553.f90 | 21 ++++++++++++++++
 2 files changed, 56 insertions(+)

diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 4dc5533be84..aad4c8094b0 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -103,6 +103,7 @@ struct nesting_info
   tree chain_field;
   tree chain_decl;
   tree nl_goto_field;
+  tree omp_new_clauses;
 
   bool thunk_p;
   bool any_parm_remapped;
@@ -1068,6 +1069,11 @@ convert_nonlocal_reference_op (tree *tp, int *walk_subtrees, void *data)
 	    if (use_pointer_in_frame (t))
 	      {
 		x = init_tmp_var (info, x, &wi->gsi);
+		tree c = build_omp_clause (DECL_SOURCE_LOCATION (x),
+					   OMP_CLAUSE_PRIVATE);
+		OMP_CLAUSE_DECL (c) = x;
+		OMP_CLAUSE_CHAIN (c) = info->omp_new_clauses;
+		info->omp_new_clauses = c;
 		x = build_simple_mem_ref_notrap (x);
 	      }
 	  }
@@ -1078,6 +1084,11 @@ convert_nonlocal_reference_op (tree *tp, int *walk_subtrees, void *data)
 	      x = save_tmp_var (info, x, &wi->gsi);
 	    else
 	      x = init_tmp_var (info, x, &wi->gsi);
+	    tree c = build_omp_clause (DECL_SOURCE_LOCATION (x),
+				       OMP_CLAUSE_PRIVATE);
+	    OMP_CLAUSE_DECL (c) = x;
+	    OMP_CLAUSE_CHAIN (c) = info->omp_new_clauses;
+	    info->omp_new_clauses = c;
 	  }
 
 	*tp = x;
@@ -1450,6 +1461,18 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
 	  break;
 	}
 
+  struct nesting_info *n;
+  FOR_EACH_NEST_INFO (n, info)
+    if (n->omp_new_clauses)
+      {
+	tree last_clause = n->omp_new_clauses;
+	while (OMP_CLAUSE_CHAIN (last_clause))
+	  last_clause = OMP_CLAUSE_CHAIN (last_clause);
+	OMP_CLAUSE_CHAIN (last_clause) = *pclauses;
+	*pclauses = n->omp_new_clauses;
+	n->omp_new_clauses = NULL_TREE;
+      }
+
   return need_chain;
 }
 
@@ -2193,6 +2216,18 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
 	  break;
 	}
 
+  struct nesting_info *n;
+  FOR_EACH_NEST_INFO (n, info)
+    if (n->omp_new_clauses)
+      {
+	tree last_clause = n->omp_new_clauses;
+	while (OMP_CLAUSE_CHAIN (last_clause))
+	  last_clause = OMP_CLAUSE_CHAIN (last_clause);
+	OMP_CLAUSE_CHAIN (last_clause) = *pclauses;
+	*pclauses = n->omp_new_clauses;
+	n->omp_new_clauses = NULL_TREE;
+      }
+
   return need_frame;
 }
 
diff --git a/libgomp/testsuite/libgomp.fortran/pr93553.f90 b/libgomp/testsuite/libgomp.fortran/pr93553.f90
new file mode 100644
index 00000000000..5d6f10febed
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/pr93553.f90
@@ -0,0 +1,21 @@
+program p
+   implicit none
+   integer :: x(8) = 0
+   call sub(x)
+end
+subroutine sub(x)
+   implicit none
+   integer i
+   integer :: x(8)
+   integer :: c(8) = [(11*i, i=1,8)]
+   call s
+   if (any (x /= c)) stop 1
+contains
+   subroutine s
+      integer :: i
+      !$omp parallel do reduction(+:x)
+      do i = 1, 8
+         x(i) = c(i)
+      end do
+   end
+end

Reply via email to