OSDN Git Service

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