openmp: Handle clauses with gimple sequences in convert_nonlocal_omp_clauses properly

If the walk_body on the various sequences of reduction, lastprivate and/or linear
clauses needs to create a temporary variable, we should declare that variable
in that sequence rather than outside, where it would need to be privatized inside of
the construct.

2020-08-08  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/93553
	* tree-nested.c (convert_nonlocal_omp_clauses): For
	OMP_CLAUSE_REDUCTION, OMP_CLAUSE_LASTPRIVATE and OMP_CLAUSE_LINEAR
	save info->new_local_var_chain around walks of the clause gimple
	sequences and declare_vars if needed into the sequence.

2020-08-08  Tobias Burnus  <tobias@codesourcery.com>

	PR fortran/93553
	* testsuite/libgomp.fortran/pr93553.f90: New test.
This commit is contained in:
Jakub Jelinek 2020-08-08 11:10:30 +02:00
parent 87d6dae308
commit 676b5525e8
2 changed files with 57 additions and 10 deletions

View File

@ -1419,12 +1419,22 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clause))
DECL_CONTEXT (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clause))
= info->context;
tree save_local_var_chain = info->new_local_var_chain;
info->new_local_var_chain = NULL;
gimple_seq *seq = &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (clause);
walk_body (convert_nonlocal_reference_stmt,
convert_nonlocal_reference_op, info,
&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (clause));
convert_nonlocal_reference_op, info, seq);
if (info->new_local_var_chain)
declare_vars (info->new_local_var_chain,
gimple_seq_first_stmt (*seq), false);
info->new_local_var_chain = NULL;
seq = &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (clause);
walk_body (convert_nonlocal_reference_stmt,
convert_nonlocal_reference_op, info,
&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (clause));
convert_nonlocal_reference_op, info, seq);
if (info->new_local_var_chain)
declare_vars (info->new_local_var_chain,
gimple_seq_first_stmt (*seq), false);
info->new_local_var_chain = save_local_var_chain;
DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
= old_context;
if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clause))
@ -1434,15 +1444,31 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
break;
case OMP_CLAUSE_LASTPRIVATE:
walk_body (convert_nonlocal_reference_stmt,
convert_nonlocal_reference_op, info,
&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause));
{
tree save_local_var_chain = info->new_local_var_chain;
info->new_local_var_chain = NULL;
gimple_seq *seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause);
walk_body (convert_nonlocal_reference_stmt,
convert_nonlocal_reference_op, info, seq);
if (info->new_local_var_chain)
declare_vars (info->new_local_var_chain,
gimple_seq_first_stmt (*seq), false);
info->new_local_var_chain = save_local_var_chain;
}
break;
case OMP_CLAUSE_LINEAR:
walk_body (convert_nonlocal_reference_stmt,
convert_nonlocal_reference_op, info,
&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (clause));
{
tree save_local_var_chain = info->new_local_var_chain;
info->new_local_var_chain = NULL;
gimple_seq *seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (clause);
walk_body (convert_nonlocal_reference_stmt,
convert_nonlocal_reference_op, info, seq);
if (info->new_local_var_chain)
declare_vars (info->new_local_var_chain,
gimple_seq_first_stmt (*seq), false);
info->new_local_var_chain = save_local_var_chain;
}
break;
default:

View File

@ -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