OSDN Git Service

* trans-intrinsic.c (gfc_conv_intrinsic_minmaxloc): Set loop's
[pf3gnuchains/gcc-fork.git] / gcc / fortran / trans-intrinsic.c
index c216873..506cdf2 100644 (file)
@@ -139,7 +139,7 @@ static tree
 builtin_decl_for_precision (enum built_in_function base_built_in,
                            int precision)
 {
-  int i = END_BUILTINS;
+  enum built_in_function i = END_BUILTINS;
 
   gfc_intrinsic_map_t *m;
   for (m = gfc_intrinsic_map; m->double_built_in != base_built_in ; m++)
@@ -158,7 +158,7 @@ builtin_decl_for_precision (enum built_in_function base_built_in,
       return m->real16_decl;
     }
 
-  return (i == END_BUILTINS ? NULL_TREE : built_in_decls[i]);
+  return (i == END_BUILTINS ? NULL_TREE : builtin_decl_explicit (i));
 }
 
 
@@ -679,26 +679,28 @@ gfc_build_intrinsic_lib_fndecls (void)
        m->id != GFC_ISYM_NONE || m->double_built_in != END_BUILTINS; m++)
     {
       if (m->float_built_in != END_BUILTINS)
-       m->real4_decl = built_in_decls[m->float_built_in];
+       m->real4_decl = builtin_decl_explicit (m->float_built_in);
       if (m->complex_float_built_in != END_BUILTINS)
-       m->complex4_decl = built_in_decls[m->complex_float_built_in];
+       m->complex4_decl = builtin_decl_explicit (m->complex_float_built_in);
       if (m->double_built_in != END_BUILTINS)
-       m->real8_decl = built_in_decls[m->double_built_in];
+       m->real8_decl = builtin_decl_explicit (m->double_built_in);
       if (m->complex_double_built_in != END_BUILTINS)
-       m->complex8_decl = built_in_decls[m->complex_double_built_in];
+       m->complex8_decl = builtin_decl_explicit (m->complex_double_built_in);
 
       /* If real(kind=10) exists, it is always long double.  */
       if (m->long_double_built_in != END_BUILTINS)
-       m->real10_decl = built_in_decls[m->long_double_built_in];
+       m->real10_decl = builtin_decl_explicit (m->long_double_built_in);
       if (m->complex_long_double_built_in != END_BUILTINS)
-       m->complex10_decl = built_in_decls[m->complex_long_double_built_in];
+       m->complex10_decl
+         = builtin_decl_explicit (m->complex_long_double_built_in);
 
       if (!gfc_real16_is_float128)
        {
          if (m->long_double_built_in != END_BUILTINS)
-           m->real16_decl = built_in_decls[m->long_double_built_in];
+           m->real16_decl = builtin_decl_explicit (m->long_double_built_in);
          if (m->complex_long_double_built_in != END_BUILTINS)
-           m->complex16_decl = built_in_decls[m->complex_long_double_built_in];
+           m->complex16_decl
+             = builtin_decl_explicit (m->complex_long_double_built_in);
        }
       else if (quad_decls[m->double_built_in] != NULL_TREE)
         {
@@ -924,18 +926,37 @@ gfc_conv_intrinsic_exponent (gfc_se *se, gfc_expr *expr)
 /* Convert the last ref of a scalar coarray from an AR_ELEMENT to an
    AR_FULL, suitable for the scalarizer.  */
 
-static void
-convert_element_to_coarray_ref (gfc_expr *expr)
+static gfc_ss *
+walk_coarray (gfc_expr *e)
 {
-  gfc_ref *ref;
+  gfc_ss *ss;
 
-  for (ref = expr->ref; ref; ref = ref->next)
-    if (ref->type == REF_ARRAY && ref->next == NULL
-       && ref->u.ar.codimen)
-      {
-       ref->u.ar.type = AR_FULL;
-       break;
-      }
+  gcc_assert (gfc_get_corank (e) > 0);
+
+  ss = gfc_walk_expr (e);
+
+  /* Fix scalar coarray.  */
+  if (ss == gfc_ss_terminator)
+    {
+      gfc_ref *ref;
+
+      ref = e->ref;
+      while (ref)
+       {
+         if (ref->type == REF_ARRAY
+             && ref->u.ar.codimen > 0)
+           break;
+
+         ref = ref->next;
+       }
+
+      gcc_assert (ref != NULL);
+      if (ref->u.ar.type == AR_ELEMENT)
+       ref->u.ar.type = AR_SECTION;
+      ss = gfc_reverse_ss (gfc_walk_array_ref (ss, e, ref));
+    }
+
+  return ss;
 }
 
 
@@ -969,11 +990,8 @@ trans_this_image (gfc_se * se, gfc_expr *expr)
 
   /* Obtain the descriptor of the COARRAY.  */
   gfc_init_se (&argse, NULL);
-  if (expr->value.function.actual->expr->rank == 0)
-    convert_element_to_coarray_ref (expr->value.function.actual->expr);
-  ss = gfc_walk_expr (expr->value.function.actual->expr);
+  ss = walk_coarray (expr->value.function.actual->expr);
   gcc_assert (ss != gfc_ss_terminator);
-  ss->data.info.codimen = corank;
   argse.want_coarray = 1;
   gfc_conv_expr_descriptor (&argse, expr->value.function.actual->expr, ss);
   gfc_add_block_to_block (&se->pre, &argse.pre);
@@ -986,7 +1004,7 @@ trans_this_image (gfc_se * se, gfc_expr *expr)
       gcc_assert (!expr->value.function.actual->next->expr);
       gcc_assert (corank > 0);
       gcc_assert (se->loop->dimen == 1);
-      gcc_assert (se->ss->expr == expr);
+      gcc_assert (se->ss->info->expr == expr);
 
       dim_arg = se->loop->loopvar[0];
       dim_arg = fold_build2_loc (input_location, PLUS_EXPR,
@@ -1157,11 +1175,8 @@ trans_image_index (gfc_se * se, gfc_expr *expr)
 
   /* Obtain the descriptor of the COARRAY.  */
   gfc_init_se (&argse, NULL);
-  if (expr->value.function.actual->expr->rank == 0)
-    convert_element_to_coarray_ref (expr->value.function.actual->expr);
-  ss = gfc_walk_expr (expr->value.function.actual->expr);
+  ss = walk_coarray (expr->value.function.actual->expr);
   gcc_assert (ss != gfc_ss_terminator);
-  ss->data.info.codimen = corank;
   argse.want_coarray = 1;
   gfc_conv_expr_descriptor (&argse, expr->value.function.actual->expr, ss);
   gfc_add_block_to_block (&se->pre, &argse.pre);
@@ -1306,7 +1321,7 @@ gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
       /* Create an implicit second parameter from the loop variable.  */
       gcc_assert (!arg2->expr);
       gcc_assert (se->loop->dimen == 1);
-      gcc_assert (se->ss->expr == expr);
+      gcc_assert (se->ss->info->expr == expr);
       gfc_advance_se_ss_chain (se);
       bound = se->loop->loopvar[0];
       bound = fold_build2_loc (input_location, MINUS_EXPR,
@@ -1484,11 +1499,8 @@ conv_intrinsic_cobound (gfc_se * se, gfc_expr * expr)
   gcc_assert (arg->expr->expr_type == EXPR_VARIABLE);
   corank = gfc_get_corank (arg->expr);
 
-  if (expr->value.function.actual->expr->rank == 0)
-    convert_element_to_coarray_ref (expr->value.function.actual->expr);
-  ss = gfc_walk_expr (arg->expr);
+  ss = walk_coarray (arg->expr);
   gcc_assert (ss != gfc_ss_terminator);
-  ss->data.info.codimen = corank;
   gfc_init_se (&argse, NULL);
   argse.want_coarray = 1;
 
@@ -1503,7 +1515,7 @@ conv_intrinsic_cobound (gfc_se * se, gfc_expr * expr)
       gcc_assert (!arg2->expr);
       gcc_assert (corank > 0);
       gcc_assert (se->loop->dimen == 1);
-      gcc_assert (se->ss->expr == expr);
+      gcc_assert (se->ss->info->expr == expr);
 
       bound = se->loop->loopvar[0];
       bound = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
@@ -2205,7 +2217,8 @@ gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, enum tree_code op)
       if (FLOAT_TYPE_P (TREE_TYPE (mvar)))
        {
          isnan = build_call_expr_loc (input_location,
-                                  built_in_decls[BUILT_IN_ISNAN], 1, mvar);
+                                      builtin_decl_explicit (BUILT_IN_ISNAN),
+                                      1, mvar);
          tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
                                 boolean_type_node, tmp,
                                 fold_convert (boolean_type_node, isnan));
@@ -2310,7 +2323,7 @@ gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
   gfc_symbol *sym;
   VEC(tree,gc) *append_args;
 
-  gcc_assert (!se->ss || se->ss->expr == expr);
+  gcc_assert (!se->ss || se->ss->info->expr == expr);
 
   if (se->ss)
     gcc_assert (expr->rank > 0);
@@ -3048,6 +3061,23 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
 
   /* Initialize the loop.  */
   gfc_conv_ss_startstride (&loop);
+
+  /* The code generated can have more than one loop in sequence (see the
+     comment at the function header).  This doesn't work well with the
+     scalarizer, which changes arrays' offset when the scalarization loops
+     are generated (see gfc_trans_preloop_setup).  Fortunately, {min,max}loc
+     are  currently inlined in the scalar case only (for which loop is of rank
+     one).  As there is no dependency to care about in that case, there is no
+     temporary, so that we can use the scalarizer temporary code to handle
+     multiple loops.  Thus, we set temp_dim here, we call gfc_mark_ss_chain_used
+     with flag=3 later, and we use gfc_trans_scalarized_loop_boundary even later
+     to restore offset.
+     TODO: this prevents inlining of rank > 0 minmaxloc calls, so this
+     should eventually go away.  We could either create two loops properly,
+     or find another way to save/restore the array offsets between the two
+     loops (without conflicting with temporary management), or use a single
+     loop minmaxloc implementation.  See PR 31067.  */
+  loop.temp_dim = loop.dimen;
   gfc_conv_loop_setup (&loop, &expr->where);
 
   gcc_assert (loop.dimen == 1);
@@ -3077,9 +3107,17 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
       TREE_USED (lab2) = 1;
     }
 
-  gfc_mark_ss_chain_used (arrayss, 1);
+  /* An offset must be added to the loop
+     counter to obtain the required position.  */
+  gcc_assert (loop.from[0]);
+
+  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+                        gfc_index_one_node, loop.from[0]);
+  gfc_add_modify (&loop.pre, offset, tmp);
+
+  gfc_mark_ss_chain_used (arrayss, lab1 ? 3 : 1);
   if (maskss)
-    gfc_mark_ss_chain_used (maskss, 1);
+    gfc_mark_ss_chain_used (maskss, lab1 ? 3 : 1);
   /* Generate the loop body.  */
   gfc_start_scalarized_body (&loop, &body);
 
@@ -3110,16 +3148,6 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
   /* Assign the value to the limit...  */
   gfc_add_modify (&ifblock, limit, arrayse.expr);
 
-  /* Remember where we are.  An offset must be added to the loop
-     counter to obtain the required position.  */
-  if (loop.from[0])
-    tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
-                          gfc_index_one_node, loop.from[0]);
-  else
-    tmp = gfc_index_one_node;
-
-  gfc_add_modify (&block, offset, tmp);
-
   if (nonempty == NULL && HONOR_NANS (DECL_MODE (limit)))
     {
       stmtblock_t ifblock2;
@@ -3175,7 +3203,7 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
 
   if (lab1)
     {
-      gfc_trans_scalarized_loop_end (&loop, 0, &body);
+      gfc_trans_scalarized_loop_boundary (&loop, &body);
 
       if (HONOR_NANS (DECL_MODE (limit)))
        {
@@ -3190,7 +3218,6 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
 
       gfc_add_expr_to_block (&loop.code[0], build1_v (GOTO_EXPR, lab2));
       gfc_add_expr_to_block (&loop.code[0], build1_v (LABEL_EXPR, lab1));
-      gfc_start_block (&body);
 
       /* If we have a mask, only check this element if the mask is set.  */
       if (maskss)
@@ -3219,16 +3246,6 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
       /* Assign the value to the limit...  */
       gfc_add_modify (&ifblock, limit, arrayse.expr);
 
-      /* Remember where we are.  An offset must be added to the loop
-        counter to obtain the required position.  */
-      if (loop.from[0])
-       tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
-                              gfc_index_one_node, loop.from[0]);
-      else
-       tmp = gfc_index_one_node;
-
-      gfc_add_modify (&block, offset, tmp);
-
       tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (pos),
                             loop.loopvar[0], offset);
       gfc_add_modify (&ifblock, pos, tmp);
@@ -4082,17 +4099,17 @@ gfc_conv_intrinsic_leadz (gfc_se * se, gfc_expr * expr)
   if (argsize <= INT_TYPE_SIZE)
     {
       arg_type = unsigned_type_node;
-      func = built_in_decls[BUILT_IN_CLZ];
+      func = builtin_decl_explicit (BUILT_IN_CLZ);
     }
   else if (argsize <= LONG_TYPE_SIZE)
     {
       arg_type = long_unsigned_type_node;
-      func = built_in_decls[BUILT_IN_CLZL];
+      func = builtin_decl_explicit (BUILT_IN_CLZL);
     }
   else if (argsize <= LONG_LONG_TYPE_SIZE)
     {
       arg_type = long_long_unsigned_type_node;
-      func = built_in_decls[BUILT_IN_CLZLL];
+      func = builtin_decl_explicit (BUILT_IN_CLZLL);
     }
   else
     {
@@ -4131,7 +4148,7 @@ gfc_conv_intrinsic_leadz (gfc_se * se, gfc_expr * expr)
         where ULL_MAX is the largest value that a ULL_MAX can hold
         (0xFFFFFFFFFFFFFFFF for a 64-bit long long type), and ULLSIZE
         is the bit-size of the long long type (64 in this example).  */
-      tree ullsize, ullmax, tmp1, tmp2;
+      tree ullsize, ullmax, tmp1, tmp2, btmp;
 
       ullsize = build_int_cst (result_type, LONG_LONG_TYPE_SIZE);
       ullmax = fold_build1_loc (input_location, BIT_NOT_EXPR,
@@ -4149,16 +4166,14 @@ gfc_conv_intrinsic_leadz (gfc_se * se, gfc_expr * expr)
       tmp1 = fold_build2_loc (input_location, RSHIFT_EXPR, arg_type,
                              arg, ullsize);
       tmp1 = fold_convert (long_long_unsigned_type_node, tmp1);
+      btmp = builtin_decl_explicit (BUILT_IN_CLZLL);
       tmp1 = fold_convert (result_type,
-                          build_call_expr_loc (input_location, 
-                                               built_in_decls[BUILT_IN_CLZLL],
-                                               1, tmp1));
+                          build_call_expr_loc (input_location, btmp, 1, tmp1));
 
       tmp2 = fold_convert (long_long_unsigned_type_node, arg);
+      btmp = builtin_decl_explicit (BUILT_IN_CLZLL);
       tmp2 = fold_convert (result_type,
-                          build_call_expr_loc (input_location,
-                                               built_in_decls[BUILT_IN_CLZLL],
-                                               1, tmp2));
+                          build_call_expr_loc (input_location, btmp, 1, tmp2));
       tmp2 = fold_build2_loc (input_location, PLUS_EXPR, result_type,
                              tmp2, ullsize);
 
@@ -4201,17 +4216,17 @@ gfc_conv_intrinsic_trailz (gfc_se * se, gfc_expr *expr)
   if (argsize <= INT_TYPE_SIZE)
     {
       arg_type = unsigned_type_node;
-      func = built_in_decls[BUILT_IN_CTZ];
+      func = builtin_decl_explicit (BUILT_IN_CTZ);
     }
   else if (argsize <= LONG_TYPE_SIZE)
     {
       arg_type = long_unsigned_type_node;
-      func = built_in_decls[BUILT_IN_CTZL];
+      func = builtin_decl_explicit (BUILT_IN_CTZL);
     }
   else if (argsize <= LONG_LONG_TYPE_SIZE)
     {
       arg_type = long_long_unsigned_type_node;
-      func = built_in_decls[BUILT_IN_CTZLL];
+      func = builtin_decl_explicit (BUILT_IN_CTZLL);
     }
   else
     {
@@ -4245,7 +4260,7 @@ gfc_conv_intrinsic_trailz (gfc_se * se, gfc_expr *expr)
         where ULL_MAX is the largest value that a ULL_MAX can hold
         (0xFFFFFFFFFFFFFFFF for a 64-bit long long type), and ULLSIZE
         is the bit-size of the long long type (64 in this example).  */
-      tree ullsize, ullmax, tmp1, tmp2;
+      tree ullsize, ullmax, tmp1, tmp2, btmp;
 
       ullsize = build_int_cst (result_type, LONG_LONG_TYPE_SIZE);
       ullmax = fold_build1_loc (input_location, BIT_NOT_EXPR,
@@ -4260,18 +4275,16 @@ gfc_conv_intrinsic_trailz (gfc_se * se, gfc_expr *expr)
       tmp1 = fold_build2_loc (input_location, RSHIFT_EXPR, arg_type,
                              arg, ullsize);
       tmp1 = fold_convert (long_long_unsigned_type_node, tmp1);
+      btmp = builtin_decl_explicit (BUILT_IN_CTZLL);
       tmp1 = fold_convert (result_type,
-                          build_call_expr_loc (input_location, 
-                                               built_in_decls[BUILT_IN_CTZLL],
-                                               1, tmp1));
+                          build_call_expr_loc (input_location, btmp, 1, tmp1));
       tmp1 = fold_build2_loc (input_location, PLUS_EXPR, result_type,
                              tmp1, ullsize);
 
       tmp2 = fold_convert (long_long_unsigned_type_node, arg);
+      btmp = builtin_decl_explicit (BUILT_IN_CTZLL);
       tmp2 = fold_convert (result_type,
-                          build_call_expr_loc (input_location,
-                                               built_in_decls[BUILT_IN_CTZLL],
-                                               1, tmp2));
+                          build_call_expr_loc (input_location, btmp, 1, tmp2));
 
       trailz = fold_build3_loc (input_location, COND_EXPR, result_type,
                                cond, tmp1, tmp2);
@@ -4307,17 +4320,23 @@ gfc_conv_intrinsic_popcnt_poppar (gfc_se * se, gfc_expr *expr, int parity)
   if (argsize <= INT_TYPE_SIZE)
     {
       arg_type = unsigned_type_node;
-      func = built_in_decls[parity ? BUILT_IN_PARITY : BUILT_IN_POPCOUNT];
+      func = builtin_decl_explicit (parity
+                                   ? BUILT_IN_PARITY
+                                   : BUILT_IN_POPCOUNT);
     }
   else if (argsize <= LONG_TYPE_SIZE)
     {
       arg_type = long_unsigned_type_node;
-      func = built_in_decls[parity ? BUILT_IN_PARITYL : BUILT_IN_POPCOUNTL];
+      func = builtin_decl_explicit (parity
+                                   ? BUILT_IN_PARITYL
+                                   : BUILT_IN_POPCOUNTL);
     }
   else if (argsize <= LONG_LONG_TYPE_SIZE)
     {
       arg_type = long_long_unsigned_type_node;
-      func = built_in_decls[parity ? BUILT_IN_PARITYLL : BUILT_IN_POPCOUNTLL];
+      func = builtin_decl_explicit (parity
+                                   ? BUILT_IN_PARITYLL
+                                   : BUILT_IN_POPCOUNTLL);
     }
   else
     {
@@ -4330,7 +4349,9 @@ gfc_conv_intrinsic_popcnt_poppar (gfc_se * se, gfc_expr *expr, int parity)
         as 'long long'.  */
       gcc_assert (argsize == 2 * LONG_LONG_TYPE_SIZE);
 
-      func = built_in_decls[parity ? BUILT_IN_PARITYLL : BUILT_IN_POPCOUNTLL];
+      func = builtin_decl_explicit (parity
+                                   ? BUILT_IN_PARITYLL
+                                   : BUILT_IN_POPCOUNTLL);
 
       /* Convert it to an integer, and store into a variable.  */
       utype = gfc_build_uint_type (argsize);
@@ -4583,7 +4604,8 @@ gfc_conv_intrinsic_isnan (gfc_se * se, gfc_expr * expr)
 
   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
   se->expr = build_call_expr_loc (input_location,
-                             built_in_decls[BUILT_IN_ISNAN], 1, arg);
+                                 builtin_decl_explicit (BUILT_IN_ISNAN),
+                                 1, arg);
   STRIP_TYPE_NOPS (se->expr);
   se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
 }
@@ -5251,14 +5273,14 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
   gfc_actual_arglist *arg;
   gfc_se argse;
   gfc_ss *ss;
-  gfc_ss_info *info;
+  gfc_array_info *info;
   stmtblock_t block;
   int n;
   bool scalar_mold;
 
   info = NULL;
   if (se->loop)
-    info = &se->ss->data.info;
+    info = &se->ss->info->data.array;
 
   /* Convert SOURCE.  The output from this stage is:-
        source_bytes = length of the source in bytes
@@ -5483,9 +5505,8 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
 
   /* Build a destination descriptor, using the pointer, source, as the
      data field.  */
-  gfc_trans_create_temp_array (&se->pre, &se->post, se->loop,
-                              info, mold_type, NULL_TREE, false, true, false,
-                              &expr->where);
+  gfc_trans_create_temp_array (&se->pre, &se->post, se->ss, mold_type,
+                              NULL_TREE, false, true, false, &expr->where);
 
   /* Cast the pointer to the result.  */
   tmp = gfc_conv_descriptor_data_get (info->descriptor);
@@ -5493,7 +5514,7 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
 
   /* Use memcpy to do the transfer.  */
   tmp = build_call_expr_loc (input_location,
-                        built_in_decls[BUILT_IN_MEMCPY],
+                        builtin_decl_explicit (BUILT_IN_MEMCPY),
                         3,
                         tmp,
                         fold_convert (pvoid_type_node, source),
@@ -5538,7 +5559,7 @@ scalar_transfer:
       gfc_add_modify (&block, tmpdecl,
                      fold_convert (TREE_TYPE (ptr), tmp));
       tmp = build_call_expr_loc (input_location,
-                            built_in_decls[BUILT_IN_MEMCPY], 3,
+                            builtin_decl_explicit (BUILT_IN_MEMCPY), 3,
                             fold_convert (pvoid_type_node, tmpdecl),
                             fold_convert (pvoid_type_node, ptr),
                             extent);
@@ -5563,7 +5584,7 @@ scalar_transfer:
       /* Use memcpy to do the transfer.  */
       tmp = gfc_build_addr_expr (NULL_TREE, tmpdecl);
       tmp = build_call_expr_loc (input_location,
-                            built_in_decls[BUILT_IN_MEMCPY], 3,
+                            builtin_decl_explicit (BUILT_IN_MEMCPY), 3,
                             fold_convert (pvoid_type_node, tmp),
                             fold_convert (pvoid_type_node, ptr),
                             extent);
@@ -6004,7 +6025,8 @@ gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
   tmp = fold_build_pointer_plus_loc (input_location,
                                     fold_convert (pvoid_type_node, dest), tmp);
   tmp = build_call_expr_loc (input_location,
-                            built_in_decls[BUILT_IN_MEMMOVE], 3, tmp, src,
+                            builtin_decl_explicit (BUILT_IN_MEMMOVE),
+                            3, tmp, src,
                             fold_build2_loc (input_location, MULT_EXPR,
                                              size_type_node, slen,
                                              fold_convert (size_type_node,
@@ -6615,7 +6637,7 @@ gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
       break;
 
     case GFC_ISYM_TRANSFER:
-      if (se->ss && se->ss->useflags)
+      if (se->ss && se->ss->info->useflags)
        /* Access the previously obtained result.  */
        gfc_conv_tmp_array_ref (se);
       else
@@ -6734,19 +6756,17 @@ walk_inline_intrinsic_transpose (gfc_ss *ss, gfc_expr *expr)
 
   for (tmp_ss = arg_ss; ; tmp_ss = tmp_ss->next)
     {
-      if (tmp_ss->type != GFC_SS_SCALAR
-         && tmp_ss->type != GFC_SS_REFERENCE)
+      if (tmp_ss->info->type != GFC_SS_SCALAR
+         && tmp_ss->info->type != GFC_SS_REFERENCE)
        {
          int tmp_dim;
-         gfc_ss_info *info;
 
-         info = &tmp_ss->data.info;
-         gcc_assert (info->dimen == 2);
+         gcc_assert (tmp_ss->dimen == 2);
 
          /* We just invert dimensions.  */
-         tmp_dim = info->dim[0];
-         info->dim[0] = info->dim[1];
-         info->dim[1] = tmp_dim;
+         tmp_dim = tmp_ss->dim[0];
+         tmp_ss->dim[0] = tmp_ss->dim[1];
+         tmp_ss->dim[1] = tmp_dim;
        }
 
       /* Stop when tmp_ss points to the last valid element of the chain...  */
@@ -6783,7 +6803,7 @@ walk_inline_intrinsic_function (gfc_ss * ss, gfc_expr * expr)
 void
 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
 {
-  switch (ss->expr->value.function.isym->id)
+  switch (ss->info->expr->value.function.isym->id)
     {
     case GFC_ISYM_UBOUND:
     case GFC_ISYM_LBOUND: