This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, fortran] [05..09/14] Support coarray subreferences: Add support for array elements.


The  walk_coarray function introduced at
http://gcc.gnu.org/ml/fortran/2011-09/msg00074.html doesn't (like the code it
replaces) support subreferences after the coarray.
These patches are going to change that.

- The first step is, while looking for the coarray reference, to really look for
  it, instead of walking blindly to the last ref (patch 7).
- Then, in the code generated, an offset to the full array has to be added,
  corresponding to the subreference.
  The path taken is to reuse the scalarizer initialization handling for array
  sections subreferences in gfc_walk_variable_expr, and then let the rest
  of the scalarizer do the right thing with that (patch 9).
- For that to work, we need to skip the array ref lookup in
  gfc_walk_variable_expr, which is not valid for coarrays. A new funtion
  gfc_walk_array_ref is introduced, containing all of gfc_walk_variable_expr's 
  code but the array ref lookup (patch 5).
- Then for array elements (like coarray(1,1)), we change them from AR_ELEMENT
  to AR_SECTION so that they get the same treatment as normal arrays in
  gfc_walk_array_ref (patch 8).
- There is a small problem with the latter change; there is an assertion in
  gfc_walk_array_ref that in the AR_SECTION case, rank is non-zero.
  Patch 6 fixes that.

OK?

PS: The patch numbering is odd, because I have tried to reorder patches so that
no regression is introduced.  However, I haven't checked that it is actually the
case.  All I know is at the end, it's fine. ;-)


Attachment: pr50420-5.CL
Description: Text document

diff --git a/trans-array.c b/trans-array.c
index 605b356..1cfe382 100644
--- a/trans-array.c
+++ b/trans-array.c
@@ -7591,14 +7591,22 @@ static gfc_ss *
 gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
 {
   gfc_ref *ref;
-  gfc_array_ref *ar;
-  gfc_ss *newss;
-  int n;
 
   for (ref = expr->ref; ref; ref = ref->next)
     if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
       break;
 
+  return gfc_walk_array_ref (ss, expr, ref);
+}
+
+
+gfc_ss *
+gfc_walk_array_ref (gfc_ss * ss, gfc_expr * expr, gfc_ref * ref)
+{
+  gfc_array_ref *ar;
+  gfc_ss *newss;
+  int n;
+
   for (; ref; ref = ref->next)
     {
       if (ref->type == REF_SUBSTRING)
diff --git a/trans-array.h b/trans-array.h
index 73d8c40..4d737bd 100644
--- a/trans-array.h
+++ b/trans-array.h
@@ -70,6 +70,8 @@ void gfc_trans_static_array_pointer (gfc_symbol *);
 gfc_ss *gfc_walk_expr (gfc_expr *);
 /* Workhorse for gfc_walk_expr.  */
 gfc_ss *gfc_walk_subexpr (gfc_ss *, gfc_expr *);
+/* Workhorse for gfc_walk_variable_expr.  */
+gfc_ss *gfc_walk_array_ref (gfc_ss *, gfc_expr *, gfc_ref * ref);
 /* Walk the arguments of an elemental function.  */
 gfc_ss *gfc_walk_elemental_function_args (gfc_ss *, gfc_actual_arglist *,
 					  gfc_ss_type);

Attachment: pr50420-6.CL
Description: Text document

diff --git a/trans-array.c b/trans-array.c
index 1cfe382..4158a32 100644
--- a/trans-array.c
+++ b/trans-array.c
@@ -7688,8 +7688,10 @@ gfc_walk_array_ref (gfc_ss * ss, gfc_expr * expr, gfc_ref * ref)
 		  gcc_unreachable ();
 		}
 	    }
-	  /* We should have at least one non-elemental dimension.  */
-	  gcc_assert (newss->data.info.dimen > 0);
+	  /* We should have at least one non-elemental dimension,
+	     unless we are creating a descriptor for a (scalar) coarray.  */
+	  gcc_assert (newss->data.info.dimen > 0
+		      || newss->data.info.ref->u.ar.as->corank > 0);
 	  ss = newss;
 	  break;
 

Attachment: pr50420-7.CL
Description: Text document

diff --git a/trans-intrinsic.c b/trans-intrinsic.c
index c47e678..7d12eb9 100644
--- a/trans-intrinsic.c
+++ b/trans-intrinsic.c
@@ -941,10 +941,16 @@ walk_coarray (gfc_expr *e)
       ss = gfc_get_array_ss (gfc_ss_terminator, e, 0, GFC_SS_SECTION);
 
       ref = e->ref;
-      while (ref->next)
-	ref = ref->next;
+      while (ref)
+	{
+	  if (ref->type == REF_ARRAY
+	      && ref->u.ar.codimen > 0)
+	    break;
+
+	  ref = ref->next;
+	}
 
-      gcc_assert (ref->type == REF_ARRAY && ref->u.ar.codimen > 0);
+      gcc_assert (ref != NULL);
       ref->u.ar.type = AR_FULL;
       ss->data.info.ref = ref;
     }

Attachment: pr50420-8.CL
Description: Text document

diff --git a/trans-intrinsic.c b/trans-intrinsic.c
index 7d12eb9..e4a8873 100644
--- a/trans-intrinsic.c
+++ b/trans-intrinsic.c
@@ -951,7 +951,8 @@ walk_coarray (gfc_expr *e)
 	}
 
       gcc_assert (ref != NULL);
-      ref->u.ar.type = AR_FULL;
+      if (ref->u.ar.type == AR_ELEMENT)
+	ref->u.ar.type = AR_SECTION;
       ss->data.info.ref = ref;
     }
 

Attachment: pr50420-9.CL
Description: Text document

diff --git a/trans-intrinsic.c b/trans-intrinsic.c
index e4a8873..95f7f0b 100644
--- a/trans-intrinsic.c
+++ b/trans-intrinsic.c
@@ -938,8 +938,6 @@ walk_coarray (gfc_expr *e)
     {
       gfc_ref *ref;
 
-      ss = gfc_get_array_ss (gfc_ss_terminator, e, 0, GFC_SS_SECTION);
-
       ref = e->ref;
       while (ref)
 	{
@@ -953,7 +951,7 @@ walk_coarray (gfc_expr *e)
       gcc_assert (ref != NULL);
       if (ref->u.ar.type == AR_ELEMENT)
 	ref->u.ar.type = AR_SECTION;
-      ss->data.info.ref = ref;
+      ss = gfc_reverse_ss (gfc_walk_array_ref (ss, e, ref));
     }
 
   return ss;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]