aboutsummaryrefslogtreecommitdiff
path: root/gcc/omp-expand.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/omp-expand.cc')
-rw-r--r--gcc/omp-expand.cc85
1 files changed, 81 insertions, 4 deletions
diff --git a/gcc/omp-expand.cc b/gcc/omp-expand.cc
index 648ede2..48f57cb 100644
--- a/gcc/omp-expand.cc
+++ b/gcc/omp-expand.cc
@@ -1079,11 +1079,16 @@ remove_exit_barrier (struct omp_region *region)
from within current function (this would be easy to check)
or from some function it calls and gets passed an address
of such a variable. */
+ gomp_parallel *parallel_stmt
+ = as_a <gomp_parallel *> (last_nondebug_stmt (region->entry));
+ tree child_fun = gimple_omp_parallel_child_fn (parallel_stmt);
+
+ if (flag_openmp_target == OMP_TARGET_MODE_OMPACC
+ && child_fun == NULL_TREE)
+ any_addressable_vars = 0;
+
if (any_addressable_vars < 0)
{
- gomp_parallel *parallel_stmt
- = as_a <gomp_parallel *> (last_nondebug_stmt (region->entry));
- tree child_fun = gimple_omp_parallel_child_fn (parallel_stmt);
tree local_decls, block, decl;
unsigned ix;
@@ -7768,6 +7773,17 @@ expand_oacc_for (struct omp_region *region, struct omp_for_data *fd)
/* The SSA parallelizer does gang parallelism. */
gwv = build_int_cst (integer_type_node, GOMP_DIM_MASK (GOMP_DIM_GANG));
}
+ else if (flag_openmp_target == OMP_TARGET_MODE_OMPACC)
+ {
+ tree clauses = gimple_omp_for_clauses (for_stmt);
+ int omp_mask = 0;
+ if (omp_find_clause (clauses, OMP_CLAUSE_GANG))
+ omp_mask |= GOMP_DIM_MASK (GOMP_DIM_GANG);
+ if (omp_find_clause (clauses, OMP_CLAUSE_VECTOR))
+ omp_mask |= GOMP_DIM_MASK (GOMP_DIM_VECTOR);
+ gcc_assert (omp_mask);
+ gwv = build_int_cst (integer_type_node, omp_mask);
+ }
if (fd->collapse > 1 || fd->tiling)
{
@@ -7814,7 +7830,10 @@ expand_oacc_for (struct omp_region *region, struct omp_for_data *fd)
tile_size = create_tmp_var (diff_type, ".tile_size");
expr = build_int_cst (diff_type, 1);
for (int ix = 0; ix < fd->collapse; ix++)
- expr = fold_build2 (MULT_EXPR, diff_type, counts[ix].tile, expr);
+ {
+ tree tile = fold_convert (diff_type, counts[ix].tile);
+ expr = fold_build2 (MULT_EXPR, diff_type, tile, expr);
+ }
expr = force_gimple_operand_gsi (&gsi, expr, true,
NULL_TREE, true, GSI_SAME_STMT);
ass = gimple_build_assign (tile_size, expr);
@@ -9792,6 +9811,13 @@ get_target_arguments (gimple_stmt_iterator *gsi, gomp_target *tgt_stmt)
t = OMP_CLAUSE_THREAD_LIMIT_EXPR (c);
else
t = integer_minus_one_node;
+
+ /* Currently, OMPACC mode has a limitation of only one warp thread. */
+ if (flag_openmp_target == OMP_TARGET_MODE_OMPACC
+ && lookup_attribute
+ ("ompacc", DECL_ATTRIBUTES (gimple_omp_target_child_fn (tgt_stmt))))
+ t = integer_one_node;
+
push_target_argument_according_to_value (gsi, GOMP_TARGET_ARG_DEVICE_ALL,
GOMP_TARGET_ARG_THREAD_LIMIT, t,
&args);
@@ -10633,6 +10659,19 @@ expand_omp_target (struct omp_region *region)
gsi_insert_before (&gsi, g, GSI_SAME_STMT);
}
+ /* We assume index >= 3 in gimple_omp_target_data_arg are non-contiguous
+ array descriptor pointer arguments. */
+ if (t != NULL
+ && TREE_VEC_LENGTH (t) > 3
+ && (start_ix == BUILT_IN_GOACC_DATA_START
+ || start_ix == BUILT_IN_GOACC_PARALLEL))
+ {
+ gcc_assert ((c = omp_find_clause (clauses, OMP_CLAUSE_MAP))
+ && GOMP_MAP_NONCONTIG_ARRAY_P (OMP_CLAUSE_MAP_KIND (c)));
+ for (int i = 3; i < TREE_VEC_LENGTH (t); i++)
+ args.safe_push (TREE_VEC_ELT (t, i));
+ }
+
g = gimple_build_call_vec (builtin_decl_explicit (start_ix), args);
gimple_set_location (g, gimple_location (entry_stmt));
gsi_insert_before (&gsi, g, GSI_SAME_STMT);
@@ -10678,6 +10717,44 @@ expand_omp (struct omp_region *region)
switch (region->type)
{
case GIMPLE_OMP_PARALLEL:
+ if (flag_openmp_target == OMP_TARGET_MODE_OMPACC)
+ {
+ struct omp_region *r;
+ for (r = region->outer; r; r = r->outer)
+ if (r->type == GIMPLE_OMP_TARGET)
+ {
+ gomp_target *tgt
+ = as_a <gomp_target *> (last_nondebug_stmt (r->entry));
+ tree tgtfn_attrs
+ = DECL_ATTRIBUTES (gimple_omp_target_child_fn (tgt));
+ if (!lookup_attribute ("ompacc", tgtfn_attrs))
+ r = NULL;
+ break;
+ }
+ if (r != NULL
+ || (lookup_attribute
+ ("ompacc", DECL_ATTRIBUTES (current_function_decl))))
+ {
+ gimple_stmt_iterator gsi;
+ gsi = gsi_last_nondebug_bb (region->entry);
+ gcc_assert (!gsi_end_p (gsi)
+ && gimple_code
+ (gsi_stmt (gsi)) == GIMPLE_OMP_PARALLEL);
+ gsi_remove (&gsi, true);
+
+ if (region->exit)
+ {
+ gsi = gsi_last_nondebug_bb (region->exit);
+ gcc_assert (!gsi_end_p (gsi)
+ && gimple_code
+ (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
+ gsi_remove (&gsi, true);
+ }
+ break;
+ }
+ }
+ /* Fallthrough. */
+
case GIMPLE_OMP_TASK:
expand_omp_taskreg (region);
break;