diff options
Diffstat (limited to 'gcc/omp-expand.cc')
-rw-r--r-- | gcc/omp-expand.cc | 85 |
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; |