The GCN backend uses tree nodes like MEM((__lds TYPE *) <constant>) for reduction temporaries. Unlike e.g. var decls and SSA names, these nodes cannot be shared during gimplification, but are so in some circumstances. This is detected when appropriate --enable-checking options are used. This patch unshares such nodes when they are reused more than once.
Tested with offloading to AMD GCN. I will apply shortly. Thanks, Julian 2020-07-30 Julian Brown <jul...@codesourcery.com> gcc/ * config/gcn/gcn-tree.c (gcn_goacc_get_worker_red_decl): Do not cache/share decls for reduction temporaries between invocations. (gcn_goacc_reduction_teardown): Unshare VAR on second use. * config/gcn/gcn.c (gcn_init_machine_status): Do not initialise reduc_decls. * config/gcn/gcn.h (machine_function): Remove reduc_decls cache. --- gcc/ChangeLog.omp | 9 +++++++++ gcc/config/gcn/gcn-tree.c | 30 ++++++------------------------ gcc/config/gcn/gcn.c | 3 --- gcc/config/gcn/gcn.h | 1 - 4 files changed, 15 insertions(+), 28 deletions(-) diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp index 12b8c044a1b1..34622a3bfa1b 100644 --- a/gcc/ChangeLog.omp +++ b/gcc/ChangeLog.omp @@ -1,3 +1,12 @@ +2020-07-30 Julian Brown <jul...@codesourcery.com> + + * config/gcn/gcn-tree.c (gcn_goacc_get_worker_red_decl): Do not + cache/share decls for reduction temporaries between invocations. + (gcn_goacc_reduction_teardown): Unshare VAR on second use. + * config/gcn/gcn.c (gcn_init_machine_status): Do not initialise + reduc_decls. + * config/gcn/gcn.h (machine_function): Remove reduc_decls cache. + 2020-07-30 Julian Brown <jul...@codesourcery.com> * config/gcn/gcn-tree.c (gcn_goacc_reduction_teardown): Remove useless diff --git a/gcc/config/gcn/gcn-tree.c b/gcc/config/gcn/gcn-tree.c index bfde71555d8a..96fdf75a8cd9 100644 --- a/gcc/config/gcn/gcn-tree.c +++ b/gcc/config/gcn/gcn-tree.c @@ -429,7 +429,6 @@ static tree gcn_goacc_get_worker_red_decl (tree type, unsigned offset) { machine_function *machfun = cfun->machine; - tree existing_decl; if (TREE_CODE (type) == REFERENCE_TYPE) type = TREE_TYPE (type); @@ -439,29 +438,12 @@ gcn_goacc_get_worker_red_decl (tree type, unsigned offset) (TYPE_QUALS (type) | ENCODE_QUAL_ADDR_SPACE (ADDR_SPACE_LDS))); - if (machfun->reduc_decls - && offset < machfun->reduc_decls->length () - && (existing_decl = (*machfun->reduc_decls)[offset])) - { - gcc_assert (TREE_TYPE (existing_decl) == var_type); - return existing_decl; - } - else - { - gcc_assert (offset - < (machfun->reduction_limit - machfun->reduction_base)); - tree ptr_type = build_pointer_type (var_type); - tree addr = build_int_cst (ptr_type, machfun->reduction_base + offset); - - tree decl = build_simple_mem_ref (addr); + gcc_assert (offset + < (machfun->reduction_limit - machfun->reduction_base)); + tree ptr_type = build_pointer_type (var_type); + tree addr = build_int_cst (ptr_type, machfun->reduction_base + offset); - vec_safe_grow_cleared (machfun->reduc_decls, offset + 1); - (*machfun->reduc_decls)[offset] = decl; - - return decl; - } - - return NULL_TREE; + return build_simple_mem_ref (addr); } /* Expand IFN_GOACC_REDUCTION_SETUP. */ @@ -616,7 +598,7 @@ gcn_goacc_reduction_teardown (gcall *call) } if (lhs) - gimplify_assign (lhs, var, &seq); + gimplify_assign (lhs, unshare_expr (var), &seq); pop_gimplify_context (NULL); diff --git a/gcc/config/gcn/gcn.c b/gcc/config/gcn/gcn.c index 4b2df3c7df06..028e5c577c07 100644 --- a/gcc/config/gcn/gcn.c +++ b/gcc/config/gcn/gcn.c @@ -106,9 +106,6 @@ gcn_init_machine_status (void) f = ggc_cleared_alloc<machine_function> (); - /* And LDS temporary decls for worker reductions. */ - vec_alloc (f->reduc_decls, 0); - if (TARGET_GCN3) f->use_flat_addressing = true; diff --git a/gcc/config/gcn/gcn.h b/gcc/config/gcn/gcn.h index 91b3d88c062a..06475f59ad79 100644 --- a/gcc/config/gcn/gcn.h +++ b/gcc/config/gcn/gcn.h @@ -573,7 +573,6 @@ struct GTY(()) machine_function unsigned HOST_WIDE_INT reduction_base; unsigned HOST_WIDE_INT reduction_limit; - vec<tree, va_gc> *reduc_decls; bool use_flat_addressing; }; -- 2.23.0