diff options
| author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-10-03 08:17:34 +0000 |
|---|---|---|
| committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-10-03 08:17:34 +0000 |
| commit | ecddc70ebcac131c126752ff7e09c3587b52f921 (patch) | |
| tree | 15b30df3ab06d306619062cc75a1d2f82e657298 | |
| parent | f2a141287ffa531ad79f348bdad3bdb4bcab160f (diff) | |
| download | ppe42-gcc-ecddc70ebcac131c126752ff7e09c3587b52f921.tar.gz ppe42-gcc-ecddc70ebcac131c126752ff7e09c3587b52f921.zip | |
PR libgomp/61200
* omp-low.c (taskreg_contexts): New variable.
(scan_omp_parallel): Push newly created context into taskreg_contexts
vector and move record layout code to finish_taskreg_scan.
(scan_omp_task): Likewise.
(finish_taskreg_scan): New function.
(execute_lower_omp): Call finish_taskreg_scan on all taskreg_contexts
vector elements and release it.
* c-c++-common/gomp/pr61200.c: New test.
* testsuite/libgomp.c/pr61200.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch@215838 138bc75d-0d04-0410-961f-82ee72b054a4
| -rw-r--r-- | gcc/ChangeLog | 11 | ||||
| -rw-r--r-- | gcc/omp-low.c | 85 | ||||
| -rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
| -rw-r--r-- | gcc/testsuite/c-c++-common/gomp/pr61200.c | 13 | ||||
| -rw-r--r-- | libgomp/ChangeLog | 5 | ||||
| -rw-r--r-- | libgomp/testsuite/libgomp.c/pr61200.c | 87 |
6 files changed, 196 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 50cb1c3f541..805966c39ca 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2014-10-03 Jakub Jelinek <jakub@redhat.com> + + PR libgomp/61200 + * omp-low.c (taskreg_contexts): New variable. + (scan_omp_parallel): Push newly created context into taskreg_contexts + vector and move record layout code to finish_taskreg_scan. + (scan_omp_task): Likewise. + (finish_taskreg_scan): New function. + (execute_lower_omp): Call finish_taskreg_scan on all taskreg_contexts + vector elements and release it. + 2014-10-02 Martin Jambor <mjambor@suse.cz> PR tree-optimization/63375 diff --git a/gcc/omp-low.c b/gcc/omp-low.c index efe3cb73e6d..f77df897679 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -204,6 +204,7 @@ static int taskreg_nesting_level; static int target_nesting_level; static struct omp_region *root_omp_region; static bitmap task_shared_vars; +static vec<omp_context *> taskreg_contexts; static void scan_omp (gimple_seq *, omp_context *); static tree scan_omp_1_op (tree *, int *, void *); @@ -2024,6 +2025,7 @@ scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx) } ctx = new_omp_context (stmt, outer_ctx); + taskreg_contexts.safe_push (ctx); if (taskreg_nesting_level > 1) ctx->is_nested = true; ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0); @@ -2043,11 +2045,6 @@ scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx) if (TYPE_FIELDS (ctx->record_type) == NULL) ctx->record_type = ctx->receiver_decl = NULL; - else - { - layout_type (ctx->record_type); - fixup_child_record_type (ctx); - } } /* Scan an OpenMP task directive. */ @@ -2058,7 +2055,6 @@ scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx) omp_context *ctx; tree name, t; gimple stmt = gsi_stmt (*gsi); - location_t loc = gimple_location (stmt); /* Ignore task directives with empty bodies. */ if (optimize > 0 @@ -2069,6 +2065,7 @@ scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx) } ctx = new_omp_context (stmt, outer_ctx); + taskreg_contexts.safe_push (ctx); if (taskreg_nesting_level > 1) ctx->is_nested = true; ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0); @@ -2106,8 +2103,71 @@ scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx) t = build_int_cst (long_integer_type_node, 1); gimple_omp_task_set_arg_align (stmt, t); } +} + + +/* If any decls have been made addressable during scan_omp, + adjust their fields if needed, and layout record types + of parallel/task constructs. */ + +static void +finish_taskreg_scan (omp_context *ctx) +{ + if (ctx->record_type == NULL_TREE) + return; + + /* If any task_shared_vars were needed, verify all + OMP_CLAUSE_SHARED clauses on GIMPLE_OMP_{PARALLEL,TASK} + statements if use_pointer_for_field hasn't changed + because of that. If it did, update field types now. */ + if (task_shared_vars) + { + tree c; + + for (c = gimple_omp_taskreg_clauses (ctx->stmt); + c; c = OMP_CLAUSE_CHAIN (c)) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED) + { + tree decl = OMP_CLAUSE_DECL (c); + + /* Global variables don't need to be copied, + the receiver side will use them directly. */ + if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))) + continue; + if (!bitmap_bit_p (task_shared_vars, DECL_UID (decl)) + || !use_pointer_for_field (decl, ctx)) + continue; + tree field = lookup_field (decl, ctx); + if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE + && TREE_TYPE (TREE_TYPE (field)) == TREE_TYPE (decl)) + continue; + TREE_TYPE (field) = build_pointer_type (TREE_TYPE (decl)); + TREE_THIS_VOLATILE (field) = 0; + DECL_USER_ALIGN (field) = 0; + DECL_ALIGN (field) = TYPE_ALIGN (TREE_TYPE (field)); + if (TYPE_ALIGN (ctx->record_type) < DECL_ALIGN (field)) + TYPE_ALIGN (ctx->record_type) = DECL_ALIGN (field); + if (ctx->srecord_type) + { + tree sfield = lookup_sfield (decl, ctx); + TREE_TYPE (sfield) = TREE_TYPE (field); + TREE_THIS_VOLATILE (sfield) = 0; + DECL_USER_ALIGN (sfield) = 0; + DECL_ALIGN (sfield) = DECL_ALIGN (field); + if (TYPE_ALIGN (ctx->srecord_type) < DECL_ALIGN (sfield)) + TYPE_ALIGN (ctx->srecord_type) = DECL_ALIGN (sfield); + } + } + } + + if (gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL) + { + layout_type (ctx->record_type); + fixup_child_record_type (ctx); + } else { + location_t loc = gimple_location (ctx->stmt); tree *p, vla_fields = NULL_TREE, *q = &vla_fields; /* Move VLA fields to the end. */ p = &TYPE_FIELDS (ctx->record_type); @@ -2127,12 +2187,12 @@ scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx) fixup_child_record_type (ctx); if (ctx->srecord_type) layout_type (ctx->srecord_type); - t = fold_convert_loc (loc, long_integer_type_node, - TYPE_SIZE_UNIT (ctx->record_type)); - gimple_omp_task_set_arg_size (stmt, t); + tree t = fold_convert_loc (loc, long_integer_type_node, + TYPE_SIZE_UNIT (ctx->record_type)); + gimple_omp_task_set_arg_size (ctx->stmt, t); t = build_int_cst (long_integer_type_node, TYPE_ALIGN_UNIT (ctx->record_type)); - gimple_omp_task_set_arg_align (stmt, t); + gimple_omp_task_set_arg_align (ctx->stmt, t); } } @@ -10270,6 +10330,8 @@ static unsigned int execute_lower_omp (void) { gimple_seq body; + int i; + omp_context *ctx; /* This pass always runs, to provide PROP_gimple_lomp. But there is nothing to do unless -fopenmp is given. */ @@ -10282,6 +10344,9 @@ execute_lower_omp (void) body = gimple_body (current_function_decl); scan_omp (&body, NULL); gcc_assert (taskreg_nesting_level == 0); + FOR_EACH_VEC_ELT (taskreg_contexts, i, ctx) + finish_taskreg_scan (ctx); + taskreg_contexts.release (); if (all_contexts->root) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 94b915f0222..e83af88c095 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-10-03 Jakub Jelinek <jakub@redhat.com> + + PR libgomp/61200 + * c-c++-common/gomp/pr61200.c: New test. + 2014-10-01 Jakub Jelinek <jakub@redhat.com> PR debug/63342 diff --git a/gcc/testsuite/c-c++-common/gomp/pr61200.c b/gcc/testsuite/c-c++-common/gomp/pr61200.c new file mode 100644 index 00000000000..d0d699dfa0b --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr61200.c @@ -0,0 +1,13 @@ +/* PR libgomp/61200 */ + +int +main () +{ + int var = 1; + #pragma omp parallel + if (var != 1) + __builtin_abort (); + #pragma omp task shared(var) + var = 2; + return 0; +} diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 295800b4ba9..58f83f52b50 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,8 @@ +2014-10-03 Jakub Jelinek <jakub@redhat.com> + + PR libgomp/61200 + * testsuite/libgomp.c/pr61200.c: New test. + 2014-09-18 Jakub Jelinek <jakub@redhat.com> PR c++/63248 diff --git a/libgomp/testsuite/libgomp.c/pr61200.c b/libgomp/testsuite/libgomp.c/pr61200.c new file mode 100644 index 00000000000..ba3ed37e040 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr61200.c @@ -0,0 +1,87 @@ +/* PR libgomp/61200 */ +/* { dg-do run } */ + +#include <omp.h> +#include <stdlib.h> +#include <unistd.h> + +volatile int x; + +void +foo () +{ + int var = 1; + int i; + + for (i = 0; i < 2; i++) + { + if (i == 1) + { + #pragma omp parallel num_threads(2) + if (x) + var++; + else + { + #pragma omp single + sleep (2); + } + } + else + { + #pragma omp task shared(var) + { + sleep (1); + var = 2; + } + } + } + #pragma omp taskwait + if (var != 2) + abort (); +} + +void +bar () +{ + int var = 1; + int i; + + for (i = 0; i < 2; i++) + { + if (i == 0) + { + #pragma omp task shared(var) + { + sleep (1); + var = 2; + } + } + else + { + #pragma omp parallel num_threads(2) + if (x) + var++; + else + { + #pragma omp single + sleep (2); + } + } + } + #pragma omp taskwait + if (var != 2) + abort (); +} + +int +main () +{ + omp_set_nested (1); + #pragma omp parallel num_threads(2) + #pragma omp single + foo (); + #pragma omp parallel num_threads(2) + #pragma omp single + bar (); + return 0; +} |

