On Mon, Jun 29, 2015 at 11:23:24AM +0200, Eric Botcazou wrote: > > Don't you need to handle convert_nonlocal_omp_clauses similarly (need_chain > > in that case)? > > At least looking at your r211308 commit, for !optimize you force not just > > the frame, but also chain. > > You're very likely right, although I didn't manage to write a Fortran > testcase > with my limited knowledge of the language (I get a "Bad statement code" ICE). > > In fact the conditions should also mimic those of the aforementioned commit. > I initially didn't realize it, because I didn't quite grasp how the GOMP > stuff > was interacting with the nesting stuff, but I guess that the code ought not > to > do anything if there aren't pre-existing nested functions in the sources.
After looking into this some more, because the PR got reopened, there were two issues: 1) __builtin_adjust_trampoline call needing a frame or chain (as can be seen on the new testcases) that wasn't added to parallel/task/target clauses 2) for !optimize, there is code to add those, when frame or chain is needed for calls, but the problem was that as !optimize didn't clear DECL_STATIC_CHAIN initially it wasn't discovered. Both issues fixed in the following patch, which made the earlier change unnecessary. Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk. Should go to 5 branch eventually. 2015-07-09 Jakub Jelinek <ja...@redhat.com> PR middle-end/66633 * tree-nested.c (get_static_chain): Or in a flag into info->static_chain_added. (get_frame_field, get_nonlocal_debug_decl): Likewise. (convert_nonlocal_omp_clauses, convert_local_omp_clauses): Revert 2015-07-01 changes. (convert_tramp_reference_stmt): If a frame_decl or chain_decl is needed newly inside of GIMPLE_OMP_{PARALLEL,TASK,TARGET} body, add it to clauses. * gcc.dg/gomp/pr66633-1.c: New test. * gcc.dg/gomp/pr66633-2.c: New test. * gcc.dg/gomp/pr66633-3.c: New test. * gcc.dg/gomp/pr66633-4.c: New test. --- gcc/tree-nested.c.jj 2015-07-08 19:50:09.000000000 +0200 +++ gcc/tree-nested.c 2015-07-09 19:33:51.116923514 +0200 @@ -767,10 +767,12 @@ get_static_chain (struct nesting_info *i if (info->context == target_context) { x = build_addr (info->frame_decl, target_context); + info->static_chain_added |= 1; } else { x = get_chain_decl (info); + info->static_chain_added |= 2; for (i = info->outer; i->context != target_context; i = i->outer) { @@ -802,10 +804,12 @@ get_frame_field (struct nesting_info *in /* Make sure frame_decl gets created. */ (void) get_frame_type (info); x = info->frame_decl; + info->static_chain_added |= 1; } else { x = get_chain_decl (info); + info->static_chain_added |= 2; for (i = info->outer; i->context != target_context; i = i->outer) { @@ -851,10 +855,12 @@ get_nonlocal_debug_decl (struct nesting_ (void) get_frame_type (info); x = info->frame_decl; i = info; + info->static_chain_added |= 1; } else { x = get_chain_decl (info); + info->static_chain_added |= 2; for (i = info->outer; i->context != target_context; i = i->outer) { field = get_chain_field (i); @@ -1061,9 +1067,7 @@ static bool convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) { struct nesting_info *const info = (struct nesting_info *) wi->info; - /* If not optimizing, we will force the creation of the CHAIN object in - convert_all_function_calls, so we need to take it into account here. */ - bool need_chain = info->outer && !optimize, need_stmts = false; + bool need_chain = false, need_stmts = false; tree clause, decl; int dummy; bitmap new_suppress; @@ -1691,9 +1695,7 @@ static bool convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) { struct nesting_info *const info = (struct nesting_info *) wi->info; - /* If not optimizing, we will force the creation of the FRAME object in - convert_all_function_calls, so we need to take it into account here. */ - bool need_frame = info->inner && !optimize, need_stmts = false; + bool need_frame = false, need_stmts = false; tree clause, decl; int dummy; bitmap new_suppress; @@ -2292,17 +2294,55 @@ convert_tramp_reference_stmt (gimple_stm case GIMPLE_OMP_PARALLEL: case GIMPLE_OMP_TASK: { - tree save_local_var_chain; + tree save_local_var_chain = info->new_local_var_chain; walk_gimple_op (stmt, convert_tramp_reference_op, wi); - save_local_var_chain = info->new_local_var_chain; info->new_local_var_chain = NULL; + char save_static_chain_added = info->static_chain_added; + info->static_chain_added = 0; walk_body (convert_tramp_reference_stmt, convert_tramp_reference_op, info, gimple_omp_body_ptr (stmt)); if (info->new_local_var_chain) declare_vars (info->new_local_var_chain, gimple_seq_first_stmt (gimple_omp_body (stmt)), false); + for (int i = 0; i < 2; i++) + { + tree c, decl; + if ((info->static_chain_added & (1 << i)) == 0) + continue; + decl = i ? get_chain_decl (info) : info->frame_decl; + /* Don't add CHAIN.* or FRAME.* twice. */ + for (c = gimple_omp_taskreg_clauses (stmt); + c; + c = OMP_CLAUSE_CHAIN (c)) + if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED) + && OMP_CLAUSE_DECL (c) == decl) + break; + if (c == NULL && gimple_code (stmt) != GIMPLE_OMP_TARGET) + { + c = build_omp_clause (gimple_location (stmt), + i ? OMP_CLAUSE_FIRSTPRIVATE + : OMP_CLAUSE_SHARED); + OMP_CLAUSE_DECL (c) = decl; + OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt); + gimple_omp_taskreg_set_clauses (stmt, c); + } + else if (c == NULL) + { + c = build_omp_clause (gimple_location (stmt), + OMP_CLAUSE_MAP); + OMP_CLAUSE_DECL (c) = decl; + OMP_CLAUSE_SET_MAP_KIND (c, + i ? GOMP_MAP_TO : GOMP_MAP_TOFROM); + OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl); + OMP_CLAUSE_CHAIN (c) = gimple_omp_target_clauses (stmt); + gimple_omp_target_set_clauses (as_a <gomp_target *> (stmt), + c); + } + } info->new_local_var_chain = save_local_var_chain; + info->static_chain_added |= save_static_chain_added; } break; --- gcc/testsuite/gcc.dg/gomp/pr66633-1.c.jj 2015-07-09 19:36:33.849506037 +0200 +++ gcc/testsuite/gcc.dg/gomp/pr66633-1.c 2015-07-09 19:37:22.320785971 +0200 @@ -0,0 +1,14 @@ +/* PR middle-end/66633 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -O1" } */ + +void baz (int (*) ()); + +void +foo (void) +{ + int i; + auto int bar (void) { return i; } + #pragma omp parallel + baz (bar); +} --- gcc/testsuite/gcc.dg/gomp/pr66633-2.c.jj 2015-07-09 19:36:36.913460521 +0200 +++ gcc/testsuite/gcc.dg/gomp/pr66633-2.c 2015-07-09 19:36:56.949162880 +0200 @@ -0,0 +1,5 @@ +/* PR middle-end/66633 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -O0" } */ + +#include "pr66633-1.c" --- gcc/testsuite/gcc.dg/gomp/pr66633-3.c.jj 2015-07-09 19:37:08.591989920 +0200 +++ gcc/testsuite/gcc.dg/gomp/pr66633-3.c 2015-07-09 19:36:01.000000000 +0200 @@ -0,0 +1,18 @@ +/* PR middle-end/66633 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -O1" } */ + +void baz (int (*) ()); + +void +foo (void) +{ + int i; + auto int bar (void) { return i; } + auto void bar2 (void) + { + #pragma omp parallel + baz (bar); + } + bar2 (); +} --- gcc/testsuite/gcc.dg/gomp/pr66633-4.c.jj 2015-07-09 19:37:38.302548554 +0200 +++ gcc/testsuite/gcc.dg/gomp/pr66633-4.c 2015-07-09 19:37:44.241460329 +0200 @@ -0,0 +1,5 @@ +/* PR middle-end/66633 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -O0" } */ + +#include "pr66633-3.c" Jakub