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)
611 while (ss != gfc_ss_terminator)
613 gcc_assert (ss != NULL);
614 next = ss->loop_chain;
622 set_ss_loop (gfc_ss *ss, gfc_loopinfo *loop)
626 for (; ss != gfc_ss_terminator; ss = ss->next)
630 if (ss->info->type == GFC_SS_SCALAR
631 || ss->info->type == GFC_SS_REFERENCE
632 || ss->info->type == GFC_SS_TEMP)
635 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
636 if (ss->info->data.array.subscript[n] != NULL)
637 set_ss_loop (ss->info->data.array.subscript[n], loop);
642 /* Associate a SS chain with a loop. */
645 gfc_add_ss_to_loop (gfc_loopinfo * loop, gfc_ss * head)
649 if (head == gfc_ss_terminator)
652 set_ss_loop (head, loop);
655 for (; ss && ss != gfc_ss_terminator; ss = ss->next)
657 if (ss->next == gfc_ss_terminator)
658 ss->loop_chain = loop->ss;
660 ss->loop_chain = ss->next;
662 gcc_assert (ss == gfc_ss_terminator);
667 /* Generate an initializer for a static pointer or allocatable array. */
670 gfc_trans_static_array_pointer (gfc_symbol * sym)
674 gcc_assert (TREE_STATIC (sym->backend_decl));
675 /* Just zero the data member. */
676 type = TREE_TYPE (sym->backend_decl);
677 DECL_INITIAL (sym->backend_decl) = gfc_build_null_descriptor (type);
681 /* If the bounds of SE's loop have not yet been set, see if they can be
682 determined from array spec AS, which is the array spec of a called
683 function. MAPPING maps the callee's dummy arguments to the values
684 that the caller is passing. Add any initialization and finalization
688 gfc_set_loop_bounds_from_array_spec (gfc_interface_mapping * mapping,
689 gfc_se * se, gfc_array_spec * as)
697 if (as && as->type == AS_EXPLICIT)
698 for (n = 0; n < se->loop->dimen; n++)
700 dim = se->ss->dim[n];
701 gcc_assert (dim < as->rank);
702 gcc_assert (se->loop->dimen == as->rank);
703 if (se->loop->to[n] == NULL_TREE)
705 /* Evaluate the lower bound. */
706 gfc_init_se (&tmpse, NULL);
707 gfc_apply_interface_mapping (mapping, &tmpse, as->lower[dim]);
708 gfc_add_block_to_block (&se->pre, &tmpse.pre);
709 gfc_add_block_to_block (&se->post, &tmpse.post);
710 lower = fold_convert (gfc_array_index_type, tmpse.expr);
712 /* ...and the upper bound. */
713 gfc_init_se (&tmpse, NULL);
714 gfc_apply_interface_mapping (mapping, &tmpse, as->upper[dim]);
715 gfc_add_block_to_block (&se->pre, &tmpse.pre);
716 gfc_add_block_to_block (&se->post, &tmpse.post);
717 upper = fold_convert (gfc_array_index_type, tmpse.expr);
719 /* Set the upper bound of the loop to UPPER - LOWER. */
720 tmp = fold_build2_loc (input_location, MINUS_EXPR,
721 gfc_array_index_type, upper, lower);
722 tmp = gfc_evaluate_now (tmp, &se->pre);
723 se->loop->to[n] = tmp;
729 /* Generate code to allocate an array temporary, or create a variable to
730 hold the data. If size is NULL, zero the descriptor so that the
731 callee will allocate the array. If DEALLOC is true, also generate code to
732 free the array afterwards.
734 If INITIAL is not NULL, it is packed using internal_pack and the result used
735 as data instead of allocating a fresh, unitialized area of memory.
737 Initialization code is added to PRE and finalization code to POST.
738 DYNAMIC is true if the caller may want to extend the array later
739 using realloc. This prevents us from putting the array on the stack. */
742 gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
743 gfc_array_info * info, tree size, tree nelem,
744 tree initial, bool dynamic, bool dealloc)
750 desc = info->descriptor;
751 info->offset = gfc_index_zero_node;
752 if (size == NULL_TREE || integer_zerop (size))
754 /* A callee allocated array. */
755 gfc_conv_descriptor_data_set (pre, desc, null_pointer_node);
760 /* Allocate the temporary. */
761 onstack = !dynamic && initial == NULL_TREE
762 && (gfc_option.flag_stack_arrays
763 || gfc_can_put_var_on_stack (size));
767 /* Make a temporary variable to hold the data. */
768 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (nelem),
769 nelem, gfc_index_one_node);
770 tmp = gfc_evaluate_now (tmp, pre);
771 tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
773 tmp = build_array_type (gfc_get_element_type (TREE_TYPE (desc)),
775 tmp = gfc_create_var (tmp, "A");
776 /* If we're here only because of -fstack-arrays we have to
777 emit a DECL_EXPR to make the gimplifier emit alloca calls. */
778 if (!gfc_can_put_var_on_stack (size))
779 gfc_add_expr_to_block (pre,
780 fold_build1_loc (input_location,
781 DECL_EXPR, TREE_TYPE (tmp),
783 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
784 gfc_conv_descriptor_data_set (pre, desc, tmp);
788 /* Allocate memory to hold the data or call internal_pack. */
789 if (initial == NULL_TREE)
791 tmp = gfc_call_malloc (pre, NULL, size);
792 tmp = gfc_evaluate_now (tmp, pre);
799 stmtblock_t do_copying;
801 tmp = TREE_TYPE (initial); /* Pointer to descriptor. */
802 gcc_assert (TREE_CODE (tmp) == POINTER_TYPE);
803 tmp = TREE_TYPE (tmp); /* The descriptor itself. */
804 tmp = gfc_get_element_type (tmp);
805 gcc_assert (tmp == gfc_get_element_type (TREE_TYPE (desc)));
806 packed = gfc_create_var (build_pointer_type (tmp), "data");
808 tmp = build_call_expr_loc (input_location,
809 gfor_fndecl_in_pack, 1, initial);
810 tmp = fold_convert (TREE_TYPE (packed), tmp);
811 gfc_add_modify (pre, packed, tmp);
813 tmp = build_fold_indirect_ref_loc (input_location,
815 source_data = gfc_conv_descriptor_data_get (tmp);
817 /* internal_pack may return source->data without any allocation
818 or copying if it is already packed. If that's the case, we
819 need to allocate and copy manually. */
821 gfc_start_block (&do_copying);
822 tmp = gfc_call_malloc (&do_copying, NULL, size);
823 tmp = fold_convert (TREE_TYPE (packed), tmp);
824 gfc_add_modify (&do_copying, packed, tmp);
825 tmp = gfc_build_memcpy_call (packed, source_data, size);
826 gfc_add_expr_to_block (&do_copying, tmp);
828 was_packed = fold_build2_loc (input_location, EQ_EXPR,
829 boolean_type_node, packed,
831 tmp = gfc_finish_block (&do_copying);
832 tmp = build3_v (COND_EXPR, was_packed, tmp,
833 build_empty_stmt (input_location));
834 gfc_add_expr_to_block (pre, tmp);
836 tmp = fold_convert (pvoid_type_node, packed);
839 gfc_conv_descriptor_data_set (pre, desc, tmp);
842 info->data = gfc_conv_descriptor_data_get (desc);
844 /* The offset is zero because we create temporaries with a zero
846 gfc_conv_descriptor_offset_set (pre, desc, gfc_index_zero_node);
848 if (dealloc && !onstack)
850 /* Free the temporary. */
851 tmp = gfc_conv_descriptor_data_get (desc);
852 tmp = gfc_call_free (fold_convert (pvoid_type_node, tmp));
853 gfc_add_expr_to_block (post, tmp);
858 /* Get the array reference dimension corresponding to the given loop dimension.
859 It is different from the true array dimension given by the dim array in
860 the case of a partial array reference
861 It is different from the loop dimension in the case of a transposed array.
865 get_array_ref_dim (gfc_ss *ss, int loop_dim)
867 int n, array_dim, array_ref_dim;
870 array_dim = ss->dim[loop_dim];
872 for (n = 0; n < ss->dimen; n++)
873 if (ss->dim[n] < array_dim)
876 return array_ref_dim;
880 /* Generate code to create and initialize the descriptor for a temporary
881 array. This is used for both temporaries needed by the scalarizer, and
882 functions returning arrays. Adjusts the loop variables to be
883 zero-based, and calculates the loop bounds for callee allocated arrays.
884 Allocate the array unless it's callee allocated (we have a callee
885 allocated array if 'callee_alloc' is true, or if loop->to[n] is
886 NULL_TREE for any n). Also fills in the descriptor, data and offset
887 fields of info if known. Returns the size of the array, or NULL for a
888 callee allocated array.
890 PRE, POST, INITIAL, DYNAMIC and DEALLOC are as for
891 gfc_trans_allocate_array_storage.
895 gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post,
896 gfc_loopinfo * loop, gfc_ss * ss,
897 tree eltype, tree initial, bool dynamic,
898 bool dealloc, bool callee_alloc, locus * where)
900 gfc_array_info *info;
901 tree from[GFC_MAX_DIMENSIONS], to[GFC_MAX_DIMENSIONS];
911 memset (from, 0, sizeof (from));
912 memset (to, 0, sizeof (to));
914 info = &ss->info->data.array;
916 gcc_assert (ss->dimen > 0);
917 gcc_assert (loop->dimen == ss->dimen);
919 if (gfc_option.warn_array_temp && where)
920 gfc_warning ("Creating array temporary at %L", where);
922 /* Set the lower bound to zero. */
923 for (n = 0; n < loop->dimen; n++)
927 /* Callee allocated arrays may not have a known bound yet. */
929 loop->to[n] = gfc_evaluate_now (
930 fold_build2_loc (input_location, MINUS_EXPR,
931 gfc_array_index_type,
932 loop->to[n], loop->from[n]),
934 loop->from[n] = gfc_index_zero_node;
936 /* We have just changed the loop bounds, we must clear the
937 corresponding specloop, so that delta calculation is not skipped
938 later in set_delta. */
939 loop->specloop[n] = NULL;
941 /* We are constructing the temporary's descriptor based on the loop
942 dimensions. As the dimensions may be accessed in arbitrary order
943 (think of transpose) the size taken from the n'th loop may not map
944 to the n'th dimension of the array. We need to reconstruct loop infos
945 in the right order before using it to set the descriptor
947 tmp_dim = get_array_ref_dim (ss, n);
948 from[tmp_dim] = loop->from[n];
949 to[tmp_dim] = loop->to[n];
951 info->delta[dim] = gfc_index_zero_node;
952 info->start[dim] = gfc_index_zero_node;
953 info->end[dim] = gfc_index_zero_node;
954 info->stride[dim] = gfc_index_one_node;
957 /* Initialize the descriptor. */
959 gfc_get_array_type_bounds (eltype, ss->dimen, 0, from, to, 1,
960 GFC_ARRAY_UNKNOWN, true);
961 desc = gfc_create_var (type, "atmp");
962 GFC_DECL_PACKED_ARRAY (desc) = 1;
964 info->descriptor = desc;
965 size = gfc_index_one_node;
967 /* Fill in the array dtype. */
968 tmp = gfc_conv_descriptor_dtype (desc);
969 gfc_add_modify (pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
972 Fill in the bounds and stride. This is a packed array, so:
975 for (n = 0; n < rank; n++)
978 delta = ubound[n] + 1 - lbound[n];
981 size = size * sizeof(element);
986 /* If there is at least one null loop->to[n], it is a callee allocated
988 for (n = 0; n < loop->dimen; n++)
989 if (loop->to[n] == NULL_TREE)
995 if (size == NULL_TREE)
997 for (n = 0; n < loop->dimen; n++)
1001 /* For a callee allocated array express the loop bounds in terms
1002 of the descriptor fields. */
1003 tmp = fold_build2_loc (input_location,
1004 MINUS_EXPR, gfc_array_index_type,
1005 gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]),
1006 gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]));
1012 for (n = 0; n < loop->dimen; n++)
1014 /* Store the stride and bound components in the descriptor. */
1015 gfc_conv_descriptor_stride_set (pre, desc, gfc_rank_cst[n], size);
1017 gfc_conv_descriptor_lbound_set (pre, desc, gfc_rank_cst[n],
1018 gfc_index_zero_node);
1020 gfc_conv_descriptor_ubound_set (pre, desc, gfc_rank_cst[n], to[n]);
1022 tmp = fold_build2_loc (input_location, PLUS_EXPR,
1023 gfc_array_index_type,
1024 to[n], gfc_index_one_node);
1026 /* Check whether the size for this dimension is negative. */
1027 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
1028 tmp, gfc_index_zero_node);
1029 cond = gfc_evaluate_now (cond, pre);
1034 or_expr = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1035 boolean_type_node, or_expr, cond);
1037 size = fold_build2_loc (input_location, MULT_EXPR,
1038 gfc_array_index_type, size, tmp);
1039 size = gfc_evaluate_now (size, pre);
1043 /* Get the size of the array. */
1044 if (size && !callee_alloc)
1046 /* If or_expr is true, then the extent in at least one
1047 dimension is zero and the size is set to zero. */
1048 size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
1049 or_expr, gfc_index_zero_node, size);
1052 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
1054 fold_convert (gfc_array_index_type,
1055 TYPE_SIZE_UNIT (gfc_get_element_type (type))));
1063 gfc_trans_allocate_array_storage (pre, post, info, size, nelem, initial,
1066 if (ss->dimen > loop->temp_dim)
1067 loop->temp_dim = ss->dimen;
1073 /* Return the number of iterations in a loop that starts at START,
1074 ends at END, and has step STEP. */
1077 gfc_get_iteration_count (tree start, tree end, tree step)
1082 type = TREE_TYPE (step);
1083 tmp = fold_build2_loc (input_location, MINUS_EXPR, type, end, start);
1084 tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, type, tmp, step);
1085 tmp = fold_build2_loc (input_location, PLUS_EXPR, type, tmp,
1086 build_int_cst (type, 1));
1087 tmp = fold_build2_loc (input_location, MAX_EXPR, type, tmp,
1088 build_int_cst (type, 0));
1089 return fold_convert (gfc_array_index_type, tmp);
1093 /* Extend the data in array DESC by EXTRA elements. */
1096 gfc_grow_array (stmtblock_t * pblock, tree desc, tree extra)
1103 if (integer_zerop (extra))
1106 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[0]);
1108 /* Add EXTRA to the upper bound. */
1109 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1111 gfc_conv_descriptor_ubound_set (pblock, desc, gfc_rank_cst[0], tmp);
1113 /* Get the value of the current data pointer. */
1114 arg0 = gfc_conv_descriptor_data_get (desc);
1116 /* Calculate the new array size. */
1117 size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
1118 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1119 ubound, gfc_index_one_node);
1120 arg1 = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
1121 fold_convert (size_type_node, tmp),
1122 fold_convert (size_type_node, size));
1124 /* Call the realloc() function. */
1125 tmp = gfc_call_realloc (pblock, arg0, arg1);
1126 gfc_conv_descriptor_data_set (pblock, desc, tmp);
1130 /* Return true if the bounds of iterator I can only be determined
1134 gfc_iterator_has_dynamic_bounds (gfc_iterator * i)
1136 return (i->start->expr_type != EXPR_CONSTANT
1137 || i->end->expr_type != EXPR_CONSTANT
1138 || i->step->expr_type != EXPR_CONSTANT);
1142 /* Split the size of constructor element EXPR into the sum of two terms,
1143 one of which can be determined at compile time and one of which must
1144 be calculated at run time. Set *SIZE to the former and return true
1145 if the latter might be nonzero. */
1148 gfc_get_array_constructor_element_size (mpz_t * size, gfc_expr * expr)
1150 if (expr->expr_type == EXPR_ARRAY)
1151 return gfc_get_array_constructor_size (size, expr->value.constructor);
1152 else if (expr->rank > 0)
1154 /* Calculate everything at run time. */
1155 mpz_set_ui (*size, 0);
1160 /* A single element. */
1161 mpz_set_ui (*size, 1);
1167 /* Like gfc_get_array_constructor_element_size, but applied to the whole
1168 of array constructor C. */
1171 gfc_get_array_constructor_size (mpz_t * size, gfc_constructor_base base)
1179 mpz_set_ui (*size, 0);
1184 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
1187 if (i && gfc_iterator_has_dynamic_bounds (i))
1191 dynamic |= gfc_get_array_constructor_element_size (&len, c->expr);
1194 /* Multiply the static part of the element size by the
1195 number of iterations. */
1196 mpz_sub (val, i->end->value.integer, i->start->value.integer);
1197 mpz_fdiv_q (val, val, i->step->value.integer);
1198 mpz_add_ui (val, val, 1);
1199 if (mpz_sgn (val) > 0)
1200 mpz_mul (len, len, val);
1202 mpz_set_ui (len, 0);
1204 mpz_add (*size, *size, len);
1213 /* Make sure offset is a variable. */
1216 gfc_put_offset_into_var (stmtblock_t * pblock, tree * poffset,
1219 /* We should have already created the offset variable. We cannot
1220 create it here because we may be in an inner scope. */
1221 gcc_assert (*offsetvar != NULL_TREE);
1222 gfc_add_modify (pblock, *offsetvar, *poffset);
1223 *poffset = *offsetvar;
1224 TREE_USED (*offsetvar) = 1;
1228 /* Variables needed for bounds-checking. */
1229 static bool first_len;
1230 static tree first_len_val;
1231 static bool typespec_chararray_ctor;
1234 gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc,
1235 tree offset, gfc_se * se, gfc_expr * expr)
1239 gfc_conv_expr (se, expr);
1241 /* Store the value. */
1242 tmp = build_fold_indirect_ref_loc (input_location,
1243 gfc_conv_descriptor_data_get (desc));
1244 tmp = gfc_build_array_ref (tmp, offset, NULL);
1246 if (expr->ts.type == BT_CHARACTER)
1248 int i = gfc_validate_kind (BT_CHARACTER, expr->ts.kind, false);
1251 esize = size_in_bytes (gfc_get_element_type (TREE_TYPE (desc)));
1252 esize = fold_convert (gfc_charlen_type_node, esize);
1253 esize = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
1254 gfc_charlen_type_node, esize,
1255 build_int_cst (gfc_charlen_type_node,
1256 gfc_character_kinds[i].bit_size / 8));
1258 gfc_conv_string_parameter (se);
1259 if (POINTER_TYPE_P (TREE_TYPE (tmp)))
1261 /* The temporary is an array of pointers. */
1262 se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
1263 gfc_add_modify (&se->pre, tmp, se->expr);
1267 /* The temporary is an array of string values. */
1268 tmp = gfc_build_addr_expr (gfc_get_pchar_type (expr->ts.kind), tmp);
1269 /* We know the temporary and the value will be the same length,
1270 so can use memcpy. */
1271 gfc_trans_string_copy (&se->pre, esize, tmp, expr->ts.kind,
1272 se->string_length, se->expr, expr->ts.kind);
1274 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && !typespec_chararray_ctor)
1278 gfc_add_modify (&se->pre, first_len_val,
1284 /* Verify that all constructor elements are of the same
1286 tree cond = fold_build2_loc (input_location, NE_EXPR,
1287 boolean_type_node, first_len_val,
1289 gfc_trans_runtime_check
1290 (true, false, cond, &se->pre, &expr->where,
1291 "Different CHARACTER lengths (%ld/%ld) in array constructor",
1292 fold_convert (long_integer_type_node, first_len_val),
1293 fold_convert (long_integer_type_node, se->string_length));
1299 /* TODO: Should the frontend already have done this conversion? */
1300 se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
1301 gfc_add_modify (&se->pre, tmp, se->expr);
1304 gfc_add_block_to_block (pblock, &se->pre);
1305 gfc_add_block_to_block (pblock, &se->post);
1309 /* Add the contents of an array to the constructor. DYNAMIC is as for
1310 gfc_trans_array_constructor_value. */
1313 gfc_trans_array_constructor_subarray (stmtblock_t * pblock,
1314 tree type ATTRIBUTE_UNUSED,
1315 tree desc, gfc_expr * expr,
1316 tree * poffset, tree * offsetvar,
1327 /* We need this to be a variable so we can increment it. */
1328 gfc_put_offset_into_var (pblock, poffset, offsetvar);
1330 gfc_init_se (&se, NULL);
1332 /* Walk the array expression. */
1333 ss = gfc_walk_expr (expr);
1334 gcc_assert (ss != gfc_ss_terminator);
1336 /* Initialize the scalarizer. */
1337 gfc_init_loopinfo (&loop);
1338 gfc_add_ss_to_loop (&loop, ss);
1340 /* Initialize the loop. */
1341 gfc_conv_ss_startstride (&loop);
1342 gfc_conv_loop_setup (&loop, &expr->where);
1344 /* Make sure the constructed array has room for the new data. */
1347 /* Set SIZE to the total number of elements in the subarray. */
1348 size = gfc_index_one_node;
1349 for (n = 0; n < loop.dimen; n++)
1351 tmp = gfc_get_iteration_count (loop.from[n], loop.to[n],
1352 gfc_index_one_node);
1353 size = fold_build2_loc (input_location, MULT_EXPR,
1354 gfc_array_index_type, size, tmp);
1357 /* Grow the constructed array by SIZE elements. */
1358 gfc_grow_array (&loop.pre, desc, size);
1361 /* Make the loop body. */
1362 gfc_mark_ss_chain_used (ss, 1);
1363 gfc_start_scalarized_body (&loop, &body);
1364 gfc_copy_loopinfo_to_se (&se, &loop);
1367 gfc_trans_array_ctor_element (&body, desc, *poffset, &se, expr);
1368 gcc_assert (se.ss == gfc_ss_terminator);
1370 /* Increment the offset. */
1371 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1372 *poffset, gfc_index_one_node);
1373 gfc_add_modify (&body, *poffset, tmp);
1375 /* Finish the loop. */
1376 gfc_trans_scalarizing_loops (&loop, &body);
1377 gfc_add_block_to_block (&loop.pre, &loop.post);
1378 tmp = gfc_finish_block (&loop.pre);
1379 gfc_add_expr_to_block (pblock, tmp);
1381 gfc_cleanup_loop (&loop);
1385 /* Assign the values to the elements of an array constructor. DYNAMIC
1386 is true if descriptor DESC only contains enough data for the static
1387 size calculated by gfc_get_array_constructor_size. When true, memory
1388 for the dynamic parts must be allocated using realloc. */
1391 gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
1392 tree desc, gfc_constructor_base base,
1393 tree * poffset, tree * offsetvar,
1402 tree shadow_loopvar = NULL_TREE;
1403 gfc_saved_var saved_loopvar;
1406 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
1408 /* If this is an iterator or an array, the offset must be a variable. */
1409 if ((c->iterator || c->expr->rank > 0) && INTEGER_CST_P (*poffset))
1410 gfc_put_offset_into_var (pblock, poffset, offsetvar);
1412 /* Shadowing the iterator avoids changing its value and saves us from
1413 keeping track of it. Further, it makes sure that there's always a
1414 backend-decl for the symbol, even if there wasn't one before,
1415 e.g. in the case of an iterator that appears in a specification
1416 expression in an interface mapping. */
1419 gfc_symbol *sym = c->iterator->var->symtree->n.sym;
1420 tree type = gfc_typenode_for_spec (&sym->ts);
1422 shadow_loopvar = gfc_create_var (type, "shadow_loopvar");
1423 gfc_shadow_sym (sym, shadow_loopvar, &saved_loopvar);
1426 gfc_start_block (&body);
1428 if (c->expr->expr_type == EXPR_ARRAY)
1430 /* Array constructors can be nested. */
1431 gfc_trans_array_constructor_value (&body, type, desc,
1432 c->expr->value.constructor,
1433 poffset, offsetvar, dynamic);
1435 else if (c->expr->rank > 0)
1437 gfc_trans_array_constructor_subarray (&body, type, desc, c->expr,
1438 poffset, offsetvar, dynamic);
1442 /* This code really upsets the gimplifier so don't bother for now. */
1449 while (p && !(p->iterator || p->expr->expr_type != EXPR_CONSTANT))
1451 p = gfc_constructor_next (p);
1456 /* Scalar values. */
1457 gfc_init_se (&se, NULL);
1458 gfc_trans_array_ctor_element (&body, desc, *poffset,
1461 *poffset = fold_build2_loc (input_location, PLUS_EXPR,
1462 gfc_array_index_type,
1463 *poffset, gfc_index_one_node);
1467 /* Collect multiple scalar constants into a constructor. */
1468 VEC(constructor_elt,gc) *v = NULL;
1472 HOST_WIDE_INT idx = 0;
1475 /* Count the number of consecutive scalar constants. */
1476 while (p && !(p->iterator
1477 || p->expr->expr_type != EXPR_CONSTANT))
1479 gfc_init_se (&se, NULL);
1480 gfc_conv_constant (&se, p->expr);
1482 if (c->expr->ts.type != BT_CHARACTER)
1483 se.expr = fold_convert (type, se.expr);
1484 /* For constant character array constructors we build
1485 an array of pointers. */
1486 else if (POINTER_TYPE_P (type))
1487 se.expr = gfc_build_addr_expr
1488 (gfc_get_pchar_type (p->expr->ts.kind),
1491 CONSTRUCTOR_APPEND_ELT (v,
1492 build_int_cst (gfc_array_index_type,
1496 p = gfc_constructor_next (p);
1499 bound = size_int (n - 1);
1500 /* Create an array type to hold them. */
1501 tmptype = build_range_type (gfc_array_index_type,
1502 gfc_index_zero_node, bound);
1503 tmptype = build_array_type (type, tmptype);
1505 init = build_constructor (tmptype, v);
1506 TREE_CONSTANT (init) = 1;
1507 TREE_STATIC (init) = 1;
1508 /* Create a static variable to hold the data. */
1509 tmp = gfc_create_var (tmptype, "data");
1510 TREE_STATIC (tmp) = 1;
1511 TREE_CONSTANT (tmp) = 1;
1512 TREE_READONLY (tmp) = 1;
1513 DECL_INITIAL (tmp) = init;
1516 /* Use BUILTIN_MEMCPY to assign the values. */
1517 tmp = gfc_conv_descriptor_data_get (desc);
1518 tmp = build_fold_indirect_ref_loc (input_location,
1520 tmp = gfc_build_array_ref (tmp, *poffset, NULL);
1521 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1522 init = gfc_build_addr_expr (NULL_TREE, init);
1524 size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
1525 bound = build_int_cst (size_type_node, n * size);
1526 tmp = build_call_expr_loc (input_location,
1527 builtin_decl_explicit (BUILT_IN_MEMCPY),
1528 3, tmp, init, bound);
1529 gfc_add_expr_to_block (&body, tmp);
1531 *poffset = fold_build2_loc (input_location, PLUS_EXPR,
1532 gfc_array_index_type, *poffset,
1533 build_int_cst (gfc_array_index_type, n));
1535 if (!INTEGER_CST_P (*poffset))
1537 gfc_add_modify (&body, *offsetvar, *poffset);
1538 *poffset = *offsetvar;
1542 /* The frontend should already have done any expansions
1546 /* Pass the code as is. */
1547 tmp = gfc_finish_block (&body);
1548 gfc_add_expr_to_block (pblock, tmp);
1552 /* Build the implied do-loop. */
1553 stmtblock_t implied_do_block;
1561 loopbody = gfc_finish_block (&body);
1563 /* Create a new block that holds the implied-do loop. A temporary
1564 loop-variable is used. */
1565 gfc_start_block(&implied_do_block);
1567 /* Initialize the loop. */
1568 gfc_init_se (&se, NULL);
1569 gfc_conv_expr_val (&se, c->iterator->start);
1570 gfc_add_block_to_block (&implied_do_block, &se.pre);
1571 gfc_add_modify (&implied_do_block, shadow_loopvar, se.expr);
1573 gfc_init_se (&se, NULL);
1574 gfc_conv_expr_val (&se, c->iterator->end);
1575 gfc_add_block_to_block (&implied_do_block, &se.pre);
1576 end = gfc_evaluate_now (se.expr, &implied_do_block);
1578 gfc_init_se (&se, NULL);
1579 gfc_conv_expr_val (&se, c->iterator->step);
1580 gfc_add_block_to_block (&implied_do_block, &se.pre);
1581 step = gfc_evaluate_now (se.expr, &implied_do_block);
1583 /* If this array expands dynamically, and the number of iterations
1584 is not constant, we won't have allocated space for the static
1585 part of C->EXPR's size. Do that now. */
1586 if (dynamic && gfc_iterator_has_dynamic_bounds (c->iterator))
1588 /* Get the number of iterations. */
1589 tmp = gfc_get_iteration_count (shadow_loopvar, end, step);
1591 /* Get the static part of C->EXPR's size. */
1592 gfc_get_array_constructor_element_size (&size, c->expr);
1593 tmp2 = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1595 /* Grow the array by TMP * TMP2 elements. */
1596 tmp = fold_build2_loc (input_location, MULT_EXPR,
1597 gfc_array_index_type, tmp, tmp2);
1598 gfc_grow_array (&implied_do_block, desc, tmp);
1601 /* Generate the loop body. */
1602 exit_label = gfc_build_label_decl (NULL_TREE);
1603 gfc_start_block (&body);
1605 /* Generate the exit condition. Depending on the sign of
1606 the step variable we have to generate the correct
1608 tmp = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1609 step, build_int_cst (TREE_TYPE (step), 0));
1610 cond = fold_build3_loc (input_location, COND_EXPR,
1611 boolean_type_node, tmp,
1612 fold_build2_loc (input_location, GT_EXPR,
1613 boolean_type_node, shadow_loopvar, end),
1614 fold_build2_loc (input_location, LT_EXPR,
1615 boolean_type_node, shadow_loopvar, end));
1616 tmp = build1_v (GOTO_EXPR, exit_label);
1617 TREE_USED (exit_label) = 1;
1618 tmp = build3_v (COND_EXPR, cond, tmp,
1619 build_empty_stmt (input_location));
1620 gfc_add_expr_to_block (&body, tmp);
1622 /* The main loop body. */
1623 gfc_add_expr_to_block (&body, loopbody);
1625 /* Increase loop variable by step. */
1626 tmp = fold_build2_loc (input_location, PLUS_EXPR,
1627 TREE_TYPE (shadow_loopvar), shadow_loopvar,
1629 gfc_add_modify (&body, shadow_loopvar, tmp);
1631 /* Finish the loop. */
1632 tmp = gfc_finish_block (&body);
1633 tmp = build1_v (LOOP_EXPR, tmp);
1634 gfc_add_expr_to_block (&implied_do_block, tmp);
1636 /* Add the exit label. */
1637 tmp = build1_v (LABEL_EXPR, exit_label);
1638 gfc_add_expr_to_block (&implied_do_block, tmp);
1640 /* Finishe the implied-do loop. */
1641 tmp = gfc_finish_block(&implied_do_block);
1642 gfc_add_expr_to_block(pblock, tmp);
1644 gfc_restore_sym (c->iterator->var->symtree->n.sym, &saved_loopvar);
1651 /* A catch-all to obtain the string length for anything that is not a
1652 a substring of non-constant length, a constant, array or variable. */
1655 get_array_ctor_all_strlen (stmtblock_t *block, gfc_expr *e, tree *len)
1660 /* Don't bother if we already know the length is a constant. */
1661 if (*len && INTEGER_CST_P (*len))
1664 if (!e->ref && e->ts.u.cl && e->ts.u.cl->length
1665 && e->ts.u.cl->length->expr_type == EXPR_CONSTANT)
1668 gfc_conv_const_charlen (e->ts.u.cl);
1669 *len = e->ts.u.cl->backend_decl;
1673 /* Otherwise, be brutal even if inefficient. */
1674 ss = gfc_walk_expr (e);
1675 gfc_init_se (&se, NULL);
1677 /* No function call, in case of side effects. */
1678 se.no_function_call = 1;
1679 if (ss == gfc_ss_terminator)
1680 gfc_conv_expr (&se, e);
1682 gfc_conv_expr_descriptor (&se, e, ss);
1684 /* Fix the value. */
1685 *len = gfc_evaluate_now (se.string_length, &se.pre);
1687 gfc_add_block_to_block (block, &se.pre);
1688 gfc_add_block_to_block (block, &se.post);
1690 e->ts.u.cl->backend_decl = *len;
1695 /* Figure out the string length of a variable reference expression.
1696 Used by get_array_ctor_strlen. */
1699 get_array_ctor_var_strlen (stmtblock_t *block, gfc_expr * expr, tree * len)
1705 /* Don't bother if we already know the length is a constant. */
1706 if (*len && INTEGER_CST_P (*len))
1709 ts = &expr->symtree->n.sym->ts;
1710 for (ref = expr->ref; ref; ref = ref->next)
1715 /* Array references don't change the string length. */
1719 /* Use the length of the component. */
1720 ts = &ref->u.c.component->ts;
1724 if (ref->u.ss.start->expr_type != EXPR_CONSTANT
1725 || ref->u.ss.end->expr_type != EXPR_CONSTANT)
1727 /* Note that this might evaluate expr. */
1728 get_array_ctor_all_strlen (block, expr, len);
1731 mpz_init_set_ui (char_len, 1);
1732 mpz_add (char_len, char_len, ref->u.ss.end->value.integer);
1733 mpz_sub (char_len, char_len, ref->u.ss.start->value.integer);
1734 *len = gfc_conv_mpz_to_tree (char_len, gfc_default_integer_kind);
1735 *len = convert (gfc_charlen_type_node, *len);
1736 mpz_clear (char_len);
1744 *len = ts->u.cl->backend_decl;
1748 /* Figure out the string length of a character array constructor.
1749 If len is NULL, don't calculate the length; this happens for recursive calls
1750 when a sub-array-constructor is an element but not at the first position,
1751 so when we're not interested in the length.
1752 Returns TRUE if all elements are character constants. */
1755 get_array_ctor_strlen (stmtblock_t *block, gfc_constructor_base base, tree * len)
1762 if (gfc_constructor_first (base) == NULL)
1765 *len = build_int_cstu (gfc_charlen_type_node, 0);
1769 /* Loop over all constructor elements to find out is_const, but in len we
1770 want to store the length of the first, not the last, element. We can
1771 of course exit the loop as soon as is_const is found to be false. */
1772 for (c = gfc_constructor_first (base);
1773 c && is_const; c = gfc_constructor_next (c))
1775 switch (c->expr->expr_type)
1778 if (len && !(*len && INTEGER_CST_P (*len)))
1779 *len = build_int_cstu (gfc_charlen_type_node,
1780 c->expr->value.character.length);
1784 if (!get_array_ctor_strlen (block, c->expr->value.constructor, len))
1791 get_array_ctor_var_strlen (block, c->expr, len);
1797 get_array_ctor_all_strlen (block, c->expr, len);
1801 /* After the first iteration, we don't want the length modified. */
1808 /* Check whether the array constructor C consists entirely of constant
1809 elements, and if so returns the number of those elements, otherwise
1810 return zero. Note, an empty or NULL array constructor returns zero. */
1812 unsigned HOST_WIDE_INT
1813 gfc_constant_array_constructor_p (gfc_constructor_base base)
1815 unsigned HOST_WIDE_INT nelem = 0;
1817 gfc_constructor *c = gfc_constructor_first (base);
1821 || c->expr->rank > 0
1822 || c->expr->expr_type != EXPR_CONSTANT)
1824 c = gfc_constructor_next (c);
1831 /* Given EXPR, the constant array constructor specified by an EXPR_ARRAY,
1832 and the tree type of it's elements, TYPE, return a static constant
1833 variable that is compile-time initialized. */
1836 gfc_build_constant_array_constructor (gfc_expr * expr, tree type)
1838 tree tmptype, init, tmp;
1839 HOST_WIDE_INT nelem;
1844 VEC(constructor_elt,gc) *v = NULL;
1846 /* First traverse the constructor list, converting the constants
1847 to tree to build an initializer. */
1849 c = gfc_constructor_first (expr->value.constructor);
1852 gfc_init_se (&se, NULL);
1853 gfc_conv_constant (&se, c->expr);
1854 if (c->expr->ts.type != BT_CHARACTER)
1855 se.expr = fold_convert (type, se.expr);
1856 else if (POINTER_TYPE_P (type))
1857 se.expr = gfc_build_addr_expr (gfc_get_pchar_type (c->expr->ts.kind),
1859 CONSTRUCTOR_APPEND_ELT (v, build_int_cst (gfc_array_index_type, nelem),
1861 c = gfc_constructor_next (c);
1865 /* Next determine the tree type for the array. We use the gfortran
1866 front-end's gfc_get_nodesc_array_type in order to create a suitable
1867 GFC_ARRAY_TYPE_P that may be used by the scalarizer. */
1869 memset (&as, 0, sizeof (gfc_array_spec));
1871 as.rank = expr->rank;
1872 as.type = AS_EXPLICIT;
1875 as.lower[0] = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
1876 as.upper[0] = gfc_get_int_expr (gfc_default_integer_kind,
1880 for (i = 0; i < expr->rank; i++)
1882 int tmp = (int) mpz_get_si (expr->shape[i]);
1883 as.lower[i] = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
1884 as.upper[i] = gfc_get_int_expr (gfc_default_integer_kind,
1888 tmptype = gfc_get_nodesc_array_type (type, &as, PACKED_STATIC, true);
1890 /* as is not needed anymore. */
1891 for (i = 0; i < as.rank + as.corank; i++)
1893 gfc_free_expr (as.lower[i]);
1894 gfc_free_expr (as.upper[i]);
1897 init = build_constructor (tmptype, v);
1899 TREE_CONSTANT (init) = 1;
1900 TREE_STATIC (init) = 1;
1902 tmp = gfc_create_var (tmptype, "A");
1903 TREE_STATIC (tmp) = 1;
1904 TREE_CONSTANT (tmp) = 1;
1905 TREE_READONLY (tmp) = 1;
1906 DECL_INITIAL (tmp) = init;
1912 /* Translate a constant EXPR_ARRAY array constructor for the scalarizer.
1913 This mostly initializes the scalarizer state info structure with the
1914 appropriate values to directly use the array created by the function
1915 gfc_build_constant_array_constructor. */
1918 trans_constant_array_constructor (gfc_ss * ss, tree type)
1920 gfc_array_info *info;
1924 tmp = gfc_build_constant_array_constructor (ss->info->expr, type);
1926 info = &ss->info->data.array;
1928 info->descriptor = tmp;
1929 info->data = gfc_build_addr_expr (NULL_TREE, tmp);
1930 info->offset = gfc_index_zero_node;
1932 for (i = 0; i < ss->dimen; i++)
1934 info->delta[i] = gfc_index_zero_node;
1935 info->start[i] = gfc_index_zero_node;
1936 info->end[i] = gfc_index_zero_node;
1937 info->stride[i] = gfc_index_one_node;
1941 /* Helper routine of gfc_trans_array_constructor to determine if the
1942 bounds of the loop specified by LOOP are constant and simple enough
1943 to use with trans_constant_array_constructor. Returns the
1944 iteration count of the loop if suitable, and NULL_TREE otherwise. */
1947 constant_array_constructor_loop_size (gfc_loopinfo * loop)
1949 tree size = gfc_index_one_node;
1953 for (i = 0; i < loop->dimen; i++)
1955 /* If the bounds aren't constant, return NULL_TREE. */
1956 if (!INTEGER_CST_P (loop->from[i]) || !INTEGER_CST_P (loop->to[i]))
1958 if (!integer_zerop (loop->from[i]))
1960 /* Only allow nonzero "from" in one-dimensional arrays. */
1961 if (loop->dimen != 1)
1963 tmp = fold_build2_loc (input_location, MINUS_EXPR,
1964 gfc_array_index_type,
1965 loop->to[i], loop->from[i]);
1969 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1970 tmp, gfc_index_one_node);
1971 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
1979 /* Array constructors are handled by constructing a temporary, then using that
1980 within the scalarization loop. This is not optimal, but seems by far the
1984 gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss, locus * where)
1986 gfc_constructor_base c;
1993 bool old_first_len, old_typespec_chararray_ctor;
1994 tree old_first_len_val;
1995 gfc_ss_info *ss_info;
1998 /* Save the old values for nested checking. */
1999 old_first_len = first_len;
2000 old_first_len_val = first_len_val;
2001 old_typespec_chararray_ctor = typespec_chararray_ctor;
2004 expr = ss_info->expr;
2006 /* Do bounds-checking here and in gfc_trans_array_ctor_element only if no
2007 typespec was given for the array constructor. */
2008 typespec_chararray_ctor = (expr->ts.u.cl
2009 && expr->ts.u.cl->length_from_typespec);
2011 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2012 && expr->ts.type == BT_CHARACTER && !typespec_chararray_ctor)
2014 first_len_val = gfc_create_var (gfc_charlen_type_node, "len");
2018 gcc_assert (ss->dimen == loop->dimen);
2020 c = expr->value.constructor;
2021 if (expr->ts.type == BT_CHARACTER)
2025 /* get_array_ctor_strlen walks the elements of the constructor, if a
2026 typespec was given, we already know the string length and want the one
2028 if (typespec_chararray_ctor && expr->ts.u.cl->length
2029 && expr->ts.u.cl->length->expr_type != EXPR_CONSTANT)
2033 const_string = false;
2034 gfc_init_se (&length_se, NULL);
2035 gfc_conv_expr_type (&length_se, expr->ts.u.cl->length,
2036 gfc_charlen_type_node);
2037 ss_info->string_length = length_se.expr;
2038 gfc_add_block_to_block (&loop->pre, &length_se.pre);
2039 gfc_add_block_to_block (&loop->post, &length_se.post);
2042 const_string = get_array_ctor_strlen (&loop->pre, c,
2043 &ss_info->string_length);
2045 /* Complex character array constructors should have been taken care of
2046 and not end up here. */
2047 gcc_assert (ss_info->string_length);
2049 expr->ts.u.cl->backend_decl = ss_info->string_length;
2051 type = gfc_get_character_type_len (expr->ts.kind, ss_info->string_length);
2053 type = build_pointer_type (type);
2056 type = gfc_typenode_for_spec (&expr->ts);
2058 /* See if the constructor determines the loop bounds. */
2061 if (expr->shape && loop->dimen > 1 && loop->to[0] == NULL_TREE)
2063 /* We have a multidimensional parameter. */
2065 for (n = 0; n < expr->rank; n++)
2067 loop->from[n] = gfc_index_zero_node;
2068 loop->to[n] = gfc_conv_mpz_to_tree (expr->shape [n],
2069 gfc_index_integer_kind);
2070 loop->to[n] = fold_build2_loc (input_location, MINUS_EXPR,
2071 gfc_array_index_type,
2072 loop->to[n], gfc_index_one_node);
2076 if (loop->to[0] == NULL_TREE)
2080 /* We should have a 1-dimensional, zero-based loop. */
2081 gcc_assert (loop->dimen == 1);
2082 gcc_assert (integer_zerop (loop->from[0]));
2084 /* Split the constructor size into a static part and a dynamic part.
2085 Allocate the static size up-front and record whether the dynamic
2086 size might be nonzero. */
2088 dynamic = gfc_get_array_constructor_size (&size, c);
2089 mpz_sub_ui (size, size, 1);
2090 loop->to[0] = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
2094 /* Special case constant array constructors. */
2097 unsigned HOST_WIDE_INT nelem = gfc_constant_array_constructor_p (c);
2100 tree size = constant_array_constructor_loop_size (loop);
2101 if (size && compare_tree_int (size, nelem) == 0)
2103 trans_constant_array_constructor (ss, type);
2109 if (TREE_CODE (loop->to[0]) == VAR_DECL)
2112 gfc_trans_create_temp_array (&loop->pre, &loop->post, loop, ss,
2113 type, NULL_TREE, dynamic, true, false, where);
2115 desc = ss_info->data.array.descriptor;
2116 offset = gfc_index_zero_node;
2117 offsetvar = gfc_create_var_np (gfc_array_index_type, "offset");
2118 TREE_NO_WARNING (offsetvar) = 1;
2119 TREE_USED (offsetvar) = 0;
2120 gfc_trans_array_constructor_value (&loop->pre, type, desc, c,
2121 &offset, &offsetvar, dynamic);
2123 /* If the array grows dynamically, the upper bound of the loop variable
2124 is determined by the array's final upper bound. */
2127 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2128 gfc_array_index_type,
2129 offsetvar, gfc_index_one_node);
2130 tmp = gfc_evaluate_now (tmp, &loop->pre);
2131 gfc_conv_descriptor_ubound_set (&loop->pre, desc, gfc_rank_cst[0], tmp);
2132 if (loop->to[0] && TREE_CODE (loop->to[0]) == VAR_DECL)
2133 gfc_add_modify (&loop->pre, loop->to[0], tmp);
2138 if (TREE_USED (offsetvar))
2139 pushdecl (offsetvar);
2141 gcc_assert (INTEGER_CST_P (offset));
2144 /* Disable bound checking for now because it's probably broken. */
2145 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2152 /* Restore old values of globals. */
2153 first_len = old_first_len;
2154 first_len_val = old_first_len_val;
2155 typespec_chararray_ctor = old_typespec_chararray_ctor;
2159 /* INFO describes a GFC_SS_SECTION in loop LOOP, and this function is
2160 called after evaluating all of INFO's vector dimensions. Go through
2161 each such vector dimension and see if we can now fill in any missing
2165 set_vector_loop_bounds (gfc_ss * ss)
2168 gfc_array_info *info;
2176 info = &ss->info->data.array;
2179 for (n = 0; n < loop->dimen; n++)
2182 if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR
2183 && loop->to[n] == NULL)
2185 /* Loop variable N indexes vector dimension DIM, and we don't
2186 yet know the upper bound of loop variable N. Set it to the
2187 difference between the vector's upper and lower bounds. */
2188 gcc_assert (loop->from[n] == gfc_index_zero_node);
2189 gcc_assert (info->subscript[dim]
2190 && info->subscript[dim]->info->type == GFC_SS_VECTOR);
2192 gfc_init_se (&se, NULL);
2193 desc = info->subscript[dim]->info->data.array.descriptor;
2194 zero = gfc_rank_cst[0];
2195 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2196 gfc_array_index_type,
2197 gfc_conv_descriptor_ubound_get (desc, zero),
2198 gfc_conv_descriptor_lbound_get (desc, zero));
2199 tmp = gfc_evaluate_now (tmp, &loop->pre);
2206 /* Add the pre and post chains for all the scalar expressions in a SS chain
2207 to loop. This is called after the loop parameters have been calculated,
2208 but before the actual scalarizing loops. */
2211 gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript,
2215 gfc_ss_info *ss_info;
2216 gfc_array_info *info;
2220 /* TODO: This can generate bad code if there are ordering dependencies,
2221 e.g., a callee allocated function and an unknown size constructor. */
2222 gcc_assert (ss != NULL);
2224 for (; ss != gfc_ss_terminator; ss = ss->loop_chain)
2229 expr = ss_info->expr;
2230 info = &ss_info->data.array;
2232 switch (ss_info->type)
2235 /* Scalar expression. Evaluate this now. This includes elemental
2236 dimension indices, but not array section bounds. */
2237 gfc_init_se (&se, NULL);
2238 gfc_conv_expr (&se, expr);
2239 gfc_add_block_to_block (&loop->pre, &se.pre);
2241 if (expr->ts.type != BT_CHARACTER)
2243 /* Move the evaluation of scalar expressions outside the
2244 scalarization loop, except for WHERE assignments. */
2246 se.expr = convert(gfc_array_index_type, se.expr);
2247 if (!ss_info->where)
2248 se.expr = gfc_evaluate_now (se.expr, &loop->pre);
2249 gfc_add_block_to_block (&loop->pre, &se.post);
2252 gfc_add_block_to_block (&loop->post, &se.post);
2254 ss_info->data.scalar.value = se.expr;
2255 ss_info->string_length = se.string_length;
2258 case GFC_SS_REFERENCE:
2259 /* Scalar argument to elemental procedure. Evaluate this
2261 gfc_init_se (&se, NULL);
2262 gfc_conv_expr (&se, expr);
2263 gfc_add_block_to_block (&loop->pre, &se.pre);
2264 gfc_add_block_to_block (&loop->post, &se.post);
2266 ss_info->data.scalar.value = gfc_evaluate_now (se.expr, &loop->pre);
2267 ss_info->string_length = se.string_length;
2270 case GFC_SS_SECTION:
2271 /* Add the expressions for scalar and vector subscripts. */
2272 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
2273 if (info->subscript[n])
2274 gfc_add_loop_ss_code (loop, info->subscript[n], true, where);
2276 set_vector_loop_bounds (ss);
2280 /* Get the vector's descriptor and store it in SS. */
2281 gfc_init_se (&se, NULL);
2282 gfc_conv_expr_descriptor (&se, expr, gfc_walk_expr (expr));
2283 gfc_add_block_to_block (&loop->pre, &se.pre);
2284 gfc_add_block_to_block (&loop->post, &se.post);
2285 info->descriptor = se.expr;
2288 case GFC_SS_INTRINSIC:
2289 gfc_add_intrinsic_ss_code (loop, ss);
2292 case GFC_SS_FUNCTION:
2293 /* Array function return value. We call the function and save its
2294 result in a temporary for use inside the loop. */
2295 gfc_init_se (&se, NULL);
2298 gfc_conv_expr (&se, expr);
2299 gfc_add_block_to_block (&loop->pre, &se.pre);
2300 gfc_add_block_to_block (&loop->post, &se.post);
2301 ss_info->string_length = se.string_length;
2304 case GFC_SS_CONSTRUCTOR:
2305 if (expr->ts.type == BT_CHARACTER
2306 && ss_info->string_length == NULL
2308 && expr->ts.u.cl->length)
2310 gfc_init_se (&se, NULL);
2311 gfc_conv_expr_type (&se, expr->ts.u.cl->length,
2312 gfc_charlen_type_node);
2313 ss_info->string_length = se.expr;
2314 gfc_add_block_to_block (&loop->pre, &se.pre);
2315 gfc_add_block_to_block (&loop->post, &se.post);
2317 gfc_trans_array_constructor (loop, ss, where);
2321 case GFC_SS_COMPONENT:
2322 /* Do nothing. These are handled elsewhere. */
2332 /* Translate expressions for the descriptor and data pointer of a SS. */
2336 gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)
2339 gfc_ss_info *ss_info;
2340 gfc_array_info *info;
2344 info = &ss_info->data.array;
2346 /* Get the descriptor for the array to be scalarized. */
2347 gcc_assert (ss_info->expr->expr_type == EXPR_VARIABLE);
2348 gfc_init_se (&se, NULL);
2349 se.descriptor_only = 1;
2350 gfc_conv_expr_lhs (&se, ss_info->expr);
2351 gfc_add_block_to_block (block, &se.pre);
2352 info->descriptor = se.expr;
2353 ss_info->string_length = se.string_length;
2357 /* Also the data pointer. */
2358 tmp = gfc_conv_array_data (se.expr);
2359 /* If this is a variable or address of a variable we use it directly.
2360 Otherwise we must evaluate it now to avoid breaking dependency
2361 analysis by pulling the expressions for elemental array indices
2364 || (TREE_CODE (tmp) == ADDR_EXPR
2365 && DECL_P (TREE_OPERAND (tmp, 0)))))
2366 tmp = gfc_evaluate_now (tmp, block);
2369 tmp = gfc_conv_array_offset (se.expr);
2370 info->offset = gfc_evaluate_now (tmp, block);
2372 /* Make absolutely sure that the saved_offset is indeed saved
2373 so that the variable is still accessible after the loops
2375 info->saved_offset = info->offset;
2380 /* Initialize a gfc_loopinfo structure. */
2383 gfc_init_loopinfo (gfc_loopinfo * loop)
2387 memset (loop, 0, sizeof (gfc_loopinfo));
2388 gfc_init_block (&loop->pre);
2389 gfc_init_block (&loop->post);
2391 /* Initially scalarize in order and default to no loop reversal. */
2392 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
2395 loop->reverse[n] = GFC_INHIBIT_REVERSE;
2398 loop->ss = gfc_ss_terminator;
2402 /* Copies the loop variable info to a gfc_se structure. Does not copy the SS
2406 gfc_copy_loopinfo_to_se (gfc_se * se, gfc_loopinfo * loop)
2412 /* Return an expression for the data pointer of an array. */
2415 gfc_conv_array_data (tree descriptor)
2419 type = TREE_TYPE (descriptor);
2420 if (GFC_ARRAY_TYPE_P (type))
2422 if (TREE_CODE (type) == POINTER_TYPE)
2426 /* Descriptorless arrays. */
2427 return gfc_build_addr_expr (NULL_TREE, descriptor);
2431 return gfc_conv_descriptor_data_get (descriptor);
2435 /* Return an expression for the base offset of an array. */
2438 gfc_conv_array_offset (tree descriptor)
2442 type = TREE_TYPE (descriptor);
2443 if (GFC_ARRAY_TYPE_P (type))
2444 return GFC_TYPE_ARRAY_OFFSET (type);
2446 return gfc_conv_descriptor_offset_get (descriptor);
2450 /* Get an expression for the array stride. */
2453 gfc_conv_array_stride (tree descriptor, int dim)
2458 type = TREE_TYPE (descriptor);
2460 /* For descriptorless arrays use the array size. */
2461 tmp = GFC_TYPE_ARRAY_STRIDE (type, dim);
2462 if (tmp != NULL_TREE)
2465 tmp = gfc_conv_descriptor_stride_get (descriptor, gfc_rank_cst[dim]);
2470 /* Like gfc_conv_array_stride, but for the lower bound. */
2473 gfc_conv_array_lbound (tree descriptor, int dim)
2478 type = TREE_TYPE (descriptor);
2480 tmp = GFC_TYPE_ARRAY_LBOUND (type, dim);
2481 if (tmp != NULL_TREE)
2484 tmp = gfc_conv_descriptor_lbound_get (descriptor, gfc_rank_cst[dim]);
2489 /* Like gfc_conv_array_stride, but for the upper bound. */
2492 gfc_conv_array_ubound (tree descriptor, int dim)
2497 type = TREE_TYPE (descriptor);
2499 tmp = GFC_TYPE_ARRAY_UBOUND (type, dim);
2500 if (tmp != NULL_TREE)
2503 /* This should only ever happen when passing an assumed shape array
2504 as an actual parameter. The value will never be used. */
2505 if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor)))
2506 return gfc_index_zero_node;
2508 tmp = gfc_conv_descriptor_ubound_get (descriptor, gfc_rank_cst[dim]);
2513 /* Generate code to perform an array index bound check. */
2516 trans_array_bound_check (gfc_se * se, gfc_ss *ss, tree index, int n,
2517 locus * where, bool check_upper)
2520 tree tmp_lo, tmp_up;
2523 const char * name = NULL;
2525 if (!(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
2528 descriptor = ss->info->data.array.descriptor;
2530 index = gfc_evaluate_now (index, &se->pre);
2532 /* We find a name for the error message. */
2533 name = ss->info->expr->symtree->n.sym->name;
2534 gcc_assert (name != NULL);
2536 if (TREE_CODE (descriptor) == VAR_DECL)
2537 name = IDENTIFIER_POINTER (DECL_NAME (descriptor));
2539 /* If upper bound is present, include both bounds in the error message. */
2542 tmp_lo = gfc_conv_array_lbound (descriptor, n);
2543 tmp_up = gfc_conv_array_ubound (descriptor, n);
2546 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
2547 "outside of expected range (%%ld:%%ld)", n+1, name);
2549 asprintf (&msg, "Index '%%ld' of dimension %d "
2550 "outside of expected range (%%ld:%%ld)", n+1);
2552 fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
2554 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2555 fold_convert (long_integer_type_node, index),
2556 fold_convert (long_integer_type_node, tmp_lo),
2557 fold_convert (long_integer_type_node, tmp_up));
2558 fault = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
2560 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2561 fold_convert (long_integer_type_node, index),
2562 fold_convert (long_integer_type_node, tmp_lo),
2563 fold_convert (long_integer_type_node, tmp_up));
2568 tmp_lo = gfc_conv_array_lbound (descriptor, n);
2571 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
2572 "below lower bound of %%ld", n+1, name);
2574 asprintf (&msg, "Index '%%ld' of dimension %d "
2575 "below lower bound of %%ld", n+1);
2577 fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
2579 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2580 fold_convert (long_integer_type_node, index),
2581 fold_convert (long_integer_type_node, tmp_lo));
2589 /* Return the offset for an index. Performs bound checking for elemental
2590 dimensions. Single element references are processed separately.
2591 DIM is the array dimension, I is the loop dimension. */
2594 conv_array_index_offset (gfc_se * se, gfc_ss * ss, int dim, int i,
2595 gfc_array_ref * ar, tree stride)
2597 gfc_array_info *info;
2602 info = &ss->info->data.array;
2604 /* Get the index into the array for this dimension. */
2607 gcc_assert (ar->type != AR_ELEMENT);
2608 switch (ar->dimen_type[dim])
2610 case DIMEN_THIS_IMAGE:
2614 /* Elemental dimension. */
2615 gcc_assert (info->subscript[dim]
2616 && info->subscript[dim]->info->type == GFC_SS_SCALAR);
2617 /* We've already translated this value outside the loop. */
2618 index = info->subscript[dim]->info->data.scalar.value;
2620 index = trans_array_bound_check (se, ss, index, dim, &ar->where,
2621 ar->as->type != AS_ASSUMED_SIZE
2622 || dim < ar->dimen - 1);
2626 gcc_assert (info && se->loop);
2627 gcc_assert (info->subscript[dim]
2628 && info->subscript[dim]->info->type == GFC_SS_VECTOR);
2629 desc = info->subscript[dim]->info->data.array.descriptor;
2631 /* Get a zero-based index into the vector. */
2632 index = fold_build2_loc (input_location, MINUS_EXPR,
2633 gfc_array_index_type,
2634 se->loop->loopvar[i], se->loop->from[i]);
2636 /* Multiply the index by the stride. */
2637 index = fold_build2_loc (input_location, MULT_EXPR,
2638 gfc_array_index_type,
2639 index, gfc_conv_array_stride (desc, 0));
2641 /* Read the vector to get an index into info->descriptor. */
2642 data = build_fold_indirect_ref_loc (input_location,
2643 gfc_conv_array_data (desc));
2644 index = gfc_build_array_ref (data, index, NULL);
2645 index = gfc_evaluate_now (index, &se->pre);
2646 index = fold_convert (gfc_array_index_type, index);
2648 /* Do any bounds checking on the final info->descriptor index. */
2649 index = trans_array_bound_check (se, ss, index, dim, &ar->where,
2650 ar->as->type != AS_ASSUMED_SIZE
2651 || dim < ar->dimen - 1);
2655 /* Scalarized dimension. */
2656 gcc_assert (info && se->loop);
2658 /* Multiply the loop variable by the stride and delta. */
2659 index = se->loop->loopvar[i];
2660 if (!integer_onep (info->stride[dim]))
2661 index = fold_build2_loc (input_location, MULT_EXPR,
2662 gfc_array_index_type, index,
2664 if (!integer_zerop (info->delta[dim]))
2665 index = fold_build2_loc (input_location, PLUS_EXPR,
2666 gfc_array_index_type, index,
2676 /* Temporary array or derived type component. */
2677 gcc_assert (se->loop);
2678 index = se->loop->loopvar[se->loop->order[i]];
2680 /* Pointer functions can have stride[0] different from unity.
2681 Use the stride returned by the function call and stored in
2682 the descriptor for the temporary. */
2683 if (se->ss && se->ss->info->type == GFC_SS_FUNCTION
2684 && se->ss->info->expr
2685 && se->ss->info->expr->symtree
2686 && se->ss->info->expr->symtree->n.sym->result
2687 && se->ss->info->expr->symtree->n.sym->result->attr.pointer)
2688 stride = gfc_conv_descriptor_stride_get (info->descriptor,
2691 if (!integer_zerop (info->delta[dim]))
2692 index = fold_build2_loc (input_location, PLUS_EXPR,
2693 gfc_array_index_type, index, info->delta[dim]);
2696 /* Multiply by the stride. */
2697 if (!integer_onep (stride))
2698 index = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
2705 /* Build a scalarized reference to an array. */
2708 gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
2710 gfc_array_info *info;
2711 tree decl = NULL_TREE;
2719 expr = ss->info->expr;
2720 info = &ss->info->data.array;
2722 n = se->loop->order[0];
2726 index = conv_array_index_offset (se, ss, ss->dim[n], n, ar, info->stride0);
2727 /* Add the offset for this dimension to the stored offset for all other
2729 if (!integer_zerop (info->offset))
2730 index = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
2731 index, info->offset);
2733 if (expr && is_subref_array (expr))
2734 decl = expr->symtree->n.sym->backend_decl;
2736 tmp = build_fold_indirect_ref_loc (input_location, info->data);
2737 se->expr = gfc_build_array_ref (tmp, index, decl);
2741 /* Translate access of temporary array. */
2744 gfc_conv_tmp_array_ref (gfc_se * se)
2746 se->string_length = se->ss->info->string_length;
2747 gfc_conv_scalarized_array_ref (se, NULL);
2748 gfc_advance_se_ss_chain (se);
2751 /* Add T to the offset pair *OFFSET, *CST_OFFSET. */
2754 add_to_offset (tree *cst_offset, tree *offset, tree t)
2756 if (TREE_CODE (t) == INTEGER_CST)
2757 *cst_offset = int_const_binop (PLUS_EXPR, *cst_offset, t);
2760 if (!integer_zerop (*offset))
2761 *offset = fold_build2_loc (input_location, PLUS_EXPR,
2762 gfc_array_index_type, *offset, t);
2768 /* Build an array reference. se->expr already holds the array descriptor.
2769 This should be either a variable, indirect variable reference or component
2770 reference. For arrays which do not have a descriptor, se->expr will be
2772 a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
2775 gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym,
2779 tree offset, cst_offset;
2787 gcc_assert (ar->codimen);
2789 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se->expr)))
2790 se->expr = build_fold_indirect_ref (gfc_conv_array_data (se->expr));
2793 if (GFC_ARRAY_TYPE_P (TREE_TYPE (se->expr))
2794 && TREE_CODE (TREE_TYPE (se->expr)) == POINTER_TYPE)
2795 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
2797 /* Use the actual tree type and not the wrapped coarray. */
2798 if (!se->want_pointer)
2799 se->expr = fold_convert (TYPE_MAIN_VARIANT (TREE_TYPE (se->expr)),
2806 /* Handle scalarized references separately. */
2807 if (ar->type != AR_ELEMENT)
2809 gfc_conv_scalarized_array_ref (se, ar);
2810 gfc_advance_se_ss_chain (se);
2814 cst_offset = offset = gfc_index_zero_node;
2815 add_to_offset (&cst_offset, &offset, gfc_conv_array_offset (se->expr));
2817 /* Calculate the offsets from all the dimensions. Make sure to associate
2818 the final offset so that we form a chain of loop invariant summands. */
2819 for (n = ar->dimen - 1; n >= 0; n--)
2821 /* Calculate the index for this dimension. */
2822 gfc_init_se (&indexse, se);
2823 gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type);
2824 gfc_add_block_to_block (&se->pre, &indexse.pre);
2826 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2828 /* Check array bounds. */
2832 /* Evaluate the indexse.expr only once. */
2833 indexse.expr = save_expr (indexse.expr);
2836 tmp = gfc_conv_array_lbound (se->expr, n);
2837 if (sym->attr.temporary)
2839 gfc_init_se (&tmpse, se);
2840 gfc_conv_expr_type (&tmpse, ar->as->lower[n],
2841 gfc_array_index_type);
2842 gfc_add_block_to_block (&se->pre, &tmpse.pre);
2846 cond = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
2848 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
2849 "below lower bound of %%ld", n+1, sym->name);
2850 gfc_trans_runtime_check (true, false, cond, &se->pre, where, msg,
2851 fold_convert (long_integer_type_node,
2853 fold_convert (long_integer_type_node, tmp));
2856 /* Upper bound, but not for the last dimension of assumed-size
2858 if (n < ar->dimen - 1 || ar->as->type != AS_ASSUMED_SIZE)
2860 tmp = gfc_conv_array_ubound (se->expr, n);
2861 if (sym->attr.temporary)
2863 gfc_init_se (&tmpse, se);
2864 gfc_conv_expr_type (&tmpse, ar->as->upper[n],
2865 gfc_array_index_type);
2866 gfc_add_block_to_block (&se->pre, &tmpse.pre);
2870 cond = fold_build2_loc (input_location, GT_EXPR,
2871 boolean_type_node, indexse.expr, tmp);
2872 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
2873 "above upper bound of %%ld", n+1, sym->name);
2874 gfc_trans_runtime_check (true, false, cond, &se->pre, where, msg,
2875 fold_convert (long_integer_type_node,
2877 fold_convert (long_integer_type_node, tmp));
2882 /* Multiply the index by the stride. */
2883 stride = gfc_conv_array_stride (se->expr, n);
2884 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
2885 indexse.expr, stride);
2887 /* And add it to the total. */
2888 add_to_offset (&cst_offset, &offset, tmp);
2891 if (!integer_zerop (cst_offset))
2892 offset = fold_build2_loc (input_location, PLUS_EXPR,
2893 gfc_array_index_type, offset, cst_offset);
2895 /* Access the calculated element. */
2896 tmp = gfc_conv_array_data (se->expr);
2897 tmp = build_fold_indirect_ref (tmp);
2898 se->expr = gfc_build_array_ref (tmp, offset, sym->backend_decl);
2902 /* Add the offset corresponding to array's ARRAY_DIM dimension and loop's
2903 LOOP_DIM dimension (if any) to array's offset. */
2906 add_array_offset (stmtblock_t *pblock, gfc_loopinfo *loop, gfc_ss *ss,
2907 gfc_array_ref *ar, int array_dim, int loop_dim)
2910 gfc_array_info *info;
2913 info = &ss->info->data.array;
2915 gfc_init_se (&se, NULL);
2917 se.expr = info->descriptor;
2918 stride = gfc_conv_array_stride (info->descriptor, array_dim);
2919 index = conv_array_index_offset (&se, ss, array_dim, loop_dim, ar, stride);
2920 gfc_add_block_to_block (pblock, &se.pre);
2922 info->offset = fold_build2_loc (input_location, PLUS_EXPR,
2923 gfc_array_index_type,
2924 info->offset, index);
2925 info->offset = gfc_evaluate_now (info->offset, pblock);
2929 /* Generate the code to be executed immediately before entering a
2930 scalarization loop. */
2933 gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
2934 stmtblock_t * pblock)
2937 gfc_ss_info *ss_info;
2938 gfc_array_info *info;
2939 gfc_ss_type ss_type;
2944 /* This code will be executed before entering the scalarization loop
2945 for this dimension. */
2946 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2950 if ((ss_info->useflags & flag) == 0)
2953 ss_type = ss_info->type;
2954 if (ss_type != GFC_SS_SECTION
2955 && ss_type != GFC_SS_FUNCTION
2956 && ss_type != GFC_SS_CONSTRUCTOR
2957 && ss_type != GFC_SS_COMPONENT)
2960 info = &ss_info->data.array;
2962 gcc_assert (dim < ss->dimen);
2963 gcc_assert (ss->dimen == loop->dimen);
2966 ar = &info->ref->u.ar;
2970 if (dim == loop->dimen - 1)
2975 /* For the time being, there is no loop reordering. */
2976 gcc_assert (i == loop->order[i]);
2979 if (dim == loop->dimen - 1)
2981 stride = gfc_conv_array_stride (info->descriptor, ss->dim[i]);
2983 /* Calculate the stride of the innermost loop. Hopefully this will
2984 allow the backend optimizers to do their stuff more effectively.
2986 info->stride0 = gfc_evaluate_now (stride, pblock);
2988 /* For the outermost loop calculate the offset due to any
2989 elemental dimensions. It will have been initialized with the
2990 base offset of the array. */
2993 for (i = 0; i < ar->dimen; i++)
2995 if (ar->dimen_type[i] != DIMEN_ELEMENT)
2998 add_array_offset (pblock, loop, ss, ar, i, /* unused */ -1);
3003 /* Add the offset for the previous loop dimension. */
3004 add_array_offset (pblock, loop, ss, ar, ss->dim[i], i);
3006 /* Remember this offset for the second loop. */
3007 if (dim == loop->temp_dim - 1)
3008 info->saved_offset = info->offset;
3013 /* Start a scalarized expression. Creates a scope and declares loop
3017 gfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody)
3023 gcc_assert (!loop->array_parameter);
3025 for (dim = loop->dimen - 1; dim >= 0; dim--)
3027 n = loop->order[dim];
3029 gfc_start_block (&loop->code[n]);
3031 /* Create the loop variable. */
3032 loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "S");
3034 if (dim < loop->temp_dim)
3038 /* Calculate values that will be constant within this loop. */
3039 gfc_trans_preloop_setup (loop, dim, flags, &loop->code[n]);
3041 gfc_start_block (pbody);
3045 /* Generates the actual loop code for a scalarization loop. */
3048 gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
3049 stmtblock_t * pbody)
3060 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS))
3061 == (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS)
3062 && n == loop->dimen - 1)
3064 /* We create an OMP_FOR construct for the outermost scalarized loop. */
3065 init = make_tree_vec (1);
3066 cond = make_tree_vec (1);
3067 incr = make_tree_vec (1);
3069 /* Cycle statement is implemented with a goto. Exit statement must not
3070 be present for this loop. */
3071 exit_label = gfc_build_label_decl (NULL_TREE);
3072 TREE_USED (exit_label) = 1;
3074 /* Label for cycle statements (if needed). */
3075 tmp = build1_v (LABEL_EXPR, exit_label);
3076 gfc_add_expr_to_block (pbody, tmp);
3078 stmt = make_node (OMP_FOR);
3080 TREE_TYPE (stmt) = void_type_node;
3081 OMP_FOR_BODY (stmt) = loopbody = gfc_finish_block (pbody);
3083 OMP_FOR_CLAUSES (stmt) = build_omp_clause (input_location,
3084 OMP_CLAUSE_SCHEDULE);
3085 OMP_CLAUSE_SCHEDULE_KIND (OMP_FOR_CLAUSES (stmt))
3086 = OMP_CLAUSE_SCHEDULE_STATIC;
3087 if (ompws_flags & OMPWS_NOWAIT)
3088 OMP_CLAUSE_CHAIN (OMP_FOR_CLAUSES (stmt))
3089 = build_omp_clause (input_location, OMP_CLAUSE_NOWAIT);
3091 /* Initialize the loopvar. */
3092 TREE_VEC_ELT (init, 0) = build2_v (MODIFY_EXPR, loop->loopvar[n],
3094 OMP_FOR_INIT (stmt) = init;
3095 /* The exit condition. */
3096 TREE_VEC_ELT (cond, 0) = build2_loc (input_location, LE_EXPR,
3098 loop->loopvar[n], loop->to[n]);
3099 SET_EXPR_LOCATION (TREE_VEC_ELT (cond, 0), input_location);
3100 OMP_FOR_COND (stmt) = cond;
3101 /* Increment the loopvar. */
3102 tmp = build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3103 loop->loopvar[n], gfc_index_one_node);
3104 TREE_VEC_ELT (incr, 0) = fold_build2_loc (input_location, MODIFY_EXPR,
3105 void_type_node, loop->loopvar[n], tmp);
3106 OMP_FOR_INCR (stmt) = incr;
3108 ompws_flags &= ~OMPWS_CURR_SINGLEUNIT;
3109 gfc_add_expr_to_block (&loop->code[n], stmt);
3113 bool reverse_loop = (loop->reverse[n] == GFC_REVERSE_SET)
3114 && (loop->temp_ss == NULL);
3116 loopbody = gfc_finish_block (pbody);
3120 tmp = loop->from[n];
3121 loop->from[n] = loop->to[n];
3125 /* Initialize the loopvar. */
3126 if (loop->loopvar[n] != loop->from[n])
3127 gfc_add_modify (&loop->code[n], loop->loopvar[n], loop->from[n]);
3129 exit_label = gfc_build_label_decl (NULL_TREE);
3131 /* Generate the loop body. */
3132 gfc_init_block (&block);
3134 /* The exit condition. */
3135 cond = fold_build2_loc (input_location, reverse_loop ? LT_EXPR : GT_EXPR,
3136 boolean_type_node, loop->loopvar[n], loop->to[n]);
3137 tmp = build1_v (GOTO_EXPR, exit_label);
3138 TREE_USED (exit_label) = 1;
3139 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
3140 gfc_add_expr_to_block (&block, tmp);
3142 /* The main body. */
3143 gfc_add_expr_to_block (&block, loopbody);
3145 /* Increment the loopvar. */
3146 tmp = fold_build2_loc (input_location,
3147 reverse_loop ? MINUS_EXPR : PLUS_EXPR,
3148 gfc_array_index_type, loop->loopvar[n],
3149 gfc_index_one_node);
3151 gfc_add_modify (&block, loop->loopvar[n], tmp);
3153 /* Build the loop. */
3154 tmp = gfc_finish_block (&block);
3155 tmp = build1_v (LOOP_EXPR, tmp);
3156 gfc_add_expr_to_block (&loop->code[n], tmp);
3158 /* Add the exit label. */
3159 tmp = build1_v (LABEL_EXPR, exit_label);
3160 gfc_add_expr_to_block (&loop->code[n], tmp);
3166 /* Finishes and generates the loops for a scalarized expression. */
3169 gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body)
3174 stmtblock_t *pblock;
3178 /* Generate the loops. */
3179 for (dim = 0; dim < loop->dimen; dim++)
3181 n = loop->order[dim];
3182 gfc_trans_scalarized_loop_end (loop, n, pblock);
3183 loop->loopvar[n] = NULL_TREE;
3184 pblock = &loop->code[n];
3187 tmp = gfc_finish_block (pblock);
3188 gfc_add_expr_to_block (&loop->pre, tmp);
3190 /* Clear all the used flags. */
3191 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3192 ss->info->useflags = 0;
3196 /* Finish the main body of a scalarized expression, and start the secondary
3200 gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
3204 stmtblock_t *pblock;
3208 /* We finish as many loops as are used by the temporary. */
3209 for (dim = 0; dim < loop->temp_dim - 1; dim++)
3211 n = loop->order[dim];
3212 gfc_trans_scalarized_loop_end (loop, n, pblock);
3213 loop->loopvar[n] = NULL_TREE;
3214 pblock = &loop->code[n];
3217 /* We don't want to finish the outermost loop entirely. */
3218 n = loop->order[loop->temp_dim - 1];
3219 gfc_trans_scalarized_loop_end (loop, n, pblock);
3221 /* Restore the initial offsets. */
3222 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3224 gfc_ss_type ss_type;
3225 gfc_ss_info *ss_info;
3229 if ((ss_info->useflags & 2) == 0)
3232 ss_type = ss_info->type;
3233 if (ss_type != GFC_SS_SECTION
3234 && ss_type != GFC_SS_FUNCTION
3235 && ss_type != GFC_SS_CONSTRUCTOR
3236 && ss_type != GFC_SS_COMPONENT)
3239 ss_info->data.array.offset = ss_info->data.array.saved_offset;
3242 /* Restart all the inner loops we just finished. */
3243 for (dim = loop->temp_dim - 2; dim >= 0; dim--)
3245 n = loop->order[dim];
3247 gfc_start_block (&loop->code[n]);
3249 loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "Q");
3251 gfc_trans_preloop_setup (loop, dim, 2, &loop->code[n]);
3254 /* Start a block for the secondary copying code. */
3255 gfc_start_block (body);
3259 /* Precalculate (either lower or upper) bound of an array section.
3260 BLOCK: Block in which the (pre)calculation code will go.
3261 BOUNDS[DIM]: Where the bound value will be stored once evaluated.
3262 VALUES[DIM]: Specified bound (NULL <=> unspecified).
3263 DESC: Array descriptor from which the bound will be picked if unspecified
3264 (either lower or upper bound according to LBOUND). */
3267 evaluate_bound (stmtblock_t *block, tree *bounds, gfc_expr ** values,
3268 tree desc, int dim, bool lbound)
3271 gfc_expr * input_val = values[dim];
3272 tree *output = &bounds[dim];
3277 /* Specified section bound. */
3278 gfc_init_se (&se, NULL);
3279 gfc_conv_expr_type (&se, input_val, gfc_array_index_type);
3280 gfc_add_block_to_block (block, &se.pre);
3285 /* No specific bound specified so use the bound of the array. */
3286 *output = lbound ? gfc_conv_array_lbound (desc, dim) :
3287 gfc_conv_array_ubound (desc, dim);
3289 *output = gfc_evaluate_now (*output, block);
3293 /* Calculate the lower bound of an array section. */
3296 gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int dim)
3298 gfc_expr *stride = NULL;
3301 gfc_array_info *info;
3304 gcc_assert (ss->info->type == GFC_SS_SECTION);
3306 info = &ss->info->data.array;
3307 ar = &info->ref->u.ar;
3309 if (ar->dimen_type[dim] == DIMEN_VECTOR)
3311 /* We use a zero-based index to access the vector. */
3312 info->start[dim] = gfc_index_zero_node;
3313 info->end[dim] = NULL;
3314 info->stride[dim] = gfc_index_one_node;
3318 gcc_assert (ar->dimen_type[dim] == DIMEN_RANGE
3319 || ar->dimen_type[dim] == DIMEN_THIS_IMAGE);
3320 desc = info->descriptor;
3321 stride = ar->stride[dim];
3323 /* Calculate the start of the range. For vector subscripts this will
3324 be the range of the vector. */
3325 evaluate_bound (&loop->pre, info->start, ar->start, desc, dim, true);
3327 /* Similarly calculate the end. Although this is not used in the
3328 scalarizer, it is needed when checking bounds and where the end
3329 is an expression with side-effects. */
3330 evaluate_bound (&loop->pre, info->end, ar->end, desc, dim, false);
3332 /* Calculate the stride. */
3334 info->stride[dim] = gfc_index_one_node;
3337 gfc_init_se (&se, NULL);
3338 gfc_conv_expr_type (&se, stride, gfc_array_index_type);
3339 gfc_add_block_to_block (&loop->pre, &se.pre);
3340 info->stride[dim] = gfc_evaluate_now (se.expr, &loop->pre);
3345 /* Calculates the range start and stride for a SS chain. Also gets the
3346 descriptor and data pointer. The range of vector subscripts is the size
3347 of the vector. Array bounds are also checked. */
3350 gfc_conv_ss_startstride (gfc_loopinfo * loop)
3358 /* Determine the rank of the loop. */
3359 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3361 switch (ss->info->type)
3363 case GFC_SS_SECTION:
3364 case GFC_SS_CONSTRUCTOR:
3365 case GFC_SS_FUNCTION:
3366 case GFC_SS_COMPONENT:
3367 loop->dimen = ss->dimen;
3370 /* As usual, lbound and ubound are exceptions!. */
3371 case GFC_SS_INTRINSIC:
3372 switch (ss->info->expr->value.function.isym->id)
3374 case GFC_ISYM_LBOUND:
3375 case GFC_ISYM_UBOUND:
3376 case GFC_ISYM_LCOBOUND:
3377 case GFC_ISYM_UCOBOUND:
3378 case GFC_ISYM_THIS_IMAGE:
3379 loop->dimen = ss->dimen;
3391 /* We should have determined the rank of the expression by now. If
3392 not, that's bad news. */
3396 /* Loop over all the SS in the chain. */
3397 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3399 gfc_ss_info *ss_info;
3400 gfc_array_info *info;
3404 expr = ss_info->expr;
3405 info = &ss_info->data.array;
3407 if (expr && expr->shape && !info->shape)
3408 info->shape = expr->shape;
3410 switch (ss_info->type)
3412 case GFC_SS_SECTION:
3413 /* Get the descriptor for the array. */
3414 gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter);
3416 for (n = 0; n < ss->dimen; n++)
3417 gfc_conv_section_startstride (loop, ss, ss->dim[n]);
3420 case GFC_SS_INTRINSIC:
3421 switch (expr->value.function.isym->id)
3423 /* Fall through to supply start and stride. */
3424 case GFC_ISYM_LBOUND:
3425 case GFC_ISYM_UBOUND:
3426 case GFC_ISYM_LCOBOUND:
3427 case GFC_ISYM_UCOBOUND:
3428 case GFC_ISYM_THIS_IMAGE:
3435 case GFC_SS_CONSTRUCTOR:
3436 case GFC_SS_FUNCTION:
3437 for (n = 0; n < ss->dimen; n++)
3439 int dim = ss->dim[n];
3441 info->start[dim] = gfc_index_zero_node;
3442 info->end[dim] = gfc_index_zero_node;
3443 info->stride[dim] = gfc_index_one_node;
3452 /* The rest is just runtime bound checking. */
3453 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
3456 tree lbound, ubound;
3458 tree size[GFC_MAX_DIMENSIONS];
3459 tree stride_pos, stride_neg, non_zerosized, tmp2, tmp3;
3460 gfc_array_info *info;
3464 gfc_start_block (&block);
3466 for (n = 0; n < loop->dimen; n++)
3467 size[n] = NULL_TREE;
3469 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3472 gfc_ss_info *ss_info;
3475 const char *expr_name;
3478 if (ss_info->type != GFC_SS_SECTION)
3481 /* Catch allocatable lhs in f2003. */
3482 if (gfc_option.flag_realloc_lhs && ss->is_alloc_lhs)
3485 expr = ss_info->expr;
3486 expr_loc = &expr->where;
3487 expr_name = expr->symtree->name;
3489 gfc_start_block (&inner);
3491 /* TODO: range checking for mapped dimensions. */
3492 info = &ss_info->data.array;
3494 /* This code only checks ranges. Elemental and vector
3495 dimensions are checked later. */
3496 for (n = 0; n < loop->dimen; n++)
3501 if (info->ref->u.ar.dimen_type[dim] != DIMEN_RANGE)
3504 if (dim == info->ref->u.ar.dimen - 1
3505 && info->ref->u.ar.as->type == AS_ASSUMED_SIZE)
3506 check_upper = false;
3510 /* Zero stride is not allowed. */
3511 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
3512 info->stride[dim], gfc_index_zero_node);
3513 asprintf (&msg, "Zero stride is not allowed, for dimension %d "
3514 "of array '%s'", dim + 1, expr_name);
3515 gfc_trans_runtime_check (true, false, tmp, &inner,
3519 desc = info->descriptor;
3521 /* This is the run-time equivalent of resolve.c's
3522 check_dimension(). The logical is more readable there
3523 than it is here, with all the trees. */
3524 lbound = gfc_conv_array_lbound (desc, dim);
3525 end = info->end[dim];
3527 ubound = gfc_conv_array_ubound (desc, dim);
3531 /* non_zerosized is true when the selected range is not
3533 stride_pos = fold_build2_loc (input_location, GT_EXPR,
3534 boolean_type_node, info->stride[dim],
3535 gfc_index_zero_node);
3536 tmp = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
3537 info->start[dim], end);
3538 stride_pos = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3539 boolean_type_node, stride_pos, tmp);
3541 stride_neg = fold_build2_loc (input_location, LT_EXPR,
3543 info->stride[dim], gfc_index_zero_node);
3544 tmp = fold_build2_loc (input_location, GE_EXPR, boolean_type_node,
3545 info->start[dim], end);
3546 stride_neg = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3549 non_zerosized = fold_build2_loc (input_location, TRUTH_OR_EXPR,
3551 stride_pos, stride_neg);
3553 /* Check the start of the range against the lower and upper
3554 bounds of the array, if the range is not empty.
3555 If upper bound is present, include both bounds in the
3559 tmp = fold_build2_loc (input_location, LT_EXPR,
3561 info->start[dim], lbound);
3562 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3564 non_zerosized, tmp);
3565 tmp2 = fold_build2_loc (input_location, GT_EXPR,
3567 info->start[dim], ubound);
3568 tmp2 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3570 non_zerosized, tmp2);
3571 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3572 "outside of expected range (%%ld:%%ld)",
3573 dim + 1, expr_name);
3574 gfc_trans_runtime_check (true, false, tmp, &inner,
3576 fold_convert (long_integer_type_node, info->start[dim]),
3577 fold_convert (long_integer_type_node, lbound),
3578 fold_convert (long_integer_type_node, ubound));
3579 gfc_trans_runtime_check (true, false, tmp2, &inner,
3581 fold_convert (long_integer_type_node, info->start[dim]),
3582 fold_convert (long_integer_type_node, lbound),
3583 fold_convert (long_integer_type_node, ubound));
3588 tmp = fold_build2_loc (input_location, LT_EXPR,
3590 info->start[dim], lbound);
3591 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3592 boolean_type_node, non_zerosized, tmp);
3593 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3594 "below lower bound of %%ld",
3595 dim + 1, expr_name);
3596 gfc_trans_runtime_check (true, false, tmp, &inner,
3598 fold_convert (long_integer_type_node, info->start[dim]),
3599 fold_convert (long_integer_type_node, lbound));
3603 /* Compute the last element of the range, which is not
3604 necessarily "end" (think 0:5:3, which doesn't contain 5)
3605 and check it against both lower and upper bounds. */
3607 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3608 gfc_array_index_type, end,
3610 tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
3611 gfc_array_index_type, tmp,
3613 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3614 gfc_array_index_type, end, tmp);
3615 tmp2 = fold_build2_loc (input_location, LT_EXPR,
3616 boolean_type_node, tmp, lbound);
3617 tmp2 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3618 boolean_type_node, non_zerosized, tmp2);
3621 tmp3 = fold_build2_loc (input_location, GT_EXPR,
3622 boolean_type_node, tmp, ubound);
3623 tmp3 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3624 boolean_type_node, non_zerosized, tmp3);
3625 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3626 "outside of expected range (%%ld:%%ld)",
3627 dim + 1, expr_name);
3628 gfc_trans_runtime_check (true, false, tmp2, &inner,
3630 fold_convert (long_integer_type_node, tmp),
3631 fold_convert (long_integer_type_node, ubound),
3632 fold_convert (long_integer_type_node, lbound));
3633 gfc_trans_runtime_check (true, false, tmp3, &inner,
3635 fold_convert (long_integer_type_node, tmp),
3636 fold_convert (long_integer_type_node, ubound),
3637 fold_convert (long_integer_type_node, lbound));
3642 asprintf (&msg, "Index '%%ld' of dimension %d of array '%s' "
3643 "below lower bound of %%ld",
3644 dim + 1, expr_name);
3645 gfc_trans_runtime_check (true, false, tmp2, &inner,
3647 fold_convert (long_integer_type_node, tmp),
3648 fold_convert (long_integer_type_node, lbound));
3652 /* Check the section sizes match. */
3653 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3654 gfc_array_index_type, end,
3656 tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR,
3657 gfc_array_index_type, tmp,
3659 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3660 gfc_array_index_type,
3661 gfc_index_one_node, tmp);
3662 tmp = fold_build2_loc (input_location, MAX_EXPR,
3663 gfc_array_index_type, tmp,
3664 build_int_cst (gfc_array_index_type, 0));
3665 /* We remember the size of the first section, and check all the
3666 others against this. */
3669 tmp3 = fold_build2_loc (input_location, NE_EXPR,
3670 boolean_type_node, tmp, size[n]);
3671 asprintf (&msg, "Array bound mismatch for dimension %d "
3672 "of array '%s' (%%ld/%%ld)",
3673 dim + 1, expr_name);
3675 gfc_trans_runtime_check (true, false, tmp3, &inner,
3677 fold_convert (long_integer_type_node, tmp),
3678 fold_convert (long_integer_type_node, size[n]));
3683 size[n] = gfc_evaluate_now (tmp, &inner);
3686 tmp = gfc_finish_block (&inner);
3688 /* For optional arguments, only check bounds if the argument is
3690 if (expr->symtree->n.sym->attr.optional
3691 || expr->symtree->n.sym->attr.not_always_present)
3692 tmp = build3_v (COND_EXPR,
3693 gfc_conv_expr_present (expr->symtree->n.sym),
3694 tmp, build_empty_stmt (input_location));
3696 gfc_add_expr_to_block (&block, tmp);
3700 tmp = gfc_finish_block (&block);
3701 gfc_add_expr_to_block (&loop->pre, tmp);
3705 /* Return true if both symbols could refer to the same data object. Does
3706 not take account of aliasing due to equivalence statements. */
3709 symbols_could_alias (gfc_symbol *lsym, gfc_symbol *rsym, bool lsym_pointer,
3710 bool lsym_target, bool rsym_pointer, bool rsym_target)
3712 /* Aliasing isn't possible if the symbols have different base types. */
3713 if (gfc_compare_types (&lsym->ts, &rsym->ts) == 0)
3716 /* Pointers can point to other pointers and target objects. */
3718 if ((lsym_pointer && (rsym_pointer || rsym_target))
3719 || (rsym_pointer && (lsym_pointer || lsym_target)))
3722 /* Special case: Argument association, cf. F90 12.4.1.6, F2003 12.4.1.7
3723 and F2008 12.5.2.13 items 3b and 4b. The pointer case (a) is already
3725 if (lsym_target && rsym_target
3726 && ((lsym->attr.dummy && !lsym->attr.contiguous
3727 && (!lsym->attr.dimension || lsym->as->type == AS_ASSUMED_SHAPE))
3728 || (rsym->attr.dummy && !rsym->attr.contiguous
3729 && (!rsym->attr.dimension
3730 || rsym->as->type == AS_ASSUMED_SHAPE))))
3737 /* Return true if the two SS could be aliased, i.e. both point to the same data
3739 /* TODO: resolve aliases based on frontend expressions. */
3742 gfc_could_be_alias (gfc_ss * lss, gfc_ss * rss)
3746 gfc_expr *lexpr, *rexpr;
3749 bool lsym_pointer, lsym_target, rsym_pointer, rsym_target;
3751 lexpr = lss->info->expr;
3752 rexpr = rss->info->expr;
3754 lsym = lexpr->symtree->n.sym;
3755 rsym = rexpr->symtree->n.sym;
3757 lsym_pointer = lsym->attr.pointer;
3758 lsym_target = lsym->attr.target;
3759 rsym_pointer = rsym->attr.pointer;
3760 rsym_target = rsym->attr.target;
3762 if (symbols_could_alias (lsym, rsym, lsym_pointer, lsym_target,
3763 rsym_pointer, rsym_target))
3766 if (rsym->ts.type != BT_DERIVED && rsym->ts.type != BT_CLASS
3767 && lsym->ts.type != BT_DERIVED && lsym->ts.type != BT_CLASS)
3770 /* For derived types we must check all the component types. We can ignore
3771 array references as these will have the same base type as the previous
3773 for (lref = lexpr->ref; lref != lss->info->data.array.ref; lref = lref->next)
3775 if (lref->type != REF_COMPONENT)
3778 lsym_pointer = lsym_pointer || lref->u.c.sym->attr.pointer;
3779 lsym_target = lsym_target || lref->u.c.sym->attr.target;
3781 if (symbols_could_alias (lref->u.c.sym, rsym, lsym_pointer, lsym_target,
3782 rsym_pointer, rsym_target))
3785 if ((lsym_pointer && (rsym_pointer || rsym_target))
3786 || (rsym_pointer && (lsym_pointer || lsym_target)))
3788 if (gfc_compare_types (&lref->u.c.component->ts,
3793 for (rref = rexpr->ref; rref != rss->info->data.array.ref;
3796 if (rref->type != REF_COMPONENT)
3799 rsym_pointer = rsym_pointer || rref->u.c.sym->attr.pointer;
3800 rsym_target = lsym_target || rref->u.c.sym->attr.target;
3802 if (symbols_could_alias (lref->u.c.sym, rref->u.c.sym,
3803 lsym_pointer, lsym_target,
3804 rsym_pointer, rsym_target))
3807 if ((lsym_pointer && (rsym_pointer || rsym_target))
3808 || (rsym_pointer && (lsym_pointer || lsym_target)))
3810 if (gfc_compare_types (&lref->u.c.component->ts,
3811 &rref->u.c.sym->ts))
3813 if (gfc_compare_types (&lref->u.c.sym->ts,
3814 &rref->u.c.component->ts))
3816 if (gfc_compare_types (&lref->u.c.component->ts,
3817 &rref->u.c.component->ts))
3823 lsym_pointer = lsym->attr.pointer;
3824 lsym_target = lsym->attr.target;
3825 lsym_pointer = lsym->attr.pointer;
3826 lsym_target = lsym->attr.target;
3828 for (rref = rexpr->ref; rref != rss->info->data.array.ref; rref = rref->next)
3830 if (rref->type != REF_COMPONENT)
3833 rsym_pointer = rsym_pointer || rref->u.c.sym->attr.pointer;
3834 rsym_target = lsym_target || rref->u.c.sym->attr.target;
3836 if (symbols_could_alias (rref->u.c.sym, lsym,
3837 lsym_pointer, lsym_target,
3838 rsym_pointer, rsym_target))
3841 if ((lsym_pointer && (rsym_pointer || rsym_target))
3842 || (rsym_pointer && (lsym_pointer || lsym_target)))
3844 if (gfc_compare_types (&lsym->ts, &rref->u.c.component->ts))
3853 /* Resolve array data dependencies. Creates a temporary if required. */
3854 /* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
3858 gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
3864 gfc_expr *dest_expr;
3869 loop->temp_ss = NULL;
3870 dest_expr = dest->info->expr;
3872 for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
3874 if (ss->info->type != GFC_SS_SECTION)
3877 ss_expr = ss->info->expr;
3879 if (dest_expr->symtree->n.sym != ss_expr->symtree->n.sym)
3881 if (gfc_could_be_alias (dest, ss)
3882 || gfc_are_equivalenced_arrays (dest_expr, ss_expr))
3890 lref = dest_expr->ref;
3891 rref = ss_expr->ref;
3893 nDepend = gfc_dep_resolver (lref, rref, &loop->reverse[0]);
3898 for (i = 0; i < dest->dimen; i++)
3899 for (j = 0; j < ss->dimen; j++)
3901 && dest->dim[i] == ss->dim[j])
3903 /* If we don't access array elements in the same order,
3904 there is a dependency. */
3909 /* TODO : loop shifting. */
3912 /* Mark the dimensions for LOOP SHIFTING */
3913 for (n = 0; n < loop->dimen; n++)
3915 int dim = dest->data.info.dim[n];
3917 if (lref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
3919 else if (! gfc_is_same_range (&lref->u.ar,
3920 &rref->u.ar, dim, 0))
3924 /* Put all the dimensions with dependencies in the
3927 for (n = 0; n < loop->dimen; n++)