gfortranspec.c: Update copyright years.
[gcc.git] / gcc / fortran / trans-array.c
1 /* Array translation routines
2 Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
3 Inc.
4 Contributed by Paul Brook <paul@nowt.org>
5 and Steven Bosscher <s.bosscher@student.tudelft.nl>
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to the Free
21 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
22 02110-1301, USA. */
23
24 /* trans-array.c-- Various array related code, including scalarization,
25 allocation, initialization and other support routines. */
26
27 /* How the scalarizer works.
28 In gfortran, array expressions use the same core routines as scalar
29 expressions.
30 First, a Scalarization State (SS) chain is built. This is done by walking
31 the expression tree, and building a linear list of the terms in the
32 expression. As the tree is walked, scalar subexpressions are translated.
33
34 The scalarization parameters are stored in a gfc_loopinfo structure.
35 First the start and stride of each term is calculated by
36 gfc_conv_ss_startstride. During this process the expressions for the array
37 descriptors and data pointers are also translated.
38
39 If the expression is an assignment, we must then resolve any dependencies.
40 In fortran all the rhs values of an assignment must be evaluated before
41 any assignments take place. This can require a temporary array to store the
42 values. We also require a temporary when we are passing array expressions
43 or vector subecripts as procedure parameters.
44
45 Array sections are passed without copying to a temporary. These use the
46 scalarizer to determine the shape of the section. The flag
47 loop->array_parameter tells the scalarizer that the actual values and loop
48 variables will not be required.
49
50 The function gfc_conv_loop_setup generates the scalarization setup code.
51 It determines the range of the scalarizing loop variables. If a temporary
52 is required, this is created and initialized. Code for scalar expressions
53 taken outside the loop is also generated at this time. Next the offset and
54 scaling required to translate from loop variables to array indices for each
55 term is calculated.
56
57 A call to gfc_start_scalarized_body marks the start of the scalarized
58 expression. This creates a scope and declares the loop variables. Before
59 calling this gfc_make_ss_chain_used must be used to indicate which terms
60 will be used inside this loop.
61
62 The scalar gfc_conv_* functions are then used to build the main body of the
63 scalarization loop. Scalarization loop variables and precalculated scalar
64 values are automatically substituted. Note that gfc_advance_se_ss_chain
65 must be used, rather than changing the se->ss directly.
66
67 For assignment expressions requiring a temporary two sub loops are
68 generated. The first stores the result of the expression in the temporary,
69 the second copies it to the result. A call to
70 gfc_trans_scalarized_loop_boundary marks the end of the main loop code and
71 the start of the copying loop. The temporary may be less than full rank.
72
73 Finally gfc_trans_scalarizing_loops is called to generate the implicit do
74 loops. The loops are added to the pre chain of the loopinfo. The post
75 chain may still contain cleanup code.
76
77 After the loop code has been added into its parent scope gfc_cleanup_loop
78 is called to free all the SS allocated by the scalarizer. */
79
80 #include "config.h"
81 #include "system.h"
82 #include "coretypes.h"
83 #include "tree.h"
84 #include "tree-gimple.h"
85 #include "ggc.h"
86 #include "toplev.h"
87 #include "real.h"
88 #include "flags.h"
89 #include "gfortran.h"
90 #include "trans.h"
91 #include "trans-stmt.h"
92 #include "trans-types.h"
93 #include "trans-array.h"
94 #include "trans-const.h"
95 #include "dependency.h"
96
97 static gfc_ss *gfc_walk_subexpr (gfc_ss *, gfc_expr *);
98 static bool gfc_get_array_constructor_size (mpz_t *, gfc_constructor *);
99
100 /* The contents of this structure aren't actually used, just the address. */
101 static gfc_ss gfc_ss_terminator_var;
102 gfc_ss * const gfc_ss_terminator = &gfc_ss_terminator_var;
103
104
105 static tree
106 gfc_array_dataptr_type (tree desc)
107 {
108 return (GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc)));
109 }
110
111
112 /* Build expressions to access the members of an array descriptor.
113 It's surprisingly easy to mess up here, so never access
114 an array descriptor by "brute force", always use these
115 functions. This also avoids problems if we change the format
116 of an array descriptor.
117
118 To understand these magic numbers, look at the comments
119 before gfc_build_array_type() in trans-types.c.
120
121 The code within these defines should be the only code which knows the format
122 of an array descriptor.
123
124 Any code just needing to read obtain the bounds of an array should use
125 gfc_conv_array_* rather than the following functions as these will return
126 know constant values, and work with arrays which do not have descriptors.
127
128 Don't forget to #undef these! */
129
130 #define DATA_FIELD 0
131 #define OFFSET_FIELD 1
132 #define DTYPE_FIELD 2
133 #define DIMENSION_FIELD 3
134
135 #define STRIDE_SUBFIELD 0
136 #define LBOUND_SUBFIELD 1
137 #define UBOUND_SUBFIELD 2
138
139 /* This provides READ-ONLY access to the data field. The field itself
140 doesn't have the proper type. */
141
142 tree
143 gfc_conv_descriptor_data_get (tree desc)
144 {
145 tree field, type, t;
146
147 type = TREE_TYPE (desc);
148 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
149
150 field = TYPE_FIELDS (type);
151 gcc_assert (DATA_FIELD == 0);
152
153 t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
154 t = fold_convert (GFC_TYPE_ARRAY_DATAPTR_TYPE (type), t);
155
156 return t;
157 }
158
159 /* This provides WRITE access to the data field. */
160
161 void
162 gfc_conv_descriptor_data_set (stmtblock_t *block, tree desc, tree value)
163 {
164 tree field, type, t;
165
166 type = TREE_TYPE (desc);
167 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
168
169 field = TYPE_FIELDS (type);
170 gcc_assert (DATA_FIELD == 0);
171
172 t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
173 gfc_add_modify_expr (block, t, fold_convert (TREE_TYPE (field), value));
174 }
175
176
177 /* This provides address access to the data field. This should only be
178 used by array allocation, passing this on to the runtime. */
179
180 tree
181 gfc_conv_descriptor_data_addr (tree desc)
182 {
183 tree field, type, t;
184
185 type = TREE_TYPE (desc);
186 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
187
188 field = TYPE_FIELDS (type);
189 gcc_assert (DATA_FIELD == 0);
190
191 t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
192 return build_fold_addr_expr (t);
193 }
194
195 tree
196 gfc_conv_descriptor_offset (tree desc)
197 {
198 tree type;
199 tree field;
200
201 type = TREE_TYPE (desc);
202 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
203
204 field = gfc_advance_chain (TYPE_FIELDS (type), OFFSET_FIELD);
205 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
206
207 return build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
208 }
209
210 tree
211 gfc_conv_descriptor_dtype (tree desc)
212 {
213 tree field;
214 tree type;
215
216 type = TREE_TYPE (desc);
217 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
218
219 field = gfc_advance_chain (TYPE_FIELDS (type), DTYPE_FIELD);
220 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
221
222 return build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
223 }
224
225 static tree
226 gfc_conv_descriptor_dimension (tree desc, tree dim)
227 {
228 tree field;
229 tree type;
230 tree tmp;
231
232 type = TREE_TYPE (desc);
233 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
234
235 field = gfc_advance_chain (TYPE_FIELDS (type), DIMENSION_FIELD);
236 gcc_assert (field != NULL_TREE
237 && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
238 && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE);
239
240 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
241 tmp = gfc_build_array_ref (tmp, dim);
242 return tmp;
243 }
244
245 tree
246 gfc_conv_descriptor_stride (tree desc, tree dim)
247 {
248 tree tmp;
249 tree field;
250
251 tmp = gfc_conv_descriptor_dimension (desc, dim);
252 field = TYPE_FIELDS (TREE_TYPE (tmp));
253 field = gfc_advance_chain (field, STRIDE_SUBFIELD);
254 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
255
256 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
257 return tmp;
258 }
259
260 tree
261 gfc_conv_descriptor_lbound (tree desc, tree dim)
262 {
263 tree tmp;
264 tree field;
265
266 tmp = gfc_conv_descriptor_dimension (desc, dim);
267 field = TYPE_FIELDS (TREE_TYPE (tmp));
268 field = gfc_advance_chain (field, LBOUND_SUBFIELD);
269 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
270
271 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
272 return tmp;
273 }
274
275 tree
276 gfc_conv_descriptor_ubound (tree desc, tree dim)
277 {
278 tree tmp;
279 tree field;
280
281 tmp = gfc_conv_descriptor_dimension (desc, dim);
282 field = TYPE_FIELDS (TREE_TYPE (tmp));
283 field = gfc_advance_chain (field, UBOUND_SUBFIELD);
284 gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
285
286 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
287 return tmp;
288 }
289
290
291 /* Build a null array descriptor constructor. */
292
293 tree
294 gfc_build_null_descriptor (tree type)
295 {
296 tree field;
297 tree tmp;
298
299 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
300 gcc_assert (DATA_FIELD == 0);
301 field = TYPE_FIELDS (type);
302
303 /* Set a NULL data pointer. */
304 tmp = build_constructor_single (type, field, null_pointer_node);
305 TREE_CONSTANT (tmp) = 1;
306 TREE_INVARIANT (tmp) = 1;
307 /* All other fields are ignored. */
308
309 return tmp;
310 }
311
312
313 /* Cleanup those #defines. */
314
315 #undef DATA_FIELD
316 #undef OFFSET_FIELD
317 #undef DTYPE_FIELD
318 #undef DIMENSION_FIELD
319 #undef STRIDE_SUBFIELD
320 #undef LBOUND_SUBFIELD
321 #undef UBOUND_SUBFIELD
322
323
324 /* Mark a SS chain as used. Flags specifies in which loops the SS is used.
325 flags & 1 = Main loop body.
326 flags & 2 = temp copy loop. */
327
328 void
329 gfc_mark_ss_chain_used (gfc_ss * ss, unsigned flags)
330 {
331 for (; ss != gfc_ss_terminator; ss = ss->next)
332 ss->useflags = flags;
333 }
334
335 static void gfc_free_ss (gfc_ss *);
336
337
338 /* Free a gfc_ss chain. */
339
340 static void
341 gfc_free_ss_chain (gfc_ss * ss)
342 {
343 gfc_ss *next;
344
345 while (ss != gfc_ss_terminator)
346 {
347 gcc_assert (ss != NULL);
348 next = ss->next;
349 gfc_free_ss (ss);
350 ss = next;
351 }
352 }
353
354
355 /* Free a SS. */
356
357 static void
358 gfc_free_ss (gfc_ss * ss)
359 {
360 int n;
361
362 switch (ss->type)
363 {
364 case GFC_SS_SECTION:
365 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
366 {
367 if (ss->data.info.subscript[n])
368 gfc_free_ss_chain (ss->data.info.subscript[n]);
369 }
370 break;
371
372 default:
373 break;
374 }
375
376 gfc_free (ss);
377 }
378
379
380 /* Free all the SS associated with a loop. */
381
382 void
383 gfc_cleanup_loop (gfc_loopinfo * loop)
384 {
385 gfc_ss *ss;
386 gfc_ss *next;
387
388 ss = loop->ss;
389 while (ss != gfc_ss_terminator)
390 {
391 gcc_assert (ss != NULL);
392 next = ss->loop_chain;
393 gfc_free_ss (ss);
394 ss = next;
395 }
396 }
397
398
399 /* Associate a SS chain with a loop. */
400
401 void
402 gfc_add_ss_to_loop (gfc_loopinfo * loop, gfc_ss * head)
403 {
404 gfc_ss *ss;
405
406 if (head == gfc_ss_terminator)
407 return;
408
409 ss = head;
410 for (; ss && ss != gfc_ss_terminator; ss = ss->next)
411 {
412 if (ss->next == gfc_ss_terminator)
413 ss->loop_chain = loop->ss;
414 else
415 ss->loop_chain = ss->next;
416 }
417 gcc_assert (ss == gfc_ss_terminator);
418 loop->ss = head;
419 }
420
421
422 /* Generate an initializer for a static pointer or allocatable array. */
423
424 void
425 gfc_trans_static_array_pointer (gfc_symbol * sym)
426 {
427 tree type;
428
429 gcc_assert (TREE_STATIC (sym->backend_decl));
430 /* Just zero the data member. */
431 type = TREE_TYPE (sym->backend_decl);
432 DECL_INITIAL (sym->backend_decl) = gfc_build_null_descriptor (type);
433 }
434
435
436 /* If the bounds of SE's loop have not yet been set, see if they can be
437 determined from array spec AS, which is the array spec of a called
438 function. MAPPING maps the callee's dummy arguments to the values
439 that the caller is passing. Add any initialization and finalization
440 code to SE. */
441
442 void
443 gfc_set_loop_bounds_from_array_spec (gfc_interface_mapping * mapping,
444 gfc_se * se, gfc_array_spec * as)
445 {
446 int n, dim;
447 gfc_se tmpse;
448 tree lower;
449 tree upper;
450 tree tmp;
451
452 if (as && as->type == AS_EXPLICIT)
453 for (dim = 0; dim < se->loop->dimen; dim++)
454 {
455 n = se->loop->order[dim];
456 if (se->loop->to[n] == NULL_TREE)
457 {
458 /* Evaluate the lower bound. */
459 gfc_init_se (&tmpse, NULL);
460 gfc_apply_interface_mapping (mapping, &tmpse, as->lower[dim]);
461 gfc_add_block_to_block (&se->pre, &tmpse.pre);
462 gfc_add_block_to_block (&se->post, &tmpse.post);
463 lower = tmpse.expr;
464
465 /* ...and the upper bound. */
466 gfc_init_se (&tmpse, NULL);
467 gfc_apply_interface_mapping (mapping, &tmpse, as->upper[dim]);
468 gfc_add_block_to_block (&se->pre, &tmpse.pre);
469 gfc_add_block_to_block (&se->post, &tmpse.post);
470 upper = tmpse.expr;
471
472 /* Set the upper bound of the loop to UPPER - LOWER. */
473 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, upper, lower);
474 tmp = gfc_evaluate_now (tmp, &se->pre);
475 se->loop->to[n] = tmp;
476 }
477 }
478 }
479
480
481 /* Generate code to allocate an array temporary, or create a variable to
482 hold the data. If size is NULL zero the descriptor so that so that the
483 callee will allocate the array. Also generates code to free the array
484 afterwards.
485
486 Initialization code is added to PRE and finalization code to POST.
487 DYNAMIC is true if the caller may want to extend the array later
488 using realloc. This prevents us from putting the array on the stack. */
489
490 static void
491 gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
492 gfc_ss_info * info, tree size, tree nelem,
493 bool dynamic)
494 {
495 tree tmp;
496 tree args;
497 tree desc;
498 bool onstack;
499
500 desc = info->descriptor;
501 info->offset = gfc_index_zero_node;
502 if (size == NULL_TREE || integer_zerop (size))
503 {
504 /* A callee allocated array. */
505 gfc_conv_descriptor_data_set (pre, desc, null_pointer_node);
506 onstack = FALSE;
507 }
508 else
509 {
510 /* Allocate the temporary. */
511 onstack = !dynamic && gfc_can_put_var_on_stack (size);
512
513 if (onstack)
514 {
515 /* Make a temporary variable to hold the data. */
516 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (nelem), nelem,
517 integer_one_node);
518 tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
519 tmp);
520 tmp = build_array_type (gfc_get_element_type (TREE_TYPE (desc)),
521 tmp);
522 tmp = gfc_create_var (tmp, "A");
523 tmp = build_fold_addr_expr (tmp);
524 gfc_conv_descriptor_data_set (pre, desc, tmp);
525 }
526 else
527 {
528 /* Allocate memory to hold the data. */
529 args = gfc_chainon_list (NULL_TREE, size);
530
531 if (gfc_index_integer_kind == 4)
532 tmp = gfor_fndecl_internal_malloc;
533 else if (gfc_index_integer_kind == 8)
534 tmp = gfor_fndecl_internal_malloc64;
535 else
536 gcc_unreachable ();
537 tmp = build_function_call_expr (tmp, args);
538 tmp = gfc_evaluate_now (tmp, pre);
539 gfc_conv_descriptor_data_set (pre, desc, tmp);
540 }
541 }
542 info->data = gfc_conv_descriptor_data_get (desc);
543
544 /* The offset is zero because we create temporaries with a zero
545 lower bound. */
546 tmp = gfc_conv_descriptor_offset (desc);
547 gfc_add_modify_expr (pre, tmp, gfc_index_zero_node);
548
549 if (!onstack)
550 {
551 /* Free the temporary. */
552 tmp = gfc_conv_descriptor_data_get (desc);
553 tmp = fold_convert (pvoid_type_node, tmp);
554 tmp = gfc_chainon_list (NULL_TREE, tmp);
555 tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
556 gfc_add_expr_to_block (post, tmp);
557 }
558 }
559
560
561 /* Generate code to allocate and initialize the descriptor for a temporary
562 array. This is used for both temporaries needed by the scalarizer, and
563 functions returning arrays. Adjusts the loop variables to be zero-based,
564 and calculates the loop bounds for callee allocated arrays.
565 Also fills in the descriptor, data and offset fields of info if known.
566 Returns the size of the array, or NULL for a callee allocated array.
567
568 PRE, POST and DYNAMIC are as for gfc_trans_allocate_array_storage. */
569
570 tree
571 gfc_trans_allocate_temp_array (stmtblock_t * pre, stmtblock_t * post,
572 gfc_loopinfo * loop, gfc_ss_info * info,
573 tree eltype, bool dynamic)
574 {
575 tree type;
576 tree desc;
577 tree tmp;
578 tree size;
579 tree nelem;
580 int n;
581 int dim;
582
583 gcc_assert (info->dimen > 0);
584 /* Set the lower bound to zero. */
585 for (dim = 0; dim < info->dimen; dim++)
586 {
587 n = loop->order[dim];
588 if (n < loop->temp_dim)
589 gcc_assert (integer_zerop (loop->from[n]));
590 else
591 {
592 /* Callee allocated arrays may not have a known bound yet. */
593 if (loop->to[n])
594 loop->to[n] = fold_build2 (MINUS_EXPR, gfc_array_index_type,
595 loop->to[n], loop->from[n]);
596 loop->from[n] = gfc_index_zero_node;
597 }
598
599 info->delta[dim] = gfc_index_zero_node;
600 info->start[dim] = gfc_index_zero_node;
601 info->stride[dim] = gfc_index_one_node;
602 info->dim[dim] = dim;
603 }
604
605 /* Initialize the descriptor. */
606 type =
607 gfc_get_array_type_bounds (eltype, info->dimen, loop->from, loop->to, 1);
608 desc = gfc_create_var (type, "atmp");
609 GFC_DECL_PACKED_ARRAY (desc) = 1;
610
611 info->descriptor = desc;
612 size = gfc_index_one_node;
613
614 /* Fill in the array dtype. */
615 tmp = gfc_conv_descriptor_dtype (desc);
616 gfc_add_modify_expr (pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
617
618 /*
619 Fill in the bounds and stride. This is a packed array, so:
620
621 size = 1;
622 for (n = 0; n < rank; n++)
623 {
624 stride[n] = size
625 delta = ubound[n] + 1 - lbound[n];
626 size = size * delta;
627 }
628 size = size * sizeof(element);
629 */
630
631 for (n = 0; n < info->dimen; n++)
632 {
633 if (loop->to[n] == NULL_TREE)
634 {
635 /* For a callee allocated array express the loop bounds in terms
636 of the descriptor fields. */
637 tmp = build2 (MINUS_EXPR, gfc_array_index_type,
638 gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]),
639 gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]));
640 loop->to[n] = tmp;
641 size = NULL_TREE;
642 continue;
643 }
644
645 /* Store the stride and bound components in the descriptor. */
646 tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[n]);
647 gfc_add_modify_expr (pre, tmp, size);
648
649 tmp = gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]);
650 gfc_add_modify_expr (pre, tmp, gfc_index_zero_node);
651
652 tmp = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]);
653 gfc_add_modify_expr (pre, tmp, loop->to[n]);
654
655 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
656 loop->to[n], gfc_index_one_node);
657
658 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
659 size = gfc_evaluate_now (size, pre);
660 }
661
662 /* Get the size of the array. */
663 nelem = size;
664 if (size)
665 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
666 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
667
668 gfc_trans_allocate_array_storage (pre, post, info, size, nelem, dynamic);
669
670 if (info->dimen > loop->temp_dim)
671 loop->temp_dim = info->dimen;
672
673 return size;
674 }
675
676
677 /* Generate code to transpose array EXPR by creating a new descriptor
678 in which the dimension specifications have been reversed. */
679
680 void
681 gfc_conv_array_transpose (gfc_se * se, gfc_expr * expr)
682 {
683 tree dest, src, dest_index, src_index;
684 gfc_loopinfo *loop;
685 gfc_ss_info *dest_info, *src_info;
686 gfc_ss *dest_ss, *src_ss;
687 gfc_se src_se;
688 int n;
689
690 loop = se->loop;
691
692 src_ss = gfc_walk_expr (expr);
693 dest_ss = se->ss;
694
695 src_info = &src_ss->data.info;
696 dest_info = &dest_ss->data.info;
697
698 /* Get a descriptor for EXPR. */
699 gfc_init_se (&src_se, NULL);
700 gfc_conv_expr_descriptor (&src_se, expr, src_ss);
701 gfc_add_block_to_block (&se->pre, &src_se.pre);
702 gfc_add_block_to_block (&se->post, &src_se.post);
703 src = src_se.expr;
704
705 /* Allocate a new descriptor for the return value. */
706 dest = gfc_create_var (TREE_TYPE (src), "atmp");
707 dest_info->descriptor = dest;
708 se->expr = dest;
709
710 /* Copy across the dtype field. */
711 gfc_add_modify_expr (&se->pre,
712 gfc_conv_descriptor_dtype (dest),
713 gfc_conv_descriptor_dtype (src));
714
715 /* Copy the dimension information, renumbering dimension 1 to 0 and
716 0 to 1. */
717 gcc_assert (dest_info->dimen == 2);
718 gcc_assert (src_info->dimen == 2);
719 for (n = 0; n < 2; n++)
720 {
721 dest_info->delta[n] = integer_zero_node;
722 dest_info->start[n] = integer_zero_node;
723 dest_info->stride[n] = integer_one_node;
724 dest_info->dim[n] = n;
725
726 dest_index = gfc_rank_cst[n];
727 src_index = gfc_rank_cst[1 - n];
728
729 gfc_add_modify_expr (&se->pre,
730 gfc_conv_descriptor_stride (dest, dest_index),
731 gfc_conv_descriptor_stride (src, src_index));
732
733 gfc_add_modify_expr (&se->pre,
734 gfc_conv_descriptor_lbound (dest, dest_index),
735 gfc_conv_descriptor_lbound (src, src_index));
736
737 gfc_add_modify_expr (&se->pre,
738 gfc_conv_descriptor_ubound (dest, dest_index),
739 gfc_conv_descriptor_ubound (src, src_index));
740
741 if (!loop->to[n])
742 {
743 gcc_assert (integer_zerop (loop->from[n]));
744 loop->to[n] = build2 (MINUS_EXPR, gfc_array_index_type,
745 gfc_conv_descriptor_ubound (dest, dest_index),
746 gfc_conv_descriptor_lbound (dest, dest_index));
747 }
748 }
749
750 /* Copy the data pointer. */
751 dest_info->data = gfc_conv_descriptor_data_get (src);
752 gfc_conv_descriptor_data_set (&se->pre, dest, dest_info->data);
753
754 /* Copy the offset. This is not changed by transposition: the top-left
755 element is still at the same offset as before. */
756 dest_info->offset = gfc_conv_descriptor_offset (src);
757 gfc_add_modify_expr (&se->pre,
758 gfc_conv_descriptor_offset (dest),
759 dest_info->offset);
760
761 if (dest_info->dimen > loop->temp_dim)
762 loop->temp_dim = dest_info->dimen;
763 }
764
765
766 /* Return the number of iterations in a loop that starts at START,
767 ends at END, and has step STEP. */
768
769 static tree
770 gfc_get_iteration_count (tree start, tree end, tree step)
771 {
772 tree tmp;
773 tree type;
774
775 type = TREE_TYPE (step);
776 tmp = fold_build2 (MINUS_EXPR, type, end, start);
777 tmp = fold_build2 (FLOOR_DIV_EXPR, type, tmp, step);
778 tmp = fold_build2 (PLUS_EXPR, type, tmp, build_int_cst (type, 1));
779 tmp = fold_build2 (MAX_EXPR, type, tmp, build_int_cst (type, 0));
780 return fold_convert (gfc_array_index_type, tmp);
781 }
782
783
784 /* Extend the data in array DESC by EXTRA elements. */
785
786 static void
787 gfc_grow_array (stmtblock_t * pblock, tree desc, tree extra)
788 {
789 tree args;
790 tree tmp;
791 tree size;
792 tree ubound;
793
794 if (integer_zerop (extra))
795 return;
796
797 ubound = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[0]);
798
799 /* Add EXTRA to the upper bound. */
800 tmp = build2 (PLUS_EXPR, gfc_array_index_type, ubound, extra);
801 gfc_add_modify_expr (pblock, ubound, tmp);
802
803 /* Get the value of the current data pointer. */
804 tmp = gfc_conv_descriptor_data_get (desc);
805 args = gfc_chainon_list (NULL_TREE, tmp);
806
807 /* Calculate the new array size. */
808 size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
809 tmp = build2 (PLUS_EXPR, gfc_array_index_type, ubound, gfc_index_one_node);
810 tmp = build2 (MULT_EXPR, gfc_array_index_type, tmp, size);
811 args = gfc_chainon_list (args, tmp);
812
813 /* Pick the appropriate realloc function. */
814 if (gfc_index_integer_kind == 4)
815 tmp = gfor_fndecl_internal_realloc;
816 else if (gfc_index_integer_kind == 8)
817 tmp = gfor_fndecl_internal_realloc64;
818 else
819 gcc_unreachable ();
820
821 /* Set the new data pointer. */
822 tmp = build_function_call_expr (tmp, args);
823 gfc_conv_descriptor_data_set (pblock, desc, tmp);
824 }
825
826
827 /* Return true if the bounds of iterator I can only be determined
828 at run time. */
829
830 static inline bool
831 gfc_iterator_has_dynamic_bounds (gfc_iterator * i)
832 {
833 return (i->start->expr_type != EXPR_CONSTANT
834 || i->end->expr_type != EXPR_CONSTANT
835 || i->step->expr_type != EXPR_CONSTANT);
836 }
837
838
839 /* Split the size of constructor element EXPR into the sum of two terms,
840 one of which can be determined at compile time and one of which must
841 be calculated at run time. Set *SIZE to the former and return true
842 if the latter might be nonzero. */
843
844 static bool
845 gfc_get_array_constructor_element_size (mpz_t * size, gfc_expr * expr)
846 {
847 if (expr->expr_type == EXPR_ARRAY)
848 return gfc_get_array_constructor_size (size, expr->value.constructor);
849 else if (expr->rank > 0)
850 {
851 /* Calculate everything at run time. */
852 mpz_set_ui (*size, 0);
853 return true;
854 }
855 else
856 {
857 /* A single element. */
858 mpz_set_ui (*size, 1);
859 return false;
860 }
861 }
862
863
864 /* Like gfc_get_array_constructor_element_size, but applied to the whole
865 of array constructor C. */
866
867 static bool
868 gfc_get_array_constructor_size (mpz_t * size, gfc_constructor * c)
869 {
870 gfc_iterator *i;
871 mpz_t val;
872 mpz_t len;
873 bool dynamic;
874
875 mpz_set_ui (*size, 0);
876 mpz_init (len);
877 mpz_init (val);
878
879 dynamic = false;
880 for (; c; c = c->next)
881 {
882 i = c->iterator;
883 if (i && gfc_iterator_has_dynamic_bounds (i))
884 dynamic = true;
885 else
886 {
887 dynamic |= gfc_get_array_constructor_element_size (&len, c->expr);
888 if (i)
889 {
890 /* Multiply the static part of the element size by the
891 number of iterations. */
892 mpz_sub (val, i->end->value.integer, i->start->value.integer);
893 mpz_fdiv_q (val, val, i->step->value.integer);
894 mpz_add_ui (val, val, 1);
895 if (mpz_sgn (val) > 0)
896 mpz_mul (len, len, val);
897 else
898 mpz_set_ui (len, 0);
899 }
900 mpz_add (*size, *size, len);
901 }
902 }
903 mpz_clear (len);
904 mpz_clear (val);
905 return dynamic;
906 }
907
908
909 /* Make sure offset is a variable. */
910
911 static void
912 gfc_put_offset_into_var (stmtblock_t * pblock, tree * poffset,
913 tree * offsetvar)
914 {
915 /* We should have already created the offset variable. We cannot
916 create it here because we may be in an inner scope. */
917 gcc_assert (*offsetvar != NULL_TREE);
918 gfc_add_modify_expr (pblock, *offsetvar, *poffset);
919 *poffset = *offsetvar;
920 TREE_USED (*offsetvar) = 1;
921 }
922
923
924 /* Assign an element of an array constructor. */
925
926 static void
927 gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc,
928 tree offset, gfc_se * se, gfc_expr * expr)
929 {
930 tree tmp;
931 tree args;
932
933 gfc_conv_expr (se, expr);
934
935 /* Store the value. */
936 tmp = build_fold_indirect_ref (gfc_conv_descriptor_data_get (desc));
937 tmp = gfc_build_array_ref (tmp, offset);
938 if (expr->ts.type == BT_CHARACTER)
939 {
940 gfc_conv_string_parameter (se);
941 if (POINTER_TYPE_P (TREE_TYPE (tmp)))
942 {
943 /* The temporary is an array of pointers. */
944 se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
945 gfc_add_modify_expr (&se->pre, tmp, se->expr);
946 }
947 else
948 {
949 /* The temporary is an array of string values. */
950 tmp = gfc_build_addr_expr (pchar_type_node, tmp);
951 /* We know the temporary and the value will be the same length,
952 so can use memcpy. */
953 args = gfc_chainon_list (NULL_TREE, tmp);
954 args = gfc_chainon_list (args, se->expr);
955 args = gfc_chainon_list (args, se->string_length);
956 tmp = built_in_decls[BUILT_IN_MEMCPY];
957 tmp = build_function_call_expr (tmp, args);
958 gfc_add_expr_to_block (&se->pre, tmp);
959 }
960 }
961 else
962 {
963 /* TODO: Should the frontend already have done this conversion? */
964 se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
965 gfc_add_modify_expr (&se->pre, tmp, se->expr);
966 }
967
968 gfc_add_block_to_block (pblock, &se->pre);
969 gfc_add_block_to_block (pblock, &se->post);
970 }
971
972
973 /* Add the contents of an array to the constructor. DYNAMIC is as for
974 gfc_trans_array_constructor_value. */
975
976 static void
977 gfc_trans_array_constructor_subarray (stmtblock_t * pblock,
978 tree type ATTRIBUTE_UNUSED,
979 tree desc, gfc_expr * expr,
980 tree * poffset, tree * offsetvar,
981 bool dynamic)
982 {
983 gfc_se se;
984 gfc_ss *ss;
985 gfc_loopinfo loop;
986 stmtblock_t body;
987 tree tmp;
988 tree size;
989 int n;
990
991 /* We need this to be a variable so we can increment it. */
992 gfc_put_offset_into_var (pblock, poffset, offsetvar);
993
994 gfc_init_se (&se, NULL);
995
996 /* Walk the array expression. */
997 ss = gfc_walk_expr (expr);
998 gcc_assert (ss != gfc_ss_terminator);
999
1000 /* Initialize the scalarizer. */
1001 gfc_init_loopinfo (&loop);
1002 gfc_add_ss_to_loop (&loop, ss);
1003
1004 /* Initialize the loop. */
1005 gfc_conv_ss_startstride (&loop);
1006 gfc_conv_loop_setup (&loop);
1007
1008 /* Make sure the constructed array has room for the new data. */
1009 if (dynamic)
1010 {
1011 /* Set SIZE to the total number of elements in the subarray. */
1012 size = gfc_index_one_node;
1013 for (n = 0; n < loop.dimen; n++)
1014 {
1015 tmp = gfc_get_iteration_count (loop.from[n], loop.to[n],
1016 gfc_index_one_node);
1017 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
1018 }
1019
1020 /* Grow the constructed array by SIZE elements. */
1021 gfc_grow_array (&loop.pre, desc, size);
1022 }
1023
1024 /* Make the loop body. */
1025 gfc_mark_ss_chain_used (ss, 1);
1026 gfc_start_scalarized_body (&loop, &body);
1027 gfc_copy_loopinfo_to_se (&se, &loop);
1028 se.ss = ss;
1029
1030 if (expr->ts.type == BT_CHARACTER)
1031 gfc_todo_error ("character arrays in constructors");
1032
1033 gfc_trans_array_ctor_element (&body, desc, *poffset, &se, expr);
1034 gcc_assert (se.ss == gfc_ss_terminator);
1035
1036 /* Increment the offset. */
1037 tmp = build2 (PLUS_EXPR, gfc_array_index_type, *poffset, gfc_index_one_node);
1038 gfc_add_modify_expr (&body, *poffset, tmp);
1039
1040 /* Finish the loop. */
1041 gfc_trans_scalarizing_loops (&loop, &body);
1042 gfc_add_block_to_block (&loop.pre, &loop.post);
1043 tmp = gfc_finish_block (&loop.pre);
1044 gfc_add_expr_to_block (pblock, tmp);
1045
1046 gfc_cleanup_loop (&loop);
1047 }
1048
1049
1050 /* Assign the values to the elements of an array constructor. DYNAMIC
1051 is true if descriptor DESC only contains enough data for the static
1052 size calculated by gfc_get_array_constructor_size. When true, memory
1053 for the dynamic parts must be allocated using realloc. */
1054
1055 static void
1056 gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
1057 tree desc, gfc_constructor * c,
1058 tree * poffset, tree * offsetvar,
1059 bool dynamic)
1060 {
1061 tree tmp;
1062 stmtblock_t body;
1063 gfc_se se;
1064 mpz_t size;
1065
1066 mpz_init (size);
1067 for (; c; c = c->next)
1068 {
1069 /* If this is an iterator or an array, the offset must be a variable. */
1070 if ((c->iterator || c->expr->rank > 0) && INTEGER_CST_P (*poffset))
1071 gfc_put_offset_into_var (pblock, poffset, offsetvar);
1072
1073 gfc_start_block (&body);
1074
1075 if (c->expr->expr_type == EXPR_ARRAY)
1076 {
1077 /* Array constructors can be nested. */
1078 gfc_trans_array_constructor_value (&body, type, desc,
1079 c->expr->value.constructor,
1080 poffset, offsetvar, dynamic);
1081 }
1082 else if (c->expr->rank > 0)
1083 {
1084 gfc_trans_array_constructor_subarray (&body, type, desc, c->expr,
1085 poffset, offsetvar, dynamic);
1086 }
1087 else
1088 {
1089 /* This code really upsets the gimplifier so don't bother for now. */
1090 gfc_constructor *p;
1091 HOST_WIDE_INT n;
1092 HOST_WIDE_INT size;
1093
1094 p = c;
1095 n = 0;
1096 while (p && !(p->iterator || p->expr->expr_type != EXPR_CONSTANT))
1097 {
1098 p = p->next;
1099 n++;
1100 }
1101 if (n < 4)
1102 {
1103 /* Scalar values. */
1104 gfc_init_se (&se, NULL);
1105 gfc_trans_array_ctor_element (&body, desc, *poffset,
1106 &se, c->expr);
1107
1108 *poffset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1109 *poffset, gfc_index_one_node);
1110 }
1111 else
1112 {
1113 /* Collect multiple scalar constants into a constructor. */
1114 tree list;
1115 tree init;
1116 tree bound;
1117 tree tmptype;
1118
1119 p = c;
1120 list = NULL_TREE;
1121 /* Count the number of consecutive scalar constants. */
1122 while (p && !(p->iterator
1123 || p->expr->expr_type != EXPR_CONSTANT))
1124 {
1125 gfc_init_se (&se, NULL);
1126 gfc_conv_constant (&se, p->expr);
1127 if (p->expr->ts.type == BT_CHARACTER
1128 && POINTER_TYPE_P (type))
1129 {
1130 /* For constant character array constructors we build
1131 an array of pointers. */
1132 se.expr = gfc_build_addr_expr (pchar_type_node,
1133 se.expr);
1134 }
1135
1136 list = tree_cons (NULL_TREE, se.expr, list);
1137 c = p;
1138 p = p->next;
1139 }
1140
1141 bound = build_int_cst (NULL_TREE, n - 1);
1142 /* Create an array type to hold them. */
1143 tmptype = build_range_type (gfc_array_index_type,
1144 gfc_index_zero_node, bound);
1145 tmptype = build_array_type (type, tmptype);
1146
1147 init = build_constructor_from_list (tmptype, nreverse (list));
1148 TREE_CONSTANT (init) = 1;
1149 TREE_INVARIANT (init) = 1;
1150 TREE_STATIC (init) = 1;
1151 /* Create a static variable to hold the data. */
1152 tmp = gfc_create_var (tmptype, "data");
1153 TREE_STATIC (tmp) = 1;
1154 TREE_CONSTANT (tmp) = 1;
1155 TREE_INVARIANT (tmp) = 1;
1156 DECL_INITIAL (tmp) = init;
1157 init = tmp;
1158
1159 /* Use BUILTIN_MEMCPY to assign the values. */
1160 tmp = gfc_conv_descriptor_data_get (desc);
1161 tmp = build_fold_indirect_ref (tmp);
1162 tmp = gfc_build_array_ref (tmp, *poffset);
1163 tmp = build_fold_addr_expr (tmp);
1164 init = build_fold_addr_expr (init);
1165
1166 size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
1167 bound = build_int_cst (NULL_TREE, n * size);
1168 tmp = gfc_chainon_list (NULL_TREE, tmp);
1169 tmp = gfc_chainon_list (tmp, init);
1170 tmp = gfc_chainon_list (tmp, bound);
1171 tmp = build_function_call_expr (built_in_decls[BUILT_IN_MEMCPY],
1172 tmp);
1173 gfc_add_expr_to_block (&body, tmp);
1174
1175 *poffset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1176 *poffset, build_int_cst (NULL_TREE, n));
1177 }
1178 if (!INTEGER_CST_P (*poffset))
1179 {
1180 gfc_add_modify_expr (&body, *offsetvar, *poffset);
1181 *poffset = *offsetvar;
1182 }
1183 }
1184
1185 /* The frontend should already have done any expansions possible
1186 at compile-time. */
1187 if (!c->iterator)
1188 {
1189 /* Pass the code as is. */
1190 tmp = gfc_finish_block (&body);
1191 gfc_add_expr_to_block (pblock, tmp);
1192 }
1193 else
1194 {
1195 /* Build the implied do-loop. */
1196 tree cond;
1197 tree end;
1198 tree step;
1199 tree loopvar;
1200 tree exit_label;
1201 tree loopbody;
1202 tree tmp2;
1203
1204 loopbody = gfc_finish_block (&body);
1205
1206 gfc_init_se (&se, NULL);
1207 gfc_conv_expr (&se, c->iterator->var);
1208 gfc_add_block_to_block (pblock, &se.pre);
1209 loopvar = se.expr;
1210
1211 /* Initialize the loop. */
1212 gfc_init_se (&se, NULL);
1213 gfc_conv_expr_val (&se, c->iterator->start);
1214 gfc_add_block_to_block (pblock, &se.pre);
1215 gfc_add_modify_expr (pblock, loopvar, se.expr);
1216
1217 gfc_init_se (&se, NULL);
1218 gfc_conv_expr_val (&se, c->iterator->end);
1219 gfc_add_block_to_block (pblock, &se.pre);
1220 end = gfc_evaluate_now (se.expr, pblock);
1221
1222 gfc_init_se (&se, NULL);
1223 gfc_conv_expr_val (&se, c->iterator->step);
1224 gfc_add_block_to_block (pblock, &se.pre);
1225 step = gfc_evaluate_now (se.expr, pblock);
1226
1227 /* If this array expands dynamically, and the number of iterations
1228 is not constant, we won't have allocated space for the static
1229 part of C->EXPR's size. Do that now. */
1230 if (dynamic && gfc_iterator_has_dynamic_bounds (c->iterator))
1231 {
1232 /* Get the number of iterations. */
1233 tmp = gfc_get_iteration_count (loopvar, end, step);
1234
1235 /* Get the static part of C->EXPR's size. */
1236 gfc_get_array_constructor_element_size (&size, c->expr);
1237 tmp2 = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1238
1239 /* Grow the array by TMP * TMP2 elements. */
1240 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp, tmp2);
1241 gfc_grow_array (pblock, desc, tmp);
1242 }
1243
1244 /* Generate the loop body. */
1245 exit_label = gfc_build_label_decl (NULL_TREE);
1246 gfc_start_block (&body);
1247
1248 /* Generate the exit condition. Depending on the sign of
1249 the step variable we have to generate the correct
1250 comparison. */
1251 tmp = fold_build2 (GT_EXPR, boolean_type_node, step,
1252 build_int_cst (TREE_TYPE (step), 0));
1253 cond = fold_build3 (COND_EXPR, boolean_type_node, tmp,
1254 build2 (GT_EXPR, boolean_type_node,
1255 loopvar, end),
1256 build2 (LT_EXPR, boolean_type_node,
1257 loopvar, end));
1258 tmp = build1_v (GOTO_EXPR, exit_label);
1259 TREE_USED (exit_label) = 1;
1260 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1261 gfc_add_expr_to_block (&body, tmp);
1262
1263 /* The main loop body. */
1264 gfc_add_expr_to_block (&body, loopbody);
1265
1266 /* Increase loop variable by step. */
1267 tmp = build2 (PLUS_EXPR, TREE_TYPE (loopvar), loopvar, step);
1268 gfc_add_modify_expr (&body, loopvar, tmp);
1269
1270 /* Finish the loop. */
1271 tmp = gfc_finish_block (&body);
1272 tmp = build1_v (LOOP_EXPR, tmp);
1273 gfc_add_expr_to_block (pblock, tmp);
1274
1275 /* Add the exit label. */
1276 tmp = build1_v (LABEL_EXPR, exit_label);
1277 gfc_add_expr_to_block (pblock, tmp);
1278 }
1279 }
1280 mpz_clear (size);
1281 }
1282
1283
1284 /* Figure out the string length of a variable reference expression.
1285 Used by get_array_ctor_strlen. */
1286
1287 static void
1288 get_array_ctor_var_strlen (gfc_expr * expr, tree * len)
1289 {
1290 gfc_ref *ref;
1291 gfc_typespec *ts;
1292
1293 /* Don't bother if we already know the length is a constant. */
1294 if (*len && INTEGER_CST_P (*len))
1295 return;
1296
1297 ts = &expr->symtree->n.sym->ts;
1298 for (ref = expr->ref; ref; ref = ref->next)
1299 {
1300 switch (ref->type)
1301 {
1302 case REF_ARRAY:
1303 /* Array references don't change the string length. */
1304 break;
1305
1306 case COMPONENT_REF:
1307 /* Use the length of the component. */
1308 ts = &ref->u.c.component->ts;
1309 break;
1310
1311 default:
1312 /* TODO: Substrings are tricky because we can't evaluate the
1313 expression more than once. For now we just give up, and hope
1314 we can figure it out elsewhere. */
1315 return;
1316 }
1317 }
1318
1319 *len = ts->cl->backend_decl;
1320 }
1321
1322
1323 /* Figure out the string length of a character array constructor.
1324 Returns TRUE if all elements are character constants. */
1325
1326 static bool
1327 get_array_ctor_strlen (gfc_constructor * c, tree * len)
1328 {
1329 bool is_const;
1330
1331 is_const = TRUE;
1332 for (; c; c = c->next)
1333 {
1334 switch (c->expr->expr_type)
1335 {
1336 case EXPR_CONSTANT:
1337 if (!(*len && INTEGER_CST_P (*len)))
1338 *len = build_int_cstu (gfc_charlen_type_node,
1339 c->expr->value.character.length);
1340 break;
1341
1342 case EXPR_ARRAY:
1343 if (!get_array_ctor_strlen (c->expr->value.constructor, len))
1344 is_const = FALSE;
1345 break;
1346
1347 case EXPR_VARIABLE:
1348 is_const = false;
1349 get_array_ctor_var_strlen (c->expr, len);
1350 break;
1351
1352 default:
1353 is_const = FALSE;
1354 /* TODO: For now we just ignore anything we don't know how to
1355 handle, and hope we can figure it out a different way. */
1356 break;
1357 }
1358 }
1359
1360 return is_const;
1361 }
1362
1363
1364 /* Array constructors are handled by constructing a temporary, then using that
1365 within the scalarization loop. This is not optimal, but seems by far the
1366 simplest method. */
1367
1368 static void
1369 gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss)
1370 {
1371 gfc_constructor *c;
1372 tree offset;
1373 tree offsetvar;
1374 tree desc;
1375 tree type;
1376 bool const_string;
1377 bool dynamic;
1378
1379 ss->data.info.dimen = loop->dimen;
1380
1381 c = ss->expr->value.constructor;
1382 if (ss->expr->ts.type == BT_CHARACTER)
1383 {
1384 const_string = get_array_ctor_strlen (c, &ss->string_length);
1385 if (!ss->string_length)
1386 gfc_todo_error ("complex character array constructors");
1387
1388 type = gfc_get_character_type_len (ss->expr->ts.kind, ss->string_length);
1389 if (const_string)
1390 type = build_pointer_type (type);
1391 }
1392 else
1393 {
1394 const_string = TRUE;
1395 type = gfc_typenode_for_spec (&ss->expr->ts);
1396 }
1397
1398 /* See if the constructor determines the loop bounds. */
1399 dynamic = false;
1400 if (loop->to[0] == NULL_TREE)
1401 {
1402 mpz_t size;
1403
1404 /* We should have a 1-dimensional, zero-based loop. */
1405 gcc_assert (loop->dimen == 1);
1406 gcc_assert (integer_zerop (loop->from[0]));
1407
1408 /* Split the constructor size into a static part and a dynamic part.
1409 Allocate the static size up-front and record whether the dynamic
1410 size might be nonzero. */
1411 mpz_init (size);
1412 dynamic = gfc_get_array_constructor_size (&size, c);
1413 mpz_sub_ui (size, size, 1);
1414 loop->to[0] = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1415 mpz_clear (size);
1416 }
1417
1418 gfc_trans_allocate_temp_array (&loop->pre, &loop->post, loop,
1419 &ss->data.info, type, dynamic);
1420
1421 desc = ss->data.info.descriptor;
1422 offset = gfc_index_zero_node;
1423 offsetvar = gfc_create_var_np (gfc_array_index_type, "offset");
1424 TREE_USED (offsetvar) = 0;
1425 gfc_trans_array_constructor_value (&loop->pre, type, desc, c,
1426 &offset, &offsetvar, dynamic);
1427
1428 /* If the array grows dynamically, the upper bound of the loop variable
1429 is determined by the array's final upper bound. */
1430 if (dynamic)
1431 loop->to[0] = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[0]);
1432
1433 if (TREE_USED (offsetvar))
1434 pushdecl (offsetvar);
1435 else
1436 gcc_assert (INTEGER_CST_P (offset));
1437 #if 0
1438 /* Disable bound checking for now because it's probably broken. */
1439 if (flag_bounds_check)
1440 {
1441 gcc_unreachable ();
1442 }
1443 #endif
1444 }
1445
1446
1447 /* INFO describes a GFC_SS_SECTION in loop LOOP, and this function is
1448 called after evaluating all of INFO's vector dimensions. Go through
1449 each such vector dimension and see if we can now fill in any missing
1450 loop bounds. */
1451
1452 static void
1453 gfc_set_vector_loop_bounds (gfc_loopinfo * loop, gfc_ss_info * info)
1454 {
1455 gfc_se se;
1456 tree tmp;
1457 tree desc;
1458 tree zero;
1459 int n;
1460 int dim;
1461
1462 for (n = 0; n < loop->dimen; n++)
1463 {
1464 dim = info->dim[n];
1465 if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR
1466 && loop->to[n] == NULL)
1467 {
1468 /* Loop variable N indexes vector dimension DIM, and we don't
1469 yet know the upper bound of loop variable N. Set it to the
1470 difference between the vector's upper and lower bounds. */
1471 gcc_assert (loop->from[n] == gfc_index_zero_node);
1472 gcc_assert (info->subscript[dim]
1473 && info->subscript[dim]->type == GFC_SS_VECTOR);
1474
1475 gfc_init_se (&se, NULL);
1476 desc = info->subscript[dim]->data.info.descriptor;
1477 zero = gfc_rank_cst[0];
1478 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1479 gfc_conv_descriptor_ubound (desc, zero),
1480 gfc_conv_descriptor_lbound (desc, zero));
1481 tmp = gfc_evaluate_now (tmp, &loop->pre);
1482 loop->to[n] = tmp;
1483 }
1484 }
1485 }
1486
1487
1488 /* Add the pre and post chains for all the scalar expressions in a SS chain
1489 to loop. This is called after the loop parameters have been calculated,
1490 but before the actual scalarizing loops. */
1491
1492 static void
1493 gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript)
1494 {
1495 gfc_se se;
1496 int n;
1497
1498 /* TODO: This can generate bad code if there are ordering dependencies.
1499 eg. a callee allocated function and an unknown size constructor. */
1500 gcc_assert (ss != NULL);
1501
1502 for (; ss != gfc_ss_terminator; ss = ss->loop_chain)
1503 {
1504 gcc_assert (ss);
1505
1506 switch (ss->type)
1507 {
1508 case GFC_SS_SCALAR:
1509 /* Scalar expression. Evaluate this now. This includes elemental
1510 dimension indices, but not array section bounds. */
1511 gfc_init_se (&se, NULL);
1512 gfc_conv_expr (&se, ss->expr);
1513 gfc_add_block_to_block (&loop->pre, &se.pre);
1514
1515 if (ss->expr->ts.type != BT_CHARACTER)
1516 {
1517 /* Move the evaluation of scalar expressions outside the
1518 scalarization loop. */
1519 if (subscript)
1520 se.expr = convert(gfc_array_index_type, se.expr);
1521 se.expr = gfc_evaluate_now (se.expr, &loop->pre);
1522 gfc_add_block_to_block (&loop->pre, &se.post);
1523 }
1524 else
1525 gfc_add_block_to_block (&loop->post, &se.post);
1526
1527 ss->data.scalar.expr = se.expr;
1528 ss->string_length = se.string_length;
1529 break;
1530
1531 case GFC_SS_REFERENCE:
1532 /* Scalar reference. Evaluate this now. */
1533 gfc_init_se (&se, NULL);
1534 gfc_conv_expr_reference (&se, ss->expr);
1535 gfc_add_block_to_block (&loop->pre, &se.pre);
1536 gfc_add_block_to_block (&loop->post, &se.post);
1537
1538 ss->data.scalar.expr = gfc_evaluate_now (se.expr, &loop->pre);
1539 ss->string_length = se.string_length;
1540 break;
1541
1542 case GFC_SS_SECTION:
1543 /* Add the expressions for scalar and vector subscripts. */
1544 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1545 if (ss->data.info.subscript[n])
1546 gfc_add_loop_ss_code (loop, ss->data.info.subscript[n], true);
1547
1548 gfc_set_vector_loop_bounds (loop, &ss->data.info);
1549 break;
1550
1551 case GFC_SS_VECTOR:
1552 /* Get the vector's descriptor and store it in SS. */
1553 gfc_init_se (&se, NULL);
1554 gfc_conv_expr_descriptor (&se, ss->expr, gfc_walk_expr (ss->expr));
1555 gfc_add_block_to_block (&loop->pre, &se.pre);
1556 gfc_add_block_to_block (&loop->post, &se.post);
1557 ss->data.info.descriptor = se.expr;
1558 break;
1559
1560 case GFC_SS_INTRINSIC:
1561 gfc_add_intrinsic_ss_code (loop, ss);
1562 break;
1563
1564 case GFC_SS_FUNCTION:
1565 /* Array function return value. We call the function and save its
1566 result in a temporary for use inside the loop. */
1567 gfc_init_se (&se, NULL);
1568 se.loop = loop;
1569 se.ss = ss;
1570 gfc_conv_expr (&se, ss->expr);
1571 gfc_add_block_to_block (&loop->pre, &se.pre);
1572 gfc_add_block_to_block (&loop->post, &se.post);
1573 ss->string_length = se.string_length;
1574 break;
1575
1576 case GFC_SS_CONSTRUCTOR:
1577 gfc_trans_array_constructor (loop, ss);
1578 break;
1579
1580 case GFC_SS_TEMP:
1581 case GFC_SS_COMPONENT:
1582 /* Do nothing. These are handled elsewhere. */
1583 break;
1584
1585 default:
1586 gcc_unreachable ();
1587 }
1588 }
1589 }
1590
1591
1592 /* Translate expressions for the descriptor and data pointer of a SS. */
1593 /*GCC ARRAYS*/
1594
1595 static void
1596 gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)
1597 {
1598 gfc_se se;
1599 tree tmp;
1600
1601 /* Get the descriptor for the array to be scalarized. */
1602 gcc_assert (ss->expr->expr_type == EXPR_VARIABLE);
1603 gfc_init_se (&se, NULL);
1604 se.descriptor_only = 1;
1605 gfc_conv_expr_lhs (&se, ss->expr);
1606 gfc_add_block_to_block (block, &se.pre);
1607 ss->data.info.descriptor = se.expr;
1608 ss->string_length = se.string_length;
1609
1610 if (base)
1611 {
1612 /* Also the data pointer. */
1613 tmp = gfc_conv_array_data (se.expr);
1614 /* If this is a variable or address of a variable we use it directly.
1615 Otherwise we must evaluate it now to avoid breaking dependency
1616 analysis by pulling the expressions for elemental array indices
1617 inside the loop. */
1618 if (!(DECL_P (tmp)
1619 || (TREE_CODE (tmp) == ADDR_EXPR
1620 && DECL_P (TREE_OPERAND (tmp, 0)))))
1621 tmp = gfc_evaluate_now (tmp, block);
1622 ss->data.info.data = tmp;
1623
1624 tmp = gfc_conv_array_offset (se.expr);
1625 ss->data.info.offset = gfc_evaluate_now (tmp, block);
1626 }
1627 }
1628
1629
1630 /* Initialize a gfc_loopinfo structure. */
1631
1632 void
1633 gfc_init_loopinfo (gfc_loopinfo * loop)
1634 {
1635 int n;
1636
1637 memset (loop, 0, sizeof (gfc_loopinfo));
1638 gfc_init_block (&loop->pre);
1639 gfc_init_block (&loop->post);
1640
1641 /* Initially scalarize in order. */
1642 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1643 loop->order[n] = n;
1644
1645 loop->ss = gfc_ss_terminator;
1646 }
1647
1648
1649 /* Copies the loop variable info to a gfc_se structure. Does not copy the SS
1650 chain. */
1651
1652 void
1653 gfc_copy_loopinfo_to_se (gfc_se * se, gfc_loopinfo * loop)
1654 {
1655 se->loop = loop;
1656 }
1657
1658
1659 /* Return an expression for the data pointer of an array. */
1660
1661 tree
1662 gfc_conv_array_data (tree descriptor)
1663 {
1664 tree type;
1665
1666 type = TREE_TYPE (descriptor);
1667 if (GFC_ARRAY_TYPE_P (type))
1668 {
1669 if (TREE_CODE (type) == POINTER_TYPE)
1670 return descriptor;
1671 else
1672 {
1673 /* Descriptorless arrays. */
1674 return build_fold_addr_expr (descriptor);
1675 }
1676 }
1677 else
1678 return gfc_conv_descriptor_data_get (descriptor);
1679 }
1680
1681
1682 /* Return an expression for the base offset of an array. */
1683
1684 tree
1685 gfc_conv_array_offset (tree descriptor)
1686 {
1687 tree type;
1688
1689 type = TREE_TYPE (descriptor);
1690 if (GFC_ARRAY_TYPE_P (type))
1691 return GFC_TYPE_ARRAY_OFFSET (type);
1692 else
1693 return gfc_conv_descriptor_offset (descriptor);
1694 }
1695
1696
1697 /* Get an expression for the array stride. */
1698
1699 tree
1700 gfc_conv_array_stride (tree descriptor, int dim)
1701 {
1702 tree tmp;
1703 tree type;
1704
1705 type = TREE_TYPE (descriptor);
1706
1707 /* For descriptorless arrays use the array size. */
1708 tmp = GFC_TYPE_ARRAY_STRIDE (type, dim);
1709 if (tmp != NULL_TREE)
1710 return tmp;
1711
1712 tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[dim]);
1713 return tmp;
1714 }
1715
1716
1717 /* Like gfc_conv_array_stride, but for the lower bound. */
1718
1719 tree
1720 gfc_conv_array_lbound (tree descriptor, int dim)
1721 {
1722 tree tmp;
1723 tree type;
1724
1725 type = TREE_TYPE (descriptor);
1726
1727 tmp = GFC_TYPE_ARRAY_LBOUND (type, dim);
1728 if (tmp != NULL_TREE)
1729 return tmp;
1730
1731 tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[dim]);
1732 return tmp;
1733 }
1734
1735
1736 /* Like gfc_conv_array_stride, but for the upper bound. */
1737
1738 tree
1739 gfc_conv_array_ubound (tree descriptor, int dim)
1740 {
1741 tree tmp;
1742 tree type;
1743
1744 type = TREE_TYPE (descriptor);
1745
1746 tmp = GFC_TYPE_ARRAY_UBOUND (type, dim);
1747 if (tmp != NULL_TREE)
1748 return tmp;
1749
1750 /* This should only ever happen when passing an assumed shape array
1751 as an actual parameter. The value will never be used. */
1752 if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor)))
1753 return gfc_index_zero_node;
1754
1755 tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[dim]);
1756 return tmp;
1757 }
1758
1759
1760 /* Generate code to perform an array index bound check. */
1761
1762 static tree
1763 gfc_trans_array_bound_check (gfc_se * se, tree descriptor, tree index, int n)
1764 {
1765 tree cond;
1766 tree fault;
1767 tree tmp;
1768
1769 if (!flag_bounds_check)
1770 return index;
1771
1772 index = gfc_evaluate_now (index, &se->pre);
1773 /* Check lower bound. */
1774 tmp = gfc_conv_array_lbound (descriptor, n);
1775 fault = fold_build2 (LT_EXPR, boolean_type_node, index, tmp);
1776 /* Check upper bound. */
1777 tmp = gfc_conv_array_ubound (descriptor, n);
1778 cond = fold_build2 (GT_EXPR, boolean_type_node, index, tmp);
1779 fault = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault, cond);
1780
1781 gfc_trans_runtime_check (fault, gfc_strconst_fault, &se->pre);
1782
1783 return index;
1784 }
1785
1786
1787 /* Return the offset for an index. Performs bound checking for elemental
1788 dimensions. Single element references are processed separately. */
1789
1790 static tree
1791 gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i,
1792 gfc_array_ref * ar, tree stride)
1793 {
1794 tree index;
1795 tree desc;
1796 tree data;
1797
1798 /* Get the index into the array for this dimension. */
1799 if (ar)
1800 {
1801 gcc_assert (ar->type != AR_ELEMENT);
1802 switch (ar->dimen_type[dim])
1803 {
1804 case DIMEN_ELEMENT:
1805 gcc_assert (i == -1);
1806 /* Elemental dimension. */
1807 gcc_assert (info->subscript[dim]
1808 && info->subscript[dim]->type == GFC_SS_SCALAR);
1809 /* We've already translated this value outside the loop. */
1810 index = info->subscript[dim]->data.scalar.expr;
1811
1812 index =
1813 gfc_trans_array_bound_check (se, info->descriptor, index, dim);
1814 break;
1815
1816 case DIMEN_VECTOR:
1817 gcc_assert (info && se->loop);
1818 gcc_assert (info->subscript[dim]
1819 && info->subscript[dim]->type == GFC_SS_VECTOR);
1820 desc = info->subscript[dim]->data.info.descriptor;
1821
1822 /* Get a zero-based index into the vector. */
1823 index = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1824 se->loop->loopvar[i], se->loop->from[i]);
1825
1826 /* Multiply the index by the stride. */
1827 index = fold_build2 (MULT_EXPR, gfc_array_index_type,
1828 index, gfc_conv_array_stride (desc, 0));
1829
1830 /* Read the vector to get an index into info->descriptor. */
1831 data = build_fold_indirect_ref (gfc_conv_array_data (desc));
1832 index = gfc_build_array_ref (data, index);
1833 index = gfc_evaluate_now (index, &se->pre);
1834
1835 /* Do any bounds checking on the final info->descriptor index. */
1836 index = gfc_trans_array_bound_check (se, info->descriptor,
1837 index, dim);
1838 break;
1839
1840 case DIMEN_RANGE:
1841 /* Scalarized dimension. */
1842 gcc_assert (info && se->loop);
1843
1844 /* Multiply the loop variable by the stride and delta. */
1845 index = se->loop->loopvar[i];
1846 index = fold_build2 (MULT_EXPR, gfc_array_index_type, index,
1847 info->stride[i]);
1848 index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index,
1849 info->delta[i]);
1850 break;
1851
1852 default:
1853 gcc_unreachable ();
1854 }
1855 }
1856 else
1857 {
1858 /* Temporary array or derived type component. */
1859 gcc_assert (se->loop);
1860 index = se->loop->loopvar[se->loop->order[i]];
1861 if (!integer_zerop (info->delta[i]))
1862 index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1863 index, info->delta[i]);
1864 }
1865
1866 /* Multiply by the stride. */
1867 index = fold_build2 (MULT_EXPR, gfc_array_index_type, index, stride);
1868
1869 return index;
1870 }
1871
1872
1873 /* Build a scalarized reference to an array. */
1874
1875 static void
1876 gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
1877 {
1878 gfc_ss_info *info;
1879 tree index;
1880 tree tmp;
1881 int n;
1882
1883 info = &se->ss->data.info;
1884 if (ar)
1885 n = se->loop->order[0];
1886 else
1887 n = 0;
1888
1889 index = gfc_conv_array_index_offset (se, info, info->dim[n], n, ar,
1890 info->stride0);
1891 /* Add the offset for this dimension to the stored offset for all other
1892 dimensions. */
1893 index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, info->offset);
1894
1895 tmp = build_fold_indirect_ref (info->data);
1896 se->expr = gfc_build_array_ref (tmp, index);
1897 }
1898
1899
1900 /* Translate access of temporary array. */
1901
1902 void
1903 gfc_conv_tmp_array_ref (gfc_se * se)
1904 {
1905 se->string_length = se->ss->string_length;
1906 gfc_conv_scalarized_array_ref (se, NULL);
1907 }
1908
1909
1910 /* Build an array reference. se->expr already holds the array descriptor.
1911 This should be either a variable, indirect variable reference or component
1912 reference. For arrays which do not have a descriptor, se->expr will be
1913 the data pointer.
1914 a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
1915
1916 void
1917 gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar)
1918 {
1919 int n;
1920 tree index;
1921 tree tmp;
1922 tree stride;
1923 tree fault;
1924 gfc_se indexse;
1925
1926 /* Handle scalarized references separately. */
1927 if (ar->type != AR_ELEMENT)
1928 {
1929 gfc_conv_scalarized_array_ref (se, ar);
1930 gfc_advance_se_ss_chain (se);
1931 return;
1932 }
1933
1934 index = gfc_index_zero_node;
1935
1936 fault = gfc_index_zero_node;
1937
1938 /* Calculate the offsets from all the dimensions. */
1939 for (n = 0; n < ar->dimen; n++)
1940 {
1941 /* Calculate the index for this dimension. */
1942 gfc_init_se (&indexse, se);
1943 gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type);
1944 gfc_add_block_to_block (&se->pre, &indexse.pre);
1945
1946 if (flag_bounds_check)
1947 {
1948 /* Check array bounds. */
1949 tree cond;
1950
1951 indexse.expr = gfc_evaluate_now (indexse.expr, &se->pre);
1952
1953 tmp = gfc_conv_array_lbound (se->expr, n);
1954 cond = fold_build2 (LT_EXPR, boolean_type_node,
1955 indexse.expr, tmp);
1956 fault =
1957 fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault, cond);
1958
1959 tmp = gfc_conv_array_ubound (se->expr, n);
1960 cond = fold_build2 (GT_EXPR, boolean_type_node,
1961 indexse.expr, tmp);
1962 fault =
1963 fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault, cond);
1964 }
1965
1966 /* Multiply the index by the stride. */
1967 stride = gfc_conv_array_stride (se->expr, n);
1968 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, indexse.expr,
1969 stride);
1970
1971 /* And add it to the total. */
1972 index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
1973 }
1974
1975 if (flag_bounds_check)
1976 gfc_trans_runtime_check (fault, gfc_strconst_fault, &se->pre);
1977
1978 tmp = gfc_conv_array_offset (se->expr);
1979 if (!integer_zerop (tmp))
1980 index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
1981
1982 /* Access the calculated element. */
1983 tmp = gfc_conv_array_data (se->expr);
1984 tmp = build_fold_indirect_ref (tmp);
1985 se->expr = gfc_build_array_ref (tmp, index);
1986 }
1987
1988
1989 /* Generate the code to be executed immediately before entering a
1990 scalarization loop. */
1991
1992 static void
1993 gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
1994 stmtblock_t * pblock)
1995 {
1996 tree index;
1997 tree stride;
1998 gfc_ss_info *info;
1999 gfc_ss *ss;
2000 gfc_se se;
2001 int i;
2002
2003 /* This code will be executed before entering the scalarization loop
2004 for this dimension. */
2005 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2006 {
2007 if ((ss->useflags & flag) == 0)
2008 continue;
2009
2010 if (ss->type != GFC_SS_SECTION
2011 && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
2012 && ss->type != GFC_SS_COMPONENT)
2013 continue;
2014
2015 info = &ss->data.info;
2016
2017 if (dim >= info->dimen)
2018 continue;
2019
2020 if (dim == info->dimen - 1)
2021 {
2022 /* For the outermost loop calculate the offset due to any
2023 elemental dimensions. It will have been initialized with the
2024 base offset of the array. */
2025 if (info->ref)
2026 {
2027 for (i = 0; i < info->ref->u.ar.dimen; i++)
2028 {
2029 if (info->ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
2030 continue;
2031
2032 gfc_init_se (&se, NULL);
2033 se.loop = loop;
2034 se.expr = info->descriptor;
2035 stride = gfc_conv_array_stride (info->descriptor, i);
2036 index = gfc_conv_array_index_offset (&se, info, i, -1,
2037 &info->ref->u.ar,
2038 stride);
2039 gfc_add_block_to_block (pblock, &se.pre);
2040
2041 info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2042 info->offset, index);
2043 info->offset = gfc_evaluate_now (info->offset, pblock);
2044 }
2045
2046 i = loop->order[0];
2047 stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
2048 }
2049 else
2050 stride = gfc_conv_array_stride (info->descriptor, 0);
2051
2052 /* Calculate the stride of the innermost loop. Hopefully this will
2053 allow the backend optimizers to do their stuff more effectively.
2054 */
2055 info->stride0 = gfc_evaluate_now (stride, pblock);
2056 }
2057 else
2058 {
2059 /* Add the offset for the previous loop dimension. */
2060 gfc_array_ref *ar;
2061
2062 if (info->ref)
2063 {
2064 ar = &info->ref->u.ar;
2065 i = loop->order[dim + 1];
2066 }
2067 else
2068 {
2069 ar = NULL;
2070 i = dim + 1;
2071 }
2072
2073 gfc_init_se (&se, NULL);
2074 se.loop = loop;
2075 se.expr = info->descriptor;
2076 stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
2077 index = gfc_conv_array_index_offset (&se, info, info->dim[i], i,
2078 ar, stride);
2079 gfc_add_block_to_block (pblock, &se.pre);
2080 info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2081 info->offset, index);
2082 info->offset = gfc_evaluate_now (info->offset, pblock);
2083 }
2084
2085 /* Remember this offset for the second loop. */
2086 if (dim == loop->temp_dim - 1)
2087 info->saved_offset = info->offset;
2088 }
2089 }
2090
2091
2092 /* Start a scalarized expression. Creates a scope and declares loop
2093 variables. */
2094
2095 void
2096 gfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody)
2097 {
2098 int dim;
2099 int n;
2100 int flags;
2101
2102 gcc_assert (!loop->array_parameter);
2103
2104 for (dim = loop->dimen - 1; dim >= 0; dim--)
2105 {
2106 n = loop->order[dim];
2107
2108 gfc_start_block (&loop->code[n]);
2109
2110 /* Create the loop variable. */
2111 loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "S");
2112
2113 if (dim < loop->temp_dim)
2114 flags = 3;
2115 else
2116 flags = 1;
2117 /* Calculate values that will be constant within this loop. */
2118 gfc_trans_preloop_setup (loop, dim, flags, &loop->code[n]);
2119 }
2120 gfc_start_block (pbody);
2121 }
2122
2123
2124 /* Generates the actual loop code for a scalarization loop. */
2125
2126 static void
2127 gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
2128 stmtblock_t * pbody)
2129 {
2130 stmtblock_t block;
2131 tree cond;
2132 tree tmp;
2133 tree loopbody;
2134 tree exit_label;
2135
2136 loopbody = gfc_finish_block (pbody);
2137
2138 /* Initialize the loopvar. */
2139 gfc_add_modify_expr (&loop->code[n], loop->loopvar[n], loop->from[n]);
2140
2141 exit_label = gfc_build_label_decl (NULL_TREE);
2142
2143 /* Generate the loop body. */
2144 gfc_init_block (&block);
2145
2146 /* The exit condition. */
2147 cond = build2 (GT_EXPR, boolean_type_node, loop->loopvar[n], loop->to[n]);
2148 tmp = build1_v (GOTO_EXPR, exit_label);
2149 TREE_USED (exit_label) = 1;
2150 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
2151 gfc_add_expr_to_block (&block, tmp);
2152
2153 /* The main body. */
2154 gfc_add_expr_to_block (&block, loopbody);
2155
2156 /* Increment the loopvar. */
2157 tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2158 loop->loopvar[n], gfc_index_one_node);
2159 gfc_add_modify_expr (&block, loop->loopvar[n], tmp);
2160
2161 /* Build the loop. */
2162 tmp = gfc_finish_block (&block);
2163 tmp = build1_v (LOOP_EXPR, tmp);
2164 gfc_add_expr_to_block (&loop->code[n], tmp);
2165
2166 /* Add the exit label. */
2167 tmp = build1_v (LABEL_EXPR, exit_label);
2168 gfc_add_expr_to_block (&loop->code[n], tmp);
2169 }
2170
2171
2172 /* Finishes and generates the loops for a scalarized expression. */
2173
2174 void
2175 gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body)
2176 {
2177 int dim;
2178 int n;
2179 gfc_ss *ss;
2180 stmtblock_t *pblock;
2181 tree tmp;
2182
2183 pblock = body;
2184 /* Generate the loops. */
2185 for (dim = 0; dim < loop->dimen; dim++)
2186 {
2187 n = loop->order[dim];
2188 gfc_trans_scalarized_loop_end (loop, n, pblock);
2189 loop->loopvar[n] = NULL_TREE;
2190 pblock = &loop->code[n];
2191 }
2192
2193 tmp = gfc_finish_block (pblock);
2194 gfc_add_expr_to_block (&loop->pre, tmp);
2195
2196 /* Clear all the used flags. */
2197 for (ss = loop->ss; ss; ss = ss->loop_chain)
2198 ss->useflags = 0;
2199 }
2200
2201
2202 /* Finish the main body of a scalarized expression, and start the secondary
2203 copying body. */
2204
2205 void
2206 gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
2207 {
2208 int dim;
2209 int n;
2210 stmtblock_t *pblock;
2211 gfc_ss *ss;
2212
2213 pblock = body;
2214 /* We finish as many loops as are used by the temporary. */
2215 for (dim = 0; dim < loop->temp_dim - 1; dim++)
2216 {
2217 n = loop->order[dim];
2218 gfc_trans_scalarized_loop_end (loop, n, pblock);
2219 loop->loopvar[n] = NULL_TREE;
2220 pblock = &loop->code[n];
2221 }
2222
2223 /* We don't want to finish the outermost loop entirely. */
2224 n = loop->order[loop->temp_dim - 1];
2225 gfc_trans_scalarized_loop_end (loop, n, pblock);
2226
2227 /* Restore the initial offsets. */
2228 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2229 {
2230 if ((ss->useflags & 2) == 0)
2231 continue;
2232
2233 if (ss->type != GFC_SS_SECTION
2234 && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
2235 && ss->type != GFC_SS_COMPONENT)
2236 continue;
2237
2238 ss->data.info.offset = ss->data.info.saved_offset;
2239 }
2240
2241 /* Restart all the inner loops we just finished. */
2242 for (dim = loop->temp_dim - 2; dim >= 0; dim--)
2243 {
2244 n = loop->order[dim];
2245
2246 gfc_start_block (&loop->code[n]);
2247
2248 loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "Q");
2249
2250 gfc_trans_preloop_setup (loop, dim, 2, &loop->code[n]);
2251 }
2252
2253 /* Start a block for the secondary copying code. */
2254 gfc_start_block (body);
2255 }
2256
2257
2258 /* Calculate the upper bound of an array section. */
2259
2260 static tree
2261 gfc_conv_section_upper_bound (gfc_ss * ss, int n, stmtblock_t * pblock)
2262 {
2263 int dim;
2264 gfc_expr *end;
2265 tree desc;
2266 tree bound;
2267 gfc_se se;
2268 gfc_ss_info *info;
2269
2270 gcc_assert (ss->type == GFC_SS_SECTION);
2271
2272 info = &ss->data.info;
2273 dim = info->dim[n];
2274
2275 if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2276 /* We'll calculate the upper bound once we have access to the
2277 vector's descriptor. */
2278 return NULL;
2279
2280 gcc_assert (info->ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
2281 desc = info->descriptor;
2282 end = info->ref->u.ar.end[dim];
2283
2284 if (end)
2285 {
2286 /* The upper bound was specified. */
2287 gfc_init_se (&se, NULL);
2288 gfc_conv_expr_type (&se, end, gfc_array_index_type);
2289 gfc_add_block_to_block (pblock, &se.pre);
2290 bound = se.expr;
2291 }
2292 else
2293 {
2294 /* No upper bound was specified, so use the bound of the array. */
2295 bound = gfc_conv_array_ubound (desc, dim);
2296 }
2297
2298 return bound;
2299 }
2300
2301
2302 /* Calculate the lower bound of an array section. */
2303
2304 static void
2305 gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int n)
2306 {
2307 gfc_expr *start;
2308 gfc_expr *stride;
2309 tree desc;
2310 gfc_se se;
2311 gfc_ss_info *info;
2312 int dim;
2313
2314 gcc_assert (ss->type == GFC_SS_SECTION);
2315
2316 info = &ss->data.info;
2317 dim = info->dim[n];
2318
2319 if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2320 {
2321 /* We use a zero-based index to access the vector. */
2322 info->start[n] = gfc_index_zero_node;
2323 info->stride[n] = gfc_index_one_node;
2324 return;
2325 }
2326
2327 gcc_assert (info->ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
2328 desc = info->descriptor;
2329 start = info->ref->u.ar.start[dim];
2330 stride = info->ref->u.ar.stride[dim];
2331
2332 /* Calculate the start of the range. For vector subscripts this will
2333 be the range of the vector. */
2334 if (start)
2335 {
2336 /* Specified section start. */
2337 gfc_init_se (&se, NULL);
2338 gfc_conv_expr_type (&se, start, gfc_array_index_type);
2339 gfc_add_block_to_block (&loop->pre, &se.pre);
2340 info->start[n] = se.expr;
2341 }
2342 else
2343 {
2344 /* No lower bound specified so use the bound of the array. */
2345 info->start[n] = gfc_conv_array_lbound (desc, dim);
2346 }
2347 info->start[n] = gfc_evaluate_now (info->start[n], &loop->pre);
2348
2349 /* Calculate the stride. */
2350 if (stride == NULL)
2351 info->stride[n] = gfc_index_one_node;
2352 else
2353 {
2354 gfc_init_se (&se, NULL);
2355 gfc_conv_expr_type (&se, stride, gfc_array_index_type);
2356 gfc_add_block_to_block (&loop->pre, &se.pre);
2357 info->stride[n] = gfc_evaluate_now (se.expr, &loop->pre);
2358 }
2359 }
2360
2361
2362 /* Calculates the range start and stride for a SS chain. Also gets the
2363 descriptor and data pointer. The range of vector subscripts is the size
2364 of the vector. Array bounds are also checked. */
2365
2366 void
2367 gfc_conv_ss_startstride (gfc_loopinfo * loop)
2368 {
2369 int n;
2370 tree tmp;
2371 gfc_ss *ss;
2372 tree desc;
2373
2374 loop->dimen = 0;
2375 /* Determine the rank of the loop. */
2376 for (ss = loop->ss;
2377 ss != gfc_ss_terminator && loop->dimen == 0; ss = ss->loop_chain)
2378 {
2379 switch (ss->type)
2380 {
2381 case GFC_SS_SECTION:
2382 case GFC_SS_CONSTRUCTOR:
2383 case GFC_SS_FUNCTION:
2384 case GFC_SS_COMPONENT:
2385 loop->dimen = ss->data.info.dimen;
2386 break;
2387
2388 default:
2389 break;
2390 }
2391 }
2392
2393 if (loop->dimen == 0)
2394 gfc_todo_error ("Unable to determine rank of expression");
2395
2396
2397 /* Loop over all the SS in the chain. */
2398 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2399 {
2400 if (ss->expr && ss->expr->shape && !ss->shape)
2401 ss->shape = ss->expr->shape;
2402
2403 switch (ss->type)
2404 {
2405 case GFC_SS_SECTION:
2406 /* Get the descriptor for the array. */
2407 gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter);
2408
2409 for (n = 0; n < ss->data.info.dimen; n++)
2410 gfc_conv_section_startstride (loop, ss, n);
2411 break;
2412
2413 case GFC_SS_CONSTRUCTOR:
2414 case GFC_SS_FUNCTION:
2415 for (n = 0; n < ss->data.info.dimen; n++)
2416 {
2417 ss->data.info.start[n] = gfc_index_zero_node;
2418 ss->data.info.stride[n] = gfc_index_one_node;
2419 }
2420 break;
2421
2422 default:
2423 break;
2424 }
2425 }
2426
2427 /* The rest is just runtime bound checking. */
2428 if (flag_bounds_check)
2429 {
2430 stmtblock_t block;
2431 tree fault;
2432 tree bound;
2433 tree end;
2434 tree size[GFC_MAX_DIMENSIONS];
2435 gfc_ss_info *info;
2436 int dim;
2437
2438 gfc_start_block (&block);
2439
2440 fault = integer_zero_node;
2441 for (n = 0; n < loop->dimen; n++)
2442 size[n] = NULL_TREE;
2443
2444 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2445 {
2446 if (ss->type != GFC_SS_SECTION)
2447 continue;
2448
2449 /* TODO: range checking for mapped dimensions. */
2450 info = &ss->data.info;
2451
2452 /* This code only checks ranges. Elemental and vector
2453 dimensions are checked later. */
2454 for (n = 0; n < loop->dimen; n++)
2455 {
2456 dim = info->dim[n];
2457 if (info->ref->u.ar.dimen_type[dim] != DIMEN_RANGE)
2458 continue;
2459
2460 desc = ss->data.info.descriptor;
2461
2462 /* Check lower bound. */
2463 bound = gfc_conv_array_lbound (desc, dim);
2464 tmp = info->start[n];
2465 tmp = fold_build2 (LT_EXPR, boolean_type_node, tmp, bound);
2466 fault = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault,
2467 tmp);
2468
2469 /* Check the upper bound. */
2470 bound = gfc_conv_array_ubound (desc, dim);
2471 end = gfc_conv_section_upper_bound (ss, n, &block);
2472 tmp = fold_build2 (GT_EXPR, boolean_type_node, end, bound);
2473 fault = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault,
2474 tmp);
2475
2476 /* Check the section sizes match. */
2477 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
2478 info->start[n]);
2479 tmp = fold_build2 (FLOOR_DIV_EXPR, gfc_array_index_type, tmp,
2480 info->stride[n]);
2481 /* We remember the size of the first section, and check all the
2482 others against this. */
2483 if (size[n])
2484 {
2485 tmp =
2486 fold_build2 (NE_EXPR, boolean_type_node, tmp, size[n]);
2487 fault =
2488 build2 (TRUTH_OR_EXPR, boolean_type_node, fault, tmp);
2489 }
2490 else
2491 size[n] = gfc_evaluate_now (tmp, &block);
2492 }
2493 }
2494 gfc_trans_runtime_check (fault, gfc_strconst_bounds, &block);
2495
2496 tmp = gfc_finish_block (&block);
2497 gfc_add_expr_to_block (&loop->pre, tmp);
2498 }
2499 }
2500
2501
2502 /* Return true if the two SS could be aliased, i.e. both point to the same data
2503 object. */
2504 /* TODO: resolve aliases based on frontend expressions. */
2505
2506 static int
2507 gfc_could_be_alias (gfc_ss * lss, gfc_ss * rss)
2508 {
2509 gfc_ref *lref;
2510 gfc_ref *rref;
2511 gfc_symbol *lsym;
2512 gfc_symbol *rsym;
2513
2514 lsym = lss->expr->symtree->n.sym;
2515 rsym = rss->expr->symtree->n.sym;
2516 if (gfc_symbols_could_alias (lsym, rsym))
2517 return 1;
2518
2519 if (rsym->ts.type != BT_DERIVED
2520 && lsym->ts.type != BT_DERIVED)
2521 return 0;
2522
2523 /* For derived types we must check all the component types. We can ignore
2524 array references as these will have the same base type as the previous
2525 component ref. */
2526 for (lref = lss->expr->ref; lref != lss->data.info.ref; lref = lref->next)
2527 {
2528 if (lref->type != REF_COMPONENT)
2529 continue;
2530
2531 if (gfc_symbols_could_alias (lref->u.c.sym, rsym))
2532 return 1;
2533
2534 for (rref = rss->expr->ref; rref != rss->data.info.ref;
2535 rref = rref->next)
2536 {
2537 if (rref->type != REF_COMPONENT)
2538 continue;
2539
2540 if (gfc_symbols_could_alias (lref->u.c.sym, rref->u.c.sym))
2541 return 1;
2542 }
2543 }
2544
2545 for (rref = rss->expr->ref; rref != rss->data.info.ref; rref = rref->next)
2546 {
2547 if (rref->type != REF_COMPONENT)
2548 break;
2549
2550 if (gfc_symbols_could_alias (rref->u.c.sym, lsym))
2551 return 1;
2552 }
2553
2554 return 0;
2555 }
2556
2557
2558 /* Resolve array data dependencies. Creates a temporary if required. */
2559 /* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
2560 dependency.c. */
2561
2562 void
2563 gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
2564 gfc_ss * rss)
2565 {
2566 gfc_ss *ss;
2567 gfc_ref *lref;
2568 gfc_ref *rref;
2569 gfc_ref *aref;
2570 int nDepend = 0;
2571 int temp_dim = 0;
2572
2573 loop->temp_ss = NULL;
2574 aref = dest->data.info.ref;
2575 temp_dim = 0;
2576
2577 for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
2578 {
2579 if (ss->type != GFC_SS_SECTION)
2580 continue;
2581
2582 if (gfc_could_be_alias (dest, ss))
2583 {
2584 nDepend = 1;
2585 break;
2586 }
2587
2588 if (dest->expr->symtree->n.sym == ss->expr->symtree->n.sym)
2589 {
2590 lref = dest->expr->ref;
2591 rref = ss->expr->ref;
2592
2593 nDepend = gfc_dep_resolver (lref, rref);
2594 #if 0
2595 /* TODO : loop shifting. */
2596 if (nDepend == 1)
2597 {
2598 /* Mark the dimensions for LOOP SHIFTING */
2599 for (n = 0; n < loop->dimen; n++)
2600 {
2601 int dim = dest->data.info.dim[n];
2602
2603 if (lref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2604 depends[n] = 2;
2605 else if (! gfc_is_same_range (&lref->u.ar,
2606 &rref->u.ar, dim, 0))
2607 depends[n] = 1;
2608 }
2609
2610 /* Put all the dimensions with dependencies in the
2611 innermost loops. */
2612 dim = 0;
2613 for (n = 0; n < loop->dimen; n++)
2614 {
2615 gcc_assert (loop->order[n] == n);
2616 if (depends[n])
2617 loop->order[dim++] = n;
2618 }
2619 temp_dim = dim;
2620 for (n = 0; n < loop->dimen; n++)
2621 {
2622 if (! depends[n])
2623 loop->order[dim++] = n;
2624 }
2625
2626 gcc_assert (dim == loop->dimen);
2627 break;
2628 }
2629 #endif
2630 }
2631 }
2632
2633 if (nDepend == 1)
2634 {
2635 tree base_type = gfc_typenode_for_spec (&dest->expr->ts);
2636 if (GFC_ARRAY_TYPE_P (base_type)
2637 || GFC_DESCRIPTOR_TYPE_P (base_type))
2638 base_type = gfc_get_element_type (base_type);
2639 loop->temp_ss = gfc_get_ss ();
2640 loop->temp_ss->type = GFC_SS_TEMP;
2641 loop->temp_ss->data.temp.type = base_type;
2642 loop->temp_ss->string_length = dest->string_length;
2643 loop->temp_ss->data.temp.dimen = loop->dimen;
2644 loop->temp_ss->next = gfc_ss_terminator;
2645 gfc_add_ss_to_loop (loop, loop->temp_ss);
2646 }
2647 else
2648 loop->temp_ss = NULL;
2649 }
2650
2651
2652 /* Initialize the scalarization loop. Creates the loop variables. Determines
2653 the range of the loop variables. Creates a temporary if required.
2654 Calculates how to transform from loop variables to array indices for each
2655 expression. Also generates code for scalar expressions which have been
2656 moved outside the loop. */
2657
2658 void
2659 gfc_conv_loop_setup (gfc_loopinfo * loop)
2660 {
2661 int n;
2662 int dim;
2663 gfc_ss_info *info;
2664 gfc_ss_info *specinfo;
2665 gfc_ss *ss;
2666 tree tmp;
2667 tree len;
2668 gfc_ss *loopspec[GFC_MAX_DIMENSIONS];
2669 bool dynamic[GFC_MAX_DIMENSIONS];
2670 gfc_constructor *c;
2671 mpz_t *cshape;
2672 mpz_t i;
2673
2674 mpz_init (i);
2675 for (n = 0; n < loop->dimen; n++)
2676 {
2677 loopspec[n] = NULL;
2678 dynamic[n] = false;
2679 /* We use one SS term, and use that to determine the bounds of the
2680 loop for this dimension. We try to pick the simplest term. */
2681 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2682 {
2683 if (ss->shape)
2684 {
2685 /* The frontend has worked out the size for us. */
2686 loopspec[n] = ss;
2687 continue;
2688 }
2689
2690 if (ss->type == GFC_SS_CONSTRUCTOR)
2691 {
2692 /* An unknown size constructor will always be rank one.
2693 Higher rank constructors will either have known shape,
2694 or still be wrapped in a call to reshape. */
2695 gcc_assert (loop->dimen == 1);
2696
2697 /* Always prefer to use the constructor bounds if the size
2698 can be determined at compile time. Prefer not to otherwise,
2699 since the general case involves realloc, and it's better to
2700 avoid that overhead if possible. */
2701 c = ss->expr->value.constructor;
2702 dynamic[n] = gfc_get_array_constructor_size (&i, c);
2703 if (!dynamic[n] || !loopspec[n])
2704 loopspec[n] = ss;
2705 continue;
2706 }
2707
2708 /* TODO: Pick the best bound if we have a choice between a
2709 function and something else. */
2710 if (ss->type == GFC_SS_FUNCTION)
2711 {
2712 loopspec[n] = ss;
2713 continue;
2714 }
2715
2716 if (ss->type != GFC_SS_SECTION)
2717 continue;
2718
2719 if (loopspec[n])
2720 specinfo = &loopspec[n]->data.info;
2721 else
2722 specinfo = NULL;
2723 info = &ss->data.info;
2724
2725 if (!specinfo)
2726 loopspec[n] = ss;
2727 /* Criteria for choosing a loop specifier (most important first):
2728 doesn't need realloc
2729 stride of one
2730 known stride
2731 known lower bound
2732 known upper bound
2733 */
2734 else if (loopspec[n]->type == GFC_SS_CONSTRUCTOR && dynamic[n])
2735 loopspec[n] = ss;
2736 else if (integer_onep (info->stride[n])
2737 && !integer_onep (specinfo->stride[n]))
2738 loopspec[n] = ss;
2739 else if (INTEGER_CST_P (info->stride[n])
2740 && !INTEGER_CST_P (specinfo->stride[n]))
2741 loopspec[n] = ss;
2742 else if (INTEGER_CST_P (info->start[n])
2743 && !INTEGER_CST_P (specinfo->start[n]))
2744 loopspec[n] = ss;
2745 /* We don't work out the upper bound.
2746 else if (INTEGER_CST_P (info->finish[n])
2747 && ! INTEGER_CST_P (specinfo->finish[n]))
2748 loopspec[n] = ss; */
2749 }
2750
2751 if (!loopspec[n])
2752 gfc_todo_error ("Unable to find scalarization loop specifier");
2753
2754 info = &loopspec[n]->data.info;
2755
2756 /* Set the extents of this range. */
2757 cshape = loopspec[n]->shape;
2758 if (cshape && INTEGER_CST_P (info->start[n])
2759 && INTEGER_CST_P (info->stride[n]))
2760 {
2761 loop->from[n] = info->start[n];
2762 mpz_set (i, cshape[n]);
2763 mpz_sub_ui (i, i, 1);
2764 /* To = from + (size - 1) * stride. */
2765 tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
2766 if (!integer_onep (info->stride[n]))
2767 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
2768 tmp, info->stride[n]);
2769 loop->to[n] = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2770 loop->from[n], tmp);
2771 }
2772 else
2773 {
2774 loop->from[n] = info->start[n];
2775 switch (loopspec[n]->type)
2776 {
2777 case GFC_SS_CONSTRUCTOR:
2778 /* The upper bound is calculated when we expand the
2779 constructor. */
2780 gcc_assert (loop->to[n] == NULL_TREE);
2781 break;
2782
2783 case GFC_SS_SECTION:
2784 loop->to[n] = gfc_conv_section_upper_bound (loopspec[n], n,
2785 &loop->pre);
2786 break;
2787
2788 case GFC_SS_FUNCTION:
2789 /* The loop bound will be set when we generate the call. */
2790 gcc_assert (loop->to[n] == NULL_TREE);
2791 break;
2792
2793 default:
2794 gcc_unreachable ();
2795 }
2796 }
2797
2798 /* Transform everything so we have a simple incrementing variable. */
2799 if (integer_onep (info->stride[n]))
2800 info->delta[n] = gfc_index_zero_node;
2801 else
2802 {
2803 /* Set the delta for this section. */
2804 info->delta[n] = gfc_evaluate_now (loop->from[n], &loop->pre);
2805 /* Number of iterations is (end - start + step) / step.
2806 with start = 0, this simplifies to
2807 last = end / step;
2808 for (i = 0; i<=last; i++){...}; */
2809 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2810 loop->to[n], loop->from[n]);
2811 tmp = fold_build2 (TRUNC_DIV_EXPR, gfc_array_index_type,
2812 tmp, info->stride[n]);
2813 loop->to[n] = gfc_evaluate_now (tmp, &loop->pre);
2814 /* Make the loop variable start at 0. */
2815 loop->from[n] = gfc_index_zero_node;
2816 }
2817 }
2818
2819 /* Add all the scalar code that can be taken out of the loops.
2820 This may include calculating the loop bounds, so do it before
2821 allocating the temporary. */
2822 gfc_add_loop_ss_code (loop, loop->ss, false);
2823
2824 /* If we want a temporary then create it. */
2825 if (loop->temp_ss != NULL)
2826 {
2827 gcc_assert (loop->temp_ss->type == GFC_SS_TEMP);
2828 tmp = loop->temp_ss->data.temp.type;
2829 len = loop->temp_ss->string_length;
2830 n = loop->temp_ss->data.temp.dimen;
2831 memset (&loop->temp_ss->data.info, 0, sizeof (gfc_ss_info));
2832 loop->temp_ss->type = GFC_SS_SECTION;
2833 loop->temp_ss->data.info.dimen = n;
2834 gfc_trans_allocate_temp_array (&loop->pre, &loop->post, loop,
2835 &loop->temp_ss->data.info, tmp, false);
2836 }
2837
2838 for (n = 0; n < loop->temp_dim; n++)
2839 loopspec[loop->order[n]] = NULL;
2840
2841 mpz_clear (i);
2842
2843 /* For array parameters we don't have loop variables, so don't calculate the
2844 translations. */
2845 if (loop->array_parameter)
2846 return;
2847
2848 /* Calculate the translation from loop variables to array indices. */
2849 for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2850 {
2851 if (ss->type != GFC_SS_SECTION && ss->type != GFC_SS_COMPONENT)
2852 continue;
2853
2854 info = &ss->data.info;
2855
2856 for (n = 0; n < info->dimen; n++)
2857 {
2858 dim = info->dim[n];
2859
2860 /* If we are specifying the range the delta is already set. */
2861 if (loopspec[n] != ss)
2862 {
2863 /* Calculate the offset relative to the loop variable.
2864 First multiply by the stride. */
2865 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
2866 loop->from[n], info->stride[n]);
2867
2868 /* Then subtract this from our starting value. */
2869 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2870 info->start[n], tmp);
2871
2872 info->delta[n] = gfc_evaluate_now (tmp, &loop->pre);
2873 }
2874 }
2875 }
2876 }
2877
2878
2879 /* Fills in an array descriptor, and returns the size of the array. The size
2880 will be a simple_val, ie a variable or a constant. Also calculates the
2881 offset of the base. Returns the size of the array.
2882 {
2883 stride = 1;
2884 offset = 0;
2885 for (n = 0; n < rank; n++)
2886 {
2887 a.lbound[n] = specified_lower_bound;
2888 offset = offset + a.lbond[n] * stride;
2889 size = 1 - lbound;
2890 a.ubound[n] = specified_upper_bound;
2891 a.stride[n] = stride;
2892 size = ubound + size; //size = ubound + 1 - lbound
2893 stride = stride * size;
2894 }
2895 return (stride);
2896 } */
2897 /*GCC ARRAYS*/
2898
2899 static tree
2900 gfc_array_init_size (tree descriptor, int rank, tree * poffset,
2901 gfc_expr ** lower, gfc_expr ** upper,
2902 stmtblock_t * pblock)
2903 {
2904 tree type;
2905 tree tmp;
2906 tree size;
2907 tree offset;
2908 tree stride;
2909 gfc_expr *ubound;
2910 gfc_se se;
2911 int n;
2912
2913 type = TREE_TYPE (descriptor);
2914
2915 stride = gfc_index_one_node;
2916 offset = gfc_index_zero_node;
2917
2918 /* Set the dtype. */
2919 tmp = gfc_conv_descriptor_dtype (descriptor);
2920 gfc_add_modify_expr (pblock, tmp, gfc_get_dtype (TREE_TYPE (descriptor)));
2921
2922 for (n = 0; n < rank; n++)
2923 {
2924 /* We have 3 possibilities for determining the size of the array:
2925 lower == NULL => lbound = 1, ubound = upper[n]
2926 upper[n] = NULL => lbound = 1, ubound = lower[n]
2927 upper[n] != NULL => lbound = lower[n], ubound = upper[n] */
2928 ubound = upper[n];
2929
2930 /* Set lower bound. */
2931 gfc_init_se (&se, NULL);
2932 if (lower == NULL)
2933 se.expr = gfc_index_one_node;
2934 else
2935 {
2936 gcc_assert (lower[n]);
2937 if (ubound)
2938 {
2939 gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
2940 gfc_add_block_to_block (pblock, &se.pre);
2941 }
2942 else
2943 {
2944 se.expr = gfc_index_one_node;
2945 ubound = lower[n];
2946 }
2947 }
2948 tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[n]);
2949 gfc_add_modify_expr (pblock, tmp, se.expr);
2950
2951 /* Work out the offset for this component. */
2952 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, se.expr, stride);
2953 offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
2954
2955 /* Start the calculation for the size of this dimension. */
2956 size = build2 (MINUS_EXPR, gfc_array_index_type,
2957 gfc_index_one_node, se.expr);
2958
2959 /* Set upper bound. */
2960 gfc_init_se (&se, NULL);
2961 gcc_assert (ubound);
2962 gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
2963 gfc_add_block_to_block (pblock, &se.pre);
2964
2965 tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[n]);
2966 gfc_add_modify_expr (pblock, tmp, se.expr);
2967
2968 /* Store the stride. */
2969 tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[n]);
2970 gfc_add_modify_expr (pblock, tmp, stride);
2971
2972 /* Calculate the size of this dimension. */
2973 size = fold_build2 (PLUS_EXPR, gfc_array_index_type, se.expr, size);
2974
2975 /* Multiply the stride by the number of elements in this dimension. */
2976 stride = fold_build2 (MULT_EXPR, gfc_array_index_type, stride, size);
2977 stride = gfc_evaluate_now (stride, pblock);
2978 }
2979
2980 /* The stride is the number of elements in the array, so multiply by the
2981 size of an element to get the total size. */
2982 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
2983 size = fold_build2 (MULT_EXPR, gfc_array_index_type, stride, tmp);
2984
2985 if (poffset != NULL)
2986 {
2987 offset = gfc_evaluate_now (offset, pblock);
2988 *poffset = offset;
2989 }
2990
2991 size = gfc_evaluate_now (size, pblock);
2992 return size;
2993 }
2994
2995
2996 /* Initializes the descriptor and generates a call to _gfor_allocate. Does
2997 the work for an ALLOCATE statement. */
2998 /*GCC ARRAYS*/
2999
3000 void
3001 gfc_array_allocate (gfc_se * se, gfc_ref * ref, tree pstat)
3002 {
3003 tree tmp;
3004 tree pointer;
3005 tree allocate;
3006 tree offset;
3007 tree size;
3008 gfc_expr **lower;
3009 gfc_expr **upper;
3010
3011 /* Figure out the size of the array. */
3012 switch (ref->u.ar.type)
3013 {
3014 case AR_ELEMENT:
3015 lower = NULL;
3016 upper = ref->u.ar.start;
3017 break;
3018
3019 case AR_FULL:
3020 gcc_assert (ref->u.ar.as->type == AS_EXPLICIT);
3021
3022 lower = ref->u.ar.as->lower;
3023 upper = ref->u.ar.as->upper;
3024 break;
3025
3026 case AR_SECTION:
3027 lower = ref->u.ar.start;
3028 upper = ref->u.ar.end;
3029 break;
3030
3031 default:
3032 gcc_unreachable ();
3033 break;
3034 }
3035
3036 size = gfc_array_init_size (se->expr, ref->u.ar.as->rank, &offset,
3037 lower, upper, &se->pre);
3038
3039 /* Allocate memory to store the data. */
3040 tmp = gfc_conv_descriptor_data_addr (se->expr);
3041 pointer = gfc_evaluate_now (tmp, &se->pre);
3042
3043 if (TYPE_PRECISION (gfc_array_index_type) == 32)
3044 allocate = gfor_fndecl_allocate;
3045 else if (TYPE_PRECISION (gfc_array_index_type) == 64)
3046 allocate = gfor_fndecl_allocate64;
3047 else
3048 gcc_unreachable ();
3049
3050 tmp = gfc_chainon_list (NULL_TREE, pointer);
3051 tmp = gfc_chainon_list (tmp, size);
3052 tmp = gfc_chainon_list (tmp, pstat);
3053 tmp = build_function_call_expr (allocate, tmp);
3054 gfc_add_expr_to_block (&se->pre, tmp);
3055
3056 tmp = gfc_conv_descriptor_offset (se->expr);
3057 gfc_add_modify_expr (&se->pre, tmp, offset);
3058 }
3059
3060
3061 /* Deallocate an array variable. Also used when an allocated variable goes
3062 out of scope. */
3063 /*GCC ARRAYS*/
3064
3065 tree
3066 gfc_array_deallocate (tree descriptor, tree pstat)
3067 {
3068 tree var;
3069 tree tmp;
3070 stmtblock_t block;
3071
3072 gfc_start_block (&block);
3073 /* Get a pointer to the data. */
3074 tmp = gfc_conv_descriptor_data_addr (descriptor);
3075 var = gfc_evaluate_now (tmp, &block);
3076
3077 /* Parameter is the address of the data component. */
3078 tmp = gfc_chainon_list (NULL_TREE, var);
3079 tmp = gfc_chainon_list (tmp, pstat);
3080 tmp = build_function_call_expr (gfor_fndecl_deallocate, tmp);
3081 gfc_add_expr_to_block (&block, tmp);
3082
3083 return gfc_finish_block (&block);
3084 }
3085
3086
3087 /* Create an array constructor from an initialization expression.
3088 We assume the frontend already did any expansions and conversions. */
3089
3090 tree
3091 gfc_conv_array_initializer (tree type, gfc_expr * expr)
3092 {
3093 gfc_constructor *c;
3094 tree tmp;
3095 mpz_t maxval;
3096 gfc_se se;
3097 HOST_WIDE_INT hi;
3098 unsigned HOST_WIDE_INT lo;
3099 tree index, range;
3100 VEC(constructor_elt,gc) *v = NULL;
3101
3102 switch (expr->expr_type)
3103 {
3104 case EXPR_CONSTANT:
3105 case EXPR_STRUCTURE:
3106 /* A single scalar or derived type value. Create an array with all
3107 elements equal to that value. */
3108 gfc_init_se (&se, NULL);
3109
3110 if (expr->expr_type == EXPR_CONSTANT)
3111 gfc_conv_constant (&se, expr);
3112 else
3113 gfc_conv_structure (&se, expr, 1);
3114
3115 tmp = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3116 gcc_assert (tmp && INTEGER_CST_P (tmp));
3117 hi = TREE_INT_CST_HIGH (tmp);
3118 lo = TREE_INT_CST_LOW (tmp);
3119 lo++;
3120 if (lo == 0)
3121 hi++;
3122 /* This will probably eat buckets of memory for large arrays. */
3123 while (hi != 0 || lo != 0)
3124 {
3125 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, se.expr);
3126 if (lo == 0)
3127 hi--;
3128 lo--;
3129 }
3130 break;
3131
3132 case EXPR_ARRAY:
3133 /* Create a vector of all the elements. */
3134 for (c = expr->value.constructor; c; c = c->next)
3135 {
3136 if (c->iterator)
3137 {
3138 /* Problems occur when we get something like
3139 integer :: a(lots) = (/(i, i=1,lots)/) */
3140 /* TODO: Unexpanded array initializers. */
3141 internal_error
3142 ("Possible frontend bug: array constructor not expanded");
3143 }
3144 if (mpz_cmp_si (c->n.offset, 0) != 0)
3145 index = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
3146 else
3147 index = NULL_TREE;
3148 mpz_init (maxval);
3149 if (mpz_cmp_si (c->repeat, 0) != 0)
3150 {
3151 tree tmp1, tmp2;
3152
3153 mpz_set (maxval, c->repeat);
3154 mpz_add (maxval, c->n.offset, maxval);
3155 mpz_sub_ui (maxval, maxval, 1);
3156 tmp2 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
3157 if (mpz_cmp_si (c->n.offset, 0) != 0)
3158 {
3159 mpz_add_ui (maxval, c->n.offset, 1);
3160 tmp1 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
3161 }
3162 else
3163 tmp1 = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
3164
3165 range = build2 (RANGE_EXPR, integer_type_node, tmp1, tmp2);
3166 }
3167 else
3168 range = NULL;
3169 mpz_clear (maxval);
3170
3171 gfc_init_se (&se, NULL);
3172 switch (c->expr->expr_type)
3173 {
3174 case EXPR_CONSTANT:
3175 gfc_conv_constant (&se, c->expr);
3176 if (range == NULL_TREE)
3177 CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3178 else
3179 {
3180 if (index != NULL_TREE)
3181 CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3182 CONSTRUCTOR_APPEND_ELT (v, range, se.expr);
3183 }
3184 break;
3185
3186 case EXPR_STRUCTURE:
3187 gfc_conv_structure (&se, c->expr, 1);
3188 CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3189 break;
3190
3191 default:
3192 gcc_unreachable ();
3193 }
3194 }
3195 break;
3196
3197 default:
3198 gcc_unreachable ();
3199 }
3200
3201 /* Create a constructor from the list of elements. */
3202 tmp = build_constructor (type, v);
3203 TREE_CONSTANT (tmp) = 1;
3204 TREE_INVARIANT (tmp) = 1;
3205 return tmp;
3206 }
3207
3208
3209 /* Generate code to evaluate non-constant array bounds. Sets *poffset and
3210 returns the size (in elements) of the array. */
3211
3212 static tree
3213 gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
3214 stmtblock_t * pblock)
3215 {
3216 gfc_array_spec *as;
3217 tree size;
3218 tree stride;
3219 tree offset;
3220 tree ubound;
3221 tree lbound;
3222 tree tmp;
3223 gfc_se se;
3224
3225 int dim;
3226
3227 as = sym->as;
3228
3229 size = gfc_index_one_node;
3230 offset = gfc_index_zero_node;
3231 for (dim = 0; dim < as->rank; dim++)
3232 {
3233 /* Evaluate non-constant array bound expressions. */
3234 lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
3235 if (as->lower[dim] && !INTEGER_CST_P (lbound))
3236 {
3237 gfc_init_se (&se, NULL);
3238 gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
3239 gfc_add_block_to_block (pblock, &se.pre);
3240 gfc_add_modify_expr (pblock, lbound, se.expr);
3241 }
3242 ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
3243 if (as->upper[dim] && !INTEGER_CST_P (ubound))
3244 {
3245 gfc_init_se (&se, NULL);
3246 gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
3247 gfc_add_block_to_block (pblock, &se.pre);
3248 gfc_add_modify_expr (pblock, ubound, se.expr);
3249 }
3250 /* The offset of this dimension. offset = offset - lbound * stride. */
3251 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, size);
3252 offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3253
3254 /* The size of this dimension, and the stride of the next. */
3255 if (dim + 1 < as->rank)
3256 stride = GFC_TYPE_ARRAY_STRIDE (type, dim + 1);
3257 else
3258 stride = NULL_TREE;
3259
3260 if (ubound != NULL_TREE && !(stride && INTEGER_CST_P (stride)))
3261 {
3262 /* Calculate stride = size * (ubound + 1 - lbound). */
3263 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3264 gfc_index_one_node, lbound);
3265 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, ubound, tmp);
3266 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
3267 if (stride)
3268 gfc_add_modify_expr (pblock, stride, tmp);
3269 else
3270 stride = gfc_evaluate_now (tmp, pblock);
3271 }
3272
3273 size = stride;
3274 }
3275
3276 *poffset = offset;
3277 return size;
3278 }
3279
3280
3281 /* Generate code to initialize/allocate an array variable. */
3282
3283 tree
3284 gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, tree fnbody)
3285 {
3286 stmtblock_t block;
3287 tree type;
3288 tree tmp;
3289 tree fndecl;
3290 tree size;
3291 tree offset;
3292 bool onstack;
3293
3294 gcc_assert (!(sym->attr.pointer || sym->attr.allocatable));
3295
3296 /* Do nothing for USEd variables. */
3297 if (sym->attr.use_assoc)
3298 return fnbody;
3299
3300 type = TREE_TYPE (decl);
3301 gcc_assert (GFC_ARRAY_TYPE_P (type));
3302 onstack = TREE_CODE (type) != POINTER_TYPE;
3303
3304 gfc_start_block (&block);
3305
3306 /* Evaluate character string length. */
3307 if (sym->ts.type == BT_CHARACTER
3308 && onstack && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3309 {
3310 gfc_trans_init_string_length (sym->ts.cl, &block);
3311
3312 /* Emit a DECL_EXPR for this variable, which will cause the
3313 gimplifier to allocate storage, and all that good stuff. */
3314 tmp = build1 (DECL_EXPR, TREE_TYPE (decl), decl);
3315 gfc_add_expr_to_block (&block, tmp);
3316 }
3317
3318 if (onstack)
3319 {
3320 gfc_add_expr_to_block (&block, fnbody);
3321 return gfc_finish_block (&block);
3322 }
3323
3324 type = TREE_TYPE (type);
3325
3326 gcc_assert (!sym->attr.use_assoc);
3327 gcc_assert (!TREE_STATIC (decl));
3328 gcc_assert (!sym->module);
3329
3330 if (sym->ts.type == BT_CHARACTER
3331 && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3332 gfc_trans_init_string_length (sym->ts.cl, &block);
3333
3334 size = gfc_trans_array_bounds (type, sym, &offset, &block);
3335
3336 /* Don't actually allocate space for Cray Pointees. */
3337 if (sym->attr.cray_pointee)
3338 {
3339 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3340 gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3341 gfc_add_expr_to_block (&block, fnbody);
3342 return gfc_finish_block (&block);
3343 }
3344
3345 /* The size is the number of elements in the array, so multiply by the
3346 size of an element to get the total size. */
3347 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
3348 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
3349
3350 /* Allocate memory to hold the data. */
3351 tmp = gfc_chainon_list (NULL_TREE, size);
3352
3353 if (gfc_index_integer_kind == 4)
3354 fndecl = gfor_fndecl_internal_malloc;
3355 else if (gfc_index_integer_kind == 8)
3356 fndecl = gfor_fndecl_internal_malloc64;
3357 else
3358 gcc_unreachable ();
3359 tmp = build_function_call_expr (fndecl, tmp);
3360 tmp = fold (convert (TREE_TYPE (decl), tmp));
3361 gfc_add_modify_expr (&block, decl, tmp);
3362
3363 /* Set offset of the array. */
3364 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3365 gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3366
3367
3368 /* Automatic arrays should not have initializers. */
3369 gcc_assert (!sym->value);
3370
3371 gfc_add_expr_to_block (&block, fnbody);
3372
3373 /* Free the temporary. */
3374 tmp = convert (pvoid_type_node, decl);
3375 tmp = gfc_chainon_list (NULL_TREE, tmp);
3376 tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
3377 gfc_add_expr_to_block (&block, tmp);
3378
3379 return gfc_finish_block (&block);
3380 }
3381
3382
3383 /* Generate entry and exit code for g77 calling convention arrays. */
3384
3385 tree
3386 gfc_trans_g77_array (gfc_symbol * sym, tree body)
3387 {
3388 tree parm;
3389 tree type;
3390 locus loc;
3391 tree offset;
3392 tree tmp;
3393 stmtblock_t block;
3394
3395 gfc_get_backend_locus (&loc);
3396 gfc_set_backend_locus (&sym->declared_at);
3397
3398 /* Descriptor type. */
3399 parm = sym->backend_decl;
3400 type = TREE_TYPE (parm);
3401 gcc_assert (GFC_ARRAY_TYPE_P (type));
3402
3403 gfc_start_block (&block);
3404
3405 if (sym->ts.type == BT_CHARACTER
3406 && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
3407 gfc_trans_init_string_length (sym->ts.cl, &block);
3408
3409 /* Evaluate the bounds of the array. */
3410 gfc_trans_array_bounds (type, sym, &offset, &block);
3411
3412 /* Set the offset. */
3413 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3414 gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3415
3416 /* Set the pointer itself if we aren't using the parameter directly. */
3417 if (TREE_CODE (parm) != PARM_DECL)
3418 {
3419 tmp = convert (TREE_TYPE (parm), GFC_DECL_SAVED_DESCRIPTOR (parm));
3420 gfc_add_modify_expr (&block, parm, tmp);
3421 }
3422 tmp = gfc_finish_block (&block);
3423
3424 gfc_set_backend_locus (&loc);
3425
3426 gfc_start_block (&block);
3427 /* Add the initialization code to the start of the function. */
3428 gfc_add_expr_to_block (&block, tmp);
3429 gfc_add_expr_to_block (&block, body);
3430
3431 return gfc_finish_block (&block);
3432 }
3433
3434
3435 /* Modify the descriptor of an array parameter so that it has the
3436 correct lower bound. Also move the upper bound accordingly.
3437 If the array is not packed, it will be copied into a temporary.
3438 For each dimension we set the new lower and upper bounds. Then we copy the
3439 stride and calculate the offset for this dimension. We also work out
3440 what the stride of a packed array would be, and see it the two match.
3441 If the array need repacking, we set the stride to the values we just
3442 calculated, recalculate the offset and copy the array data.
3443 Code is also added to copy the data back at the end of the function.
3444 */
3445
3446 tree
3447 gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
3448 {
3449 tree size;
3450 tree type;
3451 tree offset;
3452 locus loc;
3453 stmtblock_t block;
3454 stmtblock_t cleanup;
3455 tree lbound;
3456 tree ubound;
3457 tree dubound;
3458 tree dlbound;
3459 tree dumdesc;
3460 tree tmp;
3461 tree stmt;
3462 tree stride;
3463 tree stmt_packed;
3464 tree stmt_unpacked;
3465 tree partial;
3466 gfc_se se;
3467 int n;
3468 int checkparm;
3469 int no_repack;
3470 bool optional_arg;
3471
3472 /* Do nothing for pointer and allocatable arrays. */
3473 if (sym->attr.pointer || sym->attr.allocatable)
3474 return body;
3475
3476 if (sym->attr.dummy && gfc_is_nodesc_array (sym))
3477 return gfc_trans_g77_array (sym, body);
3478
3479 gfc_get_backend_locus (&loc);
3480 gfc_set_backend_locus (&sym->declared_at);
3481
3482 /* Descriptor type. */
3483 type = TREE_TYPE (tmpdesc);
3484 gcc_assert (GFC_ARRAY_TYPE_P (type));
3485 dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3486 dumdesc = build_fold_indirect_ref (dumdesc);
3487 gfc_start_block (&block);
3488
3489 if (sym->ts.type == BT_CHARACTER
3490 && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
3491 gfc_trans_init_string_length (sym->ts.cl, &block);
3492
3493 checkparm = (sym->as->type == AS_EXPLICIT && flag_bounds_check);
3494
3495 no_repack = !(GFC_DECL_PACKED_ARRAY (tmpdesc)
3496 || GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc));
3497
3498 if (GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc))
3499 {
3500 /* For non-constant shape arrays we only check if the first dimension
3501 is contiguous. Repacking higher dimensions wouldn't gain us
3502 anything as we still don't know the array stride. */
3503 partial = gfc_create_var (boolean_type_node, "partial");
3504 TREE_USED (partial) = 1;
3505 tmp = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
3506 tmp = fold_build2 (EQ_EXPR, boolean_type_node, tmp, integer_one_node);
3507 gfc_add_modify_expr (&block, partial, tmp);
3508 }
3509 else
3510 {
3511 partial = NULL_TREE;
3512 }
3513
3514 /* The naming of stmt_unpacked and stmt_packed may be counter-intuitive
3515 here, however I think it does the right thing. */
3516 if (no_repack)
3517 {
3518 /* Set the first stride. */
3519 stride = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
3520 stride = gfc_evaluate_now (stride, &block);
3521
3522 tmp = build2 (EQ_EXPR, boolean_type_node, stride, integer_zero_node);
3523 tmp = build3 (COND_EXPR, gfc_array_index_type, tmp,
3524 gfc_index_one_node, stride);
3525 stride = GFC_TYPE_ARRAY_STRIDE (type, 0);
3526 gfc_add_modify_expr (&block, stride, tmp);
3527
3528 /* Allow the user to disable array repacking. */
3529 stmt_unpacked = NULL_TREE;
3530 }
3531 else
3532 {
3533 gcc_assert (integer_onep (GFC_TYPE_ARRAY_STRIDE (type, 0)));
3534 /* A library call to repack the array if necessary. */
3535 tmp = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3536 tmp = gfc_chainon_list (NULL_TREE, tmp);
3537 stmt_unpacked = build_function_call_expr (gfor_fndecl_in_pack, tmp);
3538
3539 stride = gfc_index_one_node;
3540 }
3541
3542 /* This is for the case where the array data is used directly without
3543 calling the repack function. */
3544 if (no_repack || partial != NULL_TREE)
3545 stmt_packed = gfc_conv_descriptor_data_get (dumdesc);
3546 else
3547 stmt_packed = NULL_TREE;
3548
3549 /* Assign the data pointer. */
3550 if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
3551 {
3552 /* Don't repack unknown shape arrays when the first stride is 1. */
3553 tmp = build3 (COND_EXPR, TREE_TYPE (stmt_packed), partial,
3554 stmt_packed, stmt_unpacked);
3555 }
3556 else
3557 tmp = stmt_packed != NULL_TREE ? stmt_packed : stmt_unpacked;
3558 gfc_add_modify_expr (&block, tmpdesc, fold_convert (type, tmp));
3559
3560 offset = gfc_index_zero_node;
3561 size = gfc_index_one_node;
3562
3563 /* Evaluate the bounds of the array. */
3564 for (n = 0; n < sym->as->rank; n++)
3565 {
3566 if (checkparm || !sym->as->upper[n])
3567 {
3568 /* Get the bounds of the actual parameter. */
3569 dubound = gfc_conv_descriptor_ubound (dumdesc, gfc_rank_cst[n]);
3570 dlbound = gfc_conv_descriptor_lbound (dumdesc, gfc_rank_cst[n]);
3571 }
3572 else
3573 {
3574 dubound = NULL_TREE;
3575 dlbound = NULL_TREE;
3576 }
3577
3578 lbound = GFC_TYPE_ARRAY_LBOUND (type, n);
3579 if (!INTEGER_CST_P (lbound))
3580 {
3581 gfc_init_se (&se, NULL);
3582 gfc_conv_expr_type (&se, sym->as->lower[n],
3583 gfc_array_index_type);
3584 gfc_add_block_to_block (&block, &se.pre);
3585 gfc_add_modify_expr (&block, lbound, se.expr);
3586 }
3587
3588 ubound = GFC_TYPE_ARRAY_UBOUND (type, n);
3589 /* Set the desired upper bound. */
3590 if (sym->as->upper[n])
3591 {
3592 /* We know what we want the upper bound to be. */
3593 if (!INTEGER_CST_P (ubound))
3594 {
3595 gfc_init_se (&se, NULL);
3596 gfc_conv_expr_type (&se, sym->as->upper[n],
3597 gfc_array_index_type);
3598 gfc_add_block_to_block (&block, &se.pre);
3599 gfc_add_modify_expr (&block, ubound, se.expr);
3600 }
3601
3602 /* Check the sizes match. */
3603 if (checkparm)
3604 {
3605 /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)). */
3606
3607 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3608 ubound, lbound);
3609 stride = build2 (MINUS_EXPR, gfc_array_index_type,
3610 dubound, dlbound);
3611 tmp = fold_build2 (NE_EXPR, gfc_array_index_type, tmp, stride);
3612 gfc_trans_runtime_check (tmp, gfc_strconst_bounds, &block);
3613 }
3614 }
3615 else
3616 {
3617 /* For assumed shape arrays move the upper bound by the same amount
3618 as the lower bound. */
3619 tmp = build2 (MINUS_EXPR, gfc_array_index_type, dubound, dlbound);
3620 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp, lbound);
3621 gfc_add_modify_expr (&block, ubound, tmp);
3622 }
3623 /* The offset of this dimension. offset = offset - lbound * stride. */
3624 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, stride);
3625 offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3626
3627 /* The size of this dimension, and the stride of the next. */
3628 if (n + 1 < sym->as->rank)
3629 {
3630 stride = GFC_TYPE_ARRAY_STRIDE (type, n + 1);
3631
3632 if (no_repack || partial != NULL_TREE)
3633 {
3634 stmt_unpacked =
3635 gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[n+1]);
3636 }
3637
3638 /* Figure out the stride if not a known constant. */
3639 if (!INTEGER_CST_P (stride))
3640 {
3641 if (no_repack)
3642 stmt_packed = NULL_TREE;
3643 else
3644 {
3645 /* Calculate stride = size * (ubound + 1 - lbound). */
3646 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3647 gfc_index_one_node, lbound);
3648 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3649 ubound, tmp);
3650 size = fold_build2 (MULT_EXPR, gfc_array_index_type,
3651 size, tmp);
3652 stmt_packed = size;
3653 }
3654
3655 /* Assign the stride. */
3656 if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
3657 tmp = build3 (COND_EXPR, gfc_array_index_type, partial,
3658 stmt_unpacked, stmt_packed);
3659 else
3660 tmp = (stmt_packed != NULL_TREE) ? stmt_packed : stmt_unpacked;
3661 gfc_add_modify_expr (&block, stride, tmp);
3662 }
3663 }
3664 }
3665
3666 /* Set the offset. */
3667 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3668 gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3669
3670 stmt = gfc_finish_block (&block);
3671
3672 gfc_start_block (&block);
3673
3674 /* Only do the entry/initialization code if the arg is present. */
3675 dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3676 optional_arg = (sym->attr.optional
3677 || (sym->ns->proc_name->attr.entry_master
3678 && sym->attr.dummy));
3679 if (optional_arg)
3680 {
3681 tmp = gfc_conv_expr_present (sym);
3682 stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3683 }
3684 gfc_add_expr_to_block (&block, stmt);
3685
3686 /* Add the main function body. */
3687 gfc_add_expr_to_block (&block, body);
3688
3689 /* Cleanup code. */
3690 if (!no_repack)
3691 {
3692 gfc_start_block (&cleanup);
3693
3694 if (sym->attr.intent != INTENT_IN)
3695 {
3696 /* Copy the data back. */
3697 tmp = gfc_chainon_list (NULL_TREE, dumdesc);
3698 tmp = gfc_chainon_list (tmp, tmpdesc);
3699 tmp = build_function_call_expr (gfor_fndecl_in_unpack, tmp);
3700 gfc_add_expr_to_block (&cleanup, tmp);
3701 }
3702
3703 /* Free the temporary. */
3704 tmp = gfc_chainon_list (NULL_TREE, tmpdesc);
3705 tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
3706 gfc_add_expr_to_block (&cleanup, tmp);
3707
3708 stmt = gfc_finish_block (&cleanup);
3709
3710 /* Only do the cleanup if the array was repacked. */
3711 tmp = build_fold_indirect_ref (dumdesc);
3712 tmp = gfc_conv_descriptor_data_get (tmp);
3713 tmp = build2 (NE_EXPR, boolean_type_node, tmp, tmpdesc);
3714 stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3715
3716 if (optional_arg)
3717 {
3718 tmp = gfc_conv_expr_present (sym);
3719 stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3720 }
3721 gfc_add_expr_to_block (&block, stmt);
3722 }
3723 /* We don't need to free any memory allocated by internal_pack as it will
3724 be freed at the end of the function by pop_context. */
3725 return gfc_finish_block (&block);
3726 }
3727
3728
3729 /* Convert an array for passing as an actual argument. Expressions and
3730 vector subscripts are evaluated and stored in a temporary, which is then
3731 passed. For whole arrays the descriptor is passed. For array sections
3732 a modified copy of the descriptor is passed, but using the original data.
3733
3734 This function is also used for array pointer assignments, and there
3735 are three cases:
3736
3737 - want_pointer && !se->direct_byref
3738 EXPR is an actual argument. On exit, se->expr contains a
3739 pointer to the array descriptor.
3740
3741 - !want_pointer && !se->direct_byref
3742 EXPR is an actual argument to an intrinsic function or the
3743 left-hand side of a pointer assignment. On exit, se->expr
3744 contains the descriptor for EXPR.
3745
3746 - !want_pointer && se->direct_byref
3747 EXPR is the right-hand side of a pointer assignment and
3748 se->expr is the descriptor for the previously-evaluated
3749 left-hand side. The function creates an assignment from
3750 EXPR to se->expr. */
3751
3752 void
3753 gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
3754 {
3755 gfc_loopinfo loop;
3756 gfc_ss *secss;
3757 gfc_ss_info *info;
3758 int need_tmp;
3759 int n;
3760 tree tmp;
3761 tree desc;
3762 stmtblock_t block;
3763 tree start;
3764 tree offset;
3765 int full;
3766 gfc_ref *ref;
3767
3768 gcc_assert (ss != gfc_ss_terminator);
3769
3770 /* TODO: Pass constant array constructors without a temporary. */
3771 /* Special case things we know we can pass easily. */
3772 switch (expr->expr_type)
3773 {
3774 case EXPR_VARIABLE:
3775 /* If we have a linear array section, we can pass it directly.
3776 Otherwise we need to copy it into a temporary. */
3777
3778 /* Find the SS for the array section. */
3779 secss = ss;
3780 while (secss != gfc_ss_terminator && secss->type != GFC_SS_SECTION)
3781 secss = secss->next;
3782
3783 gcc_assert (secss != gfc_ss_terminator);
3784 info = &secss->data.info;
3785
3786 /* Get the descriptor for the array. */
3787 gfc_conv_ss_descriptor (&se->pre, secss, 0);
3788 desc = info->descriptor;
3789
3790 need_tmp = gfc_ref_needs_temporary_p (expr->ref);
3791 if (need_tmp)
3792 full = 0;
3793 else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
3794 {
3795 /* Create a new descriptor if the array doesn't have one. */
3796 full = 0;
3797 }
3798 else if (info->ref->u.ar.type == AR_FULL)
3799 full = 1;
3800 else if (se->direct_byref)
3801 full = 0;
3802 else
3803 {
3804 ref = info->ref;
3805 gcc_assert (ref->u.ar.type == AR_SECTION);
3806
3807 full = 1;
3808 for (n = 0; n < ref->u.ar.dimen; n++)
3809 {
3810 /* Detect passing the full array as a section. This could do
3811 even more checking, but it doesn't seem worth it. */
3812 if (ref->u.ar.start[n]
3813 || ref->u.ar.end[n]
3814 || (ref->u.ar.stride[n]
3815 && !gfc_expr_is_one (ref->u.ar.stride[n], 0)))
3816 {
3817 full = 0;
3818 break;
3819 }
3820 }
3821 }
3822
3823 if (full)
3824 {
3825 if (se->direct_byref)
3826 {
3827 /* Copy the descriptor for pointer assignments. */
3828 gfc_add_modify_expr (&se->pre, se->expr, desc);
3829 }
3830 else if (se->want_pointer)
3831 {
3832 /* We pass full arrays directly. This means that pointers and
3833 allocatable arrays should also work. */
3834 se->expr = build_fold_addr_expr (desc);
3835 }
3836 else
3837 {
3838 se->expr = desc;
3839 }
3840
3841 if (expr->ts.type == BT_CHARACTER)
3842 se->string_length = gfc_get_expr_charlen (expr);
3843
3844 return;
3845 }
3846 break;
3847
3848 case EXPR_FUNCTION:
3849 /* A transformational function return value will be a temporary
3850 array descriptor. We still need to go through the scalarizer
3851 to create the descriptor. Elemental functions ar handled as
3852 arbitrary expressions, i.e. copy to a temporary. */
3853 secss = ss;
3854 /* Look for the SS for this function. */
3855 while (secss != gfc_ss_terminator
3856 && (secss->type != GFC_SS_FUNCTION || secss->expr != expr))
3857 secss = secss->next;
3858
3859 if (se->direct_byref)
3860 {
3861 gcc_assert (secss != gfc_ss_terminator);
3862
3863 /* For pointer assignments pass the descriptor directly. */
3864 se->ss = secss;
3865 se->expr = build_fold_addr_expr (se->expr);
3866 gfc_conv_expr (se, expr);
3867 return;
3868 }
3869
3870 if (secss == gfc_ss_terminator)
3871 {
3872 /* Elemental function. */
3873 need_tmp = 1;
3874 info = NULL;
3875 }
3876 else
3877 {
3878 /* Transformational function. */
3879 info = &secss->data.info;
3880 need_tmp = 0;
3881 }
3882 break;
3883
3884 default:
3885 /* Something complicated. Copy it into a temporary. */
3886 need_tmp = 1;
3887 secss = NULL;
3888 info = NULL;
3889 break;
3890 }
3891
3892
3893 gfc_init_loopinfo (&loop);
3894
3895 /* Associate the SS with the loop. */
3896 gfc_add_ss_to_loop (&loop, ss);
3897
3898 /* Tell the scalarizer not to bother creating loop variables, etc. */
3899 if (!need_tmp)
3900 loop.array_parameter = 1;
3901 else
3902 /* The right-hand side of a pointer assignment mustn't use a temporary. */
3903 gcc_assert (!se->direct_byref);
3904
3905 /* Setup the scalarizing loops and bounds. */
3906 gfc_conv_ss_startstride (&loop);
3907
3908 if (need_tmp)
3909 {
3910 /* Tell the scalarizer to make a temporary. */
3911 loop.temp_ss = gfc_get_ss ();
3912 loop.temp_ss->type = GFC_SS_TEMP;
3913 loop.temp_ss->next = gfc_ss_terminator;
3914 if (expr->ts.type == BT_CHARACTER)
3915 {
3916 gcc_assert (expr->ts.cl && expr->ts.cl->length
3917 && expr->ts.cl->length->expr_type == EXPR_CONSTANT);
3918 loop.temp_ss->string_length = gfc_conv_mpz_to_tree
3919 (expr->ts.cl->length->value.integer,
3920 expr->ts.cl->length->ts.kind);
3921 expr->ts.cl->backend_decl = loop.temp_ss->string_length;
3922 }
3923 loop.temp_ss->data.temp.type = gfc_typenode_for_spec (&expr->ts);
3924
3925 /* ... which can hold our string, if present. */
3926 if (expr->ts.type == BT_CHARACTER)
3927 {
3928 loop.temp_ss->string_length = TYPE_SIZE_UNIT (loop.temp_ss->data.temp.type);
3929 se->string_length = loop.temp_ss->string_length;
3930 }
3931 else
3932 loop.temp_ss->string_length = NULL;
3933 loop.temp_ss->data.temp.dimen = loop.dimen;
3934 gfc_add_ss_to_loop (&loop, loop.temp_ss);
3935 }
3936
3937 gfc_conv_loop_setup (&loop);
3938
3939 if (need_tmp)
3940 {
3941 /* Copy into a temporary and pass that. We don't need to copy the data
3942 back because expressions and vector subscripts must be INTENT_IN. */
3943 /* TODO: Optimize passing function return values. */
3944 gfc_se lse;
3945 gfc_se rse;
3946
3947 /* Start the copying loops. */
3948 gfc_mark_ss_chain_used (loop.temp_ss, 1);
3949 gfc_mark_ss_chain_used (ss, 1);
3950 gfc_start_scalarized_body (&loop, &block);
3951
3952 /* Copy each data element. */
3953 gfc_init_se (&lse, NULL);
3954 gfc_copy_loopinfo_to_se (&lse, &loop);
3955 gfc_init_se (&rse, NULL);
3956 gfc_copy_loopinfo_to_se (&rse, &loop);
3957
3958 lse.ss = loop.temp_ss;
3959 rse.ss = ss;
3960
3961 gfc_conv_scalarized_array_ref (&lse, NULL);
3962 if (expr->ts.type == BT_CHARACTER)
3963 {
3964 gfc_conv_expr (&rse, expr);
3965 rse.expr = build_fold_indirect_ref (rse.expr);
3966 }
3967 else
3968 gfc_conv_expr_val (&rse, expr);
3969
3970 gfc_add_block_to_block (&block, &rse.pre);
3971 gfc_add_block_to_block (&block, &lse.pre);
3972
3973 gfc_add_modify_expr (&block, lse.expr, rse.expr);
3974
3975 /* Finish the copying loops. */
3976 gfc_trans_scalarizing_loops (&loop, &block);
3977
3978 /* Set the first stride component to zero to indicate a temporary. */
3979 desc = loop.temp_ss->data.info.descriptor;
3980 tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[0]);
3981 gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
3982
3983 gcc_assert (is_gimple_lvalue (desc));
3984 }
3985 else if (expr->expr_type == EXPR_FUNCTION)
3986 {
3987 desc = info->descriptor;
3988 se->string_length = ss->string_length;
3989 }
3990 else
3991 {
3992 /* We pass sections without copying to a temporary. Make a new
3993 descriptor and point it at the section we want. The loop variable
3994 limits will be the limits of the section.
3995 A function may decide to repack the array to speed up access, but
3996 we're not bothered about that here. */
3997 int dim;
3998 tree parm;
3999 tree parmtype;
4000 tree stride;
4001 tree from;
4002 tree to;
4003 tree base;
4004
4005 /* Set the string_length for a character array. */
4006 if (expr->ts.type == BT_CHARACTER)
4007 se->string_length = gfc_get_expr_charlen (expr);
4008
4009 desc = info->descriptor;
4010 gcc_assert (secss && secss != gfc_ss_terminator);
4011 if (se->direct_byref)
4012 {
4013 /* For pointer assignments we fill in the destination. */
4014 parm = se->expr;
4015 parmtype = TREE_TYPE (parm);
4016 }
4017 else
4018 {
4019 /* Otherwise make a new one. */
4020 parmtype = gfc_get_element_type (TREE_TYPE (desc));
4021 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen,
4022 loop.from, loop.to, 0);
4023 parm = gfc_create_var (parmtype, "parm");
4024 }
4025
4026 offset = gfc_index_zero_node;
4027 dim = 0;
4028
4029 /* The following can be somewhat confusing. We have two
4030 descriptors, a new one and the original array.
4031 {parm, parmtype, dim} refer to the new one.
4032 {desc, type, n, secss, loop} refer to the original, which maybe
4033 a descriptorless array.
4034 The bounds of the scalarization are the bounds of the section.
4035 We don't have to worry about numeric overflows when calculating
4036 the offsets because all elements are within the array data. */
4037
4038 /* Set the dtype. */
4039 tmp = gfc_conv_descriptor_dtype (parm);
4040 gfc_add_modify_expr (&loop.pre, tmp, gfc_get_dtype (parmtype));
4041
4042 if (se->direct_byref)
4043 base = gfc_index_zero_node;
4044 else
4045 base = NULL_TREE;
4046
4047 for (n = 0; n < info->ref->u.ar.dimen; n++)
4048 {
4049 stride = gfc_conv_array_stride (desc, n);
4050
4051 /* Work out the offset. */
4052 if (info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4053 {
4054 gcc_assert (info->subscript[n]
4055 && info->subscript[n]->type == GFC_SS_SCALAR);
4056 start = info->subscript[n]->data.scalar.expr;
4057 }
4058 else
4059 {
4060 /* Check we haven't somehow got out of sync. */
4061 gcc_assert (info->dim[dim] == n);
4062
4063 /* Evaluate and remember the start of the section. */
4064 start = info->start[dim];
4065 stride = gfc_evaluate_now (stride, &loop.pre);
4066 }
4067
4068 tmp = gfc_conv_array_lbound (desc, n);
4069 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), start, tmp);
4070
4071 tmp = fold_build2 (MULT_EXPR, TREE_TYPE (tmp), tmp, stride);
4072 offset = fold_build2 (PLUS_EXPR, TREE_TYPE (tmp), offset, tmp);
4073
4074 if (info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4075 {
4076 /* For elemental dimensions, we only need the offset. */
4077 continue;
4078 }
4079
4080 /* Vector subscripts need copying and are handled elsewhere. */
4081 gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_RANGE);
4082
4083 /* Set the new lower bound. */
4084 from = loop.from[dim];
4085 to = loop.to[dim];
4086
4087 /* If we have an array section or are assigning to a pointer,
4088 make sure that the lower bound is 1. References to the full
4089 array should otherwise keep the original bounds. */
4090 if ((info->ref->u.ar.type != AR_FULL || se->direct_byref)
4091 && !integer_onep (from))
4092 {
4093 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4094 gfc_index_one_node, from);
4095 to = fold_build2 (PLUS_EXPR, gfc_array_index_type, to, tmp);
4096 from = gfc_index_one_node;
4097 }
4098 tmp = gfc_conv_descriptor_lbound (parm, gfc_rank_cst[dim]);
4099 gfc_add_modify_expr (&loop.pre, tmp, from);
4100
4101 /* Set the new upper bound. */
4102 tmp = gfc_conv_descriptor_ubound (parm, gfc_rank_cst[dim]);
4103 gfc_add_modify_expr (&loop.pre, tmp, to);
4104
4105 /* Multiply the stride by the section stride to get the
4106 total stride. */
4107 stride = fold_build2 (MULT_EXPR, gfc_array_index_type,
4108 stride, info->stride[dim]);
4109
4110 if (se->direct_byref)
4111 base = fold_build2 (MINUS_EXPR, TREE_TYPE (base),
4112 base, stride);
4113
4114 /* Store the new stride. */
4115 tmp = gfc_conv_descriptor_stride (parm, gfc_rank_cst[dim]);
4116 gfc_add_modify_expr (&loop.pre, tmp, stride);
4117
4118 dim++;
4119 }
4120
4121 /* Point the data pointer at the first element in the section. */
4122 tmp = gfc_conv_array_data (desc);
4123 tmp = build_fold_indirect_ref (tmp);
4124 tmp = gfc_build_array_ref (tmp, offset);
4125 offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
4126 gfc_conv_descriptor_data_set (&loop.pre, parm, offset);
4127
4128 if (se->direct_byref)
4129 {
4130 /* Set the offset. */
4131 tmp = gfc_conv_descriptor_offset (parm);
4132 gfc_add_modify_expr (&loop.pre, tmp, base);
4133 }
4134 else
4135 {
4136 /* Only the callee knows what the correct offset it, so just set
4137 it to zero here. */
4138 tmp = gfc_conv_descriptor_offset (parm);
4139 gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
4140 }
4141 desc = parm;
4142 }
4143
4144 if (!se->direct_byref)
4145 {
4146 /* Get a pointer to the new descriptor. */
4147 if (se->want_pointer)
4148 se->expr = build_fold_addr_expr (desc);
4149 else
4150 se->expr = desc;
4151 }
4152
4153 gfc_add_block_to_block (&se->pre, &loop.pre);
4154 gfc_add_block_to_block (&se->post, &loop.post);
4155
4156 /* Cleanup the scalarizer. */
4157 gfc_cleanup_loop (&loop);
4158 }
4159
4160
4161 /* Convert an array for passing as an actual parameter. */
4162 /* TODO: Optimize passing g77 arrays. */
4163
4164 void
4165 gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77)
4166 {
4167 tree ptr;
4168 tree desc;
4169 tree tmp;
4170 tree stmt;
4171 gfc_symbol *sym;
4172 stmtblock_t block;
4173
4174 /* Passing address of the array if it is not pointer or assumed-shape. */
4175 if (expr->expr_type == EXPR_VARIABLE
4176 && expr->ref->u.ar.type == AR_FULL && g77)
4177 {
4178 sym = expr->symtree->n.sym;
4179 tmp = gfc_get_symbol_decl (sym);
4180
4181 if (sym->ts.type == BT_CHARACTER)
4182 se->string_length = sym->ts.cl->backend_decl;
4183 if (!sym->attr.pointer && sym->as->type != AS_ASSUMED_SHAPE
4184 && !sym->attr.allocatable)
4185 {
4186 /* Some variables are declared directly, others are declared as
4187 pointers and allocated on the heap. */
4188 if (sym->attr.dummy || POINTER_TYPE_P (TREE_TYPE (tmp)))
4189 se->expr = tmp;
4190 else
4191 se->expr = build_fold_addr_expr (tmp);
4192 return;
4193 }
4194 if (sym->attr.allocatable)
4195 {
4196 se->expr = gfc_conv_array_data (tmp);
4197 return;
4198 }
4199 }
4200
4201 se->want_pointer = 1;
4202 gfc_conv_expr_descriptor (se, expr, ss);
4203
4204 if (g77)
4205 {
4206 desc = se->expr;
4207 /* Repack the array. */
4208 tmp = gfc_chainon_list (NULL_TREE, desc);
4209 ptr = build_function_call_expr (gfor_fndecl_in_pack, tmp);
4210 ptr = gfc_evaluate_now (ptr, &se->pre);
4211 se->expr = ptr;
4212
4213 gfc_start_block (&block);
4214
4215 /* Copy the data back. */
4216 tmp = gfc_chainon_list (NULL_TREE, desc);
4217 tmp = gfc_chainon_list (tmp, ptr);
4218 tmp = build_function_call_expr (gfor_fndecl_in_unpack, tmp);
4219 gfc_add_expr_to_block (&block, tmp);
4220
4221 /* Free the temporary. */
4222 tmp = convert (pvoid_type_node, ptr);
4223 tmp = gfc_chainon_list (NULL_TREE, tmp);
4224 tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
4225 gfc_add_expr_to_block (&block, tmp);
4226
4227 stmt = gfc_finish_block (&block);
4228
4229 gfc_init_block (&block);
4230 /* Only if it was repacked. This code needs to be executed before the
4231 loop cleanup code. */
4232 tmp = build_fold_indirect_ref (desc);
4233 tmp = gfc_conv_array_data (tmp);
4234 tmp = build2 (NE_EXPR, boolean_type_node, ptr, tmp);
4235 tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4236
4237 gfc_add_expr_to_block (&block, tmp);
4238 gfc_add_block_to_block (&block, &se->post);
4239
4240 gfc_init_block (&se->post);
4241 gfc_add_block_to_block (&se->post, &block);
4242 }
4243 }
4244
4245
4246 /* NULLIFY an allocatable/pointer array on function entry, free it on exit. */
4247
4248 tree
4249 gfc_trans_deferred_array (gfc_symbol * sym, tree body)
4250 {
4251 tree type;
4252 tree tmp;
4253 tree descriptor;
4254 tree deallocate;
4255 stmtblock_t block;
4256 stmtblock_t fnblock;
4257 locus loc;
4258
4259 /* Make sure the frontend gets these right. */
4260 if (!(sym->attr.pointer || sym->attr.allocatable))
4261 fatal_error
4262 ("Possible frontend bug: Deferred array size without pointer or allocatable attribute.");
4263
4264 gfc_init_block (&fnblock);
4265
4266 gcc_assert (TREE_CODE (sym->backend_decl) == VAR_DECL
4267 || TREE_CODE (sym->backend_decl) == PARM_DECL);
4268
4269 if (sym->ts.type == BT_CHARACTER
4270 && !INTEGER_CST_P (sym->ts.cl->backend_decl))
4271 gfc_trans_init_string_length (sym->ts.cl, &fnblock);
4272
4273 /* Dummy and use associated variables don't need anything special. */
4274 if (sym->attr.dummy || sym->attr.use_assoc)
4275 {
4276 gfc_add_expr_to_block (&fnblock, body);
4277
4278 return gfc_finish_block (&fnblock);
4279 }
4280
4281 gfc_get_backend_locus (&loc);
4282 gfc_set_backend_locus (&sym->declared_at);
4283 descriptor = sym->backend_decl;
4284
4285 if (TREE_STATIC (descriptor))
4286 {
4287 /* SAVEd variables are not freed on exit. */
4288 gfc_trans_static_array_pointer (sym);
4289 return body;
4290 }
4291
4292 /* Get the descriptor type. */
4293 type = TREE_TYPE (sym->backend_decl);
4294 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
4295
4296 /* NULLIFY the data pointer. */
4297 gfc_conv_descriptor_data_set (&fnblock, descriptor, null_pointer_node);
4298
4299 gfc_add_expr_to_block (&fnblock, body);
4300
4301 gfc_set_backend_locus (&loc);
4302 /* Allocatable arrays need to be freed when they go out of scope. */
4303 if (sym->attr.allocatable)
4304 {
4305 gfc_start_block (&block);
4306
4307 /* Deallocate if still allocated at the end of the procedure. */
4308 deallocate = gfc_array_deallocate (descriptor, null_pointer_node);
4309
4310 tmp = gfc_conv_descriptor_data_get (descriptor);
4311 tmp = build2 (NE_EXPR, boolean_type_node, tmp,
4312 build_int_cst (TREE_TYPE (tmp), 0));
4313 tmp = build3_v (COND_EXPR, tmp, deallocate, build_empty_stmt ());
4314 gfc_add_expr_to_block (&block, tmp);
4315
4316 tmp = gfc_finish_block (&block);
4317 gfc_add_expr_to_block (&fnblock, tmp);
4318 }
4319
4320 return gfc_finish_block (&fnblock);
4321 }
4322
4323 /************ Expression Walking Functions ******************/
4324
4325 /* Walk a variable reference.
4326
4327 Possible extension - multiple component subscripts.
4328 x(:,:) = foo%a(:)%b(:)
4329 Transforms to
4330 forall (i=..., j=...)
4331 x(i,j) = foo%a(j)%b(i)
4332 end forall
4333 This adds a fair amout of complexity because you need to deal with more
4334 than one ref. Maybe handle in a similar manner to vector subscripts.
4335 Maybe not worth the effort. */
4336
4337
4338 static gfc_ss *
4339 gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
4340 {
4341 gfc_ref *ref;
4342 gfc_array_ref *ar;
4343 gfc_ss *newss;
4344 gfc_ss *head;
4345 int n;
4346
4347 for (ref = expr->ref; ref; ref = ref->next)
4348 if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
4349 break;
4350
4351 for (; ref; ref = ref->next)
4352 {
4353 if (ref->type == REF_SUBSTRING)
4354 {
4355 newss = gfc_get_ss ();
4356 newss->type = GFC_SS_SCALAR;
4357 newss->expr = ref->u.ss.start;
4358 newss->next = ss;
4359 ss = newss;
4360
4361 newss = gfc_get_ss ();
4362 newss->type = GFC_SS_SCALAR;
4363 newss->expr = ref->u.ss.end;
4364 newss->next = ss;
4365 ss = newss;
4366 }
4367
4368 /* We're only interested in array sections from now on. */
4369 if (ref->type != REF_ARRAY)
4370 continue;
4371
4372 ar = &ref->u.ar;
4373 switch (ar->type)
4374 {
4375 case AR_ELEMENT:
4376 for (n = 0; n < ar->dimen; n++)
4377 {
4378 newss = gfc_get_ss ();
4379 newss->type = GFC_SS_SCALAR;
4380 newss->expr = ar->start[n];
4381 newss->next = ss;
4382 ss = newss;
4383 }
4384 break;
4385
4386 case AR_FULL:
4387 newss = gfc_get_ss ();
4388 newss->type = GFC_SS_SECTION;
4389 newss->expr = expr;
4390 newss->next = ss;
4391 newss->data.info.dimen = ar->as->rank;
4392 newss->data.info.ref = ref;
4393
4394 /* Make sure array is the same as array(:,:), this way
4395 we don't need to special case all the time. */
4396 ar->dimen = ar->as->rank;
4397 for (n = 0; n < ar->dimen; n++)
4398 {
4399 newss->data.info.dim[n] = n;
4400 ar->dimen_type[n] = DIMEN_RANGE;
4401
4402 gcc_assert (ar->start[n] == NULL);
4403 gcc_assert (ar->end[n] == NULL);
4404 gcc_assert (ar->stride[n] == NULL);
4405 }
4406 ss = newss;
4407 break;
4408
4409 case AR_SECTION:
4410 newss = gfc_get_ss ();
4411 newss->type = GFC_SS_SECTION;
4412 newss->expr = expr;
4413 newss->next = ss;
4414 newss->data.info.dimen = 0;
4415 newss->data.info.ref = ref;
4416
4417 head = newss;
4418
4419 /* We add SS chains for all the subscripts in the section. */
4420 for (n = 0; n < ar->dimen; n++)
4421 {
4422 gfc_ss *indexss;
4423
4424 switch (ar->dimen_type[n])
4425 {
4426 case DIMEN_ELEMENT:
4427 /* Add SS for elemental (scalar) subscripts. */
4428 gcc_assert (ar->start[n]);
4429 indexss = gfc_get_ss ();
4430 indexss->type = GFC_SS_SCALAR;
4431 indexss->expr = ar->start[n];
4432 indexss->next = gfc_ss_terminator;
4433 indexss->loop_chain = gfc_ss_terminator;
4434 newss->data.info.subscript[n] = indexss;
4435 break;
4436
4437 case DIMEN_RANGE:
4438 /* We don't add anything for sections, just remember this
4439 dimension for later. */
4440 newss->data.info.dim[newss->data.info.dimen] = n;
4441 newss->data.info.dimen++;
4442 break;
4443
4444 case DIMEN_VECTOR:
4445 /* Create a GFC_SS_VECTOR index in which we can store
4446 the vector's descriptor. */
4447 indexss = gfc_get_ss ();
4448 indexss->type = GFC_SS_VECTOR;
4449 indexss->expr = ar->start[n];
4450 indexss->next = gfc_ss_terminator;
4451 indexss->loop_chain = gfc_ss_terminator;
4452 newss->data.info.subscript[n] = indexss;
4453 newss->data.info.dim[newss->data.info.dimen] = n;
4454 newss->data.info.dimen++;
4455 break;
4456
4457 default:
4458 /* We should know what sort of section it is by now. */
4459 gcc_unreachable ();
4460 }
4461 }
4462 /* We should have at least one non-elemental dimension. */
4463 gcc_assert (newss->data.info.dimen > 0);
4464 ss = newss;
4465 break;
4466
4467 default:
4468 /* We should know what sort of section it is by now. */
4469 gcc_unreachable ();
4470 }
4471
4472 }
4473 return ss;
4474 }
4475
4476
4477 /* Walk an expression operator. If only one operand of a binary expression is
4478 scalar, we must also add the scalar term to the SS chain. */
4479
4480 static gfc_ss *
4481 gfc_walk_op_expr (gfc_ss * ss, gfc_expr * expr)
4482 {
4483 gfc_ss *head;
4484 gfc_ss *head2;
4485 gfc_ss *newss;
4486
4487 head = gfc_walk_subexpr (ss, expr->value.op.op1);
4488 if (expr->value.op.op2 == NULL)
4489 head2 = head;
4490 else
4491 head2 = gfc_walk_subexpr (head, expr->value.op.op2);
4492
4493 /* All operands are scalar. Pass back and let the caller deal with it. */
4494 if (head2 == ss)
4495 return head2;
4496
4497 /* All operands require scalarization. */
4498 if (head != ss && (expr->value.op.op2 == NULL || head2 != head))
4499 return head2;
4500
4501 /* One of the operands needs scalarization, the other is scalar.
4502 Create a gfc_ss for the scalar expression. */
4503 newss = gfc_get_ss ();
4504 newss->type = GFC_SS_SCALAR;
4505 if (head == ss)
4506 {
4507 /* First operand is scalar. We build the chain in reverse order, so
4508 add the scarar SS after the second operand. */
4509 head = head2;
4510 while (head && head->next != ss)
4511 head = head->next;
4512 /* Check we haven't somehow broken the chain. */
4513 gcc_assert (head);
4514 newss->next = ss;
4515 head->next = newss;
4516 newss->expr = expr->value.op.op1;
4517 }
4518 else /* head2 == head */
4519 {
4520 gcc_assert (head2 == head);
4521 /* Second operand is scalar. */
4522 newss->next = head2;
4523 head2 = newss;
4524 newss->expr = expr->value.op.op2;
4525 }
4526
4527 return head2;
4528 }
4529
4530
4531 /* Reverse a SS chain. */
4532
4533 gfc_ss *
4534 gfc_reverse_ss (gfc_ss * ss)
4535 {
4536 gfc_ss *next;
4537 gfc_ss *head;
4538
4539 gcc_assert (ss != NULL);
4540
4541 head = gfc_ss_terminator;
4542 while (ss != gfc_ss_terminator)
4543 {
4544 next = ss->next;
4545 /* Check we didn't somehow break the chain. */
4546 gcc_assert (next != NULL);
4547 ss->next = head;
4548 head = ss;
4549 ss = next;
4550 }
4551
4552 return (head);
4553 }
4554
4555
4556 /* Walk the arguments of an elemental function. */
4557
4558 gfc_ss *
4559 gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
4560 gfc_ss_type type)
4561 {
4562 int scalar;
4563 gfc_ss *head;
4564 gfc_ss *tail;
4565 gfc_ss *newss;
4566
4567 head = gfc_ss_terminator;
4568 tail = NULL;
4569 scalar = 1;
4570 for (; arg; arg = arg->next)
4571 {
4572 if (!arg->expr)
4573 continue;
4574
4575 newss = gfc_walk_subexpr (head, arg->expr);
4576 if (newss == head)
4577 {
4578 /* Scalar argument. */
4579 newss = gfc_get_ss ();
4580 newss->type = type;
4581 newss->expr = arg->expr;
4582 newss->next = head;
4583 }
4584 else
4585 scalar = 0;
4586
4587 head = newss;
4588 if (!tail)
4589 {
4590 tail = head;
4591 while (tail->next != gfc_ss_terminator)
4592 tail = tail->next;
4593 }
4594 }
4595
4596 if (scalar)
4597 {
4598 /* If all the arguments are scalar we don't need the argument SS. */
4599 gfc_free_ss_chain (head);
4600 /* Pass it back. */
4601 return ss;
4602 }
4603
4604 /* Add it onto the existing chain. */
4605 tail->next = ss;
4606 return head;
4607 }
4608
4609
4610 /* Walk a function call. Scalar functions are passed back, and taken out of
4611 scalarization loops. For elemental functions we walk their arguments.
4612 The result of functions returning arrays is stored in a temporary outside
4613 the loop, so that the function is only called once. Hence we do not need
4614 to walk their arguments. */
4615
4616 static gfc_ss *
4617 gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
4618 {
4619 gfc_ss *newss;
4620 gfc_intrinsic_sym *isym;
4621 gfc_symbol *sym;
4622
4623 isym = expr->value.function.isym;
4624
4625 /* Handle intrinsic functions separately. */
4626 if (isym)
4627 return gfc_walk_intrinsic_function (ss, expr, isym);
4628
4629 sym = expr->value.function.esym;
4630 if (!sym)
4631 sym = expr->symtree->n.sym;
4632
4633 /* A function that returns arrays. */
4634 if (gfc_return_by_reference (sym) && sym->result->attr.dimension)
4635 {
4636 newss = gfc_get_ss ();
4637 newss->type = GFC_SS_FUNCTION;
4638 newss->expr = expr;
4639 newss->next = ss;
4640 newss->data.info.dimen = expr->rank;
4641 return newss;
4642 }
4643
4644 /* Walk the parameters of an elemental function. For now we always pass
4645 by reference. */
4646 if (sym->attr.elemental)
4647 return gfc_walk_elemental_function_args (ss, expr->value.function.actual,
4648 GFC_SS_REFERENCE);
4649
4650 /* Scalar functions are OK as these are evaluated outside the scalarization
4651 loop. Pass back and let the caller deal with it. */
4652 return ss;
4653 }
4654
4655
4656 /* An array temporary is constructed for array constructors. */
4657
4658 static gfc_ss *
4659 gfc_walk_array_constructor (gfc_ss * ss, gfc_expr * expr)
4660 {
4661 gfc_ss *newss;
4662 int n;
4663
4664 newss = gfc_get_ss ();
4665 newss->type = GFC_SS_CONSTRUCTOR;
4666 newss->expr = expr;
4667 newss->next = ss;
4668 newss->data.info.dimen = expr->rank;
4669 for (n = 0; n < expr->rank; n++)
4670 newss->data.info.dim[n] = n;
4671
4672 return newss;
4673 }
4674
4675
4676 /* Walk an expression. Add walked expressions to the head of the SS chain.
4677 A wholly scalar expression will not be added. */
4678
4679 static gfc_ss *
4680 gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr)
4681 {
4682 gfc_ss *head;
4683
4684 switch (expr->expr_type)
4685 {
4686 case EXPR_VARIABLE:
4687 head = gfc_walk_variable_expr (ss, expr);
4688 return head;
4689
4690 case EXPR_OP:
4691 head = gfc_walk_op_expr (ss, expr);
4692 return head;
4693
4694 case EXPR_FUNCTION:
4695 head = gfc_walk_function_expr (ss, expr);
4696 return head;
4697
4698 case EXPR_CONSTANT:
4699 case EXPR_NULL:
4700 case EXPR_STRUCTURE:
4701 /* Pass back and let the caller deal with it. */
4702 break;
4703
4704 case EXPR_ARRAY:
4705 head = gfc_walk_array_constructor (ss, expr);
4706 return head;
4707
4708 case EXPR_SUBSTRING:
4709 /* Pass back and let the caller deal with it. */
4710 break;
4711
4712 default:
4713 internal_error ("bad expression type during walk (%d)",
4714 expr->expr_type);
4715 }
4716 return ss;
4717 }
4718
4719
4720 /* Entry point for expression walking.
4721 A return value equal to the passed chain means this is
4722 a scalar expression. It is up to the caller to take whatever action is
4723 necessary to translate these. */
4724
4725 gfc_ss *
4726 gfc_walk_expr (gfc_expr * expr)
4727 {
4728 gfc_ss *res;
4729
4730 res = gfc_walk_subexpr (gfc_ss_terminator, expr);
4731 return gfc_reverse_ss (res);
4732 }