1 /* Array translation routines
2 Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 /* trans-array.c-- Various array related code, including scalarization,
24 allocation, initialization and other support routines. */
26 /* How the scalarizer works.
27 In gfortran, array expressions use the same core routines as scalar
29 First, a Scalarization State (SS) chain is built. This is done by walking
30 the expression tree, and building a linear list of the terms in the
31 expression. As the tree is walked, scalar subexpressions are translated.
33 The scalarization parameters are stored in a gfc_loopinfo structure.
34 First the start and stride of each term is calculated by
35 gfc_conv_ss_startstride. During this process the expressions for the array
36 descriptors and data pointers are also translated.
38 If the expression is an assignment, we must then resolve any dependencies.
39 In fortran all the rhs values of an assignment must be evaluated before
40 any assignments take place. This can require a temporary array to store the
41 values. We also require a temporary when we are passing array expressions
42 or vector subecripts as procedure parameters.
44 Array sections are passed without copying to a temporary. These use the
45 scalarizer to determine the shape of the section. The flag
46 loop->array_parameter tells the scalarizer that the actual values and loop
47 variables will not be required.
49 The function gfc_conv_loop_setup generates the scalarization setup code.
50 It determines the range of the scalarizing loop variables. If a temporary
51 is required, this is created and initialized. Code for scalar expressions
52 taken outside the loop is also generated at this time. Next the offset and
53 scaling required to translate from loop variables to array indices for each
56 A call to gfc_start_scalarized_body marks the start of the scalarized
57 expression. This creates a scope and declares the loop variables. Before
58 calling this gfc_make_ss_chain_used must be used to indicate which terms
59 will be used inside this loop.
61 The scalar gfc_conv_* functions are then used to build the main body of the
62 scalarization loop. Scalarization loop variables and precalculated scalar
63 values are automatically substituted. Note that gfc_advance_se_ss_chain
64 must be used, rather than changing the se->ss directly.
66 For assignment expressions requiring a temporary two sub loops are
67 generated. The first stores the result of the expression in the temporary,
68 the second copies it to the result. A call to
69 gfc_trans_scalarized_loop_boundary marks the end of the main loop code and
70 the start of the copying loop. The temporary may be less than full rank.
72 Finally gfc_trans_scalarizing_loops is called to generate the implicit do
73 loops. The loops are added to the pre chain of the loopinfo. The post
74 chain may still contain cleanup code.
76 After the loop code has been added into its parent scope gfc_cleanup_loop
77 is called to free all the SS allocated by the scalarizer. */
81 #include "coretypes.h"
83 #include "tree-gimple.h"
90 #include "trans-stmt.h"
91 #include "trans-types.h"
92 #include "trans-array.h"
93 #include "trans-const.h"
94 #include "dependency.h"
96 static gfc_ss
*gfc_walk_subexpr (gfc_ss
*, gfc_expr
*);
98 /* The contents of this structure aren't actually used, just the address. */
99 static gfc_ss gfc_ss_terminator_var
;
100 gfc_ss
* const gfc_ss_terminator
= &gfc_ss_terminator_var
;
104 gfc_array_dataptr_type (tree desc
)
106 return (GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc
)));
110 /* Build expressions to access the members of an array descriptor.
111 It's surprisingly easy to mess up here, so never access
112 an array descriptor by "brute force", always use these
113 functions. This also avoids problems if we change the format
114 of an array descriptor.
116 To understand these magic numbers, look at the comments
117 before gfc_build_array_type() in trans-types.c.
119 The code within these defines should be the only code which knows the format
120 of an array descriptor.
122 Any code just needing to read obtain the bounds of an array should use
123 gfc_conv_array_* rather than the following functions as these will return
124 know constant values, and work with arrays which do not have descriptors.
126 Don't forget to #undef these! */
129 #define OFFSET_FIELD 1
130 #define DTYPE_FIELD 2
131 #define DIMENSION_FIELD 3
133 #define STRIDE_SUBFIELD 0
134 #define LBOUND_SUBFIELD 1
135 #define UBOUND_SUBFIELD 2
138 gfc_conv_descriptor_data (tree desc
)
143 type
= TREE_TYPE (desc
);
144 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type
));
146 field
= TYPE_FIELDS (type
);
147 gcc_assert (DATA_FIELD
== 0);
148 gcc_assert (field
!= NULL_TREE
149 && TREE_CODE (TREE_TYPE (field
)) == POINTER_TYPE
150 && TREE_CODE (TREE_TYPE (TREE_TYPE (field
))) == ARRAY_TYPE
);
152 return build3 (COMPONENT_REF
, TREE_TYPE (field
), desc
, field
, NULL_TREE
);
156 gfc_conv_descriptor_offset (tree desc
)
161 type
= TREE_TYPE (desc
);
162 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type
));
164 field
= gfc_advance_chain (TYPE_FIELDS (type
), OFFSET_FIELD
);
165 gcc_assert (field
!= NULL_TREE
&& TREE_TYPE (field
) == gfc_array_index_type
);
167 return build3 (COMPONENT_REF
, TREE_TYPE (field
), desc
, field
, NULL_TREE
);
171 gfc_conv_descriptor_dtype (tree desc
)
176 type
= TREE_TYPE (desc
);
177 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type
));
179 field
= gfc_advance_chain (TYPE_FIELDS (type
), DTYPE_FIELD
);
180 gcc_assert (field
!= NULL_TREE
&& TREE_TYPE (field
) == gfc_array_index_type
);
182 return build3 (COMPONENT_REF
, TREE_TYPE (field
), desc
, field
, NULL_TREE
);
186 gfc_conv_descriptor_dimension (tree desc
, tree dim
)
192 type
= TREE_TYPE (desc
);
193 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type
));
195 field
= gfc_advance_chain (TYPE_FIELDS (type
), DIMENSION_FIELD
);
196 gcc_assert (field
!= NULL_TREE
197 && TREE_CODE (TREE_TYPE (field
)) == ARRAY_TYPE
198 && TREE_CODE (TREE_TYPE (TREE_TYPE (field
))) == RECORD_TYPE
);
200 tmp
= build3 (COMPONENT_REF
, TREE_TYPE (field
), desc
, field
, NULL_TREE
);
201 tmp
= gfc_build_array_ref (tmp
, dim
);
206 gfc_conv_descriptor_stride (tree desc
, tree dim
)
211 tmp
= gfc_conv_descriptor_dimension (desc
, dim
);
212 field
= TYPE_FIELDS (TREE_TYPE (tmp
));
213 field
= gfc_advance_chain (field
, STRIDE_SUBFIELD
);
214 gcc_assert (field
!= NULL_TREE
&& TREE_TYPE (field
) == gfc_array_index_type
);
216 tmp
= build3 (COMPONENT_REF
, TREE_TYPE (field
), tmp
, field
, NULL_TREE
);
221 gfc_conv_descriptor_lbound (tree desc
, tree dim
)
226 tmp
= gfc_conv_descriptor_dimension (desc
, dim
);
227 field
= TYPE_FIELDS (TREE_TYPE (tmp
));
228 field
= gfc_advance_chain (field
, LBOUND_SUBFIELD
);
229 gcc_assert (field
!= NULL_TREE
&& TREE_TYPE (field
) == gfc_array_index_type
);
231 tmp
= build3 (COMPONENT_REF
, TREE_TYPE (field
), tmp
, field
, NULL_TREE
);
236 gfc_conv_descriptor_ubound (tree desc
, tree dim
)
241 tmp
= gfc_conv_descriptor_dimension (desc
, dim
);
242 field
= TYPE_FIELDS (TREE_TYPE (tmp
));
243 field
= gfc_advance_chain (field
, UBOUND_SUBFIELD
);
244 gcc_assert (field
!= NULL_TREE
&& TREE_TYPE (field
) == gfc_array_index_type
);
246 tmp
= build3 (COMPONENT_REF
, TREE_TYPE (field
), tmp
, field
, NULL_TREE
);
251 /* Build an null array descriptor constructor. */
254 gfc_build_null_descriptor (tree type
)
259 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type
));
260 gcc_assert (DATA_FIELD
== 0);
261 field
= TYPE_FIELDS (type
);
263 /* Set a NULL data pointer. */
264 tmp
= tree_cons (field
, null_pointer_node
, NULL_TREE
);
265 tmp
= build1 (CONSTRUCTOR
, type
, tmp
);
266 TREE_CONSTANT (tmp
) = 1;
267 TREE_INVARIANT (tmp
) = 1;
268 /* All other fields are ignored. */
274 /* Cleanup those #defines. */
279 #undef DIMENSION_FIELD
280 #undef STRIDE_SUBFIELD
281 #undef LBOUND_SUBFIELD
282 #undef UBOUND_SUBFIELD
285 /* Mark a SS chain as used. Flags specifies in which loops the SS is used.
286 flags & 1 = Main loop body.
287 flags & 2 = temp copy loop. */
290 gfc_mark_ss_chain_used (gfc_ss
* ss
, unsigned flags
)
292 for (; ss
!= gfc_ss_terminator
; ss
= ss
->next
)
293 ss
->useflags
= flags
;
296 static void gfc_free_ss (gfc_ss
*);
299 /* Free a gfc_ss chain. */
302 gfc_free_ss_chain (gfc_ss
* ss
)
306 while (ss
!= gfc_ss_terminator
)
308 gcc_assert (ss
!= NULL
);
319 gfc_free_ss (gfc_ss
* ss
)
327 for (n
= 0; n
< GFC_MAX_DIMENSIONS
; n
++)
329 if (ss
->data
.info
.subscript
[n
])
330 gfc_free_ss_chain (ss
->data
.info
.subscript
[n
]);
342 /* Free all the SS associated with a loop. */
345 gfc_cleanup_loop (gfc_loopinfo
* loop
)
351 while (ss
!= gfc_ss_terminator
)
353 gcc_assert (ss
!= NULL
);
354 next
= ss
->loop_chain
;
361 /* Associate a SS chain with a loop. */
364 gfc_add_ss_to_loop (gfc_loopinfo
* loop
, gfc_ss
* head
)
368 if (head
== gfc_ss_terminator
)
372 for (; ss
&& ss
!= gfc_ss_terminator
; ss
= ss
->next
)
374 if (ss
->next
== gfc_ss_terminator
)
375 ss
->loop_chain
= loop
->ss
;
377 ss
->loop_chain
= ss
->next
;
379 gcc_assert (ss
== gfc_ss_terminator
);
384 /* Generate an initializer for a static pointer or allocatable array. */
387 gfc_trans_static_array_pointer (gfc_symbol
* sym
)
391 gcc_assert (TREE_STATIC (sym
->backend_decl
));
392 /* Just zero the data member. */
393 type
= TREE_TYPE (sym
->backend_decl
);
394 DECL_INITIAL (sym
->backend_decl
) = gfc_build_null_descriptor (type
);
398 /* Generate code to allocate an array temporary, or create a variable to
399 hold the data. If size is NULL zero the descriptor so that so that the
400 callee will allocate the array. Also generates code to free the array
404 gfc_trans_allocate_array_storage (gfc_loopinfo
* loop
, gfc_ss_info
* info
,
405 tree size
, tree nelem
)
413 desc
= info
->descriptor
;
414 data
= gfc_conv_descriptor_data (desc
);
415 if (size
== NULL_TREE
)
417 /* A callee allocated array. */
418 gfc_add_modify_expr (&loop
->pre
, data
, convert (TREE_TYPE (data
),
419 gfc_index_zero_node
));
421 info
->offset
= gfc_index_zero_node
;
426 /* Allocate the temporary. */
427 onstack
= gfc_can_put_var_on_stack (size
);
431 /* Make a temporary variable to hold the data. */
432 tmp
= fold_build2 (MINUS_EXPR
, TREE_TYPE (nelem
), nelem
,
434 tmp
= build_range_type (gfc_array_index_type
, gfc_index_zero_node
,
436 tmp
= build_array_type (gfc_get_element_type (TREE_TYPE (desc
)),
438 tmp
= gfc_create_var (tmp
, "A");
439 tmp
= gfc_build_addr_expr (TREE_TYPE (data
), tmp
);
440 gfc_add_modify_expr (&loop
->pre
, data
, tmp
);
442 info
->offset
= gfc_index_zero_node
;
447 /* Allocate memory to hold the data. */
448 args
= gfc_chainon_list (NULL_TREE
, size
);
450 if (gfc_index_integer_kind
== 4)
451 tmp
= gfor_fndecl_internal_malloc
;
452 else if (gfc_index_integer_kind
== 8)
453 tmp
= gfor_fndecl_internal_malloc64
;
456 tmp
= gfc_build_function_call (tmp
, args
);
457 tmp
= convert (TREE_TYPE (data
), tmp
);
458 gfc_add_modify_expr (&loop
->pre
, data
, tmp
);
461 info
->offset
= gfc_index_zero_node
;
465 /* The offset is zero because we create temporaries with a zero
467 tmp
= gfc_conv_descriptor_offset (desc
);
468 gfc_add_modify_expr (&loop
->pre
, tmp
, gfc_index_zero_node
);
472 /* Free the temporary. */
473 tmp
= convert (pvoid_type_node
, info
->data
);
474 tmp
= gfc_chainon_list (NULL_TREE
, tmp
);
475 tmp
= gfc_build_function_call (gfor_fndecl_internal_free
, tmp
);
476 gfc_add_expr_to_block (&loop
->post
, tmp
);
481 /* Generate code to allocate and initialize the descriptor for a temporary
482 array. This is used for both temporaries needed by the scalarizer, and
483 functions returning arrays. Adjusts the loop variables to be zero-based,
484 and calculates the loop bounds for callee allocated arrays.
485 Also fills in the descriptor, data and offset fields of info if known.
486 Returns the size of the array, or NULL for a callee allocated array. */
489 gfc_trans_allocate_temp_array (gfc_loopinfo
* loop
, gfc_ss_info
* info
,
500 gcc_assert (info
->dimen
> 0);
501 /* Set the lower bound to zero. */
502 for (dim
= 0; dim
< info
->dimen
; dim
++)
504 n
= loop
->order
[dim
];
505 if (n
< loop
->temp_dim
)
506 gcc_assert (integer_zerop (loop
->from
[n
]));
509 /* Callee allocated arrays may not have a known bound yet. */
511 loop
->to
[n
] = fold_build2 (MINUS_EXPR
, gfc_array_index_type
,
512 loop
->to
[n
], loop
->from
[n
]);
513 loop
->from
[n
] = gfc_index_zero_node
;
516 info
->delta
[dim
] = gfc_index_zero_node
;
517 info
->start
[dim
] = gfc_index_zero_node
;
518 info
->stride
[dim
] = gfc_index_one_node
;
519 info
->dim
[dim
] = dim
;
522 /* Initialize the descriptor. */
524 gfc_get_array_type_bounds (eltype
, info
->dimen
, loop
->from
, loop
->to
, 1);
525 desc
= gfc_create_var (type
, "atmp");
526 GFC_DECL_PACKED_ARRAY (desc
) = 1;
528 info
->descriptor
= desc
;
529 size
= gfc_index_one_node
;
531 /* Fill in the array dtype. */
532 tmp
= gfc_conv_descriptor_dtype (desc
);
533 gfc_add_modify_expr (&loop
->pre
, tmp
, gfc_get_dtype (TREE_TYPE (desc
)));
536 Fill in the bounds and stride. This is a packed array, so:
539 for (n = 0; n < rank; n++)
542 delta = ubound[n] + 1 - lbound[n];
545 size = size * sizeof(element);
548 for (n
= 0; n
< info
->dimen
; n
++)
550 if (loop
->to
[n
] == NULL_TREE
)
552 /* For a callee allocated array express the loop bounds in terms
553 of the descriptor fields. */
554 tmp
= build2 (MINUS_EXPR
, gfc_array_index_type
,
555 gfc_conv_descriptor_ubound (desc
, gfc_rank_cst
[n
]),
556 gfc_conv_descriptor_lbound (desc
, gfc_rank_cst
[n
]));
562 /* Store the stride and bound components in the descriptor. */
563 tmp
= gfc_conv_descriptor_stride (desc
, gfc_rank_cst
[n
]);
564 gfc_add_modify_expr (&loop
->pre
, tmp
, size
);
566 tmp
= gfc_conv_descriptor_lbound (desc
, gfc_rank_cst
[n
]);
567 gfc_add_modify_expr (&loop
->pre
, tmp
, gfc_index_zero_node
);
569 tmp
= gfc_conv_descriptor_ubound (desc
, gfc_rank_cst
[n
]);
570 gfc_add_modify_expr (&loop
->pre
, tmp
, loop
->to
[n
]);
572 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
573 loop
->to
[n
], gfc_index_one_node
);
575 size
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, size
, tmp
);
576 size
= gfc_evaluate_now (size
, &loop
->pre
);
579 /* Get the size of the array. */
582 size
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, size
,
583 TYPE_SIZE_UNIT (gfc_get_element_type (type
)));
585 gfc_trans_allocate_array_storage (loop
, info
, size
, nelem
);
587 if (info
->dimen
> loop
->temp_dim
)
588 loop
->temp_dim
= info
->dimen
;
594 /* Make sure offset is a variable. */
597 gfc_put_offset_into_var (stmtblock_t
* pblock
, tree
* poffset
,
600 /* We should have already created the offset variable. We cannot
601 create it here because we may be in an inner scope. */
602 gcc_assert (*offsetvar
!= NULL_TREE
);
603 gfc_add_modify_expr (pblock
, *offsetvar
, *poffset
);
604 *poffset
= *offsetvar
;
605 TREE_USED (*offsetvar
) = 1;
609 /* Assign an element of an array constructor. */
612 gfc_trans_array_ctor_element (stmtblock_t
* pblock
, tree pointer
,
613 tree offset
, gfc_se
* se
, gfc_expr
* expr
)
618 gfc_conv_expr (se
, expr
);
620 /* Store the value. */
621 tmp
= gfc_build_indirect_ref (pointer
);
622 tmp
= gfc_build_array_ref (tmp
, offset
);
623 if (expr
->ts
.type
== BT_CHARACTER
)
625 gfc_conv_string_parameter (se
);
626 if (POINTER_TYPE_P (TREE_TYPE (tmp
)))
628 /* The temporary is an array of pointers. */
629 se
->expr
= fold_convert (TREE_TYPE (tmp
), se
->expr
);
630 gfc_add_modify_expr (&se
->pre
, tmp
, se
->expr
);
634 /* The temporary is an array of string values. */
635 tmp
= gfc_build_addr_expr (pchar_type_node
, tmp
);
636 /* We know the temporary and the value will be the same length,
637 so can use memcpy. */
638 args
= gfc_chainon_list (NULL_TREE
, tmp
);
639 args
= gfc_chainon_list (args
, se
->expr
);
640 args
= gfc_chainon_list (args
, se
->string_length
);
641 tmp
= built_in_decls
[BUILT_IN_MEMCPY
];
642 tmp
= gfc_build_function_call (tmp
, args
);
643 gfc_add_expr_to_block (&se
->pre
, tmp
);
648 /* TODO: Should the frontend already have done this conversion? */
649 se
->expr
= fold_convert (TREE_TYPE (tmp
), se
->expr
);
650 gfc_add_modify_expr (&se
->pre
, tmp
, se
->expr
);
653 gfc_add_block_to_block (pblock
, &se
->pre
);
654 gfc_add_block_to_block (pblock
, &se
->post
);
658 /* Add the contents of an array to the constructor. */
661 gfc_trans_array_constructor_subarray (stmtblock_t
* pblock
,
662 tree type ATTRIBUTE_UNUSED
,
663 tree pointer
, gfc_expr
* expr
,
664 tree
* poffset
, tree
* offsetvar
)
672 /* We need this to be a variable so we can increment it. */
673 gfc_put_offset_into_var (pblock
, poffset
, offsetvar
);
675 gfc_init_se (&se
, NULL
);
677 /* Walk the array expression. */
678 ss
= gfc_walk_expr (expr
);
679 gcc_assert (ss
!= gfc_ss_terminator
);
681 /* Initialize the scalarizer. */
682 gfc_init_loopinfo (&loop
);
683 gfc_add_ss_to_loop (&loop
, ss
);
685 /* Initialize the loop. */
686 gfc_conv_ss_startstride (&loop
);
687 gfc_conv_loop_setup (&loop
);
689 /* Make the loop body. */
690 gfc_mark_ss_chain_used (ss
, 1);
691 gfc_start_scalarized_body (&loop
, &body
);
692 gfc_copy_loopinfo_to_se (&se
, &loop
);
695 if (expr
->ts
.type
== BT_CHARACTER
)
696 gfc_todo_error ("character arrays in constructors");
698 gfc_trans_array_ctor_element (&body
, pointer
, *poffset
, &se
, expr
);
699 gcc_assert (se
.ss
== gfc_ss_terminator
);
701 /* Increment the offset. */
702 tmp
= build2 (PLUS_EXPR
, gfc_array_index_type
, *poffset
, gfc_index_one_node
);
703 gfc_add_modify_expr (&body
, *poffset
, tmp
);
705 /* Finish the loop. */
706 gfc_trans_scalarizing_loops (&loop
, &body
);
707 gfc_add_block_to_block (&loop
.pre
, &loop
.post
);
708 tmp
= gfc_finish_block (&loop
.pre
);
709 gfc_add_expr_to_block (pblock
, tmp
);
711 gfc_cleanup_loop (&loop
);
715 /* Assign the values to the elements of an array constructor. */
718 gfc_trans_array_constructor_value (stmtblock_t
* pblock
, tree type
,
719 tree pointer
, gfc_constructor
* c
,
720 tree
* poffset
, tree
* offsetvar
)
726 for (; c
; c
= c
->next
)
728 /* If this is an iterator or an array, the offset must be a variable. */
729 if ((c
->iterator
|| c
->expr
->rank
> 0) && INTEGER_CST_P (*poffset
))
730 gfc_put_offset_into_var (pblock
, poffset
, offsetvar
);
732 gfc_start_block (&body
);
734 if (c
->expr
->expr_type
== EXPR_ARRAY
)
736 /* Array constructors can be nested. */
737 gfc_trans_array_constructor_value (&body
, type
, pointer
,
738 c
->expr
->value
.constructor
,
741 else if (c
->expr
->rank
> 0)
743 gfc_trans_array_constructor_subarray (&body
, type
, pointer
,
744 c
->expr
, poffset
, offsetvar
);
748 /* This code really upsets the gimplifier so don't bother for now. */
755 while (p
&& !(p
->iterator
|| p
->expr
->expr_type
!= EXPR_CONSTANT
))
763 gfc_init_se (&se
, NULL
);
764 gfc_trans_array_ctor_element (&body
, pointer
, *poffset
, &se
,
767 *poffset
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
768 *poffset
, gfc_index_one_node
);
772 /* Collect multiple scalar constants into a constructor. */
780 /* Count the number of consecutive scalar constants. */
781 while (p
&& !(p
->iterator
782 || p
->expr
->expr_type
!= EXPR_CONSTANT
))
784 gfc_init_se (&se
, NULL
);
785 gfc_conv_constant (&se
, p
->expr
);
786 if (p
->expr
->ts
.type
== BT_CHARACTER
787 && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE
788 (TREE_TYPE (pointer
)))))
790 /* For constant character array constructors we build
791 an array of pointers. */
792 se
.expr
= gfc_build_addr_expr (pchar_type_node
,
796 list
= tree_cons (NULL_TREE
, se
.expr
, list
);
801 bound
= build_int_cst (NULL_TREE
, n
- 1);
802 /* Create an array type to hold them. */
803 tmptype
= build_range_type (gfc_array_index_type
,
804 gfc_index_zero_node
, bound
);
805 tmptype
= build_array_type (type
, tmptype
);
807 init
= build1 (CONSTRUCTOR
, tmptype
, nreverse (list
));
808 TREE_CONSTANT (init
) = 1;
809 TREE_INVARIANT (init
) = 1;
810 TREE_STATIC (init
) = 1;
811 /* Create a static variable to hold the data. */
812 tmp
= gfc_create_var (tmptype
, "data");
813 TREE_STATIC (tmp
) = 1;
814 TREE_CONSTANT (tmp
) = 1;
815 TREE_INVARIANT (tmp
) = 1;
816 DECL_INITIAL (tmp
) = init
;
819 /* Use BUILTIN_MEMCPY to assign the values. */
820 tmp
= gfc_build_indirect_ref (pointer
);
821 tmp
= gfc_build_array_ref (tmp
, *poffset
);
822 tmp
= gfc_build_addr_expr (NULL
, tmp
);
823 init
= gfc_build_addr_expr (NULL
, init
);
825 size
= TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type
));
826 bound
= build_int_cst (NULL_TREE
, n
* size
);
827 tmp
= gfc_chainon_list (NULL_TREE
, tmp
);
828 tmp
= gfc_chainon_list (tmp
, init
);
829 tmp
= gfc_chainon_list (tmp
, bound
);
830 tmp
= gfc_build_function_call (built_in_decls
[BUILT_IN_MEMCPY
],
832 gfc_add_expr_to_block (&body
, tmp
);
834 *poffset
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
837 if (!INTEGER_CST_P (*poffset
))
839 gfc_add_modify_expr (&body
, *offsetvar
, *poffset
);
840 *poffset
= *offsetvar
;
844 /* The frontend should already have done any expansions possible
848 /* Pass the code as is. */
849 tmp
= gfc_finish_block (&body
);
850 gfc_add_expr_to_block (pblock
, tmp
);
854 /* Build the implied do-loop. */
862 loopbody
= gfc_finish_block (&body
);
864 gfc_init_se (&se
, NULL
);
865 gfc_conv_expr (&se
, c
->iterator
->var
);
866 gfc_add_block_to_block (pblock
, &se
.pre
);
869 /* Initialize the loop. */
870 gfc_init_se (&se
, NULL
);
871 gfc_conv_expr_val (&se
, c
->iterator
->start
);
872 gfc_add_block_to_block (pblock
, &se
.pre
);
873 gfc_add_modify_expr (pblock
, loopvar
, se
.expr
);
875 gfc_init_se (&se
, NULL
);
876 gfc_conv_expr_val (&se
, c
->iterator
->end
);
877 gfc_add_block_to_block (pblock
, &se
.pre
);
878 end
= gfc_evaluate_now (se
.expr
, pblock
);
880 gfc_init_se (&se
, NULL
);
881 gfc_conv_expr_val (&se
, c
->iterator
->step
);
882 gfc_add_block_to_block (pblock
, &se
.pre
);
883 step
= gfc_evaluate_now (se
.expr
, pblock
);
885 /* Generate the loop body. */
886 exit_label
= gfc_build_label_decl (NULL_TREE
);
887 gfc_start_block (&body
);
889 /* Generate the exit condition. Depending on the sign of
890 the step variable we have to generate the correct
892 tmp
= fold_build2 (GT_EXPR
, boolean_type_node
, step
,
893 build_int_cst (TREE_TYPE (step
), 0));
894 cond
= fold_build3 (COND_EXPR
, boolean_type_node
, tmp
,
895 build2 (GT_EXPR
, boolean_type_node
,
897 build2 (LT_EXPR
, boolean_type_node
,
899 tmp
= build1_v (GOTO_EXPR
, exit_label
);
900 TREE_USED (exit_label
) = 1;
901 tmp
= build3_v (COND_EXPR
, cond
, tmp
, build_empty_stmt ());
902 gfc_add_expr_to_block (&body
, tmp
);
904 /* The main loop body. */
905 gfc_add_expr_to_block (&body
, loopbody
);
907 /* Increase loop variable by step. */
908 tmp
= build2 (PLUS_EXPR
, TREE_TYPE (loopvar
), loopvar
, step
);
909 gfc_add_modify_expr (&body
, loopvar
, tmp
);
911 /* Finish the loop. */
912 tmp
= gfc_finish_block (&body
);
913 tmp
= build1_v (LOOP_EXPR
, tmp
);
914 gfc_add_expr_to_block (pblock
, tmp
);
916 /* Add the exit label. */
917 tmp
= build1_v (LABEL_EXPR
, exit_label
);
918 gfc_add_expr_to_block (pblock
, tmp
);
924 /* Get the size of an expression. Returns -1 if the size isn't constant.
925 Implied do loops with non-constant bounds are tricky because we must only
926 evaluate the bounds once. */
929 gfc_get_array_cons_size (mpz_t
* size
, gfc_constructor
* c
)
935 mpz_set_ui (*size
, 0);
939 for (; c
; c
= c
->next
)
941 if (c
->expr
->expr_type
== EXPR_ARRAY
)
943 /* A nested array constructor. */
944 gfc_get_array_cons_size (&len
, c
->expr
->value
.constructor
);
945 if (mpz_sgn (len
) < 0)
947 mpz_set (*size
, len
);
955 if (c
->expr
->rank
> 0)
957 mpz_set_si (*size
, -1);
969 if (i
->start
->expr_type
!= EXPR_CONSTANT
970 || i
->end
->expr_type
!= EXPR_CONSTANT
971 || i
->step
->expr_type
!= EXPR_CONSTANT
)
973 mpz_set_si (*size
, -1);
979 mpz_add (val
, i
->end
->value
.integer
, i
->start
->value
.integer
);
980 mpz_tdiv_q (val
, val
, i
->step
->value
.integer
);
981 mpz_add_ui (val
, val
, 1);
982 mpz_mul (len
, len
, val
);
984 mpz_add (*size
, *size
, len
);
991 /* Figure out the string length of a variable reference expression.
992 Used by get_array_ctor_strlen. */
995 get_array_ctor_var_strlen (gfc_expr
* expr
, tree
* len
)
1000 /* Don't bother if we already know the length is a constant. */
1001 if (*len
&& INTEGER_CST_P (*len
))
1004 ts
= &expr
->symtree
->n
.sym
->ts
;
1005 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
1010 /* Array references don't change the string length. */
1014 /* Use the length of the component. */
1015 ts
= &ref
->u
.c
.component
->ts
;
1019 /* TODO: Substrings are tricky because we can't evaluate the
1020 expression more than once. For now we just give up, and hope
1021 we can figure it out elsewhere. */
1026 *len
= ts
->cl
->backend_decl
;
1030 /* Figure out the string length of a character array constructor.
1031 Returns TRUE if all elements are character constants. */
1034 get_array_ctor_strlen (gfc_constructor
* c
, tree
* len
)
1039 for (; c
; c
= c
->next
)
1041 switch (c
->expr
->expr_type
)
1044 if (!(*len
&& INTEGER_CST_P (*len
)))
1045 *len
= build_int_cstu (gfc_charlen_type_node
,
1046 c
->expr
->value
.character
.length
);
1050 if (!get_array_ctor_strlen (c
->expr
->value
.constructor
, len
))
1056 get_array_ctor_var_strlen (c
->expr
, len
);
1061 /* TODO: For now we just ignore anything we don't know how to
1062 handle, and hope we can figure it out a different way. */
1071 /* Array constructors are handled by constructing a temporary, then using that
1072 within the scalarization loop. This is not optimal, but seems by far the
1076 gfc_trans_array_constructor (gfc_loopinfo
* loop
, gfc_ss
* ss
)
1085 ss
->data
.info
.dimen
= loop
->dimen
;
1087 if (ss
->expr
->ts
.type
== BT_CHARACTER
)
1089 const_string
= get_array_ctor_strlen (ss
->expr
->value
.constructor
,
1090 &ss
->string_length
);
1091 if (!ss
->string_length
)
1092 gfc_todo_error ("complex character array constructors");
1094 type
= gfc_get_character_type_len (ss
->expr
->ts
.kind
, ss
->string_length
);
1096 type
= build_pointer_type (type
);
1100 const_string
= TRUE
;
1101 type
= gfc_typenode_for_spec (&ss
->expr
->ts
);
1104 size
= gfc_trans_allocate_temp_array (loop
, &ss
->data
.info
, type
);
1106 desc
= ss
->data
.info
.descriptor
;
1107 offset
= gfc_index_zero_node
;
1108 offsetvar
= gfc_create_var_np (gfc_array_index_type
, "offset");
1109 TREE_USED (offsetvar
) = 0;
1110 gfc_trans_array_constructor_value (&loop
->pre
, type
,
1112 ss
->expr
->value
.constructor
, &offset
,
1115 if (TREE_USED (offsetvar
))
1116 pushdecl (offsetvar
);
1118 gcc_assert (INTEGER_CST_P (offset
));
1120 /* Disable bound checking for now because it's probably broken. */
1121 if (flag_bounds_check
)
1129 /* Add the pre and post chains for all the scalar expressions in a SS chain
1130 to loop. This is called after the loop parameters have been calculated,
1131 but before the actual scalarizing loops. */
1134 gfc_add_loop_ss_code (gfc_loopinfo
* loop
, gfc_ss
* ss
, bool subscript
)
1139 /* TODO: This can generate bad code if there are ordering dependencies.
1140 eg. a callee allocated function and an unknown size constructor. */
1141 gcc_assert (ss
!= NULL
);
1143 for (; ss
!= gfc_ss_terminator
; ss
= ss
->loop_chain
)
1150 /* Scalar expression. Evaluate this now. This includes elemental
1151 dimension indices, but not array section bounds. */
1152 gfc_init_se (&se
, NULL
);
1153 gfc_conv_expr (&se
, ss
->expr
);
1154 gfc_add_block_to_block (&loop
->pre
, &se
.pre
);
1156 if (ss
->expr
->ts
.type
!= BT_CHARACTER
)
1158 /* Move the evaluation of scalar expressions outside the
1159 scalarization loop. */
1161 se
.expr
= convert(gfc_array_index_type
, se
.expr
);
1162 se
.expr
= gfc_evaluate_now (se
.expr
, &loop
->pre
);
1163 gfc_add_block_to_block (&loop
->pre
, &se
.post
);
1166 gfc_add_block_to_block (&loop
->post
, &se
.post
);
1168 ss
->data
.scalar
.expr
= se
.expr
;
1169 ss
->string_length
= se
.string_length
;
1172 case GFC_SS_REFERENCE
:
1173 /* Scalar reference. Evaluate this now. */
1174 gfc_init_se (&se
, NULL
);
1175 gfc_conv_expr_reference (&se
, ss
->expr
);
1176 gfc_add_block_to_block (&loop
->pre
, &se
.pre
);
1177 gfc_add_block_to_block (&loop
->post
, &se
.post
);
1179 ss
->data
.scalar
.expr
= gfc_evaluate_now (se
.expr
, &loop
->pre
);
1180 ss
->string_length
= se
.string_length
;
1183 case GFC_SS_SECTION
:
1185 /* Scalarized expression. Evaluate any scalar subscripts. */
1186 for (n
= 0; n
< GFC_MAX_DIMENSIONS
; n
++)
1188 /* Add the expressions for scalar subscripts. */
1189 if (ss
->data
.info
.subscript
[n
])
1190 gfc_add_loop_ss_code (loop
, ss
->data
.info
.subscript
[n
], true);
1194 case GFC_SS_INTRINSIC
:
1195 gfc_add_intrinsic_ss_code (loop
, ss
);
1198 case GFC_SS_FUNCTION
:
1199 /* Array function return value. We call the function and save its
1200 result in a temporary for use inside the loop. */
1201 gfc_init_se (&se
, NULL
);
1204 gfc_conv_expr (&se
, ss
->expr
);
1205 gfc_add_block_to_block (&loop
->pre
, &se
.pre
);
1206 gfc_add_block_to_block (&loop
->post
, &se
.post
);
1209 case GFC_SS_CONSTRUCTOR
:
1210 gfc_trans_array_constructor (loop
, ss
);
1214 case GFC_SS_COMPONENT
:
1215 /* Do nothing. These are handled elsewhere. */
1225 /* Translate expressions for the descriptor and data pointer of a SS. */
1229 gfc_conv_ss_descriptor (stmtblock_t
* block
, gfc_ss
* ss
, int base
)
1234 /* Get the descriptor for the array to be scalarized. */
1235 gcc_assert (ss
->expr
->expr_type
== EXPR_VARIABLE
);
1236 gfc_init_se (&se
, NULL
);
1237 se
.descriptor_only
= 1;
1238 gfc_conv_expr_lhs (&se
, ss
->expr
);
1239 gfc_add_block_to_block (block
, &se
.pre
);
1240 ss
->data
.info
.descriptor
= se
.expr
;
1241 ss
->string_length
= se
.string_length
;
1245 /* Also the data pointer. */
1246 tmp
= gfc_conv_array_data (se
.expr
);
1247 /* If this is a variable or address of a variable we use it directly.
1248 Otherwise we must evaluate it now to avoid breaking dependency
1249 analysis by pulling the expressions for elemental array indices
1252 || (TREE_CODE (tmp
) == ADDR_EXPR
1253 && DECL_P (TREE_OPERAND (tmp
, 0)))))
1254 tmp
= gfc_evaluate_now (tmp
, block
);
1255 ss
->data
.info
.data
= tmp
;
1257 tmp
= gfc_conv_array_offset (se
.expr
);
1258 ss
->data
.info
.offset
= gfc_evaluate_now (tmp
, block
);
1263 /* Initialize a gfc_loopinfo structure. */
1266 gfc_init_loopinfo (gfc_loopinfo
* loop
)
1270 memset (loop
, 0, sizeof (gfc_loopinfo
));
1271 gfc_init_block (&loop
->pre
);
1272 gfc_init_block (&loop
->post
);
1274 /* Initially scalarize in order. */
1275 for (n
= 0; n
< GFC_MAX_DIMENSIONS
; n
++)
1278 loop
->ss
= gfc_ss_terminator
;
1282 /* Copies the loop variable info to a gfc_se structure. Does not copy the SS
1286 gfc_copy_loopinfo_to_se (gfc_se
* se
, gfc_loopinfo
* loop
)
1292 /* Return an expression for the data pointer of an array. */
1295 gfc_conv_array_data (tree descriptor
)
1299 type
= TREE_TYPE (descriptor
);
1300 if (GFC_ARRAY_TYPE_P (type
))
1302 if (TREE_CODE (type
) == POINTER_TYPE
)
1306 /* Descriptorless arrays. */
1307 return gfc_build_addr_expr (NULL
, descriptor
);
1311 return gfc_conv_descriptor_data (descriptor
);
1315 /* Return an expression for the base offset of an array. */
1318 gfc_conv_array_offset (tree descriptor
)
1322 type
= TREE_TYPE (descriptor
);
1323 if (GFC_ARRAY_TYPE_P (type
))
1324 return GFC_TYPE_ARRAY_OFFSET (type
);
1326 return gfc_conv_descriptor_offset (descriptor
);
1330 /* Get an expression for the array stride. */
1333 gfc_conv_array_stride (tree descriptor
, int dim
)
1338 type
= TREE_TYPE (descriptor
);
1340 /* For descriptorless arrays use the array size. */
1341 tmp
= GFC_TYPE_ARRAY_STRIDE (type
, dim
);
1342 if (tmp
!= NULL_TREE
)
1345 tmp
= gfc_conv_descriptor_stride (descriptor
, gfc_rank_cst
[dim
]);
1350 /* Like gfc_conv_array_stride, but for the lower bound. */
1353 gfc_conv_array_lbound (tree descriptor
, int dim
)
1358 type
= TREE_TYPE (descriptor
);
1360 tmp
= GFC_TYPE_ARRAY_LBOUND (type
, dim
);
1361 if (tmp
!= NULL_TREE
)
1364 tmp
= gfc_conv_descriptor_lbound (descriptor
, gfc_rank_cst
[dim
]);
1369 /* Like gfc_conv_array_stride, but for the upper bound. */
1372 gfc_conv_array_ubound (tree descriptor
, int dim
)
1377 type
= TREE_TYPE (descriptor
);
1379 tmp
= GFC_TYPE_ARRAY_UBOUND (type
, dim
);
1380 if (tmp
!= NULL_TREE
)
1383 /* This should only ever happen when passing an assumed shape array
1384 as an actual parameter. The value will never be used. */
1385 if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor
)))
1386 return gfc_index_zero_node
;
1388 tmp
= gfc_conv_descriptor_ubound (descriptor
, gfc_rank_cst
[dim
]);
1393 /* Translate an array reference. The descriptor should be in se->expr.
1394 Do not use this function, it wil be removed soon. */
1398 gfc_conv_array_index_ref (gfc_se
* se
, tree pointer
, tree
* indices
,
1399 tree offset
, int dimen
)
1406 array
= gfc_build_indirect_ref (pointer
);
1409 for (n
= 0; n
< dimen
; n
++)
1411 /* index = index + stride[n]*indices[n] */
1412 tmp
= gfc_conv_array_stride (se
->expr
, n
);
1413 tmp
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, indices
[n
], tmp
);
1415 index
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
, index
, tmp
);
1418 /* Result = data[index]. */
1419 tmp
= gfc_build_array_ref (array
, index
);
1421 /* Check we've used the correct number of dimensions. */
1422 gcc_assert (TREE_CODE (TREE_TYPE (tmp
)) != ARRAY_TYPE
);
1428 /* Generate code to perform an array index bound check. */
1431 gfc_trans_array_bound_check (gfc_se
* se
, tree descriptor
, tree index
, int n
)
1437 if (!flag_bounds_check
)
1440 index
= gfc_evaluate_now (index
, &se
->pre
);
1441 /* Check lower bound. */
1442 tmp
= gfc_conv_array_lbound (descriptor
, n
);
1443 fault
= fold_build2 (LT_EXPR
, boolean_type_node
, index
, tmp
);
1444 /* Check upper bound. */
1445 tmp
= gfc_conv_array_ubound (descriptor
, n
);
1446 cond
= fold_build2 (GT_EXPR
, boolean_type_node
, index
, tmp
);
1447 fault
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, fault
, cond
);
1449 gfc_trans_runtime_check (fault
, gfc_strconst_fault
, &se
->pre
);
1455 /* A reference to an array vector subscript. Uses recursion to handle nested
1456 vector subscripts. */
1459 gfc_conv_vector_array_index (gfc_se
* se
, tree index
, gfc_ss
* ss
)
1462 tree indices
[GFC_MAX_DIMENSIONS
];
1467 gcc_assert (ss
&& ss
->type
== GFC_SS_VECTOR
);
1469 /* Save the descriptor. */
1470 descsave
= se
->expr
;
1471 info
= &ss
->data
.info
;
1472 se
->expr
= info
->descriptor
;
1474 ar
= &info
->ref
->u
.ar
;
1475 for (n
= 0; n
< ar
->dimen
; n
++)
1477 switch (ar
->dimen_type
[n
])
1480 gcc_assert (info
->subscript
[n
] != gfc_ss_terminator
1481 && info
->subscript
[n
]->type
== GFC_SS_SCALAR
);
1482 indices
[n
] = info
->subscript
[n
]->data
.scalar
.expr
;
1490 index
= gfc_conv_vector_array_index (se
, index
, info
->subscript
[n
]);
1493 gfc_trans_array_bound_check (se
, info
->descriptor
, index
, n
);
1500 /* Get the index from the vector. */
1501 gfc_conv_array_index_ref (se
, info
->data
, indices
, info
->offset
, ar
->dimen
);
1503 /* Put the descriptor back. */
1504 se
->expr
= descsave
;
1510 /* Return the offset for an index. Performs bound checking for elemental
1511 dimensions. Single element references are processed separately. */
1514 gfc_conv_array_index_offset (gfc_se
* se
, gfc_ss_info
* info
, int dim
, int i
,
1515 gfc_array_ref
* ar
, tree stride
)
1519 /* Get the index into the array for this dimension. */
1522 gcc_assert (ar
->type
!= AR_ELEMENT
);
1523 if (ar
->dimen_type
[dim
] == DIMEN_ELEMENT
)
1525 gcc_assert (i
== -1);
1526 /* Elemental dimension. */
1527 gcc_assert (info
->subscript
[dim
]
1528 && info
->subscript
[dim
]->type
== GFC_SS_SCALAR
);
1529 /* We've already translated this value outside the loop. */
1530 index
= info
->subscript
[dim
]->data
.scalar
.expr
;
1533 gfc_trans_array_bound_check (se
, info
->descriptor
, index
, dim
);
1537 /* Scalarized dimension. */
1538 gcc_assert (info
&& se
->loop
);
1540 /* Multiply the loop variable by the stride and delta. */
1541 index
= se
->loop
->loopvar
[i
];
1542 index
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, index
,
1544 index
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
, index
,
1547 if (ar
->dimen_type
[dim
] == DIMEN_VECTOR
)
1549 /* Handle vector subscripts. */
1550 index
= gfc_conv_vector_array_index (se
, index
,
1551 info
->subscript
[dim
]);
1553 gfc_trans_array_bound_check (se
, info
->descriptor
, index
,
1557 gcc_assert (ar
->dimen_type
[dim
] == DIMEN_RANGE
);
1562 /* Temporary array or derived type component. */
1563 gcc_assert (se
->loop
);
1564 index
= se
->loop
->loopvar
[se
->loop
->order
[i
]];
1565 if (!integer_zerop (info
->delta
[i
]))
1566 index
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
1567 index
, info
->delta
[i
]);
1570 /* Multiply by the stride. */
1571 index
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, index
, stride
);
1577 /* Build a scalarized reference to an array. */
1580 gfc_conv_scalarized_array_ref (gfc_se
* se
, gfc_array_ref
* ar
)
1587 info
= &se
->ss
->data
.info
;
1589 n
= se
->loop
->order
[0];
1593 index
= gfc_conv_array_index_offset (se
, info
, info
->dim
[n
], n
, ar
,
1595 /* Add the offset for this dimension to the stored offset for all other
1597 index
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
, index
, info
->offset
);
1599 tmp
= gfc_build_indirect_ref (info
->data
);
1600 se
->expr
= gfc_build_array_ref (tmp
, index
);
1604 /* Translate access of temporary array. */
1607 gfc_conv_tmp_array_ref (gfc_se
* se
)
1609 se
->string_length
= se
->ss
->string_length
;
1610 gfc_conv_scalarized_array_ref (se
, NULL
);
1614 /* Build an array reference. se->expr already holds the array descriptor.
1615 This should be either a variable, indirect variable reference or component
1616 reference. For arrays which do not have a descriptor, se->expr will be
1618 a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
1621 gfc_conv_array_ref (gfc_se
* se
, gfc_array_ref
* ar
)
1630 /* Handle scalarized references separately. */
1631 if (ar
->type
!= AR_ELEMENT
)
1633 gfc_conv_scalarized_array_ref (se
, ar
);
1637 index
= gfc_index_zero_node
;
1639 fault
= gfc_index_zero_node
;
1641 /* Calculate the offsets from all the dimensions. */
1642 for (n
= 0; n
< ar
->dimen
; n
++)
1644 /* Calculate the index for this dimension. */
1645 gfc_init_se (&indexse
, NULL
);
1646 gfc_conv_expr_type (&indexse
, ar
->start
[n
], gfc_array_index_type
);
1647 gfc_add_block_to_block (&se
->pre
, &indexse
.pre
);
1649 if (flag_bounds_check
)
1651 /* Check array bounds. */
1654 indexse
.expr
= gfc_evaluate_now (indexse
.expr
, &se
->pre
);
1656 tmp
= gfc_conv_array_lbound (se
->expr
, n
);
1657 cond
= fold_build2 (LT_EXPR
, boolean_type_node
,
1660 fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, fault
, cond
);
1662 tmp
= gfc_conv_array_ubound (se
->expr
, n
);
1663 cond
= fold_build2 (GT_EXPR
, boolean_type_node
,
1666 fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, fault
, cond
);
1669 /* Multiply the index by the stride. */
1670 stride
= gfc_conv_array_stride (se
->expr
, n
);
1671 tmp
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, indexse
.expr
,
1674 /* And add it to the total. */
1675 index
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
, index
, tmp
);
1678 if (flag_bounds_check
)
1679 gfc_trans_runtime_check (fault
, gfc_strconst_fault
, &se
->pre
);
1681 tmp
= gfc_conv_array_offset (se
->expr
);
1682 if (!integer_zerop (tmp
))
1683 index
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
, index
, tmp
);
1685 /* Access the calculated element. */
1686 tmp
= gfc_conv_array_data (se
->expr
);
1687 tmp
= gfc_build_indirect_ref (tmp
);
1688 se
->expr
= gfc_build_array_ref (tmp
, index
);
1692 /* Generate the code to be executed immediately before entering a
1693 scalarization loop. */
1696 gfc_trans_preloop_setup (gfc_loopinfo
* loop
, int dim
, int flag
,
1697 stmtblock_t
* pblock
)
1706 /* This code will be executed before entering the scalarization loop
1707 for this dimension. */
1708 for (ss
= loop
->ss
; ss
!= gfc_ss_terminator
; ss
= ss
->loop_chain
)
1710 if ((ss
->useflags
& flag
) == 0)
1713 if (ss
->type
!= GFC_SS_SECTION
1714 && ss
->type
!= GFC_SS_FUNCTION
&& ss
->type
!= GFC_SS_CONSTRUCTOR
1715 && ss
->type
!= GFC_SS_COMPONENT
)
1718 info
= &ss
->data
.info
;
1720 if (dim
>= info
->dimen
)
1723 if (dim
== info
->dimen
- 1)
1725 /* For the outermost loop calculate the offset due to any
1726 elemental dimensions. It will have been initialized with the
1727 base offset of the array. */
1730 for (i
= 0; i
< info
->ref
->u
.ar
.dimen
; i
++)
1732 if (info
->ref
->u
.ar
.dimen_type
[i
] != DIMEN_ELEMENT
)
1735 gfc_init_se (&se
, NULL
);
1737 se
.expr
= info
->descriptor
;
1738 stride
= gfc_conv_array_stride (info
->descriptor
, i
);
1739 index
= gfc_conv_array_index_offset (&se
, info
, i
, -1,
1742 gfc_add_block_to_block (pblock
, &se
.pre
);
1744 info
->offset
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
1745 info
->offset
, index
);
1746 info
->offset
= gfc_evaluate_now (info
->offset
, pblock
);
1750 stride
= gfc_conv_array_stride (info
->descriptor
, info
->dim
[i
]);
1753 stride
= gfc_conv_array_stride (info
->descriptor
, 0);
1755 /* Calculate the stride of the innermost loop. Hopefully this will
1756 allow the backend optimizers to do their stuff more effectively.
1758 info
->stride0
= gfc_evaluate_now (stride
, pblock
);
1762 /* Add the offset for the previous loop dimension. */
1767 ar
= &info
->ref
->u
.ar
;
1768 i
= loop
->order
[dim
+ 1];
1776 gfc_init_se (&se
, NULL
);
1778 se
.expr
= info
->descriptor
;
1779 stride
= gfc_conv_array_stride (info
->descriptor
, info
->dim
[i
]);
1780 index
= gfc_conv_array_index_offset (&se
, info
, info
->dim
[i
], i
,
1782 gfc_add_block_to_block (pblock
, &se
.pre
);
1783 info
->offset
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
1784 info
->offset
, index
);
1785 info
->offset
= gfc_evaluate_now (info
->offset
, pblock
);
1788 /* Remember this offset for the second loop. */
1789 if (dim
== loop
->temp_dim
- 1)
1790 info
->saved_offset
= info
->offset
;
1795 /* Start a scalarized expression. Creates a scope and declares loop
1799 gfc_start_scalarized_body (gfc_loopinfo
* loop
, stmtblock_t
* pbody
)
1805 gcc_assert (!loop
->array_parameter
);
1807 for (dim
= loop
->dimen
- 1; dim
>= 0; dim
--)
1809 n
= loop
->order
[dim
];
1811 gfc_start_block (&loop
->code
[n
]);
1813 /* Create the loop variable. */
1814 loop
->loopvar
[n
] = gfc_create_var (gfc_array_index_type
, "S");
1816 if (dim
< loop
->temp_dim
)
1820 /* Calculate values that will be constant within this loop. */
1821 gfc_trans_preloop_setup (loop
, dim
, flags
, &loop
->code
[n
]);
1823 gfc_start_block (pbody
);
1827 /* Generates the actual loop code for a scalarization loop. */
1830 gfc_trans_scalarized_loop_end (gfc_loopinfo
* loop
, int n
,
1831 stmtblock_t
* pbody
)
1839 loopbody
= gfc_finish_block (pbody
);
1841 /* Initialize the loopvar. */
1842 gfc_add_modify_expr (&loop
->code
[n
], loop
->loopvar
[n
], loop
->from
[n
]);
1844 exit_label
= gfc_build_label_decl (NULL_TREE
);
1846 /* Generate the loop body. */
1847 gfc_init_block (&block
);
1849 /* The exit condition. */
1850 cond
= build2 (GT_EXPR
, boolean_type_node
, loop
->loopvar
[n
], loop
->to
[n
]);
1851 tmp
= build1_v (GOTO_EXPR
, exit_label
);
1852 TREE_USED (exit_label
) = 1;
1853 tmp
= build3_v (COND_EXPR
, cond
, tmp
, build_empty_stmt ());
1854 gfc_add_expr_to_block (&block
, tmp
);
1856 /* The main body. */
1857 gfc_add_expr_to_block (&block
, loopbody
);
1859 /* Increment the loopvar. */
1860 tmp
= build2 (PLUS_EXPR
, gfc_array_index_type
,
1861 loop
->loopvar
[n
], gfc_index_one_node
);
1862 gfc_add_modify_expr (&block
, loop
->loopvar
[n
], tmp
);
1864 /* Build the loop. */
1865 tmp
= gfc_finish_block (&block
);
1866 tmp
= build1_v (LOOP_EXPR
, tmp
);
1867 gfc_add_expr_to_block (&loop
->code
[n
], tmp
);
1869 /* Add the exit label. */
1870 tmp
= build1_v (LABEL_EXPR
, exit_label
);
1871 gfc_add_expr_to_block (&loop
->code
[n
], tmp
);
1875 /* Finishes and generates the loops for a scalarized expression. */
1878 gfc_trans_scalarizing_loops (gfc_loopinfo
* loop
, stmtblock_t
* body
)
1883 stmtblock_t
*pblock
;
1887 /* Generate the loops. */
1888 for (dim
= 0; dim
< loop
->dimen
; dim
++)
1890 n
= loop
->order
[dim
];
1891 gfc_trans_scalarized_loop_end (loop
, n
, pblock
);
1892 loop
->loopvar
[n
] = NULL_TREE
;
1893 pblock
= &loop
->code
[n
];
1896 tmp
= gfc_finish_block (pblock
);
1897 gfc_add_expr_to_block (&loop
->pre
, tmp
);
1899 /* Clear all the used flags. */
1900 for (ss
= loop
->ss
; ss
; ss
= ss
->loop_chain
)
1905 /* Finish the main body of a scalarized expression, and start the secondary
1909 gfc_trans_scalarized_loop_boundary (gfc_loopinfo
* loop
, stmtblock_t
* body
)
1913 stmtblock_t
*pblock
;
1917 /* We finish as many loops as are used by the temporary. */
1918 for (dim
= 0; dim
< loop
->temp_dim
- 1; dim
++)
1920 n
= loop
->order
[dim
];
1921 gfc_trans_scalarized_loop_end (loop
, n
, pblock
);
1922 loop
->loopvar
[n
] = NULL_TREE
;
1923 pblock
= &loop
->code
[n
];
1926 /* We don't want to finish the outermost loop entirely. */
1927 n
= loop
->order
[loop
->temp_dim
- 1];
1928 gfc_trans_scalarized_loop_end (loop
, n
, pblock
);
1930 /* Restore the initial offsets. */
1931 for (ss
= loop
->ss
; ss
!= gfc_ss_terminator
; ss
= ss
->loop_chain
)
1933 if ((ss
->useflags
& 2) == 0)
1936 if (ss
->type
!= GFC_SS_SECTION
1937 && ss
->type
!= GFC_SS_FUNCTION
&& ss
->type
!= GFC_SS_CONSTRUCTOR
1938 && ss
->type
!= GFC_SS_COMPONENT
)
1941 ss
->data
.info
.offset
= ss
->data
.info
.saved_offset
;
1944 /* Restart all the inner loops we just finished. */
1945 for (dim
= loop
->temp_dim
- 2; dim
>= 0; dim
--)
1947 n
= loop
->order
[dim
];
1949 gfc_start_block (&loop
->code
[n
]);
1951 loop
->loopvar
[n
] = gfc_create_var (gfc_array_index_type
, "Q");
1953 gfc_trans_preloop_setup (loop
, dim
, 2, &loop
->code
[n
]);
1956 /* Start a block for the secondary copying code. */
1957 gfc_start_block (body
);
1961 /* Calculate the upper bound of an array section. */
1964 gfc_conv_section_upper_bound (gfc_ss
* ss
, int n
, stmtblock_t
* pblock
)
1973 gcc_assert (ss
->type
== GFC_SS_SECTION
);
1975 /* For vector array subscripts we want the size of the vector. */
1976 dim
= ss
->data
.info
.dim
[n
];
1978 while (vecss
->data
.info
.ref
->u
.ar
.dimen_type
[dim
] == DIMEN_VECTOR
)
1980 vecss
= vecss
->data
.info
.subscript
[dim
];
1981 gcc_assert (vecss
&& vecss
->type
== GFC_SS_VECTOR
);
1982 dim
= vecss
->data
.info
.dim
[0];
1985 gcc_assert (vecss
->data
.info
.ref
->u
.ar
.dimen_type
[dim
] == DIMEN_RANGE
);
1986 end
= vecss
->data
.info
.ref
->u
.ar
.end
[dim
];
1987 desc
= vecss
->data
.info
.descriptor
;
1991 /* The upper bound was specified. */
1992 gfc_init_se (&se
, NULL
);
1993 gfc_conv_expr_type (&se
, end
, gfc_array_index_type
);
1994 gfc_add_block_to_block (pblock
, &se
.pre
);
1999 /* No upper bound was specified, so use the bound of the array. */
2000 bound
= gfc_conv_array_ubound (desc
, dim
);
2007 /* Calculate the lower bound of an array section. */
2010 gfc_conv_section_startstride (gfc_loopinfo
* loop
, gfc_ss
* ss
, int n
)
2020 info
= &ss
->data
.info
;
2024 /* For vector array subscripts we want the size of the vector. */
2026 while (vecss
->data
.info
.ref
->u
.ar
.dimen_type
[dim
] == DIMEN_VECTOR
)
2028 vecss
= vecss
->data
.info
.subscript
[dim
];
2029 gcc_assert (vecss
&& vecss
->type
== GFC_SS_VECTOR
);
2030 /* Get the descriptors for the vector subscripts as well. */
2031 if (!vecss
->data
.info
.descriptor
)
2032 gfc_conv_ss_descriptor (&loop
->pre
, vecss
, !loop
->array_parameter
);
2033 dim
= vecss
->data
.info
.dim
[0];
2036 gcc_assert (vecss
->data
.info
.ref
->u
.ar
.dimen_type
[dim
] == DIMEN_RANGE
);
2037 start
= vecss
->data
.info
.ref
->u
.ar
.start
[dim
];
2038 stride
= vecss
->data
.info
.ref
->u
.ar
.stride
[dim
];
2039 desc
= vecss
->data
.info
.descriptor
;
2041 /* Calculate the start of the range. For vector subscripts this will
2042 be the range of the vector. */
2045 /* Specified section start. */
2046 gfc_init_se (&se
, NULL
);
2047 gfc_conv_expr_type (&se
, start
, gfc_array_index_type
);
2048 gfc_add_block_to_block (&loop
->pre
, &se
.pre
);
2049 info
->start
[n
] = se
.expr
;
2053 /* No lower bound specified so use the bound of the array. */
2054 info
->start
[n
] = gfc_conv_array_lbound (desc
, dim
);
2056 info
->start
[n
] = gfc_evaluate_now (info
->start
[n
], &loop
->pre
);
2058 /* Calculate the stride. */
2060 info
->stride
[n
] = gfc_index_one_node
;
2063 gfc_init_se (&se
, NULL
);
2064 gfc_conv_expr_type (&se
, stride
, gfc_array_index_type
);
2065 gfc_add_block_to_block (&loop
->pre
, &se
.pre
);
2066 info
->stride
[n
] = gfc_evaluate_now (se
.expr
, &loop
->pre
);
2071 /* Calculates the range start and stride for a SS chain. Also gets the
2072 descriptor and data pointer. The range of vector subscripts is the size
2073 of the vector. Array bounds are also checked. */
2076 gfc_conv_ss_startstride (gfc_loopinfo
* loop
)
2085 /* Determine the rank of the loop. */
2087 ss
!= gfc_ss_terminator
&& loop
->dimen
== 0; ss
= ss
->loop_chain
)
2091 case GFC_SS_SECTION
:
2092 case GFC_SS_CONSTRUCTOR
:
2093 case GFC_SS_FUNCTION
:
2094 case GFC_SS_COMPONENT
:
2095 loop
->dimen
= ss
->data
.info
.dimen
;
2103 if (loop
->dimen
== 0)
2104 gfc_todo_error ("Unable to determine rank of expression");
2107 /* Loop over all the SS in the chain. */
2108 for (ss
= loop
->ss
; ss
!= gfc_ss_terminator
; ss
= ss
->loop_chain
)
2110 if (ss
->expr
&& ss
->expr
->shape
&& !ss
->shape
)
2111 ss
->shape
= ss
->expr
->shape
;
2115 case GFC_SS_SECTION
:
2116 /* Get the descriptor for the array. */
2117 gfc_conv_ss_descriptor (&loop
->pre
, ss
, !loop
->array_parameter
);
2119 for (n
= 0; n
< ss
->data
.info
.dimen
; n
++)
2120 gfc_conv_section_startstride (loop
, ss
, n
);
2123 case GFC_SS_CONSTRUCTOR
:
2124 case GFC_SS_FUNCTION
:
2125 for (n
= 0; n
< ss
->data
.info
.dimen
; n
++)
2127 ss
->data
.info
.start
[n
] = gfc_index_zero_node
;
2128 ss
->data
.info
.stride
[n
] = gfc_index_one_node
;
2137 /* The rest is just runtime bound checking. */
2138 if (flag_bounds_check
)
2144 tree size
[GFC_MAX_DIMENSIONS
];
2148 gfc_start_block (&block
);
2150 fault
= integer_zero_node
;
2151 for (n
= 0; n
< loop
->dimen
; n
++)
2152 size
[n
] = NULL_TREE
;
2154 for (ss
= loop
->ss
; ss
!= gfc_ss_terminator
; ss
= ss
->loop_chain
)
2156 if (ss
->type
!= GFC_SS_SECTION
)
2159 /* TODO: range checking for mapped dimensions. */
2160 info
= &ss
->data
.info
;
2162 /* This only checks scalarized dimensions, elemental dimensions are
2164 for (n
= 0; n
< loop
->dimen
; n
++)
2168 while (vecss
->data
.info
.ref
->u
.ar
.dimen_type
[dim
]
2171 vecss
= vecss
->data
.info
.subscript
[dim
];
2172 gcc_assert (vecss
&& vecss
->type
== GFC_SS_VECTOR
);
2173 dim
= vecss
->data
.info
.dim
[0];
2175 gcc_assert (vecss
->data
.info
.ref
->u
.ar
.dimen_type
[dim
]
2177 desc
= vecss
->data
.info
.descriptor
;
2179 /* Check lower bound. */
2180 bound
= gfc_conv_array_lbound (desc
, dim
);
2181 tmp
= info
->start
[n
];
2182 tmp
= fold_build2 (LT_EXPR
, boolean_type_node
, tmp
, bound
);
2183 fault
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, fault
,
2186 /* Check the upper bound. */
2187 bound
= gfc_conv_array_ubound (desc
, dim
);
2188 end
= gfc_conv_section_upper_bound (ss
, n
, &block
);
2189 tmp
= fold_build2 (GT_EXPR
, boolean_type_node
, end
, bound
);
2190 fault
= fold_build2 (TRUTH_OR_EXPR
, boolean_type_node
, fault
,
2193 /* Check the section sizes match. */
2194 tmp
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
, end
,
2196 tmp
= fold_build2 (FLOOR_DIV_EXPR
, gfc_array_index_type
, tmp
,
2198 /* We remember the size of the first section, and check all the
2199 others against this. */
2203 fold_build2 (NE_EXPR
, boolean_type_node
, tmp
, size
[n
]);
2205 build2 (TRUTH_OR_EXPR
, boolean_type_node
, fault
, tmp
);
2208 size
[n
] = gfc_evaluate_now (tmp
, &block
);
2211 gfc_trans_runtime_check (fault
, gfc_strconst_bounds
, &block
);
2213 tmp
= gfc_finish_block (&block
);
2214 gfc_add_expr_to_block (&loop
->pre
, tmp
);
2219 /* Return true if the two SS could be aliased, i.e. both point to the same data
2221 /* TODO: resolve aliases based on frontend expressions. */
2224 gfc_could_be_alias (gfc_ss
* lss
, gfc_ss
* rss
)
2231 lsym
= lss
->expr
->symtree
->n
.sym
;
2232 rsym
= rss
->expr
->symtree
->n
.sym
;
2233 if (gfc_symbols_could_alias (lsym
, rsym
))
2236 if (rsym
->ts
.type
!= BT_DERIVED
2237 && lsym
->ts
.type
!= BT_DERIVED
)
2240 /* For derived types we must check all the component types. We can ignore
2241 array references as these will have the same base type as the previous
2243 for (lref
= lss
->expr
->ref
; lref
!= lss
->data
.info
.ref
; lref
= lref
->next
)
2245 if (lref
->type
!= REF_COMPONENT
)
2248 if (gfc_symbols_could_alias (lref
->u
.c
.sym
, rsym
))
2251 for (rref
= rss
->expr
->ref
; rref
!= rss
->data
.info
.ref
;
2254 if (rref
->type
!= REF_COMPONENT
)
2257 if (gfc_symbols_could_alias (lref
->u
.c
.sym
, rref
->u
.c
.sym
))
2262 for (rref
= rss
->expr
->ref
; rref
!= rss
->data
.info
.ref
; rref
= rref
->next
)
2264 if (rref
->type
!= REF_COMPONENT
)
2267 if (gfc_symbols_could_alias (rref
->u
.c
.sym
, lsym
))
2275 /* Resolve array data dependencies. Creates a temporary if required. */
2276 /* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
2280 gfc_conv_resolve_dependencies (gfc_loopinfo
* loop
, gfc_ss
* dest
,
2290 loop
->temp_ss
= NULL
;
2291 aref
= dest
->data
.info
.ref
;
2294 for (ss
= rss
; ss
!= gfc_ss_terminator
; ss
= ss
->next
)
2296 if (ss
->type
!= GFC_SS_SECTION
)
2299 if (gfc_could_be_alias (dest
, ss
))
2305 if (dest
->expr
->symtree
->n
.sym
== ss
->expr
->symtree
->n
.sym
)
2307 lref
= dest
->expr
->ref
;
2308 rref
= ss
->expr
->ref
;
2310 nDepend
= gfc_dep_resolver (lref
, rref
);
2312 /* TODO : loop shifting. */
2315 /* Mark the dimensions for LOOP SHIFTING */
2316 for (n
= 0; n
< loop
->dimen
; n
++)
2318 int dim
= dest
->data
.info
.dim
[n
];
2320 if (lref
->u
.ar
.dimen_type
[dim
] == DIMEN_VECTOR
)
2322 else if (! gfc_is_same_range (&lref
->u
.ar
,
2323 &rref
->u
.ar
, dim
, 0))
2327 /* Put all the dimensions with dependencies in the
2330 for (n
= 0; n
< loop
->dimen
; n
++)
2332 gcc_assert (loop
->order
[n
] == n
);
2334 loop
->order
[dim
++] = n
;
2337 for (n
= 0; n
< loop
->dimen
; n
++)
2340 loop
->order
[dim
++] = n
;
2343 gcc_assert (dim
== loop
->dimen
);
2352 loop
->temp_ss
= gfc_get_ss ();
2353 loop
->temp_ss
->type
= GFC_SS_TEMP
;
2354 loop
->temp_ss
->data
.temp
.type
=
2355 gfc_get_element_type (TREE_TYPE (dest
->data
.info
.descriptor
));
2356 loop
->temp_ss
->string_length
= dest
->string_length
;
2357 loop
->temp_ss
->data
.temp
.dimen
= loop
->dimen
;
2358 loop
->temp_ss
->next
= gfc_ss_terminator
;
2359 gfc_add_ss_to_loop (loop
, loop
->temp_ss
);
2362 loop
->temp_ss
= NULL
;
2366 /* Initialize the scalarization loop. Creates the loop variables. Determines
2367 the range of the loop variables. Creates a temporary if required.
2368 Calculates how to transform from loop variables to array indices for each
2369 expression. Also generates code for scalar expressions which have been
2370 moved outside the loop. */
2373 gfc_conv_loop_setup (gfc_loopinfo
* loop
)
2378 gfc_ss_info
*specinfo
;
2382 gfc_ss
*loopspec
[GFC_MAX_DIMENSIONS
];
2387 for (n
= 0; n
< loop
->dimen
; n
++)
2390 /* We use one SS term, and use that to determine the bounds of the
2391 loop for this dimension. We try to pick the simplest term. */
2392 for (ss
= loop
->ss
; ss
!= gfc_ss_terminator
; ss
= ss
->loop_chain
)
2396 /* The frontend has worked out the size for us. */
2401 if (ss
->type
== GFC_SS_CONSTRUCTOR
)
2403 /* An unknown size constructor will always be rank one.
2404 Higher rank constructors will either have known shape,
2405 or still be wrapped in a call to reshape. */
2406 gcc_assert (loop
->dimen
== 1);
2407 /* Try to figure out the size of the constructor. */
2408 /* TODO: avoid this by making the frontend set the shape. */
2409 gfc_get_array_cons_size (&i
, ss
->expr
->value
.constructor
);
2410 /* A negative value means we failed. */
2411 if (mpz_sgn (i
) > 0)
2413 mpz_sub_ui (i
, i
, 1);
2415 gfc_conv_mpz_to_tree (i
, gfc_index_integer_kind
);
2421 /* TODO: Pick the best bound if we have a choice between a
2422 function and something else. */
2423 if (ss
->type
== GFC_SS_FUNCTION
)
2429 if (ss
->type
!= GFC_SS_SECTION
)
2433 specinfo
= &loopspec
[n
]->data
.info
;
2436 info
= &ss
->data
.info
;
2438 /* Criteria for choosing a loop specifier (most important first):
2446 /* TODO: Is != constructor correct? */
2447 else if (loopspec
[n
]->type
!= GFC_SS_CONSTRUCTOR
)
2449 if (integer_onep (info
->stride
[n
])
2450 && !integer_onep (specinfo
->stride
[n
]))
2452 else if (INTEGER_CST_P (info
->stride
[n
])
2453 && !INTEGER_CST_P (specinfo
->stride
[n
]))
2455 else if (INTEGER_CST_P (info
->start
[n
])
2456 && !INTEGER_CST_P (specinfo
->start
[n
]))
2458 /* We don't work out the upper bound.
2459 else if (INTEGER_CST_P (info->finish[n])
2460 && ! INTEGER_CST_P (specinfo->finish[n]))
2461 loopspec[n] = ss; */
2466 gfc_todo_error ("Unable to find scalarization loop specifier");
2468 info
= &loopspec
[n
]->data
.info
;
2470 /* Set the extents of this range. */
2471 cshape
= loopspec
[n
]->shape
;
2472 if (cshape
&& INTEGER_CST_P (info
->start
[n
])
2473 && INTEGER_CST_P (info
->stride
[n
]))
2475 loop
->from
[n
] = info
->start
[n
];
2476 mpz_set (i
, cshape
[n
]);
2477 mpz_sub_ui (i
, i
, 1);
2478 /* To = from + (size - 1) * stride. */
2479 tmp
= gfc_conv_mpz_to_tree (i
, gfc_index_integer_kind
);
2480 if (!integer_onep (info
->stride
[n
]))
2481 tmp
= fold_build2 (MULT_EXPR
, gfc_array_index_type
,
2482 tmp
, info
->stride
[n
]);
2483 loop
->to
[n
] = fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
2484 loop
->from
[n
], tmp
);
2488 loop
->from
[n
] = info
->start
[n
];
2489 switch (loopspec
[n
]->type
)
2491 case GFC_SS_CONSTRUCTOR
:
2492 gcc_assert (info
->dimen
== 1);
2493 gcc_assert (loop
->to
[n
]);
2496 case GFC_SS_SECTION
:
2497 loop
->to
[n
] = gfc_conv_section_upper_bound (loopspec
[n
], n
,
2501 case GFC_SS_FUNCTION
:
2502 /* The loop bound will be set when we generate the call. */
2503 gcc_assert (loop
->to
[n
] == NULL_TREE
);
2511 /* Transform everything so we have a simple incrementing variable. */
2512 if (integer_onep (info
->stride
[n
]))
2513 info
->delta
[n
] = gfc_index_zero_node
;
2516 /* Set the delta for this section. */
2517 info
->delta
[n
] = gfc_evaluate_now (loop
->from
[n
], &loop
->pre
);
2518 /* Number of iterations is (end - start + step) / step.
2519 with start = 0, this simplifies to
2521 for (i = 0; i<=last; i++){...}; */
2522 tmp
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
,
2523 loop
->to
[n
], loop
->from
[n
]);
2524 tmp
= fold_build2 (TRUNC_DIV_EXPR
, gfc_array_index_type
,
2525 tmp
, info
->stride
[n
]);
2526 loop
->to
[n
] = gfc_evaluate_now (tmp
, &loop
->pre
);
2527 /* Make the loop variable start at 0. */
2528 loop
->from
[n
] = gfc_index_zero_node
;
2532 /* Add all the scalar code that can be taken out of the loops.
2533 This may include calculating the loop bounds, so do it before
2534 allocating the temporary. */
2535 gfc_add_loop_ss_code (loop
, loop
->ss
, false);
2537 /* If we want a temporary then create it. */
2538 if (loop
->temp_ss
!= NULL
)
2540 gcc_assert (loop
->temp_ss
->type
== GFC_SS_TEMP
);
2541 tmp
= loop
->temp_ss
->data
.temp
.type
;
2542 len
= loop
->temp_ss
->string_length
;
2543 n
= loop
->temp_ss
->data
.temp
.dimen
;
2544 memset (&loop
->temp_ss
->data
.info
, 0, sizeof (gfc_ss_info
));
2545 loop
->temp_ss
->type
= GFC_SS_SECTION
;
2546 loop
->temp_ss
->data
.info
.dimen
= n
;
2547 gfc_trans_allocate_temp_array (loop
, &loop
->temp_ss
->data
.info
, tmp
);
2550 for (n
= 0; n
< loop
->temp_dim
; n
++)
2551 loopspec
[loop
->order
[n
]] = NULL
;
2555 /* For array parameters we don't have loop variables, so don't calculate the
2557 if (loop
->array_parameter
)
2560 /* Calculate the translation from loop variables to array indices. */
2561 for (ss
= loop
->ss
; ss
!= gfc_ss_terminator
; ss
= ss
->loop_chain
)
2563 if (ss
->type
!= GFC_SS_SECTION
&& ss
->type
!= GFC_SS_COMPONENT
)
2566 info
= &ss
->data
.info
;
2568 for (n
= 0; n
< info
->dimen
; n
++)
2572 /* If we are specifying the range the delta is already set. */
2573 if (loopspec
[n
] != ss
)
2575 /* Calculate the offset relative to the loop variable.
2576 First multiply by the stride. */
2577 tmp
= fold_build2 (MULT_EXPR
, gfc_array_index_type
,
2578 loop
->from
[n
], info
->stride
[n
]);
2580 /* Then subtract this from our starting value. */
2581 tmp
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
,
2582 info
->start
[n
], tmp
);
2584 info
->delta
[n
] = gfc_evaluate_now (tmp
, &loop
->pre
);
2591 /* Fills in an array descriptor, and returns the size of the array. The size
2592 will be a simple_val, ie a variable or a constant. Also calculates the
2593 offset of the base. Returns the size of the array.
2597 for (n = 0; n < rank; n++)
2599 a.lbound[n] = specified_lower_bound;
2600 offset = offset + a.lbond[n] * stride;
2602 a.ubound[n] = specified_upper_bound;
2603 a.stride[n] = stride;
2604 size = ubound + size; //size = ubound + 1 - lbound
2605 stride = stride * size;
2612 gfc_array_init_size (tree descriptor
, int rank
, tree
* poffset
,
2613 gfc_expr
** lower
, gfc_expr
** upper
,
2614 stmtblock_t
* pblock
)
2625 type
= TREE_TYPE (descriptor
);
2627 stride
= gfc_index_one_node
;
2628 offset
= gfc_index_zero_node
;
2630 /* Set the dtype. */
2631 tmp
= gfc_conv_descriptor_dtype (descriptor
);
2632 gfc_add_modify_expr (pblock
, tmp
, gfc_get_dtype (TREE_TYPE (descriptor
)));
2634 for (n
= 0; n
< rank
; n
++)
2636 /* We have 3 possibilities for determining the size of the array:
2637 lower == NULL => lbound = 1, ubound = upper[n]
2638 upper[n] = NULL => lbound = 1, ubound = lower[n]
2639 upper[n] != NULL => lbound = lower[n], ubound = upper[n] */
2642 /* Set lower bound. */
2643 gfc_init_se (&se
, NULL
);
2645 se
.expr
= gfc_index_one_node
;
2648 gcc_assert (lower
[n
]);
2651 gfc_conv_expr_type (&se
, lower
[n
], gfc_array_index_type
);
2652 gfc_add_block_to_block (pblock
, &se
.pre
);
2656 se
.expr
= gfc_index_one_node
;
2660 tmp
= gfc_conv_descriptor_lbound (descriptor
, gfc_rank_cst
[n
]);
2661 gfc_add_modify_expr (pblock
, tmp
, se
.expr
);
2663 /* Work out the offset for this component. */
2664 tmp
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, se
.expr
, stride
);
2665 offset
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
, offset
, tmp
);
2667 /* Start the calculation for the size of this dimension. */
2668 size
= build2 (MINUS_EXPR
, gfc_array_index_type
,
2669 gfc_index_one_node
, se
.expr
);
2671 /* Set upper bound. */
2672 gfc_init_se (&se
, NULL
);
2673 gcc_assert (ubound
);
2674 gfc_conv_expr_type (&se
, ubound
, gfc_array_index_type
);
2675 gfc_add_block_to_block (pblock
, &se
.pre
);
2677 tmp
= gfc_conv_descriptor_ubound (descriptor
, gfc_rank_cst
[n
]);
2678 gfc_add_modify_expr (pblock
, tmp
, se
.expr
);
2680 /* Store the stride. */
2681 tmp
= gfc_conv_descriptor_stride (descriptor
, gfc_rank_cst
[n
]);
2682 gfc_add_modify_expr (pblock
, tmp
, stride
);
2684 /* Calculate the size of this dimension. */
2685 size
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
, se
.expr
, size
);
2687 /* Multiply the stride by the number of elements in this dimension. */
2688 stride
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, stride
, size
);
2689 stride
= gfc_evaluate_now (stride
, pblock
);
2692 /* The stride is the number of elements in the array, so multiply by the
2693 size of an element to get the total size. */
2694 tmp
= TYPE_SIZE_UNIT (gfc_get_element_type (type
));
2695 size
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, stride
, tmp
);
2697 if (poffset
!= NULL
)
2699 offset
= gfc_evaluate_now (offset
, pblock
);
2703 size
= gfc_evaluate_now (size
, pblock
);
2708 /* Initializes the descriptor and generates a call to _gfor_allocate. Does
2709 the work for an ALLOCATE statement. */
2713 gfc_array_allocate (gfc_se
* se
, gfc_ref
* ref
, tree pstat
)
2723 /* Figure out the size of the array. */
2724 switch (ref
->u
.ar
.type
)
2728 upper
= ref
->u
.ar
.start
;
2732 gcc_assert (ref
->u
.ar
.as
->type
== AS_EXPLICIT
);
2734 lower
= ref
->u
.ar
.as
->lower
;
2735 upper
= ref
->u
.ar
.as
->upper
;
2739 lower
= ref
->u
.ar
.start
;
2740 upper
= ref
->u
.ar
.end
;
2748 size
= gfc_array_init_size (se
->expr
, ref
->u
.ar
.as
->rank
, &offset
,
2749 lower
, upper
, &se
->pre
);
2751 /* Allocate memory to store the data. */
2752 tmp
= gfc_conv_descriptor_data (se
->expr
);
2753 pointer
= gfc_build_addr_expr (NULL
, tmp
);
2754 pointer
= gfc_evaluate_now (pointer
, &se
->pre
);
2756 if (TYPE_PRECISION (gfc_array_index_type
) == 32)
2757 allocate
= gfor_fndecl_allocate
;
2758 else if (TYPE_PRECISION (gfc_array_index_type
) == 64)
2759 allocate
= gfor_fndecl_allocate64
;
2763 tmp
= gfc_chainon_list (NULL_TREE
, pointer
);
2764 tmp
= gfc_chainon_list (tmp
, size
);
2765 tmp
= gfc_chainon_list (tmp
, pstat
);
2766 tmp
= gfc_build_function_call (allocate
, tmp
);
2767 gfc_add_expr_to_block (&se
->pre
, tmp
);
2769 pointer
= gfc_conv_descriptor_data (se
->expr
);
2771 tmp
= gfc_conv_descriptor_offset (se
->expr
);
2772 gfc_add_modify_expr (&se
->pre
, tmp
, offset
);
2776 /* Deallocate an array variable. Also used when an allocated variable goes
2781 gfc_array_deallocate (tree descriptor
)
2787 gfc_start_block (&block
);
2788 /* Get a pointer to the data. */
2789 tmp
= gfc_conv_descriptor_data (descriptor
);
2790 tmp
= gfc_build_addr_expr (NULL
, tmp
);
2791 var
= gfc_create_var (TREE_TYPE (tmp
), "ptr");
2792 gfc_add_modify_expr (&block
, var
, tmp
);
2794 /* Parameter is the address of the data component. */
2795 tmp
= gfc_chainon_list (NULL_TREE
, var
);
2796 tmp
= gfc_chainon_list (tmp
, integer_zero_node
);
2797 tmp
= gfc_build_function_call (gfor_fndecl_deallocate
, tmp
);
2798 gfc_add_expr_to_block (&block
, tmp
);
2800 return gfc_finish_block (&block
);
2804 /* Create an array constructor from an initialization expression.
2805 We assume the frontend already did any expansions and conversions. */
2808 gfc_conv_array_initializer (tree type
, gfc_expr
* expr
)
2816 unsigned HOST_WIDE_INT lo
;
2820 switch (expr
->expr_type
)
2823 case EXPR_STRUCTURE
:
2824 /* A single scalar or derived type value. Create an array with all
2825 elements equal to that value. */
2826 gfc_init_se (&se
, NULL
);
2828 if (expr
->expr_type
== EXPR_CONSTANT
)
2829 gfc_conv_constant (&se
, expr
);
2831 gfc_conv_structure (&se
, expr
, 1);
2833 tmp
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
2834 gcc_assert (tmp
&& INTEGER_CST_P (tmp
));
2835 hi
= TREE_INT_CST_HIGH (tmp
);
2836 lo
= TREE_INT_CST_LOW (tmp
);
2840 /* This will probably eat buckets of memory for large arrays. */
2841 while (hi
!= 0 || lo
!= 0)
2843 list
= tree_cons (NULL_TREE
, se
.expr
, list
);
2851 /* Create a list of all the elements. */
2852 for (c
= expr
->value
.constructor
; c
; c
= c
->next
)
2856 /* Problems occur when we get something like
2857 integer :: a(lots) = (/(i, i=1,lots)/) */
2858 /* TODO: Unexpanded array initializers. */
2860 ("Possible frontend bug: array constructor not expanded");
2862 if (mpz_cmp_si (c
->n
.offset
, 0) != 0)
2863 index
= gfc_conv_mpz_to_tree (c
->n
.offset
, gfc_index_integer_kind
);
2867 if (mpz_cmp_si (c
->repeat
, 0) != 0)
2871 mpz_set (maxval
, c
->repeat
);
2872 mpz_add (maxval
, c
->n
.offset
, maxval
);
2873 mpz_sub_ui (maxval
, maxval
, 1);
2874 tmp2
= gfc_conv_mpz_to_tree (maxval
, gfc_index_integer_kind
);
2875 if (mpz_cmp_si (c
->n
.offset
, 0) != 0)
2877 mpz_add_ui (maxval
, c
->n
.offset
, 1);
2878 tmp1
= gfc_conv_mpz_to_tree (maxval
, gfc_index_integer_kind
);
2881 tmp1
= gfc_conv_mpz_to_tree (c
->n
.offset
, gfc_index_integer_kind
);
2883 range
= build2 (RANGE_EXPR
, integer_type_node
, tmp1
, tmp2
);
2889 gfc_init_se (&se
, NULL
);
2890 switch (c
->expr
->expr_type
)
2893 gfc_conv_constant (&se
, c
->expr
);
2894 if (range
== NULL_TREE
)
2895 list
= tree_cons (index
, se
.expr
, list
);
2898 if (index
!= NULL_TREE
)
2899 list
= tree_cons (index
, se
.expr
, list
);
2900 list
= tree_cons (range
, se
.expr
, list
);
2904 case EXPR_STRUCTURE
:
2905 gfc_conv_structure (&se
, c
->expr
, 1);
2906 list
= tree_cons (index
, se
.expr
, list
);
2913 /* We created the list in reverse order. */
2914 list
= nreverse (list
);
2921 /* Create a constructor from the list of elements. */
2922 tmp
= build1 (CONSTRUCTOR
, type
, list
);
2923 TREE_CONSTANT (tmp
) = 1;
2924 TREE_INVARIANT (tmp
) = 1;
2929 /* Generate code to evaluate non-constant array bounds. Sets *poffset and
2930 returns the size (in elements) of the array. */
2933 gfc_trans_array_bounds (tree type
, gfc_symbol
* sym
, tree
* poffset
,
2934 stmtblock_t
* pblock
)
2949 size
= gfc_index_one_node
;
2950 offset
= gfc_index_zero_node
;
2951 for (dim
= 0; dim
< as
->rank
; dim
++)
2953 /* Evaluate non-constant array bound expressions. */
2954 lbound
= GFC_TYPE_ARRAY_LBOUND (type
, dim
);
2955 if (as
->lower
[dim
] && !INTEGER_CST_P (lbound
))
2957 gfc_init_se (&se
, NULL
);
2958 gfc_conv_expr_type (&se
, as
->lower
[dim
], gfc_array_index_type
);
2959 gfc_add_block_to_block (pblock
, &se
.pre
);
2960 gfc_add_modify_expr (pblock
, lbound
, se
.expr
);
2962 ubound
= GFC_TYPE_ARRAY_UBOUND (type
, dim
);
2963 if (as
->upper
[dim
] && !INTEGER_CST_P (ubound
))
2965 gfc_init_se (&se
, NULL
);
2966 gfc_conv_expr_type (&se
, as
->upper
[dim
], gfc_array_index_type
);
2967 gfc_add_block_to_block (pblock
, &se
.pre
);
2968 gfc_add_modify_expr (pblock
, ubound
, se
.expr
);
2970 /* The offset of this dimension. offset = offset - lbound * stride. */
2971 tmp
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, lbound
, size
);
2972 offset
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
, offset
, tmp
);
2974 /* The size of this dimension, and the stride of the next. */
2975 if (dim
+ 1 < as
->rank
)
2976 stride
= GFC_TYPE_ARRAY_STRIDE (type
, dim
+ 1);
2980 if (ubound
!= NULL_TREE
&& !(stride
&& INTEGER_CST_P (stride
)))
2982 /* Calculate stride = size * (ubound + 1 - lbound). */
2983 tmp
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
,
2984 gfc_index_one_node
, lbound
);
2985 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
, ubound
, tmp
);
2986 tmp
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, size
, tmp
);
2988 gfc_add_modify_expr (pblock
, stride
, tmp
);
2990 stride
= gfc_evaluate_now (tmp
, pblock
);
3001 /* Generate code to initialize/allocate an array variable. */
3004 gfc_trans_auto_array_allocation (tree decl
, gfc_symbol
* sym
, tree fnbody
)
3014 gcc_assert (!(sym
->attr
.pointer
|| sym
->attr
.allocatable
));
3016 /* Do nothing for USEd variables. */
3017 if (sym
->attr
.use_assoc
)
3020 type
= TREE_TYPE (decl
);
3021 gcc_assert (GFC_ARRAY_TYPE_P (type
));
3022 onstack
= TREE_CODE (type
) != POINTER_TYPE
;
3024 gfc_start_block (&block
);
3026 /* Evaluate character string length. */
3027 if (sym
->ts
.type
== BT_CHARACTER
3028 && onstack
&& !INTEGER_CST_P (sym
->ts
.cl
->backend_decl
))
3030 gfc_trans_init_string_length (sym
->ts
.cl
, &block
);
3032 /* Emit a DECL_EXPR for this variable, which will cause the
3033 gimplifier to allocate storage, and all that good stuff. */
3034 tmp
= build1 (DECL_EXPR
, TREE_TYPE (decl
), decl
);
3035 gfc_add_expr_to_block (&block
, tmp
);
3040 gfc_add_expr_to_block (&block
, fnbody
);
3041 return gfc_finish_block (&block
);
3044 type
= TREE_TYPE (type
);
3046 gcc_assert (!sym
->attr
.use_assoc
);
3047 gcc_assert (!TREE_STATIC (decl
));
3048 gcc_assert (!sym
->module
);
3050 if (sym
->ts
.type
== BT_CHARACTER
3051 && !INTEGER_CST_P (sym
->ts
.cl
->backend_decl
))
3052 gfc_trans_init_string_length (sym
->ts
.cl
, &block
);
3054 size
= gfc_trans_array_bounds (type
, sym
, &offset
, &block
);
3056 /* The size is the number of elements in the array, so multiply by the
3057 size of an element to get the total size. */
3058 tmp
= TYPE_SIZE_UNIT (gfc_get_element_type (type
));
3059 size
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, size
, tmp
);
3061 /* Allocate memory to hold the data. */
3062 tmp
= gfc_chainon_list (NULL_TREE
, size
);
3064 if (gfc_index_integer_kind
== 4)
3065 fndecl
= gfor_fndecl_internal_malloc
;
3066 else if (gfc_index_integer_kind
== 8)
3067 fndecl
= gfor_fndecl_internal_malloc64
;
3070 tmp
= gfc_build_function_call (fndecl
, tmp
);
3071 tmp
= fold (convert (TREE_TYPE (decl
), tmp
));
3072 gfc_add_modify_expr (&block
, decl
, tmp
);
3074 /* Set offset of the array. */
3075 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type
)) == VAR_DECL
)
3076 gfc_add_modify_expr (&block
, GFC_TYPE_ARRAY_OFFSET (type
), offset
);
3079 /* Automatic arrays should not have initializers. */
3080 gcc_assert (!sym
->value
);
3082 gfc_add_expr_to_block (&block
, fnbody
);
3084 /* Free the temporary. */
3085 tmp
= convert (pvoid_type_node
, decl
);
3086 tmp
= gfc_chainon_list (NULL_TREE
, tmp
);
3087 tmp
= gfc_build_function_call (gfor_fndecl_internal_free
, tmp
);
3088 gfc_add_expr_to_block (&block
, tmp
);
3090 return gfc_finish_block (&block
);
3094 /* Generate entry and exit code for g77 calling convention arrays. */
3097 gfc_trans_g77_array (gfc_symbol
* sym
, tree body
)
3106 gfc_get_backend_locus (&loc
);
3107 gfc_set_backend_locus (&sym
->declared_at
);
3109 /* Descriptor type. */
3110 parm
= sym
->backend_decl
;
3111 type
= TREE_TYPE (parm
);
3112 gcc_assert (GFC_ARRAY_TYPE_P (type
));
3114 gfc_start_block (&block
);
3116 if (sym
->ts
.type
== BT_CHARACTER
3117 && TREE_CODE (sym
->ts
.cl
->backend_decl
) == VAR_DECL
)
3118 gfc_trans_init_string_length (sym
->ts
.cl
, &block
);
3120 /* Evaluate the bounds of the array. */
3121 gfc_trans_array_bounds (type
, sym
, &offset
, &block
);
3123 /* Set the offset. */
3124 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type
)) == VAR_DECL
)
3125 gfc_add_modify_expr (&block
, GFC_TYPE_ARRAY_OFFSET (type
), offset
);
3127 /* Set the pointer itself if we aren't using the parameter directly. */
3128 if (TREE_CODE (parm
) != PARM_DECL
)
3130 tmp
= convert (TREE_TYPE (parm
), GFC_DECL_SAVED_DESCRIPTOR (parm
));
3131 gfc_add_modify_expr (&block
, parm
, tmp
);
3133 tmp
= gfc_finish_block (&block
);
3135 gfc_set_backend_locus (&loc
);
3137 gfc_start_block (&block
);
3138 /* Add the initialization code to the start of the function. */
3139 gfc_add_expr_to_block (&block
, tmp
);
3140 gfc_add_expr_to_block (&block
, body
);
3142 return gfc_finish_block (&block
);
3146 /* Modify the descriptor of an array parameter so that it has the
3147 correct lower bound. Also move the upper bound accordingly.
3148 If the array is not packed, it will be copied into a temporary.
3149 For each dimension we set the new lower and upper bounds. Then we copy the
3150 stride and calculate the offset for this dimension. We also work out
3151 what the stride of a packed array would be, and see it the two match.
3152 If the array need repacking, we set the stride to the values we just
3153 calculated, recalculate the offset and copy the array data.
3154 Code is also added to copy the data back at the end of the function.
3158 gfc_trans_dummy_array_bias (gfc_symbol
* sym
, tree tmpdesc
, tree body
)
3165 stmtblock_t cleanup
;
3183 /* Do nothing for pointer and allocatable arrays. */
3184 if (sym
->attr
.pointer
|| sym
->attr
.allocatable
)
3187 if (sym
->attr
.dummy
&& gfc_is_nodesc_array (sym
))
3188 return gfc_trans_g77_array (sym
, body
);
3190 gfc_get_backend_locus (&loc
);
3191 gfc_set_backend_locus (&sym
->declared_at
);
3193 /* Descriptor type. */
3194 type
= TREE_TYPE (tmpdesc
);
3195 gcc_assert (GFC_ARRAY_TYPE_P (type
));
3196 dumdesc
= GFC_DECL_SAVED_DESCRIPTOR (tmpdesc
);
3197 dumdesc
= gfc_build_indirect_ref (dumdesc
);
3198 gfc_start_block (&block
);
3200 if (sym
->ts
.type
== BT_CHARACTER
3201 && TREE_CODE (sym
->ts
.cl
->backend_decl
) == VAR_DECL
)
3202 gfc_trans_init_string_length (sym
->ts
.cl
, &block
);
3204 checkparm
= (sym
->as
->type
== AS_EXPLICIT
&& flag_bounds_check
);
3206 no_repack
= !(GFC_DECL_PACKED_ARRAY (tmpdesc
)
3207 || GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc
));
3209 if (GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc
))
3211 /* For non-constant shape arrays we only check if the first dimension
3212 is contiguous. Repacking higher dimensions wouldn't gain us
3213 anything as we still don't know the array stride. */
3214 partial
= gfc_create_var (boolean_type_node
, "partial");
3215 TREE_USED (partial
) = 1;
3216 tmp
= gfc_conv_descriptor_stride (dumdesc
, gfc_rank_cst
[0]);
3217 tmp
= fold_build2 (EQ_EXPR
, boolean_type_node
, tmp
, integer_one_node
);
3218 gfc_add_modify_expr (&block
, partial
, tmp
);
3222 partial
= NULL_TREE
;
3225 /* The naming of stmt_unpacked and stmt_packed may be counter-intuitive
3226 here, however I think it does the right thing. */
3229 /* Set the first stride. */
3230 stride
= gfc_conv_descriptor_stride (dumdesc
, gfc_rank_cst
[0]);
3231 stride
= gfc_evaluate_now (stride
, &block
);
3233 tmp
= build2 (EQ_EXPR
, boolean_type_node
, stride
, integer_zero_node
);
3234 tmp
= build3 (COND_EXPR
, gfc_array_index_type
, tmp
,
3235 gfc_index_one_node
, stride
);
3236 stride
= GFC_TYPE_ARRAY_STRIDE (type
, 0);
3237 gfc_add_modify_expr (&block
, stride
, tmp
);
3239 /* Allow the user to disable array repacking. */
3240 stmt_unpacked
= NULL_TREE
;
3244 gcc_assert (integer_onep (GFC_TYPE_ARRAY_STRIDE (type
, 0)));
3245 /* A library call to repack the array if necessary. */
3246 tmp
= GFC_DECL_SAVED_DESCRIPTOR (tmpdesc
);
3247 tmp
= gfc_chainon_list (NULL_TREE
, tmp
);
3248 stmt_unpacked
= gfc_build_function_call (gfor_fndecl_in_pack
, tmp
);
3250 stride
= gfc_index_one_node
;
3253 /* This is for the case where the array data is used directly without
3254 calling the repack function. */
3255 if (no_repack
|| partial
!= NULL_TREE
)
3256 stmt_packed
= gfc_conv_descriptor_data (dumdesc
);
3258 stmt_packed
= NULL_TREE
;
3260 /* Assign the data pointer. */
3261 if (stmt_packed
!= NULL_TREE
&& stmt_unpacked
!= NULL_TREE
)
3263 /* Don't repack unknown shape arrays when the first stride is 1. */
3264 tmp
= build3 (COND_EXPR
, TREE_TYPE (stmt_packed
), partial
,
3265 stmt_packed
, stmt_unpacked
);
3268 tmp
= stmt_packed
!= NULL_TREE
? stmt_packed
: stmt_unpacked
;
3269 gfc_add_modify_expr (&block
, tmpdesc
, fold_convert (type
, tmp
));
3271 offset
= gfc_index_zero_node
;
3272 size
= gfc_index_one_node
;
3274 /* Evaluate the bounds of the array. */
3275 for (n
= 0; n
< sym
->as
->rank
; n
++)
3277 if (checkparm
|| !sym
->as
->upper
[n
])
3279 /* Get the bounds of the actual parameter. */
3280 dubound
= gfc_conv_descriptor_ubound (dumdesc
, gfc_rank_cst
[n
]);
3281 dlbound
= gfc_conv_descriptor_lbound (dumdesc
, gfc_rank_cst
[n
]);
3285 dubound
= NULL_TREE
;
3286 dlbound
= NULL_TREE
;
3289 lbound
= GFC_TYPE_ARRAY_LBOUND (type
, n
);
3290 if (!INTEGER_CST_P (lbound
))
3292 gfc_init_se (&se
, NULL
);
3293 gfc_conv_expr_type (&se
, sym
->as
->upper
[n
],
3294 gfc_array_index_type
);
3295 gfc_add_block_to_block (&block
, &se
.pre
);
3296 gfc_add_modify_expr (&block
, lbound
, se
.expr
);
3299 ubound
= GFC_TYPE_ARRAY_UBOUND (type
, n
);
3300 /* Set the desired upper bound. */
3301 if (sym
->as
->upper
[n
])
3303 /* We know what we want the upper bound to be. */
3304 if (!INTEGER_CST_P (ubound
))
3306 gfc_init_se (&se
, NULL
);
3307 gfc_conv_expr_type (&se
, sym
->as
->upper
[n
],
3308 gfc_array_index_type
);
3309 gfc_add_block_to_block (&block
, &se
.pre
);
3310 gfc_add_modify_expr (&block
, ubound
, se
.expr
);
3313 /* Check the sizes match. */
3316 /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)). */
3318 tmp
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
,
3320 stride
= build2 (MINUS_EXPR
, gfc_array_index_type
,
3322 tmp
= fold_build2 (NE_EXPR
, gfc_array_index_type
, tmp
, stride
);
3323 gfc_trans_runtime_check (tmp
, gfc_strconst_bounds
, &block
);
3328 /* For assumed shape arrays move the upper bound by the same amount
3329 as the lower bound. */
3330 tmp
= build2 (MINUS_EXPR
, gfc_array_index_type
, dubound
, dlbound
);
3331 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
, tmp
, lbound
);
3332 gfc_add_modify_expr (&block
, ubound
, tmp
);
3334 /* The offset of this dimension. offset = offset - lbound * stride. */
3335 tmp
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, lbound
, stride
);
3336 offset
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
, offset
, tmp
);
3338 /* The size of this dimension, and the stride of the next. */
3339 if (n
+ 1 < sym
->as
->rank
)
3341 stride
= GFC_TYPE_ARRAY_STRIDE (type
, n
+ 1);
3343 if (no_repack
|| partial
!= NULL_TREE
)
3346 gfc_conv_descriptor_stride (dumdesc
, gfc_rank_cst
[n
+1]);
3349 /* Figure out the stride if not a known constant. */
3350 if (!INTEGER_CST_P (stride
))
3353 stmt_packed
= NULL_TREE
;
3356 /* Calculate stride = size * (ubound + 1 - lbound). */
3357 tmp
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
,
3358 gfc_index_one_node
, lbound
);
3359 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
3361 size
= fold_build2 (MULT_EXPR
, gfc_array_index_type
,
3366 /* Assign the stride. */
3367 if (stmt_packed
!= NULL_TREE
&& stmt_unpacked
!= NULL_TREE
)
3368 tmp
= build3 (COND_EXPR
, gfc_array_index_type
, partial
,
3369 stmt_unpacked
, stmt_packed
);
3371 tmp
= (stmt_packed
!= NULL_TREE
) ? stmt_packed
: stmt_unpacked
;
3372 gfc_add_modify_expr (&block
, stride
, tmp
);
3377 /* Set the offset. */
3378 if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type
)) == VAR_DECL
)
3379 gfc_add_modify_expr (&block
, GFC_TYPE_ARRAY_OFFSET (type
), offset
);
3381 stmt
= gfc_finish_block (&block
);
3383 gfc_start_block (&block
);
3385 /* Only do the entry/initialization code if the arg is present. */
3386 dumdesc
= GFC_DECL_SAVED_DESCRIPTOR (tmpdesc
);
3387 optional_arg
= (sym
->attr
.optional
3388 || (sym
->ns
->proc_name
->attr
.entry_master
3389 && sym
->attr
.dummy
));
3392 tmp
= gfc_conv_expr_present (sym
);
3393 stmt
= build3_v (COND_EXPR
, tmp
, stmt
, build_empty_stmt ());
3395 gfc_add_expr_to_block (&block
, stmt
);
3397 /* Add the main function body. */
3398 gfc_add_expr_to_block (&block
, body
);
3403 gfc_start_block (&cleanup
);
3405 if (sym
->attr
.intent
!= INTENT_IN
)
3407 /* Copy the data back. */
3408 tmp
= gfc_chainon_list (NULL_TREE
, dumdesc
);
3409 tmp
= gfc_chainon_list (tmp
, tmpdesc
);
3410 tmp
= gfc_build_function_call (gfor_fndecl_in_unpack
, tmp
);
3411 gfc_add_expr_to_block (&cleanup
, tmp
);
3414 /* Free the temporary. */
3415 tmp
= gfc_chainon_list (NULL_TREE
, tmpdesc
);
3416 tmp
= gfc_build_function_call (gfor_fndecl_internal_free
, tmp
);
3417 gfc_add_expr_to_block (&cleanup
, tmp
);
3419 stmt
= gfc_finish_block (&cleanup
);
3421 /* Only do the cleanup if the array was repacked. */
3422 tmp
= gfc_build_indirect_ref (dumdesc
);
3423 tmp
= gfc_conv_descriptor_data (tmp
);
3424 tmp
= build2 (NE_EXPR
, boolean_type_node
, tmp
, tmpdesc
);
3425 stmt
= build3_v (COND_EXPR
, tmp
, stmt
, build_empty_stmt ());
3429 tmp
= gfc_conv_expr_present (sym
);
3430 stmt
= build3_v (COND_EXPR
, tmp
, stmt
, build_empty_stmt ());
3432 gfc_add_expr_to_block (&block
, stmt
);
3434 /* We don't need to free any memory allocated by internal_pack as it will
3435 be freed at the end of the function by pop_context. */
3436 return gfc_finish_block (&block
);
3440 /* Convert an array for passing as an actual parameter. Expressions and
3441 vector subscripts are evaluated and stored in a temporary, which is then
3442 passed. For whole arrays the descriptor is passed. For array sections
3443 a modified copy of the descriptor is passed, but using the original data.
3444 Also used for array pointer assignments by setting se->direct_byref. */
3447 gfc_conv_expr_descriptor (gfc_se
* se
, gfc_expr
* expr
, gfc_ss
* ss
)
3463 gcc_assert (ss
!= gfc_ss_terminator
);
3465 /* TODO: Pass constant array constructors without a temporary. */
3466 /* Special case things we know we can pass easily. */
3467 switch (expr
->expr_type
)
3470 /* If we have a linear array section, we can pass it directly.
3471 Otherwise we need to copy it into a temporary. */
3473 /* Find the SS for the array section. */
3475 while (secss
!= gfc_ss_terminator
&& secss
->type
!= GFC_SS_SECTION
)
3476 secss
= secss
->next
;
3478 gcc_assert (secss
!= gfc_ss_terminator
);
3481 for (n
= 0; n
< secss
->data
.info
.dimen
; n
++)
3483 vss
= secss
->data
.info
.subscript
[secss
->data
.info
.dim
[n
]];
3484 if (vss
&& vss
->type
== GFC_SS_VECTOR
)
3488 info
= &secss
->data
.info
;
3490 /* Get the descriptor for the array. */
3491 gfc_conv_ss_descriptor (&se
->pre
, secss
, 0);
3492 desc
= info
->descriptor
;
3493 if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc
)))
3495 /* Create a new descriptor if the array doesn't have one. */
3498 else if (info
->ref
->u
.ar
.type
== AR_FULL
)
3500 else if (se
->direct_byref
)
3505 gcc_assert (ref
->u
.ar
.type
== AR_SECTION
);
3508 for (n
= 0; n
< ref
->u
.ar
.dimen
; n
++)
3510 /* Detect passing the full array as a section. This could do
3511 even more checking, but it doesn't seem worth it. */
3512 if (ref
->u
.ar
.start
[n
]
3514 || (ref
->u
.ar
.stride
[n
]
3515 && !gfc_expr_is_one (ref
->u
.ar
.stride
[n
], 0)))
3523 /* Check for substring references. */
3525 if (!need_tmp
&& ref
&& expr
->ts
.type
== BT_CHARACTER
)
3529 if (ref
->type
== REF_SUBSTRING
)
3531 /* In general character substrings need a copy. Character
3532 array strides are expressed as multiples of the element
3533 size (consistent with other array types), not in
3542 if (se
->direct_byref
)
3544 /* Copy the descriptor for pointer assignments. */
3545 gfc_add_modify_expr (&se
->pre
, se
->expr
, desc
);
3547 else if (se
->want_pointer
)
3549 /* We pass full arrays directly. This means that pointers and
3550 allocatable arrays should also work. */
3551 se
->expr
= gfc_build_addr_expr (NULL_TREE
, desc
);
3558 if (expr
->ts
.type
== BT_CHARACTER
)
3559 se
->string_length
= gfc_get_expr_charlen (expr
);
3566 /* A transformational function return value will be a temporary
3567 array descriptor. We still need to go through the scalarizer
3568 to create the descriptor. Elemental functions ar handled as
3569 arbitrary expressions, i.e. copy to a temporary. */
3571 /* Look for the SS for this function. */
3572 while (secss
!= gfc_ss_terminator
3573 && (secss
->type
!= GFC_SS_FUNCTION
|| secss
->expr
!= expr
))
3574 secss
= secss
->next
;
3576 if (se
->direct_byref
)
3578 gcc_assert (secss
!= gfc_ss_terminator
);
3580 /* For pointer assignments pass the descriptor directly. */
3582 se
->expr
= gfc_build_addr_expr (NULL
, se
->expr
);
3583 gfc_conv_expr (se
, expr
);
3587 if (secss
== gfc_ss_terminator
)
3589 /* Elemental function. */
3595 /* Transformational function. */
3596 info
= &secss
->data
.info
;
3602 /* Something complicated. Copy it into a temporary. */
3610 gfc_init_loopinfo (&loop
);
3612 /* Associate the SS with the loop. */
3613 gfc_add_ss_to_loop (&loop
, ss
);
3615 /* Tell the scalarizer not to bother creating loop variables, etc. */
3617 loop
.array_parameter
= 1;
3619 gcc_assert (se
->want_pointer
&& !se
->direct_byref
);
3621 /* Setup the scalarizing loops and bounds. */
3622 gfc_conv_ss_startstride (&loop
);
3626 /* Tell the scalarizer to make a temporary. */
3627 loop
.temp_ss
= gfc_get_ss ();
3628 loop
.temp_ss
->type
= GFC_SS_TEMP
;
3629 loop
.temp_ss
->next
= gfc_ss_terminator
;
3630 if (expr
->ts
.type
== BT_CHARACTER
)
3632 gcc_assert (expr
->ts
.cl
&& expr
->ts
.cl
->length
3633 && expr
->ts
.cl
->length
->expr_type
== EXPR_CONSTANT
);
3634 loop
.temp_ss
->string_length
= gfc_conv_mpz_to_tree
3635 (expr
->ts
.cl
->length
->value
.integer
,
3636 expr
->ts
.cl
->length
->ts
.kind
);
3637 expr
->ts
.cl
->backend_decl
= loop
.temp_ss
->string_length
;
3639 loop
.temp_ss
->data
.temp
.type
= gfc_typenode_for_spec (&expr
->ts
);
3641 /* ... which can hold our string, if present. */
3642 if (expr
->ts
.type
== BT_CHARACTER
)
3644 loop
.temp_ss
->string_length
= TYPE_SIZE_UNIT (loop
.temp_ss
->data
.temp
.type
);
3645 se
->string_length
= loop
.temp_ss
->string_length
;
3648 loop
.temp_ss
->string_length
= NULL
;
3649 loop
.temp_ss
->data
.temp
.dimen
= loop
.dimen
;
3650 gfc_add_ss_to_loop (&loop
, loop
.temp_ss
);
3653 gfc_conv_loop_setup (&loop
);
3657 /* Copy into a temporary and pass that. We don't need to copy the data
3658 back because expressions and vector subscripts must be INTENT_IN. */
3659 /* TODO: Optimize passing function return values. */
3663 /* Start the copying loops. */
3664 gfc_mark_ss_chain_used (loop
.temp_ss
, 1);
3665 gfc_mark_ss_chain_used (ss
, 1);
3666 gfc_start_scalarized_body (&loop
, &block
);
3668 /* Copy each data element. */
3669 gfc_init_se (&lse
, NULL
);
3670 gfc_copy_loopinfo_to_se (&lse
, &loop
);
3671 gfc_init_se (&rse
, NULL
);
3672 gfc_copy_loopinfo_to_se (&rse
, &loop
);
3674 lse
.ss
= loop
.temp_ss
;
3677 gfc_conv_scalarized_array_ref (&lse
, NULL
);
3678 if (expr
->ts
.type
== BT_CHARACTER
)
3680 gfc_conv_expr (&rse
, expr
);
3681 rse
.expr
= gfc_build_indirect_ref (rse
.expr
);
3684 gfc_conv_expr_val (&rse
, expr
);
3686 gfc_add_block_to_block (&block
, &rse
.pre
);
3687 gfc_add_block_to_block (&block
, &lse
.pre
);
3689 gfc_add_modify_expr (&block
, lse
.expr
, rse
.expr
);
3691 /* Finish the copying loops. */
3692 gfc_trans_scalarizing_loops (&loop
, &block
);
3694 /* Set the first stride component to zero to indicate a temporary. */
3695 desc
= loop
.temp_ss
->data
.info
.descriptor
;
3696 tmp
= gfc_conv_descriptor_stride (desc
, gfc_rank_cst
[0]);
3697 gfc_add_modify_expr (&loop
.pre
, tmp
, gfc_index_zero_node
);
3699 gcc_assert (is_gimple_lvalue (desc
));
3700 se
->expr
= gfc_build_addr_expr (NULL
, desc
);
3702 else if (expr
->expr_type
== EXPR_FUNCTION
)
3704 desc
= info
->descriptor
;
3706 if (se
->want_pointer
)
3707 se
->expr
= gfc_build_addr_expr (NULL_TREE
, desc
);
3711 if (expr
->ts
.type
== BT_CHARACTER
)
3712 se
->string_length
= expr
->symtree
->n
.sym
->ts
.cl
->backend_decl
;
3716 /* We pass sections without copying to a temporary. Make a new
3717 descriptor and point it at the section we want. The loop variable
3718 limits will be the limits of the section.
3719 A function may decide to repack the array to speed up access, but
3720 we're not bothered about that here. */
3729 /* Set the string_length for a character array. */
3730 if (expr
->ts
.type
== BT_CHARACTER
)
3731 se
->string_length
= gfc_get_expr_charlen (expr
);
3733 desc
= info
->descriptor
;
3734 gcc_assert (secss
&& secss
!= gfc_ss_terminator
);
3735 if (se
->direct_byref
)
3737 /* For pointer assignments we fill in the destination. */
3739 parmtype
= TREE_TYPE (parm
);
3743 /* Otherwise make a new one. */
3744 parmtype
= gfc_get_element_type (TREE_TYPE (desc
));
3745 parmtype
= gfc_get_array_type_bounds (parmtype
, loop
.dimen
,
3746 loop
.from
, loop
.to
, 0);
3747 parm
= gfc_create_var (parmtype
, "parm");
3750 offset
= gfc_index_zero_node
;
3753 /* The following can be somewhat confusing. We have two
3754 descriptors, a new one and the original array.
3755 {parm, parmtype, dim} refer to the new one.
3756 {desc, type, n, secss, loop} refer to the original, which maybe
3757 a descriptorless array.
3758 The bounds of the scalarization are the bounds of the section.
3759 We don't have to worry about numeric overflows when calculating
3760 the offsets because all elements are within the array data. */
3762 /* Set the dtype. */
3763 tmp
= gfc_conv_descriptor_dtype (parm
);
3764 gfc_add_modify_expr (&loop
.pre
, tmp
, gfc_get_dtype (parmtype
));
3766 if (se
->direct_byref
)
3767 base
= gfc_index_zero_node
;
3771 for (n
= 0; n
< info
->ref
->u
.ar
.dimen
; n
++)
3773 stride
= gfc_conv_array_stride (desc
, n
);
3775 /* Work out the offset. */
3776 if (info
->ref
->u
.ar
.dimen_type
[n
] == DIMEN_ELEMENT
)
3778 gcc_assert (info
->subscript
[n
]
3779 && info
->subscript
[n
]->type
== GFC_SS_SCALAR
);
3780 start
= info
->subscript
[n
]->data
.scalar
.expr
;
3784 /* Check we haven't somehow got out of sync. */
3785 gcc_assert (info
->dim
[dim
] == n
);
3787 /* Evaluate and remember the start of the section. */
3788 start
= info
->start
[dim
];
3789 stride
= gfc_evaluate_now (stride
, &loop
.pre
);
3792 tmp
= gfc_conv_array_lbound (desc
, n
);
3793 tmp
= fold_build2 (MINUS_EXPR
, TREE_TYPE (tmp
), start
, tmp
);
3795 tmp
= fold_build2 (MULT_EXPR
, TREE_TYPE (tmp
), tmp
, stride
);
3796 offset
= fold_build2 (PLUS_EXPR
, TREE_TYPE (tmp
), offset
, tmp
);
3798 if (info
->ref
->u
.ar
.dimen_type
[n
] == DIMEN_ELEMENT
)
3800 /* For elemental dimensions, we only need the offset. */
3804 /* Vector subscripts need copying and are handled elsewhere. */
3805 gcc_assert (info
->ref
->u
.ar
.dimen_type
[n
] == DIMEN_RANGE
);
3807 /* Set the new lower bound. */
3808 from
= loop
.from
[dim
];
3810 if (!integer_onep (from
))
3812 /* Make sure the new section starts at 1. */
3813 tmp
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
,
3814 gfc_index_one_node
, from
);
3815 to
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
, to
, tmp
);
3816 from
= gfc_index_one_node
;
3818 tmp
= gfc_conv_descriptor_lbound (parm
, gfc_rank_cst
[dim
]);
3819 gfc_add_modify_expr (&loop
.pre
, tmp
, from
);
3821 /* Set the new upper bound. */
3822 tmp
= gfc_conv_descriptor_ubound (parm
, gfc_rank_cst
[dim
]);
3823 gfc_add_modify_expr (&loop
.pre
, tmp
, to
);
3825 /* Multiply the stride by the section stride to get the
3827 stride
= fold_build2 (MULT_EXPR
, gfc_array_index_type
,
3828 stride
, info
->stride
[dim
]);
3830 if (se
->direct_byref
)
3831 base
= fold_build2 (MINUS_EXPR
, TREE_TYPE (base
),
3834 /* Store the new stride. */
3835 tmp
= gfc_conv_descriptor_stride (parm
, gfc_rank_cst
[dim
]);
3836 gfc_add_modify_expr (&loop
.pre
, tmp
, stride
);
3841 /* Point the data pointer at the first element in the section. */
3842 tmp
= gfc_conv_array_data (desc
);
3843 tmp
= gfc_build_indirect_ref (tmp
);
3844 tmp
= gfc_build_array_ref (tmp
, offset
);
3845 offset
= gfc_build_addr_expr (gfc_array_dataptr_type (desc
), tmp
);
3847 tmp
= gfc_conv_descriptor_data (parm
);
3848 gfc_add_modify_expr (&loop
.pre
, tmp
,
3849 fold_convert (TREE_TYPE (tmp
), offset
));
3851 if (se
->direct_byref
)
3853 /* Set the offset. */
3854 tmp
= gfc_conv_descriptor_offset (parm
);
3855 gfc_add_modify_expr (&loop
.pre
, tmp
, base
);
3859 /* Only the callee knows what the correct offset it, so just set
3861 tmp
= gfc_conv_descriptor_offset (parm
);
3862 gfc_add_modify_expr (&loop
.pre
, tmp
, gfc_index_zero_node
);
3865 if (!se
->direct_byref
)
3867 /* Get a pointer to the new descriptor. */
3868 if (se
->want_pointer
)
3869 se
->expr
= gfc_build_addr_expr (NULL
, parm
);
3875 gfc_add_block_to_block (&se
->pre
, &loop
.pre
);
3876 gfc_add_block_to_block (&se
->post
, &loop
.post
);
3878 /* Cleanup the scalarizer. */
3879 gfc_cleanup_loop (&loop
);
3883 /* Convert an array for passing as an actual parameter. */
3884 /* TODO: Optimize passing g77 arrays. */
3887 gfc_conv_array_parameter (gfc_se
* se
, gfc_expr
* expr
, gfc_ss
* ss
, int g77
)
3896 /* Passing address of the array if it is not pointer or assumed-shape. */
3897 if (expr
->expr_type
== EXPR_VARIABLE
3898 && expr
->ref
->u
.ar
.type
== AR_FULL
&& g77
)
3900 sym
= expr
->symtree
->n
.sym
;
3901 tmp
= gfc_get_symbol_decl (sym
);
3902 if (sym
->ts
.type
== BT_CHARACTER
)
3903 se
->string_length
= sym
->ts
.cl
->backend_decl
;
3904 if (!sym
->attr
.pointer
&& sym
->as
->type
!= AS_ASSUMED_SHAPE
3905 && !sym
->attr
.allocatable
)
3907 /* Some variables are declared directly, others are declared as
3908 pointers and allocated on the heap. */
3909 if (sym
->attr
.dummy
|| POINTER_TYPE_P (TREE_TYPE (tmp
)))
3912 se
->expr
= gfc_build_addr_expr (NULL
, tmp
);
3915 if (sym
->attr
.allocatable
)
3917 se
->expr
= gfc_conv_array_data (tmp
);
3922 se
->want_pointer
= 1;
3923 gfc_conv_expr_descriptor (se
, expr
, ss
);
3928 /* Repack the array. */
3929 tmp
= gfc_chainon_list (NULL_TREE
, desc
);
3930 ptr
= gfc_build_function_call (gfor_fndecl_in_pack
, tmp
);
3931 ptr
= gfc_evaluate_now (ptr
, &se
->pre
);
3934 gfc_start_block (&block
);
3936 /* Copy the data back. */
3937 tmp
= gfc_chainon_list (NULL_TREE
, desc
);
3938 tmp
= gfc_chainon_list (tmp
, ptr
);
3939 tmp
= gfc_build_function_call (gfor_fndecl_in_unpack
, tmp
);
3940 gfc_add_expr_to_block (&block
, tmp
);
3942 /* Free the temporary. */
3943 tmp
= convert (pvoid_type_node
, ptr
);
3944 tmp
= gfc_chainon_list (NULL_TREE
, tmp
);
3945 tmp
= gfc_build_function_call (gfor_fndecl_internal_free
, tmp
);
3946 gfc_add_expr_to_block (&block
, tmp
);
3948 stmt
= gfc_finish_block (&block
);
3950 gfc_init_block (&block
);
3951 /* Only if it was repacked. This code needs to be executed before the
3952 loop cleanup code. */
3953 tmp
= gfc_build_indirect_ref (desc
);
3954 tmp
= gfc_conv_array_data (tmp
);
3955 tmp
= build2 (NE_EXPR
, boolean_type_node
, ptr
, tmp
);
3956 tmp
= build3_v (COND_EXPR
, tmp
, stmt
, build_empty_stmt ());
3958 gfc_add_expr_to_block (&block
, tmp
);
3959 gfc_add_block_to_block (&block
, &se
->post
);
3961 gfc_init_block (&se
->post
);
3962 gfc_add_block_to_block (&se
->post
, &block
);
3967 /* NULLIFY an allocated/pointer array on function entry, free it on exit. */
3970 gfc_trans_deferred_array (gfc_symbol
* sym
, tree body
)
3977 stmtblock_t fnblock
;
3980 /* Make sure the frontend gets these right. */
3981 if (!(sym
->attr
.pointer
|| sym
->attr
.allocatable
))
3983 ("Possible frontend bug: Deferred array size without pointer or allocatable attribute.");
3985 gfc_init_block (&fnblock
);
3987 gcc_assert (TREE_CODE (sym
->backend_decl
) == VAR_DECL
);
3988 if (sym
->ts
.type
== BT_CHARACTER
3989 && !INTEGER_CST_P (sym
->ts
.cl
->backend_decl
))
3990 gfc_trans_init_string_length (sym
->ts
.cl
, &fnblock
);
3992 /* Parameter and use associated variables don't need anything special. */
3993 if (sym
->attr
.dummy
|| sym
->attr
.use_assoc
)
3995 gfc_add_expr_to_block (&fnblock
, body
);
3997 return gfc_finish_block (&fnblock
);
4000 gfc_get_backend_locus (&loc
);
4001 gfc_set_backend_locus (&sym
->declared_at
);
4002 descriptor
= sym
->backend_decl
;
4004 if (TREE_STATIC (descriptor
))
4006 /* SAVEd variables are not freed on exit. */
4007 gfc_trans_static_array_pointer (sym
);
4011 /* Get the descriptor type. */
4012 type
= TREE_TYPE (sym
->backend_decl
);
4013 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type
));
4015 /* NULLIFY the data pointer. */
4016 tmp
= gfc_conv_descriptor_data (descriptor
);
4017 gfc_add_modify_expr (&fnblock
, tmp
,
4018 convert (TREE_TYPE (tmp
), integer_zero_node
));
4020 gfc_add_expr_to_block (&fnblock
, body
);
4022 gfc_set_backend_locus (&loc
);
4023 /* Allocatable arrays need to be freed when they go out of scope. */
4024 if (sym
->attr
.allocatable
)
4026 gfc_start_block (&block
);
4028 /* Deallocate if still allocated at the end of the procedure. */
4029 deallocate
= gfc_array_deallocate (descriptor
);
4031 tmp
= gfc_conv_descriptor_data (descriptor
);
4032 tmp
= build2 (NE_EXPR
, boolean_type_node
, tmp
,
4033 build_int_cst (TREE_TYPE (tmp
), 0));
4034 tmp
= build3_v (COND_EXPR
, tmp
, deallocate
, build_empty_stmt ());
4035 gfc_add_expr_to_block (&block
, tmp
);
4037 tmp
= gfc_finish_block (&block
);
4038 gfc_add_expr_to_block (&fnblock
, tmp
);
4041 return gfc_finish_block (&fnblock
);
4044 /************ Expression Walking Functions ******************/
4046 /* Walk a variable reference.
4048 Possible extension - multiple component subscripts.
4049 x(:,:) = foo%a(:)%b(:)
4051 forall (i=..., j=...)
4052 x(i,j) = foo%a(j)%b(i)
4054 This adds a fair amout of complexity because you need to deal with more
4055 than one ref. Maybe handle in a similar manner to vector subscripts.
4056 Maybe not worth the effort. */
4060 gfc_walk_variable_expr (gfc_ss
* ss
, gfc_expr
* expr
)
4068 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
4070 /* We're only interested in array sections. */
4071 if (ref
->type
!= REF_ARRAY
)
4078 /* TODO: Take elemental array references out of scalarization
4083 newss
= gfc_get_ss ();
4084 newss
->type
= GFC_SS_SECTION
;
4087 newss
->data
.info
.dimen
= ar
->as
->rank
;
4088 newss
->data
.info
.ref
= ref
;
4090 /* Make sure array is the same as array(:,:), this way
4091 we don't need to special case all the time. */
4092 ar
->dimen
= ar
->as
->rank
;
4093 for (n
= 0; n
< ar
->dimen
; n
++)
4095 newss
->data
.info
.dim
[n
] = n
;
4096 ar
->dimen_type
[n
] = DIMEN_RANGE
;
4098 gcc_assert (ar
->start
[n
] == NULL
);
4099 gcc_assert (ar
->end
[n
] == NULL
);
4100 gcc_assert (ar
->stride
[n
] == NULL
);
4105 newss
= gfc_get_ss ();
4106 newss
->type
= GFC_SS_SECTION
;
4109 newss
->data
.info
.dimen
= 0;
4110 newss
->data
.info
.ref
= ref
;
4114 /* We add SS chains for all the subscripts in the section. */
4115 for (n
= 0; n
< ar
->dimen
; n
++)
4119 switch (ar
->dimen_type
[n
])
4122 /* Add SS for elemental (scalar) subscripts. */
4123 gcc_assert (ar
->start
[n
]);
4124 indexss
= gfc_get_ss ();
4125 indexss
->type
= GFC_SS_SCALAR
;
4126 indexss
->expr
= ar
->start
[n
];
4127 indexss
->next
= gfc_ss_terminator
;
4128 indexss
->loop_chain
= gfc_ss_terminator
;
4129 newss
->data
.info
.subscript
[n
] = indexss
;
4133 /* We don't add anything for sections, just remember this
4134 dimension for later. */
4135 newss
->data
.info
.dim
[newss
->data
.info
.dimen
] = n
;
4136 newss
->data
.info
.dimen
++;
4140 /* Get a SS for the vector. This will not be added to the
4142 indexss
= gfc_walk_expr (ar
->start
[n
]);
4143 if (indexss
== gfc_ss_terminator
)
4144 internal_error ("scalar vector subscript???");
4146 /* We currently only handle really simple vector
4148 if (indexss
->next
!= gfc_ss_terminator
)
4149 gfc_todo_error ("vector subscript expressions");
4150 indexss
->loop_chain
= gfc_ss_terminator
;
4152 /* Mark this as a vector subscript. We don't add this
4153 directly into the chain, but as a subscript of the
4154 existing SS for this term. */
4155 indexss
->type
= GFC_SS_VECTOR
;
4156 newss
->data
.info
.subscript
[n
] = indexss
;
4157 /* Also remember this dimension. */
4158 newss
->data
.info
.dim
[newss
->data
.info
.dimen
] = n
;
4159 newss
->data
.info
.dimen
++;
4163 /* We should know what sort of section it is by now. */
4167 /* We should have at least one non-elemental dimension. */
4168 gcc_assert (newss
->data
.info
.dimen
> 0);
4173 /* We should know what sort of section it is by now. */
4182 /* Walk an expression operator. If only one operand of a binary expression is
4183 scalar, we must also add the scalar term to the SS chain. */
4186 gfc_walk_op_expr (gfc_ss
* ss
, gfc_expr
* expr
)
4192 head
= gfc_walk_subexpr (ss
, expr
->value
.op
.op1
);
4193 if (expr
->value
.op
.op2
== NULL
)
4196 head2
= gfc_walk_subexpr (head
, expr
->value
.op
.op2
);
4198 /* All operands are scalar. Pass back and let the caller deal with it. */
4202 /* All operands require scalarization. */
4203 if (head
!= ss
&& (expr
->value
.op
.op2
== NULL
|| head2
!= head
))
4206 /* One of the operands needs scalarization, the other is scalar.
4207 Create a gfc_ss for the scalar expression. */
4208 newss
= gfc_get_ss ();
4209 newss
->type
= GFC_SS_SCALAR
;
4212 /* First operand is scalar. We build the chain in reverse order, so
4213 add the scarar SS after the second operand. */
4215 while (head
&& head
->next
!= ss
)
4217 /* Check we haven't somehow broken the chain. */
4221 newss
->expr
= expr
->value
.op
.op1
;
4223 else /* head2 == head */
4225 gcc_assert (head2
== head
);
4226 /* Second operand is scalar. */
4227 newss
->next
= head2
;
4229 newss
->expr
= expr
->value
.op
.op2
;
4236 /* Reverse a SS chain. */
4239 gfc_reverse_ss (gfc_ss
* ss
)
4244 gcc_assert (ss
!= NULL
);
4246 head
= gfc_ss_terminator
;
4247 while (ss
!= gfc_ss_terminator
)
4250 /* Check we didn't somehow break the chain. */
4251 gcc_assert (next
!= NULL
);
4261 /* Walk the arguments of an elemental function. */
4264 gfc_walk_elemental_function_args (gfc_ss
* ss
, gfc_expr
* expr
,
4267 gfc_actual_arglist
*arg
;
4273 head
= gfc_ss_terminator
;
4276 for (arg
= expr
->value
.function
.actual
; arg
; arg
= arg
->next
)
4281 newss
= gfc_walk_subexpr (head
, arg
->expr
);
4284 /* Scalar argument. */
4285 newss
= gfc_get_ss ();
4287 newss
->expr
= arg
->expr
;
4297 while (tail
->next
!= gfc_ss_terminator
)
4304 /* If all the arguments are scalar we don't need the argument SS. */
4305 gfc_free_ss_chain (head
);
4310 /* Add it onto the existing chain. */
4316 /* Walk a function call. Scalar functions are passed back, and taken out of
4317 scalarization loops. For elemental functions we walk their arguments.
4318 The result of functions returning arrays is stored in a temporary outside
4319 the loop, so that the function is only called once. Hence we do not need
4320 to walk their arguments. */
4323 gfc_walk_function_expr (gfc_ss
* ss
, gfc_expr
* expr
)
4326 gfc_intrinsic_sym
*isym
;
4329 isym
= expr
->value
.function
.isym
;
4331 /* Handle intrinsic functions separately. */
4333 return gfc_walk_intrinsic_function (ss
, expr
, isym
);
4335 sym
= expr
->value
.function
.esym
;
4337 sym
= expr
->symtree
->n
.sym
;
4339 /* A function that returns arrays. */
4340 if (gfc_return_by_reference (sym
) && sym
->result
->attr
.dimension
)
4342 newss
= gfc_get_ss ();
4343 newss
->type
= GFC_SS_FUNCTION
;
4346 newss
->data
.info
.dimen
= expr
->rank
;
4350 /* Walk the parameters of an elemental function. For now we always pass
4352 if (sym
->attr
.elemental
)
4353 return gfc_walk_elemental_function_args (ss
, expr
, GFC_SS_REFERENCE
);
4355 /* Scalar functions are OK as these are evaluated outside the scalarization
4356 loop. Pass back and let the caller deal with it. */
4361 /* An array temporary is constructed for array constructors. */
4364 gfc_walk_array_constructor (gfc_ss
* ss
, gfc_expr
* expr
)
4369 newss
= gfc_get_ss ();
4370 newss
->type
= GFC_SS_CONSTRUCTOR
;
4373 newss
->data
.info
.dimen
= expr
->rank
;
4374 for (n
= 0; n
< expr
->rank
; n
++)
4375 newss
->data
.info
.dim
[n
] = n
;
4381 /* Walk an expression. Add walked expressions to the head of the SS chain.
4382 A wholly scalar expression will not be added. */
4385 gfc_walk_subexpr (gfc_ss
* ss
, gfc_expr
* expr
)
4389 switch (expr
->expr_type
)
4392 head
= gfc_walk_variable_expr (ss
, expr
);
4396 head
= gfc_walk_op_expr (ss
, expr
);
4400 head
= gfc_walk_function_expr (ss
, expr
);
4405 case EXPR_STRUCTURE
:
4406 /* Pass back and let the caller deal with it. */
4410 head
= gfc_walk_array_constructor (ss
, expr
);
4413 case EXPR_SUBSTRING
:
4414 /* Pass back and let the caller deal with it. */
4418 internal_error ("bad expression type during walk (%d)",
4425 /* Entry point for expression walking.
4426 A return value equal to the passed chain means this is
4427 a scalar expression. It is up to the caller to take whatever action is
4428 necessary to translate these. */
4431 gfc_walk_expr (gfc_expr
* expr
)
4435 res
= gfc_walk_subexpr (gfc_ss_terminator
, expr
);
4436 return gfc_reverse_ss (res
);