aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJulian Brown <julian@codesourcery.com>2019-02-26 15:10:21 -0800
committerKwok Cheung Yeung <kcy@codesourcery.com>2022-06-21 14:11:11 +0100
commitbfe3562fe9cdd1d2091c883d3c489d4b24a30353 (patch)
tree3695be11bc8caadfd02161e5aaf56c50457a21ed /gcc
parent241ee1126178d74c85ff37df8ba72572c9e7d7ae (diff)
downloadgcc-bfe3562fe9cdd1d2091c883d3c489d4b24a30353.zip
gcc-bfe3562fe9cdd1d2091c883d3c489d4b24a30353.tar.gz
gcc-bfe3562fe9cdd1d2091c883d3c489d4b24a30353.tar.bz2
Enable GOMP_MAP_FIRSTPRIVATE_INT for OpenACC
2018-12-22 Cesar Philippidis <cesar@codesourcery.com> Julian Brown <julian@codesourcery.com> Tobias Burnus <tobias@codesourcery.com> gcc/ * omp-low.cc (maybe_lookup_field_in_outer_ctx): New function. (convert_to_firstprivate_int): New function. (convert_from_firstprivate_int): New function. (lower_omp_target): Enable GOMP_MAP_FIRSTPRIVATE_INT in OpenACC. Remove unused variable. libgomp/ * oacc-parallel.c (GOACC_parallel_keyed): Handle GOMP_MAP_FIRSTPRIVATE_INT host addresses. * plugin/plugin-nvptx.c (nvptx_exec): Handle GOMP_MAP_FIRSTPRIVATE_INT host addresses. * testsuite/libgomp.oacc-c++/firstprivate-int.C: New test. * testsuite/libgomp.oacc-c-c++-common/firstprivate-int.c: New test. * testsuite/libgomp.oacc-fortran/firstprivate-int.f90: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog.omp10
-rw-r--r--gcc/omp-low.cc147
2 files changed, 145 insertions, 12 deletions
diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp
index d9ec563..ac03493 100644
--- a/gcc/ChangeLog.omp
+++ b/gcc/ChangeLog.omp
@@ -1,3 +1,13 @@
+2018-12-22 Cesar Philippidis <cesar@codesourcery.com>
+ Julian Brown <julian@codesourcery.com>
+ Tobias Burnus <tobias@codesourcery.com>
+
+ * omp-low.cc (maybe_lookup_field_in_outer_ctx): New function.
+ (convert_to_firstprivate_int): New function.
+ (convert_from_firstprivate_int): New function.
+ (lower_omp_target): Enable GOMP_MAP_FIRSTPRIVATE_INT in OpenACC.
+ Remove unused variable.
+
2018-08-28 Julian Brown <julian@codesourcery.com>
Cesar Philippidis <cesar@codesourcery.com>
diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
index 5dbff93..779cc26 100644
--- a/gcc/omp-low.cc
+++ b/gcc/omp-low.cc
@@ -4729,6 +4729,19 @@ maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
return t ? t : decl;
}
+/* Returns true if DECL is present inside a field that encloses CTX. */
+
+static bool
+maybe_lookup_field_in_outer_ctx (tree decl, omp_context *ctx)
+{
+ omp_context *up;
+
+ for (up = ctx->outer; up; up = up->outer)
+ if (maybe_lookup_field (decl, up))
+ return true;
+
+ return false;
+}
/* Construct the initialization value for reduction operation OP. */
@@ -12868,6 +12881,74 @@ lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
}
}
+/* Helper function for lower_omp_target. Converts VAR to something that can
+ be represented by a POINTER_SIZED_INT_NODE. Any new instructions are
+ appended to GS. This is used to optimize firstprivate variables, so that
+ small types (less precision than POINTER_SIZE) do not require additional
+ data mappings. */
+
+static tree
+convert_to_firstprivate_int (tree var, gimple_seq *gs)
+{
+ tree type = TREE_TYPE (var), new_type = NULL_TREE;
+
+ if (omp_privatize_by_reference (var))
+ {
+ type = TREE_TYPE (type);
+ tree tmp = create_tmp_var (type);
+ gimplify_assign (tmp, build_simple_mem_ref (var), gs);
+ var = tmp;
+ }
+
+ if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
+ return fold_convert (pointer_sized_int_node, var);
+
+ gcc_assert (tree_to_uhwi (TYPE_SIZE (type)) <= POINTER_SIZE);
+
+ new_type = lang_hooks.types.type_for_size (tree_to_uhwi (TYPE_SIZE (type)),
+ true);
+ tree tmp = create_tmp_var (new_type);
+ var = fold_build1 (VIEW_CONVERT_EXPR, new_type, var);
+ gimplify_assign (tmp, var, gs);
+
+ return fold_convert (pointer_sized_int_node, tmp);
+}
+
+/* Like convert_to_firstprivate_int, but restore the original type. */
+
+static tree
+convert_from_firstprivate_int (tree var, bool is_ref, gimple_seq *gs)
+{
+ tree type = TREE_TYPE (var);
+ tree new_type = NULL_TREE;
+ tree tmp = NULL_TREE;
+
+ gcc_assert (TREE_CODE (var) == MEM_REF);
+ var = TREE_OPERAND (var, 0);
+
+ if (INTEGRAL_TYPE_P (var) || POINTER_TYPE_P (type))
+ return fold_convert (type, var);
+
+ gcc_assert (tree_to_uhwi (TYPE_SIZE (type)) <= POINTER_SIZE);
+
+ new_type = lang_hooks.types.type_for_size (tree_to_uhwi (TYPE_SIZE (type)),
+ true);
+
+ tmp = create_tmp_var (new_type);
+ var = fold_convert (new_type, var);
+ gimplify_assign (tmp, var, gs);
+ var = fold_build1 (VIEW_CONVERT_EXPR, type, tmp);
+
+ if (is_ref)
+ {
+ tmp = create_tmp_var (build_pointer_type (type));
+ gimplify_assign (tmp, build_fold_addr_expr (var), gs);
+ var = tmp;
+ }
+
+ return var;
+}
+
/* Lower the GIMPLE_OMP_TARGET in the current statement
in GSI_P. CTX holds context information for the directive. */
@@ -13082,6 +13163,9 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
tree var_type = TREE_TYPE (var);
tree new_var = lookup_decl (var, ctx);
+ tree inner_type
+ = omp_privatize_by_reference (new_var)
+ ? TREE_TYPE (var_type) : var_type;
bool rcv_by_ref =
(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
&& GOMP_MAP_NONCONTIG_ARRAY_P (OMP_CLAUSE_MAP_KIND (c))
@@ -13090,23 +13174,37 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
x = build_receiver_ref (var, rcv_by_ref, ctx);
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
+ && (FLOAT_TYPE_P (inner_type)
+ || ANY_INTEGRAL_TYPE_P (inner_type))
+ && tree_to_uhwi (TYPE_SIZE (inner_type)) <= POINTER_SIZE
+ && !maybe_lookup_field_in_outer_ctx (var, ctx))
+ {
+ gcc_assert (is_gimple_omp_oacc (ctx->stmt));
+ x = convert_from_firstprivate_int (x,
+ omp_privatize_by_reference (var),
+ &fplist);
+ gimplify_assign (new_var, x, &fplist);
+ map_cnt++;
+ break;
+ }
+
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
&& OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
&& !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
- && TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
+ && TREE_CODE (var_type) == ARRAY_TYPE)
x = build_simple_mem_ref (x);
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
{
gcc_assert (is_gimple_omp_oacc (ctx->stmt));
if (omp_privatize_by_reference (new_var)
- && (TREE_CODE (TREE_TYPE (new_var)) != POINTER_TYPE
+ && (TREE_CODE (var_type) != POINTER_TYPE
|| DECL_BY_REFERENCE (var)))
{
/* Create a local object to hold the instance
value. */
- tree type = TREE_TYPE (TREE_TYPE (new_var));
const char *id = IDENTIFIER_POINTER (DECL_NAME (new_var));
- tree inst = create_tmp_var (type, id);
+ tree inst = create_tmp_var (TREE_TYPE (var_type), id);
gimplify_assign (inst, fold_indirect_ref (x), &fplist);
x = build_fold_addr_expr (inst);
}
@@ -13292,6 +13390,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
tree ovar, nc, s, purpose, var, x, type;
unsigned int talign;
+ bool oacc_firstprivate_int;
default:
break;
@@ -13300,6 +13399,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
case OMP_CLAUSE_TO:
case OMP_CLAUSE_FROM:
oacc_firstprivate_map:
+ oacc_firstprivate_int = false;
nc = c;
ovar = OMP_CLAUSE_DECL (c);
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
@@ -13458,8 +13558,23 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
}
else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
{
- gcc_assert (is_gimple_omp_oacc (ctx->stmt));
- if (!omp_privatize_by_reference (var))
+ gcc_checking_assert (is_gimple_omp_oacc (ctx->stmt));
+ tree type = TREE_TYPE (var);
+ tree inner_type
+ = omp_privatize_by_reference (var)
+ ? TREE_TYPE (type) : type;
+ if ((FLOAT_TYPE_P (inner_type)
+ || ANY_INTEGRAL_TYPE_P (inner_type))
+ && tree_to_uhwi (TYPE_SIZE (inner_type)) <= POINTER_SIZE
+ && !maybe_lookup_field_in_outer_ctx (var, ctx))
+ {
+ oacc_firstprivate_int = true;
+ if (is_gimple_reg (var)
+ && OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
+ TREE_NO_WARNING (var) = 1;
+ var = convert_to_firstprivate_int (var, &ilist);
+ }
+ else if (!omp_privatize_by_reference (var))
{
if (is_gimple_reg (var)
&& OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
@@ -13522,11 +13637,16 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
{
gcc_checking_assert (is_gimple_omp_oacc (ctx->stmt));
- s = TREE_TYPE (ovar);
- if (TREE_CODE (s) == REFERENCE_TYPE
- || omp_check_optional_argument (ovar, false))
- s = TREE_TYPE (s);
- s = TYPE_SIZE_UNIT (s);
+ if (oacc_firstprivate_int)
+ s = size_int (0);
+ else
+ {
+ s = TREE_TYPE (ovar);
+ if (TREE_CODE (s) == REFERENCE_TYPE
+ || omp_check_optional_argument (ovar, false))
+ s = TREE_TYPE (s);
+ s = TYPE_SIZE_UNIT (s);
+ }
}
else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
&& GOMP_MAP_NONCONTIG_ARRAY_P (OMP_CLAUSE_MAP_KIND (c)))
@@ -13593,7 +13713,10 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
break;
case OMP_CLAUSE_FIRSTPRIVATE:
gcc_checking_assert (is_gimple_omp_oacc (ctx->stmt));
- tkind = GOMP_MAP_TO;
+ if (oacc_firstprivate_int)
+ tkind = GOMP_MAP_FIRSTPRIVATE_INT;
+ else
+ tkind = GOMP_MAP_TO;
tkind_zero = tkind;
break;
case OMP_CLAUSE_TO: