OSDN Git Service

* trans-array.c (gfc_trans_array_bound_check): Use ss argument
[pf3gnuchains/gcc-fork.git] / gcc / fortran / trans-array.c
index 476978e..d8f5448 100644 (file)
@@ -815,7 +815,7 @@ get_array_ref_dim (gfc_ss_info *info, int loop_dim)
   array_dim = info->dim[loop_dim];
 
   for (n = 0; n < info->dimen; n++)
-    if (n != loop_dim && info->dim[n] < array_dim)
+    if (info->dim[n] < array_dim)
       array_ref_dim++;
 
   return array_ref_dim;
@@ -1849,8 +1849,7 @@ gfc_build_constant_array_constructor (gfc_expr * expr, tree type)
    gfc_build_constant_array_constructor.  */
 
 static void
-gfc_trans_constant_array_constructor (gfc_loopinfo * loop,
-                                     gfc_ss * ss, tree type)
+trans_constant_array_constructor (gfc_ss * ss, tree type)
 {
   gfc_ss_info *info;
   tree tmp;
@@ -1871,14 +1870,11 @@ gfc_trans_constant_array_constructor (gfc_loopinfo * loop,
       info->end[i] = gfc_index_zero_node;
       info->stride[i] = gfc_index_one_node;
     }
-
-  if (info->dimen > loop->temp_dim)
-    loop->temp_dim = info->dimen;
 }
 
 /* Helper routine of gfc_trans_array_constructor to determine if the
    bounds of the loop specified by LOOP are constant and simple enough
-   to use with gfc_trans_constant_array_constructor.  Returns the
+   to use with trans_constant_array_constructor.  Returns the
    iteration count of the loop if suitable, and NULL_TREE otherwise.  */
 
 static tree
@@ -2033,7 +2029,7 @@ gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss, locus * where)
          tree size = constant_array_constructor_loop_size (loop);
          if (size && compare_tree_int (size, nelem) == 0)
            {
-             gfc_trans_constant_array_constructor (loop, ss, type);
+             trans_constant_array_constructor (ss, type);
              goto finish;
            }
        }
@@ -2430,42 +2426,25 @@ gfc_conv_array_ubound (tree descriptor, int dim)
 /* Generate code to perform an array index bound check.  */
 
 static tree
-gfc_trans_array_bound_check (gfc_se * se, tree descriptor, tree index, int n,
-                            locus * where, bool check_upper)
+trans_array_bound_check (gfc_se * se, gfc_ss *ss, tree index, int n,
+                        locus * where, bool check_upper)
 {
   tree fault;
   tree tmp_lo, tmp_up;
+  tree descriptor;
   char *msg;
   const char * name = NULL;
 
   if (!(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
     return index;
 
+  descriptor = ss->data.info.descriptor;
+
   index = gfc_evaluate_now (index, &se->pre);
 
   /* We find a name for the error message.  */
-  if (se->ss)
-    name = se->ss->expr->symtree->name;
-
-  if (!name && se->loop && se->loop->ss && se->loop->ss->expr
-      && se->loop->ss->expr->symtree)
-    name = se->loop->ss->expr->symtree->name;
-
-  if (!name && se->loop && se->loop->ss && se->loop->ss->loop_chain
-      && se->loop->ss->loop_chain->expr
-      && se->loop->ss->loop_chain->expr->symtree)
-    name = se->loop->ss->loop_chain->expr->symtree->name;
-
-  if (!name && se->loop && se->loop->ss && se->loop->ss->expr)
-    {
-      if (se->loop->ss->expr->expr_type == EXPR_FUNCTION
-         && se->loop->ss->expr->value.function.name)
-       name = se->loop->ss->expr->value.function.name;
-      else
-       if (se->loop->ss->type == GFC_SS_CONSTRUCTOR
-           || se->loop->ss->type == GFC_SS_SCALAR)
-         name = "unnamed constant";
-    }
+  name = ss->expr->symtree->n.sym->name;
+  gcc_assert (name != NULL);
 
   if (TREE_CODE (descriptor) == VAR_DECL)
     name = IDENTIFIER_POINTER (DECL_NAME (descriptor));
@@ -2525,13 +2504,16 @@ gfc_trans_array_bound_check (gfc_se * se, tree descriptor, tree index, int n,
    DIM is the array dimension, I is the loop dimension.  */
 
 static tree
-gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i,
-                            gfc_array_ref * ar, tree stride)
+conv_array_index_offset (gfc_se * se, gfc_ss * ss, int dim, int i,
+                        gfc_array_ref * ar, tree stride)
 {
+  gfc_ss_info *info;
   tree index;
   tree desc;
   tree data;
 
+  info = &ss->data.info;
+
   /* Get the index into the array for this dimension.  */
   if (ar)
     {
@@ -2548,10 +2530,9 @@ gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i,
          /* We've already translated this value outside the loop.  */
          index = info->subscript[dim]->data.scalar.expr;
 
-         index = gfc_trans_array_bound_check (se, info->descriptor,
-                       index, dim, &ar->where,
-                       ar->as->type != AS_ASSUMED_SIZE
-                       || dim < ar->dimen - 1);
+         index = trans_array_bound_check (se, ss, index, dim, &ar->where,
+                                          ar->as->type != AS_ASSUMED_SIZE
+                                          || dim < ar->dimen - 1);
          break;
 
        case DIMEN_VECTOR:
@@ -2578,10 +2559,9 @@ gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i,
          index = fold_convert (gfc_array_index_type, index);
 
          /* Do any bounds checking on the final info->descriptor index.  */
-         index = gfc_trans_array_bound_check (se, info->descriptor,
-                       index, dim, &ar->where,
-                       ar->as->type != AS_ASSUMED_SIZE
-                       || dim < ar->dimen - 1);
+         index = trans_array_bound_check (se, ss, index, dim, &ar->where,
+                                          ar->as->type != AS_ASSUMED_SIZE
+                                          || dim < ar->dimen - 1);
          break;
 
        case DIMEN_RANGE:
@@ -2652,7 +2632,7 @@ gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
   else
     n = 0;
 
-  index = gfc_conv_array_index_offset (se, info, info->dim[n], n, ar,
+  index = conv_array_index_offset (se, se->ss, info->dim[n], n, ar,
                                       info->stride0);
   /* Add the offset for this dimension to the stored offset for all other
      dimensions.  */
@@ -2830,6 +2810,33 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym,
 }
 
 
+/* Add the offset corresponding to array's ARRAY_DIM dimension and loop's
+   LOOP_DIM dimension (if any) to array's offset.  */
+
+static void
+add_array_offset (stmtblock_t *pblock, gfc_loopinfo *loop, gfc_ss *ss,
+                 gfc_array_ref *ar, int array_dim, int loop_dim)
+{
+  gfc_se se;
+  gfc_ss_info *info;
+  tree stride, index;
+
+  info = &ss->data.info;
+
+  gfc_init_se (&se, NULL);
+  se.loop = loop;
+  se.expr = info->descriptor;
+  stride = gfc_conv_array_stride (info->descriptor, array_dim);
+  index = conv_array_index_offset (&se, ss, array_dim, loop_dim, ar, stride);
+  gfc_add_block_to_block (pblock, &se.pre);
+
+  info->offset = fold_build2_loc (input_location, PLUS_EXPR,
+                                 gfc_array_index_type,
+                                 info->offset, index);
+  info->offset = gfc_evaluate_now (info->offset, pblock);
+}
+
+
 /* Generate the code to be executed immediately before entering a
    scalarization loop.  */
 
@@ -2837,11 +2844,9 @@ static void
 gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
                         stmtblock_t * pblock)
 {
-  tree index;
   tree stride;
   gfc_ss_info *info;
   gfc_ss *ss;
-  gfc_se se;
   gfc_array_ref *ar;
   int i;
 
@@ -2859,8 +2864,7 @@ gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
 
       info = &ss->data.info;
 
-      if (dim >= info->dimen)
-       continue;
+      gcc_assert (dim < info->dimen);
       gcc_assert (info->dimen == loop->dimen);
 
       if (info->ref)
@@ -2896,36 +2900,13 @@ gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
                  if (ar->dimen_type[i] != DIMEN_ELEMENT)
                    continue;
 
-                 gfc_init_se (&se, NULL);
-                 se.loop = loop;
-                 se.expr = info->descriptor;
-                 stride = gfc_conv_array_stride (info->descriptor, i);
-                 index = gfc_conv_array_index_offset (&se, info, i, -1,
-                                                      ar, stride);
-                 gfc_add_block_to_block (pblock, &se.pre);
-
-                 info->offset = fold_build2_loc (input_location, PLUS_EXPR,
-                                                 gfc_array_index_type,
-                                                 info->offset, index);
-                 info->offset = gfc_evaluate_now (info->offset, pblock);
+                 add_array_offset (pblock, loop, ss, ar, i, /* unused */ -1);
                }
            }
        }
       else
-       {
-         /* Add the offset for the previous loop dimension.  */
-         gfc_init_se (&se, NULL);
-         se.loop = loop;
-         se.expr = info->descriptor;
-         stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
-         index = gfc_conv_array_index_offset (&se, info, info->dim[i], i,
-                                              ar, stride);
-         gfc_add_block_to_block (pblock, &se.pre);
-         info->offset = fold_build2_loc (input_location, PLUS_EXPR,
-                                         gfc_array_index_type, info->offset,
-                                         index);
-         info->offset = gfc_evaluate_now (info->offset, pblock);
-       }
+       /* Add the offset for the previous loop dimension.  */
+       add_array_offset (pblock, loop, ss, ar, info->dim[i], i);
 
       /* Remember this offset for the second loop.  */
       if (dim == loop->temp_dim - 1)
@@ -3112,7 +3093,7 @@ gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body)
   gfc_add_expr_to_block (&loop->pre, tmp);
 
   /* Clear all the used flags.  */
-  for (ss = loop->ss; ss; ss = ss->loop_chain)
+  for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
     ss->useflags = 0;
 }
 
@@ -3345,9 +3326,11 @@ done:
        case GFC_SS_FUNCTION:
          for (n = 0; n < ss->data.info.dimen; n++)
            {
-             ss->data.info.start[n] = gfc_index_zero_node;
-             ss->data.info.end[n] = gfc_index_zero_node;
-             ss->data.info.stride[n] = gfc_index_one_node;
+             int dim = ss->data.info.dim[n];
+
+             ss->data.info.start[dim]  = gfc_index_zero_node;
+             ss->data.info.end[dim]    = gfc_index_zero_node;
+             ss->data.info.stride[dim] = gfc_index_one_node;
            }
          break;
 
@@ -3877,7 +3860,12 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
         loop for this dimension.  We try to pick the simplest term.  */
       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
        {
-         if (ss->type == GFC_SS_SCALAR || ss->type == GFC_SS_REFERENCE)
+         gfc_ss_type ss_type;
+
+         ss_type = ss->type;
+         if (ss_type == GFC_SS_SCALAR
+             || ss_type == GFC_SS_TEMP
+             || ss_type == GFC_SS_REFERENCE)
            continue;
 
          info = &ss->data.info;
@@ -7634,7 +7622,7 @@ gfc_walk_array_ref (gfc_ss * ss, gfc_expr * expr, gfc_ref * ref)
       switch (ar->type)
        {
        case AR_ELEMENT:
-         for (n = ar->dimen + ar->codimen - 1; n >= 0; n--)
+         for (n = ar->dimen - 1; n >= 0; n--)
            ss = gfc_get_scalar_ss (ss, ar->start[n]);
          break;