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;
469 static void gfc_free_ss (gfc_ss *);
472 /* Free a gfc_ss chain. */
475 gfc_free_ss_chain (gfc_ss * ss)
479 while (ss != gfc_ss_terminator)
481 gcc_assert (ss != NULL);
490 free_ss_info (gfc_ss_info *ss_info)
493 if (ss_info->refcount > 0)
496 gcc_assert (ss_info->refcount == 0);
504 gfc_free_ss (gfc_ss * ss)
506 gfc_ss_info *ss_info;
511 switch (ss_info->type)
514 for (n = 0; n < ss->dimen; n++)
516 if (ss_info->data.array.subscript[ss->dim[n]])
517 gfc_free_ss_chain (ss_info->data.array.subscript[ss->dim[n]]);
525 free_ss_info (ss_info);
530 /* Creates and initializes an array type gfc_ss struct. */
533 gfc_get_array_ss (gfc_ss *next, gfc_expr *expr, int dimen, gfc_ss_type type)
536 gfc_ss_info *ss_info;
539 ss_info = gfc_get_ss_info ();
541 ss_info->type = type;
542 ss_info->expr = expr;
548 for (i = 0; i < ss->dimen; i++)
555 /* Creates and initializes a temporary type gfc_ss struct. */
558 gfc_get_temp_ss (tree type, tree string_length, int dimen)
561 gfc_ss_info *ss_info;
564 ss_info = gfc_get_ss_info ();
566 ss_info->type = GFC_SS_TEMP;
567 ss_info->string_length = string_length;
568 ss_info->data.temp.type = type;
572 ss->next = gfc_ss_terminator;
574 for (i = 0; i < ss->dimen; i++)
581 /* Creates and initializes a scalar type gfc_ss struct. */
584 gfc_get_scalar_ss (gfc_ss *next, gfc_expr *expr)
587 gfc_ss_info *ss_info;
589 ss_info = gfc_get_ss_info ();
591 ss_info->type = GFC_SS_SCALAR;
592 ss_info->expr = expr;
602 /* Free all the SS associated with a loop. */
605 gfc_cleanup_loop (gfc_loopinfo * loop)
607 gfc_loopinfo *loop_next, **ploop;
612 while (ss != gfc_ss_terminator)
614 gcc_assert (ss != NULL);
615 next = ss->loop_chain;
620 /* Remove reference to self in the parent loop. */
622 for (ploop = &loop->parent->nested; *ploop; ploop = &(*ploop)->next)
629 /* Free non-freed nested loops. */
630 for (loop = loop->nested; loop; loop = loop_next)
632 loop_next = loop->next;
633 gfc_cleanup_loop (loop);
640 set_ss_loop (gfc_ss *ss, gfc_loopinfo *loop)
644 for (; ss != gfc_ss_terminator; ss = ss->next)
648 if (ss->info->type == GFC_SS_SCALAR
649 || ss->info->type == GFC_SS_REFERENCE
650 || ss->info->type == GFC_SS_TEMP)
653 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
654 if (ss->info->data.array.subscript[n] != NULL)
655 set_ss_loop (ss->info->data.array.subscript[n], loop);
660 /* Associate a SS chain with a loop. */
663 gfc_add_ss_to_loop (gfc_loopinfo * loop, gfc_ss * head)
666 gfc_loopinfo *nested_loop;
668 if (head == gfc_ss_terminator)
671 set_ss_loop (head, loop);
674 for (; ss && ss != gfc_ss_terminator; ss = ss->next)
678 nested_loop = ss->nested_ss->loop;
680 /* More than one ss can belong to the same loop. Hence, we add the
681 loop to the chain only if it is different from the previously
682 added one, to avoid duplicate nested loops. */
683 if (nested_loop != loop->nested)
685 gcc_assert (nested_loop->parent == NULL);
686 nested_loop->parent = loop;
688 gcc_assert (nested_loop->next == NULL);
689 nested_loop->next = loop->nested;
690 loop->nested = nested_loop;
693 gcc_assert (nested_loop->parent == loop);
696 if (ss->next == gfc_ss_terminator)
697 ss->loop_chain = loop->ss;
699 ss->loop_chain = ss->next;
701 gcc_assert (ss == gfc_ss_terminator);
706 /* Generate an initializer for a static pointer or allocatable array. */
709 gfc_trans_static_array_pointer (gfc_symbol * sym)
713 gcc_assert (TREE_STATIC (sym->backend_decl));
714 /* Just zero the data member. */
715 type = TREE_TYPE (sym->backend_decl);
716 DECL_INITIAL (sym->backend_decl) = gfc_build_null_descriptor (type);
720 /* If the bounds of SE's loop have not yet been set, see if they can be
721 determined from array spec AS, which is the array spec of a called
722 function. MAPPING maps the callee's dummy arguments to the values
723 that the caller is passing. Add any initialization and finalization
727 gfc_set_loop_bounds_from_array_spec (gfc_interface_mapping * mapping,
728 gfc_se * se, gfc_array_spec * as)
730 int n, dim, total_dim;
739 if (!as || as->type != AS_EXPLICIT)
742 for (ss = se->ss; ss; ss = ss->parent)
744 total_dim += ss->loop->dimen;
745 for (n = 0; n < ss->loop->dimen; n++)
747 /* The bound is known, nothing to do. */
748 if (ss->loop->to[n] != NULL_TREE)
752 gcc_assert (dim < as->rank);
753 gcc_assert (ss->loop->dimen <= as->rank);
755 /* Evaluate the lower bound. */
756 gfc_init_se (&tmpse, NULL);
757 gfc_apply_interface_mapping (mapping, &tmpse, as->lower[dim]);
758 gfc_add_block_to_block (&se->pre, &tmpse.pre);
759 gfc_add_block_to_block (&se->post, &tmpse.post);
760 lower = fold_convert (gfc_array_index_type, tmpse.expr);
762 /* ...and the upper bound. */
763 gfc_init_se (&tmpse, NULL);
764 gfc_apply_interface_mapping (mapping, &tmpse, as->upper[dim]);
765 gfc_add_block_to_block (&se->pre, &tmpse.pre);
766 gfc_add_block_to_block (&se->post, &tmpse.post);
767 upper = fold_convert (gfc_array_index_type, tmpse.expr);
769 /* Set the upper bound of the loop to UPPER - LOWER. */
770 tmp = fold_build2_loc (input_location, MINUS_EXPR,
771 gfc_array_index_type, upper, lower);
772 tmp = gfc_evaluate_now (tmp, &se->pre);
773 ss->loop->to[n] = tmp;
777 gcc_assert (total_dim == as->rank);
781 /* Generate code to allocate an array temporary, or create a variable to
782 hold the data. If size is NULL, zero the descriptor so that the
783 callee will allocate the array. If DEALLOC is true, also generate code to
784 free the array afterwards.
786 If INITIAL is not NULL, it is packed using internal_pack and the result used
787 as data instead of allocating a fresh, unitialized area of memory.
789 Initialization code is added to PRE and finalization code to POST.
790 DYNAMIC is true if the caller may want to extend the array later
791 using realloc. This prevents us from putting the array on the stack. */
794 gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
795 gfc_array_info * info, tree size, tree nelem,
796 tree initial, bool dynamic, bool dealloc)
802 desc = info->descriptor;
803 info->offset = gfc_index_zero_node;
804 if (size == NULL_TREE || integer_zerop (size))
806 /* A callee allocated array. */
807 gfc_conv_descriptor_data_set (pre, desc, null_pointer_node);
812 /* Allocate the temporary. */
813 onstack = !dynamic && initial == NULL_TREE
814 && (gfc_option.flag_stack_arrays
815 || gfc_can_put_var_on_stack (size));
819 /* Make a temporary variable to hold the data. */
820 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (nelem),
821 nelem, gfc_index_one_node);
822 tmp = gfc_evaluate_now (tmp, pre);
823 tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
825 tmp = build_array_type (gfc_get_element_type (TREE_TYPE (desc)),
827 tmp = gfc_create_var (tmp, "A");
828 /* If we're here only because of -fstack-arrays we have to
829 emit a DECL_EXPR to make the gimplifier emit alloca calls. */
830 if (!gfc_can_put_var_on_stack (size))
831 gfc_add_expr_to_block (pre,
832 fold_build1_loc (input_location,
833 DECL_EXPR, TREE_TYPE (tmp),
835 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
836 gfc_conv_descriptor_data_set (pre, desc, tmp);
840 /* Allocate memory to hold the data or call internal_pack. */
841 if (initial == NULL_TREE)
843 tmp = gfc_call_malloc (pre, NULL, size);
844 tmp = gfc_evaluate_now (tmp, pre);
851 stmtblock_t do_copying;
853 tmp = TREE_TYPE (initial); /* Pointer to descriptor. */
854 gcc_assert (TREE_CODE (tmp) == POINTER_TYPE);
855 tmp = TREE_TYPE (tmp); /* The descriptor itself. */
856 tmp = gfc_get_element_type (tmp);
857 gcc_assert (tmp == gfc_get_element_type (TREE_TYPE (desc)));
858 packed = gfc_create_var (build_pointer_type (tmp), "data");
860 tmp = build_call_expr_loc (input_location,
861 gfor_fndecl_in_pack, 1, initial);
862 tmp = fold_convert (TREE_TYPE (packed), tmp);
863 gfc_add_modify (pre, packed, tmp);
865 tmp = build_fold_indirect_ref_loc (input_location,
867 source_data = gfc_conv_descriptor_data_get (tmp);
869 /* internal_pack may return source->data without any allocation
870 or copying if it is already packed. If that's the case, we
871 need to allocate and copy manually. */
873 gfc_start_block (&do_copying);
874 tmp = gfc_call_malloc (&do_copying, NULL, size);
875 tmp = fold_convert (TREE_TYPE (packed), tmp);
876 gfc_add_modify (&do_copying, packed, tmp);
877 tmp = gfc_build_memcpy_call (packed, source_data, size);
878 gfc_add_expr_to_block (&do_copying, tmp);
880 was_packed = fold_build2_loc (input_location, EQ_EXPR,
881 boolean_type_node, packed,
883 tmp = gfc_finish_block (&do_copying);
884 tmp = build3_v (COND_EXPR, was_packed, tmp,
885 build_empty_stmt (input_location));
886 gfc_add_expr_to_block (pre, tmp);
888 tmp = fold_convert (pvoid_type_node, packed);
891 gfc_conv_descriptor_data_set (pre, desc, tmp);
894 info->data = gfc_conv_descriptor_data_get (desc);
896 /* The offset is zero because we create temporaries with a zero
898 gfc_conv_descriptor_offset_set (pre, desc, gfc_index_zero_node);
900 if (dealloc && !onstack)
902 /* Free the temporary. */
903 tmp = gfc_conv_descriptor_data_get (desc);
904 tmp = gfc_call_free (fold_convert (pvoid_type_node, tmp));
905 gfc_add_expr_to_block (post, tmp);
910 /* Get the scalarizer array dimension corresponding to actual array dimension
913 For example, if SS represents the array ref a(1,:,:,1), it is a
914 bidimensional scalarizer array, and the result would be 0 for ARRAY_DIM=1,
915 and 1 for ARRAY_DIM=2.
916 If SS represents transpose(a(:,1,1,:)), it is again a bidimensional
917 scalarizer array, and the result would be 1 for ARRAY_DIM=0 and 0 for
919 If SS represents sum(a(:,:,:,1), dim=1), it is a 2+1-dimensional scalarizer
920 array. If called on the inner ss, the result would be respectively 0,1,2 for
921 ARRAY_DIM=0,1,2. If called on the outer ss, the result would be 0,1
922 for ARRAY_DIM=1,2. */
925 get_scalarizer_dim_for_array_dim (gfc_ss *ss, int array_dim)
932 for (; ss; ss = ss->parent)
933 for (n = 0; n < ss->dimen; n++)
934 if (ss->dim[n] < array_dim)
937 return array_ref_dim;
942 innermost_ss (gfc_ss *ss)
944 while (ss->nested_ss != NULL)
952 /* Get the array reference dimension corresponding to the given loop dimension.
953 It is different from the true array dimension given by the dim array in
954 the case of a partial array reference (i.e. a(:,:,1,:) for example)
955 It is different from the loop dimension in the case of a transposed array.
959 get_array_ref_dim_for_loop_dim (gfc_ss *ss, int loop_dim)
961 return get_scalarizer_dim_for_array_dim (innermost_ss (ss),
966 /* Generate code to create and initialize the descriptor for a temporary
967 array. This is used for both temporaries needed by the scalarizer, and
968 functions returning arrays. Adjusts the loop variables to be
969 zero-based, and calculates the loop bounds for callee allocated arrays.
970 Allocate the array unless it's callee allocated (we have a callee
971 allocated array if 'callee_alloc' is true, or if loop->to[n] is
972 NULL_TREE for any n). Also fills in the descriptor, data and offset
973 fields of info if known. Returns the size of the array, or NULL for a
974 callee allocated array.
976 PRE, POST, INITIAL, DYNAMIC and DEALLOC are as for
977 gfc_trans_allocate_array_storage. */
980 gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss,
981 tree eltype, tree initial, bool dynamic,
982 bool dealloc, bool callee_alloc, locus * where)
986 gfc_array_info *info;
987 tree from[GFC_MAX_DIMENSIONS], to[GFC_MAX_DIMENSIONS];
998 memset (from, 0, sizeof (from));
999 memset (to, 0, sizeof (to));
1001 info = &ss->info->data.array;
1003 gcc_assert (ss->dimen > 0);
1004 gcc_assert (ss->loop->dimen == ss->dimen);
1006 if (gfc_option.warn_array_temp && where)
1007 gfc_warning ("Creating array temporary at %L", where);
1009 /* Set the lower bound to zero. */
1010 for (s = ss; s; s = s->parent)
1014 total_dim += loop->dimen;
1015 for (n = 0; n < loop->dimen; n++)
1019 /* Callee allocated arrays may not have a known bound yet. */
1021 loop->to[n] = gfc_evaluate_now (
1022 fold_build2_loc (input_location, MINUS_EXPR,
1023 gfc_array_index_type,
1024 loop->to[n], loop->from[n]),
1026 loop->from[n] = gfc_index_zero_node;
1028 /* We have just changed the loop bounds, we must clear the
1029 corresponding specloop, so that delta calculation is not skipped
1030 later in set_delta. */
1031 loop->specloop[n] = NULL;
1033 /* We are constructing the temporary's descriptor based on the loop
1034 dimensions. As the dimensions may be accessed in arbitrary order
1035 (think of transpose) the size taken from the n'th loop may not map
1036 to the n'th dimension of the array. We need to reconstruct loop
1037 infos in the right order before using it to set the descriptor
1039 tmp_dim = get_scalarizer_dim_for_array_dim (ss, dim);
1040 from[tmp_dim] = loop->from[n];
1041 to[tmp_dim] = loop->to[n];
1043 info->delta[dim] = gfc_index_zero_node;
1044 info->start[dim] = gfc_index_zero_node;
1045 info->end[dim] = gfc_index_zero_node;
1046 info->stride[dim] = gfc_index_one_node;
1050 /* Initialize the descriptor. */
1052 gfc_get_array_type_bounds (eltype, total_dim, 0, from, to, 1,
1053 GFC_ARRAY_UNKNOWN, true);
1054 desc = gfc_create_var (type, "atmp");
1055 GFC_DECL_PACKED_ARRAY (desc) = 1;
1057 info->descriptor = desc;
1058 size = gfc_index_one_node;
1060 /* Fill in the array dtype. */
1061 tmp = gfc_conv_descriptor_dtype (desc);
1062 gfc_add_modify (pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
1065 Fill in the bounds and stride. This is a packed array, so:
1068 for (n = 0; n < rank; n++)
1071 delta = ubound[n] + 1 - lbound[n];
1072 size = size * delta;
1074 size = size * sizeof(element);
1077 or_expr = NULL_TREE;
1079 /* If there is at least one null loop->to[n], it is a callee allocated
1081 for (n = 0; n < total_dim; n++)
1082 if (to[n] == NULL_TREE)
1088 if (size == NULL_TREE)
1089 for (s = ss; s; s = s->parent)
1090 for (n = 0; n < s->loop->dimen; n++)
1092 dim = get_scalarizer_dim_for_array_dim (ss, ss->dim[n]);
1094 /* For a callee allocated array express the loop bounds in terms
1095 of the descriptor fields. */
1096 tmp = fold_build2_loc (input_location,
1097 MINUS_EXPR, gfc_array_index_type,
1098 gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]),
1099 gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]));
1100 s->loop->to[n] = tmp;
1104 for (n = 0; n < total_dim; n++)
1106 /* Store the stride and bound components in the descriptor. */
1107 gfc_conv_descriptor_stride_set (pre, desc, gfc_rank_cst[n], size);
1109 gfc_conv_descriptor_lbound_set (pre, desc, gfc_rank_cst[n],
1110 gfc_index_zero_node);
1112 gfc_conv_descriptor_ubound_set (pre, desc, gfc_rank_cst[n], to[n]);
1114 tmp = fold_build2_loc (input_location, PLUS_EXPR,
1115 gfc_array_index_type,
1116 to[n], gfc_index_one_node);
1118 /* Check whether the size for this dimension is negative. */
1119 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
1120 tmp, gfc_index_zero_node);
1121 cond = gfc_evaluate_now (cond, pre);
1126 or_expr = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1127 boolean_type_node, or_expr, cond);
1129 size = fold_build2_loc (input_location, MULT_EXPR,
1130 gfc_array_index_type, size, tmp);
1131 size = gfc_evaluate_now (size, pre);
1135 /* Get the size of the array. */
1136 if (size && !callee_alloc)
1138 /* If or_expr is true, then the extent in at least one
1139 dimension is zero and the size is set to zero. */
1140 size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
1141 or_expr, gfc_index_zero_node, size);
1144 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
1146 fold_convert (gfc_array_index_type,
1147 TYPE_SIZE_UNIT (gfc_get_element_type (type))));
1155 gfc_trans_allocate_array_storage (pre, post, info, size, nelem, initial,
1161 if (ss->dimen > ss->loop->temp_dim)
1162 ss->loop->temp_dim = ss->dimen;
1168 /* Return the number of iterations in a loop that starts at START,
1169 ends at END, and has step STEP. */
1172 gfc_get_iteration_count (tree start, tree end, tree step)
1177 type = TREE_TYPE (step);
1178 tmp = fold_build2_loc (input_location, MINUS_EXPR, type, end, start);
1179 tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, type, tmp, step);
1180 tmp = fold_build2_loc (input_location, PLUS_EXPR, type, tmp,
1181 build_int_cst (type, 1));
1182 tmp = fold_build2_loc (input_location, MAX_EXPR, type, tmp,
1183 build_int_cst (type, 0));
1184 return fold_convert (gfc_array_index_type, tmp);
1188 /* Extend the data in array DESC by EXTRA elements. */
1191 gfc_grow_array (stmtblock_t * pblock, tree desc, tree extra)
1198 if (integer_zerop (extra))
1201 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[0]);
1203 /* Add EXTRA to the upper bound. */
1204 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1206 gfc_conv_descriptor_ubound_set (pblock, desc, gfc_rank_cst[0], tmp);
1208 /* Get the value of the current data pointer. */
1209 arg0 = gfc_conv_descriptor_data_get (desc);
1211 /* Calculate the new array size. */
1212 size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
1213 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1214 ubound, gfc_index_one_node);
1215 arg1 = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
1216 fold_convert (size_type_node, tmp),
1217 fold_convert (size_type_node, size));
1219 /* Call the realloc() function. */
1220 tmp = gfc_call_realloc (pblock, arg0, arg1);
1221 gfc_conv_descriptor_data_set (pblock, desc, tmp);
1225 /* Return true if the bounds of iterator I can only be determined
1229 gfc_iterator_has_dynamic_bounds (gfc_iterator * i)
1231 return (i->start->expr_type != EXPR_CONSTANT
1232 || i->end->expr_type != EXPR_CONSTANT
1233 || i->step->expr_type != EXPR_CONSTANT);
1237 /* Split the size of constructor element EXPR into the sum of two terms,
1238 one of which can be determined at compile time and one of which must
1239 be calculated at run time. Set *SIZE to the former and return true
1240 if the latter might be nonzero. */
1243 gfc_get_array_constructor_element_size (mpz_t * size, gfc_expr * expr)
1245 if (expr->expr_type == EXPR_ARRAY)
1246 return gfc_get_array_constructor_size (size, expr->value.constructor);
1247 else if (expr->rank > 0)
1249 /* Calculate everything at run time. */
1250 mpz_set_ui (*size, 0);
1255 /* A single element. */
1256 mpz_set_ui (*size, 1);
1262 /* Like gfc_get_array_constructor_element_size, but applied to the whole
1263 of array constructor C. */
1266 gfc_get_array_constructor_size (mpz_t * size, gfc_constructor_base base)
1274 mpz_set_ui (*size, 0);
1279 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
1282 if (i && gfc_iterator_has_dynamic_bounds (i))
1286 dynamic |= gfc_get_array_constructor_element_size (&len, c->expr);
1289 /* Multiply the static part of the element size by the
1290 number of iterations. */
1291 mpz_sub (val, i->end->value.integer, i->start->value.integer);
1292 mpz_fdiv_q (val, val, i->step->value.integer);
1293 mpz_add_ui (val, val, 1);
1294 if (mpz_sgn (val) > 0)
1295 mpz_mul (len, len, val);
1297 mpz_set_ui (len, 0);
1299 mpz_add (*size, *size, len);
1308 /* Make sure offset is a variable. */
1311 gfc_put_offset_into_var (stmtblock_t * pblock, tree * poffset,
1314 /* We should have already created the offset variable. We cannot
1315 create it here because we may be in an inner scope. */
1316 gcc_assert (*offsetvar != NULL_TREE);
1317 gfc_add_modify (pblock, *offsetvar, *poffset);
1318 *poffset = *offsetvar;
1319 TREE_USED (*offsetvar) = 1;
1323 /* Variables needed for bounds-checking. */
1324 static bool first_len;
1325 static tree first_len_val;
1326 static bool typespec_chararray_ctor;
1329 gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc,
1330 tree offset, gfc_se * se, gfc_expr * expr)
1334 gfc_conv_expr (se, expr);
1336 /* Store the value. */
1337 tmp = build_fold_indirect_ref_loc (input_location,
1338 gfc_conv_descriptor_data_get (desc));
1339 tmp = gfc_build_array_ref (tmp, offset, NULL);
1341 if (expr->ts.type == BT_CHARACTER)
1343 int i = gfc_validate_kind (BT_CHARACTER, expr->ts.kind, false);
1346 esize = size_in_bytes (gfc_get_element_type (TREE_TYPE (desc)));
1347 esize = fold_convert (gfc_charlen_type_node, esize);
1348 esize = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
1349 gfc_charlen_type_node, esize,
1350 build_int_cst (gfc_charlen_type_node,
1351 gfc_character_kinds[i].bit_size / 8));
1353 gfc_conv_string_parameter (se);
1354 if (POINTER_TYPE_P (TREE_TYPE (tmp)))
1356 /* The temporary is an array of pointers. */
1357 se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
1358 gfc_add_modify (&se->pre, tmp, se->expr);
1362 /* The temporary is an array of string values. */
1363 tmp = gfc_build_addr_expr (gfc_get_pchar_type (expr->ts.kind), tmp);
1364 /* We know the temporary and the value will be the same length,
1365 so can use memcpy. */
1366 gfc_trans_string_copy (&se->pre, esize, tmp, expr->ts.kind,
1367 se->string_length, se->expr, expr->ts.kind);
1369 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && !typespec_chararray_ctor)
1373 gfc_add_modify (&se->pre, first_len_val,
1379 /* Verify that all constructor elements are of the same
1381 tree cond = fold_build2_loc (input_location, NE_EXPR,
1382 boolean_type_node, first_len_val,
1384 gfc_trans_runtime_check
1385 (true, false, cond, &se->pre, &expr->where,
1386 "Different CHARACTER lengths (%ld/%ld) in array constructor",
1387 fold_convert (long_integer_type_node, first_len_val),
1388 fold_convert (long_integer_type_node, se->string_length));
1394 /* TODO: Should the frontend already have done this conversion? */
1395 se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
1396 gfc_add_modify (&se->pre, tmp, se->expr);
1399 gfc_add_block_to_block (pblock, &se->pre);
1400 gfc_add_block_to_block (pblock, &se->post);
1404 /* Add the contents of an array to the constructor. DYNAMIC is as for
1405 gfc_trans_array_constructor_value. */
1408 gfc_trans_array_constructor_subarray (stmtblock_t * pblock,
1409 tree type ATTRIBUTE_UNUSED,
1410 tree desc, gfc_expr * expr,
1411 tree * poffset, tree * offsetvar,
1422 /* We need this to be a variable so we can increment it. */
1423 gfc_put_offset_into_var (pblock, poffset, offsetvar);
1425 gfc_init_se (&se, NULL);
1427 /* Walk the array expression. */
1428 ss = gfc_walk_expr (expr);
1429 gcc_assert (ss != gfc_ss_terminator);
1431 /* Initialize the scalarizer. */
1432 gfc_init_loopinfo (&loop);
1433 gfc_add_ss_to_loop (&loop, ss);
1435 /* Initialize the loop. */
1436 gfc_conv_ss_startstride (&loop);
1437 gfc_conv_loop_setup (&loop, &expr->where);
1439 /* Make sure the constructed array has room for the new data. */
1442 /* Set SIZE to the total number of elements in the subarray. */
1443 size = gfc_index_one_node;
1444 for (n = 0; n < loop.dimen; n++)
1446 tmp = gfc_get_iteration_count (loop.from[n], loop.to[n],
1447 gfc_index_one_node);
1448 size = fold_build2_loc (input_location, MULT_EXPR,
1449 gfc_array_index_type, size, tmp);
1452 /* Grow the constructed array by SIZE elements. */
1453 gfc_grow_array (&loop.pre, desc, size);
1456 /* Make the loop body. */
1457 gfc_mark_ss_chain_used (ss, 1);
1458 gfc_start_scalarized_body (&loop, &body);
1459 gfc_copy_loopinfo_to_se (&se, &loop);
1462 gfc_trans_array_ctor_element (&body, desc, *poffset, &se, expr);
1463 gcc_assert (se.ss == gfc_ss_terminator);
1465 /* Increment the offset. */
1466 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1467 *poffset, gfc_index_one_node);
1468 gfc_add_modify (&body, *poffset, tmp);
1470 /* Finish the loop. */
1471 gfc_trans_scalarizing_loops (&loop, &body);
1472 gfc_add_block_to_block (&loop.pre, &loop.post);
1473 tmp = gfc_finish_block (&loop.pre);
1474 gfc_add_expr_to_block (pblock, tmp);
1476 gfc_cleanup_loop (&loop);
1480 /* Assign the values to the elements of an array constructor. DYNAMIC
1481 is true if descriptor DESC only contains enough data for the static
1482 size calculated by gfc_get_array_constructor_size. When true, memory
1483 for the dynamic parts must be allocated using realloc. */
1486 gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
1487 tree desc, gfc_constructor_base base,
1488 tree * poffset, tree * offsetvar,
1497 tree shadow_loopvar = NULL_TREE;
1498 gfc_saved_var saved_loopvar;
1501 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
1503 /* If this is an iterator or an array, the offset must be a variable. */
1504 if ((c->iterator || c->expr->rank > 0) && INTEGER_CST_P (*poffset))
1505 gfc_put_offset_into_var (pblock, poffset, offsetvar);
1507 /* Shadowing the iterator avoids changing its value and saves us from
1508 keeping track of it. Further, it makes sure that there's always a
1509 backend-decl for the symbol, even if there wasn't one before,
1510 e.g. in the case of an iterator that appears in a specification
1511 expression in an interface mapping. */
1514 gfc_symbol *sym = c->iterator->var->symtree->n.sym;
1515 tree type = gfc_typenode_for_spec (&sym->ts);
1517 shadow_loopvar = gfc_create_var (type, "shadow_loopvar");
1518 gfc_shadow_sym (sym, shadow_loopvar, &saved_loopvar);
1521 gfc_start_block (&body);
1523 if (c->expr->expr_type == EXPR_ARRAY)
1525 /* Array constructors can be nested. */
1526 gfc_trans_array_constructor_value (&body, type, desc,
1527 c->expr->value.constructor,
1528 poffset, offsetvar, dynamic);
1530 else if (c->expr->rank > 0)
1532 gfc_trans_array_constructor_subarray (&body, type, desc, c->expr,
1533 poffset, offsetvar, dynamic);
1537 /* This code really upsets the gimplifier so don't bother for now. */
1544 while (p && !(p->iterator || p->expr->expr_type != EXPR_CONSTANT))
1546 p = gfc_constructor_next (p);
1551 /* Scalar values. */
1552 gfc_init_se (&se, NULL);
1553 gfc_trans_array_ctor_element (&body, desc, *poffset,
1556 *poffset = fold_build2_loc (input_location, PLUS_EXPR,
1557 gfc_array_index_type,
1558 *poffset, gfc_index_one_node);
1562 /* Collect multiple scalar constants into a constructor. */
1563 VEC(constructor_elt,gc) *v = NULL;
1567 HOST_WIDE_INT idx = 0;
1570 /* Count the number of consecutive scalar constants. */
1571 while (p && !(p->iterator
1572 || p->expr->expr_type != EXPR_CONSTANT))
1574 gfc_init_se (&se, NULL);
1575 gfc_conv_constant (&se, p->expr);
1577 if (c->expr->ts.type != BT_CHARACTER)
1578 se.expr = fold_convert (type, se.expr);
1579 /* For constant character array constructors we build
1580 an array of pointers. */
1581 else if (POINTER_TYPE_P (type))
1582 se.expr = gfc_build_addr_expr
1583 (gfc_get_pchar_type (p->expr->ts.kind),
1586 CONSTRUCTOR_APPEND_ELT (v,
1587 build_int_cst (gfc_array_index_type,
1591 p = gfc_constructor_next (p);
1594 bound = size_int (n - 1);
1595 /* Create an array type to hold them. */
1596 tmptype = build_range_type (gfc_array_index_type,
1597 gfc_index_zero_node, bound);
1598 tmptype = build_array_type (type, tmptype);
1600 init = build_constructor (tmptype, v);
1601 TREE_CONSTANT (init) = 1;
1602 TREE_STATIC (init) = 1;
1603 /* Create a static variable to hold the data. */
1604 tmp = gfc_create_var (tmptype, "data");
1605 TREE_STATIC (tmp) = 1;
1606 TREE_CONSTANT (tmp) = 1;
1607 TREE_READONLY (tmp) = 1;
1608 DECL_INITIAL (tmp) = init;
1611 /* Use BUILTIN_MEMCPY to assign the values. */
1612 tmp = gfc_conv_descriptor_data_get (desc);
1613 tmp = build_fold_indirect_ref_loc (input_location,
1615 tmp = gfc_build_array_ref (tmp, *poffset, NULL);
1616 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1617 init = gfc_build_addr_expr (NULL_TREE, init);
1619 size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
1620 bound = build_int_cst (size_type_node, n * size);
1621 tmp = build_call_expr_loc (input_location,
1622 builtin_decl_explicit (BUILT_IN_MEMCPY),
1623 3, tmp, init, bound);
1624 gfc_add_expr_to_block (&body, tmp);
1626 *poffset = fold_build2_loc (input_location, PLUS_EXPR,
1627 gfc_array_index_type, *poffset,
1628 build_int_cst (gfc_array_index_type, n));
1630 if (!INTEGER_CST_P (*poffset))
1632 gfc_add_modify (&body, *offsetvar, *poffset);
1633 *poffset = *offsetvar;
1637 /* The frontend should already have done any expansions
1641 /* Pass the code as is. */
1642 tmp = gfc_finish_block (&body);
1643 gfc_add_expr_to_block (pblock, tmp);
1647 /* Build the implied do-loop. */
1648 stmtblock_t implied_do_block;
1656 loopbody = gfc_finish_block (&body);
1658 /* Create a new block that holds the implied-do loop. A temporary
1659 loop-variable is used. */
1660 gfc_start_block(&implied_do_block);
1662 /* Initialize the loop. */
1663 gfc_init_se (&se, NULL);
1664 gfc_conv_expr_val (&se, c->iterator->start);
1665 gfc_add_block_to_block (&implied_do_block, &se.pre);
1666 gfc_add_modify (&implied_do_block, shadow_loopvar, se.expr);
1668 gfc_init_se (&se, NULL);
1669 gfc_conv_expr_val (&se, c->iterator->end);
1670 gfc_add_block_to_block (&implied_do_block, &se.pre);
1671 end = gfc_evaluate_now (se.expr, &implied_do_block);
1673 gfc_init_se (&se, NULL);
1674 gfc_conv_expr_val (&se, c->iterator->step);
1675 gfc_add_block_to_block (&implied_do_block, &se.pre);
1676 step = gfc_evaluate_now (se.expr, &implied_do_block);
1678 /* If this array expands dynamically, and the number of iterations
1679 is not constant, we won't have allocated space for the static
1680 part of C->EXPR's size. Do that now. */
1681 if (dynamic && gfc_iterator_has_dynamic_bounds (c->iterator))
1683 /* Get the number of iterations. */
1684 tmp = gfc_get_iteration_count (shadow_loopvar, end, step);
1686 /* Get the static part of C->EXPR's size. */
1687 gfc_get_array_constructor_element_size (&size, c->expr);
1688 tmp2 = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1690 /* Grow the array by TMP * TMP2 elements. */
1691 tmp = fold_build2_loc (input_location, MULT_EXPR,
1692 gfc_array_index_type, tmp, tmp2);
1693 gfc_grow_array (&implied_do_block, desc, tmp);
1696 /* Generate the loop body. */
1697 exit_label = gfc_build_label_decl (NULL_TREE);
1698 gfc_start_block (&body);
1700 /* Generate the exit condition. Depending on the sign of
1701 the step variable we have to generate the correct
1703 tmp = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1704 step, build_int_cst (TREE_TYPE (step), 0));
1705 cond = fold_build3_loc (input_location, COND_EXPR,
1706 boolean_type_node, tmp,
1707 fold_build2_loc (input_location, GT_EXPR,
1708 boolean_type_node, shadow_loopvar, end),
1709 fold_build2_loc (input_location, LT_EXPR,
1710 boolean_type_node, shadow_loopvar, end));
1711 tmp = build1_v (GOTO_EXPR, exit_label);
1712 TREE_USED (exit_label) = 1;
1713 tmp = build3_v (COND_EXPR, cond, tmp,
1714 build_empty_stmt (input_location));
1715 gfc_add_expr_to_block (&body, tmp);
1717 /* The main loop body. */
1718 gfc_add_expr_to_block (&body, loopbody);
1720 /* Increase loop variable by step. */
1721 tmp = fold_build2_loc (input_location, PLUS_EXPR,
1722 TREE_TYPE (shadow_loopvar), shadow_loopvar,
1724 gfc_add_modify (&body, shadow_loopvar, tmp);
1726 /* Finish the loop. */
1727 tmp = gfc_finish_block (&body);
1728 tmp = build1_v (LOOP_EXPR, tmp);
1729 gfc_add_expr_to_block (&implied_do_block, tmp);
1731 /* Add the exit label. */
1732 tmp = build1_v (LABEL_EXPR, exit_label);
1733 gfc_add_expr_to_block (&implied_do_block, tmp);
1735 /* Finishe the implied-do loop. */
1736 tmp = gfc_finish_block(&implied_do_block);
1737 gfc_add_expr_to_block(pblock, tmp);
1739 gfc_restore_sym (c->iterator->var->symtree->n.sym, &saved_loopvar);
1746 /* A catch-all to obtain the string length for anything that is not a
1747 a substring of non-constant length, a constant, array or variable. */
1750 get_array_ctor_all_strlen (stmtblock_t *block, gfc_expr *e, tree *len)
1755 /* Don't bother if we already know the length is a constant. */
1756 if (*len && INTEGER_CST_P (*len))
1759 if (!e->ref && e->ts.u.cl && e->ts.u.cl->length
1760 && e->ts.u.cl->length->expr_type == EXPR_CONSTANT)
1763 gfc_conv_const_charlen (e->ts.u.cl);
1764 *len = e->ts.u.cl->backend_decl;
1768 /* Otherwise, be brutal even if inefficient. */
1769 ss = gfc_walk_expr (e);
1770 gfc_init_se (&se, NULL);
1772 /* No function call, in case of side effects. */
1773 se.no_function_call = 1;
1774 if (ss == gfc_ss_terminator)
1775 gfc_conv_expr (&se, e);
1777 gfc_conv_expr_descriptor (&se, e, ss);
1779 /* Fix the value. */
1780 *len = gfc_evaluate_now (se.string_length, &se.pre);
1782 gfc_add_block_to_block (block, &se.pre);
1783 gfc_add_block_to_block (block, &se.post);
1785 e->ts.u.cl->backend_decl = *len;
1790 /* Figure out the string length of a variable reference expression.
1791 Used by get_array_ctor_strlen. */
1794 get_array_ctor_var_strlen (stmtblock_t *block, gfc_expr * expr, tree * len)
1800 /* Don't bother if we already know the length is a constant. */
1801 if (*len && INTEGER_CST_P (*len))
1804 ts = &expr->symtree->n.sym->ts;
1805 for (ref = expr->ref; ref; ref = ref->next)
1810 /* Array references don't change the string length. */
1814 /* Use the length of the component. */
1815 ts = &ref->u.c.component->ts;
1819 if (ref->u.ss.start->expr_type != EXPR_CONSTANT
1820 || ref->u.ss.end->expr_type != EXPR_CONSTANT)
1822 /* Note that this might evaluate expr. */
1823 get_array_ctor_all_strlen (block, expr, len);
1826 mpz_init_set_ui (char_len, 1);
1827 mpz_add (char_len, char_len, ref->u.ss.end->value.integer);
1828 mpz_sub (char_len, char_len, ref->u.ss.start->value.integer);
1829 *len = gfc_conv_mpz_to_tree (char_len, gfc_default_integer_kind);
1830 *len = convert (gfc_charlen_type_node, *len);
1831 mpz_clear (char_len);
1839 *len = ts->u.cl->backend_decl;
1843 /* Figure out the string length of a character array constructor.
1844 If len is NULL, don't calculate the length; this happens for recursive calls
1845 when a sub-array-constructor is an element but not at the first position,
1846 so when we're not interested in the length.
1847 Returns TRUE if all elements are character constants. */
1850 get_array_ctor_strlen (stmtblock_t *block, gfc_constructor_base base, tree * len)
1857 if (gfc_constructor_first (base) == NULL)
1860 *len = build_int_cstu (gfc_charlen_type_node, 0);
1864 /* Loop over all constructor elements to find out is_const, but in len we
1865 want to store the length of the first, not the last, element. We can
1866 of course exit the loop as soon as is_const is found to be false. */
1867 for (c = gfc_constructor_first (base);
1868 c && is_const; c = gfc_constructor_next (c))
1870 switch (c->expr->expr_type)
1873 if (len && !(*len && INTEGER_CST_P (*len)))
1874 *len = build_int_cstu (gfc_charlen_type_node,
1875 c->expr->value.character.length);
1879 if (!get_array_ctor_strlen (block, c->expr->value.constructor, len))
1886 get_array_ctor_var_strlen (block, c->expr, len);
1892 get_array_ctor_all_strlen (block, c->expr, len);
1896 /* After the first iteration, we don't want the length modified. */
1903 /* Check whether the array constructor C consists entirely of constant
1904 elements, and if so returns the number of those elements, otherwise
1905 return zero. Note, an empty or NULL array constructor returns zero. */
1907 unsigned HOST_WIDE_INT
1908 gfc_constant_array_constructor_p (gfc_constructor_base base)
1910 unsigned HOST_WIDE_INT nelem = 0;
1912 gfc_constructor *c = gfc_constructor_first (base);
1916 || c->expr->rank > 0
1917 || c->expr->expr_type != EXPR_CONSTANT)
1919 c = gfc_constructor_next (c);
1926 /* Given EXPR, the constant array constructor specified by an EXPR_ARRAY,
1927 and the tree type of it's elements, TYPE, return a static constant
1928 variable that is compile-time initialized. */
1931 gfc_build_constant_array_constructor (gfc_expr * expr, tree type)
1933 tree tmptype, init, tmp;
1934 HOST_WIDE_INT nelem;
1939 VEC(constructor_elt,gc) *v = NULL;
1941 /* First traverse the constructor list, converting the constants
1942 to tree to build an initializer. */
1944 c = gfc_constructor_first (expr->value.constructor);
1947 gfc_init_se (&se, NULL);
1948 gfc_conv_constant (&se, c->expr);
1949 if (c->expr->ts.type != BT_CHARACTER)
1950 se.expr = fold_convert (type, se.expr);
1951 else if (POINTER_TYPE_P (type))
1952 se.expr = gfc_build_addr_expr (gfc_get_pchar_type (c->expr->ts.kind),
1954 CONSTRUCTOR_APPEND_ELT (v, build_int_cst (gfc_array_index_type, nelem),
1956 c = gfc_constructor_next (c);
1960 /* Next determine the tree type for the array. We use the gfortran
1961 front-end's gfc_get_nodesc_array_type in order to create a suitable
1962 GFC_ARRAY_TYPE_P that may be used by the scalarizer. */
1964 memset (&as, 0, sizeof (gfc_array_spec));
1966 as.rank = expr->rank;
1967 as.type = AS_EXPLICIT;
1970 as.lower[0] = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
1971 as.upper[0] = gfc_get_int_expr (gfc_default_integer_kind,
1975 for (i = 0; i < expr->rank; i++)
1977 int tmp = (int) mpz_get_si (expr->shape[i]);
1978 as.lower[i] = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
1979 as.upper[i] = gfc_get_int_expr (gfc_default_integer_kind,
1983 tmptype = gfc_get_nodesc_array_type (type, &as, PACKED_STATIC, true);
1985 /* as is not needed anymore. */
1986 for (i = 0; i < as.rank + as.corank; i++)
1988 gfc_free_expr (as.lower[i]);
1989 gfc_free_expr (as.upper[i]);
1992 init = build_constructor (tmptype, v);
1994 TREE_CONSTANT (init) = 1;
1995 TREE_STATIC (init) = 1;
1997 tmp = gfc_create_var (tmptype, "A");
1998 TREE_STATIC (tmp) = 1;
1999 TREE_CONSTANT (tmp) = 1;
2000 TREE_READONLY (tmp) = 1;
2001 DECL_INITIAL (tmp) = init;
2007 /* Translate a constant EXPR_ARRAY array constructor for the scalarizer.
2008 This mostly initializes the scalarizer state info structure with the
2009 appropriate values to directly use the array created by the function
2010 gfc_build_constant_array_constructor. */
2013 trans_constant_array_constructor (gfc_ss * ss, tree type)
2015 gfc_array_info *info;
2019 tmp = gfc_build_constant_array_constructor (ss->info->expr, type);
2021 info = &ss->info->data.array;
2023 info->descriptor = tmp;
2024 info->data = gfc_build_addr_expr (NULL_TREE, tmp);
2025 info->offset = gfc_index_zero_node;
2027 for (i = 0; i < ss->dimen; i++)
2029 info->delta[i] = gfc_index_zero_node;
2030 info->start[i] = gfc_index_zero_node;
2031 info->end[i] = gfc_index_zero_node;
2032 info->stride[i] = gfc_index_one_node;
2038 get_rank (gfc_loopinfo *loop)
2043 for (; loop; loop = loop->parent)
2044 rank += loop->dimen;
2050 /* Helper routine of gfc_trans_array_constructor to determine if the
2051 bounds of the loop specified by LOOP are constant and simple enough
2052 to use with trans_constant_array_constructor. Returns the
2053 iteration count of the loop if suitable, and NULL_TREE otherwise. */
2056 constant_array_constructor_loop_size (gfc_loopinfo * loop)
2058 tree size = gfc_index_one_node;
2062 for (i = 0; i < loop->dimen; i++)
2064 /* If the bounds aren't constant, return NULL_TREE. */
2065 if (!INTEGER_CST_P (loop->from[i]) || !INTEGER_CST_P (loop->to[i]))
2067 if (!integer_zerop (loop->from[i]))
2069 /* Only allow nonzero "from" in one-dimensional arrays. */
2070 if (loop->dimen != 1)
2072 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2073 gfc_array_index_type,
2074 loop->to[i], loop->from[i]);
2078 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
2079 tmp, gfc_index_one_node);
2080 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
2089 get_loop_upper_bound_for_array (gfc_ss *array, int array_dim)
2094 gcc_assert (array->nested_ss == NULL);
2096 for (ss = array; ss; ss = ss->parent)
2097 for (n = 0; n < ss->loop->dimen; n++)
2098 if (array_dim == get_array_ref_dim_for_loop_dim (ss, n))
2099 return &(ss->loop->to[n]);
2105 /* Array constructors are handled by constructing a temporary, then using that
2106 within the scalarization loop. This is not optimal, but seems by far the
2110 trans_array_constructor (gfc_ss * ss, locus * where)
2112 gfc_constructor_base c;
2120 bool old_first_len, old_typespec_chararray_ctor;
2121 tree old_first_len_val;
2123 gfc_ss_info *ss_info;
2127 /* Save the old values for nested checking. */
2128 old_first_len = first_len;
2129 old_first_len_val = first_len_val;
2130 old_typespec_chararray_ctor = typespec_chararray_ctor;
2134 expr = ss_info->expr;
2136 /* Do bounds-checking here and in gfc_trans_array_ctor_element only if no
2137 typespec was given for the array constructor. */
2138 typespec_chararray_ctor = (expr->ts.u.cl
2139 && expr->ts.u.cl->length_from_typespec);
2141 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2142 && expr->ts.type == BT_CHARACTER && !typespec_chararray_ctor)
2144 first_len_val = gfc_create_var (gfc_charlen_type_node, "len");
2148 gcc_assert (ss->dimen == ss->loop->dimen);
2150 c = expr->value.constructor;
2151 if (expr->ts.type == BT_CHARACTER)
2155 /* get_array_ctor_strlen walks the elements of the constructor, if a
2156 typespec was given, we already know the string length and want the one
2158 if (typespec_chararray_ctor && expr->ts.u.cl->length
2159 && expr->ts.u.cl->length->expr_type != EXPR_CONSTANT)
2163 const_string = false;
2164 gfc_init_se (&length_se, NULL);
2165 gfc_conv_expr_type (&length_se, expr->ts.u.cl->length,
2166 gfc_charlen_type_node);
2167 ss_info->string_length = length_se.expr;
2168 gfc_add_block_to_block (&loop->pre, &length_se.pre);
2169 gfc_add_block_to_block (&loop->post, &length_se.post);
2172 const_string = get_array_ctor_strlen (&loop->pre, c,
2173 &ss_info->string_length);
2175 /* Complex character array constructors should have been taken care of
2176 and not end up here. */
2177 gcc_assert (ss_info->string_length);
2179 expr->ts.u.cl->backend_decl = ss_info->string_length;
2181 type = gfc_get_character_type_len (expr->ts.kind, ss_info->string_length);
2183 type = build_pointer_type (type);
2186 type = gfc_typenode_for_spec (&expr->ts);
2188 /* See if the constructor determines the loop bounds. */
2191 loop_ubound0 = get_loop_upper_bound_for_array (ss, 0);
2193 if (expr->shape && get_rank (loop) > 1 && *loop_ubound0 == NULL_TREE)
2195 /* We have a multidimensional parameter. */
2196 for (s = ss; s; s = s->parent)
2199 for (n = 0; n < s->loop->dimen; n++)
2201 s->loop->from[n] = gfc_index_zero_node;
2202 s->loop->to[n] = gfc_conv_mpz_to_tree (expr->shape[s->dim[n]],
2203 gfc_index_integer_kind);
2204 s->loop->to[n] = fold_build2_loc (input_location, MINUS_EXPR,
2205 gfc_array_index_type,
2207 gfc_index_one_node);
2212 if (*loop_ubound0 == NULL_TREE)
2216 /* We should have a 1-dimensional, zero-based loop. */
2217 gcc_assert (loop->parent == NULL && loop->nested == NULL);
2218 gcc_assert (loop->dimen == 1);
2219 gcc_assert (integer_zerop (loop->from[0]));
2221 /* Split the constructor size into a static part and a dynamic part.
2222 Allocate the static size up-front and record whether the dynamic
2223 size might be nonzero. */
2225 dynamic = gfc_get_array_constructor_size (&size, c);
2226 mpz_sub_ui (size, size, 1);
2227 loop->to[0] = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
2231 /* Special case constant array constructors. */
2234 unsigned HOST_WIDE_INT nelem = gfc_constant_array_constructor_p (c);
2237 tree size = constant_array_constructor_loop_size (loop);
2238 if (size && compare_tree_int (size, nelem) == 0)
2240 trans_constant_array_constructor (ss, type);
2246 if (TREE_CODE (*loop_ubound0) == VAR_DECL)
2249 gfc_trans_create_temp_array (&loop->pre, &loop->post, ss, type, NULL_TREE,
2250 dynamic, true, false, where);
2252 desc = ss_info->data.array.descriptor;
2253 offset = gfc_index_zero_node;
2254 offsetvar = gfc_create_var_np (gfc_array_index_type, "offset");
2255 TREE_NO_WARNING (offsetvar) = 1;
2256 TREE_USED (offsetvar) = 0;
2257 gfc_trans_array_constructor_value (&loop->pre, type, desc, c,
2258 &offset, &offsetvar, dynamic);
2260 /* If the array grows dynamically, the upper bound of the loop variable
2261 is determined by the array's final upper bound. */
2264 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2265 gfc_array_index_type,
2266 offsetvar, gfc_index_one_node);
2267 tmp = gfc_evaluate_now (tmp, &loop->pre);
2268 gfc_conv_descriptor_ubound_set (&loop->pre, desc, gfc_rank_cst[0], tmp);
2269 if (*loop_ubound0 && TREE_CODE (*loop_ubound0) == VAR_DECL)
2270 gfc_add_modify (&loop->pre, *loop_ubound0, tmp);
2272 *loop_ubound0 = tmp;
2275 if (TREE_USED (offsetvar))
2276 pushdecl (offsetvar);
2278 gcc_assert (INTEGER_CST_P (offset));
2281 /* Disable bound checking for now because it's probably broken. */
2282 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2289 /* Restore old values of globals. */
2290 first_len = old_first_len;
2291 first_len_val = old_first_len_val;
2292 typespec_chararray_ctor = old_typespec_chararray_ctor;
2296 /* INFO describes a GFC_SS_SECTION in loop LOOP, and this function is
2297 called after evaluating all of INFO's vector dimensions. Go through
2298 each such vector dimension and see if we can now fill in any missing
2302 set_vector_loop_bounds (gfc_ss * ss)
2305 gfc_array_info *info;
2313 info = &ss->info->data.array;
2315 for (; ss; ss = ss->parent)
2319 for (n = 0; n < loop->dimen; n++)
2322 if (info->ref->u.ar.dimen_type[dim] != DIMEN_VECTOR
2323 || loop->to[n] != NULL)
2326 /* Loop variable N indexes vector dimension DIM, and we don't
2327 yet know the upper bound of loop variable N. Set it to the
2328 difference between the vector's upper and lower bounds. */
2329 gcc_assert (loop->from[n] == gfc_index_zero_node);
2330 gcc_assert (info->subscript[dim]
2331 && info->subscript[dim]->info->type == GFC_SS_VECTOR);
2333 gfc_init_se (&se, NULL);
2334 desc = info->subscript[dim]->info->data.array.descriptor;
2335 zero = gfc_rank_cst[0];
2336 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2337 gfc_array_index_type,
2338 gfc_conv_descriptor_ubound_get (desc, zero),
2339 gfc_conv_descriptor_lbound_get (desc, zero));
2340 tmp = gfc_evaluate_now (tmp, &loop->pre);
2347 /* Add the pre and post chains for all the scalar expressions in a SS chain
2348 to loop. This is called after the loop parameters have been calculated,
2349 but before the actual scalarizing loops. */
2352 gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript,
2355 gfc_loopinfo *nested_loop;
2357 gfc_ss_info *ss_info;
2358 gfc_array_info *info;
2360 bool skip_nested = false;
2363 /* TODO: This can generate bad code if there are ordering dependencies,
2364 e.g., a callee allocated function and an unknown size constructor. */
2365 gcc_assert (ss != NULL);
2367 for (; ss != gfc_ss_terminator; ss = ss->loop_chain)
2371 /* Cross loop arrays are handled from within the most nested loop. */
2372 if (ss->nested_ss != NULL)
2376 expr = ss_info->expr;
2377 info = &ss_info->data.array;
2379 switch (ss_info->type)
2382 /* Scalar expression. Evaluate this now. This includes elemental
2383 dimension indices, but not array section bounds. */
2384 gfc_init_se (&se, NULL);
2385 gfc_conv_expr (&se, expr);
2386 gfc_add_block_to_block (&loop->pre, &se.pre);
2388 if (expr->ts.type != BT_CHARACTER)
2390 /* Move the evaluation of scalar expressions outside the
2391 scalarization loop, except for WHERE assignments. */
2393 se.expr = convert(gfc_array_index_type, se.expr);
2394 if (!ss_info->where)
2395 se.expr = gfc_evaluate_now (se.expr, &loop->pre);
2396 gfc_add_block_to_block (&loop->pre, &se.post);
2399 gfc_add_block_to_block (&loop->post, &se.post);
2401 ss_info->data.scalar.value = se.expr;
2402 ss_info->string_length = se.string_length;
2405 case GFC_SS_REFERENCE:
2406 /* Scalar argument to elemental procedure. Evaluate this
2408 gfc_init_se (&se, NULL);
2409 gfc_conv_expr (&se, expr);
2410 gfc_add_block_to_block (&loop->pre, &se.pre);
2411 gfc_add_block_to_block (&loop->post, &se.post);
2413 ss_info->data.scalar.value = gfc_evaluate_now (se.expr, &loop->pre);
2414 ss_info->string_length = se.string_length;
2417 case GFC_SS_SECTION:
2418 /* Add the expressions for scalar and vector subscripts. */
2419 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
2420 if (info->subscript[n])
2422 gfc_add_loop_ss_code (loop, info->subscript[n], true, where);
2423 /* The recursive call will have taken care of the nested loops.
2424 No need to do it twice. */
2428 set_vector_loop_bounds (ss);
2432 /* Get the vector's descriptor and store it in SS. */
2433 gfc_init_se (&se, NULL);
2434 gfc_conv_expr_descriptor (&se, expr, gfc_walk_expr (expr));
2435 gfc_add_block_to_block (&loop->pre, &se.pre);
2436 gfc_add_block_to_block (&loop->post, &se.post);
2437 info->descriptor = se.expr;
2440 case GFC_SS_INTRINSIC:
2441 gfc_add_intrinsic_ss_code (loop, ss);
2444 case GFC_SS_FUNCTION:
2445 /* Array function return value. We call the function and save its
2446 result in a temporary for use inside the loop. */
2447 gfc_init_se (&se, NULL);
2450 gfc_conv_expr (&se, expr);
2451 gfc_add_block_to_block (&loop->pre, &se.pre);
2452 gfc_add_block_to_block (&loop->post, &se.post);
2453 ss_info->string_length = se.string_length;
2456 case GFC_SS_CONSTRUCTOR:
2457 if (expr->ts.type == BT_CHARACTER
2458 && ss_info->string_length == NULL
2460 && expr->ts.u.cl->length)
2462 gfc_init_se (&se, NULL);
2463 gfc_conv_expr_type (&se, expr->ts.u.cl->length,
2464 gfc_charlen_type_node);
2465 ss_info->string_length = se.expr;
2466 gfc_add_block_to_block (&loop->pre, &se.pre);
2467 gfc_add_block_to_block (&loop->post, &se.post);
2469 trans_array_constructor (ss, where);
2473 case GFC_SS_COMPONENT:
2474 /* Do nothing. These are handled elsewhere. */
2483 for (nested_loop = loop->nested; nested_loop;
2484 nested_loop = nested_loop->next)
2485 gfc_add_loop_ss_code (nested_loop, nested_loop->ss, subscript, where);
2489 /* Translate expressions for the descriptor and data pointer of a SS. */
2493 gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)
2496 gfc_ss_info *ss_info;
2497 gfc_array_info *info;
2501 info = &ss_info->data.array;
2503 /* Get the descriptor for the array to be scalarized. */
2504 gcc_assert (ss_info->expr->expr_type == EXPR_VARIABLE);
2505 gfc_init_se (&se, NULL);
2506 se.descriptor_only = 1;
2507 gfc_conv_expr_lhs (&se, ss_info->expr);
2508 gfc_add_block_to_block (block, &se.pre);
2509 info->descriptor = se.expr;
2510 ss_info->string_length = se.string_length;
2514 /* Also the data pointer. */
2515 tmp = gfc_conv_array_data (se.expr);
2516 /* If this is a variable or address of a variable we use it directly.
2517 Otherwise we must evaluate it now to avoid breaking dependency
2518 analysis by pulling the expressions for elemental array indices
2521 || (TREE_CODE (tmp) == ADDR_EXPR
2522 && DECL_P (TREE_OPERAND (tmp, 0)))))
2523 tmp = gfc_evaluate_now (tmp, block);
2526 tmp = gfc_conv_array_offset (se.expr);
2527 info->offset = gfc_evaluate_now (tmp, block);
2529 /* Make absolutely sure that the saved_offset is indeed saved
2530 so that the variable is still accessible after the loops
2532 info->saved_offset = info->offset;
2537 /* Initialize a gfc_loopinfo structure. */
2540 gfc_init_loopinfo (gfc_loopinfo * loop)
2544 memset (loop, 0, sizeof (gfc_loopinfo));
2545 gfc_init_block (&loop->pre);
2546 gfc_init_block (&loop->post);
2548 /* Initially scalarize in order and default to no loop reversal. */
2549 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
2552 loop->reverse[n] = GFC_INHIBIT_REVERSE;
2555 loop->ss = gfc_ss_terminator;
2559 /* Copies the loop variable info to a gfc_se structure. Does not copy the SS
2563 gfc_copy_loopinfo_to_se (gfc_se * se, gfc_loopinfo * loop)
2569 /* Return an expression for the data pointer of an array. */
2572 gfc_conv_array_data (tree descriptor)
2576 type = TREE_TYPE (descriptor);
2577 if (GFC_ARRAY_TYPE_P (type))
2579 if (TREE_CODE (type) == POINTER_TYPE)
2583 /* Descriptorless arrays. */
2584 return gfc_build_addr_expr (NULL_TREE, descriptor);
2588 return gfc_conv_descriptor_data_get (descriptor);
2592 /* Return an expression for the base offset of an array. */
2595 gfc_conv_array_offset (tree descriptor)
2599 type = TREE_TYPE (descriptor);
2600 if (GFC_ARRAY_TYPE_P (type))
2601 return GFC_TYPE_ARRAY_OFFSET (type);
2603 return gfc_conv_descriptor_offset_get (descriptor);
2607 /* Get an expression for the array stride. */
2610 gfc_conv_array_stride (tree descriptor, int dim)
2615 type = TREE_TYPE (descriptor);
2617 /* For descriptorless arrays use the array size. */
2618 tmp = GFC_TYPE_ARRAY_STRIDE (type, dim);
2619 if (tmp != NULL_TREE)
2622 tmp = gfc_conv_descriptor_stride_get (descriptor, gfc_rank_cst[dim]);
2627 /* Like gfc_conv_array_stride, but for the lower bound. */
2630 gfc_conv_array_lbound (tree descriptor, int dim)
2635 type = TREE_TYPE (descriptor);
2637 tmp = GFC_TYPE_ARRAY_LBOUND (type, dim);
2638 if (tmp != NULL_TREE)
2641 tmp = gfc_conv_descriptor_lbound_get (descriptor, gfc_rank_cst[dim]);
2646 /* Like gfc_conv_array_stride, but for the upper bound. */
2649 gfc_conv_array_ubound (tree descriptor, int dim)
2654 type = TREE_TYPE (descriptor);
2656 tmp = GFC_TYPE_ARRAY_UBOUND (type, dim);
2657 if (tmp != NULL_TREE)
2660 /* This should only ever happen when passing an assumed shape array
2661 as an actual parameter. The value will never be used. */
2662 if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor)))
2663 return gfc_index_zero_node;
2665 tmp = gfc_conv_descriptor_ubound_get (descriptor, gfc_rank_cst[dim]);
2670 /* Generate code to perform an array index bound check. */
2673 trans_array_bound_check (gfc_se * se, gfc_ss *ss, tree index, int n,
2674 locus * where, bool check_upper)
2677 tree tmp_lo, tmp_up;
2680 const char * name = NULL;
2682 if (!(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
2685 descriptor = ss->info->data.array.descriptor;
2687 index = gfc_evaluate_now (index, &se->pre);
2689 /* We find a name for the error message. */
2690 name = ss->info->expr->symtree->n.sym->name;
2691 gcc_assert (name != NULL);
2693 if (TREE_CODE (descriptor) == VAR_DECL)
2694 name = IDENTIFIER_POINTER (DECL_NAME (descriptor));
2696 /* If upper bound is present, include both bounds in the error message. */
2699 tmp_lo = gfc_conv_array_lbound (descriptor, n);
2700 tmp_up = gfc_conv_array_ubound (descriptor, n);
2703 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
2704 "outside of expected range (%%ld:%%ld)", n+1, name);
2706 asprintf (&msg, "Index '%%ld' of dimension %d "
2707 "outside of expected range (%%ld:%%ld)", n+1);
2709 fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
2711 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2712 fold_convert (long_integer_type_node, index),
2713 fold_convert (long_integer_type_node, tmp_lo),
2714 fold_convert (long_integer_type_node, tmp_up));
2715 fault = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
2717 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2718 fold_convert (long_integer_type_node, index),
2719 fold_convert (long_integer_type_node, tmp_lo),
2720 fold_convert (long_integer_type_node, tmp_up));
2725 tmp_lo = gfc_conv_array_lbound (descriptor, n);
2728 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
2729 "below lower bound of %%ld", n+1, name);
2731 asprintf (&msg, "Index '%%ld' of dimension %d "
2732 "below lower bound of %%ld", n+1);
2734 fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
2736 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2737 fold_convert (long_integer_type_node, index),
2738 fold_convert (long_integer_type_node, tmp_lo));
2746 /* Return the offset for an index. Performs bound checking for elemental
2747 dimensions. Single element references are processed separately.
2748 DIM is the array dimension, I is the loop dimension. */
2751 conv_array_index_offset (gfc_se * se, gfc_ss * ss, int dim, int i,
2752 gfc_array_ref * ar, tree stride)
2754 gfc_array_info *info;
2759 info = &ss->info->data.array;
2761 /* Get the index into the array for this dimension. */
2764 gcc_assert (ar->type != AR_ELEMENT);
2765 switch (ar->dimen_type[dim])
2767 case DIMEN_THIS_IMAGE:
2771 /* Elemental dimension. */
2772 gcc_assert (info->subscript[dim]
2773 && info->subscript[dim]->info->type == GFC_SS_SCALAR);
2774 /* We've already translated this value outside the loop. */
2775 index = info->subscript[dim]->info->data.scalar.value;
2777 index = trans_array_bound_check (se, ss, index, dim, &ar->where,
2778 ar->as->type != AS_ASSUMED_SIZE
2779 || dim < ar->dimen - 1);
2783 gcc_assert (info && se->loop);
2784 gcc_assert (info->subscript[dim]
2785 && info->subscript[dim]->info->type == GFC_SS_VECTOR);
2786 desc = info->subscript[dim]->info->data.array.descriptor;
2788 /* Get a zero-based index into the vector. */
2789 index = fold_build2_loc (input_location, MINUS_EXPR,
2790 gfc_array_index_type,
2791 se->loop->loopvar[i], se->loop->from[i]);
2793 /* Multiply the index by the stride. */
2794 index = fold_build2_loc (input_location, MULT_EXPR,
2795 gfc_array_index_type,
2796 index, gfc_conv_array_stride (desc, 0));
2798 /* Read the vector to get an index into info->descriptor. */
2799 data = build_fold_indirect_ref_loc (input_location,
2800 gfc_conv_array_data (desc));
2801 index = gfc_build_array_ref (data, index, NULL);
2802 index = gfc_evaluate_now (index, &se->pre);
2803 index = fold_convert (gfc_array_index_type, index);
2805 /* Do any bounds checking on the final info->descriptor index. */
2806 index = trans_array_bound_check (se, ss, index, dim, &ar->where,
2807 ar->as->type != AS_ASSUMED_SIZE
2808 || dim < ar->dimen - 1);
2812 /* Scalarized dimension. */
2813 gcc_assert (info && se->loop);
2815 /* Multiply the loop variable by the stride and delta. */
2816 index = se->loop->loopvar[i];
2817 if (!integer_onep (info->stride[dim]))
2818 index = fold_build2_loc (input_location, MULT_EXPR,
2819 gfc_array_index_type, index,
2821 if (!integer_zerop (info->delta[dim]))
2822 index = fold_build2_loc (input_location, PLUS_EXPR,
2823 gfc_array_index_type, index,
2833 /* Temporary array or derived type component. */
2834 gcc_assert (se->loop);
2835 index = se->loop->loopvar[se->loop->order[i]];
2837 /* Pointer functions can have stride[0] different from unity.
2838 Use the stride returned by the function call and stored in
2839 the descriptor for the temporary. */
2840 if (se->ss && se->ss->info->type == GFC_SS_FUNCTION
2841 && se->ss->info->expr
2842 && se->ss->info->expr->symtree
2843 && se->ss->info->expr->symtree->n.sym->result
2844 && se->ss->info->expr->symtree->n.sym->result->attr.pointer)
2845 stride = gfc_conv_descriptor_stride_get (info->descriptor,
2848 if (!integer_zerop (info->delta[dim]))
2849 index = fold_build2_loc (input_location, PLUS_EXPR,
2850 gfc_array_index_type, index, info->delta[dim]);
2853 /* Multiply by the stride. */
2854 if (!integer_onep (stride))
2855 index = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
2862 /* Build a scalarized reference to an array. */
2865 gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
2867 gfc_array_info *info;
2868 tree decl = NULL_TREE;
2876 expr = ss->info->expr;
2877 info = &ss->info->data.array;
2879 n = se->loop->order[0];
2883 index = conv_array_index_offset (se, ss, ss->dim[n], n, ar, info->stride0);
2884 /* Add the offset for this dimension to the stored offset for all other
2886 if (!integer_zerop (info->offset))
2887 index = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
2888 index, info->offset);
2890 if (expr && is_subref_array (expr))
2891 decl = expr->symtree->n.sym->backend_decl;
2893 tmp = build_fold_indirect_ref_loc (input_location, info->data);
2894 se->expr = gfc_build_array_ref (tmp, index, decl);
2898 /* Translate access of temporary array. */
2901 gfc_conv_tmp_array_ref (gfc_se * se)
2903 se->string_length = se->ss->info->string_length;
2904 gfc_conv_scalarized_array_ref (se, NULL);
2905 gfc_advance_se_ss_chain (se);
2908 /* Add T to the offset pair *OFFSET, *CST_OFFSET. */
2911 add_to_offset (tree *cst_offset, tree *offset, tree t)
2913 if (TREE_CODE (t) == INTEGER_CST)
2914 *cst_offset = int_const_binop (PLUS_EXPR, *cst_offset, t);
2917 if (!integer_zerop (*offset))
2918 *offset = fold_build2_loc (input_location, PLUS_EXPR,
2919 gfc_array_index_type, *offset, t);
2925 /* Build an array reference. se->expr already holds the array descriptor.
2926 This should be either a variable, indirect variable reference or component
2927 reference. For arrays which do not have a descriptor, se->expr will be
2929 a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
2932 gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym,
2936 tree offset, cst_offset;
2944 gcc_assert (ar->codimen);
2946 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se->expr)))
2947 se->expr = build_fold_indirect_ref (gfc_conv_array_data (se->expr));
2950 if (GFC_ARRAY_TYPE_P (TREE_TYPE (se->expr))
2951 && TREE_CODE (TREE_TYPE (se->expr)) == POINTER_TYPE)
2952 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
2954 /* Use the actual tree type and not the wrapped coarray. */
2955 if (!se->want_pointer)
2956 se->expr = fold_convert (TYPE_MAIN_VARIANT (TREE_TYPE (se->expr)),
2963 /* Handle scalarized references separately. */
2964 if (ar->type != AR_ELEMENT)
2966 gfc_conv_scalarized_array_ref (se, ar);
2967 gfc_advance_se_ss_chain (se);
2971 cst_offset = offset = gfc_index_zero_node;
2972 add_to_offset (&cst_offset, &offset, gfc_conv_array_offset (se->expr));
2974 /* Calculate the offsets from all the dimensions. Make sure to associate
2975 the final offset so that we form a chain of loop invariant summands. */
2976 for (n = ar->dimen - 1; n >= 0; n--)
2978 /* Calculate the index for this dimension. */
2979 gfc_init_se (&indexse, se);
2980 gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type);
2981 gfc_add_block_to_block (&se->pre, &indexse.pre);
2983 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2985 /* Check array bounds. */
2989 /* Evaluate the indexse.expr only once. */
2990 indexse.expr = save_expr (indexse.expr);
2993 tmp = gfc_conv_array_lbound (se->expr, n);
2994 if (sym->attr.temporary)
2996 gfc_init_se (&tmpse, se);
2997 gfc_conv_expr_type (&tmpse, ar->as->lower[n],
2998 gfc_array_index_type);
2999 gfc_add_block_to_block (&se->pre, &tmpse.pre);
3003 cond = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
3005 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3006 "below lower bound of %%ld", n+1, sym->name);
3007 gfc_trans_runtime_check (true, false, cond, &se->pre, where, msg,
3008 fold_convert (long_integer_type_node,
3010 fold_convert (long_integer_type_node, tmp));
3013 /* Upper bound, but not for the last dimension of assumed-size
3015 if (n < ar->dimen - 1 || ar->as->type != AS_ASSUMED_SIZE)
3017 tmp = gfc_conv_array_ubound (se->expr, n);
3018 if (sym->attr.temporary)
3020 gfc_init_se (&tmpse, se);
3021 gfc_conv_expr_type (&tmpse, ar->as->upper[n],
3022 gfc_array_index_type);
3023 gfc_add_block_to_block (&se->pre, &tmpse.pre);
3027 cond = fold_build2_loc (input_location, GT_EXPR,
3028 boolean_type_node, indexse.expr, tmp);
3029 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3030 "above upper bound of %%ld", n+1, sym->name);
3031 gfc_trans_runtime_check (true, false, cond, &se->pre, where, msg,
3032 fold_convert (long_integer_type_node,
3034 fold_convert (long_integer_type_node, tmp));
3039 /* Multiply the index by the stride. */
3040 stride = gfc_conv_array_stride (se->expr, n);
3041 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
3042 indexse.expr, stride);
3044 /* And add it to the total. */
3045 add_to_offset (&cst_offset, &offset, tmp);
3048 if (!integer_zerop (cst_offset))
3049 offset = fold_build2_loc (input_location, PLUS_EXPR,
3050 gfc_array_index_type, offset, cst_offset);
3052 /* Access the calculated element. */
3053 tmp = gfc_conv_array_data (se->expr);
3054 tmp = build_fold_indirect_ref (tmp);
3055 se->expr = gfc_build_array_ref (tmp, offset, sym->backend_decl);
3059 /* Add the offset corresponding to array's ARRAY_DIM dimension and loop's
3060 LOOP_DIM dimension (if any) to array's offset. */
3063 add_array_offset (stmtblock_t *pblock, gfc_loopinfo *loop, gfc_ss *ss,
3064 gfc_array_ref *ar, int array_dim, int loop_dim)
3067 gfc_array_info *info;
3070 info = &ss->info->data.array;
3072 gfc_init_se (&se, NULL);
3074 se.expr = info->descriptor;
3075 stride = gfc_conv_array_stride (info->descriptor, array_dim);
3076 index = conv_array_index_offset (&se, ss, array_dim, loop_dim, ar, stride);
3077 gfc_add_block_to_block (pblock, &se.pre);
3079 info->offset = fold_build2_loc (input_location, PLUS_EXPR,
3080 gfc_array_index_type,
3081 info->offset, index);
3082 info->offset = gfc_evaluate_now (info->offset, pblock);
3086 /* Generate the code to be executed immediately before entering a
3087 scalarization loop. */
3090 gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
3091 stmtblock_t * pblock)
3094 gfc_ss_info *ss_info;
3095 gfc_array_info *info;
3096 gfc_ss_type ss_type;
3101 /* This code will be executed before entering the scalarization loop
3102 for this dimension. */
3103 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3107 if ((ss_info->useflags & flag) == 0)
3110 ss_type = ss_info->type;
3111 if (ss_type != GFC_SS_SECTION
3112 && ss_type != GFC_SS_FUNCTION
3113 && ss_type != GFC_SS_CONSTRUCTOR
3114 && ss_type != GFC_SS_COMPONENT)
3117 info = &ss_info->data.array;
3119 gcc_assert (dim < ss->dimen);
3120 gcc_assert (ss->dimen == loop->dimen);
3123 ar = &info->ref->u.ar;
3127 if (dim == loop->dimen - 1)
3132 /* For the time being, there is no loop reordering. */
3133 gcc_assert (i == loop->order[i]);
3136 if (dim == loop->dimen - 1)
3138 stride = gfc_conv_array_stride (info->descriptor, ss->dim[i]);
3140 /* Calculate the stride of the innermost loop. Hopefully this will
3141 allow the backend optimizers to do their stuff more effectively.
3143 info->stride0 = gfc_evaluate_now (stride, pblock);
3145 /* For the outermost loop calculate the offset due to any
3146 elemental dimensions. It will have been initialized with the
3147 base offset of the array. */
3150 for (i = 0; i < ar->dimen; i++)
3152 if (ar->dimen_type[i] != DIMEN_ELEMENT)
3155 add_array_offset (pblock, loop, ss, ar, i, /* unused */ -1);
3160 /* Add the offset for the previous loop dimension. */
3161 add_array_offset (pblock, loop, ss, ar, ss->dim[i], i);
3163 /* Remember this offset for the second loop. */
3164 if (dim == loop->temp_dim - 1)
3165 info->saved_offset = info->offset;
3170 /* Start a scalarized expression. Creates a scope and declares loop
3174 gfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody)
3180 gcc_assert (!loop->array_parameter);
3182 for (dim = loop->dimen - 1; dim >= 0; dim--)
3184 n = loop->order[dim];
3186 gfc_start_block (&loop->code[n]);
3188 /* Create the loop variable. */
3189 loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "S");
3191 if (dim < loop->temp_dim)
3195 /* Calculate values that will be constant within this loop. */
3196 gfc_trans_preloop_setup (loop, dim, flags, &loop->code[n]);
3198 gfc_start_block (pbody);
3202 /* Generates the actual loop code for a scalarization loop. */
3205 gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
3206 stmtblock_t * pbody)
3217 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS))
3218 == (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS)
3219 && n == loop->dimen - 1)
3221 /* We create an OMP_FOR construct for the outermost scalarized loop. */
3222 init = make_tree_vec (1);
3223 cond = make_tree_vec (1);
3224 incr = make_tree_vec (1);
3226 /* Cycle statement is implemented with a goto. Exit statement must not
3227 be present for this loop. */
3228 exit_label = gfc_build_label_decl (NULL_TREE);
3229 TREE_USED (exit_label) = 1;
3231 /* Label for cycle statements (if needed). */
3232 tmp = build1_v (LABEL_EXPR, exit_label);
3233 gfc_add_expr_to_block (pbody, tmp);
3235 stmt = make_node (OMP_FOR);
3237 TREE_TYPE (stmt) = void_type_node;
3238 OMP_FOR_BODY (stmt) = loopbody = gfc_finish_block (pbody);
3240 OMP_FOR_CLAUSES (stmt) = build_omp_clause (input_location,
3241 OMP_CLAUSE_SCHEDULE);
3242 OMP_CLAUSE_SCHEDULE_KIND (OMP_FOR_CLAUSES (stmt))
3243 = OMP_CLAUSE_SCHEDULE_STATIC;
3244 if (ompws_flags & OMPWS_NOWAIT)
3245 OMP_CLAUSE_CHAIN (OMP_FOR_CLAUSES (stmt))
3246 = build_omp_clause (input_location, OMP_CLAUSE_NOWAIT);
3248 /* Initialize the loopvar. */
3249 TREE_VEC_ELT (init, 0) = build2_v (MODIFY_EXPR, loop->loopvar[n],
3251 OMP_FOR_INIT (stmt) = init;
3252 /* The exit condition. */
3253 TREE_VEC_ELT (cond, 0) = build2_loc (input_location, LE_EXPR,
3255 loop->loopvar[n], loop->to[n]);
3256 SET_EXPR_LOCATION (TREE_VEC_ELT (cond, 0), input_location);
3257 OMP_FOR_COND (stmt) = cond;
3258 /* Increment the loopvar. */
3259 tmp = build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3260 loop->loopvar[n], gfc_index_one_node);
3261 TREE_VEC_ELT (incr, 0) = fold_build2_loc (input_location, MODIFY_EXPR,
3262 void_type_node, loop->loopvar[n], tmp);
3263 OMP_FOR_INCR (stmt) = incr;
3265 ompws_flags &= ~OMPWS_CURR_SINGLEUNIT;
3266 gfc_add_expr_to_block (&loop->code[n], stmt);
3270 bool reverse_loop = (loop->reverse[n] == GFC_REVERSE_SET)
3271 && (loop->temp_ss == NULL);
3273 loopbody = gfc_finish_block (pbody);
3277 tmp = loop->from[n];
3278 loop->from[n] = loop->to[n];
3282 /* Initialize the loopvar. */
3283 if (loop->loopvar[n] != loop->from[n])
3284 gfc_add_modify (&loop->code[n], loop->loopvar[n], loop->from[n]);
3286 exit_label = gfc_build_label_decl (NULL_TREE);
3288 /* Generate the loop body. */
3289 gfc_init_block (&block);
3291 /* The exit condition. */
3292 cond = fold_build2_loc (input_location, reverse_loop ? LT_EXPR : GT_EXPR,
3293 boolean_type_node, loop->loopvar[n], loop->to[n]);
3294 tmp = build1_v (GOTO_EXPR, exit_label);
3295 TREE_USED (exit_label) = 1;
3296 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
3297 gfc_add_expr_to_block (&block, tmp);
3299 /* The main body. */
3300 gfc_add_expr_to_block (&block, loopbody);
3302 /* Increment the loopvar. */
3303 tmp = fold_build2_loc (input_location,
3304 reverse_loop ? MINUS_EXPR : PLUS_EXPR,
3305 gfc_array_index_type, loop->loopvar[n],
3306 gfc_index_one_node);
3308 gfc_add_modify (&block, loop->loopvar[n], tmp);
3310 /* Build the loop. */
3311 tmp = gfc_finish_block (&block);
3312 tmp = build1_v (LOOP_EXPR, tmp);
3313 gfc_add_expr_to_block (&loop->code[n], tmp);
3315 /* Add the exit label. */
3316 tmp = build1_v (LABEL_EXPR, exit_label);
3317 gfc_add_expr_to_block (&loop->code[n], tmp);
3323 /* Finishes and generates the loops for a scalarized expression. */
3326 gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body)
3331 stmtblock_t *pblock;
3335 /* Generate the loops. */
3336 for (dim = 0; dim < loop->dimen; dim++)
3338 n = loop->order[dim];
3339 gfc_trans_scalarized_loop_end (loop, n, pblock);
3340 loop->loopvar[n] = NULL_TREE;
3341 pblock = &loop->code[n];
3344 tmp = gfc_finish_block (pblock);
3345 gfc_add_expr_to_block (&loop->pre, tmp);
3347 /* Clear all the used flags. */
3348 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3349 if (ss->parent == NULL)
3350 ss->info->useflags = 0;
3354 /* Finish the main body of a scalarized expression, and start the secondary
3358 gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
3362 stmtblock_t *pblock;
3366 /* We finish as many loops as are used by the temporary. */
3367 for (dim = 0; dim < loop->temp_dim - 1; dim++)
3369 n = loop->order[dim];
3370 gfc_trans_scalarized_loop_end (loop, n, pblock);
3371 loop->loopvar[n] = NULL_TREE;
3372 pblock = &loop->code[n];
3375 /* We don't want to finish the outermost loop entirely. */
3376 n = loop->order[loop->temp_dim - 1];
3377 gfc_trans_scalarized_loop_end (loop, n, pblock);
3379 /* Restore the initial offsets. */
3380 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3382 gfc_ss_type ss_type;
3383 gfc_ss_info *ss_info;
3387 if ((ss_info->useflags & 2) == 0)
3390 ss_type = ss_info->type;
3391 if (ss_type != GFC_SS_SECTION
3392 && ss_type != GFC_SS_FUNCTION
3393 && ss_type != GFC_SS_CONSTRUCTOR
3394 && ss_type != GFC_SS_COMPONENT)
3397 ss_info->data.array.offset = ss_info->data.array.saved_offset;
3400 /* Restart all the inner loops we just finished. */
3401 for (dim = loop->temp_dim - 2; dim >= 0; dim--)
3403 n = loop->order[dim];
3405 gfc_start_block (&loop->code[n]);
3407 loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "Q");
3409 gfc_trans_preloop_setup (loop, dim, 2, &loop->code[n]);
3412 /* Start a block for the secondary copying code. */
3413 gfc_start_block (body);
3417 /* Precalculate (either lower or upper) bound of an array section.
3418 BLOCK: Block in which the (pre)calculation code will go.
3419 BOUNDS[DIM]: Where the bound value will be stored once evaluated.
3420 VALUES[DIM]: Specified bound (NULL <=> unspecified).
3421 DESC: Array descriptor from which the bound will be picked if unspecified
3422 (either lower or upper bound according to LBOUND). */
3425 evaluate_bound (stmtblock_t *block, tree *bounds, gfc_expr ** values,
3426 tree desc, int dim, bool lbound)