summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/cp-gimplify.c64
-rw-r--r--gcc/gimplify.c56
-rw-r--r--gcc/omp-general.c56
-rw-r--r--gcc/omp-general.h1
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 *);