* trans-array.c (gfc_trans_array_constructor_value): Make the
[official-gcc.git] / gcc / fortran / trans-array.c
blob86e565781203c1cabe5a8d2b7605bdadfd9e9bd1
1 /* Array translation routines
2 Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
3 Inc.
4 Contributed by Paul Brook <paul@nowt.org>
5 and Steven Bosscher <s.bosscher@student.tudelft.nl>
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 wether 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;
1467 /* Array constructors are handled by constructing a temporary, then using that
1468 within the scalarization loop. This is not optimal, but seems by far the
1469 simplest method. */
1471 static void
1472 gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss)
1474 gfc_constructor *c;
1475 tree offset;
1476 tree offsetvar;
1477 tree desc;
1478 tree type;
1479 bool const_string;
1480 bool dynamic;
1482 ss->data.info.dimen = loop->dimen;
1484 c = ss->expr->value.constructor;
1485 if (ss->expr->ts.type == BT_CHARACTER)
1487 const_string = get_array_ctor_strlen (c, &ss->string_length);
1488 if (!ss->string_length)
1489 gfc_todo_error ("complex character array constructors");
1491 type = gfc_get_character_type_len (ss->expr->ts.kind, ss->string_length);
1492 if (const_string)
1493 type = build_pointer_type (type);
1495 else
1497 const_string = TRUE;
1498 type = gfc_typenode_for_spec (&ss->expr->ts);
1501 /* See if the constructor determines the loop bounds. */
1502 dynamic = false;
1503 if (loop->to[0] == NULL_TREE)
1505 mpz_t size;
1507 /* We should have a 1-dimensional, zero-based loop. */
1508 gcc_assert (loop->dimen == 1);
1509 gcc_assert (integer_zerop (loop->from[0]));
1511 /* Split the constructor size into a static part and a dynamic part.
1512 Allocate the static size up-front and record whether the dynamic
1513 size might be nonzero. */
1514 mpz_init (size);
1515 dynamic = gfc_get_array_constructor_size (&size, c);
1516 mpz_sub_ui (size, size, 1);
1517 loop->to[0] = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1518 mpz_clear (size);
1521 gfc_trans_create_temp_array (&loop->pre, &loop->post, loop, &ss->data.info,
1522 type, dynamic, true, false, false);
1524 desc = ss->data.info.descriptor;
1525 offset = gfc_index_zero_node;
1526 offsetvar = gfc_create_var_np (gfc_array_index_type, "offset");
1527 TREE_USED (offsetvar) = 0;
1528 gfc_trans_array_constructor_value (&loop->pre, type, desc, c,
1529 &offset, &offsetvar, dynamic);
1531 /* If the array grows dynamically, the upper bound of the loop variable
1532 is determined by the array's final upper bound. */
1533 if (dynamic)
1534 loop->to[0] = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[0]);
1536 if (TREE_USED (offsetvar))
1537 pushdecl (offsetvar);
1538 else
1539 gcc_assert (INTEGER_CST_P (offset));
1540 #if 0
1541 /* Disable bound checking for now because it's probably broken. */
1542 if (flag_bounds_check)
1544 gcc_unreachable ();
1546 #endif
1550 /* INFO describes a GFC_SS_SECTION in loop LOOP, and this function is
1551 called after evaluating all of INFO's vector dimensions. Go through
1552 each such vector dimension and see if we can now fill in any missing
1553 loop bounds. */
1555 static void
1556 gfc_set_vector_loop_bounds (gfc_loopinfo * loop, gfc_ss_info * info)
1558 gfc_se se;
1559 tree tmp;
1560 tree desc;
1561 tree zero;
1562 int n;
1563 int dim;
1565 for (n = 0; n < loop->dimen; n++)
1567 dim = info->dim[n];
1568 if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR
1569 && loop->to[n] == NULL)
1571 /* Loop variable N indexes vector dimension DIM, and we don't
1572 yet know the upper bound of loop variable N. Set it to the
1573 difference between the vector's upper and lower bounds. */
1574 gcc_assert (loop->from[n] == gfc_index_zero_node);
1575 gcc_assert (info->subscript[dim]
1576 && info->subscript[dim]->type == GFC_SS_VECTOR);
1578 gfc_init_se (&se, NULL);
1579 desc = info->subscript[dim]->data.info.descriptor;
1580 zero = gfc_rank_cst[0];
1581 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1582 gfc_conv_descriptor_ubound (desc, zero),
1583 gfc_conv_descriptor_lbound (desc, zero));
1584 tmp = gfc_evaluate_now (tmp, &loop->pre);
1585 loop->to[n] = tmp;
1591 /* Add the pre and post chains for all the scalar expressions in a SS chain
1592 to loop. This is called after the loop parameters have been calculated,
1593 but before the actual scalarizing loops. */
1595 static void
1596 gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript)
1598 gfc_se se;
1599 int n;
1601 /* TODO: This can generate bad code if there are ordering dependencies.
1602 eg. a callee allocated function and an unknown size constructor. */
1603 gcc_assert (ss != NULL);
1605 for (; ss != gfc_ss_terminator; ss = ss->loop_chain)
1607 gcc_assert (ss);
1609 switch (ss->type)
1611 case GFC_SS_SCALAR:
1612 /* Scalar expression. Evaluate this now. This includes elemental
1613 dimension indices, but not array section bounds. */
1614 gfc_init_se (&se, NULL);
1615 gfc_conv_expr (&se, ss->expr);
1616 gfc_add_block_to_block (&loop->pre, &se.pre);
1618 if (ss->expr->ts.type != BT_CHARACTER)
1620 /* Move the evaluation of scalar expressions outside the
1621 scalarization loop. */
1622 if (subscript)
1623 se.expr = convert(gfc_array_index_type, se.expr);
1624 se.expr = gfc_evaluate_now (se.expr, &loop->pre);
1625 gfc_add_block_to_block (&loop->pre, &se.post);
1627 else
1628 gfc_add_block_to_block (&loop->post, &se.post);
1630 ss->data.scalar.expr = se.expr;
1631 ss->string_length = se.string_length;
1632 break;
1634 case GFC_SS_REFERENCE:
1635 /* Scalar reference. Evaluate this now. */
1636 gfc_init_se (&se, NULL);
1637 gfc_conv_expr_reference (&se, ss->expr);
1638 gfc_add_block_to_block (&loop->pre, &se.pre);
1639 gfc_add_block_to_block (&loop->post, &se.post);
1641 ss->data.scalar.expr = gfc_evaluate_now (se.expr, &loop->pre);
1642 ss->string_length = se.string_length;
1643 break;
1645 case GFC_SS_SECTION:
1646 /* Add the expressions for scalar and vector subscripts. */
1647 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1648 if (ss->data.info.subscript[n])
1649 gfc_add_loop_ss_code (loop, ss->data.info.subscript[n], true);
1651 gfc_set_vector_loop_bounds (loop, &ss->data.info);
1652 break;
1654 case GFC_SS_VECTOR:
1655 /* Get the vector's descriptor and store it in SS. */
1656 gfc_init_se (&se, NULL);
1657 gfc_conv_expr_descriptor (&se, ss->expr, gfc_walk_expr (ss->expr));
1658 gfc_add_block_to_block (&loop->pre, &se.pre);
1659 gfc_add_block_to_block (&loop->post, &se.post);
1660 ss->data.info.descriptor = se.expr;
1661 break;
1663 case GFC_SS_INTRINSIC:
1664 gfc_add_intrinsic_ss_code (loop, ss);
1665 break;
1667 case GFC_SS_FUNCTION:
1668 /* Array function return value. We call the function and save its
1669 result in a temporary for use inside the loop. */
1670 gfc_init_se (&se, NULL);
1671 se.loop = loop;
1672 se.ss = ss;
1673 gfc_conv_expr (&se, ss->expr);
1674 gfc_add_block_to_block (&loop->pre, &se.pre);
1675 gfc_add_block_to_block (&loop->post, &se.post);
1676 ss->string_length = se.string_length;
1677 break;
1679 case GFC_SS_CONSTRUCTOR:
1680 gfc_trans_array_constructor (loop, ss);
1681 break;
1683 case GFC_SS_TEMP:
1684 case GFC_SS_COMPONENT:
1685 /* Do nothing. These are handled elsewhere. */
1686 break;
1688 default:
1689 gcc_unreachable ();
1695 /* Translate expressions for the descriptor and data pointer of a SS. */
1696 /*GCC ARRAYS*/
1698 static void
1699 gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)
1701 gfc_se se;
1702 tree tmp;
1704 /* Get the descriptor for the array to be scalarized. */
1705 gcc_assert (ss->expr->expr_type == EXPR_VARIABLE);
1706 gfc_init_se (&se, NULL);
1707 se.descriptor_only = 1;
1708 gfc_conv_expr_lhs (&se, ss->expr);
1709 gfc_add_block_to_block (block, &se.pre);
1710 ss->data.info.descriptor = se.expr;
1711 ss->string_length = se.string_length;
1713 if (base)
1715 /* Also the data pointer. */
1716 tmp = gfc_conv_array_data (se.expr);
1717 /* If this is a variable or address of a variable we use it directly.
1718 Otherwise we must evaluate it now to avoid breaking dependency
1719 analysis by pulling the expressions for elemental array indices
1720 inside the loop. */
1721 if (!(DECL_P (tmp)
1722 || (TREE_CODE (tmp) == ADDR_EXPR
1723 && DECL_P (TREE_OPERAND (tmp, 0)))))
1724 tmp = gfc_evaluate_now (tmp, block);
1725 ss->data.info.data = tmp;
1727 tmp = gfc_conv_array_offset (se.expr);
1728 ss->data.info.offset = gfc_evaluate_now (tmp, block);
1733 /* Initialize a gfc_loopinfo structure. */
1735 void
1736 gfc_init_loopinfo (gfc_loopinfo * loop)
1738 int n;
1740 memset (loop, 0, sizeof (gfc_loopinfo));
1741 gfc_init_block (&loop->pre);
1742 gfc_init_block (&loop->post);
1744 /* Initially scalarize in order. */
1745 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1746 loop->order[n] = n;
1748 loop->ss = gfc_ss_terminator;
1752 /* Copies the loop variable info to a gfc_se structure. Does not copy the SS
1753 chain. */
1755 void
1756 gfc_copy_loopinfo_to_se (gfc_se * se, gfc_loopinfo * loop)
1758 se->loop = loop;
1762 /* Return an expression for the data pointer of an array. */
1764 tree
1765 gfc_conv_array_data (tree descriptor)
1767 tree type;
1769 type = TREE_TYPE (descriptor);
1770 if (GFC_ARRAY_TYPE_P (type))
1772 if (TREE_CODE (type) == POINTER_TYPE)
1773 return descriptor;
1774 else
1776 /* Descriptorless arrays. */
1777 return build_fold_addr_expr (descriptor);
1780 else
1781 return gfc_conv_descriptor_data_get (descriptor);
1785 /* Return an expression for the base offset of an array. */
1787 tree
1788 gfc_conv_array_offset (tree descriptor)
1790 tree type;
1792 type = TREE_TYPE (descriptor);
1793 if (GFC_ARRAY_TYPE_P (type))
1794 return GFC_TYPE_ARRAY_OFFSET (type);
1795 else
1796 return gfc_conv_descriptor_offset (descriptor);
1800 /* Get an expression for the array stride. */
1802 tree
1803 gfc_conv_array_stride (tree descriptor, int dim)
1805 tree tmp;
1806 tree type;
1808 type = TREE_TYPE (descriptor);
1810 /* For descriptorless arrays use the array size. */
1811 tmp = GFC_TYPE_ARRAY_STRIDE (type, dim);
1812 if (tmp != NULL_TREE)
1813 return tmp;
1815 tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[dim]);
1816 return tmp;
1820 /* Like gfc_conv_array_stride, but for the lower bound. */
1822 tree
1823 gfc_conv_array_lbound (tree descriptor, int dim)
1825 tree tmp;
1826 tree type;
1828 type = TREE_TYPE (descriptor);
1830 tmp = GFC_TYPE_ARRAY_LBOUND (type, dim);
1831 if (tmp != NULL_TREE)
1832 return tmp;
1834 tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[dim]);
1835 return tmp;
1839 /* Like gfc_conv_array_stride, but for the upper bound. */
1841 tree
1842 gfc_conv_array_ubound (tree descriptor, int dim)
1844 tree tmp;
1845 tree type;
1847 type = TREE_TYPE (descriptor);
1849 tmp = GFC_TYPE_ARRAY_UBOUND (type, dim);
1850 if (tmp != NULL_TREE)
1851 return tmp;
1853 /* This should only ever happen when passing an assumed shape array
1854 as an actual parameter. The value will never be used. */
1855 if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor)))
1856 return gfc_index_zero_node;
1858 tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[dim]);
1859 return tmp;
1863 /* Generate code to perform an array index bound check. */
1865 static tree
1866 gfc_trans_array_bound_check (gfc_se * se, tree descriptor, tree index, int n,
1867 locus * where)
1869 tree fault;
1870 tree tmp;
1871 char *msg;
1872 const char * name = NULL;
1874 if (!flag_bounds_check)
1875 return index;
1877 index = gfc_evaluate_now (index, &se->pre);
1879 /* We find a name for the error message. */
1880 if (se->ss)
1881 name = se->ss->expr->symtree->name;
1883 if (!name && se->loop && se->loop->ss && se->loop->ss->expr
1884 && se->loop->ss->expr->symtree)
1885 name = se->loop->ss->expr->symtree->name;
1887 if (!name && se->loop && se->loop->ss && se->loop->ss->loop_chain
1888 && se->loop->ss->loop_chain->expr
1889 && se->loop->ss->loop_chain->expr->symtree)
1890 name = se->loop->ss->loop_chain->expr->symtree->name;
1892 if (!name && se->loop && se->loop->ss && se->loop->ss->loop_chain
1893 && se->loop->ss->loop_chain->expr->symtree)
1894 name = se->loop->ss->loop_chain->expr->symtree->name;
1896 if (!name && se->loop && se->loop->ss && se->loop->ss->expr)
1898 if (se->loop->ss->expr->expr_type == EXPR_FUNCTION
1899 && se->loop->ss->expr->value.function.name)
1900 name = se->loop->ss->expr->value.function.name;
1901 else
1902 if (se->loop->ss->type == GFC_SS_CONSTRUCTOR
1903 || se->loop->ss->type == GFC_SS_SCALAR)
1904 name = "unnamed constant";
1907 /* Check lower bound. */
1908 tmp = gfc_conv_array_lbound (descriptor, n);
1909 fault = fold_build2 (LT_EXPR, boolean_type_node, index, tmp);
1910 if (name)
1911 asprintf (&msg, "%s for array '%s', lower bound of dimension %d exceeded",
1912 gfc_msg_fault, name, n+1);
1913 else
1914 asprintf (&msg, "%s, lower bound of dimension %d exceeded",
1915 gfc_msg_fault, n+1);
1916 gfc_trans_runtime_check (fault, msg, &se->pre, where);
1917 gfc_free (msg);
1919 /* Check upper bound. */
1920 tmp = gfc_conv_array_ubound (descriptor, n);
1921 fault = fold_build2 (GT_EXPR, boolean_type_node, index, tmp);
1922 if (name)
1923 asprintf (&msg, "%s for array '%s', upper bound of dimension %d exceeded",
1924 gfc_msg_fault, name, n+1);
1925 else
1926 asprintf (&msg, "%s, upper bound of dimension %d exceeded",
1927 gfc_msg_fault, n+1);
1928 gfc_trans_runtime_check (fault, msg, &se->pre, where);
1929 gfc_free (msg);
1931 return index;
1935 /* Return the offset for an index. Performs bound checking for elemental
1936 dimensions. Single element references are processed separately. */
1938 static tree
1939 gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i,
1940 gfc_array_ref * ar, tree stride)
1942 tree index;
1943 tree desc;
1944 tree data;
1946 /* Get the index into the array for this dimension. */
1947 if (ar)
1949 gcc_assert (ar->type != AR_ELEMENT);
1950 switch (ar->dimen_type[dim])
1952 case DIMEN_ELEMENT:
1953 gcc_assert (i == -1);
1954 /* Elemental dimension. */
1955 gcc_assert (info->subscript[dim]
1956 && info->subscript[dim]->type == GFC_SS_SCALAR);
1957 /* We've already translated this value outside the loop. */
1958 index = info->subscript[dim]->data.scalar.expr;
1960 if ((ar->as->type != AS_ASSUMED_SIZE && !ar->as->cp_was_assumed)
1961 || dim < ar->dimen - 1)
1962 index = gfc_trans_array_bound_check (se, info->descriptor,
1963 index, dim, &ar->where);
1964 break;
1966 case DIMEN_VECTOR:
1967 gcc_assert (info && se->loop);
1968 gcc_assert (info->subscript[dim]
1969 && info->subscript[dim]->type == GFC_SS_VECTOR);
1970 desc = info->subscript[dim]->data.info.descriptor;
1972 /* Get a zero-based index into the vector. */
1973 index = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1974 se->loop->loopvar[i], se->loop->from[i]);
1976 /* Multiply the index by the stride. */
1977 index = fold_build2 (MULT_EXPR, gfc_array_index_type,
1978 index, gfc_conv_array_stride (desc, 0));
1980 /* Read the vector to get an index into info->descriptor. */
1981 data = build_fold_indirect_ref (gfc_conv_array_data (desc));
1982 index = gfc_build_array_ref (data, index);
1983 index = gfc_evaluate_now (index, &se->pre);
1985 /* Do any bounds checking on the final info->descriptor index. */
1986 if ((ar->as->type != AS_ASSUMED_SIZE && !ar->as->cp_was_assumed)
1987 || dim < ar->dimen - 1)
1988 index = gfc_trans_array_bound_check (se, info->descriptor,
1989 index, dim, &ar->where);
1990 break;
1992 case DIMEN_RANGE:
1993 /* Scalarized dimension. */
1994 gcc_assert (info && se->loop);
1996 /* Multiply the loop variable by the stride and delta. */
1997 index = se->loop->loopvar[i];
1998 if (!integer_onep (info->stride[i]))
1999 index = fold_build2 (MULT_EXPR, gfc_array_index_type, index,
2000 info->stride[i]);
2001 if (!integer_zerop (info->delta[i]))
2002 index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index,
2003 info->delta[i]);
2004 break;
2006 default:
2007 gcc_unreachable ();
2010 else
2012 /* Temporary array or derived type component. */
2013 gcc_assert (se->loop);
2014 index = se->loop->loopvar[se->loop->order[i]];
2015 if (!integer_zerop (info->delta[i]))
2016 index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2017 index, info->delta[i]);
2020 /* Multiply by the stride. */
2021 if (!integer_onep (stride))
2022 index = fold_build2 (MULT_EXPR, gfc_array_index_type, index, stride);
2024 return index;
2028 /* Build a scalarized reference to an array. */
2030 static void
2031 gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
2033 gfc_ss_info *info;
2034 tree index;
2035 tree tmp;
2036 int n;
2038 info = &se->ss->data.info;
2039 if (ar)
2040 n = se->loop->order[0];
2041 else
2042 n = 0;
2044 index = gfc_conv_array_index_offset (se, info, info->dim[n], n, ar,
2045 info->stride0);
2046 /* Add the offset for this dimension to the stored offset for all other
2047 dimensions. */
2048 index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, info->offset);
2050 tmp = build_fold_indirect_ref (info->data);
2051 se->expr = gfc_build_array_ref (tmp, index);
2055 /* Translate access of temporary array. */
2057 void
2058 gfc_conv_tmp_array_ref (gfc_se * se)
2060 se->string_length = se->ss->string_length;
2061 gfc_conv_scalarized_array_ref (se, NULL);
2065 /* Build an array reference. se->expr already holds the array descriptor.
2066 This should be either a variable, indirect variable reference or component
2067 reference. For arrays which do not have a descriptor, se->expr will be
2068 the data pointer.
2069 a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
2071 void
2072 gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym,
2073 locus * where)
2075 int n;
2076 tree index;
2077 tree tmp;
2078 tree stride;
2079 gfc_se indexse;
2081 /* Handle scalarized references separately. */
2082 if (ar->type != AR_ELEMENT)
2084 gfc_conv_scalarized_array_ref (se, ar);
2085 gfc_advance_se_ss_chain (se);
2086 return;
2089 index = gfc_index_zero_node;
2091 /* Calculate the offsets from all the dimensions. */
2092 for (n = 0; n < ar->dimen; n++)
2094 /* Calculate the index for this dimension. */
2095 gfc_init_se (&indexse, se);
2096 gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type);
2097 gfc_add_block_to_block (&se->pre, &indexse.pre);
2099 if (flag_bounds_check &&
2100 ((ar->as->type != AS_ASSUMED_SIZE && !ar->as->cp_was_assumed)
2101 || n < ar->dimen - 1))
2103 /* Check array bounds. */
2104 tree cond;
2105 char *msg;
2107 tmp = gfc_conv_array_lbound (se->expr, n);
2108 cond = fold_build2 (LT_EXPR, boolean_type_node,
2109 indexse.expr, tmp);
2110 asprintf (&msg, "%s for array '%s', "
2111 "lower bound of dimension %d exceeded", gfc_msg_fault,
2112 sym->name, n+1);
2113 gfc_trans_runtime_check (cond, msg, &se->pre, where);
2114 gfc_free (msg);
2116 tmp = gfc_conv_array_ubound (se->expr, n);
2117 cond = fold_build2 (GT_EXPR, boolean_type_node,
2118 indexse.expr, tmp);
2119 asprintf (&msg, "%s for array '%s', "
2120 "upper bound of dimension %d exceeded", gfc_msg_fault,
2121 sym->name, n+1);
2122 gfc_trans_runtime_check (cond, msg, &se->pre, where);
2123 gfc_free (msg);
2126 /* Multiply the index by the stride. */
2127 stride = gfc_conv_array_stride (se->expr, n);
2128 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, indexse.expr,
2129 stride);
2131 /* And add it to the total. */
2132 index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
2135 tmp = gfc_conv_array_offset (se->expr);
2136 if (!integer_zerop (tmp))
2137 index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
2139 /* Access the calculated element. */
2140 tmp = gfc_conv_array_data (se->expr);
2141 tmp = build_fold_indirect_ref (tmp);
2142 se->expr = gfc_build_array_ref (tmp, index);
2146 /* Generate the code to be executed immediately before entering a
2147 scalarization loop. */
2149 static void
2150 gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
2151 stmtblock_t * pblock)
2153 tree index;
2154 tree stride;
2155 gfc_ss_info *info;
2156 gfc_ss *ss;
2157 gfc_se se;
2158 int i;
2160 /* This code will be executed before entering the scalarization loop
2161 for this dimension. */
2162 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2164 if ((ss->useflags & flag) == 0)
2165 continue;
2167 if (ss->type != GFC_SS_SECTION
2168 && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
2169 && ss->type != GFC_SS_COMPONENT)
2170 continue;
2172 info = &ss->data.info;
2174 if (dim >= info->dimen)
2175 continue;
2177 if (dim == info->dimen - 1)
2179 /* For the outermost loop calculate the offset due to any
2180 elemental dimensions. It will have been initialized with the
2181 base offset of the array. */
2182 if (info->ref)
2184 for (i = 0; i < info->ref->u.ar.dimen; i++)
2186 if (info->ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
2187 continue;
2189 gfc_init_se (&se, NULL);
2190 se.loop = loop;
2191 se.expr = info->descriptor;
2192 stride = gfc_conv_array_stride (info->descriptor, i);
2193 index = gfc_conv_array_index_offset (&se, info, i, -1,
2194 &info->ref->u.ar,
2195 stride);
2196 gfc_add_block_to_block (pblock, &se.pre);
2198 info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2199 info->offset, index);
2200 info->offset = gfc_evaluate_now (info->offset, pblock);
2203 i = loop->order[0];
2204 stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
2206 else
2207 stride = gfc_conv_array_stride (info->descriptor, 0);
2209 /* Calculate the stride of the innermost loop. Hopefully this will
2210 allow the backend optimizers to do their stuff more effectively.
2212 info->stride0 = gfc_evaluate_now (stride, pblock);
2214 else
2216 /* Add the offset for the previous loop dimension. */
2217 gfc_array_ref *ar;
2219 if (info->ref)
2221 ar = &info->ref->u.ar;
2222 i = loop->order[dim + 1];
2224 else
2226 ar = NULL;
2227 i = dim + 1;
2230 gfc_init_se (&se, NULL);
2231 se.loop = loop;
2232 se.expr = info->descriptor;
2233 stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
2234 index = gfc_conv_array_index_offset (&se, info, info->dim[i], i,
2235 ar, stride);
2236 gfc_add_block_to_block (pblock, &se.pre);
2237 info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2238 info->offset, index);
2239 info->offset = gfc_evaluate_now (info->offset, pblock);
2242 /* Remember this offset for the second loop. */
2243 if (dim == loop->temp_dim - 1)
2244 info->saved_offset = info->offset;
2249 /* Start a scalarized expression. Creates a scope and declares loop
2250 variables. */
2252 void
2253 gfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody)
2255 int dim;
2256 int n;
2257 int flags;
2259 gcc_assert (!loop->array_parameter);
2261 for (dim = loop->dimen - 1; dim >= 0; dim--)
2263 n = loop->order[dim];
2265 gfc_start_block (&loop->code[n]);
2267 /* Create the loop variable. */
2268 loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "S");
2270 if (dim < loop->temp_dim)
2271 flags = 3;
2272 else
2273 flags = 1;
2274 /* Calculate values that will be constant within this loop. */
2275 gfc_trans_preloop_setup (loop, dim, flags, &loop->code[n]);
2277 gfc_start_block (pbody);
2281 /* Generates the actual loop code for a scalarization loop. */
2283 static void
2284 gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
2285 stmtblock_t * pbody)
2287 stmtblock_t block;
2288 tree cond;
2289 tree tmp;
2290 tree loopbody;
2291 tree exit_label;
2293 loopbody = gfc_finish_block (pbody);
2295 /* Initialize the loopvar. */
2296 gfc_add_modify_expr (&loop->code[n], loop->loopvar[n], loop->from[n]);
2298 exit_label = gfc_build_label_decl (NULL_TREE);
2300 /* Generate the loop body. */
2301 gfc_init_block (&block);
2303 /* The exit condition. */
2304 cond = build2 (GT_EXPR, boolean_type_node, loop->loopvar[n], loop->to[n]);
2305 tmp = build1_v (GOTO_EXPR, exit_label);
2306 TREE_USED (exit_label) = 1;
2307 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
2308 gfc_add_expr_to_block (&block, tmp);
2310 /* The main body. */
2311 gfc_add_expr_to_block (&block, loopbody);
2313 /* Increment the loopvar. */
2314 tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2315 loop->loopvar[n], gfc_index_one_node);
2316 gfc_add_modify_expr (&block, loop->loopvar[n], tmp);
2318 /* Build the loop. */
2319 tmp = gfc_finish_block (&block);
2320 tmp = build1_v (LOOP_EXPR, tmp);
2321 gfc_add_expr_to_block (&loop->code[n], tmp);
2323 /* Add the exit label. */
2324 tmp = build1_v (LABEL_EXPR, exit_label);
2325 gfc_add_expr_to_block (&loop->code[n], tmp);
2329 /* Finishes and generates the loops for a scalarized expression. */
2331 void
2332 gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body)
2334 int dim;
2335 int n;
2336 gfc_ss *ss;
2337 stmtblock_t *pblock;
2338 tree tmp;
2340 pblock = body;
2341 /* Generate the loops. */
2342 for (dim = 0; dim < loop->dimen; dim++)
2344 n = loop->order[dim];
2345 gfc_trans_scalarized_loop_end (loop, n, pblock);
2346 loop->loopvar[n] = NULL_TREE;
2347 pblock = &loop->code[n];
2350 tmp = gfc_finish_block (pblock);
2351 gfc_add_expr_to_block (&loop->pre, tmp);
2353 /* Clear all the used flags. */
2354 for (ss = loop->ss; ss; ss = ss->loop_chain)
2355 ss->useflags = 0;
2359 /* Finish the main body of a scalarized expression, and start the secondary
2360 copying body. */
2362 void
2363 gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
2365 int dim;
2366 int n;
2367 stmtblock_t *pblock;
2368 gfc_ss *ss;
2370 pblock = body;
2371 /* We finish as many loops as are used by the temporary. */
2372 for (dim = 0; dim < loop->temp_dim - 1; dim++)
2374 n = loop->order[dim];
2375 gfc_trans_scalarized_loop_end (loop, n, pblock);
2376 loop->loopvar[n] = NULL_TREE;
2377 pblock = &loop->code[n];
2380 /* We don't want to finish the outermost loop entirely. */
2381 n = loop->order[loop->temp_dim - 1];
2382 gfc_trans_scalarized_loop_end (loop, n, pblock);
2384 /* Restore the initial offsets. */
2385 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2387 if ((ss->useflags & 2) == 0)
2388 continue;
2390 if (ss->type != GFC_SS_SECTION
2391 && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
2392 && ss->type != GFC_SS_COMPONENT)
2393 continue;
2395 ss->data.info.offset = ss->data.info.saved_offset;
2398 /* Restart all the inner loops we just finished. */
2399 for (dim = loop->temp_dim - 2; dim >= 0; dim--)
2401 n = loop->order[dim];
2403 gfc_start_block (&loop->code[n]);
2405 loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "Q");
2407 gfc_trans_preloop_setup (loop, dim, 2, &loop->code[n]);
2410 /* Start a block for the secondary copying code. */
2411 gfc_start_block (body);
2415 /* Calculate the upper bound of an array section. */
2417 static tree
2418 gfc_conv_section_upper_bound (gfc_ss * ss, int n, stmtblock_t * pblock)
2420 int dim;
2421 gfc_expr *end;
2422 tree desc;
2423 tree bound;
2424 gfc_se se;
2425 gfc_ss_info *info;
2427 gcc_assert (ss->type == GFC_SS_SECTION);
2429 info = &ss->data.info;
2430 dim = info->dim[n];
2432 if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2433 /* We'll calculate the upper bound once we have access to the
2434 vector's descriptor. */
2435 return NULL;
2437 gcc_assert (info->ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
2438 desc = info->descriptor;
2439 end = info->ref->u.ar.end[dim];
2441 if (end)
2443 /* The upper bound was specified. */
2444 gfc_init_se (&se, NULL);
2445 gfc_conv_expr_type (&se, end, gfc_array_index_type);
2446 gfc_add_block_to_block (pblock, &se.pre);
2447 bound = se.expr;
2449 else
2451 /* No upper bound was specified, so use the bound of the array. */
2452 bound = gfc_conv_array_ubound (desc, dim);
2455 return bound;
2459 /* Calculate the lower bound of an array section. */
2461 static void
2462 gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int n)
2464 gfc_expr *start;
2465 gfc_expr *end;
2466 gfc_expr *stride;
2467 tree desc;
2468 gfc_se se;
2469 gfc_ss_info *info;
2470 int dim;
2472 gcc_assert (ss->type == GFC_SS_SECTION);
2474 info = &ss->data.info;
2475 dim = info->dim[n];
2477 if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2479 /* We use a zero-based index to access the vector. */
2480 info->start[n] = gfc_index_zero_node;
2481 info->end[n] = gfc_index_zero_node;
2482 info->stride[n] = gfc_index_one_node;
2483 return;
2486 gcc_assert (info->ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
2487 desc = info->descriptor;
2488 start = info->ref->u.ar.start[dim];
2489 end = info->ref->u.ar.end[dim];
2490 stride = info->ref->u.ar.stride[dim];
2492 /* Calculate the start of the range. For vector subscripts this will
2493 be the range of the vector. */
2494 if (start)
2496 /* Specified section start. */
2497 gfc_init_se (&se, NULL);
2498 gfc_conv_expr_type (&se, start, gfc_array_index_type);
2499 gfc_add_block_to_block (&loop->pre, &se.pre);
2500 info->start[n] = se.expr;
2502 else
2504 /* No lower bound specified so use the bound of the array. */
2505 info->start[n] = gfc_conv_array_lbound (desc, dim);
2507 info->start[n] = gfc_evaluate_now (info->start[n], &loop->pre);
2509 /* Similarly calculate the end. Although this is not used in the
2510 scalarizer, it is needed when checking bounds and where the end
2511 is an expression with side-effects. */
2512 if (end)
2514 /* Specified section start. */
2515 gfc_init_se (&se, NULL);
2516 gfc_conv_expr_type (&se, end, gfc_array_index_type);
2517 gfc_add_block_to_block (&loop->pre, &se.pre);
2518 info->end[n] = se.expr;
2520 else
2522 /* No upper bound specified so use the bound of the array. */
2523 info->end[n] = gfc_conv_array_ubound (desc, dim);
2525 info->end[n] = gfc_evaluate_now (info->end[n], &loop->pre);
2527 /* Calculate the stride. */
2528 if (stride == NULL)
2529 info->stride[n] = gfc_index_one_node;
2530 else
2532 gfc_init_se (&se, NULL);
2533 gfc_conv_expr_type (&se, stride, gfc_array_index_type);
2534 gfc_add_block_to_block (&loop->pre, &se.pre);
2535 info->stride[n] = gfc_evaluate_now (se.expr, &loop->pre);
2540 /* Calculates the range start and stride for a SS chain. Also gets the
2541 descriptor and data pointer. The range of vector subscripts is the size
2542 of the vector. Array bounds are also checked. */
2544 void
2545 gfc_conv_ss_startstride (gfc_loopinfo * loop)
2547 int n;
2548 tree tmp;
2549 gfc_ss *ss;
2550 tree desc;
2552 loop->dimen = 0;
2553 /* Determine the rank of the loop. */
2554 for (ss = loop->ss;
2555 ss != gfc_ss_terminator && loop->dimen == 0; ss = ss->loop_chain)
2557 switch (ss->type)
2559 case GFC_SS_SECTION:
2560 case GFC_SS_CONSTRUCTOR:
2561 case GFC_SS_FUNCTION:
2562 case GFC_SS_COMPONENT:
2563 loop->dimen = ss->data.info.dimen;
2564 break;
2566 /* As usual, lbound and ubound are exceptions!. */
2567 case GFC_SS_INTRINSIC:
2568 switch (ss->expr->value.function.isym->generic_id)
2570 case GFC_ISYM_LBOUND:
2571 case GFC_ISYM_UBOUND:
2572 loop->dimen = ss->data.info.dimen;
2574 default:
2575 break;
2578 default:
2579 break;
2583 if (loop->dimen == 0)
2584 gfc_todo_error ("Unable to determine rank of expression");
2587 /* Loop over all the SS in the chain. */
2588 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2590 if (ss->expr && ss->expr->shape && !ss->shape)
2591 ss->shape = ss->expr->shape;
2593 switch (ss->type)
2595 case GFC_SS_SECTION:
2596 /* Get the descriptor for the array. */
2597 gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter);
2599 for (n = 0; n < ss->data.info.dimen; n++)
2600 gfc_conv_section_startstride (loop, ss, n);
2601 break;
2603 case GFC_SS_INTRINSIC:
2604 switch (ss->expr->value.function.isym->generic_id)
2606 /* Fall through to supply start and stride. */
2607 case GFC_ISYM_LBOUND:
2608 case GFC_ISYM_UBOUND:
2609 break;
2610 default:
2611 continue;
2614 case GFC_SS_CONSTRUCTOR:
2615 case GFC_SS_FUNCTION:
2616 for (n = 0; n < ss->data.info.dimen; n++)
2618 ss->data.info.start[n] = gfc_index_zero_node;
2619 ss->data.info.end[n] = gfc_index_zero_node;
2620 ss->data.info.stride[n] = gfc_index_one_node;
2622 break;
2624 default:
2625 break;
2629 /* The rest is just runtime bound checking. */
2630 if (flag_bounds_check)
2632 stmtblock_t block;
2633 tree lbound, ubound;
2634 tree end;
2635 tree size[GFC_MAX_DIMENSIONS];
2636 tree stride_pos, stride_neg, non_zerosized, tmp2;
2637 gfc_ss_info *info;
2638 char *msg;
2639 int dim;
2641 gfc_start_block (&block);
2643 for (n = 0; n < loop->dimen; n++)
2644 size[n] = NULL_TREE;
2646 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2648 if (ss->type != GFC_SS_SECTION)
2649 continue;
2651 /* TODO: range checking for mapped dimensions. */
2652 info = &ss->data.info;
2654 /* This code only checks ranges. Elemental and vector
2655 dimensions are checked later. */
2656 for (n = 0; n < loop->dimen; n++)
2658 dim = info->dim[n];
2659 if (info->ref->u.ar.dimen_type[dim] != DIMEN_RANGE)
2660 continue;
2661 if (n == info->ref->u.ar.dimen - 1
2662 && (info->ref->u.ar.as->type == AS_ASSUMED_SIZE
2663 || info->ref->u.ar.as->cp_was_assumed))
2664 continue;
2666 desc = ss->data.info.descriptor;
2668 /* This is the run-time equivalent of resolve.c's
2669 check_dimension(). The logical is more readable there
2670 than it is here, with all the trees. */
2671 lbound = gfc_conv_array_lbound (desc, dim);
2672 ubound = gfc_conv_array_ubound (desc, dim);
2673 end = info->end[n];
2675 /* Zero stride is not allowed. */
2676 tmp = fold_build2 (EQ_EXPR, boolean_type_node, info->stride[n],
2677 gfc_index_zero_node);
2678 asprintf (&msg, "Zero stride is not allowed, for dimension %d "
2679 "of array '%s'", info->dim[n]+1,
2680 ss->expr->symtree->name);
2681 gfc_trans_runtime_check (tmp, msg, &block, &ss->expr->where);
2682 gfc_free (msg);
2684 /* non_zerosized is true when the selected range is not
2685 empty. */
2686 stride_pos = fold_build2 (GT_EXPR, boolean_type_node,
2687 info->stride[n], gfc_index_zero_node);
2688 tmp = fold_build2 (LE_EXPR, boolean_type_node, info->start[n],
2689 end);
2690 stride_pos = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2691 stride_pos, tmp);
2693 stride_neg = fold_build2 (LT_EXPR, boolean_type_node,
2694 info->stride[n], gfc_index_zero_node);
2695 tmp = fold_build2 (GE_EXPR, boolean_type_node, info->start[n],
2696 end);
2697 stride_neg = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2698 stride_neg, tmp);
2699 non_zerosized = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
2700 stride_pos, stride_neg);
2702 /* Check the start of the range against the lower and upper
2703 bounds of the array, if the range is not empty. */
2704 tmp = fold_build2 (LT_EXPR, boolean_type_node, info->start[n],
2705 lbound);
2706 tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2707 non_zerosized, tmp);
2708 asprintf (&msg, "%s, lower bound of dimension %d of array '%s'"
2709 " exceeded", gfc_msg_fault, info->dim[n]+1,
2710 ss->expr->symtree->name);
2711 gfc_trans_runtime_check (tmp, msg, &block, &ss->expr->where);
2712 gfc_free (msg);
2714 tmp = fold_build2 (GT_EXPR, boolean_type_node, info->start[n],
2715 ubound);
2716 tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2717 non_zerosized, tmp);
2718 asprintf (&msg, "%s, upper bound of dimension %d of array '%s'"
2719 " exceeded", gfc_msg_fault, info->dim[n]+1,
2720 ss->expr->symtree->name);
2721 gfc_trans_runtime_check (tmp, msg, &block, &ss->expr->where);
2722 gfc_free (msg);
2724 /* Compute the last element of the range, which is not
2725 necessarily "end" (think 0:5:3, which doesn't contain 5)
2726 and check it against both lower and upper bounds. */
2727 tmp2 = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
2728 info->start[n]);
2729 tmp2 = fold_build2 (TRUNC_MOD_EXPR, gfc_array_index_type, tmp2,
2730 info->stride[n]);
2731 tmp2 = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
2732 tmp2);
2734 tmp = fold_build2 (LT_EXPR, boolean_type_node, tmp2, lbound);
2735 tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2736 non_zerosized, tmp);
2737 asprintf (&msg, "%s, lower bound of dimension %d of array '%s'"
2738 " exceeded", gfc_msg_fault, info->dim[n]+1,
2739 ss->expr->symtree->name);
2740 gfc_trans_runtime_check (tmp, msg, &block, &ss->expr->where);
2741 gfc_free (msg);
2743 tmp = fold_build2 (GT_EXPR, boolean_type_node, tmp2, ubound);
2744 tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2745 non_zerosized, tmp);
2746 asprintf (&msg, "%s, upper bound of dimension %d of array '%s'"
2747 " exceeded", gfc_msg_fault, info->dim[n]+1,
2748 ss->expr->symtree->name);
2749 gfc_trans_runtime_check (tmp, msg, &block, &ss->expr->where);
2750 gfc_free (msg);
2752 /* Check the section sizes match. */
2753 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
2754 info->start[n]);
2755 tmp = fold_build2 (FLOOR_DIV_EXPR, gfc_array_index_type, tmp,
2756 info->stride[n]);
2757 /* We remember the size of the first section, and check all the
2758 others against this. */
2759 if (size[n])
2761 tmp =
2762 fold_build2 (NE_EXPR, boolean_type_node, tmp, size[n]);
2763 asprintf (&msg, "%s, size mismatch for dimension %d "
2764 "of array '%s'", gfc_msg_bounds, info->dim[n]+1,
2765 ss->expr->symtree->name);
2766 gfc_trans_runtime_check (tmp, msg, &block, &ss->expr->where);
2767 gfc_free (msg);
2769 else
2770 size[n] = gfc_evaluate_now (tmp, &block);
2774 tmp = gfc_finish_block (&block);
2775 gfc_add_expr_to_block (&loop->pre, tmp);
2780 /* Return true if the two SS could be aliased, i.e. both point to the same data
2781 object. */
2782 /* TODO: resolve aliases based on frontend expressions. */
2784 static int
2785 gfc_could_be_alias (gfc_ss * lss, gfc_ss * rss)
2787 gfc_ref *lref;
2788 gfc_ref *rref;
2789 gfc_symbol *lsym;
2790 gfc_symbol *rsym;
2792 lsym = lss->expr->symtree->n.sym;
2793 rsym = rss->expr->symtree->n.sym;
2794 if (gfc_symbols_could_alias (lsym, rsym))
2795 return 1;
2797 if (rsym->ts.type != BT_DERIVED
2798 && lsym->ts.type != BT_DERIVED)
2799 return 0;
2801 /* For derived types we must check all the component types. We can ignore
2802 array references as these will have the same base type as the previous
2803 component ref. */
2804 for (lref = lss->expr->ref; lref != lss->data.info.ref; lref = lref->next)
2806 if (lref->type != REF_COMPONENT)
2807 continue;
2809 if (gfc_symbols_could_alias (lref->u.c.sym, rsym))
2810 return 1;
2812 for (rref = rss->expr->ref; rref != rss->data.info.ref;
2813 rref = rref->next)
2815 if (rref->type != REF_COMPONENT)
2816 continue;
2818 if (gfc_symbols_could_alias (lref->u.c.sym, rref->u.c.sym))
2819 return 1;
2823 for (rref = rss->expr->ref; rref != rss->data.info.ref; rref = rref->next)
2825 if (rref->type != REF_COMPONENT)
2826 break;
2828 if (gfc_symbols_could_alias (rref->u.c.sym, lsym))
2829 return 1;
2832 return 0;
2836 /* Resolve array data dependencies. Creates a temporary if required. */
2837 /* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
2838 dependency.c. */
2840 void
2841 gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
2842 gfc_ss * rss)
2844 gfc_ss *ss;
2845 gfc_ref *lref;
2846 gfc_ref *rref;
2847 gfc_ref *aref;
2848 int nDepend = 0;
2849 int temp_dim = 0;
2851 loop->temp_ss = NULL;
2852 aref = dest->data.info.ref;
2853 temp_dim = 0;
2855 for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
2857 if (ss->type != GFC_SS_SECTION)
2858 continue;
2860 if (gfc_could_be_alias (dest, ss)
2861 || gfc_are_equivalenced_arrays (dest->expr, ss->expr))
2863 nDepend = 1;
2864 break;
2867 if (dest->expr->symtree->n.sym == ss->expr->symtree->n.sym)
2869 lref = dest->expr->ref;
2870 rref = ss->expr->ref;
2872 nDepend = gfc_dep_resolver (lref, rref);
2873 #if 0
2874 /* TODO : loop shifting. */
2875 if (nDepend == 1)
2877 /* Mark the dimensions for LOOP SHIFTING */
2878 for (n = 0; n < loop->dimen; n++)
2880 int dim = dest->data.info.dim[n];
2882 if (lref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2883 depends[n] = 2;
2884 else if (! gfc_is_same_range (&lref->u.ar,
2885 &rref->u.ar, dim, 0))
2886 depends[n] = 1;
2889 /* Put all the dimensions with dependencies in the
2890 innermost loops. */
2891 dim = 0;
2892 for (n = 0; n < loop->dimen; n++)
2894 gcc_assert (loop->order[n] == n);
2895 if (depends[n])
2896 loop->order[dim++] = n;
2898 temp_dim = dim;
2899 for (n = 0; n < loop->dimen; n++)
2901 if (! depends[n])
2902 loop->order[dim++] = n;
2905 gcc_assert (dim == loop->dimen);
2906 break;
2908 #endif
2912 if (nDepend == 1)
2914 tree base_type = gfc_typenode_for_spec (&dest->expr->ts);
2915 if (GFC_ARRAY_TYPE_P (base_type)
2916 || GFC_DESCRIPTOR_TYPE_P (base_type))
2917 base_type = gfc_get_element_type (base_type);
2918 loop->temp_ss = gfc_get_ss ();
2919 loop->temp_ss->type = GFC_SS_TEMP;
2920 loop->temp_ss->data.temp.type = base_type;
2921 loop->temp_ss->string_length = dest->string_length;
2922 loop->temp_ss->data.temp.dimen = loop->dimen;
2923 loop->temp_ss->next = gfc_ss_terminator;
2924 gfc_add_ss_to_loop (loop, loop->temp_ss);
2926 else
2927 loop->temp_ss = NULL;
2931 /* Initialize the scalarization loop. Creates the loop variables. Determines
2932 the range of the loop variables. Creates a temporary if required.
2933 Calculates how to transform from loop variables to array indices for each
2934 expression. Also generates code for scalar expressions which have been
2935 moved outside the loop. */
2937 void
2938 gfc_conv_loop_setup (gfc_loopinfo * loop)
2940 int n;
2941 int dim;
2942 gfc_ss_info *info;
2943 gfc_ss_info *specinfo;
2944 gfc_ss *ss;
2945 tree tmp;
2946 tree len;
2947 gfc_ss *loopspec[GFC_MAX_DIMENSIONS];
2948 bool dynamic[GFC_MAX_DIMENSIONS];
2949 gfc_constructor *c;
2950 mpz_t *cshape;
2951 mpz_t i;
2953 mpz_init (i);
2954 for (n = 0; n < loop->dimen; n++)
2956 loopspec[n] = NULL;
2957 dynamic[n] = false;
2958 /* We use one SS term, and use that to determine the bounds of the
2959 loop for this dimension. We try to pick the simplest term. */
2960 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2962 if (ss->shape)
2964 /* The frontend has worked out the size for us. */
2965 loopspec[n] = ss;
2966 continue;
2969 if (ss->type == GFC_SS_CONSTRUCTOR)
2971 /* An unknown size constructor will always be rank one.
2972 Higher rank constructors will either have known shape,
2973 or still be wrapped in a call to reshape. */
2974 gcc_assert (loop->dimen == 1);
2976 /* Always prefer to use the constructor bounds if the size
2977 can be determined at compile time. Prefer not to otherwise,
2978 since the general case involves realloc, and it's better to
2979 avoid that overhead if possible. */
2980 c = ss->expr->value.constructor;
2981 dynamic[n] = gfc_get_array_constructor_size (&i, c);
2982 if (!dynamic[n] || !loopspec[n])
2983 loopspec[n] = ss;
2984 continue;
2987 /* TODO: Pick the best bound if we have a choice between a
2988 function and something else. */
2989 if (ss->type == GFC_SS_FUNCTION)
2991 loopspec[n] = ss;
2992 continue;
2995 if (ss->type != GFC_SS_SECTION)
2996 continue;
2998 if (loopspec[n])
2999 specinfo = &loopspec[n]->data.info;
3000 else
3001 specinfo = NULL;
3002 info = &ss->data.info;
3004 if (!specinfo)
3005 loopspec[n] = ss;
3006 /* Criteria for choosing a loop specifier (most important first):
3007 doesn't need realloc
3008 stride of one
3009 known stride
3010 known lower bound
3011 known upper bound
3013 else if (loopspec[n]->type == GFC_SS_CONSTRUCTOR && dynamic[n])
3014 loopspec[n] = ss;
3015 else if (integer_onep (info->stride[n])
3016 && !integer_onep (specinfo->stride[n]))
3017 loopspec[n] = ss;
3018 else if (INTEGER_CST_P (info->stride[n])
3019 && !INTEGER_CST_P (specinfo->stride[n]))
3020 loopspec[n] = ss;
3021 else if (INTEGER_CST_P (info->start[n])
3022 && !INTEGER_CST_P (specinfo->start[n]))
3023 loopspec[n] = ss;
3024 /* We don't work out the upper bound.
3025 else if (INTEGER_CST_P (info->finish[n])
3026 && ! INTEGER_CST_P (specinfo->finish[n]))
3027 loopspec[n] = ss; */
3030 if (!loopspec[n])
3031 gfc_todo_error ("Unable to find scalarization loop specifier");
3033 info = &loopspec[n]->data.info;
3035 /* Set the extents of this range. */
3036 cshape = loopspec[n]->shape;
3037 if (cshape && INTEGER_CST_P (info->start[n])
3038 && INTEGER_CST_P (info->stride[n]))
3040 loop->from[n] = info->start[n];
3041 mpz_set (i, cshape[n]);
3042 mpz_sub_ui (i, i, 1);
3043 /* To = from + (size - 1) * stride. */
3044 tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
3045 if (!integer_onep (info->stride[n]))
3046 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3047 tmp, info->stride[n]);
3048 loop->to[n] = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3049 loop->from[n], tmp);
3051 else
3053 loop->from[n] = info->start[n];
3054 switch (loopspec[n]->type)
3056 case GFC_SS_CONSTRUCTOR:
3057 /* The upper bound is calculated when we expand the
3058 constructor. */
3059 gcc_assert (loop->to[n] == NULL_TREE);
3060 break;
3062 case GFC_SS_SECTION:
3063 loop->to[n] = gfc_conv_section_upper_bound (loopspec[n], n,
3064 &loop->pre);
3065 break;
3067 case GFC_SS_FUNCTION:
3068 /* The loop bound will be set when we generate the call. */
3069 gcc_assert (loop->to[n] == NULL_TREE);
3070 break;
3072 default:
3073 gcc_unreachable ();
3077 /* Transform everything so we have a simple incrementing variable. */
3078 if (integer_onep (info->stride[n]))
3079 info->delta[n] = gfc_index_zero_node;
3080 else
3082 /* Set the delta for this section. */
3083 info->delta[n] = gfc_evaluate_now (loop->from[n], &loop->pre);
3084 /* Number of iterations is (end - start + step) / step.
3085 with start = 0, this simplifies to
3086 last = end / step;
3087 for (i = 0; i<=last; i++){...}; */
3088 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3089 loop->to[n], loop->from[n]);
3090 tmp = fold_build2 (TRUNC_DIV_EXPR, gfc_array_index_type,
3091 tmp, info->stride[n]);
3092 loop->to[n] = gfc_evaluate_now (tmp, &loop->pre);
3093 /* Make the loop variable start at 0. */
3094 loop->from[n] = gfc_index_zero_node;
3098 /* Add all the scalar code that can be taken out of the loops.
3099 This may include calculating the loop bounds, so do it before
3100 allocating the temporary. */
3101 gfc_add_loop_ss_code (loop, loop->ss, false);
3103 /* If we want a temporary then create it. */
3104 if (loop->temp_ss != NULL)
3106 gcc_assert (loop->temp_ss->type == GFC_SS_TEMP);
3107 tmp = loop->temp_ss->data.temp.type;
3108 len = loop->temp_ss->string_length;
3109 n = loop->temp_ss->data.temp.dimen;
3110 memset (&loop->temp_ss->data.info, 0, sizeof (gfc_ss_info));
3111 loop->temp_ss->type = GFC_SS_SECTION;
3112 loop->temp_ss->data.info.dimen = n;
3113 gfc_trans_create_temp_array (&loop->pre, &loop->post, loop,
3114 &loop->temp_ss->data.info, tmp, false, true,
3115 false, false);
3118 for (n = 0; n < loop->temp_dim; n++)
3119 loopspec[loop->order[n]] = NULL;
3121 mpz_clear (i);
3123 /* For array parameters we don't have loop variables, so don't calculate the
3124 translations. */
3125 if (loop->array_parameter)
3126 return;
3128 /* Calculate the translation from loop variables to array indices. */
3129 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3131 if (ss->type != GFC_SS_SECTION && ss->type != GFC_SS_COMPONENT)
3132 continue;
3134 info = &ss->data.info;
3136 for (n = 0; n < info->dimen; n++)
3138 dim = info->dim[n];
3140 /* If we are specifying the range the delta is already set. */
3141 if (loopspec[n] != ss)
3143 /* Calculate the offset relative to the loop variable.
3144 First multiply by the stride. */
3145 tmp = loop->from[n];
3146 if (!integer_onep (info->stride[n]))
3147 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3148 tmp, info->stride[n]);
3150 /* Then subtract this from our starting value. */
3151 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3152 info->start[n], tmp);
3154 info->delta[n] = gfc_evaluate_now (tmp, &loop->pre);
3161 /* Fills in an array descriptor, and returns the size of the array. The size
3162 will be a simple_val, ie a variable or a constant. Also calculates the
3163 offset of the base. Returns the size of the array.
3165 stride = 1;
3166 offset = 0;
3167 for (n = 0; n < rank; n++)
3169 a.lbound[n] = specified_lower_bound;
3170 offset = offset + a.lbond[n] * stride;
3171 size = 1 - lbound;
3172 a.ubound[n] = specified_upper_bound;
3173 a.stride[n] = stride;
3174 size = ubound + size; //size = ubound + 1 - lbound
3175 stride = stride * size;
3177 return (stride);
3178 } */
3179 /*GCC ARRAYS*/
3181 static tree
3182 gfc_array_init_size (tree descriptor, int rank, tree * poffset,
3183 gfc_expr ** lower, gfc_expr ** upper,
3184 stmtblock_t * pblock)
3186 tree type;
3187 tree tmp;
3188 tree size;
3189 tree offset;
3190 tree stride;
3191 tree cond;
3192 tree or_expr;
3193 tree thencase;
3194 tree elsecase;
3195 tree var;
3196 stmtblock_t thenblock;
3197 stmtblock_t elseblock;
3198 gfc_expr *ubound;
3199 gfc_se se;
3200 int n;
3202 type = TREE_TYPE (descriptor);
3204 stride = gfc_index_one_node;
3205 offset = gfc_index_zero_node;
3207 /* Set the dtype. */
3208 tmp = gfc_conv_descriptor_dtype (descriptor);
3209 gfc_add_modify_expr (pblock, tmp, gfc_get_dtype (TREE_TYPE (descriptor)));
3211 or_expr = NULL_TREE;
3213 for (n = 0; n < rank; n++)
3215 /* We have 3 possibilities for determining the size of the array:
3216 lower == NULL => lbound = 1, ubound = upper[n]
3217 upper[n] = NULL => lbound = 1, ubound = lower[n]
3218 upper[n] != NULL => lbound = lower[n], ubound = upper[n] */
3219 ubound = upper[n];
3221 /* Set lower bound. */
3222 gfc_init_se (&se, NULL);
3223 if (lower == NULL)
3224 se.expr = gfc_index_one_node;
3225 else
3227 gcc_assert (lower[n]);
3228 if (ubound)
3230 gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
3231 gfc_add_block_to_block (pblock, &se.pre);
3233 else
3235 se.expr = gfc_index_one_node;
3236 ubound = lower[n];
3239 tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[n]);
3240 gfc_add_modify_expr (pblock, tmp, se.expr);
3242 /* Work out the offset for this component. */
3243 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, se.expr, stride);
3244 offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3246 /* Start the calculation for the size of this dimension. */
3247 size = build2 (MINUS_EXPR, gfc_array_index_type,
3248 gfc_index_one_node, se.expr);
3250 /* Set upper bound. */
3251 gfc_init_se (&se, NULL);
3252 gcc_assert (ubound);
3253 gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
3254 gfc_add_block_to_block (pblock, &se.pre);
3256 tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[n]);
3257 gfc_add_modify_expr (pblock, tmp, se.expr);
3259 /* Store the stride. */
3260 tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[n]);
3261 gfc_add_modify_expr (pblock, tmp, stride);
3263 /* Calculate the size of this dimension. */
3264 size = fold_build2 (PLUS_EXPR, gfc_array_index_type, se.expr, size);
3266 /* Check wether the size for this dimension is negative. */
3267 cond = fold_build2 (LE_EXPR, boolean_type_node, size,
3268 gfc_index_zero_node);
3269 if (n == 0)
3270 or_expr = cond;
3271 else
3272 or_expr = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, or_expr, cond);
3274 /* Multiply the stride by the number of elements in this dimension. */
3275 stride = fold_build2 (MULT_EXPR, gfc_array_index_type, stride, size);
3276 stride = gfc_evaluate_now (stride, pblock);
3279 /* The stride is the number of elements in the array, so multiply by the
3280 size of an element to get the total size. */
3281 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
3282 size = fold_build2 (MULT_EXPR, gfc_array_index_type, stride, tmp);
3284 if (poffset != NULL)
3286 offset = gfc_evaluate_now (offset, pblock);
3287 *poffset = offset;
3290 if (integer_zerop (or_expr))
3291 return size;
3292 if (integer_onep (or_expr))
3293 return gfc_index_zero_node;
3295 var = gfc_create_var (TREE_TYPE (size), "size");
3296 gfc_start_block (&thenblock);
3297 gfc_add_modify_expr (&thenblock, var, gfc_index_zero_node);
3298 thencase = gfc_finish_block (&thenblock);
3300 gfc_start_block (&elseblock);
3301 gfc_add_modify_expr (&elseblock, var, size);
3302 elsecase = gfc_finish_block (&elseblock);
3304 tmp = gfc_evaluate_now (or_expr, pblock);
3305 tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
3306 gfc_add_expr_to_block (pblock, tmp);
3308 return var;
3312 /* Initializes the descriptor and generates a call to _gfor_allocate. Does
3313 the work for an ALLOCATE statement. */
3314 /*GCC ARRAYS*/
3316 bool
3317 gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree pstat)
3319 tree tmp;
3320 tree pointer;
3321 tree allocate;
3322 tree offset;
3323 tree size;
3324 gfc_expr **lower;
3325 gfc_expr **upper;
3326 gfc_ref *ref, *prev_ref = NULL;
3327 bool allocatable_array;
3329 ref = expr->ref;
3331 /* Find the last reference in the chain. */
3332 while (ref && ref->next != NULL)
3334 gcc_assert (ref->type != REF_ARRAY || ref->u.ar.type == AR_ELEMENT);
3335 prev_ref = ref;
3336 ref = ref->next;
3339 if (ref == NULL || ref->type != REF_ARRAY)
3340 return false;
3342 if (!prev_ref)
3343 allocatable_array = expr->symtree->n.sym->attr.allocatable;
3344 else
3345 allocatable_array = prev_ref->u.c.component->allocatable;
3347 /* Figure out the size of the array. */
3348 switch (ref->u.ar.type)
3350 case AR_ELEMENT:
3351 lower = NULL;
3352 upper = ref->u.ar.start;
3353 break;
3355 case AR_FULL:
3356 gcc_assert (ref->u.ar.as->type == AS_EXPLICIT);
3358 lower = ref->u.ar.as->lower;
3359 upper = ref->u.ar.as->upper;
3360 break;
3362 case AR_SECTION:
3363 lower = ref->u.ar.start;
3364 upper = ref->u.ar.end;
3365 break;
3367 default:
3368 gcc_unreachable ();
3369 break;
3372 size = gfc_array_init_size (se->expr, ref->u.ar.as->rank, &offset,
3373 lower, upper, &se->pre);
3375 /* Allocate memory to store the data. */
3376 pointer = gfc_conv_descriptor_data_get (se->expr);
3377 STRIP_NOPS (pointer);
3379 if (TYPE_PRECISION (gfc_array_index_type) == 32)
3381 if (allocatable_array)
3382 allocate = gfor_fndecl_allocate_array;
3383 else
3384 allocate = gfor_fndecl_allocate;
3386 else if (TYPE_PRECISION (gfc_array_index_type) == 64)
3388 if (allocatable_array)
3389 allocate = gfor_fndecl_allocate64_array;
3390 else
3391 allocate = gfor_fndecl_allocate64;
3393 else
3394 gcc_unreachable ();
3396 tmp = NULL_TREE;
3397 /* The allocate_array variants take the old pointer as first argument. */
3398 if (allocatable_array)
3399 tmp = gfc_chainon_list (tmp, pointer);
3400 tmp = gfc_chainon_list (tmp, size);
3401 tmp = gfc_chainon_list (tmp, pstat);
3402 tmp = build_function_call_expr (allocate, tmp);
3403 tmp = build2 (MODIFY_EXPR, void_type_node, pointer, tmp);
3404 gfc_add_expr_to_block (&se->pre, tmp);
3406 tmp = gfc_conv_descriptor_offset (se->expr);
3407 gfc_add_modify_expr (&se->pre, tmp, offset);
3409 if (expr->ts.type == BT_DERIVED
3410 && expr->ts.derived->attr.alloc_comp)
3412 tmp = gfc_nullify_alloc_comp (expr->ts.derived, se->expr,
3413 ref->u.ar.as->rank);
3414 gfc_add_expr_to_block (&se->pre, tmp);
3417 return true;
3421 /* Deallocate an array variable. Also used when an allocated variable goes
3422 out of scope. */
3423 /*GCC ARRAYS*/
3425 tree
3426 gfc_array_deallocate (tree descriptor, tree pstat)
3428 tree var;
3429 tree tmp;
3430 stmtblock_t block;
3432 gfc_start_block (&block);
3433 /* Get a pointer to the data. */
3434 var = gfc_conv_descriptor_data_get (descriptor);
3435 STRIP_NOPS (var);
3437 /* Parameter is the address of the data component. */
3438 tmp = gfc_chainon_list (NULL_TREE, var);
3439 tmp = gfc_chainon_list (tmp, pstat);
3440 tmp = build_function_call_expr (gfor_fndecl_deallocate, tmp);
3441 gfc_add_expr_to_block (&block, tmp);
3443 /* Zero the data pointer. */
3444 tmp = build2 (MODIFY_EXPR, void_type_node,
3445 var, build_int_cst (TREE_TYPE (var), 0));
3446 gfc_add_expr_to_block (&block, tmp);
3448 return gfc_finish_block (&block);
3452 /* Create an array constructor from an initialization expression.
3453 We assume the frontend already did any expansions and conversions. */
3455 tree
3456 gfc_conv_array_initializer (tree type, gfc_expr * expr)
3458 gfc_constructor *c;
3459 tree tmp;
3460 mpz_t maxval;
3461 gfc_se se;
3462 HOST_WIDE_INT hi;
3463 unsigned HOST_WIDE_INT lo;
3464 tree index, range;
3465 VEC(constructor_elt,gc) *v = NULL;
3467 switch (expr->expr_type)
3469 case EXPR_CONSTANT:
3470 case EXPR_STRUCTURE:
3471 /* A single scalar or derived type value. Create an array with all
3472 elements equal to that value. */
3473 gfc_init_se (&se, NULL);
3475 if (expr->expr_type == EXPR_CONSTANT)
3476 gfc_conv_constant (&se, expr);
3477 else
3478 gfc_conv_structure (&se, expr, 1);
3480 tmp = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3481 gcc_assert (tmp && INTEGER_CST_P (tmp));
3482 hi = TREE_INT_CST_HIGH (tmp);
3483 lo = TREE_INT_CST_LOW (tmp);
3484 lo++;
3485 if (lo == 0)
3486 hi++;
3487 /* This will probably eat buckets of memory for large arrays. */
3488 while (hi != 0 || lo != 0)
3490 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, se.expr);
3491 if (lo == 0)
3492 hi--;
3493 lo--;
3495 break;
3497 case EXPR_ARRAY:
3498 /* Create a vector of all the elements. */
3499 for (c = expr->value.constructor; c; c = c->next)
3501 if (c->iterator)
3503 /* Problems occur when we get something like
3504 integer :: a(lots) = (/(i, i=1,lots)/) */
3505 /* TODO: Unexpanded array initializers. */
3506 internal_error
3507 ("Possible frontend bug: array constructor not expanded");
3509 if (mpz_cmp_si (c->n.offset, 0) != 0)
3510 index = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
3511 else
3512 index = NULL_TREE;
3513 mpz_init (maxval);
3514 if (mpz_cmp_si (c->repeat, 0) != 0)
3516 tree tmp1, tmp2;
3518 mpz_set (maxval, c->repeat);
3519 mpz_add (maxval, c->n.offset, maxval);
3520 mpz_sub_ui (maxval, maxval, 1);
3521 tmp2 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
3522 if (mpz_cmp_si (c->n.offset, 0) != 0)
3524 mpz_add_ui (maxval, c->n.offset, 1);
3525 tmp1 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
3527 else
3528 tmp1 = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
3530 range = build2 (RANGE_EXPR, integer_type_node, tmp1, tmp2);
3532 else
3533 range = NULL;
3534 mpz_clear (maxval);
3536 gfc_init_se (&se, NULL);
3537 switch (c->expr->expr_type)
3539 case EXPR_CONSTANT:
3540 gfc_conv_constant (&se, c->expr);
3541 if (range == NULL_TREE)
3542 CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3543 else
3545 if (index != NULL_TREE)
3546 CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3547 CONSTRUCTOR_APPEND_ELT (v, range, se.expr);
3549 break;
3551 case EXPR_STRUCTURE:
3552 gfc_conv_structure (&se, c->expr, 1);
3553 CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3554 break;
3556 default:
3557 gcc_unreachable ();
3560 break;
3562 case EXPR_NULL:
3563 return gfc_build_null_descriptor (type);
3565 default:
3566 gcc_unreachable ();
3569 /* Create a constructor from the list of elements. */
3570 tmp = build_constructor (type, v);
3571 TREE_CONSTANT (tmp) = 1;
3572 TREE_INVARIANT (tmp) = 1;
3573 return tmp;
3577 /* Generate code to evaluate non-constant array bounds. Sets *poffset and
3578 returns the size (in elements) of the array. */
3580 static tree
3581 gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
3582 stmtblock_t * pblock)
3584 gfc_array_spec *as;
3585 tree size;
3586 tree stride;
3587 tree offset;
3588 tree ubound;
3589 tree lbound;
3590 tree tmp;
3591 gfc_se se;
3593 int dim;
3595 as = sym->as;
3597 size = gfc_index_one_node;
3598 offset = gfc_index_zero_node;
3599 for (dim = 0; dim < as->rank; dim++)
3601 /* Evaluate non-constant array bound expressions. */
3602 lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
3603 if (as->lower[dim] && !INTEGER_CST_P (lbound))
3605 gfc_init_se (&se, NULL);
3606 gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
3607 gfc_add_block_to_block (pblock, &se.pre);
3608 gfc_add_modify_expr (pblock, lbound, se.expr);
3610 ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
3611 if (as->upper[dim] && !INTEGER_CST_P (ubound))
3613 gfc_init_se (&se, NULL);
3614 gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
3615 gfc_add_block_to_block (pblock, &se.pre);
3616 gfc_add_modify_expr (pblock, ubound, se.expr);
3618 /* The offset of this dimension. offset = offset - lbound * stride. */
3619 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, size);
3620 offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3622 /* The size of this dimension, and the stride of the next. */
3623 if (dim + 1 < as->rank)
3624 stride = GFC_TYPE_ARRAY_STRIDE (type, dim + 1);
3625 else
3626 stride = GFC_TYPE_ARRAY_SIZE (type);
3628 if (ubound != NULL_TREE && !(stride && INTEGER_CST_P (stride)))
3630 /* Calculate stride = size * (ubound + 1 - lbound). */
3631 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3632 gfc_index_one_node, lbound);
3633 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, ubound, tmp);
3634 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
3635 if (stride)
3636 gfc_add_modify_expr (pblock, stride, tmp);
3637 else
3638 stride = gfc_evaluate_now (tmp, pblock);
3640 /* Make sure that negative size arrays are translated
3641 to being zero size. */
3642 tmp = build2 (GE_EXPR, boolean_type_node,
3643 stride, gfc_index_zero_node);
3644 tmp = build3 (COND_EXPR, gfc_array_index_type, tmp,
3645 stride, gfc_index_zero_node);
3646 gfc_add_modify_expr (pblock, stride, tmp);
3649 size = stride;
3652 gfc_trans_vla_type_sizes (sym, pblock);
3654 *poffset = offset;
3655 return size;
3659 /* Generate code to initialize/allocate an array variable. */
3661 tree
3662 gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, tree fnbody)
3664 stmtblock_t block;
3665 tree type;
3666 tree tmp;
3667 tree fndecl;
3668 tree size;
3669 tree offset;
3670 bool onstack;
3672 gcc_assert (!(sym->attr.pointer || sym->attr.allocatable));
3674 /* Do nothing for USEd variables. */
3675 if (sym->attr.use_assoc)
3676 return fnbody;
3678 type = TREE_TYPE (decl);
3679 gcc_assert (GFC_ARRAY_TYPE_P (type));
3680 onstack = TREE_CODE (type) != POINTER_TYPE;
3682 gfc_start_block (&block);
3684 /* Evaluate character string length. */
3685 if (sym->ts.type == BT_CHARACTER
3686 && onstack && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3688 gfc_trans_init_string_length (sym->ts.cl, &block);
3690 gfc_trans_vla_type_sizes (sym, &block);
3692 /* Emit a DECL_EXPR for this variable, which will cause the
3693 gimplifier to allocate storage, and all that good stuff. */
3694 tmp = build1 (DECL_EXPR, TREE_TYPE (decl), decl);
3695 gfc_add_expr_to_block (&block, tmp);
3698 if (onstack)
3700 gfc_add_expr_to_block (&block, fnbody);
3701 return gfc_finish_block (&block);
3704 type = TREE_TYPE (type);
3706 gcc_assert (!sym->attr.use_assoc);
3707 gcc_assert (!TREE_STATIC (decl));
3708 gcc_assert (!sym->module);
3710 if (sym->ts.type == BT_CHARACTER
3711 && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3712 gfc_trans_init_string_length (sym->ts.cl, &block);
3714 size = gfc_trans_array_bounds (type, sym, &offset, &block);
3716 /* Don't actually allocate space for Cray Pointees. */
3717 if (sym->attr.cray_pointee)
3719 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3720 gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3721 gfc_add_expr_to_block (&block, fnbody);
3722 return gfc_finish_block (&block);
3725 /* The size is the number of elements in the array, so multiply by the
3726 size of an element to get the total size. */
3727 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
3728 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
3730 /* Allocate memory to hold the data. */
3731 tmp = gfc_chainon_list (NULL_TREE, size);
3733 if (gfc_index_integer_kind == 4)
3734 fndecl = gfor_fndecl_internal_malloc;
3735 else if (gfc_index_integer_kind == 8)
3736 fndecl = gfor_fndecl_internal_malloc64;
3737 else
3738 gcc_unreachable ();
3739 tmp = build_function_call_expr (fndecl, tmp);
3740 tmp = fold (convert (TREE_TYPE (decl), tmp));
3741 gfc_add_modify_expr (&block, decl, tmp);
3743 /* Set offset of the array. */
3744 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3745 gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3748 /* Automatic arrays should not have initializers. */
3749 gcc_assert (!sym->value);
3751 gfc_add_expr_to_block (&block, fnbody);
3753 /* Free the temporary. */
3754 tmp = convert (pvoid_type_node, decl);
3755 tmp = gfc_chainon_list (NULL_TREE, tmp);
3756 tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
3757 gfc_add_expr_to_block (&block, tmp);
3759 return gfc_finish_block (&block);
3763 /* Generate entry and exit code for g77 calling convention arrays. */
3765 tree
3766 gfc_trans_g77_array (gfc_symbol * sym, tree body)
3768 tree parm;
3769 tree type;
3770 locus loc;
3771 tree offset;
3772 tree tmp;
3773 tree stmt;
3774 stmtblock_t block;
3776 gfc_get_backend_locus (&loc);
3777 gfc_set_backend_locus (&sym->declared_at);
3779 /* Descriptor type. */
3780 parm = sym->backend_decl;
3781 type = TREE_TYPE (parm);
3782 gcc_assert (GFC_ARRAY_TYPE_P (type));
3784 gfc_start_block (&block);
3786 if (sym->ts.type == BT_CHARACTER
3787 && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
3788 gfc_trans_init_string_length (sym->ts.cl, &block);
3790 /* Evaluate the bounds of the array. */
3791 gfc_trans_array_bounds (type, sym, &offset, &block);
3793 /* Set the offset. */
3794 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3795 gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3797 /* Set the pointer itself if we aren't using the parameter directly. */
3798 if (TREE_CODE (parm) != PARM_DECL)
3800 tmp = convert (TREE_TYPE (parm), GFC_DECL_SAVED_DESCRIPTOR (parm));
3801 gfc_add_modify_expr (&block, parm, tmp);
3803 stmt = gfc_finish_block (&block);
3805 gfc_set_backend_locus (&loc);
3807 gfc_start_block (&block);
3809 /* Add the initialization code to the start of the function. */
3811 if (sym->attr.optional || sym->attr.not_always_present)
3813 tmp = gfc_conv_expr_present (sym);
3814 stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3817 gfc_add_expr_to_block (&block, stmt);
3818 gfc_add_expr_to_block (&block, body);
3820 return gfc_finish_block (&block);
3824 /* Modify the descriptor of an array parameter so that it has the
3825 correct lower bound. Also move the upper bound accordingly.
3826 If the array is not packed, it will be copied into a temporary.
3827 For each dimension we set the new lower and upper bounds. Then we copy the
3828 stride and calculate the offset for this dimension. We also work out
3829 what the stride of a packed array would be, and see it the two match.
3830 If the array need repacking, we set the stride to the values we just
3831 calculated, recalculate the offset and copy the array data.
3832 Code is also added to copy the data back at the end of the function.
3835 tree
3836 gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
3838 tree size;
3839 tree type;
3840 tree offset;
3841 locus loc;
3842 stmtblock_t block;
3843 stmtblock_t cleanup;
3844 tree lbound;
3845 tree ubound;
3846 tree dubound;
3847 tree dlbound;
3848 tree dumdesc;
3849 tree tmp;
3850 tree stmt;
3851 tree stride, stride2;
3852 tree stmt_packed;
3853 tree stmt_unpacked;
3854 tree partial;
3855 gfc_se se;
3856 int n;
3857 int checkparm;
3858 int no_repack;
3859 bool optional_arg;
3861 /* Do nothing for pointer and allocatable arrays. */
3862 if (sym->attr.pointer || sym->attr.allocatable)
3863 return body;
3865 if (sym->attr.dummy && gfc_is_nodesc_array (sym))
3866 return gfc_trans_g77_array (sym, body);
3868 gfc_get_backend_locus (&loc);
3869 gfc_set_backend_locus (&sym->declared_at);
3871 /* Descriptor type. */
3872 type = TREE_TYPE (tmpdesc);
3873 gcc_assert (GFC_ARRAY_TYPE_P (type));
3874 dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3875 dumdesc = build_fold_indirect_ref (dumdesc);
3876 gfc_start_block (&block);
3878 if (sym->ts.type == BT_CHARACTER
3879 && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
3880 gfc_trans_init_string_length (sym->ts.cl, &block);
3882 checkparm = (sym->as->type == AS_EXPLICIT && flag_bounds_check);
3884 no_repack = !(GFC_DECL_PACKED_ARRAY (tmpdesc)
3885 || GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc));
3887 if (GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc))
3889 /* For non-constant shape arrays we only check if the first dimension
3890 is contiguous. Repacking higher dimensions wouldn't gain us
3891 anything as we still don't know the array stride. */
3892 partial = gfc_create_var (boolean_type_node, "partial");
3893 TREE_USED (partial) = 1;
3894 tmp = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
3895 tmp = fold_build2 (EQ_EXPR, boolean_type_node, tmp, gfc_index_one_node);
3896 gfc_add_modify_expr (&block, partial, tmp);
3898 else
3900 partial = NULL_TREE;
3903 /* The naming of stmt_unpacked and stmt_packed may be counter-intuitive
3904 here, however I think it does the right thing. */
3905 if (no_repack)
3907 /* Set the first stride. */
3908 stride = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
3909 stride = gfc_evaluate_now (stride, &block);
3911 tmp = build2 (EQ_EXPR, boolean_type_node, stride, gfc_index_zero_node);
3912 tmp = build3 (COND_EXPR, gfc_array_index_type, tmp,
3913 gfc_index_one_node, stride);
3914 stride = GFC_TYPE_ARRAY_STRIDE (type, 0);
3915 gfc_add_modify_expr (&block, stride, tmp);
3917 /* Allow the user to disable array repacking. */
3918 stmt_unpacked = NULL_TREE;
3920 else
3922 gcc_assert (integer_onep (GFC_TYPE_ARRAY_STRIDE (type, 0)));
3923 /* A library call to repack the array if necessary. */
3924 tmp = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3925 tmp = gfc_chainon_list (NULL_TREE, tmp);
3926 stmt_unpacked = build_function_call_expr (gfor_fndecl_in_pack, tmp);
3928 stride = gfc_index_one_node;
3931 /* This is for the case where the array data is used directly without
3932 calling the repack function. */
3933 if (no_repack || partial != NULL_TREE)
3934 stmt_packed = gfc_conv_descriptor_data_get (dumdesc);
3935 else
3936 stmt_packed = NULL_TREE;
3938 /* Assign the data pointer. */
3939 if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
3941 /* Don't repack unknown shape arrays when the first stride is 1. */
3942 tmp = build3 (COND_EXPR, TREE_TYPE (stmt_packed), partial,
3943 stmt_packed, stmt_unpacked);
3945 else
3946 tmp = stmt_packed != NULL_TREE ? stmt_packed : stmt_unpacked;
3947 gfc_add_modify_expr (&block, tmpdesc, fold_convert (type, tmp));
3949 offset = gfc_index_zero_node;
3950 size = gfc_index_one_node;
3952 /* Evaluate the bounds of the array. */
3953 for (n = 0; n < sym->as->rank; n++)
3955 if (checkparm || !sym->as->upper[n])
3957 /* Get the bounds of the actual parameter. */
3958 dubound = gfc_conv_descriptor_ubound (dumdesc, gfc_rank_cst[n]);
3959 dlbound = gfc_conv_descriptor_lbound (dumdesc, gfc_rank_cst[n]);
3961 else
3963 dubound = NULL_TREE;
3964 dlbound = NULL_TREE;
3967 lbound = GFC_TYPE_ARRAY_LBOUND (type, n);
3968 if (!INTEGER_CST_P (lbound))
3970 gfc_init_se (&se, NULL);
3971 gfc_conv_expr_type (&se, sym->as->lower[n],
3972 gfc_array_index_type);
3973 gfc_add_block_to_block (&block, &se.pre);
3974 gfc_add_modify_expr (&block, lbound, se.expr);
3977 ubound = GFC_TYPE_ARRAY_UBOUND (type, n);
3978 /* Set the desired upper bound. */
3979 if (sym->as->upper[n])
3981 /* We know what we want the upper bound to be. */
3982 if (!INTEGER_CST_P (ubound))
3984 gfc_init_se (&se, NULL);
3985 gfc_conv_expr_type (&se, sym->as->upper[n],
3986 gfc_array_index_type);
3987 gfc_add_block_to_block (&block, &se.pre);
3988 gfc_add_modify_expr (&block, ubound, se.expr);
3991 /* Check the sizes match. */
3992 if (checkparm)
3994 /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)). */
3995 char * msg;
3997 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3998 ubound, lbound);
3999 stride2 = build2 (MINUS_EXPR, gfc_array_index_type,
4000 dubound, dlbound);
4001 tmp = fold_build2 (NE_EXPR, gfc_array_index_type, tmp, stride2);
4002 asprintf (&msg, "%s for dimension %d of array '%s'",
4003 gfc_msg_bounds, n+1, sym->name);
4004 gfc_trans_runtime_check (tmp, msg, &block, &loc);
4005 gfc_free (msg);
4008 else
4010 /* For assumed shape arrays move the upper bound by the same amount
4011 as the lower bound. */
4012 tmp = build2 (MINUS_EXPR, gfc_array_index_type, dubound, dlbound);
4013 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp, lbound);
4014 gfc_add_modify_expr (&block, ubound, tmp);
4016 /* The offset of this dimension. offset = offset - lbound * stride. */
4017 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, stride);
4018 offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
4020 /* The size of this dimension, and the stride of the next. */
4021 if (n + 1 < sym->as->rank)
4023 stride = GFC_TYPE_ARRAY_STRIDE (type, n + 1);
4025 if (no_repack || partial != NULL_TREE)
4027 stmt_unpacked =
4028 gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[n+1]);
4031 /* Figure out the stride if not a known constant. */
4032 if (!INTEGER_CST_P (stride))
4034 if (no_repack)
4035 stmt_packed = NULL_TREE;
4036 else
4038 /* Calculate stride = size * (ubound + 1 - lbound). */
4039 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4040 gfc_index_one_node, lbound);
4041 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4042 ubound, tmp);
4043 size = fold_build2 (MULT_EXPR, gfc_array_index_type,
4044 size, tmp);
4045 stmt_packed = size;
4048 /* Assign the stride. */
4049 if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
4050 tmp = build3 (COND_EXPR, gfc_array_index_type, partial,
4051 stmt_unpacked, stmt_packed);
4052 else
4053 tmp = (stmt_packed != NULL_TREE) ? stmt_packed : stmt_unpacked;
4054 gfc_add_modify_expr (&block, stride, tmp);
4057 else
4059 stride = GFC_TYPE_ARRAY_SIZE (type);
4061 if (stride && !INTEGER_CST_P (stride))
4063 /* Calculate size = stride * (ubound + 1 - lbound). */
4064 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4065 gfc_index_one_node, lbound);
4066 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4067 ubound, tmp);
4068 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
4069 GFC_TYPE_ARRAY_STRIDE (type, n), tmp);
4070 gfc_add_modify_expr (&block, stride, tmp);
4075 /* Set the offset. */
4076 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
4077 gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
4079 gfc_trans_vla_type_sizes (sym, &block);
4081 stmt = gfc_finish_block (&block);
4083 gfc_start_block (&block);
4085 /* Only do the entry/initialization code if the arg is present. */
4086 dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
4087 optional_arg = (sym->attr.optional
4088 || (sym->ns->proc_name->attr.entry_master
4089 && sym->attr.dummy));
4090 if (optional_arg)
4092 tmp = gfc_conv_expr_present (sym);
4093 stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4095 gfc_add_expr_to_block (&block, stmt);
4097 /* Add the main function body. */
4098 gfc_add_expr_to_block (&block, body);
4100 /* Cleanup code. */
4101 if (!no_repack)
4103 gfc_start_block (&cleanup);
4105 if (sym->attr.intent != INTENT_IN)
4107 /* Copy the data back. */
4108 tmp = gfc_chainon_list (NULL_TREE, dumdesc);
4109 tmp = gfc_chainon_list (tmp, tmpdesc);
4110 tmp = build_function_call_expr (gfor_fndecl_in_unpack, tmp);
4111 gfc_add_expr_to_block (&cleanup, tmp);
4114 /* Free the temporary. */
4115 tmp = gfc_chainon_list (NULL_TREE, tmpdesc);
4116 tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
4117 gfc_add_expr_to_block (&cleanup, tmp);
4119 stmt = gfc_finish_block (&cleanup);
4121 /* Only do the cleanup if the array was repacked. */
4122 tmp = build_fold_indirect_ref (dumdesc);
4123 tmp = gfc_conv_descriptor_data_get (tmp);
4124 tmp = build2 (NE_EXPR, boolean_type_node, tmp, tmpdesc);
4125 stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4127 if (optional_arg)
4129 tmp = gfc_conv_expr_present (sym);
4130 stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4132 gfc_add_expr_to_block (&block, stmt);
4134 /* We don't need to free any memory allocated by internal_pack as it will
4135 be freed at the end of the function by pop_context. */
4136 return gfc_finish_block (&block);
4140 /* Convert an array for passing as an actual argument. Expressions and
4141 vector subscripts are evaluated and stored in a temporary, which is then
4142 passed. For whole arrays the descriptor is passed. For array sections
4143 a modified copy of the descriptor is passed, but using the original data.
4145 This function is also used for array pointer assignments, and there
4146 are three cases:
4148 - want_pointer && !se->direct_byref
4149 EXPR is an actual argument. On exit, se->expr contains a
4150 pointer to the array descriptor.
4152 - !want_pointer && !se->direct_byref
4153 EXPR is an actual argument to an intrinsic function or the
4154 left-hand side of a pointer assignment. On exit, se->expr
4155 contains the descriptor for EXPR.
4157 - !want_pointer && se->direct_byref
4158 EXPR is the right-hand side of a pointer assignment and
4159 se->expr is the descriptor for the previously-evaluated
4160 left-hand side. The function creates an assignment from
4161 EXPR to se->expr. */
4163 void
4164 gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
4166 gfc_loopinfo loop;
4167 gfc_ss *secss;
4168 gfc_ss_info *info;
4169 int need_tmp;
4170 int n;
4171 tree tmp;
4172 tree desc;
4173 stmtblock_t block;
4174 tree start;
4175 tree offset;
4176 int full;
4178 gcc_assert (ss != gfc_ss_terminator);
4180 /* TODO: Pass constant array constructors without a temporary. */
4181 /* Special case things we know we can pass easily. */
4182 switch (expr->expr_type)
4184 case EXPR_VARIABLE:
4185 /* If we have a linear array section, we can pass it directly.
4186 Otherwise we need to copy it into a temporary. */
4188 /* Find the SS for the array section. */
4189 secss = ss;
4190 while (secss != gfc_ss_terminator && secss->type != GFC_SS_SECTION)
4191 secss = secss->next;
4193 gcc_assert (secss != gfc_ss_terminator);
4194 info = &secss->data.info;
4196 /* Get the descriptor for the array. */
4197 gfc_conv_ss_descriptor (&se->pre, secss, 0);
4198 desc = info->descriptor;
4200 need_tmp = gfc_ref_needs_temporary_p (expr->ref);
4201 if (need_tmp)
4202 full = 0;
4203 else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
4205 /* Create a new descriptor if the array doesn't have one. */
4206 full = 0;
4208 else if (info->ref->u.ar.type == AR_FULL)
4209 full = 1;
4210 else if (se->direct_byref)
4211 full = 0;
4212 else
4213 full = gfc_full_array_ref_p (info->ref);
4215 if (full)
4217 if (se->direct_byref)
4219 /* Copy the descriptor for pointer assignments. */
4220 gfc_add_modify_expr (&se->pre, se->expr, desc);
4222 else if (se->want_pointer)
4224 /* We pass full arrays directly. This means that pointers and
4225 allocatable arrays should also work. */
4226 se->expr = build_fold_addr_expr (desc);
4228 else
4230 se->expr = desc;
4233 if (expr->ts.type == BT_CHARACTER)
4234 se->string_length = gfc_get_expr_charlen (expr);
4236 return;
4238 break;
4240 case EXPR_FUNCTION:
4241 /* A transformational function return value will be a temporary
4242 array descriptor. We still need to go through the scalarizer
4243 to create the descriptor. Elemental functions ar handled as
4244 arbitrary expressions, i.e. copy to a temporary. */
4245 secss = ss;
4246 /* Look for the SS for this function. */
4247 while (secss != gfc_ss_terminator
4248 && (secss->type != GFC_SS_FUNCTION || secss->expr != expr))
4249 secss = secss->next;
4251 if (se->direct_byref)
4253 gcc_assert (secss != gfc_ss_terminator);
4255 /* For pointer assignments pass the descriptor directly. */
4256 se->ss = secss;
4257 se->expr = build_fold_addr_expr (se->expr);
4258 gfc_conv_expr (se, expr);
4259 return;
4262 if (secss == gfc_ss_terminator)
4264 /* Elemental function. */
4265 need_tmp = 1;
4266 info = NULL;
4268 else
4270 /* Transformational function. */
4271 info = &secss->data.info;
4272 need_tmp = 0;
4274 break;
4276 default:
4277 /* Something complicated. Copy it into a temporary. */
4278 need_tmp = 1;
4279 secss = NULL;
4280 info = NULL;
4281 break;
4285 gfc_init_loopinfo (&loop);
4287 /* Associate the SS with the loop. */
4288 gfc_add_ss_to_loop (&loop, ss);
4290 /* Tell the scalarizer not to bother creating loop variables, etc. */
4291 if (!need_tmp)
4292 loop.array_parameter = 1;
4293 else
4294 /* The right-hand side of a pointer assignment mustn't use a temporary. */
4295 gcc_assert (!se->direct_byref);
4297 /* Setup the scalarizing loops and bounds. */
4298 gfc_conv_ss_startstride (&loop);
4300 if (need_tmp)
4302 /* Tell the scalarizer to make a temporary. */
4303 loop.temp_ss = gfc_get_ss ();
4304 loop.temp_ss->type = GFC_SS_TEMP;
4305 loop.temp_ss->next = gfc_ss_terminator;
4306 if (expr->ts.type == BT_CHARACTER)
4308 if (expr->ts.cl == NULL)
4310 /* This had better be a substring reference! */
4311 gfc_ref *char_ref = expr->ref;
4312 for (; char_ref; char_ref = char_ref->next)
4313 if (char_ref->type == REF_SUBSTRING)
4315 mpz_t char_len;
4316 expr->ts.cl = gfc_get_charlen ();
4317 expr->ts.cl->next = char_ref->u.ss.length->next;
4318 char_ref->u.ss.length->next = expr->ts.cl;
4320 mpz_init_set_ui (char_len, 1);
4321 mpz_add (char_len, char_len,
4322 char_ref->u.ss.end->value.integer);
4323 mpz_sub (char_len, char_len,
4324 char_ref->u.ss.start->value.integer);
4325 expr->ts.cl->backend_decl
4326 = gfc_conv_mpz_to_tree (char_len,
4327 gfc_default_character_kind);
4328 /* Cast is necessary for *-charlen refs. */
4329 expr->ts.cl->backend_decl
4330 = convert (gfc_charlen_type_node,
4331 expr->ts.cl->backend_decl);
4332 mpz_clear (char_len);
4333 break;
4335 gcc_assert (char_ref != NULL);
4336 loop.temp_ss->data.temp.type
4337 = gfc_typenode_for_spec (&expr->ts);
4338 loop.temp_ss->string_length = expr->ts.cl->backend_decl;
4340 else if (expr->ts.cl->length
4341 && expr->ts.cl->length->expr_type == EXPR_CONSTANT)
4343 expr->ts.cl->backend_decl
4344 = gfc_conv_mpz_to_tree (expr->ts.cl->length->value.integer,
4345 expr->ts.cl->length->ts.kind);
4346 loop.temp_ss->data.temp.type
4347 = gfc_typenode_for_spec (&expr->ts);
4348 loop.temp_ss->string_length
4349 = TYPE_SIZE_UNIT (loop.temp_ss->data.temp.type);
4351 else
4353 loop.temp_ss->data.temp.type
4354 = gfc_typenode_for_spec (&expr->ts);
4355 loop.temp_ss->string_length = expr->ts.cl->backend_decl;
4357 se->string_length = loop.temp_ss->string_length;
4359 else
4361 loop.temp_ss->data.temp.type
4362 = gfc_typenode_for_spec (&expr->ts);
4363 loop.temp_ss->string_length = NULL;
4365 loop.temp_ss->data.temp.dimen = loop.dimen;
4366 gfc_add_ss_to_loop (&loop, loop.temp_ss);
4369 gfc_conv_loop_setup (&loop);
4371 if (need_tmp)
4373 /* Copy into a temporary and pass that. We don't need to copy the data
4374 back because expressions and vector subscripts must be INTENT_IN. */
4375 /* TODO: Optimize passing function return values. */
4376 gfc_se lse;
4377 gfc_se rse;
4379 /* Start the copying loops. */
4380 gfc_mark_ss_chain_used (loop.temp_ss, 1);
4381 gfc_mark_ss_chain_used (ss, 1);
4382 gfc_start_scalarized_body (&loop, &block);
4384 /* Copy each data element. */
4385 gfc_init_se (&lse, NULL);
4386 gfc_copy_loopinfo_to_se (&lse, &loop);
4387 gfc_init_se (&rse, NULL);
4388 gfc_copy_loopinfo_to_se (&rse, &loop);
4390 lse.ss = loop.temp_ss;
4391 rse.ss = ss;
4393 gfc_conv_scalarized_array_ref (&lse, NULL);
4394 if (expr->ts.type == BT_CHARACTER)
4396 gfc_conv_expr (&rse, expr);
4397 if (POINTER_TYPE_P (TREE_TYPE (rse.expr)))
4398 rse.expr = build_fold_indirect_ref (rse.expr);
4400 else
4401 gfc_conv_expr_val (&rse, expr);
4403 gfc_add_block_to_block (&block, &rse.pre);
4404 gfc_add_block_to_block (&block, &lse.pre);
4406 gfc_add_modify_expr (&block, lse.expr, rse.expr);
4408 /* Finish the copying loops. */
4409 gfc_trans_scalarizing_loops (&loop, &block);
4411 desc = loop.temp_ss->data.info.descriptor;
4413 gcc_assert (is_gimple_lvalue (desc));
4415 else if (expr->expr_type == EXPR_FUNCTION)
4417 desc = info->descriptor;
4418 se->string_length = ss->string_length;
4420 else
4422 /* We pass sections without copying to a temporary. Make a new
4423 descriptor and point it at the section we want. The loop variable
4424 limits will be the limits of the section.
4425 A function may decide to repack the array to speed up access, but
4426 we're not bothered about that here. */
4427 int dim;
4428 tree parm;
4429 tree parmtype;
4430 tree stride;
4431 tree from;
4432 tree to;
4433 tree base;
4435 /* Set the string_length for a character array. */
4436 if (expr->ts.type == BT_CHARACTER)
4437 se->string_length = gfc_get_expr_charlen (expr);
4439 desc = info->descriptor;
4440 gcc_assert (secss && secss != gfc_ss_terminator);
4441 if (se->direct_byref)
4443 /* For pointer assignments we fill in the destination. */
4444 parm = se->expr;
4445 parmtype = TREE_TYPE (parm);
4447 else
4449 /* Otherwise make a new one. */
4450 parmtype = gfc_get_element_type (TREE_TYPE (desc));
4451 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen,
4452 loop.from, loop.to, 0);
4453 parm = gfc_create_var (parmtype, "parm");
4456 offset = gfc_index_zero_node;
4457 dim = 0;
4459 /* The following can be somewhat confusing. We have two
4460 descriptors, a new one and the original array.
4461 {parm, parmtype, dim} refer to the new one.
4462 {desc, type, n, secss, loop} refer to the original, which maybe
4463 a descriptorless array.
4464 The bounds of the scalarization are the bounds of the section.
4465 We don't have to worry about numeric overflows when calculating
4466 the offsets because all elements are within the array data. */
4468 /* Set the dtype. */
4469 tmp = gfc_conv_descriptor_dtype (parm);
4470 gfc_add_modify_expr (&loop.pre, tmp, gfc_get_dtype (parmtype));
4472 if (se->direct_byref)
4473 base = gfc_index_zero_node;
4474 else
4475 base = NULL_TREE;
4477 for (n = 0; n < info->ref->u.ar.dimen; n++)
4479 stride = gfc_conv_array_stride (desc, n);
4481 /* Work out the offset. */
4482 if (info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4484 gcc_assert (info->subscript[n]
4485 && info->subscript[n]->type == GFC_SS_SCALAR);
4486 start = info->subscript[n]->data.scalar.expr;
4488 else
4490 /* Check we haven't somehow got out of sync. */
4491 gcc_assert (info->dim[dim] == n);
4493 /* Evaluate and remember the start of the section. */
4494 start = info->start[dim];
4495 stride = gfc_evaluate_now (stride, &loop.pre);
4498 tmp = gfc_conv_array_lbound (desc, n);
4499 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), start, tmp);
4501 tmp = fold_build2 (MULT_EXPR, TREE_TYPE (tmp), tmp, stride);
4502 offset = fold_build2 (PLUS_EXPR, TREE_TYPE (tmp), offset, tmp);
4504 if (info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4506 /* For elemental dimensions, we only need the offset. */
4507 continue;
4510 /* Vector subscripts need copying and are handled elsewhere. */
4511 gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_RANGE);
4513 /* Set the new lower bound. */
4514 from = loop.from[dim];
4515 to = loop.to[dim];
4517 /* If we have an array section or are assigning to a pointer,
4518 make sure that the lower bound is 1. References to the full
4519 array should otherwise keep the original bounds. */
4520 if ((info->ref->u.ar.type != AR_FULL || se->direct_byref)
4521 && !integer_onep (from))
4523 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4524 gfc_index_one_node, from);
4525 to = fold_build2 (PLUS_EXPR, gfc_array_index_type, to, tmp);
4526 from = gfc_index_one_node;
4528 tmp = gfc_conv_descriptor_lbound (parm, gfc_rank_cst[dim]);
4529 gfc_add_modify_expr (&loop.pre, tmp, from);
4531 /* Set the new upper bound. */
4532 tmp = gfc_conv_descriptor_ubound (parm, gfc_rank_cst[dim]);
4533 gfc_add_modify_expr (&loop.pre, tmp, to);
4535 /* Multiply the stride by the section stride to get the
4536 total stride. */
4537 stride = fold_build2 (MULT_EXPR, gfc_array_index_type,
4538 stride, info->stride[dim]);
4540 if (se->direct_byref)
4541 base = fold_build2 (MINUS_EXPR, TREE_TYPE (base),
4542 base, stride);
4544 /* Store the new stride. */
4545 tmp = gfc_conv_descriptor_stride (parm, gfc_rank_cst[dim]);
4546 gfc_add_modify_expr (&loop.pre, tmp, stride);
4548 dim++;
4551 if (se->data_not_needed)
4552 gfc_conv_descriptor_data_set (&loop.pre, parm, gfc_index_zero_node);
4553 else
4555 /* Point the data pointer at the first element in the section. */
4556 tmp = gfc_conv_array_data (desc);
4557 tmp = build_fold_indirect_ref (tmp);
4558 tmp = gfc_build_array_ref (tmp, offset);
4559 offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
4560 gfc_conv_descriptor_data_set (&loop.pre, parm, offset);
4563 if (se->direct_byref && !se->data_not_needed)
4565 /* Set the offset. */
4566 tmp = gfc_conv_descriptor_offset (parm);
4567 gfc_add_modify_expr (&loop.pre, tmp, base);
4569 else
4571 /* Only the callee knows what the correct offset it, so just set
4572 it to zero here. */
4573 tmp = gfc_conv_descriptor_offset (parm);
4574 gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
4576 desc = parm;
4579 if (!se->direct_byref)
4581 /* Get a pointer to the new descriptor. */
4582 if (se->want_pointer)
4583 se->expr = build_fold_addr_expr (desc);
4584 else
4585 se->expr = desc;
4588 gfc_add_block_to_block (&se->pre, &loop.pre);
4589 gfc_add_block_to_block (&se->post, &loop.post);
4591 /* Cleanup the scalarizer. */
4592 gfc_cleanup_loop (&loop);
4596 /* Convert an array for passing as an actual parameter. */
4597 /* TODO: Optimize passing g77 arrays. */
4599 void
4600 gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77)
4602 tree ptr;
4603 tree desc;
4604 tree tmp;
4605 tree stmt;
4606 gfc_symbol *sym;
4607 stmtblock_t block;
4609 /* Passing address of the array if it is not pointer or assumed-shape. */
4610 if (expr->expr_type == EXPR_VARIABLE
4611 && expr->ref->u.ar.type == AR_FULL && g77)
4613 sym = expr->symtree->n.sym;
4614 tmp = gfc_get_symbol_decl (sym);
4616 if (sym->ts.type == BT_CHARACTER)
4617 se->string_length = sym->ts.cl->backend_decl;
4618 if (!sym->attr.pointer && sym->as->type != AS_ASSUMED_SHAPE
4619 && !sym->attr.allocatable)
4621 /* Some variables are declared directly, others are declared as
4622 pointers and allocated on the heap. */
4623 if (sym->attr.dummy || POINTER_TYPE_P (TREE_TYPE (tmp)))
4624 se->expr = tmp;
4625 else
4626 se->expr = build_fold_addr_expr (tmp);
4627 return;
4629 if (sym->attr.allocatable)
4631 if (sym->attr.dummy)
4633 gfc_conv_expr_descriptor (se, expr, ss);
4634 se->expr = gfc_conv_array_data (se->expr);
4636 else
4637 se->expr = gfc_conv_array_data (tmp);
4638 return;
4642 se->want_pointer = 1;
4643 gfc_conv_expr_descriptor (se, expr, ss);
4645 /* Deallocate the allocatable components of structures that are
4646 not variable. */
4647 if (expr->ts.type == BT_DERIVED
4648 && expr->ts.derived->attr.alloc_comp
4649 && expr->expr_type != EXPR_VARIABLE)
4651 tmp = build_fold_indirect_ref (se->expr);
4652 tmp = gfc_deallocate_alloc_comp (expr->ts.derived, tmp, expr->rank);
4653 gfc_add_expr_to_block (&se->post, tmp);
4656 if (g77)
4658 desc = se->expr;
4659 /* Repack the array. */
4660 tmp = gfc_chainon_list (NULL_TREE, desc);
4661 ptr = build_function_call_expr (gfor_fndecl_in_pack, tmp);
4662 ptr = gfc_evaluate_now (ptr, &se->pre);
4663 se->expr = ptr;
4665 gfc_start_block (&block);
4667 /* Copy the data back. */
4668 tmp = gfc_chainon_list (NULL_TREE, desc);
4669 tmp = gfc_chainon_list (tmp, ptr);
4670 tmp = build_function_call_expr (gfor_fndecl_in_unpack, tmp);
4671 gfc_add_expr_to_block (&block, tmp);
4673 /* Free the temporary. */
4674 tmp = convert (pvoid_type_node, ptr);
4675 tmp = gfc_chainon_list (NULL_TREE, tmp);
4676 tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
4677 gfc_add_expr_to_block (&block, tmp);
4679 stmt = gfc_finish_block (&block);
4681 gfc_init_block (&block);
4682 /* Only if it was repacked. This code needs to be executed before the
4683 loop cleanup code. */
4684 tmp = build_fold_indirect_ref (desc);
4685 tmp = gfc_conv_array_data (tmp);
4686 tmp = build2 (NE_EXPR, boolean_type_node, ptr, tmp);
4687 tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4689 gfc_add_expr_to_block (&block, tmp);
4690 gfc_add_block_to_block (&block, &se->post);
4692 gfc_init_block (&se->post);
4693 gfc_add_block_to_block (&se->post, &block);
4698 /* Generate code to deallocate an array, if it is allocated. */
4700 tree
4701 gfc_trans_dealloc_allocated (tree descriptor)
4703 tree tmp;
4704 tree ptr;
4705 tree var;
4706 stmtblock_t block;
4708 gfc_start_block (&block);
4710 var = gfc_conv_descriptor_data_get (descriptor);
4711 STRIP_NOPS (var);
4712 tmp = gfc_create_var (gfc_array_index_type, NULL);
4713 ptr = build_fold_addr_expr (tmp);
4715 /* Call array_deallocate with an int* present in the second argument.
4716 Although it is ignored here, it's presence ensures that arrays that
4717 are already deallocated are ignored. */
4718 tmp = gfc_chainon_list (NULL_TREE, var);
4719 tmp = gfc_chainon_list (tmp, ptr);
4720 tmp = build_function_call_expr (gfor_fndecl_deallocate, tmp);
4721 gfc_add_expr_to_block (&block, tmp);
4723 /* Zero the data pointer. */
4724 tmp = build2 (MODIFY_EXPR, void_type_node,
4725 var, build_int_cst (TREE_TYPE (var), 0));
4726 gfc_add_expr_to_block (&block, tmp);
4728 return gfc_finish_block (&block);
4732 /* This helper function calculates the size in words of a full array. */
4734 static tree
4735 get_full_array_size (stmtblock_t *block, tree decl, int rank)
4737 tree idx;
4738 tree nelems;
4739 tree tmp;
4740 idx = gfc_rank_cst[rank - 1];
4741 nelems = gfc_conv_descriptor_ubound (decl, idx);
4742 tmp = gfc_conv_descriptor_lbound (decl, idx);
4743 tmp = build2 (MINUS_EXPR, gfc_array_index_type, nelems, tmp);
4744 tmp = build2 (PLUS_EXPR, gfc_array_index_type,
4745 tmp, gfc_index_one_node);
4746 tmp = gfc_evaluate_now (tmp, block);
4748 nelems = gfc_conv_descriptor_stride (decl, idx);
4749 tmp = build2 (MULT_EXPR, gfc_array_index_type, nelems, tmp);
4750 return gfc_evaluate_now (tmp, block);
4754 /* Allocate dest to the same size as src, and copy src -> dest. */
4756 tree
4757 gfc_duplicate_allocatable(tree dest, tree src, tree type, int rank)
4759 tree tmp;
4760 tree size;
4761 tree nelems;
4762 tree args;
4763 tree null_cond;
4764 tree null_data;
4765 stmtblock_t block;
4767 /* If the source is null, set the destination to null. */
4768 gfc_init_block (&block);
4769 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
4770 null_data = gfc_finish_block (&block);
4772 gfc_init_block (&block);
4774 nelems = get_full_array_size (&block, src, rank);
4775 size = fold_build2 (MULT_EXPR, gfc_array_index_type, nelems,
4776 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
4778 /* Allocate memory to the destination. */
4779 tmp = gfc_chainon_list (NULL_TREE, size);
4780 if (gfc_index_integer_kind == 4)
4781 tmp = build_function_call_expr (gfor_fndecl_internal_malloc, tmp);
4782 else if (gfc_index_integer_kind == 8)
4783 tmp = build_function_call_expr (gfor_fndecl_internal_malloc64, tmp);
4784 else
4785 gcc_unreachable ();
4786 tmp = fold (convert (TREE_TYPE (gfc_conv_descriptor_data_get (src)),
4787 tmp));
4788 gfc_conv_descriptor_data_set (&block, dest, tmp);
4790 /* We know the temporary and the value will be the same length,
4791 so can use memcpy. */
4792 tmp = gfc_conv_descriptor_data_get (dest);
4793 args = gfc_chainon_list (NULL_TREE, tmp);
4794 tmp = gfc_conv_descriptor_data_get (src);
4795 args = gfc_chainon_list (args, tmp);
4796 args = gfc_chainon_list (args, size);
4797 tmp = built_in_decls[BUILT_IN_MEMCPY];
4798 tmp = build_function_call_expr (tmp, args);
4799 gfc_add_expr_to_block (&block, tmp);
4800 tmp = gfc_finish_block (&block);
4802 /* Null the destination if the source is null; otherwise do
4803 the allocate and copy. */
4804 null_cond = gfc_conv_descriptor_data_get (src);
4805 null_cond = convert (pvoid_type_node, null_cond);
4806 null_cond = build2 (NE_EXPR, boolean_type_node, null_cond,
4807 null_pointer_node);
4808 return build3_v (COND_EXPR, null_cond, tmp, null_data);
4812 /* Recursively traverse an object of derived type, generating code to
4813 deallocate, nullify or copy allocatable components. This is the work horse
4814 function for the functions named in this enum. */
4816 enum {DEALLOCATE_ALLOC_COMP = 1, NULLIFY_ALLOC_COMP, COPY_ALLOC_COMP};
4818 static tree
4819 structure_alloc_comps (gfc_symbol * der_type, tree decl,
4820 tree dest, int rank, int purpose)
4822 gfc_component *c;
4823 gfc_loopinfo loop;
4824 stmtblock_t fnblock;
4825 stmtblock_t loopbody;
4826 tree tmp;
4827 tree comp;
4828 tree dcmp;
4829 tree nelems;
4830 tree index;
4831 tree var;
4832 tree cdecl;
4833 tree ctype;
4834 tree vref, dref;
4835 tree null_cond = NULL_TREE;
4837 gfc_init_block (&fnblock);
4839 if (POINTER_TYPE_P (TREE_TYPE (decl)))
4840 decl = build_fold_indirect_ref (decl);
4842 /* If this an array of derived types with allocatable components
4843 build a loop and recursively call this function. */
4844 if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
4845 || GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
4847 tmp = gfc_conv_array_data (decl);
4848 var = build_fold_indirect_ref (tmp);
4850 /* Get the number of elements - 1 and set the counter. */
4851 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
4853 /* Use the descriptor for an allocatable array. Since this
4854 is a full array reference, we only need the descriptor
4855 information from dimension = rank. */
4856 tmp = get_full_array_size (&fnblock, decl, rank);
4857 tmp = build2 (MINUS_EXPR, gfc_array_index_type,
4858 tmp, gfc_index_one_node);
4860 null_cond = gfc_conv_descriptor_data_get (decl);
4861 null_cond = build2 (NE_EXPR, boolean_type_node, null_cond,
4862 build_int_cst (TREE_TYPE (tmp), 0));
4864 else
4866 /* Otherwise use the TYPE_DOMAIN information. */
4867 tmp = array_type_nelts (TREE_TYPE (decl));
4868 tmp = fold_convert (gfc_array_index_type, tmp);
4871 /* Remember that this is, in fact, the no. of elements - 1. */
4872 nelems = gfc_evaluate_now (tmp, &fnblock);
4873 index = gfc_create_var (gfc_array_index_type, "S");
4875 /* Build the body of the loop. */
4876 gfc_init_block (&loopbody);
4878 vref = gfc_build_array_ref (var, index);
4880 if (purpose == COPY_ALLOC_COMP)
4882 tmp = gfc_duplicate_allocatable (dest, decl, TREE_TYPE(decl), rank);
4883 gfc_add_expr_to_block (&fnblock, tmp);
4885 tmp = build_fold_indirect_ref (gfc_conv_descriptor_data_get (dest));
4886 dref = gfc_build_array_ref (tmp, index);
4887 tmp = structure_alloc_comps (der_type, vref, dref, rank, purpose);
4889 else
4890 tmp = structure_alloc_comps (der_type, vref, NULL_TREE, rank, purpose);
4892 gfc_add_expr_to_block (&loopbody, tmp);
4894 /* Build the loop and return. */
4895 gfc_init_loopinfo (&loop);
4896 loop.dimen = 1;
4897 loop.from[0] = gfc_index_zero_node;
4898 loop.loopvar[0] = index;
4899 loop.to[0] = nelems;
4900 gfc_trans_scalarizing_loops (&loop, &loopbody);
4901 gfc_add_block_to_block (&fnblock, &loop.pre);
4903 tmp = gfc_finish_block (&fnblock);
4904 if (null_cond != NULL_TREE)
4905 tmp = build3_v (COND_EXPR, null_cond, tmp, build_empty_stmt ());
4907 return tmp;
4910 /* Otherwise, act on the components or recursively call self to
4911 act on a chain of components. */
4912 for (c = der_type->components; c; c = c->next)
4914 bool cmp_has_alloc_comps = (c->ts.type == BT_DERIVED)
4915 && c->ts.derived->attr.alloc_comp;
4916 cdecl = c->backend_decl;
4917 ctype = TREE_TYPE (cdecl);
4919 switch (purpose)
4921 case DEALLOCATE_ALLOC_COMP:
4922 /* Do not deallocate the components of ultimate pointer
4923 components. */
4924 if (cmp_has_alloc_comps && !c->pointer)
4926 comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
4927 rank = c->as ? c->as->rank : 0;
4928 tmp = structure_alloc_comps (c->ts.derived, comp, NULL_TREE,
4929 rank, purpose);
4930 gfc_add_expr_to_block (&fnblock, tmp);
4933 if (c->allocatable)
4935 comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
4936 tmp = gfc_trans_dealloc_allocated (comp);
4937 gfc_add_expr_to_block (&fnblock, tmp);
4939 break;
4941 case NULLIFY_ALLOC_COMP:
4942 if (c->pointer)
4943 continue;
4944 else if (c->allocatable)
4946 comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
4947 gfc_conv_descriptor_data_set (&fnblock, comp, null_pointer_node);
4949 else if (cmp_has_alloc_comps)
4951 comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
4952 rank = c->as ? c->as->rank : 0;
4953 tmp = structure_alloc_comps (c->ts.derived, comp, NULL_TREE,
4954 rank, purpose);
4955 gfc_add_expr_to_block (&fnblock, tmp);
4957 break;
4959 case COPY_ALLOC_COMP:
4960 if (c->pointer)
4961 continue;
4963 /* We need source and destination components. */
4964 comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
4965 dcmp = build3 (COMPONENT_REF, ctype, dest, cdecl, NULL_TREE);
4966 dcmp = fold_convert (TREE_TYPE (comp), dcmp);
4968 if (c->allocatable && !cmp_has_alloc_comps)
4970 tmp = gfc_duplicate_allocatable(dcmp, comp, ctype, c->as->rank);
4971 gfc_add_expr_to_block (&fnblock, tmp);
4974 if (cmp_has_alloc_comps)
4976 rank = c->as ? c->as->rank : 0;
4977 tmp = fold_convert (TREE_TYPE (dcmp), comp);
4978 gfc_add_modify_expr (&fnblock, dcmp, tmp);
4979 tmp = structure_alloc_comps (c->ts.derived, comp, dcmp,
4980 rank, purpose);
4981 gfc_add_expr_to_block (&fnblock, tmp);
4983 break;
4985 default:
4986 gcc_unreachable ();
4987 break;
4991 return gfc_finish_block (&fnblock);
4994 /* Recursively traverse an object of derived type, generating code to
4995 nullify allocatable components. */
4997 tree
4998 gfc_nullify_alloc_comp (gfc_symbol * der_type, tree decl, int rank)
5000 return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
5001 NULLIFY_ALLOC_COMP);
5005 /* Recursively traverse an object of derived type, generating code to
5006 deallocate allocatable components. */
5008 tree
5009 gfc_deallocate_alloc_comp (gfc_symbol * der_type, tree decl, int rank)
5011 return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
5012 DEALLOCATE_ALLOC_COMP);
5016 /* Recursively traverse an object of derived type, generating code to
5017 copy its allocatable components. */
5019 tree
5020 gfc_copy_alloc_comp (gfc_symbol * der_type, tree decl, tree dest, int rank)
5022 return structure_alloc_comps (der_type, decl, dest, rank, COPY_ALLOC_COMP);
5026 /* NULLIFY an allocatable/pointer array on function entry, free it on exit.
5027 Do likewise, recursively if necessary, with the allocatable components of
5028 derived types. */
5030 tree
5031 gfc_trans_deferred_array (gfc_symbol * sym, tree body)
5033 tree type;
5034 tree tmp;
5035 tree descriptor;
5036 stmtblock_t fnblock;
5037 locus loc;
5038 int rank;
5039 bool sym_has_alloc_comp;
5041 sym_has_alloc_comp = (sym->ts.type == BT_DERIVED)
5042 && sym->ts.derived->attr.alloc_comp;
5044 /* Make sure the frontend gets these right. */
5045 if (!(sym->attr.pointer || sym->attr.allocatable || sym_has_alloc_comp))
5046 fatal_error ("Possible frontend bug: Deferred array size without pointer, "
5047 "allocatable attribute or derived type without allocatable "
5048 "components.");
5050 gfc_init_block (&fnblock);
5052 gcc_assert (TREE_CODE (sym->backend_decl) == VAR_DECL
5053 || TREE_CODE (sym->backend_decl) == PARM_DECL);
5055 if (sym->ts.type == BT_CHARACTER
5056 && !INTEGER_CST_P (sym->ts.cl->backend_decl))
5058 gfc_trans_init_string_length (sym->ts.cl, &fnblock);
5059 gfc_trans_vla_type_sizes (sym, &fnblock);
5062 /* Dummy and use associated variables don't need anything special. */
5063 if (sym->attr.dummy || sym->attr.use_assoc)
5065 gfc_add_expr_to_block (&fnblock, body);
5067 return gfc_finish_block (&fnblock);
5070 gfc_get_backend_locus (&loc);
5071 gfc_set_backend_locus (&sym->declared_at);
5072 descriptor = sym->backend_decl;
5074 /* Although static, derived types with default initializers and
5075 allocatable components must not be nulled wholesale; instead they
5076 are treated component by component. */
5077 if (TREE_STATIC (descriptor) && !sym_has_alloc_comp)
5079 /* SAVEd variables are not freed on exit. */
5080 gfc_trans_static_array_pointer (sym);
5081 return body;
5084 /* Get the descriptor type. */
5085 type = TREE_TYPE (sym->backend_decl);
5087 if (sym_has_alloc_comp && !(sym->attr.pointer || sym->attr.allocatable))
5089 rank = sym->as ? sym->as->rank : 0;
5090 tmp = gfc_nullify_alloc_comp (sym->ts.derived, descriptor, rank);
5091 gfc_add_expr_to_block (&fnblock, tmp);
5093 else if (!GFC_DESCRIPTOR_TYPE_P (type))
5095 /* If the backend_decl is not a descriptor, we must have a pointer
5096 to one. */
5097 descriptor = build_fold_indirect_ref (sym->backend_decl);
5098 type = TREE_TYPE (descriptor);
5101 /* NULLIFY the data pointer. */
5102 if (GFC_DESCRIPTOR_TYPE_P (type))
5103 gfc_conv_descriptor_data_set (&fnblock, descriptor, null_pointer_node);
5105 gfc_add_expr_to_block (&fnblock, body);
5107 gfc_set_backend_locus (&loc);
5109 /* Allocatable arrays need to be freed when they go out of scope.
5110 The allocatable components of pointers must not be touched. */
5111 if (sym_has_alloc_comp && !(sym->attr.function || sym->attr.result)
5112 && !sym->attr.pointer)
5114 int rank;
5115 rank = sym->as ? sym->as->rank : 0;
5116 tmp = gfc_deallocate_alloc_comp (sym->ts.derived, descriptor, rank);
5117 gfc_add_expr_to_block (&fnblock, tmp);
5120 if (sym->attr.allocatable)
5122 tmp = gfc_trans_dealloc_allocated (sym->backend_decl);
5123 gfc_add_expr_to_block (&fnblock, tmp);
5126 return gfc_finish_block (&fnblock);
5129 /************ Expression Walking Functions ******************/
5131 /* Walk a variable reference.
5133 Possible extension - multiple component subscripts.
5134 x(:,:) = foo%a(:)%b(:)
5135 Transforms to
5136 forall (i=..., j=...)
5137 x(i,j) = foo%a(j)%b(i)
5138 end forall
5139 This adds a fair amout of complexity because you need to deal with more
5140 than one ref. Maybe handle in a similar manner to vector subscripts.
5141 Maybe not worth the effort. */
5144 static gfc_ss *
5145 gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
5147 gfc_ref *ref;
5148 gfc_array_ref *ar;
5149 gfc_ss *newss;
5150 gfc_ss *head;
5151 int n;
5153 for (ref = expr->ref; ref; ref = ref->next)
5154 if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
5155 break;
5157 for (; ref; ref = ref->next)
5159 if (ref->type == REF_SUBSTRING)
5161 newss = gfc_get_ss ();
5162 newss->type = GFC_SS_SCALAR;
5163 newss->expr = ref->u.ss.start;
5164 newss->next = ss;
5165 ss = newss;
5167 newss = gfc_get_ss ();
5168 newss->type = GFC_SS_SCALAR;
5169 newss->expr = ref->u.ss.end;
5170 newss->next = ss;
5171 ss = newss;
5174 /* We're only interested in array sections from now on. */
5175 if (ref->type != REF_ARRAY)
5176 continue;
5178 ar = &ref->u.ar;
5179 switch (ar->type)
5181 case AR_ELEMENT:
5182 for (n = 0; n < ar->dimen; n++)
5184 newss = gfc_get_ss ();
5185 newss->type = GFC_SS_SCALAR;
5186 newss->expr = ar->start[n];
5187 newss->next = ss;
5188 ss = newss;
5190 break;
5192 case AR_FULL:
5193 newss = gfc_get_ss ();
5194 newss->type = GFC_SS_SECTION;
5195 newss->expr = expr;
5196 newss->next = ss;
5197 newss->data.info.dimen = ar->as->rank;
5198 newss->data.info.ref = ref;
5200 /* Make sure array is the same as array(:,:), this way
5201 we don't need to special case all the time. */
5202 ar->dimen = ar->as->rank;
5203 for (n = 0; n < ar->dimen; n++)
5205 newss->data.info.dim[n] = n;
5206 ar->dimen_type[n] = DIMEN_RANGE;
5208 gcc_assert (ar->start[n] == NULL);
5209 gcc_assert (ar->end[n] == NULL);
5210 gcc_assert (ar->stride[n] == NULL);
5212 ss = newss;
5213 break;
5215 case AR_SECTION:
5216 newss = gfc_get_ss ();
5217 newss->type = GFC_SS_SECTION;
5218 newss->expr = expr;
5219 newss->next = ss;
5220 newss->data.info.dimen = 0;
5221 newss->data.info.ref = ref;
5223 head = newss;
5225 /* We add SS chains for all the subscripts in the section. */
5226 for (n = 0; n < ar->dimen; n++)
5228 gfc_ss *indexss;
5230 switch (ar->dimen_type[n])
5232 case DIMEN_ELEMENT:
5233 /* Add SS for elemental (scalar) subscripts. */
5234 gcc_assert (ar->start[n]);
5235 indexss = gfc_get_ss ();
5236 indexss->type = GFC_SS_SCALAR;
5237 indexss->expr = ar->start[n];
5238 indexss->next = gfc_ss_terminator;
5239 indexss->loop_chain = gfc_ss_terminator;
5240 newss->data.info.subscript[n] = indexss;
5241 break;
5243 case DIMEN_RANGE:
5244 /* We don't add anything for sections, just remember this
5245 dimension for later. */
5246 newss->data.info.dim[newss->data.info.dimen] = n;
5247 newss->data.info.dimen++;
5248 break;
5250 case DIMEN_VECTOR:
5251 /* Create a GFC_SS_VECTOR index in which we can store
5252 the vector's descriptor. */
5253 indexss = gfc_get_ss ();
5254 indexss->type = GFC_SS_VECTOR;
5255 indexss->expr = ar->start[n];
5256 indexss->next = gfc_ss_terminator;
5257 indexss->loop_chain = gfc_ss_terminator;
5258 newss->data.info.subscript[n] = indexss;
5259 newss->data.info.dim[newss->data.info.dimen] = n;
5260 newss->data.info.dimen++;
5261 break;
5263 default:
5264 /* We should know what sort of section it is by now. */
5265 gcc_unreachable ();
5268 /* We should have at least one non-elemental dimension. */
5269 gcc_assert (newss->data.info.dimen > 0);
5270 ss = newss;
5271 break;
5273 default:
5274 /* We should know what sort of section it is by now. */
5275 gcc_unreachable ();
5279 return ss;
5283 /* Walk an expression operator. If only one operand of a binary expression is
5284 scalar, we must also add the scalar term to the SS chain. */
5286 static gfc_ss *
5287 gfc_walk_op_expr (gfc_ss * ss, gfc_expr * expr)
5289 gfc_ss *head;
5290 gfc_ss *head2;
5291 gfc_ss *newss;
5293 head = gfc_walk_subexpr (ss, expr->value.op.op1);
5294 if (expr->value.op.op2 == NULL)
5295 head2 = head;
5296 else
5297 head2 = gfc_walk_subexpr (head, expr->value.op.op2);
5299 /* All operands are scalar. Pass back and let the caller deal with it. */
5300 if (head2 == ss)
5301 return head2;
5303 /* All operands require scalarization. */
5304 if (head != ss && (expr->value.op.op2 == NULL || head2 != head))
5305 return head2;
5307 /* One of the operands needs scalarization, the other is scalar.
5308 Create a gfc_ss for the scalar expression. */
5309 newss = gfc_get_ss ();
5310 newss->type = GFC_SS_SCALAR;
5311 if (head == ss)
5313 /* First operand is scalar. We build the chain in reverse order, so
5314 add the scarar SS after the second operand. */
5315 head = head2;
5316 while (head && head->next != ss)
5317 head = head->next;
5318 /* Check we haven't somehow broken the chain. */
5319 gcc_assert (head);
5320 newss->next = ss;
5321 head->next = newss;
5322 newss->expr = expr->value.op.op1;
5324 else /* head2 == head */
5326 gcc_assert (head2 == head);
5327 /* Second operand is scalar. */
5328 newss->next = head2;
5329 head2 = newss;
5330 newss->expr = expr->value.op.op2;
5333 return head2;
5337 /* Reverse a SS chain. */
5339 gfc_ss *
5340 gfc_reverse_ss (gfc_ss * ss)
5342 gfc_ss *next;
5343 gfc_ss *head;
5345 gcc_assert (ss != NULL);
5347 head = gfc_ss_terminator;
5348 while (ss != gfc_ss_terminator)
5350 next = ss->next;
5351 /* Check we didn't somehow break the chain. */
5352 gcc_assert (next != NULL);
5353 ss->next = head;
5354 head = ss;
5355 ss = next;
5358 return (head);
5362 /* Walk the arguments of an elemental function. */
5364 gfc_ss *
5365 gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
5366 gfc_ss_type type)
5368 int scalar;
5369 gfc_ss *head;
5370 gfc_ss *tail;
5371 gfc_ss *newss;
5373 head = gfc_ss_terminator;
5374 tail = NULL;
5375 scalar = 1;
5376 for (; arg; arg = arg->next)
5378 if (!arg->expr)
5379 continue;
5381 newss = gfc_walk_subexpr (head, arg->expr);
5382 if (newss == head)
5384 /* Scalar argument. */
5385 newss = gfc_get_ss ();
5386 newss->type = type;
5387 newss->expr = arg->expr;
5388 newss->next = head;
5390 else
5391 scalar = 0;
5393 head = newss;
5394 if (!tail)
5396 tail = head;
5397 while (tail->next != gfc_ss_terminator)
5398 tail = tail->next;
5402 if (scalar)
5404 /* If all the arguments are scalar we don't need the argument SS. */
5405 gfc_free_ss_chain (head);
5406 /* Pass it back. */
5407 return ss;
5410 /* Add it onto the existing chain. */
5411 tail->next = ss;
5412 return head;
5416 /* Walk a function call. Scalar functions are passed back, and taken out of
5417 scalarization loops. For elemental functions we walk their arguments.
5418 The result of functions returning arrays is stored in a temporary outside
5419 the loop, so that the function is only called once. Hence we do not need
5420 to walk their arguments. */
5422 static gfc_ss *
5423 gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
5425 gfc_ss *newss;
5426 gfc_intrinsic_sym *isym;
5427 gfc_symbol *sym;
5429 isym = expr->value.function.isym;
5431 /* Handle intrinsic functions separately. */
5432 if (isym)
5433 return gfc_walk_intrinsic_function (ss, expr, isym);
5435 sym = expr->value.function.esym;
5436 if (!sym)
5437 sym = expr->symtree->n.sym;
5439 /* A function that returns arrays. */
5440 if (gfc_return_by_reference (sym) && sym->result->attr.dimension)
5442 newss = gfc_get_ss ();
5443 newss->type = GFC_SS_FUNCTION;
5444 newss->expr = expr;
5445 newss->next = ss;
5446 newss->data.info.dimen = expr->rank;
5447 return newss;
5450 /* Walk the parameters of an elemental function. For now we always pass
5451 by reference. */
5452 if (sym->attr.elemental)
5453 return gfc_walk_elemental_function_args (ss, expr->value.function.actual,
5454 GFC_SS_REFERENCE);
5456 /* Scalar functions are OK as these are evaluated outside the scalarization
5457 loop. Pass back and let the caller deal with it. */
5458 return ss;
5462 /* An array temporary is constructed for array constructors. */
5464 static gfc_ss *
5465 gfc_walk_array_constructor (gfc_ss * ss, gfc_expr * expr)
5467 gfc_ss *newss;
5468 int n;
5470 newss = gfc_get_ss ();
5471 newss->type = GFC_SS_CONSTRUCTOR;
5472 newss->expr = expr;
5473 newss->next = ss;
5474 newss->data.info.dimen = expr->rank;
5475 for (n = 0; n < expr->rank; n++)
5476 newss->data.info.dim[n] = n;
5478 return newss;
5482 /* Walk an expression. Add walked expressions to the head of the SS chain.
5483 A wholly scalar expression will not be added. */
5485 static gfc_ss *
5486 gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr)
5488 gfc_ss *head;
5490 switch (expr->expr_type)
5492 case EXPR_VARIABLE:
5493 head = gfc_walk_variable_expr (ss, expr);
5494 return head;
5496 case EXPR_OP:
5497 head = gfc_walk_op_expr (ss, expr);
5498 return head;
5500 case EXPR_FUNCTION:
5501 head = gfc_walk_function_expr (ss, expr);
5502 return head;
5504 case EXPR_CONSTANT:
5505 case EXPR_NULL:
5506 case EXPR_STRUCTURE:
5507 /* Pass back and let the caller deal with it. */
5508 break;
5510 case EXPR_ARRAY:
5511 head = gfc_walk_array_constructor (ss, expr);
5512 return head;
5514 case EXPR_SUBSTRING:
5515 /* Pass back and let the caller deal with it. */
5516 break;
5518 default:
5519 internal_error ("bad expression type during walk (%d)",
5520 expr->expr_type);
5522 return ss;
5526 /* Entry point for expression walking.
5527 A return value equal to the passed chain means this is
5528 a scalar expression. It is up to the caller to take whatever action is
5529 necessary to translate these. */
5531 gfc_ss *
5532 gfc_walk_expr (gfc_expr * expr)
5534 gfc_ss *res;
5536 res = gfc_walk_subexpr (gfc_ss_terminator, expr);
5537 return gfc_reverse_ss (res);