1 /* Array translation routines
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4 Free Software Foundation, Inc.
5 Contributed by Paul Brook <paul@nowt.org>
6 and Steven Bosscher <s.bosscher@student.tudelft.nl>
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
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
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 subscripts 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
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. */
82 #include "coretypes.h"
85 #include "diagnostic-core.h" /* For internal_error/fatal_error. */
88 #include "constructor.h"
90 #include "trans-stmt.h"
91 #include "trans-types.h"
92 #include "trans-array.h"
93 #include "trans-const.h"
94 #include "dependency.h"
96 static bool gfc_get_array_constructor_size (mpz_t *, gfc_constructor_base);
98 /* The contents of this structure aren't actually used, just the address. */
99 static gfc_ss gfc_ss_terminator_var;
100 gfc_ss * const gfc_ss_terminator = &gfc_ss_terminator_var;
104 gfc_array_dataptr_type (tree desc)
106 return (GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc)));
110 /* Build expressions to access the members of an array descriptor.
111 It's surprisingly easy to mess up here, so never access
112 an array descriptor by "brute force", always use these
113 functions. This also avoids problems if we change the format
114 of an array descriptor.
116 To understand these magic numbers, look at the comments
117 before gfc_build_array_type() in trans-types.c.
119 The code within these defines should be the only code which knows the format
120 of an array descriptor.
122 Any code just needing to read obtain the bounds of an array should use
123 gfc_conv_array_* rather than the following functions as these will return
124 know constant values, and work with arrays which do not have descriptors.
126 Don't forget to #undef these! */
129 #define OFFSET_FIELD 1
130 #define DTYPE_FIELD 2
131 #define DIMENSION_FIELD 3
132 #define CAF_TOKEN_FIELD 4
134 #define STRIDE_SUBFIELD 0
135 #define LBOUND_SUBFIELD 1
136 #define UBOUND_SUBFIELD 2
138 /* This provides READ-ONLY access to the data field. The field itself
139 doesn't have the proper type. */
142 gfc_conv_descriptor_data_get (tree desc)
146 type = TREE_TYPE (desc);
147 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
149 field = TYPE_FIELDS (type);
150 gcc_assert (DATA_FIELD == 0);
152 t = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), desc,
154 t = fold_convert (GFC_TYPE_ARRAY_DATAPTR_TYPE (type), 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. */
168 gfc_conv_descriptor_data_set (stmtblock_t *block, tree desc, tree value)
172 type = TREE_TYPE (desc);
173 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
175 field = TYPE_FIELDS (type);
176 gcc_assert (DATA_FIELD == 0);
178 t = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), desc,
180 gfc_add_modify (block, t, fold_convert (TREE_TYPE (field), value));
184 /* This provides address access to the data field. This should only be
185 used by array allocation, passing this on to the runtime. */
188 gfc_conv_descriptor_data_addr (tree desc)
192 type = TREE_TYPE (desc);
193 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
195 field = TYPE_FIELDS (type);
196 gcc_assert (DATA_FIELD == 0);
198 t = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), desc,
200 return gfc_build_addr_expr (NULL_TREE, t);
204 gfc_conv_descriptor_offset (tree desc)
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 fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
216 desc, field, NULL_TREE);
220 gfc_conv_descriptor_offset_get (tree desc)
222 return gfc_conv_descriptor_offset (desc);
226 gfc_conv_descriptor_offset_set (stmtblock_t *block, tree desc,
229 tree t = gfc_conv_descriptor_offset (desc);
230 gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
235 gfc_conv_descriptor_dtype (tree desc)
240 type = TREE_TYPE (desc);
241 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
243 field = gfc_advance_chain (TYPE_FIELDS (type), DTYPE_FIELD);
244 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
246 return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
247 desc, field, NULL_TREE);
251 gfc_conv_descriptor_dimension (tree desc, tree dim)
257 type = TREE_TYPE (desc);
258 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
260 field = gfc_advance_chain (TYPE_FIELDS (type), DIMENSION_FIELD);
261 gcc_assert (field != NULL_TREE
262 && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
263 && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE);
265 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
266 desc, field, NULL_TREE);
267 tmp = gfc_build_array_ref (tmp, dim, NULL);
273 gfc_conv_descriptor_token (tree desc)
278 type = TREE_TYPE (desc);
279 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
280 gcc_assert (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE);
281 gcc_assert (gfc_option.coarray == GFC_FCOARRAY_LIB);
282 field = gfc_advance_chain (TYPE_FIELDS (type), CAF_TOKEN_FIELD);
283 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == prvoid_type_node);
285 return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
286 desc, field, NULL_TREE);
291 gfc_conv_descriptor_stride (tree desc, tree dim)
296 tmp = gfc_conv_descriptor_dimension (desc, dim);
297 field = TYPE_FIELDS (TREE_TYPE (tmp));
298 field = gfc_advance_chain (field, STRIDE_SUBFIELD);
299 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
301 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
302 tmp, field, NULL_TREE);
307 gfc_conv_descriptor_stride_get (tree desc, tree dim)
309 tree type = TREE_TYPE (desc);
310 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
311 if (integer_zerop (dim)
312 && (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE
313 ||GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_SHAPE_CONT
314 ||GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER_CONT))
315 return gfc_index_one_node;
317 return gfc_conv_descriptor_stride (desc, dim);
321 gfc_conv_descriptor_stride_set (stmtblock_t *block, tree desc,
322 tree dim, tree value)
324 tree t = gfc_conv_descriptor_stride (desc, dim);
325 gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
329 gfc_conv_descriptor_lbound (tree desc, tree dim)
334 tmp = gfc_conv_descriptor_dimension (desc, dim);
335 field = TYPE_FIELDS (TREE_TYPE (tmp));
336 field = gfc_advance_chain (field, LBOUND_SUBFIELD);
337 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
339 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
340 tmp, field, NULL_TREE);
345 gfc_conv_descriptor_lbound_get (tree desc, tree dim)
347 return gfc_conv_descriptor_lbound (desc, dim);
351 gfc_conv_descriptor_lbound_set (stmtblock_t *block, tree desc,
352 tree dim, tree value)
354 tree t = gfc_conv_descriptor_lbound (desc, dim);
355 gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
359 gfc_conv_descriptor_ubound (tree desc, tree dim)
364 tmp = gfc_conv_descriptor_dimension (desc, dim);
365 field = TYPE_FIELDS (TREE_TYPE (tmp));
366 field = gfc_advance_chain (field, UBOUND_SUBFIELD);
367 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
369 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
370 tmp, field, NULL_TREE);
375 gfc_conv_descriptor_ubound_get (tree desc, tree dim)
377 return gfc_conv_descriptor_ubound (desc, dim);
381 gfc_conv_descriptor_ubound_set (stmtblock_t *block, tree desc,
382 tree dim, tree value)
384 tree t = gfc_conv_descriptor_ubound (desc, dim);
385 gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
388 /* Build a null array descriptor constructor. */
391 gfc_build_null_descriptor (tree type)
396 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
397 gcc_assert (DATA_FIELD == 0);
398 field = TYPE_FIELDS (type);
400 /* Set a NULL data pointer. */
401 tmp = build_constructor_single (type, field, null_pointer_node);
402 TREE_CONSTANT (tmp) = 1;
403 /* All other fields are ignored. */
409 /* Modify a descriptor such that the lbound of a given dimension is the value
410 specified. This also updates ubound and offset accordingly. */
413 gfc_conv_shift_descriptor_lbound (stmtblock_t* block, tree desc,
414 int dim, tree new_lbound)
416 tree offs, ubound, lbound, stride;
417 tree diff, offs_diff;
419 new_lbound = fold_convert (gfc_array_index_type, new_lbound);
421 offs = gfc_conv_descriptor_offset_get (desc);
422 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]);
423 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]);
424 stride = gfc_conv_descriptor_stride_get (desc, gfc_rank_cst[dim]);
426 /* Get difference (new - old) by which to shift stuff. */
427 diff = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
430 /* Shift ubound and offset accordingly. This has to be done before
431 updating the lbound, as they depend on the lbound expression! */
432 ubound = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
434 gfc_conv_descriptor_ubound_set (block, desc, gfc_rank_cst[dim], ubound);
435 offs_diff = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
437 offs = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
439 gfc_conv_descriptor_offset_set (block, desc, offs);
441 /* Finally set lbound to value we want. */
442 gfc_conv_descriptor_lbound_set (block, desc, gfc_rank_cst[dim], new_lbound);
446 /* Cleanup those #defines. */
451 #undef DIMENSION_FIELD
452 #undef CAF_TOKEN_FIELD
453 #undef STRIDE_SUBFIELD
454 #undef LBOUND_SUBFIELD
455 #undef UBOUND_SUBFIELD
458 /* Mark a SS chain as used. Flags specifies in which loops the SS is used.
459 flags & 1 = Main loop body.
460 flags & 2 = temp copy loop. */
463 gfc_mark_ss_chain_used (gfc_ss * ss, unsigned flags)
465 for (; ss != gfc_ss_terminator; ss = ss->next)
466 ss->info->useflags = flags;
470 /* Free a gfc_ss chain. */
473 gfc_free_ss_chain (gfc_ss * ss)
477 while (ss != gfc_ss_terminator)
479 gcc_assert (ss != NULL);
488 free_ss_info (gfc_ss_info *ss_info)
491 if (ss_info->refcount > 0)
494 gcc_assert (ss_info->refcount == 0);
502 gfc_free_ss (gfc_ss * ss)
504 gfc_ss_info *ss_info;
509 switch (ss_info->type)
512 for (n = 0; n < ss->dimen; n++)
514 if (ss_info->data.array.subscript[ss->dim[n]])
515 gfc_free_ss_chain (ss_info->data.array.subscript[ss->dim[n]]);
523 free_ss_info (ss_info);
528 /* Creates and initializes an array type gfc_ss struct. */
531 gfc_get_array_ss (gfc_ss *next, gfc_expr *expr, int dimen, gfc_ss_type type)
534 gfc_ss_info *ss_info;
537 ss_info = gfc_get_ss_info ();
539 ss_info->type = type;
540 ss_info->expr = expr;
546 for (i = 0; i < ss->dimen; i++)
553 /* Creates and initializes a temporary type gfc_ss struct. */
556 gfc_get_temp_ss (tree type, tree string_length, int dimen)
559 gfc_ss_info *ss_info;
562 ss_info = gfc_get_ss_info ();
564 ss_info->type = GFC_SS_TEMP;
565 ss_info->string_length = string_length;
566 ss_info->data.temp.type = type;
570 ss->next = gfc_ss_terminator;
572 for (i = 0; i < ss->dimen; i++)
579 /* Creates and initializes a scalar type gfc_ss struct. */
582 gfc_get_scalar_ss (gfc_ss *next, gfc_expr *expr)
585 gfc_ss_info *ss_info;
587 ss_info = gfc_get_ss_info ();
589 ss_info->type = GFC_SS_SCALAR;
590 ss_info->expr = expr;
600 /* Free all the SS associated with a loop. */
603 gfc_cleanup_loop (gfc_loopinfo * loop)
605 gfc_loopinfo *loop_next, **ploop;
610 while (ss != gfc_ss_terminator)
612 gcc_assert (ss != NULL);
613 next = ss->loop_chain;
618 /* Remove reference to self in the parent loop. */
620 for (ploop = &loop->parent->nested; *ploop; ploop = &(*ploop)->next)
627 /* Free non-freed nested loops. */
628 for (loop = loop->nested; loop; loop = loop_next)
630 loop_next = loop->next;
631 gfc_cleanup_loop (loop);
638 set_ss_loop (gfc_ss *ss, gfc_loopinfo *loop)
642 for (; ss != gfc_ss_terminator; ss = ss->next)
646 if (ss->info->type == GFC_SS_SCALAR
647 || ss->info->type == GFC_SS_REFERENCE
648 || ss->info->type == GFC_SS_TEMP)
651 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
652 if (ss->info->data.array.subscript[n] != NULL)
653 set_ss_loop (ss->info->data.array.subscript[n], loop);
658 /* Associate a SS chain with a loop. */
661 gfc_add_ss_to_loop (gfc_loopinfo * loop, gfc_ss * head)
664 gfc_loopinfo *nested_loop;
666 if (head == gfc_ss_terminator)
669 set_ss_loop (head, loop);
672 for (; ss && ss != gfc_ss_terminator; ss = ss->next)
676 nested_loop = ss->nested_ss->loop;
678 /* More than one ss can belong to the same loop. Hence, we add the
679 loop to the chain only if it is different from the previously
680 added one, to avoid duplicate nested loops. */
681 if (nested_loop != loop->nested)
683 gcc_assert (nested_loop->parent == NULL);
684 nested_loop->parent = loop;
686 gcc_assert (nested_loop->next == NULL);
687 nested_loop->next = loop->nested;
688 loop->nested = nested_loop;
691 gcc_assert (nested_loop->parent == loop);
694 if (ss->next == gfc_ss_terminator)
695 ss->loop_chain = loop->ss;
697 ss->loop_chain = ss->next;
699 gcc_assert (ss == gfc_ss_terminator);
704 /* Generate an initializer for a static pointer or allocatable array. */
707 gfc_trans_static_array_pointer (gfc_symbol * sym)
711 gcc_assert (TREE_STATIC (sym->backend_decl));
712 /* Just zero the data member. */
713 type = TREE_TYPE (sym->backend_decl);
714 DECL_INITIAL (sym->backend_decl) = gfc_build_null_descriptor (type);
718 /* If the bounds of SE's loop have not yet been set, see if they can be
719 determined from array spec AS, which is the array spec of a called
720 function. MAPPING maps the callee's dummy arguments to the values
721 that the caller is passing. Add any initialization and finalization
725 gfc_set_loop_bounds_from_array_spec (gfc_interface_mapping * mapping,
726 gfc_se * se, gfc_array_spec * as)
728 int n, dim, total_dim;
737 if (!as || as->type != AS_EXPLICIT)
740 for (ss = se->ss; ss; ss = ss->parent)
742 total_dim += ss->loop->dimen;
743 for (n = 0; n < ss->loop->dimen; n++)
745 /* The bound is known, nothing to do. */
746 if (ss->loop->to[n] != NULL_TREE)
750 gcc_assert (dim < as->rank);
751 gcc_assert (ss->loop->dimen <= as->rank);
753 /* Evaluate the lower bound. */
754 gfc_init_se (&tmpse, NULL);
755 gfc_apply_interface_mapping (mapping, &tmpse, as->lower[dim]);
756 gfc_add_block_to_block (&se->pre, &tmpse.pre);
757 gfc_add_block_to_block (&se->post, &tmpse.post);
758 lower = fold_convert (gfc_array_index_type, tmpse.expr);
760 /* ...and the upper bound. */
761 gfc_init_se (&tmpse, NULL);
762 gfc_apply_interface_mapping (mapping, &tmpse, as->upper[dim]);
763 gfc_add_block_to_block (&se->pre, &tmpse.pre);
764 gfc_add_block_to_block (&se->post, &tmpse.post);
765 upper = fold_convert (gfc_array_index_type, tmpse.expr);
767 /* Set the upper bound of the loop to UPPER - LOWER. */
768 tmp = fold_build2_loc (input_location, MINUS_EXPR,
769 gfc_array_index_type, upper, lower);
770 tmp = gfc_evaluate_now (tmp, &se->pre);
771 ss->loop->to[n] = tmp;
775 gcc_assert (total_dim == as->rank);
779 /* Generate code to allocate an array temporary, or create a variable to
780 hold the data. If size is NULL, zero the descriptor so that the
781 callee will allocate the array. If DEALLOC is true, also generate code to
782 free the array afterwards.
784 If INITIAL is not NULL, it is packed using internal_pack and the result used
785 as data instead of allocating a fresh, unitialized area of memory.
787 Initialization code is added to PRE and finalization code to POST.
788 DYNAMIC is true if the caller may want to extend the array later
789 using realloc. This prevents us from putting the array on the stack. */
792 gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
793 gfc_array_info * info, tree size, tree nelem,
794 tree initial, bool dynamic, bool dealloc)
800 desc = info->descriptor;
801 info->offset = gfc_index_zero_node;
802 if (size == NULL_TREE || integer_zerop (size))
804 /* A callee allocated array. */
805 gfc_conv_descriptor_data_set (pre, desc, null_pointer_node);
810 /* Allocate the temporary. */
811 onstack = !dynamic && initial == NULL_TREE
812 && (gfc_option.flag_stack_arrays
813 || gfc_can_put_var_on_stack (size));
817 /* Make a temporary variable to hold the data. */
818 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (nelem),
819 nelem, gfc_index_one_node);
820 tmp = gfc_evaluate_now (tmp, pre);
821 tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
823 tmp = build_array_type (gfc_get_element_type (TREE_TYPE (desc)),
825 tmp = gfc_create_var (tmp, "A");
826 /* If we're here only because of -fstack-arrays we have to
827 emit a DECL_EXPR to make the gimplifier emit alloca calls. */
828 if (!gfc_can_put_var_on_stack (size))
829 gfc_add_expr_to_block (pre,
830 fold_build1_loc (input_location,
831 DECL_EXPR, TREE_TYPE (tmp),
833 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
834 gfc_conv_descriptor_data_set (pre, desc, tmp);
838 /* Allocate memory to hold the data or call internal_pack. */
839 if (initial == NULL_TREE)
841 tmp = gfc_call_malloc (pre, NULL, size);
842 tmp = gfc_evaluate_now (tmp, pre);
849 stmtblock_t do_copying;
851 tmp = TREE_TYPE (initial); /* Pointer to descriptor. */
852 gcc_assert (TREE_CODE (tmp) == POINTER_TYPE);
853 tmp = TREE_TYPE (tmp); /* The descriptor itself. */
854 tmp = gfc_get_element_type (tmp);
855 gcc_assert (tmp == gfc_get_element_type (TREE_TYPE (desc)));
856 packed = gfc_create_var (build_pointer_type (tmp), "data");
858 tmp = build_call_expr_loc (input_location,
859 gfor_fndecl_in_pack, 1, initial);
860 tmp = fold_convert (TREE_TYPE (packed), tmp);
861 gfc_add_modify (pre, packed, tmp);
863 tmp = build_fold_indirect_ref_loc (input_location,
865 source_data = gfc_conv_descriptor_data_get (tmp);
867 /* internal_pack may return source->data without any allocation
868 or copying if it is already packed. If that's the case, we
869 need to allocate and copy manually. */
871 gfc_start_block (&do_copying);
872 tmp = gfc_call_malloc (&do_copying, NULL, size);
873 tmp = fold_convert (TREE_TYPE (packed), tmp);
874 gfc_add_modify (&do_copying, packed, tmp);
875 tmp = gfc_build_memcpy_call (packed, source_data, size);
876 gfc_add_expr_to_block (&do_copying, tmp);
878 was_packed = fold_build2_loc (input_location, EQ_EXPR,
879 boolean_type_node, packed,
881 tmp = gfc_finish_block (&do_copying);
882 tmp = build3_v (COND_EXPR, was_packed, tmp,
883 build_empty_stmt (input_location));
884 gfc_add_expr_to_block (pre, tmp);
886 tmp = fold_convert (pvoid_type_node, packed);
889 gfc_conv_descriptor_data_set (pre, desc, tmp);
892 info->data = gfc_conv_descriptor_data_get (desc);
894 /* The offset is zero because we create temporaries with a zero
896 gfc_conv_descriptor_offset_set (pre, desc, gfc_index_zero_node);
898 if (dealloc && !onstack)
900 /* Free the temporary. */
901 tmp = gfc_conv_descriptor_data_get (desc);
902 tmp = gfc_call_free (fold_convert (pvoid_type_node, tmp));
903 gfc_add_expr_to_block (post, tmp);
908 /* Get the scalarizer array dimension corresponding to actual array dimension
911 For example, if SS represents the array ref a(1,:,:,1), it is a
912 bidimensional scalarizer array, and the result would be 0 for ARRAY_DIM=1,
913 and 1 for ARRAY_DIM=2.
914 If SS represents transpose(a(:,1,1,:)), it is again a bidimensional
915 scalarizer array, and the result would be 1 for ARRAY_DIM=0 and 0 for
917 If SS represents sum(a(:,:,:,1), dim=1), it is a 2+1-dimensional scalarizer
918 array. If called on the inner ss, the result would be respectively 0,1,2 for
919 ARRAY_DIM=0,1,2. If called on the outer ss, the result would be 0,1
920 for ARRAY_DIM=1,2. */
923 get_scalarizer_dim_for_array_dim (gfc_ss *ss, int array_dim)
930 for (; ss; ss = ss->parent)
931 for (n = 0; n < ss->dimen; n++)
932 if (ss->dim[n] < array_dim)
935 return array_ref_dim;
940 innermost_ss (gfc_ss *ss)
942 while (ss->nested_ss != NULL)
950 /* Get the array reference dimension corresponding to the given loop dimension.
951 It is different from the true array dimension given by the dim array in
952 the case of a partial array reference (i.e. a(:,:,1,:) for example)
953 It is different from the loop dimension in the case of a transposed array.
957 get_array_ref_dim_for_loop_dim (gfc_ss *ss, int loop_dim)
959 return get_scalarizer_dim_for_array_dim (innermost_ss (ss),
964 /* Generate code to create and initialize the descriptor for a temporary
965 array. This is used for both temporaries needed by the scalarizer, and
966 functions returning arrays. Adjusts the loop variables to be
967 zero-based, and calculates the loop bounds for callee allocated arrays.
968 Allocate the array unless it's callee allocated (we have a callee
969 allocated array if 'callee_alloc' is true, or if loop->to[n] is
970 NULL_TREE for any n). Also fills in the descriptor, data and offset
971 fields of info if known. Returns the size of the array, or NULL for a
972 callee allocated array.
974 'eltype' == NULL signals that the temporary should be a class object.
975 The 'initial' expression is used to obtain the size of the dynamic
976 type; otehrwise the allocation and initialisation proceeds as for any
979 PRE, POST, INITIAL, DYNAMIC and DEALLOC are as for
980 gfc_trans_allocate_array_storage. */
983 gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss,
984 tree eltype, tree initial, bool dynamic,
985 bool dealloc, bool callee_alloc, locus * where)
989 gfc_array_info *info;
990 tree from[GFC_MAX_DIMENSIONS], to[GFC_MAX_DIMENSIONS];
998 tree class_expr = NULL_TREE;
1002 /* This signals a class array for which we need the size of the
1003 dynamic type. Generate an eltype and then the class expression. */
1004 if (eltype == NULL_TREE && initial)
1006 if (POINTER_TYPE_P (TREE_TYPE (initial)))
1007 class_expr = build_fold_indirect_ref_loc (input_location, initial);
1008 eltype = TREE_TYPE (class_expr);
1009 eltype = gfc_get_element_type (eltype);
1010 /* Obtain the structure (class) expression. */
1011 class_expr = TREE_OPERAND (class_expr, 0);
1012 gcc_assert (class_expr);
1015 memset (from, 0, sizeof (from));
1016 memset (to, 0, sizeof (to));
1018 info = &ss->info->data.array;
1020 gcc_assert (ss->dimen > 0);
1021 gcc_assert (ss->loop->dimen == ss->dimen);
1023 if (gfc_option.warn_array_temp && where)
1024 gfc_warning ("Creating array temporary at %L", where);
1026 /* Set the lower bound to zero. */
1027 for (s = ss; s; s = s->parent)
1031 total_dim += loop->dimen;
1032 for (n = 0; n < loop->dimen; n++)
1036 /* Callee allocated arrays may not have a known bound yet. */
1038 loop->to[n] = gfc_evaluate_now (
1039 fold_build2_loc (input_location, MINUS_EXPR,
1040 gfc_array_index_type,
1041 loop->to[n], loop->from[n]),
1043 loop->from[n] = gfc_index_zero_node;
1045 /* We have just changed the loop bounds, we must clear the
1046 corresponding specloop, so that delta calculation is not skipped
1047 later in gfc_set_delta. */
1048 loop->specloop[n] = NULL;
1050 /* We are constructing the temporary's descriptor based on the loop
1051 dimensions. As the dimensions may be accessed in arbitrary order
1052 (think of transpose) the size taken from the n'th loop may not map
1053 to the n'th dimension of the array. We need to reconstruct loop
1054 infos in the right order before using it to set the descriptor
1056 tmp_dim = get_scalarizer_dim_for_array_dim (ss, dim);
1057 from[tmp_dim] = loop->from[n];
1058 to[tmp_dim] = loop->to[n];
1060 info->delta[dim] = gfc_index_zero_node;
1061 info->start[dim] = gfc_index_zero_node;
1062 info->end[dim] = gfc_index_zero_node;
1063 info->stride[dim] = gfc_index_one_node;
1067 /* Initialize the descriptor. */
1069 gfc_get_array_type_bounds (eltype, total_dim, 0, from, to, 1,
1070 GFC_ARRAY_UNKNOWN, true);
1071 desc = gfc_create_var (type, "atmp");
1072 GFC_DECL_PACKED_ARRAY (desc) = 1;
1074 info->descriptor = desc;
1075 size = gfc_index_one_node;
1077 /* Fill in the array dtype. */
1078 tmp = gfc_conv_descriptor_dtype (desc);
1079 gfc_add_modify (pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
1082 Fill in the bounds and stride. This is a packed array, so:
1085 for (n = 0; n < rank; n++)
1088 delta = ubound[n] + 1 - lbound[n];
1089 size = size * delta;
1091 size = size * sizeof(element);
1094 or_expr = NULL_TREE;
1096 /* If there is at least one null loop->to[n], it is a callee allocated
1098 for (n = 0; n < total_dim; n++)
1099 if (to[n] == NULL_TREE)
1105 if (size == NULL_TREE)
1106 for (s = ss; s; s = s->parent)
1107 for (n = 0; n < s->loop->dimen; n++)
1109 dim = get_scalarizer_dim_for_array_dim (ss, s->dim[n]);
1111 /* For a callee allocated array express the loop bounds in terms
1112 of the descriptor fields. */
1113 tmp = fold_build2_loc (input_location,
1114 MINUS_EXPR, gfc_array_index_type,
1115 gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]),
1116 gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]));
1117 s->loop->to[n] = tmp;
1121 for (n = 0; n < total_dim; n++)
1123 /* Store the stride and bound components in the descriptor. */
1124 gfc_conv_descriptor_stride_set (pre, desc, gfc_rank_cst[n], size);
1126 gfc_conv_descriptor_lbound_set (pre, desc, gfc_rank_cst[n],
1127 gfc_index_zero_node);
1129 gfc_conv_descriptor_ubound_set (pre, desc, gfc_rank_cst[n], to[n]);
1131 tmp = fold_build2_loc (input_location, PLUS_EXPR,
1132 gfc_array_index_type,
1133 to[n], gfc_index_one_node);
1135 /* Check whether the size for this dimension is negative. */
1136 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
1137 tmp, gfc_index_zero_node);
1138 cond = gfc_evaluate_now (cond, pre);
1143 or_expr = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1144 boolean_type_node, or_expr, cond);
1146 size = fold_build2_loc (input_location, MULT_EXPR,
1147 gfc_array_index_type, size, tmp);
1148 size = gfc_evaluate_now (size, pre);
1152 /* Get the size of the array. */
1153 if (size && !callee_alloc)
1156 /* If or_expr is true, then the extent in at least one
1157 dimension is zero and the size is set to zero. */
1158 size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
1159 or_expr, gfc_index_zero_node, size);
1162 if (class_expr == NULL_TREE)
1163 elemsize = fold_convert (gfc_array_index_type,
1164 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
1166 elemsize = gfc_vtable_size_get (class_expr);
1168 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
1177 gfc_trans_allocate_array_storage (pre, post, info, size, nelem, initial,
1183 if (ss->dimen > ss->loop->temp_dim)
1184 ss->loop->temp_dim = ss->dimen;
1190 /* Return the number of iterations in a loop that starts at START,
1191 ends at END, and has step STEP. */
1194 gfc_get_iteration_count (tree start, tree end, tree step)
1199 type = TREE_TYPE (step);
1200 tmp = fold_build2_loc (input_location, MINUS_EXPR, type, end, start);
1201 tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, type, tmp, step);
1202 tmp = fold_build2_loc (input_location, PLUS_EXPR, type, tmp,
1203 build_int_cst (type, 1));
1204 tmp = fold_build2_loc (input_location, MAX_EXPR, type, tmp,
1205 build_int_cst (type, 0));
1206 return fold_convert (gfc_array_index_type, tmp);
1210 /* Extend the data in array DESC by EXTRA elements. */
1213 gfc_grow_array (stmtblock_t * pblock, tree desc, tree extra)
1220 if (integer_zerop (extra))
1223 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[0]);
1225 /* Add EXTRA to the upper bound. */
1226 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1228 gfc_conv_descriptor_ubound_set (pblock, desc, gfc_rank_cst[0], tmp);
1230 /* Get the value of the current data pointer. */
1231 arg0 = gfc_conv_descriptor_data_get (desc);
1233 /* Calculate the new array size. */
1234 size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
1235 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1236 ubound, gfc_index_one_node);
1237 arg1 = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
1238 fold_convert (size_type_node, tmp),
1239 fold_convert (size_type_node, size));
1241 /* Call the realloc() function. */
1242 tmp = gfc_call_realloc (pblock, arg0, arg1);
1243 gfc_conv_descriptor_data_set (pblock, desc, tmp);
1247 /* Return true if the bounds of iterator I can only be determined
1251 gfc_iterator_has_dynamic_bounds (gfc_iterator * i)
1253 return (i->start->expr_type != EXPR_CONSTANT
1254 || i->end->expr_type != EXPR_CONSTANT
1255 || i->step->expr_type != EXPR_CONSTANT);
1259 /* Split the size of constructor element EXPR into the sum of two terms,
1260 one of which can be determined at compile time and one of which must
1261 be calculated at run time. Set *SIZE to the former and return true
1262 if the latter might be nonzero. */
1265 gfc_get_array_constructor_element_size (mpz_t * size, gfc_expr * expr)
1267 if (expr->expr_type == EXPR_ARRAY)
1268 return gfc_get_array_constructor_size (size, expr->value.constructor);
1269 else if (expr->rank > 0)
1271 /* Calculate everything at run time. */
1272 mpz_set_ui (*size, 0);
1277 /* A single element. */
1278 mpz_set_ui (*size, 1);
1284 /* Like gfc_get_array_constructor_element_size, but applied to the whole
1285 of array constructor C. */
1288 gfc_get_array_constructor_size (mpz_t * size, gfc_constructor_base base)
1296 mpz_set_ui (*size, 0);
1301 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
1304 if (i && gfc_iterator_has_dynamic_bounds (i))
1308 dynamic |= gfc_get_array_constructor_element_size (&len, c->expr);
1311 /* Multiply the static part of the element size by the
1312 number of iterations. */
1313 mpz_sub (val, i->end->value.integer, i->start->value.integer);
1314 mpz_fdiv_q (val, val, i->step->value.integer);
1315 mpz_add_ui (val, val, 1);
1316 if (mpz_sgn (val) > 0)
1317 mpz_mul (len, len, val);
1319 mpz_set_ui (len, 0);
1321 mpz_add (*size, *size, len);
1330 /* Make sure offset is a variable. */
1333 gfc_put_offset_into_var (stmtblock_t * pblock, tree * poffset,
1336 /* We should have already created the offset variable. We cannot
1337 create it here because we may be in an inner scope. */
1338 gcc_assert (*offsetvar != NULL_TREE);
1339 gfc_add_modify (pblock, *offsetvar, *poffset);
1340 *poffset = *offsetvar;
1341 TREE_USED (*offsetvar) = 1;
1345 /* Variables needed for bounds-checking. */
1346 static bool first_len;
1347 static tree first_len_val;
1348 static bool typespec_chararray_ctor;
1351 gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc,
1352 tree offset, gfc_se * se, gfc_expr * expr)
1356 gfc_conv_expr (se, expr);
1358 /* Store the value. */
1359 tmp = build_fold_indirect_ref_loc (input_location,
1360 gfc_conv_descriptor_data_get (desc));
1361 tmp = gfc_build_array_ref (tmp, offset, NULL);
1363 if (expr->ts.type == BT_CHARACTER)
1365 int i = gfc_validate_kind (BT_CHARACTER, expr->ts.kind, false);
1368 esize = size_in_bytes (gfc_get_element_type (TREE_TYPE (desc)));
1369 esize = fold_convert (gfc_charlen_type_node, esize);
1370 esize = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
1371 gfc_charlen_type_node, esize,
1372 build_int_cst (gfc_charlen_type_node,
1373 gfc_character_kinds[i].bit_size / 8));
1375 gfc_conv_string_parameter (se);
1376 if (POINTER_TYPE_P (TREE_TYPE (tmp)))
1378 /* The temporary is an array of pointers. */
1379 se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
1380 gfc_add_modify (&se->pre, tmp, se->expr);
1384 /* The temporary is an array of string values. */
1385 tmp = gfc_build_addr_expr (gfc_get_pchar_type (expr->ts.kind), tmp);
1386 /* We know the temporary and the value will be the same length,
1387 so can use memcpy. */
1388 gfc_trans_string_copy (&se->pre, esize, tmp, expr->ts.kind,
1389 se->string_length, se->expr, expr->ts.kind);
1391 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && !typespec_chararray_ctor)
1395 gfc_add_modify (&se->pre, first_len_val,
1401 /* Verify that all constructor elements are of the same
1403 tree cond = fold_build2_loc (input_location, NE_EXPR,
1404 boolean_type_node, first_len_val,
1406 gfc_trans_runtime_check
1407 (true, false, cond, &se->pre, &expr->where,
1408 "Different CHARACTER lengths (%ld/%ld) in array constructor",
1409 fold_convert (long_integer_type_node, first_len_val),
1410 fold_convert (long_integer_type_node, se->string_length));
1416 /* TODO: Should the frontend already have done this conversion? */
1417 se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
1418 gfc_add_modify (&se->pre, tmp, se->expr);
1421 gfc_add_block_to_block (pblock, &se->pre);
1422 gfc_add_block_to_block (pblock, &se->post);
1426 /* Add the contents of an array to the constructor. DYNAMIC is as for
1427 gfc_trans_array_constructor_value. */
1430 gfc_trans_array_constructor_subarray (stmtblock_t * pblock,
1431 tree type ATTRIBUTE_UNUSED,
1432 tree desc, gfc_expr * expr,
1433 tree * poffset, tree * offsetvar,
1444 /* We need this to be a variable so we can increment it. */
1445 gfc_put_offset_into_var (pblock, poffset, offsetvar);
1447 gfc_init_se (&se, NULL);
1449 /* Walk the array expression. */
1450 ss = gfc_walk_expr (expr);
1451 gcc_assert (ss != gfc_ss_terminator);
1453 /* Initialize the scalarizer. */
1454 gfc_init_loopinfo (&loop);
1455 gfc_add_ss_to_loop (&loop, ss);
1457 /* Initialize the loop. */
1458 gfc_conv_ss_startstride (&loop);
1459 gfc_conv_loop_setup (&loop, &expr->where);
1461 /* Make sure the constructed array has room for the new data. */
1464 /* Set SIZE to the total number of elements in the subarray. */
1465 size = gfc_index_one_node;
1466 for (n = 0; n < loop.dimen; n++)
1468 tmp = gfc_get_iteration_count (loop.from[n], loop.to[n],
1469 gfc_index_one_node);
1470 size = fold_build2_loc (input_location, MULT_EXPR,
1471 gfc_array_index_type, size, tmp);
1474 /* Grow the constructed array by SIZE elements. */
1475 gfc_grow_array (&loop.pre, desc, size);
1478 /* Make the loop body. */
1479 gfc_mark_ss_chain_used (ss, 1);
1480 gfc_start_scalarized_body (&loop, &body);
1481 gfc_copy_loopinfo_to_se (&se, &loop);
1484 gfc_trans_array_ctor_element (&body, desc, *poffset, &se, expr);
1485 gcc_assert (se.ss == gfc_ss_terminator);
1487 /* Increment the offset. */
1488 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1489 *poffset, gfc_index_one_node);
1490 gfc_add_modify (&body, *poffset, tmp);
1492 /* Finish the loop. */
1493 gfc_trans_scalarizing_loops (&loop, &body);
1494 gfc_add_block_to_block (&loop.pre, &loop.post);
1495 tmp = gfc_finish_block (&loop.pre);
1496 gfc_add_expr_to_block (pblock, tmp);
1498 gfc_cleanup_loop (&loop);
1502 /* Assign the values to the elements of an array constructor. DYNAMIC
1503 is true if descriptor DESC only contains enough data for the static
1504 size calculated by gfc_get_array_constructor_size. When true, memory
1505 for the dynamic parts must be allocated using realloc. */
1508 gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
1509 tree desc, gfc_constructor_base base,
1510 tree * poffset, tree * offsetvar,
1519 tree shadow_loopvar = NULL_TREE;
1520 gfc_saved_var saved_loopvar;
1523 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
1525 /* If this is an iterator or an array, the offset must be a variable. */
1526 if ((c->iterator || c->expr->rank > 0) && INTEGER_CST_P (*poffset))
1527 gfc_put_offset_into_var (pblock, poffset, offsetvar);
1529 /* Shadowing the iterator avoids changing its value and saves us from
1530 keeping track of it. Further, it makes sure that there's always a
1531 backend-decl for the symbol, even if there wasn't one before,
1532 e.g. in the case of an iterator that appears in a specification
1533 expression in an interface mapping. */
1536 gfc_symbol *sym = c->iterator->var->symtree->n.sym;
1537 tree type = gfc_typenode_for_spec (&sym->ts);
1539 shadow_loopvar = gfc_create_var (type, "shadow_loopvar");
1540 gfc_shadow_sym (sym, shadow_loopvar, &saved_loopvar);
1543 gfc_start_block (&body);
1545 if (c->expr->expr_type == EXPR_ARRAY)
1547 /* Array constructors can be nested. */
1548 gfc_trans_array_constructor_value (&body, type, desc,
1549 c->expr->value.constructor,
1550 poffset, offsetvar, dynamic);
1552 else if (c->expr->rank > 0)
1554 gfc_trans_array_constructor_subarray (&body, type, desc, c->expr,
1555 poffset, offsetvar, dynamic);
1559 /* This code really upsets the gimplifier so don't bother for now. */
1566 while (p && !(p->iterator || p->expr->expr_type != EXPR_CONSTANT))
1568 p = gfc_constructor_next (p);
1573 /* Scalar values. */
1574 gfc_init_se (&se, NULL);
1575 gfc_trans_array_ctor_element (&body, desc, *poffset,
1578 *poffset = fold_build2_loc (input_location, PLUS_EXPR,
1579 gfc_array_index_type,
1580 *poffset, gfc_index_one_node);
1584 /* Collect multiple scalar constants into a constructor. */
1585 VEC(constructor_elt,gc) *v = NULL;
1589 HOST_WIDE_INT idx = 0;
1592 /* Count the number of consecutive scalar constants. */
1593 while (p && !(p->iterator
1594 || p->expr->expr_type != EXPR_CONSTANT))
1596 gfc_init_se (&se, NULL);
1597 gfc_conv_constant (&se, p->expr);
1599 if (c->expr->ts.type != BT_CHARACTER)
1600 se.expr = fold_convert (type, se.expr);
1601 /* For constant character array constructors we build
1602 an array of pointers. */
1603 else if (POINTER_TYPE_P (type))
1604 se.expr = gfc_build_addr_expr
1605 (gfc_get_pchar_type (p->expr->ts.kind),
1608 CONSTRUCTOR_APPEND_ELT (v,
1609 build_int_cst (gfc_array_index_type,
1613 p = gfc_constructor_next (p);
1616 bound = size_int (n - 1);
1617 /* Create an array type to hold them. */
1618 tmptype = build_range_type (gfc_array_index_type,
1619 gfc_index_zero_node, bound);
1620 tmptype = build_array_type (type, tmptype);
1622 init = build_constructor (tmptype, v);
1623 TREE_CONSTANT (init) = 1;
1624 TREE_STATIC (init) = 1;
1625 /* Create a static variable to hold the data. */
1626 tmp = gfc_create_var (tmptype, "data");
1627 TREE_STATIC (tmp) = 1;
1628 TREE_CONSTANT (tmp) = 1;
1629 TREE_READONLY (tmp) = 1;
1630 DECL_INITIAL (tmp) = init;
1633 /* Use BUILTIN_MEMCPY to assign the values. */
1634 tmp = gfc_conv_descriptor_data_get (desc);
1635 tmp = build_fold_indirect_ref_loc (input_location,
1637 tmp = gfc_build_array_ref (tmp, *poffset, NULL);
1638 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1639 init = gfc_build_addr_expr (NULL_TREE, init);
1641 size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
1642 bound = build_int_cst (size_type_node, n * size);
1643 tmp = build_call_expr_loc (input_location,
1644 builtin_decl_explicit (BUILT_IN_MEMCPY),
1645 3, tmp, init, bound);
1646 gfc_add_expr_to_block (&body, tmp);
1648 *poffset = fold_build2_loc (input_location, PLUS_EXPR,
1649 gfc_array_index_type, *poffset,
1650 build_int_cst (gfc_array_index_type, n));
1652 if (!INTEGER_CST_P (*poffset))
1654 gfc_add_modify (&body, *offsetvar, *poffset);
1655 *poffset = *offsetvar;
1659 /* The frontend should already have done any expansions
1663 /* Pass the code as is. */
1664 tmp = gfc_finish_block (&body);
1665 gfc_add_expr_to_block (pblock, tmp);
1669 /* Build the implied do-loop. */
1670 stmtblock_t implied_do_block;
1678 loopbody = gfc_finish_block (&body);
1680 /* Create a new block that holds the implied-do loop. A temporary
1681 loop-variable is used. */
1682 gfc_start_block(&implied_do_block);
1684 /* Initialize the loop. */
1685 gfc_init_se (&se, NULL);
1686 gfc_conv_expr_val (&se, c->iterator->start);
1687 gfc_add_block_to_block (&implied_do_block, &se.pre);
1688 gfc_add_modify (&implied_do_block, shadow_loopvar, se.expr);
1690 gfc_init_se (&se, NULL);
1691 gfc_conv_expr_val (&se, c->iterator->end);
1692 gfc_add_block_to_block (&implied_do_block, &se.pre);
1693 end = gfc_evaluate_now (se.expr, &implied_do_block);
1695 gfc_init_se (&se, NULL);
1696 gfc_conv_expr_val (&se, c->iterator->step);
1697 gfc_add_block_to_block (&implied_do_block, &se.pre);
1698 step = gfc_evaluate_now (se.expr, &implied_do_block);
1700 /* If this array expands dynamically, and the number of iterations
1701 is not constant, we won't have allocated space for the static
1702 part of C->EXPR's size. Do that now. */
1703 if (dynamic && gfc_iterator_has_dynamic_bounds (c->iterator))
1705 /* Get the number of iterations. */
1706 tmp = gfc_get_iteration_count (shadow_loopvar, end, step);
1708 /* Get the static part of C->EXPR's size. */
1709 gfc_get_array_constructor_element_size (&size, c->expr);
1710 tmp2 = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1712 /* Grow the array by TMP * TMP2 elements. */
1713 tmp = fold_build2_loc (input_location, MULT_EXPR,
1714 gfc_array_index_type, tmp, tmp2);
1715 gfc_grow_array (&implied_do_block, desc, tmp);
1718 /* Generate the loop body. */
1719 exit_label = gfc_build_label_decl (NULL_TREE);
1720 gfc_start_block (&body);
1722 /* Generate the exit condition. Depending on the sign of
1723 the step variable we have to generate the correct
1725 tmp = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1726 step, build_int_cst (TREE_TYPE (step), 0));
1727 cond = fold_build3_loc (input_location, COND_EXPR,
1728 boolean_type_node, tmp,
1729 fold_build2_loc (input_location, GT_EXPR,
1730 boolean_type_node, shadow_loopvar, end),
1731 fold_build2_loc (input_location, LT_EXPR,
1732 boolean_type_node, shadow_loopvar, end));
1733 tmp = build1_v (GOTO_EXPR, exit_label);
1734 TREE_USED (exit_label) = 1;
1735 tmp = build3_v (COND_EXPR, cond, tmp,
1736 build_empty_stmt (input_location));
1737 gfc_add_expr_to_block (&body, tmp);
1739 /* The main loop body. */
1740 gfc_add_expr_to_block (&body, loopbody);
1742 /* Increase loop variable by step. */
1743 tmp = fold_build2_loc (input_location, PLUS_EXPR,
1744 TREE_TYPE (shadow_loopvar), shadow_loopvar,
1746 gfc_add_modify (&body, shadow_loopvar, tmp);
1748 /* Finish the loop. */
1749 tmp = gfc_finish_block (&body);
1750 tmp = build1_v (LOOP_EXPR, tmp);
1751 gfc_add_expr_to_block (&implied_do_block, tmp);
1753 /* Add the exit label. */
1754 tmp = build1_v (LABEL_EXPR, exit_label);
1755 gfc_add_expr_to_block (&implied_do_block, tmp);
1757 /* Finishe the implied-do loop. */
1758 tmp = gfc_finish_block(&implied_do_block);
1759 gfc_add_expr_to_block(pblock, tmp);
1761 gfc_restore_sym (c->iterator->var->symtree->n.sym, &saved_loopvar);
1768 /* A catch-all to obtain the string length for anything that is not a
1769 a substring of non-constant length, a constant, array or variable. */
1772 get_array_ctor_all_strlen (stmtblock_t *block, gfc_expr *e, tree *len)
1777 /* Don't bother if we already know the length is a constant. */
1778 if (*len && INTEGER_CST_P (*len))
1781 if (!e->ref && e->ts.u.cl && e->ts.u.cl->length
1782 && e->ts.u.cl->length->expr_type == EXPR_CONSTANT)
1785 gfc_conv_const_charlen (e->ts.u.cl);
1786 *len = e->ts.u.cl->backend_decl;
1790 /* Otherwise, be brutal even if inefficient. */
1791 ss = gfc_walk_expr (e);
1792 gfc_init_se (&se, NULL);
1794 /* No function call, in case of side effects. */
1795 se.no_function_call = 1;
1796 if (ss == gfc_ss_terminator)
1797 gfc_conv_expr (&se, e);
1799 gfc_conv_expr_descriptor (&se, e, ss);
1801 /* Fix the value. */
1802 *len = gfc_evaluate_now (se.string_length, &se.pre);
1804 gfc_add_block_to_block (block, &se.pre);
1805 gfc_add_block_to_block (block, &se.post);
1807 e->ts.u.cl->backend_decl = *len;
1812 /* Figure out the string length of a variable reference expression.
1813 Used by get_array_ctor_strlen. */
1816 get_array_ctor_var_strlen (stmtblock_t *block, gfc_expr * expr, tree * len)
1822 /* Don't bother if we already know the length is a constant. */
1823 if (*len && INTEGER_CST_P (*len))
1826 ts = &expr->symtree->n.sym->ts;
1827 for (ref = expr->ref; ref; ref = ref->next)
1832 /* Array references don't change the string length. */
1836 /* Use the length of the component. */
1837 ts = &ref->u.c.component->ts;
1841 if (ref->u.ss.start->expr_type != EXPR_CONSTANT
1842 || ref->u.ss.end->expr_type != EXPR_CONSTANT)
1844 /* Note that this might evaluate expr. */
1845 get_array_ctor_all_strlen (block, expr, len);
1848 mpz_init_set_ui (char_len, 1);
1849 mpz_add (char_len, char_len, ref->u.ss.end->value.integer);
1850 mpz_sub (char_len, char_len, ref->u.ss.start->value.integer);
1851 *len = gfc_conv_mpz_to_tree (char_len, gfc_default_integer_kind);
1852 *len = convert (gfc_charlen_type_node, *len);
1853 mpz_clear (char_len);
1861 *len = ts->u.cl->backend_decl;
1865 /* Figure out the string length of a character array constructor.
1866 If len is NULL, don't calculate the length; this happens for recursive calls
1867 when a sub-array-constructor is an element but not at the first position,
1868 so when we're not interested in the length.
1869 Returns TRUE if all elements are character constants. */
1872 get_array_ctor_strlen (stmtblock_t *block, gfc_constructor_base base, tree * len)
1879 if (gfc_constructor_first (base) == NULL)
1882 *len = build_int_cstu (gfc_charlen_type_node, 0);
1886 /* Loop over all constructor elements to find out is_const, but in len we
1887 want to store the length of the first, not the last, element. We can
1888 of course exit the loop as soon as is_const is found to be false. */
1889 for (c = gfc_constructor_first (base);
1890 c && is_const; c = gfc_constructor_next (c))
1892 switch (c->expr->expr_type)
1895 if (len && !(*len && INTEGER_CST_P (*len)))
1896 *len = build_int_cstu (gfc_charlen_type_node,
1897 c->expr->value.character.length);
1901 if (!get_array_ctor_strlen (block, c->expr->value.constructor, len))
1908 get_array_ctor_var_strlen (block, c->expr, len);
1914 get_array_ctor_all_strlen (block, c->expr, len);
1918 /* After the first iteration, we don't want the length modified. */
1925 /* Check whether the array constructor C consists entirely of constant
1926 elements, and if so returns the number of those elements, otherwise
1927 return zero. Note, an empty or NULL array constructor returns zero. */
1929 unsigned HOST_WIDE_INT
1930 gfc_constant_array_constructor_p (gfc_constructor_base base)
1932 unsigned HOST_WIDE_INT nelem = 0;
1934 gfc_constructor *c = gfc_constructor_first (base);
1938 || c->expr->rank > 0
1939 || c->expr->expr_type != EXPR_CONSTANT)
1941 c = gfc_constructor_next (c);
1948 /* Given EXPR, the constant array constructor specified by an EXPR_ARRAY,
1949 and the tree type of it's elements, TYPE, return a static constant
1950 variable that is compile-time initialized. */
1953 gfc_build_constant_array_constructor (gfc_expr * expr, tree type)
1955 tree tmptype, init, tmp;
1956 HOST_WIDE_INT nelem;
1961 VEC(constructor_elt,gc) *v = NULL;
1963 /* First traverse the constructor list, converting the constants
1964 to tree to build an initializer. */
1966 c = gfc_constructor_first (expr->value.constructor);
1969 gfc_init_se (&se, NULL);
1970 gfc_conv_constant (&se, c->expr);
1971 if (c->expr->ts.type != BT_CHARACTER)
1972 se.expr = fold_convert (type, se.expr);
1973 else if (POINTER_TYPE_P (type))
1974 se.expr = gfc_build_addr_expr (gfc_get_pchar_type (c->expr->ts.kind),
1976 CONSTRUCTOR_APPEND_ELT (v, build_int_cst (gfc_array_index_type, nelem),
1978 c = gfc_constructor_next (c);
1982 /* Next determine the tree type for the array. We use the gfortran
1983 front-end's gfc_get_nodesc_array_type in order to create a suitable
1984 GFC_ARRAY_TYPE_P that may be used by the scalarizer. */
1986 memset (&as, 0, sizeof (gfc_array_spec));
1988 as.rank = expr->rank;
1989 as.type = AS_EXPLICIT;
1992 as.lower[0] = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
1993 as.upper[0] = gfc_get_int_expr (gfc_default_integer_kind,
1997 for (i = 0; i < expr->rank; i++)
1999 int tmp = (int) mpz_get_si (expr->shape[i]);
2000 as.lower[i] = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
2001 as.upper[i] = gfc_get_int_expr (gfc_default_integer_kind,
2005 tmptype = gfc_get_nodesc_array_type (type, &as, PACKED_STATIC, true);
2007 /* as is not needed anymore. */
2008 for (i = 0; i < as.rank + as.corank; i++)
2010 gfc_free_expr (as.lower[i]);
2011 gfc_free_expr (as.upper[i]);
2014 init = build_constructor (tmptype, v);
2016 TREE_CONSTANT (init) = 1;
2017 TREE_STATIC (init) = 1;
2019 tmp = gfc_create_var (tmptype, "A");
2020 TREE_STATIC (tmp) = 1;
2021 TREE_CONSTANT (tmp) = 1;
2022 TREE_READONLY (tmp) = 1;
2023 DECL_INITIAL (tmp) = init;
2029 /* Translate a constant EXPR_ARRAY array constructor for the scalarizer.
2030 This mostly initializes the scalarizer state info structure with the
2031 appropriate values to directly use the array created by the function
2032 gfc_build_constant_array_constructor. */
2035 trans_constant_array_constructor (gfc_ss * ss, tree type)
2037 gfc_array_info *info;
2041 tmp = gfc_build_constant_array_constructor (ss->info->expr, type);
2043 info = &ss->info->data.array;
2045 info->descriptor = tmp;
2046 info->data = gfc_build_addr_expr (NULL_TREE, tmp);
2047 info->offset = gfc_index_zero_node;
2049 for (i = 0; i < ss->dimen; i++)
2051 info->delta[i] = gfc_index_zero_node;
2052 info->start[i] = gfc_index_zero_node;
2053 info->end[i] = gfc_index_zero_node;
2054 info->stride[i] = gfc_index_one_node;
2060 get_rank (gfc_loopinfo *loop)
2065 for (; loop; loop = loop->parent)
2066 rank += loop->dimen;
2072 /* Helper routine of gfc_trans_array_constructor to determine if the
2073 bounds of the loop specified by LOOP are constant and simple enough
2074 to use with trans_constant_array_constructor. Returns the
2075 iteration count of the loop if suitable, and NULL_TREE otherwise. */
2078 constant_array_constructor_loop_size (gfc_loopinfo * l)
2081 tree size = gfc_index_one_node;
2085 total_dim = get_rank (l);
2087 for (loop = l; loop; loop = loop->parent)
2089 for (i = 0; i < loop->dimen; i++)
2091 /* If the bounds aren't constant, return NULL_TREE. */
2092 if (!INTEGER_CST_P (loop->from[i]) || !INTEGER_CST_P (loop->to[i]))
2094 if (!integer_zerop (loop->from[i]))
2096 /* Only allow nonzero "from" in one-dimensional arrays. */
2099 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2100 gfc_array_index_type,
2101 loop->to[i], loop->from[i]);
2105 tmp = fold_build2_loc (input_location, PLUS_EXPR,
2106 gfc_array_index_type, tmp, gfc_index_one_node);
2107 size = fold_build2_loc (input_location, MULT_EXPR,
2108 gfc_array_index_type, size, tmp);
2117 get_loop_upper_bound_for_array (gfc_ss *array, int array_dim)
2122 gcc_assert (array->nested_ss == NULL);
2124 for (ss = array; ss; ss = ss->parent)
2125 for (n = 0; n < ss->loop->dimen; n++)
2126 if (array_dim == get_array_ref_dim_for_loop_dim (ss, n))
2127 return &(ss->loop->to[n]);
2133 static gfc_loopinfo *
2134 outermost_loop (gfc_loopinfo * loop)
2136 while (loop->parent != NULL)
2137 loop = loop->parent;
2143 /* Array constructors are handled by constructing a temporary, then using that
2144 within the scalarization loop. This is not optimal, but seems by far the
2148 trans_array_constructor (gfc_ss * ss, locus * where)
2150 gfc_constructor_base c;
2158 bool old_first_len, old_typespec_chararray_ctor;
2159 tree old_first_len_val;
2160 gfc_loopinfo *loop, *outer_loop;
2161 gfc_ss_info *ss_info;
2165 /* Save the old values for nested checking. */
2166 old_first_len = first_len;
2167 old_first_len_val = first_len_val;
2168 old_typespec_chararray_ctor = typespec_chararray_ctor;
2171 outer_loop = outermost_loop (loop);
2173 expr = ss_info->expr;
2175 /* Do bounds-checking here and in gfc_trans_array_ctor_element only if no
2176 typespec was given for the array constructor. */
2177 typespec_chararray_ctor = (expr->ts.u.cl
2178 && expr->ts.u.cl->length_from_typespec);
2180 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2181 && expr->ts.type == BT_CHARACTER && !typespec_chararray_ctor)
2183 first_len_val = gfc_create_var (gfc_charlen_type_node, "len");
2187 gcc_assert (ss->dimen == ss->loop->dimen);
2189 c = expr->value.constructor;
2190 if (expr->ts.type == BT_CHARACTER)
2194 /* get_array_ctor_strlen walks the elements of the constructor, if a
2195 typespec was given, we already know the string length and want the one
2197 if (typespec_chararray_ctor && expr->ts.u.cl->length
2198 && expr->ts.u.cl->length->expr_type != EXPR_CONSTANT)
2202 const_string = false;
2203 gfc_init_se (&length_se, NULL);
2204 gfc_conv_expr_type (&length_se, expr->ts.u.cl->length,
2205 gfc_charlen_type_node);
2206 ss_info->string_length = length_se.expr;
2207 gfc_add_block_to_block (&outer_loop->pre, &length_se.pre);
2208 gfc_add_block_to_block (&outer_loop->post, &length_se.post);
2211 const_string = get_array_ctor_strlen (&outer_loop->pre, c,
2212 &ss_info->string_length);
2214 /* Complex character array constructors should have been taken care of
2215 and not end up here. */
2216 gcc_assert (ss_info->string_length);
2218 expr->ts.u.cl->backend_decl = ss_info->string_length;
2220 type = gfc_get_character_type_len (expr->ts.kind, ss_info->string_length);
2222 type = build_pointer_type (type);
2225 type = gfc_typenode_for_spec (&expr->ts);
2227 /* See if the constructor determines the loop bounds. */
2230 loop_ubound0 = get_loop_upper_bound_for_array (ss, 0);
2232 if (expr->shape && get_rank (loop) > 1 && *loop_ubound0 == NULL_TREE)
2234 /* We have a multidimensional parameter. */
2235 for (s = ss; s; s = s->parent)
2238 for (n = 0; n < s->loop->dimen; n++)
2240 s->loop->from[n] = gfc_index_zero_node;
2241 s->loop->to[n] = gfc_conv_mpz_to_tree (expr->shape[s->dim[n]],
2242 gfc_index_integer_kind);
2243 s->loop->to[n] = fold_build2_loc (input_location, MINUS_EXPR,
2244 gfc_array_index_type,
2246 gfc_index_one_node);
2251 if (*loop_ubound0 == NULL_TREE)
2255 /* We should have a 1-dimensional, zero-based loop. */
2256 gcc_assert (loop->parent == NULL && loop->nested == NULL);
2257 gcc_assert (loop->dimen == 1);
2258 gcc_assert (integer_zerop (loop->from[0]));
2260 /* Split the constructor size into a static part and a dynamic part.
2261 Allocate the static size up-front and record whether the dynamic
2262 size might be nonzero. */
2264 dynamic = gfc_get_array_constructor_size (&size, c);
2265 mpz_sub_ui (size, size, 1);
2266 loop->to[0] = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
2270 /* Special case constant array constructors. */
2273 unsigned HOST_WIDE_INT nelem = gfc_constant_array_constructor_p (c);
2276 tree size = constant_array_constructor_loop_size (loop);
2277 if (size && compare_tree_int (size, nelem) == 0)
2279 trans_constant_array_constructor (ss, type);
2285 if (TREE_CODE (*loop_ubound0) == VAR_DECL)
2288 gfc_trans_create_temp_array (&outer_loop->pre, &outer_loop->post, ss, type,
2289 NULL_TREE, dynamic, true, false, where);
2291 desc = ss_info->data.array.descriptor;
2292 offset = gfc_index_zero_node;
2293 offsetvar = gfc_create_var_np (gfc_array_index_type, "offset");
2294 TREE_NO_WARNING (offsetvar) = 1;
2295 TREE_USED (offsetvar) = 0;
2296 gfc_trans_array_constructor_value (&outer_loop->pre, type, desc, c,
2297 &offset, &offsetvar, dynamic);
2299 /* If the array grows dynamically, the upper bound of the loop variable
2300 is determined by the array's final upper bound. */
2303 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2304 gfc_array_index_type,
2305 offsetvar, gfc_index_one_node);
2306 tmp = gfc_evaluate_now (tmp, &outer_loop->pre);
2307 gfc_conv_descriptor_ubound_set (&loop->pre, desc, gfc_rank_cst[0], tmp);
2308 if (*loop_ubound0 && TREE_CODE (*loop_ubound0) == VAR_DECL)
2309 gfc_add_modify (&outer_loop->pre, *loop_ubound0, tmp);
2311 *loop_ubound0 = tmp;
2314 if (TREE_USED (offsetvar))
2315 pushdecl (offsetvar);
2317 gcc_assert (INTEGER_CST_P (offset));
2320 /* Disable bound checking for now because it's probably broken. */
2321 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2328 /* Restore old values of globals. */
2329 first_len = old_first_len;
2330 first_len_val = old_first_len_val;
2331 typespec_chararray_ctor = old_typespec_chararray_ctor;
2335 /* INFO describes a GFC_SS_SECTION in loop LOOP, and this function is
2336 called after evaluating all of INFO's vector dimensions. Go through
2337 each such vector dimension and see if we can now fill in any missing
2341 set_vector_loop_bounds (gfc_ss * ss)
2343 gfc_loopinfo *loop, *outer_loop;
2344 gfc_array_info *info;
2352 outer_loop = outermost_loop (ss->loop);
2354 info = &ss->info->data.array;
2356 for (; ss; ss = ss->parent)
2360 for (n = 0; n < loop->dimen; n++)
2363 if (info->ref->u.ar.dimen_type[dim] != DIMEN_VECTOR
2364 || loop->to[n] != NULL)
2367 /* Loop variable N indexes vector dimension DIM, and we don't
2368 yet know the upper bound of loop variable N. Set it to the
2369 difference between the vector's upper and lower bounds. */
2370 gcc_assert (loop->from[n] == gfc_index_zero_node);
2371 gcc_assert (info->subscript[dim]
2372 && info->subscript[dim]->info->type == GFC_SS_VECTOR);
2374 gfc_init_se (&se, NULL);
2375 desc = info->subscript[dim]->info->data.array.descriptor;
2376 zero = gfc_rank_cst[0];
2377 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2378 gfc_array_index_type,
2379 gfc_conv_descriptor_ubound_get (desc, zero),
2380 gfc_conv_descriptor_lbound_get (desc, zero));
2381 tmp = gfc_evaluate_now (tmp, &outer_loop->pre);
2388 /* Add the pre and post chains for all the scalar expressions in a SS chain
2389 to loop. This is called after the loop parameters have been calculated,
2390 but before the actual scalarizing loops. */
2393 gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript,
2396 gfc_loopinfo *nested_loop, *outer_loop;
2398 gfc_ss_info *ss_info;
2399 gfc_array_info *info;
2401 bool skip_nested = false;
2404 outer_loop = outermost_loop (loop);
2406 /* TODO: This can generate bad code if there are ordering dependencies,
2407 e.g., a callee allocated function and an unknown size constructor. */
2408 gcc_assert (ss != NULL);
2410 for (; ss != gfc_ss_terminator; ss = ss->loop_chain)
2414 /* Cross loop arrays are handled from within the most nested loop. */
2415 if (ss->nested_ss != NULL)
2419 expr = ss_info->expr;
2420 info = &ss_info->data.array;
2422 switch (ss_info->type)
2425 /* Scalar expression. Evaluate this now. This includes elemental
2426 dimension indices, but not array section bounds. */
2427 gfc_init_se (&se, NULL);
2428 gfc_conv_expr (&se, expr);
2429 gfc_add_block_to_block (&outer_loop->pre, &se.pre);
2431 if (expr->ts.type != BT_CHARACTER)
2433 /* Move the evaluation of scalar expressions outside the
2434 scalarization loop, except for WHERE assignments. */
2436 se.expr = convert(gfc_array_index_type, se.expr);
2437 if (!ss_info->where)
2438 se.expr = gfc_evaluate_now (se.expr, &outer_loop->pre);
2439 gfc_add_block_to_block (&outer_loop->pre, &se.post);
2442 gfc_add_block_to_block (&outer_loop->post, &se.post);
2444 ss_info->data.scalar.value = se.expr;
2445 ss_info->string_length = se.string_length;
2448 case GFC_SS_REFERENCE:
2449 /* Scalar argument to elemental procedure. */
2450 gfc_init_se (&se, NULL);
2451 if (ss_info->data.scalar.can_be_null_ref)
2453 /* If the actual argument can be absent (in other words, it can
2454 be a NULL reference), don't try to evaluate it; pass instead
2455 the reference directly. */
2456 gfc_conv_expr_reference (&se, expr);
2460 /* Otherwise, evaluate the argument outside the loop and pass
2461 a reference to the value. */
2462 gfc_conv_expr (&se, expr);
2464 gfc_add_block_to_block (&outer_loop->pre, &se.pre);
2465 gfc_add_block_to_block (&outer_loop->post, &se.post);
2466 if (gfc_is_class_scalar_expr (expr))
2467 /* This is necessary because the dynamic type will always be
2468 large than the declared type. In consequence, assigning
2469 the value to a temporary could segfault.
2470 OOP-TODO: see if this is generally correct or is the value
2471 has to be written to an allocated temporary, whose address
2472 is passed via ss_info. */
2473 ss_info->data.scalar.value = se.expr;
2475 ss_info->data.scalar.value = gfc_evaluate_now (se.expr,
2478 ss_info->string_length = se.string_length;
2481 case GFC_SS_SECTION:
2482 /* Add the expressions for scalar and vector subscripts. */
2483 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
2484 if (info->subscript[n])
2486 gfc_add_loop_ss_code (loop, info->subscript[n], true, where);
2487 /* The recursive call will have taken care of the nested loops.
2488 No need to do it twice. */
2492 set_vector_loop_bounds (ss);
2496 /* Get the vector's descriptor and store it in SS. */
2497 gfc_init_se (&se, NULL);
2498 gfc_conv_expr_descriptor (&se, expr, gfc_walk_expr (expr));
2499 gfc_add_block_to_block (&outer_loop->pre, &se.pre);
2500 gfc_add_block_to_block (&outer_loop->post, &se.post);
2501 info->descriptor = se.expr;
2504 case GFC_SS_INTRINSIC:
2505 gfc_add_intrinsic_ss_code (loop, ss);
2508 case GFC_SS_FUNCTION:
2509 /* Array function return value. We call the function and save its
2510 result in a temporary for use inside the loop. */
2511 gfc_init_se (&se, NULL);
2514 gfc_conv_expr (&se, expr);
2515 gfc_add_block_to_block (&outer_loop->pre, &se.pre);
2516 gfc_add_block_to_block (&outer_loop->post, &se.post);
2517 ss_info->string_length = se.string_length;
2520 case GFC_SS_CONSTRUCTOR:
2521 if (expr->ts.type == BT_CHARACTER
2522 && ss_info->string_length == NULL
2524 && expr->ts.u.cl->length)
2526 gfc_init_se (&se, NULL);
2527 gfc_conv_expr_type (&se, expr->ts.u.cl->length,
2528 gfc_charlen_type_node);
2529 ss_info->string_length = se.expr;
2530 gfc_add_block_to_block (&outer_loop->pre, &se.pre);
2531 gfc_add_block_to_block (&outer_loop->post, &se.post);
2533 trans_array_constructor (ss, where);
2537 case GFC_SS_COMPONENT:
2538 /* Do nothing. These are handled elsewhere. */
2547 for (nested_loop = loop->nested; nested_loop;
2548 nested_loop = nested_loop->next)
2549 gfc_add_loop_ss_code (nested_loop, nested_loop->ss, subscript, where);
2553 /* Translate expressions for the descriptor and data pointer of a SS. */
2557 gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)
2560 gfc_ss_info *ss_info;
2561 gfc_array_info *info;
2565 info = &ss_info->data.array;
2567 /* Get the descriptor for the array to be scalarized. */
2568 gcc_assert (ss_info->expr->expr_type == EXPR_VARIABLE);
2569 gfc_init_se (&se, NULL);
2570 se.descriptor_only = 1;
2571 gfc_conv_expr_lhs (&se, ss_info->expr);
2572 gfc_add_block_to_block (block, &se.pre);
2573 info->descriptor = se.expr;
2574 ss_info->string_length = se.string_length;
2578 /* Also the data pointer. */
2579 tmp = gfc_conv_array_data (se.expr);
2580 /* If this is a variable or address of a variable we use it directly.
2581 Otherwise we must evaluate it now to avoid breaking dependency
2582 analysis by pulling the expressions for elemental array indices
2585 || (TREE_CODE (tmp) == ADDR_EXPR
2586 && DECL_P (TREE_OPERAND (tmp, 0)))))
2587 tmp = gfc_evaluate_now (tmp, block);
2590 tmp = gfc_conv_array_offset (se.expr);
2591 info->offset = gfc_evaluate_now (tmp, block);
2593 /* Make absolutely sure that the saved_offset is indeed saved
2594 so that the variable is still accessible after the loops
2596 info->saved_offset = info->offset;
2601 /* Initialize a gfc_loopinfo structure. */
2604 gfc_init_loopinfo (gfc_loopinfo * loop)
2608 memset (loop, 0, sizeof (gfc_loopinfo));
2609 gfc_init_block (&loop->pre);
2610 gfc_init_block (&loop->post);
2612 /* Initially scalarize in order and default to no loop reversal. */
2613 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
2616 loop->reverse[n] = GFC_INHIBIT_REVERSE;
2619 loop->ss = gfc_ss_terminator;
2623 /* Copies the loop variable info to a gfc_se structure. Does not copy the SS
2627 gfc_copy_loopinfo_to_se (gfc_se * se, gfc_loopinfo * loop)
2633 /* Return an expression for the data pointer of an array. */
2636 gfc_conv_array_data (tree descriptor)
2640 type = TREE_TYPE (descriptor);
2641 if (GFC_ARRAY_TYPE_P (type))
2643 if (TREE_CODE (type) == POINTER_TYPE)
2647 /* Descriptorless arrays. */
2648 return gfc_build_addr_expr (NULL_TREE, descriptor);
2652 return gfc_conv_descriptor_data_get (descriptor);
2656 /* Return an expression for the base offset of an array. */
2659 gfc_conv_array_offset (tree descriptor)
2663 type = TREE_TYPE (descriptor);
2664 if (GFC_ARRAY_TYPE_P (type))
2665 return GFC_TYPE_ARRAY_OFFSET (type);
2667 return gfc_conv_descriptor_offset_get (descriptor);
2671 /* Get an expression for the array stride. */
2674 gfc_conv_array_stride (tree descriptor, int dim)
2679 type = TREE_TYPE (descriptor);
2681 /* For descriptorless arrays use the array size. */
2682 tmp = GFC_TYPE_ARRAY_STRIDE (type, dim);
2683 if (tmp != NULL_TREE)
2686 tmp = gfc_conv_descriptor_stride_get (descriptor, gfc_rank_cst[dim]);
2691 /* Like gfc_conv_array_stride, but for the lower bound. */
2694 gfc_conv_array_lbound (tree descriptor, int dim)
2699 type = TREE_TYPE (descriptor);
2701 tmp = GFC_TYPE_ARRAY_LBOUND (type, dim);
2702 if (tmp != NULL_TREE)
2705 tmp = gfc_conv_descriptor_lbound_get (descriptor, gfc_rank_cst[dim]);
2710 /* Like gfc_conv_array_stride, but for the upper bound. */
2713 gfc_conv_array_ubound (tree descriptor, int dim)
2718 type = TREE_TYPE (descriptor);
2720 tmp = GFC_TYPE_ARRAY_UBOUND (type, dim);
2721 if (tmp != NULL_TREE)
2724 /* This should only ever happen when passing an assumed shape array
2725 as an actual parameter. The value will never be used. */
2726 if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor)))
2727 return gfc_index_zero_node;
2729 tmp = gfc_conv_descriptor_ubound_get (descriptor, gfc_rank_cst[dim]);
2734 /* Generate code to perform an array index bound check. */
2737 trans_array_bound_check (gfc_se * se, gfc_ss *ss, tree index, int n,
2738 locus * where, bool check_upper)
2741 tree tmp_lo, tmp_up;
2744 const char * name = NULL;
2746 if (!(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
2749 descriptor = ss->info->data.array.descriptor;
2751 index = gfc_evaluate_now (index, &se->pre);
2753 /* We find a name for the error message. */
2754 name = ss->info->expr->symtree->n.sym->name;
2755 gcc_assert (name != NULL);
2757 if (TREE_CODE (descriptor) == VAR_DECL)
2758 name = IDENTIFIER_POINTER (DECL_NAME (descriptor));
2760 /* If upper bound is present, include both bounds in the error message. */
2763 tmp_lo = gfc_conv_array_lbound (descriptor, n);
2764 tmp_up = gfc_conv_array_ubound (descriptor, n);
2767 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
2768 "outside of expected range (%%ld:%%ld)", n+1, name);
2770 asprintf (&msg, "Index '%%ld' of dimension %d "
2771 "outside of expected range (%%ld:%%ld)", n+1);
2773 fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
2775 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2776 fold_convert (long_integer_type_node, index),
2777 fold_convert (long_integer_type_node, tmp_lo),
2778 fold_convert (long_integer_type_node, tmp_up));
2779 fault = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
2781 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2782 fold_convert (long_integer_type_node, index),
2783 fold_convert (long_integer_type_node, tmp_lo),
2784 fold_convert (long_integer_type_node, tmp_up));
2789 tmp_lo = gfc_conv_array_lbound (descriptor, n);
2792 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
2793 "below lower bound of %%ld", n+1, name);
2795 asprintf (&msg, "Index '%%ld' of dimension %d "
2796 "below lower bound of %%ld", n+1);
2798 fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
2800 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2801 fold_convert (long_integer_type_node, index),
2802 fold_convert (long_integer_type_node, tmp_lo));
2810 /* Return the offset for an index. Performs bound checking for elemental
2811 dimensions. Single element references are processed separately.
2812 DIM is the array dimension, I is the loop dimension. */
2815 conv_array_index_offset (gfc_se * se, gfc_ss * ss, int dim, int i,
2816 gfc_array_ref * ar, tree stride)
2818 gfc_array_info *info;
2823 info = &ss->info->data.array;
2825 /* Get the index into the array for this dimension. */
2828 gcc_assert (ar->type != AR_ELEMENT);
2829 switch (ar->dimen_type[dim])
2831 case DIMEN_THIS_IMAGE:
2835 /* Elemental dimension. */
2836 gcc_assert (info->subscript[dim]
2837 && info->subscript[dim]->info->type == GFC_SS_SCALAR);
2838 /* We've already translated this value outside the loop. */
2839 index = info->subscript[dim]->info->data.scalar.value;
2841 index = trans_array_bound_check (se, ss, index, dim, &ar->where,
2842 ar->as->type != AS_ASSUMED_SIZE
2843 || dim < ar->dimen - 1);
2847 gcc_assert (info && se->loop);
2848 gcc_assert (info->subscript[dim]
2849 && info->subscript[dim]->info->type == GFC_SS_VECTOR);
2850 desc = info->subscript[dim]->info->data.array.descriptor;
2852 /* Get a zero-based index into the vector. */
2853 index = fold_build2_loc (input_location, MINUS_EXPR,
2854 gfc_array_index_type,
2855 se->loop->loopvar[i], se->loop->from[i]);
2857 /* Multiply the index by the stride. */
2858 index = fold_build2_loc (input_location, MULT_EXPR,
2859 gfc_array_index_type,
2860 index, gfc_conv_array_stride (desc, 0));
2862 /* Read the vector to get an index into info->descriptor. */
2863 data = build_fold_indirect_ref_loc (input_location,
2864 gfc_conv_array_data (desc));
2865 index = gfc_build_array_ref (data, index, NULL);
2866 index = gfc_evaluate_now (index, &se->pre);
2867 index = fold_convert (gfc_array_index_type, index);
2869 /* Do any bounds checking on the final info->descriptor index. */
2870 index = trans_array_bound_check (se, ss, index, dim, &ar->where,
2871 ar->as->type != AS_ASSUMED_SIZE
2872 || dim < ar->dimen - 1);
2876 /* Scalarized dimension. */
2877 gcc_assert (info && se->loop);
2879 /* Multiply the loop variable by the stride and delta. */
2880 index = se->loop->loopvar[i];
2881 if (!integer_onep (info->stride[dim]))
2882 index = fold_build2_loc (input_location, MULT_EXPR,
2883 gfc_array_index_type, index,
2885 if (!integer_zerop (info->delta[dim]))
2886 index = fold_build2_loc (input_location, PLUS_EXPR,
2887 gfc_array_index_type, index,
2897 /* Temporary array or derived type component. */
2898 gcc_assert (se->loop);
2899 index = se->loop->loopvar[se->loop->order[i]];
2901 /* Pointer functions can have stride[0] different from unity.
2902 Use the stride returned by the function call and stored in
2903 the descriptor for the temporary. */
2904 if (se->ss && se->ss->info->type == GFC_SS_FUNCTION
2905 && se->ss->info->expr
2906 && se->ss->info->expr->symtree
2907 && se->ss->info->expr->symtree->n.sym->result
2908 && se->ss->info->expr->symtree->n.sym->result->attr.pointer)
2909 stride = gfc_conv_descriptor_stride_get (info->descriptor,
2912 if (!integer_zerop (info->delta[dim]))
2913 index = fold_build2_loc (input_location, PLUS_EXPR,
2914 gfc_array_index_type, index, info->delta[dim]);
2917 /* Multiply by the stride. */
2918 if (!integer_onep (stride))
2919 index = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
2926 /* Build a scalarized array reference using the vptr 'size'. */
2929 build_class_array_ref (gfc_se *se, tree base, tree index)
2936 gfc_expr *expr = se->ss->info->expr;
2941 if (expr == NULL || expr->ts.type != BT_CLASS)
2944 if (expr->symtree && expr->symtree->n.sym->ts.type == BT_CLASS)
2945 ts = &expr->symtree->n.sym->ts;
2950 for (ref = expr->ref; ref; ref = ref->next)
2952 if (ref->type == REF_COMPONENT
2953 && ref->u.c.component->ts.type == BT_CLASS
2954 && ref->next && ref->next->type == REF_COMPONENT
2955 && strcmp (ref->next->u.c.component->name, "_data") == 0
2957 && ref->next->next->type == REF_ARRAY
2958 && ref->next->next->u.ar.type != AR_ELEMENT)
2960 ts = &ref->u.c.component->ts;
2969 if (class_ref == NULL)
2970 decl = expr->symtree->n.sym->backend_decl;
2973 /* Remove everything after the last class reference, convert the
2974 expression and then recover its tailend once more. */
2976 ref = class_ref->next;
2977 class_ref->next = NULL;
2978 gfc_init_se (&tmpse, NULL);
2979 gfc_conv_expr (&tmpse, expr);
2981 class_ref->next = ref;
2984 size = gfc_vtable_size_get (decl);
2986 /* Build the address of the element. */
2987 type = TREE_TYPE (TREE_TYPE (base));
2988 size = fold_convert (TREE_TYPE (index), size);
2989 offset = fold_build2_loc (input_location, MULT_EXPR,
2990 gfc_array_index_type,
2992 tmp = gfc_build_addr_expr (pvoid_type_node, base);
2993 tmp = fold_build_pointer_plus_loc (input_location, tmp, offset);
2994 tmp = fold_convert (build_pointer_type (type), tmp);
2996 /* Return the element in the se expression. */
2997 se->expr = build_fold_indirect_ref_loc (input_location, tmp);
3002 /* Build a scalarized reference to an array. */
3005 gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
3007 gfc_array_info *info;
3008 tree decl = NULL_TREE;
3016 expr = ss->info->expr;
3017 info = &ss->info->data.array;
3019 n = se->loop->order[0];
3023 index = conv_array_index_offset (se, ss, ss->dim[n], n, ar, info->stride0);
3024 /* Add the offset for this dimension to the stored offset for all other
3026 if (!integer_zerop (info->offset))
3027 index = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3028 index, info->offset);
3030 if (expr && is_subref_array (expr))
3031 decl = expr->symtree->n.sym->backend_decl;
3033 tmp = build_fold_indirect_ref_loc (input_location, info->data);
3035 /* Use the vptr 'size' field to access a class the element of a class
3037 if (build_class_array_ref (se, tmp, index))
3040 se->expr = gfc_build_array_ref (tmp, index, decl);
3044 /* Translate access of temporary array. */
3047 gfc_conv_tmp_array_ref (gfc_se * se)
3049 se->string_length = se->ss->info->string_length;
3050 gfc_conv_scalarized_array_ref (se, NULL);
3051 gfc_advance_se_ss_chain (se);
3054 /* Add T to the offset pair *OFFSET, *CST_OFFSET. */
3057 add_to_offset (tree *cst_offset, tree *offset, tree t)
3059 if (TREE_CODE (t) == INTEGER_CST)
3060 *cst_offset = int_const_binop (PLUS_EXPR, *cst_offset, t);
3063 if (!integer_zerop (*offset))
3064 *offset = fold_build2_loc (input_location, PLUS_EXPR,
3065 gfc_array_index_type, *offset, t);
3071 /* Build an array reference. se->expr already holds the array descriptor.
3072 This should be either a variable, indirect variable reference or component
3073 reference. For arrays which do not have a descriptor, se->expr will be
3075 a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
3078 gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym,
3082 tree offset, cst_offset;
3090 gcc_assert (ar->codimen);
3092 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se->expr)))
3093 se->expr = build_fold_indirect_ref (gfc_conv_array_data (se->expr));
3096 if (GFC_ARRAY_TYPE_P (TREE_TYPE (se->expr))
3097 && TREE_CODE (TREE_TYPE (se->expr)) == POINTER_TYPE)
3098 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
3100 /* Use the actual tree type and not the wrapped coarray. */
3101 if (!se->want_pointer)
3102 se->expr = fold_convert (TYPE_MAIN_VARIANT (TREE_TYPE (se->expr)),
3109 /* Handle scalarized references separately. */
3110 if (ar->type != AR_ELEMENT)
3112 gfc_conv_scalarized_array_ref (se, ar);
3113 gfc_advance_se_ss_chain (se);
3117 cst_offset = offset = gfc_index_zero_node;
3118 add_to_offset (&cst_offset, &offset, gfc_conv_array_offset (se->expr));
3120 /* Calculate the offsets from all the dimensions. Make sure to associate
3121 the final offset so that we form a chain of loop invariant summands. */
3122 for (n = ar->dimen - 1; n >= 0; n--)
3124 /* Calculate the index for this dimension. */
3125 gfc_init_se (&indexse, se);
3126 gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type);
3127 gfc_add_block_to_block (&se->pre, &indexse.pre);
3129 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
3131 /* Check array bounds. */
3135 /* Evaluate the indexse.expr only once. */
3136 indexse.expr = save_expr (indexse.expr);
3139 tmp = gfc_conv_array_lbound (se->expr, n);
3140 if (sym->attr.temporary)
3142 gfc_init_se (&tmpse, se);
3143 gfc_conv_expr_type (&tmpse, ar->as->lower[n],
3144 gfc_array_index_type);
3145 gfc_add_block_to_block (&se->pre, &tmpse.pre);
3149 cond = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
3151 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3152 "below lower bound of %%ld", n+1, sym->name);
3153 gfc_trans_runtime_check (true, false, cond, &se->pre, where, msg,
3154 fold_convert (long_integer_type_node,
3156 fold_convert (long_integer_type_node, tmp));
3159 /* Upper bound, but not for the last dimension of assumed-size
3161 if (n < ar->dimen - 1 || ar->as->type != AS_ASSUMED_SIZE)
3163 tmp = gfc_conv_array_ubound (se->expr, n);
3164 if (sym->attr.temporary)
3166 gfc_init_se (&tmpse, se);
3167 gfc_conv_expr_type (&tmpse, ar->as->upper[n],
3168 gfc_array_index_type);
3169 gfc_add_block_to_block (&se->pre, &tmpse.pre);
3173 cond = fold_build2_loc (input_location, GT_EXPR,
3174 boolean_type_node, indexse.expr, tmp);
3175 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3176 "above upper bound of %%ld", n+1, sym->name);
3177 gfc_trans_runtime_check (true, false, cond, &se->pre, where, msg,
3178 fold_convert (long_integer_type_node,
3180 fold_convert (long_integer_type_node, tmp));
3185 /* Multiply the index by the stride. */
3186 stride = gfc_conv_array_stride (se->expr, n);
3187 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
3188 indexse.expr, stride);
3190 /* And add it to the total. */
3191 add_to_offset (&cst_offset, &offset, tmp);
3194 if (!integer_zerop (cst_offset))
3195 offset = fold_build2_loc (input_location, PLUS_EXPR,
3196 gfc_array_index_type, offset, cst_offset);
3198 /* Access the calculated element. */
3199 tmp = gfc_conv_array_data (se->expr);
3200 tmp = build_fold_indirect_ref (tmp);
3201 se->expr = gfc_build_array_ref (tmp, offset, sym->backend_decl);
3205 /* Add the offset corresponding to array's ARRAY_DIM dimension and loop's
3206 LOOP_DIM dimension (if any) to array's offset. */
3209 add_array_offset (stmtblock_t *pblock, gfc_loopinfo *loop, gfc_ss *ss,
3210 gfc_array_ref *ar, int array_dim, int loop_dim)
3213 gfc_array_info *info;
3216 info = &ss->info->data.array;
3218 gfc_init_se (&se, NULL);
3220 se.expr = info->descriptor;
3221 stride = gfc_conv_array_stride (info->descriptor, array_dim);
3222 index = conv_array_index_offset (&se, ss, array_dim, loop_dim, ar, stride);
3223 gfc_add_block_to_block (pblock, &se.pre);
3225 info->offset = fold_build2_loc (input_location, PLUS_EXPR,
3226 gfc_array_index_type,
3227 info->offset, index);
3228 info->offset = gfc_evaluate_now (info->offset, pblock);
3232 /* Generate the code to be executed immediately before entering a
3233 scalarization loop. */
3236 gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
3237 stmtblock_t * pblock)
3240 gfc_ss_info *ss_info;
3241 gfc_array_info *info;
3242 gfc_ss_type ss_type;
3244 gfc_loopinfo *ploop;
3248 /* This code will be executed before entering the scalarization loop
3249 for this dimension. */
3250 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3254 if ((ss_info->useflags & flag) == 0)
3257 ss_type = ss_info->type;
3258 if (ss_type != GFC_SS_SECTION
3259 && ss_type != GFC_SS_FUNCTION
3260 && ss_type != GFC_SS_CONSTRUCTOR
3261 && ss_type != GFC_SS_COMPONENT)
3264 info = &ss_info->data.array;
3266 gcc_assert (dim < ss->dimen);
3267 gcc_assert (ss->dimen == loop->dimen);
3270 ar = &info->ref->u.ar;
3274 if (dim == loop->dimen - 1 && loop->parent != NULL)
3276 /* If we are in the outermost dimension of this loop, the previous
3277 dimension shall be in the parent loop. */
3278 gcc_assert (ss->parent != NULL);
3281 ploop = loop->parent;
3283 /* ss and ss->parent are about the same array. */
3284 gcc_assert (ss_info == pss->info);
3292 if (dim == loop->dimen - 1)
3297 /* For the time being, there is no loop reordering. */
3298 gcc_assert (i == ploop->order[i]);
3299 i = ploop->order[i];
3301 if (dim == loop->dimen - 1 && loop->parent == NULL)
3303 stride = gfc_conv_array_stride (info->descriptor,
3304 innermost_ss (ss)->dim[i]);
3306 /* Calculate the stride of the innermost loop. Hopefully this will
3307 allow the backend optimizers to do their stuff more effectively.
3309 info->stride0 = gfc_evaluate_now (stride, pblock);
3311 /* For the outermost loop calculate the offset due to any
3312 elemental dimensions. It will have been initialized with the
3313 base offset of the array. */
3316 for (i = 0; i < ar->dimen; i++)
3318 if (ar->dimen_type[i] != DIMEN_ELEMENT)
3321 add_array_offset (pblock, loop, ss, ar, i, /* unused */ -1);
3326 /* Add the offset for the previous loop dimension. */
3327 add_array_offset (pblock, ploop, ss, ar, pss->dim[i], i);
3329 /* Remember this offset for the second loop. */
3330 if (dim == loop->temp_dim - 1 && loop->parent == NULL)
3331 info->saved_offset = info->offset;
3336 /* Start a scalarized expression. Creates a scope and declares loop
3340 gfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody)
3346 gcc_assert (!loop->array_parameter);
3348 for (dim = loop->dimen - 1; dim >= 0; dim--)
3350 n = loop->order[dim];
3352 gfc_start_block (&loop->code[n]);
3354 /* Create the loop variable. */
3355 loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "S");
3357 if (dim < loop->temp_dim)
3361 /* Calculate values that will be constant within this loop. */
3362 gfc_trans_preloop_setup (loop, dim, flags, &loop->code[n]);
3364 gfc_start_block (pbody);
3368 /* Generates the actual loop code for a scalarization loop. */
3371 gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
3372 stmtblock_t * pbody)
3383 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS))
3384 == (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS)
3385 && n == loop->dimen - 1)
3387 /* We create an OMP_FOR construct for the outermost scalarized loop. */
3388 init = make_tree_vec (1);
3389 cond = make_tree_vec (1);
3390 incr = make_tree_vec (1);
3392 /* Cycle statement is implemented with a goto. Exit statement must not
3393 be present for this loop. */
3394 exit_label = gfc_build_label_decl (NULL_TREE);
3395 TREE_USED (exit_label) = 1;
3397 /* Label for cycle statements (if needed). */
3398 tmp = build1_v (LABEL_EXPR, exit_label);
3399 gfc_add_expr_to_block (pbody, tmp);
3401 stmt = make_node (OMP_FOR);
3403 TREE_TYPE (stmt) = void_type_node;
3404 OMP_FOR_BODY (stmt) = loopbody = gfc_finish_block (pbody);
3406 OMP_FOR_CLAUSES (stmt) = build_omp_clause (input_location,
3407 OMP_CLAUSE_SCHEDULE);
3408 OMP_CLAUSE_SCHEDULE_KIND (OMP_FOR_CLAUSES (stmt))
3409 = OMP_CLAUSE_SCHEDULE_STATIC;
3410 if (ompws_flags & OMPWS_NOWAIT)
3411 OMP_CLAUSE_CHAIN (OMP_FOR_CLAUSES (stmt))
3412 = build_omp_clause (input_location, OMP_CLAUSE_NOWAIT);
3414 /* Initialize the loopvar. */
3415 TREE_VEC_ELT (init, 0) = build2_v (MODIFY_EXPR, loop->loopvar[n],
3417 OMP_FOR_INIT (stmt) = init;
3418 /* The exit condition. */
3419 TREE_VEC_ELT (cond, 0) = build2_loc (input_location, LE_EXPR,
3421 loop->loopvar[n], loop->to[n]);
3422 SET_EXPR_LOCATION (TREE_VEC_ELT (cond, 0), input_location);
3423 OMP_FOR_COND (stmt) = cond;
3424 /* Increment the loopvar. */
3425 tmp = build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3426 loop->loopvar[n], gfc_index_one_node);
3427 TREE_VEC_ELT (incr, 0) = fold_build2_loc (input_location, MODIFY_EXPR,
3428 void_type_node, loop->loopvar[n], tmp);
3429 OMP_FOR_INCR (stmt) = incr;
3431 ompws_flags &= ~OMPWS_CURR_SINGLEUNIT;
3432 gfc_add_expr_to_block (&loop->code[n], stmt);
3436 bool reverse_loop = (loop->reverse[n] == GFC_REVERSE_SET)
3437 && (loop->temp_ss == NULL);
3439 loopbody = gfc_finish_block (pbody);
3443 tmp = loop->from[n];
3444 loop->from[n] = loop->to[n];
3448 /* Initialize the loopvar. */
3449 if (loop->loopvar[n] != loop->from[n])
3450 gfc_add_modify (&loop->code[n], loop->loopvar[n], loop->from[n]);
3452 exit_label = gfc_build_label_decl (NULL_TREE);
3454 /* Generate the loop body. */
3455 gfc_init_block (&block);
3457 /* The exit condition. */
3458 cond = fold_build2_loc (input_location, reverse_loop ? LT_EXPR : GT_EXPR,
3459 boolean_type_node, loop->loopvar[n], loop->to[n]);
3460 tmp = build1_v (GOTO_EXPR, exit_label);
3461 TREE_USED (exit_label) = 1;
3462 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
3463 gfc_add_expr_to_block (&block, tmp);
3465 /* The main body. */
3466 gfc_add_expr_to_block (&block, loopbody);
3468 /* Increment the loopvar. */
3469 tmp = fold_build2_loc (input_location,
3470 reverse_loop ? MINUS_EXPR : PLUS_EXPR,
3471 gfc_array_index_type, loop->loopvar[n],
3472 gfc_index_one_node);
3474 gfc_add_modify (&block, loop->loopvar[n], tmp);
3476 /* Build the loop. */
3477 tmp = gfc_finish_block (&block);
3478 tmp = build1_v (LOOP_EXPR, tmp);
3479 gfc_add_expr_to_block (&loop->code[n], tmp);
3481 /* Add the exit label. */
3482 tmp = build1_v (LABEL_EXPR, exit_label);
3483 gfc_add_expr_to_block (&loop->code[n], tmp);
3489 /* Finishes and generates the loops for a scalarized expression. */
3492 gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body)
3497 stmtblock_t *pblock;
3501 /* Generate the loops. */
3502 for (dim = 0; dim < loop->dimen; dim++)
3504 n = loop->order[dim];
3505 gfc_trans_scalarized_loop_end (loop, n, pblock);
3506 loop->loopvar[n] = NULL_TREE;
3507 pblock = &loop->code[n];
3510 tmp = gfc_finish_block (pblock);
3511 gfc_add_expr_to_block (&loop->pre, tmp);
3513 /* Clear all the used flags. */
3514 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3515 if (ss->parent == NULL)
3516 ss->info->useflags = 0;
3520 /* Finish the main body of a scalarized expression, and start the secondary
3524 gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
3528 stmtblock_t *pblock;
3532 /* We finish as many loops as are used by the temporary. */
3533 for (dim = 0; dim < loop->temp_dim - 1; dim++)
3535 n = loop->order[dim];
3536 gfc_trans_scalarized_loop_end (loop, n, pblock);
3537 loop->loopvar[n] = NULL_TREE;
3538 pblock = &loop->code[n];
3541 /* We don't want to finish the outermost loop entirely. */
3542 n = loop->order[loop->temp_dim - 1];
3543 gfc_trans_scalarized_loop_end (loop, n, pblock);
3545 /* Restore the initial offsets. */
3546 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3548 gfc_ss_type ss_type;
3549 gfc_ss_info *ss_info;
3553 if ((ss_info->useflags & 2) == 0)
3556 ss_type = ss_info->type;
3557 if (ss_type != GFC_SS_SECTION
3558 && ss_type != GFC_SS_FUNCTION
3559 && ss_type != GFC_SS_CONSTRUCTOR
3560 && ss_type != GFC_SS_COMPONENT)
3563 ss_info->data.array.offset = ss_info->data.array.saved_offset;
3566 /* Restart all the inner loops we just finished. */
3567 for (dim = loop->temp_dim - 2; dim >= 0; dim--)
3569 n = loop->order[dim];
3571 gfc_start_block (&loop->code[n]);
3573 loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "Q");
3575 gfc_trans_preloop_setup (loop, dim, 2, &loop->code[n]);
3578 /* Start a block for the secondary copying code. */
3579 gfc_start_block (body);
3583 /* Precalculate (either lower or upper) bound of an array section.
3584 BLOCK: Block in which the (pre)calculation code will go.
3585 BOUNDS[DIM]: Where the bound value will be stored once evaluated.
3586 VALUES[DIM]: Specified bound (NULL <=> unspecified).
3587 DESC: Array descriptor from which the bound will be picked if unspecified
3588 (either lower or upper bound according to LBOUND). */
3591 evaluate_bound (stmtblock_t *block, tree *bounds, gfc_expr ** values,
3592 tree desc, int dim, bool lbound)
3595 gfc_expr * input_val = values[dim];
3596 tree *output = &bounds[dim];
3601 /* Specified section bound. */
3602 gfc_init_se (&se, NULL);
3603 gfc_conv_expr_type (&se, input_val, gfc_array_index_type);
3604 gfc_add_block_to_block (block, &se.pre);
3609 /* No specific bound specified so use the bound of the array. */
3610 *output = lbound ? gfc_conv_array_lbound (desc, dim) :
3611 gfc_conv_array_ubound (desc, dim);
3613 *output = gfc_evaluate_now (*output, block);
3617 /* Calculate the lower bound of an array section. */
3620 gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int dim)
3622 gfc_expr *stride = NULL;
3625 gfc_array_info *info;
3628 gcc_assert (ss->info->type == GFC_SS_SECTION);
3630 info = &ss->info->data.array;
3631 ar = &info->ref->u.ar;
3633 if (ar->dimen_type[dim] == DIMEN_VECTOR)
3635 /* We use a zero-based index to access the vector. */
3636 info->start[dim] = gfc_index_zero_node;
3637 info->end[dim] = NULL;
3638 info->stride[dim] = gfc_index_one_node;
3642 gcc_assert (ar->dimen_type[dim] == DIMEN_RANGE
3643 || ar->dimen_type[dim] == DIMEN_THIS_IMAGE);
3644 desc = info->descriptor;
3645 stride = ar->stride[dim];
3647 /* Calculate the start of the range. For vector subscripts this will
3648 be the range of the vector. */
3649 evaluate_bound (&loop->pre, info->start, ar->start, desc, dim, true);
3651 /* Similarly calculate the end. Although this is not used in the
3652 scalarizer, it is needed when checking bounds and where the end
3653 is an expression with side-effects. */
3654 evaluate_bound (&loop->pre, info->end, ar->end, desc, dim, false);
3656 /* Calculate the stride. */
3658 info->stride[dim] = gfc_index_one_node;
3661 gfc_init_se (&se, NULL);
3662 gfc_conv_expr_type (&se, stride, gfc_array_index_type);
3663 gfc_add_block_to_block (&loop->pre, &se.pre);
3664 info->stride[dim] = gfc_evaluate_now (se.expr, &loop->pre);
3669 /* Calculates the range start and stride for a SS chain. Also gets the
3670 descriptor and data pointer. The range of vector subscripts is the size
3671 of the vector. Array bounds are also checked. */
3674 gfc_conv_ss_startstride (gfc_loopinfo * loop)
3682 /* Determine the rank of the loop. */
3683 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3685 switch (ss->info->type)
3687 case GFC_SS_SECTION:
3688 case GFC_SS_CONSTRUCTOR:
3689 case GFC_SS_FUNCTION:
3690 case GFC_SS_COMPONENT:
3691 loop->dimen = ss->dimen;
3694 /* As usual, lbound and ubound are exceptions!. */
3695 case GFC_SS_INTRINSIC:
3696 switch (ss->info->expr->value.function.isym->id)
3698 case GFC_ISYM_LBOUND:
3699 case GFC_ISYM_UBOUND:
3700 case GFC_ISYM_LCOBOUND:
3701 case GFC_ISYM_UCOBOUND:
3702 case GFC_ISYM_THIS_IMAGE:
3703 loop->dimen = ss->dimen;
3715 /* We should have determined the rank of the expression by now. If
3716 not, that's bad news. */
3720 /* Loop over all the SS in the chain. */
3721 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3723 gfc_ss_info *ss_info;
3724 gfc_array_info *info;
3728 expr = ss_info->expr;
3729 info = &ss_info->data.array;
3731 if (expr && expr->shape && !info->shape)
3732 info->shape = expr->shape;
3734 switch (ss_info->type)
3736 case GFC_SS_SECTION:
3737 /* Get the descriptor for the array. If it is a cross loops array,
3738 we got the descriptor already in the outermost loop. */
3739 if (ss->parent == NULL)
3740 gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter);
3742 for (n = 0; n < ss->dimen; n++)
3743 gfc_conv_section_startstride (loop, ss, ss->dim[n]);
3746 case GFC_SS_INTRINSIC:
3747 switch (expr->value.function.isym->id)
3749 /* Fall through to supply start and stride. */
3750 case GFC_ISYM_LBOUND:
3751 case GFC_ISYM_UBOUND:
3752 case GFC_ISYM_LCOBOUND:
3753 case GFC_ISYM_UCOBOUND:
3754 case GFC_ISYM_THIS_IMAGE:
3761 case GFC_SS_CONSTRUCTOR:
3762 case GFC_SS_FUNCTION:
3763 for (n = 0; n < ss->dimen; n++)
3765 int dim = ss->dim[n];
3767 info->start[dim] = gfc_index_zero_node;
3768 info->end[dim] = gfc_index_zero_node;
3769 info->stride[dim] = gfc_index_one_node;
3778 /* The rest is just runtime bound checking. */
3779 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
3782 tree lbound, ubound;
3784 tree size[GFC_MAX_DIMENSIONS];
3785 tree stride_pos, stride_neg, non_zerosized, tmp2, tmp3;
3786 gfc_array_info *info;
3790 gfc_start_block (&block);
3792 for (n = 0; n < loop->dimen; n++)
3793 size[n] = NULL_TREE;
3795 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3798 gfc_ss_info *ss_info;
3801 const char *expr_name;
3804 if (ss_info->type != GFC_SS_SECTION)
3807 /* Catch allocatable lhs in f2003. */
3808 if (gfc_option.flag_realloc_lhs && ss->is_alloc_lhs)
3811 expr = ss_info->expr;
3812 expr_loc = &expr->where;
3813 expr_name = expr->symtree->name;
3815 gfc_start_block (&inner);
3817 /* TODO: range checking for mapped dimensions. */
3818 info = &ss_info->data.array;
3820 /* This code only checks ranges. Elemental and vector
3821 dimensions are checked later. */
3822 for (n = 0; n < loop->dimen; n++)
3827 if (info->ref->u.ar.dimen_type[dim] != DIMEN_RANGE)
3830 if (dim == info->ref->u.ar.dimen - 1
3831 && info->ref->u.ar.as->type == AS_ASSUMED_SIZE)
3832 check_upper = false;
3836 /* Zero stride is not allowed. */
3837 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
3838 info->stride[dim], gfc_index_zero_node);
3839 asprintf (&msg, "Zero stride is not allowed, for dimension %d "
3840 "of array '%s'", dim + 1, expr_name);
3841 gfc_trans_runtime_check (true, false, tmp, &inner,
3845 desc = info->descriptor;
3847 /* This is the run-time equivalent of resolve.c's
3848 check_dimension(). The logical is more readable there
3849 than it is here, with all the trees. */
3850 lbound = gfc_conv_array_lbound (desc, dim);
3851 end = info->end[dim];
3853 ubound = gfc_conv_array_ubound (desc, dim);
3857 /* non_zerosized is true when the selected range is not
3859 stride_pos = fold_build2_loc (input_location, GT_EXPR,
3860 boolean_type_node, info->stride[dim],
3861 gfc_index_zero_node);
3862 tmp = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
3863 info->start[dim], end);
3864 stride_pos = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3865 boolean_type_node, stride_pos, tmp);
3867 stride_neg = fold_build2_loc (input_location, LT_EXPR,
3869 info->stride[dim], gfc_index_zero_node);
3870 tmp = fold_build2_loc (input_location, GE_EXPR, boolean_type_node,
3871 info->start[dim], end);
3872 stride_neg = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3875 non_zerosized = fold_build2_loc (input_location, TRUTH_OR_EXPR,
3877 stride_pos, stride_neg);
3879 /* Check the start of the range against the lower and upper
3880 bounds of the array, if the range is not empty.
3881 If upper bound is present, include both bounds in the
3885 tmp = fold_build2_loc (input_location, LT_EXPR,
3887 info->start[dim], lbound);
3888 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3890 non_zerosized, tmp);
3891 tmp2 = fold_build2_loc (input_location, GT_EXPR,
3893 info->start[dim], ubound);
3894 tmp2 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3896 non_zerosized, tmp2);
3897 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3898 "outside of expected range (%%ld:%%ld)",
3899 dim + 1, expr_name);
3900 gfc_trans_runtime_check (true, false, tmp, &inner,
3902 fold_convert (long_integer_type_node, info->start[dim]),
3903 fold_convert (long_integer_type_node, lbound),
3904 fold_convert (long_integer_type_node, ubound));
3905 gfc_trans_runtime_check (true, false, tmp2, &inner,
3907 fold_convert (long_integer_type_node, info->start[dim]),
3908 fold_convert (long_integer_type_node, lbound),
3909 fold_convert (long_integer_type_node, ubound));
3914 tmp = fold_build2_loc (input_location, LT_EXPR,
3916 info->start[dim], lbound);
3917 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3918 boolean_type_node, non_zerosized, tmp);
3919 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3920 "below lower bound of %%ld",
3921 dim + 1, expr_name);
3922 gfc_trans_runtime_check (true, false, tmp, &inner,
3924 fold_convert (long_integer_type_node, info->start[dim]),
3925 fold_convert (long_integer_type_node, lbound));
3929 /* Compute the last element of the range, which is not
3930 necessarily "end" (think 0:5:3, which doesn't contain 5)
3931 and check it against both lower and upper bounds. */
3933 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3934 gfc_array_index_type, end,
3936 tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
3937 gfc_array_index_type, tmp,
3939 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3940 gfc_array_index_type, end, tmp);
3941 tmp2 = fold_build2_loc (input_location, LT_EXPR,
3942 boolean_type_node, tmp, lbound);
3943 tmp2 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3944 boolean_type_node, non_zerosized, tmp2);
3947 tmp3 = fold_build2_loc (input_location, GT_EXPR,
3948 boolean_type_node, tmp, ubound);
3949 tmp3 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3950 boolean_type_node, non_zerosized, tmp3);
3951 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3952 "outside of expected range (%%ld:%%ld)",
3953 dim + 1, expr_name);
3954 gfc_trans_runtime_check (true, false, tmp2, &inner,
3956 fold_convert (long_integer_type_node, tmp),
3957 fold_convert (long_integer_type_node, ubound),
3958 fold_convert (long_integer_type_node, lbound));
3959 gfc_trans_runtime_check (true, false, tmp3, &inner,
3961 fold_convert (long_integer_type_node, tmp),
3962 fold_convert (long_integer_type_node, ubound),
3963 fold_convert (long_integer_type_node, lbound));
3968 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3969 "below lower bound of %%ld",
3970 dim + 1, expr_name);
3971 gfc_trans_runtime_check (true, false, tmp2, &inner,
3973 fold_convert (long_integer_type_node, tmp),
3974 fold_convert (long_integer_type_node, lbound));
3978 /* Check the section sizes match. */
3979 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3980 gfc_array_index_type, end,
3982 tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR,
3983 gfc_array_index_type, tmp,
3985 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3986 gfc_array_index_type,
3987 gfc_index_one_node, tmp);
3988 tmp = fold_build2_loc (input_location, MAX_EXPR,
3989 gfc_array_index_type, tmp,
3990 build_int_cst (gfc_array_index_type, 0));
3991 /* We remember the size of the first section, and check all the
3992 others against this. */
3995 tmp3 = fold_build2_loc (input_location, NE_EXPR,
3996 boolean_type_node, tmp, size[n]);
3997 asprintf (&msg, "Array bound mismatch for dimension %d "
3998 "of array '%s' (%%ld/%%ld)",
3999 dim + 1, expr_name);
4001 gfc_trans_runtime_check (true, false, tmp3, &inner,
4003 fold_convert (long_integer_type_node, tmp),
4004 fold_convert (long_integer_type_node, size[n]));
4009 size[n] = gfc_evaluate_now (tmp, &inner);
4012 tmp = gfc_finish_block (&inner);
4014 /* For optional arguments, only check bounds if the argument is
4016 if (expr->symtree->n.sym->attr.optional
4017 || expr->symtree->n.sym->attr.not_always_present)
4018 tmp = build3_v (COND_EXPR,
4019 gfc_conv_expr_present (expr->symtree->n.sym),
4020 tmp, build_empty_stmt (input_location));
4022 gfc_add_expr_to_block (&block, tmp);
4026 tmp = gfc_finish_block (&block);
4027 gfc_add_expr_to_block (&loop->pre, tmp);
4030 for (loop = loop->nested; loop; loop = loop->next)
4031 gfc_conv_ss_startstride (loop);
4034 /* Return true if both symbols could refer to the same data object. Does
4035 not take account of aliasing due to equivalence statements. */
4038 symbols_could_alias (gfc_symbol *lsym, gfc_symbol *rsym, bool lsym_pointer,
4039 bool lsym_target, bool rsym_pointer, bool rsym_target)
4041 /* Aliasing isn't possible if the symbols have different base types. */
4042 if (gfc_compare_types (&lsym->ts, &rsym->ts) == 0)
4045 /* Pointers can point to other pointers and target objects. */
4047 if ((lsym_pointer && (rsym_pointer || rsym_target))
4048 || (rsym_pointer && (lsym_pointer || lsym_target)))
4051 /* Special case: Argument association, cf. F90 12.4.1.6, F2003 12.4.1.7
4052 and F2008 12.5.2.13 items 3b and 4b. The pointer case (a) is already
4054 if (lsym_target && rsym_target
4055 && ((lsym->attr.dummy && !lsym->attr.contiguous
4056 && (!lsym->attr.dimension || lsym->as->type == AS_ASSUMED_SHAPE))
4057 || (rsym->attr.dummy && !rsym->attr.contiguous
4058 && (!rsym->attr.dimension
4059 || rsym->as->type == AS_ASSUMED_SHAPE))))
4066 /* Return true if the two SS could be aliased, i.e. both point to the same data
4068 /* TODO: resolve aliases based on frontend expressions. */
4071 gfc_could_be_alias (gfc_ss * lss, gfc_ss * rss)
4075 gfc_expr *lexpr, *rexpr;
4078 bool lsym_pointer, lsym_target, rsym_pointer, rsym_target;
4080 lexpr = lss->info->expr;
4081 rexpr = rss->info->expr;
4083 lsym = lexpr->symtree->n.sym;
4084 rsym = rexpr->symtree->n.sym;
4086 lsym_pointer = lsym->attr.pointer;
4087 lsym_target = lsym->attr.target;
4088 rsym_pointer = rsym->attr.pointer;
4089 rsym_target = rsym->attr.target;
4091 if (symbols_could_alias (lsym, rsym, lsym_pointer, lsym_target,
4092 rsym_pointer, rsym_target))
4095 if (rsym->ts.type != BT_DERIVED && rsym->ts.type != BT_CLASS
4096 && lsym->ts.type != BT_DERIVED && lsym->ts.type != BT_CLASS)
4099 /* For derived types we must check all the component types. We can ignore
4100 array references as these will have the same base type as the previous
4102 for (lref = lexpr->ref; lref != lss->info->data.array.ref; lref = lref->next)
4104 if (lref->type != REF_COMPONENT)
4107 lsym_pointer = lsym_pointer || lref->u.c.sym->attr.pointer;
4108 lsym_target = lsym_target || lref->u.c.sym->attr.target;
4110 if (symbols_could_alias (lref->u.c.sym, rsym, lsym_pointer, lsym_target,
4111 rsym_pointer, rsym_target))
4114 if ((lsym_pointer && (rsym_pointer || rsym_target))
4115 || (rsym_pointer && (lsym_pointer || lsym_target)))
4117 if (gfc_compare_types (&lref->u.c.component->ts,
4122 for (rref = rexpr->ref; rref != rss->info->data.array.ref;
4125 if (rref->type != REF_COMPONENT)
4128 rsym_pointer = rsym_pointer || rref->u.c.sym->attr.pointer;
4129 rsym_target = lsym_target || rref->u.c.sym->attr.target;
4131 if (symbols_could_alias (lref->u.c.sym, rref->u.c.sym,
4132 lsym_pointer, lsym_target,
4133 rsym_pointer, rsym_target))
4136 if ((lsym_pointer && (rsym_pointer || rsym_target))
4137 || (rsym_pointer && (lsym_pointer || lsym_target)))
4139 if (gfc_compare_types (&lref->u.c.component->ts,
4140 &rref->u.c.sym->ts))
4142 if (gfc_compare_types (&lref->u.c.sym->ts,
4143 &rref->u.c.component->ts))
4145 if (gfc_compare_types (&lref->u.c.component->ts,
4146 &rref->u.c.component->ts))
4152 lsym_pointer = lsym->attr.pointer;
4153 lsym_target = lsym->attr.target;
4154 lsym_pointer = lsym->attr.pointer;
4155 lsym_target = lsym->attr.target;
4157 for (rref = rexpr->ref; rref != rss->info->data.array.ref; rref = rref->next)
4159 if (rref->type != REF_COMPONENT)
4162 rsym_pointer = rsym_pointer || rref->u.c.sym->attr.pointer;
4163 rsym_target = lsym_target || rref->u.c.sym->attr.target;
4165 if (symbols_could_alias (rref->u.c.sym, lsym,
4166 lsym_pointer, lsym_target,
4167 rsym_pointer, rsym_target))
4170 if ((lsym_pointer && (rsym_pointer || rsym_target))
4171 || (rsym_pointer && (lsym_pointer || lsym_target)))
4173 if (gfc_compare_types (&lsym->ts, &rref->u.c.component->ts))
4182 /* Resolve array data dependencies. Creates a temporary if required. */
4183 /* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
4187 gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
4193 gfc_expr *dest_expr;
4198 loop->temp_ss = NULL;
4199 dest_expr = dest->info->expr;
4201 for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
4203 if (ss->info->type != GFC_SS_SECTION)
4206 ss_expr = ss->info->expr;
4208 if (dest_expr->symtree->n.sym != ss_expr->symtree->n.sym)
4210 if (gfc_could_be_alias (dest, ss)
4211 || gfc_are_equivalenced_arrays (dest_expr, ss_expr))
4219 lref = dest_expr->ref;
4220 rref = ss_expr->ref;
4222 nDepend = gfc_dep_resolver (lref, rref, &loop->reverse[0]);
4227 for (i = 0; i < dest->dimen; i++)
4228 for (j = 0; j < ss->dimen; j++)
4230 && dest->dim[i] == ss->dim[j])
4232 /* If we don't access array elements in the same order,
4233 there is a dependency. */
4238 /* TODO : loop shifting. */
4241 /* Mark the dimensions for LOOP SHIFTING */
4242 for (n = 0; n < loop->dimen; n++)
4244 int dim = dest->data.info.dim[n];
4246 if (lref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
4248 else if (! gfc_is_same_range (&lref->u.ar,
4249 &rref->u.ar, dim, 0))
4253 /* Put all the dimensions with dependencies in the
4256 for (n = 0; n < loop->dimen; n++)
4258 gcc_assert (loop->order[n] == n);
4260 loop->order[dim++] = n;
4262 for (n = 0; n < loop->dimen; n++)
4265 loop->order[dim++] = n;
4268 gcc_assert (dim == loop->dimen);
4279 tree base_type = gfc_typenode_for_spec (&dest_expr->ts);
4280 if (GFC_ARRAY_TYPE_P (base_type)
4281 || GFC_DESCRIPTOR_TYPE_P (base_type))
4282 base_type = gfc_get_element_type (base_type);
4283 loop->temp_ss = gfc_get_temp_ss (base_type, dest->info->string_length,
4285 gfc_add_ss_to_loop (loop, loop->temp_ss);
4288 loop->temp_ss = NULL;
4292 /* Browse through each array's information from the scalarizer and set the loop
4293 bounds according to the "best" one (per dimension), i.e. the one which
4294 provides the most information (constant bounds, shape, etc). */
4297 set_loop_bounds (gfc_loopinfo *loop)
4299 int n, dim, spec_dim;
4300 gfc_array_info *info;
4301 gfc_array_info *specinfo;
4305 bool dynamic[GFC_MAX_DIMENSIONS];
4309 loopspec = loop->specloop;
4312 for (n = 0; n < loop->dimen; n++)
4316 /* We use one SS term, and use that to determine the bounds of the
4317 loop for this dimension. We try to pick the simplest term. */
4318 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
4320 gfc_ss_type ss_type;
4322 ss_type = ss->info->type;
4323 if (ss_type == GFC_SS_SCALAR
4324 || ss_type == GFC_SS_TEMP
4325 || ss_type == GFC_SS_REFERENCE)
4328 info = &ss->info->data.array;
4331 if (loopspec[n] != NULL)
4333 specinfo = &loopspec[n]->info->data.array;
4334 spec_dim = loopspec[n]->dim[n];
4338 /* Silence unitialized warnings. */
4345 gcc_assert (info->shape[dim]);
4346 /* The frontend has worked out the size for us. */
4349 || !integer_zerop (specinfo->start[spec_dim]))
4350 /* Prefer zero-based descriptors if possible. */
4355 if (ss_type == GFC_SS_CONSTRUCTOR)
4357 gfc_constructor_base base;
4358 /* An unknown size constructor will always be rank one.
4359 Higher rank constructors will either have known shape,
4360 or still be wrapped in a call to reshape. */
4361 gcc_assert (loop->dimen == 1);
4363 /* Always prefer to use the constructor bounds if the size
4364 can be determined at compile time. Prefer not to otherwise,
4365 since the general case involves realloc, and it's better to
4366 avoid that overhead if possible. */
4367 base = ss->info->expr->value.constructor;
4368 dynamic[n] = gfc_get_array_constructor_size (&i, base);
4369 if (!dynamic[n] || !loopspec[n])
4374 /* TODO: Pick the best bound if we have a choice between a
4375 function and something else. */
4376 if (ss_type == GFC_SS_FUNCTION)
4382 /* Avoid using an allocatable lhs in an assignment, since
4383 there might be a reallocation coming. */
4384 if (loopspec[n] && ss->is_alloc_lhs)
4387 if (ss_type != GFC_SS_SECTION)
4392 /* Criteria for choosing a loop specifier (most important first):
4393 doesn't need realloc
4399 else if ((loopspec[n]->info->type == GFC_SS_CONSTRUCTOR && dynamic[n])
4400 || n >= loop->dimen)
4402 else if (integer_onep (info->stride[dim])
4403 && !integer_onep (specinfo->stride[spec_dim]))
4405 else if (INTEGER_CST_P (info->stride[dim])
4406 && !INTEGER_CST_P (specinfo->stride[spec_dim]))
4408 else if (INTEGER_CST_P (info->start[dim])
4409 && !INTEGER_CST_P (specinfo->start[spec_dim]))
4411 /* We don't work out the upper bound.
4412 else if (INTEGER_CST_P (info->finish[n])
4413 && ! INTEGER_CST_P (specinfo->finish[n]))
4414 loopspec[n] = ss; */
4417 /* We should have found the scalarization loop specifier. If not,
4419 gcc_assert (loopspec[n]);
4421 info = &loopspec[n]->info->data.array;
4422 dim = loopspec[n]->dim[n];
4424 /* Set the extents of this range. */
4425 cshape = info->shape;
4426 if (cshape && INTEGER_CST_P (info->start[dim])
4427 && INTEGER_CST_P (info->stride[dim]))
4429 loop->from[n] = info->start[dim];
4430 mpz_set (i, cshape[get_array_ref_dim_for_loop_dim (loopspec[n], n)]);
4431 mpz_sub_ui (i, i, 1);
4432 /* To = from + (size - 1) * stride. */
4433 tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
4434 if (!integer_onep (info->stride[dim]))
4435 tmp = fold_build2_loc (input_location, MULT_EXPR,
4436 gfc_array_index_type, tmp,
4438 loop->to[n] = fold_build2_loc (input_location, PLUS_EXPR,
4439 gfc_array_index_type,
4440 loop->from[n], tmp);
4444 loop->from[n] = info->start[dim];
4445 switch (loopspec[n]->info->type)
4447 case GFC_SS_CONSTRUCTOR:
4448 /* The upper bound is calculated when we expand the
4450 gcc_assert (loop->to[n] == NULL_TREE);
4453 case GFC_SS_SECTION:
4454 /* Use the end expression if it exists and is not constant,
4455 so that it is only evaluated once. */
4456 loop->to[n] = info->end[dim];
4459 case GFC_SS_FUNCTION:
4460 /* The loop bound will be set when we generate the call. */
4461 gcc_assert (loop->to[n] == NULL_TREE);
4469 /* Transform everything so we have a simple incrementing variable. */
4470 if (integer_onep (info->stride[dim]))
4471 info->delta[dim] = gfc_index_zero_node;
4474 /* Set the delta for this section. */
4475 info->delta[dim] = gfc_evaluate_now (loop->from[n], &loop->pre);
4476 /* Number of iterations is (end - start + step) / step.
4477 with start = 0, this simplifies to
4479 for (i = 0; i<=last; i++){...}; */
4480 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4481 gfc_array_index_type, loop->to[n],
4483 tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR,
4484 gfc_array_index_type, tmp, info->stride[dim]);
4485 tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_array_index_type,
4486 tmp, build_int_cst (gfc_array_index_type, -1));
4487 loop->to[n] = gfc_evaluate_now (tmp, &loop->pre);
4488 /* Make the loop variable start at 0. */
4489 loop->from[n] = gfc_index_zero_node;
4494 for (loop = loop->nested; loop; loop = loop->next)
4495 set_loop_bounds (loop);
4499 /* Initialize the scalarization loop. Creates the loop variables. Determines
4500 the range of the loop variables. Creates a temporary if required.
4501 Also generates code for scalar expressions which have been
4502 moved outside the loop. */
4505 gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
4510 set_loop_bounds (loop);
4512 /* Add all the scalar code that can be taken out of the loops.
4513 This may include calculating the loop bounds, so do it before
4514 allocating the temporary. */
4515 gfc_add_loop_ss_code (loop, loop->ss, false, where);
4517 tmp_ss = loop->temp_ss;
4518 /* If we want a temporary then create it. */
4521 gfc_ss_info *tmp_ss_info;
4523 tmp_ss_info = tmp_ss->info;
4524 gcc_assert (tmp_ss_info->type == GFC_SS_TEMP);
4525 gcc_assert (loop->parent == NULL);
4527 /* Make absolutely sure that this is a complete type. */
4528 if (tmp_ss_info->string_length)
4529 tmp_ss_info->data.temp.type
4530 = gfc_get_character_type_len_for_eltype
4531 (TREE_TYPE (tmp_ss_info->data.temp.type),
4532 tmp_ss_info->string_length);
4534 tmp = tmp_ss_info->data.temp.type;
4535 memset (&tmp_ss_info->data.array, 0, sizeof (gfc_array_info));
4536 tmp_ss_info->type = GFC_SS_SECTION;
4538 gcc_assert (tmp_ss->dimen != 0);
4540 gfc_trans_create_temp_array (&loop->pre, &loop->post, tmp_ss, tmp,
4541 NULL_TREE, false, true, false, where);
4544 /* For array parameters we don't have loop variables, so don't calculate the
4546 if (!loop->array_parameter)
4547 gfc_set_delta (loop);
4551 /* Calculates how to transform from loop variables to array indices for each
4552 array: once loop bounds are chosen, sets the difference (DELTA field) between
4553 loop bounds and array reference bounds, for each array info. */
4556 gfc_set_delta (gfc_loopinfo *loop)
4558 gfc_ss *ss, **loopspec;
4559 gfc_array_info *info;
4563 loopspec = loop->specloop;
4565 /* Calculate the translation from loop variables to array indices. */
4566 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
4568 gfc_ss_type ss_type;
4570 ss_type = ss->info->type;
4571 if (ss_type != GFC_SS_SECTION
4572 && ss_type != GFC_SS_COMPONENT
4573 && ss_type != GFC_SS_CONSTRUCTOR)
4576 info = &ss->info->data.array;
4578 for (n = 0; n < ss->dimen; n++)
4580 /* If we are specifying the range the delta is already set. */
4581 if (loopspec[n] != ss)
4585 /* Calculate the offset relative to the loop variable.
4586 First multiply by the stride. */
4587 tmp = loop->from[n];
4588 if (!integer_onep (info->stride[dim]))
4589 tmp = fold_build2_loc (input_location, MULT_EXPR,
4590 gfc_array_index_type,
4591 tmp, info->stride[dim]);
4593 /* Then subtract this from our starting value. */
4594 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4595 gfc_array_index_type,
4596 info->start[dim], tmp);
4598 info->delta[dim] = gfc_evaluate_now (tmp, &loop->pre);
4603 for (loop = loop->nested; loop; loop = loop->next)
4604 gfc_set_delta (loop);
4608 /* Calculate the size of a given array dimension from the bounds. This
4609 is simply (ubound - lbound + 1) if this expression is positive
4610 or 0 if it is negative (pick either one if it is zero). Optionally
4611 (if or_expr is present) OR the (expression != 0) condition to it. */
4614 gfc_conv_array_extent_dim (tree lbound, tree ubound, tree* or_expr)
4619 /* Calculate (ubound - lbound + 1). */
4620 res = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
4622 res = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, res,
4623 gfc_index_one_node);
4625 /* Check whether the size for this dimension is negative. */
4626 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node, res,
4627 gfc_index_zero_node);
4628 res = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type, cond,
4629 gfc_index_zero_node, res);
4631 /* Build OR expression. */
4633 *or_expr = fold_build2_loc (input_location, TRUTH_OR_EXPR,
4634 boolean_type_node, *or_expr, cond);
4640 /* For an array descriptor, get the total number of elements. This is just
4641 the product of the extents along from_dim to to_dim. */
4644 gfc_conv_descriptor_size_1 (tree desc, int from_dim, int to_dim)
4649 res = gfc_index_one_node;
4651 for (dim = from_dim; dim < to_dim; ++dim)
4657 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]);
4658 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]);
4660 extent = gfc_conv_array_extent_dim (lbound, ubound, NULL);
4661 res = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4669 /* Full size of an array. */
4672 gfc_conv_descriptor_size (tree desc, int rank)
4674 return gfc_conv_descriptor_size_1 (desc, 0, rank);
4678 /* Size of a coarray for all dimensions but the last. */
4681 gfc_conv_descriptor_cosize (tree desc, int rank, int corank)
4683 return gfc_conv_descriptor_size_1 (desc, rank, rank + corank - 1);
4687 /* Fills in an array descriptor, and returns the size of the array.
4688 The size will be a simple_val, ie a variable or a constant. Also
4689 calculates the offset of the base. The pointer argument overflow,
4690 which should be of integer type, will increase in value if overflow
4691 occurs during the size calculation. Returns the size of the array.
4695 for (n = 0; n < rank; n++)
4697 a.lbound[n] = specified_lower_bound;
4698 offset = offset + a.lbond[n] * stride;
4700 a.ubound[n] = specified_upper_bound;
4701 a.stride[n] = stride;
4702 size = size >= 0 ? ubound + size : 0; //size = ubound + 1 - lbound
4703 overflow += size == 0 ? 0: (MAX/size < stride ? 1: 0);
4704 stride = stride * size;
4706 for (n = rank; n < rank+corank; n++)
4707 (Set lcobound/ucobound as above.)
4708 element_size = sizeof (array element);
4711 stride = (size_t) stride;
4712 overflow += element_size == 0 ? 0: (MAX/element_size < stride ? 1: 0);
4713 stride = stride * element_size;
4719 gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset,
4720 gfc_expr ** lower, gfc_expr ** upper, stmtblock_t * pblock,
4721 stmtblock_t * descriptor_block, tree * overflow,
4735 stmtblock_t thenblock;
4736 stmtblock_t elseblock;
4741 type = TREE_TYPE (descriptor);
4743 stride = gfc_index_one_node;
4744 offset = gfc_index_zero_node;
4746 /* Set the dtype. */
4747 tmp = gfc_conv_descriptor_dtype (descriptor);
4748 gfc_add_modify (descriptor_block, tmp, gfc_get_dtype (TREE_TYPE (descriptor)));
4750 or_expr = boolean_false_node;
4752 for (n = 0; n < rank; n++)
4757 /* We have 3 possibilities for determining the size of the array:
4758 lower == NULL => lbound = 1, ubound = upper[n]
4759 upper[n] = NULL => lbound = 1, ubound = lower[n]
4760 upper[n] != NULL => lbound = lower[n], ubound = upper[n] */
4763 /* Set lower bound. */
4764 gfc_init_se (&se, NULL);
4766 se.expr = gfc_index_one_node;
4769 gcc_assert (lower[n]);
4772 gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
4773 gfc_add_block_to_block (pblock, &se.pre);
4777 se.expr = gfc_index_one_node;
4781 gfc_conv_descriptor_lbound_set (descriptor_block, descriptor,
4782 gfc_rank_cst[n], se.expr);
4783 conv_lbound = se.expr;
4785 /* Work out the offset for this component. */
4786 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4788 offset = fold_build2_loc (input_location, MINUS_EXPR,
4789 gfc_array_index_type, offset, tmp);
4791 /* Set upper bound. */
4792 gfc_init_se (&se, NULL);
4793 gcc_assert (ubound);
4794 gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
4795 gfc_add_block_to_block (pblock, &se.pre);
4797 gfc_conv_descriptor_ubound_set (descriptor_block, descriptor,
4798 gfc_rank_cst[n], se.expr);
4799 conv_ubound = se.expr;
4801 /* Store the stride. */
4802 gfc_conv_descriptor_stride_set (descriptor_block, descriptor,
4803 gfc_rank_cst[n], stride);
4805 /* Calculate size and check whether extent is negative. */
4806 size = gfc_conv_array_extent_dim (conv_lbound, conv_ubound, &or_expr);
4807 size = gfc_evaluate_now (size, pblock);
4809 /* Check whether multiplying the stride by the number of
4810 elements in this dimension would overflow. We must also check
4811 whether the current dimension has zero size in order to avoid
4814 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
4815 gfc_array_index_type,
4816 fold_convert (gfc_array_index_type,
4817 TYPE_MAX_VALUE (gfc_array_index_type)),
4819 cond = gfc_unlikely (fold_build2_loc (input_location, LT_EXPR,
4820 boolean_type_node, tmp, stride));
4821 tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
4822 integer_one_node, integer_zero_node);
4823 cond = gfc_unlikely (fold_build2_loc (input_location, EQ_EXPR,
4824 boolean_type_node, size,
4825 gfc_index_zero_node));
4826 tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
4827 integer_zero_node, tmp);
4828 tmp = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
4830 *overflow = gfc_evaluate_now (tmp, pblock);
4832 /* Multiply the stride by the number of elements in this dimension. */
4833 stride = fold_build2_loc (input_location, MULT_EXPR,
4834 gfc_array_index_type, stride, size);
4835 stride = gfc_evaluate_now (stride, pblock);
4838 for (n = rank; n < rank + corank; n++)
4842 /* Set lower bound. */
4843 gfc_init_se (&se, NULL);
4844 if (lower == NULL || lower[n] == NULL)
4846 gcc_assert (n == rank + corank - 1);
4847 se.expr = gfc_index_one_node;
4851 if (ubound || n == rank + corank - 1)
4853 gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
4854 gfc_add_block_to_block (pblock, &se.pre);
4858 se.expr = gfc_index_one_node;
4862 gfc_conv_descriptor_lbound_set (descriptor_block, descriptor,
4863 gfc_rank_cst[n], se.expr);
4865 if (n < rank + corank - 1)
4867 gfc_init_se (&se, NULL);
4868 gcc_assert (ubound);
4869 gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
4870 gfc_add_block_to_block (pblock, &se.pre);
4871 gfc_conv_descriptor_ubound_set (descriptor_block, descriptor,
4872 gfc_rank_cst[n], se.expr);
4876 /* The stride is the number of elements in the array, so multiply by the
4877 size of an element to get the total size. Obviously, if there ia a
4878 SOURCE expression (expr3) we must use its element size. */
4881 if (expr3->ts.type == BT_CLASS)
4884 gfc_expr *sz = gfc_copy_expr (expr3);
4885 gfc_add_vptr_component (sz);
4886 gfc_add_size_component (sz);
4887 gfc_init_se (&se_sz, NULL);
4888 gfc_conv_expr (&se_sz, sz);
4894 tmp = gfc_typenode_for_spec (&expr3->ts);
4895 tmp = TYPE_SIZE_UNIT (tmp);
4899 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
4901 /* Convert to size_t. */
4902 element_size = fold_convert (size_type_node, tmp);
4905 return element_size;
4907 stride = fold_convert (size_type_node, stride);
4909 /* First check for overflow. Since an array of type character can
4910 have zero element_size, we must check for that before
4912 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
4914 TYPE_MAX_VALUE (size_type_node), element_size);
4915 cond = gfc_unlikely (fold_build2_loc (input_location, LT_EXPR,
4916 boolean_type_node, tmp, stride));
4917 tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
4918 integer_one_node, integer_zero_node);
4919 cond = gfc_unlikely (fold_build2_loc (input_location, EQ_EXPR,
4920 boolean_type_node, element_size,
4921 build_int_cst (size_type_node, 0)));
4922 tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
4923 integer_zero_node, tmp);
4924 tmp = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
4926 *overflow = gfc_evaluate_now (tmp, pblock);
4928 size = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
4929 stride, element_size);
4931 if (poffset != NULL)
4933 offset = gfc_evaluate_now (offset, pblock);
4937 if (integer_zerop (or_expr))
4939 if (integer_onep (or_expr))
4940 return build_int_cst (size_type_node, 0);
4942 var = gfc_create_var (TREE_TYPE (size), "size");
4943 gfc_start_block (&thenblock);
4944 gfc_add_modify (&thenblock, var, build_int_cst (size_type_node, 0));
4945 thencase = gfc_finish_block (&thenblock);
4947 gfc_start_block (&elseblock);
4948 gfc_add_modify (&elseblock, var, size);
4949 elsecase = gfc_finish_block (&elseblock);
4951 tmp = gfc_evaluate_now (or_expr, pblock);
4952 tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
4953 gfc_add_expr_to_block (pblock, tmp);
4959 /* Initializes the descriptor and generates a call to _gfor_allocate. Does
4960 the work for an ALLOCATE statement. */
4964 gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg,
4965 tree errlen, tree label_finish, gfc_expr *expr3)
4969 tree offset = NULL_TREE;
4970 tree token = NULL_TREE;
4973 tree error = NULL_TREE;
4974 tree overflow; /* Boolean storing whether size calculation overflows. */
4975 tree var_overflow = NULL_TREE;
4977 tree set_descriptor;
4978 stmtblock_t set_descriptor_block;
4979 stmtblock_t elseblock;
4982 gfc_ref *ref, *prev_ref = NULL;
4983 bool allocatable, coarray, dimension;
4987 /* Find the last reference in the chain. */
4988 while (ref && ref->next != NULL)
4990 gcc_assert (ref->type != REF_ARRAY || ref->u.ar.type == AR_ELEMENT
4991 || (ref->u.ar.dimen == 0 && ref->u.ar.codimen > 0));
4996 if (ref == NULL || ref->type != REF_ARRAY)
5001 allocatable = expr->symtree->n.sym->attr.allocatable;
5002 coarray = expr->symtree->n.sym->attr.codimension;
5003 dimension = expr->symtree->n.sym->attr.dimension;
5007 allocatable = prev_ref->u.c.component->attr.allocatable;
5008 coarray = prev_ref->u.c.component->attr.codimension;
5009 dimension = prev_ref->u.c.component->attr.dimension;
5013 gcc_assert (coarray);
5015 /* Figure out the size of the array. */
5016 switch (ref->u.ar.type)
5022 upper = ref->u.ar.start;
5028 lower = ref->u.ar.start;
5029 upper = ref->u.ar.end;
5033 gcc_assert (ref->u.ar.as->type == AS_EXPLICIT);
5035 lower = ref->u.ar.as->lower;
5036 upper = ref->u.ar.as->upper;
5044 overflow = integer_zero_node;
5046 gfc_init_block (&set_descriptor_block);
5047 size = gfc_array_init_size (se->expr, ref->u.ar.as->rank,
5048 ref->u.ar.as->corank, &offset, lower, upper,
5049 &se->pre, &set_descriptor_block, &overflow,
5055 var_overflow = gfc_create_var (integer_type_node, "overflow");
5056 gfc_add_modify (&se->pre, var_overflow, overflow);
5058 /* Generate the block of code handling overflow. */
5059 msg = gfc_build_addr_expr (pchar_type_node,
5060 gfc_build_localized_cstring_const
5061 ("Integer overflow when calculating the amount of "
5062 "memory to allocate"));
5063 error = build_call_expr_loc (input_location, gfor_fndecl_runtime_error,
5067 if (status != NULL_TREE)
5069 tree status_type = TREE_TYPE (status);
5070 stmtblock_t set_status_block;
5072 gfc_start_block (&set_status_block);
5073 gfc_add_modify (&set_status_block, status,
5074 build_int_cst (status_type, LIBERROR_ALLOCATION));
5075 error = gfc_finish_block (&set_status_block);
5078 gfc_start_block (&elseblock);
5080 /* Allocate memory to store the data. */
5081 pointer = gfc_conv_descriptor_data_get (se->expr);
5082 STRIP_NOPS (pointer);
5084 if (coarray && gfc_option.coarray == GFC_FCOARRAY_LIB)
5085 token = gfc_build_addr_expr (NULL_TREE,
5086 gfc_conv_descriptor_token (se->expr));
5088 /* The allocatable variant takes the old pointer as first argument. */
5090 gfc_allocate_allocatable (&elseblock, pointer, size, token,
5091 status, errmsg, errlen, label_finish, expr);
5093 gfc_allocate_using_malloc (&elseblock, pointer, size, status);
5097 cond = gfc_unlikely (fold_build2_loc (input_location, NE_EXPR,
5098 boolean_type_node, var_overflow, integer_zero_node));
5099 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5100 error, gfc_finish_block (&elseblock));
5103 tmp = gfc_finish_block (&elseblock);
5105 gfc_add_expr_to_block (&se->pre, tmp);
5107 if (expr->ts.type == BT_CLASS && expr3)
5109 tmp = build_int_cst (unsigned_char_type_node, 0);
5110 /* With class objects, it is best to play safe and null the
5111 memory because we cannot know if dynamic types have allocatable
5112 components or not. */
5113 tmp = build_call_expr_loc (input_location,
5114 builtin_decl_explicit (BUILT_IN_MEMSET),
5115 3, pointer, tmp, size);
5116 gfc_add_expr_to_block (&se->pre, tmp);
5119 /* Update the array descriptors. */
5121 gfc_conv_descriptor_offset_set (&set_descriptor_block, se->expr, offset);
5123 set_descriptor = gfc_finish_block (&set_descriptor_block);
5124 if (status != NULL_TREE)
5126 cond = fold_build2_loc (input_location, EQ_EXPR,
5127 boolean_type_node, status,
5128 build_int_cst (TREE_TYPE (status), 0));
5129 gfc_add_expr_to_block (&se->pre,
5130 fold_build3_loc (input_location, COND_EXPR, void_type_node,
5131 gfc_likely (cond), set_descriptor,
5132 build_empty_stmt (input_location)));
5135 gfc_add_expr_to_block (&se->pre, set_descriptor);
5137 if ((expr->ts.type == BT_DERIVED)
5138 && expr->ts.u.derived->attr.alloc_comp)
5140 tmp = gfc_nullify_alloc_comp (expr->ts.u.derived, se->expr,
5141 ref->u.ar.as->rank);
5142 gfc_add_expr_to_block (&se->pre, tmp);
5149 /* Deallocate an array variable. Also used when an allocated variable goes
5154 gfc_array_deallocate (tree descriptor, tree pstat, tree errmsg, tree errlen,
5155 tree label_finish, gfc_expr* expr)
5160 bool coarray = gfc_is_coarray (expr);
5162 gfc_start_block (&block);
5164 /* Get a pointer to the data. */
5165 var = gfc_conv_descriptor_data_get (descriptor);
5168 /* Parameter is the address of the data component. */
5169 tmp = gfc_deallocate_with_status (coarray ? descriptor : var, pstat, errmsg,
5170 errlen, label_finish, false, expr, coarray);
5171 gfc_add_expr_to_block (&block, tmp);
5173 /* Zero the data pointer; only for coarrays an error can occur and then
5174 the allocation status may not be changed. */
5175 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
5176 var, build_int_cst (TREE_TYPE (var), 0));
5177 if (pstat != NULL_TREE && coarray && gfc_option.coarray == GFC_FCOARRAY_LIB)
5180 tree stat = build_fold_indirect_ref_loc (input_location, pstat);
5182 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
5183 stat, build_int_cst (TREE_TYPE (stat), 0));
5184 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
5185 cond, tmp, build_empty_stmt (input_location));
5188 gfc_add_expr_to_block (&block, tmp);
5190 return gfc_finish_block (&block);
5194 /* Create an array constructor from an initialization expression.
5195 We assume the frontend already did any expansions and conversions. */
5198 gfc_conv_array_initializer (tree type, gfc_expr * expr)
5204 unsigned HOST_WIDE_INT lo;
5206 VEC(constructor_elt,gc) *v = NULL;
5208 if (expr->expr_type == EXPR_VARIABLE
5209 && expr->symtree->n.sym->attr.flavor == FL_PARAMETER
5210 && expr->symtree->n.sym->value)
5211 expr = expr->symtree->n.sym->value;
5213 switch (expr->expr_type)
5216 case EXPR_STRUCTURE:
5217 /* A single scalar or derived type value. Create an array with all
5218 elements equal to that value. */
5219 gfc_init_se (&se, NULL);
5221 if (expr->expr_type == EXPR_CONSTANT)
5222 gfc_conv_constant (&se, expr);
5224 gfc_conv_structure (&se, expr, 1);
5226 tmp = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
5227 gcc_assert (tmp && INTEGER_CST_P (tmp));
5228 hi = TREE_INT_CST_HIGH (tmp);
5229 lo = TREE_INT_CST_LOW (tmp);
5233 /* This will probably eat buckets of memory for large arrays. */
5234 while (hi != 0 || lo != 0)
5236 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, se.expr);
5244 /* Create a vector of all the elements. */
5245 for (c = gfc_constructor_first (expr->value.constructor);
5246 c; c = gfc_constructor_next (c))
5250 /* Problems occur when we get something like
5251 integer :: a(lots) = (/(i, i=1, lots)/) */
5252 gfc_fatal_error ("The number of elements in the array constructor "
5253 "at %L requires an increase of the allowed %d "
5254 "upper limit. See -fmax-array-constructor "
5255 "option", &expr->where,
5256 gfc_option.flag_max_array_constructor);
5259 if (mpz_cmp_si (c->offset, 0) != 0)
5260 index = gfc_conv_mpz_to_tree (c->offset, gfc_index_integer_kind);
5264 if (mpz_cmp_si (c->repeat, 1) > 0)
5270 mpz_add (maxval, c->offset, c->repeat);
5271 mpz_sub_ui (maxval, maxval, 1);
5272 tmp2 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
5273 if (mpz_cmp_si (c->offset, 0) != 0)
5275 mpz_add_ui (maxval, c->offset, 1);
5276 tmp1 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
5279 tmp1 = gfc_conv_mpz_to_tree (c->offset, gfc_index_integer_kind);
5281 range = fold_build2 (RANGE_EXPR, gfc_array_index_type, tmp1, tmp2);
5287 gfc_init_se (&se, NULL);
5288 switch (c->expr->expr_type)
5291 gfc_conv_constant (&se, c->expr);
5294 case EXPR_STRUCTURE:
5295 gfc_conv_structure (&se, c->expr, 1);
5299 /* Catch those occasional beasts that do not simplify
5300 for one reason or another, assuming that if they are
5301 standard defying the frontend will catch them. */
5302 gfc_conv_expr (&se, c->expr);
5306 if (range == NULL_TREE)
5307 CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
5310 if (index != NULL_TREE)
5311 CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
5312 CONSTRUCTOR_APPEND_ELT (v, range, se.expr);
5318 return gfc_build_null_descriptor (type);
5324 /* Create a constructor from the list of elements. */
5325 tmp = build_constructor (type, v);
5326 TREE_CONSTANT (tmp) = 1;
5331 /* Generate code to evaluate non-constant coarray cobounds. */
5334 gfc_trans_array_cobounds (tree type, stmtblock_t * pblock,
5335 const gfc_symbol *sym)
5345 for (dim = as->rank; dim < as->rank + as->corank; dim++)
5347 /* Evaluate non-constant array bound expressions. */
5348 lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
5349 if (as->lower[dim] && !INTEGER_CST_P (lbound))
5351 gfc_init_se (&se, NULL);
5352 gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
5353 gfc_add_block_to_block (pblock, &se.pre);
5354 gfc_add_modify (pblock, lbound, se.expr);
5356 ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
5357 if (as->upper[dim] && !INTEGER_CST_P (ubound))
5359 gfc_init_se (&se, NULL);
5360 gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
5361 gfc_add_block_to_block (pblock, &se.pre);
5362 gfc_add_modify (pblock, ubound, se.expr);
5368 /* Generate code to evaluate non-constant array bounds. Sets *poffset and
5369 returns the size (in elements) of the array. */
5372 gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
5373 stmtblock_t * pblock)
5388 size = gfc_index_one_node;
5389 offset = gfc_index_zero_node;
5390 for (dim = 0; dim < as->rank; dim++)
5392 /* Evaluate non-constant array bound expressions. */
5393 lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
5394 if (as->lower[dim] && !INTEGER_CST_P (lbound))
5396 gfc_init_se (&se, NULL);
5397 gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
5398 gfc_add_block_to_block (pblock, &se.pre);
5399 gfc_add_modify (pblock, lbound, se.expr);
5401 ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
5402 if (as->upper[dim] && !INTEGER_CST_P (ubound))
5404 gfc_init_se (&se, NULL);
5405 gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
5406 gfc_add_block_to_block (pblock, &se.pre);
5407 gfc_add_modify (pblock, ubound, se.expr);
5409 /* The offset of this dimension. offset = offset - lbound * stride. */
5410 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5412 offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5415 /* The size of this dimension, and the stride of the next. */
5416 if (dim + 1 < as->rank)
5417 stride = GFC_TYPE_ARRAY_STRIDE (type, dim + 1);
5419 stride = GFC_TYPE_ARRAY_SIZE (type);
5421 if (ubound != NULL_TREE && !(stride && INTEGER_CST_P (stride)))
5423 /* Calculate stride = size * (ubound + 1 - lbound). */
5424 tmp = fold_build2_loc (input_location, MINUS_EXPR,
5425 gfc_array_index_type,
5426 gfc_index_one_node, lbound);
5427 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5428 gfc_array_index_type, ubound, tmp);
5429 tmp = fold_build2_loc (input_location, MULT_EXPR,
5430 gfc_array_index_type, size, tmp);
5432 gfc_add_modify (pblock, stride, tmp);
5434 stride = gfc_evaluate_now (tmp, pblock);
5436 /* Make sure that negative size arrays are translated
5437 to being zero size. */
5438 tmp = fold_build2_loc (input_location, GE_EXPR, boolean_type_node,
5439 stride, gfc_index_zero_node);
5440 tmp = fold_build3_loc (input_location, COND_EXPR,
5441 gfc_array_index_type, tmp,
5442 stride, gfc_index_zero_node);
5443 gfc_add_modify (pblock, stride, tmp);
5449 gfc_trans_array_cobounds (type, pblock, sym);
5450 gfc_trans_vla_type_sizes (sym, pblock);
5457 /* Generate code to initialize/allocate an array variable. */
5460 gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym,
5461 gfc_wrapped_block * block)
5465 tree tmp = NULL_TREE;
5472 gcc_assert (!(sym->attr.pointer || sym->attr.allocatable));
5474 /* Do nothing for USEd variables. */
5475 if (sym->attr.use_assoc)
5478 type = TREE_TYPE (decl);
5479 gcc_assert (GFC_ARRAY_TYPE_P (type));
5480 onstack = TREE_CODE (type) != POINTER_TYPE;
5482 gfc_init_block (&init);
5484 /* Evaluate character string length. */
5485 if (sym->ts.type == BT_CHARACTER
5486 && onstack && !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
5488 gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
5490 gfc_trans_vla_type_sizes (sym, &init);
5492 /* Emit a DECL_EXPR for this variable, which will cause the
5493 gimplifier to allocate storage, and all that good stuff. */
5494 tmp = fold_build1_loc (input_location, DECL_EXPR, TREE_TYPE (decl), decl);
5495 gfc_add_expr_to_block (&init, tmp);
5500 gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
5504 type = TREE_TYPE (type);
5506 gcc_assert (!sym->attr.use_assoc);
5507 gcc_assert (!TREE_STATIC (decl));
5508 gcc_assert (!sym->module);
5510 if (sym->ts.type == BT_CHARACTER
5511 && !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
5512 gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
5514 size = gfc_trans_array_bounds (type, sym, &offset, &init);
5516 /* Don't actually allocate space for Cray Pointees. */
5517 if (sym->attr.cray_pointee)
5519 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
5520 gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
5522 gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
5526 if (gfc_option.flag_stack_arrays)
5528 gcc_assert (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE);
5529 space = build_decl (sym->declared_at.lb->location,
5530 VAR_DECL, create_tmp_var_name ("A"),
5531 TREE_TYPE (TREE_TYPE (decl)));
5532 gfc_trans_vla_type_sizes (sym, &init);
5536 /* The size is the number of elements in the array, so multiply by the
5537 size of an element to get the total size. */
5538 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
5539 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5540 size, fold_convert (gfc_array_index_type, tmp));
5542 /* Allocate memory to hold the data. */
5543 tmp = gfc_call_malloc (&init, TREE_TYPE (decl), size);
5544 gfc_add_modify (&init, decl, tmp);
5546 /* Free the temporary. */
5547 tmp = gfc_call_free (convert (pvoid_type_node, decl));
5551 /* Set offset of the array. */
5552 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
5553 gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
5555 /* Automatic arrays should not have initializers. */
5556 gcc_assert (!sym->value);
5558 inittree = gfc_finish_block (&init);
5565 /* Don't create new scope, emit the DECL_EXPR in exactly the scope
5566 where also space is located. */
5567 gfc_init_block (&init);
5568 tmp = fold_build1_loc (input_location, DECL_EXPR,
5569 TREE_TYPE (space), space);
5570 gfc_add_expr_to_block (&init, tmp);
5571 addr = fold_build1_loc (sym->declared_at.lb->location,
5572 ADDR_EXPR, TREE_TYPE (decl), space);
5573 gfc_add_modify (&init, decl, addr);
5574 gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
5577 gfc_add_init_cleanup (block, inittree, tmp);
5581 /* Generate entry and exit code for g77 calling convention arrays. */
5584 gfc_trans_g77_array (gfc_symbol * sym, gfc_wrapped_block * block)
5594 gfc_save_backend_locus (&loc);
5595 gfc_set_backend_locus (&sym->declared_at);
5597 /* Descriptor type. */
5598 parm = sym->backend_decl;
5599 type = TREE_TYPE (parm);
5600 gcc_assert (GFC_ARRAY_TYPE_P (type));
5602 gfc_start_block (&init);
5604 if (sym->ts.type == BT_CHARACTER
5605 && TREE_CODE (sym->ts.u.cl->backend_decl) == VAR_DECL)
5606 gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
5608 /* Evaluate the bounds of the array. */
5609 gfc_trans_array_bounds (type, sym, &offset, &init);
5611 /* Set the offset. */
5612 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
5613 gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
5615 /* Set the pointer itself if we aren't using the parameter directly. */
5616 if (TREE_CODE (parm) != PARM_DECL)
5618 tmp = convert (TREE_TYPE (parm), GFC_DECL_SAVED_DESCRIPTOR (parm));
5619 gfc_add_modify (&init, parm, tmp);
5621 stmt = gfc_finish_block (&init);
5623 gfc_restore_backend_locus (&loc);
5625 /* Add the initialization code to the start of the function. */
5627 if (sym->attr.optional || sym->attr.not_always_present)
5629 tmp = gfc_conv_expr_present (sym);
5630 stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt (input_location));
5633 gfc_add_init_cleanup (block, stmt, NULL_TREE);
5637 /* Modify the descriptor of an array parameter so that it has the
5638 correct lower bound. Also move the upper bound accordingly.
5639 If the array is not packed, it will be copied into a temporary.
5640 For each dimension we set the new lower and upper bounds. Then we copy the
5641 stride and calculate the offset for this dimension. We also work out
5642 what the stride of a packed array would be, and see it the two match.
5643 If the array need repacking, we set the stride to the values we just
5644 calculated, recalculate the offset and copy the array data.
5645 Code is also added to copy the data back at the end of the function.
5649 gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc,
5650 gfc_wrapped_block * block)
5657 tree stmtInit, stmtCleanup;
5664 tree stride, stride2;
5674 /* Do nothing for pointer and allocatable arrays. */
5675 if (sym->attr.pointer || sym->attr.allocatable)
5678 if (sym->attr.dummy && gfc_is_nodesc_array (sym))
5680 gfc_trans_g77_array (sym, block);
5684 gfc_save_backend_locus (&loc);
5685 gfc_set_backend_locus (&sym->declared_at);
5687 /* Descriptor type. */
5688 type = TREE_TYPE (tmpdesc);
5689 gcc_assert (GFC_ARRAY_TYPE_P (type));
5690 dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
5691 dumdesc = build_fold_indirect_ref_loc (input_location, dumdesc);
5692 gfc_start_block (&init);
5694 if (sym->ts.type == BT_CHARACTER
5695 && TREE_CODE (sym->ts.u.cl->backend_decl) == VAR_DECL)
5696 gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
5698 checkparm = (sym->as->type == AS_EXPLICIT
5699 && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS));
5701 no_repack = !(GFC_DECL_PACKED_ARRAY (tmpdesc)
5702 || GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc));
5704 if (GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc))
5706 /* For non-constant shape arrays we only check if the first dimension
5707 is contiguous. Repacking higher dimensions wouldn't gain us
5708 anything as we still don't know the array stride. */
5709 partial = gfc_create_var (boolean_type_node, "partial");
5710 TREE_USED (partial) = 1;
5711 tmp = gfc_conv_descriptor_stride_get (dumdesc, gfc_rank_cst[0]);
5712 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, tmp,
5713 gfc_index_one_node);
5714 gfc_add_modify (&init, partial, tmp);
5717 partial = NULL_TREE;
5719 /* The naming of stmt_unpacked and stmt_packed may be counter-intuitive
5720 here, however I think it does the right thing. */
5723 /* Set the first stride. */
5724 stride = gfc_conv_descriptor_stride_get (dumdesc, gfc_rank_cst[0]);
5725 stride = gfc_evaluate_now (stride, &init);
5727 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
5728 stride, gfc_index_zero_node);
5729 tmp = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
5730 tmp, gfc_index_one_node, stride);
5731 stride = GFC_TYPE_ARRAY_STRIDE (type, 0);
5732 gfc_add_modify (&init, stride, tmp);
5734 /* Allow the user to disable array repacking. */
5735 stmt_unpacked = NULL_TREE;
5739 gcc_assert (integer_onep (GFC_TYPE_ARRAY_STRIDE (type, 0)));
5740 /* A library call to repack the array if necessary. */
5741 tmp = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
5742 stmt_unpacked = build_call_expr_loc (input_location,
5743 gfor_fndecl_in_pack, 1, tmp);
5745 stride = gfc_index_one_node;
5747 if (gfc_option.warn_array_temp)
5748 gfc_warning ("Creating array temporary at %L", &loc);
5751 /* This is for the case where the array data is used directly without
5752 calling the repack function. */
5753 if (no_repack || partial != NULL_TREE)
5754 stmt_packed = gfc_conv_descriptor_data_get (dumdesc);
5756 stmt_packed = NULL_TREE;
5758 /* Assign the data pointer. */
5759 if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
5761 /* Don't repack unknown shape arrays when the first stride is 1. */
5762 tmp = fold_build3_loc (input_location, COND_EXPR, TREE_TYPE (stmt_packed),
5763 partial, stmt_packed, stmt_unpacked);
5766 tmp = stmt_packed != NULL_TREE ? stmt_packed : stmt_unpacked;
5767 gfc_add_modify (&init, tmpdesc, fold_convert (type, tmp));
5769 offset = gfc_index_zero_node;
5770 size = gfc_index_one_node;
5772 /* Evaluate the bounds of the array. */
5773 for (n = 0; n < sym->as->rank; n++)
5775 if (checkparm || !sym->as->upper[n])
5777 /* Get the bounds of the actual parameter. */
5778 dubound = gfc_conv_descriptor_ubound_get (dumdesc, gfc_rank_cst[n]);
5779 dlbound = gfc_conv_descriptor_lbound_get (dumdesc, gfc_rank_cst[n]);
5783 dubound = NULL_TREE;
5784 dlbound = NULL_TREE;
5787 lbound = GFC_TYPE_ARRAY_LBOUND (type, n);
5788 if (!INTEGER_CST_P (lbound))
5790 gfc_init_se (&se, NULL);
5791 gfc_conv_expr_type (&se, sym->as->lower[n],
5792 gfc_array_index_type);
5793 gfc_add_block_to_block (&init, &se.pre);
5794 gfc_add_modify (&init, lbound, se.expr);
5797 ubound = GFC_TYPE_ARRAY_UBOUND (type, n);
5798 /* Set the desired upper bound. */
5799 if (sym->as->upper[n])
5801 /* We know what we want the upper bound to be. */
5802 if (!INTEGER_CST_P (ubound))
5804 gfc_init_se (&se, NULL);
5805 gfc_conv_expr_type (&se, sym->as->upper[n],
5806 gfc_array_index_type);
5807 gfc_add_block_to_block (&init, &se.pre);
5808 gfc_add_modify (&init, ubound, se.expr);
5811 /* Check the sizes match. */
5814 /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)). */
5818 temp = fold_build2_loc (input_location, MINUS_EXPR,
5819 gfc_array_index_type, ubound, lbound);
5820 temp = fold_build2_loc (input_location, PLUS_EXPR,
5821 gfc_array_index_type,
5822 gfc_index_one_node, temp);
5823 stride2 = fold_build2_loc (input_location, MINUS_EXPR,
5824 gfc_array_index_type, dubound,
5826 stride2 = fold_build2_loc (input_location, PLUS_EXPR,
5827 gfc_array_index_type,
5828 gfc_index_one_node, stride2);
5829 tmp = fold_build2_loc (input_location, NE_EXPR,
5830 gfc_array_index_type, temp, stride2);
5831 asprintf (&msg, "Dimension %d of array '%s' has extent "
5832 "%%ld instead of %%ld", n+1, sym->name);
5834 gfc_trans_runtime_check (true, false, tmp, &init, &loc, msg,
5835 fold_convert (long_integer_type_node, temp),
5836 fold_convert (long_integer_type_node, stride2));
5843 /* For assumed shape arrays move the upper bound by the same amount
5844 as the lower bound. */
5845 tmp = fold_build2_loc (input_location, MINUS_EXPR,
5846 gfc_array_index_type, dubound, dlbound);
5847 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5848 gfc_array_index_type, tmp, lbound);
5849 gfc_add_modify (&init, ubound, tmp);
5851 /* The offset of this dimension. offset = offset - lbound * stride. */
5852 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5854 offset = fold_build2_loc (input_location, MINUS_EXPR,
5855 gfc_array_index_type, offset, tmp);
5857 /* The size of this dimension, and the stride of the next. */
5858 if (n + 1 < sym->as->rank)
5860 stride = GFC_TYPE_ARRAY_STRIDE (type, n + 1);
5862 if (no_repack || partial != NULL_TREE)
5864 gfc_conv_descriptor_stride_get (dumdesc, gfc_rank_cst[n+1]);
5866 /* Figure out the stride if not a known constant. */
5867 if (!INTEGER_CST_P (stride))
5870 stmt_packed = NULL_TREE;
5873 /* Calculate stride = size * (ubound + 1 - lbound). */
5874 tmp = fold_build2_loc (input_location, MINUS_EXPR,
5875 gfc_array_index_type,
5876 gfc_index_one_node, lbound);
5877 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5878 gfc_array_index_type, ubound, tmp);
5879 size = fold_build2_loc (input_location, MULT_EXPR,
5880 gfc_array_index_type, size, tmp);
5884 /* Assign the stride. */
5885 if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
5886 tmp = fold_build3_loc (input_location, COND_EXPR,
5887 gfc_array_index_type, partial,
5888 stmt_unpacked, stmt_packed);
5890 tmp = (stmt_packed != NULL_TREE) ? stmt_packed : stmt_unpacked;
5891 gfc_add_modify (&init, stride, tmp);
5896 stride = GFC_TYPE_ARRAY_SIZE (type);
5898 if (stride && !INTEGER_CST_P (stride))
5900 /* Calculate size = stride * (ubound + 1 - lbound). */
5901 tmp = fold_build2_loc (input_location, MINUS_EXPR,
5902 gfc_array_index_type,
5903 gfc_index_one_node, lbound);
5904 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5905 gfc_array_index_type,
5907 tmp = fold_build2_loc (input_location, MULT_EXPR,
5908 gfc_array_index_type,
5909 GFC_TYPE_ARRAY_STRIDE (type, n), tmp);
5910 gfc_add_modify (&init, stride, tmp);
5915 gfc_trans_array_cobounds (type, &init, sym);
5917 /* Set the offset. */
5918 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
5919 gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
5921 gfc_trans_vla_type_sizes (sym, &init);
5923 stmtInit = gfc_finish_block (&init);
5925 /* Only do the entry/initialization code if the arg is present. */
5926 dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
5927 optional_arg = (sym->attr.optional
5928 || (sym->ns->proc_name->attr.entry_master
5929 && sym->attr.dummy));
5932 tmp = gfc_conv_expr_present (sym);
5933 stmtInit = build3_v (COND_EXPR, tmp, stmtInit,
5934 build_empty_stmt (input_location));
5939 stmtCleanup = NULL_TREE;
5942 stmtblock_t cleanup;
5943 gfc_start_block (&cleanup);
5945 if (sym->attr.intent != INTENT_IN)
5947 /* Copy the data back. */
5948 tmp = build_call_expr_loc (input_location,
5949 gfor_fndecl_in_unpack, 2, dumdesc, tmpdesc);
5950 gfc_add_expr_to_block (&cleanup, tmp);
5953 /* Free the temporary. */
5954 tmp = gfc_call_free (tmpdesc);
5955 gfc_add_expr_to_block (&cleanup, tmp);
5957 stmtCleanup = gfc_finish_block (&cleanup);
5959 /* Only do the cleanup if the array was repacked. */
5960 tmp = build_fold_indirect_ref_loc (input_location, dumdesc);
5961 tmp = gfc_conv_descriptor_data_get (tmp);
5962 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5964 stmtCleanup = build3_v (COND_EXPR, tmp, stmtCleanup,
5965 build_empty_stmt (input_location));
5969 tmp = gfc_conv_expr_present (sym);
5970 stmtCleanup = build3_v (COND_EXPR, tmp, stmtCleanup,
5971 build_empty_stmt (input_location));
5975 /* We don't need to free any memory allocated by internal_pack as it will
5976 be freed at the end of the function by pop_context. */
5977 gfc_add_init_cleanup (block, stmtInit, stmtCleanup);
5979 gfc_restore_backend_locus (&loc);
5983 /* Calculate the overall offset, including subreferences. */
5985 gfc_get_dataptr_offset (stmtblock_t *block, tree parm, tree desc, tree offset,
5986 bool subref, gfc_expr *expr)
5996 /* If offset is NULL and this is not a subreferenced array, there is
5998 if (offset == NULL_TREE)
6001 offset = gfc_index_zero_node;
6006 tmp = gfc_conv_array_data (desc);
6007 tmp = build_fold_indirect_ref_loc (input_location,
6009 tmp = gfc_build_array_ref (tmp, offset, NULL);
6011 /* Offset the data pointer for pointer assignments from arrays with
6012 subreferences; e.g. my_integer => my_type(:)%integer_component. */
6015 /* Go past the array reference. */
6016 for (ref = expr->ref; ref; ref = ref->next)
6017 if (ref->type == REF_ARRAY &&
6018 ref->u.ar.type != AR_ELEMENT)
6024 /* Calculate the offset for each subsequent subreference. */
6025 for (; ref; ref = ref->next)
6030 field = ref->u.c.component->backend_decl;
6031 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
6032 tmp = fold_build3_loc (input_location, COMPONENT_REF,
6034 tmp, field, NULL_TREE);
6038 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
6039 gfc_init_se (&start, NULL);
6040 gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
6041 gfc_add_block_to_block (block, &start.pre);
6042 tmp = gfc_build_array_ref (tmp, start.expr, NULL);
6046 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE
6047 && ref->u.ar.type == AR_ELEMENT);
6049 /* TODO - Add bounds checking. */
6050 stride = gfc_index_one_node;
6051 index = gfc_index_zero_node;
6052 for (n = 0; n < ref->u.ar.dimen; n++)
6057 /* Update the index. */
6058 gfc_init_se (&start, NULL);
6059 gfc_conv_expr_type (&start, ref->u.ar.start[n], gfc_array_index_type);
6060 itmp = gfc_evaluate_now (start.expr, block);
6061 gfc_init_se (&start, NULL);
6062 gfc_conv_expr_type (&start, ref->u.ar.as->lower[n], gfc_array_index_type);
6063 jtmp = gfc_evaluate_now (start.expr, block);
6064 itmp = fold_build2_loc (input_location, MINUS_EXPR,
6065 gfc_array_index_type, itmp, jtmp);
6066 itmp = fold_build2_loc (input_location, MULT_EXPR,
6067 gfc_array_index_type, itmp, stride);
6068 index = fold_build2_loc (input_location, PLUS_EXPR,
6069 gfc_array_index_type, itmp, index);
6070 index = gfc_evaluate_now (index, block);
6072 /* Update the stride. */
6073 gfc_init_se (&start, NULL);
6074 gfc_conv_expr_type (&start, ref->u.ar.as->upper[n], gfc_array_index_type);
6075 itmp = fold_build2_loc (input_location, MINUS_EXPR,
6076 gfc_array_index_type, start.expr,
6078 itmp = fold_build2_loc (input_location, PLUS_EXPR,
6079 gfc_array_index_type,
6080 gfc_index_one_node, itmp);
6081 stride = fold_build2_loc (input_location, MULT_EXPR,
6082 gfc_array_index_type, stride, itmp);
6083 stride = gfc_evaluate_now (stride, block);
6086 /* Apply the index to obtain the array element. */
6087 tmp = gfc_build_array_ref (tmp, index, NULL);
6097 /* Set the target data pointer. */
6098 offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
6099 gfc_conv_descriptor_data_set (block, parm, offset);
6103 /* gfc_conv_expr_descriptor needs the string length an expression
6104 so that the size of the temporary can be obtained. This is done
6105 by adding up the string lengths of all the elements in the
6106 expression. Function with non-constant expressions have their
6107 string lengths mapped onto the actual arguments using the
6108 interface mapping machinery in trans-expr.c. */
6110 get_array_charlen (gfc_expr *expr, gfc_se *se)
6112 gfc_interface_mapping mapping;
6113 gfc_formal_arglist *formal;
6114 gfc_actual_arglist *arg;
6117 if (expr->ts.u.cl->length
6118 && gfc_is_constant_expr (expr->ts.u.cl->length))
6120 if (!expr->ts.u.cl->backend_decl)
6121 gfc_conv_string_length (expr->ts.u.cl, expr, &se->pre);
6125 switch (expr->expr_type)
6128 get_array_charlen (expr->value.op.op1, se);
6130 /* For parentheses the expression ts.u.cl is identical. */
6131 if (expr->value.op.op == INTRINSIC_PARENTHESES)
6134 expr->ts.u.cl->backend_decl =
6135 gfc_create_var (gfc_charlen_type_node, "sln");
6137 if (expr->value.op.op2)
6139 get_array_charlen (expr->value.op.op2, se);
6141 gcc_assert (expr->value.op.op == INTRINSIC_CONCAT);
6143 /* Add the string lengths and assign them to the expression
6144 string length backend declaration. */
6145 gfc_add_modify (&se->pre, expr->ts.u.cl->backend_decl,
6146 fold_build2_loc (input_location, PLUS_EXPR,
6147 gfc_charlen_type_node,
6148 expr->value.op.op1->ts.u.cl->backend_decl,
6149 expr->value.op.op2->ts.u.cl->backend_decl));
6152 gfc_add_modify (&se->pre, expr->ts.u.cl->backend_decl,
6153 expr->value.op.op1->ts.u.cl->backend_decl);
6157 if (expr->value.function.esym == NULL
6158 || expr->ts.u.cl->length->expr_type == EXPR_CONSTANT)
6160 gfc_conv_string_length (expr->ts.u.cl, expr, &se->pre);
6164 /* Map expressions involving the dummy arguments onto the actual
6165 argument expressions. */
6166 gfc_init_interface_mapping (&mapping);
6167 formal = expr->symtree->n.sym->formal;
6168 arg = expr->value.function.actual;
6170 /* Set se = NULL in the calls to the interface mapping, to suppress any
6172 for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
6177 gfc_add_interface_mapping (&mapping, formal->sym, NULL, arg->expr);
6180 gfc_init_se (&tse, NULL);
6182 /* Build the expression for the character length and convert it. */
6183 gfc_apply_interface_mapping (&mapping, &tse, expr->ts.u.cl->length);
6185 gfc_add_block_to_block (&se->pre, &tse.pre);
6186 gfc_add_block_to_block (&se->post, &tse.post);
6187 tse.expr = fold_convert (gfc_charlen_type_node, tse.expr);
6188 tse.expr = fold_build2_loc (input_location, MAX_EXPR,
6189 gfc_charlen_type_node, tse.expr,
6190 build_int_cst (gfc_charlen_type_node, 0));
6191 expr->ts.u.cl->backend_decl = tse.expr;
6192 gfc_free_interface_mapping (&mapping);
6196 gfc_conv_string_length (expr->ts.u.cl, expr, &se->pre);
6202 /* Helper function to check dimensions. */
6204 transposed_dims (gfc_ss *ss)
6208 for (n = 0; n < ss->dimen; n++)
6209 if (ss->dim[n] != n)
6214 /* Convert an array for passing as an actual argument. Expressions and
6215 vector subscripts are evaluated and stored in a temporary, which is then
6216 passed. For whole arrays the descriptor is passed. For array sections
6217 a modified copy of the descriptor is passed, but using the original data.
6219 This function is also used for array pointer assignments, and there
6222 - se->want_pointer && !se->direct_byref
6223 EXPR is an actual argument. On exit, se->expr contains a
6224 pointer to the array descriptor.
6226 - !se->want_pointer && !se->direct_byref
6227 EXPR is an actual argument to an intrinsic function or the
6228 left-hand side of a pointer assignment. On exit, se->expr
6229 contains the descriptor for EXPR.
6231 - !se->want_pointer && se->direct_byref
6232 EXPR is the right-hand side of a pointer assignment and
6233 se->expr is the descriptor for the previously-evaluated
6234 left-hand side. The function creates an assignment from
6238 The se->force_tmp flag disables the non-copying descriptor optimization
6239 that is used for transpose. It may be used in cases where there is an
6240 alias between the transpose argument and another argument in the same
6244 gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
6246 gfc_ss_type ss_type;
6247 gfc_ss_info *ss_info;
6249 gfc_array_info *info;
6258 bool subref_array_target = false;
6259 gfc_expr *arg, *ss_expr;
6261 gcc_assert (ss != NULL);
6262 gcc_assert (ss != gfc_ss_terminator);
6265 ss_type = ss_info->type;
6266 ss_expr = ss_info->expr;
6268 /* Special case things we know we can pass easily. */
6269 switch (expr->expr_type)
6272 /* If we have a linear array section, we can pass it directly.
6273 Otherwise we need to copy it into a temporary. */
6275 gcc_assert (ss_type == GFC_SS_SECTION);
6276 gcc_assert (ss_expr == expr);
6277 info = &ss_info->data.array;
6279 /* Get the descriptor for the array. */
6280 gfc_conv_ss_descriptor (&se->pre, ss, 0);
6281 desc = info->descriptor;
6283 subref_array_target = se->direct_byref && is_subref_array (expr);
6284 need_tmp = gfc_ref_needs_temporary_p (expr->ref)
6285 && !subref_array_target;
6292 else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
6294 /* Create a new descriptor if the array doesn't have one. */
6297 else if (info->ref->u.ar.type == AR_FULL)
6299 else if (se->direct_byref)
6302 full = gfc_full_array_ref_p (info->ref, NULL);
6304 if (full && !transposed_dims (ss))
6306 if (se->direct_byref && !se->byref_noassign)
6308 /* Copy the descriptor for pointer assignments. */
6309 gfc_add_modify (&se->pre, se->expr, desc);
6311 /* Add any offsets from subreferences. */
6312 gfc_get_dataptr_offset (&se->pre, se->expr, desc, NULL_TREE,
6313 subref_array_target, expr);
6315 else if (se->want_pointer)
6317 /* We pass full arrays directly. This means that pointers and
6318 allocatable arrays should also work. */
6319 se->expr = gfc_build_addr_expr (NULL_TREE, desc);
6326 if (expr->ts.type == BT_CHARACTER)
6327 se->string_length = gfc_get_expr_charlen (expr);
6335 /* We don't need to copy data in some cases. */
6336 arg = gfc_get_noncopying_intrinsic_argument (expr);
6339 /* This is a call to transpose... */
6340 gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
6341 /* ... which has already been handled by the scalarizer, so
6342 that we just need to get its argument's descriptor. */
6343 gfc_conv_expr_descriptor (se, expr->value.function.actual->expr, ss);
6347 /* A transformational function return value will be a temporary
6348 array descriptor. We still need to go through the scalarizer
6349 to create the descriptor. Elemental functions ar handled as
6350 arbitrary expressions, i.e. copy to a temporary. */
6352 if (se->direct_byref)
6354 gcc_assert (ss_type == GFC_SS_FUNCTION && ss_expr == expr);
6356 /* For pointer assignments pass the descriptor directly. */
6360 gcc_assert (se->ss == ss);
6361 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
6362 gfc_conv_expr (se, expr);
6366 if (ss_expr != expr || ss_type != GFC_SS_FUNCTION)
6368 if (ss_expr != expr)
6369 /* Elemental function. */
6370 gcc_assert ((expr->value.function.esym != NULL
6371 && expr->value.function.esym->attr.elemental)
6372 || (expr->value.function.isym != NULL
6373 && expr->value.function.isym->elemental)
6374 || gfc_inline_intrinsic_function_p (expr));
6376 gcc_assert (ss_type == GFC_SS_INTRINSIC);
6379 if (expr->ts.type == BT_CHARACTER
6380 && expr->ts.u.cl->length->expr_type != EXPR_CONSTANT)
6381 get_array_charlen (expr, se);
6387 /* Transformational function. */
6388 info = &ss_info->data.array;
6394 /* Constant array constructors don't need a temporary. */
6395 if (ss_type == GFC_SS_CONSTRUCTOR
6396 && expr->ts.type != BT_CHARACTER
6397 && gfc_constant_array_constructor_p (expr->value.constructor))
6400 info = &ss_info->data.array;
6410 /* Something complicated. Copy it into a temporary. */
6416 /* If we are creating a temporary, we don't need to bother about aliases
6421 gfc_init_loopinfo (&loop);
6423 /* Associate the SS with the loop. */
6424 gfc_add_ss_to_loop (&loop, ss);
6426 /* Tell the scalarizer not to bother creating loop variables, etc. */
6428 loop.array_parameter = 1;
6430 /* The right-hand side of a pointer assignment mustn't use a temporary. */
6431 gcc_assert (!se->direct_byref);
6433 /* Setup the scalarizing loops and bounds. */
6434 gfc_conv_ss_startstride (&loop);
6438 if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
6439 get_array_charlen (expr, se);
6441 /* Tell the scalarizer to make a temporary. */
6442 loop.temp_ss = gfc_get_temp_ss (gfc_typenode_for_spec (&expr->ts),
6443 ((expr->ts.type == BT_CHARACTER)
6444 ? expr->ts.u.cl->backend_decl
6448 se->string_length = loop.temp_ss->info->string_length;
6449 gcc_assert (loop.temp_ss->dimen == loop.dimen);
6450 gfc_add_ss_to_loop (&loop, loop.temp_ss);
6453 gfc_conv_loop_setup (&loop, & expr->where);
6457 /* Copy into a temporary and pass that. We don't need to copy the data
6458 back because expressions and vector subscripts must be INTENT_IN. */
6459 /* TODO: Optimize passing function return values. */
6463 /* Start the copying loops. */
6464 gfc_mark_ss_chain_used (loop.temp_ss, 1);
6465 gfc_mark_ss_chain_used (ss, 1);
6466 gfc_start_scalarized_body (&loop, &block);
6468 /* Copy each data element. */
6469 gfc_init_se (&lse, NULL);
6470 gfc_copy_loopinfo_to_se (&lse, &loop);
6471 gfc_init_se (&rse, NULL);
6472 gfc_copy_loopinfo_to_se (&rse, &loop);
6474 lse.ss = loop.temp_ss;
6477 gfc_conv_scalarized_array_ref (&lse, NULL);
6478 if (expr->ts.type == BT_CHARACTER)
6480 gfc_conv_expr (&rse, expr);
6481 if (POINTER_TYPE_P (TREE_TYPE (rse.expr)))
6482 rse.expr = build_fold_indirect_ref_loc (input_location,
6486 gfc_conv_expr_val (&rse, expr);
6488 gfc_add_block_to_block (&block, &rse.pre);
6489 gfc_add_block_to_block (&block, &lse.pre);
6491 lse.string_length = rse.string_length;
6492 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true,
6493 expr->expr_type == EXPR_VARIABLE
6494 || expr->expr_type == EXPR_ARRAY, true);
6495 gfc_add_expr_to_block (&block, tmp);
6497 /* Finish the copying loops. */
6498 gfc_trans_scalarizing_loops (&loop, &block);
6500 desc = loop.temp_ss->info->data.array.descriptor;
6502 else if (expr->expr_type == EXPR_FUNCTION && !transposed_dims (ss))
6504 desc = info->descriptor;
6505 se->string_length = ss_info->string_length;
6509 /* We pass sections without copying to a temporary. Make a new
6510 descriptor and point it at the section we want. The loop variable
6511 limits will be the limits of the section.
6512 A function may decide to repack the array to speed up access, but
6513 we're not bothered about that here. */
6514 int dim, ndim, codim;
6522 ndim = info->ref ? info->ref->u.ar.dimen : ss->dimen;
6524 if (se->want_coarray)
6526 gfc_array_ref *ar = &info->ref->u.ar;
6528 codim = gfc_get_corank (expr);
6529 for (n = 0; n < codim - 1; n++)
6531 /* Make sure we are not lost somehow. */
6532 gcc_assert (ar->dimen_type[n + ndim] == DIMEN_THIS_IMAGE);
6534 /* Make sure the call to gfc_conv_section_startstride won't
6535 generate unnecessary code to calculate stride. */
6536 gcc_assert (ar->stride[n + ndim] == NULL);
6538 gfc_conv_section_startstride (&loop, ss, n + ndim);
6539 loop.from[n + loop.dimen] = info->start[n + ndim];
6540 loop.to[n + loop.dimen] = info->end[n + ndim];
6543 gcc_assert (n == codim - 1);
6544 evaluate_bound (&loop.pre, info->start, ar->start,
6545 info->descriptor, n + ndim, true);
6546 loop.from[n + loop.dimen] = info->start[n + ndim];
6551 /* Set the string_length for a character array. */
6552 if (expr->ts.type == BT_CHARACTER)
6553 se->string_length = gfc_get_expr_charlen (expr);
6555 desc = info->descriptor;
6556 if (se->direct_byref && !se->byref_noassign)
6558 /* For pointer assignments we fill in the destination. */
6560 parmtype = TREE_TYPE (parm);
6564 /* Otherwise make a new one. */
6565 parmtype = gfc_get_element_type (TREE_TYPE (desc));
6566 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, codim,
6567 loop.from, loop.to, 0,
6568 GFC_ARRAY_UNKNOWN, false);
6569 parm = gfc_create_var (parmtype, "parm");
6572 offset = gfc_index_zero_node;
6574 /* The following can be somewhat confusing. We have two
6575 descriptors, a new one and the original array.
6576 {parm, parmtype, dim} refer to the new one.
6577 {desc, type, n, loop} refer to the original, which maybe
6578 a descriptorless array.
6579 The bounds of the scalarization are the bounds of the section.
6580 We don't have to worry about numeric overflows when calculating
6581 the offsets because all elements are within the array data. */
6583 /* Set the dtype. */
6584 tmp = gfc_conv_descriptor_dtype (parm);
6585 gfc_add_modify (&loop.pre, tmp, gfc_get_dtype (parmtype));
6587 /* Set offset for assignments to pointer only to zero if it is not
6589 if (se->direct_byref
6590 && info->ref && info->ref->u.ar.type != AR_FULL)
6591 base = gfc_index_zero_node;
6592 else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
6593 base = gfc_evaluate_now (gfc_conv_array_offset (desc), &loop.pre);
6597 for (n = 0; n < ndim; n++)
6599 stride = gfc_conv_array_stride (desc, n);
6601 /* Work out the offset. */
6603 && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
6605 gcc_assert (info->subscript[n]
6606 && info->subscript[n]->info->type == GFC_SS_SCALAR);
6607 start = info->subscript[n]->info->data.scalar.value;
6611 /* Evaluate and remember the start of the section. */
6612 start = info->start[n];
6613 stride = gfc_evaluate_now (stride, &loop.pre);
6616 tmp = gfc_conv_array_lbound (desc, n);
6617 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (tmp),
6619 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
6621 offset = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
6625 && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
6627 /* For elemental dimensions, we only need the offset. */
6631 /* Vector subscripts need copying and are handled elsewhere. */
6633 gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_RANGE);
6635 /* look for the corresponding scalarizer dimension: dim. */
6636 for (dim = 0; dim < ndim; dim++)
6637 if (ss->dim[dim] == n)
6640 /* loop exited early: the DIM being looked for has been found. */
6641 gcc_assert (dim < ndim);
6643 /* Set the new lower bound. */
6644 from = loop.from[dim];
6647 /* If we have an array section or are assigning make sure that
6648 the lower bound is 1. References to the full
6649 array should otherwise keep the original bounds. */
6651 || info->ref->u.ar.type != AR_FULL)
6652 && !integer_onep (from))
6654 tmp = fold_build2_loc (input_location, MINUS_EXPR,
6655 gfc_array_index_type, gfc_index_one_node,
6657 to = fold_build2_loc (input_location, PLUS_EXPR,
6658 gfc_array_index_type, to, tmp);
6659 from = gfc_index_one_node;
6661 gfc_conv_descriptor_lbound_set (&loop.pre, parm,
6662 gfc_rank_cst[dim], from);
6664 /* Set the new upper bound. */
6665 gfc_conv_descriptor_ubound_set (&loop.pre, parm,
6666 gfc_rank_cst[dim], to);
6668 /* Multiply the stride by the section stride to get the
6670 stride = fold_build2_loc (input_location, MULT_EXPR,
6671 gfc_array_index_type,
6672 stride, info->stride[n]);
6674 if (se->direct_byref
6676 && info->ref->u.ar.type != AR_FULL)
6678 base = fold_build2_loc (input_location, MINUS_EXPR,
6679 TREE_TYPE (base), base, stride);
6681 else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
6683 tmp = gfc_conv_array_lbound (desc, n);
6684 tmp = fold_build2_loc (input_location, MINUS_EXPR,
6685 TREE_TYPE (base), tmp, loop.from[dim]);
6686 tmp = fold_build2_loc (input_location, MULT_EXPR,
6687 TREE_TYPE (base), tmp,
6688 gfc_conv_array_stride (desc, n));
6689 base = fold_build2_loc (input_location, PLUS_EXPR,
6690 TREE_TYPE (base), tmp, base);
6693 /* Store the new stride. */
6694 gfc_conv_descriptor_stride_set (&loop.pre, parm,
6695 gfc_rank_cst[dim], stride);
6698 for (n = loop.dimen; n < loop.dimen + codim; n++)
6700 from = loop.from[n];
6702 gfc_conv_descriptor_lbound_set (&loop.pre, parm,
6703 gfc_rank_cst[n], from);
6704 if (n < loop.dimen + codim - 1)
6705 gfc_conv_descriptor_ubound_set (&loop.pre, parm,
6706 gfc_rank_cst[n], to);
6709 if (se->data_not_needed)
6710 gfc_conv_descriptor_data_set (&loop.pre, parm,
6711 gfc_index_zero_node);
6713 /* Point the data pointer at the 1st element in the section. */
6714 gfc_get_dataptr_offset (&loop.pre, parm, desc, offset,
6715 subref_array_target, expr);
6717 if ((se->direct_byref || GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
6718 && !se->data_not_needed)
6720 /* Set the offset. */
6721 gfc_conv_descriptor_offset_set (&loop.pre, parm, base);
6725 /* Only the callee knows what the correct offset it, so just set
6727 gfc_conv_descriptor_offset_set (&loop.pre, parm, gfc_index_zero_node);
6732 if (!se->direct_byref || se->byref_noassign)
6734 /* Get a pointer to the new descriptor. */
6735 if (se->want_pointer)
6736 se->expr = gfc_build_addr_expr (NULL_TREE, desc);
6741 gfc_add_block_to_block (&se->pre, &loop.pre);
6742 gfc_add_block_to_block (&se->post, &loop.post);
6744 /* Cleanup the scalarizer. */
6745 gfc_cleanup_loop (&loop);
6748 /* Helper function for gfc_conv_array_parameter if array size needs to be
6752 array_parameter_size (tree desc, gfc_expr *expr, tree *size)
6755 if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
6756 *size = GFC_TYPE_ARRAY_SIZE (TREE_TYPE (desc));
6757 else if (expr->rank > 1)
6758 *size = build_call_expr_loc (input_location,
6759 gfor_fndecl_size0, 1,
6760 gfc_build_addr_expr (NULL, desc));
6763 tree ubound = gfc_conv_descriptor_ubound_get (desc, gfc_index_zero_node);
6764 tree lbound = gfc_conv_descriptor_lbound_get (desc, gfc_index_zero_node);
6766 *size = fold_build2_loc (input_location, MINUS_EXPR,
6767 gfc_array_index_type, ubound, lbound);
6768 *size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
6769 *size, gfc_index_one_node);
6770 *size = fold_build2_loc (input_location, MAX_EXPR, gfc_array_index_type,
6771 *size, gfc_index_zero_node);
6773 elem = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
6774 *size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
6775 *size, fold_convert (gfc_array_index_type, elem));
6778 /* Convert an array for passing as an actual parameter. */
6779 /* TODO: Optimize passing g77 arrays. */
6782 gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, bool g77,
6783 const gfc_symbol *fsym, const char *proc_name,
6788 tree tmp = NULL_TREE;
6790 tree parent = DECL_CONTEXT (current_function_decl);
6791 bool full_array_var;
6792 bool this_array_result;
6795 bool array_constructor;
6796 bool good_allocatable;
6797 bool ultimate_ptr_comp;
6798 bool ultimate_alloc_comp;
6803 ultimate_ptr_comp = false;
6804 ultimate_alloc_comp = false;
6806 for (ref = expr->ref; ref; ref = ref->next)
6808 if (ref->next == NULL)
6811 if (ref->type == REF_COMPONENT)
6813 ultimate_ptr_comp = ref->u.c.component->attr.pointer;
6814 ultimate_alloc_comp = ref->u.c.component->attr.allocatable;
6818 full_array_var = false;
6821 if (expr->expr_type == EXPR_VARIABLE && ref && !ultimate_ptr_comp)
6822 full_array_var = gfc_full_array_ref_p (ref, &contiguous);
6824 sym = full_array_var ? expr->symtree->n.sym : NULL;
6826 /* The symbol should have an array specification. */
6827 gcc_assert (!sym || sym->as || ref->u.ar.as);
6829 if (expr->expr_type == EXPR_ARRAY && expr->ts.type == BT_CHARACTER)
6831 get_array_ctor_strlen (&se->pre, expr->value.constructor, &tmp);
6832 expr->ts.u.cl->backend_decl = tmp;
6833 se->string_length = tmp;
6836 /* Is this the result of the enclosing procedure? */
6837 this_array_result = (full_array_var && sym->attr.flavor == FL_PROCEDURE);
6838 if (this_array_result
6839 && (sym->backend_decl != current_function_decl)
6840 && (sym->backend_decl != parent))
6841 this_array_result = false;
6843 /* Passing address of the array if it is not pointer or assumed-shape. */
6844 if (full_array_var && g77 && !this_array_result)
6846 tmp = gfc_get_symbol_decl (sym);
6848 if (sym->ts.type == BT_CHARACTER)
6849 se->string_length = sym->ts.u.cl->backend_decl;
6851 if (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS)
6853 gfc_conv_expr_descriptor (se, expr, ss);
6854 se->expr = gfc_conv_array_data (se->expr);
6858 if (!sym->attr.pointer
6860 && sym->as->type != AS_ASSUMED_SHAPE
6861 && !sym->attr.allocatable)
6863 /* Some variables are declared directly, others are declared as
6864 pointers and allocated on the heap. */
6865 if (sym->attr.dummy || POINTER_TYPE_P (TREE_TYPE (tmp)))
6868 se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
6870 array_parameter_size (tmp, expr, size);
6874 if (sym->attr.allocatable)
6876 if (sym->attr.dummy || sym->attr.result)
6878 gfc_conv_expr_descriptor (se, expr, ss);
6882 array_parameter_size (tmp, expr, size);
6883 se->expr = gfc_conv_array_data (tmp);
6888 /* A convenient reduction in scope. */
6889 contiguous = g77 && !this_array_result && contiguous;
6891 /* There is no need to pack and unpack the array, if it is contiguous
6892 and not a deferred- or assumed-shape array, or if it is simply
6894 no_pack = ((sym && sym->as
6895 && !sym->attr.pointer
6896 && sym->as->type != AS_DEFERRED
6897 && sym->as->type != AS_ASSUMED_SHAPE)
6899 (ref && ref->u.ar.as
6900 && ref->u.ar.as->type != AS_DEFERRED
6901 && ref->u.ar.as->type != AS_ASSUMED_SHAPE)
6903 gfc_is_simply_contiguous (expr, false));
6905 no_pack = contiguous && no_pack;
6907 /* Array constructors are always contiguous and do not need packing. */
6908 array_constructor = g77 && !this_array_result && expr->expr_type == EXPR_ARRAY;
6910 /* Same is true of contiguous sections from allocatable variables. */
6911 good_allocatable = contiguous
6913 && expr->symtree->n.sym->attr.allocatable;
6915 /* Or ultimate allocatable components. */
6916 ultimate_alloc_comp = contiguous && ultimate_alloc_comp;
6918 if (no_pack || array_constructor || good_allocatable || ultimate_alloc_comp)
6920 gfc_conv_expr_descriptor (se, expr, ss);
6921 if (expr->ts.type == BT_CHARACTER)
6922 se->string_length = expr->ts.u.cl->backend_decl;
6924 array_parameter_size (se->expr, expr, size);
6925 se->expr = gfc_conv_array_data (se->expr);
6929 if (this_array_result)
6931 /* Result of the enclosing function. */
6932 gfc_conv_expr_descriptor (se, expr, ss);
6934 array_parameter_size (se->expr, expr, size);
6935 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
6937 if (g77 && TREE_TYPE (TREE_TYPE (se->expr)) != NULL_TREE
6938 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
6939 se->expr = gfc_conv_array_data (build_fold_indirect_ref_loc (input_location,
6946 /* Every other type of array. */
6947 se->want_pointer = 1;
6948 gfc_conv_expr_descriptor (se, expr, ss);
6950 array_parameter_size (build_fold_indirect_ref_loc (input_location,
6955 /* Deallocate the allocatable components of structures that are
6957 if ((expr->ts.type == BT_DERIVED || expr->ts.type == BT_CLASS)
6958 && expr->ts.u.derived->attr.alloc_comp
6959 && expr->expr_type != EXPR_VARIABLE)
6961 tmp = build_fold_indirect_ref_loc (input_location, se->expr);
6962 tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp, expr->rank);
6964 /* The components shall be deallocated before their containing entity. */
6965 gfc_prepend_expr_to_block (&se->post, tmp);
6968 if (g77 || (fsym && fsym->attr.contiguous
6969 && !gfc_is_simply_contiguous (expr, false)))
6971 tree origptr = NULL_TREE;
6975 /* For contiguous arrays, save the original value of the descriptor. */
6978 origptr = gfc_create_var (pvoid_type_node, "origptr");
6979 tmp = build_fold_indirect_ref_loc (input_location, desc);
6980 tmp = gfc_conv_array_data (tmp);
6981 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6982 TREE_TYPE (origptr), origptr,
6983 fold_convert (TREE_TYPE (origptr), tmp));
6984 gfc_add_expr_to_block (&se->pre, tmp);
6987 /* Repack the array. */
6988 if (gfc_option.warn_array_temp)
6991 gfc_warning ("Creating array temporary at %L for argument '%s'",
6992 &expr->where, fsym->name);
6994 gfc_warning ("Creating array temporary at %L", &expr->where);
6997 ptr = build_call_expr_loc (input_location,
6998 gfor_fndecl_in_pack, 1, desc);
7000 if (fsym && fsym->attr.optional && sym && sym->attr.optional)
7002 tmp = gfc_conv_expr_present (sym);
7003 ptr = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
7004 tmp, fold_convert (TREE_TYPE (se->expr), ptr),
7005 fold_convert (TREE_TYPE (se->expr), null_pointer_node));
7008 ptr = gfc_evaluate_now (ptr, &se->pre);
7010 /* Use the packed data for the actual argument, except for contiguous arrays,
7011 where the descriptor's data component is set. */
7016 tmp = build_fold_indirect_ref_loc (input_location, desc);
7017 gfc_conv_descriptor_data_set (&se->pre, tmp, ptr);
7020 if (gfc_option.rtcheck & GFC_RTCHECK_ARRAY_TEMPS)
7024 if (fsym && proc_name)
7025 asprintf (&msg, "An array temporary was created for argument "
7026 "'%s' of procedure '%s'", fsym->name, proc_name);
7028 asprintf (&msg, "An array temporary was created");
7030 tmp = build_fold_indirect_ref_loc (input_location,
7032 tmp = gfc_conv_array_data (tmp);
7033 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7034 fold_convert (TREE_TYPE (tmp), ptr), tmp);
7036 if (fsym && fsym->attr.optional && sym && sym->attr.optional)
7037 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
7039 gfc_conv_expr_present (sym), tmp);
7041 gfc_trans_runtime_check (false, true, tmp, &se->pre,
7046 gfc_start_block (&block);
7048 /* Copy the data back. */
7049 if (fsym == NULL || fsym->attr.intent != INTENT_IN)
7051 tmp = build_call_expr_loc (input_location,
7052 gfor_fndecl_in_unpack, 2, desc, ptr);
7053 gfc_add_expr_to_block (&block, tmp);
7056 /* Free the temporary. */
7057 tmp = gfc_call_free (convert (pvoid_type_node, ptr));
7058 gfc_add_expr_to_block (&block, tmp);
7060 stmt = gfc_finish_block (&block);
7062 gfc_init_block (&block);
7063 /* Only if it was repacked. This code needs to be executed before the
7064 loop cleanup code. */
7065 tmp = build_fold_indirect_ref_loc (input_location,
7067 tmp = gfc_conv_array_data (tmp);
7068 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7069 fold_convert (TREE_TYPE (tmp), ptr), tmp);
7071 if (fsym && fsym->attr.optional && sym && sym->attr.optional)
7072 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
7074 gfc_conv_expr_present (sym), tmp);
7076 tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt (input_location));
7078 gfc_add_expr_to_block (&block, tmp);
7079 gfc_add_block_to_block (&block, &se->post);
7081 gfc_init_block (&se->post);
7083 /* Reset the descriptor pointer. */
7086 tmp = build_fold_indirect_ref_loc (input_location, desc);
7087 gfc_conv_descriptor_data_set (&se->post, tmp, origptr);
7090 gfc_add_block_to_block (&se->post, &block);
7095 /* Generate code to deallocate an array, if it is allocated. */
7098 gfc_trans_dealloc_allocated (tree descriptor, bool coarray)
7104 gfc_start_block (&block);
7106 var = gfc_conv_descriptor_data_get (descriptor);
7109 /* Call array_deallocate with an int * present in the second argument.
7110 Although it is ignored here, it's presence ensures that arrays that
7111 are already deallocated are ignored. */
7112 tmp = gfc_deallocate_with_status (coarray ? descriptor : var, NULL_TREE,
7113 NULL_TREE, NULL_TREE, NULL_TREE, true,
7115 gfc_add_expr_to_block (&block, tmp);
7117 /* Zero the data pointer. */
7118 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
7119 var, build_int_cst (TREE_TYPE (var), 0));
7120 gfc_add_expr_to_block (&block, tmp);
7122 return gfc_finish_block (&block);
7126 /* This helper function calculates the size in words of a full array. */
7129 get_full_array_size (stmtblock_t *block, tree decl, int rank)
7134 idx = gfc_rank_cst[rank - 1];
7135 nelems = gfc_conv_descriptor_ubound_get (decl, idx);
7136 tmp = gfc_conv_descriptor_lbound_get (decl, idx);
7137 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
7139 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
7140 tmp, gfc_index_one_node);
7141 tmp = gfc_evaluate_now (tmp, block);
7143 nelems = gfc_conv_descriptor_stride_get (decl, idx);
7144 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
7146 return gfc_evaluate_now (tmp, block);
7150 /* Allocate dest to the same size as src, and copy src -> dest.
7151 If no_malloc is set, only the copy is done. */
7154 duplicate_allocatable (tree dest, tree src, tree type, int rank,
7164 /* If the source is null, set the destination to null. Then,
7165 allocate memory to the destination. */
7166 gfc_init_block (&block);
7170 tmp = null_pointer_node;
7171 tmp = fold_build2_loc (input_location, MODIFY_EXPR, type, dest, tmp);
7172 gfc_add_expr_to_block (&block, tmp);
7173 null_data = gfc_finish_block (&block);
7175 gfc_init_block (&block);
7176 size = TYPE_SIZE_UNIT (TREE_TYPE (type));
7179 tmp = gfc_call_malloc (&block, type, size);
7180 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
7181 dest, fold_convert (type, tmp));
7182 gfc_add_expr_to_block (&block, tmp);
7185 tmp = builtin_decl_explicit (BUILT_IN_MEMCPY);
7186 tmp = build_call_expr_loc (input_location, tmp, 3,
7191 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
7192 null_data = gfc_finish_block (&block);
7194 gfc_init_block (&block);
7195 nelems = get_full_array_size (&block, src, rank);
7196 tmp = fold_convert (gfc_array_index_type,
7197 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
7198 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
7202 tmp = TREE_TYPE (gfc_conv_descriptor_data_get (src));
7203 tmp = gfc_call_malloc (&block, tmp, size);
7204 gfc_conv_descriptor_data_set (&block, dest, tmp);
7207 /* We know the temporary and the value will be the same length,
7208 so can use memcpy. */
7209 tmp = builtin_decl_explicit (BUILT_IN_MEMCPY);
7210 tmp = build_call_expr_loc (input_location,
7211 tmp, 3, gfc_conv_descriptor_data_get (dest),
7212 gfc_conv_descriptor_data_get (src), size);
7215 gfc_add_expr_to_block (&block, tmp);
7216 tmp = gfc_finish_block (&block);
7218 /* Null the destination if the source is null; otherwise do
7219 the allocate and copy. */
7223 null_cond = gfc_conv_descriptor_data_get (src);
7225 null_cond = convert (pvoid_type_node, null_cond);
7226 null_cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7227 null_cond, null_pointer_node);
7228 return build3_v (COND_EXPR, null_cond, tmp, null_data);
7232 /* Allocate dest to the same size as src, and copy data src -> dest. */
7235 gfc_duplicate_allocatable (tree dest, tree src, tree type, int rank)
7237 return duplicate_allocatable (dest, src, type, rank, false);
7241 /* Copy data src -> dest. */
7244 gfc_copy_allocatable_data (tree dest, tree src, tree type, int rank)
7246 return duplicate_allocatable (dest, src, type, rank, true);
7250 /* Recursively traverse an object of derived type, generating code to
7251 deallocate, nullify or copy allocatable components. This is the work horse
7252 function for the functions named in this enum. */
7254 enum {DEALLOCATE_ALLOC_COMP = 1, NULLIFY_ALLOC_COMP, COPY_ALLOC_COMP,
7255 COPY_ONLY_ALLOC_COMP};
7258 structure_alloc_comps (gfc_symbol * der_type, tree decl,
7259 tree dest, int rank, int purpose)
7263 stmtblock_t fnblock;
7264 stmtblock_t loopbody;
7265 stmtblock_t tmpblock;
7276 tree null_cond = NULL_TREE;
7277 bool called_dealloc_with_status;
7279 gfc_init_block (&fnblock);
7281 decl_type = TREE_TYPE (decl);
7283 if ((POINTER_TYPE_P (decl_type) && rank != 0)
7284 || (TREE_CODE (decl_type) == REFERENCE_TYPE && rank == 0))
7286 decl = build_fold_indirect_ref_loc (input_location,
7289 /* Just in case in gets dereferenced. */
7290 decl_type = TREE_TYPE (decl);
7292 /* If this an array of derived types with allocatable components
7293 build a loop and recursively call this function. */
7294 if (TREE_CODE (decl_type) == ARRAY_TYPE
7295 || GFC_DESCRIPTOR_TYPE_P (decl_type))
7297 tmp = gfc_conv_array_data (decl);
7298 var = build_fold_indirect_ref_loc (input_location,
7301 /* Get the number of elements - 1 and set the counter. */
7302 if (GFC_DESCRIPTOR_TYPE_P (decl_type))
7304 /* Use the descriptor for an allocatable array. Since this
7305 is a full array reference, we only need the descriptor
7306 information from dimension = rank. */
7307 tmp = get_full_array_size (&fnblock, decl, rank);
7308 tmp = fold_build2_loc (input_location, MINUS_EXPR,
7309 gfc_array_index_type, tmp,
7310 gfc_index_one_node);
7312 null_cond = gfc_conv_descriptor_data_get (decl);
7313 null_cond = fold_build2_loc (input_location, NE_EXPR,
7314 boolean_type_node, null_cond,
7315 build_int_cst (TREE_TYPE (null_cond), 0));
7319 /* Otherwise use the TYPE_DOMAIN information. */
7320 tmp = array_type_nelts (decl_type);
7321 tmp = fold_convert (gfc_array_index_type, tmp);
7324 /* Remember that this is, in fact, the no. of elements - 1. */
7325 nelems = gfc_evaluate_now (tmp, &fnblock);
7326 index = gfc_create_var (gfc_array_index_type, "S");
7328 /* Build the body of the loop. */
7329 gfc_init_block (&loopbody);
7331 vref = gfc_build_array_ref (var, index, NULL);
7333 if (purpose == COPY_ALLOC_COMP)
7335 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (dest)))
7337 tmp = gfc_duplicate_allocatable (dest, decl, decl_type, rank);
7338 gfc_add_expr_to_block (&fnblock, tmp);
7340 tmp = build_fold_indirect_ref_loc (input_location,
7341 gfc_conv_array_data (dest));
7342 dref = gfc_build_array_ref (tmp, index, NULL);
7343 tmp = structure_alloc_comps (der_type, vref, dref, rank, purpose);
7345 else if (purpose == COPY_ONLY_ALLOC_COMP)
7347 tmp = build_fold_indirect_ref_loc (input_location,
7348 gfc_conv_array_data (dest));
7349 dref = gfc_build_array_ref (tmp, index, NULL);
7350 tmp = structure_alloc_comps (der_type, vref, dref, rank,
7354 tmp = structure_alloc_comps (der_type, vref, NULL_TREE, rank, purpose);
7356 gfc_add_expr_to_block (&loopbody, tmp);
7358 /* Build the loop and return. */
7359 gfc_init_loopinfo (&loop);
7361 loop.from[0] = gfc_index_zero_node;
7362 loop.loopvar[0] = index;
7363 loop.to[0] = nelems;
7364 gfc_trans_scalarizing_loops (&loop, &loopbody);
7365 gfc_add_block_to_block (&fnblock, &loop.pre);
7367 tmp = gfc_finish_block (&fnblock);
7368 if (null_cond != NULL_TREE)
7369 tmp = build3_v (COND_EXPR, null_cond, tmp,
7370 build_empty_stmt (input_location));
7375 /* Otherwise, act on the components or recursively call self to
7376 act on a chain of components. */
7377 for (c = der_type->components; c; c = c->next)
7379 bool cmp_has_alloc_comps = (c->ts.type == BT_DERIVED
7380 || c->ts.type == BT_CLASS)
7381 && c->ts.u.derived->attr.alloc_comp;
7382 cdecl = c->backend_decl;
7383 ctype = TREE_TYPE (cdecl);
7387 case DEALLOCATE_ALLOC_COMP:
7389 /* gfc_deallocate_scalar_with_status calls gfc_deallocate_alloc_comp
7390 (ie. this function) so generate all the calls and suppress the
7391 recursion from here, if necessary. */
7392 called_dealloc_with_status = false;
7393 gfc_init_block (&tmpblock);
7395 if (c->attr.allocatable
7396 && (c->attr.dimension || c->attr.codimension))
7398 comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
7399 decl, cdecl, NULL_TREE);
7400 tmp = gfc_trans_dealloc_allocated (comp, c->attr.codimension);
7401 gfc_add_expr_to_block (&tmpblock, tmp);
7403 else if (c->attr.allocatable)
7405 /* Allocatable scalar components. */
7406 comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
7407 decl, cdecl, NULL_TREE);
7409 tmp = gfc_deallocate_scalar_with_status (comp, NULL, true, NULL,
7411 gfc_add_expr_to_block (&tmpblock, tmp);
7412 called_dealloc_with_status = true;
7414 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
7415 void_type_node, comp,
7416 build_int_cst (TREE_TYPE (comp), 0));
7417 gfc_add_expr_to_block (&tmpblock, tmp);
7419 else if (c->ts.type == BT_CLASS && CLASS_DATA (c)->attr.allocatable)
7421 /* Allocatable CLASS components. */
7422 comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
7423 decl, cdecl, NULL_TREE);
7425 /* Add reference to '_data' component. */
7426 tmp = CLASS_DATA (c)->backend_decl;
7427 comp = fold_build3_loc (input_location, COMPONENT_REF,
7428 TREE_TYPE (tmp), comp, tmp, NULL_TREE);
7430 if (GFC_DESCRIPTOR_TYPE_P(TREE_TYPE (comp)))
7431 tmp = gfc_trans_dealloc_allocated (comp,
7432 CLASS_DATA (c)->attr.codimension);
7435 tmp = gfc_deallocate_scalar_with_status (comp, NULL, true, NULL,
7436 CLASS_DATA (c)->ts);
7437 gfc_add_expr_to_block (&tmpblock, tmp);
7438 called_dealloc_with_status = true;
7440 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
7441 void_type_node, comp,
7442 build_int_cst (TREE_TYPE (comp), 0));
7444 gfc_add_expr_to_block (&tmpblock, tmp);
7447 if (cmp_has_alloc_comps
7449 && !called_dealloc_with_status)
7451 /* Do not deallocate the components of ultimate pointer
7452 components or iteratively call self if call has been made
7453 to gfc_trans_dealloc_allocated */
7454 comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
7455 decl, cdecl, NULL_TREE);
7456 rank = c->as ? c->as->rank : 0;
7457 tmp = structure_alloc_comps (c->ts.u.derived, comp, NULL_TREE,
7459 gfc_add_expr_to_block (&fnblock, tmp);
7462 /* Now add the deallocation of this component. */
7463 gfc_add_block_to_block (&fnblock, &tmpblock);
7466 case NULLIFY_ALLOC_COMP:
7467 if (c->attr.pointer)
7469 else if (c->attr.allocatable
7470 && (c->attr.dimension|| c->attr.codimension))
7472 comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
7473 decl, cdecl, NULL_TREE);
7474 gfc_conv_descriptor_data_set (&fnblock, comp, null_pointer_node);
7476 else if (c->attr.allocatable)
7478 /* Allocatable scalar components. */
7479 comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
7480 decl, cdecl, NULL_TREE);
7481 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
7482 void_type_node, comp,
7483 build_int_cst (TREE_TYPE (comp), 0));
7484 gfc_add_expr_to_block (&fnblock, tmp);
7486 else if (c->ts.type == BT_CLASS && CLASS_DATA (c)->attr.allocatable)
7488 /* Allocatable CLASS components. */
7489 comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
7490 decl, cdecl, NULL_TREE);
7491 /* Add reference to '_data' component. */
7492 tmp = CLASS_DATA (c)->backend_decl;
7493 comp = fold_build3_loc (input_location, COMPONENT_REF,
7494 TREE_TYPE (tmp), comp, tmp, NULL_TREE);
7495 if (GFC_DESCRIPTOR_TYPE_P(TREE_TYPE (comp)))
7496 gfc_conv_descriptor_data_set (&fnblock, comp, null_pointer_node);
7499 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
7500 void_type_node, comp,
7501 build_int_cst (TREE_TYPE (comp), 0));
7502 gfc_add_expr_to_block (&fnblock, tmp);
7505 else if (cmp_has_alloc_comps)
7507 comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
7508 decl, cdecl, NULL_TREE);
7509 rank = c->as ? c->as->rank : 0;
7510 tmp = structure_alloc_comps (c->ts.u.derived, comp, NULL_TREE,
7512 gfc_add_expr_to_block (&fnblock, tmp);
7516 case COPY_ALLOC_COMP:
7517 if (c->attr.pointer)
7520 /* We need source and destination components. */
7521 comp = fold_build3_loc (input_location, COMPONENT_REF, ctype, decl,
7523 dcmp = fold_build3_loc (input_location, COMPONENT_REF, ctype, dest,
7525 dcmp = fold_convert (TREE_TYPE (comp), dcmp);
7527 if (c->attr.allocatable && !cmp_has_alloc_comps)
7529 rank = c->as ? c->as->rank : 0;
7530 tmp = gfc_duplicate_allocatable (dcmp, comp, ctype, rank);
7531 gfc_add_expr_to_block (&fnblock, tmp);
7534 if (cmp_has_alloc_comps)
7536 rank = c->as ? c->as->rank : 0;
7537 tmp = fold_convert (TREE_TYPE (dcmp), comp);
7538 gfc_add_modify (&fnblock, dcmp, tmp);
7539 tmp = structure_alloc_comps (c->ts.u.derived, comp, dcmp,
7541 gfc_add_expr_to_block (&fnblock, tmp);
7551 return gfc_finish_block (&fnblock);
7554 /* Recursively traverse an object of derived type, generating code to
7555 nullify allocatable components. */
7558 gfc_nullify_alloc_comp (gfc_symbol * der_type, tree decl, int rank)
7560 return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
7561 NULLIFY_ALLOC_COMP);
7565 /* Recursively traverse an object of derived type, generating code to
7566 deallocate allocatable components. */
7569 gfc_deallocate_alloc_comp (gfc_symbol * der_type, tree decl, int rank)
7571 return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
7572 DEALLOCATE_ALLOC_COMP);
7576 /* Recursively traverse an object of derived type, generating code to
7577 copy it and its allocatable components. */
7580 gfc_copy_alloc_comp (gfc_symbol * der_type, tree decl, tree dest, int rank)
7582 return structure_alloc_comps (der_type, decl, dest, rank, COPY_ALLOC_COMP);
7586 /* Recursively traverse an object of derived type, generating code to
7587 copy only its allocatable components. */
7590 gfc_copy_only_alloc_comp (gfc_symbol * der_type, tree decl, tree dest, int rank)
7592 return structure_alloc_comps (der_type, decl, dest, rank, COPY_ONLY_ALLOC_COMP);
7596 /* Returns the value of LBOUND for an expression. This could be broken out
7597 from gfc_conv_intrinsic_bound but this seemed to be simpler. This is
7598 called by gfc_alloc_allocatable_for_assignment. */
7600 get_std_lbound (gfc_expr *expr, tree desc, int dim, bool assumed_size)
7605 tree cond, cond1, cond3, cond4;
7609 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
7611 tmp = gfc_rank_cst[dim];
7612 lbound = gfc_conv_descriptor_lbound_get (desc, tmp);
7613 ubound = gfc_conv_descriptor_ubound_get (desc, tmp);
7614 stride = gfc_conv_descriptor_stride_get (desc, tmp);
7615 cond1 = fold_build2_loc (input_location, GE_EXPR, boolean_type_node,
7617 cond3 = fold_build2_loc (input_location, GE_EXPR, boolean_type_node,
7618 stride, gfc_index_zero_node);
7619 cond3 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
7620 boolean_type_node, cond3, cond1);
7621 cond4 = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
7622 stride, gfc_index_zero_node);
7624 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
7625 tmp, build_int_cst (gfc_array_index_type,
7628 cond = boolean_false_node;
7630 cond1 = fold_build2_loc (input_location, TRUTH_OR_EXPR,
7631 boolean_type_node, cond3, cond4);
7632 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
7633 boolean_type_node, cond, cond1);
7635 return fold_build3_loc (input_location, COND_EXPR,
7636 gfc_array_index_type, cond,
7637 lbound, gfc_index_one_node);
7640 if (expr->expr_type == EXPR_FUNCTION)
7642 /* A conversion function, so use the argument. */
7643 gcc_assert (expr->value.function.isym
7644 && expr->value.function.isym->conversion);
7645 expr = expr->value.function.actual->expr;
7648 if (expr->expr_type == EXPR_VARIABLE)
7650 tmp = TREE_TYPE (expr->symtree->n.sym->backend_decl);
7651 for (ref = expr->ref; ref; ref = ref->next)
7653 if (ref->type == REF_COMPONENT
7654 && ref->u.c.component->as
7656 && ref->next->u.ar.type == AR_FULL)
7657 tmp = TREE_TYPE (ref->u.c.component->backend_decl);
7659 return GFC_TYPE_ARRAY_LBOUND(tmp, dim);
7662 return gfc_index_one_node;
7666 /* Returns true if an expression represents an lhs that can be reallocated
7670 gfc_is_reallocatable_lhs (gfc_expr *expr)
7677 /* An allocatable variable. */
7678 if (expr->symtree->n.sym->attr.allocatable
7680 && expr->ref->type == REF_ARRAY
7681 && expr->ref->u.ar.type == AR_FULL)
7684 /* All that can be left are allocatable components. */
7685 if ((expr->symtree->n.sym->ts.type != BT_DERIVED
7686 && expr->symtree->n.sym->ts.type != BT_CLASS)
7687 || !expr->symtree->n.sym->ts.u.derived->attr.alloc_comp)
7690 /* Find a component ref followed by an array reference. */
7691 for (ref = expr->ref; ref; ref = ref->next)
7693 && ref->type == REF_COMPONENT
7694 && ref->next->type == REF_ARRAY
7695 && !ref->next->next)
7701 /* Return true if valid reallocatable lhs. */
7702 if (ref->u.c.component->attr.allocatable
7703 && ref->next->u.ar.type == AR_FULL)
7710 /* Allocate the lhs of an assignment to an allocatable array, otherwise
7714 gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
7718 stmtblock_t realloc_block;
7719 stmtblock_t alloc_block;
7723 gfc_array_info *linfo;
7743 gfc_array_spec * as;
7745 /* x = f(...) with x allocatable. In this case, expr1 is the rhs.
7746 Find the lhs expression in the loop chain and set expr1 and
7747 expr2 accordingly. */
7748 if (expr1->expr_type == EXPR_FUNCTION && expr2 == NULL)
7751 /* Find the ss for the lhs. */
7753 for (; lss && lss != gfc_ss_terminator; lss = lss->loop_chain)
7754 if (lss->info->expr && lss->info->expr->expr_type == EXPR_VARIABLE)
7756 if (lss == gfc_ss_terminator)
7758 expr1 = lss->info->expr;
7761 /* Bail out if this is not a valid allocate on assignment. */
7762 if (!gfc_is_reallocatable_lhs (expr1)
7763 || (expr2 && !expr2->rank))
7766 /* Find the ss for the lhs. */
7768 for (; lss && lss != gfc_ss_terminator; lss = lss->loop_chain)
7769 if (lss->info->expr == expr1)
7772 if (lss == gfc_ss_terminator)
7775 linfo = &lss->info->data.array;
7777 /* Find an ss for the rhs. For operator expressions, we see the
7778 ss's for the operands. Any one of these will do. */
7780 for (; rss && rss != gfc_ss_terminator; rss = rss->loop_chain)
7781 if (rss->info->expr != expr1 && rss != loop->temp_ss)
7784 if (expr2 && rss == gfc_ss_terminator)
7787 gfc_start_block (&fblock);
7789 /* Since the lhs is allocatable, this must be a descriptor type.
7790 Get the data and array size. */
7791 desc = linfo->descriptor;
7792 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)));
7793 array1 = gfc_conv_descriptor_data_get (desc);
7795 /* 7.4.1.3 "If variable is an allocated allocatable variable, it is
7796 deallocated if expr is an array of different shape or any of the
7797 corresponding length type parameter values of variable and expr
7798 differ." This assures F95 compatibility. */
7799 jump_label1 = gfc_build_label_decl (NULL_TREE);
7800 jump_label2 = gfc_build_label_decl (NULL_TREE);
7802 /* Allocate if data is NULL. */
7803 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
7804 array1, build_int_cst (TREE_TYPE (array1), 0));
7805 tmp = build3_v (COND_EXPR, cond,
7806 build1_v (GOTO_EXPR, jump_label1),
7807 build_empty_stmt (input_location));
7808 gfc_add_expr_to_block (&fblock, tmp);
7810 /* Get arrayspec if expr is a full array. */
7811 if (expr2 && expr2->expr_type == EXPR_FUNCTION
7812 && expr2->value.function.isym
7813 && expr2->value.function.isym->conversion)
7815 /* For conversion functions, take the arg. */
7816 gfc_expr *arg = expr2->value.function.actual->expr;
7817 as = gfc_get_full_arrayspec_from_expr (arg);
7820 as = gfc_get_full_arrayspec_from_expr (expr2);
7824 /* If the lhs shape is not the same as the rhs jump to setting the
7825 bounds and doing the reallocation....... */
7826 for (n = 0; n < expr1->rank; n++)
7828 /* Check the shape. */
7829 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
7830 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
7831 tmp = fold_build2_loc (input_location, MINUS_EXPR,
7832 gfc_array_index_type,
7833 loop->to[n], loop->from[n]);
7834 tmp = fold_build2_loc (input_location, PLUS_EXPR,
7835 gfc_array_index_type,
7837 tmp = fold_build2_loc (input_location, MINUS_EXPR,
7838 gfc_array_index_type,
7840 cond = fold_build2_loc (input_location, NE_EXPR,
7842 tmp, gfc_index_zero_node);
7843 tmp = build3_v (COND_EXPR, cond,
7844 build1_v (GOTO_EXPR, jump_label1),
7845 build_empty_stmt (input_location));
7846 gfc_add_expr_to_block (&fblock, tmp);
7849 /* ....else jump past the (re)alloc code. */
7850 tmp = build1_v (GOTO_EXPR, jump_label2);
7851 gfc_add_expr_to_block (&fblock, tmp);
7853 /* Add the label to start automatic (re)allocation. */
7854 tmp = build1_v (LABEL_EXPR, jump_label1);
7855 gfc_add_expr_to_block (&fblock, tmp);
7857 size1 = gfc_conv_descriptor_size (desc, expr1->rank);
7859 /* Get the rhs size. Fix both sizes. */
7861 desc2 = rss->info->data.array.descriptor;
7864 size2 = gfc_index_one_node;
7865 for (n = 0; n < expr2->rank; n++)
7867 tmp = fold_build2_loc (input_location, MINUS_EXPR,
7868 gfc_array_index_type,
7869 loop->to[n], loop->from[n]);
7870 tmp = fold_build2_loc (input_location, PLUS_EXPR,
7871 gfc_array_index_type,
7872 tmp, gfc_index_one_node);
7873 size2 = fold_build2_loc (input_location, MULT_EXPR,
7874 gfc_array_index_type,
7878 size1 = gfc_evaluate_now (size1, &fblock);
7879 size2 = gfc_evaluate_now (size2, &fblock);
7881 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7883 neq_size = gfc_evaluate_now (cond, &fblock);
7886 /* Now modify the lhs descriptor and the associated scalarizer
7887 variables. F2003 7.4.1.3: "If variable is or becomes an
7888 unallocated allocatable variable, then it is allocated with each
7889 deferred type parameter equal to the corresponding type parameters
7890 of expr , with the shape of expr , and with each lower bound equal
7891 to the corresponding element of LBOUND(expr)."
7892 Reuse size1 to keep a dimension-by-dimension track of the
7893 stride of the new array. */
7894 size1 = gfc_index_one_node;
7895 offset = gfc_index_zero_node;
7897 for (n = 0; n < expr2->rank; n++)
7899 tmp = fold_build2_loc (input_location, MINUS_EXPR,
7900 gfc_array_index_type,
7901 loop->to[n], loop->from[n]);
7902 tmp = fold_build2_loc (input_location, PLUS_EXPR,
7903 gfc_array_index_type,
7904 tmp, gfc_index_one_node);
7906 lbound = gfc_index_one_node;
7911 lbd = get_std_lbound (expr2, desc2, n,
7912 as->type == AS_ASSUMED_SIZE);
7913 ubound = fold_build2_loc (input_location,
7915 gfc_array_index_type,
7917 ubound = fold_build2_loc (input_location,
7919 gfc_array_index_type,
7924 gfc_conv_descriptor_lbound_set (&fblock, desc,
7927 gfc_conv_descriptor_ubound_set (&fblock, desc,
7930 gfc_conv_descriptor_stride_set (&fblock, desc,
7933 lbound = gfc_conv_descriptor_lbound_get (desc,
7935 tmp2 = fold_build2_loc (input_location, MULT_EXPR,
7936 gfc_array_index_type,
7938 offset = fold_build2_loc (input_location, MINUS_EXPR,
7939 gfc_array_index_type,
7941 size1 = fold_build2_loc (input_location, MULT_EXPR,
7942 gfc_array_index_type,
7946 /* Set the lhs descriptor and scalarizer offsets. For rank > 1,
7947 the array offset is saved and the info.offset is used for a
7948 running offset. Use the saved_offset instead. */
7949 tmp = gfc_conv_descriptor_offset (desc);
7950 gfc_add_modify (&fblock, tmp, offset);
7951 if (linfo->saved_offset
7952 && TREE_CODE (linfo->saved_offset) == VAR_DECL)
7953 gfc_add_modify (&fblock, linfo->saved_offset, tmp);
7955 /* Now set the deltas for the lhs. */
7956 for (n = 0; n < expr1->rank; n++)
7958 tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
7960 tmp = fold_build2_loc (input_location, MINUS_EXPR,
7961 gfc_array_index_type, tmp,
7963 if (linfo->delta[dim]
7964 && TREE_CODE (linfo->delta[dim]) == VAR_DECL)
7965 gfc_add_modify (&fblock, linfo->delta[dim], tmp);
7968 /* Get the new lhs size in bytes. */
7969 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
7971 tmp = expr2->ts.u.cl->backend_decl;
7972 gcc_assert (expr1->ts.u.cl->backend_decl);
7973 tmp = fold_convert (TREE_TYPE (expr1->ts.u.cl->backend_decl), tmp);
7974 gfc_add_modify (&fblock, expr1->ts.u.cl->backend_decl, tmp);
7976 else if (expr1->ts.type == BT_CHARACTER && expr1->ts.u.cl->backend_decl)
7978 tmp = TYPE_SIZE_UNIT (TREE_TYPE (gfc_typenode_for_spec (&expr1->ts)));
7979 tmp = fold_build2_loc (input_location, MULT_EXPR,
7980 gfc_array_index_type, tmp,
7981 expr1->ts.u.cl->backend_decl);
7984 tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts));
7985 tmp = fold_convert (gfc_array_index_type, tmp);
7986 size2 = fold_build2_loc (input_location, MULT_EXPR,
7987 gfc_array_index_type,
7989 size2 = fold_convert (size_type_node, size2);
7990 size2 = gfc_evaluate_now (size2, &fblock);
7992 /* Realloc expression. Note that the scalarizer uses desc.data
7993 in the array reference - (*desc.data)[<element>]. */
7994 gfc_init_block (&realloc_block);
7995 tmp = build_call_expr_loc (input_location,
7996 builtin_decl_explicit (BUILT_IN_REALLOC), 2,
7997 fold_convert (pvoid_type_node, array1),
7999 gfc_conv_descriptor_data_set (&realloc_block,
8001 realloc_expr = gfc_finish_block (&realloc_block);
8003 /* Only reallocate if sizes are different. */
8004 tmp = build3_v (COND_EXPR, neq_size, realloc_expr,
8005 build_empty_stmt (input_location));
8009 /* Malloc expression. */
8010 gfc_init_block (&alloc_block);
8011 tmp = build_call_expr_loc (input_location,
8012 builtin_decl_explicit (BUILT_IN_MALLOC),
8014 gfc_conv_descriptor_data_set (&alloc_block,
8016 tmp = gfc_conv_descriptor_dtype (desc);
8017 gfc_add_modify (&alloc_block, tmp, gfc_get_dtype (TREE_TYPE (desc)));
8018 alloc_expr = gfc_finish_block (&alloc_block);
8020 /* Malloc if not allocated; realloc otherwise. */
8021 tmp = build_int_cst (TREE_TYPE (array1), 0);
8022 cond = fold_build2_loc (input_location, EQ_EXPR,
8025 tmp = build3_v (COND_EXPR, cond, alloc_expr, realloc_expr);
8026 gfc_add_expr_to_block (&fblock, tmp);
8028 /* Make sure that the scalarizer data pointer is updated. */
8030 && TREE_CODE (linfo->data) == VAR_DECL)
8032 tmp = gfc_conv_descriptor_data_get (desc);
8033 gfc_add_modify (&fblock, linfo->data, tmp);
8036 /* Add the exit label. */
8037 tmp = build1_v (LABEL_EXPR, jump_label2);
8038 gfc_add_expr_to_block (&fblock, tmp);
8040 return gfc_finish_block (&fblock);
8044 /* NULLIFY an allocatable/pointer array on function entry, free it on exit.
8045 Do likewise, recursively if necessary, with the allocatable components of
8049 gfc_trans_deferred_array (gfc_symbol * sym, gfc_wrapped_block * block)
8055 stmtblock_t cleanup;
8058 bool sym_has_alloc_comp;
8060 sym_has_alloc_comp = (sym->ts.type == BT_DERIVED
8061 || sym->ts.type == BT_CLASS)
8062 && sym->ts.u.derived->attr.alloc_comp;
8064 /* Make sure the frontend gets these right. */
8065 if (!(sym->attr.pointer || sym->attr.allocatable || sym_has_alloc_comp))
8066 fatal_error ("Possible front-end bug: Deferred array size without pointer, "
8067 "allocatable attribute or derived type without allocatable "
8070 gfc_save_backend_locus (&loc);
8071 gfc_set_backend_locus (&sym->declared_at);
8072 gfc_init_block (&init);
8074 gcc_assert (TREE_CODE (sym->backend_decl) == VAR_DECL
8075 || TREE_CODE (sym->backend_decl) == PARM_DECL);
8077 if (sym->ts.type == BT_CHARACTER
8078 && !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
8080 gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
8081 gfc_trans_vla_type_sizes (sym, &init);
8084 /* Dummy, use associated and result variables don't need anything special. */
8085 if (sym->attr.dummy || sym->attr.use_assoc || sym->attr.result)
8087 gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
8088 gfc_restore_backend_locus (&loc);
8092 descriptor = sym->backend_decl;
8094 /* Although static, derived types with default initializers and
8095 allocatable components must not be nulled wholesale; instead they
8096 are treated component by component. */
8097 if (TREE_STATIC (descriptor) && !sym_has_alloc_comp)
8099 /* SAVEd variables are not freed on exit. */
8100 gfc_trans_static_array_pointer (sym);
8102 gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
8103 gfc_restore_backend_locus (&loc);
8107 /* Get the descriptor type. */
8108 type = TREE_TYPE (sym->backend_decl);
8110 if (sym_has_alloc_comp && !(sym->attr.pointer || sym->attr.allocatable))
8113 && !(TREE_STATIC (sym->backend_decl) && sym->attr.is_main_program))
8115 if (sym->value == NULL
8116 || !gfc_has_default_initializer (sym->ts.u.derived))
8118 rank = sym->as ? sym->as->rank : 0;
8119 tmp = gfc_nullify_alloc_comp (sym->ts.u.derived,
8121 gfc_add_expr_to_block (&init, tmp);
8124 gfc_init_default_dt (sym, &init, false);
8127 else if (!GFC_DESCRIPTOR_TYPE_P (type))
8129 /* If the backend_decl is not a descriptor, we must have a pointer
8131 descriptor = build_fold_indirect_ref_loc (input_location,
8133 type = TREE_TYPE (descriptor);
8136 /* NULLIFY the data pointer. */
8137 if (GFC_DESCRIPTOR_TYPE_P (type) && !sym->attr.save)
8138 gfc_conv_descriptor_data_set (&init, descriptor, null_pointer_node);
8140 gfc_restore_backend_locus (&loc);
8141 gfc_init_block (&cleanup);
8143 /* Allocatable arrays need to be freed when they go out of scope.
8144 The allocatable components of pointers must not be touched. */
8145 if (sym_has_alloc_comp && !(sym->attr.function || sym->attr.result)
8146 && !sym->attr.pointer && !sym->attr.save)
8149 rank = sym->as ? sym->as->rank : 0;
8150 tmp = gfc_deallocate_alloc_comp (sym->ts.u.derived, descriptor, rank);
8151 gfc_add_expr_to_block (&cleanup, tmp);
8154 if (sym->attr.allocatable && (sym->attr.dimension || sym->attr.codimension)
8155 && !sym->attr.save && !sym->attr.result)
8157 tmp = gfc_trans_dealloc_allocated (sym->backend_decl,
8158 sym->attr.codimension);
8159 gfc_add_expr_to_block (&cleanup, tmp);
8162 gfc_add_init_cleanup (block, gfc_finish_block (&init),
8163 gfc_finish_block (&cleanup));
8166 /************ Expression Walking Functions ******************/
8168 /* Walk a variable reference.
8170 Possible extension - multiple component subscripts.
8171 x(:,:) = foo%a(:)%b(:)
8173 forall (i=..., j=...)
8174 x(i,j) = foo%a(j)%b(i)
8176 This adds a fair amount of complexity because you need to deal with more
8177 than one ref. Maybe handle in a similar manner to vector subscripts.
8178 Maybe not worth the effort. */
8182 gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
8186 for (ref = expr->ref; ref; ref = ref->next)
8187 if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
8190 return gfc_walk_array_ref (ss, expr, ref);
8195 gfc_walk_array_ref (gfc_ss * ss, gfc_expr * expr, gfc_ref * ref)
8201 for (; ref; ref = ref->next)
8203 if (ref->type == REF_SUBSTRING)
8205 ss = gfc_get_scalar_ss (ss, ref->u.ss.start);
8206 ss = gfc_get_scalar_ss (ss, ref->u.ss.end);
8209 /* We're only interested in array sections from now on. */
8210 if (ref->type != REF_ARRAY)
8218 for (n = ar->dimen - 1; n >= 0; n--)
8219 ss = gfc_get_scalar_ss (ss, ar->start[n]);
8223 newss = gfc_get_array_ss (ss, expr, ar->as->rank, GFC_SS_SECTION);
8224 newss->info->data.array.ref = ref;
8226 /* Make sure array is the same as array(:,:), this way
8227 we don't need to special case all the time. */
8228 ar->dimen = ar->as->rank;
8229 for (n = 0; n < ar->dimen; n++)
8231 ar->dimen_type[n] = DIMEN_RANGE;
8233 gcc_assert (ar->start[n] == NULL);
8234 gcc_assert (ar->end[n] == NULL);
8235 gcc_assert (ar->stride[n] == NULL);
8241 newss = gfc_get_array_ss (ss, expr, 0, GFC_SS_SECTION);
8242 newss->info->data.array.ref = ref;
8244 /* We add SS chains for all the subscripts in the section. */
8245 for (n = 0; n < ar->dimen; n++)
8249 switch (ar->dimen_type[n])
8252 /* Add SS for elemental (scalar) subscripts. */
8253 gcc_assert (ar->start[n]);
8254 indexss = gfc_get_scalar_ss (gfc_ss_terminator, ar->start[n]);
8255 indexss->loop_chain = gfc_ss_terminator;
8256 newss->info->data.array.subscript[n] = indexss;
8260 /* We don't add anything for sections, just remember this
8261 dimension for later. */
8262 newss->dim[newss->dimen] = n;
8267 /* Create a GFC_SS_VECTOR index in which we can store
8268 the vector's descriptor. */
8269 indexss = gfc_get_array_ss (gfc_ss_terminator, ar->start[n],
8271 indexss->loop_chain = gfc_ss_terminator;
8272 newss->info->data.array.subscript[n] = indexss;
8273 newss->dim[newss->dimen] = n;
8278 /* We should know what sort of section it is by now. */
8282 /* We should have at least one non-elemental dimension,
8283 unless we are creating a descriptor for a (scalar) coarray. */
8284 gcc_assert (newss->dimen > 0
8285 || newss->info->data.array.ref->u.ar.as->corank > 0);
8290 /* We should know what sort of section it is by now. */
8299 /* Walk an expression operator. If only one operand of a binary expression is
8300 scalar, we must also add the scalar term to the SS chain. */
8303 gfc_walk_op_expr (gfc_ss * ss, gfc_expr * expr)
8308 head = gfc_walk_subexpr (ss, expr->value.op.op1);
8309 if (expr->value.op.op2 == NULL)
8312 head2 = gfc_walk_subexpr (head, expr->value.op.op2);
8314 /* All operands are scalar. Pass back and let the caller deal with it. */
8318 /* All operands require scalarization. */
8319 if (head != ss && (expr->value.op.op2 == NULL || head2 != head))
8322 /* One of the operands needs scalarization, the other is scalar.
8323 Create a gfc_ss for the scalar expression. */
8326 /* First operand is scalar. We build the chain in reverse order, so
8327 add the scalar SS after the second operand. */
8329 while (head && head->next != ss)
8331 /* Check we haven't somehow broken the chain. */
8333 head->next = gfc_get_scalar_ss (ss, expr->value.op.op1);
8335 else /* head2 == head */
8337 gcc_assert (head2 == head);
8338 /* Second operand is scalar. */
8339 head2 = gfc_get_scalar_ss (head2, expr->value.op.op2);
8346 /* Reverse a SS chain. */
8349 gfc_reverse_ss (gfc_ss * ss)
8354 gcc_assert (ss != NULL);
8356 head = gfc_ss_terminator;
8357 while (ss != gfc_ss_terminator)
8360 /* Check we didn't somehow break the chain. */
8361 gcc_assert (next != NULL);
8371 /* Walk the arguments of an elemental function.
8372 PROC_EXPR is used to check whether an argument is permitted to be absent. If
8373 it is NULL, we don't do the check and the argument is assumed to be present.
8377 gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
8378 gfc_expr *proc_expr, gfc_ss_type type)
8380 gfc_formal_arglist *dummy_arg;
8386 head = gfc_ss_terminator;
8393 /* Normal procedure case. */
8394 dummy_arg = proc_expr->symtree->n.sym->formal;
8396 /* Typebound procedure case. */
8397 for (ref = proc_expr->ref; ref; ref = ref->next)
8399 if (ref->type == REF_COMPONENT
8400 && ref->u.c.component->attr.proc_pointer
8401 && ref->u.c.component->ts.interface)
8402 dummy_arg = ref->u.c.component->ts.interface->formal;
8411 for (; arg; arg = arg->next)
8413 if (!arg->expr || arg->expr->expr_type == EXPR_NULL)
8416 newss = gfc_walk_subexpr (head, arg->expr);
8419 /* Scalar argument. */
8420 gcc_assert (type == GFC_SS_SCALAR || type == GFC_SS_REFERENCE);
8421 newss = gfc_get_scalar_ss (head, arg->expr);
8422 newss->info->type = type;
8424 if (dummy_arg != NULL
8425 && dummy_arg->sym->attr.optional
8426 && arg->expr->symtree
8427 && arg->expr->symtree->n.sym->attr.optional
8428 && arg->expr->ref == NULL)
8429 newss->info->data.scalar.can_be_null_ref = true;
8438 while (tail->next != gfc_ss_terminator)
8442 if (dummy_arg != NULL)
8443 dummy_arg = dummy_arg->next;
8448 /* If all the arguments are scalar we don't need the argument SS. */
8449 gfc_free_ss_chain (head);
8454 /* Add it onto the existing chain. */
8460 /* Walk a function call. Scalar functions are passed back, and taken out of
8461 scalarization loops. For elemental functions we walk their arguments.
8462 The result of functions returning arrays is stored in a temporary outside
8463 the loop, so that the function is only called once. Hence we do not need
8464 to walk their arguments. */
8467 gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
8469 gfc_intrinsic_sym *isym;
8471 gfc_component *comp = NULL;
8473 isym = expr->value.function.isym;
8475 /* Handle intrinsic functions separately. */
8477 return gfc_walk_intrinsic_function (ss, expr, isym);
8479 sym = expr->value.function.esym;
8481 sym = expr->symtree->n.sym;
8483 /* A function that returns arrays. */
8484 gfc_is_proc_ptr_comp (expr, &comp);
8485 if ((!comp && gfc_return_by_reference (sym) && sym->result->attr.dimension)
8486 || (comp && comp->attr.dimension))
8487 return gfc_get_array_ss (ss, expr, expr->rank, GFC_SS_FUNCTION);
8489 /* Walk the parameters of an elemental function. For now we always pass
8491 if (sym->attr.elemental || (comp && comp->attr.elemental))
8492 return gfc_walk_elemental_function_args (ss, expr->value.function.actual,
8493 expr, GFC_SS_REFERENCE);
8495 /* Scalar functions are OK as these are evaluated outside the scalarization
8496 loop. Pass back and let the caller deal with it. */
8501 /* An array temporary is constructed for array constructors. */
8504 gfc_walk_array_constructor (gfc_ss * ss, gfc_expr * expr)
8506 return gfc_get_array_ss (ss, expr, expr->rank, GFC_SS_CONSTRUCTOR);
8510 /* Walk an expression. Add walked expressions to the head of the SS chain.
8511 A wholly scalar expression will not be added. */
8514 gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr)
8518 switch (expr->expr_type)
8521 head = gfc_walk_variable_expr (ss, expr);
8525 head = gfc_walk_op_expr (ss, expr);
8529 head = gfc_walk_function_expr (ss, expr);
8534 case EXPR_STRUCTURE:
8535 /* Pass back and let the caller deal with it. */
8539 head = gfc_walk_array_constructor (ss, expr);
8542 case EXPR_SUBSTRING:
8543 /* Pass back and let the caller deal with it. */
8547 internal_error ("bad expression type during walk (%d)",
8554 /* Entry point for expression walking.
8555 A return value equal to the passed chain means this is
8556 a scalar expression. It is up to the caller to take whatever action is
8557 necessary to translate these. */
8560 gfc_walk_expr (gfc_expr * expr)
8564 res = gfc_walk_subexpr (gfc_ss_terminator, expr);
8565 return gfc_reverse_ss (res);