Hello,

On Wednesday 03 August 2011 15:47:37 Richard Guenther wrote:
> Comments?  Any idea why reversing the loop would break?

Yes, the list of scalarized expressions has to be created in the same order it 
is consumed. Here the scalarized expressions are array indexes to be 
precomputed out of the loop.
The attached patch seems to work (the interesting part is in 
gfc_walk_variable_expr).

Mikael
diff --git a/trans-array.c b/trans-array.c
index 85acf0c..ebab43f 100644
--- a/trans-array.c
+++ b/trans-array.c
@@ -2623,6 +2623,21 @@ gfc_conv_tmp_array_ref (gfc_se * se)
 }
 
 
+static void
+add_to_offset (tree *cst_offset, tree *offset, tree value)
+{
+  if (integer_zerop (value))
+    return;
+
+  if (TREE_CODE (value) == INTEGER_CST)
+    *cst_offset = fold_build2_loc (input_location, PLUS_EXPR,
+				   gfc_array_index_type, *cst_offset, value);
+  else
+    *offset = fold_build2_loc (input_location, PLUS_EXPR,
+			       gfc_array_index_type, *offset, value);
+}
+
+
 /* Build an array reference.  se->expr already holds the array descriptor.
    This should be either a variable, indirect variable reference or component
    reference.  For arrays which do not have a descriptor, se->expr will be
@@ -2634,9 +2649,9 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym,
 		    locus * where)
 {
   int n;
-  tree index;
   tree tmp;
   tree stride;
+  tree offset, cst_offset;
   gfc_se indexse;
   gfc_se tmpse;
 
@@ -2669,10 +2684,12 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym,
       return;
     }
 
-  index = gfc_index_zero_node;
+  cst_offset = offset = gfc_index_zero_node;
+
+  add_to_offset (&cst_offset, &offset, gfc_conv_array_offset (se->expr));
 
   /* Calculate the offsets from all the dimensions.  */
-  for (n = 0; n < ar->dimen; n++)
+  for (n = ar->dimen - 1; n >= 0; n--)
     {
       /* Calculate the index for this dimension.  */
       gfc_init_se (&indexse, se);
@@ -2741,19 +2758,17 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym,
 			     indexse.expr, stride);
 
       /* And add it to the total.  */
-      index = fold_build2_loc (input_location, PLUS_EXPR,
-			       gfc_array_index_type, index, tmp);
+      add_to_offset (&cst_offset, &offset, tmp);
     }
 
-  tmp = gfc_conv_array_offset (se->expr);
-  if (!integer_zerop (tmp))
-    index = fold_build2_loc (input_location, PLUS_EXPR,
-			     gfc_array_index_type, index, tmp);
+  if (!integer_zerop (cst_offset))
+    offset = fold_build2_loc (input_location, PLUS_EXPR,
+			      gfc_array_index_type, offset, cst_offset);
 
   /* Access the calculated element.  */
   tmp = gfc_conv_array_data (se->expr);
   tmp = build_fold_indirect_ref (tmp);
-  se->expr = gfc_build_array_ref (tmp, index, sym->backend_decl);
+  se->expr = gfc_build_array_ref (tmp, offset, sym->backend_decl);
 }
 
 
@@ -7575,7 +7590,7 @@ gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
       switch (ar->type)
 	{
 	case AR_ELEMENT:
-	  for (n = 0; n < ar->dimen + ar->codimen; n++)
+	  for (n = ar->dimen + ar->codimen - 1; n >= 0; n--)
 	    {
 	      newss = gfc_get_ss ();
 	      newss->type = GFC_SS_SCALAR;

Reply via email to