* combine.c (try_combine): Use hard_regno_nregs array instead of
[official-gcc.git] / gcc / fortran / trans-array.c
blob3554107ab832dd41c8ebbca14f79b50a9517fca9
1 /* Array translation routines
2 Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
23 /* trans-array.c-- Various array related code, including scalarization,
24 allocation, initialization and other support routines. */
26 /* How the scalarizer works.
27 In gfortran, array expressions use the same core routines as scalar
28 expressions.
29 First, a Scalarization State (SS) chain is built. This is done by walking
30 the expression tree, and building a linear list of the terms in the
31 expression. As the tree is walked, scalar subexpressions are translated.
33 The scalarization parameters are stored in a gfc_loopinfo structure.
34 First the start and stride of each term is calculated by
35 gfc_conv_ss_startstride. During this process the expressions for the array
36 descriptors and data pointers are also translated.
38 If the expression is an assignment, we must then resolve any dependencies.
39 In fortran all the rhs values of an assignment must be evaluated before
40 any assignments take place. This can require a temporary array to store the
41 values. We also require a temporary when we are passing array expressions
42 or vector subecripts as procedure parameters.
44 Array sections are passed without copying to a temporary. These use the
45 scalarizer to determine the shape of the section. The flag
46 loop->array_parameter tells the scalarizer that the actual values and loop
47 variables will not be required.
49 The function gfc_conv_loop_setup generates the scalarization setup code.
50 It determines the range of the scalarizing loop variables. If a temporary
51 is required, this is created and initialized. Code for scalar expressions
52 taken outside the loop is also generated at this time. Next the offset and
53 scaling required to translate from loop variables to array indices for each
54 term is calculated.
56 A call to gfc_start_scalarized_body marks the start of the scalarized
57 expression. This creates a scope and declares the loop variables. Before
58 calling this gfc_make_ss_chain_used must be used to indicate which terms
59 will be used inside this loop.
61 The scalar gfc_conv_* functions are then used to build the main body of the
62 scalarization loop. Scalarization loop variables and precalculated scalar
63 values are automatically substituted. Note that gfc_advance_se_ss_chain
64 must be used, rather than changing the se->ss directly.
66 For assignment expressions requiring a temporary two sub loops are
67 generated. The first stores the result of the expression in the temporary,
68 the second copies it to the result. A call to
69 gfc_trans_scalarized_loop_boundary marks the end of the main loop code and
70 the start of the copying loop. The temporary may be less than full rank.
72 Finally gfc_trans_scalarizing_loops is called to generate the implicit do
73 loops. The loops are added to the pre chain of the loopinfo. The post
74 chain may still contain cleanup code.
76 After the loop code has been added into its parent scope gfc_cleanup_loop
77 is called to free all the SS allocated by the scalarizer. */
79 #include "config.h"
80 #include "system.h"
81 #include "coretypes.h"
82 #include "tree.h"
83 #include "tree-gimple.h"
84 #include "ggc.h"
85 #include "toplev.h"
86 #include "real.h"
87 #include "flags.h"
88 #include "gfortran.h"
89 #include "trans.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 gfc_ss *gfc_walk_subexpr (gfc_ss *, gfc_expr *);
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;
103 static tree
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! */
128 #define DATA_FIELD 0
129 #define OFFSET_FIELD 1
130 #define DTYPE_FIELD 2
131 #define DIMENSION_FIELD 3
133 #define STRIDE_SUBFIELD 0
134 #define LBOUND_SUBFIELD 1
135 #define UBOUND_SUBFIELD 2
137 tree
138 gfc_conv_descriptor_data (tree desc)
140 tree field;
141 tree type;
143 type = TREE_TYPE (desc);
144 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
146 field = TYPE_FIELDS (type);
147 gcc_assert (DATA_FIELD == 0);
148 gcc_assert (field != NULL_TREE
149 && TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE
150 && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == ARRAY_TYPE);
152 return build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
155 tree
156 gfc_conv_descriptor_offset (tree desc)
158 tree type;
159 tree field;
161 type = TREE_TYPE (desc);
162 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
164 field = gfc_advance_chain (TYPE_FIELDS (type), OFFSET_FIELD);
165 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
167 return build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
170 tree
171 gfc_conv_descriptor_dtype (tree desc)
173 tree field;
174 tree type;
176 type = TREE_TYPE (desc);
177 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
179 field = gfc_advance_chain (TYPE_FIELDS (type), DTYPE_FIELD);
180 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
182 return build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
185 static tree
186 gfc_conv_descriptor_dimension (tree desc, tree dim)
188 tree field;
189 tree type;
190 tree tmp;
192 type = TREE_TYPE (desc);
193 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
195 field = gfc_advance_chain (TYPE_FIELDS (type), DIMENSION_FIELD);
196 gcc_assert (field != NULL_TREE
197 && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
198 && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE);
200 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
201 tmp = gfc_build_array_ref (tmp, dim);
202 return tmp;
205 tree
206 gfc_conv_descriptor_stride (tree desc, tree dim)
208 tree tmp;
209 tree field;
211 tmp = gfc_conv_descriptor_dimension (desc, dim);
212 field = TYPE_FIELDS (TREE_TYPE (tmp));
213 field = gfc_advance_chain (field, STRIDE_SUBFIELD);
214 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
216 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
217 return tmp;
220 tree
221 gfc_conv_descriptor_lbound (tree desc, tree dim)
223 tree tmp;
224 tree field;
226 tmp = gfc_conv_descriptor_dimension (desc, dim);
227 field = TYPE_FIELDS (TREE_TYPE (tmp));
228 field = gfc_advance_chain (field, LBOUND_SUBFIELD);
229 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
231 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
232 return tmp;
235 tree
236 gfc_conv_descriptor_ubound (tree desc, tree dim)
238 tree tmp;
239 tree field;
241 tmp = gfc_conv_descriptor_dimension (desc, dim);
242 field = TYPE_FIELDS (TREE_TYPE (tmp));
243 field = gfc_advance_chain (field, UBOUND_SUBFIELD);
244 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
246 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
247 return tmp;
251 /* Build an null array descriptor constructor. */
253 tree
254 gfc_build_null_descriptor (tree type)
256 tree field;
257 tree tmp;
259 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
260 gcc_assert (DATA_FIELD == 0);
261 field = TYPE_FIELDS (type);
263 /* Set a NULL data pointer. */
264 tmp = tree_cons (field, null_pointer_node, NULL_TREE);
265 tmp = build1 (CONSTRUCTOR, type, tmp);
266 TREE_CONSTANT (tmp) = 1;
267 TREE_INVARIANT (tmp) = 1;
268 /* All other fields are ignored. */
270 return tmp;
274 /* Cleanup those #defines. */
276 #undef DATA_FIELD
277 #undef OFFSET_FIELD
278 #undef DTYPE_FIELD
279 #undef DIMENSION_FIELD
280 #undef STRIDE_SUBFIELD
281 #undef LBOUND_SUBFIELD
282 #undef UBOUND_SUBFIELD
285 /* Mark a SS chain as used. Flags specifies in which loops the SS is used.
286 flags & 1 = Main loop body.
287 flags & 2 = temp copy loop. */
289 void
290 gfc_mark_ss_chain_used (gfc_ss * ss, unsigned flags)
292 for (; ss != gfc_ss_terminator; ss = ss->next)
293 ss->useflags = flags;
296 static void gfc_free_ss (gfc_ss *);
299 /* Free a gfc_ss chain. */
301 static void
302 gfc_free_ss_chain (gfc_ss * ss)
304 gfc_ss *next;
306 while (ss != gfc_ss_terminator)
308 gcc_assert (ss != NULL);
309 next = ss->next;
310 gfc_free_ss (ss);
311 ss = next;
316 /* Free a SS. */
318 static void
319 gfc_free_ss (gfc_ss * ss)
321 int n;
323 switch (ss->type)
325 case GFC_SS_SECTION:
326 case GFC_SS_VECTOR:
327 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
329 if (ss->data.info.subscript[n])
330 gfc_free_ss_chain (ss->data.info.subscript[n]);
332 break;
334 default:
335 break;
338 gfc_free (ss);
342 /* Free all the SS associated with a loop. */
344 void
345 gfc_cleanup_loop (gfc_loopinfo * loop)
347 gfc_ss *ss;
348 gfc_ss *next;
350 ss = loop->ss;
351 while (ss != gfc_ss_terminator)
353 gcc_assert (ss != NULL);
354 next = ss->loop_chain;
355 gfc_free_ss (ss);
356 ss = next;
361 /* Associate a SS chain with a loop. */
363 void
364 gfc_add_ss_to_loop (gfc_loopinfo * loop, gfc_ss * head)
366 gfc_ss *ss;
368 if (head == gfc_ss_terminator)
369 return;
371 ss = head;
372 for (; ss && ss != gfc_ss_terminator; ss = ss->next)
374 if (ss->next == gfc_ss_terminator)
375 ss->loop_chain = loop->ss;
376 else
377 ss->loop_chain = ss->next;
379 gcc_assert (ss == gfc_ss_terminator);
380 loop->ss = head;
384 /* Generate an initializer for a static pointer or allocatable array. */
386 void
387 gfc_trans_static_array_pointer (gfc_symbol * sym)
389 tree type;
391 gcc_assert (TREE_STATIC (sym->backend_decl));
392 /* Just zero the data member. */
393 type = TREE_TYPE (sym->backend_decl);
394 DECL_INITIAL (sym->backend_decl) = gfc_build_null_descriptor (type);
398 /* Generate code to allocate an array temporary, or create a variable to
399 hold the data. If size is NULL zero the descriptor so that so that the
400 callee will allocate the array. Also generates code to free the array
401 afterwards. */
403 static void
404 gfc_trans_allocate_array_storage (gfc_loopinfo * loop, gfc_ss_info * info,
405 tree size, tree nelem)
407 tree tmp;
408 tree args;
409 tree desc;
410 tree data;
411 bool onstack;
413 desc = info->descriptor;
414 data = gfc_conv_descriptor_data (desc);
415 if (size == NULL_TREE)
417 /* A callee allocated array. */
418 gfc_add_modify_expr (&loop->pre, data, convert (TREE_TYPE (data),
419 gfc_index_zero_node));
420 info->data = data;
421 info->offset = gfc_index_zero_node;
422 onstack = FALSE;
424 else
426 /* Allocate the temporary. */
427 onstack = gfc_can_put_var_on_stack (size);
429 if (onstack)
431 /* Make a temporary variable to hold the data. */
432 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (nelem), nelem,
433 integer_one_node);
434 tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
435 tmp);
436 tmp = build_array_type (gfc_get_element_type (TREE_TYPE (desc)),
437 tmp);
438 tmp = gfc_create_var (tmp, "A");
439 tmp = gfc_build_addr_expr (TREE_TYPE (data), tmp);
440 gfc_add_modify_expr (&loop->pre, data, tmp);
441 info->data = data;
442 info->offset = gfc_index_zero_node;
445 else
447 /* Allocate memory to hold the data. */
448 args = gfc_chainon_list (NULL_TREE, size);
450 if (gfc_index_integer_kind == 4)
451 tmp = gfor_fndecl_internal_malloc;
452 else if (gfc_index_integer_kind == 8)
453 tmp = gfor_fndecl_internal_malloc64;
454 else
455 gcc_unreachable ();
456 tmp = gfc_build_function_call (tmp, args);
457 tmp = convert (TREE_TYPE (data), tmp);
458 gfc_add_modify_expr (&loop->pre, data, tmp);
460 info->data = data;
461 info->offset = gfc_index_zero_node;
465 /* The offset is zero because we create temporaries with a zero
466 lower bound. */
467 tmp = gfc_conv_descriptor_offset (desc);
468 gfc_add_modify_expr (&loop->pre, tmp, gfc_index_zero_node);
470 if (!onstack)
472 /* Free the temporary. */
473 tmp = convert (pvoid_type_node, info->data);
474 tmp = gfc_chainon_list (NULL_TREE, tmp);
475 tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
476 gfc_add_expr_to_block (&loop->post, tmp);
481 /* Generate code to allocate and initialize the descriptor for a temporary
482 array. This is used for both temporaries needed by the scalarizer, and
483 functions returning arrays. Adjusts the loop variables to be zero-based,
484 and calculates the loop bounds for callee allocated arrays.
485 Also fills in the descriptor, data and offset fields of info if known.
486 Returns the size of the array, or NULL for a callee allocated array. */
488 tree
489 gfc_trans_allocate_temp_array (gfc_loopinfo * loop, gfc_ss_info * info,
490 tree eltype)
492 tree type;
493 tree desc;
494 tree tmp;
495 tree size;
496 tree nelem;
497 int n;
498 int dim;
500 gcc_assert (info->dimen > 0);
501 /* Set the lower bound to zero. */
502 for (dim = 0; dim < info->dimen; dim++)
504 n = loop->order[dim];
505 if (n < loop->temp_dim)
506 gcc_assert (integer_zerop (loop->from[n]));
507 else
509 /* Callee allocated arrays may not have a known bound yet. */
510 if (loop->to[n])
511 loop->to[n] = fold_build2 (MINUS_EXPR, gfc_array_index_type,
512 loop->to[n], loop->from[n]);
513 loop->from[n] = gfc_index_zero_node;
516 info->delta[dim] = gfc_index_zero_node;
517 info->start[dim] = gfc_index_zero_node;
518 info->stride[dim] = gfc_index_one_node;
519 info->dim[dim] = dim;
522 /* Initialize the descriptor. */
523 type =
524 gfc_get_array_type_bounds (eltype, info->dimen, loop->from, loop->to, 1);
525 desc = gfc_create_var (type, "atmp");
526 GFC_DECL_PACKED_ARRAY (desc) = 1;
528 info->descriptor = desc;
529 size = gfc_index_one_node;
531 /* Fill in the array dtype. */
532 tmp = gfc_conv_descriptor_dtype (desc);
533 gfc_add_modify_expr (&loop->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
536 Fill in the bounds and stride. This is a packed array, so:
538 size = 1;
539 for (n = 0; n < rank; n++)
541 stride[n] = size
542 delta = ubound[n] + 1 - lbound[n];
543 size = size * delta;
545 size = size * sizeof(element);
548 for (n = 0; n < info->dimen; n++)
550 if (loop->to[n] == NULL_TREE)
552 /* For a callee allocated array express the loop bounds in terms
553 of the descriptor fields. */
554 tmp = build2 (MINUS_EXPR, gfc_array_index_type,
555 gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]),
556 gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]));
557 loop->to[n] = tmp;
558 size = NULL_TREE;
559 continue;
562 /* Store the stride and bound components in the descriptor. */
563 tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[n]);
564 gfc_add_modify_expr (&loop->pre, tmp, size);
566 tmp = gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]);
567 gfc_add_modify_expr (&loop->pre, tmp, gfc_index_zero_node);
569 tmp = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]);
570 gfc_add_modify_expr (&loop->pre, tmp, loop->to[n]);
572 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
573 loop->to[n], gfc_index_one_node);
575 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
576 size = gfc_evaluate_now (size, &loop->pre);
579 /* Get the size of the array. */
580 nelem = size;
581 if (size)
582 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
583 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
585 gfc_trans_allocate_array_storage (loop, info, size, nelem);
587 if (info->dimen > loop->temp_dim)
588 loop->temp_dim = info->dimen;
590 return size;
594 /* Make sure offset is a variable. */
596 static void
597 gfc_put_offset_into_var (stmtblock_t * pblock, tree * poffset,
598 tree * offsetvar)
600 /* We should have already created the offset variable. We cannot
601 create it here because we may be in an inner scope. */
602 gcc_assert (*offsetvar != NULL_TREE);
603 gfc_add_modify_expr (pblock, *offsetvar, *poffset);
604 *poffset = *offsetvar;
605 TREE_USED (*offsetvar) = 1;
609 /* Assign an element of an array constructor. */
611 static void
612 gfc_trans_array_ctor_element (stmtblock_t * pblock, tree pointer,
613 tree offset, gfc_se * se, gfc_expr * expr)
615 tree tmp;
616 tree args;
618 gfc_conv_expr (se, expr);
620 /* Store the value. */
621 tmp = gfc_build_indirect_ref (pointer);
622 tmp = gfc_build_array_ref (tmp, offset);
623 if (expr->ts.type == BT_CHARACTER)
625 gfc_conv_string_parameter (se);
626 if (POINTER_TYPE_P (TREE_TYPE (tmp)))
628 /* The temporary is an array of pointers. */
629 se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
630 gfc_add_modify_expr (&se->pre, tmp, se->expr);
632 else
634 /* The temporary is an array of string values. */
635 tmp = gfc_build_addr_expr (pchar_type_node, tmp);
636 /* We know the temporary and the value will be the same length,
637 so can use memcpy. */
638 args = gfc_chainon_list (NULL_TREE, tmp);
639 args = gfc_chainon_list (args, se->expr);
640 args = gfc_chainon_list (args, se->string_length);
641 tmp = built_in_decls[BUILT_IN_MEMCPY];
642 tmp = gfc_build_function_call (tmp, args);
643 gfc_add_expr_to_block (&se->pre, tmp);
646 else
648 /* TODO: Should the frontend already have done this conversion? */
649 se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
650 gfc_add_modify_expr (&se->pre, tmp, se->expr);
653 gfc_add_block_to_block (pblock, &se->pre);
654 gfc_add_block_to_block (pblock, &se->post);
658 /* Add the contents of an array to the constructor. */
660 static void
661 gfc_trans_array_constructor_subarray (stmtblock_t * pblock,
662 tree type ATTRIBUTE_UNUSED,
663 tree pointer, gfc_expr * expr,
664 tree * poffset, tree * offsetvar)
666 gfc_se se;
667 gfc_ss *ss;
668 gfc_loopinfo loop;
669 stmtblock_t body;
670 tree tmp;
672 /* We need this to be a variable so we can increment it. */
673 gfc_put_offset_into_var (pblock, poffset, offsetvar);
675 gfc_init_se (&se, NULL);
677 /* Walk the array expression. */
678 ss = gfc_walk_expr (expr);
679 gcc_assert (ss != gfc_ss_terminator);
681 /* Initialize the scalarizer. */
682 gfc_init_loopinfo (&loop);
683 gfc_add_ss_to_loop (&loop, ss);
685 /* Initialize the loop. */
686 gfc_conv_ss_startstride (&loop);
687 gfc_conv_loop_setup (&loop);
689 /* Make the loop body. */
690 gfc_mark_ss_chain_used (ss, 1);
691 gfc_start_scalarized_body (&loop, &body);
692 gfc_copy_loopinfo_to_se (&se, &loop);
693 se.ss = ss;
695 if (expr->ts.type == BT_CHARACTER)
696 gfc_todo_error ("character arrays in constructors");
698 gfc_trans_array_ctor_element (&body, pointer, *poffset, &se, expr);
699 gcc_assert (se.ss == gfc_ss_terminator);
701 /* Increment the offset. */
702 tmp = build2 (PLUS_EXPR, gfc_array_index_type, *poffset, gfc_index_one_node);
703 gfc_add_modify_expr (&body, *poffset, tmp);
705 /* Finish the loop. */
706 gfc_trans_scalarizing_loops (&loop, &body);
707 gfc_add_block_to_block (&loop.pre, &loop.post);
708 tmp = gfc_finish_block (&loop.pre);
709 gfc_add_expr_to_block (pblock, tmp);
711 gfc_cleanup_loop (&loop);
715 /* Assign the values to the elements of an array constructor. */
717 static void
718 gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
719 tree pointer, gfc_constructor * c,
720 tree * poffset, tree * offsetvar)
722 tree tmp;
723 stmtblock_t body;
724 gfc_se se;
726 for (; c; c = c->next)
728 /* If this is an iterator or an array, the offset must be a variable. */
729 if ((c->iterator || c->expr->rank > 0) && INTEGER_CST_P (*poffset))
730 gfc_put_offset_into_var (pblock, poffset, offsetvar);
732 gfc_start_block (&body);
734 if (c->expr->expr_type == EXPR_ARRAY)
736 /* Array constructors can be nested. */
737 gfc_trans_array_constructor_value (&body, type, pointer,
738 c->expr->value.constructor,
739 poffset, offsetvar);
741 else if (c->expr->rank > 0)
743 gfc_trans_array_constructor_subarray (&body, type, pointer,
744 c->expr, poffset, offsetvar);
746 else
748 /* This code really upsets the gimplifier so don't bother for now. */
749 gfc_constructor *p;
750 HOST_WIDE_INT n;
751 HOST_WIDE_INT size;
753 p = c;
754 n = 0;
755 while (p && !(p->iterator || p->expr->expr_type != EXPR_CONSTANT))
757 p = p->next;
758 n++;
760 if (n < 4)
762 /* Scalar values. */
763 gfc_init_se (&se, NULL);
764 gfc_trans_array_ctor_element (&body, pointer, *poffset, &se,
765 c->expr);
767 *poffset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
768 *poffset, gfc_index_one_node);
770 else
772 /* Collect multiple scalar constants into a constructor. */
773 tree list;
774 tree init;
775 tree bound;
776 tree tmptype;
778 p = c;
779 list = NULL_TREE;
780 /* Count the number of consecutive scalar constants. */
781 while (p && !(p->iterator
782 || p->expr->expr_type != EXPR_CONSTANT))
784 gfc_init_se (&se, NULL);
785 gfc_conv_constant (&se, p->expr);
786 if (p->expr->ts.type == BT_CHARACTER
787 && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE
788 (TREE_TYPE (pointer)))))
790 /* For constant character array constructors we build
791 an array of pointers. */
792 se.expr = gfc_build_addr_expr (pchar_type_node,
793 se.expr);
796 list = tree_cons (NULL_TREE, se.expr, list);
797 c = p;
798 p = p->next;
801 bound = build_int_cst (NULL_TREE, n - 1);
802 /* Create an array type to hold them. */
803 tmptype = build_range_type (gfc_array_index_type,
804 gfc_index_zero_node, bound);
805 tmptype = build_array_type (type, tmptype);
807 init = build1 (CONSTRUCTOR, tmptype, nreverse (list));
808 TREE_CONSTANT (init) = 1;
809 TREE_INVARIANT (init) = 1;
810 TREE_STATIC (init) = 1;
811 /* Create a static variable to hold the data. */
812 tmp = gfc_create_var (tmptype, "data");
813 TREE_STATIC (tmp) = 1;
814 TREE_CONSTANT (tmp) = 1;
815 TREE_INVARIANT (tmp) = 1;
816 DECL_INITIAL (tmp) = init;
817 init = tmp;
819 /* Use BUILTIN_MEMCPY to assign the values. */
820 tmp = gfc_build_indirect_ref (pointer);
821 tmp = gfc_build_array_ref (tmp, *poffset);
822 tmp = gfc_build_addr_expr (NULL, tmp);
823 init = gfc_build_addr_expr (NULL, init);
825 size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
826 bound = build_int_cst (NULL_TREE, n * size);
827 tmp = gfc_chainon_list (NULL_TREE, tmp);
828 tmp = gfc_chainon_list (tmp, init);
829 tmp = gfc_chainon_list (tmp, bound);
830 tmp = gfc_build_function_call (built_in_decls[BUILT_IN_MEMCPY],
831 tmp);
832 gfc_add_expr_to_block (&body, tmp);
834 *poffset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
835 *poffset, bound);
837 if (!INTEGER_CST_P (*poffset))
839 gfc_add_modify_expr (&body, *offsetvar, *poffset);
840 *poffset = *offsetvar;
844 /* The frontend should already have done any expansions possible
845 at compile-time. */
846 if (!c->iterator)
848 /* Pass the code as is. */
849 tmp = gfc_finish_block (&body);
850 gfc_add_expr_to_block (pblock, tmp);
852 else
854 /* Build the implied do-loop. */
855 tree cond;
856 tree end;
857 tree step;
858 tree loopvar;
859 tree exit_label;
860 tree loopbody;
862 loopbody = gfc_finish_block (&body);
864 gfc_init_se (&se, NULL);
865 gfc_conv_expr (&se, c->iterator->var);
866 gfc_add_block_to_block (pblock, &se.pre);
867 loopvar = se.expr;
869 /* Initialize the loop. */
870 gfc_init_se (&se, NULL);
871 gfc_conv_expr_val (&se, c->iterator->start);
872 gfc_add_block_to_block (pblock, &se.pre);
873 gfc_add_modify_expr (pblock, loopvar, se.expr);
875 gfc_init_se (&se, NULL);
876 gfc_conv_expr_val (&se, c->iterator->end);
877 gfc_add_block_to_block (pblock, &se.pre);
878 end = gfc_evaluate_now (se.expr, pblock);
880 gfc_init_se (&se, NULL);
881 gfc_conv_expr_val (&se, c->iterator->step);
882 gfc_add_block_to_block (pblock, &se.pre);
883 step = gfc_evaluate_now (se.expr, pblock);
885 /* Generate the loop body. */
886 exit_label = gfc_build_label_decl (NULL_TREE);
887 gfc_start_block (&body);
889 /* Generate the exit condition. Depending on the sign of
890 the step variable we have to generate the correct
891 comparison. */
892 tmp = fold_build2 (GT_EXPR, boolean_type_node, step,
893 build_int_cst (TREE_TYPE (step), 0));
894 cond = fold_build3 (COND_EXPR, boolean_type_node, tmp,
895 build2 (GT_EXPR, boolean_type_node,
896 loopvar, end),
897 build2 (LT_EXPR, boolean_type_node,
898 loopvar, end));
899 tmp = build1_v (GOTO_EXPR, exit_label);
900 TREE_USED (exit_label) = 1;
901 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
902 gfc_add_expr_to_block (&body, tmp);
904 /* The main loop body. */
905 gfc_add_expr_to_block (&body, loopbody);
907 /* Increase loop variable by step. */
908 tmp = build2 (PLUS_EXPR, TREE_TYPE (loopvar), loopvar, step);
909 gfc_add_modify_expr (&body, loopvar, tmp);
911 /* Finish the loop. */
912 tmp = gfc_finish_block (&body);
913 tmp = build1_v (LOOP_EXPR, tmp);
914 gfc_add_expr_to_block (pblock, tmp);
916 /* Add the exit label. */
917 tmp = build1_v (LABEL_EXPR, exit_label);
918 gfc_add_expr_to_block (pblock, tmp);
924 /* Get the size of an expression. Returns -1 if the size isn't constant.
925 Implied do loops with non-constant bounds are tricky because we must only
926 evaluate the bounds once. */
928 static void
929 gfc_get_array_cons_size (mpz_t * size, gfc_constructor * c)
931 gfc_iterator *i;
932 mpz_t val;
933 mpz_t len;
935 mpz_set_ui (*size, 0);
936 mpz_init (len);
937 mpz_init (val);
939 for (; c; c = c->next)
941 if (c->expr->expr_type == EXPR_ARRAY)
943 /* A nested array constructor. */
944 gfc_get_array_cons_size (&len, c->expr->value.constructor);
945 if (mpz_sgn (len) < 0)
947 mpz_set (*size, len);
948 mpz_clear (len);
949 mpz_clear (val);
950 return;
953 else
955 if (c->expr->rank > 0)
957 mpz_set_si (*size, -1);
958 mpz_clear (len);
959 mpz_clear (val);
960 return;
962 mpz_set_ui (len, 1);
965 if (c->iterator)
967 i = c->iterator;
969 if (i->start->expr_type != EXPR_CONSTANT
970 || i->end->expr_type != EXPR_CONSTANT
971 || i->step->expr_type != EXPR_CONSTANT)
973 mpz_set_si (*size, -1);
974 mpz_clear (len);
975 mpz_clear (val);
976 return;
979 mpz_add (val, i->end->value.integer, i->start->value.integer);
980 mpz_tdiv_q (val, val, i->step->value.integer);
981 mpz_add_ui (val, val, 1);
982 mpz_mul (len, len, val);
984 mpz_add (*size, *size, len);
986 mpz_clear (len);
987 mpz_clear (val);
991 /* Figure out the string length of a variable reference expression.
992 Used by get_array_ctor_strlen. */
994 static void
995 get_array_ctor_var_strlen (gfc_expr * expr, tree * len)
997 gfc_ref *ref;
998 gfc_typespec *ts;
1000 /* Don't bother if we already know the length is a constant. */
1001 if (*len && INTEGER_CST_P (*len))
1002 return;
1004 ts = &expr->symtree->n.sym->ts;
1005 for (ref = expr->ref; ref; ref = ref->next)
1007 switch (ref->type)
1009 case REF_ARRAY:
1010 /* Array references don't change the string length. */
1011 break;
1013 case COMPONENT_REF:
1014 /* Use the length of the component. */
1015 ts = &ref->u.c.component->ts;
1016 break;
1018 default:
1019 /* TODO: Substrings are tricky because we can't evaluate the
1020 expression more than once. For now we just give up, and hope
1021 we can figure it out elsewhere. */
1022 return;
1026 *len = ts->cl->backend_decl;
1030 /* Figure out the string length of a character array constructor.
1031 Returns TRUE if all elements are character constants. */
1033 static bool
1034 get_array_ctor_strlen (gfc_constructor * c, tree * len)
1036 bool is_const;
1038 is_const = TRUE;
1039 for (; c; c = c->next)
1041 switch (c->expr->expr_type)
1043 case EXPR_CONSTANT:
1044 if (!(*len && INTEGER_CST_P (*len)))
1045 *len = build_int_cstu (gfc_charlen_type_node,
1046 c->expr->value.character.length);
1047 break;
1049 case EXPR_ARRAY:
1050 if (!get_array_ctor_strlen (c->expr->value.constructor, len))
1051 is_const = FALSE;
1052 break;
1054 case EXPR_VARIABLE:
1055 is_const = false;
1056 get_array_ctor_var_strlen (c->expr, len);
1057 break;
1059 default:
1060 is_const = FALSE;
1061 /* TODO: For now we just ignore anything we don't know how to
1062 handle, and hope we can figure it out a different way. */
1063 break;
1067 return is_const;
1071 /* Array constructors are handled by constructing a temporary, then using that
1072 within the scalarization loop. This is not optimal, but seems by far the
1073 simplest method. */
1075 static void
1076 gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss)
1078 tree offset;
1079 tree offsetvar;
1080 tree desc;
1081 tree size;
1082 tree type;
1083 bool const_string;
1085 ss->data.info.dimen = loop->dimen;
1087 if (ss->expr->ts.type == BT_CHARACTER)
1089 const_string = get_array_ctor_strlen (ss->expr->value.constructor,
1090 &ss->string_length);
1091 if (!ss->string_length)
1092 gfc_todo_error ("complex character array constructors");
1094 type = gfc_get_character_type_len (ss->expr->ts.kind, ss->string_length);
1095 if (const_string)
1096 type = build_pointer_type (type);
1098 else
1100 const_string = TRUE;
1101 type = gfc_typenode_for_spec (&ss->expr->ts);
1104 size = gfc_trans_allocate_temp_array (loop, &ss->data.info, type);
1106 desc = ss->data.info.descriptor;
1107 offset = gfc_index_zero_node;
1108 offsetvar = gfc_create_var_np (gfc_array_index_type, "offset");
1109 TREE_USED (offsetvar) = 0;
1110 gfc_trans_array_constructor_value (&loop->pre, type,
1111 ss->data.info.data,
1112 ss->expr->value.constructor, &offset,
1113 &offsetvar);
1115 if (TREE_USED (offsetvar))
1116 pushdecl (offsetvar);
1117 else
1118 gcc_assert (INTEGER_CST_P (offset));
1119 #if 0
1120 /* Disable bound checking for now because it's probably broken. */
1121 if (flag_bounds_check)
1123 gcc_unreachable ();
1125 #endif
1129 /* Add the pre and post chains for all the scalar expressions in a SS chain
1130 to loop. This is called after the loop parameters have been calculated,
1131 but before the actual scalarizing loops. */
1133 static void
1134 gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript)
1136 gfc_se se;
1137 int n;
1139 /* TODO: This can generate bad code if there are ordering dependencies.
1140 eg. a callee allocated function and an unknown size constructor. */
1141 gcc_assert (ss != NULL);
1143 for (; ss != gfc_ss_terminator; ss = ss->loop_chain)
1145 gcc_assert (ss);
1147 switch (ss->type)
1149 case GFC_SS_SCALAR:
1150 /* Scalar expression. Evaluate this now. This includes elemental
1151 dimension indices, but not array section bounds. */
1152 gfc_init_se (&se, NULL);
1153 gfc_conv_expr (&se, ss->expr);
1154 gfc_add_block_to_block (&loop->pre, &se.pre);
1156 if (ss->expr->ts.type != BT_CHARACTER)
1158 /* Move the evaluation of scalar expressions outside the
1159 scalarization loop. */
1160 if (subscript)
1161 se.expr = convert(gfc_array_index_type, se.expr);
1162 se.expr = gfc_evaluate_now (se.expr, &loop->pre);
1163 gfc_add_block_to_block (&loop->pre, &se.post);
1165 else
1166 gfc_add_block_to_block (&loop->post, &se.post);
1168 ss->data.scalar.expr = se.expr;
1169 ss->string_length = se.string_length;
1170 break;
1172 case GFC_SS_REFERENCE:
1173 /* Scalar reference. Evaluate this now. */
1174 gfc_init_se (&se, NULL);
1175 gfc_conv_expr_reference (&se, ss->expr);
1176 gfc_add_block_to_block (&loop->pre, &se.pre);
1177 gfc_add_block_to_block (&loop->post, &se.post);
1179 ss->data.scalar.expr = gfc_evaluate_now (se.expr, &loop->pre);
1180 ss->string_length = se.string_length;
1181 break;
1183 case GFC_SS_SECTION:
1184 case GFC_SS_VECTOR:
1185 /* Scalarized expression. Evaluate any scalar subscripts. */
1186 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1188 /* Add the expressions for scalar subscripts. */
1189 if (ss->data.info.subscript[n])
1190 gfc_add_loop_ss_code (loop, ss->data.info.subscript[n], true);
1192 break;
1194 case GFC_SS_INTRINSIC:
1195 gfc_add_intrinsic_ss_code (loop, ss);
1196 break;
1198 case GFC_SS_FUNCTION:
1199 /* Array function return value. We call the function and save its
1200 result in a temporary for use inside the loop. */
1201 gfc_init_se (&se, NULL);
1202 se.loop = loop;
1203 se.ss = ss;
1204 gfc_conv_expr (&se, ss->expr);
1205 gfc_add_block_to_block (&loop->pre, &se.pre);
1206 gfc_add_block_to_block (&loop->post, &se.post);
1207 break;
1209 case GFC_SS_CONSTRUCTOR:
1210 gfc_trans_array_constructor (loop, ss);
1211 break;
1213 case GFC_SS_TEMP:
1214 case GFC_SS_COMPONENT:
1215 /* Do nothing. These are handled elsewhere. */
1216 break;
1218 default:
1219 gcc_unreachable ();
1225 /* Translate expressions for the descriptor and data pointer of a SS. */
1226 /*GCC ARRAYS*/
1228 static void
1229 gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)
1231 gfc_se se;
1232 tree tmp;
1234 /* Get the descriptor for the array to be scalarized. */
1235 gcc_assert (ss->expr->expr_type == EXPR_VARIABLE);
1236 gfc_init_se (&se, NULL);
1237 se.descriptor_only = 1;
1238 gfc_conv_expr_lhs (&se, ss->expr);
1239 gfc_add_block_to_block (block, &se.pre);
1240 ss->data.info.descriptor = se.expr;
1241 ss->string_length = se.string_length;
1243 if (base)
1245 /* Also the data pointer. */
1246 tmp = gfc_conv_array_data (se.expr);
1247 /* If this is a variable or address of a variable we use it directly.
1248 Otherwise we must evaluate it now to avoid breaking dependency
1249 analysis by pulling the expressions for elemental array indices
1250 inside the loop. */
1251 if (!(DECL_P (tmp)
1252 || (TREE_CODE (tmp) == ADDR_EXPR
1253 && DECL_P (TREE_OPERAND (tmp, 0)))))
1254 tmp = gfc_evaluate_now (tmp, block);
1255 ss->data.info.data = tmp;
1257 tmp = gfc_conv_array_offset (se.expr);
1258 ss->data.info.offset = gfc_evaluate_now (tmp, block);
1263 /* Initialize a gfc_loopinfo structure. */
1265 void
1266 gfc_init_loopinfo (gfc_loopinfo * loop)
1268 int n;
1270 memset (loop, 0, sizeof (gfc_loopinfo));
1271 gfc_init_block (&loop->pre);
1272 gfc_init_block (&loop->post);
1274 /* Initially scalarize in order. */
1275 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1276 loop->order[n] = n;
1278 loop->ss = gfc_ss_terminator;
1282 /* Copies the loop variable info to a gfc_se structure. Does not copy the SS
1283 chain. */
1285 void
1286 gfc_copy_loopinfo_to_se (gfc_se * se, gfc_loopinfo * loop)
1288 se->loop = loop;
1292 /* Return an expression for the data pointer of an array. */
1294 tree
1295 gfc_conv_array_data (tree descriptor)
1297 tree type;
1299 type = TREE_TYPE (descriptor);
1300 if (GFC_ARRAY_TYPE_P (type))
1302 if (TREE_CODE (type) == POINTER_TYPE)
1303 return descriptor;
1304 else
1306 /* Descriptorless arrays. */
1307 return gfc_build_addr_expr (NULL, descriptor);
1310 else
1311 return gfc_conv_descriptor_data (descriptor);
1315 /* Return an expression for the base offset of an array. */
1317 tree
1318 gfc_conv_array_offset (tree descriptor)
1320 tree type;
1322 type = TREE_TYPE (descriptor);
1323 if (GFC_ARRAY_TYPE_P (type))
1324 return GFC_TYPE_ARRAY_OFFSET (type);
1325 else
1326 return gfc_conv_descriptor_offset (descriptor);
1330 /* Get an expression for the array stride. */
1332 tree
1333 gfc_conv_array_stride (tree descriptor, int dim)
1335 tree tmp;
1336 tree type;
1338 type = TREE_TYPE (descriptor);
1340 /* For descriptorless arrays use the array size. */
1341 tmp = GFC_TYPE_ARRAY_STRIDE (type, dim);
1342 if (tmp != NULL_TREE)
1343 return tmp;
1345 tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[dim]);
1346 return tmp;
1350 /* Like gfc_conv_array_stride, but for the lower bound. */
1352 tree
1353 gfc_conv_array_lbound (tree descriptor, int dim)
1355 tree tmp;
1356 tree type;
1358 type = TREE_TYPE (descriptor);
1360 tmp = GFC_TYPE_ARRAY_LBOUND (type, dim);
1361 if (tmp != NULL_TREE)
1362 return tmp;
1364 tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[dim]);
1365 return tmp;
1369 /* Like gfc_conv_array_stride, but for the upper bound. */
1371 tree
1372 gfc_conv_array_ubound (tree descriptor, int dim)
1374 tree tmp;
1375 tree type;
1377 type = TREE_TYPE (descriptor);
1379 tmp = GFC_TYPE_ARRAY_UBOUND (type, dim);
1380 if (tmp != NULL_TREE)
1381 return tmp;
1383 /* This should only ever happen when passing an assumed shape array
1384 as an actual parameter. The value will never be used. */
1385 if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor)))
1386 return gfc_index_zero_node;
1388 tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[dim]);
1389 return tmp;
1393 /* Translate an array reference. The descriptor should be in se->expr.
1394 Do not use this function, it wil be removed soon. */
1395 /*GCC ARRAYS*/
1397 static void
1398 gfc_conv_array_index_ref (gfc_se * se, tree pointer, tree * indices,
1399 tree offset, int dimen)
1401 tree array;
1402 tree tmp;
1403 tree index;
1404 int n;
1406 array = gfc_build_indirect_ref (pointer);
1408 index = offset;
1409 for (n = 0; n < dimen; n++)
1411 /* index = index + stride[n]*indices[n] */
1412 tmp = gfc_conv_array_stride (se->expr, n);
1413 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, indices[n], tmp);
1415 index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
1418 /* Result = data[index]. */
1419 tmp = gfc_build_array_ref (array, index);
1421 /* Check we've used the correct number of dimensions. */
1422 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) != ARRAY_TYPE);
1424 se->expr = tmp;
1428 /* Generate code to perform an array index bound check. */
1430 static tree
1431 gfc_trans_array_bound_check (gfc_se * se, tree descriptor, tree index, int n)
1433 tree cond;
1434 tree fault;
1435 tree tmp;
1437 if (!flag_bounds_check)
1438 return index;
1440 index = gfc_evaluate_now (index, &se->pre);
1441 /* Check lower bound. */
1442 tmp = gfc_conv_array_lbound (descriptor, n);
1443 fault = fold_build2 (LT_EXPR, boolean_type_node, index, tmp);
1444 /* Check upper bound. */
1445 tmp = gfc_conv_array_ubound (descriptor, n);
1446 cond = fold_build2 (GT_EXPR, boolean_type_node, index, tmp);
1447 fault = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault, cond);
1449 gfc_trans_runtime_check (fault, gfc_strconst_fault, &se->pre);
1451 return index;
1455 /* A reference to an array vector subscript. Uses recursion to handle nested
1456 vector subscripts. */
1458 static tree
1459 gfc_conv_vector_array_index (gfc_se * se, tree index, gfc_ss * ss)
1461 tree descsave;
1462 tree indices[GFC_MAX_DIMENSIONS];
1463 gfc_array_ref *ar;
1464 gfc_ss_info *info;
1465 int n;
1467 gcc_assert (ss && ss->type == GFC_SS_VECTOR);
1469 /* Save the descriptor. */
1470 descsave = se->expr;
1471 info = &ss->data.info;
1472 se->expr = info->descriptor;
1474 ar = &info->ref->u.ar;
1475 for (n = 0; n < ar->dimen; n++)
1477 switch (ar->dimen_type[n])
1479 case DIMEN_ELEMENT:
1480 gcc_assert (info->subscript[n] != gfc_ss_terminator
1481 && info->subscript[n]->type == GFC_SS_SCALAR);
1482 indices[n] = info->subscript[n]->data.scalar.expr;
1483 break;
1485 case DIMEN_RANGE:
1486 indices[n] = index;
1487 break;
1489 case DIMEN_VECTOR:
1490 index = gfc_conv_vector_array_index (se, index, info->subscript[n]);
1492 indices[n] =
1493 gfc_trans_array_bound_check (se, info->descriptor, index, n);
1494 break;
1496 default:
1497 gcc_unreachable ();
1500 /* Get the index from the vector. */
1501 gfc_conv_array_index_ref (se, info->data, indices, info->offset, ar->dimen);
1502 index = se->expr;
1503 /* Put the descriptor back. */
1504 se->expr = descsave;
1506 return index;
1510 /* Return the offset for an index. Performs bound checking for elemental
1511 dimensions. Single element references are processed separately. */
1513 static tree
1514 gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i,
1515 gfc_array_ref * ar, tree stride)
1517 tree index;
1519 /* Get the index into the array for this dimension. */
1520 if (ar)
1522 gcc_assert (ar->type != AR_ELEMENT);
1523 if (ar->dimen_type[dim] == DIMEN_ELEMENT)
1525 gcc_assert (i == -1);
1526 /* Elemental dimension. */
1527 gcc_assert (info->subscript[dim]
1528 && info->subscript[dim]->type == GFC_SS_SCALAR);
1529 /* We've already translated this value outside the loop. */
1530 index = info->subscript[dim]->data.scalar.expr;
1532 index =
1533 gfc_trans_array_bound_check (se, info->descriptor, index, dim);
1535 else
1537 /* Scalarized dimension. */
1538 gcc_assert (info && se->loop);
1540 /* Multiply the loop variable by the stride and delta. */
1541 index = se->loop->loopvar[i];
1542 index = fold_build2 (MULT_EXPR, gfc_array_index_type, index,
1543 info->stride[i]);
1544 index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index,
1545 info->delta[i]);
1547 if (ar->dimen_type[dim] == DIMEN_VECTOR)
1549 /* Handle vector subscripts. */
1550 index = gfc_conv_vector_array_index (se, index,
1551 info->subscript[dim]);
1552 index =
1553 gfc_trans_array_bound_check (se, info->descriptor, index,
1554 dim);
1556 else
1557 gcc_assert (ar->dimen_type[dim] == DIMEN_RANGE);
1560 else
1562 /* Temporary array or derived type component. */
1563 gcc_assert (se->loop);
1564 index = se->loop->loopvar[se->loop->order[i]];
1565 if (!integer_zerop (info->delta[i]))
1566 index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1567 index, info->delta[i]);
1570 /* Multiply by the stride. */
1571 index = fold_build2 (MULT_EXPR, gfc_array_index_type, index, stride);
1573 return index;
1577 /* Build a scalarized reference to an array. */
1579 static void
1580 gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
1582 gfc_ss_info *info;
1583 tree index;
1584 tree tmp;
1585 int n;
1587 info = &se->ss->data.info;
1588 if (ar)
1589 n = se->loop->order[0];
1590 else
1591 n = 0;
1593 index = gfc_conv_array_index_offset (se, info, info->dim[n], n, ar,
1594 info->stride0);
1595 /* Add the offset for this dimension to the stored offset for all other
1596 dimensions. */
1597 index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, info->offset);
1599 tmp = gfc_build_indirect_ref (info->data);
1600 se->expr = gfc_build_array_ref (tmp, index);
1604 /* Translate access of temporary array. */
1606 void
1607 gfc_conv_tmp_array_ref (gfc_se * se)
1609 se->string_length = se->ss->string_length;
1610 gfc_conv_scalarized_array_ref (se, NULL);
1614 /* Build an array reference. se->expr already holds the array descriptor.
1615 This should be either a variable, indirect variable reference or component
1616 reference. For arrays which do not have a descriptor, se->expr will be
1617 the data pointer.
1618 a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
1620 void
1621 gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar)
1623 int n;
1624 tree index;
1625 tree tmp;
1626 tree stride;
1627 tree fault;
1628 gfc_se indexse;
1630 /* Handle scalarized references separately. */
1631 if (ar->type != AR_ELEMENT)
1633 gfc_conv_scalarized_array_ref (se, ar);
1634 return;
1637 index = gfc_index_zero_node;
1639 fault = gfc_index_zero_node;
1641 /* Calculate the offsets from all the dimensions. */
1642 for (n = 0; n < ar->dimen; n++)
1644 /* Calculate the index for this dimension. */
1645 gfc_init_se (&indexse, NULL);
1646 gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type);
1647 gfc_add_block_to_block (&se->pre, &indexse.pre);
1649 if (flag_bounds_check)
1651 /* Check array bounds. */
1652 tree cond;
1654 indexse.expr = gfc_evaluate_now (indexse.expr, &se->pre);
1656 tmp = gfc_conv_array_lbound (se->expr, n);
1657 cond = fold_build2 (LT_EXPR, boolean_type_node,
1658 indexse.expr, tmp);
1659 fault =
1660 fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault, cond);
1662 tmp = gfc_conv_array_ubound (se->expr, n);
1663 cond = fold_build2 (GT_EXPR, boolean_type_node,
1664 indexse.expr, tmp);
1665 fault =
1666 fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault, cond);
1669 /* Multiply the index by the stride. */
1670 stride = gfc_conv_array_stride (se->expr, n);
1671 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, indexse.expr,
1672 stride);
1674 /* And add it to the total. */
1675 index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
1678 if (flag_bounds_check)
1679 gfc_trans_runtime_check (fault, gfc_strconst_fault, &se->pre);
1681 tmp = gfc_conv_array_offset (se->expr);
1682 if (!integer_zerop (tmp))
1683 index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
1685 /* Access the calculated element. */
1686 tmp = gfc_conv_array_data (se->expr);
1687 tmp = gfc_build_indirect_ref (tmp);
1688 se->expr = gfc_build_array_ref (tmp, index);
1692 /* Generate the code to be executed immediately before entering a
1693 scalarization loop. */
1695 static void
1696 gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
1697 stmtblock_t * pblock)
1699 tree index;
1700 tree stride;
1701 gfc_ss_info *info;
1702 gfc_ss *ss;
1703 gfc_se se;
1704 int i;
1706 /* This code will be executed before entering the scalarization loop
1707 for this dimension. */
1708 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
1710 if ((ss->useflags & flag) == 0)
1711 continue;
1713 if (ss->type != GFC_SS_SECTION
1714 && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
1715 && ss->type != GFC_SS_COMPONENT)
1716 continue;
1718 info = &ss->data.info;
1720 if (dim >= info->dimen)
1721 continue;
1723 if (dim == info->dimen - 1)
1725 /* For the outermost loop calculate the offset due to any
1726 elemental dimensions. It will have been initialized with the
1727 base offset of the array. */
1728 if (info->ref)
1730 for (i = 0; i < info->ref->u.ar.dimen; i++)
1732 if (info->ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
1733 continue;
1735 gfc_init_se (&se, NULL);
1736 se.loop = loop;
1737 se.expr = info->descriptor;
1738 stride = gfc_conv_array_stride (info->descriptor, i);
1739 index = gfc_conv_array_index_offset (&se, info, i, -1,
1740 &info->ref->u.ar,
1741 stride);
1742 gfc_add_block_to_block (pblock, &se.pre);
1744 info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1745 info->offset, index);
1746 info->offset = gfc_evaluate_now (info->offset, pblock);
1749 i = loop->order[0];
1750 stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
1752 else
1753 stride = gfc_conv_array_stride (info->descriptor, 0);
1755 /* Calculate the stride of the innermost loop. Hopefully this will
1756 allow the backend optimizers to do their stuff more effectively.
1758 info->stride0 = gfc_evaluate_now (stride, pblock);
1760 else
1762 /* Add the offset for the previous loop dimension. */
1763 gfc_array_ref *ar;
1765 if (info->ref)
1767 ar = &info->ref->u.ar;
1768 i = loop->order[dim + 1];
1770 else
1772 ar = NULL;
1773 i = dim + 1;
1776 gfc_init_se (&se, NULL);
1777 se.loop = loop;
1778 se.expr = info->descriptor;
1779 stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
1780 index = gfc_conv_array_index_offset (&se, info, info->dim[i], i,
1781 ar, stride);
1782 gfc_add_block_to_block (pblock, &se.pre);
1783 info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1784 info->offset, index);
1785 info->offset = gfc_evaluate_now (info->offset, pblock);
1788 /* Remember this offset for the second loop. */
1789 if (dim == loop->temp_dim - 1)
1790 info->saved_offset = info->offset;
1795 /* Start a scalarized expression. Creates a scope and declares loop
1796 variables. */
1798 void
1799 gfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody)
1801 int dim;
1802 int n;
1803 int flags;
1805 gcc_assert (!loop->array_parameter);
1807 for (dim = loop->dimen - 1; dim >= 0; dim--)
1809 n = loop->order[dim];
1811 gfc_start_block (&loop->code[n]);
1813 /* Create the loop variable. */
1814 loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "S");
1816 if (dim < loop->temp_dim)
1817 flags = 3;
1818 else
1819 flags = 1;
1820 /* Calculate values that will be constant within this loop. */
1821 gfc_trans_preloop_setup (loop, dim, flags, &loop->code[n]);
1823 gfc_start_block (pbody);
1827 /* Generates the actual loop code for a scalarization loop. */
1829 static void
1830 gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
1831 stmtblock_t * pbody)
1833 stmtblock_t block;
1834 tree cond;
1835 tree tmp;
1836 tree loopbody;
1837 tree exit_label;
1839 loopbody = gfc_finish_block (pbody);
1841 /* Initialize the loopvar. */
1842 gfc_add_modify_expr (&loop->code[n], loop->loopvar[n], loop->from[n]);
1844 exit_label = gfc_build_label_decl (NULL_TREE);
1846 /* Generate the loop body. */
1847 gfc_init_block (&block);
1849 /* The exit condition. */
1850 cond = build2 (GT_EXPR, boolean_type_node, loop->loopvar[n], loop->to[n]);
1851 tmp = build1_v (GOTO_EXPR, exit_label);
1852 TREE_USED (exit_label) = 1;
1853 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1854 gfc_add_expr_to_block (&block, tmp);
1856 /* The main body. */
1857 gfc_add_expr_to_block (&block, loopbody);
1859 /* Increment the loopvar. */
1860 tmp = build2 (PLUS_EXPR, gfc_array_index_type,
1861 loop->loopvar[n], gfc_index_one_node);
1862 gfc_add_modify_expr (&block, loop->loopvar[n], tmp);
1864 /* Build the loop. */
1865 tmp = gfc_finish_block (&block);
1866 tmp = build1_v (LOOP_EXPR, tmp);
1867 gfc_add_expr_to_block (&loop->code[n], tmp);
1869 /* Add the exit label. */
1870 tmp = build1_v (LABEL_EXPR, exit_label);
1871 gfc_add_expr_to_block (&loop->code[n], tmp);
1875 /* Finishes and generates the loops for a scalarized expression. */
1877 void
1878 gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body)
1880 int dim;
1881 int n;
1882 gfc_ss *ss;
1883 stmtblock_t *pblock;
1884 tree tmp;
1886 pblock = body;
1887 /* Generate the loops. */
1888 for (dim = 0; dim < loop->dimen; dim++)
1890 n = loop->order[dim];
1891 gfc_trans_scalarized_loop_end (loop, n, pblock);
1892 loop->loopvar[n] = NULL_TREE;
1893 pblock = &loop->code[n];
1896 tmp = gfc_finish_block (pblock);
1897 gfc_add_expr_to_block (&loop->pre, tmp);
1899 /* Clear all the used flags. */
1900 for (ss = loop->ss; ss; ss = ss->loop_chain)
1901 ss->useflags = 0;
1905 /* Finish the main body of a scalarized expression, and start the secondary
1906 copying body. */
1908 void
1909 gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
1911 int dim;
1912 int n;
1913 stmtblock_t *pblock;
1914 gfc_ss *ss;
1916 pblock = body;
1917 /* We finish as many loops as are used by the temporary. */
1918 for (dim = 0; dim < loop->temp_dim - 1; dim++)
1920 n = loop->order[dim];
1921 gfc_trans_scalarized_loop_end (loop, n, pblock);
1922 loop->loopvar[n] = NULL_TREE;
1923 pblock = &loop->code[n];
1926 /* We don't want to finish the outermost loop entirely. */
1927 n = loop->order[loop->temp_dim - 1];
1928 gfc_trans_scalarized_loop_end (loop, n, pblock);
1930 /* Restore the initial offsets. */
1931 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
1933 if ((ss->useflags & 2) == 0)
1934 continue;
1936 if (ss->type != GFC_SS_SECTION
1937 && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
1938 && ss->type != GFC_SS_COMPONENT)
1939 continue;
1941 ss->data.info.offset = ss->data.info.saved_offset;
1944 /* Restart all the inner loops we just finished. */
1945 for (dim = loop->temp_dim - 2; dim >= 0; dim--)
1947 n = loop->order[dim];
1949 gfc_start_block (&loop->code[n]);
1951 loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "Q");
1953 gfc_trans_preloop_setup (loop, dim, 2, &loop->code[n]);
1956 /* Start a block for the secondary copying code. */
1957 gfc_start_block (body);
1961 /* Calculate the upper bound of an array section. */
1963 static tree
1964 gfc_conv_section_upper_bound (gfc_ss * ss, int n, stmtblock_t * pblock)
1966 int dim;
1967 gfc_ss *vecss;
1968 gfc_expr *end;
1969 tree desc;
1970 tree bound;
1971 gfc_se se;
1973 gcc_assert (ss->type == GFC_SS_SECTION);
1975 /* For vector array subscripts we want the size of the vector. */
1976 dim = ss->data.info.dim[n];
1977 vecss = ss;
1978 while (vecss->data.info.ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
1980 vecss = vecss->data.info.subscript[dim];
1981 gcc_assert (vecss && vecss->type == GFC_SS_VECTOR);
1982 dim = vecss->data.info.dim[0];
1985 gcc_assert (vecss->data.info.ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
1986 end = vecss->data.info.ref->u.ar.end[dim];
1987 desc = vecss->data.info.descriptor;
1989 if (end)
1991 /* The upper bound was specified. */
1992 gfc_init_se (&se, NULL);
1993 gfc_conv_expr_type (&se, end, gfc_array_index_type);
1994 gfc_add_block_to_block (pblock, &se.pre);
1995 bound = se.expr;
1997 else
1999 /* No upper bound was specified, so use the bound of the array. */
2000 bound = gfc_conv_array_ubound (desc, dim);
2003 return bound;
2007 /* Calculate the lower bound of an array section. */
2009 static void
2010 gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int n)
2012 gfc_expr *start;
2013 gfc_expr *stride;
2014 gfc_ss *vecss;
2015 tree desc;
2016 gfc_se se;
2017 gfc_ss_info *info;
2018 int dim;
2020 info = &ss->data.info;
2022 dim = info->dim[n];
2024 /* For vector array subscripts we want the size of the vector. */
2025 vecss = ss;
2026 while (vecss->data.info.ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2028 vecss = vecss->data.info.subscript[dim];
2029 gcc_assert (vecss && vecss->type == GFC_SS_VECTOR);
2030 /* Get the descriptors for the vector subscripts as well. */
2031 if (!vecss->data.info.descriptor)
2032 gfc_conv_ss_descriptor (&loop->pre, vecss, !loop->array_parameter);
2033 dim = vecss->data.info.dim[0];
2036 gcc_assert (vecss->data.info.ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
2037 start = vecss->data.info.ref->u.ar.start[dim];
2038 stride = vecss->data.info.ref->u.ar.stride[dim];
2039 desc = vecss->data.info.descriptor;
2041 /* Calculate the start of the range. For vector subscripts this will
2042 be the range of the vector. */
2043 if (start)
2045 /* Specified section start. */
2046 gfc_init_se (&se, NULL);
2047 gfc_conv_expr_type (&se, start, gfc_array_index_type);
2048 gfc_add_block_to_block (&loop->pre, &se.pre);
2049 info->start[n] = se.expr;
2051 else
2053 /* No lower bound specified so use the bound of the array. */
2054 info->start[n] = gfc_conv_array_lbound (desc, dim);
2056 info->start[n] = gfc_evaluate_now (info->start[n], &loop->pre);
2058 /* Calculate the stride. */
2059 if (stride == NULL)
2060 info->stride[n] = gfc_index_one_node;
2061 else
2063 gfc_init_se (&se, NULL);
2064 gfc_conv_expr_type (&se, stride, gfc_array_index_type);
2065 gfc_add_block_to_block (&loop->pre, &se.pre);
2066 info->stride[n] = gfc_evaluate_now (se.expr, &loop->pre);
2071 /* Calculates the range start and stride for a SS chain. Also gets the
2072 descriptor and data pointer. The range of vector subscripts is the size
2073 of the vector. Array bounds are also checked. */
2075 void
2076 gfc_conv_ss_startstride (gfc_loopinfo * loop)
2078 int n;
2079 tree tmp;
2080 gfc_ss *ss;
2081 gfc_ss *vecss;
2082 tree desc;
2084 loop->dimen = 0;
2085 /* Determine the rank of the loop. */
2086 for (ss = loop->ss;
2087 ss != gfc_ss_terminator && loop->dimen == 0; ss = ss->loop_chain)
2089 switch (ss->type)
2091 case GFC_SS_SECTION:
2092 case GFC_SS_CONSTRUCTOR:
2093 case GFC_SS_FUNCTION:
2094 case GFC_SS_COMPONENT:
2095 loop->dimen = ss->data.info.dimen;
2096 break;
2098 default:
2099 break;
2103 if (loop->dimen == 0)
2104 gfc_todo_error ("Unable to determine rank of expression");
2107 /* Loop over all the SS in the chain. */
2108 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2110 if (ss->expr && ss->expr->shape && !ss->shape)
2111 ss->shape = ss->expr->shape;
2113 switch (ss->type)
2115 case GFC_SS_SECTION:
2116 /* Get the descriptor for the array. */
2117 gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter);
2119 for (n = 0; n < ss->data.info.dimen; n++)
2120 gfc_conv_section_startstride (loop, ss, n);
2121 break;
2123 case GFC_SS_CONSTRUCTOR:
2124 case GFC_SS_FUNCTION:
2125 for (n = 0; n < ss->data.info.dimen; n++)
2127 ss->data.info.start[n] = gfc_index_zero_node;
2128 ss->data.info.stride[n] = gfc_index_one_node;
2130 break;
2132 default:
2133 break;
2137 /* The rest is just runtime bound checking. */
2138 if (flag_bounds_check)
2140 stmtblock_t block;
2141 tree fault;
2142 tree bound;
2143 tree end;
2144 tree size[GFC_MAX_DIMENSIONS];
2145 gfc_ss_info *info;
2146 int dim;
2148 gfc_start_block (&block);
2150 fault = integer_zero_node;
2151 for (n = 0; n < loop->dimen; n++)
2152 size[n] = NULL_TREE;
2154 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2156 if (ss->type != GFC_SS_SECTION)
2157 continue;
2159 /* TODO: range checking for mapped dimensions. */
2160 info = &ss->data.info;
2162 /* This only checks scalarized dimensions, elemental dimensions are
2163 checked later. */
2164 for (n = 0; n < loop->dimen; n++)
2166 dim = info->dim[n];
2167 vecss = ss;
2168 while (vecss->data.info.ref->u.ar.dimen_type[dim]
2169 == DIMEN_VECTOR)
2171 vecss = vecss->data.info.subscript[dim];
2172 gcc_assert (vecss && vecss->type == GFC_SS_VECTOR);
2173 dim = vecss->data.info.dim[0];
2175 gcc_assert (vecss->data.info.ref->u.ar.dimen_type[dim]
2176 == DIMEN_RANGE);
2177 desc = vecss->data.info.descriptor;
2179 /* Check lower bound. */
2180 bound = gfc_conv_array_lbound (desc, dim);
2181 tmp = info->start[n];
2182 tmp = fold_build2 (LT_EXPR, boolean_type_node, tmp, bound);
2183 fault = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault,
2184 tmp);
2186 /* Check the upper bound. */
2187 bound = gfc_conv_array_ubound (desc, dim);
2188 end = gfc_conv_section_upper_bound (ss, n, &block);
2189 tmp = fold_build2 (GT_EXPR, boolean_type_node, end, bound);
2190 fault = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault,
2191 tmp);
2193 /* Check the section sizes match. */
2194 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
2195 info->start[n]);
2196 tmp = fold_build2 (FLOOR_DIV_EXPR, gfc_array_index_type, tmp,
2197 info->stride[n]);
2198 /* We remember the size of the first section, and check all the
2199 others against this. */
2200 if (size[n])
2202 tmp =
2203 fold_build2 (NE_EXPR, boolean_type_node, tmp, size[n]);
2204 fault =
2205 build2 (TRUTH_OR_EXPR, boolean_type_node, fault, tmp);
2207 else
2208 size[n] = gfc_evaluate_now (tmp, &block);
2211 gfc_trans_runtime_check (fault, gfc_strconst_bounds, &block);
2213 tmp = gfc_finish_block (&block);
2214 gfc_add_expr_to_block (&loop->pre, tmp);
2219 /* Return true if the two SS could be aliased, i.e. both point to the same data
2220 object. */
2221 /* TODO: resolve aliases based on frontend expressions. */
2223 static int
2224 gfc_could_be_alias (gfc_ss * lss, gfc_ss * rss)
2226 gfc_ref *lref;
2227 gfc_ref *rref;
2228 gfc_symbol *lsym;
2229 gfc_symbol *rsym;
2231 lsym = lss->expr->symtree->n.sym;
2232 rsym = rss->expr->symtree->n.sym;
2233 if (gfc_symbols_could_alias (lsym, rsym))
2234 return 1;
2236 if (rsym->ts.type != BT_DERIVED
2237 && lsym->ts.type != BT_DERIVED)
2238 return 0;
2240 /* For derived types we must check all the component types. We can ignore
2241 array references as these will have the same base type as the previous
2242 component ref. */
2243 for (lref = lss->expr->ref; lref != lss->data.info.ref; lref = lref->next)
2245 if (lref->type != REF_COMPONENT)
2246 continue;
2248 if (gfc_symbols_could_alias (lref->u.c.sym, rsym))
2249 return 1;
2251 for (rref = rss->expr->ref; rref != rss->data.info.ref;
2252 rref = rref->next)
2254 if (rref->type != REF_COMPONENT)
2255 continue;
2257 if (gfc_symbols_could_alias (lref->u.c.sym, rref->u.c.sym))
2258 return 1;
2262 for (rref = rss->expr->ref; rref != rss->data.info.ref; rref = rref->next)
2264 if (rref->type != REF_COMPONENT)
2265 break;
2267 if (gfc_symbols_could_alias (rref->u.c.sym, lsym))
2268 return 1;
2271 return 0;
2275 /* Resolve array data dependencies. Creates a temporary if required. */
2276 /* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
2277 dependency.c. */
2279 void
2280 gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
2281 gfc_ss * rss)
2283 gfc_ss *ss;
2284 gfc_ref *lref;
2285 gfc_ref *rref;
2286 gfc_ref *aref;
2287 int nDepend = 0;
2288 int temp_dim = 0;
2290 loop->temp_ss = NULL;
2291 aref = dest->data.info.ref;
2292 temp_dim = 0;
2294 for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
2296 if (ss->type != GFC_SS_SECTION)
2297 continue;
2299 if (gfc_could_be_alias (dest, ss))
2301 nDepend = 1;
2302 break;
2305 if (dest->expr->symtree->n.sym == ss->expr->symtree->n.sym)
2307 lref = dest->expr->ref;
2308 rref = ss->expr->ref;
2310 nDepend = gfc_dep_resolver (lref, rref);
2311 #if 0
2312 /* TODO : loop shifting. */
2313 if (nDepend == 1)
2315 /* Mark the dimensions for LOOP SHIFTING */
2316 for (n = 0; n < loop->dimen; n++)
2318 int dim = dest->data.info.dim[n];
2320 if (lref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2321 depends[n] = 2;
2322 else if (! gfc_is_same_range (&lref->u.ar,
2323 &rref->u.ar, dim, 0))
2324 depends[n] = 1;
2327 /* Put all the dimensions with dependencies in the
2328 innermost loops. */
2329 dim = 0;
2330 for (n = 0; n < loop->dimen; n++)
2332 gcc_assert (loop->order[n] == n);
2333 if (depends[n])
2334 loop->order[dim++] = n;
2336 temp_dim = dim;
2337 for (n = 0; n < loop->dimen; n++)
2339 if (! depends[n])
2340 loop->order[dim++] = n;
2343 gcc_assert (dim == loop->dimen);
2344 break;
2346 #endif
2350 if (nDepend == 1)
2352 loop->temp_ss = gfc_get_ss ();
2353 loop->temp_ss->type = GFC_SS_TEMP;
2354 loop->temp_ss->data.temp.type =
2355 gfc_get_element_type (TREE_TYPE (dest->data.info.descriptor));
2356 loop->temp_ss->string_length = dest->string_length;
2357 loop->temp_ss->data.temp.dimen = loop->dimen;
2358 loop->temp_ss->next = gfc_ss_terminator;
2359 gfc_add_ss_to_loop (loop, loop->temp_ss);
2361 else
2362 loop->temp_ss = NULL;
2366 /* Initialize the scalarization loop. Creates the loop variables. Determines
2367 the range of the loop variables. Creates a temporary if required.
2368 Calculates how to transform from loop variables to array indices for each
2369 expression. Also generates code for scalar expressions which have been
2370 moved outside the loop. */
2372 void
2373 gfc_conv_loop_setup (gfc_loopinfo * loop)
2375 int n;
2376 int dim;
2377 gfc_ss_info *info;
2378 gfc_ss_info *specinfo;
2379 gfc_ss *ss;
2380 tree tmp;
2381 tree len;
2382 gfc_ss *loopspec[GFC_MAX_DIMENSIONS];
2383 mpz_t *cshape;
2384 mpz_t i;
2386 mpz_init (i);
2387 for (n = 0; n < loop->dimen; n++)
2389 loopspec[n] = NULL;
2390 /* We use one SS term, and use that to determine the bounds of the
2391 loop for this dimension. We try to pick the simplest term. */
2392 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2394 if (ss->shape)
2396 /* The frontend has worked out the size for us. */
2397 loopspec[n] = ss;
2398 continue;
2401 if (ss->type == GFC_SS_CONSTRUCTOR)
2403 /* An unknown size constructor will always be rank one.
2404 Higher rank constructors will either have known shape,
2405 or still be wrapped in a call to reshape. */
2406 gcc_assert (loop->dimen == 1);
2407 /* Try to figure out the size of the constructor. */
2408 /* TODO: avoid this by making the frontend set the shape. */
2409 gfc_get_array_cons_size (&i, ss->expr->value.constructor);
2410 /* A negative value means we failed. */
2411 if (mpz_sgn (i) > 0)
2413 mpz_sub_ui (i, i, 1);
2414 loop->to[n] =
2415 gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
2416 loopspec[n] = ss;
2418 continue;
2421 /* TODO: Pick the best bound if we have a choice between a
2422 function and something else. */
2423 if (ss->type == GFC_SS_FUNCTION)
2425 loopspec[n] = ss;
2426 continue;
2429 if (ss->type != GFC_SS_SECTION)
2430 continue;
2432 if (loopspec[n])
2433 specinfo = &loopspec[n]->data.info;
2434 else
2435 specinfo = NULL;
2436 info = &ss->data.info;
2438 /* Criteria for choosing a loop specifier (most important first):
2439 stride of one
2440 known stride
2441 known lower bound
2442 known upper bound
2444 if (!specinfo)
2445 loopspec[n] = ss;
2446 /* TODO: Is != constructor correct? */
2447 else if (loopspec[n]->type != GFC_SS_CONSTRUCTOR)
2449 if (integer_onep (info->stride[n])
2450 && !integer_onep (specinfo->stride[n]))
2451 loopspec[n] = ss;
2452 else if (INTEGER_CST_P (info->stride[n])
2453 && !INTEGER_CST_P (specinfo->stride[n]))
2454 loopspec[n] = ss;
2455 else if (INTEGER_CST_P (info->start[n])
2456 && !INTEGER_CST_P (specinfo->start[n]))
2457 loopspec[n] = ss;
2458 /* We don't work out the upper bound.
2459 else if (INTEGER_CST_P (info->finish[n])
2460 && ! INTEGER_CST_P (specinfo->finish[n]))
2461 loopspec[n] = ss; */
2465 if (!loopspec[n])
2466 gfc_todo_error ("Unable to find scalarization loop specifier");
2468 info = &loopspec[n]->data.info;
2470 /* Set the extents of this range. */
2471 cshape = loopspec[n]->shape;
2472 if (cshape && INTEGER_CST_P (info->start[n])
2473 && INTEGER_CST_P (info->stride[n]))
2475 loop->from[n] = info->start[n];
2476 mpz_set (i, cshape[n]);
2477 mpz_sub_ui (i, i, 1);
2478 /* To = from + (size - 1) * stride. */
2479 tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
2480 if (!integer_onep (info->stride[n]))
2481 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
2482 tmp, info->stride[n]);
2483 loop->to[n] = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2484 loop->from[n], tmp);
2486 else
2488 loop->from[n] = info->start[n];
2489 switch (loopspec[n]->type)
2491 case GFC_SS_CONSTRUCTOR:
2492 gcc_assert (info->dimen == 1);
2493 gcc_assert (loop->to[n]);
2494 break;
2496 case GFC_SS_SECTION:
2497 loop->to[n] = gfc_conv_section_upper_bound (loopspec[n], n,
2498 &loop->pre);
2499 break;
2501 case GFC_SS_FUNCTION:
2502 /* The loop bound will be set when we generate the call. */
2503 gcc_assert (loop->to[n] == NULL_TREE);
2504 break;
2506 default:
2507 gcc_unreachable ();
2511 /* Transform everything so we have a simple incrementing variable. */
2512 if (integer_onep (info->stride[n]))
2513 info->delta[n] = gfc_index_zero_node;
2514 else
2516 /* Set the delta for this section. */
2517 info->delta[n] = gfc_evaluate_now (loop->from[n], &loop->pre);
2518 /* Number of iterations is (end - start + step) / step.
2519 with start = 0, this simplifies to
2520 last = end / step;
2521 for (i = 0; i<=last; i++){...}; */
2522 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2523 loop->to[n], loop->from[n]);
2524 tmp = fold_build2 (TRUNC_DIV_EXPR, gfc_array_index_type,
2525 tmp, info->stride[n]);
2526 loop->to[n] = gfc_evaluate_now (tmp, &loop->pre);
2527 /* Make the loop variable start at 0. */
2528 loop->from[n] = gfc_index_zero_node;
2532 /* Add all the scalar code that can be taken out of the loops.
2533 This may include calculating the loop bounds, so do it before
2534 allocating the temporary. */
2535 gfc_add_loop_ss_code (loop, loop->ss, false);
2537 /* If we want a temporary then create it. */
2538 if (loop->temp_ss != NULL)
2540 gcc_assert (loop->temp_ss->type == GFC_SS_TEMP);
2541 tmp = loop->temp_ss->data.temp.type;
2542 len = loop->temp_ss->string_length;
2543 n = loop->temp_ss->data.temp.dimen;
2544 memset (&loop->temp_ss->data.info, 0, sizeof (gfc_ss_info));
2545 loop->temp_ss->type = GFC_SS_SECTION;
2546 loop->temp_ss->data.info.dimen = n;
2547 gfc_trans_allocate_temp_array (loop, &loop->temp_ss->data.info, tmp);
2550 for (n = 0; n < loop->temp_dim; n++)
2551 loopspec[loop->order[n]] = NULL;
2553 mpz_clear (i);
2555 /* For array parameters we don't have loop variables, so don't calculate the
2556 translations. */
2557 if (loop->array_parameter)
2558 return;
2560 /* Calculate the translation from loop variables to array indices. */
2561 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2563 if (ss->type != GFC_SS_SECTION && ss->type != GFC_SS_COMPONENT)
2564 continue;
2566 info = &ss->data.info;
2568 for (n = 0; n < info->dimen; n++)
2570 dim = info->dim[n];
2572 /* If we are specifying the range the delta is already set. */
2573 if (loopspec[n] != ss)
2575 /* Calculate the offset relative to the loop variable.
2576 First multiply by the stride. */
2577 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
2578 loop->from[n], info->stride[n]);
2580 /* Then subtract this from our starting value. */
2581 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2582 info->start[n], tmp);
2584 info->delta[n] = gfc_evaluate_now (tmp, &loop->pre);
2591 /* Fills in an array descriptor, and returns the size of the array. The size
2592 will be a simple_val, ie a variable or a constant. Also calculates the
2593 offset of the base. Returns the size of the array.
2595 stride = 1;
2596 offset = 0;
2597 for (n = 0; n < rank; n++)
2599 a.lbound[n] = specified_lower_bound;
2600 offset = offset + a.lbond[n] * stride;
2601 size = 1 - lbound;
2602 a.ubound[n] = specified_upper_bound;
2603 a.stride[n] = stride;
2604 size = ubound + size; //size = ubound + 1 - lbound
2605 stride = stride * size;
2607 return (stride);
2608 } */
2609 /*GCC ARRAYS*/
2611 static tree
2612 gfc_array_init_size (tree descriptor, int rank, tree * poffset,
2613 gfc_expr ** lower, gfc_expr ** upper,
2614 stmtblock_t * pblock)
2616 tree type;
2617 tree tmp;
2618 tree size;
2619 tree offset;
2620 tree stride;
2621 gfc_expr *ubound;
2622 gfc_se se;
2623 int n;
2625 type = TREE_TYPE (descriptor);
2627 stride = gfc_index_one_node;
2628 offset = gfc_index_zero_node;
2630 /* Set the dtype. */
2631 tmp = gfc_conv_descriptor_dtype (descriptor);
2632 gfc_add_modify_expr (pblock, tmp, gfc_get_dtype (TREE_TYPE (descriptor)));
2634 for (n = 0; n < rank; n++)
2636 /* We have 3 possibilities for determining the size of the array:
2637 lower == NULL => lbound = 1, ubound = upper[n]
2638 upper[n] = NULL => lbound = 1, ubound = lower[n]
2639 upper[n] != NULL => lbound = lower[n], ubound = upper[n] */
2640 ubound = upper[n];
2642 /* Set lower bound. */
2643 gfc_init_se (&se, NULL);
2644 if (lower == NULL)
2645 se.expr = gfc_index_one_node;
2646 else
2648 gcc_assert (lower[n]);
2649 if (ubound)
2651 gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
2652 gfc_add_block_to_block (pblock, &se.pre);
2654 else
2656 se.expr = gfc_index_one_node;
2657 ubound = lower[n];
2660 tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[n]);
2661 gfc_add_modify_expr (pblock, tmp, se.expr);
2663 /* Work out the offset for this component. */
2664 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, se.expr, stride);
2665 offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
2667 /* Start the calculation for the size of this dimension. */
2668 size = build2 (MINUS_EXPR, gfc_array_index_type,
2669 gfc_index_one_node, se.expr);
2671 /* Set upper bound. */
2672 gfc_init_se (&se, NULL);
2673 gcc_assert (ubound);
2674 gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
2675 gfc_add_block_to_block (pblock, &se.pre);
2677 tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[n]);
2678 gfc_add_modify_expr (pblock, tmp, se.expr);
2680 /* Store the stride. */
2681 tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[n]);
2682 gfc_add_modify_expr (pblock, tmp, stride);
2684 /* Calculate the size of this dimension. */
2685 size = fold_build2 (PLUS_EXPR, gfc_array_index_type, se.expr, size);
2687 /* Multiply the stride by the number of elements in this dimension. */
2688 stride = fold_build2 (MULT_EXPR, gfc_array_index_type, stride, size);
2689 stride = gfc_evaluate_now (stride, pblock);
2692 /* The stride is the number of elements in the array, so multiply by the
2693 size of an element to get the total size. */
2694 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
2695 size = fold_build2 (MULT_EXPR, gfc_array_index_type, stride, tmp);
2697 if (poffset != NULL)
2699 offset = gfc_evaluate_now (offset, pblock);
2700 *poffset = offset;
2703 size = gfc_evaluate_now (size, pblock);
2704 return size;
2708 /* Initializes the descriptor and generates a call to _gfor_allocate. Does
2709 the work for an ALLOCATE statement. */
2710 /*GCC ARRAYS*/
2712 void
2713 gfc_array_allocate (gfc_se * se, gfc_ref * ref, tree pstat)
2715 tree tmp;
2716 tree pointer;
2717 tree allocate;
2718 tree offset;
2719 tree size;
2720 gfc_expr **lower;
2721 gfc_expr **upper;
2723 /* Figure out the size of the array. */
2724 switch (ref->u.ar.type)
2726 case AR_ELEMENT:
2727 lower = NULL;
2728 upper = ref->u.ar.start;
2729 break;
2731 case AR_FULL:
2732 gcc_assert (ref->u.ar.as->type == AS_EXPLICIT);
2734 lower = ref->u.ar.as->lower;
2735 upper = ref->u.ar.as->upper;
2736 break;
2738 case AR_SECTION:
2739 lower = ref->u.ar.start;
2740 upper = ref->u.ar.end;
2741 break;
2743 default:
2744 gcc_unreachable ();
2745 break;
2748 size = gfc_array_init_size (se->expr, ref->u.ar.as->rank, &offset,
2749 lower, upper, &se->pre);
2751 /* Allocate memory to store the data. */
2752 tmp = gfc_conv_descriptor_data (se->expr);
2753 pointer = gfc_build_addr_expr (NULL, tmp);
2754 pointer = gfc_evaluate_now (pointer, &se->pre);
2756 if (TYPE_PRECISION (gfc_array_index_type) == 32)
2757 allocate = gfor_fndecl_allocate;
2758 else if (TYPE_PRECISION (gfc_array_index_type) == 64)
2759 allocate = gfor_fndecl_allocate64;
2760 else
2761 gcc_unreachable ();
2763 tmp = gfc_chainon_list (NULL_TREE, pointer);
2764 tmp = gfc_chainon_list (tmp, size);
2765 tmp = gfc_chainon_list (tmp, pstat);
2766 tmp = gfc_build_function_call (allocate, tmp);
2767 gfc_add_expr_to_block (&se->pre, tmp);
2769 pointer = gfc_conv_descriptor_data (se->expr);
2771 tmp = gfc_conv_descriptor_offset (se->expr);
2772 gfc_add_modify_expr (&se->pre, tmp, offset);
2776 /* Deallocate an array variable. Also used when an allocated variable goes
2777 out of scope. */
2778 /*GCC ARRAYS*/
2780 tree
2781 gfc_array_deallocate (tree descriptor)
2783 tree var;
2784 tree tmp;
2785 stmtblock_t block;
2787 gfc_start_block (&block);
2788 /* Get a pointer to the data. */
2789 tmp = gfc_conv_descriptor_data (descriptor);
2790 tmp = gfc_build_addr_expr (NULL, tmp);
2791 var = gfc_create_var (TREE_TYPE (tmp), "ptr");
2792 gfc_add_modify_expr (&block, var, tmp);
2794 /* Parameter is the address of the data component. */
2795 tmp = gfc_chainon_list (NULL_TREE, var);
2796 tmp = gfc_chainon_list (tmp, integer_zero_node);
2797 tmp = gfc_build_function_call (gfor_fndecl_deallocate, tmp);
2798 gfc_add_expr_to_block (&block, tmp);
2800 return gfc_finish_block (&block);
2804 /* Create an array constructor from an initialization expression.
2805 We assume the frontend already did any expansions and conversions. */
2807 tree
2808 gfc_conv_array_initializer (tree type, gfc_expr * expr)
2810 gfc_constructor *c;
2811 tree list;
2812 tree tmp;
2813 mpz_t maxval;
2814 gfc_se se;
2815 HOST_WIDE_INT hi;
2816 unsigned HOST_WIDE_INT lo;
2817 tree index, range;
2819 list = NULL_TREE;
2820 switch (expr->expr_type)
2822 case EXPR_CONSTANT:
2823 case EXPR_STRUCTURE:
2824 /* A single scalar or derived type value. Create an array with all
2825 elements equal to that value. */
2826 gfc_init_se (&se, NULL);
2828 if (expr->expr_type == EXPR_CONSTANT)
2829 gfc_conv_constant (&se, expr);
2830 else
2831 gfc_conv_structure (&se, expr, 1);
2833 tmp = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
2834 gcc_assert (tmp && INTEGER_CST_P (tmp));
2835 hi = TREE_INT_CST_HIGH (tmp);
2836 lo = TREE_INT_CST_LOW (tmp);
2837 lo++;
2838 if (lo == 0)
2839 hi++;
2840 /* This will probably eat buckets of memory for large arrays. */
2841 while (hi != 0 || lo != 0)
2843 list = tree_cons (NULL_TREE, se.expr, list);
2844 if (lo == 0)
2845 hi--;
2846 lo--;
2848 break;
2850 case EXPR_ARRAY:
2851 /* Create a list of all the elements. */
2852 for (c = expr->value.constructor; c; c = c->next)
2854 if (c->iterator)
2856 /* Problems occur when we get something like
2857 integer :: a(lots) = (/(i, i=1,lots)/) */
2858 /* TODO: Unexpanded array initializers. */
2859 internal_error
2860 ("Possible frontend bug: array constructor not expanded");
2862 if (mpz_cmp_si (c->n.offset, 0) != 0)
2863 index = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
2864 else
2865 index = NULL_TREE;
2866 mpz_init (maxval);
2867 if (mpz_cmp_si (c->repeat, 0) != 0)
2869 tree tmp1, tmp2;
2871 mpz_set (maxval, c->repeat);
2872 mpz_add (maxval, c->n.offset, maxval);
2873 mpz_sub_ui (maxval, maxval, 1);
2874 tmp2 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
2875 if (mpz_cmp_si (c->n.offset, 0) != 0)
2877 mpz_add_ui (maxval, c->n.offset, 1);
2878 tmp1 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
2880 else
2881 tmp1 = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
2883 range = build2 (RANGE_EXPR, integer_type_node, tmp1, tmp2);
2885 else
2886 range = NULL;
2887 mpz_clear (maxval);
2889 gfc_init_se (&se, NULL);
2890 switch (c->expr->expr_type)
2892 case EXPR_CONSTANT:
2893 gfc_conv_constant (&se, c->expr);
2894 if (range == NULL_TREE)
2895 list = tree_cons (index, se.expr, list);
2896 else
2898 if (index != NULL_TREE)
2899 list = tree_cons (index, se.expr, list);
2900 list = tree_cons (range, se.expr, list);
2902 break;
2904 case EXPR_STRUCTURE:
2905 gfc_conv_structure (&se, c->expr, 1);
2906 list = tree_cons (index, se.expr, list);
2907 break;
2909 default:
2910 gcc_unreachable ();
2913 /* We created the list in reverse order. */
2914 list = nreverse (list);
2915 break;
2917 default:
2918 gcc_unreachable ();
2921 /* Create a constructor from the list of elements. */
2922 tmp = build1 (CONSTRUCTOR, type, list);
2923 TREE_CONSTANT (tmp) = 1;
2924 TREE_INVARIANT (tmp) = 1;
2925 return tmp;
2929 /* Generate code to evaluate non-constant array bounds. Sets *poffset and
2930 returns the size (in elements) of the array. */
2932 static tree
2933 gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
2934 stmtblock_t * pblock)
2936 gfc_array_spec *as;
2937 tree size;
2938 tree stride;
2939 tree offset;
2940 tree ubound;
2941 tree lbound;
2942 tree tmp;
2943 gfc_se se;
2945 int dim;
2947 as = sym->as;
2949 size = gfc_index_one_node;
2950 offset = gfc_index_zero_node;
2951 for (dim = 0; dim < as->rank; dim++)
2953 /* Evaluate non-constant array bound expressions. */
2954 lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
2955 if (as->lower[dim] && !INTEGER_CST_P (lbound))
2957 gfc_init_se (&se, NULL);
2958 gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
2959 gfc_add_block_to_block (pblock, &se.pre);
2960 gfc_add_modify_expr (pblock, lbound, se.expr);
2962 ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
2963 if (as->upper[dim] && !INTEGER_CST_P (ubound))
2965 gfc_init_se (&se, NULL);
2966 gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
2967 gfc_add_block_to_block (pblock, &se.pre);
2968 gfc_add_modify_expr (pblock, ubound, se.expr);
2970 /* The offset of this dimension. offset = offset - lbound * stride. */
2971 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, size);
2972 offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
2974 /* The size of this dimension, and the stride of the next. */
2975 if (dim + 1 < as->rank)
2976 stride = GFC_TYPE_ARRAY_STRIDE (type, dim + 1);
2977 else
2978 stride = NULL_TREE;
2980 if (ubound != NULL_TREE && !(stride && INTEGER_CST_P (stride)))
2982 /* Calculate stride = size * (ubound + 1 - lbound). */
2983 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2984 gfc_index_one_node, lbound);
2985 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, ubound, tmp);
2986 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
2987 if (stride)
2988 gfc_add_modify_expr (pblock, stride, tmp);
2989 else
2990 stride = gfc_evaluate_now (tmp, pblock);
2993 size = stride;
2996 *poffset = offset;
2997 return size;
3001 /* Generate code to initialize/allocate an array variable. */
3003 tree
3004 gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, tree fnbody)
3006 stmtblock_t block;
3007 tree type;
3008 tree tmp;
3009 tree fndecl;
3010 tree size;
3011 tree offset;
3012 bool onstack;
3014 gcc_assert (!(sym->attr.pointer || sym->attr.allocatable));
3016 /* Do nothing for USEd variables. */
3017 if (sym->attr.use_assoc)
3018 return fnbody;
3020 type = TREE_TYPE (decl);
3021 gcc_assert (GFC_ARRAY_TYPE_P (type));
3022 onstack = TREE_CODE (type) != POINTER_TYPE;
3024 gfc_start_block (&block);
3026 /* Evaluate character string length. */
3027 if (sym->ts.type == BT_CHARACTER
3028 && onstack && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3030 gfc_trans_init_string_length (sym->ts.cl, &block);
3032 /* Emit a DECL_EXPR for this variable, which will cause the
3033 gimplifier to allocate storage, and all that good stuff. */
3034 tmp = build1 (DECL_EXPR, TREE_TYPE (decl), decl);
3035 gfc_add_expr_to_block (&block, tmp);
3038 if (onstack)
3040 gfc_add_expr_to_block (&block, fnbody);
3041 return gfc_finish_block (&block);
3044 type = TREE_TYPE (type);
3046 gcc_assert (!sym->attr.use_assoc);
3047 gcc_assert (!TREE_STATIC (decl));
3048 gcc_assert (!sym->module);
3050 if (sym->ts.type == BT_CHARACTER
3051 && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3052 gfc_trans_init_string_length (sym->ts.cl, &block);
3054 size = gfc_trans_array_bounds (type, sym, &offset, &block);
3056 /* The size is the number of elements in the array, so multiply by the
3057 size of an element to get the total size. */
3058 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
3059 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
3061 /* Allocate memory to hold the data. */
3062 tmp = gfc_chainon_list (NULL_TREE, size);
3064 if (gfc_index_integer_kind == 4)
3065 fndecl = gfor_fndecl_internal_malloc;
3066 else if (gfc_index_integer_kind == 8)
3067 fndecl = gfor_fndecl_internal_malloc64;
3068 else
3069 gcc_unreachable ();
3070 tmp = gfc_build_function_call (fndecl, tmp);
3071 tmp = fold (convert (TREE_TYPE (decl), tmp));
3072 gfc_add_modify_expr (&block, decl, tmp);
3074 /* Set offset of the array. */
3075 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3076 gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3079 /* Automatic arrays should not have initializers. */
3080 gcc_assert (!sym->value);
3082 gfc_add_expr_to_block (&block, fnbody);
3084 /* Free the temporary. */
3085 tmp = convert (pvoid_type_node, decl);
3086 tmp = gfc_chainon_list (NULL_TREE, tmp);
3087 tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
3088 gfc_add_expr_to_block (&block, tmp);
3090 return gfc_finish_block (&block);
3094 /* Generate entry and exit code for g77 calling convention arrays. */
3096 tree
3097 gfc_trans_g77_array (gfc_symbol * sym, tree body)
3099 tree parm;
3100 tree type;
3101 locus loc;
3102 tree offset;
3103 tree tmp;
3104 stmtblock_t block;
3106 gfc_get_backend_locus (&loc);
3107 gfc_set_backend_locus (&sym->declared_at);
3109 /* Descriptor type. */
3110 parm = sym->backend_decl;
3111 type = TREE_TYPE (parm);
3112 gcc_assert (GFC_ARRAY_TYPE_P (type));
3114 gfc_start_block (&block);
3116 if (sym->ts.type == BT_CHARACTER
3117 && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
3118 gfc_trans_init_string_length (sym->ts.cl, &block);
3120 /* Evaluate the bounds of the array. */
3121 gfc_trans_array_bounds (type, sym, &offset, &block);
3123 /* Set the offset. */
3124 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3125 gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3127 /* Set the pointer itself if we aren't using the parameter directly. */
3128 if (TREE_CODE (parm) != PARM_DECL)
3130 tmp = convert (TREE_TYPE (parm), GFC_DECL_SAVED_DESCRIPTOR (parm));
3131 gfc_add_modify_expr (&block, parm, tmp);
3133 tmp = gfc_finish_block (&block);
3135 gfc_set_backend_locus (&loc);
3137 gfc_start_block (&block);
3138 /* Add the initialization code to the start of the function. */
3139 gfc_add_expr_to_block (&block, tmp);
3140 gfc_add_expr_to_block (&block, body);
3142 return gfc_finish_block (&block);
3146 /* Modify the descriptor of an array parameter so that it has the
3147 correct lower bound. Also move the upper bound accordingly.
3148 If the array is not packed, it will be copied into a temporary.
3149 For each dimension we set the new lower and upper bounds. Then we copy the
3150 stride and calculate the offset for this dimension. We also work out
3151 what the stride of a packed array would be, and see it the two match.
3152 If the array need repacking, we set the stride to the values we just
3153 calculated, recalculate the offset and copy the array data.
3154 Code is also added to copy the data back at the end of the function.
3157 tree
3158 gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
3160 tree size;
3161 tree type;
3162 tree offset;
3163 locus loc;
3164 stmtblock_t block;
3165 stmtblock_t cleanup;
3166 tree lbound;
3167 tree ubound;
3168 tree dubound;
3169 tree dlbound;
3170 tree dumdesc;
3171 tree tmp;
3172 tree stmt;
3173 tree stride;
3174 tree stmt_packed;
3175 tree stmt_unpacked;
3176 tree partial;
3177 gfc_se se;
3178 int n;
3179 int checkparm;
3180 int no_repack;
3181 bool optional_arg;
3183 /* Do nothing for pointer and allocatable arrays. */
3184 if (sym->attr.pointer || sym->attr.allocatable)
3185 return body;
3187 if (sym->attr.dummy && gfc_is_nodesc_array (sym))
3188 return gfc_trans_g77_array (sym, body);
3190 gfc_get_backend_locus (&loc);
3191 gfc_set_backend_locus (&sym->declared_at);
3193 /* Descriptor type. */
3194 type = TREE_TYPE (tmpdesc);
3195 gcc_assert (GFC_ARRAY_TYPE_P (type));
3196 dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3197 dumdesc = gfc_build_indirect_ref (dumdesc);
3198 gfc_start_block (&block);
3200 if (sym->ts.type == BT_CHARACTER
3201 && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
3202 gfc_trans_init_string_length (sym->ts.cl, &block);
3204 checkparm = (sym->as->type == AS_EXPLICIT && flag_bounds_check);
3206 no_repack = !(GFC_DECL_PACKED_ARRAY (tmpdesc)
3207 || GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc));
3209 if (GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc))
3211 /* For non-constant shape arrays we only check if the first dimension
3212 is contiguous. Repacking higher dimensions wouldn't gain us
3213 anything as we still don't know the array stride. */
3214 partial = gfc_create_var (boolean_type_node, "partial");
3215 TREE_USED (partial) = 1;
3216 tmp = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
3217 tmp = fold_build2 (EQ_EXPR, boolean_type_node, tmp, integer_one_node);
3218 gfc_add_modify_expr (&block, partial, tmp);
3220 else
3222 partial = NULL_TREE;
3225 /* The naming of stmt_unpacked and stmt_packed may be counter-intuitive
3226 here, however I think it does the right thing. */
3227 if (no_repack)
3229 /* Set the first stride. */
3230 stride = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
3231 stride = gfc_evaluate_now (stride, &block);
3233 tmp = build2 (EQ_EXPR, boolean_type_node, stride, integer_zero_node);
3234 tmp = build3 (COND_EXPR, gfc_array_index_type, tmp,
3235 gfc_index_one_node, stride);
3236 stride = GFC_TYPE_ARRAY_STRIDE (type, 0);
3237 gfc_add_modify_expr (&block, stride, tmp);
3239 /* Allow the user to disable array repacking. */
3240 stmt_unpacked = NULL_TREE;
3242 else
3244 gcc_assert (integer_onep (GFC_TYPE_ARRAY_STRIDE (type, 0)));
3245 /* A library call to repack the array if necessary. */
3246 tmp = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3247 tmp = gfc_chainon_list (NULL_TREE, tmp);
3248 stmt_unpacked = gfc_build_function_call (gfor_fndecl_in_pack, tmp);
3250 stride = gfc_index_one_node;
3253 /* This is for the case where the array data is used directly without
3254 calling the repack function. */
3255 if (no_repack || partial != NULL_TREE)
3256 stmt_packed = gfc_conv_descriptor_data (dumdesc);
3257 else
3258 stmt_packed = NULL_TREE;
3260 /* Assign the data pointer. */
3261 if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
3263 /* Don't repack unknown shape arrays when the first stride is 1. */
3264 tmp = build3 (COND_EXPR, TREE_TYPE (stmt_packed), partial,
3265 stmt_packed, stmt_unpacked);
3267 else
3268 tmp = stmt_packed != NULL_TREE ? stmt_packed : stmt_unpacked;
3269 gfc_add_modify_expr (&block, tmpdesc, fold_convert (type, tmp));
3271 offset = gfc_index_zero_node;
3272 size = gfc_index_one_node;
3274 /* Evaluate the bounds of the array. */
3275 for (n = 0; n < sym->as->rank; n++)
3277 if (checkparm || !sym->as->upper[n])
3279 /* Get the bounds of the actual parameter. */
3280 dubound = gfc_conv_descriptor_ubound (dumdesc, gfc_rank_cst[n]);
3281 dlbound = gfc_conv_descriptor_lbound (dumdesc, gfc_rank_cst[n]);
3283 else
3285 dubound = NULL_TREE;
3286 dlbound = NULL_TREE;
3289 lbound = GFC_TYPE_ARRAY_LBOUND (type, n);
3290 if (!INTEGER_CST_P (lbound))
3292 gfc_init_se (&se, NULL);
3293 gfc_conv_expr_type (&se, sym->as->upper[n],
3294 gfc_array_index_type);
3295 gfc_add_block_to_block (&block, &se.pre);
3296 gfc_add_modify_expr (&block, lbound, se.expr);
3299 ubound = GFC_TYPE_ARRAY_UBOUND (type, n);
3300 /* Set the desired upper bound. */
3301 if (sym->as->upper[n])
3303 /* We know what we want the upper bound to be. */
3304 if (!INTEGER_CST_P (ubound))
3306 gfc_init_se (&se, NULL);
3307 gfc_conv_expr_type (&se, sym->as->upper[n],
3308 gfc_array_index_type);
3309 gfc_add_block_to_block (&block, &se.pre);
3310 gfc_add_modify_expr (&block, ubound, se.expr);
3313 /* Check the sizes match. */
3314 if (checkparm)
3316 /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)). */
3318 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3319 ubound, lbound);
3320 stride = build2 (MINUS_EXPR, gfc_array_index_type,
3321 dubound, dlbound);
3322 tmp = fold_build2 (NE_EXPR, gfc_array_index_type, tmp, stride);
3323 gfc_trans_runtime_check (tmp, gfc_strconst_bounds, &block);
3326 else
3328 /* For assumed shape arrays move the upper bound by the same amount
3329 as the lower bound. */
3330 tmp = build2 (MINUS_EXPR, gfc_array_index_type, dubound, dlbound);
3331 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp, lbound);
3332 gfc_add_modify_expr (&block, ubound, tmp);
3334 /* The offset of this dimension. offset = offset - lbound * stride. */
3335 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, stride);
3336 offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3338 /* The size of this dimension, and the stride of the next. */
3339 if (n + 1 < sym->as->rank)
3341 stride = GFC_TYPE_ARRAY_STRIDE (type, n + 1);
3343 if (no_repack || partial != NULL_TREE)
3345 stmt_unpacked =
3346 gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[n+1]);
3349 /* Figure out the stride if not a known constant. */
3350 if (!INTEGER_CST_P (stride))
3352 if (no_repack)
3353 stmt_packed = NULL_TREE;
3354 else
3356 /* Calculate stride = size * (ubound + 1 - lbound). */
3357 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3358 gfc_index_one_node, lbound);
3359 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3360 ubound, tmp);
3361 size = fold_build2 (MULT_EXPR, gfc_array_index_type,
3362 size, tmp);
3363 stmt_packed = size;
3366 /* Assign the stride. */
3367 if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
3368 tmp = build3 (COND_EXPR, gfc_array_index_type, partial,
3369 stmt_unpacked, stmt_packed);
3370 else
3371 tmp = (stmt_packed != NULL_TREE) ? stmt_packed : stmt_unpacked;
3372 gfc_add_modify_expr (&block, stride, tmp);
3377 /* Set the offset. */
3378 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3379 gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3381 stmt = gfc_finish_block (&block);
3383 gfc_start_block (&block);
3385 /* Only do the entry/initialization code if the arg is present. */
3386 dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3387 optional_arg = (sym->attr.optional
3388 || (sym->ns->proc_name->attr.entry_master
3389 && sym->attr.dummy));
3390 if (optional_arg)
3392 tmp = gfc_conv_expr_present (sym);
3393 stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3395 gfc_add_expr_to_block (&block, stmt);
3397 /* Add the main function body. */
3398 gfc_add_expr_to_block (&block, body);
3400 /* Cleanup code. */
3401 if (!no_repack)
3403 gfc_start_block (&cleanup);
3405 if (sym->attr.intent != INTENT_IN)
3407 /* Copy the data back. */
3408 tmp = gfc_chainon_list (NULL_TREE, dumdesc);
3409 tmp = gfc_chainon_list (tmp, tmpdesc);
3410 tmp = gfc_build_function_call (gfor_fndecl_in_unpack, tmp);
3411 gfc_add_expr_to_block (&cleanup, tmp);
3414 /* Free the temporary. */
3415 tmp = gfc_chainon_list (NULL_TREE, tmpdesc);
3416 tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
3417 gfc_add_expr_to_block (&cleanup, tmp);
3419 stmt = gfc_finish_block (&cleanup);
3421 /* Only do the cleanup if the array was repacked. */
3422 tmp = gfc_build_indirect_ref (dumdesc);
3423 tmp = gfc_conv_descriptor_data (tmp);
3424 tmp = build2 (NE_EXPR, boolean_type_node, tmp, tmpdesc);
3425 stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3427 if (optional_arg)
3429 tmp = gfc_conv_expr_present (sym);
3430 stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3432 gfc_add_expr_to_block (&block, stmt);
3434 /* We don't need to free any memory allocated by internal_pack as it will
3435 be freed at the end of the function by pop_context. */
3436 return gfc_finish_block (&block);
3440 /* Convert an array for passing as an actual parameter. Expressions and
3441 vector subscripts are evaluated and stored in a temporary, which is then
3442 passed. For whole arrays the descriptor is passed. For array sections
3443 a modified copy of the descriptor is passed, but using the original data.
3444 Also used for array pointer assignments by setting se->direct_byref. */
3446 void
3447 gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
3449 gfc_loopinfo loop;
3450 gfc_ss *secss;
3451 gfc_ss_info *info;
3452 int need_tmp;
3453 int n;
3454 tree tmp;
3455 tree desc;
3456 stmtblock_t block;
3457 tree start;
3458 tree offset;
3459 int full;
3460 gfc_ss *vss;
3461 gfc_ref *ref;
3463 gcc_assert (ss != gfc_ss_terminator);
3465 /* TODO: Pass constant array constructors without a temporary. */
3466 /* Special case things we know we can pass easily. */
3467 switch (expr->expr_type)
3469 case EXPR_VARIABLE:
3470 /* If we have a linear array section, we can pass it directly.
3471 Otherwise we need to copy it into a temporary. */
3473 /* Find the SS for the array section. */
3474 secss = ss;
3475 while (secss != gfc_ss_terminator && secss->type != GFC_SS_SECTION)
3476 secss = secss->next;
3478 gcc_assert (secss != gfc_ss_terminator);
3480 need_tmp = 0;
3481 for (n = 0; n < secss->data.info.dimen; n++)
3483 vss = secss->data.info.subscript[secss->data.info.dim[n]];
3484 if (vss && vss->type == GFC_SS_VECTOR)
3485 need_tmp = 1;
3488 info = &secss->data.info;
3490 /* Get the descriptor for the array. */
3491 gfc_conv_ss_descriptor (&se->pre, secss, 0);
3492 desc = info->descriptor;
3493 if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
3495 /* Create a new descriptor if the array doesn't have one. */
3496 full = 0;
3498 else if (info->ref->u.ar.type == AR_FULL)
3499 full = 1;
3500 else if (se->direct_byref)
3501 full = 0;
3502 else
3504 ref = info->ref;
3505 gcc_assert (ref->u.ar.type == AR_SECTION);
3507 full = 1;
3508 for (n = 0; n < ref->u.ar.dimen; n++)
3510 /* Detect passing the full array as a section. This could do
3511 even more checking, but it doesn't seem worth it. */
3512 if (ref->u.ar.start[n]
3513 || ref->u.ar.end[n]
3514 || (ref->u.ar.stride[n]
3515 && !gfc_expr_is_one (ref->u.ar.stride[n], 0)))
3517 full = 0;
3518 break;
3523 /* Check for substring references. */
3524 ref = expr->ref;
3525 if (!need_tmp && ref && expr->ts.type == BT_CHARACTER)
3527 while (ref->next)
3528 ref = ref->next;
3529 if (ref->type == REF_SUBSTRING)
3531 /* In general character substrings need a copy. Character
3532 array strides are expressed as multiples of the element
3533 size (consistent with other array types), not in
3534 characters. */
3535 full = 0;
3536 need_tmp = 1;
3540 if (full)
3542 if (se->direct_byref)
3544 /* Copy the descriptor for pointer assignments. */
3545 gfc_add_modify_expr (&se->pre, se->expr, desc);
3547 else if (se->want_pointer)
3549 /* We pass full arrays directly. This means that pointers and
3550 allocatable arrays should also work. */
3551 se->expr = gfc_build_addr_expr (NULL_TREE, desc);
3553 else
3555 se->expr = desc;
3558 if (expr->ts.type == BT_CHARACTER)
3559 se->string_length = gfc_get_expr_charlen (expr);
3561 return;
3563 break;
3565 case EXPR_FUNCTION:
3566 /* A transformational function return value will be a temporary
3567 array descriptor. We still need to go through the scalarizer
3568 to create the descriptor. Elemental functions ar handled as
3569 arbitrary expressions, i.e. copy to a temporary. */
3570 secss = ss;
3571 /* Look for the SS for this function. */
3572 while (secss != gfc_ss_terminator
3573 && (secss->type != GFC_SS_FUNCTION || secss->expr != expr))
3574 secss = secss->next;
3576 if (se->direct_byref)
3578 gcc_assert (secss != gfc_ss_terminator);
3580 /* For pointer assignments pass the descriptor directly. */
3581 se->ss = secss;
3582 se->expr = gfc_build_addr_expr (NULL, se->expr);
3583 gfc_conv_expr (se, expr);
3584 return;
3587 if (secss == gfc_ss_terminator)
3589 /* Elemental function. */
3590 need_tmp = 1;
3591 info = NULL;
3593 else
3595 /* Transformational function. */
3596 info = &secss->data.info;
3597 need_tmp = 0;
3599 break;
3601 default:
3602 /* Something complicated. Copy it into a temporary. */
3603 need_tmp = 1;
3604 secss = NULL;
3605 info = NULL;
3606 break;
3610 gfc_init_loopinfo (&loop);
3612 /* Associate the SS with the loop. */
3613 gfc_add_ss_to_loop (&loop, ss);
3615 /* Tell the scalarizer not to bother creating loop variables, etc. */
3616 if (!need_tmp)
3617 loop.array_parameter = 1;
3618 else
3619 gcc_assert (se->want_pointer && !se->direct_byref);
3621 /* Setup the scalarizing loops and bounds. */
3622 gfc_conv_ss_startstride (&loop);
3624 if (need_tmp)
3626 /* Tell the scalarizer to make a temporary. */
3627 loop.temp_ss = gfc_get_ss ();
3628 loop.temp_ss->type = GFC_SS_TEMP;
3629 loop.temp_ss->next = gfc_ss_terminator;
3630 if (expr->ts.type == BT_CHARACTER)
3632 gcc_assert (expr->ts.cl && expr->ts.cl->length
3633 && expr->ts.cl->length->expr_type == EXPR_CONSTANT);
3634 loop.temp_ss->string_length = gfc_conv_mpz_to_tree
3635 (expr->ts.cl->length->value.integer,
3636 expr->ts.cl->length->ts.kind);
3637 expr->ts.cl->backend_decl = loop.temp_ss->string_length;
3639 loop.temp_ss->data.temp.type = gfc_typenode_for_spec (&expr->ts);
3641 /* ... which can hold our string, if present. */
3642 if (expr->ts.type == BT_CHARACTER)
3644 loop.temp_ss->string_length = TYPE_SIZE_UNIT (loop.temp_ss->data.temp.type);
3645 se->string_length = loop.temp_ss->string_length;
3647 else
3648 loop.temp_ss->string_length = NULL;
3649 loop.temp_ss->data.temp.dimen = loop.dimen;
3650 gfc_add_ss_to_loop (&loop, loop.temp_ss);
3653 gfc_conv_loop_setup (&loop);
3655 if (need_tmp)
3657 /* Copy into a temporary and pass that. We don't need to copy the data
3658 back because expressions and vector subscripts must be INTENT_IN. */
3659 /* TODO: Optimize passing function return values. */
3660 gfc_se lse;
3661 gfc_se rse;
3663 /* Start the copying loops. */
3664 gfc_mark_ss_chain_used (loop.temp_ss, 1);
3665 gfc_mark_ss_chain_used (ss, 1);
3666 gfc_start_scalarized_body (&loop, &block);
3668 /* Copy each data element. */
3669 gfc_init_se (&lse, NULL);
3670 gfc_copy_loopinfo_to_se (&lse, &loop);
3671 gfc_init_se (&rse, NULL);
3672 gfc_copy_loopinfo_to_se (&rse, &loop);
3674 lse.ss = loop.temp_ss;
3675 rse.ss = ss;
3677 gfc_conv_scalarized_array_ref (&lse, NULL);
3678 if (expr->ts.type == BT_CHARACTER)
3680 gfc_conv_expr (&rse, expr);
3681 rse.expr = gfc_build_indirect_ref (rse.expr);
3683 else
3684 gfc_conv_expr_val (&rse, expr);
3686 gfc_add_block_to_block (&block, &rse.pre);
3687 gfc_add_block_to_block (&block, &lse.pre);
3689 gfc_add_modify_expr (&block, lse.expr, rse.expr);
3691 /* Finish the copying loops. */
3692 gfc_trans_scalarizing_loops (&loop, &block);
3694 /* Set the first stride component to zero to indicate a temporary. */
3695 desc = loop.temp_ss->data.info.descriptor;
3696 tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[0]);
3697 gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
3699 gcc_assert (is_gimple_lvalue (desc));
3700 se->expr = gfc_build_addr_expr (NULL, desc);
3702 else if (expr->expr_type == EXPR_FUNCTION)
3704 desc = info->descriptor;
3706 if (se->want_pointer)
3707 se->expr = gfc_build_addr_expr (NULL_TREE, desc);
3708 else
3709 se->expr = desc;
3711 if (expr->ts.type == BT_CHARACTER)
3712 se->string_length = expr->symtree->n.sym->ts.cl->backend_decl;
3714 else
3716 /* We pass sections without copying to a temporary. Make a new
3717 descriptor and point it at the section we want. The loop variable
3718 limits will be the limits of the section.
3719 A function may decide to repack the array to speed up access, but
3720 we're not bothered about that here. */
3721 int dim;
3722 tree parm;
3723 tree parmtype;
3724 tree stride;
3725 tree from;
3726 tree to;
3727 tree base;
3729 /* Set the string_length for a character array. */
3730 if (expr->ts.type == BT_CHARACTER)
3731 se->string_length = gfc_get_expr_charlen (expr);
3733 desc = info->descriptor;
3734 gcc_assert (secss && secss != gfc_ss_terminator);
3735 if (se->direct_byref)
3737 /* For pointer assignments we fill in the destination. */
3738 parm = se->expr;
3739 parmtype = TREE_TYPE (parm);
3741 else
3743 /* Otherwise make a new one. */
3744 parmtype = gfc_get_element_type (TREE_TYPE (desc));
3745 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen,
3746 loop.from, loop.to, 0);
3747 parm = gfc_create_var (parmtype, "parm");
3750 offset = gfc_index_zero_node;
3751 dim = 0;
3753 /* The following can be somewhat confusing. We have two
3754 descriptors, a new one and the original array.
3755 {parm, parmtype, dim} refer to the new one.
3756 {desc, type, n, secss, loop} refer to the original, which maybe
3757 a descriptorless array.
3758 The bounds of the scalarization are the bounds of the section.
3759 We don't have to worry about numeric overflows when calculating
3760 the offsets because all elements are within the array data. */
3762 /* Set the dtype. */
3763 tmp = gfc_conv_descriptor_dtype (parm);
3764 gfc_add_modify_expr (&loop.pre, tmp, gfc_get_dtype (parmtype));
3766 if (se->direct_byref)
3767 base = gfc_index_zero_node;
3768 else
3769 base = NULL_TREE;
3771 for (n = 0; n < info->ref->u.ar.dimen; n++)
3773 stride = gfc_conv_array_stride (desc, n);
3775 /* Work out the offset. */
3776 if (info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
3778 gcc_assert (info->subscript[n]
3779 && info->subscript[n]->type == GFC_SS_SCALAR);
3780 start = info->subscript[n]->data.scalar.expr;
3782 else
3784 /* Check we haven't somehow got out of sync. */
3785 gcc_assert (info->dim[dim] == n);
3787 /* Evaluate and remember the start of the section. */
3788 start = info->start[dim];
3789 stride = gfc_evaluate_now (stride, &loop.pre);
3792 tmp = gfc_conv_array_lbound (desc, n);
3793 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), start, tmp);
3795 tmp = fold_build2 (MULT_EXPR, TREE_TYPE (tmp), tmp, stride);
3796 offset = fold_build2 (PLUS_EXPR, TREE_TYPE (tmp), offset, tmp);
3798 if (info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
3800 /* For elemental dimensions, we only need the offset. */
3801 continue;
3804 /* Vector subscripts need copying and are handled elsewhere. */
3805 gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_RANGE);
3807 /* Set the new lower bound. */
3808 from = loop.from[dim];
3809 to = loop.to[dim];
3810 if (!integer_onep (from))
3812 /* Make sure the new section starts at 1. */
3813 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3814 gfc_index_one_node, from);
3815 to = fold_build2 (PLUS_EXPR, gfc_array_index_type, to, tmp);
3816 from = gfc_index_one_node;
3818 tmp = gfc_conv_descriptor_lbound (parm, gfc_rank_cst[dim]);
3819 gfc_add_modify_expr (&loop.pre, tmp, from);
3821 /* Set the new upper bound. */
3822 tmp = gfc_conv_descriptor_ubound (parm, gfc_rank_cst[dim]);
3823 gfc_add_modify_expr (&loop.pre, tmp, to);
3825 /* Multiply the stride by the section stride to get the
3826 total stride. */
3827 stride = fold_build2 (MULT_EXPR, gfc_array_index_type,
3828 stride, info->stride[dim]);
3830 if (se->direct_byref)
3831 base = fold_build2 (MINUS_EXPR, TREE_TYPE (base),
3832 base, stride);
3834 /* Store the new stride. */
3835 tmp = gfc_conv_descriptor_stride (parm, gfc_rank_cst[dim]);
3836 gfc_add_modify_expr (&loop.pre, tmp, stride);
3838 dim++;
3841 /* Point the data pointer at the first element in the section. */
3842 tmp = gfc_conv_array_data (desc);
3843 tmp = gfc_build_indirect_ref (tmp);
3844 tmp = gfc_build_array_ref (tmp, offset);
3845 offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
3847 tmp = gfc_conv_descriptor_data (parm);
3848 gfc_add_modify_expr (&loop.pre, tmp,
3849 fold_convert (TREE_TYPE (tmp), offset));
3851 if (se->direct_byref)
3853 /* Set the offset. */
3854 tmp = gfc_conv_descriptor_offset (parm);
3855 gfc_add_modify_expr (&loop.pre, tmp, base);
3857 else
3859 /* Only the callee knows what the correct offset it, so just set
3860 it to zero here. */
3861 tmp = gfc_conv_descriptor_offset (parm);
3862 gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
3865 if (!se->direct_byref)
3867 /* Get a pointer to the new descriptor. */
3868 if (se->want_pointer)
3869 se->expr = gfc_build_addr_expr (NULL, parm);
3870 else
3871 se->expr = parm;
3875 gfc_add_block_to_block (&se->pre, &loop.pre);
3876 gfc_add_block_to_block (&se->post, &loop.post);
3878 /* Cleanup the scalarizer. */
3879 gfc_cleanup_loop (&loop);
3883 /* Convert an array for passing as an actual parameter. */
3884 /* TODO: Optimize passing g77 arrays. */
3886 void
3887 gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77)
3889 tree ptr;
3890 tree desc;
3891 tree tmp;
3892 tree stmt;
3893 gfc_symbol *sym;
3894 stmtblock_t block;
3896 /* Passing address of the array if it is not pointer or assumed-shape. */
3897 if (expr->expr_type == EXPR_VARIABLE
3898 && expr->ref->u.ar.type == AR_FULL && g77)
3900 sym = expr->symtree->n.sym;
3901 tmp = gfc_get_symbol_decl (sym);
3902 if (sym->ts.type == BT_CHARACTER)
3903 se->string_length = sym->ts.cl->backend_decl;
3904 if (!sym->attr.pointer && sym->as->type != AS_ASSUMED_SHAPE
3905 && !sym->attr.allocatable)
3907 /* Some variables are declared directly, others are declared as
3908 pointers and allocated on the heap. */
3909 if (sym->attr.dummy || POINTER_TYPE_P (TREE_TYPE (tmp)))
3910 se->expr = tmp;
3911 else
3912 se->expr = gfc_build_addr_expr (NULL, tmp);
3913 return;
3915 if (sym->attr.allocatable)
3917 se->expr = gfc_conv_array_data (tmp);
3918 return;
3922 se->want_pointer = 1;
3923 gfc_conv_expr_descriptor (se, expr, ss);
3925 if (g77)
3927 desc = se->expr;
3928 /* Repack the array. */
3929 tmp = gfc_chainon_list (NULL_TREE, desc);
3930 ptr = gfc_build_function_call (gfor_fndecl_in_pack, tmp);
3931 ptr = gfc_evaluate_now (ptr, &se->pre);
3932 se->expr = ptr;
3934 gfc_start_block (&block);
3936 /* Copy the data back. */
3937 tmp = gfc_chainon_list (NULL_TREE, desc);
3938 tmp = gfc_chainon_list (tmp, ptr);
3939 tmp = gfc_build_function_call (gfor_fndecl_in_unpack, tmp);
3940 gfc_add_expr_to_block (&block, tmp);
3942 /* Free the temporary. */
3943 tmp = convert (pvoid_type_node, ptr);
3944 tmp = gfc_chainon_list (NULL_TREE, tmp);
3945 tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
3946 gfc_add_expr_to_block (&block, tmp);
3948 stmt = gfc_finish_block (&block);
3950 gfc_init_block (&block);
3951 /* Only if it was repacked. This code needs to be executed before the
3952 loop cleanup code. */
3953 tmp = gfc_build_indirect_ref (desc);
3954 tmp = gfc_conv_array_data (tmp);
3955 tmp = build2 (NE_EXPR, boolean_type_node, ptr, tmp);
3956 tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3958 gfc_add_expr_to_block (&block, tmp);
3959 gfc_add_block_to_block (&block, &se->post);
3961 gfc_init_block (&se->post);
3962 gfc_add_block_to_block (&se->post, &block);
3967 /* NULLIFY an allocated/pointer array on function entry, free it on exit. */
3969 tree
3970 gfc_trans_deferred_array (gfc_symbol * sym, tree body)
3972 tree type;
3973 tree tmp;
3974 tree descriptor;
3975 tree deallocate;
3976 stmtblock_t block;
3977 stmtblock_t fnblock;
3978 locus loc;
3980 /* Make sure the frontend gets these right. */
3981 if (!(sym->attr.pointer || sym->attr.allocatable))
3982 fatal_error
3983 ("Possible frontend bug: Deferred array size without pointer or allocatable attribute.");
3985 gfc_init_block (&fnblock);
3987 gcc_assert (TREE_CODE (sym->backend_decl) == VAR_DECL);
3988 if (sym->ts.type == BT_CHARACTER
3989 && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3990 gfc_trans_init_string_length (sym->ts.cl, &fnblock);
3992 /* Parameter and use associated variables don't need anything special. */
3993 if (sym->attr.dummy || sym->attr.use_assoc)
3995 gfc_add_expr_to_block (&fnblock, body);
3997 return gfc_finish_block (&fnblock);
4000 gfc_get_backend_locus (&loc);
4001 gfc_set_backend_locus (&sym->declared_at);
4002 descriptor = sym->backend_decl;
4004 if (TREE_STATIC (descriptor))
4006 /* SAVEd variables are not freed on exit. */
4007 gfc_trans_static_array_pointer (sym);
4008 return body;
4011 /* Get the descriptor type. */
4012 type = TREE_TYPE (sym->backend_decl);
4013 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
4015 /* NULLIFY the data pointer. */
4016 tmp = gfc_conv_descriptor_data (descriptor);
4017 gfc_add_modify_expr (&fnblock, tmp,
4018 convert (TREE_TYPE (tmp), integer_zero_node));
4020 gfc_add_expr_to_block (&fnblock, body);
4022 gfc_set_backend_locus (&loc);
4023 /* Allocatable arrays need to be freed when they go out of scope. */
4024 if (sym->attr.allocatable)
4026 gfc_start_block (&block);
4028 /* Deallocate if still allocated at the end of the procedure. */
4029 deallocate = gfc_array_deallocate (descriptor);
4031 tmp = gfc_conv_descriptor_data (descriptor);
4032 tmp = build2 (NE_EXPR, boolean_type_node, tmp,
4033 build_int_cst (TREE_TYPE (tmp), 0));
4034 tmp = build3_v (COND_EXPR, tmp, deallocate, build_empty_stmt ());
4035 gfc_add_expr_to_block (&block, tmp);
4037 tmp = gfc_finish_block (&block);
4038 gfc_add_expr_to_block (&fnblock, tmp);
4041 return gfc_finish_block (&fnblock);
4044 /************ Expression Walking Functions ******************/
4046 /* Walk a variable reference.
4048 Possible extension - multiple component subscripts.
4049 x(:,:) = foo%a(:)%b(:)
4050 Transforms to
4051 forall (i=..., j=...)
4052 x(i,j) = foo%a(j)%b(i)
4053 end forall
4054 This adds a fair amout of complexity because you need to deal with more
4055 than one ref. Maybe handle in a similar manner to vector subscripts.
4056 Maybe not worth the effort. */
4059 static gfc_ss *
4060 gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
4062 gfc_ref *ref;
4063 gfc_array_ref *ar;
4064 gfc_ss *newss;
4065 gfc_ss *head;
4066 int n;
4068 for (ref = expr->ref; ref; ref = ref->next)
4070 /* We're only interested in array sections. */
4071 if (ref->type != REF_ARRAY)
4072 continue;
4074 ar = &ref->u.ar;
4075 switch (ar->type)
4077 case AR_ELEMENT:
4078 /* TODO: Take elemental array references out of scalarization
4079 loop. */
4080 break;
4082 case AR_FULL:
4083 newss = gfc_get_ss ();
4084 newss->type = GFC_SS_SECTION;
4085 newss->expr = expr;
4086 newss->next = ss;
4087 newss->data.info.dimen = ar->as->rank;
4088 newss->data.info.ref = ref;
4090 /* Make sure array is the same as array(:,:), this way
4091 we don't need to special case all the time. */
4092 ar->dimen = ar->as->rank;
4093 for (n = 0; n < ar->dimen; n++)
4095 newss->data.info.dim[n] = n;
4096 ar->dimen_type[n] = DIMEN_RANGE;
4098 gcc_assert (ar->start[n] == NULL);
4099 gcc_assert (ar->end[n] == NULL);
4100 gcc_assert (ar->stride[n] == NULL);
4102 return newss;
4104 case AR_SECTION:
4105 newss = gfc_get_ss ();
4106 newss->type = GFC_SS_SECTION;
4107 newss->expr = expr;
4108 newss->next = ss;
4109 newss->data.info.dimen = 0;
4110 newss->data.info.ref = ref;
4112 head = newss;
4114 /* We add SS chains for all the subscripts in the section. */
4115 for (n = 0; n < ar->dimen; n++)
4117 gfc_ss *indexss;
4119 switch (ar->dimen_type[n])
4121 case DIMEN_ELEMENT:
4122 /* Add SS for elemental (scalar) subscripts. */
4123 gcc_assert (ar->start[n]);
4124 indexss = gfc_get_ss ();
4125 indexss->type = GFC_SS_SCALAR;
4126 indexss->expr = ar->start[n];
4127 indexss->next = gfc_ss_terminator;
4128 indexss->loop_chain = gfc_ss_terminator;
4129 newss->data.info.subscript[n] = indexss;
4130 break;
4132 case DIMEN_RANGE:
4133 /* We don't add anything for sections, just remember this
4134 dimension for later. */
4135 newss->data.info.dim[newss->data.info.dimen] = n;
4136 newss->data.info.dimen++;
4137 break;
4139 case DIMEN_VECTOR:
4140 /* Get a SS for the vector. This will not be added to the
4141 chain directly. */
4142 indexss = gfc_walk_expr (ar->start[n]);
4143 if (indexss == gfc_ss_terminator)
4144 internal_error ("scalar vector subscript???");
4146 /* We currently only handle really simple vector
4147 subscripts. */
4148 if (indexss->next != gfc_ss_terminator)
4149 gfc_todo_error ("vector subscript expressions");
4150 indexss->loop_chain = gfc_ss_terminator;
4152 /* Mark this as a vector subscript. We don't add this
4153 directly into the chain, but as a subscript of the
4154 existing SS for this term. */
4155 indexss->type = GFC_SS_VECTOR;
4156 newss->data.info.subscript[n] = indexss;
4157 /* Also remember this dimension. */
4158 newss->data.info.dim[newss->data.info.dimen] = n;
4159 newss->data.info.dimen++;
4160 break;
4162 default:
4163 /* We should know what sort of section it is by now. */
4164 gcc_unreachable ();
4167 /* We should have at least one non-elemental dimension. */
4168 gcc_assert (newss->data.info.dimen > 0);
4169 return head;
4170 break;
4172 default:
4173 /* We should know what sort of section it is by now. */
4174 gcc_unreachable ();
4178 return ss;
4182 /* Walk an expression operator. If only one operand of a binary expression is
4183 scalar, we must also add the scalar term to the SS chain. */
4185 static gfc_ss *
4186 gfc_walk_op_expr (gfc_ss * ss, gfc_expr * expr)
4188 gfc_ss *head;
4189 gfc_ss *head2;
4190 gfc_ss *newss;
4192 head = gfc_walk_subexpr (ss, expr->value.op.op1);
4193 if (expr->value.op.op2 == NULL)
4194 head2 = head;
4195 else
4196 head2 = gfc_walk_subexpr (head, expr->value.op.op2);
4198 /* All operands are scalar. Pass back and let the caller deal with it. */
4199 if (head2 == ss)
4200 return head2;
4202 /* All operands require scalarization. */
4203 if (head != ss && (expr->value.op.op2 == NULL || head2 != head))
4204 return head2;
4206 /* One of the operands needs scalarization, the other is scalar.
4207 Create a gfc_ss for the scalar expression. */
4208 newss = gfc_get_ss ();
4209 newss->type = GFC_SS_SCALAR;
4210 if (head == ss)
4212 /* First operand is scalar. We build the chain in reverse order, so
4213 add the scarar SS after the second operand. */
4214 head = head2;
4215 while (head && head->next != ss)
4216 head = head->next;
4217 /* Check we haven't somehow broken the chain. */
4218 gcc_assert (head);
4219 newss->next = ss;
4220 head->next = newss;
4221 newss->expr = expr->value.op.op1;
4223 else /* head2 == head */
4225 gcc_assert (head2 == head);
4226 /* Second operand is scalar. */
4227 newss->next = head2;
4228 head2 = newss;
4229 newss->expr = expr->value.op.op2;
4232 return head2;
4236 /* Reverse a SS chain. */
4238 static gfc_ss *
4239 gfc_reverse_ss (gfc_ss * ss)
4241 gfc_ss *next;
4242 gfc_ss *head;
4244 gcc_assert (ss != NULL);
4246 head = gfc_ss_terminator;
4247 while (ss != gfc_ss_terminator)
4249 next = ss->next;
4250 /* Check we didn't somehow break the chain. */
4251 gcc_assert (next != NULL);
4252 ss->next = head;
4253 head = ss;
4254 ss = next;
4257 return (head);
4261 /* Walk the arguments of an elemental function. */
4263 gfc_ss *
4264 gfc_walk_elemental_function_args (gfc_ss * ss, gfc_expr * expr,
4265 gfc_ss_type type)
4267 gfc_actual_arglist *arg;
4268 int scalar;
4269 gfc_ss *head;
4270 gfc_ss *tail;
4271 gfc_ss *newss;
4273 head = gfc_ss_terminator;
4274 tail = NULL;
4275 scalar = 1;
4276 for (arg = expr->value.function.actual; arg; arg = arg->next)
4278 if (!arg->expr)
4279 continue;
4281 newss = gfc_walk_subexpr (head, arg->expr);
4282 if (newss == head)
4284 /* Scalar argument. */
4285 newss = gfc_get_ss ();
4286 newss->type = type;
4287 newss->expr = arg->expr;
4288 newss->next = head;
4290 else
4291 scalar = 0;
4293 head = newss;
4294 if (!tail)
4296 tail = head;
4297 while (tail->next != gfc_ss_terminator)
4298 tail = tail->next;
4302 if (scalar)
4304 /* If all the arguments are scalar we don't need the argument SS. */
4305 gfc_free_ss_chain (head);
4306 /* Pass it back. */
4307 return ss;
4310 /* Add it onto the existing chain. */
4311 tail->next = ss;
4312 return head;
4316 /* Walk a function call. Scalar functions are passed back, and taken out of
4317 scalarization loops. For elemental functions we walk their arguments.
4318 The result of functions returning arrays is stored in a temporary outside
4319 the loop, so that the function is only called once. Hence we do not need
4320 to walk their arguments. */
4322 static gfc_ss *
4323 gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
4325 gfc_ss *newss;
4326 gfc_intrinsic_sym *isym;
4327 gfc_symbol *sym;
4329 isym = expr->value.function.isym;
4331 /* Handle intrinsic functions separately. */
4332 if (isym)
4333 return gfc_walk_intrinsic_function (ss, expr, isym);
4335 sym = expr->value.function.esym;
4336 if (!sym)
4337 sym = expr->symtree->n.sym;
4339 /* A function that returns arrays. */
4340 if (gfc_return_by_reference (sym) && sym->result->attr.dimension)
4342 newss = gfc_get_ss ();
4343 newss->type = GFC_SS_FUNCTION;
4344 newss->expr = expr;
4345 newss->next = ss;
4346 newss->data.info.dimen = expr->rank;
4347 return newss;
4350 /* Walk the parameters of an elemental function. For now we always pass
4351 by reference. */
4352 if (sym->attr.elemental)
4353 return gfc_walk_elemental_function_args (ss, expr, GFC_SS_REFERENCE);
4355 /* Scalar functions are OK as these are evaluated outside the scalarization
4356 loop. Pass back and let the caller deal with it. */
4357 return ss;
4361 /* An array temporary is constructed for array constructors. */
4363 static gfc_ss *
4364 gfc_walk_array_constructor (gfc_ss * ss, gfc_expr * expr)
4366 gfc_ss *newss;
4367 int n;
4369 newss = gfc_get_ss ();
4370 newss->type = GFC_SS_CONSTRUCTOR;
4371 newss->expr = expr;
4372 newss->next = ss;
4373 newss->data.info.dimen = expr->rank;
4374 for (n = 0; n < expr->rank; n++)
4375 newss->data.info.dim[n] = n;
4377 return newss;
4381 /* Walk an expression. Add walked expressions to the head of the SS chain.
4382 A wholly scalar expression will not be added. */
4384 static gfc_ss *
4385 gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr)
4387 gfc_ss *head;
4389 switch (expr->expr_type)
4391 case EXPR_VARIABLE:
4392 head = gfc_walk_variable_expr (ss, expr);
4393 return head;
4395 case EXPR_OP:
4396 head = gfc_walk_op_expr (ss, expr);
4397 return head;
4399 case EXPR_FUNCTION:
4400 head = gfc_walk_function_expr (ss, expr);
4401 return head;
4403 case EXPR_CONSTANT:
4404 case EXPR_NULL:
4405 case EXPR_STRUCTURE:
4406 /* Pass back and let the caller deal with it. */
4407 break;
4409 case EXPR_ARRAY:
4410 head = gfc_walk_array_constructor (ss, expr);
4411 return head;
4413 case EXPR_SUBSTRING:
4414 /* Pass back and let the caller deal with it. */
4415 break;
4417 default:
4418 internal_error ("bad expression type during walk (%d)",
4419 expr->expr_type);
4421 return ss;
4425 /* Entry point for expression walking.
4426 A return value equal to the passed chain means this is
4427 a scalar expression. It is up to the caller to take whatever action is
4428 necessary to translate these. */
4430 gfc_ss *
4431 gfc_walk_expr (gfc_expr * expr)
4433 gfc_ss *res;
4435 res = gfc_walk_subexpr (gfc_ss_terminator, expr);
4436 return gfc_reverse_ss (res);