OSDN Git Service

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