In the following patches, we are going to use gfc_conv_section_startstride
to calculate cobounds. The problem is that we don't want to calculate the last
ucobound. As a result, we should have a way to evaluate the lower bound
and the upper bound independently.
This patch moves bound evaluation to a function of its own, and use that new
function in gfc_conv_section_startstride.

OK?

PS: I could have kept the current flag trick to separate lower vs upper bound
evaluation, but besides the fact that I don't like flags in general, having
coarray in their name finished to convince me that they deserved to die. ;-)

2011-09-14  Mikael Morin  <mikael.mo...@sfr.fr>

        * trans-array.c (gfc_conv_section_startstride): Move code to
        evaluate_bound.  Use evaluate_bound.
        (evaluate_bound): New function.
diff --git a/trans-array.c b/trans-array.c
index 7f44514..ee5761b 100644
--- a/trans-array.c
+++ b/trans-array.c
@@ -3175,14 +3175,46 @@ gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
 }
 
 
+/* Precalculate (either lower or upper) bound of an array section.
+     BLOCK: Block in which the (pre)calculation code will go.
+     BOUNDS[DIM]: Where the bound value will be stored once evaluated.
+     VALUES[DIM]: Specified bound (NULL <=> unspecified).
+     DESC: Array descriptor from which the bound will be picked if unspecified
+       (either lower or upper bound according to LBOUND).  */
+
+static void
+evaluate_bound (stmtblock_t *block, tree *bounds, gfc_expr ** values,
+		tree desc, int dim, bool lbound)
+{
+  gfc_se se;
+  gfc_expr * input_val = values[dim];
+  tree *output = &bounds[dim];
+
+
+  if (input_val)
+    {
+      /* Specified section bound.  */
+      gfc_init_se (&se, NULL);
+      gfc_conv_expr_type (&se, input_val, gfc_array_index_type);
+      gfc_add_block_to_block (block, &se.pre);
+      *output = se.expr;
+    }
+  else
+    {
+      /* No specific bound specified so use the bound of the array.  */
+      *output = lbound ? gfc_conv_array_lbound (desc, dim) :
+			 gfc_conv_array_ubound (desc, dim);
+    }
+  *output = gfc_evaluate_now (*output, block);
+}
+
+
 /* Calculate the lower bound of an array section.  */
 
 static void
 gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int dim,
 			      bool coarray, bool coarray_last)
 {
-  gfc_expr *start;
-  gfc_expr *end;
   gfc_expr *stride = NULL;
   tree desc;
   gfc_se se;
@@ -3207,48 +3239,18 @@ gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int dim,
   gcc_assert (ar->dimen_type[dim] == DIMEN_RANGE
 	      || ar->dimen_type[dim] == DIMEN_THIS_IMAGE);
   desc = info->descriptor;
-  start = ar->start[dim];
-  end = ar->end[dim];
   if (!coarray)
     stride = ar->stride[dim];
 
   /* Calculate the start of the range.  For vector subscripts this will
      be the range of the vector.  */
-  if (start)
-    {
-      /* Specified section start.  */
-      gfc_init_se (&se, NULL);
-      gfc_conv_expr_type (&se, start, gfc_array_index_type);
-      gfc_add_block_to_block (&loop->pre, &se.pre);
-      info->start[dim] = se.expr;
-    }
-  else
-    {
-      /* No lower bound specified so use the bound of the array.  */
-      info->start[dim] = gfc_conv_array_lbound (desc, dim);
-    }
-  info->start[dim] = gfc_evaluate_now (info->start[dim], &loop->pre);
+  evaluate_bound (&loop->pre, info->start, ar->start, desc, dim, true);
 
   /* Similarly calculate the end.  Although this is not used in the
      scalarizer, it is needed when checking bounds and where the end
      is an expression with side-effects.  */
   if (!coarray_last)
-    {
-      if (end)
-	{
-	  /* Specified section start.  */
-	  gfc_init_se (&se, NULL);
-	  gfc_conv_expr_type (&se, end, gfc_array_index_type);
-	  gfc_add_block_to_block (&loop->pre, &se.pre);
-	  info->end[dim] = se.expr;
-	}
-      else
-	{
-	  /* No upper bound specified so use the bound of the array.  */
-	  info->end[dim] = gfc_conv_array_ubound (desc, dim);
-	}
-      info->end[dim] = gfc_evaluate_now (info->end[dim], &loop->pre);
-    }
+    evaluate_bound (&loop->pre, info->end, ar->end, desc, dim, false);
 
   /* Calculate the stride.  */
   if (!coarray && stride == NULL)

Reply via email to