[PATCH 2/5, OpenACC] Support Fortran optional arguments in the firstprivate clause

Kwok Cheung Yeung kcy@codesourcery.com
Fri Jul 12 11:36:00 GMT 2019


Reference types used by Fortran often need to be treated specially in 
the OACC lowering to deal with the referenced object as well as the 
reference itself. However, as optional arguments can be null, they are 
pointer types rather than reference types, so the code to detect these 
situations needs to be updated.

	gcc/
	* omp-general.c (omp_is_optional_argument): New.
	* omp-general.h (omp_is_optional_argument): New.
	* omp-low.c (lower_omp_target): Use size of referenced object when
	optional argument used as argument to firstprivate.  Create temporary
	for received value and take the address for new_var if the original
	variable was an optional argument.
---
  gcc/omp-general.c | 14 ++++++++++++++
  gcc/omp-general.h |  1 +
  gcc/omp-low.c     |  8 +++++---
  3 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/gcc/omp-general.c b/gcc/omp-general.c
index 8086f9a..e5173b8 100644
--- a/gcc/omp-general.c
+++ b/gcc/omp-general.c
@@ -48,6 +48,20 @@ omp_find_clause (tree clauses, enum omp_clause_code kind)
    return NULL_TREE;
  }

+/* Return true if DECL is a Fortran optional argument.  */
+
+bool
+omp_is_optional_argument (tree decl)
+{
+  /* A passed-by-reference Fortran optional argument is similar to
+     a normal argument, but since it can be null the type is a
+     POINTER_TYPE rather than a REFERENCE_TYPE.  */
+  return lang_GNU_Fortran ()
+        && TREE_CODE (decl) == PARM_DECL
+        && DECL_BY_REFERENCE (decl)
+	 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE;
+}
+
  /* Return true if DECL is a reference type.  */

  bool
diff --git a/gcc/omp-general.h b/gcc/omp-general.h
index 80d42af..bbaa7b1 100644
--- a/gcc/omp-general.h
+++ b/gcc/omp-general.h
@@ -73,6 +73,7 @@ struct omp_for_data
  #define OACC_FN_ATTRIB "oacc function"

  extern tree omp_find_clause (tree clauses, enum omp_clause_code kind);
+extern bool omp_is_optional_argument (tree decl);
  extern bool omp_is_reference (tree decl);
  extern void omp_adjust_for_condition (location_t loc, enum tree_code 
*cond_code,
  				      tree *n2, tree v, tree step);
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index a855c5b..625df1e 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -11172,8 +11172,9 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, 
omp_context *ctx)
  	    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
  	      {
  		gcc_assert (is_gimple_omp_oacc (ctx->stmt));
-		if (omp_is_reference (new_var)
-		    && TREE_CODE (TREE_TYPE (new_var)) != POINTER_TYPE)
+		if ((omp_is_reference (new_var)
+		     && TREE_CODE (TREE_TYPE (new_var)) != POINTER_TYPE)
+		    || omp_is_optional_argument (var))
  		  {
  		    /* Create a local object to hold the instance
  		       value.  */
@@ -11461,7 +11462,8 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, 
omp_context *ctx)
  	      {
  		gcc_checking_assert (is_gimple_omp_oacc (ctx->stmt));
  		s = TREE_TYPE (ovar);
-		if (TREE_CODE (s) == REFERENCE_TYPE)
+		if (TREE_CODE (s) == REFERENCE_TYPE
+		    || omp_is_optional_argument (ovar))
  		  s = TREE_TYPE (s);
  		s = TYPE_SIZE_UNIT (s);
  	      }
-- 
2.8.1




More information about the Fortran mailing list