diff options
author | Jakub Jelinek <jakub@redhat.com> | 2015-07-09 23:14:11 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2015-07-09 23:14:11 +0200 |
commit | a0945730e542f08d3a575cb6c73fe3c6bc48fd03 (patch) | |
tree | ad4e5ec5d126191f3c267cfc9089da8e3515f025 /gcc/tree-nested.c | |
parent | 17b658af6686e89568ef734aca6ff46248203a81 (diff) | |
download | gcc-a0945730e542f08d3a575cb6c73fe3c6bc48fd03.zip gcc-a0945730e542f08d3a575cb6c73fe3c6bc48fd03.tar.gz gcc-a0945730e542f08d3a575cb6c73fe3c6bc48fd03.tar.bz2 |
re PR middle-end/66633 (ICE on valid "verify_gimple failed" with OpenMP)
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.
From-SVN: r225638
Diffstat (limited to 'gcc/tree-nested.c')
-rw-r--r-- | gcc/tree-nested.c | 56 |
1 files changed, 48 insertions, 8 deletions
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index 6b75020..27986f6 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -767,10 +767,12 @@ get_static_chain (struct nesting_info *info, tree target_context, 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 *info, tree target_context, /* 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_info *info, tree decl) (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_stmt_iterator *gsi, bool *handled_ops_p, 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; |