public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Bernd Edlinger <bernd.edlinger@hotmail.de>
To: Julian Brown <julian@codesourcery.com>, gcc-patches@gcc.gnu.org
Cc: Jakub Jelinek <jakub@redhat.com>,
	Tobias Burnus <tobias@codesourcery.com>,
	Chung-Lin Tang <cltang@codesourcery.com>,
	Thomas Schwinge <thomas@codesourcery.com>,
	fortran@gcc.gnu.org
Subject: Re: [PATCH 4/5] Rework indirect struct handling for OpenACC/OpenMP in gimplify.c
Date: Mon, 17 May 2021 14:12:00 +0200	[thread overview]
Message-ID: <AM8PR10MB470875A817A42095E6397469E42D9@AM8PR10MB4708.EURPRD10.PROD.OUTLOOK.COM> (raw)
In-Reply-To: <d158d1e24695cf9338df488e36822e23ec7813f4.1621026372.git.julian@codesourcery.com>

On 5/14/21 11:26 PM, Julian Brown wrote:
> This patch reworks indirect struct handling in gimplify.c (i.e. for struct
> components mapped with "mystruct->a[0:n]", "mystruct->b", etc.), for
> both OpenACC and OpenMP.  The key observation leading to these changes
> was that component mappings of references-to-structures is already
> implemented and working, and indirect struct component handling via a
> pointer can work quite similarly.  That lets us remove some earlier,
> special-case handling for mapping indirect struct component accesses
> for OpenACC, which required the pointed-to struct to be manually mapped
> before the indirect component mapping.
> 
> With this patch, you can map struct components directly (e.g. an array
> slice "mystruct->a[0:n]") just like you can map a non-indirect struct
> component slice ("mystruct.a[0:n]"). Both references-to-pointers (with
> the former syntax) and references to structs (with the latter syntax)
> work now.
> 
> For Fortran class pointers, we no longer re-use GOMP_MAP_TO_PSET for the
> class metadata (the structure that points to the class data and vptr)
> -- it is instead treated as any other struct.
> 
> For C++, the struct handling also works for class members ("this->foo"),
> without having to explicitly map "this[:1]" first.
> 
> For OpenACC, we permit chained indirect component references
> ("mystruct->a->b[0:n]"), though only the last part of such mappings will
> trigger an attach/detach operation.  To properly use such a construct
> on the target, you must still manually map "mystruct->a[:1]" first --
> but there's no need to map "mystruct[:1]" explicitly before that.
> 
> This patch incorporates parts of Chung-Lin's patch "Recommit "Enable
> gimplify GOMP_MAP_STRUCT handling of (COMPONENT_REF (INDIRECT_REF
> ...)) map clauses"." from the og10 branch.
> 
> OK for trunk?
> 
> Thanks,
> 
> Julian
> 
> 2021-05-14  Julian Brown  <julian@codesourcery.com>
> 	    Chung-Lin Tang  <cltang@codesourcery.com>
> 
> gcc/fortran/
> 	* trans-openmp.c (gfc_trans_omp_clauses): Don't create GOMP_MAP_TO_PSET
> 	mappings for class metadata, nor GOMP_MAP_POINTER mappings for
> 	POINTER_TYPE_P decls.
> 
> gcc/
> 	* gimplify.c (tree-hash-traits.h): Include.
> 	(extract_base_bit_offset): Add BASE_IND parameter.  Handle
> 	pointer-typed indirect references alongside reference-typed ones.
> 	(strip_components_and_deref, aggregate_base_p): New functions.
> 	(build_struct_group): Update struct_map_to_clause type.  Add pointer
> 	type indirect ref handling, including chained references.  Handle
> 	pointers and references to structs in OpenACC regions as well as
> 	OpenMP ones.
> 	(gimplify_scan_omp_clauses): Remove struct_deref_set handling.  Rework
> 	pointer-type indirect structure access handling to work more like
> 	the reference-typed handling.
> 	* omp-low.c (scan_sharing_clauses): Handle pointer-type indirect struct
> 	references, and references to pointers to structs also.
> 
> gcc/testsuite/
> 	* g++.dg/goacc/member-array-acc.C: New test (XFAILed for now).
> 	* g++.dg/gomp/member-array-omp.C: New test (XFAILed for now).
> 
> libgomp/
> 	* testsuite/libgomp.oacc-c-c++-common/deep-copy-15.c: New test.
> 	* testsuite/libgomp.oacc-c-c++-common/deep-copy-16.c: New test.
> 	* testsuite/libgomp.oacc-c++/deep-copy-17.C: New test.
> ---
>  gcc/fortran/trans-openmp.c                    |  20 +-
>  gcc/gimplify.c                                | 285 ++++++++++--------
>  gcc/omp-low.c                                 |  16 +-
>  gcc/testsuite/g++.dg/goacc/member-array-acc.C |  14 +
>  gcc/testsuite/g++.dg/gomp/member-array-omp.C  |  14 +
>  .../testsuite/libgomp.oacc-c++/deep-copy-17.C | 101 +++++++
>  .../libgomp.oacc-c-c++-common/deep-copy-15.c  |  71 +++++
>  .../libgomp.oacc-c-c++-common/deep-copy-16.c  | 231 ++++++++++++++
>  8 files changed, 612 insertions(+), 140 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/goacc/member-array-acc.C
>  create mode 100644 gcc/testsuite/g++.dg/gomp/member-array-omp.C
>  create mode 100644 libgomp/testsuite/libgomp.oacc-c++/deep-copy-17.C
>  create mode 100644 libgomp/testsuite/libgomp.oacc-c-c++-common/deep-copy-15.c
>  create mode 100644 libgomp/testsuite/libgomp.oacc-c-c++-common/deep-copy-16.c
> 
> diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
> index 5666cd68c7e..ff614ffe744 100644
> --- a/gcc/fortran/trans-openmp.c
> +++ b/gcc/fortran/trans-openmp.c
> @@ -2721,30 +2721,16 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
>  		  tree present = gfc_omp_check_optional_argument (decl, true);
>  		  if (openacc && n->sym->ts.type == BT_CLASS)
>  		    {
> -		      tree type = TREE_TYPE (decl);
>  		      if (n->sym->attr.optional)
>  			sorry ("optional class parameter");
> -		      if (POINTER_TYPE_P (type))
> -			{
> -			  node4 = build_omp_clause (input_location,
> -						    OMP_CLAUSE_MAP);
> -			  OMP_CLAUSE_SET_MAP_KIND (node4, GOMP_MAP_POINTER);
> -			  OMP_CLAUSE_DECL (node4) = decl;
> -			  OMP_CLAUSE_SIZE (node4) = size_int (0);
> -			  decl = build_fold_indirect_ref (decl);
> -			}
>  		      tree ptr = gfc_class_data_get (decl);
>  		      ptr = build_fold_indirect_ref (ptr);
>  		      OMP_CLAUSE_DECL (node) = ptr;
>  		      OMP_CLAUSE_SIZE (node) = gfc_class_vtab_size_get (decl);
>  		      node2 = build_omp_clause (input_location, OMP_CLAUSE_MAP);
> -		      OMP_CLAUSE_SET_MAP_KIND (node2, GOMP_MAP_TO_PSET);
> -		      OMP_CLAUSE_DECL (node2) = decl;
> -		      OMP_CLAUSE_SIZE (node2) = TYPE_SIZE_UNIT (type);
> -		      node3 = build_omp_clause (input_location, OMP_CLAUSE_MAP);
> -		      OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_ATTACH_DETACH);
> -		      OMP_CLAUSE_DECL (node3) = gfc_class_data_get (decl);
> -		      OMP_CLAUSE_SIZE (node3) = size_int (0);
> +		      OMP_CLAUSE_SET_MAP_KIND (node2, GOMP_MAP_ATTACH_DETACH);
> +		      OMP_CLAUSE_DECL (node2) = gfc_class_data_get (decl);
> +		      OMP_CLAUSE_SIZE (node2) = size_int (0);
>  		      goto finalize_map_clause;
>  		    }
>  		  else if (POINTER_TYPE_P (TREE_TYPE (decl))
> diff --git a/gcc/gimplify.c b/gcc/gimplify.c
> index 69ab637367c..c0f068a725d 100644
> --- a/gcc/gimplify.c
> +++ b/gcc/gimplify.c
> @@ -53,6 +53,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "langhooks.h"
>  #include "tree-cfg.h"
>  #include "tree-ssa.h"
> +#include "tree-hash-traits.h"
>  #include "omp-general.h"
>  #include "omp-low.h"
>  #include "gimple-low.h"
> @@ -8351,8 +8352,8 @@ build_struct_comp_nodes (enum tree_code code, tree grp_start, tree grp_end,
>     has array type, else return NULL.  */
>  
>  static tree
> -extract_base_bit_offset (tree base, tree *base_ref, poly_int64 *bitposp,
> -			 poly_offset_int *poffsetp)
> +extract_base_bit_offset (tree base, tree *base_ind, tree *base_ref,
> +			 poly_int64 *bitposp, poly_offset_int *poffsetp)
>  {
>    tree offset;
>    poly_int64 bitsize, bitpos;
> @@ -8360,6 +8361,9 @@ extract_base_bit_offset (tree base, tree *base_ref, poly_int64 *bitposp,
>    int unsignedp, reversep, volatilep = 0;
>    poly_offset_int poffset;
>  
> +  if (base_ind)
> +    *base_ind = NULL_TREE;
> +
>    if (base_ref)
>      *base_ref = NULL_TREE;
>  
> @@ -8380,14 +8384,27 @@ extract_base_bit_offset (tree base, tree *base_ref, poly_int64 *bitposp,
>    base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
>  			      &unsignedp, &reversep, &volatilep);
>  
> -  tree orig_base = base;
> -
> +  if ((TREE_CODE (base) == INDIRECT_REF
> +       || (TREE_CODE (base) == MEM_REF
> +	   && integer_zerop (TREE_OPERAND (base, 1))))
> +      && TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0))) == POINTER_TYPE)
> +    {
> +      if (base_ind)
> +	*base_ind = base;
> +      base = TREE_OPERAND (base, 0);
> +    }
>    if ((TREE_CODE (base) == INDIRECT_REF
>         || (TREE_CODE (base) == MEM_REF
>  	   && integer_zerop (TREE_OPERAND (base, 1))))
>        && DECL_P (TREE_OPERAND (base, 0))
>        && TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0))) == REFERENCE_TYPE)
> -    base = TREE_OPERAND (base, 0);
> +    {
> +      if (base_ref)
> +	*base_ref = base;
> +      base = TREE_OPERAND (base, 0);
> +    }
> +
> +  STRIP_NOPS (base);
>  
>    gcc_assert (offset == NULL_TREE || poly_int_tree_p (offset));
>  
> @@ -8402,10 +8419,6 @@ extract_base_bit_offset (tree base, tree *base_ref, poly_int64 *bitposp,
>    *bitposp = bitpos;
>    *poffsetp = poffset;
>  
> -  /* Set *BASE_REF if BASE was a dereferenced reference variable.  */
> -  if (base_ref && orig_base != base)
> -    *base_ref = orig_base;
> -
>    return base;
>  }
>  
> @@ -8422,6 +8435,48 @@ is_or_contains_p (tree expr, tree base_ptr)
>    return expr == base_ptr;
>  }
>  
> +/* Remove COMPONENT_REFS and indirections from EXPR.  */
> +
> +static tree
> +strip_components_and_deref (tree expr)
> +{
> +  while (TREE_CODE (expr) == COMPONENT_REF
> +	 || TREE_CODE (expr) == INDIRECT_REF
> +	 || (TREE_CODE (expr) == MEM_REF
> +	     && integer_zerop (TREE_OPERAND (expr, 1))))
> +    expr = TREE_OPERAND (expr, 0);
> +
> +  return expr;
> +}
> +
> +/* Return TRUE if EXPR is something we will use as the base of an aggregate
> +   access, either:
> +
> +  - a DECL_P.
> +  - a struct component with no indirection ("a.b.c").
> +  - a struct component with indirection ("a->b->c").
> +*/
> +
> +static bool
> +aggregate_base_p (tree expr)
> +{
> +  while (TREE_CODE (expr) == COMPONENT_REF
> +	 && (DECL_P (TREE_OPERAND (expr, 0))
> +	     || (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPONENT_REF)))
> +    expr = TREE_OPERAND (expr, 0);
> +
> +  if (DECL_P (expr))
> +    return true;
> +
> +  if (TREE_CODE (expr) == COMPONENT_REF
> +      && (TREE_CODE (TREE_OPERAND (expr, 0)) == INDIRECT_REF
> +	  || (TREE_CODE (TREE_OPERAND (expr, 0)) == MEM_REF
> +	      && integer_zerop (TREE_OPERAND (TREE_OPERAND (expr, 0), 1)))))
> +    return true;
> +
> +  return false;
> +}
> +
>  /* Implement OpenMP 5.x map ordering rules for target directives. There are
>     several rules, and with some level of ambiguity, hopefully we can at least
>     collect the complexity here in one place.  */
> @@ -8715,19 +8770,26 @@ static tree
>  build_struct_group (struct gimplify_omp_ctx *ctx,
>  		    enum omp_region_type region_type, enum tree_code code,
>  		    tree decl, unsigned int *flags, tree c,
> -		    hash_map<tree, tree> *&struct_map_to_clause,
> +		    hash_map<tree_operand_hash, tree> *&struct_map_to_clause,
>  		    tree *&prev_list_p, tree *&list_p, bool *cont)
>  {
>    poly_offset_int coffset;
>    poly_int64 cbitpos;
> -  tree base_ref;
> +  tree base_ind, base_ref;
> +  tree *list_in_p = list_p, *prev_list_in_p = prev_list_p;
>  

Is this a kind of debug code?
This fails to compile:

../../gcc-trunk/gcc/gimplify.c: In function ‘tree_node* build_struct_group(gimplify_omp_ctx*, omp_region_type, tree_code, tree, unsigned int*, tree, hash_map<tree_operand_hash, tree_node*>*&, tree_node**&, tree_node**&, bool*)’:
../../gcc-trunk/gcc/gimplify.c:8779:9: error: unused variable ‘list_in_p’ [-Werror=unused-variable]
 8779 |   tree *list_in_p = list_p, *prev_list_in_p = prev_list_p;
      |         ^~~~~~~~~
../../gcc-trunk/gcc/gimplify.c:8779:30: error: unused variable ‘prev_list_in_p’ [-Werror=unused-variable]
 8779 |   tree *list_in_p = list_p, *prev_list_in_p = prev_list_p;
      |                              ^~~~~~~~~~~~~~


You need to boot-strap and do your regression testing before sending
a patch to this list.


Thanks
Bernd.

  reply	other threads:[~2021-05-17 12:12 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-14 21:26 [PATCH 0/5] OpenACC/OpenMP: Rework struct component handling Julian Brown
2021-05-14 21:26 ` [PATCH 1/5] Unify ARRAY_REF/INDIRECT_REF stripping code in extract_base_bit_offset Julian Brown
2021-05-14 21:26 ` [PATCH 2/5] Refactor struct lowering for OpenMP/OpenACC in gimplify.c Julian Brown
2021-05-14 21:26 ` [PATCH 3/5] Rewrite GOMP_MAP_ATTACH_DETACH mappings for OpenMP also Julian Brown
2021-05-14 21:26 ` [PATCH 4/5] Rework indirect struct handling for OpenACC/OpenMP in gimplify.c Julian Brown
2021-05-17 12:12   ` Bernd Edlinger [this message]
2021-05-17 14:10     ` Julian Brown
2021-05-14 21:27 ` [PATCH 5/5] Mapping of components of references to pointers to structs for OpenMP/OpenACC Julian Brown
2021-05-17 13:07   ` Chung-Lin Tang
2021-05-17 14:12     ` Julian Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=AM8PR10MB470875A817A42095E6397469E42D9@AM8PR10MB4708.EURPRD10.PROD.OUTLOOK.COM \
    --to=bernd.edlinger@hotmail.de \
    --cc=cltang@codesourcery.com \
    --cc=fortran@gcc.gnu.org \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jakub@redhat.com \
    --cc=julian@codesourcery.com \
    --cc=thomas@codesourcery.com \
    --cc=tobias@codesourcery.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).