diff options
-rw-r--r-- | gcc/cp/cp-gimplify.c | 64 | ||||
-rw-r--r-- | gcc/gimplify.c | 56 | ||||
-rw-r--r-- | gcc/omp-general.c | 56 | ||||
-rw-r--r-- | gcc/omp-general.h | 1 |
4 files changed, 120 insertions, 57 deletions
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index b60a319283f..53d715dcd89 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see #include "output.h" #include "file-prefix-map.h" #include "cgraph.h" +#include "omp-general.h" /* Forward declarations. */ @@ -1650,9 +1651,70 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) *stmt_p = genericize_spaceship (*stmt_p); break; + case OMP_DISTRIBUTE: + /* Need to explicitly instantiate copy ctors on class iterators of + composite distribute parallel for. */ + if (OMP_FOR_INIT (*stmt_p) == NULL_TREE) + { + tree *data[4] = { NULL, NULL, NULL, NULL }; + tree inner = walk_tree (&OMP_FOR_BODY (*stmt_p), + find_combined_omp_for, data, NULL); + if (inner != NULL_TREE + && TREE_CODE (inner) == OMP_FOR) + { + for (int i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner)); i++) + if (OMP_FOR_ORIG_DECLS (inner) + && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner), + i)) == TREE_LIST + && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner), + i))) + { + tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner), i); + /* Class iterators aren't allowed on OMP_SIMD, so the only + case we need to solve is distribute parallel for. */ + gcc_assert (TREE_CODE (inner) == OMP_FOR + && data[1]); + tree orig_decl = TREE_PURPOSE (orig); + tree c, cl = NULL_TREE; + for (c = OMP_FOR_CLAUSES (inner); + c; c = OMP_CLAUSE_CHAIN (c)) + if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE) + && OMP_CLAUSE_DECL (c) == orig_decl) + { + cl = c; + break; + } + if (cl == NULL_TREE) + { + for (c = OMP_PARALLEL_CLAUSES (*data[1]); + c; c = OMP_CLAUSE_CHAIN (c)) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE + && OMP_CLAUSE_DECL (c) == orig_decl) + { + cl = c; + break; + } + } + if (cl) + { + orig_decl = require_complete_type (orig_decl); + tree inner_type = TREE_TYPE (orig_decl); + if (orig_decl == error_mark_node) + continue; + if (TYPE_REF_P (TREE_TYPE (orig_decl))) + inner_type = TREE_TYPE (inner_type); + + while (TREE_CODE (inner_type) == ARRAY_TYPE) + inner_type = TREE_TYPE (inner_type); + get_copy_ctor (inner_type, tf_warning_or_error); + } + } + } + } + /* FALLTHRU */ case OMP_FOR: case OMP_SIMD: - case OMP_DISTRIBUTE: case OMP_LOOP: case OACC_LOOP: genericize_omp_for_stmt (stmt_p, walk_subtrees, data); diff --git a/gcc/gimplify.c b/gcc/gimplify.c index e104e766517..7f00d97baa1 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -10963,62 +10963,6 @@ gimplify_omp_task (tree *expr_p, gimple_seq *pre_p) *expr_p = NULL_TREE; } -/* Helper function of gimplify_omp_for, find OMP_FOR resp. OMP_SIMD - with non-NULL OMP_FOR_INIT. Also, fill in pdata array, - pdata[0] non-NULL if there is anything non-trivial in between, pdata[1] - is address of OMP_PARALLEL in between if any, pdata[2] is address of - OMP_FOR in between if any and pdata[3] is address of the inner - OMP_FOR/OMP_SIMD. */ - -static tree -find_combined_omp_for (tree *tp, int *walk_subtrees, void *data) -{ - tree **pdata = (tree **) data; - *walk_subtrees = 0; - switch (TREE_CODE (*tp)) - { - case OMP_FOR: - if (OMP_FOR_INIT (*tp) != NULL_TREE) - { - pdata[3] = tp; - return *tp; - } - pdata[2] = tp; - *walk_subtrees = 1; - break; - case OMP_SIMD: - if (OMP_FOR_INIT (*tp) != NULL_TREE) - { - pdata[3] = tp; - return *tp; - } - break; - case BIND_EXPR: - if (BIND_EXPR_VARS (*tp) - || (BIND_EXPR_BLOCK (*tp) - && BLOCK_VARS (BIND_EXPR_BLOCK (*tp)))) - pdata[0] = tp; - *walk_subtrees = 1; - break; - case STATEMENT_LIST: - if (!tsi_one_before_end_p (tsi_start (*tp))) - pdata[0] = tp; - *walk_subtrees = 1; - break; - case TRY_FINALLY_EXPR: - pdata[0] = tp; - *walk_subtrees = 1; - break; - case OMP_PARALLEL: - pdata[1] = tp; - *walk_subtrees = 1; - break; - default: - break; - } - return NULL_TREE; -} - /* Gimplify the gross structure of an OMP_FOR statement. */ static enum gimplify_status diff --git a/gcc/omp-general.c b/gcc/omp-general.c index 315f24aeddf..1a2e71ecf8c 100644 --- a/gcc/omp-general.c +++ b/gcc/omp-general.c @@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see #include "hsa-common.h" #include "tree-pass.h" #include "omp-device-properties.h" +#include "tree-iterator.h" enum omp_requires omp_requires_mask; @@ -504,6 +505,61 @@ omp_build_barrier (tree lhs) return g; } +/* Find OMP_FOR resp. OMP_SIMD with non-NULL OMP_FOR_INIT. Also, fill in pdata + array, pdata[0] non-NULL if there is anything non-trivial in between, + pdata[1] is address of OMP_PARALLEL in between if any, pdata[2] is address + of OMP_FOR in between if any and pdata[3] is address of the inner + OMP_FOR/OMP_SIMD. */ + +tree +find_combined_omp_for (tree *tp, int *walk_subtrees, void *data) +{ + tree **pdata = (tree **) data; + *walk_subtrees = 0; + switch (TREE_CODE (*tp)) + { + case OMP_FOR: + if (OMP_FOR_INIT (*tp) != NULL_TREE) + { + pdata[3] = tp; + return *tp; + } + pdata[2] = tp; + *walk_subtrees = 1; + break; + case OMP_SIMD: + if (OMP_FOR_INIT (*tp) != NULL_TREE) + { + pdata[3] = tp; + return *tp; + } + break; + case BIND_EXPR: + if (BIND_EXPR_VARS (*tp) + || (BIND_EXPR_BLOCK (*tp) + && BLOCK_VARS (BIND_EXPR_BLOCK (*tp)))) + pdata[0] = tp; + *walk_subtrees = 1; + break; + case STATEMENT_LIST: + if (!tsi_one_before_end_p (tsi_start (*tp))) + pdata[0] = tp; + *walk_subtrees = 1; + break; + case TRY_FINALLY_EXPR: + pdata[0] = tp; + *walk_subtrees = 1; + break; + case OMP_PARALLEL: + pdata[1] = tp; + *walk_subtrees = 1; + break; + default: + break; + } + return NULL_TREE; +} + /* Return maximum possible vectorization factor for the target. */ poly_uint64 diff --git a/gcc/omp-general.h b/gcc/omp-general.h index f4cc302e5b9..ad28b2b7970 100644 --- a/gcc/omp-general.h +++ b/gcc/omp-general.h @@ -82,6 +82,7 @@ extern tree omp_get_for_step_from_incr (location_t loc, tree incr); extern void omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd, struct omp_for_data_loop *loops); extern gimple *omp_build_barrier (tree lhs); +extern tree find_combined_omp_for (tree *, int *, void *); extern poly_uint64 omp_max_vf (void); extern int omp_max_simt_vf (void); extern int omp_constructor_traits_to_codes (tree, enum tree_code *); |