* trans-array.c (gfc_conv_expr_descriptor): We don't need to use
[official-gcc.git] / gcc / fortran / trans-array.c
blob529d721795eb0633e7da3cd4a135e60c464f1bfe
1 /* Array translation routines
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
3 Free Software Foundation, Inc.
4 Contributed by Paul Brook <paul@nowt.org>
5 and Steven Bosscher <s.bosscher@student.tudelft.nl>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
12 version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to the Free
21 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
22 02110-1301, USA. */
24 /* trans-array.c-- Various array related code, including scalarization,
25 allocation, initialization and other support routines. */
27 /* How the scalarizer works.
28 In gfortran, array expressions use the same core routines as scalar
29 expressions.
30 First, a Scalarization State (SS) chain is built. This is done by walking
31 the expression tree, and building a linear list of the terms in the
32 expression. As the tree is walked, scalar subexpressions are translated.
34 The scalarization parameters are stored in a gfc_loopinfo structure.
35 First the start and stride of each term is calculated by
36 gfc_conv_ss_startstride. During this process the expressions for the array
37 descriptors and data pointers are also translated.
39 If the expression is an assignment, we must then resolve any dependencies.
40 In fortran all the rhs values of an assignment must be evaluated before
41 any assignments take place. This can require a temporary array to store the
42 values. We also require a temporary when we are passing array expressions
43 or vector subecripts as procedure parameters.
45 Array sections are passed without copying to a temporary. These use the
46 scalarizer to determine the shape of the section. The flag
47 loop->array_parameter tells the scalarizer that the actual values and loop
48 variables will not be required.
50 The function gfc_conv_loop_setup generates the scalarization setup code.
51 It determines the range of the scalarizing loop variables. If a temporary
52 is required, this is created and initialized. Code for scalar expressions
53 taken outside the loop is also generated at this time. Next the offset and
54 scaling required to translate from loop variables to array indices for each
55 term is calculated.
57 A call to gfc_start_scalarized_body marks the start of the scalarized
58 expression. This creates a scope and declares the loop variables. Before
59 calling this gfc_make_ss_chain_used must be used to indicate which terms
60 will be used inside this loop.
62 The scalar gfc_conv_* functions are then used to build the main body of the
63 scalarization loop. Scalarization loop variables and precalculated scalar
64 values are automatically substituted. Note that gfc_advance_se_ss_chain
65 must be used, rather than changing the se->ss directly.
67 For assignment expressions requiring a temporary two sub loops are
68 generated. The first stores the result of the expression in the temporary,
69 the second copies it to the result. A call to
70 gfc_trans_scalarized_loop_boundary marks the end of the main loop code and
71 the start of the copying loop. The temporary may be less than full rank.
73 Finally gfc_trans_scalarizing_loops is called to generate the implicit do
74 loops. The loops are added to the pre chain of the loopinfo. The post
75 chain may still contain cleanup code.
77 After the loop code has been added into its parent scope gfc_cleanup_loop
78 is called to free all the SS allocated by the scalarizer. */
80 #include "config.h"
81 #include "system.h"
82 #include "coretypes.h"
83 #include "tree.h"
84 #include "tree-gimple.h"
85 #include "ggc.h"
86 #include "toplev.h"
87 #include "real.h"
88 #include "flags.h"
89 #include "gfortran.h"
90 #include "trans.h"
91 #include "trans-stmt.h"
92 #include "trans-types.h"
93 #include "trans-array.h"
94 #include "trans-const.h"
95 #include "dependency.h"
97 static gfc_ss *gfc_walk_subexpr (gfc_ss *, gfc_expr *);
98 static bool gfc_get_array_constructor_size (mpz_t *, gfc_constructor *);
100 /* The contents of this structure aren't actually used, just the address. */
101 static gfc_ss gfc_ss_terminator_var;
102 gfc_ss * const gfc_ss_terminator = &gfc_ss_terminator_var;
105 static tree
106 gfc_array_dataptr_type (tree desc)
108 return (GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc)));
112 /* Build expressions to access the members of an array descriptor.
113 It's surprisingly easy to mess up here, so never access
114 an array descriptor by "brute force", always use these
115 functions. This also avoids problems if we change the format
116 of an array descriptor.
118 To understand these magic numbers, look at the comments
119 before gfc_build_array_type() in trans-types.c.
121 The code within these defines should be the only code which knows the format
122 of an array descriptor.
124 Any code just needing to read obtain the bounds of an array should use
125 gfc_conv_array_* rather than the following functions as these will return
126 know constant values, and work with arrays which do not have descriptors.
128 Don't forget to #undef these! */
130 #define DATA_FIELD 0
131 #define OFFSET_FIELD 1
132 #define DTYPE_FIELD 2
133 #define DIMENSION_FIELD 3
135 #define STRIDE_SUBFIELD 0
136 #define LBOUND_SUBFIELD 1
137 #define UBOUND_SUBFIELD 2
139 /* This provides READ-ONLY access to the data field. The field itself
140 doesn't have the proper type. */
142 tree
143 gfc_conv_descriptor_data_get (tree desc)
145 tree field, type, t;
147 type = TREE_TYPE (desc);
148 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
150 field = TYPE_FIELDS (type);
151 gcc_assert (DATA_FIELD == 0);
153 t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
154 t = fold_convert (GFC_TYPE_ARRAY_DATAPTR_TYPE (type), t);
156 return t;
159 /* This provides WRITE access to the data field.
161 TUPLES_P is true if we are generating tuples.
163 This function gets called through the following macros:
164 gfc_conv_descriptor_data_set
165 gfc_conv_descriptor_data_set_tuples. */
167 void
168 gfc_conv_descriptor_data_set_internal (stmtblock_t *block,
169 tree desc, tree value,
170 bool tuples_p)
172 tree field, type, t;
174 type = TREE_TYPE (desc);
175 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
177 field = TYPE_FIELDS (type);
178 gcc_assert (DATA_FIELD == 0);
180 t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
181 gfc_add_modify (block, t, fold_convert (TREE_TYPE (field), value), tuples_p);
185 /* This provides address access to the data field. This should only be
186 used by array allocation, passing this on to the runtime. */
188 tree
189 gfc_conv_descriptor_data_addr (tree desc)
191 tree field, type, t;
193 type = TREE_TYPE (desc);
194 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
196 field = TYPE_FIELDS (type);
197 gcc_assert (DATA_FIELD == 0);
199 t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
200 return build_fold_addr_expr (t);
203 tree
204 gfc_conv_descriptor_offset (tree desc)
206 tree type;
207 tree field;
209 type = TREE_TYPE (desc);
210 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
212 field = gfc_advance_chain (TYPE_FIELDS (type), OFFSET_FIELD);
213 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
215 return build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
218 tree
219 gfc_conv_descriptor_dtype (tree desc)
221 tree field;
222 tree type;
224 type = TREE_TYPE (desc);
225 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
227 field = gfc_advance_chain (TYPE_FIELDS (type), DTYPE_FIELD);
228 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
230 return build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
233 static tree
234 gfc_conv_descriptor_dimension (tree desc, tree dim)
236 tree field;
237 tree type;
238 tree tmp;
240 type = TREE_TYPE (desc);
241 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
243 field = gfc_advance_chain (TYPE_FIELDS (type), DIMENSION_FIELD);
244 gcc_assert (field != NULL_TREE
245 && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
246 && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE);
248 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
249 tmp = gfc_build_array_ref (tmp, dim);
250 return tmp;
253 tree
254 gfc_conv_descriptor_stride (tree desc, tree dim)
256 tree tmp;
257 tree field;
259 tmp = gfc_conv_descriptor_dimension (desc, dim);
260 field = TYPE_FIELDS (TREE_TYPE (tmp));
261 field = gfc_advance_chain (field, STRIDE_SUBFIELD);
262 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
264 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
265 return tmp;
268 tree
269 gfc_conv_descriptor_lbound (tree desc, tree dim)
271 tree tmp;
272 tree field;
274 tmp = gfc_conv_descriptor_dimension (desc, dim);
275 field = TYPE_FIELDS (TREE_TYPE (tmp));
276 field = gfc_advance_chain (field, LBOUND_SUBFIELD);
277 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
279 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
280 return tmp;
283 tree
284 gfc_conv_descriptor_ubound (tree desc, tree dim)
286 tree tmp;
287 tree field;
289 tmp = gfc_conv_descriptor_dimension (desc, dim);
290 field = TYPE_FIELDS (TREE_TYPE (tmp));
291 field = gfc_advance_chain (field, UBOUND_SUBFIELD);
292 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
294 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
295 return tmp;
299 /* Build a null array descriptor constructor. */
301 tree
302 gfc_build_null_descriptor (tree type)
304 tree field;
305 tree tmp;
307 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
308 gcc_assert (DATA_FIELD == 0);
309 field = TYPE_FIELDS (type);
311 /* Set a NULL data pointer. */
312 tmp = build_constructor_single (type, field, null_pointer_node);
313 TREE_CONSTANT (tmp) = 1;
314 TREE_INVARIANT (tmp) = 1;
315 /* All other fields are ignored. */
317 return tmp;
321 /* Cleanup those #defines. */
323 #undef DATA_FIELD
324 #undef OFFSET_FIELD
325 #undef DTYPE_FIELD
326 #undef DIMENSION_FIELD
327 #undef STRIDE_SUBFIELD
328 #undef LBOUND_SUBFIELD
329 #undef UBOUND_SUBFIELD
332 /* Mark a SS chain as used. Flags specifies in which loops the SS is used.
333 flags & 1 = Main loop body.
334 flags & 2 = temp copy loop. */
336 void
337 gfc_mark_ss_chain_used (gfc_ss * ss, unsigned flags)
339 for (; ss != gfc_ss_terminator; ss = ss->next)
340 ss->useflags = flags;
343 static void gfc_free_ss (gfc_ss *);
346 /* Free a gfc_ss chain. */
348 static void
349 gfc_free_ss_chain (gfc_ss * ss)
351 gfc_ss *next;
353 while (ss != gfc_ss_terminator)
355 gcc_assert (ss != NULL);
356 next = ss->next;
357 gfc_free_ss (ss);
358 ss = next;
363 /* Free a SS. */
365 static void
366 gfc_free_ss (gfc_ss * ss)
368 int n;
370 switch (ss->type)
372 case GFC_SS_SECTION:
373 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
375 if (ss->data.info.subscript[n])
376 gfc_free_ss_chain (ss->data.info.subscript[n]);
378 break;
380 default:
381 break;
384 gfc_free (ss);
388 /* Free all the SS associated with a loop. */
390 void
391 gfc_cleanup_loop (gfc_loopinfo * loop)
393 gfc_ss *ss;
394 gfc_ss *next;
396 ss = loop->ss;
397 while (ss != gfc_ss_terminator)
399 gcc_assert (ss != NULL);
400 next = ss->loop_chain;
401 gfc_free_ss (ss);
402 ss = next;
407 /* Associate a SS chain with a loop. */
409 void
410 gfc_add_ss_to_loop (gfc_loopinfo * loop, gfc_ss * head)
412 gfc_ss *ss;
414 if (head == gfc_ss_terminator)
415 return;
417 ss = head;
418 for (; ss && ss != gfc_ss_terminator; ss = ss->next)
420 if (ss->next == gfc_ss_terminator)
421 ss->loop_chain = loop->ss;
422 else
423 ss->loop_chain = ss->next;
425 gcc_assert (ss == gfc_ss_terminator);
426 loop->ss = head;
430 /* Generate an initializer for a static pointer or allocatable array. */
432 void
433 gfc_trans_static_array_pointer (gfc_symbol * sym)
435 tree type;
437 gcc_assert (TREE_STATIC (sym->backend_decl));
438 /* Just zero the data member. */
439 type = TREE_TYPE (sym->backend_decl);
440 DECL_INITIAL (sym->backend_decl) = gfc_build_null_descriptor (type);
444 /* If the bounds of SE's loop have not yet been set, see if they can be
445 determined from array spec AS, which is the array spec of a called
446 function. MAPPING maps the callee's dummy arguments to the values
447 that the caller is passing. Add any initialization and finalization
448 code to SE. */
450 void
451 gfc_set_loop_bounds_from_array_spec (gfc_interface_mapping * mapping,
452 gfc_se * se, gfc_array_spec * as)
454 int n, dim;
455 gfc_se tmpse;
456 tree lower;
457 tree upper;
458 tree tmp;
460 if (as && as->type == AS_EXPLICIT)
461 for (dim = 0; dim < se->loop->dimen; dim++)
463 n = se->loop->order[dim];
464 if (se->loop->to[n] == NULL_TREE)
466 /* Evaluate the lower bound. */
467 gfc_init_se (&tmpse, NULL);
468 gfc_apply_interface_mapping (mapping, &tmpse, as->lower[dim]);
469 gfc_add_block_to_block (&se->pre, &tmpse.pre);
470 gfc_add_block_to_block (&se->post, &tmpse.post);
471 lower = tmpse.expr;
473 /* ...and the upper bound. */
474 gfc_init_se (&tmpse, NULL);
475 gfc_apply_interface_mapping (mapping, &tmpse, as->upper[dim]);
476 gfc_add_block_to_block (&se->pre, &tmpse.pre);
477 gfc_add_block_to_block (&se->post, &tmpse.post);
478 upper = tmpse.expr;
480 /* Set the upper bound of the loop to UPPER - LOWER. */
481 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, upper, lower);
482 tmp = gfc_evaluate_now (tmp, &se->pre);
483 se->loop->to[n] = tmp;
489 /* Generate code to allocate an array temporary, or create a variable to
490 hold the data. If size is NULL, zero the descriptor so that the
491 callee will allocate the array. If DEALLOC is true, also generate code to
492 free the array afterwards.
494 Initialization code is added to PRE and finalization code to POST.
495 DYNAMIC is true if the caller may want to extend the array later
496 using realloc. This prevents us from putting the array on the stack. */
498 static void
499 gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
500 gfc_ss_info * info, tree size, tree nelem,
501 bool dynamic, bool dealloc)
503 tree tmp;
504 tree args;
505 tree desc;
506 bool onstack;
508 desc = info->descriptor;
509 info->offset = gfc_index_zero_node;
510 if (size == NULL_TREE || integer_zerop (size))
512 /* A callee allocated array. */
513 gfc_conv_descriptor_data_set (pre, desc, null_pointer_node);
514 onstack = FALSE;
516 else
518 /* Allocate the temporary. */
519 onstack = !dynamic && gfc_can_put_var_on_stack (size);
521 if (onstack)
523 /* Make a temporary variable to hold the data. */
524 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (nelem), nelem,
525 gfc_index_one_node);
526 tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
527 tmp);
528 tmp = build_array_type (gfc_get_element_type (TREE_TYPE (desc)),
529 tmp);
530 tmp = gfc_create_var (tmp, "A");
531 tmp = build_fold_addr_expr (tmp);
532 gfc_conv_descriptor_data_set (pre, desc, tmp);
534 else
536 /* Allocate memory to hold the data. */
537 args = gfc_chainon_list (NULL_TREE, size);
539 if (gfc_index_integer_kind == 4)
540 tmp = gfor_fndecl_internal_malloc;
541 else if (gfc_index_integer_kind == 8)
542 tmp = gfor_fndecl_internal_malloc64;
543 else
544 gcc_unreachable ();
545 tmp = build_function_call_expr (tmp, args);
546 tmp = gfc_evaluate_now (tmp, pre);
547 gfc_conv_descriptor_data_set (pre, desc, tmp);
550 info->data = gfc_conv_descriptor_data_get (desc);
552 /* The offset is zero because we create temporaries with a zero
553 lower bound. */
554 tmp = gfc_conv_descriptor_offset (desc);
555 gfc_add_modify_expr (pre, tmp, gfc_index_zero_node);
557 if (dealloc && !onstack)
559 /* Free the temporary. */
560 tmp = gfc_conv_descriptor_data_get (desc);
561 tmp = fold_convert (pvoid_type_node, tmp);
562 tmp = gfc_chainon_list (NULL_TREE, tmp);
563 tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
564 gfc_add_expr_to_block (post, tmp);
569 /* Generate code to create and initialize the descriptor for a temporary
570 array. This is used for both temporaries needed by the scalarizer, and
571 functions returning arrays. Adjusts the loop variables to be
572 zero-based, and calculates the loop bounds for callee allocated arrays.
573 Allocate the array unless it's callee allocated (we have a callee
574 allocated array if 'callee_alloc' is true, or if loop->to[n] is
575 NULL_TREE for any n). Also fills in the descriptor, data and offset
576 fields of info if known. Returns the size of the array, or NULL for a
577 callee allocated array.
579 PRE, POST, DYNAMIC and DEALLOC are as for gfc_trans_allocate_array_storage.
582 tree
583 gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post,
584 gfc_loopinfo * loop, gfc_ss_info * info,
585 tree eltype, bool dynamic, bool dealloc,
586 bool callee_alloc, bool function)
588 tree type;
589 tree desc;
590 tree tmp;
591 tree size;
592 tree nelem;
593 tree cond;
594 tree or_expr;
595 tree thencase;
596 tree elsecase;
597 tree var;
598 stmtblock_t thenblock;
599 stmtblock_t elseblock;
600 int n;
601 int dim;
603 gcc_assert (info->dimen > 0);
604 /* Set the lower bound to zero. */
605 for (dim = 0; dim < info->dimen; dim++)
607 n = loop->order[dim];
608 if (n < loop->temp_dim)
609 gcc_assert (integer_zerop (loop->from[n]));
610 else
612 /* Callee allocated arrays may not have a known bound yet. */
613 if (loop->to[n])
614 loop->to[n] = fold_build2 (MINUS_EXPR, gfc_array_index_type,
615 loop->to[n], loop->from[n]);
616 loop->from[n] = gfc_index_zero_node;
619 info->delta[dim] = gfc_index_zero_node;
620 info->start[dim] = gfc_index_zero_node;
621 info->end[dim] = gfc_index_zero_node;
622 info->stride[dim] = gfc_index_one_node;
623 info->dim[dim] = dim;
626 /* Initialize the descriptor. */
627 type =
628 gfc_get_array_type_bounds (eltype, info->dimen, loop->from, loop->to, 1);
629 desc = gfc_create_var (type, "atmp");
630 GFC_DECL_PACKED_ARRAY (desc) = 1;
632 info->descriptor = desc;
633 size = gfc_index_one_node;
635 /* Fill in the array dtype. */
636 tmp = gfc_conv_descriptor_dtype (desc);
637 gfc_add_modify_expr (pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
640 Fill in the bounds and stride. This is a packed array, so:
642 size = 1;
643 for (n = 0; n < rank; n++)
645 stride[n] = size
646 delta = ubound[n] + 1 - lbound[n];
647 size = size * delta;
649 size = size * sizeof(element);
652 or_expr = NULL_TREE;
654 for (n = 0; n < info->dimen; n++)
656 if (loop->to[n] == NULL_TREE)
658 /* For a callee allocated array express the loop bounds in terms
659 of the descriptor fields. */
660 tmp = build2 (MINUS_EXPR, gfc_array_index_type,
661 gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]),
662 gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]));
663 loop->to[n] = tmp;
664 size = NULL_TREE;
665 continue;
668 /* Store the stride and bound components in the descriptor. */
669 tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[n]);
670 gfc_add_modify_expr (pre, tmp, size);
672 tmp = gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]);
673 gfc_add_modify_expr (pre, tmp, gfc_index_zero_node);
675 tmp = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]);
676 gfc_add_modify_expr (pre, tmp, loop->to[n]);
678 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
679 loop->to[n], gfc_index_one_node);
681 if (function)
683 /* Check whether the size for this dimension is negative. */
684 cond = fold_build2 (LE_EXPR, boolean_type_node, tmp,
685 gfc_index_zero_node);
687 cond = gfc_evaluate_now (cond, pre);
689 if (n == 0)
690 or_expr = cond;
691 else
692 or_expr = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, or_expr, cond);
694 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
695 size = gfc_evaluate_now (size, pre);
698 /* Get the size of the array. */
700 if (size && !callee_alloc)
702 if (function)
704 /* If we know at compile-time whether any dimension size is
705 negative, we can avoid a conditional and pass the true size
706 to gfc_trans_allocate_array_storage, which can then decide
707 whether to allocate this on the heap or on the stack. */
708 if (integer_zerop (or_expr))
710 else if (integer_onep (or_expr))
711 size = gfc_index_zero_node;
712 else
714 var = gfc_create_var (TREE_TYPE (size), "size");
715 gfc_start_block (&thenblock);
716 gfc_add_modify_expr (&thenblock, var, gfc_index_zero_node);
717 thencase = gfc_finish_block (&thenblock);
719 gfc_start_block (&elseblock);
720 gfc_add_modify_expr (&elseblock, var, size);
721 elsecase = gfc_finish_block (&elseblock);
723 tmp = gfc_evaluate_now (or_expr, pre);
724 tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
725 gfc_add_expr_to_block (pre, tmp);
726 size = var;
730 nelem = size;
731 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
732 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
734 else
736 nelem = size;
737 size = NULL_TREE;
740 gfc_trans_allocate_array_storage (pre, post, info, size, nelem, dynamic,
741 dealloc);
743 if (info->dimen > loop->temp_dim)
744 loop->temp_dim = info->dimen;
746 return size;
750 /* Generate code to transpose array EXPR by creating a new descriptor
751 in which the dimension specifications have been reversed. */
753 void
754 gfc_conv_array_transpose (gfc_se * se, gfc_expr * expr)
756 tree dest, src, dest_index, src_index;
757 gfc_loopinfo *loop;
758 gfc_ss_info *dest_info, *src_info;
759 gfc_ss *dest_ss, *src_ss;
760 gfc_se src_se;
761 int n;
763 loop = se->loop;
765 src_ss = gfc_walk_expr (expr);
766 dest_ss = se->ss;
768 src_info = &src_ss->data.info;
769 dest_info = &dest_ss->data.info;
770 gcc_assert (dest_info->dimen == 2);
771 gcc_assert (src_info->dimen == 2);
773 /* Get a descriptor for EXPR. */
774 gfc_init_se (&src_se, NULL);
775 gfc_conv_expr_descriptor (&src_se, expr, src_ss);
776 gfc_add_block_to_block (&se->pre, &src_se.pre);
777 gfc_add_block_to_block (&se->post, &src_se.post);
778 src = src_se.expr;
780 /* Allocate a new descriptor for the return value. */
781 dest = gfc_create_var (TREE_TYPE (src), "atmp");
782 dest_info->descriptor = dest;
783 se->expr = dest;
785 /* Copy across the dtype field. */
786 gfc_add_modify_expr (&se->pre,
787 gfc_conv_descriptor_dtype (dest),
788 gfc_conv_descriptor_dtype (src));
790 /* Copy the dimension information, renumbering dimension 1 to 0 and
791 0 to 1. */
792 for (n = 0; n < 2; n++)
794 dest_info->delta[n] = gfc_index_zero_node;
795 dest_info->start[n] = gfc_index_zero_node;
796 dest_info->end[n] = gfc_index_zero_node;
797 dest_info->stride[n] = gfc_index_one_node;
798 dest_info->dim[n] = n;
800 dest_index = gfc_rank_cst[n];
801 src_index = gfc_rank_cst[1 - n];
803 gfc_add_modify_expr (&se->pre,
804 gfc_conv_descriptor_stride (dest, dest_index),
805 gfc_conv_descriptor_stride (src, src_index));
807 gfc_add_modify_expr (&se->pre,
808 gfc_conv_descriptor_lbound (dest, dest_index),
809 gfc_conv_descriptor_lbound (src, src_index));
811 gfc_add_modify_expr (&se->pre,
812 gfc_conv_descriptor_ubound (dest, dest_index),
813 gfc_conv_descriptor_ubound (src, src_index));
815 if (!loop->to[n])
817 gcc_assert (integer_zerop (loop->from[n]));
818 loop->to[n] = build2 (MINUS_EXPR, gfc_array_index_type,
819 gfc_conv_descriptor_ubound (dest, dest_index),
820 gfc_conv_descriptor_lbound (dest, dest_index));
824 /* Copy the data pointer. */
825 dest_info->data = gfc_conv_descriptor_data_get (src);
826 gfc_conv_descriptor_data_set (&se->pre, dest, dest_info->data);
828 /* Copy the offset. This is not changed by transposition: the top-left
829 element is still at the same offset as before. */
830 dest_info->offset = gfc_conv_descriptor_offset (src);
831 gfc_add_modify_expr (&se->pre,
832 gfc_conv_descriptor_offset (dest),
833 dest_info->offset);
835 if (dest_info->dimen > loop->temp_dim)
836 loop->temp_dim = dest_info->dimen;
840 /* Return the number of iterations in a loop that starts at START,
841 ends at END, and has step STEP. */
843 static tree
844 gfc_get_iteration_count (tree start, tree end, tree step)
846 tree tmp;
847 tree type;
849 type = TREE_TYPE (step);
850 tmp = fold_build2 (MINUS_EXPR, type, end, start);
851 tmp = fold_build2 (FLOOR_DIV_EXPR, type, tmp, step);
852 tmp = fold_build2 (PLUS_EXPR, type, tmp, build_int_cst (type, 1));
853 tmp = fold_build2 (MAX_EXPR, type, tmp, build_int_cst (type, 0));
854 return fold_convert (gfc_array_index_type, tmp);
858 /* Extend the data in array DESC by EXTRA elements. */
860 static void
861 gfc_grow_array (stmtblock_t * pblock, tree desc, tree extra)
863 tree args;
864 tree tmp;
865 tree size;
866 tree ubound;
868 if (integer_zerop (extra))
869 return;
871 ubound = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[0]);
873 /* Add EXTRA to the upper bound. */
874 tmp = build2 (PLUS_EXPR, gfc_array_index_type, ubound, extra);
875 gfc_add_modify_expr (pblock, ubound, tmp);
877 /* Get the value of the current data pointer. */
878 tmp = gfc_conv_descriptor_data_get (desc);
879 args = gfc_chainon_list (NULL_TREE, tmp);
881 /* Calculate the new array size. */
882 size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
883 tmp = build2 (PLUS_EXPR, gfc_array_index_type, ubound, gfc_index_one_node);
884 tmp = build2 (MULT_EXPR, gfc_array_index_type, tmp, size);
885 args = gfc_chainon_list (args, tmp);
887 /* Pick the appropriate realloc function. */
888 if (gfc_index_integer_kind == 4)
889 tmp = gfor_fndecl_internal_realloc;
890 else if (gfc_index_integer_kind == 8)
891 tmp = gfor_fndecl_internal_realloc64;
892 else
893 gcc_unreachable ();
895 /* Set the new data pointer. */
896 tmp = build_function_call_expr (tmp, args);
897 gfc_conv_descriptor_data_set (pblock, desc, tmp);
901 /* Return true if the bounds of iterator I can only be determined
902 at run time. */
904 static inline bool
905 gfc_iterator_has_dynamic_bounds (gfc_iterator * i)
907 return (i->start->expr_type != EXPR_CONSTANT
908 || i->end->expr_type != EXPR_CONSTANT
909 || i->step->expr_type != EXPR_CONSTANT);
913 /* Split the size of constructor element EXPR into the sum of two terms,
914 one of which can be determined at compile time and one of which must
915 be calculated at run time. Set *SIZE to the former and return true
916 if the latter might be nonzero. */
918 static bool
919 gfc_get_array_constructor_element_size (mpz_t * size, gfc_expr * expr)
921 if (expr->expr_type == EXPR_ARRAY)
922 return gfc_get_array_constructor_size (size, expr->value.constructor);
923 else if (expr->rank > 0)
925 /* Calculate everything at run time. */
926 mpz_set_ui (*size, 0);
927 return true;
929 else
931 /* A single element. */
932 mpz_set_ui (*size, 1);
933 return false;
938 /* Like gfc_get_array_constructor_element_size, but applied to the whole
939 of array constructor C. */
941 static bool
942 gfc_get_array_constructor_size (mpz_t * size, gfc_constructor * c)
944 gfc_iterator *i;
945 mpz_t val;
946 mpz_t len;
947 bool dynamic;
949 mpz_set_ui (*size, 0);
950 mpz_init (len);
951 mpz_init (val);
953 dynamic = false;
954 for (; c; c = c->next)
956 i = c->iterator;
957 if (i && gfc_iterator_has_dynamic_bounds (i))
958 dynamic = true;
959 else
961 dynamic |= gfc_get_array_constructor_element_size (&len, c->expr);
962 if (i)
964 /* Multiply the static part of the element size by the
965 number of iterations. */
966 mpz_sub (val, i->end->value.integer, i->start->value.integer);
967 mpz_fdiv_q (val, val, i->step->value.integer);
968 mpz_add_ui (val, val, 1);
969 if (mpz_sgn (val) > 0)
970 mpz_mul (len, len, val);
971 else
972 mpz_set_ui (len, 0);
974 mpz_add (*size, *size, len);
977 mpz_clear (len);
978 mpz_clear (val);
979 return dynamic;
983 /* Make sure offset is a variable. */
985 static void
986 gfc_put_offset_into_var (stmtblock_t * pblock, tree * poffset,
987 tree * offsetvar)
989 /* We should have already created the offset variable. We cannot
990 create it here because we may be in an inner scope. */
991 gcc_assert (*offsetvar != NULL_TREE);
992 gfc_add_modify_expr (pblock, *offsetvar, *poffset);
993 *poffset = *offsetvar;
994 TREE_USED (*offsetvar) = 1;
998 /* Assign an element of an array constructor. */
1000 static void
1001 gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc,
1002 tree offset, gfc_se * se, gfc_expr * expr)
1004 tree tmp;
1005 tree args;
1007 gfc_conv_expr (se, expr);
1009 /* Store the value. */
1010 tmp = build_fold_indirect_ref (gfc_conv_descriptor_data_get (desc));
1011 tmp = gfc_build_array_ref (tmp, offset);
1012 if (expr->ts.type == BT_CHARACTER)
1014 gfc_conv_string_parameter (se);
1015 if (POINTER_TYPE_P (TREE_TYPE (tmp)))
1017 /* The temporary is an array of pointers. */
1018 se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
1019 gfc_add_modify_expr (&se->pre, tmp, se->expr);
1021 else
1023 /* The temporary is an array of string values. */
1024 tmp = gfc_build_addr_expr (pchar_type_node, tmp);
1025 /* We know the temporary and the value will be the same length,
1026 so can use memcpy. */
1027 args = gfc_chainon_list (NULL_TREE, tmp);
1028 args = gfc_chainon_list (args, se->expr);
1029 args = gfc_chainon_list (args, se->string_length);
1030 tmp = built_in_decls[BUILT_IN_MEMCPY];
1031 tmp = build_function_call_expr (tmp, args);
1032 gfc_add_expr_to_block (&se->pre, tmp);
1035 else
1037 /* TODO: Should the frontend already have done this conversion? */
1038 se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
1039 gfc_add_modify_expr (&se->pre, tmp, se->expr);
1042 gfc_add_block_to_block (pblock, &se->pre);
1043 gfc_add_block_to_block (pblock, &se->post);
1047 /* Add the contents of an array to the constructor. DYNAMIC is as for
1048 gfc_trans_array_constructor_value. */
1050 static void
1051 gfc_trans_array_constructor_subarray (stmtblock_t * pblock,
1052 tree type ATTRIBUTE_UNUSED,
1053 tree desc, gfc_expr * expr,
1054 tree * poffset, tree * offsetvar,
1055 bool dynamic)
1057 gfc_se se;
1058 gfc_ss *ss;
1059 gfc_loopinfo loop;
1060 stmtblock_t body;
1061 tree tmp;
1062 tree size;
1063 int n;
1065 /* We need this to be a variable so we can increment it. */
1066 gfc_put_offset_into_var (pblock, poffset, offsetvar);
1068 gfc_init_se (&se, NULL);
1070 /* Walk the array expression. */
1071 ss = gfc_walk_expr (expr);
1072 gcc_assert (ss != gfc_ss_terminator);
1074 /* Initialize the scalarizer. */
1075 gfc_init_loopinfo (&loop);
1076 gfc_add_ss_to_loop (&loop, ss);
1078 /* Initialize the loop. */
1079 gfc_conv_ss_startstride (&loop);
1080 gfc_conv_loop_setup (&loop);
1082 /* Make sure the constructed array has room for the new data. */
1083 if (dynamic)
1085 /* Set SIZE to the total number of elements in the subarray. */
1086 size = gfc_index_one_node;
1087 for (n = 0; n < loop.dimen; n++)
1089 tmp = gfc_get_iteration_count (loop.from[n], loop.to[n],
1090 gfc_index_one_node);
1091 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
1094 /* Grow the constructed array by SIZE elements. */
1095 gfc_grow_array (&loop.pre, desc, size);
1098 /* Make the loop body. */
1099 gfc_mark_ss_chain_used (ss, 1);
1100 gfc_start_scalarized_body (&loop, &body);
1101 gfc_copy_loopinfo_to_se (&se, &loop);
1102 se.ss = ss;
1104 gfc_trans_array_ctor_element (&body, desc, *poffset, &se, expr);
1105 gcc_assert (se.ss == gfc_ss_terminator);
1107 /* Increment the offset. */
1108 tmp = build2 (PLUS_EXPR, gfc_array_index_type, *poffset, gfc_index_one_node);
1109 gfc_add_modify_expr (&body, *poffset, tmp);
1111 /* Finish the loop. */
1112 gfc_trans_scalarizing_loops (&loop, &body);
1113 gfc_add_block_to_block (&loop.pre, &loop.post);
1114 tmp = gfc_finish_block (&loop.pre);
1115 gfc_add_expr_to_block (pblock, tmp);
1117 gfc_cleanup_loop (&loop);
1121 /* Assign the values to the elements of an array constructor. DYNAMIC
1122 is true if descriptor DESC only contains enough data for the static
1123 size calculated by gfc_get_array_constructor_size. When true, memory
1124 for the dynamic parts must be allocated using realloc. */
1126 static void
1127 gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
1128 tree desc, gfc_constructor * c,
1129 tree * poffset, tree * offsetvar,
1130 bool dynamic)
1132 tree tmp;
1133 stmtblock_t body;
1134 gfc_se se;
1135 mpz_t size;
1137 mpz_init (size);
1138 for (; c; c = c->next)
1140 /* If this is an iterator or an array, the offset must be a variable. */
1141 if ((c->iterator || c->expr->rank > 0) && INTEGER_CST_P (*poffset))
1142 gfc_put_offset_into_var (pblock, poffset, offsetvar);
1144 gfc_start_block (&body);
1146 if (c->expr->expr_type == EXPR_ARRAY)
1148 /* Array constructors can be nested. */
1149 gfc_trans_array_constructor_value (&body, type, desc,
1150 c->expr->value.constructor,
1151 poffset, offsetvar, dynamic);
1153 else if (c->expr->rank > 0)
1155 gfc_trans_array_constructor_subarray (&body, type, desc, c->expr,
1156 poffset, offsetvar, dynamic);
1158 else
1160 /* This code really upsets the gimplifier so don't bother for now. */
1161 gfc_constructor *p;
1162 HOST_WIDE_INT n;
1163 HOST_WIDE_INT size;
1165 p = c;
1166 n = 0;
1167 while (p && !(p->iterator || p->expr->expr_type != EXPR_CONSTANT))
1169 p = p->next;
1170 n++;
1172 if (n < 4)
1174 /* Scalar values. */
1175 gfc_init_se (&se, NULL);
1176 gfc_trans_array_ctor_element (&body, desc, *poffset,
1177 &se, c->expr);
1179 *poffset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1180 *poffset, gfc_index_one_node);
1182 else
1184 /* Collect multiple scalar constants into a constructor. */
1185 tree list;
1186 tree init;
1187 tree bound;
1188 tree tmptype;
1190 p = c;
1191 list = NULL_TREE;
1192 /* Count the number of consecutive scalar constants. */
1193 while (p && !(p->iterator
1194 || p->expr->expr_type != EXPR_CONSTANT))
1196 gfc_init_se (&se, NULL);
1197 gfc_conv_constant (&se, p->expr);
1198 if (p->expr->ts.type == BT_CHARACTER
1199 && POINTER_TYPE_P (type))
1201 /* For constant character array constructors we build
1202 an array of pointers. */
1203 se.expr = gfc_build_addr_expr (pchar_type_node,
1204 se.expr);
1207 list = tree_cons (NULL_TREE, se.expr, list);
1208 c = p;
1209 p = p->next;
1212 bound = build_int_cst (NULL_TREE, n - 1);
1213 /* Create an array type to hold them. */
1214 tmptype = build_range_type (gfc_array_index_type,
1215 gfc_index_zero_node, bound);
1216 tmptype = build_array_type (type, tmptype);
1218 init = build_constructor_from_list (tmptype, nreverse (list));
1219 TREE_CONSTANT (init) = 1;
1220 TREE_INVARIANT (init) = 1;
1221 TREE_STATIC (init) = 1;
1222 /* Create a static variable to hold the data. */
1223 tmp = gfc_create_var (tmptype, "data");
1224 TREE_STATIC (tmp) = 1;
1225 TREE_CONSTANT (tmp) = 1;
1226 TREE_INVARIANT (tmp) = 1;
1227 TREE_READONLY (tmp) = 1;
1228 DECL_INITIAL (tmp) = init;
1229 init = tmp;
1231 /* Use BUILTIN_MEMCPY to assign the values. */
1232 tmp = gfc_conv_descriptor_data_get (desc);
1233 tmp = build_fold_indirect_ref (tmp);
1234 tmp = gfc_build_array_ref (tmp, *poffset);
1235 tmp = build_fold_addr_expr (tmp);
1236 init = build_fold_addr_expr (init);
1238 size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
1239 bound = build_int_cst (NULL_TREE, n * size);
1240 tmp = gfc_chainon_list (NULL_TREE, tmp);
1241 tmp = gfc_chainon_list (tmp, init);
1242 tmp = gfc_chainon_list (tmp, bound);
1243 tmp = build_function_call_expr (built_in_decls[BUILT_IN_MEMCPY],
1244 tmp);
1245 gfc_add_expr_to_block (&body, tmp);
1247 *poffset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1248 *poffset, build_int_cst (NULL_TREE, n));
1250 if (!INTEGER_CST_P (*poffset))
1252 gfc_add_modify_expr (&body, *offsetvar, *poffset);
1253 *poffset = *offsetvar;
1257 /* The frontend should already have done any expansions possible
1258 at compile-time. */
1259 if (!c->iterator)
1261 /* Pass the code as is. */
1262 tmp = gfc_finish_block (&body);
1263 gfc_add_expr_to_block (pblock, tmp);
1265 else
1267 /* Build the implied do-loop. */
1268 tree cond;
1269 tree end;
1270 tree step;
1271 tree loopvar;
1272 tree exit_label;
1273 tree loopbody;
1274 tree tmp2;
1275 tree tmp_loopvar;
1277 loopbody = gfc_finish_block (&body);
1279 gfc_init_se (&se, NULL);
1280 gfc_conv_expr (&se, c->iterator->var);
1281 gfc_add_block_to_block (pblock, &se.pre);
1282 loopvar = se.expr;
1284 /* Make a temporary, store the current value in that
1285 and return it, once the loop is done. */
1286 tmp_loopvar = gfc_create_var (TREE_TYPE (loopvar), "loopvar");
1287 gfc_add_modify_expr (pblock, tmp_loopvar, loopvar);
1289 /* Initialize the loop. */
1290 gfc_init_se (&se, NULL);
1291 gfc_conv_expr_val (&se, c->iterator->start);
1292 gfc_add_block_to_block (pblock, &se.pre);
1293 gfc_add_modify_expr (pblock, loopvar, se.expr);
1295 gfc_init_se (&se, NULL);
1296 gfc_conv_expr_val (&se, c->iterator->end);
1297 gfc_add_block_to_block (pblock, &se.pre);
1298 end = gfc_evaluate_now (se.expr, pblock);
1300 gfc_init_se (&se, NULL);
1301 gfc_conv_expr_val (&se, c->iterator->step);
1302 gfc_add_block_to_block (pblock, &se.pre);
1303 step = gfc_evaluate_now (se.expr, pblock);
1305 /* If this array expands dynamically, and the number of iterations
1306 is not constant, we won't have allocated space for the static
1307 part of C->EXPR's size. Do that now. */
1308 if (dynamic && gfc_iterator_has_dynamic_bounds (c->iterator))
1310 /* Get the number of iterations. */
1311 tmp = gfc_get_iteration_count (loopvar, end, step);
1313 /* Get the static part of C->EXPR's size. */
1314 gfc_get_array_constructor_element_size (&size, c->expr);
1315 tmp2 = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1317 /* Grow the array by TMP * TMP2 elements. */
1318 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp, tmp2);
1319 gfc_grow_array (pblock, desc, tmp);
1322 /* Generate the loop body. */
1323 exit_label = gfc_build_label_decl (NULL_TREE);
1324 gfc_start_block (&body);
1326 /* Generate the exit condition. Depending on the sign of
1327 the step variable we have to generate the correct
1328 comparison. */
1329 tmp = fold_build2 (GT_EXPR, boolean_type_node, step,
1330 build_int_cst (TREE_TYPE (step), 0));
1331 cond = fold_build3 (COND_EXPR, boolean_type_node, tmp,
1332 build2 (GT_EXPR, boolean_type_node,
1333 loopvar, end),
1334 build2 (LT_EXPR, boolean_type_node,
1335 loopvar, end));
1336 tmp = build1_v (GOTO_EXPR, exit_label);
1337 TREE_USED (exit_label) = 1;
1338 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1339 gfc_add_expr_to_block (&body, tmp);
1341 /* The main loop body. */
1342 gfc_add_expr_to_block (&body, loopbody);
1344 /* Increase loop variable by step. */
1345 tmp = build2 (PLUS_EXPR, TREE_TYPE (loopvar), loopvar, step);
1346 gfc_add_modify_expr (&body, loopvar, tmp);
1348 /* Finish the loop. */
1349 tmp = gfc_finish_block (&body);
1350 tmp = build1_v (LOOP_EXPR, tmp);
1351 gfc_add_expr_to_block (pblock, tmp);
1353 /* Add the exit label. */
1354 tmp = build1_v (LABEL_EXPR, exit_label);
1355 gfc_add_expr_to_block (pblock, tmp);
1357 /* Restore the original value of the loop counter. */
1358 gfc_add_modify_expr (pblock, loopvar, tmp_loopvar);
1361 mpz_clear (size);
1365 /* Figure out the string length of a variable reference expression.
1366 Used by get_array_ctor_strlen. */
1368 static void
1369 get_array_ctor_var_strlen (gfc_expr * expr, tree * len)
1371 gfc_ref *ref;
1372 gfc_typespec *ts;
1373 mpz_t char_len;
1375 /* Don't bother if we already know the length is a constant. */
1376 if (*len && INTEGER_CST_P (*len))
1377 return;
1379 ts = &expr->symtree->n.sym->ts;
1380 for (ref = expr->ref; ref; ref = ref->next)
1382 switch (ref->type)
1384 case REF_ARRAY:
1385 /* Array references don't change the string length. */
1386 break;
1388 case REF_COMPONENT:
1389 /* Use the length of the component. */
1390 ts = &ref->u.c.component->ts;
1391 break;
1393 case REF_SUBSTRING:
1394 if (ref->u.ss.start->expr_type != EXPR_CONSTANT
1395 || ref->u.ss.start->expr_type != EXPR_CONSTANT)
1396 break;
1397 mpz_init_set_ui (char_len, 1);
1398 mpz_add (char_len, char_len, ref->u.ss.end->value.integer);
1399 mpz_sub (char_len, char_len, ref->u.ss.start->value.integer);
1400 *len = gfc_conv_mpz_to_tree (char_len,
1401 gfc_default_character_kind);
1402 *len = convert (gfc_charlen_type_node, *len);
1403 mpz_clear (char_len);
1404 return;
1406 default:
1407 /* TODO: Substrings are tricky because we can't evaluate the
1408 expression more than once. For now we just give up, and hope
1409 we can figure it out elsewhere. */
1410 return;
1414 *len = ts->cl->backend_decl;
1418 /* Figure out the string length of a character array constructor.
1419 Returns TRUE if all elements are character constants. */
1421 bool
1422 get_array_ctor_strlen (gfc_constructor * c, tree * len)
1424 bool is_const;
1426 is_const = TRUE;
1427 for (; c; c = c->next)
1429 switch (c->expr->expr_type)
1431 case EXPR_CONSTANT:
1432 if (!(*len && INTEGER_CST_P (*len)))
1433 *len = build_int_cstu (gfc_charlen_type_node,
1434 c->expr->value.character.length);
1435 break;
1437 case EXPR_ARRAY:
1438 if (!get_array_ctor_strlen (c->expr->value.constructor, len))
1439 is_const = false;
1440 break;
1442 case EXPR_VARIABLE:
1443 is_const = false;
1444 get_array_ctor_var_strlen (c->expr, len);
1445 break;
1447 default:
1448 is_const = false;
1450 /* Hope that whatever we have possesses a constant character
1451 length! */
1452 if (!(*len && INTEGER_CST_P (*len)) && c->expr->ts.cl)
1454 gfc_conv_const_charlen (c->expr->ts.cl);
1455 *len = c->expr->ts.cl->backend_decl;
1457 /* TODO: For now we just ignore anything we don't know how to
1458 handle, and hope we can figure it out a different way. */
1459 break;
1463 return is_const;
1466 /* Check whether the array constructor C consists entirely of constant
1467 elements, and if so returns the number of those elements, otherwise
1468 return zero. Note, an empty or NULL array constructor returns zero. */
1470 unsigned HOST_WIDE_INT
1471 gfc_constant_array_constructor_p (gfc_constructor * c)
1473 unsigned HOST_WIDE_INT nelem = 0;
1475 while (c)
1477 if (c->iterator
1478 || c->expr->rank > 0
1479 || c->expr->expr_type != EXPR_CONSTANT)
1480 return 0;
1481 c = c->next;
1482 nelem++;
1484 return nelem;
1488 /* Given EXPR, the constant array constructor specified by an EXPR_ARRAY,
1489 and the tree type of it's elements, TYPE, return a static constant
1490 variable that is compile-time initialized. */
1492 tree
1493 gfc_build_constant_array_constructor (gfc_expr * expr, tree type)
1495 tree tmptype, list, init, tmp;
1496 HOST_WIDE_INT nelem;
1497 gfc_constructor *c;
1498 gfc_array_spec as;
1499 gfc_se se;
1502 /* First traverse the constructor list, converting the constants
1503 to tree to build an initializer. */
1504 nelem = 0;
1505 list = NULL_TREE;
1506 c = expr->value.constructor;
1507 while (c)
1509 gfc_init_se (&se, NULL);
1510 gfc_conv_constant (&se, c->expr);
1511 if (c->expr->ts.type == BT_CHARACTER
1512 && POINTER_TYPE_P (type))
1513 se.expr = gfc_build_addr_expr (pchar_type_node, se.expr);
1514 list = tree_cons (NULL_TREE, se.expr, list);
1515 c = c->next;
1516 nelem++;
1519 /* Next determine the tree type for the array. We use the gfortran
1520 front-end's gfc_get_nodesc_array_type in order to create a suitable
1521 GFC_ARRAY_TYPE_P that may be used by the scalarizer. */
1523 memset (&as, 0, sizeof (gfc_array_spec));
1525 as.rank = 1;
1526 as.type = AS_EXPLICIT;
1527 as.lower[0] = gfc_int_expr (0);
1528 as.upper[0] = gfc_int_expr (nelem - 1);
1529 tmptype = gfc_get_nodesc_array_type (type, &as, 3);
1531 init = build_constructor_from_list (tmptype, nreverse (list));
1533 TREE_CONSTANT (init) = 1;
1534 TREE_INVARIANT (init) = 1;
1535 TREE_STATIC (init) = 1;
1537 tmp = gfc_create_var (tmptype, "A");
1538 TREE_STATIC (tmp) = 1;
1539 TREE_CONSTANT (tmp) = 1;
1540 TREE_INVARIANT (tmp) = 1;
1541 TREE_READONLY (tmp) = 1;
1542 DECL_INITIAL (tmp) = init;
1544 return tmp;
1548 /* Translate a constant EXPR_ARRAY array constructor for the scalarizer.
1549 This mostly initializes the scalarizer state info structure with the
1550 appropriate values to directly use the array created by the function
1551 gfc_build_constant_array_constructor. */
1553 static void
1554 gfc_trans_constant_array_constructor (gfc_loopinfo * loop,
1555 gfc_ss * ss, tree type)
1557 gfc_ss_info *info;
1558 tree tmp;
1560 tmp = gfc_build_constant_array_constructor (ss->expr, type);
1562 info = &ss->data.info;
1564 info->descriptor = tmp;
1565 info->data = build_fold_addr_expr (tmp);
1566 info->offset = fold_build1 (NEGATE_EXPR, gfc_array_index_type,
1567 loop->from[0]);
1569 info->delta[0] = gfc_index_zero_node;
1570 info->start[0] = gfc_index_zero_node;
1571 info->end[0] = gfc_index_zero_node;
1572 info->stride[0] = gfc_index_one_node;
1573 info->dim[0] = 0;
1575 if (info->dimen > loop->temp_dim)
1576 loop->temp_dim = info->dimen;
1580 /* Array constructors are handled by constructing a temporary, then using that
1581 within the scalarization loop. This is not optimal, but seems by far the
1582 simplest method. */
1584 static void
1585 gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss)
1587 gfc_constructor *c;
1588 tree offset;
1589 tree offsetvar;
1590 tree desc;
1591 tree type;
1592 bool dynamic;
1594 ss->data.info.dimen = loop->dimen;
1596 c = ss->expr->value.constructor;
1597 if (ss->expr->ts.type == BT_CHARACTER)
1599 bool const_string = get_array_ctor_strlen (c, &ss->string_length);
1600 if (!ss->string_length)
1601 gfc_todo_error ("complex character array constructors");
1603 type = gfc_get_character_type_len (ss->expr->ts.kind, ss->string_length);
1604 if (const_string)
1605 type = build_pointer_type (type);
1607 else
1608 type = gfc_typenode_for_spec (&ss->expr->ts);
1610 /* See if the constructor determines the loop bounds. */
1611 dynamic = false;
1612 if (loop->to[0] == NULL_TREE)
1614 mpz_t size;
1616 /* We should have a 1-dimensional, zero-based loop. */
1617 gcc_assert (loop->dimen == 1);
1618 gcc_assert (integer_zerop (loop->from[0]));
1620 /* Split the constructor size into a static part and a dynamic part.
1621 Allocate the static size up-front and record whether the dynamic
1622 size might be nonzero. */
1623 mpz_init (size);
1624 dynamic = gfc_get_array_constructor_size (&size, c);
1625 mpz_sub_ui (size, size, 1);
1626 loop->to[0] = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1627 mpz_clear (size);
1630 /* Special case constant array constructors. */
1631 if (!dynamic
1632 && loop->dimen == 1
1633 && INTEGER_CST_P (loop->from[0])
1634 && INTEGER_CST_P (loop->to[0]))
1636 unsigned HOST_WIDE_INT nelem = gfc_constant_array_constructor_p (c);
1637 if (nelem > 0)
1639 tree diff = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1640 loop->to[0], loop->from[0]);
1641 if (compare_tree_int (diff, nelem - 1) == 0)
1643 gfc_trans_constant_array_constructor (loop, ss, type);
1644 return;
1649 gfc_trans_create_temp_array (&loop->pre, &loop->post, loop, &ss->data.info,
1650 type, dynamic, true, false, false);
1652 desc = ss->data.info.descriptor;
1653 offset = gfc_index_zero_node;
1654 offsetvar = gfc_create_var_np (gfc_array_index_type, "offset");
1655 TREE_USED (offsetvar) = 0;
1656 gfc_trans_array_constructor_value (&loop->pre, type, desc, c,
1657 &offset, &offsetvar, dynamic);
1659 /* If the array grows dynamically, the upper bound of the loop variable
1660 is determined by the array's final upper bound. */
1661 if (dynamic)
1662 loop->to[0] = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[0]);
1664 if (TREE_USED (offsetvar))
1665 pushdecl (offsetvar);
1666 else
1667 gcc_assert (INTEGER_CST_P (offset));
1668 #if 0
1669 /* Disable bound checking for now because it's probably broken. */
1670 if (flag_bounds_check)
1672 gcc_unreachable ();
1674 #endif
1678 /* INFO describes a GFC_SS_SECTION in loop LOOP, and this function is
1679 called after evaluating all of INFO's vector dimensions. Go through
1680 each such vector dimension and see if we can now fill in any missing
1681 loop bounds. */
1683 static void
1684 gfc_set_vector_loop_bounds (gfc_loopinfo * loop, gfc_ss_info * info)
1686 gfc_se se;
1687 tree tmp;
1688 tree desc;
1689 tree zero;
1690 int n;
1691 int dim;
1693 for (n = 0; n < loop->dimen; n++)
1695 dim = info->dim[n];
1696 if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR
1697 && loop->to[n] == NULL)
1699 /* Loop variable N indexes vector dimension DIM, and we don't
1700 yet know the upper bound of loop variable N. Set it to the
1701 difference between the vector's upper and lower bounds. */
1702 gcc_assert (loop->from[n] == gfc_index_zero_node);
1703 gcc_assert (info->subscript[dim]
1704 && info->subscript[dim]->type == GFC_SS_VECTOR);
1706 gfc_init_se (&se, NULL);
1707 desc = info->subscript[dim]->data.info.descriptor;
1708 zero = gfc_rank_cst[0];
1709 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1710 gfc_conv_descriptor_ubound (desc, zero),
1711 gfc_conv_descriptor_lbound (desc, zero));
1712 tmp = gfc_evaluate_now (tmp, &loop->pre);
1713 loop->to[n] = tmp;
1719 /* Add the pre and post chains for all the scalar expressions in a SS chain
1720 to loop. This is called after the loop parameters have been calculated,
1721 but before the actual scalarizing loops. */
1723 static void
1724 gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript)
1726 gfc_se se;
1727 int n;
1729 /* TODO: This can generate bad code if there are ordering dependencies.
1730 eg. a callee allocated function and an unknown size constructor. */
1731 gcc_assert (ss != NULL);
1733 for (; ss != gfc_ss_terminator; ss = ss->loop_chain)
1735 gcc_assert (ss);
1737 switch (ss->type)
1739 case GFC_SS_SCALAR:
1740 /* Scalar expression. Evaluate this now. This includes elemental
1741 dimension indices, but not array section bounds. */
1742 gfc_init_se (&se, NULL);
1743 gfc_conv_expr (&se, ss->expr);
1744 gfc_add_block_to_block (&loop->pre, &se.pre);
1746 if (ss->expr->ts.type != BT_CHARACTER)
1748 /* Move the evaluation of scalar expressions outside the
1749 scalarization loop. */
1750 if (subscript)
1751 se.expr = convert(gfc_array_index_type, se.expr);
1752 se.expr = gfc_evaluate_now (se.expr, &loop->pre);
1753 gfc_add_block_to_block (&loop->pre, &se.post);
1755 else
1756 gfc_add_block_to_block (&loop->post, &se.post);
1758 ss->data.scalar.expr = se.expr;
1759 ss->string_length = se.string_length;
1760 break;
1762 case GFC_SS_REFERENCE:
1763 /* Scalar reference. Evaluate this now. */
1764 gfc_init_se (&se, NULL);
1765 gfc_conv_expr_reference (&se, ss->expr);
1766 gfc_add_block_to_block (&loop->pre, &se.pre);
1767 gfc_add_block_to_block (&loop->post, &se.post);
1769 ss->data.scalar.expr = gfc_evaluate_now (se.expr, &loop->pre);
1770 ss->string_length = se.string_length;
1771 break;
1773 case GFC_SS_SECTION:
1774 /* Add the expressions for scalar and vector subscripts. */
1775 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1776 if (ss->data.info.subscript[n])
1777 gfc_add_loop_ss_code (loop, ss->data.info.subscript[n], true);
1779 gfc_set_vector_loop_bounds (loop, &ss->data.info);
1780 break;
1782 case GFC_SS_VECTOR:
1783 /* Get the vector's descriptor and store it in SS. */
1784 gfc_init_se (&se, NULL);
1785 gfc_conv_expr_descriptor (&se, ss->expr, gfc_walk_expr (ss->expr));
1786 gfc_add_block_to_block (&loop->pre, &se.pre);
1787 gfc_add_block_to_block (&loop->post, &se.post);
1788 ss->data.info.descriptor = se.expr;
1789 break;
1791 case GFC_SS_INTRINSIC:
1792 gfc_add_intrinsic_ss_code (loop, ss);
1793 break;
1795 case GFC_SS_FUNCTION:
1796 /* Array function return value. We call the function and save its
1797 result in a temporary for use inside the loop. */
1798 gfc_init_se (&se, NULL);
1799 se.loop = loop;
1800 se.ss = ss;
1801 gfc_conv_expr (&se, ss->expr);
1802 gfc_add_block_to_block (&loop->pre, &se.pre);
1803 gfc_add_block_to_block (&loop->post, &se.post);
1804 ss->string_length = se.string_length;
1805 break;
1807 case GFC_SS_CONSTRUCTOR:
1808 gfc_trans_array_constructor (loop, ss);
1809 break;
1811 case GFC_SS_TEMP:
1812 case GFC_SS_COMPONENT:
1813 /* Do nothing. These are handled elsewhere. */
1814 break;
1816 default:
1817 gcc_unreachable ();
1823 /* Translate expressions for the descriptor and data pointer of a SS. */
1824 /*GCC ARRAYS*/
1826 static void
1827 gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)
1829 gfc_se se;
1830 tree tmp;
1832 /* Get the descriptor for the array to be scalarized. */
1833 gcc_assert (ss->expr->expr_type == EXPR_VARIABLE);
1834 gfc_init_se (&se, NULL);
1835 se.descriptor_only = 1;
1836 gfc_conv_expr_lhs (&se, ss->expr);
1837 gfc_add_block_to_block (block, &se.pre);
1838 ss->data.info.descriptor = se.expr;
1839 ss->string_length = se.string_length;
1841 if (base)
1843 /* Also the data pointer. */
1844 tmp = gfc_conv_array_data (se.expr);
1845 /* If this is a variable or address of a variable we use it directly.
1846 Otherwise we must evaluate it now to avoid breaking dependency
1847 analysis by pulling the expressions for elemental array indices
1848 inside the loop. */
1849 if (!(DECL_P (tmp)
1850 || (TREE_CODE (tmp) == ADDR_EXPR
1851 && DECL_P (TREE_OPERAND (tmp, 0)))))
1852 tmp = gfc_evaluate_now (tmp, block);
1853 ss->data.info.data = tmp;
1855 tmp = gfc_conv_array_offset (se.expr);
1856 ss->data.info.offset = gfc_evaluate_now (tmp, block);
1861 /* Initialize a gfc_loopinfo structure. */
1863 void
1864 gfc_init_loopinfo (gfc_loopinfo * loop)
1866 int n;
1868 memset (loop, 0, sizeof (gfc_loopinfo));
1869 gfc_init_block (&loop->pre);
1870 gfc_init_block (&loop->post);
1872 /* Initially scalarize in order. */
1873 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1874 loop->order[n] = n;
1876 loop->ss = gfc_ss_terminator;
1880 /* Copies the loop variable info to a gfc_se structure. Does not copy the SS
1881 chain. */
1883 void
1884 gfc_copy_loopinfo_to_se (gfc_se * se, gfc_loopinfo * loop)
1886 se->loop = loop;
1890 /* Return an expression for the data pointer of an array. */
1892 tree
1893 gfc_conv_array_data (tree descriptor)
1895 tree type;
1897 type = TREE_TYPE (descriptor);
1898 if (GFC_ARRAY_TYPE_P (type))
1900 if (TREE_CODE (type) == POINTER_TYPE)
1901 return descriptor;
1902 else
1904 /* Descriptorless arrays. */
1905 return build_fold_addr_expr (descriptor);
1908 else
1909 return gfc_conv_descriptor_data_get (descriptor);
1913 /* Return an expression for the base offset of an array. */
1915 tree
1916 gfc_conv_array_offset (tree descriptor)
1918 tree type;
1920 type = TREE_TYPE (descriptor);
1921 if (GFC_ARRAY_TYPE_P (type))
1922 return GFC_TYPE_ARRAY_OFFSET (type);
1923 else
1924 return gfc_conv_descriptor_offset (descriptor);
1928 /* Get an expression for the array stride. */
1930 tree
1931 gfc_conv_array_stride (tree descriptor, int dim)
1933 tree tmp;
1934 tree type;
1936 type = TREE_TYPE (descriptor);
1938 /* For descriptorless arrays use the array size. */
1939 tmp = GFC_TYPE_ARRAY_STRIDE (type, dim);
1940 if (tmp != NULL_TREE)
1941 return tmp;
1943 tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[dim]);
1944 return tmp;
1948 /* Like gfc_conv_array_stride, but for the lower bound. */
1950 tree
1951 gfc_conv_array_lbound (tree descriptor, int dim)
1953 tree tmp;
1954 tree type;
1956 type = TREE_TYPE (descriptor);
1958 tmp = GFC_TYPE_ARRAY_LBOUND (type, dim);
1959 if (tmp != NULL_TREE)
1960 return tmp;
1962 tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[dim]);
1963 return tmp;
1967 /* Like gfc_conv_array_stride, but for the upper bound. */
1969 tree
1970 gfc_conv_array_ubound (tree descriptor, int dim)
1972 tree tmp;
1973 tree type;
1975 type = TREE_TYPE (descriptor);
1977 tmp = GFC_TYPE_ARRAY_UBOUND (type, dim);
1978 if (tmp != NULL_TREE)
1979 return tmp;
1981 /* This should only ever happen when passing an assumed shape array
1982 as an actual parameter. The value will never be used. */
1983 if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor)))
1984 return gfc_index_zero_node;
1986 tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[dim]);
1987 return tmp;
1991 /* Generate code to perform an array index bound check. */
1993 static tree
1994 gfc_trans_array_bound_check (gfc_se * se, tree descriptor, tree index, int n,
1995 locus * where)
1997 tree fault;
1998 tree tmp;
1999 char *msg;
2000 const char * name = NULL;
2002 if (!flag_bounds_check)
2003 return index;
2005 index = gfc_evaluate_now (index, &se->pre);
2007 /* We find a name for the error message. */
2008 if (se->ss)
2009 name = se->ss->expr->symtree->name;
2011 if (!name && se->loop && se->loop->ss && se->loop->ss->expr
2012 && se->loop->ss->expr->symtree)
2013 name = se->loop->ss->expr->symtree->name;
2015 if (!name && se->loop && se->loop->ss && se->loop->ss->loop_chain
2016 && se->loop->ss->loop_chain->expr
2017 && se->loop->ss->loop_chain->expr->symtree)
2018 name = se->loop->ss->loop_chain->expr->symtree->name;
2020 if (!name && se->loop && se->loop->ss && se->loop->ss->loop_chain
2021 && se->loop->ss->loop_chain->expr->symtree)
2022 name = se->loop->ss->loop_chain->expr->symtree->name;
2024 if (!name && se->loop && se->loop->ss && se->loop->ss->expr)
2026 if (se->loop->ss->expr->expr_type == EXPR_FUNCTION
2027 && se->loop->ss->expr->value.function.name)
2028 name = se->loop->ss->expr->value.function.name;
2029 else
2030 if (se->loop->ss->type == GFC_SS_CONSTRUCTOR
2031 || se->loop->ss->type == GFC_SS_SCALAR)
2032 name = "unnamed constant";
2035 /* Check lower bound. */
2036 tmp = gfc_conv_array_lbound (descriptor, n);
2037 fault = fold_build2 (LT_EXPR, boolean_type_node, index, tmp);
2038 if (name)
2039 asprintf (&msg, "%s for array '%s', lower bound of dimension %d exceeded",
2040 gfc_msg_fault, name, n+1);
2041 else
2042 asprintf (&msg, "%s, lower bound of dimension %d exceeded",
2043 gfc_msg_fault, n+1);
2044 gfc_trans_runtime_check (fault, msg, &se->pre, where);
2045 gfc_free (msg);
2047 /* Check upper bound. */
2048 tmp = gfc_conv_array_ubound (descriptor, n);
2049 fault = fold_build2 (GT_EXPR, boolean_type_node, index, tmp);
2050 if (name)
2051 asprintf (&msg, "%s for array '%s', upper bound of dimension %d exceeded",
2052 gfc_msg_fault, name, n+1);
2053 else
2054 asprintf (&msg, "%s, upper bound of dimension %d exceeded",
2055 gfc_msg_fault, n+1);
2056 gfc_trans_runtime_check (fault, msg, &se->pre, where);
2057 gfc_free (msg);
2059 return index;
2063 /* Return the offset for an index. Performs bound checking for elemental
2064 dimensions. Single element references are processed separately. */
2066 static tree
2067 gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i,
2068 gfc_array_ref * ar, tree stride)
2070 tree index;
2071 tree desc;
2072 tree data;
2074 /* Get the index into the array for this dimension. */
2075 if (ar)
2077 gcc_assert (ar->type != AR_ELEMENT);
2078 switch (ar->dimen_type[dim])
2080 case DIMEN_ELEMENT:
2081 gcc_assert (i == -1);
2082 /* Elemental dimension. */
2083 gcc_assert (info->subscript[dim]
2084 && info->subscript[dim]->type == GFC_SS_SCALAR);
2085 /* We've already translated this value outside the loop. */
2086 index = info->subscript[dim]->data.scalar.expr;
2088 if ((ar->as->type != AS_ASSUMED_SIZE && !ar->as->cp_was_assumed)
2089 || dim < ar->dimen - 1)
2090 index = gfc_trans_array_bound_check (se, info->descriptor,
2091 index, dim, &ar->where);
2092 break;
2094 case DIMEN_VECTOR:
2095 gcc_assert (info && se->loop);
2096 gcc_assert (info->subscript[dim]
2097 && info->subscript[dim]->type == GFC_SS_VECTOR);
2098 desc = info->subscript[dim]->data.info.descriptor;
2100 /* Get a zero-based index into the vector. */
2101 index = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2102 se->loop->loopvar[i], se->loop->from[i]);
2104 /* Multiply the index by the stride. */
2105 index = fold_build2 (MULT_EXPR, gfc_array_index_type,
2106 index, gfc_conv_array_stride (desc, 0));
2108 /* Read the vector to get an index into info->descriptor. */
2109 data = build_fold_indirect_ref (gfc_conv_array_data (desc));
2110 index = gfc_build_array_ref (data, index);
2111 index = gfc_evaluate_now (index, &se->pre);
2113 /* Do any bounds checking on the final info->descriptor index. */
2114 if ((ar->as->type != AS_ASSUMED_SIZE && !ar->as->cp_was_assumed)
2115 || dim < ar->dimen - 1)
2116 index = gfc_trans_array_bound_check (se, info->descriptor,
2117 index, dim, &ar->where);
2118 break;
2120 case DIMEN_RANGE:
2121 /* Scalarized dimension. */
2122 gcc_assert (info && se->loop);
2124 /* Multiply the loop variable by the stride and delta. */
2125 index = se->loop->loopvar[i];
2126 if (!integer_onep (info->stride[i]))
2127 index = fold_build2 (MULT_EXPR, gfc_array_index_type, index,
2128 info->stride[i]);
2129 if (!integer_zerop (info->delta[i]))
2130 index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index,
2131 info->delta[i]);
2132 break;
2134 default:
2135 gcc_unreachable ();
2138 else
2140 /* Temporary array or derived type component. */
2141 gcc_assert (se->loop);
2142 index = se->loop->loopvar[se->loop->order[i]];
2143 if (!integer_zerop (info->delta[i]))
2144 index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2145 index, info->delta[i]);
2148 /* Multiply by the stride. */
2149 if (!integer_onep (stride))
2150 index = fold_build2 (MULT_EXPR, gfc_array_index_type, index, stride);
2152 return index;
2156 /* Build a scalarized reference to an array. */
2158 static void
2159 gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
2161 gfc_ss_info *info;
2162 tree index;
2163 tree tmp;
2164 int n;
2166 info = &se->ss->data.info;
2167 if (ar)
2168 n = se->loop->order[0];
2169 else
2170 n = 0;
2172 index = gfc_conv_array_index_offset (se, info, info->dim[n], n, ar,
2173 info->stride0);
2174 /* Add the offset for this dimension to the stored offset for all other
2175 dimensions. */
2176 if (!integer_zerop (info->offset))
2177 index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, info->offset);
2179 tmp = build_fold_indirect_ref (info->data);
2180 se->expr = gfc_build_array_ref (tmp, index);
2184 /* Translate access of temporary array. */
2186 void
2187 gfc_conv_tmp_array_ref (gfc_se * se)
2189 se->string_length = se->ss->string_length;
2190 gfc_conv_scalarized_array_ref (se, NULL);
2194 /* Build an array reference. se->expr already holds the array descriptor.
2195 This should be either a variable, indirect variable reference or component
2196 reference. For arrays which do not have a descriptor, se->expr will be
2197 the data pointer.
2198 a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
2200 void
2201 gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym,
2202 locus * where)
2204 int n;
2205 tree index;
2206 tree tmp;
2207 tree stride;
2208 gfc_se indexse;
2210 /* Handle scalarized references separately. */
2211 if (ar->type != AR_ELEMENT)
2213 gfc_conv_scalarized_array_ref (se, ar);
2214 gfc_advance_se_ss_chain (se);
2215 return;
2218 index = gfc_index_zero_node;
2220 /* Calculate the offsets from all the dimensions. */
2221 for (n = 0; n < ar->dimen; n++)
2223 /* Calculate the index for this dimension. */
2224 gfc_init_se (&indexse, se);
2225 gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type);
2226 gfc_add_block_to_block (&se->pre, &indexse.pre);
2228 if (flag_bounds_check &&
2229 ((ar->as->type != AS_ASSUMED_SIZE && !ar->as->cp_was_assumed)
2230 || n < ar->dimen - 1))
2232 /* Check array bounds. */
2233 tree cond;
2234 char *msg;
2236 tmp = gfc_conv_array_lbound (se->expr, n);
2237 cond = fold_build2 (LT_EXPR, boolean_type_node,
2238 indexse.expr, tmp);
2239 asprintf (&msg, "%s for array '%s', "
2240 "lower bound of dimension %d exceeded", gfc_msg_fault,
2241 sym->name, n+1);
2242 gfc_trans_runtime_check (cond, msg, &se->pre, where);
2243 gfc_free (msg);
2245 tmp = gfc_conv_array_ubound (se->expr, n);
2246 cond = fold_build2 (GT_EXPR, boolean_type_node,
2247 indexse.expr, tmp);
2248 asprintf (&msg, "%s for array '%s', "
2249 "upper bound of dimension %d exceeded", gfc_msg_fault,
2250 sym->name, n+1);
2251 gfc_trans_runtime_check (cond, msg, &se->pre, where);
2252 gfc_free (msg);
2255 /* Multiply the index by the stride. */
2256 stride = gfc_conv_array_stride (se->expr, n);
2257 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, indexse.expr,
2258 stride);
2260 /* And add it to the total. */
2261 index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
2264 tmp = gfc_conv_array_offset (se->expr);
2265 if (!integer_zerop (tmp))
2266 index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
2268 /* Access the calculated element. */
2269 tmp = gfc_conv_array_data (se->expr);
2270 tmp = build_fold_indirect_ref (tmp);
2271 se->expr = gfc_build_array_ref (tmp, index);
2275 /* Generate the code to be executed immediately before entering a
2276 scalarization loop. */
2278 static void
2279 gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
2280 stmtblock_t * pblock)
2282 tree index;
2283 tree stride;
2284 gfc_ss_info *info;
2285 gfc_ss *ss;
2286 gfc_se se;
2287 int i;
2289 /* This code will be executed before entering the scalarization loop
2290 for this dimension. */
2291 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2293 if ((ss->useflags & flag) == 0)
2294 continue;
2296 if (ss->type != GFC_SS_SECTION
2297 && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
2298 && ss->type != GFC_SS_COMPONENT)
2299 continue;
2301 info = &ss->data.info;
2303 if (dim >= info->dimen)
2304 continue;
2306 if (dim == info->dimen - 1)
2308 /* For the outermost loop calculate the offset due to any
2309 elemental dimensions. It will have been initialized with the
2310 base offset of the array. */
2311 if (info->ref)
2313 for (i = 0; i < info->ref->u.ar.dimen; i++)
2315 if (info->ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
2316 continue;
2318 gfc_init_se (&se, NULL);
2319 se.loop = loop;
2320 se.expr = info->descriptor;
2321 stride = gfc_conv_array_stride (info->descriptor, i);
2322 index = gfc_conv_array_index_offset (&se, info, i, -1,
2323 &info->ref->u.ar,
2324 stride);
2325 gfc_add_block_to_block (pblock, &se.pre);
2327 info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2328 info->offset, index);
2329 info->offset = gfc_evaluate_now (info->offset, pblock);
2332 i = loop->order[0];
2333 stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
2335 else
2336 stride = gfc_conv_array_stride (info->descriptor, 0);
2338 /* Calculate the stride of the innermost loop. Hopefully this will
2339 allow the backend optimizers to do their stuff more effectively.
2341 info->stride0 = gfc_evaluate_now (stride, pblock);
2343 else
2345 /* Add the offset for the previous loop dimension. */
2346 gfc_array_ref *ar;
2348 if (info->ref)
2350 ar = &info->ref->u.ar;
2351 i = loop->order[dim + 1];
2353 else
2355 ar = NULL;
2356 i = dim + 1;
2359 gfc_init_se (&se, NULL);
2360 se.loop = loop;
2361 se.expr = info->descriptor;
2362 stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
2363 index = gfc_conv_array_index_offset (&se, info, info->dim[i], i,
2364 ar, stride);
2365 gfc_add_block_to_block (pblock, &se.pre);
2366 info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2367 info->offset, index);
2368 info->offset = gfc_evaluate_now (info->offset, pblock);
2371 /* Remember this offset for the second loop. */
2372 if (dim == loop->temp_dim - 1)
2373 info->saved_offset = info->offset;
2378 /* Start a scalarized expression. Creates a scope and declares loop
2379 variables. */
2381 void
2382 gfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody)
2384 int dim;
2385 int n;
2386 int flags;
2388 gcc_assert (!loop->array_parameter);
2390 for (dim = loop->dimen - 1; dim >= 0; dim--)
2392 n = loop->order[dim];
2394 gfc_start_block (&loop->code[n]);
2396 /* Create the loop variable. */
2397 loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "S");
2399 if (dim < loop->temp_dim)
2400 flags = 3;
2401 else
2402 flags = 1;
2403 /* Calculate values that will be constant within this loop. */
2404 gfc_trans_preloop_setup (loop, dim, flags, &loop->code[n]);
2406 gfc_start_block (pbody);
2410 /* Generates the actual loop code for a scalarization loop. */
2412 static void
2413 gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
2414 stmtblock_t * pbody)
2416 stmtblock_t block;
2417 tree cond;
2418 tree tmp;
2419 tree loopbody;
2420 tree exit_label;
2422 loopbody = gfc_finish_block (pbody);
2424 /* Initialize the loopvar. */
2425 gfc_add_modify_expr (&loop->code[n], loop->loopvar[n], loop->from[n]);
2427 exit_label = gfc_build_label_decl (NULL_TREE);
2429 /* Generate the loop body. */
2430 gfc_init_block (&block);
2432 /* The exit condition. */
2433 cond = build2 (GT_EXPR, boolean_type_node, loop->loopvar[n], loop->to[n]);
2434 tmp = build1_v (GOTO_EXPR, exit_label);
2435 TREE_USED (exit_label) = 1;
2436 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
2437 gfc_add_expr_to_block (&block, tmp);
2439 /* The main body. */
2440 gfc_add_expr_to_block (&block, loopbody);
2442 /* Increment the loopvar. */
2443 tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2444 loop->loopvar[n], gfc_index_one_node);
2445 gfc_add_modify_expr (&block, loop->loopvar[n], tmp);
2447 /* Build the loop. */
2448 tmp = gfc_finish_block (&block);
2449 tmp = build1_v (LOOP_EXPR, tmp);
2450 gfc_add_expr_to_block (&loop->code[n], tmp);
2452 /* Add the exit label. */
2453 tmp = build1_v (LABEL_EXPR, exit_label);
2454 gfc_add_expr_to_block (&loop->code[n], tmp);
2458 /* Finishes and generates the loops for a scalarized expression. */
2460 void
2461 gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body)
2463 int dim;
2464 int n;
2465 gfc_ss *ss;
2466 stmtblock_t *pblock;
2467 tree tmp;
2469 pblock = body;
2470 /* Generate the loops. */
2471 for (dim = 0; dim < loop->dimen; dim++)
2473 n = loop->order[dim];
2474 gfc_trans_scalarized_loop_end (loop, n, pblock);
2475 loop->loopvar[n] = NULL_TREE;
2476 pblock = &loop->code[n];
2479 tmp = gfc_finish_block (pblock);
2480 gfc_add_expr_to_block (&loop->pre, tmp);
2482 /* Clear all the used flags. */
2483 for (ss = loop->ss; ss; ss = ss->loop_chain)
2484 ss->useflags = 0;
2488 /* Finish the main body of a scalarized expression, and start the secondary
2489 copying body. */
2491 void
2492 gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
2494 int dim;
2495 int n;
2496 stmtblock_t *pblock;
2497 gfc_ss *ss;
2499 pblock = body;
2500 /* We finish as many loops as are used by the temporary. */
2501 for (dim = 0; dim < loop->temp_dim - 1; dim++)
2503 n = loop->order[dim];
2504 gfc_trans_scalarized_loop_end (loop, n, pblock);
2505 loop->loopvar[n] = NULL_TREE;
2506 pblock = &loop->code[n];
2509 /* We don't want to finish the outermost loop entirely. */
2510 n = loop->order[loop->temp_dim - 1];
2511 gfc_trans_scalarized_loop_end (loop, n, pblock);
2513 /* Restore the initial offsets. */
2514 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2516 if ((ss->useflags & 2) == 0)
2517 continue;
2519 if (ss->type != GFC_SS_SECTION
2520 && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
2521 && ss->type != GFC_SS_COMPONENT)
2522 continue;
2524 ss->data.info.offset = ss->data.info.saved_offset;
2527 /* Restart all the inner loops we just finished. */
2528 for (dim = loop->temp_dim - 2; dim >= 0; dim--)
2530 n = loop->order[dim];
2532 gfc_start_block (&loop->code[n]);
2534 loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "Q");
2536 gfc_trans_preloop_setup (loop, dim, 2, &loop->code[n]);
2539 /* Start a block for the secondary copying code. */
2540 gfc_start_block (body);
2544 /* Calculate the upper bound of an array section. */
2546 static tree
2547 gfc_conv_section_upper_bound (gfc_ss * ss, int n, stmtblock_t * pblock)
2549 int dim;
2550 gfc_expr *end;
2551 tree desc;
2552 tree bound;
2553 gfc_se se;
2554 gfc_ss_info *info;
2556 gcc_assert (ss->type == GFC_SS_SECTION);
2558 info = &ss->data.info;
2559 dim = info->dim[n];
2561 if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2562 /* We'll calculate the upper bound once we have access to the
2563 vector's descriptor. */
2564 return NULL;
2566 gcc_assert (info->ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
2567 desc = info->descriptor;
2568 end = info->ref->u.ar.end[dim];
2570 if (end)
2572 /* The upper bound was specified. */
2573 gfc_init_se (&se, NULL);
2574 gfc_conv_expr_type (&se, end, gfc_array_index_type);
2575 gfc_add_block_to_block (pblock, &se.pre);
2576 bound = se.expr;
2578 else
2580 /* No upper bound was specified, so use the bound of the array. */
2581 bound = gfc_conv_array_ubound (desc, dim);
2584 return bound;
2588 /* Calculate the lower bound of an array section. */
2590 static void
2591 gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int n)
2593 gfc_expr *start;
2594 gfc_expr *end;
2595 gfc_expr *stride;
2596 tree desc;
2597 gfc_se se;
2598 gfc_ss_info *info;
2599 int dim;
2601 gcc_assert (ss->type == GFC_SS_SECTION);
2603 info = &ss->data.info;
2604 dim = info->dim[n];
2606 if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2608 /* We use a zero-based index to access the vector. */
2609 info->start[n] = gfc_index_zero_node;
2610 info->end[n] = gfc_index_zero_node;
2611 info->stride[n] = gfc_index_one_node;
2612 return;
2615 gcc_assert (info->ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
2616 desc = info->descriptor;
2617 start = info->ref->u.ar.start[dim];
2618 end = info->ref->u.ar.end[dim];
2619 stride = info->ref->u.ar.stride[dim];
2621 /* Calculate the start of the range. For vector subscripts this will
2622 be the range of the vector. */
2623 if (start)
2625 /* Specified section start. */
2626 gfc_init_se (&se, NULL);
2627 gfc_conv_expr_type (&se, start, gfc_array_index_type);
2628 gfc_add_block_to_block (&loop->pre, &se.pre);
2629 info->start[n] = se.expr;
2631 else
2633 /* No lower bound specified so use the bound of the array. */
2634 info->start[n] = gfc_conv_array_lbound (desc, dim);
2636 info->start[n] = gfc_evaluate_now (info->start[n], &loop->pre);
2638 /* Similarly calculate the end. Although this is not used in the
2639 scalarizer, it is needed when checking bounds and where the end
2640 is an expression with side-effects. */
2641 if (end)
2643 /* Specified section start. */
2644 gfc_init_se (&se, NULL);
2645 gfc_conv_expr_type (&se, end, gfc_array_index_type);
2646 gfc_add_block_to_block (&loop->pre, &se.pre);
2647 info->end[n] = se.expr;
2649 else
2651 /* No upper bound specified so use the bound of the array. */
2652 info->end[n] = gfc_conv_array_ubound (desc, dim);
2654 info->end[n] = gfc_evaluate_now (info->end[n], &loop->pre);
2656 /* Calculate the stride. */
2657 if (stride == NULL)
2658 info->stride[n] = gfc_index_one_node;
2659 else
2661 gfc_init_se (&se, NULL);
2662 gfc_conv_expr_type (&se, stride, gfc_array_index_type);
2663 gfc_add_block_to_block (&loop->pre, &se.pre);
2664 info->stride[n] = gfc_evaluate_now (se.expr, &loop->pre);
2669 /* Calculates the range start and stride for a SS chain. Also gets the
2670 descriptor and data pointer. The range of vector subscripts is the size
2671 of the vector. Array bounds are also checked. */
2673 void
2674 gfc_conv_ss_startstride (gfc_loopinfo * loop)
2676 int n;
2677 tree tmp;
2678 gfc_ss *ss;
2679 tree desc;
2681 loop->dimen = 0;
2682 /* Determine the rank of the loop. */
2683 for (ss = loop->ss;
2684 ss != gfc_ss_terminator && loop->dimen == 0; ss = ss->loop_chain)
2686 switch (ss->type)
2688 case GFC_SS_SECTION:
2689 case GFC_SS_CONSTRUCTOR:
2690 case GFC_SS_FUNCTION:
2691 case GFC_SS_COMPONENT:
2692 loop->dimen = ss->data.info.dimen;
2693 break;
2695 /* As usual, lbound and ubound are exceptions!. */
2696 case GFC_SS_INTRINSIC:
2697 switch (ss->expr->value.function.isym->generic_id)
2699 case GFC_ISYM_LBOUND:
2700 case GFC_ISYM_UBOUND:
2701 loop->dimen = ss->data.info.dimen;
2703 default:
2704 break;
2707 default:
2708 break;
2712 if (loop->dimen == 0)
2713 gfc_todo_error ("Unable to determine rank of expression");
2716 /* Loop over all the SS in the chain. */
2717 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2719 if (ss->expr && ss->expr->shape && !ss->shape)
2720 ss->shape = ss->expr->shape;
2722 switch (ss->type)
2724 case GFC_SS_SECTION:
2725 /* Get the descriptor for the array. */
2726 gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter);
2728 for (n = 0; n < ss->data.info.dimen; n++)
2729 gfc_conv_section_startstride (loop, ss, n);
2730 break;
2732 case GFC_SS_INTRINSIC:
2733 switch (ss->expr->value.function.isym->generic_id)
2735 /* Fall through to supply start and stride. */
2736 case GFC_ISYM_LBOUND:
2737 case GFC_ISYM_UBOUND:
2738 break;
2739 default:
2740 continue;
2743 case GFC_SS_CONSTRUCTOR:
2744 case GFC_SS_FUNCTION:
2745 for (n = 0; n < ss->data.info.dimen; n++)
2747 ss->data.info.start[n] = gfc_index_zero_node;
2748 ss->data.info.end[n] = gfc_index_zero_node;
2749 ss->data.info.stride[n] = gfc_index_one_node;
2751 break;
2753 default:
2754 break;
2758 /* The rest is just runtime bound checking. */
2759 if (flag_bounds_check)
2761 stmtblock_t block;
2762 tree lbound, ubound;
2763 tree end;
2764 tree size[GFC_MAX_DIMENSIONS];
2765 tree stride_pos, stride_neg, non_zerosized, tmp2;
2766 gfc_ss_info *info;
2767 char *msg;
2768 int dim;
2770 gfc_start_block (&block);
2772 for (n = 0; n < loop->dimen; n++)
2773 size[n] = NULL_TREE;
2775 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2777 if (ss->type != GFC_SS_SECTION)
2778 continue;
2780 /* TODO: range checking for mapped dimensions. */
2781 info = &ss->data.info;
2783 /* This code only checks ranges. Elemental and vector
2784 dimensions are checked later. */
2785 for (n = 0; n < loop->dimen; n++)
2787 dim = info->dim[n];
2788 if (info->ref->u.ar.dimen_type[dim] != DIMEN_RANGE)
2789 continue;
2790 if (n == info->ref->u.ar.dimen - 1
2791 && (info->ref->u.ar.as->type == AS_ASSUMED_SIZE
2792 || info->ref->u.ar.as->cp_was_assumed))
2793 continue;
2795 desc = ss->data.info.descriptor;
2797 /* This is the run-time equivalent of resolve.c's
2798 check_dimension(). The logical is more readable there
2799 than it is here, with all the trees. */
2800 lbound = gfc_conv_array_lbound (desc, dim);
2801 ubound = gfc_conv_array_ubound (desc, dim);
2802 end = info->end[n];
2804 /* Zero stride is not allowed. */
2805 tmp = fold_build2 (EQ_EXPR, boolean_type_node, info->stride[n],
2806 gfc_index_zero_node);
2807 asprintf (&msg, "Zero stride is not allowed, for dimension %d "
2808 "of array '%s'", info->dim[n]+1,
2809 ss->expr->symtree->name);
2810 gfc_trans_runtime_check (tmp, msg, &block, &ss->expr->where);
2811 gfc_free (msg);
2813 /* non_zerosized is true when the selected range is not
2814 empty. */
2815 stride_pos = fold_build2 (GT_EXPR, boolean_type_node,
2816 info->stride[n], gfc_index_zero_node);
2817 tmp = fold_build2 (LE_EXPR, boolean_type_node, info->start[n],
2818 end);
2819 stride_pos = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2820 stride_pos, tmp);
2822 stride_neg = fold_build2 (LT_EXPR, boolean_type_node,
2823 info->stride[n], gfc_index_zero_node);
2824 tmp = fold_build2 (GE_EXPR, boolean_type_node, info->start[n],
2825 end);
2826 stride_neg = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2827 stride_neg, tmp);
2828 non_zerosized = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
2829 stride_pos, stride_neg);
2831 /* Check the start of the range against the lower and upper
2832 bounds of the array, if the range is not empty. */
2833 tmp = fold_build2 (LT_EXPR, boolean_type_node, info->start[n],
2834 lbound);
2835 tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2836 non_zerosized, tmp);
2837 asprintf (&msg, "%s, lower bound of dimension %d of array '%s'"
2838 " exceeded", gfc_msg_fault, info->dim[n]+1,
2839 ss->expr->symtree->name);
2840 gfc_trans_runtime_check (tmp, msg, &block, &ss->expr->where);
2841 gfc_free (msg);
2843 tmp = fold_build2 (GT_EXPR, boolean_type_node, info->start[n],
2844 ubound);
2845 tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2846 non_zerosized, tmp);
2847 asprintf (&msg, "%s, upper bound of dimension %d of array '%s'"
2848 " exceeded", gfc_msg_fault, info->dim[n]+1,
2849 ss->expr->symtree->name);
2850 gfc_trans_runtime_check (tmp, msg, &block, &ss->expr->where);
2851 gfc_free (msg);
2853 /* Compute the last element of the range, which is not
2854 necessarily "end" (think 0:5:3, which doesn't contain 5)
2855 and check it against both lower and upper bounds. */
2856 tmp2 = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
2857 info->start[n]);
2858 tmp2 = fold_build2 (TRUNC_MOD_EXPR, gfc_array_index_type, tmp2,
2859 info->stride[n]);
2860 tmp2 = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
2861 tmp2);
2863 tmp = fold_build2 (LT_EXPR, boolean_type_node, tmp2, lbound);
2864 tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2865 non_zerosized, tmp);
2866 asprintf (&msg, "%s, lower bound of dimension %d of array '%s'"
2867 " exceeded", gfc_msg_fault, info->dim[n]+1,
2868 ss->expr->symtree->name);
2869 gfc_trans_runtime_check (tmp, msg, &block, &ss->expr->where);
2870 gfc_free (msg);
2872 tmp = fold_build2 (GT_EXPR, boolean_type_node, tmp2, ubound);
2873 tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2874 non_zerosized, tmp);
2875 asprintf (&msg, "%s, upper bound of dimension %d of array '%s'"
2876 " exceeded", gfc_msg_fault, info->dim[n]+1,
2877 ss->expr->symtree->name);
2878 gfc_trans_runtime_check (tmp, msg, &block, &ss->expr->where);
2879 gfc_free (msg);
2881 /* Check the section sizes match. */
2882 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
2883 info->start[n]);
2884 tmp = fold_build2 (FLOOR_DIV_EXPR, gfc_array_index_type, tmp,
2885 info->stride[n]);
2886 /* We remember the size of the first section, and check all the
2887 others against this. */
2888 if (size[n])
2890 tmp =
2891 fold_build2 (NE_EXPR, boolean_type_node, tmp, size[n]);
2892 asprintf (&msg, "%s, size mismatch for dimension %d "
2893 "of array '%s'", gfc_msg_bounds, info->dim[n]+1,
2894 ss->expr->symtree->name);
2895 gfc_trans_runtime_check (tmp, msg, &block, &ss->expr->where);
2896 gfc_free (msg);
2898 else
2899 size[n] = gfc_evaluate_now (tmp, &block);
2903 tmp = gfc_finish_block (&block);
2904 gfc_add_expr_to_block (&loop->pre, tmp);
2909 /* Return true if the two SS could be aliased, i.e. both point to the same data
2910 object. */
2911 /* TODO: resolve aliases based on frontend expressions. */
2913 static int
2914 gfc_could_be_alias (gfc_ss * lss, gfc_ss * rss)
2916 gfc_ref *lref;
2917 gfc_ref *rref;
2918 gfc_symbol *lsym;
2919 gfc_symbol *rsym;
2921 lsym = lss->expr->symtree->n.sym;
2922 rsym = rss->expr->symtree->n.sym;
2923 if (gfc_symbols_could_alias (lsym, rsym))
2924 return 1;
2926 if (rsym->ts.type != BT_DERIVED
2927 && lsym->ts.type != BT_DERIVED)
2928 return 0;
2930 /* For derived types we must check all the component types. We can ignore
2931 array references as these will have the same base type as the previous
2932 component ref. */
2933 for (lref = lss->expr->ref; lref != lss->data.info.ref; lref = lref->next)
2935 if (lref->type != REF_COMPONENT)
2936 continue;
2938 if (gfc_symbols_could_alias (lref->u.c.sym, rsym))
2939 return 1;
2941 for (rref = rss->expr->ref; rref != rss->data.info.ref;
2942 rref = rref->next)
2944 if (rref->type != REF_COMPONENT)
2945 continue;
2947 if (gfc_symbols_could_alias (lref->u.c.sym, rref->u.c.sym))
2948 return 1;
2952 for (rref = rss->expr->ref; rref != rss->data.info.ref; rref = rref->next)
2954 if (rref->type != REF_COMPONENT)
2955 break;
2957 if (gfc_symbols_could_alias (rref->u.c.sym, lsym))
2958 return 1;
2961 return 0;
2965 /* Resolve array data dependencies. Creates a temporary if required. */
2966 /* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
2967 dependency.c. */
2969 void
2970 gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
2971 gfc_ss * rss)
2973 gfc_ss *ss;
2974 gfc_ref *lref;
2975 gfc_ref *rref;
2976 gfc_ref *aref;
2977 int nDepend = 0;
2978 int temp_dim = 0;
2980 loop->temp_ss = NULL;
2981 aref = dest->data.info.ref;
2982 temp_dim = 0;
2984 for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
2986 if (ss->type != GFC_SS_SECTION)
2987 continue;
2989 if (gfc_could_be_alias (dest, ss)
2990 || gfc_are_equivalenced_arrays (dest->expr, ss->expr))
2992 nDepend = 1;
2993 break;
2996 if (dest->expr->symtree->n.sym == ss->expr->symtree->n.sym)
2998 lref = dest->expr->ref;
2999 rref = ss->expr->ref;
3001 nDepend = gfc_dep_resolver (lref, rref);
3002 #if 0
3003 /* TODO : loop shifting. */
3004 if (nDepend == 1)
3006 /* Mark the dimensions for LOOP SHIFTING */
3007 for (n = 0; n < loop->dimen; n++)
3009 int dim = dest->data.info.dim[n];
3011 if (lref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
3012 depends[n] = 2;
3013 else if (! gfc_is_same_range (&lref->u.ar,
3014 &rref->u.ar, dim, 0))
3015 depends[n] = 1;
3018 /* Put all the dimensions with dependencies in the
3019 innermost loops. */
3020 dim = 0;
3021 for (n = 0; n < loop->dimen; n++)
3023 gcc_assert (loop->order[n] == n);
3024 if (depends[n])
3025 loop->order[dim++] = n;
3027 temp_dim = dim;
3028 for (n = 0; n < loop->dimen; n++)
3030 if (! depends[n])
3031 loop->order[dim++] = n;
3034 gcc_assert (dim == loop->dimen);
3035 break;
3037 #endif
3041 if (nDepend == 1)
3043 tree base_type = gfc_typenode_for_spec (&dest->expr->ts);
3044 if (GFC_ARRAY_TYPE_P (base_type)
3045 || GFC_DESCRIPTOR_TYPE_P (base_type))
3046 base_type = gfc_get_element_type (base_type);
3047 loop->temp_ss = gfc_get_ss ();
3048 loop->temp_ss->type = GFC_SS_TEMP;
3049 loop->temp_ss->data.temp.type = base_type;
3050 loop->temp_ss->string_length = dest->string_length;
3051 loop->temp_ss->data.temp.dimen = loop->dimen;
3052 loop->temp_ss->next = gfc_ss_terminator;
3053 gfc_add_ss_to_loop (loop, loop->temp_ss);
3055 else
3056 loop->temp_ss = NULL;
3060 /* Initialize the scalarization loop. Creates the loop variables. Determines
3061 the range of the loop variables. Creates a temporary if required.
3062 Calculates how to transform from loop variables to array indices for each
3063 expression. Also generates code for scalar expressions which have been
3064 moved outside the loop. */
3066 void
3067 gfc_conv_loop_setup (gfc_loopinfo * loop)
3069 int n;
3070 int dim;
3071 gfc_ss_info *info;
3072 gfc_ss_info *specinfo;
3073 gfc_ss *ss;
3074 tree tmp;
3075 tree len;
3076 gfc_ss *loopspec[GFC_MAX_DIMENSIONS];
3077 bool dynamic[GFC_MAX_DIMENSIONS];
3078 gfc_constructor *c;
3079 mpz_t *cshape;
3080 mpz_t i;
3082 mpz_init (i);
3083 for (n = 0; n < loop->dimen; n++)
3085 loopspec[n] = NULL;
3086 dynamic[n] = false;
3087 /* We use one SS term, and use that to determine the bounds of the
3088 loop for this dimension. We try to pick the simplest term. */
3089 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3091 if (ss->shape)
3093 /* The frontend has worked out the size for us. */
3094 loopspec[n] = ss;
3095 continue;
3098 if (ss->type == GFC_SS_CONSTRUCTOR)
3100 /* An unknown size constructor will always be rank one.
3101 Higher rank constructors will either have known shape,
3102 or still be wrapped in a call to reshape. */
3103 gcc_assert (loop->dimen == 1);
3105 /* Always prefer to use the constructor bounds if the size
3106 can be determined at compile time. Prefer not to otherwise,
3107 since the general case involves realloc, and it's better to
3108 avoid that overhead if possible. */
3109 c = ss->expr->value.constructor;
3110 dynamic[n] = gfc_get_array_constructor_size (&i, c);
3111 if (!dynamic[n] || !loopspec[n])
3112 loopspec[n] = ss;
3113 continue;
3116 /* TODO: Pick the best bound if we have a choice between a
3117 function and something else. */
3118 if (ss->type == GFC_SS_FUNCTION)
3120 loopspec[n] = ss;
3121 continue;
3124 if (ss->type != GFC_SS_SECTION)
3125 continue;
3127 if (loopspec[n])
3128 specinfo = &loopspec[n]->data.info;
3129 else
3130 specinfo = NULL;
3131 info = &ss->data.info;
3133 if (!specinfo)
3134 loopspec[n] = ss;
3135 /* Criteria for choosing a loop specifier (most important first):
3136 doesn't need realloc
3137 stride of one
3138 known stride
3139 known lower bound
3140 known upper bound
3142 else if (loopspec[n]->type == GFC_SS_CONSTRUCTOR && dynamic[n])
3143 loopspec[n] = ss;
3144 else if (integer_onep (info->stride[n])
3145 && !integer_onep (specinfo->stride[n]))
3146 loopspec[n] = ss;
3147 else if (INTEGER_CST_P (info->stride[n])
3148 && !INTEGER_CST_P (specinfo->stride[n]))
3149 loopspec[n] = ss;
3150 else if (INTEGER_CST_P (info->start[n])
3151 && !INTEGER_CST_P (specinfo->start[n]))
3152 loopspec[n] = ss;
3153 /* We don't work out the upper bound.
3154 else if (INTEGER_CST_P (info->finish[n])
3155 && ! INTEGER_CST_P (specinfo->finish[n]))
3156 loopspec[n] = ss; */
3159 if (!loopspec[n])
3160 gfc_todo_error ("Unable to find scalarization loop specifier");
3162 info = &loopspec[n]->data.info;
3164 /* Set the extents of this range. */
3165 cshape = loopspec[n]->shape;
3166 if (cshape && INTEGER_CST_P (info->start[n])
3167 && INTEGER_CST_P (info->stride[n]))
3169 loop->from[n] = info->start[n];
3170 mpz_set (i, cshape[n]);
3171 mpz_sub_ui (i, i, 1);
3172 /* To = from + (size - 1) * stride. */
3173 tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
3174 if (!integer_onep (info->stride[n]))
3175 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3176 tmp, info->stride[n]);
3177 loop->to[n] = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3178 loop->from[n], tmp);
3180 else
3182 loop->from[n] = info->start[n];
3183 switch (loopspec[n]->type)
3185 case GFC_SS_CONSTRUCTOR:
3186 /* The upper bound is calculated when we expand the
3187 constructor. */
3188 gcc_assert (loop->to[n] == NULL_TREE);
3189 break;
3191 case GFC_SS_SECTION:
3192 loop->to[n] = gfc_conv_section_upper_bound (loopspec[n], n,
3193 &loop->pre);
3194 break;
3196 case GFC_SS_FUNCTION:
3197 /* The loop bound will be set when we generate the call. */
3198 gcc_assert (loop->to[n] == NULL_TREE);
3199 break;
3201 default:
3202 gcc_unreachable ();
3206 /* Transform everything so we have a simple incrementing variable. */
3207 if (integer_onep (info->stride[n]))
3208 info->delta[n] = gfc_index_zero_node;
3209 else
3211 /* Set the delta for this section. */
3212 info->delta[n] = gfc_evaluate_now (loop->from[n], &loop->pre);
3213 /* Number of iterations is (end - start + step) / step.
3214 with start = 0, this simplifies to
3215 last = end / step;
3216 for (i = 0; i<=last; i++){...}; */
3217 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3218 loop->to[n], loop->from[n]);
3219 tmp = fold_build2 (TRUNC_DIV_EXPR, gfc_array_index_type,
3220 tmp, info->stride[n]);
3221 loop->to[n] = gfc_evaluate_now (tmp, &loop->pre);
3222 /* Make the loop variable start at 0. */
3223 loop->from[n] = gfc_index_zero_node;
3227 /* Add all the scalar code that can be taken out of the loops.
3228 This may include calculating the loop bounds, so do it before
3229 allocating the temporary. */
3230 gfc_add_loop_ss_code (loop, loop->ss, false);
3232 /* If we want a temporary then create it. */
3233 if (loop->temp_ss != NULL)
3235 gcc_assert (loop->temp_ss->type == GFC_SS_TEMP);
3236 tmp = loop->temp_ss->data.temp.type;
3237 len = loop->temp_ss->string_length;
3238 n = loop->temp_ss->data.temp.dimen;
3239 memset (&loop->temp_ss->data.info, 0, sizeof (gfc_ss_info));
3240 loop->temp_ss->type = GFC_SS_SECTION;
3241 loop->temp_ss->data.info.dimen = n;
3242 gfc_trans_create_temp_array (&loop->pre, &loop->post, loop,
3243 &loop->temp_ss->data.info, tmp, false, true,
3244 false, false);
3247 for (n = 0; n < loop->temp_dim; n++)
3248 loopspec[loop->order[n]] = NULL;
3250 mpz_clear (i);
3252 /* For array parameters we don't have loop variables, so don't calculate the
3253 translations. */
3254 if (loop->array_parameter)
3255 return;
3257 /* Calculate the translation from loop variables to array indices. */
3258 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3260 if (ss->type != GFC_SS_SECTION && ss->type != GFC_SS_COMPONENT)
3261 continue;
3263 info = &ss->data.info;
3265 for (n = 0; n < info->dimen; n++)
3267 dim = info->dim[n];
3269 /* If we are specifying the range the delta is already set. */
3270 if (loopspec[n] != ss)
3272 /* Calculate the offset relative to the loop variable.
3273 First multiply by the stride. */
3274 tmp = loop->from[n];
3275 if (!integer_onep (info->stride[n]))
3276 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3277 tmp, info->stride[n]);
3279 /* Then subtract this from our starting value. */
3280 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3281 info->start[n], tmp);
3283 info->delta[n] = gfc_evaluate_now (tmp, &loop->pre);
3290 /* Fills in an array descriptor, and returns the size of the array. The size
3291 will be a simple_val, ie a variable or a constant. Also calculates the
3292 offset of the base. Returns the size of the array.
3294 stride = 1;
3295 offset = 0;
3296 for (n = 0; n < rank; n++)
3298 a.lbound[n] = specified_lower_bound;
3299 offset = offset + a.lbond[n] * stride;
3300 size = 1 - lbound;
3301 a.ubound[n] = specified_upper_bound;
3302 a.stride[n] = stride;
3303 size = ubound + size; //size = ubound + 1 - lbound
3304 stride = stride * size;
3306 return (stride);
3307 } */
3308 /*GCC ARRAYS*/
3310 static tree
3311 gfc_array_init_size (tree descriptor, int rank, tree * poffset,
3312 gfc_expr ** lower, gfc_expr ** upper,
3313 stmtblock_t * pblock)
3315 tree type;
3316 tree tmp;
3317 tree size;
3318 tree offset;
3319 tree stride;
3320 tree cond;
3321 tree or_expr;
3322 tree thencase;
3323 tree elsecase;
3324 tree var;
3325 stmtblock_t thenblock;
3326 stmtblock_t elseblock;
3327 gfc_expr *ubound;
3328 gfc_se se;
3329 int n;
3331 type = TREE_TYPE (descriptor);
3333 stride = gfc_index_one_node;
3334 offset = gfc_index_zero_node;
3336 /* Set the dtype. */
3337 tmp = gfc_conv_descriptor_dtype (descriptor);
3338 gfc_add_modify_expr (pblock, tmp, gfc_get_dtype (TREE_TYPE (descriptor)));
3340 or_expr = NULL_TREE;
3342 for (n = 0; n < rank; n++)
3344 /* We have 3 possibilities for determining the size of the array:
3345 lower == NULL => lbound = 1, ubound = upper[n]
3346 upper[n] = NULL => lbound = 1, ubound = lower[n]
3347 upper[n] != NULL => lbound = lower[n], ubound = upper[n] */
3348 ubound = upper[n];
3350 /* Set lower bound. */
3351 gfc_init_se (&se, NULL);
3352 if (lower == NULL)
3353 se.expr = gfc_index_one_node;
3354 else
3356 gcc_assert (lower[n]);
3357 if (ubound)
3359 gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
3360 gfc_add_block_to_block (pblock, &se.pre);
3362 else
3364 se.expr = gfc_index_one_node;
3365 ubound = lower[n];
3368 tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[n]);
3369 gfc_add_modify_expr (pblock, tmp, se.expr);
3371 /* Work out the offset for this component. */
3372 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, se.expr, stride);
3373 offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3375 /* Start the calculation for the size of this dimension. */
3376 size = build2 (MINUS_EXPR, gfc_array_index_type,
3377 gfc_index_one_node, se.expr);
3379 /* Set upper bound. */
3380 gfc_init_se (&se, NULL);
3381 gcc_assert (ubound);
3382 gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
3383 gfc_add_block_to_block (pblock, &se.pre);
3385 tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[n]);
3386 gfc_add_modify_expr (pblock, tmp, se.expr);
3388 /* Store the stride. */
3389 tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[n]);
3390 gfc_add_modify_expr (pblock, tmp, stride);
3392 /* Calculate the size of this dimension. */
3393 size = fold_build2 (PLUS_EXPR, gfc_array_index_type, se.expr, size);
3395 /* Check whether the size for this dimension is negative. */
3396 cond = fold_build2 (LE_EXPR, boolean_type_node, size,
3397 gfc_index_zero_node);
3398 if (n == 0)
3399 or_expr = cond;
3400 else
3401 or_expr = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, or_expr, cond);
3403 /* Multiply the stride by the number of elements in this dimension. */
3404 stride = fold_build2 (MULT_EXPR, gfc_array_index_type, stride, size);
3405 stride = gfc_evaluate_now (stride, pblock);
3408 /* The stride is the number of elements in the array, so multiply by the
3409 size of an element to get the total size. */
3410 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
3411 size = fold_build2 (MULT_EXPR, gfc_array_index_type, stride, tmp);
3413 if (poffset != NULL)
3415 offset = gfc_evaluate_now (offset, pblock);
3416 *poffset = offset;
3419 if (integer_zerop (or_expr))
3420 return size;
3421 if (integer_onep (or_expr))
3422 return gfc_index_zero_node;
3424 var = gfc_create_var (TREE_TYPE (size), "size");
3425 gfc_start_block (&thenblock);
3426 gfc_add_modify_expr (&thenblock, var, gfc_index_zero_node);
3427 thencase = gfc_finish_block (&thenblock);
3429 gfc_start_block (&elseblock);
3430 gfc_add_modify_expr (&elseblock, var, size);
3431 elsecase = gfc_finish_block (&elseblock);
3433 tmp = gfc_evaluate_now (or_expr, pblock);
3434 tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
3435 gfc_add_expr_to_block (pblock, tmp);
3437 return var;
3441 /* Initializes the descriptor and generates a call to _gfor_allocate. Does
3442 the work for an ALLOCATE statement. */
3443 /*GCC ARRAYS*/
3445 bool
3446 gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree pstat)
3448 tree tmp;
3449 tree pointer;
3450 tree allocate;
3451 tree offset;
3452 tree size;
3453 gfc_expr **lower;
3454 gfc_expr **upper;
3455 gfc_ref *ref, *prev_ref = NULL;
3456 bool allocatable_array;
3458 ref = expr->ref;
3460 /* Find the last reference in the chain. */
3461 while (ref && ref->next != NULL)
3463 gcc_assert (ref->type != REF_ARRAY || ref->u.ar.type == AR_ELEMENT);
3464 prev_ref = ref;
3465 ref = ref->next;
3468 if (ref == NULL || ref->type != REF_ARRAY)
3469 return false;
3471 if (!prev_ref)
3472 allocatable_array = expr->symtree->n.sym->attr.allocatable;
3473 else
3474 allocatable_array = prev_ref->u.c.component->allocatable;
3476 /* Figure out the size of the array. */
3477 switch (ref->u.ar.type)
3479 case AR_ELEMENT:
3480 lower = NULL;
3481 upper = ref->u.ar.start;
3482 break;
3484 case AR_FULL:
3485 gcc_assert (ref->u.ar.as->type == AS_EXPLICIT);
3487 lower = ref->u.ar.as->lower;
3488 upper = ref->u.ar.as->upper;
3489 break;
3491 case AR_SECTION:
3492 lower = ref->u.ar.start;
3493 upper = ref->u.ar.end;
3494 break;
3496 default:
3497 gcc_unreachable ();
3498 break;
3501 size = gfc_array_init_size (se->expr, ref->u.ar.as->rank, &offset,
3502 lower, upper, &se->pre);
3504 /* Allocate memory to store the data. */
3505 pointer = gfc_conv_descriptor_data_get (se->expr);
3506 STRIP_NOPS (pointer);
3508 if (TYPE_PRECISION (gfc_array_index_type) == 32)
3510 if (allocatable_array)
3511 allocate = gfor_fndecl_allocate_array;
3512 else
3513 allocate = gfor_fndecl_allocate;
3515 else if (TYPE_PRECISION (gfc_array_index_type) == 64)
3517 if (allocatable_array)
3518 allocate = gfor_fndecl_allocate64_array;
3519 else
3520 allocate = gfor_fndecl_allocate64;
3522 else
3523 gcc_unreachable ();
3525 tmp = NULL_TREE;
3526 /* The allocate_array variants take the old pointer as first argument. */
3527 if (allocatable_array)
3528 tmp = gfc_chainon_list (tmp, pointer);
3529 tmp = gfc_chainon_list (tmp, size);
3530 tmp = gfc_chainon_list (tmp, pstat);
3531 tmp = build_function_call_expr (allocate, tmp);
3532 tmp = build2 (MODIFY_EXPR, void_type_node, pointer, tmp);
3533 gfc_add_expr_to_block (&se->pre, tmp);
3535 tmp = gfc_conv_descriptor_offset (se->expr);
3536 gfc_add_modify_expr (&se->pre, tmp, offset);
3538 if (expr->ts.type == BT_DERIVED
3539 && expr->ts.derived->attr.alloc_comp)
3541 tmp = gfc_nullify_alloc_comp (expr->ts.derived, se->expr,
3542 ref->u.ar.as->rank);
3543 gfc_add_expr_to_block (&se->pre, tmp);
3546 return true;
3550 /* Deallocate an array variable. Also used when an allocated variable goes
3551 out of scope. */
3552 /*GCC ARRAYS*/
3554 tree
3555 gfc_array_deallocate (tree descriptor, tree pstat)
3557 tree var;
3558 tree tmp;
3559 stmtblock_t block;
3561 gfc_start_block (&block);
3562 /* Get a pointer to the data. */
3563 var = gfc_conv_descriptor_data_get (descriptor);
3564 STRIP_NOPS (var);
3566 /* Parameter is the address of the data component. */
3567 tmp = gfc_chainon_list (NULL_TREE, var);
3568 tmp = gfc_chainon_list (tmp, pstat);
3569 tmp = build_function_call_expr (gfor_fndecl_deallocate, tmp);
3570 gfc_add_expr_to_block (&block, tmp);
3572 /* Zero the data pointer. */
3573 tmp = build2 (MODIFY_EXPR, void_type_node,
3574 var, build_int_cst (TREE_TYPE (var), 0));
3575 gfc_add_expr_to_block (&block, tmp);
3577 return gfc_finish_block (&block);
3581 /* Create an array constructor from an initialization expression.
3582 We assume the frontend already did any expansions and conversions. */
3584 tree
3585 gfc_conv_array_initializer (tree type, gfc_expr * expr)
3587 gfc_constructor *c;
3588 tree tmp;
3589 mpz_t maxval;
3590 gfc_se se;
3591 HOST_WIDE_INT hi;
3592 unsigned HOST_WIDE_INT lo;
3593 tree index, range;
3594 VEC(constructor_elt,gc) *v = NULL;
3596 switch (expr->expr_type)
3598 case EXPR_CONSTANT:
3599 case EXPR_STRUCTURE:
3600 /* A single scalar or derived type value. Create an array with all
3601 elements equal to that value. */
3602 gfc_init_se (&se, NULL);
3604 if (expr->expr_type == EXPR_CONSTANT)
3605 gfc_conv_constant (&se, expr);
3606 else
3607 gfc_conv_structure (&se, expr, 1);
3609 tmp = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3610 gcc_assert (tmp && INTEGER_CST_P (tmp));
3611 hi = TREE_INT_CST_HIGH (tmp);
3612 lo = TREE_INT_CST_LOW (tmp);
3613 lo++;
3614 if (lo == 0)
3615 hi++;
3616 /* This will probably eat buckets of memory for large arrays. */
3617 while (hi != 0 || lo != 0)
3619 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, se.expr);
3620 if (lo == 0)
3621 hi--;
3622 lo--;
3624 break;
3626 case EXPR_ARRAY:
3627 /* Create a vector of all the elements. */
3628 for (c = expr->value.constructor; c; c = c->next)
3630 if (c->iterator)
3632 /* Problems occur when we get something like
3633 integer :: a(lots) = (/(i, i=1,lots)/) */
3634 /* TODO: Unexpanded array initializers. */
3635 internal_error
3636 ("Possible frontend bug: array constructor not expanded");
3638 if (mpz_cmp_si (c->n.offset, 0) != 0)
3639 index = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
3640 else
3641 index = NULL_TREE;
3642 mpz_init (maxval);
3643 if (mpz_cmp_si (c->repeat, 0) != 0)
3645 tree tmp1, tmp2;
3647 mpz_set (maxval, c->repeat);
3648 mpz_add (maxval, c->n.offset, maxval);
3649 mpz_sub_ui (maxval, maxval, 1);
3650 tmp2 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
3651 if (mpz_cmp_si (c->n.offset, 0) != 0)
3653 mpz_add_ui (maxval, c->n.offset, 1);
3654 tmp1 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
3656 else
3657 tmp1 = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
3659 range = build2 (RANGE_EXPR, integer_type_node, tmp1, tmp2);
3661 else
3662 range = NULL;
3663 mpz_clear (maxval);
3665 gfc_init_se (&se, NULL);
3666 switch (c->expr->expr_type)
3668 case EXPR_CONSTANT:
3669 gfc_conv_constant (&se, c->expr);
3670 if (range == NULL_TREE)
3671 CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3672 else
3674 if (index != NULL_TREE)
3675 CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3676 CONSTRUCTOR_APPEND_ELT (v, range, se.expr);
3678 break;
3680 case EXPR_STRUCTURE:
3681 gfc_conv_structure (&se, c->expr, 1);
3682 CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3683 break;
3685 default:
3686 gcc_unreachable ();
3689 break;
3691 case EXPR_NULL:
3692 return gfc_build_null_descriptor (type);
3694 default:
3695 gcc_unreachable ();
3698 /* Create a constructor from the list of elements. */
3699 tmp = build_constructor (type, v);
3700 TREE_CONSTANT (tmp) = 1;
3701 TREE_INVARIANT (tmp) = 1;
3702 return tmp;
3706 /* Generate code to evaluate non-constant array bounds. Sets *poffset and
3707 returns the size (in elements) of the array. */
3709 static tree
3710 gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
3711 stmtblock_t * pblock)
3713 gfc_array_spec *as;
3714 tree size;
3715 tree stride;
3716 tree offset;
3717 tree ubound;
3718 tree lbound;
3719 tree tmp;
3720 gfc_se se;
3722 int dim;
3724 as = sym->as;
3726 size = gfc_index_one_node;
3727 offset = gfc_index_zero_node;
3728 for (dim = 0; dim < as->rank; dim++)
3730 /* Evaluate non-constant array bound expressions. */
3731 lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
3732 if (as->lower[dim] && !INTEGER_CST_P (lbound))
3734 gfc_init_se (&se, NULL);
3735 gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
3736 gfc_add_block_to_block (pblock, &se.pre);
3737 gfc_add_modify_expr (pblock, lbound, se.expr);
3739 ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
3740 if (as->upper[dim] && !INTEGER_CST_P (ubound))
3742 gfc_init_se (&se, NULL);
3743 gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
3744 gfc_add_block_to_block (pblock, &se.pre);
3745 gfc_add_modify_expr (pblock, ubound, se.expr);
3747 /* The offset of this dimension. offset = offset - lbound * stride. */
3748 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, size);
3749 offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3751 /* The size of this dimension, and the stride of the next. */
3752 if (dim + 1 < as->rank)
3753 stride = GFC_TYPE_ARRAY_STRIDE (type, dim + 1);
3754 else
3755 stride = GFC_TYPE_ARRAY_SIZE (type);
3757 if (ubound != NULL_TREE && !(stride && INTEGER_CST_P (stride)))
3759 /* Calculate stride = size * (ubound + 1 - lbound). */
3760 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3761 gfc_index_one_node, lbound);
3762 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, ubound, tmp);
3763 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
3764 if (stride)
3765 gfc_add_modify_expr (pblock, stride, tmp);
3766 else
3767 stride = gfc_evaluate_now (tmp, pblock);
3769 /* Make sure that negative size arrays are translated
3770 to being zero size. */
3771 tmp = build2 (GE_EXPR, boolean_type_node,
3772 stride, gfc_index_zero_node);
3773 tmp = build3 (COND_EXPR, gfc_array_index_type, tmp,
3774 stride, gfc_index_zero_node);
3775 gfc_add_modify_expr (pblock, stride, tmp);
3778 size = stride;
3781 gfc_trans_vla_type_sizes (sym, pblock);
3783 *poffset = offset;
3784 return size;
3788 /* Generate code to initialize/allocate an array variable. */
3790 tree
3791 gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, tree fnbody)
3793 stmtblock_t block;
3794 tree type;
3795 tree tmp;
3796 tree fndecl;
3797 tree size;
3798 tree offset;
3799 bool onstack;
3801 gcc_assert (!(sym->attr.pointer || sym->attr.allocatable));
3803 /* Do nothing for USEd variables. */
3804 if (sym->attr.use_assoc)
3805 return fnbody;
3807 type = TREE_TYPE (decl);
3808 gcc_assert (GFC_ARRAY_TYPE_P (type));
3809 onstack = TREE_CODE (type) != POINTER_TYPE;
3811 gfc_start_block (&block);
3813 /* Evaluate character string length. */
3814 if (sym->ts.type == BT_CHARACTER
3815 && onstack && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3817 gfc_trans_init_string_length (sym->ts.cl, &block);
3819 gfc_trans_vla_type_sizes (sym, &block);
3821 /* Emit a DECL_EXPR for this variable, which will cause the
3822 gimplifier to allocate storage, and all that good stuff. */
3823 tmp = build1 (DECL_EXPR, TREE_TYPE (decl), decl);
3824 gfc_add_expr_to_block (&block, tmp);
3827 if (onstack)
3829 gfc_add_expr_to_block (&block, fnbody);
3830 return gfc_finish_block (&block);
3833 type = TREE_TYPE (type);
3835 gcc_assert (!sym->attr.use_assoc);
3836 gcc_assert (!TREE_STATIC (decl));
3837 gcc_assert (!sym->module);
3839 if (sym->ts.type == BT_CHARACTER
3840 && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3841 gfc_trans_init_string_length (sym->ts.cl, &block);
3843 size = gfc_trans_array_bounds (type, sym, &offset, &block);
3845 /* Don't actually allocate space for Cray Pointees. */
3846 if (sym->attr.cray_pointee)
3848 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3849 gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3850 gfc_add_expr_to_block (&block, fnbody);
3851 return gfc_finish_block (&block);
3854 /* The size is the number of elements in the array, so multiply by the
3855 size of an element to get the total size. */
3856 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
3857 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
3859 /* Allocate memory to hold the data. */
3860 tmp = gfc_chainon_list (NULL_TREE, size);
3862 if (gfc_index_integer_kind == 4)
3863 fndecl = gfor_fndecl_internal_malloc;
3864 else if (gfc_index_integer_kind == 8)
3865 fndecl = gfor_fndecl_internal_malloc64;
3866 else
3867 gcc_unreachable ();
3868 tmp = build_function_call_expr (fndecl, tmp);
3869 tmp = fold (convert (TREE_TYPE (decl), tmp));
3870 gfc_add_modify_expr (&block, decl, tmp);
3872 /* Set offset of the array. */
3873 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3874 gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3877 /* Automatic arrays should not have initializers. */
3878 gcc_assert (!sym->value);
3880 gfc_add_expr_to_block (&block, fnbody);
3882 /* Free the temporary. */
3883 tmp = convert (pvoid_type_node, decl);
3884 tmp = gfc_chainon_list (NULL_TREE, tmp);
3885 tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
3886 gfc_add_expr_to_block (&block, tmp);
3888 return gfc_finish_block (&block);
3892 /* Generate entry and exit code for g77 calling convention arrays. */
3894 tree
3895 gfc_trans_g77_array (gfc_symbol * sym, tree body)
3897 tree parm;
3898 tree type;
3899 locus loc;
3900 tree offset;
3901 tree tmp;
3902 tree stmt;
3903 stmtblock_t block;
3905 gfc_get_backend_locus (&loc);
3906 gfc_set_backend_locus (&sym->declared_at);
3908 /* Descriptor type. */
3909 parm = sym->backend_decl;
3910 type = TREE_TYPE (parm);
3911 gcc_assert (GFC_ARRAY_TYPE_P (type));
3913 gfc_start_block (&block);
3915 if (sym->ts.type == BT_CHARACTER
3916 && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
3917 gfc_trans_init_string_length (sym->ts.cl, &block);
3919 /* Evaluate the bounds of the array. */
3920 gfc_trans_array_bounds (type, sym, &offset, &block);
3922 /* Set the offset. */
3923 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3924 gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3926 /* Set the pointer itself if we aren't using the parameter directly. */
3927 if (TREE_CODE (parm) != PARM_DECL)
3929 tmp = convert (TREE_TYPE (parm), GFC_DECL_SAVED_DESCRIPTOR (parm));
3930 gfc_add_modify_expr (&block, parm, tmp);
3932 stmt = gfc_finish_block (&block);
3934 gfc_set_backend_locus (&loc);
3936 gfc_start_block (&block);
3938 /* Add the initialization code to the start of the function. */
3940 if (sym->attr.optional || sym->attr.not_always_present)
3942 tmp = gfc_conv_expr_present (sym);
3943 stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3946 gfc_add_expr_to_block (&block, stmt);
3947 gfc_add_expr_to_block (&block, body);
3949 return gfc_finish_block (&block);
3953 /* Modify the descriptor of an array parameter so that it has the
3954 correct lower bound. Also move the upper bound accordingly.
3955 If the array is not packed, it will be copied into a temporary.
3956 For each dimension we set the new lower and upper bounds. Then we copy the
3957 stride and calculate the offset for this dimension. We also work out
3958 what the stride of a packed array would be, and see it the two match.
3959 If the array need repacking, we set the stride to the values we just
3960 calculated, recalculate the offset and copy the array data.
3961 Code is also added to copy the data back at the end of the function.
3964 tree
3965 gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
3967 tree size;
3968 tree type;
3969 tree offset;
3970 locus loc;
3971 stmtblock_t block;
3972 stmtblock_t cleanup;
3973 tree lbound;
3974 tree ubound;
3975 tree dubound;
3976 tree dlbound;
3977 tree dumdesc;
3978 tree tmp;
3979 tree stmt;
3980 tree stride, stride2;
3981 tree stmt_packed;
3982 tree stmt_unpacked;
3983 tree partial;
3984 gfc_se se;
3985 int n;
3986 int checkparm;
3987 int no_repack;
3988 bool optional_arg;
3990 /* Do nothing for pointer and allocatable arrays. */
3991 if (sym->attr.pointer || sym->attr.allocatable)
3992 return body;
3994 if (sym->attr.dummy && gfc_is_nodesc_array (sym))
3995 return gfc_trans_g77_array (sym, body);
3997 gfc_get_backend_locus (&loc);
3998 gfc_set_backend_locus (&sym->declared_at);
4000 /* Descriptor type. */
4001 type = TREE_TYPE (tmpdesc);
4002 gcc_assert (GFC_ARRAY_TYPE_P (type));
4003 dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
4004 dumdesc = build_fold_indirect_ref (dumdesc);
4005 gfc_start_block (&block);
4007 if (sym->ts.type == BT_CHARACTER
4008 && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
4009 gfc_trans_init_string_length (sym->ts.cl, &block);
4011 checkparm = (sym->as->type == AS_EXPLICIT && flag_bounds_check);
4013 no_repack = !(GFC_DECL_PACKED_ARRAY (tmpdesc)
4014 || GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc));
4016 if (GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc))
4018 /* For non-constant shape arrays we only check if the first dimension
4019 is contiguous. Repacking higher dimensions wouldn't gain us
4020 anything as we still don't know the array stride. */
4021 partial = gfc_create_var (boolean_type_node, "partial");
4022 TREE_USED (partial) = 1;
4023 tmp = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
4024 tmp = fold_build2 (EQ_EXPR, boolean_type_node, tmp, gfc_index_one_node);
4025 gfc_add_modify_expr (&block, partial, tmp);
4027 else
4029 partial = NULL_TREE;
4032 /* The naming of stmt_unpacked and stmt_packed may be counter-intuitive
4033 here, however I think it does the right thing. */
4034 if (no_repack)
4036 /* Set the first stride. */
4037 stride = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
4038 stride = gfc_evaluate_now (stride, &block);
4040 tmp = build2 (EQ_EXPR, boolean_type_node, stride, gfc_index_zero_node);
4041 tmp = build3 (COND_EXPR, gfc_array_index_type, tmp,
4042 gfc_index_one_node, stride);
4043 stride = GFC_TYPE_ARRAY_STRIDE (type, 0);
4044 gfc_add_modify_expr (&block, stride, tmp);
4046 /* Allow the user to disable array repacking. */
4047 stmt_unpacked = NULL_TREE;
4049 else
4051 gcc_assert (integer_onep (GFC_TYPE_ARRAY_STRIDE (type, 0)));
4052 /* A library call to repack the array if necessary. */
4053 tmp = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
4054 tmp = gfc_chainon_list (NULL_TREE, tmp);
4055 stmt_unpacked = build_function_call_expr (gfor_fndecl_in_pack, tmp);
4057 stride = gfc_index_one_node;
4060 /* This is for the case where the array data is used directly without
4061 calling the repack function. */
4062 if (no_repack || partial != NULL_TREE)
4063 stmt_packed = gfc_conv_descriptor_data_get (dumdesc);
4064 else
4065 stmt_packed = NULL_TREE;
4067 /* Assign the data pointer. */
4068 if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
4070 /* Don't repack unknown shape arrays when the first stride is 1. */
4071 tmp = build3 (COND_EXPR, TREE_TYPE (stmt_packed), partial,
4072 stmt_packed, stmt_unpacked);
4074 else
4075 tmp = stmt_packed != NULL_TREE ? stmt_packed : stmt_unpacked;
4076 gfc_add_modify_expr (&block, tmpdesc, fold_convert (type, tmp));
4078 offset = gfc_index_zero_node;
4079 size = gfc_index_one_node;
4081 /* Evaluate the bounds of the array. */
4082 for (n = 0; n < sym->as->rank; n++)
4084 if (checkparm || !sym->as->upper[n])
4086 /* Get the bounds of the actual parameter. */
4087 dubound = gfc_conv_descriptor_ubound (dumdesc, gfc_rank_cst[n]);
4088 dlbound = gfc_conv_descriptor_lbound (dumdesc, gfc_rank_cst[n]);
4090 else
4092 dubound = NULL_TREE;
4093 dlbound = NULL_TREE;
4096 lbound = GFC_TYPE_ARRAY_LBOUND (type, n);
4097 if (!INTEGER_CST_P (lbound))
4099 gfc_init_se (&se, NULL);
4100 gfc_conv_expr_type (&se, sym->as->lower[n],
4101 gfc_array_index_type);
4102 gfc_add_block_to_block (&block, &se.pre);
4103 gfc_add_modify_expr (&block, lbound, se.expr);
4106 ubound = GFC_TYPE_ARRAY_UBOUND (type, n);
4107 /* Set the desired upper bound. */
4108 if (sym->as->upper[n])
4110 /* We know what we want the upper bound to be. */
4111 if (!INTEGER_CST_P (ubound))
4113 gfc_init_se (&se, NULL);
4114 gfc_conv_expr_type (&se, sym->as->upper[n],
4115 gfc_array_index_type);
4116 gfc_add_block_to_block (&block, &se.pre);
4117 gfc_add_modify_expr (&block, ubound, se.expr);
4120 /* Check the sizes match. */
4121 if (checkparm)
4123 /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)). */
4124 char * msg;
4126 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4127 ubound, lbound);
4128 stride2 = build2 (MINUS_EXPR, gfc_array_index_type,
4129 dubound, dlbound);
4130 tmp = fold_build2 (NE_EXPR, gfc_array_index_type, tmp, stride2);
4131 asprintf (&msg, "%s for dimension %d of array '%s'",
4132 gfc_msg_bounds, n+1, sym->name);
4133 gfc_trans_runtime_check (tmp, msg, &block, &loc);
4134 gfc_free (msg);
4137 else
4139 /* For assumed shape arrays move the upper bound by the same amount
4140 as the lower bound. */
4141 tmp = build2 (MINUS_EXPR, gfc_array_index_type, dubound, dlbound);
4142 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp, lbound);
4143 gfc_add_modify_expr (&block, ubound, tmp);
4145 /* The offset of this dimension. offset = offset - lbound * stride. */
4146 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, stride);
4147 offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
4149 /* The size of this dimension, and the stride of the next. */
4150 if (n + 1 < sym->as->rank)
4152 stride = GFC_TYPE_ARRAY_STRIDE (type, n + 1);
4154 if (no_repack || partial != NULL_TREE)
4156 stmt_unpacked =
4157 gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[n+1]);
4160 /* Figure out the stride if not a known constant. */
4161 if (!INTEGER_CST_P (stride))
4163 if (no_repack)
4164 stmt_packed = NULL_TREE;
4165 else
4167 /* Calculate stride = size * (ubound + 1 - lbound). */
4168 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4169 gfc_index_one_node, lbound);
4170 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4171 ubound, tmp);
4172 size = fold_build2 (MULT_EXPR, gfc_array_index_type,
4173 size, tmp);
4174 stmt_packed = size;
4177 /* Assign the stride. */
4178 if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
4179 tmp = build3 (COND_EXPR, gfc_array_index_type, partial,
4180 stmt_unpacked, stmt_packed);
4181 else
4182 tmp = (stmt_packed != NULL_TREE) ? stmt_packed : stmt_unpacked;
4183 gfc_add_modify_expr (&block, stride, tmp);
4186 else
4188 stride = GFC_TYPE_ARRAY_SIZE (type);
4190 if (stride && !INTEGER_CST_P (stride))
4192 /* Calculate size = stride * (ubound + 1 - lbound). */
4193 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4194 gfc_index_one_node, lbound);
4195 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4196 ubound, tmp);
4197 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
4198 GFC_TYPE_ARRAY_STRIDE (type, n), tmp);
4199 gfc_add_modify_expr (&block, stride, tmp);
4204 /* Set the offset. */
4205 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
4206 gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
4208 gfc_trans_vla_type_sizes (sym, &block);
4210 stmt = gfc_finish_block (&block);
4212 gfc_start_block (&block);
4214 /* Only do the entry/initialization code if the arg is present. */
4215 dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
4216 optional_arg = (sym->attr.optional
4217 || (sym->ns->proc_name->attr.entry_master
4218 && sym->attr.dummy));
4219 if (optional_arg)
4221 tmp = gfc_conv_expr_present (sym);
4222 stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4224 gfc_add_expr_to_block (&block, stmt);
4226 /* Add the main function body. */
4227 gfc_add_expr_to_block (&block, body);
4229 /* Cleanup code. */
4230 if (!no_repack)
4232 gfc_start_block (&cleanup);
4234 if (sym->attr.intent != INTENT_IN)
4236 /* Copy the data back. */
4237 tmp = gfc_chainon_list (NULL_TREE, dumdesc);
4238 tmp = gfc_chainon_list (tmp, tmpdesc);
4239 tmp = build_function_call_expr (gfor_fndecl_in_unpack, tmp);
4240 gfc_add_expr_to_block (&cleanup, tmp);
4243 /* Free the temporary. */
4244 tmp = gfc_chainon_list (NULL_TREE, tmpdesc);
4245 tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
4246 gfc_add_expr_to_block (&cleanup, tmp);
4248 stmt = gfc_finish_block (&cleanup);
4250 /* Only do the cleanup if the array was repacked. */
4251 tmp = build_fold_indirect_ref (dumdesc);
4252 tmp = gfc_conv_descriptor_data_get (tmp);
4253 tmp = build2 (NE_EXPR, boolean_type_node, tmp, tmpdesc);
4254 stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4256 if (optional_arg)
4258 tmp = gfc_conv_expr_present (sym);
4259 stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4261 gfc_add_expr_to_block (&block, stmt);
4263 /* We don't need to free any memory allocated by internal_pack as it will
4264 be freed at the end of the function by pop_context. */
4265 return gfc_finish_block (&block);
4269 /* Convert an array for passing as an actual argument. Expressions and
4270 vector subscripts are evaluated and stored in a temporary, which is then
4271 passed. For whole arrays the descriptor is passed. For array sections
4272 a modified copy of the descriptor is passed, but using the original data.
4274 This function is also used for array pointer assignments, and there
4275 are three cases:
4277 - want_pointer && !se->direct_byref
4278 EXPR is an actual argument. On exit, se->expr contains a
4279 pointer to the array descriptor.
4281 - !want_pointer && !se->direct_byref
4282 EXPR is an actual argument to an intrinsic function or the
4283 left-hand side of a pointer assignment. On exit, se->expr
4284 contains the descriptor for EXPR.
4286 - !want_pointer && se->direct_byref
4287 EXPR is the right-hand side of a pointer assignment and
4288 se->expr is the descriptor for the previously-evaluated
4289 left-hand side. The function creates an assignment from
4290 EXPR to se->expr. */
4292 void
4293 gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
4295 gfc_loopinfo loop;
4296 gfc_ss *secss;
4297 gfc_ss_info *info;
4298 int need_tmp;
4299 int n;
4300 tree tmp;
4301 tree desc;
4302 stmtblock_t block;
4303 tree start;
4304 tree offset;
4305 int full;
4307 gcc_assert (ss != gfc_ss_terminator);
4309 /* Special case things we know we can pass easily. */
4310 switch (expr->expr_type)
4312 case EXPR_VARIABLE:
4313 /* If we have a linear array section, we can pass it directly.
4314 Otherwise we need to copy it into a temporary. */
4316 /* Find the SS for the array section. */
4317 secss = ss;
4318 while (secss != gfc_ss_terminator && secss->type != GFC_SS_SECTION)
4319 secss = secss->next;
4321 gcc_assert (secss != gfc_ss_terminator);
4322 info = &secss->data.info;
4324 /* Get the descriptor for the array. */
4325 gfc_conv_ss_descriptor (&se->pre, secss, 0);
4326 desc = info->descriptor;
4328 need_tmp = gfc_ref_needs_temporary_p (expr->ref);
4329 if (need_tmp)
4330 full = 0;
4331 else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
4333 /* Create a new descriptor if the array doesn't have one. */
4334 full = 0;
4336 else if (info->ref->u.ar.type == AR_FULL)
4337 full = 1;
4338 else if (se->direct_byref)
4339 full = 0;
4340 else
4341 full = gfc_full_array_ref_p (info->ref);
4343 if (full)
4345 if (se->direct_byref)
4347 /* Copy the descriptor for pointer assignments. */
4348 gfc_add_modify_expr (&se->pre, se->expr, desc);
4350 else if (se->want_pointer)
4352 /* We pass full arrays directly. This means that pointers and
4353 allocatable arrays should also work. */
4354 se->expr = build_fold_addr_expr (desc);
4356 else
4358 se->expr = desc;
4361 if (expr->ts.type == BT_CHARACTER)
4362 se->string_length = gfc_get_expr_charlen (expr);
4364 return;
4366 break;
4368 case EXPR_FUNCTION:
4369 /* A transformational function return value will be a temporary
4370 array descriptor. We still need to go through the scalarizer
4371 to create the descriptor. Elemental functions ar handled as
4372 arbitrary expressions, i.e. copy to a temporary. */
4373 secss = ss;
4374 /* Look for the SS for this function. */
4375 while (secss != gfc_ss_terminator
4376 && (secss->type != GFC_SS_FUNCTION || secss->expr != expr))
4377 secss = secss->next;
4379 if (se->direct_byref)
4381 gcc_assert (secss != gfc_ss_terminator);
4383 /* For pointer assignments pass the descriptor directly. */
4384 se->ss = secss;
4385 se->expr = build_fold_addr_expr (se->expr);
4386 gfc_conv_expr (se, expr);
4387 return;
4390 if (secss == gfc_ss_terminator)
4392 /* Elemental function. */
4393 need_tmp = 1;
4394 info = NULL;
4396 else
4398 /* Transformational function. */
4399 info = &secss->data.info;
4400 need_tmp = 0;
4402 break;
4404 case EXPR_ARRAY:
4405 /* Constant array constructors don't need a temporary. */
4406 if (ss->type == GFC_SS_CONSTRUCTOR
4407 && expr->ts.type != BT_CHARACTER
4408 && gfc_constant_array_constructor_p (expr->value.constructor))
4410 need_tmp = 0;
4411 info = &ss->data.info;
4412 secss = ss;
4414 else
4416 need_tmp = 1;
4417 secss = NULL;
4418 info = NULL;
4420 break;
4422 default:
4423 /* Something complicated. Copy it into a temporary. */
4424 need_tmp = 1;
4425 secss = NULL;
4426 info = NULL;
4427 break;
4431 gfc_init_loopinfo (&loop);
4433 /* Associate the SS with the loop. */
4434 gfc_add_ss_to_loop (&loop, ss);
4436 /* Tell the scalarizer not to bother creating loop variables, etc. */
4437 if (!need_tmp)
4438 loop.array_parameter = 1;
4439 else
4440 /* The right-hand side of a pointer assignment mustn't use a temporary. */
4441 gcc_assert (!se->direct_byref);
4443 /* Setup the scalarizing loops and bounds. */
4444 gfc_conv_ss_startstride (&loop);
4446 if (need_tmp)
4448 /* Tell the scalarizer to make a temporary. */
4449 loop.temp_ss = gfc_get_ss ();
4450 loop.temp_ss->type = GFC_SS_TEMP;
4451 loop.temp_ss->next = gfc_ss_terminator;
4452 if (expr->ts.type == BT_CHARACTER)
4454 if (expr->ts.cl == NULL)
4456 /* This had better be a substring reference! */
4457 gfc_ref *char_ref = expr->ref;
4458 for (; char_ref; char_ref = char_ref->next)
4459 if (char_ref->type == REF_SUBSTRING)
4461 mpz_t char_len;
4462 expr->ts.cl = gfc_get_charlen ();
4463 expr->ts.cl->next = char_ref->u.ss.length->next;
4464 char_ref->u.ss.length->next = expr->ts.cl;
4466 mpz_init_set_ui (char_len, 1);
4467 mpz_add (char_len, char_len,
4468 char_ref->u.ss.end->value.integer);
4469 mpz_sub (char_len, char_len,
4470 char_ref->u.ss.start->value.integer);
4471 expr->ts.cl->backend_decl
4472 = gfc_conv_mpz_to_tree (char_len,
4473 gfc_default_character_kind);
4474 /* Cast is necessary for *-charlen refs. */
4475 expr->ts.cl->backend_decl
4476 = convert (gfc_charlen_type_node,
4477 expr->ts.cl->backend_decl);
4478 mpz_clear (char_len);
4479 break;
4481 gcc_assert (char_ref != NULL);
4482 loop.temp_ss->data.temp.type
4483 = gfc_typenode_for_spec (&expr->ts);
4484 loop.temp_ss->string_length = expr->ts.cl->backend_decl;
4486 else if (expr->ts.cl->length
4487 && expr->ts.cl->length->expr_type == EXPR_CONSTANT)
4489 expr->ts.cl->backend_decl
4490 = gfc_conv_mpz_to_tree (expr->ts.cl->length->value.integer,
4491 expr->ts.cl->length->ts.kind);
4492 loop.temp_ss->data.temp.type
4493 = gfc_typenode_for_spec (&expr->ts);
4494 loop.temp_ss->string_length
4495 = TYPE_SIZE_UNIT (loop.temp_ss->data.temp.type);
4497 else
4499 loop.temp_ss->data.temp.type
4500 = gfc_typenode_for_spec (&expr->ts);
4501 loop.temp_ss->string_length = expr->ts.cl->backend_decl;
4503 se->string_length = loop.temp_ss->string_length;
4505 else
4507 loop.temp_ss->data.temp.type
4508 = gfc_typenode_for_spec (&expr->ts);
4509 loop.temp_ss->string_length = NULL;
4511 loop.temp_ss->data.temp.dimen = loop.dimen;
4512 gfc_add_ss_to_loop (&loop, loop.temp_ss);
4515 gfc_conv_loop_setup (&loop);
4517 if (need_tmp)
4519 /* Copy into a temporary and pass that. We don't need to copy the data
4520 back because expressions and vector subscripts must be INTENT_IN. */
4521 /* TODO: Optimize passing function return values. */
4522 gfc_se lse;
4523 gfc_se rse;
4525 /* Start the copying loops. */
4526 gfc_mark_ss_chain_used (loop.temp_ss, 1);
4527 gfc_mark_ss_chain_used (ss, 1);
4528 gfc_start_scalarized_body (&loop, &block);
4530 /* Copy each data element. */
4531 gfc_init_se (&lse, NULL);
4532 gfc_copy_loopinfo_to_se (&lse, &loop);
4533 gfc_init_se (&rse, NULL);
4534 gfc_copy_loopinfo_to_se (&rse, &loop);
4536 lse.ss = loop.temp_ss;
4537 rse.ss = ss;
4539 gfc_conv_scalarized_array_ref (&lse, NULL);
4540 if (expr->ts.type == BT_CHARACTER)
4542 gfc_conv_expr (&rse, expr);
4543 if (POINTER_TYPE_P (TREE_TYPE (rse.expr)))
4544 rse.expr = build_fold_indirect_ref (rse.expr);
4546 else
4547 gfc_conv_expr_val (&rse, expr);
4549 gfc_add_block_to_block (&block, &rse.pre);
4550 gfc_add_block_to_block (&block, &lse.pre);
4552 gfc_add_modify_expr (&block, lse.expr, rse.expr);
4554 /* Finish the copying loops. */
4555 gfc_trans_scalarizing_loops (&loop, &block);
4557 desc = loop.temp_ss->data.info.descriptor;
4559 gcc_assert (is_gimple_lvalue (desc));
4561 else if (expr->expr_type == EXPR_FUNCTION)
4563 desc = info->descriptor;
4564 se->string_length = ss->string_length;
4566 else
4568 /* We pass sections without copying to a temporary. Make a new
4569 descriptor and point it at the section we want. The loop variable
4570 limits will be the limits of the section.
4571 A function may decide to repack the array to speed up access, but
4572 we're not bothered about that here. */
4573 int dim, ndim;
4574 tree parm;
4575 tree parmtype;
4576 tree stride;
4577 tree from;
4578 tree to;
4579 tree base;
4581 /* Set the string_length for a character array. */
4582 if (expr->ts.type == BT_CHARACTER)
4583 se->string_length = gfc_get_expr_charlen (expr);
4585 desc = info->descriptor;
4586 gcc_assert (secss && secss != gfc_ss_terminator);
4587 if (se->direct_byref)
4589 /* For pointer assignments we fill in the destination. */
4590 parm = se->expr;
4591 parmtype = TREE_TYPE (parm);
4593 else
4595 /* Otherwise make a new one. */
4596 parmtype = gfc_get_element_type (TREE_TYPE (desc));
4597 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen,
4598 loop.from, loop.to, 0);
4599 parm = gfc_create_var (parmtype, "parm");
4602 offset = gfc_index_zero_node;
4603 dim = 0;
4605 /* The following can be somewhat confusing. We have two
4606 descriptors, a new one and the original array.
4607 {parm, parmtype, dim} refer to the new one.
4608 {desc, type, n, secss, loop} refer to the original, which maybe
4609 a descriptorless array.
4610 The bounds of the scalarization are the bounds of the section.
4611 We don't have to worry about numeric overflows when calculating
4612 the offsets because all elements are within the array data. */
4614 /* Set the dtype. */
4615 tmp = gfc_conv_descriptor_dtype (parm);
4616 gfc_add_modify_expr (&loop.pre, tmp, gfc_get_dtype (parmtype));
4618 if (se->direct_byref)
4619 base = gfc_index_zero_node;
4620 else
4621 base = NULL_TREE;
4623 ndim = info->ref ? info->ref->u.ar.dimen : info->dimen;
4624 for (n = 0; n < ndim; n++)
4626 stride = gfc_conv_array_stride (desc, n);
4628 /* Work out the offset. */
4629 if (info->ref
4630 && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4632 gcc_assert (info->subscript[n]
4633 && info->subscript[n]->type == GFC_SS_SCALAR);
4634 start = info->subscript[n]->data.scalar.expr;
4636 else
4638 /* Check we haven't somehow got out of sync. */
4639 gcc_assert (info->dim[dim] == n);
4641 /* Evaluate and remember the start of the section. */
4642 start = info->start[dim];
4643 stride = gfc_evaluate_now (stride, &loop.pre);
4646 tmp = gfc_conv_array_lbound (desc, n);
4647 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), start, tmp);
4649 tmp = fold_build2 (MULT_EXPR, TREE_TYPE (tmp), tmp, stride);
4650 offset = fold_build2 (PLUS_EXPR, TREE_TYPE (tmp), offset, tmp);
4652 if (info->ref
4653 && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4655 /* For elemental dimensions, we only need the offset. */
4656 continue;
4659 /* Vector subscripts need copying and are handled elsewhere. */
4660 if (info->ref)
4661 gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_RANGE);
4663 /* Set the new lower bound. */
4664 from = loop.from[dim];
4665 to = loop.to[dim];
4667 /* If we have an array section or are assigning to a pointer,
4668 make sure that the lower bound is 1. References to the full
4669 array should otherwise keep the original bounds. */
4670 if ((!info->ref
4671 || info->ref->u.ar.type != AR_FULL
4672 || se->direct_byref)
4673 && !integer_onep (from))
4675 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4676 gfc_index_one_node, from);
4677 to = fold_build2 (PLUS_EXPR, gfc_array_index_type, to, tmp);
4678 from = gfc_index_one_node;
4680 tmp = gfc_conv_descriptor_lbound (parm, gfc_rank_cst[dim]);
4681 gfc_add_modify_expr (&loop.pre, tmp, from);
4683 /* Set the new upper bound. */
4684 tmp = gfc_conv_descriptor_ubound (parm, gfc_rank_cst[dim]);
4685 gfc_add_modify_expr (&loop.pre, tmp, to);
4687 /* Multiply the stride by the section stride to get the
4688 total stride. */
4689 stride = fold_build2 (MULT_EXPR, gfc_array_index_type,
4690 stride, info->stride[dim]);
4692 if (se->direct_byref)
4693 base = fold_build2 (MINUS_EXPR, TREE_TYPE (base),
4694 base, stride);
4696 /* Store the new stride. */
4697 tmp = gfc_conv_descriptor_stride (parm, gfc_rank_cst[dim]);
4698 gfc_add_modify_expr (&loop.pre, tmp, stride);
4700 dim++;
4703 if (se->data_not_needed)
4704 gfc_conv_descriptor_data_set (&loop.pre, parm, gfc_index_zero_node);
4705 else
4707 /* Point the data pointer at the first element in the section. */
4708 tmp = gfc_conv_array_data (desc);
4709 tmp = build_fold_indirect_ref (tmp);
4710 tmp = gfc_build_array_ref (tmp, offset);
4711 offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
4712 gfc_conv_descriptor_data_set (&loop.pre, parm, offset);
4715 if (se->direct_byref && !se->data_not_needed)
4717 /* Set the offset. */
4718 tmp = gfc_conv_descriptor_offset (parm);
4719 gfc_add_modify_expr (&loop.pre, tmp, base);
4721 else
4723 /* Only the callee knows what the correct offset it, so just set
4724 it to zero here. */
4725 tmp = gfc_conv_descriptor_offset (parm);
4726 gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
4728 desc = parm;
4731 if (!se->direct_byref)
4733 /* Get a pointer to the new descriptor. */
4734 if (se->want_pointer)
4735 se->expr = build_fold_addr_expr (desc);
4736 else
4737 se->expr = desc;
4740 gfc_add_block_to_block (&se->pre, &loop.pre);
4741 gfc_add_block_to_block (&se->post, &loop.post);
4743 /* Cleanup the scalarizer. */
4744 gfc_cleanup_loop (&loop);
4748 /* Convert an array for passing as an actual parameter. */
4749 /* TODO: Optimize passing g77 arrays. */
4751 void
4752 gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77)
4754 tree ptr;
4755 tree desc;
4756 tree tmp;
4757 tree stmt;
4758 gfc_symbol *sym;
4759 stmtblock_t block;
4761 /* Passing address of the array if it is not pointer or assumed-shape. */
4762 if (expr->expr_type == EXPR_VARIABLE
4763 && expr->ref->u.ar.type == AR_FULL && g77)
4765 sym = expr->symtree->n.sym;
4766 tmp = gfc_get_symbol_decl (sym);
4768 if (sym->ts.type == BT_CHARACTER)
4769 se->string_length = sym->ts.cl->backend_decl;
4770 if (!sym->attr.pointer && sym->as->type != AS_ASSUMED_SHAPE
4771 && !sym->attr.allocatable)
4773 /* Some variables are declared directly, others are declared as
4774 pointers and allocated on the heap. */
4775 if (sym->attr.dummy || POINTER_TYPE_P (TREE_TYPE (tmp)))
4776 se->expr = tmp;
4777 else
4778 se->expr = build_fold_addr_expr (tmp);
4779 return;
4781 if (sym->attr.allocatable)
4783 if (sym->attr.dummy)
4785 gfc_conv_expr_descriptor (se, expr, ss);
4786 se->expr = gfc_conv_array_data (se->expr);
4788 else
4789 se->expr = gfc_conv_array_data (tmp);
4790 return;
4794 se->want_pointer = 1;
4795 gfc_conv_expr_descriptor (se, expr, ss);
4797 /* Deallocate the allocatable components of structures that are
4798 not variable. */
4799 if (expr->ts.type == BT_DERIVED
4800 && expr->ts.derived->attr.alloc_comp
4801 && expr->expr_type != EXPR_VARIABLE)
4803 tmp = build_fold_indirect_ref (se->expr);
4804 tmp = gfc_deallocate_alloc_comp (expr->ts.derived, tmp, expr->rank);
4805 gfc_add_expr_to_block (&se->post, tmp);
4808 if (g77)
4810 desc = se->expr;
4811 /* Repack the array. */
4812 tmp = gfc_chainon_list (NULL_TREE, desc);
4813 ptr = build_function_call_expr (gfor_fndecl_in_pack, tmp);
4814 ptr = gfc_evaluate_now (ptr, &se->pre);
4815 se->expr = ptr;
4817 gfc_start_block (&block);
4819 /* Copy the data back. */
4820 tmp = gfc_chainon_list (NULL_TREE, desc);
4821 tmp = gfc_chainon_list (tmp, ptr);
4822 tmp = build_function_call_expr (gfor_fndecl_in_unpack, tmp);
4823 gfc_add_expr_to_block (&block, tmp);
4825 /* Free the temporary. */
4826 tmp = convert (pvoid_type_node, ptr);
4827 tmp = gfc_chainon_list (NULL_TREE, tmp);
4828 tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
4829 gfc_add_expr_to_block (&block, tmp);
4831 stmt = gfc_finish_block (&block);
4833 gfc_init_block (&block);
4834 /* Only if it was repacked. This code needs to be executed before the
4835 loop cleanup code. */
4836 tmp = build_fold_indirect_ref (desc);
4837 tmp = gfc_conv_array_data (tmp);
4838 tmp = build2 (NE_EXPR, boolean_type_node, ptr, tmp);
4839 tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4841 gfc_add_expr_to_block (&block, tmp);
4842 gfc_add_block_to_block (&block, &se->post);
4844 gfc_init_block (&se->post);
4845 gfc_add_block_to_block (&se->post, &block);
4850 /* Generate code to deallocate an array, if it is allocated. */
4852 tree
4853 gfc_trans_dealloc_allocated (tree descriptor)
4855 tree tmp;
4856 tree ptr;
4857 tree var;
4858 stmtblock_t block;
4860 gfc_start_block (&block);
4862 var = gfc_conv_descriptor_data_get (descriptor);
4863 STRIP_NOPS (var);
4864 tmp = gfc_create_var (gfc_array_index_type, NULL);
4865 ptr = build_fold_addr_expr (tmp);
4867 /* Call array_deallocate with an int* present in the second argument.
4868 Although it is ignored here, it's presence ensures that arrays that
4869 are already deallocated are ignored. */
4870 tmp = gfc_chainon_list (NULL_TREE, var);
4871 tmp = gfc_chainon_list (tmp, ptr);
4872 tmp = build_function_call_expr (gfor_fndecl_deallocate, tmp);
4873 gfc_add_expr_to_block (&block, tmp);
4875 /* Zero the data pointer. */
4876 tmp = build2 (MODIFY_EXPR, void_type_node,
4877 var, build_int_cst (TREE_TYPE (var), 0));
4878 gfc_add_expr_to_block (&block, tmp);
4880 return gfc_finish_block (&block);
4884 /* This helper function calculates the size in words of a full array. */
4886 static tree
4887 get_full_array_size (stmtblock_t *block, tree decl, int rank)
4889 tree idx;
4890 tree nelems;
4891 tree tmp;
4892 idx = gfc_rank_cst[rank - 1];
4893 nelems = gfc_conv_descriptor_ubound (decl, idx);
4894 tmp = gfc_conv_descriptor_lbound (decl, idx);
4895 tmp = build2 (MINUS_EXPR, gfc_array_index_type, nelems, tmp);
4896 tmp = build2 (PLUS_EXPR, gfc_array_index_type,
4897 tmp, gfc_index_one_node);
4898 tmp = gfc_evaluate_now (tmp, block);
4900 nelems = gfc_conv_descriptor_stride (decl, idx);
4901 tmp = build2 (MULT_EXPR, gfc_array_index_type, nelems, tmp);
4902 return gfc_evaluate_now (tmp, block);
4906 /* Allocate dest to the same size as src, and copy src -> dest. */
4908 tree
4909 gfc_duplicate_allocatable(tree dest, tree src, tree type, int rank)
4911 tree tmp;
4912 tree size;
4913 tree nelems;
4914 tree args;
4915 tree null_cond;
4916 tree null_data;
4917 stmtblock_t block;
4919 /* If the source is null, set the destination to null. */
4920 gfc_init_block (&block);
4921 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
4922 null_data = gfc_finish_block (&block);
4924 gfc_init_block (&block);
4926 nelems = get_full_array_size (&block, src, rank);
4927 size = fold_build2 (MULT_EXPR, gfc_array_index_type, nelems,
4928 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
4930 /* Allocate memory to the destination. */
4931 tmp = gfc_chainon_list (NULL_TREE, size);
4932 if (gfc_index_integer_kind == 4)
4933 tmp = build_function_call_expr (gfor_fndecl_internal_malloc, tmp);
4934 else if (gfc_index_integer_kind == 8)
4935 tmp = build_function_call_expr (gfor_fndecl_internal_malloc64, tmp);
4936 else
4937 gcc_unreachable ();
4938 tmp = fold (convert (TREE_TYPE (gfc_conv_descriptor_data_get (src)),
4939 tmp));
4940 gfc_conv_descriptor_data_set (&block, dest, tmp);
4942 /* We know the temporary and the value will be the same length,
4943 so can use memcpy. */
4944 tmp = gfc_conv_descriptor_data_get (dest);
4945 args = gfc_chainon_list (NULL_TREE, tmp);
4946 tmp = gfc_conv_descriptor_data_get (src);
4947 args = gfc_chainon_list (args, tmp);
4948 args = gfc_chainon_list (args, size);
4949 tmp = built_in_decls[BUILT_IN_MEMCPY];
4950 tmp = build_function_call_expr (tmp, args);
4951 gfc_add_expr_to_block (&block, tmp);
4952 tmp = gfc_finish_block (&block);
4954 /* Null the destination if the source is null; otherwise do
4955 the allocate and copy. */
4956 null_cond = gfc_conv_descriptor_data_get (src);
4957 null_cond = convert (pvoid_type_node, null_cond);
4958 null_cond = build2 (NE_EXPR, boolean_type_node, null_cond,
4959 null_pointer_node);
4960 return build3_v (COND_EXPR, null_cond, tmp, null_data);
4964 /* Recursively traverse an object of derived type, generating code to
4965 deallocate, nullify or copy allocatable components. This is the work horse
4966 function for the functions named in this enum. */
4968 enum {DEALLOCATE_ALLOC_COMP = 1, NULLIFY_ALLOC_COMP, COPY_ALLOC_COMP};
4970 static tree
4971 structure_alloc_comps (gfc_symbol * der_type, tree decl,
4972 tree dest, int rank, int purpose)
4974 gfc_component *c;
4975 gfc_loopinfo loop;
4976 stmtblock_t fnblock;
4977 stmtblock_t loopbody;
4978 tree tmp;
4979 tree comp;
4980 tree dcmp;
4981 tree nelems;
4982 tree index;
4983 tree var;
4984 tree cdecl;
4985 tree ctype;
4986 tree vref, dref;
4987 tree null_cond = NULL_TREE;
4989 gfc_init_block (&fnblock);
4991 if (POINTER_TYPE_P (TREE_TYPE (decl)))
4992 decl = build_fold_indirect_ref (decl);
4994 /* If this an array of derived types with allocatable components
4995 build a loop and recursively call this function. */
4996 if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
4997 || GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
4999 tmp = gfc_conv_array_data (decl);
5000 var = build_fold_indirect_ref (tmp);
5002 /* Get the number of elements - 1 and set the counter. */
5003 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
5005 /* Use the descriptor for an allocatable array. Since this
5006 is a full array reference, we only need the descriptor
5007 information from dimension = rank. */
5008 tmp = get_full_array_size (&fnblock, decl, rank);
5009 tmp = build2 (MINUS_EXPR, gfc_array_index_type,
5010 tmp, gfc_index_one_node);
5012 null_cond = gfc_conv_descriptor_data_get (decl);
5013 null_cond = build2 (NE_EXPR, boolean_type_node, null_cond,
5014 build_int_cst (TREE_TYPE (tmp), 0));
5016 else
5018 /* Otherwise use the TYPE_DOMAIN information. */
5019 tmp = array_type_nelts (TREE_TYPE (decl));
5020 tmp = fold_convert (gfc_array_index_type, tmp);
5023 /* Remember that this is, in fact, the no. of elements - 1. */
5024 nelems = gfc_evaluate_now (tmp, &fnblock);
5025 index = gfc_create_var (gfc_array_index_type, "S");
5027 /* Build the body of the loop. */
5028 gfc_init_block (&loopbody);
5030 vref = gfc_build_array_ref (var, index);
5032 if (purpose == COPY_ALLOC_COMP)
5034 tmp = gfc_duplicate_allocatable (dest, decl, TREE_TYPE(decl), rank);
5035 gfc_add_expr_to_block (&fnblock, tmp);
5037 tmp = build_fold_indirect_ref (gfc_conv_descriptor_data_get (dest));
5038 dref = gfc_build_array_ref (tmp, index);
5039 tmp = structure_alloc_comps (der_type, vref, dref, rank, purpose);
5041 else
5042 tmp = structure_alloc_comps (der_type, vref, NULL_TREE, rank, purpose);
5044 gfc_add_expr_to_block (&loopbody, tmp);
5046 /* Build the loop and return. */
5047 gfc_init_loopinfo (&loop);
5048 loop.dimen = 1;
5049 loop.from[0] = gfc_index_zero_node;
5050 loop.loopvar[0] = index;
5051 loop.to[0] = nelems;
5052 gfc_trans_scalarizing_loops (&loop, &loopbody);
5053 gfc_add_block_to_block (&fnblock, &loop.pre);
5055 tmp = gfc_finish_block (&fnblock);
5056 if (null_cond != NULL_TREE)
5057 tmp = build3_v (COND_EXPR, null_cond, tmp, build_empty_stmt ());
5059 return tmp;
5062 /* Otherwise, act on the components or recursively call self to
5063 act on a chain of components. */
5064 for (c = der_type->components; c; c = c->next)
5066 bool cmp_has_alloc_comps = (c->ts.type == BT_DERIVED)
5067 && c->ts.derived->attr.alloc_comp;
5068 cdecl = c->backend_decl;
5069 ctype = TREE_TYPE (cdecl);
5071 switch (purpose)
5073 case DEALLOCATE_ALLOC_COMP:
5074 /* Do not deallocate the components of ultimate pointer
5075 components. */
5076 if (cmp_has_alloc_comps && !c->pointer)
5078 comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5079 rank = c->as ? c->as->rank : 0;
5080 tmp = structure_alloc_comps (c->ts.derived, comp, NULL_TREE,
5081 rank, purpose);
5082 gfc_add_expr_to_block (&fnblock, tmp);
5085 if (c->allocatable)
5087 comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5088 tmp = gfc_trans_dealloc_allocated (comp);
5089 gfc_add_expr_to_block (&fnblock, tmp);
5091 break;
5093 case NULLIFY_ALLOC_COMP:
5094 if (c->pointer)
5095 continue;
5096 else if (c->allocatable)
5098 comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5099 gfc_conv_descriptor_data_set (&fnblock, comp, null_pointer_node);
5101 else if (cmp_has_alloc_comps)
5103 comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5104 rank = c->as ? c->as->rank : 0;
5105 tmp = structure_alloc_comps (c->ts.derived, comp, NULL_TREE,
5106 rank, purpose);
5107 gfc_add_expr_to_block (&fnblock, tmp);
5109 break;
5111 case COPY_ALLOC_COMP:
5112 if (c->pointer)
5113 continue;
5115 /* We need source and destination components. */
5116 comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5117 dcmp = build3 (COMPONENT_REF, ctype, dest, cdecl, NULL_TREE);
5118 dcmp = fold_convert (TREE_TYPE (comp), dcmp);
5120 if (c->allocatable && !cmp_has_alloc_comps)
5122 tmp = gfc_duplicate_allocatable(dcmp, comp, ctype, c->as->rank);
5123 gfc_add_expr_to_block (&fnblock, tmp);
5126 if (cmp_has_alloc_comps)
5128 rank = c->as ? c->as->rank : 0;
5129 tmp = fold_convert (TREE_TYPE (dcmp), comp);
5130 gfc_add_modify_expr (&fnblock, dcmp, tmp);
5131 tmp = structure_alloc_comps (c->ts.derived, comp, dcmp,
5132 rank, purpose);
5133 gfc_add_expr_to_block (&fnblock, tmp);
5135 break;
5137 default:
5138 gcc_unreachable ();
5139 break;
5143 return gfc_finish_block (&fnblock);
5146 /* Recursively traverse an object of derived type, generating code to
5147 nullify allocatable components. */
5149 tree
5150 gfc_nullify_alloc_comp (gfc_symbol * der_type, tree decl, int rank)
5152 return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
5153 NULLIFY_ALLOC_COMP);
5157 /* Recursively traverse an object of derived type, generating code to
5158 deallocate allocatable components. */
5160 tree
5161 gfc_deallocate_alloc_comp (gfc_symbol * der_type, tree decl, int rank)
5163 return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
5164 DEALLOCATE_ALLOC_COMP);
5168 /* Recursively traverse an object of derived type, generating code to
5169 copy its allocatable components. */
5171 tree
5172 gfc_copy_alloc_comp (gfc_symbol * der_type, tree decl, tree dest, int rank)
5174 return structure_alloc_comps (der_type, decl, dest, rank, COPY_ALLOC_COMP);
5178 /* NULLIFY an allocatable/pointer array on function entry, free it on exit.
5179 Do likewise, recursively if necessary, with the allocatable components of
5180 derived types. */
5182 tree
5183 gfc_trans_deferred_array (gfc_symbol * sym, tree body)
5185 tree type;
5186 tree tmp;
5187 tree descriptor;
5188 stmtblock_t fnblock;
5189 locus loc;
5190 int rank;
5191 bool sym_has_alloc_comp;
5193 sym_has_alloc_comp = (sym->ts.type == BT_DERIVED)
5194 && sym->ts.derived->attr.alloc_comp;
5196 /* Make sure the frontend gets these right. */
5197 if (!(sym->attr.pointer || sym->attr.allocatable || sym_has_alloc_comp))
5198 fatal_error ("Possible frontend bug: Deferred array size without pointer, "
5199 "allocatable attribute or derived type without allocatable "
5200 "components.");
5202 gfc_init_block (&fnblock);
5204 gcc_assert (TREE_CODE (sym->backend_decl) == VAR_DECL
5205 || TREE_CODE (sym->backend_decl) == PARM_DECL);
5207 if (sym->ts.type == BT_CHARACTER
5208 && !INTEGER_CST_P (sym->ts.cl->backend_decl))
5210 gfc_trans_init_string_length (sym->ts.cl, &fnblock);
5211 gfc_trans_vla_type_sizes (sym, &fnblock);
5214 /* Dummy and use associated variables don't need anything special. */
5215 if (sym->attr.dummy || sym->attr.use_assoc)
5217 gfc_add_expr_to_block (&fnblock, body);
5219 return gfc_finish_block (&fnblock);
5222 gfc_get_backend_locus (&loc);
5223 gfc_set_backend_locus (&sym->declared_at);
5224 descriptor = sym->backend_decl;
5226 /* Although static, derived types with default initializers and
5227 allocatable components must not be nulled wholesale; instead they
5228 are treated component by component. */
5229 if (TREE_STATIC (descriptor) && !sym_has_alloc_comp)
5231 /* SAVEd variables are not freed on exit. */
5232 gfc_trans_static_array_pointer (sym);
5233 return body;
5236 /* Get the descriptor type. */
5237 type = TREE_TYPE (sym->backend_decl);
5239 if (sym_has_alloc_comp && !(sym->attr.pointer || sym->attr.allocatable))
5241 rank = sym->as ? sym->as->rank : 0;
5242 tmp = gfc_nullify_alloc_comp (sym->ts.derived, descriptor, rank);
5243 gfc_add_expr_to_block (&fnblock, tmp);
5245 else if (!GFC_DESCRIPTOR_TYPE_P (type))
5247 /* If the backend_decl is not a descriptor, we must have a pointer
5248 to one. */
5249 descriptor = build_fold_indirect_ref (sym->backend_decl);
5250 type = TREE_TYPE (descriptor);
5253 /* NULLIFY the data pointer. */
5254 if (GFC_DESCRIPTOR_TYPE_P (type))
5255 gfc_conv_descriptor_data_set (&fnblock, descriptor, null_pointer_node);
5257 gfc_add_expr_to_block (&fnblock, body);
5259 gfc_set_backend_locus (&loc);
5261 /* Allocatable arrays need to be freed when they go out of scope.
5262 The allocatable components of pointers must not be touched. */
5263 if (sym_has_alloc_comp && !(sym->attr.function || sym->attr.result)
5264 && !sym->attr.pointer)
5266 int rank;
5267 rank = sym->as ? sym->as->rank : 0;
5268 tmp = gfc_deallocate_alloc_comp (sym->ts.derived, descriptor, rank);
5269 gfc_add_expr_to_block (&fnblock, tmp);
5272 if (sym->attr.allocatable)
5274 tmp = gfc_trans_dealloc_allocated (sym->backend_decl);
5275 gfc_add_expr_to_block (&fnblock, tmp);
5278 return gfc_finish_block (&fnblock);
5281 /************ Expression Walking Functions ******************/
5283 /* Walk a variable reference.
5285 Possible extension - multiple component subscripts.
5286 x(:,:) = foo%a(:)%b(:)
5287 Transforms to
5288 forall (i=..., j=...)
5289 x(i,j) = foo%a(j)%b(i)
5290 end forall
5291 This adds a fair amout of complexity because you need to deal with more
5292 than one ref. Maybe handle in a similar manner to vector subscripts.
5293 Maybe not worth the effort. */
5296 static gfc_ss *
5297 gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
5299 gfc_ref *ref;
5300 gfc_array_ref *ar;
5301 gfc_ss *newss;
5302 gfc_ss *head;
5303 int n;
5305 for (ref = expr->ref; ref; ref = ref->next)
5306 if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
5307 break;
5309 for (; ref; ref = ref->next)
5311 if (ref->type == REF_SUBSTRING)
5313 newss = gfc_get_ss ();
5314 newss->type = GFC_SS_SCALAR;
5315 newss->expr = ref->u.ss.start;
5316 newss->next = ss;
5317 ss = newss;
5319 newss = gfc_get_ss ();
5320 newss->type = GFC_SS_SCALAR;
5321 newss->expr = ref->u.ss.end;
5322 newss->next = ss;
5323 ss = newss;
5326 /* We're only interested in array sections from now on. */
5327 if (ref->type != REF_ARRAY)
5328 continue;
5330 ar = &ref->u.ar;
5331 switch (ar->type)
5333 case AR_ELEMENT:
5334 for (n = 0; n < ar->dimen; n++)
5336 newss = gfc_get_ss ();
5337 newss->type = GFC_SS_SCALAR;
5338 newss->expr = ar->start[n];
5339 newss->next = ss;
5340 ss = newss;
5342 break;
5344 case AR_FULL:
5345 newss = gfc_get_ss ();
5346 newss->type = GFC_SS_SECTION;
5347 newss->expr = expr;
5348 newss->next = ss;
5349 newss->data.info.dimen = ar->as->rank;
5350 newss->data.info.ref = ref;
5352 /* Make sure array is the same as array(:,:), this way
5353 we don't need to special case all the time. */
5354 ar->dimen = ar->as->rank;
5355 for (n = 0; n < ar->dimen; n++)
5357 newss->data.info.dim[n] = n;
5358 ar->dimen_type[n] = DIMEN_RANGE;
5360 gcc_assert (ar->start[n] == NULL);
5361 gcc_assert (ar->end[n] == NULL);
5362 gcc_assert (ar->stride[n] == NULL);
5364 ss = newss;
5365 break;
5367 case AR_SECTION:
5368 newss = gfc_get_ss ();
5369 newss->type = GFC_SS_SECTION;
5370 newss->expr = expr;
5371 newss->next = ss;
5372 newss->data.info.dimen = 0;
5373 newss->data.info.ref = ref;
5375 head = newss;
5377 /* We add SS chains for all the subscripts in the section. */
5378 for (n = 0; n < ar->dimen; n++)
5380 gfc_ss *indexss;
5382 switch (ar->dimen_type[n])
5384 case DIMEN_ELEMENT:
5385 /* Add SS for elemental (scalar) subscripts. */
5386 gcc_assert (ar->start[n]);
5387 indexss = gfc_get_ss ();
5388 indexss->type = GFC_SS_SCALAR;
5389 indexss->expr = ar->start[n];
5390 indexss->next = gfc_ss_terminator;
5391 indexss->loop_chain = gfc_ss_terminator;
5392 newss->data.info.subscript[n] = indexss;
5393 break;
5395 case DIMEN_RANGE:
5396 /* We don't add anything for sections, just remember this
5397 dimension for later. */
5398 newss->data.info.dim[newss->data.info.dimen] = n;
5399 newss->data.info.dimen++;
5400 break;
5402 case DIMEN_VECTOR:
5403 /* Create a GFC_SS_VECTOR index in which we can store
5404 the vector's descriptor. */
5405 indexss = gfc_get_ss ();
5406 indexss->type = GFC_SS_VECTOR;
5407 indexss->expr = ar->start[n];
5408 indexss->next = gfc_ss_terminator;
5409 indexss->loop_chain = gfc_ss_terminator;
5410 newss->data.info.subscript[n] = indexss;
5411 newss->data.info.dim[newss->data.info.dimen] = n;
5412 newss->data.info.dimen++;
5413 break;
5415 default:
5416 /* We should know what sort of section it is by now. */
5417 gcc_unreachable ();
5420 /* We should have at least one non-elemental dimension. */
5421 gcc_assert (newss->data.info.dimen > 0);
5422 ss = newss;
5423 break;
5425 default:
5426 /* We should know what sort of section it is by now. */
5427 gcc_unreachable ();
5431 return ss;
5435 /* Walk an expression operator. If only one operand of a binary expression is
5436 scalar, we must also add the scalar term to the SS chain. */
5438 static gfc_ss *
5439 gfc_walk_op_expr (gfc_ss * ss, gfc_expr * expr)
5441 gfc_ss *head;
5442 gfc_ss *head2;
5443 gfc_ss *newss;
5445 head = gfc_walk_subexpr (ss, expr->value.op.op1);
5446 if (expr->value.op.op2 == NULL)
5447 head2 = head;
5448 else
5449 head2 = gfc_walk_subexpr (head, expr->value.op.op2);
5451 /* All operands are scalar. Pass back and let the caller deal with it. */
5452 if (head2 == ss)
5453 return head2;
5455 /* All operands require scalarization. */
5456 if (head != ss && (expr->value.op.op2 == NULL || head2 != head))
5457 return head2;
5459 /* One of the operands needs scalarization, the other is scalar.
5460 Create a gfc_ss for the scalar expression. */
5461 newss = gfc_get_ss ();
5462 newss->type = GFC_SS_SCALAR;
5463 if (head == ss)
5465 /* First operand is scalar. We build the chain in reverse order, so
5466 add the scarar SS after the second operand. */
5467 head = head2;
5468 while (head && head->next != ss)
5469 head = head->next;
5470 /* Check we haven't somehow broken the chain. */
5471 gcc_assert (head);
5472 newss->next = ss;
5473 head->next = newss;
5474 newss->expr = expr->value.op.op1;
5476 else /* head2 == head */
5478 gcc_assert (head2 == head);
5479 /* Second operand is scalar. */
5480 newss->next = head2;
5481 head2 = newss;
5482 newss->expr = expr->value.op.op2;
5485 return head2;
5489 /* Reverse a SS chain. */
5491 gfc_ss *
5492 gfc_reverse_ss (gfc_ss * ss)
5494 gfc_ss *next;
5495 gfc_ss *head;
5497 gcc_assert (ss != NULL);
5499 head = gfc_ss_terminator;
5500 while (ss != gfc_ss_terminator)
5502 next = ss->next;
5503 /* Check we didn't somehow break the chain. */
5504 gcc_assert (next != NULL);
5505 ss->next = head;
5506 head = ss;
5507 ss = next;
5510 return (head);
5514 /* Walk the arguments of an elemental function. */
5516 gfc_ss *
5517 gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
5518 gfc_ss_type type)
5520 int scalar;
5521 gfc_ss *head;
5522 gfc_ss *tail;
5523 gfc_ss *newss;
5525 head = gfc_ss_terminator;
5526 tail = NULL;
5527 scalar = 1;
5528 for (; arg; arg = arg->next)
5530 if (!arg->expr)
5531 continue;
5533 newss = gfc_walk_subexpr (head, arg->expr);
5534 if (newss == head)
5536 /* Scalar argument. */
5537 newss = gfc_get_ss ();
5538 newss->type = type;
5539 newss->expr = arg->expr;
5540 newss->next = head;
5542 else
5543 scalar = 0;
5545 head = newss;
5546 if (!tail)
5548 tail = head;
5549 while (tail->next != gfc_ss_terminator)
5550 tail = tail->next;
5554 if (scalar)
5556 /* If all the arguments are scalar we don't need the argument SS. */
5557 gfc_free_ss_chain (head);
5558 /* Pass it back. */
5559 return ss;
5562 /* Add it onto the existing chain. */
5563 tail->next = ss;
5564 return head;
5568 /* Walk a function call. Scalar functions are passed back, and taken out of
5569 scalarization loops. For elemental functions we walk their arguments.
5570 The result of functions returning arrays is stored in a temporary outside
5571 the loop, so that the function is only called once. Hence we do not need
5572 to walk their arguments. */
5574 static gfc_ss *
5575 gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
5577 gfc_ss *newss;
5578 gfc_intrinsic_sym *isym;
5579 gfc_symbol *sym;
5581 isym = expr->value.function.isym;
5583 /* Handle intrinsic functions separately. */
5584 if (isym)
5585 return gfc_walk_intrinsic_function (ss, expr, isym);
5587 sym = expr->value.function.esym;
5588 if (!sym)
5589 sym = expr->symtree->n.sym;
5591 /* A function that returns arrays. */
5592 if (gfc_return_by_reference (sym) && sym->result->attr.dimension)
5594 newss = gfc_get_ss ();
5595 newss->type = GFC_SS_FUNCTION;
5596 newss->expr = expr;
5597 newss->next = ss;
5598 newss->data.info.dimen = expr->rank;
5599 return newss;
5602 /* Walk the parameters of an elemental function. For now we always pass
5603 by reference. */
5604 if (sym->attr.elemental)
5605 return gfc_walk_elemental_function_args (ss, expr->value.function.actual,
5606 GFC_SS_REFERENCE);
5608 /* Scalar functions are OK as these are evaluated outside the scalarization
5609 loop. Pass back and let the caller deal with it. */
5610 return ss;
5614 /* An array temporary is constructed for array constructors. */
5616 static gfc_ss *
5617 gfc_walk_array_constructor (gfc_ss * ss, gfc_expr * expr)
5619 gfc_ss *newss;
5620 int n;
5622 newss = gfc_get_ss ();
5623 newss->type = GFC_SS_CONSTRUCTOR;
5624 newss->expr = expr;
5625 newss->next = ss;
5626 newss->data.info.dimen = expr->rank;
5627 for (n = 0; n < expr->rank; n++)
5628 newss->data.info.dim[n] = n;
5630 return newss;
5634 /* Walk an expression. Add walked expressions to the head of the SS chain.
5635 A wholly scalar expression will not be added. */
5637 static gfc_ss *
5638 gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr)
5640 gfc_ss *head;
5642 switch (expr->expr_type)
5644 case EXPR_VARIABLE:
5645 head = gfc_walk_variable_expr (ss, expr);
5646 return head;
5648 case EXPR_OP:
5649 head = gfc_walk_op_expr (ss, expr);
5650 return head;
5652 case EXPR_FUNCTION:
5653 head = gfc_walk_function_expr (ss, expr);
5654 return head;
5656 case EXPR_CONSTANT:
5657 case EXPR_NULL:
5658 case EXPR_STRUCTURE:
5659 /* Pass back and let the caller deal with it. */
5660 break;
5662 case EXPR_ARRAY:
5663 head = gfc_walk_array_constructor (ss, expr);
5664 return head;
5666 case EXPR_SUBSTRING:
5667 /* Pass back and let the caller deal with it. */
5668 break;
5670 default:
5671 internal_error ("bad expression type during walk (%d)",
5672 expr->expr_type);
5674 return ss;
5678 /* Entry point for expression walking.
5679 A return value equal to the passed chain means this is
5680 a scalar expression. It is up to the caller to take whatever action is
5681 necessary to translate these. */
5683 gfc_ss *
5684 gfc_walk_expr (gfc_expr * expr)
5686 gfc_ss *res;
5688 res = gfc_walk_subexpr (gfc_ss_terminator, expr);
5689 return gfc_reverse_ss (res);