OSDN Git Service

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