This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[committed] Fix ICE with nested fns and OpenMP (PR fortran/78298)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 28 Nov 2016 18:33:40 +0100
- Subject: [committed] Fix ICE with nested fns and OpenMP (PR fortran/78298)
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
If we add shared (FRAME.NN) clause to some parallel/task OpenMP construct
or map (tofrom: FRAME.NN) clause to some target construct, we need to
add one of those to all outer parallel/task/target constructs too.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
committed to trunk, queued for backporting.
2016-11-28 Jakub Jelinek <jakub@redhat.com>
PR fortran/78298
* tree-nested.c (convert_local_reference_stmt): After adding
shared (FRAME.NN) clause to omp parallel, task or target,
add it also to all outer omp parallel, task or target constructs.
* gfortran.dg/gomp/pr78298.f90: New test.
--- gcc/tree-nested.c.jj 2016-10-31 13:28:12.000000000 +0100
+++ gcc/tree-nested.c 2016-11-28 15:00:08.755214563 +0100
@@ -2083,6 +2083,8 @@ convert_local_reference_stmt (gimple_stm
struct nesting_info *info = (struct nesting_info *) wi->info;
tree save_local_var_chain;
bitmap save_suppress;
+ char save_static_chain_added;
+ bool frame_decl_added;
gimple *stmt = gsi_stmt (*gsi);
switch (gimple_code (stmt))
@@ -2090,29 +2092,44 @@ convert_local_reference_stmt (gimple_stm
case GIMPLE_OMP_PARALLEL:
case GIMPLE_OMP_TASK:
save_suppress = info->suppress_expansion;
+ frame_decl_added = false;
if (convert_local_omp_clauses (gimple_omp_taskreg_clauses_ptr (stmt),
wi))
{
- tree c;
+ tree c = build_omp_clause (gimple_location (stmt),
+ OMP_CLAUSE_SHARED);
(void) get_frame_type (info);
- c = build_omp_clause (gimple_location (stmt),
- OMP_CLAUSE_SHARED);
OMP_CLAUSE_DECL (c) = info->frame_decl;
OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
gimple_omp_taskreg_set_clauses (stmt, c);
+ info->static_chain_added |= 4;
+ frame_decl_added = true;
}
save_local_var_chain = info->new_local_var_chain;
+ save_static_chain_added = info->static_chain_added;
info->new_local_var_chain = NULL;
+ info->static_chain_added = 0;
walk_body (convert_local_reference_stmt, convert_local_reference_op, info,
gimple_omp_body_ptr (stmt));
+ if ((info->static_chain_added & 4) != 0 && !frame_decl_added)
+ {
+ tree c = build_omp_clause (gimple_location (stmt),
+ OMP_CLAUSE_SHARED);
+ (void) get_frame_type (info);
+ OMP_CLAUSE_DECL (c) = info->frame_decl;
+ OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
+ info->static_chain_added |= 4;
+ gimple_omp_taskreg_set_clauses (stmt, c);
+ }
if (info->new_local_var_chain)
declare_vars (info->new_local_var_chain,
gimple_seq_first_stmt (gimple_omp_body (stmt)), false);
info->new_local_var_chain = save_local_var_chain;
info->suppress_expansion = save_suppress;
+ info->static_chain_added |= save_static_chain_added;
break;
case GIMPLE_OMP_FOR:
@@ -2153,29 +2170,46 @@ convert_local_reference_stmt (gimple_stm
break;
}
save_suppress = info->suppress_expansion;
+ frame_decl_added = false;
if (convert_local_omp_clauses (gimple_omp_target_clauses_ptr (stmt), wi))
{
- tree c;
+ tree c = build_omp_clause (gimple_location (stmt), OMP_CLAUSE_MAP);
(void) get_frame_type (info);
- c = build_omp_clause (gimple_location (stmt), OMP_CLAUSE_MAP);
OMP_CLAUSE_DECL (c) = info->frame_decl;
OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (info->frame_decl);
OMP_CLAUSE_CHAIN (c) = gimple_omp_target_clauses (stmt);
gimple_omp_target_set_clauses (as_a <gomp_target *> (stmt), c);
+ info->static_chain_added |= 4;
+ frame_decl_added = true;
}
save_local_var_chain = info->new_local_var_chain;
+ save_static_chain_added = info->static_chain_added;
info->new_local_var_chain = NULL;
+ info->static_chain_added = 0;
walk_body (convert_local_reference_stmt, convert_local_reference_op, info,
gimple_omp_body_ptr (stmt));
+ if ((info->static_chain_added & 4) != 0 && !frame_decl_added)
+ {
+ tree c = build_omp_clause (gimple_location (stmt), OMP_CLAUSE_MAP);
+ (void) get_frame_type (info);
+ OMP_CLAUSE_DECL (c) = info->frame_decl;
+ OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
+ OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (info->frame_decl);
+ OMP_CLAUSE_CHAIN (c) = gimple_omp_target_clauses (stmt);
+ gimple_omp_target_set_clauses (as_a <gomp_target *> (stmt), c);
+ info->static_chain_added |= 4;
+ }
+
if (info->new_local_var_chain)
declare_vars (info->new_local_var_chain,
gimple_seq_first_stmt (gimple_omp_body (stmt)), false);
info->new_local_var_chain = save_local_var_chain;
info->suppress_expansion = save_suppress;
+ info->static_chain_added |= save_static_chain_added;
break;
case GIMPLE_OMP_TEAMS:
--- gcc/testsuite/gfortran.dg/gomp/pr78298.f90.jj 2016-11-28 15:11:30.905546859 +0100
+++ gcc/testsuite/gfortran.dg/gomp/pr78298.f90 2016-11-28 15:12:22.861887658 +0100
@@ -0,0 +1,28 @@
+! PR fortran/78298
+! { dg-do compile }
+! { dg-additional-options "-O2" }
+
+program pr78298
+ integer :: i, j, n
+ n = 2
+ !$omp parallel
+ !$omp do
+ do i = 1, n
+ !$omp parallel
+ !$omp do
+ do j = 1, n
+ call sub(i)
+ end do
+ !$omp end parallel
+ end do
+ !$omp end parallel
+ !call unused()
+contains
+ subroutine sub(x)
+ integer :: x
+ end
+ subroutine unused()
+ i = 0
+ j = 0
+ end
+end
Jakub