OSDN Git Service

PR fortran/21104
[pf3gnuchains/gcc-fork.git] / gcc / fortran / trans-array.c
1 /* Array translation routines
2    Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3    Contributed by Paul Brook <paul@nowt.org>
4    and Steven Bosscher <s.bosscher@student.tudelft.nl>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING.  If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA.  */
22
23 /* trans-array.c-- Various array related code, including scalarization,
24                    allocation, initialization and other support routines.  */
25
26 /* How the scalarizer works.
27    In gfortran, array expressions use the same core routines as scalar
28    expressions.
29    First, a Scalarization State (SS) chain is built.  This is done by walking
30    the expression tree, and building a linear list of the terms in the
31    expression.  As the tree is walked, scalar subexpressions are translated.
32
33    The scalarization parameters are stored in a gfc_loopinfo structure.
34    First the start and stride of each term is calculated by
35    gfc_conv_ss_startstride.  During this process the expressions for the array
36    descriptors and data pointers are also translated.
37
38    If the expression is an assignment, we must then resolve any dependencies.
39    In fortran all the rhs values of an assignment must be evaluated before
40    any assignments take place.  This can require a temporary array to store the
41    values.  We also require a temporary when we are passing array expressions
42    or vector subecripts as procedure parameters.
43
44    Array sections are passed without copying to a temporary.  These use the
45    scalarizer to determine the shape of the section.  The flag
46    loop->array_parameter tells the scalarizer that the actual values and loop
47    variables will not be required.
48
49    The function gfc_conv_loop_setup generates the scalarization setup code.
50    It determines the range of the scalarizing loop variables.  If a temporary
51    is required, this is created and initialized.  Code for scalar expressions
52    taken outside the loop is also generated at this time.  Next the offset and
53    scaling required to translate from loop variables to array indices for each
54    term is calculated.
55
56    A call to gfc_start_scalarized_body marks the start of the scalarized
57    expression.  This creates a scope and declares the loop variables.  Before
58    calling this gfc_make_ss_chain_used must be used to indicate which terms
59    will be used inside this loop.
60
61    The scalar gfc_conv_* functions are then used to build the main body of the
62    scalarization loop.  Scalarization loop variables and precalculated scalar
63    values are automatically substituted.  Note that gfc_advance_se_ss_chain
64    must be used, rather than changing the se->ss directly.
65
66    For assignment expressions requiring a temporary two sub loops are
67    generated.  The first stores the result of the expression in the temporary,
68    the second copies it to the result.  A call to
69    gfc_trans_scalarized_loop_boundary marks the end of the main loop code and
70    the start of the copying loop.  The temporary may be less than full rank.
71
72    Finally gfc_trans_scalarizing_loops is called to generate the implicit do
73    loops.  The loops are added to the pre chain of the loopinfo.  The post
74    chain may still contain cleanup code.
75
76    After the loop code has been added into its parent scope gfc_cleanup_loop
77    is called to free all the SS allocated by the scalarizer.  */
78
79 #include "config.h"
80 #include "system.h"
81 #include "coretypes.h"
82 #include "tree.h"
83 #include "tree-gimple.h"
84 #include "ggc.h"
85 #include "toplev.h"
86 #include "real.h"
87 #include "flags.h"
88 #include "gfortran.h"
89 #include "trans.h"
90 #include "trans-stmt.h"
91 #include "trans-types.h"
92 #include "trans-array.h"
93 #include "trans-const.h"
94 #include "dependency.h"
95
96 static gfc_ss *gfc_walk_subexpr (gfc_ss *, gfc_expr *);
97 static bool gfc_get_array_constructor_size (mpz_t *, gfc_constructor *);
98
99 /* The contents of this structure aren't actually used, just the address.  */
100 static gfc_ss gfc_ss_terminator_var;
101 gfc_ss * const gfc_ss_terminator = &gfc_ss_terminator_var;
102
103
104 static tree
105 gfc_array_dataptr_type (tree desc)
106 {
107   return (GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc)));
108 }
109
110
111 /* Build expressions to access the members of an array descriptor.
112    It's surprisingly easy to mess up here, so never access
113    an array descriptor by "brute force", always use these
114    functions.  This also avoids problems if we change the format
115    of an array descriptor.
116
117    To understand these magic numbers, look at the comments
118    before gfc_build_array_type() in trans-types.c.
119
120    The code within these defines should be the only code which knows the format
121    of an array descriptor.
122
123    Any code just needing to read obtain the bounds of an array should use
124    gfc_conv_array_* rather than the following functions as these will return
125    know constant values, and work with arrays which do not have descriptors.
126
127    Don't forget to #undef these!  */
128
129 #define DATA_FIELD 0
130 #define OFFSET_FIELD 1
131 #define DTYPE_FIELD 2
132 #define DIMENSION_FIELD 3
133
134 #define STRIDE_SUBFIELD 0
135 #define LBOUND_SUBFIELD 1
136 #define UBOUND_SUBFIELD 2
137
138 /* This provides READ-ONLY access to the data field.  The field itself
139    doesn't have the proper type.  */
140
141 tree
142 gfc_conv_descriptor_data_get (tree desc)
143 {
144   tree field, type, t;
145
146   type = TREE_TYPE (desc);
147   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
148
149   field = TYPE_FIELDS (type);
150   gcc_assert (DATA_FIELD == 0);
151
152   t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
153   t = fold_convert (GFC_TYPE_ARRAY_DATAPTR_TYPE (type), t);
154
155   return t;
156 }
157
158 /* This provides WRITE access to the data field.  */
159
160 void
161 gfc_conv_descriptor_data_set (stmtblock_t *block, tree desc, tree value)
162 {
163   tree field, type, t;
164
165   type = TREE_TYPE (desc);
166   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
167
168   field = TYPE_FIELDS (type);
169   gcc_assert (DATA_FIELD == 0);
170
171   t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
172   gfc_add_modify_expr (block, t, fold_convert (TREE_TYPE (field), value));
173 }
174
175
176 /* This provides address access to the data field.  This should only be
177    used by array allocation, passing this on to the runtime.  */
178
179 tree
180 gfc_conv_descriptor_data_addr (tree desc)
181 {
182   tree field, type, t;
183
184   type = TREE_TYPE (desc);
185   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
186
187   field = TYPE_FIELDS (type);
188   gcc_assert (DATA_FIELD == 0);
189
190   t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
191   return gfc_build_addr_expr (NULL, t);
192 }
193
194 tree
195 gfc_conv_descriptor_offset (tree desc)
196 {
197   tree type;
198   tree field;
199
200   type = TREE_TYPE (desc);
201   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
202
203   field = gfc_advance_chain (TYPE_FIELDS (type), OFFSET_FIELD);
204   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
205
206   return build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
207 }
208
209 tree
210 gfc_conv_descriptor_dtype (tree desc)
211 {
212   tree field;
213   tree type;
214
215   type = TREE_TYPE (desc);
216   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
217
218   field = gfc_advance_chain (TYPE_FIELDS (type), DTYPE_FIELD);
219   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
220
221   return build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
222 }
223
224 static tree
225 gfc_conv_descriptor_dimension (tree desc, tree dim)
226 {
227   tree field;
228   tree type;
229   tree tmp;
230
231   type = TREE_TYPE (desc);
232   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
233
234   field = gfc_advance_chain (TYPE_FIELDS (type), DIMENSION_FIELD);
235   gcc_assert (field != NULL_TREE
236           && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
237           && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE);
238
239   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
240   tmp = gfc_build_array_ref (tmp, dim);
241   return tmp;
242 }
243
244 tree
245 gfc_conv_descriptor_stride (tree desc, tree dim)
246 {
247   tree tmp;
248   tree field;
249
250   tmp = gfc_conv_descriptor_dimension (desc, dim);
251   field = TYPE_FIELDS (TREE_TYPE (tmp));
252   field = gfc_advance_chain (field, STRIDE_SUBFIELD);
253   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
254
255   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
256   return tmp;
257 }
258
259 tree
260 gfc_conv_descriptor_lbound (tree desc, tree dim)
261 {
262   tree tmp;
263   tree field;
264
265   tmp = gfc_conv_descriptor_dimension (desc, dim);
266   field = TYPE_FIELDS (TREE_TYPE (tmp));
267   field = gfc_advance_chain (field, LBOUND_SUBFIELD);
268   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
269
270   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
271   return tmp;
272 }
273
274 tree
275 gfc_conv_descriptor_ubound (tree desc, tree dim)
276 {
277   tree tmp;
278   tree field;
279
280   tmp = gfc_conv_descriptor_dimension (desc, dim);
281   field = TYPE_FIELDS (TREE_TYPE (tmp));
282   field = gfc_advance_chain (field, UBOUND_SUBFIELD);
283   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
284
285   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
286   return tmp;
287 }
288
289
290 /* Build a null array descriptor constructor.  */
291
292 tree
293 gfc_build_null_descriptor (tree type)
294 {
295   tree field;
296   tree tmp;
297
298   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
299   gcc_assert (DATA_FIELD == 0);
300   field = TYPE_FIELDS (type);
301
302   /* Set a NULL data pointer.  */
303   tmp = build_constructor_single (type, field, null_pointer_node);
304   TREE_CONSTANT (tmp) = 1;
305   TREE_INVARIANT (tmp) = 1;
306   /* All other fields are ignored.  */
307
308   return tmp;
309 }
310
311
312 /* Cleanup those #defines.  */
313
314 #undef DATA_FIELD
315 #undef OFFSET_FIELD
316 #undef DTYPE_FIELD
317 #undef DIMENSION_FIELD
318 #undef STRIDE_SUBFIELD
319 #undef LBOUND_SUBFIELD
320 #undef UBOUND_SUBFIELD
321
322
323 /* Mark a SS chain as used.  Flags specifies in which loops the SS is used.
324    flags & 1 = Main loop body.
325    flags & 2 = temp copy loop.  */
326
327 void
328 gfc_mark_ss_chain_used (gfc_ss * ss, unsigned flags)
329 {
330   for (; ss != gfc_ss_terminator; ss = ss->next)
331     ss->useflags = flags;
332 }
333
334 static void gfc_free_ss (gfc_ss *);
335
336
337 /* Free a gfc_ss chain.  */
338
339 static void
340 gfc_free_ss_chain (gfc_ss * ss)
341 {
342   gfc_ss *next;
343
344   while (ss != gfc_ss_terminator)
345     {
346       gcc_assert (ss != NULL);
347       next = ss->next;
348       gfc_free_ss (ss);
349       ss = next;
350     }
351 }
352
353
354 /* Free a SS.  */
355
356 static void
357 gfc_free_ss (gfc_ss * ss)
358 {
359   int n;
360
361   switch (ss->type)
362     {
363     case GFC_SS_SECTION:
364     case GFC_SS_VECTOR:
365       for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
366         {
367           if (ss->data.info.subscript[n])
368             gfc_free_ss_chain (ss->data.info.subscript[n]);
369         }
370       break;
371
372     default:
373       break;
374     }
375
376   gfc_free (ss);
377 }
378
379
380 /* Free all the SS associated with a loop.  */
381
382 void
383 gfc_cleanup_loop (gfc_loopinfo * loop)
384 {
385   gfc_ss *ss;
386   gfc_ss *next;
387
388   ss = loop->ss;
389   while (ss != gfc_ss_terminator)
390     {
391       gcc_assert (ss != NULL);
392       next = ss->loop_chain;
393       gfc_free_ss (ss);
394       ss = next;
395     }
396 }
397
398
399 /* Associate a SS chain with a loop.  */
400
401 void
402 gfc_add_ss_to_loop (gfc_loopinfo * loop, gfc_ss * head)
403 {
404   gfc_ss *ss;
405
406   if (head == gfc_ss_terminator)
407     return;
408
409   ss = head;
410   for (; ss && ss != gfc_ss_terminator; ss = ss->next)
411     {
412       if (ss->next == gfc_ss_terminator)
413         ss->loop_chain = loop->ss;
414       else
415         ss->loop_chain = ss->next;
416     }
417   gcc_assert (ss == gfc_ss_terminator);
418   loop->ss = head;
419 }
420
421
422 /* Generate an initializer for a static pointer or allocatable array.  */
423
424 void
425 gfc_trans_static_array_pointer (gfc_symbol * sym)
426 {
427   tree type;
428
429   gcc_assert (TREE_STATIC (sym->backend_decl));
430   /* Just zero the data member.  */
431   type = TREE_TYPE (sym->backend_decl);
432   DECL_INITIAL (sym->backend_decl) = gfc_build_null_descriptor (type);
433 }
434
435
436 /* If the bounds of SE's loop have not yet been set, see if they can be
437    determined from array spec AS, which is the array spec of a called
438    function.  MAPPING maps the callee's dummy arguments to the values
439    that the caller is passing.  Add any initialization and finalization
440    code to SE.  */
441
442 void
443 gfc_set_loop_bounds_from_array_spec (gfc_interface_mapping * mapping,
444                                      gfc_se * se, gfc_array_spec * as)
445 {
446   int n, dim;
447   gfc_se tmpse;
448   tree lower;
449   tree upper;
450   tree tmp;
451
452   if (as && as->type == AS_EXPLICIT)
453     for (dim = 0; dim < se->loop->dimen; dim++)
454       {
455         n = se->loop->order[dim];
456         if (se->loop->to[n] == NULL_TREE)
457           {
458             /* Evaluate the lower bound.  */
459             gfc_init_se (&tmpse, NULL);
460             gfc_apply_interface_mapping (mapping, &tmpse, as->lower[dim]);
461             gfc_add_block_to_block (&se->pre, &tmpse.pre);
462             gfc_add_block_to_block (&se->post, &tmpse.post);
463             lower = tmpse.expr;
464
465             /* ...and the upper bound.  */
466             gfc_init_se (&tmpse, NULL);
467             gfc_apply_interface_mapping (mapping, &tmpse, as->upper[dim]);
468             gfc_add_block_to_block (&se->pre, &tmpse.pre);
469             gfc_add_block_to_block (&se->post, &tmpse.post);
470             upper = tmpse.expr;
471
472             /* Set the upper bound of the loop to UPPER - LOWER.  */
473             tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, upper, lower);
474             tmp = gfc_evaluate_now (tmp, &se->pre);
475             se->loop->to[n] = tmp;
476           }
477       }
478 }
479
480
481 /* Generate code to allocate an array temporary, or create a variable to
482    hold the data.  If size is NULL zero the descriptor so that so that the
483    callee will allocate the array.  Also generates code to free the array
484    afterwards.
485
486    Initialization code is added to PRE and finalization code to POST.
487    DYNAMIC is true if the caller may want to extend the array later
488    using realloc.  This prevents us from putting the array on the stack.  */
489
490 static void
491 gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
492                                   gfc_ss_info * info, tree size, tree nelem,
493                                   bool dynamic)
494 {
495   tree tmp;
496   tree args;
497   tree desc;
498   bool onstack;
499
500   desc = info->descriptor;
501   info->offset = gfc_index_zero_node;
502   if (size == NULL_TREE || integer_zerop (size))
503     {
504       /* A callee allocated array.  */
505       gfc_conv_descriptor_data_set (pre, desc, null_pointer_node);
506       onstack = FALSE;
507     }
508   else
509     {
510       /* Allocate the temporary.  */
511       onstack = !dynamic && gfc_can_put_var_on_stack (size);
512
513       if (onstack)
514         {
515           /* Make a temporary variable to hold the data.  */
516           tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (nelem), nelem,
517                              integer_one_node);
518           tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
519                                   tmp);
520           tmp = build_array_type (gfc_get_element_type (TREE_TYPE (desc)),
521                                   tmp);
522           tmp = gfc_create_var (tmp, "A");
523           tmp = gfc_build_addr_expr (NULL, tmp);
524           gfc_conv_descriptor_data_set (pre, desc, tmp);
525         }
526       else
527         {
528           /* Allocate memory to hold the data.  */
529           args = gfc_chainon_list (NULL_TREE, size);
530
531           if (gfc_index_integer_kind == 4)
532             tmp = gfor_fndecl_internal_malloc;
533           else if (gfc_index_integer_kind == 8)
534             tmp = gfor_fndecl_internal_malloc64;
535           else
536             gcc_unreachable ();
537           tmp = gfc_build_function_call (tmp, args);
538           tmp = gfc_evaluate_now (tmp, pre);
539           gfc_conv_descriptor_data_set (pre, desc, tmp);
540         }
541     }
542   info->data = gfc_conv_descriptor_data_get (desc);
543
544   /* The offset is zero because we create temporaries with a zero
545      lower bound.  */
546   tmp = gfc_conv_descriptor_offset (desc);
547   gfc_add_modify_expr (pre, tmp, gfc_index_zero_node);
548
549   if (!onstack)
550     {
551       /* Free the temporary.  */
552       tmp = gfc_conv_descriptor_data_get (desc);
553       tmp = fold_convert (pvoid_type_node, tmp);
554       tmp = gfc_chainon_list (NULL_TREE, tmp);
555       tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
556       gfc_add_expr_to_block (post, tmp);
557     }
558 }
559
560
561 /* Generate code to allocate and initialize the descriptor for a temporary
562    array.  This is used for both temporaries needed by the scalarizer, and
563    functions returning arrays.  Adjusts the loop variables to be zero-based,
564    and calculates the loop bounds for callee allocated arrays.
565    Also fills in the descriptor, data and offset fields of info if known.
566    Returns the size of the array, or NULL for a callee allocated array.
567
568    PRE, POST and DYNAMIC are as for gfc_trans_allocate_array_storage.  */
569
570 tree
571 gfc_trans_allocate_temp_array (stmtblock_t * pre, stmtblock_t * post,
572                                gfc_loopinfo * loop, gfc_ss_info * info,
573                                tree eltype, bool dynamic)
574 {
575   tree type;
576   tree desc;
577   tree tmp;
578   tree size;
579   tree nelem;
580   int n;
581   int dim;
582
583   gcc_assert (info->dimen > 0);
584   /* Set the lower bound to zero.  */
585   for (dim = 0; dim < info->dimen; dim++)
586     {
587       n = loop->order[dim];
588       if (n < loop->temp_dim)
589         gcc_assert (integer_zerop (loop->from[n]));
590       else
591         {
592           /* Callee allocated arrays may not have a known bound yet.  */
593           if (loop->to[n])
594               loop->to[n] = fold_build2 (MINUS_EXPR, gfc_array_index_type,
595                                          loop->to[n], loop->from[n]);
596           loop->from[n] = gfc_index_zero_node;
597         }
598
599       info->delta[dim] = gfc_index_zero_node;
600       info->start[dim] = gfc_index_zero_node;
601       info->stride[dim] = gfc_index_one_node;
602       info->dim[dim] = dim;
603     }
604
605   /* Initialize the descriptor.  */
606   type =
607     gfc_get_array_type_bounds (eltype, info->dimen, loop->from, loop->to, 1);
608   desc = gfc_create_var (type, "atmp");
609   GFC_DECL_PACKED_ARRAY (desc) = 1;
610
611   info->descriptor = desc;
612   size = gfc_index_one_node;
613
614   /* Fill in the array dtype.  */
615   tmp = gfc_conv_descriptor_dtype (desc);
616   gfc_add_modify_expr (pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
617
618   /*
619      Fill in the bounds and stride.  This is a packed array, so:
620
621      size = 1;
622      for (n = 0; n < rank; n++)
623        {
624          stride[n] = size
625          delta = ubound[n] + 1 - lbound[n];
626          size = size * delta;
627        }
628      size = size * sizeof(element);
629   */
630
631   for (n = 0; n < info->dimen; n++)
632     {
633       if (loop->to[n] == NULL_TREE)
634         {
635           /* For a callee allocated array express the loop bounds in terms
636              of the descriptor fields.  */
637           tmp = build2 (MINUS_EXPR, gfc_array_index_type,
638                         gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]),
639                         gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]));
640           loop->to[n] = tmp;
641           size = NULL_TREE;
642           continue;
643         }
644         
645       /* Store the stride and bound components in the descriptor.  */
646       tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[n]);
647       gfc_add_modify_expr (pre, tmp, size);
648
649       tmp = gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]);
650       gfc_add_modify_expr (pre, tmp, gfc_index_zero_node);
651
652       tmp = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]);
653       gfc_add_modify_expr (pre, tmp, loop->to[n]);
654
655       tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
656                          loop->to[n], gfc_index_one_node);
657
658       size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
659       size = gfc_evaluate_now (size, pre);
660     }
661
662   /* Get the size of the array.  */
663   nelem = size;
664   if (size)
665     size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
666                         TYPE_SIZE_UNIT (gfc_get_element_type (type)));
667
668   gfc_trans_allocate_array_storage (pre, post, info, size, nelem, dynamic);
669
670   if (info->dimen > loop->temp_dim)
671     loop->temp_dim = info->dimen;
672
673   return size;
674 }
675
676
677 /* Return the number of iterations in a loop that starts at START,
678    ends at END, and has step STEP.  */
679
680 static tree
681 gfc_get_iteration_count (tree start, tree end, tree step)
682 {
683   tree tmp;
684   tree type;
685
686   type = TREE_TYPE (step);
687   tmp = fold_build2 (MINUS_EXPR, type, end, start);
688   tmp = fold_build2 (FLOOR_DIV_EXPR, type, tmp, step);
689   tmp = fold_build2 (PLUS_EXPR, type, tmp, build_int_cst (type, 1));
690   tmp = fold_build2 (MAX_EXPR, type, tmp, build_int_cst (type, 0));
691   return fold_convert (gfc_array_index_type, tmp);
692 }
693
694
695 /* Extend the data in array DESC by EXTRA elements.  */
696
697 static void
698 gfc_grow_array (stmtblock_t * pblock, tree desc, tree extra)
699 {
700   tree args;
701   tree tmp;
702   tree size;
703   tree ubound;
704
705   if (integer_zerop (extra))
706     return;
707
708   ubound = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[0]);
709
710   /* Add EXTRA to the upper bound.  */
711   tmp = build2 (PLUS_EXPR, gfc_array_index_type, ubound, extra);
712   gfc_add_modify_expr (pblock, ubound, tmp);
713
714   /* Get the value of the current data pointer.  */
715   tmp = gfc_conv_descriptor_data_get (desc);
716   args = gfc_chainon_list (NULL_TREE, tmp);
717
718   /* Calculate the new array size.  */
719   size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
720   tmp = build2 (PLUS_EXPR, gfc_array_index_type, ubound, gfc_index_one_node);
721   tmp = build2 (MULT_EXPR, gfc_array_index_type, tmp, size);
722   args = gfc_chainon_list (args, tmp);
723
724   /* Pick the appropriate realloc function.  */
725   if (gfc_index_integer_kind == 4)
726     tmp = gfor_fndecl_internal_realloc;
727   else if (gfc_index_integer_kind == 8)
728     tmp = gfor_fndecl_internal_realloc64;
729   else
730     gcc_unreachable ();
731
732   /* Set the new data pointer.  */
733   tmp = gfc_build_function_call (tmp, args);
734   gfc_conv_descriptor_data_set (pblock, desc, tmp);
735 }
736
737
738 /* Return true if the bounds of iterator I can only be determined
739    at run time.  */
740
741 static inline bool
742 gfc_iterator_has_dynamic_bounds (gfc_iterator * i)
743 {
744   return (i->start->expr_type != EXPR_CONSTANT
745           || i->end->expr_type != EXPR_CONSTANT
746           || i->step->expr_type != EXPR_CONSTANT);
747 }
748
749
750 /* Split the size of constructor element EXPR into the sum of two terms,
751    one of which can be determined at compile time and one of which must
752    be calculated at run time.  Set *SIZE to the former and return true
753    if the latter might be nonzero.  */
754
755 static bool
756 gfc_get_array_constructor_element_size (mpz_t * size, gfc_expr * expr)
757 {
758   if (expr->expr_type == EXPR_ARRAY)
759     return gfc_get_array_constructor_size (size, expr->value.constructor);
760   else if (expr->rank > 0)
761     {
762       /* Calculate everything at run time.  */
763       mpz_set_ui (*size, 0);
764       return true;
765     }
766   else
767     {
768       /* A single element.  */
769       mpz_set_ui (*size, 1);
770       return false;
771     }
772 }
773
774
775 /* Like gfc_get_array_constructor_element_size, but applied to the whole
776    of array constructor C.  */
777
778 static bool
779 gfc_get_array_constructor_size (mpz_t * size, gfc_constructor * c)
780 {
781   gfc_iterator *i;
782   mpz_t val;
783   mpz_t len;
784   bool dynamic;
785
786   mpz_set_ui (*size, 0);
787   mpz_init (len);
788   mpz_init (val);
789
790   dynamic = false;
791   for (; c; c = c->next)
792     {
793       i = c->iterator;
794       if (i && gfc_iterator_has_dynamic_bounds (i))
795         dynamic = true;
796       else
797         {
798           dynamic |= gfc_get_array_constructor_element_size (&len, c->expr);
799           if (i)
800             {
801               /* Multiply the static part of the element size by the
802                  number of iterations.  */
803               mpz_sub (val, i->end->value.integer, i->start->value.integer);
804               mpz_fdiv_q (val, val, i->step->value.integer);
805               mpz_add_ui (val, val, 1);
806               if (mpz_sgn (val) > 0)
807                 mpz_mul (len, len, val);
808               else
809                 mpz_set_ui (len, 0);
810             }
811           mpz_add (*size, *size, len);
812         }
813     }
814   mpz_clear (len);
815   mpz_clear (val);
816   return dynamic;
817 }
818
819
820 /* Make sure offset is a variable.  */
821
822 static void
823 gfc_put_offset_into_var (stmtblock_t * pblock, tree * poffset,
824                          tree * offsetvar)
825 {
826   /* We should have already created the offset variable.  We cannot
827      create it here because we may be in an inner scope.  */
828   gcc_assert (*offsetvar != NULL_TREE);
829   gfc_add_modify_expr (pblock, *offsetvar, *poffset);
830   *poffset = *offsetvar;
831   TREE_USED (*offsetvar) = 1;
832 }
833
834
835 /* Assign an element of an array constructor.  */
836
837 static void
838 gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc,
839                               tree offset, gfc_se * se, gfc_expr * expr)
840 {
841   tree tmp;
842   tree args;
843
844   gfc_conv_expr (se, expr);
845
846   /* Store the value.  */
847   tmp = gfc_build_indirect_ref (gfc_conv_descriptor_data_get (desc));
848   tmp = gfc_build_array_ref (tmp, offset);
849   if (expr->ts.type == BT_CHARACTER)
850     {
851       gfc_conv_string_parameter (se);
852       if (POINTER_TYPE_P (TREE_TYPE (tmp)))
853         {
854           /* The temporary is an array of pointers.  */
855           se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
856           gfc_add_modify_expr (&se->pre, tmp, se->expr);
857         }
858       else
859         {
860           /* The temporary is an array of string values.  */
861           tmp = gfc_build_addr_expr (pchar_type_node, tmp);
862           /* We know the temporary and the value will be the same length,
863              so can use memcpy.  */
864           args = gfc_chainon_list (NULL_TREE, tmp);
865           args = gfc_chainon_list (args, se->expr);
866           args = gfc_chainon_list (args, se->string_length);
867           tmp = built_in_decls[BUILT_IN_MEMCPY];
868           tmp = gfc_build_function_call (tmp, args);
869           gfc_add_expr_to_block (&se->pre, tmp);
870         }
871     }
872   else
873     {
874       /* TODO: Should the frontend already have done this conversion?  */
875       se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
876       gfc_add_modify_expr (&se->pre, tmp, se->expr);
877     }
878
879   gfc_add_block_to_block (pblock, &se->pre);
880   gfc_add_block_to_block (pblock, &se->post);
881 }
882
883
884 /* Add the contents of an array to the constructor.  DYNAMIC is as for
885    gfc_trans_array_constructor_value.  */
886
887 static void
888 gfc_trans_array_constructor_subarray (stmtblock_t * pblock,
889                                       tree type ATTRIBUTE_UNUSED,
890                                       tree desc, gfc_expr * expr,
891                                       tree * poffset, tree * offsetvar,
892                                       bool dynamic)
893 {
894   gfc_se se;
895   gfc_ss *ss;
896   gfc_loopinfo loop;
897   stmtblock_t body;
898   tree tmp;
899   tree size;
900   int n;
901
902   /* We need this to be a variable so we can increment it.  */
903   gfc_put_offset_into_var (pblock, poffset, offsetvar);
904
905   gfc_init_se (&se, NULL);
906
907   /* Walk the array expression.  */
908   ss = gfc_walk_expr (expr);
909   gcc_assert (ss != gfc_ss_terminator);
910
911   /* Initialize the scalarizer.  */
912   gfc_init_loopinfo (&loop);
913   gfc_add_ss_to_loop (&loop, ss);
914
915   /* Initialize the loop.  */
916   gfc_conv_ss_startstride (&loop);
917   gfc_conv_loop_setup (&loop);
918
919   /* Make sure the constructed array has room for the new data.  */
920   if (dynamic)
921     {
922       /* Set SIZE to the total number of elements in the subarray.  */
923       size = gfc_index_one_node;
924       for (n = 0; n < loop.dimen; n++)
925         {
926           tmp = gfc_get_iteration_count (loop.from[n], loop.to[n],
927                                          gfc_index_one_node);
928           size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
929         }
930
931       /* Grow the constructed array by SIZE elements.  */
932       gfc_grow_array (&loop.pre, desc, size);
933     }
934
935   /* Make the loop body.  */
936   gfc_mark_ss_chain_used (ss, 1);
937   gfc_start_scalarized_body (&loop, &body);
938   gfc_copy_loopinfo_to_se (&se, &loop);
939   se.ss = ss;
940
941   if (expr->ts.type == BT_CHARACTER)
942     gfc_todo_error ("character arrays in constructors");
943
944   gfc_trans_array_ctor_element (&body, desc, *poffset, &se, expr);
945   gcc_assert (se.ss == gfc_ss_terminator);
946
947   /* Increment the offset.  */
948   tmp = build2 (PLUS_EXPR, gfc_array_index_type, *poffset, gfc_index_one_node);
949   gfc_add_modify_expr (&body, *poffset, tmp);
950
951   /* Finish the loop.  */
952   gfc_trans_scalarizing_loops (&loop, &body);
953   gfc_add_block_to_block (&loop.pre, &loop.post);
954   tmp = gfc_finish_block (&loop.pre);
955   gfc_add_expr_to_block (pblock, tmp);
956
957   gfc_cleanup_loop (&loop);
958 }
959
960
961 /* Assign the values to the elements of an array constructor.  DYNAMIC
962    is true if descriptor DESC only contains enough data for the static
963    size calculated by gfc_get_array_constructor_size.  When true, memory
964    for the dynamic parts must be allocated using realloc.  */
965
966 static void
967 gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
968                                    tree desc, gfc_constructor * c,
969                                    tree * poffset, tree * offsetvar,
970                                    bool dynamic)
971 {
972   tree tmp;
973   stmtblock_t body;
974   gfc_se se;
975   mpz_t size;
976
977   mpz_init (size);
978   for (; c; c = c->next)
979     {
980       /* If this is an iterator or an array, the offset must be a variable.  */
981       if ((c->iterator || c->expr->rank > 0) && INTEGER_CST_P (*poffset))
982         gfc_put_offset_into_var (pblock, poffset, offsetvar);
983
984       gfc_start_block (&body);
985
986       if (c->expr->expr_type == EXPR_ARRAY)
987         {
988           /* Array constructors can be nested.  */
989           gfc_trans_array_constructor_value (&body, type, desc,
990                                              c->expr->value.constructor,
991                                              poffset, offsetvar, dynamic);
992         }
993       else if (c->expr->rank > 0)
994         {
995           gfc_trans_array_constructor_subarray (&body, type, desc, c->expr,
996                                                 poffset, offsetvar, dynamic);
997         }
998       else
999         {
1000           /* This code really upsets the gimplifier so don't bother for now.  */
1001           gfc_constructor *p;
1002           HOST_WIDE_INT n;
1003           HOST_WIDE_INT size;
1004
1005           p = c;
1006           n = 0;
1007           while (p && !(p->iterator || p->expr->expr_type != EXPR_CONSTANT))
1008             {
1009               p = p->next;
1010               n++;
1011             }
1012           if (n < 4)
1013             {
1014               /* Scalar values.  */
1015               gfc_init_se (&se, NULL);
1016               gfc_trans_array_ctor_element (&body, desc, *poffset,
1017                                             &se, c->expr);
1018
1019               *poffset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1020                                       *poffset, gfc_index_one_node);
1021             }
1022           else
1023             {
1024               /* Collect multiple scalar constants into a constructor.  */
1025               tree list;
1026               tree init;
1027               tree bound;
1028               tree tmptype;
1029
1030               p = c;
1031               list = NULL_TREE;
1032               /* Count the number of consecutive scalar constants.  */
1033               while (p && !(p->iterator
1034                             || p->expr->expr_type != EXPR_CONSTANT))
1035                 {
1036                   gfc_init_se (&se, NULL);
1037                   gfc_conv_constant (&se, p->expr);
1038                   if (p->expr->ts.type == BT_CHARACTER
1039                       && POINTER_TYPE_P (type))
1040                     {
1041                       /* For constant character array constructors we build
1042                          an array of pointers.  */
1043                       se.expr = gfc_build_addr_expr (pchar_type_node,
1044                                                      se.expr);
1045                     }
1046                     
1047                   list = tree_cons (NULL_TREE, se.expr, list);
1048                   c = p;
1049                   p = p->next;
1050                 }
1051
1052               bound = build_int_cst (NULL_TREE, n - 1);
1053               /* Create an array type to hold them.  */
1054               tmptype = build_range_type (gfc_array_index_type,
1055                                           gfc_index_zero_node, bound);
1056               tmptype = build_array_type (type, tmptype);
1057
1058               init = build_constructor_from_list (tmptype, nreverse (list));
1059               TREE_CONSTANT (init) = 1;
1060               TREE_INVARIANT (init) = 1;
1061               TREE_STATIC (init) = 1;
1062               /* Create a static variable to hold the data.  */
1063               tmp = gfc_create_var (tmptype, "data");
1064               TREE_STATIC (tmp) = 1;
1065               TREE_CONSTANT (tmp) = 1;
1066               TREE_INVARIANT (tmp) = 1;
1067               DECL_INITIAL (tmp) = init;
1068               init = tmp;
1069
1070               /* Use BUILTIN_MEMCPY to assign the values.  */
1071               tmp = gfc_conv_descriptor_data_get (desc);
1072               tmp = gfc_build_indirect_ref (tmp);
1073               tmp = gfc_build_array_ref (tmp, *poffset);
1074               tmp = gfc_build_addr_expr (NULL, tmp);
1075               init = gfc_build_addr_expr (NULL, init);
1076
1077               size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
1078               bound = build_int_cst (NULL_TREE, n * size);
1079               tmp = gfc_chainon_list (NULL_TREE, tmp);
1080               tmp = gfc_chainon_list (tmp, init);
1081               tmp = gfc_chainon_list (tmp, bound);
1082               tmp = gfc_build_function_call (built_in_decls[BUILT_IN_MEMCPY],
1083                                              tmp);
1084               gfc_add_expr_to_block (&body, tmp);
1085
1086               *poffset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1087                                       *poffset, build_int_cst (NULL_TREE, n));
1088             }
1089           if (!INTEGER_CST_P (*poffset))
1090             {
1091               gfc_add_modify_expr (&body, *offsetvar, *poffset);
1092               *poffset = *offsetvar;
1093             }
1094         }
1095
1096       /* The frontend should already have done any expansions possible
1097          at compile-time.  */
1098       if (!c->iterator)
1099         {
1100           /* Pass the code as is.  */
1101           tmp = gfc_finish_block (&body);
1102           gfc_add_expr_to_block (pblock, tmp);
1103         }
1104       else
1105         {
1106           /* Build the implied do-loop.  */
1107           tree cond;
1108           tree end;
1109           tree step;
1110           tree loopvar;
1111           tree exit_label;
1112           tree loopbody;
1113           tree tmp2;
1114
1115           loopbody = gfc_finish_block (&body);
1116
1117           gfc_init_se (&se, NULL);
1118           gfc_conv_expr (&se, c->iterator->var);
1119           gfc_add_block_to_block (pblock, &se.pre);
1120           loopvar = se.expr;
1121
1122           /* Initialize the loop.  */
1123           gfc_init_se (&se, NULL);
1124           gfc_conv_expr_val (&se, c->iterator->start);
1125           gfc_add_block_to_block (pblock, &se.pre);
1126           gfc_add_modify_expr (pblock, loopvar, se.expr);
1127
1128           gfc_init_se (&se, NULL);
1129           gfc_conv_expr_val (&se, c->iterator->end);
1130           gfc_add_block_to_block (pblock, &se.pre);
1131           end = gfc_evaluate_now (se.expr, pblock);
1132
1133           gfc_init_se (&se, NULL);
1134           gfc_conv_expr_val (&se, c->iterator->step);
1135           gfc_add_block_to_block (pblock, &se.pre);
1136           step = gfc_evaluate_now (se.expr, pblock);
1137
1138           /* If this array expands dynamically, and the number of iterations
1139              is not constant, we won't have allocated space for the static
1140              part of C->EXPR's size.  Do that now.  */
1141           if (dynamic && gfc_iterator_has_dynamic_bounds (c->iterator))
1142             {
1143               /* Get the number of iterations.  */
1144               tmp = gfc_get_iteration_count (loopvar, end, step);
1145
1146               /* Get the static part of C->EXPR's size.  */
1147               gfc_get_array_constructor_element_size (&size, c->expr);
1148               tmp2 = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1149
1150               /* Grow the array by TMP * TMP2 elements.  */
1151               tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp, tmp2);
1152               gfc_grow_array (pblock, desc, tmp);
1153             }
1154
1155           /* Generate the loop body.  */
1156           exit_label = gfc_build_label_decl (NULL_TREE);
1157           gfc_start_block (&body);
1158
1159           /* Generate the exit condition.  Depending on the sign of
1160              the step variable we have to generate the correct
1161              comparison.  */
1162           tmp = fold_build2 (GT_EXPR, boolean_type_node, step, 
1163                              build_int_cst (TREE_TYPE (step), 0));
1164           cond = fold_build3 (COND_EXPR, boolean_type_node, tmp,
1165                               build2 (GT_EXPR, boolean_type_node,
1166                                       loopvar, end),
1167                               build2 (LT_EXPR, boolean_type_node,
1168                                       loopvar, end));
1169           tmp = build1_v (GOTO_EXPR, exit_label);
1170           TREE_USED (exit_label) = 1;
1171           tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1172           gfc_add_expr_to_block (&body, tmp);
1173
1174           /* The main loop body.  */
1175           gfc_add_expr_to_block (&body, loopbody);
1176
1177           /* Increase loop variable by step.  */
1178           tmp = build2 (PLUS_EXPR, TREE_TYPE (loopvar), loopvar, step);
1179           gfc_add_modify_expr (&body, loopvar, tmp);
1180
1181           /* Finish the loop.  */
1182           tmp = gfc_finish_block (&body);
1183           tmp = build1_v (LOOP_EXPR, tmp);
1184           gfc_add_expr_to_block (pblock, tmp);
1185
1186           /* Add the exit label.  */
1187           tmp = build1_v (LABEL_EXPR, exit_label);
1188           gfc_add_expr_to_block (pblock, tmp);
1189         }
1190     }
1191   mpz_clear (size);
1192 }
1193
1194
1195 /* Figure out the string length of a variable reference expression.
1196    Used by get_array_ctor_strlen.  */
1197
1198 static void
1199 get_array_ctor_var_strlen (gfc_expr * expr, tree * len)
1200 {
1201   gfc_ref *ref;
1202   gfc_typespec *ts;
1203
1204   /* Don't bother if we already know the length is a constant.  */
1205   if (*len && INTEGER_CST_P (*len))
1206     return;
1207
1208   ts = &expr->symtree->n.sym->ts;
1209   for (ref = expr->ref; ref; ref = ref->next)
1210     {
1211       switch (ref->type)
1212         {
1213         case REF_ARRAY:
1214           /* Array references don't change the string length.  */
1215           break;
1216
1217         case COMPONENT_REF:
1218           /* Use the length of the component.  */
1219           ts = &ref->u.c.component->ts;
1220           break;
1221
1222         default:
1223           /* TODO: Substrings are tricky because we can't evaluate the
1224              expression more than once.  For now we just give up, and hope
1225              we can figure it out elsewhere.  */
1226           return;
1227         }
1228     }
1229
1230   *len = ts->cl->backend_decl;
1231 }
1232
1233
1234 /* Figure out the string length of a character array constructor.
1235    Returns TRUE if all elements are character constants.  */
1236
1237 static bool
1238 get_array_ctor_strlen (gfc_constructor * c, tree * len)
1239 {
1240   bool is_const;
1241   
1242   is_const = TRUE;
1243   for (; c; c = c->next)
1244     {
1245       switch (c->expr->expr_type)
1246         {
1247         case EXPR_CONSTANT:
1248           if (!(*len && INTEGER_CST_P (*len)))
1249             *len = build_int_cstu (gfc_charlen_type_node,
1250                                    c->expr->value.character.length);
1251           break;
1252
1253         case EXPR_ARRAY:
1254           if (!get_array_ctor_strlen (c->expr->value.constructor, len))
1255             is_const = FALSE;
1256           break;
1257
1258         case EXPR_VARIABLE:
1259           is_const = false;
1260           get_array_ctor_var_strlen (c->expr, len);
1261           break;
1262
1263         default:
1264           is_const = FALSE;
1265           /* TODO: For now we just ignore anything we don't know how to
1266              handle, and hope we can figure it out a different way.  */
1267           break;
1268         }
1269     }
1270
1271   return is_const;
1272 }
1273
1274
1275 /* Array constructors are handled by constructing a temporary, then using that
1276    within the scalarization loop.  This is not optimal, but seems by far the
1277    simplest method.  */
1278
1279 static void
1280 gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss)
1281 {
1282   gfc_constructor *c;
1283   tree offset;
1284   tree offsetvar;
1285   tree desc;
1286   tree type;
1287   bool const_string;
1288   bool dynamic;
1289
1290   ss->data.info.dimen = loop->dimen;
1291
1292   c = ss->expr->value.constructor;
1293   if (ss->expr->ts.type == BT_CHARACTER)
1294     {
1295       const_string = get_array_ctor_strlen (c, &ss->string_length);
1296       if (!ss->string_length)
1297         gfc_todo_error ("complex character array constructors");
1298
1299       type = gfc_get_character_type_len (ss->expr->ts.kind, ss->string_length);
1300       if (const_string)
1301         type = build_pointer_type (type);
1302     }
1303   else
1304     {
1305       const_string = TRUE;
1306       type = gfc_typenode_for_spec (&ss->expr->ts);
1307     }
1308
1309   /* See if the constructor determines the loop bounds.  */
1310   dynamic = false;
1311   if (loop->to[0] == NULL_TREE)
1312     {
1313       mpz_t size;
1314
1315       /* We should have a 1-dimensional, zero-based loop.  */
1316       gcc_assert (loop->dimen == 1);
1317       gcc_assert (integer_zerop (loop->from[0]));
1318
1319       /* Split the constructor size into a static part and a dynamic part.
1320          Allocate the static size up-front and record whether the dynamic
1321          size might be nonzero.  */
1322       mpz_init (size);
1323       dynamic = gfc_get_array_constructor_size (&size, c);
1324       mpz_sub_ui (size, size, 1);
1325       loop->to[0] = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1326       mpz_clear (size);
1327     }
1328
1329   gfc_trans_allocate_temp_array (&loop->pre, &loop->post, loop,
1330                                  &ss->data.info, type, dynamic);
1331
1332   desc = ss->data.info.descriptor;
1333   offset = gfc_index_zero_node;
1334   offsetvar = gfc_create_var_np (gfc_array_index_type, "offset");
1335   TREE_USED (offsetvar) = 0;
1336   gfc_trans_array_constructor_value (&loop->pre, type, desc, c,
1337                                      &offset, &offsetvar, dynamic);
1338
1339   /* If the array grows dynamically, the upper bound of the loop variable
1340      is determined by the array's final upper bound.  */
1341   if (dynamic)
1342     loop->to[0] = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[0]);
1343
1344   if (TREE_USED (offsetvar))
1345     pushdecl (offsetvar);
1346   else
1347     gcc_assert (INTEGER_CST_P (offset));
1348 #if 0
1349   /* Disable bound checking for now because it's probably broken.  */
1350   if (flag_bounds_check)
1351     {
1352       gcc_unreachable ();
1353     }
1354 #endif
1355 }
1356
1357
1358 /* Add the pre and post chains for all the scalar expressions in a SS chain
1359    to loop.  This is called after the loop parameters have been calculated,
1360    but before the actual scalarizing loops.  */
1361
1362 static void
1363 gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript)
1364 {
1365   gfc_se se;
1366   int n;
1367
1368   /* TODO: This can generate bad code if there are ordering dependencies.
1369      eg. a callee allocated function and an unknown size constructor.  */
1370   gcc_assert (ss != NULL);
1371
1372   for (; ss != gfc_ss_terminator; ss = ss->loop_chain)
1373     {
1374       gcc_assert (ss);
1375
1376       switch (ss->type)
1377         {
1378         case GFC_SS_SCALAR:
1379           /* Scalar expression.  Evaluate this now.  This includes elemental
1380              dimension indices, but not array section bounds.  */
1381           gfc_init_se (&se, NULL);
1382           gfc_conv_expr (&se, ss->expr);
1383           gfc_add_block_to_block (&loop->pre, &se.pre);
1384
1385           if (ss->expr->ts.type != BT_CHARACTER)
1386             {
1387               /* Move the evaluation of scalar expressions outside the
1388                  scalarization loop.  */
1389               if (subscript)
1390                 se.expr = convert(gfc_array_index_type, se.expr);
1391               se.expr = gfc_evaluate_now (se.expr, &loop->pre);
1392               gfc_add_block_to_block (&loop->pre, &se.post);
1393             }
1394           else
1395             gfc_add_block_to_block (&loop->post, &se.post);
1396
1397           ss->data.scalar.expr = se.expr;
1398           ss->string_length = se.string_length;
1399           break;
1400
1401         case GFC_SS_REFERENCE:
1402           /* Scalar reference.  Evaluate this now.  */
1403           gfc_init_se (&se, NULL);
1404           gfc_conv_expr_reference (&se, ss->expr);
1405           gfc_add_block_to_block (&loop->pre, &se.pre);
1406           gfc_add_block_to_block (&loop->post, &se.post);
1407
1408           ss->data.scalar.expr = gfc_evaluate_now (se.expr, &loop->pre);
1409           ss->string_length = se.string_length;
1410           break;
1411
1412         case GFC_SS_SECTION:
1413         case GFC_SS_VECTOR:
1414           /* Scalarized expression.  Evaluate any scalar subscripts.  */
1415           for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1416             {
1417               /* Add the expressions for scalar subscripts.  */
1418               if (ss->data.info.subscript[n])
1419                 gfc_add_loop_ss_code (loop, ss->data.info.subscript[n], true);
1420             }
1421           break;
1422
1423         case GFC_SS_INTRINSIC:
1424           gfc_add_intrinsic_ss_code (loop, ss);
1425           break;
1426
1427         case GFC_SS_FUNCTION:
1428           /* Array function return value.  We call the function and save its
1429              result in a temporary for use inside the loop.  */
1430           gfc_init_se (&se, NULL);
1431           se.loop = loop;
1432           se.ss = ss;
1433           gfc_conv_expr (&se, ss->expr);
1434           gfc_add_block_to_block (&loop->pre, &se.pre);
1435           gfc_add_block_to_block (&loop->post, &se.post);
1436           ss->string_length = se.string_length;
1437           break;
1438
1439         case GFC_SS_CONSTRUCTOR:
1440           gfc_trans_array_constructor (loop, ss);
1441           break;
1442
1443         case GFC_SS_TEMP:
1444         case GFC_SS_COMPONENT:
1445           /* Do nothing.  These are handled elsewhere.  */
1446           break;
1447
1448         default:
1449           gcc_unreachable ();
1450         }
1451     }
1452 }
1453
1454
1455 /* Translate expressions for the descriptor and data pointer of a SS.  */
1456 /*GCC ARRAYS*/
1457
1458 static void
1459 gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)
1460 {
1461   gfc_se se;
1462   tree tmp;
1463
1464   /* Get the descriptor for the array to be scalarized.  */
1465   gcc_assert (ss->expr->expr_type == EXPR_VARIABLE);
1466   gfc_init_se (&se, NULL);
1467   se.descriptor_only = 1;
1468   gfc_conv_expr_lhs (&se, ss->expr);
1469   gfc_add_block_to_block (block, &se.pre);
1470   ss->data.info.descriptor = se.expr;
1471   ss->string_length = se.string_length;
1472
1473   if (base)
1474     {
1475       /* Also the data pointer.  */
1476       tmp = gfc_conv_array_data (se.expr);
1477       /* If this is a variable or address of a variable we use it directly.
1478          Otherwise we must evaluate it now to avoid breaking dependency
1479          analysis by pulling the expressions for elemental array indices
1480          inside the loop.  */
1481       if (!(DECL_P (tmp)
1482             || (TREE_CODE (tmp) == ADDR_EXPR
1483                 && DECL_P (TREE_OPERAND (tmp, 0)))))
1484         tmp = gfc_evaluate_now (tmp, block);
1485       ss->data.info.data = tmp;
1486
1487       tmp = gfc_conv_array_offset (se.expr);
1488       ss->data.info.offset = gfc_evaluate_now (tmp, block);
1489     }
1490 }
1491
1492
1493 /* Initialize a gfc_loopinfo structure.  */
1494
1495 void
1496 gfc_init_loopinfo (gfc_loopinfo * loop)
1497 {
1498   int n;
1499
1500   memset (loop, 0, sizeof (gfc_loopinfo));
1501   gfc_init_block (&loop->pre);
1502   gfc_init_block (&loop->post);
1503
1504   /* Initially scalarize in order.  */
1505   for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1506     loop->order[n] = n;
1507
1508   loop->ss = gfc_ss_terminator;
1509 }
1510
1511
1512 /* Copies the loop variable info to a gfc_se structure. Does not copy the SS
1513    chain.  */
1514
1515 void
1516 gfc_copy_loopinfo_to_se (gfc_se * se, gfc_loopinfo * loop)
1517 {
1518   se->loop = loop;
1519 }
1520
1521
1522 /* Return an expression for the data pointer of an array.  */
1523
1524 tree
1525 gfc_conv_array_data (tree descriptor)
1526 {
1527   tree type;
1528
1529   type = TREE_TYPE (descriptor);
1530   if (GFC_ARRAY_TYPE_P (type))
1531     {
1532       if (TREE_CODE (type) == POINTER_TYPE)
1533         return descriptor;
1534       else
1535         {
1536           /* Descriptorless arrays.  */
1537           return gfc_build_addr_expr (NULL, descriptor);
1538         }
1539     }
1540   else
1541     return gfc_conv_descriptor_data_get (descriptor);
1542 }
1543
1544
1545 /* Return an expression for the base offset of an array.  */
1546
1547 tree
1548 gfc_conv_array_offset (tree descriptor)
1549 {
1550   tree type;
1551
1552   type = TREE_TYPE (descriptor);
1553   if (GFC_ARRAY_TYPE_P (type))
1554     return GFC_TYPE_ARRAY_OFFSET (type);
1555   else
1556     return gfc_conv_descriptor_offset (descriptor);
1557 }
1558
1559
1560 /* Get an expression for the array stride.  */
1561
1562 tree
1563 gfc_conv_array_stride (tree descriptor, int dim)
1564 {
1565   tree tmp;
1566   tree type;
1567
1568   type = TREE_TYPE (descriptor);
1569
1570   /* For descriptorless arrays use the array size.  */
1571   tmp = GFC_TYPE_ARRAY_STRIDE (type, dim);
1572   if (tmp != NULL_TREE)
1573     return tmp;
1574
1575   tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[dim]);
1576   return tmp;
1577 }
1578
1579
1580 /* Like gfc_conv_array_stride, but for the lower bound.  */
1581
1582 tree
1583 gfc_conv_array_lbound (tree descriptor, int dim)
1584 {
1585   tree tmp;
1586   tree type;
1587
1588   type = TREE_TYPE (descriptor);
1589
1590   tmp = GFC_TYPE_ARRAY_LBOUND (type, dim);
1591   if (tmp != NULL_TREE)
1592     return tmp;
1593
1594   tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[dim]);
1595   return tmp;
1596 }
1597
1598
1599 /* Like gfc_conv_array_stride, but for the upper bound.  */
1600
1601 tree
1602 gfc_conv_array_ubound (tree descriptor, int dim)
1603 {
1604   tree tmp;
1605   tree type;
1606
1607   type = TREE_TYPE (descriptor);
1608
1609   tmp = GFC_TYPE_ARRAY_UBOUND (type, dim);
1610   if (tmp != NULL_TREE)
1611     return tmp;
1612
1613   /* This should only ever happen when passing an assumed shape array
1614      as an actual parameter.  The value will never be used.  */
1615   if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor)))
1616     return gfc_index_zero_node;
1617
1618   tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[dim]);
1619   return tmp;
1620 }
1621
1622
1623 /* Translate an array reference.  The descriptor should be in se->expr.
1624    Do not use this function, it wil be removed soon.  */
1625 /*GCC ARRAYS*/
1626
1627 static void
1628 gfc_conv_array_index_ref (gfc_se * se, tree pointer, tree * indices,
1629                          tree offset, int dimen)
1630 {
1631   tree array;
1632   tree tmp;
1633   tree index;
1634   int n;
1635
1636   array = gfc_build_indirect_ref (pointer);
1637
1638   index = offset;
1639   for (n = 0; n < dimen; n++)
1640     {
1641       /* index = index + stride[n]*indices[n] */
1642       tmp = gfc_conv_array_stride (se->expr, n);
1643       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, indices[n], tmp);
1644
1645       index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
1646     }
1647
1648   /* Result = data[index].  */
1649   tmp = gfc_build_array_ref (array, index);
1650
1651   /* Check we've used the correct number of dimensions.  */
1652   gcc_assert (TREE_CODE (TREE_TYPE (tmp)) != ARRAY_TYPE);
1653
1654   se->expr = tmp;
1655 }
1656
1657
1658 /* Generate code to perform an array index bound check.  */
1659
1660 static tree
1661 gfc_trans_array_bound_check (gfc_se * se, tree descriptor, tree index, int n)
1662 {
1663   tree cond;
1664   tree fault;
1665   tree tmp;
1666
1667   if (!flag_bounds_check)
1668     return index;
1669
1670   index = gfc_evaluate_now (index, &se->pre);
1671   /* Check lower bound.  */
1672   tmp = gfc_conv_array_lbound (descriptor, n);
1673   fault = fold_build2 (LT_EXPR, boolean_type_node, index, tmp);
1674   /* Check upper bound.  */
1675   tmp = gfc_conv_array_ubound (descriptor, n);
1676   cond = fold_build2 (GT_EXPR, boolean_type_node, index, tmp);
1677   fault = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault, cond);
1678
1679   gfc_trans_runtime_check (fault, gfc_strconst_fault, &se->pre);
1680
1681   return index;
1682 }
1683
1684
1685 /* A reference to an array vector subscript.  Uses recursion to handle nested
1686    vector subscripts.  */
1687
1688 static tree
1689 gfc_conv_vector_array_index (gfc_se * se, tree index, gfc_ss * ss)
1690 {
1691   tree descsave;
1692   tree indices[GFC_MAX_DIMENSIONS];
1693   gfc_array_ref *ar;
1694   gfc_ss_info *info;
1695   int n;
1696
1697   gcc_assert (ss && ss->type == GFC_SS_VECTOR);
1698
1699   /* Save the descriptor.  */
1700   descsave = se->expr;
1701   info = &ss->data.info;
1702   se->expr = info->descriptor;
1703
1704   ar = &info->ref->u.ar;
1705   for (n = 0; n < ar->dimen; n++)
1706     {
1707       switch (ar->dimen_type[n])
1708         {
1709         case DIMEN_ELEMENT:
1710           gcc_assert (info->subscript[n] != gfc_ss_terminator
1711                   && info->subscript[n]->type == GFC_SS_SCALAR);
1712           indices[n] = info->subscript[n]->data.scalar.expr;
1713           break;
1714
1715         case DIMEN_RANGE:
1716           indices[n] = index;
1717           break;
1718
1719         case DIMEN_VECTOR:
1720           index = gfc_conv_vector_array_index (se, index, info->subscript[n]);
1721
1722           indices[n] =
1723             gfc_trans_array_bound_check (se, info->descriptor, index, n);
1724           break;
1725
1726         default:
1727           gcc_unreachable ();
1728         }
1729     }
1730   /* Get the index from the vector.  */
1731   gfc_conv_array_index_ref (se, info->data, indices, info->offset, ar->dimen);
1732   index = se->expr;
1733   /* Put the descriptor back.  */
1734   se->expr = descsave;
1735
1736   return index;
1737 }
1738
1739
1740 /* Return the offset for an index.  Performs bound checking for elemental
1741    dimensions.  Single element references are processed separately.  */
1742
1743 static tree
1744 gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i,
1745                              gfc_array_ref * ar, tree stride)
1746 {
1747   tree index;
1748
1749   /* Get the index into the array for this dimension.  */
1750   if (ar)
1751     {
1752       gcc_assert (ar->type != AR_ELEMENT);
1753       if (ar->dimen_type[dim] == DIMEN_ELEMENT)
1754         {
1755           gcc_assert (i == -1);
1756           /* Elemental dimension.  */
1757           gcc_assert (info->subscript[dim]
1758                   && info->subscript[dim]->type == GFC_SS_SCALAR);
1759           /* We've already translated this value outside the loop.  */
1760           index = info->subscript[dim]->data.scalar.expr;
1761
1762           index =
1763             gfc_trans_array_bound_check (se, info->descriptor, index, dim);
1764         }
1765       else
1766         {
1767           /* Scalarized dimension.  */
1768           gcc_assert (info && se->loop);
1769
1770           /* Multiply the loop variable by the stride and delta.  */
1771           index = se->loop->loopvar[i];
1772           index = fold_build2 (MULT_EXPR, gfc_array_index_type, index,
1773                                info->stride[i]);
1774           index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index,
1775                                info->delta[i]);
1776
1777           if (ar->dimen_type[dim] == DIMEN_VECTOR)
1778             {
1779               /* Handle vector subscripts.  */
1780               index = gfc_conv_vector_array_index (se, index,
1781                                                    info->subscript[dim]);
1782               index =
1783                 gfc_trans_array_bound_check (se, info->descriptor, index,
1784                                              dim);
1785             }
1786           else
1787             gcc_assert (ar->dimen_type[dim] == DIMEN_RANGE);
1788         }
1789     }
1790   else
1791     {
1792       /* Temporary array or derived type component.  */
1793       gcc_assert (se->loop);
1794       index = se->loop->loopvar[se->loop->order[i]];
1795       if (!integer_zerop (info->delta[i]))
1796         index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1797                              index, info->delta[i]);
1798     }
1799
1800   /* Multiply by the stride.  */
1801   index = fold_build2 (MULT_EXPR, gfc_array_index_type, index, stride);
1802
1803   return index;
1804 }
1805
1806
1807 /* Build a scalarized reference to an array.  */
1808
1809 static void
1810 gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
1811 {
1812   gfc_ss_info *info;
1813   tree index;
1814   tree tmp;
1815   int n;
1816
1817   info = &se->ss->data.info;
1818   if (ar)
1819     n = se->loop->order[0];
1820   else
1821     n = 0;
1822
1823   index = gfc_conv_array_index_offset (se, info, info->dim[n], n, ar,
1824                                        info->stride0);
1825   /* Add the offset for this dimension to the stored offset for all other
1826      dimensions.  */
1827   index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, info->offset);
1828
1829   tmp = gfc_build_indirect_ref (info->data);
1830   se->expr = gfc_build_array_ref (tmp, index);
1831 }
1832
1833
1834 /* Translate access of temporary array.  */
1835
1836 void
1837 gfc_conv_tmp_array_ref (gfc_se * se)
1838 {
1839   se->string_length = se->ss->string_length;
1840   gfc_conv_scalarized_array_ref (se, NULL);
1841 }
1842
1843
1844 /* Build an array reference.  se->expr already holds the array descriptor.
1845    This should be either a variable, indirect variable reference or component
1846    reference.  For arrays which do not have a descriptor, se->expr will be
1847    the data pointer.
1848    a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
1849
1850 void
1851 gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar)
1852 {
1853   int n;
1854   tree index;
1855   tree tmp;
1856   tree stride;
1857   tree fault;
1858   gfc_se indexse;
1859
1860   /* Handle scalarized references separately.  */
1861   if (ar->type != AR_ELEMENT)
1862     {
1863       gfc_conv_scalarized_array_ref (se, ar);
1864       gfc_advance_se_ss_chain (se);
1865       return;
1866     }
1867
1868   index = gfc_index_zero_node;
1869
1870   fault = gfc_index_zero_node;
1871
1872   /* Calculate the offsets from all the dimensions.  */
1873   for (n = 0; n < ar->dimen; n++)
1874     {
1875       /* Calculate the index for this dimension.  */
1876       gfc_init_se (&indexse, se);
1877       gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type);
1878       gfc_add_block_to_block (&se->pre, &indexse.pre);
1879
1880       if (flag_bounds_check)
1881         {
1882           /* Check array bounds.  */
1883           tree cond;
1884
1885           indexse.expr = gfc_evaluate_now (indexse.expr, &se->pre);
1886
1887           tmp = gfc_conv_array_lbound (se->expr, n);
1888           cond = fold_build2 (LT_EXPR, boolean_type_node, 
1889                               indexse.expr, tmp);
1890           fault =
1891             fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault, cond);
1892
1893           tmp = gfc_conv_array_ubound (se->expr, n);
1894           cond = fold_build2 (GT_EXPR, boolean_type_node, 
1895                               indexse.expr, tmp);
1896           fault =
1897             fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault, cond);
1898         }
1899
1900       /* Multiply the index by the stride.  */
1901       stride = gfc_conv_array_stride (se->expr, n);
1902       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, indexse.expr,
1903                          stride);
1904
1905       /* And add it to the total.  */
1906       index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
1907     }
1908
1909   if (flag_bounds_check)
1910     gfc_trans_runtime_check (fault, gfc_strconst_fault, &se->pre);
1911
1912   tmp = gfc_conv_array_offset (se->expr);
1913   if (!integer_zerop (tmp))
1914     index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
1915       
1916   /* Access the calculated element.  */
1917   tmp = gfc_conv_array_data (se->expr);
1918   tmp = gfc_build_indirect_ref (tmp);
1919   se->expr = gfc_build_array_ref (tmp, index);
1920 }
1921
1922
1923 /* Generate the code to be executed immediately before entering a
1924    scalarization loop.  */
1925
1926 static void
1927 gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
1928                          stmtblock_t * pblock)
1929 {
1930   tree index;
1931   tree stride;
1932   gfc_ss_info *info;
1933   gfc_ss *ss;
1934   gfc_se se;
1935   int i;
1936
1937   /* This code will be executed before entering the scalarization loop
1938      for this dimension.  */
1939   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
1940     {
1941       if ((ss->useflags & flag) == 0)
1942         continue;
1943
1944       if (ss->type != GFC_SS_SECTION
1945           && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
1946           && ss->type != GFC_SS_COMPONENT)
1947         continue;
1948
1949       info = &ss->data.info;
1950
1951       if (dim >= info->dimen)
1952         continue;
1953
1954       if (dim == info->dimen - 1)
1955         {
1956           /* For the outermost loop calculate the offset due to any
1957              elemental dimensions.  It will have been initialized with the
1958              base offset of the array.  */
1959           if (info->ref)
1960             {
1961               for (i = 0; i < info->ref->u.ar.dimen; i++)
1962                 {
1963                   if (info->ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
1964                     continue;
1965
1966                   gfc_init_se (&se, NULL);
1967                   se.loop = loop;
1968                   se.expr = info->descriptor;
1969                   stride = gfc_conv_array_stride (info->descriptor, i);
1970                   index = gfc_conv_array_index_offset (&se, info, i, -1,
1971                                                        &info->ref->u.ar,
1972                                                        stride);
1973                   gfc_add_block_to_block (pblock, &se.pre);
1974
1975                   info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1976                                               info->offset, index);
1977                   info->offset = gfc_evaluate_now (info->offset, pblock);
1978                 }
1979
1980               i = loop->order[0];
1981               stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
1982             }
1983           else
1984             stride = gfc_conv_array_stride (info->descriptor, 0);
1985
1986           /* Calculate the stride of the innermost loop.  Hopefully this will
1987              allow the backend optimizers to do their stuff more effectively.
1988            */
1989           info->stride0 = gfc_evaluate_now (stride, pblock);
1990         }
1991       else
1992         {
1993           /* Add the offset for the previous loop dimension.  */
1994           gfc_array_ref *ar;
1995
1996           if (info->ref)
1997             {
1998               ar = &info->ref->u.ar;
1999               i = loop->order[dim + 1];
2000             }
2001           else
2002             {
2003               ar = NULL;
2004               i = dim + 1;
2005             }
2006
2007           gfc_init_se (&se, NULL);
2008           se.loop = loop;
2009           se.expr = info->descriptor;
2010           stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
2011           index = gfc_conv_array_index_offset (&se, info, info->dim[i], i,
2012                                                ar, stride);
2013           gfc_add_block_to_block (pblock, &se.pre);
2014           info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2015                                       info->offset, index);
2016           info->offset = gfc_evaluate_now (info->offset, pblock);
2017         }
2018
2019       /* Remember this offset for the second loop.  */
2020       if (dim == loop->temp_dim - 1)
2021         info->saved_offset = info->offset;
2022     }
2023 }
2024
2025
2026 /* Start a scalarized expression.  Creates a scope and declares loop
2027    variables.  */
2028
2029 void
2030 gfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody)
2031 {
2032   int dim;
2033   int n;
2034   int flags;
2035
2036   gcc_assert (!loop->array_parameter);
2037
2038   for (dim = loop->dimen - 1; dim >= 0; dim--)
2039     {
2040       n = loop->order[dim];
2041
2042       gfc_start_block (&loop->code[n]);
2043
2044       /* Create the loop variable.  */
2045       loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "S");
2046
2047       if (dim < loop->temp_dim)
2048         flags = 3;
2049       else
2050         flags = 1;
2051       /* Calculate values that will be constant within this loop.  */
2052       gfc_trans_preloop_setup (loop, dim, flags, &loop->code[n]);
2053     }
2054   gfc_start_block (pbody);
2055 }
2056
2057
2058 /* Generates the actual loop code for a scalarization loop.  */
2059
2060 static void
2061 gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
2062                                stmtblock_t * pbody)
2063 {
2064   stmtblock_t block;
2065   tree cond;
2066   tree tmp;
2067   tree loopbody;
2068   tree exit_label;
2069
2070   loopbody = gfc_finish_block (pbody);
2071
2072   /* Initialize the loopvar.  */
2073   gfc_add_modify_expr (&loop->code[n], loop->loopvar[n], loop->from[n]);
2074
2075   exit_label = gfc_build_label_decl (NULL_TREE);
2076
2077   /* Generate the loop body.  */
2078   gfc_init_block (&block);
2079
2080   /* The exit condition.  */
2081   cond = build2 (GT_EXPR, boolean_type_node, loop->loopvar[n], loop->to[n]);
2082   tmp = build1_v (GOTO_EXPR, exit_label);
2083   TREE_USED (exit_label) = 1;
2084   tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
2085   gfc_add_expr_to_block (&block, tmp);
2086
2087   /* The main body.  */
2088   gfc_add_expr_to_block (&block, loopbody);
2089
2090   /* Increment the loopvar.  */
2091   tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2092                 loop->loopvar[n], gfc_index_one_node);
2093   gfc_add_modify_expr (&block, loop->loopvar[n], tmp);
2094
2095   /* Build the loop.  */
2096   tmp = gfc_finish_block (&block);
2097   tmp = build1_v (LOOP_EXPR, tmp);
2098   gfc_add_expr_to_block (&loop->code[n], tmp);
2099
2100   /* Add the exit label.  */
2101   tmp = build1_v (LABEL_EXPR, exit_label);
2102   gfc_add_expr_to_block (&loop->code[n], tmp);
2103 }
2104
2105
2106 /* Finishes and generates the loops for a scalarized expression.  */
2107
2108 void
2109 gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body)
2110 {
2111   int dim;
2112   int n;
2113   gfc_ss *ss;
2114   stmtblock_t *pblock;
2115   tree tmp;
2116
2117   pblock = body;
2118   /* Generate the loops.  */
2119   for (dim = 0; dim < loop->dimen; dim++)
2120     {
2121       n = loop->order[dim];
2122       gfc_trans_scalarized_loop_end (loop, n, pblock);
2123       loop->loopvar[n] = NULL_TREE;
2124       pblock = &loop->code[n];
2125     }
2126
2127   tmp = gfc_finish_block (pblock);
2128   gfc_add_expr_to_block (&loop->pre, tmp);
2129
2130   /* Clear all the used flags.  */
2131   for (ss = loop->ss; ss; ss = ss->loop_chain)
2132     ss->useflags = 0;
2133 }
2134
2135
2136 /* Finish the main body of a scalarized expression, and start the secondary
2137    copying body.  */
2138
2139 void
2140 gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
2141 {
2142   int dim;
2143   int n;
2144   stmtblock_t *pblock;
2145   gfc_ss *ss;
2146
2147   pblock = body;
2148   /* We finish as many loops as are used by the temporary.  */
2149   for (dim = 0; dim < loop->temp_dim - 1; dim++)
2150     {
2151       n = loop->order[dim];
2152       gfc_trans_scalarized_loop_end (loop, n, pblock);
2153       loop->loopvar[n] = NULL_TREE;
2154       pblock = &loop->code[n];
2155     }
2156
2157   /* We don't want to finish the outermost loop entirely.  */
2158   n = loop->order[loop->temp_dim - 1];
2159   gfc_trans_scalarized_loop_end (loop, n, pblock);
2160
2161   /* Restore the initial offsets.  */
2162   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2163     {
2164       if ((ss->useflags & 2) == 0)
2165         continue;
2166
2167       if (ss->type != GFC_SS_SECTION
2168           && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
2169           && ss->type != GFC_SS_COMPONENT)
2170         continue;
2171
2172       ss->data.info.offset = ss->data.info.saved_offset;
2173     }
2174
2175   /* Restart all the inner loops we just finished.  */
2176   for (dim = loop->temp_dim - 2; dim >= 0; dim--)
2177     {
2178       n = loop->order[dim];
2179
2180       gfc_start_block (&loop->code[n]);
2181
2182       loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "Q");
2183
2184       gfc_trans_preloop_setup (loop, dim, 2, &loop->code[n]);
2185     }
2186
2187   /* Start a block for the secondary copying code.  */
2188   gfc_start_block (body);
2189 }
2190
2191
2192 /* Calculate the upper bound of an array section.  */
2193
2194 static tree
2195 gfc_conv_section_upper_bound (gfc_ss * ss, int n, stmtblock_t * pblock)
2196 {
2197   int dim;
2198   gfc_ss *vecss;
2199   gfc_expr *end;
2200   tree desc;
2201   tree bound;
2202   gfc_se se;
2203
2204   gcc_assert (ss->type == GFC_SS_SECTION);
2205
2206   /* For vector array subscripts we want the size of the vector.  */
2207   dim = ss->data.info.dim[n];
2208   vecss = ss;
2209   while (vecss->data.info.ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2210     {
2211       vecss = vecss->data.info.subscript[dim];
2212       gcc_assert (vecss && vecss->type == GFC_SS_VECTOR);
2213       dim = vecss->data.info.dim[0];
2214     }
2215
2216   gcc_assert (vecss->data.info.ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
2217   end = vecss->data.info.ref->u.ar.end[dim];
2218   desc = vecss->data.info.descriptor;
2219
2220   if (end)
2221     {
2222       /* The upper bound was specified.  */
2223       gfc_init_se (&se, NULL);
2224       gfc_conv_expr_type (&se, end, gfc_array_index_type);
2225       gfc_add_block_to_block (pblock, &se.pre);
2226       bound = se.expr;
2227     }
2228   else
2229     {
2230       /* No upper bound was specified, so use the bound of the array.  */
2231       bound = gfc_conv_array_ubound (desc, dim);
2232     }
2233
2234   return bound;
2235 }
2236
2237
2238 /* Calculate the lower bound of an array section.  */
2239
2240 static void
2241 gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int n)
2242 {
2243   gfc_expr *start;
2244   gfc_expr *stride;
2245   gfc_ss *vecss;
2246   tree desc;
2247   gfc_se se;
2248   gfc_ss_info *info;
2249   int dim;
2250
2251   info = &ss->data.info;
2252
2253   dim = info->dim[n];
2254
2255   /* For vector array subscripts we want the size of the vector.  */
2256   vecss = ss;
2257   while (vecss->data.info.ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2258     {
2259       vecss = vecss->data.info.subscript[dim];
2260       gcc_assert (vecss && vecss->type == GFC_SS_VECTOR);
2261       /* Get the descriptors for the vector subscripts as well.  */
2262       if (!vecss->data.info.descriptor)
2263         gfc_conv_ss_descriptor (&loop->pre, vecss, !loop->array_parameter);
2264       dim = vecss->data.info.dim[0];
2265     }
2266
2267   gcc_assert (vecss->data.info.ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
2268   start = vecss->data.info.ref->u.ar.start[dim];
2269   stride = vecss->data.info.ref->u.ar.stride[dim];
2270   desc = vecss->data.info.descriptor;
2271
2272   /* Calculate the start of the range.  For vector subscripts this will
2273      be the range of the vector.  */
2274   if (start)
2275     {
2276       /* Specified section start.  */
2277       gfc_init_se (&se, NULL);
2278       gfc_conv_expr_type (&se, start, gfc_array_index_type);
2279       gfc_add_block_to_block (&loop->pre, &se.pre);
2280       info->start[n] = se.expr;
2281     }
2282   else
2283     {
2284       /* No lower bound specified so use the bound of the array.  */
2285       info->start[n] = gfc_conv_array_lbound (desc, dim);
2286     }
2287   info->start[n] = gfc_evaluate_now (info->start[n], &loop->pre);
2288
2289   /* Calculate the stride.  */
2290   if (stride == NULL)
2291     info->stride[n] = gfc_index_one_node;
2292   else
2293     {
2294       gfc_init_se (&se, NULL);
2295       gfc_conv_expr_type (&se, stride, gfc_array_index_type);
2296       gfc_add_block_to_block (&loop->pre, &se.pre);
2297       info->stride[n] = gfc_evaluate_now (se.expr, &loop->pre);
2298     }
2299 }
2300
2301
2302 /* Calculates the range start and stride for a SS chain.  Also gets the
2303    descriptor and data pointer.  The range of vector subscripts is the size
2304    of the vector.  Array bounds are also checked.  */
2305
2306 void
2307 gfc_conv_ss_startstride (gfc_loopinfo * loop)
2308 {
2309   int n;
2310   tree tmp;
2311   gfc_ss *ss;
2312   gfc_ss *vecss;
2313   tree desc;
2314
2315   loop->dimen = 0;
2316   /* Determine the rank of the loop.  */
2317   for (ss = loop->ss;
2318        ss != gfc_ss_terminator && loop->dimen == 0; ss = ss->loop_chain)
2319     {
2320       switch (ss->type)
2321         {
2322         case GFC_SS_SECTION:
2323         case GFC_SS_CONSTRUCTOR:
2324         case GFC_SS_FUNCTION:
2325         case GFC_SS_COMPONENT:
2326           loop->dimen = ss->data.info.dimen;
2327           break;
2328
2329         default:
2330           break;
2331         }
2332     }
2333
2334   if (loop->dimen == 0)
2335     gfc_todo_error ("Unable to determine rank of expression");
2336
2337
2338   /* Loop over all the SS in the chain.  */
2339   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2340     {
2341       if (ss->expr && ss->expr->shape && !ss->shape)
2342         ss->shape = ss->expr->shape;
2343
2344       switch (ss->type)
2345         {
2346         case GFC_SS_SECTION:
2347           /* Get the descriptor for the array.  */
2348           gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter);
2349
2350           for (n = 0; n < ss->data.info.dimen; n++)
2351             gfc_conv_section_startstride (loop, ss, n);
2352           break;
2353
2354         case GFC_SS_CONSTRUCTOR:
2355         case GFC_SS_FUNCTION:
2356           for (n = 0; n < ss->data.info.dimen; n++)
2357             {
2358               ss->data.info.start[n] = gfc_index_zero_node;
2359               ss->data.info.stride[n] = gfc_index_one_node;
2360             }
2361           break;
2362
2363         default:
2364           break;
2365         }
2366     }
2367
2368   /* The rest is just runtime bound checking.  */
2369   if (flag_bounds_check)
2370     {
2371       stmtblock_t block;
2372       tree fault;
2373       tree bound;
2374       tree end;
2375       tree size[GFC_MAX_DIMENSIONS];
2376       gfc_ss_info *info;
2377       int dim;
2378
2379       gfc_start_block (&block);
2380
2381       fault = integer_zero_node;
2382       for (n = 0; n < loop->dimen; n++)
2383         size[n] = NULL_TREE;
2384
2385       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2386         {
2387           if (ss->type != GFC_SS_SECTION)
2388             continue;
2389
2390           /* TODO: range checking for mapped dimensions.  */
2391           info = &ss->data.info;
2392
2393           /* This only checks scalarized dimensions, elemental dimensions are
2394              checked later.  */
2395           for (n = 0; n < loop->dimen; n++)
2396             {
2397               dim = info->dim[n];
2398               vecss = ss;
2399               while (vecss->data.info.ref->u.ar.dimen_type[dim]
2400                      == DIMEN_VECTOR)
2401                 {
2402                   vecss = vecss->data.info.subscript[dim];
2403                   gcc_assert (vecss && vecss->type == GFC_SS_VECTOR);
2404                   dim = vecss->data.info.dim[0];
2405                 }
2406               gcc_assert (vecss->data.info.ref->u.ar.dimen_type[dim]
2407                       == DIMEN_RANGE);
2408               desc = vecss->data.info.descriptor;
2409
2410               /* Check lower bound.  */
2411               bound = gfc_conv_array_lbound (desc, dim);
2412               tmp = info->start[n];
2413               tmp = fold_build2 (LT_EXPR, boolean_type_node, tmp, bound);
2414               fault = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault,
2415                                    tmp);
2416
2417               /* Check the upper bound.  */
2418               bound = gfc_conv_array_ubound (desc, dim);
2419               end = gfc_conv_section_upper_bound (ss, n, &block);
2420               tmp = fold_build2 (GT_EXPR, boolean_type_node, end, bound);
2421               fault = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault,
2422                                    tmp);
2423
2424               /* Check the section sizes match.  */
2425               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
2426                                  info->start[n]);
2427               tmp = fold_build2 (FLOOR_DIV_EXPR, gfc_array_index_type, tmp,
2428                                  info->stride[n]);
2429               /* We remember the size of the first section, and check all the
2430                  others against this.  */
2431               if (size[n])
2432                 {
2433                   tmp =
2434                     fold_build2 (NE_EXPR, boolean_type_node, tmp, size[n]);
2435                   fault =
2436                     build2 (TRUTH_OR_EXPR, boolean_type_node, fault, tmp);
2437                 }
2438               else
2439                 size[n] = gfc_evaluate_now (tmp, &block);
2440             }
2441         }
2442       gfc_trans_runtime_check (fault, gfc_strconst_bounds, &block);
2443
2444       tmp = gfc_finish_block (&block);
2445       gfc_add_expr_to_block (&loop->pre, tmp);
2446     }
2447 }
2448
2449
2450 /* Return true if the two SS could be aliased, i.e. both point to the same data
2451    object.  */
2452 /* TODO: resolve aliases based on frontend expressions.  */
2453
2454 static int
2455 gfc_could_be_alias (gfc_ss * lss, gfc_ss * rss)
2456 {
2457   gfc_ref *lref;
2458   gfc_ref *rref;
2459   gfc_symbol *lsym;
2460   gfc_symbol *rsym;
2461
2462   lsym = lss->expr->symtree->n.sym;
2463   rsym = rss->expr->symtree->n.sym;
2464   if (gfc_symbols_could_alias (lsym, rsym))
2465     return 1;
2466
2467   if (rsym->ts.type != BT_DERIVED
2468       && lsym->ts.type != BT_DERIVED)
2469     return 0;
2470
2471   /* For derived types we must check all the component types.  We can ignore
2472      array references as these will have the same base type as the previous
2473      component ref.  */
2474   for (lref = lss->expr->ref; lref != lss->data.info.ref; lref = lref->next)
2475     {
2476       if (lref->type != REF_COMPONENT)
2477         continue;
2478
2479       if (gfc_symbols_could_alias (lref->u.c.sym, rsym))
2480         return 1;
2481
2482       for (rref = rss->expr->ref; rref != rss->data.info.ref;
2483            rref = rref->next)
2484         {
2485           if (rref->type != REF_COMPONENT)
2486             continue;
2487
2488           if (gfc_symbols_could_alias (lref->u.c.sym, rref->u.c.sym))
2489             return 1;
2490         }
2491     }
2492
2493   for (rref = rss->expr->ref; rref != rss->data.info.ref; rref = rref->next)
2494     {
2495       if (rref->type != REF_COMPONENT)
2496         break;
2497
2498       if (gfc_symbols_could_alias (rref->u.c.sym, lsym))
2499         return 1;
2500     }
2501
2502   return 0;
2503 }
2504
2505
2506 /* Resolve array data dependencies.  Creates a temporary if required.  */
2507 /* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
2508    dependency.c.  */
2509
2510 void
2511 gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
2512                                gfc_ss * rss)
2513 {
2514   gfc_ss *ss;
2515   gfc_ref *lref;
2516   gfc_ref *rref;
2517   gfc_ref *aref;
2518   int nDepend = 0;
2519   int temp_dim = 0;
2520
2521   loop->temp_ss = NULL;
2522   aref = dest->data.info.ref;
2523   temp_dim = 0;
2524
2525   for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
2526     {
2527       if (ss->type != GFC_SS_SECTION)
2528         continue;
2529
2530       if (gfc_could_be_alias (dest, ss))
2531         {
2532           nDepend = 1;
2533           break;
2534         }
2535
2536       if (dest->expr->symtree->n.sym == ss->expr->symtree->n.sym)
2537         {
2538           lref = dest->expr->ref;
2539           rref = ss->expr->ref;
2540
2541           nDepend = gfc_dep_resolver (lref, rref);
2542 #if 0
2543           /* TODO : loop shifting.  */
2544           if (nDepend == 1)
2545             {
2546               /* Mark the dimensions for LOOP SHIFTING */
2547               for (n = 0; n < loop->dimen; n++)
2548                 {
2549                   int dim = dest->data.info.dim[n];
2550
2551                   if (lref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2552                     depends[n] = 2;
2553                   else if (! gfc_is_same_range (&lref->u.ar,
2554                                                 &rref->u.ar, dim, 0))
2555                     depends[n] = 1;
2556                  }
2557
2558               /* Put all the dimensions with dependencies in the
2559                  innermost loops.  */
2560               dim = 0;
2561               for (n = 0; n < loop->dimen; n++)
2562                 {
2563                   gcc_assert (loop->order[n] == n);
2564                   if (depends[n])
2565                   loop->order[dim++] = n;
2566                 }
2567               temp_dim = dim;
2568               for (n = 0; n < loop->dimen; n++)
2569                 {
2570                   if (! depends[n])
2571                   loop->order[dim++] = n;
2572                 }
2573
2574               gcc_assert (dim == loop->dimen);
2575               break;
2576             }
2577 #endif
2578         }
2579     }
2580
2581   if (nDepend == 1)
2582     {
2583       loop->temp_ss = gfc_get_ss ();
2584       loop->temp_ss->type = GFC_SS_TEMP;
2585       loop->temp_ss->data.temp.type =
2586         gfc_get_element_type (TREE_TYPE (dest->data.info.descriptor));
2587       loop->temp_ss->string_length = dest->string_length;
2588       loop->temp_ss->data.temp.dimen = loop->dimen;
2589       loop->temp_ss->next = gfc_ss_terminator;
2590       gfc_add_ss_to_loop (loop, loop->temp_ss);
2591     }
2592   else
2593     loop->temp_ss = NULL;
2594 }
2595
2596
2597 /* Initialize the scalarization loop.  Creates the loop variables.  Determines
2598    the range of the loop variables.  Creates a temporary if required.
2599    Calculates how to transform from loop variables to array indices for each
2600    expression.  Also generates code for scalar expressions which have been
2601    moved outside the loop.  */
2602
2603 void
2604 gfc_conv_loop_setup (gfc_loopinfo * loop)
2605 {
2606   int n;
2607   int dim;
2608   gfc_ss_info *info;
2609   gfc_ss_info *specinfo;
2610   gfc_ss *ss;
2611   tree tmp;
2612   tree len;
2613   gfc_ss *loopspec[GFC_MAX_DIMENSIONS];
2614   bool dynamic[GFC_MAX_DIMENSIONS];
2615   gfc_constructor *c;
2616   mpz_t *cshape;
2617   mpz_t i;
2618
2619   mpz_init (i);
2620   for (n = 0; n < loop->dimen; n++)
2621     {
2622       loopspec[n] = NULL;
2623       dynamic[n] = false;
2624       /* We use one SS term, and use that to determine the bounds of the
2625          loop for this dimension.  We try to pick the simplest term.  */
2626       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2627         {
2628           if (ss->shape)
2629             {
2630               /* The frontend has worked out the size for us.  */
2631               loopspec[n] = ss;
2632               continue;
2633             }
2634
2635           if (ss->type == GFC_SS_CONSTRUCTOR)
2636             {
2637               /* An unknown size constructor will always be rank one.
2638                  Higher rank constructors will either have known shape,
2639                  or still be wrapped in a call to reshape.  */
2640               gcc_assert (loop->dimen == 1);
2641
2642               /* Always prefer to use the constructor bounds if the size
2643                  can be determined at compile time.  Prefer not to otherwise,
2644                  since the general case involves realloc, and it's better to
2645                  avoid that overhead if possible.  */
2646               c = ss->expr->value.constructor;
2647               dynamic[n] = gfc_get_array_constructor_size (&i, c);
2648               if (!dynamic[n] || !loopspec[n])
2649                 loopspec[n] = ss;
2650               continue;
2651             }
2652
2653           /* TODO: Pick the best bound if we have a choice between a
2654              function and something else.  */
2655           if (ss->type == GFC_SS_FUNCTION)
2656             {
2657               loopspec[n] = ss;
2658               continue;
2659             }
2660
2661           if (ss->type != GFC_SS_SECTION)
2662             continue;
2663
2664           if (loopspec[n])
2665             specinfo = &loopspec[n]->data.info;
2666           else
2667             specinfo = NULL;
2668           info = &ss->data.info;
2669
2670           if (!specinfo)
2671             loopspec[n] = ss;
2672           /* Criteria for choosing a loop specifier (most important first):
2673              doesn't need realloc
2674              stride of one
2675              known stride
2676              known lower bound
2677              known upper bound
2678            */
2679           else if (loopspec[n]->type == GFC_SS_CONSTRUCTOR && dynamic[n])
2680             loopspec[n] = ss;
2681           else if (integer_onep (info->stride[n])
2682                    && !integer_onep (specinfo->stride[n]))
2683             loopspec[n] = ss;
2684           else if (INTEGER_CST_P (info->stride[n])
2685                    && !INTEGER_CST_P (specinfo->stride[n]))
2686             loopspec[n] = ss;
2687           else if (INTEGER_CST_P (info->start[n])
2688                    && !INTEGER_CST_P (specinfo->start[n]))
2689             loopspec[n] = ss;
2690           /* We don't work out the upper bound.
2691              else if (INTEGER_CST_P (info->finish[n])
2692              && ! INTEGER_CST_P (specinfo->finish[n]))
2693              loopspec[n] = ss; */
2694         }
2695
2696       if (!loopspec[n])
2697         gfc_todo_error ("Unable to find scalarization loop specifier");
2698
2699       info = &loopspec[n]->data.info;
2700
2701       /* Set the extents of this range.  */
2702       cshape = loopspec[n]->shape;
2703       if (cshape && INTEGER_CST_P (info->start[n])
2704           && INTEGER_CST_P (info->stride[n]))
2705         {
2706           loop->from[n] = info->start[n];
2707           mpz_set (i, cshape[n]);
2708           mpz_sub_ui (i, i, 1);
2709           /* To = from + (size - 1) * stride.  */
2710           tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
2711           if (!integer_onep (info->stride[n]))
2712             tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
2713                                tmp, info->stride[n]);
2714           loop->to[n] = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2715                                      loop->from[n], tmp);
2716         }
2717       else
2718         {
2719           loop->from[n] = info->start[n];
2720           switch (loopspec[n]->type)
2721             {
2722             case GFC_SS_CONSTRUCTOR:
2723               /* The upper bound is calculated when we expand the
2724                  constructor.  */
2725               gcc_assert (loop->to[n] == NULL_TREE);
2726               break;
2727
2728             case GFC_SS_SECTION:
2729               loop->to[n] = gfc_conv_section_upper_bound (loopspec[n], n,
2730                                                           &loop->pre);
2731               break;
2732
2733             case GFC_SS_FUNCTION:
2734               /* The loop bound will be set when we generate the call.  */
2735               gcc_assert (loop->to[n] == NULL_TREE);
2736               break;
2737
2738             default:
2739               gcc_unreachable ();
2740             }
2741         }
2742
2743       /* Transform everything so we have a simple incrementing variable.  */
2744       if (integer_onep (info->stride[n]))
2745         info->delta[n] = gfc_index_zero_node;
2746       else
2747         {
2748           /* Set the delta for this section.  */
2749           info->delta[n] = gfc_evaluate_now (loop->from[n], &loop->pre);
2750           /* Number of iterations is (end - start + step) / step.
2751              with start = 0, this simplifies to
2752              last = end / step;
2753              for (i = 0; i<=last; i++){...};  */
2754           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2755                              loop->to[n], loop->from[n]);
2756           tmp = fold_build2 (TRUNC_DIV_EXPR, gfc_array_index_type, 
2757                              tmp, info->stride[n]);
2758           loop->to[n] = gfc_evaluate_now (tmp, &loop->pre);
2759           /* Make the loop variable start at 0.  */
2760           loop->from[n] = gfc_index_zero_node;
2761         }
2762     }
2763
2764   /* Add all the scalar code that can be taken out of the loops.
2765      This may include calculating the loop bounds, so do it before
2766      allocating the temporary.  */
2767   gfc_add_loop_ss_code (loop, loop->ss, false);
2768
2769   /* If we want a temporary then create it.  */
2770   if (loop->temp_ss != NULL)
2771     {
2772       gcc_assert (loop->temp_ss->type == GFC_SS_TEMP);
2773       tmp = loop->temp_ss->data.temp.type;
2774       len = loop->temp_ss->string_length;
2775       n = loop->temp_ss->data.temp.dimen;
2776       memset (&loop->temp_ss->data.info, 0, sizeof (gfc_ss_info));
2777       loop->temp_ss->type = GFC_SS_SECTION;
2778       loop->temp_ss->data.info.dimen = n;
2779       gfc_trans_allocate_temp_array (&loop->pre, &loop->post, loop,
2780                                      &loop->temp_ss->data.info, tmp, false);
2781     }
2782
2783   for (n = 0; n < loop->temp_dim; n++)
2784     loopspec[loop->order[n]] = NULL;
2785
2786   mpz_clear (i);
2787
2788   /* For array parameters we don't have loop variables, so don't calculate the
2789      translations.  */
2790   if (loop->array_parameter)
2791     return;
2792
2793   /* Calculate the translation from loop variables to array indices.  */
2794   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2795     {
2796       if (ss->type != GFC_SS_SECTION && ss->type != GFC_SS_COMPONENT)
2797         continue;
2798
2799       info = &ss->data.info;
2800
2801       for (n = 0; n < info->dimen; n++)
2802         {
2803           dim = info->dim[n];
2804
2805           /* If we are specifying the range the delta is already set.  */
2806           if (loopspec[n] != ss)
2807             {
2808               /* Calculate the offset relative to the loop variable.
2809                  First multiply by the stride.  */
2810               tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
2811                                  loop->from[n], info->stride[n]);
2812
2813               /* Then subtract this from our starting value.  */
2814               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2815                                  info->start[n], tmp);
2816
2817               info->delta[n] = gfc_evaluate_now (tmp, &loop->pre);
2818             }
2819         }
2820     }
2821 }
2822
2823
2824 /* Fills in an array descriptor, and returns the size of the array.  The size
2825    will be a simple_val, ie a variable or a constant.  Also calculates the
2826    offset of the base.  Returns the size of the array.
2827    {
2828     stride = 1;
2829     offset = 0;
2830     for (n = 0; n < rank; n++)
2831       {
2832         a.lbound[n] = specified_lower_bound;
2833         offset = offset + a.lbond[n] * stride;
2834         size = 1 - lbound;
2835         a.ubound[n] = specified_upper_bound;
2836         a.stride[n] = stride;
2837         size = ubound + size; //size = ubound + 1 - lbound
2838         stride = stride * size;
2839       }
2840     return (stride);
2841    }  */
2842 /*GCC ARRAYS*/
2843
2844 static tree
2845 gfc_array_init_size (tree descriptor, int rank, tree * poffset,
2846                      gfc_expr ** lower, gfc_expr ** upper,
2847                      stmtblock_t * pblock)
2848 {
2849   tree type;
2850   tree tmp;
2851   tree size;
2852   tree offset;
2853   tree stride;
2854   gfc_expr *ubound;
2855   gfc_se se;
2856   int n;
2857
2858   type = TREE_TYPE (descriptor);
2859
2860   stride = gfc_index_one_node;
2861   offset = gfc_index_zero_node;
2862
2863   /* Set the dtype.  */
2864   tmp = gfc_conv_descriptor_dtype (descriptor);
2865   gfc_add_modify_expr (pblock, tmp, gfc_get_dtype (TREE_TYPE (descriptor)));
2866
2867   for (n = 0; n < rank; n++)
2868     {
2869       /* We have 3 possibilities for determining the size of the array:
2870          lower == NULL    => lbound = 1, ubound = upper[n]
2871          upper[n] = NULL  => lbound = 1, ubound = lower[n]
2872          upper[n] != NULL => lbound = lower[n], ubound = upper[n]  */
2873       ubound = upper[n];
2874
2875       /* Set lower bound.  */
2876       gfc_init_se (&se, NULL);
2877       if (lower == NULL)
2878         se.expr = gfc_index_one_node;
2879       else
2880         {
2881           gcc_assert (lower[n]);
2882           if (ubound)
2883             {
2884               gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
2885               gfc_add_block_to_block (pblock, &se.pre);
2886             }
2887           else
2888             {
2889               se.expr = gfc_index_one_node;
2890               ubound = lower[n];
2891             }
2892         }
2893       tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[n]);
2894       gfc_add_modify_expr (pblock, tmp, se.expr);
2895
2896       /* Work out the offset for this component.  */
2897       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, se.expr, stride);
2898       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
2899
2900       /* Start the calculation for the size of this dimension.  */
2901       size = build2 (MINUS_EXPR, gfc_array_index_type,
2902                      gfc_index_one_node, se.expr);
2903
2904       /* Set upper bound.  */
2905       gfc_init_se (&se, NULL);
2906       gcc_assert (ubound);
2907       gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
2908       gfc_add_block_to_block (pblock, &se.pre);
2909
2910       tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[n]);
2911       gfc_add_modify_expr (pblock, tmp, se.expr);
2912
2913       /* Store the stride.  */
2914       tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[n]);
2915       gfc_add_modify_expr (pblock, tmp, stride);
2916
2917       /* Calculate the size of this dimension.  */
2918       size = fold_build2 (PLUS_EXPR, gfc_array_index_type, se.expr, size);
2919
2920       /* Multiply the stride by the number of elements in this dimension.  */
2921       stride = fold_build2 (MULT_EXPR, gfc_array_index_type, stride, size);
2922       stride = gfc_evaluate_now (stride, pblock);
2923     }
2924
2925   /* The stride is the number of elements in the array, so multiply by the
2926      size of an element to get the total size.  */
2927   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
2928   size = fold_build2 (MULT_EXPR, gfc_array_index_type, stride, tmp);
2929
2930   if (poffset != NULL)
2931     {
2932       offset = gfc_evaluate_now (offset, pblock);
2933       *poffset = offset;
2934     }
2935
2936   size = gfc_evaluate_now (size, pblock);
2937   return size;
2938 }
2939
2940
2941 /* Initializes the descriptor and generates a call to _gfor_allocate.  Does
2942    the work for an ALLOCATE statement.  */
2943 /*GCC ARRAYS*/
2944
2945 void
2946 gfc_array_allocate (gfc_se * se, gfc_ref * ref, tree pstat)
2947 {
2948   tree tmp;
2949   tree pointer;
2950   tree allocate;
2951   tree offset;
2952   tree size;
2953   gfc_expr **lower;
2954   gfc_expr **upper;
2955
2956   /* Figure out the size of the array.  */
2957   switch (ref->u.ar.type)
2958     {
2959     case AR_ELEMENT:
2960       lower = NULL;
2961       upper = ref->u.ar.start;
2962       break;
2963
2964     case AR_FULL:
2965       gcc_assert (ref->u.ar.as->type == AS_EXPLICIT);
2966
2967       lower = ref->u.ar.as->lower;
2968       upper = ref->u.ar.as->upper;
2969       break;
2970
2971     case AR_SECTION:
2972       lower = ref->u.ar.start;
2973       upper = ref->u.ar.end;
2974       break;
2975
2976     default:
2977       gcc_unreachable ();
2978       break;
2979     }
2980
2981   size = gfc_array_init_size (se->expr, ref->u.ar.as->rank, &offset,
2982                               lower, upper, &se->pre);
2983
2984   /* Allocate memory to store the data.  */
2985   tmp = gfc_conv_descriptor_data_addr (se->expr);
2986   pointer = gfc_evaluate_now (tmp, &se->pre);
2987
2988   if (TYPE_PRECISION (gfc_array_index_type) == 32)
2989     allocate = gfor_fndecl_allocate;
2990   else if (TYPE_PRECISION (gfc_array_index_type) == 64)
2991     allocate = gfor_fndecl_allocate64;
2992   else
2993     gcc_unreachable ();
2994
2995   tmp = gfc_chainon_list (NULL_TREE, pointer);
2996   tmp = gfc_chainon_list (tmp, size);
2997   tmp = gfc_chainon_list (tmp, pstat);
2998   tmp = gfc_build_function_call (allocate, tmp);
2999   gfc_add_expr_to_block (&se->pre, tmp);
3000
3001   tmp = gfc_conv_descriptor_offset (se->expr);
3002   gfc_add_modify_expr (&se->pre, tmp, offset);
3003 }
3004
3005
3006 /* Deallocate an array variable.  Also used when an allocated variable goes
3007    out of scope.  */
3008 /*GCC ARRAYS*/
3009
3010 tree
3011 gfc_array_deallocate (tree descriptor, tree pstat)
3012 {
3013   tree var;
3014   tree tmp;
3015   stmtblock_t block;
3016
3017   gfc_start_block (&block);
3018   /* Get a pointer to the data.  */
3019   tmp = gfc_conv_descriptor_data_addr (descriptor);
3020   var = gfc_evaluate_now (tmp, &block);
3021
3022   /* Parameter is the address of the data component.  */
3023   tmp = gfc_chainon_list (NULL_TREE, var);
3024   tmp = gfc_chainon_list (tmp, pstat);
3025   tmp = gfc_build_function_call (gfor_fndecl_deallocate, tmp);
3026   gfc_add_expr_to_block (&block, tmp);
3027
3028   return gfc_finish_block (&block);
3029 }
3030
3031
3032 /* Create an array constructor from an initialization expression.
3033    We assume the frontend already did any expansions and conversions.  */
3034
3035 tree
3036 gfc_conv_array_initializer (tree type, gfc_expr * expr)
3037 {
3038   gfc_constructor *c;
3039   tree tmp;
3040   mpz_t maxval;
3041   gfc_se se;
3042   HOST_WIDE_INT hi;
3043   unsigned HOST_WIDE_INT lo;
3044   tree index, range;
3045   VEC(constructor_elt,gc) *v = NULL;
3046
3047   switch (expr->expr_type)
3048     {
3049     case EXPR_CONSTANT:
3050     case EXPR_STRUCTURE:
3051       /* A single scalar or derived type value.  Create an array with all
3052          elements equal to that value.  */
3053       gfc_init_se (&se, NULL);
3054       
3055       if (expr->expr_type == EXPR_CONSTANT)
3056         gfc_conv_constant (&se, expr);
3057       else
3058         gfc_conv_structure (&se, expr, 1);
3059
3060       tmp = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3061       gcc_assert (tmp && INTEGER_CST_P (tmp));
3062       hi = TREE_INT_CST_HIGH (tmp);
3063       lo = TREE_INT_CST_LOW (tmp);
3064       lo++;
3065       if (lo == 0)
3066         hi++;
3067       /* This will probably eat buckets of memory for large arrays.  */
3068       while (hi != 0 || lo != 0)
3069         {
3070           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, se.expr);
3071           if (lo == 0)
3072             hi--;
3073           lo--;
3074         }
3075       break;
3076
3077     case EXPR_ARRAY:
3078       /* Create a vector of all the elements.  */
3079       for (c = expr->value.constructor; c; c = c->next)
3080         {
3081           if (c->iterator)
3082             {
3083               /* Problems occur when we get something like
3084                  integer :: a(lots) = (/(i, i=1,lots)/)  */
3085               /* TODO: Unexpanded array initializers.  */
3086               internal_error
3087                 ("Possible frontend bug: array constructor not expanded");
3088             }
3089           if (mpz_cmp_si (c->n.offset, 0) != 0)
3090             index = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
3091           else
3092             index = NULL_TREE;
3093           mpz_init (maxval);
3094           if (mpz_cmp_si (c->repeat, 0) != 0)
3095             {
3096               tree tmp1, tmp2;
3097
3098               mpz_set (maxval, c->repeat);
3099               mpz_add (maxval, c->n.offset, maxval);
3100               mpz_sub_ui (maxval, maxval, 1);
3101               tmp2 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
3102               if (mpz_cmp_si (c->n.offset, 0) != 0)
3103                 {
3104                   mpz_add_ui (maxval, c->n.offset, 1);
3105                   tmp1 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
3106                 }
3107               else
3108                 tmp1 = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
3109
3110               range = build2 (RANGE_EXPR, integer_type_node, tmp1, tmp2);
3111             }
3112           else
3113             range = NULL;
3114           mpz_clear (maxval);
3115
3116           gfc_init_se (&se, NULL);
3117           switch (c->expr->expr_type)
3118             {
3119             case EXPR_CONSTANT:
3120               gfc_conv_constant (&se, c->expr);
3121               if (range == NULL_TREE)
3122                 CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3123               else
3124                 {
3125                   if (index != NULL_TREE)
3126                     CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3127                   CONSTRUCTOR_APPEND_ELT (v, range, se.expr);
3128                 }
3129               break;
3130
3131             case EXPR_STRUCTURE:
3132               gfc_conv_structure (&se, c->expr, 1);
3133               CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3134               break;
3135
3136             default:
3137               gcc_unreachable ();
3138             }
3139         }
3140       break;
3141
3142     default:
3143       gcc_unreachable ();
3144     }
3145
3146   /* Create a constructor from the list of elements.  */
3147   tmp = build_constructor (type, v);
3148   TREE_CONSTANT (tmp) = 1;
3149   TREE_INVARIANT (tmp) = 1;
3150   return tmp;
3151 }
3152
3153
3154 /* Generate code to evaluate non-constant array bounds.  Sets *poffset and
3155    returns the size (in elements) of the array.  */
3156
3157 static tree
3158 gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
3159                         stmtblock_t * pblock)
3160 {
3161   gfc_array_spec *as;
3162   tree size;
3163   tree stride;
3164   tree offset;
3165   tree ubound;
3166   tree lbound;
3167   tree tmp;
3168   gfc_se se;
3169
3170   int dim;
3171
3172   as = sym->as;
3173
3174   size = gfc_index_one_node;
3175   offset = gfc_index_zero_node;
3176   for (dim = 0; dim < as->rank; dim++)
3177     {
3178       /* Evaluate non-constant array bound expressions.  */
3179       lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
3180       if (as->lower[dim] && !INTEGER_CST_P (lbound))
3181         {
3182           gfc_init_se (&se, NULL);
3183           gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
3184           gfc_add_block_to_block (pblock, &se.pre);
3185           gfc_add_modify_expr (pblock, lbound, se.expr);
3186         }
3187       ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
3188       if (as->upper[dim] && !INTEGER_CST_P (ubound))
3189         {
3190           gfc_init_se (&se, NULL);
3191           gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
3192           gfc_add_block_to_block (pblock, &se.pre);
3193           gfc_add_modify_expr (pblock, ubound, se.expr);
3194         }
3195       /* The offset of this dimension.  offset = offset - lbound * stride.  */
3196       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, size);
3197       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3198
3199       /* The size of this dimension, and the stride of the next.  */
3200       if (dim + 1 < as->rank)
3201         stride = GFC_TYPE_ARRAY_STRIDE (type, dim + 1);
3202       else
3203         stride = NULL_TREE;
3204
3205       if (ubound != NULL_TREE && !(stride && INTEGER_CST_P (stride)))
3206         {
3207           /* Calculate stride = size * (ubound + 1 - lbound).  */
3208           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3209                              gfc_index_one_node, lbound);
3210           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, ubound, tmp);
3211           tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
3212           if (stride)
3213             gfc_add_modify_expr (pblock, stride, tmp);
3214           else
3215             stride = gfc_evaluate_now (tmp, pblock);
3216         }
3217
3218       size = stride;
3219     }
3220
3221   *poffset = offset;
3222   return size;
3223 }
3224
3225
3226 /* Generate code to initialize/allocate an array variable.  */
3227
3228 tree
3229 gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, tree fnbody)
3230 {
3231   stmtblock_t block;
3232   tree type;
3233   tree tmp;
3234   tree fndecl;
3235   tree size;
3236   tree offset;
3237   bool onstack;
3238
3239   gcc_assert (!(sym->attr.pointer || sym->attr.allocatable));
3240
3241   /* Do nothing for USEd variables.  */
3242   if (sym->attr.use_assoc)
3243     return fnbody;
3244
3245   type = TREE_TYPE (decl);
3246   gcc_assert (GFC_ARRAY_TYPE_P (type));
3247   onstack = TREE_CODE (type) != POINTER_TYPE;
3248
3249   gfc_start_block (&block);
3250
3251   /* Evaluate character string length.  */
3252   if (sym->ts.type == BT_CHARACTER
3253       && onstack && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3254     {
3255       gfc_trans_init_string_length (sym->ts.cl, &block);
3256
3257       /* Emit a DECL_EXPR for this variable, which will cause the
3258          gimplifier to allocate storage, and all that good stuff.  */
3259       tmp = build1 (DECL_EXPR, TREE_TYPE (decl), decl);
3260       gfc_add_expr_to_block (&block, tmp);
3261     }
3262
3263   if (onstack)
3264     {
3265       gfc_add_expr_to_block (&block, fnbody);
3266       return gfc_finish_block (&block);
3267     }
3268
3269   type = TREE_TYPE (type);
3270
3271   gcc_assert (!sym->attr.use_assoc);
3272   gcc_assert (!TREE_STATIC (decl));
3273   gcc_assert (!sym->module);
3274
3275   if (sym->ts.type == BT_CHARACTER
3276       && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3277     gfc_trans_init_string_length (sym->ts.cl, &block);
3278
3279   size = gfc_trans_array_bounds (type, sym, &offset, &block);
3280
3281   /* The size is the number of elements in the array, so multiply by the
3282      size of an element to get the total size.  */
3283   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
3284   size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
3285
3286   /* Allocate memory to hold the data.  */
3287   tmp = gfc_chainon_list (NULL_TREE, size);
3288
3289   if (gfc_index_integer_kind == 4)
3290     fndecl = gfor_fndecl_internal_malloc;
3291   else if (gfc_index_integer_kind == 8)
3292     fndecl = gfor_fndecl_internal_malloc64;
3293   else
3294     gcc_unreachable ();
3295   tmp = gfc_build_function_call (fndecl, tmp);
3296   tmp = fold (convert (TREE_TYPE (decl), tmp));
3297   gfc_add_modify_expr (&block, decl, tmp);
3298
3299   /* Set offset of the array.  */
3300   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3301     gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3302
3303
3304   /* Automatic arrays should not have initializers.  */
3305   gcc_assert (!sym->value);
3306
3307   gfc_add_expr_to_block (&block, fnbody);
3308
3309   /* Free the temporary.  */
3310   tmp = convert (pvoid_type_node, decl);
3311   tmp = gfc_chainon_list (NULL_TREE, tmp);
3312   tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
3313   gfc_add_expr_to_block (&block, tmp);
3314
3315   return gfc_finish_block (&block);
3316 }
3317
3318
3319 /* Generate entry and exit code for g77 calling convention arrays.  */
3320
3321 tree
3322 gfc_trans_g77_array (gfc_symbol * sym, tree body)
3323 {
3324   tree parm;
3325   tree type;
3326   locus loc;
3327   tree offset;
3328   tree tmp;
3329   stmtblock_t block;
3330
3331   gfc_get_backend_locus (&loc);
3332   gfc_set_backend_locus (&sym->declared_at);
3333
3334   /* Descriptor type.  */
3335   parm = sym->backend_decl;
3336   type = TREE_TYPE (parm);
3337   gcc_assert (GFC_ARRAY_TYPE_P (type));
3338
3339   gfc_start_block (&block);
3340
3341   if (sym->ts.type == BT_CHARACTER
3342       && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
3343     gfc_trans_init_string_length (sym->ts.cl, &block);
3344
3345   /* Evaluate the bounds of the array.  */
3346   gfc_trans_array_bounds (type, sym, &offset, &block);
3347
3348   /* Set the offset.  */
3349   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3350     gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3351
3352   /* Set the pointer itself if we aren't using the parameter directly.  */
3353   if (TREE_CODE (parm) != PARM_DECL)
3354     {
3355       tmp = convert (TREE_TYPE (parm), GFC_DECL_SAVED_DESCRIPTOR (parm));
3356       gfc_add_modify_expr (&block, parm, tmp);
3357     }
3358   tmp = gfc_finish_block (&block);
3359
3360   gfc_set_backend_locus (&loc);
3361
3362   gfc_start_block (&block);
3363   /* Add the initialization code to the start of the function.  */
3364   gfc_add_expr_to_block (&block, tmp);
3365   gfc_add_expr_to_block (&block, body);
3366
3367   return gfc_finish_block (&block);
3368 }
3369
3370
3371 /* Modify the descriptor of an array parameter so that it has the
3372    correct lower bound.  Also move the upper bound accordingly.
3373    If the array is not packed, it will be copied into a temporary.
3374    For each dimension we set the new lower and upper bounds.  Then we copy the
3375    stride and calculate the offset for this dimension.  We also work out
3376    what the stride of a packed array would be, and see it the two match.
3377    If the array need repacking, we set the stride to the values we just
3378    calculated, recalculate the offset and copy the array data.
3379    Code is also added to copy the data back at the end of the function.
3380    */
3381
3382 tree
3383 gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
3384 {
3385   tree size;
3386   tree type;
3387   tree offset;
3388   locus loc;
3389   stmtblock_t block;
3390   stmtblock_t cleanup;
3391   tree lbound;
3392   tree ubound;
3393   tree dubound;
3394   tree dlbound;
3395   tree dumdesc;
3396   tree tmp;
3397   tree stmt;
3398   tree stride;
3399   tree stmt_packed;
3400   tree stmt_unpacked;
3401   tree partial;
3402   gfc_se se;
3403   int n;
3404   int checkparm;
3405   int no_repack;
3406   bool optional_arg;
3407
3408   /* Do nothing for pointer and allocatable arrays.  */
3409   if (sym->attr.pointer || sym->attr.allocatable)
3410     return body;
3411
3412   if (sym->attr.dummy && gfc_is_nodesc_array (sym))
3413     return gfc_trans_g77_array (sym, body);
3414
3415   gfc_get_backend_locus (&loc);
3416   gfc_set_backend_locus (&sym->declared_at);
3417
3418   /* Descriptor type.  */
3419   type = TREE_TYPE (tmpdesc);
3420   gcc_assert (GFC_ARRAY_TYPE_P (type));
3421   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3422   dumdesc = gfc_build_indirect_ref (dumdesc);
3423   gfc_start_block (&block);
3424
3425   if (sym->ts.type == BT_CHARACTER
3426       && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
3427     gfc_trans_init_string_length (sym->ts.cl, &block);
3428
3429   checkparm = (sym->as->type == AS_EXPLICIT && flag_bounds_check);
3430
3431   no_repack = !(GFC_DECL_PACKED_ARRAY (tmpdesc)
3432                 || GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc));
3433
3434   if (GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc))
3435     {
3436       /* For non-constant shape arrays we only check if the first dimension
3437          is contiguous.  Repacking higher dimensions wouldn't gain us
3438          anything as we still don't know the array stride.  */
3439       partial = gfc_create_var (boolean_type_node, "partial");
3440       TREE_USED (partial) = 1;
3441       tmp = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
3442       tmp = fold_build2 (EQ_EXPR, boolean_type_node, tmp, integer_one_node);
3443       gfc_add_modify_expr (&block, partial, tmp);
3444     }
3445   else
3446     {
3447       partial = NULL_TREE;
3448     }
3449
3450   /* The naming of stmt_unpacked and stmt_packed may be counter-intuitive
3451      here, however I think it does the right thing.  */
3452   if (no_repack)
3453     {
3454       /* Set the first stride.  */
3455       stride = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
3456       stride = gfc_evaluate_now (stride, &block);
3457
3458       tmp = build2 (EQ_EXPR, boolean_type_node, stride, integer_zero_node);
3459       tmp = build3 (COND_EXPR, gfc_array_index_type, tmp,
3460                     gfc_index_one_node, stride);
3461       stride = GFC_TYPE_ARRAY_STRIDE (type, 0);
3462       gfc_add_modify_expr (&block, stride, tmp);
3463
3464       /* Allow the user to disable array repacking.  */
3465       stmt_unpacked = NULL_TREE;
3466     }
3467   else
3468     {
3469       gcc_assert (integer_onep (GFC_TYPE_ARRAY_STRIDE (type, 0)));
3470       /* A library call to repack the array if necessary.  */
3471       tmp = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3472       tmp = gfc_chainon_list (NULL_TREE, tmp);
3473       stmt_unpacked = gfc_build_function_call (gfor_fndecl_in_pack, tmp);
3474
3475       stride = gfc_index_one_node;
3476     }
3477
3478   /* This is for the case where the array data is used directly without
3479      calling the repack function.  */
3480   if (no_repack || partial != NULL_TREE)
3481     stmt_packed = gfc_conv_descriptor_data_get (dumdesc);
3482   else
3483     stmt_packed = NULL_TREE;
3484
3485   /* Assign the data pointer.  */
3486   if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
3487     {
3488       /* Don't repack unknown shape arrays when the first stride is 1.  */
3489       tmp = build3 (COND_EXPR, TREE_TYPE (stmt_packed), partial,
3490                     stmt_packed, stmt_unpacked);
3491     }
3492   else
3493     tmp = stmt_packed != NULL_TREE ? stmt_packed : stmt_unpacked;
3494   gfc_add_modify_expr (&block, tmpdesc, fold_convert (type, tmp));
3495
3496   offset = gfc_index_zero_node;
3497   size = gfc_index_one_node;
3498
3499   /* Evaluate the bounds of the array.  */
3500   for (n = 0; n < sym->as->rank; n++)
3501     {
3502       if (checkparm || !sym->as->upper[n])
3503         {
3504           /* Get the bounds of the actual parameter.  */
3505           dubound = gfc_conv_descriptor_ubound (dumdesc, gfc_rank_cst[n]);
3506           dlbound = gfc_conv_descriptor_lbound (dumdesc, gfc_rank_cst[n]);
3507         }
3508       else
3509         {
3510           dubound = NULL_TREE;
3511           dlbound = NULL_TREE;
3512         }
3513
3514       lbound = GFC_TYPE_ARRAY_LBOUND (type, n);
3515       if (!INTEGER_CST_P (lbound))
3516         {
3517           gfc_init_se (&se, NULL);
3518           gfc_conv_expr_type (&se, sym->as->upper[n],
3519                               gfc_array_index_type);
3520           gfc_add_block_to_block (&block, &se.pre);
3521           gfc_add_modify_expr (&block, lbound, se.expr);
3522         }
3523
3524       ubound = GFC_TYPE_ARRAY_UBOUND (type, n);
3525       /* Set the desired upper bound.  */
3526       if (sym->as->upper[n])
3527         {
3528           /* We know what we want the upper bound to be.  */
3529           if (!INTEGER_CST_P (ubound))
3530             {
3531               gfc_init_se (&se, NULL);
3532               gfc_conv_expr_type (&se, sym->as->upper[n],
3533                                   gfc_array_index_type);
3534               gfc_add_block_to_block (&block, &se.pre);
3535               gfc_add_modify_expr (&block, ubound, se.expr);
3536             }
3537
3538           /* Check the sizes match.  */
3539           if (checkparm)
3540             {
3541               /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)).  */
3542
3543               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3544                                  ubound, lbound);
3545               stride = build2 (MINUS_EXPR, gfc_array_index_type,
3546                                dubound, dlbound);
3547               tmp = fold_build2 (NE_EXPR, gfc_array_index_type, tmp, stride);
3548               gfc_trans_runtime_check (tmp, gfc_strconst_bounds, &block);
3549             }
3550         }
3551       else
3552         {
3553           /* For assumed shape arrays move the upper bound by the same amount
3554              as the lower bound.  */
3555           tmp = build2 (MINUS_EXPR, gfc_array_index_type, dubound, dlbound);
3556           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp, lbound);
3557           gfc_add_modify_expr (&block, ubound, tmp);
3558         }
3559       /* The offset of this dimension.  offset = offset - lbound * stride.  */
3560       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, stride);
3561       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3562
3563       /* The size of this dimension, and the stride of the next.  */
3564       if (n + 1 < sym->as->rank)
3565         {
3566           stride = GFC_TYPE_ARRAY_STRIDE (type, n + 1);
3567
3568           if (no_repack || partial != NULL_TREE)
3569             {
3570               stmt_unpacked =
3571                 gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[n+1]);
3572             }
3573
3574           /* Figure out the stride if not a known constant.  */
3575           if (!INTEGER_CST_P (stride))
3576             {
3577               if (no_repack)
3578                 stmt_packed = NULL_TREE;
3579               else
3580                 {
3581                   /* Calculate stride = size * (ubound + 1 - lbound).  */
3582                   tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3583                                      gfc_index_one_node, lbound);
3584                   tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3585                                      ubound, tmp);
3586                   size = fold_build2 (MULT_EXPR, gfc_array_index_type,
3587                                       size, tmp);
3588                   stmt_packed = size;
3589                 }
3590
3591               /* Assign the stride.  */
3592               if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
3593                 tmp = build3 (COND_EXPR, gfc_array_index_type, partial,
3594                               stmt_unpacked, stmt_packed);
3595               else
3596                 tmp = (stmt_packed != NULL_TREE) ? stmt_packed : stmt_unpacked;
3597               gfc_add_modify_expr (&block, stride, tmp);
3598             }
3599         }
3600     }
3601
3602   /* Set the offset.  */
3603   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3604     gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3605
3606   stmt = gfc_finish_block (&block);
3607
3608   gfc_start_block (&block);
3609
3610   /* Only do the entry/initialization code if the arg is present.  */
3611   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3612   optional_arg = (sym->attr.optional
3613                   || (sym->ns->proc_name->attr.entry_master
3614                       && sym->attr.dummy));
3615   if (optional_arg)
3616     {
3617       tmp = gfc_conv_expr_present (sym);
3618       stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3619     }
3620   gfc_add_expr_to_block (&block, stmt);
3621
3622   /* Add the main function body.  */
3623   gfc_add_expr_to_block (&block, body);
3624
3625   /* Cleanup code.  */
3626   if (!no_repack)
3627     {
3628       gfc_start_block (&cleanup);
3629       
3630       if (sym->attr.intent != INTENT_IN)
3631         {
3632           /* Copy the data back.  */
3633           tmp = gfc_chainon_list (NULL_TREE, dumdesc);
3634           tmp = gfc_chainon_list (tmp, tmpdesc);
3635           tmp = gfc_build_function_call (gfor_fndecl_in_unpack, tmp);
3636           gfc_add_expr_to_block (&cleanup, tmp);
3637         }
3638
3639       /* Free the temporary.  */
3640       tmp = gfc_chainon_list (NULL_TREE, tmpdesc);
3641       tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
3642       gfc_add_expr_to_block (&cleanup, tmp);
3643
3644       stmt = gfc_finish_block (&cleanup);
3645         
3646       /* Only do the cleanup if the array was repacked.  */
3647       tmp = gfc_build_indirect_ref (dumdesc);
3648       tmp = gfc_conv_descriptor_data_get (tmp);
3649       tmp = build2 (NE_EXPR, boolean_type_node, tmp, tmpdesc);
3650       stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3651
3652       if (optional_arg)
3653         {
3654           tmp = gfc_conv_expr_present (sym);
3655           stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3656         }
3657       gfc_add_expr_to_block (&block, stmt);
3658     }
3659   /* We don't need to free any memory allocated by internal_pack as it will
3660      be freed at the end of the function by pop_context.  */
3661   return gfc_finish_block (&block);
3662 }
3663
3664
3665 /* Convert an array for passing as an actual parameter.  Expressions and
3666    vector subscripts are evaluated and stored in a temporary, which is then
3667    passed.  For whole arrays the descriptor is passed.  For array sections
3668    a modified copy of the descriptor is passed, but using the original data.
3669    Also used for array pointer assignments by setting se->direct_byref.  */
3670
3671 void
3672 gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
3673 {
3674   gfc_loopinfo loop;
3675   gfc_ss *secss;
3676   gfc_ss_info *info;
3677   int need_tmp;
3678   int n;
3679   tree tmp;
3680   tree desc;
3681   stmtblock_t block;
3682   tree start;
3683   tree offset;
3684   int full;
3685   gfc_ss *vss;
3686   gfc_ref *ref;
3687
3688   gcc_assert (ss != gfc_ss_terminator);
3689
3690   /* TODO: Pass constant array constructors without a temporary.  */
3691   /* Special case things we know we can pass easily.  */
3692   switch (expr->expr_type)
3693     {
3694     case EXPR_VARIABLE:
3695       /* If we have a linear array section, we can pass it directly.
3696          Otherwise we need to copy it into a temporary.  */
3697
3698       /* Find the SS for the array section.  */
3699       secss = ss;
3700       while (secss != gfc_ss_terminator && secss->type != GFC_SS_SECTION)
3701         secss = secss->next;
3702
3703       gcc_assert (secss != gfc_ss_terminator);
3704
3705       need_tmp = 0;
3706       for (n = 0; n < secss->data.info.dimen; n++)
3707         {
3708           vss = secss->data.info.subscript[secss->data.info.dim[n]];
3709           if (vss && vss->type == GFC_SS_VECTOR)
3710             need_tmp = 1;
3711         }
3712
3713       info = &secss->data.info;
3714
3715       /* Get the descriptor for the array.  */
3716       gfc_conv_ss_descriptor (&se->pre, secss, 0);
3717       desc = info->descriptor;
3718       if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
3719         {
3720           /* Create a new descriptor if the array doesn't have one.  */
3721           full = 0;
3722         }
3723       else if (info->ref->u.ar.type == AR_FULL)
3724         full = 1;
3725       else if (se->direct_byref)
3726         full = 0;
3727       else
3728         {
3729           ref = info->ref;
3730           gcc_assert (ref->u.ar.type == AR_SECTION);
3731
3732           full = 1;
3733           for (n = 0; n < ref->u.ar.dimen; n++)
3734             {
3735               /* Detect passing the full array as a section.  This could do
3736                  even more checking, but it doesn't seem worth it.  */
3737               if (ref->u.ar.start[n]
3738                   || ref->u.ar.end[n]
3739                   || (ref->u.ar.stride[n]
3740                       && !gfc_expr_is_one (ref->u.ar.stride[n], 0)))
3741                 {
3742                   full = 0;
3743                   break;
3744                 }
3745             }
3746         }
3747
3748       /* Check for substring references.  */
3749       ref = expr->ref;
3750       if (!need_tmp && ref && expr->ts.type == BT_CHARACTER)
3751         {
3752           while (ref->next)
3753             ref = ref->next;
3754           if (ref->type == REF_SUBSTRING)
3755             {
3756               /* In general character substrings need a copy.  Character
3757                  array strides are expressed as multiples of the element
3758                  size (consistent with other array types), not in
3759                  characters.  */
3760               full = 0;
3761               need_tmp = 1;
3762             }
3763         }
3764
3765       if (full)
3766         {
3767           if (se->direct_byref)
3768             {
3769               /* Copy the descriptor for pointer assignments.  */
3770               gfc_add_modify_expr (&se->pre, se->expr, desc);
3771             }
3772           else if (se->want_pointer)
3773             {
3774               /* We pass full arrays directly.  This means that pointers and
3775                  allocatable arrays should also work.  */
3776               se->expr = gfc_build_addr_expr (NULL_TREE, desc);
3777             }
3778           else
3779             {
3780               se->expr = desc;
3781             }
3782
3783           if (expr->ts.type == BT_CHARACTER)
3784             se->string_length = gfc_get_expr_charlen (expr);
3785
3786           return;
3787         }
3788       break;
3789       
3790     case EXPR_FUNCTION:
3791       /* A transformational function return value will be a temporary
3792          array descriptor.  We still need to go through the scalarizer
3793          to create the descriptor.  Elemental functions ar handled as
3794          arbitrary expressions, i.e. copy to a temporary.  */
3795       secss = ss;
3796       /* Look for the SS for this function.  */
3797       while (secss != gfc_ss_terminator
3798              && (secss->type != GFC_SS_FUNCTION || secss->expr != expr))
3799         secss = secss->next;
3800
3801       if (se->direct_byref)
3802         {
3803           gcc_assert (secss != gfc_ss_terminator);
3804
3805           /* For pointer assignments pass the descriptor directly.  */
3806           se->ss = secss;
3807           se->expr = gfc_build_addr_expr (NULL, se->expr);
3808           gfc_conv_expr (se, expr);
3809           return;
3810         }
3811
3812       if (secss == gfc_ss_terminator)
3813         {
3814           /* Elemental function.  */
3815           need_tmp = 1;
3816           info = NULL;
3817         }
3818       else
3819         {
3820           /* Transformational function.  */
3821           info = &secss->data.info;
3822           need_tmp = 0;
3823         }
3824       break;
3825
3826     default:
3827       /* Something complicated.  Copy it into a temporary.  */
3828       need_tmp = 1;
3829       secss = NULL;
3830       info = NULL;
3831       break;
3832     }
3833
3834
3835   gfc_init_loopinfo (&loop);
3836
3837   /* Associate the SS with the loop.  */
3838   gfc_add_ss_to_loop (&loop, ss);
3839
3840   /* Tell the scalarizer not to bother creating loop variables, etc.  */
3841   if (!need_tmp)
3842     loop.array_parameter = 1;
3843   else
3844     gcc_assert (se->want_pointer && !se->direct_byref);
3845
3846   /* Setup the scalarizing loops and bounds.  */
3847   gfc_conv_ss_startstride (&loop);
3848
3849   if (need_tmp)
3850     {
3851       /* Tell the scalarizer to make a temporary.  */
3852       loop.temp_ss = gfc_get_ss ();
3853       loop.temp_ss->type = GFC_SS_TEMP;
3854       loop.temp_ss->next = gfc_ss_terminator;
3855       if (expr->ts.type == BT_CHARACTER)
3856         {
3857           gcc_assert (expr->ts.cl && expr->ts.cl->length
3858                       && expr->ts.cl->length->expr_type == EXPR_CONSTANT);
3859           loop.temp_ss->string_length = gfc_conv_mpz_to_tree
3860                         (expr->ts.cl->length->value.integer,
3861                          expr->ts.cl->length->ts.kind);
3862           expr->ts.cl->backend_decl = loop.temp_ss->string_length;
3863         }
3864         loop.temp_ss->data.temp.type = gfc_typenode_for_spec (&expr->ts);
3865
3866       /* ... which can hold our string, if present.  */
3867       if (expr->ts.type == BT_CHARACTER)
3868         {
3869           loop.temp_ss->string_length = TYPE_SIZE_UNIT (loop.temp_ss->data.temp.type);
3870           se->string_length = loop.temp_ss->string_length;
3871         }
3872       else
3873         loop.temp_ss->string_length = NULL;
3874       loop.temp_ss->data.temp.dimen = loop.dimen;
3875       gfc_add_ss_to_loop (&loop, loop.temp_ss);
3876     }
3877
3878   gfc_conv_loop_setup (&loop);
3879
3880   if (need_tmp)
3881     {
3882       /* Copy into a temporary and pass that.  We don't need to copy the data
3883          back because expressions and vector subscripts must be INTENT_IN.  */
3884       /* TODO: Optimize passing function return values.  */
3885       gfc_se lse;
3886       gfc_se rse;
3887
3888       /* Start the copying loops.  */
3889       gfc_mark_ss_chain_used (loop.temp_ss, 1);
3890       gfc_mark_ss_chain_used (ss, 1);
3891       gfc_start_scalarized_body (&loop, &block);
3892
3893       /* Copy each data element.  */
3894       gfc_init_se (&lse, NULL);
3895       gfc_copy_loopinfo_to_se (&lse, &loop);
3896       gfc_init_se (&rse, NULL);
3897       gfc_copy_loopinfo_to_se (&rse, &loop);
3898
3899       lse.ss = loop.temp_ss;
3900       rse.ss = ss;
3901
3902       gfc_conv_scalarized_array_ref (&lse, NULL);
3903       if (expr->ts.type == BT_CHARACTER)
3904         {
3905           gfc_conv_expr (&rse, expr);
3906           rse.expr = gfc_build_indirect_ref (rse.expr);
3907         }
3908       else
3909         gfc_conv_expr_val (&rse, expr);
3910
3911       gfc_add_block_to_block (&block, &rse.pre);
3912       gfc_add_block_to_block (&block, &lse.pre);
3913
3914       gfc_add_modify_expr (&block, lse.expr, rse.expr);
3915
3916       /* Finish the copying loops.  */
3917       gfc_trans_scalarizing_loops (&loop, &block);
3918
3919       /* Set the first stride component to zero to indicate a temporary.  */
3920       desc = loop.temp_ss->data.info.descriptor;
3921       tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[0]);
3922       gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
3923
3924       gcc_assert (is_gimple_lvalue (desc));
3925       se->expr = gfc_build_addr_expr (NULL, desc);
3926     }
3927   else if (expr->expr_type == EXPR_FUNCTION)
3928     {
3929       desc = info->descriptor;
3930
3931       if (se->want_pointer)
3932         se->expr = gfc_build_addr_expr (NULL_TREE, desc);
3933       else
3934         se->expr = desc;
3935
3936       if (expr->ts.type == BT_CHARACTER)
3937         se->string_length = expr->symtree->n.sym->ts.cl->backend_decl;
3938     }
3939   else
3940     {
3941       /* We pass sections without copying to a temporary.  Make a new
3942          descriptor and point it at the section we want.  The loop variable
3943          limits will be the limits of the section.
3944          A function may decide to repack the array to speed up access, but
3945          we're not bothered about that here.  */
3946       int dim;
3947       tree parm;
3948       tree parmtype;
3949       tree stride;
3950       tree from;
3951       tree to;
3952       tree base;
3953
3954       /* Set the string_length for a character array.  */
3955       if (expr->ts.type == BT_CHARACTER)
3956         se->string_length =  gfc_get_expr_charlen (expr);
3957
3958       desc = info->descriptor;
3959       gcc_assert (secss && secss != gfc_ss_terminator);
3960       if (se->direct_byref)
3961         {
3962           /* For pointer assignments we fill in the destination.  */
3963           parm = se->expr;
3964           parmtype = TREE_TYPE (parm);
3965         }
3966       else
3967         {
3968           /* Otherwise make a new one.  */
3969           parmtype = gfc_get_element_type (TREE_TYPE (desc));
3970           parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen,
3971                                                 loop.from, loop.to, 0);
3972           parm = gfc_create_var (parmtype, "parm");
3973         }
3974
3975       offset = gfc_index_zero_node;
3976       dim = 0;
3977
3978       /* The following can be somewhat confusing.  We have two
3979          descriptors, a new one and the original array.
3980          {parm, parmtype, dim} refer to the new one.
3981          {desc, type, n, secss, loop} refer to the original, which maybe
3982          a descriptorless array.
3983          The bounds of the scalarization are the bounds of the section.
3984          We don't have to worry about numeric overflows when calculating
3985          the offsets because all elements are within the array data.  */
3986
3987       /* Set the dtype.  */
3988       tmp = gfc_conv_descriptor_dtype (parm);
3989       gfc_add_modify_expr (&loop.pre, tmp, gfc_get_dtype (parmtype));
3990
3991       if (se->direct_byref)
3992         base = gfc_index_zero_node;
3993       else
3994         base = NULL_TREE;
3995
3996       for (n = 0; n < info->ref->u.ar.dimen; n++)
3997         {
3998           stride = gfc_conv_array_stride (desc, n);
3999
4000           /* Work out the offset.  */
4001           if (info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4002             {
4003               gcc_assert (info->subscript[n]
4004                       && info->subscript[n]->type == GFC_SS_SCALAR);
4005               start = info->subscript[n]->data.scalar.expr;
4006             }
4007           else
4008             {
4009               /* Check we haven't somehow got out of sync.  */
4010               gcc_assert (info->dim[dim] == n);
4011
4012               /* Evaluate and remember the start of the section.  */
4013               start = info->start[dim];
4014               stride = gfc_evaluate_now (stride, &loop.pre);
4015             }
4016
4017           tmp = gfc_conv_array_lbound (desc, n);
4018           tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), start, tmp);
4019
4020           tmp = fold_build2 (MULT_EXPR, TREE_TYPE (tmp), tmp, stride);
4021           offset = fold_build2 (PLUS_EXPR, TREE_TYPE (tmp), offset, tmp);
4022
4023           if (info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4024             {
4025               /* For elemental dimensions, we only need the offset.  */
4026               continue;
4027             }
4028
4029           /* Vector subscripts need copying and are handled elsewhere.  */
4030           gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_RANGE);
4031
4032           /* Set the new lower bound.  */
4033           from = loop.from[dim];
4034           to = loop.to[dim];
4035           if (!integer_onep (from))
4036             {
4037               /* Make sure the new section starts at 1.  */
4038               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4039                                  gfc_index_one_node, from);
4040               to = fold_build2 (PLUS_EXPR, gfc_array_index_type, to, tmp);
4041               from = gfc_index_one_node;
4042             }
4043           tmp = gfc_conv_descriptor_lbound (parm, gfc_rank_cst[dim]);
4044           gfc_add_modify_expr (&loop.pre, tmp, from);
4045
4046           /* Set the new upper bound.  */
4047           tmp = gfc_conv_descriptor_ubound (parm, gfc_rank_cst[dim]);
4048           gfc_add_modify_expr (&loop.pre, tmp, to);
4049
4050           /* Multiply the stride by the section stride to get the
4051              total stride.  */
4052           stride = fold_build2 (MULT_EXPR, gfc_array_index_type,
4053                                 stride, info->stride[dim]);
4054
4055           if (se->direct_byref)
4056             base = fold_build2 (MINUS_EXPR, TREE_TYPE (base),
4057                                 base, stride);
4058
4059           /* Store the new stride.  */
4060           tmp = gfc_conv_descriptor_stride (parm, gfc_rank_cst[dim]);
4061           gfc_add_modify_expr (&loop.pre, tmp, stride);
4062
4063           dim++;
4064         }
4065
4066       /* Point the data pointer at the first element in the section.  */
4067       tmp = gfc_conv_array_data (desc);
4068       tmp = gfc_build_indirect_ref (tmp);
4069       tmp = gfc_build_array_ref (tmp, offset);
4070       offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
4071       gfc_conv_descriptor_data_set (&loop.pre, parm, offset);
4072
4073       if (se->direct_byref)
4074         {
4075           /* Set the offset.  */
4076           tmp = gfc_conv_descriptor_offset (parm);
4077           gfc_add_modify_expr (&loop.pre, tmp, base);
4078         }
4079       else
4080         {
4081           /* Only the callee knows what the correct offset it, so just set
4082              it to zero here.  */
4083           tmp = gfc_conv_descriptor_offset (parm);
4084           gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
4085         }
4086
4087       if (!se->direct_byref)
4088         {
4089           /* Get a pointer to the new descriptor.  */
4090           if (se->want_pointer)
4091             se->expr = gfc_build_addr_expr (NULL, parm);
4092           else
4093             se->expr = parm;
4094         }
4095     }
4096
4097   gfc_add_block_to_block (&se->pre, &loop.pre);
4098   gfc_add_block_to_block (&se->post, &loop.post);
4099
4100   /* Cleanup the scalarizer.  */
4101   gfc_cleanup_loop (&loop);
4102 }
4103
4104
4105 /* Convert an array for passing as an actual parameter.  */
4106 /* TODO: Optimize passing g77 arrays.  */
4107
4108 void
4109 gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77)
4110 {
4111   tree ptr;
4112   tree desc;
4113   tree tmp;
4114   tree stmt;
4115   gfc_symbol *sym;
4116   stmtblock_t block;
4117
4118   /* Passing address of the array if it is not pointer or assumed-shape.  */
4119   if (expr->expr_type == EXPR_VARIABLE
4120        && expr->ref->u.ar.type == AR_FULL && g77)
4121     {
4122       sym = expr->symtree->n.sym;
4123       tmp = gfc_get_symbol_decl (sym);
4124       if (sym->ts.type == BT_CHARACTER)
4125         se->string_length = sym->ts.cl->backend_decl;
4126       if (!sym->attr.pointer && sym->as->type != AS_ASSUMED_SHAPE 
4127           && !sym->attr.allocatable)
4128         {
4129           /* Some variables are declared directly, others are declared as
4130              pointers and allocated on the heap.  */
4131           if (sym->attr.dummy || POINTER_TYPE_P (TREE_TYPE (tmp)))
4132             se->expr = tmp;
4133           else
4134             se->expr = gfc_build_addr_expr (NULL, tmp);
4135           return;
4136         }
4137       if (sym->attr.allocatable)
4138         {
4139           se->expr = gfc_conv_array_data (tmp);
4140           return;
4141         }
4142     }
4143
4144   se->want_pointer = 1;
4145   gfc_conv_expr_descriptor (se, expr, ss);
4146
4147   if (g77)
4148     {
4149       desc = se->expr;
4150       /* Repack the array.  */
4151       tmp = gfc_chainon_list (NULL_TREE, desc);
4152       ptr = gfc_build_function_call (gfor_fndecl_in_pack, tmp);
4153       ptr = gfc_evaluate_now (ptr, &se->pre);
4154       se->expr = ptr;
4155
4156       gfc_start_block (&block);
4157
4158       /* Copy the data back.  */
4159       tmp = gfc_chainon_list (NULL_TREE, desc);
4160       tmp = gfc_chainon_list (tmp, ptr);
4161       tmp = gfc_build_function_call (gfor_fndecl_in_unpack, tmp);
4162       gfc_add_expr_to_block (&block, tmp);
4163
4164       /* Free the temporary.  */
4165       tmp = convert (pvoid_type_node, ptr);
4166       tmp = gfc_chainon_list (NULL_TREE, tmp);
4167       tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
4168       gfc_add_expr_to_block (&block, tmp);
4169
4170       stmt = gfc_finish_block (&block);
4171
4172       gfc_init_block (&block);
4173       /* Only if it was repacked.  This code needs to be executed before the
4174          loop cleanup code.  */
4175       tmp = gfc_build_indirect_ref (desc);
4176       tmp = gfc_conv_array_data (tmp);
4177       tmp = build2 (NE_EXPR, boolean_type_node, ptr, tmp);
4178       tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4179
4180       gfc_add_expr_to_block (&block, tmp);
4181       gfc_add_block_to_block (&block, &se->post);
4182
4183       gfc_init_block (&se->post);
4184       gfc_add_block_to_block (&se->post, &block);
4185     }
4186 }
4187
4188
4189 /* NULLIFY an allocatable/pointer array on function entry, free it on exit.  */
4190
4191 tree
4192 gfc_trans_deferred_array (gfc_symbol * sym, tree body)
4193 {
4194   tree type;
4195   tree tmp;
4196   tree descriptor;
4197   tree deallocate;
4198   stmtblock_t block;
4199   stmtblock_t fnblock;
4200   locus loc;
4201
4202   /* Make sure the frontend gets these right.  */
4203   if (!(sym->attr.pointer || sym->attr.allocatable))
4204     fatal_error
4205       ("Possible frontend bug: Deferred array size without pointer or allocatable attribute.");
4206
4207   gfc_init_block (&fnblock);
4208
4209   gcc_assert (TREE_CODE (sym->backend_decl) == VAR_DECL);
4210   if (sym->ts.type == BT_CHARACTER
4211       && !INTEGER_CST_P (sym->ts.cl->backend_decl))
4212     gfc_trans_init_string_length (sym->ts.cl, &fnblock);
4213
4214   /* Dummy and use associated variables don't need anything special.  */
4215   if (sym->attr.dummy || sym->attr.use_assoc)
4216     {
4217       gfc_add_expr_to_block (&fnblock, body);
4218
4219       return gfc_finish_block (&fnblock);
4220     }
4221
4222   gfc_get_backend_locus (&loc);
4223   gfc_set_backend_locus (&sym->declared_at);
4224   descriptor = sym->backend_decl;
4225
4226   if (TREE_STATIC (descriptor))
4227     {
4228       /* SAVEd variables are not freed on exit.  */
4229       gfc_trans_static_array_pointer (sym);
4230       return body;
4231     }
4232
4233   /* Get the descriptor type.  */
4234   type = TREE_TYPE (sym->backend_decl);
4235   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
4236
4237   /* NULLIFY the data pointer.  */
4238   gfc_conv_descriptor_data_set (&fnblock, descriptor, null_pointer_node);
4239
4240   gfc_add_expr_to_block (&fnblock, body);
4241
4242   gfc_set_backend_locus (&loc);
4243   /* Allocatable arrays need to be freed when they go out of scope.  */
4244   if (sym->attr.allocatable)
4245     {
4246       gfc_start_block (&block);
4247
4248       /* Deallocate if still allocated at the end of the procedure.  */
4249       deallocate = gfc_array_deallocate (descriptor, null_pointer_node);
4250
4251       tmp = gfc_conv_descriptor_data_get (descriptor);
4252       tmp = build2 (NE_EXPR, boolean_type_node, tmp, 
4253                     build_int_cst (TREE_TYPE (tmp), 0));
4254       tmp = build3_v (COND_EXPR, tmp, deallocate, build_empty_stmt ());
4255       gfc_add_expr_to_block (&block, tmp);
4256
4257       tmp = gfc_finish_block (&block);
4258       gfc_add_expr_to_block (&fnblock, tmp);
4259     }
4260
4261   return gfc_finish_block (&fnblock);
4262 }
4263
4264 /************ Expression Walking Functions ******************/
4265
4266 /* Walk a variable reference.
4267
4268    Possible extension - multiple component subscripts.
4269     x(:,:) = foo%a(:)%b(:)
4270    Transforms to
4271     forall (i=..., j=...)
4272       x(i,j) = foo%a(j)%b(i)
4273     end forall
4274    This adds a fair amout of complexity because you need to deal with more
4275    than one ref.  Maybe handle in a similar manner to vector subscripts.
4276    Maybe not worth the effort.  */
4277
4278
4279 static gfc_ss *
4280 gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
4281 {
4282   gfc_ref *ref;
4283   gfc_array_ref *ar;
4284   gfc_ss *newss;
4285   gfc_ss *head;
4286   int n;
4287
4288   for (ref = expr->ref; ref; ref = ref->next)
4289     if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
4290       break;
4291
4292   for (; ref; ref = ref->next)
4293     {
4294       if (ref->type == REF_SUBSTRING)
4295         {
4296           newss = gfc_get_ss ();
4297           newss->type = GFC_SS_SCALAR;
4298           newss->expr = ref->u.ss.start;
4299           newss->next = ss;
4300           ss = newss;
4301
4302           newss = gfc_get_ss ();
4303           newss->type = GFC_SS_SCALAR;
4304           newss->expr = ref->u.ss.end;
4305           newss->next = ss;
4306           ss = newss;
4307         }
4308
4309       /* We're only interested in array sections from now on.  */
4310       if (ref->type != REF_ARRAY)
4311         continue;
4312
4313       ar = &ref->u.ar;
4314       switch (ar->type)
4315         {
4316         case AR_ELEMENT:
4317           for (n = 0; n < ar->dimen; n++)
4318             {
4319               newss = gfc_get_ss ();
4320               newss->type = GFC_SS_SCALAR;
4321               newss->expr = ar->start[n];
4322               newss->next = ss;
4323               ss = newss;
4324             }
4325           break;
4326
4327         case AR_FULL:
4328           newss = gfc_get_ss ();
4329           newss->type = GFC_SS_SECTION;
4330           newss->expr = expr;
4331           newss->next = ss;
4332           newss->data.info.dimen = ar->as->rank;
4333           newss->data.info.ref = ref;
4334
4335           /* Make sure array is the same as array(:,:), this way
4336              we don't need to special case all the time.  */
4337           ar->dimen = ar->as->rank;
4338           for (n = 0; n < ar->dimen; n++)
4339             {
4340               newss->data.info.dim[n] = n;
4341               ar->dimen_type[n] = DIMEN_RANGE;
4342
4343               gcc_assert (ar->start[n] == NULL);
4344               gcc_assert (ar->end[n] == NULL);
4345               gcc_assert (ar->stride[n] == NULL);
4346             }
4347           ss = newss;
4348           break;
4349
4350         case AR_SECTION:
4351           newss = gfc_get_ss ();
4352           newss->type = GFC_SS_SECTION;
4353           newss->expr = expr;
4354           newss->next = ss;
4355           newss->data.info.dimen = 0;
4356           newss->data.info.ref = ref;
4357
4358           head = newss;
4359
4360           /* We add SS chains for all the subscripts in the section.  */
4361           for (n = 0; n < ar->dimen; n++)
4362             {
4363               gfc_ss *indexss;
4364
4365               switch (ar->dimen_type[n])
4366                 {
4367                 case DIMEN_ELEMENT:
4368                   /* Add SS for elemental (scalar) subscripts.  */
4369                   gcc_assert (ar->start[n]);
4370                   indexss = gfc_get_ss ();
4371                   indexss->type = GFC_SS_SCALAR;
4372                   indexss->expr = ar->start[n];
4373                   indexss->next = gfc_ss_terminator;
4374                   indexss->loop_chain = gfc_ss_terminator;
4375                   newss->data.info.subscript[n] = indexss;
4376                   break;
4377
4378                 case DIMEN_RANGE:
4379                   /* We don't add anything for sections, just remember this
4380                      dimension for later.  */
4381                   newss->data.info.dim[newss->data.info.dimen] = n;
4382                   newss->data.info.dimen++;
4383                   break;
4384
4385                 case DIMEN_VECTOR:
4386                   /* Get a SS for the vector.  This will not be added to the
4387                      chain directly.  */
4388                   indexss = gfc_walk_expr (ar->start[n]);
4389                   if (indexss == gfc_ss_terminator)
4390                     internal_error ("scalar vector subscript???");
4391
4392                   /* We currently only handle really simple vector
4393                      subscripts.  */
4394                   if (indexss->next != gfc_ss_terminator)
4395                     gfc_todo_error ("vector subscript expressions");
4396                   indexss->loop_chain = gfc_ss_terminator;
4397
4398                   /* Mark this as a vector subscript.  We don't add this
4399                      directly into the chain, but as a subscript of the
4400                      existing SS for this term.  */
4401                   indexss->type = GFC_SS_VECTOR;
4402                   newss->data.info.subscript[n] = indexss;
4403                   /* Also remember this dimension.  */
4404                   newss->data.info.dim[newss->data.info.dimen] = n;
4405                   newss->data.info.dimen++;
4406                   break;
4407
4408                 default:
4409                   /* We should know what sort of section it is by now.  */
4410                   gcc_unreachable ();
4411                 }
4412             }
4413           /* We should have at least one non-elemental dimension.  */
4414           gcc_assert (newss->data.info.dimen > 0);
4415           ss = newss;
4416           break;
4417
4418         default:
4419           /* We should know what sort of section it is by now.  */
4420           gcc_unreachable ();
4421         }
4422
4423     }
4424   return ss;
4425 }
4426
4427
4428 /* Walk an expression operator. If only one operand of a binary expression is
4429    scalar, we must also add the scalar term to the SS chain.  */
4430
4431 static gfc_ss *
4432 gfc_walk_op_expr (gfc_ss * ss, gfc_expr * expr)
4433 {
4434   gfc_ss *head;
4435   gfc_ss *head2;
4436   gfc_ss *newss;
4437
4438   head = gfc_walk_subexpr (ss, expr->value.op.op1);
4439   if (expr->value.op.op2 == NULL)
4440     head2 = head;
4441   else
4442     head2 = gfc_walk_subexpr (head, expr->value.op.op2);
4443
4444   /* All operands are scalar.  Pass back and let the caller deal with it.  */
4445   if (head2 == ss)
4446     return head2;
4447
4448   /* All operands require scalarization.  */
4449   if (head != ss && (expr->value.op.op2 == NULL || head2 != head))
4450     return head2;
4451
4452   /* One of the operands needs scalarization, the other is scalar.
4453      Create a gfc_ss for the scalar expression.  */
4454   newss = gfc_get_ss ();
4455   newss->type = GFC_SS_SCALAR;
4456   if (head == ss)
4457     {
4458       /* First operand is scalar.  We build the chain in reverse order, so
4459          add the scarar SS after the second operand.  */
4460       head = head2;
4461       while (head && head->next != ss)
4462         head = head->next;
4463       /* Check we haven't somehow broken the chain.  */
4464       gcc_assert (head);
4465       newss->next = ss;
4466       head->next = newss;
4467       newss->expr = expr->value.op.op1;
4468     }
4469   else                          /* head2 == head */
4470     {
4471       gcc_assert (head2 == head);
4472       /* Second operand is scalar.  */
4473       newss->next = head2;
4474       head2 = newss;
4475       newss->expr = expr->value.op.op2;
4476     }
4477
4478   return head2;
4479 }
4480
4481
4482 /* Reverse a SS chain.  */
4483
4484 static gfc_ss *
4485 gfc_reverse_ss (gfc_ss * ss)
4486 {
4487   gfc_ss *next;
4488   gfc_ss *head;
4489
4490   gcc_assert (ss != NULL);
4491
4492   head = gfc_ss_terminator;
4493   while (ss != gfc_ss_terminator)
4494     {
4495       next = ss->next;
4496       /* Check we didn't somehow break the chain.  */
4497       gcc_assert (next != NULL);
4498       ss->next = head;
4499       head = ss;
4500       ss = next;
4501     }
4502
4503   return (head);
4504 }
4505
4506
4507 /* Walk the arguments of an elemental function.  */
4508
4509 gfc_ss *
4510 gfc_walk_elemental_function_args (gfc_ss * ss, gfc_expr * expr,
4511                                   gfc_ss_type type)
4512 {
4513   gfc_actual_arglist *arg;
4514   int scalar;
4515   gfc_ss *head;
4516   gfc_ss *tail;
4517   gfc_ss *newss;
4518
4519   head = gfc_ss_terminator;
4520   tail = NULL;
4521   scalar = 1;
4522   for (arg = expr->value.function.actual; arg; arg = arg->next)
4523     {
4524       if (!arg->expr)
4525         continue;
4526
4527       newss = gfc_walk_subexpr (head, arg->expr);
4528       if (newss == head)
4529         {
4530           /* Scalar argument.  */
4531           newss = gfc_get_ss ();
4532           newss->type = type;
4533           newss->expr = arg->expr;
4534           newss->next = head;
4535         }
4536       else
4537         scalar = 0;
4538
4539       head = newss;
4540       if (!tail)
4541         {
4542           tail = head;
4543           while (tail->next != gfc_ss_terminator)
4544             tail = tail->next;
4545         }
4546     }
4547
4548   if (scalar)
4549     {
4550       /* If all the arguments are scalar we don't need the argument SS.  */
4551       gfc_free_ss_chain (head);
4552       /* Pass it back.  */
4553       return ss;
4554     }
4555
4556   /* Add it onto the existing chain.  */
4557   tail->next = ss;
4558   return head;
4559 }
4560
4561
4562 /* Walk a function call.  Scalar functions are passed back, and taken out of
4563    scalarization loops.  For elemental functions we walk their arguments.
4564    The result of functions returning arrays is stored in a temporary outside
4565    the loop, so that the function is only called once.  Hence we do not need
4566    to walk their arguments.  */
4567
4568 static gfc_ss *
4569 gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
4570 {
4571   gfc_ss *newss;
4572   gfc_intrinsic_sym *isym;
4573   gfc_symbol *sym;
4574
4575   isym = expr->value.function.isym;
4576
4577   /* Handle intrinsic functions separately.  */
4578   if (isym)
4579     return gfc_walk_intrinsic_function (ss, expr, isym);
4580
4581   sym = expr->value.function.esym;
4582   if (!sym)
4583       sym = expr->symtree->n.sym;
4584
4585   /* A function that returns arrays.  */
4586   if (gfc_return_by_reference (sym) && sym->result->attr.dimension)
4587     {
4588       newss = gfc_get_ss ();
4589       newss->type = GFC_SS_FUNCTION;
4590       newss->expr = expr;
4591       newss->next = ss;
4592       newss->data.info.dimen = expr->rank;
4593       return newss;
4594     }
4595
4596   /* Walk the parameters of an elemental function.  For now we always pass
4597      by reference.  */
4598   if (sym->attr.elemental)
4599     return gfc_walk_elemental_function_args (ss, expr, GFC_SS_REFERENCE);
4600
4601   /* Scalar functions are OK as these are evaluated outside the scalarization
4602      loop.  Pass back and let the caller deal with it.  */
4603   return ss;
4604 }
4605
4606
4607 /* An array temporary is constructed for array constructors.  */
4608
4609 static gfc_ss *
4610 gfc_walk_array_constructor (gfc_ss * ss, gfc_expr * expr)
4611 {
4612   gfc_ss *newss;
4613   int n;
4614
4615   newss = gfc_get_ss ();
4616   newss->type = GFC_SS_CONSTRUCTOR;
4617   newss->expr = expr;
4618   newss->next = ss;
4619   newss->data.info.dimen = expr->rank;
4620   for (n = 0; n < expr->rank; n++)
4621     newss->data.info.dim[n] = n;
4622
4623   return newss;
4624 }
4625
4626
4627 /* Walk an expression.  Add walked expressions to the head of the SS chain.
4628    A wholly scalar expression will not be added.  */
4629
4630 static gfc_ss *
4631 gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr)
4632 {
4633   gfc_ss *head;
4634
4635   switch (expr->expr_type)
4636     {
4637     case EXPR_VARIABLE:
4638       head = gfc_walk_variable_expr (ss, expr);
4639       return head;
4640
4641     case EXPR_OP:
4642       head = gfc_walk_op_expr (ss, expr);
4643       return head;
4644
4645     case EXPR_FUNCTION:
4646       head = gfc_walk_function_expr (ss, expr);
4647       return head;
4648
4649     case EXPR_CONSTANT:
4650     case EXPR_NULL:
4651     case EXPR_STRUCTURE:
4652       /* Pass back and let the caller deal with it.  */
4653       break;
4654
4655     case EXPR_ARRAY:
4656       head = gfc_walk_array_constructor (ss, expr);
4657       return head;
4658
4659     case EXPR_SUBSTRING:
4660       /* Pass back and let the caller deal with it.  */
4661       break;
4662
4663     default:
4664       internal_error ("bad expression type during walk (%d)",
4665                       expr->expr_type);
4666     }
4667   return ss;
4668 }
4669
4670
4671 /* Entry point for expression walking.
4672    A return value equal to the passed chain means this is
4673    a scalar expression.  It is up to the caller to take whatever action is
4674    necessary to translate these.  */
4675
4676 gfc_ss *
4677 gfc_walk_expr (gfc_expr * expr)
4678 {
4679   gfc_ss *res;
4680
4681   res = gfc_walk_subexpr (gfc_ss_terminator, expr);
4682   return gfc_reverse_ss (res);
4683 }
4684