1 /* Statement translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2002-2015 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 3, 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 COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
29 #include "fold-const.h"
30 #include "stringpool.h"
34 #include "trans-stmt.h"
35 #include "trans-types.h"
36 #include "trans-array.h"
37 #include "trans-const.h"
39 #include "dependency.h"
41 typedef struct iter_info
47 struct iter_info
*next
;
51 typedef struct forall_info
58 struct forall_info
*prev_nest
;
63 static void gfc_trans_where_2 (gfc_code
*, tree
, bool,
64 forall_info
*, stmtblock_t
*);
66 /* Translate a F95 label number to a LABEL_EXPR. */
69 gfc_trans_label_here (gfc_code
* code
)
71 return build1_v (LABEL_EXPR
, gfc_get_label_decl (code
->here
));
75 /* Given a variable expression which has been ASSIGNed to, find the decl
76 containing the auxiliary variables. For variables in common blocks this
80 gfc_conv_label_variable (gfc_se
* se
, gfc_expr
* expr
)
82 gcc_assert (expr
->symtree
->n
.sym
->attr
.assign
== 1);
83 gfc_conv_expr (se
, expr
);
84 /* Deals with variable in common block. Get the field declaration. */
85 if (TREE_CODE (se
->expr
) == COMPONENT_REF
)
86 se
->expr
= TREE_OPERAND (se
->expr
, 1);
87 /* Deals with dummy argument. Get the parameter declaration. */
88 else if (TREE_CODE (se
->expr
) == INDIRECT_REF
)
89 se
->expr
= TREE_OPERAND (se
->expr
, 0);
92 /* Translate a label assignment statement. */
95 gfc_trans_label_assign (gfc_code
* code
)
104 /* Start a new block. */
105 gfc_init_se (&se
, NULL
);
106 gfc_start_block (&se
.pre
);
107 gfc_conv_label_variable (&se
, code
->expr1
);
109 len
= GFC_DECL_STRING_LEN (se
.expr
);
110 addr
= GFC_DECL_ASSIGN_ADDR (se
.expr
);
112 label_tree
= gfc_get_label_decl (code
->label1
);
114 if (code
->label1
->defined
== ST_LABEL_TARGET
115 || code
->label1
->defined
== ST_LABEL_DO_TARGET
)
117 label_tree
= gfc_build_addr_expr (pvoid_type_node
, label_tree
);
118 len_tree
= integer_minus_one_node
;
122 gfc_expr
*format
= code
->label1
->format
;
124 label_len
= format
->value
.character
.length
;
125 len_tree
= build_int_cst (gfc_charlen_type_node
, label_len
);
126 label_tree
= gfc_build_wide_string_const (format
->ts
.kind
, label_len
+ 1,
127 format
->value
.character
.string
);
128 label_tree
= gfc_build_addr_expr (pvoid_type_node
, label_tree
);
131 gfc_add_modify (&se
.pre
, len
, len_tree
);
132 gfc_add_modify (&se
.pre
, addr
, label_tree
);
134 return gfc_finish_block (&se
.pre
);
137 /* Translate a GOTO statement. */
140 gfc_trans_goto (gfc_code
* code
)
142 locus loc
= code
->loc
;
148 if (code
->label1
!= NULL
)
149 return build1_v (GOTO_EXPR
, gfc_get_label_decl (code
->label1
));
152 gfc_init_se (&se
, NULL
);
153 gfc_start_block (&se
.pre
);
154 gfc_conv_label_variable (&se
, code
->expr1
);
155 tmp
= GFC_DECL_STRING_LEN (se
.expr
);
156 tmp
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
, tmp
,
157 build_int_cst (TREE_TYPE (tmp
), -1));
158 gfc_trans_runtime_check (true, false, tmp
, &se
.pre
, &loc
,
159 "Assigned label is not a target label");
161 assigned_goto
= GFC_DECL_ASSIGN_ADDR (se
.expr
);
163 /* We're going to ignore a label list. It does not really change the
164 statement's semantics (because it is just a further restriction on
165 what's legal code); before, we were comparing label addresses here, but
166 that's a very fragile business and may break with optimization. So
169 target
= fold_build1_loc (input_location
, GOTO_EXPR
, void_type_node
,
171 gfc_add_expr_to_block (&se
.pre
, target
);
172 return gfc_finish_block (&se
.pre
);
176 /* Translate an ENTRY statement. Just adds a label for this entry point. */
178 gfc_trans_entry (gfc_code
* code
)
180 return build1_v (LABEL_EXPR
, code
->ext
.entry
->label
);
184 /* Replace a gfc_ss structure by another both in the gfc_se struct
185 and the gfc_loopinfo struct. This is used in gfc_conv_elemental_dependencies
186 to replace a variable ss by the corresponding temporary. */
189 replace_ss (gfc_se
*se
, gfc_ss
*old_ss
, gfc_ss
*new_ss
)
191 gfc_ss
**sess
, **loopss
;
193 /* The old_ss is a ss for a single variable. */
194 gcc_assert (old_ss
->info
->type
== GFC_SS_SECTION
);
196 for (sess
= &(se
->ss
); *sess
!= gfc_ss_terminator
; sess
= &((*sess
)->next
))
199 gcc_assert (*sess
!= gfc_ss_terminator
);
202 new_ss
->next
= old_ss
->next
;
205 for (loopss
= &(se
->loop
->ss
); *loopss
!= gfc_ss_terminator
;
206 loopss
= &((*loopss
)->loop_chain
))
207 if (*loopss
== old_ss
)
209 gcc_assert (*loopss
!= gfc_ss_terminator
);
212 new_ss
->loop_chain
= old_ss
->loop_chain
;
213 new_ss
->loop
= old_ss
->loop
;
215 gfc_free_ss (old_ss
);
219 /* Check for dependencies between INTENT(IN) and INTENT(OUT) arguments of
220 elemental subroutines. Make temporaries for output arguments if any such
221 dependencies are found. Output arguments are chosen because internal_unpack
222 can be used, as is, to copy the result back to the variable. */
224 gfc_conv_elemental_dependencies (gfc_se
* se
, gfc_se
* loopse
,
225 gfc_symbol
* sym
, gfc_actual_arglist
* arg
,
226 gfc_dep_check check_variable
)
228 gfc_actual_arglist
*arg0
;
230 gfc_formal_arglist
*formal
;
238 if (loopse
->ss
== NULL
)
243 formal
= gfc_sym_get_dummy_args (sym
);
245 /* Loop over all the arguments testing for dependencies. */
246 for (; arg
!= NULL
; arg
= arg
->next
, formal
= formal
? formal
->next
: NULL
)
252 /* Obtain the info structure for the current argument. */
253 for (ss
= loopse
->ss
; ss
&& ss
!= gfc_ss_terminator
; ss
= ss
->next
)
254 if (ss
->info
->expr
== e
)
257 /* If there is a dependency, create a temporary and use it
258 instead of the variable. */
259 fsym
= formal
? formal
->sym
: NULL
;
260 if (e
->expr_type
== EXPR_VARIABLE
262 && fsym
->attr
.intent
!= INTENT_IN
263 && gfc_check_fncall_dependency (e
, fsym
->attr
.intent
,
264 sym
, arg0
, check_variable
))
266 tree initial
, temptype
;
267 stmtblock_t temp_post
;
270 tmp_ss
= gfc_get_array_ss (gfc_ss_terminator
, NULL
, ss
->dimen
,
272 gfc_mark_ss_chain_used (tmp_ss
, 1);
273 tmp_ss
->info
->expr
= ss
->info
->expr
;
274 replace_ss (loopse
, ss
, tmp_ss
);
276 /* Obtain the argument descriptor for unpacking. */
277 gfc_init_se (&parmse
, NULL
);
278 parmse
.want_pointer
= 1;
279 gfc_conv_expr_descriptor (&parmse
, e
);
280 gfc_add_block_to_block (&se
->pre
, &parmse
.pre
);
282 /* If we've got INTENT(INOUT) or a derived type with INTENT(OUT),
283 initialize the array temporary with a copy of the values. */
284 if (fsym
->attr
.intent
== INTENT_INOUT
285 || (fsym
->ts
.type
==BT_DERIVED
286 && fsym
->attr
.intent
== INTENT_OUT
))
287 initial
= parmse
.expr
;
288 /* For class expressions, we always initialize with the copy of
290 else if (e
->ts
.type
== BT_CLASS
)
291 initial
= parmse
.expr
;
295 if (e
->ts
.type
!= BT_CLASS
)
297 /* Find the type of the temporary to create; we don't use the type
298 of e itself as this breaks for subcomponent-references in e
299 (where the type of e is that of the final reference, but
300 parmse.expr's type corresponds to the full derived-type). */
301 /* TODO: Fix this somehow so we don't need a temporary of the whole
302 array but instead only the components referenced. */
303 temptype
= TREE_TYPE (parmse
.expr
); /* Pointer to descriptor. */
304 gcc_assert (TREE_CODE (temptype
) == POINTER_TYPE
);
305 temptype
= TREE_TYPE (temptype
);
306 temptype
= gfc_get_element_type (temptype
);
310 /* For class arrays signal that the size of the dynamic type has to
311 be obtained from the vtable, using the 'initial' expression. */
312 temptype
= NULL_TREE
;
314 /* Generate the temporary. Cleaning up the temporary should be the
315 very last thing done, so we add the code to a new block and add it
316 to se->post as last instructions. */
317 size
= gfc_create_var (gfc_array_index_type
, NULL
);
318 data
= gfc_create_var (pvoid_type_node
, NULL
);
319 gfc_init_block (&temp_post
);
320 tmp
= gfc_trans_create_temp_array (&se
->pre
, &temp_post
, tmp_ss
,
321 temptype
, initial
, false, true,
322 false, &arg
->expr
->where
);
323 gfc_add_modify (&se
->pre
, size
, tmp
);
324 tmp
= fold_convert (pvoid_type_node
, tmp_ss
->info
->data
.array
.data
);
325 gfc_add_modify (&se
->pre
, data
, tmp
);
327 /* Update other ss' delta. */
328 gfc_set_delta (loopse
->loop
);
330 /* Copy the result back using unpack..... */
331 if (e
->ts
.type
!= BT_CLASS
)
332 tmp
= build_call_expr_loc (input_location
,
333 gfor_fndecl_in_unpack
, 2, parmse
.expr
, data
);
336 /* ... except for class results where the copy is
338 tmp
= build_fold_indirect_ref_loc (input_location
, parmse
.expr
);
339 tmp
= gfc_conv_descriptor_data_get (tmp
);
340 tmp
= build_call_expr_loc (input_location
,
341 builtin_decl_explicit (BUILT_IN_MEMCPY
),
343 fold_convert (size_type_node
, size
));
345 gfc_add_expr_to_block (&se
->post
, tmp
);
347 /* parmse.pre is already added above. */
348 gfc_add_block_to_block (&se
->post
, &parmse
.post
);
349 gfc_add_block_to_block (&se
->post
, &temp_post
);
355 /* Get the interface symbol for the procedure corresponding to the given call.
356 We can't get the procedure symbol directly as we have to handle the case
357 of (deferred) type-bound procedures. */
360 get_proc_ifc_for_call (gfc_code
*c
)
364 gcc_assert (c
->op
== EXEC_ASSIGN_CALL
|| c
->op
== EXEC_CALL
);
366 sym
= gfc_get_proc_ifc_for_expr (c
->expr1
);
368 /* Fall back/last resort try. */
370 sym
= c
->resolved_sym
;
376 /* Translate the CALL statement. Builds a call to an F95 subroutine. */
379 gfc_trans_call (gfc_code
* code
, bool dependency_check
,
380 tree mask
, tree count1
, bool invert
)
384 int has_alternate_specifier
;
385 gfc_dep_check check_variable
;
386 tree index
= NULL_TREE
;
387 tree maskexpr
= NULL_TREE
;
390 /* A CALL starts a new block because the actual arguments may have to
391 be evaluated first. */
392 gfc_init_se (&se
, NULL
);
393 gfc_start_block (&se
.pre
);
395 gcc_assert (code
->resolved_sym
);
397 ss
= gfc_ss_terminator
;
398 if (code
->resolved_sym
->attr
.elemental
)
399 ss
= gfc_walk_elemental_function_args (ss
, code
->ext
.actual
,
400 get_proc_ifc_for_call (code
),
403 /* Is not an elemental subroutine call with array valued arguments. */
404 if (ss
== gfc_ss_terminator
)
407 /* Translate the call. */
408 has_alternate_specifier
409 = gfc_conv_procedure_call (&se
, code
->resolved_sym
, code
->ext
.actual
,
412 /* A subroutine without side-effect, by definition, does nothing! */
413 TREE_SIDE_EFFECTS (se
.expr
) = 1;
415 /* Chain the pieces together and return the block. */
416 if (has_alternate_specifier
)
418 gfc_code
*select_code
;
420 select_code
= code
->next
;
421 gcc_assert(select_code
->op
== EXEC_SELECT
);
422 sym
= select_code
->expr1
->symtree
->n
.sym
;
423 se
.expr
= convert (gfc_typenode_for_spec (&sym
->ts
), se
.expr
);
424 if (sym
->backend_decl
== NULL
)
425 sym
->backend_decl
= gfc_get_symbol_decl (sym
);
426 gfc_add_modify (&se
.pre
, sym
->backend_decl
, se
.expr
);
429 gfc_add_expr_to_block (&se
.pre
, se
.expr
);
431 gfc_add_block_to_block (&se
.pre
, &se
.post
);
436 /* An elemental subroutine call with array valued arguments has
444 /* gfc_walk_elemental_function_args renders the ss chain in the
445 reverse order to the actual argument order. */
446 ss
= gfc_reverse_ss (ss
);
448 /* Initialize the loop. */
449 gfc_init_se (&loopse
, NULL
);
450 gfc_init_loopinfo (&loop
);
451 gfc_add_ss_to_loop (&loop
, ss
);
453 gfc_conv_ss_startstride (&loop
);
454 /* TODO: gfc_conv_loop_setup generates a temporary for vector
455 subscripts. This could be prevented in the elemental case
456 as temporaries are handled separatedly
457 (below in gfc_conv_elemental_dependencies). */
458 gfc_conv_loop_setup (&loop
, &code
->expr1
->where
);
459 gfc_mark_ss_chain_used (ss
, 1);
461 /* Convert the arguments, checking for dependencies. */
462 gfc_copy_loopinfo_to_se (&loopse
, &loop
);
465 /* For operator assignment, do dependency checking. */
466 if (dependency_check
)
467 check_variable
= ELEM_CHECK_VARIABLE
;
469 check_variable
= ELEM_DONT_CHECK_VARIABLE
;
471 gfc_init_se (&depse
, NULL
);
472 gfc_conv_elemental_dependencies (&depse
, &loopse
, code
->resolved_sym
,
473 code
->ext
.actual
, check_variable
);
475 gfc_add_block_to_block (&loop
.pre
, &depse
.pre
);
476 gfc_add_block_to_block (&loop
.post
, &depse
.post
);
478 /* Generate the loop body. */
479 gfc_start_scalarized_body (&loop
, &body
);
480 gfc_init_block (&block
);
484 /* Form the mask expression according to the mask. */
486 maskexpr
= gfc_build_array_ref (mask
, index
, NULL
);
488 maskexpr
= fold_build1_loc (input_location
, TRUTH_NOT_EXPR
,
489 TREE_TYPE (maskexpr
), maskexpr
);
492 /* Add the subroutine call to the block. */
493 gfc_conv_procedure_call (&loopse
, code
->resolved_sym
,
494 code
->ext
.actual
, code
->expr1
,
499 tmp
= build3_v (COND_EXPR
, maskexpr
, loopse
.expr
,
500 build_empty_stmt (input_location
));
501 gfc_add_expr_to_block (&loopse
.pre
, tmp
);
502 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
503 gfc_array_index_type
,
504 count1
, gfc_index_one_node
);
505 gfc_add_modify (&loopse
.pre
, count1
, tmp
);
508 gfc_add_expr_to_block (&loopse
.pre
, loopse
.expr
);
510 gfc_add_block_to_block (&block
, &loopse
.pre
);
511 gfc_add_block_to_block (&block
, &loopse
.post
);
513 /* Finish up the loop block and the loop. */
514 gfc_add_expr_to_block (&body
, gfc_finish_block (&block
));
515 gfc_trans_scalarizing_loops (&loop
, &body
);
516 gfc_add_block_to_block (&se
.pre
, &loop
.pre
);
517 gfc_add_block_to_block (&se
.pre
, &loop
.post
);
518 gfc_add_block_to_block (&se
.pre
, &se
.post
);
519 gfc_cleanup_loop (&loop
);
522 return gfc_finish_block (&se
.pre
);
526 /* Translate the RETURN statement. */
529 gfc_trans_return (gfc_code
* code
)
537 /* If code->expr is not NULL, this return statement must appear
538 in a subroutine and current_fake_result_decl has already
541 result
= gfc_get_fake_result_decl (NULL
, 0);
545 "An alternate return at %L without a * dummy argument",
546 &code
->expr1
->where
);
547 return gfc_generate_return ();
550 /* Start a new block for this statement. */
551 gfc_init_se (&se
, NULL
);
552 gfc_start_block (&se
.pre
);
554 gfc_conv_expr (&se
, code
->expr1
);
556 /* Note that the actually returned expression is a simple value and
557 does not depend on any pointers or such; thus we can clean-up with
558 se.post before returning. */
559 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, TREE_TYPE (result
),
560 result
, fold_convert (TREE_TYPE (result
),
562 gfc_add_expr_to_block (&se
.pre
, tmp
);
563 gfc_add_block_to_block (&se
.pre
, &se
.post
);
565 tmp
= gfc_generate_return ();
566 gfc_add_expr_to_block (&se
.pre
, tmp
);
567 return gfc_finish_block (&se
.pre
);
570 return gfc_generate_return ();
574 /* Translate the PAUSE statement. We have to translate this statement
575 to a runtime library call. */
578 gfc_trans_pause (gfc_code
* code
)
580 tree gfc_int4_type_node
= gfc_get_int_type (4);
584 /* Start a new block for this statement. */
585 gfc_init_se (&se
, NULL
);
586 gfc_start_block (&se
.pre
);
589 if (code
->expr1
== NULL
)
591 tmp
= build_int_cst (gfc_int4_type_node
, 0);
592 tmp
= build_call_expr_loc (input_location
,
593 gfor_fndecl_pause_string
, 2,
594 build_int_cst (pchar_type_node
, 0), tmp
);
596 else if (code
->expr1
->ts
.type
== BT_INTEGER
)
598 gfc_conv_expr (&se
, code
->expr1
);
599 tmp
= build_call_expr_loc (input_location
,
600 gfor_fndecl_pause_numeric
, 1,
601 fold_convert (gfc_int4_type_node
, se
.expr
));
605 gfc_conv_expr_reference (&se
, code
->expr1
);
606 tmp
= build_call_expr_loc (input_location
,
607 gfor_fndecl_pause_string
, 2,
608 se
.expr
, se
.string_length
);
611 gfc_add_expr_to_block (&se
.pre
, tmp
);
613 gfc_add_block_to_block (&se
.pre
, &se
.post
);
615 return gfc_finish_block (&se
.pre
);
619 /* Translate the STOP statement. We have to translate this statement
620 to a runtime library call. */
623 gfc_trans_stop (gfc_code
*code
, bool error_stop
)
625 tree gfc_int4_type_node
= gfc_get_int_type (4);
629 /* Start a new block for this statement. */
630 gfc_init_se (&se
, NULL
);
631 gfc_start_block (&se
.pre
);
633 if (code
->expr1
== NULL
)
635 tmp
= build_int_cst (gfc_int4_type_node
, 0);
636 tmp
= build_call_expr_loc (input_location
,
638 ? (flag_coarray
== GFC_FCOARRAY_LIB
639 ? gfor_fndecl_caf_error_stop_str
640 : gfor_fndecl_error_stop_string
)
641 : gfor_fndecl_stop_string
,
642 2, build_int_cst (pchar_type_node
, 0), tmp
);
644 else if (code
->expr1
->ts
.type
== BT_INTEGER
)
646 gfc_conv_expr (&se
, code
->expr1
);
647 tmp
= build_call_expr_loc (input_location
,
649 ? (flag_coarray
== GFC_FCOARRAY_LIB
650 ? gfor_fndecl_caf_error_stop
651 : gfor_fndecl_error_stop_numeric
)
652 : gfor_fndecl_stop_numeric_f08
, 1,
653 fold_convert (gfc_int4_type_node
, se
.expr
));
657 gfc_conv_expr_reference (&se
, code
->expr1
);
658 tmp
= build_call_expr_loc (input_location
,
660 ? (flag_coarray
== GFC_FCOARRAY_LIB
661 ? gfor_fndecl_caf_error_stop_str
662 : gfor_fndecl_error_stop_string
)
663 : gfor_fndecl_stop_string
,
664 2, se
.expr
, se
.string_length
);
667 gfc_add_expr_to_block (&se
.pre
, tmp
);
669 gfc_add_block_to_block (&se
.pre
, &se
.post
);
671 return gfc_finish_block (&se
.pre
);
676 gfc_trans_lock_unlock (gfc_code
*code
, gfc_exec_op op
)
679 tree stat
= NULL_TREE
, stat2
= NULL_TREE
;
680 tree lock_acquired
= NULL_TREE
, lock_acquired2
= NULL_TREE
;
682 /* Short cut: For single images without STAT= or LOCK_ACQUIRED
683 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
684 if (!code
->expr2
&& !code
->expr4
&& flag_coarray
!= GFC_FCOARRAY_LIB
)
689 gcc_assert (code
->expr2
->expr_type
== EXPR_VARIABLE
);
690 gfc_init_se (&argse
, NULL
);
691 gfc_conv_expr_val (&argse
, code
->expr2
);
694 else if (flag_coarray
== GFC_FCOARRAY_LIB
)
695 stat
= null_pointer_node
;
699 gcc_assert (code
->expr4
->expr_type
== EXPR_VARIABLE
);
700 gfc_init_se (&argse
, NULL
);
701 gfc_conv_expr_val (&argse
, code
->expr4
);
702 lock_acquired
= argse
.expr
;
704 else if (flag_coarray
== GFC_FCOARRAY_LIB
)
705 lock_acquired
= null_pointer_node
;
707 gfc_start_block (&se
.pre
);
708 if (flag_coarray
== GFC_FCOARRAY_LIB
)
710 tree tmp
, token
, image_index
, errmsg
, errmsg_len
;
711 tree index
= size_zero_node
;
712 tree caf_decl
= gfc_get_tree_for_caf_expr (code
->expr1
);
714 if (code
->expr1
->symtree
->n
.sym
->ts
.type
!= BT_DERIVED
715 || code
->expr1
->symtree
->n
.sym
->ts
.u
.derived
->from_intmod
716 != INTMOD_ISO_FORTRAN_ENV
717 || code
->expr1
->symtree
->n
.sym
->ts
.u
.derived
->intmod_sym_id
718 != ISOFORTRAN_LOCK_TYPE
)
720 gfc_error ("Sorry, the lock component of derived type at %L is not "
721 "yet supported", &code
->expr1
->where
);
725 gfc_get_caf_token_offset (&token
, NULL
, caf_decl
, NULL_TREE
, code
->expr1
);
727 if (gfc_is_coindexed (code
->expr1
))
728 image_index
= gfc_caf_get_image_index (&se
.pre
, code
->expr1
, caf_decl
);
730 image_index
= integer_zero_node
;
732 /* For arrays, obtain the array index. */
733 if (gfc_expr_attr (code
->expr1
).dimension
)
735 tree desc
, tmp
, extent
, lbound
, ubound
;
736 gfc_array_ref
*ar
, ar2
;
739 /* TODO: Extend this, once DT components are supported. */
740 ar
= &code
->expr1
->ref
->u
.ar
;
742 memset (ar
, '\0', sizeof (*ar
));
746 gfc_init_se (&argse
, NULL
);
747 argse
.descriptor_only
= 1;
748 gfc_conv_expr_descriptor (&argse
, code
->expr1
);
749 gfc_add_block_to_block (&se
.pre
, &argse
.pre
);
753 extent
= integer_one_node
;
754 for (i
= 0; i
< ar
->dimen
; i
++)
756 gfc_init_se (&argse
, NULL
);
757 gfc_conv_expr_type (&argse
, ar
->start
[i
], integer_type_node
);
758 gfc_add_block_to_block (&argse
.pre
, &argse
.pre
);
759 lbound
= gfc_conv_descriptor_lbound_get (desc
, gfc_rank_cst
[i
]);
760 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
761 integer_type_node
, argse
.expr
,
762 fold_convert(integer_type_node
, lbound
));
763 tmp
= fold_build2_loc (input_location
, MULT_EXPR
,
764 integer_type_node
, extent
, tmp
);
765 index
= fold_build2_loc (input_location
, PLUS_EXPR
,
766 integer_type_node
, index
, tmp
);
767 if (i
< ar
->dimen
- 1)
769 ubound
= gfc_conv_descriptor_ubound_get (desc
, gfc_rank_cst
[i
]);
770 tmp
= gfc_conv_array_extent_dim (lbound
, ubound
, NULL
);
771 tmp
= fold_convert (integer_type_node
, tmp
);
772 extent
= fold_build2_loc (input_location
, MULT_EXPR
,
773 integer_type_node
, extent
, tmp
);
781 gfc_init_se (&argse
, NULL
);
782 gfc_conv_expr (&argse
, code
->expr3
);
783 gfc_add_block_to_block (&se
.pre
, &argse
.pre
);
785 errmsg_len
= fold_convert (integer_type_node
, argse
.string_length
);
789 errmsg
= null_pointer_node
;
790 errmsg_len
= integer_zero_node
;
793 if (stat
!= null_pointer_node
&& TREE_TYPE (stat
) != integer_type_node
)
796 stat
= gfc_create_var (integer_type_node
, "stat");
799 if (lock_acquired
!= null_pointer_node
800 && TREE_TYPE (lock_acquired
) != integer_type_node
)
802 lock_acquired2
= lock_acquired
;
803 lock_acquired
= gfc_create_var (integer_type_node
, "acquired");
807 tmp
= build_call_expr_loc (input_location
, gfor_fndecl_caf_lock
, 7,
808 token
, index
, image_index
,
809 lock_acquired
!= null_pointer_node
810 ? gfc_build_addr_expr (NULL
, lock_acquired
)
812 stat
!= null_pointer_node
813 ? gfc_build_addr_expr (NULL
, stat
) : stat
,
816 tmp
= build_call_expr_loc (input_location
, gfor_fndecl_caf_unlock
, 6,
817 token
, index
, image_index
,
818 stat
!= null_pointer_node
819 ? gfc_build_addr_expr (NULL
, stat
) : stat
,
821 gfc_add_expr_to_block (&se
.pre
, tmp
);
823 if (stat2
!= NULL_TREE
)
824 gfc_add_modify (&se
.pre
, stat2
,
825 fold_convert (TREE_TYPE (stat2
), stat
));
827 if (lock_acquired2
!= NULL_TREE
)
828 gfc_add_modify (&se
.pre
, lock_acquired2
,
829 fold_convert (TREE_TYPE (lock_acquired2
),
832 return gfc_finish_block (&se
.pre
);
835 if (stat
!= NULL_TREE
)
836 gfc_add_modify (&se
.pre
, stat
, build_int_cst (TREE_TYPE (stat
), 0));
838 if (lock_acquired
!= NULL_TREE
)
839 gfc_add_modify (&se
.pre
, lock_acquired
,
840 fold_convert (TREE_TYPE (lock_acquired
),
843 return gfc_finish_block (&se
.pre
);
848 gfc_trans_sync (gfc_code
*code
, gfc_exec_op type
)
852 tree images
= NULL_TREE
, stat
= NULL_TREE
,
853 errmsg
= NULL_TREE
, errmsglen
= NULL_TREE
;
855 /* Short cut: For single images without bound checking or without STAT=,
856 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
857 if (!code
->expr2
&& !(gfc_option
.rtcheck
& GFC_RTCHECK_BOUNDS
)
858 && flag_coarray
!= GFC_FCOARRAY_LIB
)
861 gfc_init_se (&se
, NULL
);
862 gfc_start_block (&se
.pre
);
864 if (code
->expr1
&& code
->expr1
->rank
== 0)
866 gfc_init_se (&argse
, NULL
);
867 gfc_conv_expr_val (&argse
, code
->expr1
);
873 gcc_assert (code
->expr2
->expr_type
== EXPR_VARIABLE
);
874 gfc_init_se (&argse
, NULL
);
875 gfc_conv_expr_val (&argse
, code
->expr2
);
879 stat
= null_pointer_node
;
881 if (code
->expr3
&& flag_coarray
== GFC_FCOARRAY_LIB
)
883 gcc_assert (code
->expr3
->expr_type
== EXPR_VARIABLE
);
884 gfc_init_se (&argse
, NULL
);
885 gfc_conv_expr (&argse
, code
->expr3
);
886 gfc_conv_string_parameter (&argse
);
887 errmsg
= gfc_build_addr_expr (NULL
, argse
.expr
);
888 errmsglen
= argse
.string_length
;
890 else if (flag_coarray
== GFC_FCOARRAY_LIB
)
892 errmsg
= null_pointer_node
;
893 errmsglen
= build_int_cst (integer_type_node
, 0);
896 /* Check SYNC IMAGES(imageset) for valid image index.
897 FIXME: Add a check for image-set arrays. */
898 if (code
->expr1
&& (gfc_option
.rtcheck
& GFC_RTCHECK_BOUNDS
)
899 && code
->expr1
->rank
== 0)
902 if (flag_coarray
!= GFC_FCOARRAY_LIB
)
903 cond
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
,
904 images
, build_int_cst (TREE_TYPE (images
), 1));
908 tmp
= build_call_expr_loc (input_location
, gfor_fndecl_caf_num_images
,
909 2, integer_zero_node
,
910 build_int_cst (integer_type_node
, -1));
911 cond
= fold_build2_loc (input_location
, GT_EXPR
, boolean_type_node
,
913 cond2
= fold_build2_loc (input_location
, LT_EXPR
, boolean_type_node
,
915 build_int_cst (TREE_TYPE (images
), 1));
916 cond
= fold_build2_loc (input_location
, TRUTH_OR_EXPR
,
917 boolean_type_node
, cond
, cond2
);
919 gfc_trans_runtime_check (true, false, cond
, &se
.pre
,
920 &code
->expr1
->where
, "Invalid image number "
922 fold_convert (integer_type_node
, images
));
925 if (flag_coarray
!= GFC_FCOARRAY_LIB
)
927 /* Set STAT to zero. */
929 gfc_add_modify (&se
.pre
, stat
, build_int_cst (TREE_TYPE (stat
), 0));
931 else if (type
== EXEC_SYNC_ALL
|| type
== EXEC_SYNC_MEMORY
)
933 /* SYNC ALL => stat == null_pointer_node
934 SYNC ALL(stat=s) => stat has an integer type
936 If "stat" has the wrong integer type, use a temp variable of
937 the right type and later cast the result back into "stat". */
938 if (stat
== null_pointer_node
|| TREE_TYPE (stat
) == integer_type_node
)
940 if (TREE_TYPE (stat
) == integer_type_node
)
941 stat
= gfc_build_addr_expr (NULL
, stat
);
943 if(type
== EXEC_SYNC_MEMORY
)
944 tmp
= build_call_expr_loc (input_location
, gfor_fndecl_caf_sync_memory
,
945 3, stat
, errmsg
, errmsglen
);
947 tmp
= build_call_expr_loc (input_location
, gfor_fndecl_caf_sync_all
,
948 3, stat
, errmsg
, errmsglen
);
950 gfc_add_expr_to_block (&se
.pre
, tmp
);
954 tree tmp_stat
= gfc_create_var (integer_type_node
, "stat");
956 tmp
= build_call_expr_loc (input_location
, gfor_fndecl_caf_sync_all
,
957 3, gfc_build_addr_expr (NULL
, tmp_stat
),
959 gfc_add_expr_to_block (&se
.pre
, tmp
);
961 gfc_add_modify (&se
.pre
, stat
,
962 fold_convert (TREE_TYPE (stat
), tmp_stat
));
969 gcc_assert (type
== EXEC_SYNC_IMAGES
);
973 len
= build_int_cst (integer_type_node
, -1);
974 images
= null_pointer_node
;
976 else if (code
->expr1
->rank
== 0)
978 len
= build_int_cst (integer_type_node
, 1);
979 images
= gfc_build_addr_expr (NULL_TREE
, images
);
984 if (code
->expr1
->ts
.kind
!= gfc_c_int_kind
)
985 gfc_fatal_error ("Sorry, only support for integer kind %d "
986 "implemented for image-set at %L",
987 gfc_c_int_kind
, &code
->expr1
->where
);
989 gfc_conv_array_parameter (&se
, code
->expr1
, true, NULL
, NULL
, &len
);
992 tmp
= gfc_typenode_for_spec (&code
->expr1
->ts
);
993 if (GFC_ARRAY_TYPE_P (tmp
) || GFC_DESCRIPTOR_TYPE_P (tmp
))
994 tmp
= gfc_get_element_type (tmp
);
996 len
= fold_build2_loc (input_location
, TRUNC_DIV_EXPR
,
997 TREE_TYPE (len
), len
,
998 fold_convert (TREE_TYPE (len
),
999 TYPE_SIZE_UNIT (tmp
)));
1000 len
= fold_convert (integer_type_node
, len
);
1003 /* SYNC IMAGES(imgs) => stat == null_pointer_node
1004 SYNC IMAGES(imgs,stat=s) => stat has an integer type
1006 If "stat" has the wrong integer type, use a temp variable of
1007 the right type and later cast the result back into "stat". */
1008 if (stat
== null_pointer_node
|| TREE_TYPE (stat
) == integer_type_node
)
1010 if (TREE_TYPE (stat
) == integer_type_node
)
1011 stat
= gfc_build_addr_expr (NULL
, stat
);
1013 tmp
= build_call_expr_loc (input_location
, gfor_fndecl_caf_sync_images
,
1014 5, fold_convert (integer_type_node
, len
),
1015 images
, stat
, errmsg
, errmsglen
);
1016 gfc_add_expr_to_block (&se
.pre
, tmp
);
1020 tree tmp_stat
= gfc_create_var (integer_type_node
, "stat");
1022 tmp
= build_call_expr_loc (input_location
, gfor_fndecl_caf_sync_images
,
1023 5, fold_convert (integer_type_node
, len
),
1024 images
, gfc_build_addr_expr (NULL
, tmp_stat
),
1026 gfc_add_expr_to_block (&se
.pre
, tmp
);
1028 gfc_add_modify (&se
.pre
, stat
,
1029 fold_convert (TREE_TYPE (stat
), tmp_stat
));
1033 return gfc_finish_block (&se
.pre
);
1037 /* Generate GENERIC for the IF construct. This function also deals with
1038 the simple IF statement, because the front end translates the IF
1039 statement into an IF construct.
1071 where COND_S is the simplified version of the predicate. PRE_COND_S
1072 are the pre side-effects produced by the translation of the
1074 We need to build the chain recursively otherwise we run into
1075 problems with folding incomplete statements. */
1078 gfc_trans_if_1 (gfc_code
* code
)
1081 tree stmt
, elsestmt
;
1085 /* Check for an unconditional ELSE clause. */
1087 return gfc_trans_code (code
->next
);
1089 /* Initialize a statement builder for each block. Puts in NULL_TREEs. */
1090 gfc_init_se (&if_se
, NULL
);
1091 gfc_start_block (&if_se
.pre
);
1093 /* Calculate the IF condition expression. */
1094 if (code
->expr1
->where
.lb
)
1096 gfc_save_backend_locus (&saved_loc
);
1097 gfc_set_backend_locus (&code
->expr1
->where
);
1100 gfc_conv_expr_val (&if_se
, code
->expr1
);
1102 if (code
->expr1
->where
.lb
)
1103 gfc_restore_backend_locus (&saved_loc
);
1105 /* Translate the THEN clause. */
1106 stmt
= gfc_trans_code (code
->next
);
1108 /* Translate the ELSE clause. */
1110 elsestmt
= gfc_trans_if_1 (code
->block
);
1112 elsestmt
= build_empty_stmt (input_location
);
1114 /* Build the condition expression and add it to the condition block. */
1115 loc
= code
->expr1
->where
.lb
? code
->expr1
->where
.lb
->location
: input_location
;
1116 stmt
= fold_build3_loc (loc
, COND_EXPR
, void_type_node
, if_se
.expr
, stmt
,
1119 gfc_add_expr_to_block (&if_se
.pre
, stmt
);
1121 /* Finish off this statement. */
1122 return gfc_finish_block (&if_se
.pre
);
1126 gfc_trans_if (gfc_code
* code
)
1131 /* Create exit label so it is available for trans'ing the body code. */
1132 exit_label
= gfc_build_label_decl (NULL_TREE
);
1133 code
->exit_label
= exit_label
;
1135 /* Translate the actual code in code->block. */
1136 gfc_init_block (&body
);
1137 gfc_add_expr_to_block (&body
, gfc_trans_if_1 (code
->block
));
1139 /* Add exit label. */
1140 gfc_add_expr_to_block (&body
, build1_v (LABEL_EXPR
, exit_label
));
1142 return gfc_finish_block (&body
);
1146 /* Translate an arithmetic IF expression.
1148 IF (cond) label1, label2, label3 translates to
1160 An optimized version can be generated in case of equal labels.
1161 E.g., if label1 is equal to label2, we can translate it to
1170 gfc_trans_arithmetic_if (gfc_code
* code
)
1178 /* Start a new block. */
1179 gfc_init_se (&se
, NULL
);
1180 gfc_start_block (&se
.pre
);
1182 /* Pre-evaluate COND. */
1183 gfc_conv_expr_val (&se
, code
->expr1
);
1184 se
.expr
= gfc_evaluate_now (se
.expr
, &se
.pre
);
1186 /* Build something to compare with. */
1187 zero
= gfc_build_const (TREE_TYPE (se
.expr
), integer_zero_node
);
1189 if (code
->label1
->value
!= code
->label2
->value
)
1191 /* If (cond < 0) take branch1 else take branch2.
1192 First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases. */
1193 branch1
= build1_v (GOTO_EXPR
, gfc_get_label_decl (code
->label1
));
1194 branch2
= build1_v (GOTO_EXPR
, gfc_get_label_decl (code
->label2
));
1196 if (code
->label1
->value
!= code
->label3
->value
)
1197 tmp
= fold_build2_loc (input_location
, LT_EXPR
, boolean_type_node
,
1200 tmp
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
,
1203 branch1
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
1204 tmp
, branch1
, branch2
);
1207 branch1
= build1_v (GOTO_EXPR
, gfc_get_label_decl (code
->label1
));
1209 if (code
->label1
->value
!= code
->label3
->value
1210 && code
->label2
->value
!= code
->label3
->value
)
1212 /* if (cond <= 0) take branch1 else take branch2. */
1213 branch2
= build1_v (GOTO_EXPR
, gfc_get_label_decl (code
->label3
));
1214 tmp
= fold_build2_loc (input_location
, LE_EXPR
, boolean_type_node
,
1216 branch1
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
1217 tmp
, branch1
, branch2
);
1220 /* Append the COND_EXPR to the evaluation of COND, and return. */
1221 gfc_add_expr_to_block (&se
.pre
, branch1
);
1222 return gfc_finish_block (&se
.pre
);
1226 /* Translate a CRITICAL block. */
1228 gfc_trans_critical (gfc_code
*code
)
1231 tree tmp
, token
= NULL_TREE
;
1233 gfc_start_block (&block
);
1235 if (flag_coarray
== GFC_FCOARRAY_LIB
)
1237 token
= gfc_get_symbol_decl (code
->resolved_sym
);
1238 token
= GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (token
));
1239 tmp
= build_call_expr_loc (input_location
, gfor_fndecl_caf_lock
, 7,
1240 token
, integer_zero_node
, integer_one_node
,
1241 null_pointer_node
, null_pointer_node
,
1242 null_pointer_node
, integer_zero_node
);
1243 gfc_add_expr_to_block (&block
, tmp
);
1246 tmp
= gfc_trans_code (code
->block
->next
);
1247 gfc_add_expr_to_block (&block
, tmp
);
1249 if (flag_coarray
== GFC_FCOARRAY_LIB
)
1251 tmp
= build_call_expr_loc (input_location
, gfor_fndecl_caf_unlock
, 6,
1252 token
, integer_zero_node
, integer_one_node
,
1253 null_pointer_node
, null_pointer_node
,
1255 gfc_add_expr_to_block (&block
, tmp
);
1259 return gfc_finish_block (&block
);
1263 /* Return true, when the class has a _len component. */
1266 class_has_len_component (gfc_symbol
*sym
)
1268 gfc_component
*comp
= sym
->ts
.u
.derived
->components
;
1271 if (strcmp (comp
->name
, "_len") == 0)
1279 /* Do proper initialization for ASSOCIATE names. */
1282 trans_associate_var (gfc_symbol
*sym
, gfc_wrapped_block
*block
)
1293 bool need_len_assign
;
1295 gcc_assert (sym
->assoc
);
1296 e
= sym
->assoc
->target
;
1298 class_target
= (e
->expr_type
== EXPR_VARIABLE
)
1299 && (gfc_is_class_scalar_expr (e
)
1300 || gfc_is_class_array_ref (e
, NULL
));
1302 unlimited
= UNLIMITED_POLY (e
);
1304 /* Assignments to the string length need to be generated, when
1305 ( sym is a char array or
1306 sym has a _len component)
1307 and the associated expression is unlimited polymorphic, which is
1308 not (yet) correctly in 'unlimited', because for an already associated
1309 BT_DERIVED the u-poly flag is not set, i.e.,
1310 __tmp_CHARACTER_0_1 => w => arg
1311 ^ generated temp ^ from code, the w does not have the u-poly
1312 flag set, where UNLIMITED_POLY(e) expects it. */
1313 need_len_assign
= ((unlimited
|| (e
->ts
.type
== BT_DERIVED
1314 && e
->ts
.u
.derived
->attr
.unlimited_polymorphic
))
1315 && (sym
->ts
.type
== BT_CHARACTER
1316 || ((sym
->ts
.type
== BT_CLASS
|| sym
->ts
.type
== BT_DERIVED
)
1317 && class_has_len_component (sym
))));
1318 /* Do a `pointer assignment' with updated descriptor (or assign descriptor
1319 to array temporary) for arrays with either unknown shape or if associating
1321 if (sym
->attr
.dimension
&& !class_target
1322 && (sym
->as
->type
== AS_DEFERRED
|| sym
->assoc
->variable
))
1326 bool cst_array_ctor
;
1328 desc
= sym
->backend_decl
;
1329 cst_array_ctor
= e
->expr_type
== EXPR_ARRAY
1330 && gfc_constant_array_constructor_p (e
->value
.constructor
);
1332 /* If association is to an expression, evaluate it and create temporary.
1333 Otherwise, get descriptor of target for pointer assignment. */
1334 gfc_init_se (&se
, NULL
);
1335 if (sym
->assoc
->variable
|| cst_array_ctor
)
1337 se
.direct_byref
= 1;
1342 gfc_conv_expr_descriptor (&se
, e
);
1344 /* If we didn't already do the pointer assignment, set associate-name
1345 descriptor to the one generated for the temporary. */
1346 if (!sym
->assoc
->variable
&& !cst_array_ctor
)
1350 gfc_add_modify (&se
.pre
, desc
, se
.expr
);
1352 /* The generated descriptor has lower bound zero (as array
1353 temporary), shift bounds so we get lower bounds of 1. */
1354 for (dim
= 0; dim
< e
->rank
; ++dim
)
1355 gfc_conv_shift_descriptor_lbound (&se
.pre
, desc
,
1356 dim
, gfc_index_one_node
);
1359 /* If this is a subreference array pointer associate name use the
1360 associate variable element size for the value of 'span'. */
1361 if (sym
->attr
.subref_array_pointer
)
1363 gcc_assert (e
->expr_type
== EXPR_VARIABLE
);
1364 tmp
= e
->symtree
->n
.sym
->backend_decl
;
1365 tmp
= gfc_get_element_type (TREE_TYPE (tmp
));
1366 tmp
= fold_convert (gfc_array_index_type
, size_in_bytes (tmp
));
1367 gfc_add_modify (&se
.pre
, GFC_DECL_SPAN(desc
), tmp
);
1370 /* Done, register stuff as init / cleanup code. */
1371 gfc_add_init_cleanup (block
, gfc_finish_block (&se
.pre
),
1372 gfc_finish_block (&se
.post
));
1375 /* Temporaries, arising from TYPE IS, just need the descriptor of class
1376 arrays to be assigned directly. */
1377 else if (class_target
&& sym
->attr
.dimension
1378 && (sym
->ts
.type
== BT_DERIVED
|| unlimited
))
1382 gfc_init_se (&se
, NULL
);
1383 se
.descriptor_only
= 1;
1384 /* In a select type the (temporary) associate variable shall point to
1385 a standard fortran array (lower bound == 1), but conv_expr ()
1386 just maps to the input array in the class object, whose lbound may
1387 be arbitrary. conv_expr_descriptor solves this by inserting a
1388 temporary array descriptor. */
1389 gfc_conv_expr_descriptor (&se
, e
);
1391 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se
.expr
))
1392 || GFC_ARRAY_TYPE_P (TREE_TYPE (se
.expr
)));
1393 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym
->backend_decl
)));
1395 if (GFC_ARRAY_TYPE_P (TREE_TYPE (se
.expr
)))
1397 if (INDIRECT_REF_P (se
.expr
))
1398 tmp
= TREE_OPERAND (se
.expr
, 0);
1402 gfc_add_modify (&se
.pre
, sym
->backend_decl
,
1403 gfc_class_data_get (GFC_DECL_SAVED_DESCRIPTOR (tmp
)));
1406 gfc_add_modify (&se
.pre
, sym
->backend_decl
, se
.expr
);
1410 /* Recover the dtype, which has been overwritten by the
1411 assignment from an unlimited polymorphic object. */
1412 tmp
= gfc_conv_descriptor_dtype (sym
->backend_decl
);
1413 gfc_add_modify (&se
.pre
, tmp
,
1414 gfc_get_dtype (TREE_TYPE (sym
->backend_decl
)));
1417 gfc_add_init_cleanup (block
, gfc_finish_block (&se
.pre
),
1418 gfc_finish_block (&se
.post
));
1421 /* Do a scalar pointer assignment; this is for scalar variable targets. */
1422 else if (gfc_is_associate_pointer (sym
))
1426 gcc_assert (!sym
->attr
.dimension
);
1428 gfc_init_se (&se
, NULL
);
1430 /* Class associate-names come this way because they are
1431 unconditionally associate pointers and the symbol is scalar. */
1432 if (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)->attr
.dimension
)
1435 /* For a class array we need a descriptor for the selector. */
1436 gfc_conv_expr_descriptor (&se
, e
);
1437 /* Needed to get/set the _len component below. */
1438 target_expr
= se
.expr
;
1440 /* Obtain a temporary class container for the result. */
1441 gfc_conv_class_to_class (&se
, e
, sym
->ts
, false, true, false, false);
1442 se
.expr
= build_fold_indirect_ref_loc (input_location
, se
.expr
);
1444 /* Set the offset. */
1445 desc
= gfc_class_data_get (se
.expr
);
1446 offset
= gfc_index_zero_node
;
1447 for (n
= 0; n
< e
->rank
; n
++)
1449 dim
= gfc_rank_cst
[n
];
1450 tmp
= fold_build2_loc (input_location
, MULT_EXPR
,
1451 gfc_array_index_type
,
1452 gfc_conv_descriptor_stride_get (desc
, dim
),
1453 gfc_conv_descriptor_lbound_get (desc
, dim
));
1454 offset
= fold_build2_loc (input_location
, MINUS_EXPR
,
1455 gfc_array_index_type
,
1458 if (need_len_assign
)
1461 && DECL_LANG_SPECIFIC (e
->symtree
->n
.sym
->backend_decl
)
1462 && GFC_DECL_SAVED_DESCRIPTOR (e
->symtree
->n
.sym
->backend_decl
))
1463 /* Use the original class descriptor stored in the saved
1464 descriptor to get the target_expr. */
1466 GFC_DECL_SAVED_DESCRIPTOR (e
->symtree
->n
.sym
->backend_decl
);
1468 /* Strip the _data component from the target_expr. */
1469 target_expr
= TREE_OPERAND (target_expr
, 0);
1470 /* Add a reference to the _len comp to the target expr. */
1471 tmp
= gfc_class_len_get (target_expr
);
1472 /* Get the component-ref for the temp structure's _len comp. */
1473 charlen
= gfc_class_len_get (se
.expr
);
1474 /* Add the assign to the beginning of the block... */
1475 gfc_add_modify (&se
.pre
, charlen
,
1476 fold_convert (TREE_TYPE (charlen
), tmp
));
1477 /* and the oposite way at the end of the block, to hand changes
1478 on the string length back. */
1479 gfc_add_modify (&se
.post
, tmp
,
1480 fold_convert (TREE_TYPE (tmp
), charlen
));
1481 /* Length assignment done, prevent adding it again below. */
1482 need_len_assign
= false;
1484 gfc_conv_descriptor_offset_set (&se
.pre
, desc
, offset
);
1486 else if (sym
->ts
.type
== BT_CLASS
&& e
->ts
.type
== BT_CLASS
1487 && CLASS_DATA (e
)->attr
.dimension
)
1489 /* This is bound to be a class array element. */
1490 gfc_conv_expr_reference (&se
, e
);
1491 /* Get the _vptr component of the class object. */
1492 tmp
= gfc_get_vptr_from_expr (se
.expr
);
1493 /* Obtain a temporary class container for the result. */
1494 gfc_conv_derived_to_class (&se
, e
, sym
->ts
, tmp
, false, false);
1495 se
.expr
= build_fold_indirect_ref_loc (input_location
, se
.expr
);
1499 /* For BT_CLASS and BT_DERIVED, this boils down to a pointer assign,
1500 which has the string length included. For CHARACTERS it is still
1501 needed and will be done at the end of this routine. */
1502 gfc_conv_expr (&se
, e
);
1503 need_len_assign
= need_len_assign
&& sym
->ts
.type
== BT_CHARACTER
;
1506 tmp
= TREE_TYPE (sym
->backend_decl
);
1507 tmp
= gfc_build_addr_expr (tmp
, se
.expr
);
1508 gfc_add_modify (&se
.pre
, sym
->backend_decl
, tmp
);
1510 gfc_add_init_cleanup (block
, gfc_finish_block( &se
.pre
),
1511 gfc_finish_block (&se
.post
));
1514 /* Do a simple assignment. This is for scalar expressions, where we
1515 can simply use expression assignment. */
1520 lhs
= gfc_lval_expr_from_sym (sym
);
1521 tmp
= gfc_trans_assignment (lhs
, e
, false, true);
1522 gfc_add_init_cleanup (block
, tmp
, NULL_TREE
);
1525 /* Set the stringlength, when needed. */
1526 if (need_len_assign
)
1529 gfc_init_se (&se
, NULL
);
1530 if (e
->symtree
->n
.sym
->ts
.type
== BT_CHARACTER
)
1532 /* What about deferred strings? */
1533 gcc_assert (!e
->symtree
->n
.sym
->ts
.deferred
);
1534 tmp
= e
->symtree
->n
.sym
->ts
.u
.cl
->backend_decl
;
1537 tmp
= gfc_class_len_get (gfc_get_symbol_decl (e
->symtree
->n
.sym
));
1538 gfc_get_symbol_decl (sym
);
1539 charlen
= sym
->ts
.type
== BT_CHARACTER
? sym
->ts
.u
.cl
->backend_decl
1540 : gfc_class_len_get (sym
->backend_decl
);
1541 /* Prevent adding a noop len= len. */
1544 gfc_add_modify (&se
.pre
, charlen
,
1545 fold_convert (TREE_TYPE (charlen
), tmp
));
1546 gfc_add_init_cleanup (block
, gfc_finish_block (&se
.pre
),
1547 gfc_finish_block (&se
.post
));
1553 /* Translate a BLOCK construct. This is basically what we would do for a
1557 gfc_trans_block_construct (gfc_code
* code
)
1561 gfc_wrapped_block block
;
1564 gfc_association_list
*ass
;
1566 ns
= code
->ext
.block
.ns
;
1568 sym
= ns
->proc_name
;
1571 /* Process local variables. */
1572 gcc_assert (!sym
->tlink
);
1574 gfc_process_block_locals (ns
);
1576 /* Generate code including exit-label. */
1577 gfc_init_block (&body
);
1578 exit_label
= gfc_build_label_decl (NULL_TREE
);
1579 code
->exit_label
= exit_label
;
1581 /* Generate !$ACC DECLARE directive. */
1582 if (ns
->oacc_declare_clauses
)
1584 tree tmp
= gfc_trans_oacc_declare (&body
, ns
);
1585 gfc_add_expr_to_block (&body
, tmp
);
1588 gfc_add_expr_to_block (&body
, gfc_trans_code (ns
->code
));
1589 gfc_add_expr_to_block (&body
, build1_v (LABEL_EXPR
, exit_label
));
1591 /* Finish everything. */
1592 gfc_start_wrapped_block (&block
, gfc_finish_block (&body
));
1593 gfc_trans_deferred_vars (sym
, &block
);
1594 for (ass
= code
->ext
.block
.assoc
; ass
; ass
= ass
->next
)
1595 trans_associate_var (ass
->st
->n
.sym
, &block
);
1597 return gfc_finish_wrapped_block (&block
);
1601 /* Translate the simple DO construct. This is where the loop variable has
1602 integer type and step +-1. We can't use this in the general case
1603 because integer overflow and floating point errors could give incorrect
1605 We translate a do loop from:
1607 DO dovar = from, to, step
1613 [Evaluate loop bounds and step]
1615 if ((step > 0) ? (dovar <= to) : (dovar => to))
1621 cond = (dovar == to);
1623 if (cond) goto end_label;
1628 This helps the optimizers by avoiding the extra induction variable
1629 used in the general case. */
1632 gfc_trans_simple_do (gfc_code
* code
, stmtblock_t
*pblock
, tree dovar
,
1633 tree from
, tree to
, tree step
, tree exit_cond
)
1639 tree saved_dovar
= NULL
;
1644 type
= TREE_TYPE (dovar
);
1646 loc
= code
->ext
.iterator
->start
->where
.lb
->location
;
1648 /* Initialize the DO variable: dovar = from. */
1649 gfc_add_modify_loc (loc
, pblock
, dovar
,
1650 fold_convert (TREE_TYPE(dovar
), from
));
1652 /* Save value for do-tinkering checking. */
1653 if (gfc_option
.rtcheck
& GFC_RTCHECK_DO
)
1655 saved_dovar
= gfc_create_var (type
, ".saved_dovar");
1656 gfc_add_modify_loc (loc
, pblock
, saved_dovar
, dovar
);
1659 /* Cycle and exit statements are implemented with gotos. */
1660 cycle_label
= gfc_build_label_decl (NULL_TREE
);
1661 exit_label
= gfc_build_label_decl (NULL_TREE
);
1663 /* Put the labels where they can be found later. See gfc_trans_do(). */
1664 code
->cycle_label
= cycle_label
;
1665 code
->exit_label
= exit_label
;
1668 gfc_start_block (&body
);
1670 /* Main loop body. */
1671 tmp
= gfc_trans_code_cond (code
->block
->next
, exit_cond
);
1672 gfc_add_expr_to_block (&body
, tmp
);
1674 /* Label for cycle statements (if needed). */
1675 if (TREE_USED (cycle_label
))
1677 tmp
= build1_v (LABEL_EXPR
, cycle_label
);
1678 gfc_add_expr_to_block (&body
, tmp
);
1681 /* Check whether someone has modified the loop variable. */
1682 if (gfc_option
.rtcheck
& GFC_RTCHECK_DO
)
1684 tmp
= fold_build2_loc (loc
, NE_EXPR
, boolean_type_node
,
1685 dovar
, saved_dovar
);
1686 gfc_trans_runtime_check (true, false, tmp
, &body
, &code
->loc
,
1687 "Loop variable has been modified");
1690 /* Exit the loop if there is an I/O result condition or error. */
1693 tmp
= build1_v (GOTO_EXPR
, exit_label
);
1694 tmp
= fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
1696 build_empty_stmt (loc
));
1697 gfc_add_expr_to_block (&body
, tmp
);
1700 /* Evaluate the loop condition. */
1701 cond
= fold_build2_loc (loc
, EQ_EXPR
, boolean_type_node
, dovar
,
1703 cond
= gfc_evaluate_now_loc (loc
, cond
, &body
);
1705 /* Increment the loop variable. */
1706 tmp
= fold_build2_loc (loc
, PLUS_EXPR
, type
, dovar
, step
);
1707 gfc_add_modify_loc (loc
, &body
, dovar
, tmp
);
1709 if (gfc_option
.rtcheck
& GFC_RTCHECK_DO
)
1710 gfc_add_modify_loc (loc
, &body
, saved_dovar
, dovar
);
1712 /* The loop exit. */
1713 tmp
= fold_build1_loc (loc
, GOTO_EXPR
, void_type_node
, exit_label
);
1714 TREE_USED (exit_label
) = 1;
1715 tmp
= fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
1716 cond
, tmp
, build_empty_stmt (loc
));
1717 gfc_add_expr_to_block (&body
, tmp
);
1719 /* Finish the loop body. */
1720 tmp
= gfc_finish_block (&body
);
1721 tmp
= fold_build1_loc (loc
, LOOP_EXPR
, void_type_node
, tmp
);
1723 /* Only execute the loop if the number of iterations is positive. */
1724 if (tree_int_cst_sgn (step
) > 0)
1725 cond
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
, dovar
,
1728 cond
= fold_build2_loc (loc
, GE_EXPR
, boolean_type_node
, dovar
,
1730 tmp
= fold_build3_loc (loc
, COND_EXPR
, void_type_node
, cond
, tmp
,
1731 build_empty_stmt (loc
));
1732 gfc_add_expr_to_block (pblock
, tmp
);
1734 /* Add the exit label. */
1735 tmp
= build1_v (LABEL_EXPR
, exit_label
);
1736 gfc_add_expr_to_block (pblock
, tmp
);
1738 return gfc_finish_block (pblock
);
1741 /* Translate the DO construct. This obviously is one of the most
1742 important ones to get right with any compiler, but especially
1745 We special case some loop forms as described in gfc_trans_simple_do.
1746 For other cases we implement them with a separate loop count,
1747 as described in the standard.
1749 We translate a do loop from:
1751 DO dovar = from, to, step
1757 [evaluate loop bounds and step]
1758 empty = (step > 0 ? to < from : to > from);
1759 countm1 = (to - from) / step;
1761 if (empty) goto exit_label;
1769 if (countm1t == 0) goto exit_label;
1773 countm1 is an unsigned integer. It is equal to the loop count minus one,
1774 because the loop count itself can overflow. */
1777 gfc_trans_do (gfc_code
* code
, tree exit_cond
)
1781 tree saved_dovar
= NULL
;
1796 gfc_start_block (&block
);
1798 loc
= code
->ext
.iterator
->start
->where
.lb
->location
;
1800 /* Evaluate all the expressions in the iterator. */
1801 gfc_init_se (&se
, NULL
);
1802 gfc_conv_expr_lhs (&se
, code
->ext
.iterator
->var
);
1803 gfc_add_block_to_block (&block
, &se
.pre
);
1805 type
= TREE_TYPE (dovar
);
1807 gfc_init_se (&se
, NULL
);
1808 gfc_conv_expr_val (&se
, code
->ext
.iterator
->start
);
1809 gfc_add_block_to_block (&block
, &se
.pre
);
1810 from
= gfc_evaluate_now (se
.expr
, &block
);
1812 gfc_init_se (&se
, NULL
);
1813 gfc_conv_expr_val (&se
, code
->ext
.iterator
->end
);
1814 gfc_add_block_to_block (&block
, &se
.pre
);
1815 to
= gfc_evaluate_now (se
.expr
, &block
);
1817 gfc_init_se (&se
, NULL
);
1818 gfc_conv_expr_val (&se
, code
->ext
.iterator
->step
);
1819 gfc_add_block_to_block (&block
, &se
.pre
);
1820 step
= gfc_evaluate_now (se
.expr
, &block
);
1822 if (gfc_option
.rtcheck
& GFC_RTCHECK_DO
)
1824 tmp
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
, step
,
1825 build_zero_cst (type
));
1826 gfc_trans_runtime_check (true, false, tmp
, &block
, &code
->loc
,
1827 "DO step value is zero");
1830 /* Special case simple loops. */
1831 if (TREE_CODE (type
) == INTEGER_TYPE
1832 && (integer_onep (step
)
1833 || tree_int_cst_equal (step
, integer_minus_one_node
)))
1834 return gfc_trans_simple_do (code
, &block
, dovar
, from
, to
, step
, exit_cond
);
1837 if (TREE_CODE (type
) == INTEGER_TYPE
)
1838 utype
= unsigned_type_for (type
);
1840 utype
= unsigned_type_for (gfc_array_index_type
);
1841 countm1
= gfc_create_var (utype
, "countm1");
1843 /* Cycle and exit statements are implemented with gotos. */
1844 cycle_label
= gfc_build_label_decl (NULL_TREE
);
1845 exit_label
= gfc_build_label_decl (NULL_TREE
);
1846 TREE_USED (exit_label
) = 1;
1848 /* Put these labels where they can be found later. */
1849 code
->cycle_label
= cycle_label
;
1850 code
->exit_label
= exit_label
;
1852 /* Initialize the DO variable: dovar = from. */
1853 gfc_add_modify (&block
, dovar
, from
);
1855 /* Save value for do-tinkering checking. */
1856 if (gfc_option
.rtcheck
& GFC_RTCHECK_DO
)
1858 saved_dovar
= gfc_create_var (type
, ".saved_dovar");
1859 gfc_add_modify_loc (loc
, &block
, saved_dovar
, dovar
);
1862 /* Initialize loop count and jump to exit label if the loop is empty.
1863 This code is executed before we enter the loop body. We generate:
1866 countm1 = (to - from) / step;
1872 countm1 = (from - to) / -step;
1878 if (TREE_CODE (type
) == INTEGER_TYPE
)
1880 tree pos
, neg
, tou
, fromu
, stepu
, tmp2
;
1882 /* The distance from FROM to TO cannot always be represented in a signed
1883 type, thus use unsigned arithmetic, also to avoid any undefined
1885 tou
= fold_convert (utype
, to
);
1886 fromu
= fold_convert (utype
, from
);
1887 stepu
= fold_convert (utype
, step
);
1889 /* For a positive step, when to < from, exit, otherwise compute
1890 countm1 = ((unsigned)to - (unsigned)from) / (unsigned)step */
1891 tmp
= fold_build2_loc (loc
, LT_EXPR
, boolean_type_node
, to
, from
);
1892 tmp2
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, utype
,
1893 fold_build2_loc (loc
, MINUS_EXPR
, utype
,
1896 pos
= build2 (COMPOUND_EXPR
, void_type_node
,
1897 fold_build2 (MODIFY_EXPR
, void_type_node
,
1899 build3_loc (loc
, COND_EXPR
, void_type_node
, tmp
,
1900 build1_loc (loc
, GOTO_EXPR
, void_type_node
,
1901 exit_label
), NULL_TREE
));
1903 /* For a negative step, when to > from, exit, otherwise compute
1904 countm1 = ((unsigned)from - (unsigned)to) / -(unsigned)step */
1905 tmp
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
, to
, from
);
1906 tmp2
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, utype
,
1907 fold_build2_loc (loc
, MINUS_EXPR
, utype
,
1909 fold_build1_loc (loc
, NEGATE_EXPR
, utype
, stepu
));
1910 neg
= build2 (COMPOUND_EXPR
, void_type_node
,
1911 fold_build2 (MODIFY_EXPR
, void_type_node
,
1913 build3_loc (loc
, COND_EXPR
, void_type_node
, tmp
,
1914 build1_loc (loc
, GOTO_EXPR
, void_type_node
,
1915 exit_label
), NULL_TREE
));
1917 tmp
= fold_build2_loc (loc
, LT_EXPR
, boolean_type_node
, step
,
1918 build_int_cst (TREE_TYPE (step
), 0));
1919 tmp
= fold_build3_loc (loc
, COND_EXPR
, void_type_node
, tmp
, neg
, pos
);
1921 gfc_add_expr_to_block (&block
, tmp
);
1927 /* TODO: We could use the same width as the real type.
1928 This would probably cause more problems that it solves
1929 when we implement "long double" types. */
1931 tmp
= fold_build2_loc (loc
, MINUS_EXPR
, type
, to
, from
);
1932 tmp
= fold_build2_loc (loc
, RDIV_EXPR
, type
, tmp
, step
);
1933 tmp
= fold_build1_loc (loc
, FIX_TRUNC_EXPR
, utype
, tmp
);
1934 gfc_add_modify (&block
, countm1
, tmp
);
1936 /* We need a special check for empty loops:
1937 empty = (step > 0 ? to < from : to > from); */
1938 pos_step
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
, step
,
1939 build_zero_cst (type
));
1940 tmp
= fold_build3_loc (loc
, COND_EXPR
, boolean_type_node
, pos_step
,
1941 fold_build2_loc (loc
, LT_EXPR
,
1942 boolean_type_node
, to
, from
),
1943 fold_build2_loc (loc
, GT_EXPR
,
1944 boolean_type_node
, to
, from
));
1945 /* If the loop is empty, go directly to the exit label. */
1946 tmp
= fold_build3_loc (loc
, COND_EXPR
, void_type_node
, tmp
,
1947 build1_v (GOTO_EXPR
, exit_label
),
1948 build_empty_stmt (input_location
));
1949 gfc_add_expr_to_block (&block
, tmp
);
1953 gfc_start_block (&body
);
1955 /* Main loop body. */
1956 tmp
= gfc_trans_code_cond (code
->block
->next
, exit_cond
);
1957 gfc_add_expr_to_block (&body
, tmp
);
1959 /* Label for cycle statements (if needed). */
1960 if (TREE_USED (cycle_label
))
1962 tmp
= build1_v (LABEL_EXPR
, cycle_label
);
1963 gfc_add_expr_to_block (&body
, tmp
);
1966 /* Check whether someone has modified the loop variable. */
1967 if (gfc_option
.rtcheck
& GFC_RTCHECK_DO
)
1969 tmp
= fold_build2_loc (loc
, NE_EXPR
, boolean_type_node
, dovar
,
1971 gfc_trans_runtime_check (true, false, tmp
, &body
, &code
->loc
,
1972 "Loop variable has been modified");
1975 /* Exit the loop if there is an I/O result condition or error. */
1978 tmp
= build1_v (GOTO_EXPR
, exit_label
);
1979 tmp
= fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
1981 build_empty_stmt (input_location
));
1982 gfc_add_expr_to_block (&body
, tmp
);
1985 /* Increment the loop variable. */
1986 tmp
= fold_build2_loc (loc
, PLUS_EXPR
, type
, dovar
, step
);
1987 gfc_add_modify_loc (loc
, &body
, dovar
, tmp
);
1989 if (gfc_option
.rtcheck
& GFC_RTCHECK_DO
)
1990 gfc_add_modify_loc (loc
, &body
, saved_dovar
, dovar
);
1992 /* Initialize countm1t. */
1993 tree countm1t
= gfc_create_var (utype
, "countm1t");
1994 gfc_add_modify_loc (loc
, &body
, countm1t
, countm1
);
1996 /* Decrement the loop count. */
1997 tmp
= fold_build2_loc (loc
, MINUS_EXPR
, utype
, countm1
,
1998 build_int_cst (utype
, 1));
1999 gfc_add_modify_loc (loc
, &body
, countm1
, tmp
);
2001 /* End with the loop condition. Loop until countm1t == 0. */
2002 cond
= fold_build2_loc (loc
, EQ_EXPR
, boolean_type_node
, countm1t
,
2003 build_int_cst (utype
, 0));
2004 tmp
= fold_build1_loc (loc
, GOTO_EXPR
, void_type_node
, exit_label
);
2005 tmp
= fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
2006 cond
, tmp
, build_empty_stmt (loc
));
2007 gfc_add_expr_to_block (&body
, tmp
);
2009 /* End of loop body. */
2010 tmp
= gfc_finish_block (&body
);
2012 /* The for loop itself. */
2013 tmp
= fold_build1_loc (loc
, LOOP_EXPR
, void_type_node
, tmp
);
2014 gfc_add_expr_to_block (&block
, tmp
);
2016 /* Add the exit label. */
2017 tmp
= build1_v (LABEL_EXPR
, exit_label
);
2018 gfc_add_expr_to_block (&block
, tmp
);
2020 return gfc_finish_block (&block
);
2024 /* Translate the DO WHILE construct.
2037 if (! cond) goto exit_label;
2043 Because the evaluation of the exit condition `cond' may have side
2044 effects, we can't do much for empty loop bodies. The backend optimizers
2045 should be smart enough to eliminate any dead loops. */
2048 gfc_trans_do_while (gfc_code
* code
)
2056 /* Everything we build here is part of the loop body. */
2057 gfc_start_block (&block
);
2059 /* Cycle and exit statements are implemented with gotos. */
2060 cycle_label
= gfc_build_label_decl (NULL_TREE
);
2061 exit_label
= gfc_build_label_decl (NULL_TREE
);
2063 /* Put the labels where they can be found later. See gfc_trans_do(). */
2064 code
->cycle_label
= cycle_label
;
2065 code
->exit_label
= exit_label
;
2067 /* Create a GIMPLE version of the exit condition. */
2068 gfc_init_se (&cond
, NULL
);
2069 gfc_conv_expr_val (&cond
, code
->expr1
);
2070 gfc_add_block_to_block (&block
, &cond
.pre
);
2071 cond
.expr
= fold_build1_loc (code
->expr1
->where
.lb
->location
,
2072 TRUTH_NOT_EXPR
, TREE_TYPE (cond
.expr
), cond
.expr
);
2074 /* Build "IF (! cond) GOTO exit_label". */
2075 tmp
= build1_v (GOTO_EXPR
, exit_label
);
2076 TREE_USED (exit_label
) = 1;
2077 tmp
= fold_build3_loc (code
->expr1
->where
.lb
->location
, COND_EXPR
,
2078 void_type_node
, cond
.expr
, tmp
,
2079 build_empty_stmt (code
->expr1
->where
.lb
->location
));
2080 gfc_add_expr_to_block (&block
, tmp
);
2082 /* The main body of the loop. */
2083 tmp
= gfc_trans_code (code
->block
->next
);
2084 gfc_add_expr_to_block (&block
, tmp
);
2086 /* Label for cycle statements (if needed). */
2087 if (TREE_USED (cycle_label
))
2089 tmp
= build1_v (LABEL_EXPR
, cycle_label
);
2090 gfc_add_expr_to_block (&block
, tmp
);
2093 /* End of loop body. */
2094 tmp
= gfc_finish_block (&block
);
2096 gfc_init_block (&block
);
2097 /* Build the loop. */
2098 tmp
= fold_build1_loc (code
->expr1
->where
.lb
->location
, LOOP_EXPR
,
2099 void_type_node
, tmp
);
2100 gfc_add_expr_to_block (&block
, tmp
);
2102 /* Add the exit label. */
2103 tmp
= build1_v (LABEL_EXPR
, exit_label
);
2104 gfc_add_expr_to_block (&block
, tmp
);
2106 return gfc_finish_block (&block
);
2110 /* Translate the SELECT CASE construct for INTEGER case expressions,
2111 without killing all potential optimizations. The problem is that
2112 Fortran allows unbounded cases, but the back-end does not, so we
2113 need to intercept those before we enter the equivalent SWITCH_EXPR
2116 For example, we translate this,
2119 CASE (:100,101,105:115)
2129 to the GENERIC equivalent,
2133 case (minimum value for typeof(expr) ... 100:
2139 case 200 ... (maximum value for typeof(expr):
2156 gfc_trans_integer_select (gfc_code
* code
)
2166 gfc_start_block (&block
);
2168 /* Calculate the switch expression. */
2169 gfc_init_se (&se
, NULL
);
2170 gfc_conv_expr_val (&se
, code
->expr1
);
2171 gfc_add_block_to_block (&block
, &se
.pre
);
2173 end_label
= gfc_build_label_decl (NULL_TREE
);
2175 gfc_init_block (&body
);
2177 for (c
= code
->block
; c
; c
= c
->block
)
2179 for (cp
= c
->ext
.block
.case_list
; cp
; cp
= cp
->next
)
2184 /* Assume it's the default case. */
2185 low
= high
= NULL_TREE
;
2189 low
= gfc_conv_mpz_to_tree (cp
->low
->value
.integer
,
2192 /* If there's only a lower bound, set the high bound to the
2193 maximum value of the case expression. */
2195 high
= TYPE_MAX_VALUE (TREE_TYPE (se
.expr
));
2200 /* Three cases are possible here:
2202 1) There is no lower bound, e.g. CASE (:N).
2203 2) There is a lower bound .NE. high bound, that is
2204 a case range, e.g. CASE (N:M) where M>N (we make
2205 sure that M>N during type resolution).
2206 3) There is a lower bound, and it has the same value
2207 as the high bound, e.g. CASE (N:N). This is our
2208 internal representation of CASE(N).
2210 In the first and second case, we need to set a value for
2211 high. In the third case, we don't because the GCC middle
2212 end represents a single case value by just letting high be
2213 a NULL_TREE. We can't do that because we need to be able
2214 to represent unbounded cases. */
2218 && mpz_cmp (cp
->low
->value
.integer
,
2219 cp
->high
->value
.integer
) != 0))
2220 high
= gfc_conv_mpz_to_tree (cp
->high
->value
.integer
,
2223 /* Unbounded case. */
2225 low
= TYPE_MIN_VALUE (TREE_TYPE (se
.expr
));
2228 /* Build a label. */
2229 label
= gfc_build_label_decl (NULL_TREE
);
2231 /* Add this case label.
2232 Add parameter 'label', make it match GCC backend. */
2233 tmp
= build_case_label (low
, high
, label
);
2234 gfc_add_expr_to_block (&body
, tmp
);
2237 /* Add the statements for this case. */
2238 tmp
= gfc_trans_code (c
->next
);
2239 gfc_add_expr_to_block (&body
, tmp
);
2241 /* Break to the end of the construct. */
2242 tmp
= build1_v (GOTO_EXPR
, end_label
);
2243 gfc_add_expr_to_block (&body
, tmp
);
2246 tmp
= gfc_finish_block (&body
);
2247 tmp
= fold_build3_loc (input_location
, SWITCH_EXPR
, NULL_TREE
,
2248 se
.expr
, tmp
, NULL_TREE
);
2249 gfc_add_expr_to_block (&block
, tmp
);
2251 tmp
= build1_v (LABEL_EXPR
, end_label
);
2252 gfc_add_expr_to_block (&block
, tmp
);
2254 return gfc_finish_block (&block
);
2258 /* Translate the SELECT CASE construct for LOGICAL case expressions.
2260 There are only two cases possible here, even though the standard
2261 does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
2262 .FALSE., and DEFAULT.
2264 We never generate more than two blocks here. Instead, we always
2265 try to eliminate the DEFAULT case. This way, we can translate this
2266 kind of SELECT construct to a simple
2270 expression in GENERIC. */
2273 gfc_trans_logical_select (gfc_code
* code
)
2276 gfc_code
*t
, *f
, *d
;
2281 /* Assume we don't have any cases at all. */
2284 /* Now see which ones we actually do have. We can have at most two
2285 cases in a single case list: one for .TRUE. and one for .FALSE.
2286 The default case is always separate. If the cases for .TRUE. and
2287 .FALSE. are in the same case list, the block for that case list
2288 always executed, and we don't generate code a COND_EXPR. */
2289 for (c
= code
->block
; c
; c
= c
->block
)
2291 for (cp
= c
->ext
.block
.case_list
; cp
; cp
= cp
->next
)
2295 if (cp
->low
->value
.logical
== 0) /* .FALSE. */
2297 else /* if (cp->value.logical != 0), thus .TRUE. */
2305 /* Start a new block. */
2306 gfc_start_block (&block
);
2308 /* Calculate the switch expression. We always need to do this
2309 because it may have side effects. */
2310 gfc_init_se (&se
, NULL
);
2311 gfc_conv_expr_val (&se
, code
->expr1
);
2312 gfc_add_block_to_block (&block
, &se
.pre
);
2314 if (t
== f
&& t
!= NULL
)
2316 /* Cases for .TRUE. and .FALSE. are in the same block. Just
2317 translate the code for these cases, append it to the current
2319 gfc_add_expr_to_block (&block
, gfc_trans_code (t
->next
));
2323 tree true_tree
, false_tree
, stmt
;
2325 true_tree
= build_empty_stmt (input_location
);
2326 false_tree
= build_empty_stmt (input_location
);
2328 /* If we have a case for .TRUE. and for .FALSE., discard the default case.
2329 Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
2330 make the missing case the default case. */
2331 if (t
!= NULL
&& f
!= NULL
)
2341 /* Translate the code for each of these blocks, and append it to
2342 the current block. */
2344 true_tree
= gfc_trans_code (t
->next
);
2347 false_tree
= gfc_trans_code (f
->next
);
2349 stmt
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
2350 se
.expr
, true_tree
, false_tree
);
2351 gfc_add_expr_to_block (&block
, stmt
);
2354 return gfc_finish_block (&block
);
2358 /* The jump table types are stored in static variables to avoid
2359 constructing them from scratch every single time. */
2360 static GTY(()) tree select_struct
[2];
2362 /* Translate the SELECT CASE construct for CHARACTER case expressions.
2363 Instead of generating compares and jumps, it is far simpler to
2364 generate a data structure describing the cases in order and call a
2365 library subroutine that locates the right case.
2366 This is particularly true because this is the only case where we
2367 might have to dispose of a temporary.
2368 The library subroutine returns a pointer to jump to or NULL if no
2369 branches are to be taken. */
2372 gfc_trans_character_select (gfc_code
*code
)
2374 tree init
, end_label
, tmp
, type
, case_num
, label
, fndecl
;
2375 stmtblock_t block
, body
;
2380 vec
<constructor_elt
, va_gc
> *inits
= NULL
;
2382 tree pchartype
= gfc_get_pchar_type (code
->expr1
->ts
.kind
);
2384 /* The jump table types are stored in static variables to avoid
2385 constructing them from scratch every single time. */
2386 static tree ss_string1
[2], ss_string1_len
[2];
2387 static tree ss_string2
[2], ss_string2_len
[2];
2388 static tree ss_target
[2];
2390 cp
= code
->block
->ext
.block
.case_list
;
2391 while (cp
->left
!= NULL
)
2394 /* Generate the body */
2395 gfc_start_block (&block
);
2396 gfc_init_se (&expr1se
, NULL
);
2397 gfc_conv_expr_reference (&expr1se
, code
->expr1
);
2399 gfc_add_block_to_block (&block
, &expr1se
.pre
);
2401 end_label
= gfc_build_label_decl (NULL_TREE
);
2403 gfc_init_block (&body
);
2405 /* Attempt to optimize length 1 selects. */
2406 if (integer_onep (expr1se
.string_length
))
2408 for (d
= cp
; d
; d
= d
->right
)
2413 gcc_assert (d
->low
->expr_type
== EXPR_CONSTANT
2414 && d
->low
->ts
.type
== BT_CHARACTER
);
2415 if (d
->low
->value
.character
.length
> 1)
2417 for (i
= 1; i
< d
->low
->value
.character
.length
; i
++)
2418 if (d
->low
->value
.character
.string
[i
] != ' ')
2420 if (i
!= d
->low
->value
.character
.length
)
2422 if (optimize
&& d
->high
&& i
== 1)
2424 gcc_assert (d
->high
->expr_type
== EXPR_CONSTANT
2425 && d
->high
->ts
.type
== BT_CHARACTER
);
2426 if (d
->high
->value
.character
.length
> 1
2427 && (d
->low
->value
.character
.string
[0]
2428 == d
->high
->value
.character
.string
[0])
2429 && d
->high
->value
.character
.string
[1] != ' '
2430 && ((d
->low
->value
.character
.string
[1] < ' ')
2431 == (d
->high
->value
.character
.string
[1]
2441 gcc_assert (d
->high
->expr_type
== EXPR_CONSTANT
2442 && d
->high
->ts
.type
== BT_CHARACTER
);
2443 if (d
->high
->value
.character
.length
> 1)
2445 for (i
= 1; i
< d
->high
->value
.character
.length
; i
++)
2446 if (d
->high
->value
.character
.string
[i
] != ' ')
2448 if (i
!= d
->high
->value
.character
.length
)
2455 tree ctype
= gfc_get_char_type (code
->expr1
->ts
.kind
);
2457 for (c
= code
->block
; c
; c
= c
->block
)
2459 for (cp
= c
->ext
.block
.case_list
; cp
; cp
= cp
->next
)
2465 /* Assume it's the default case. */
2466 low
= high
= NULL_TREE
;
2470 /* CASE ('ab') or CASE ('ab':'az') will never match
2471 any length 1 character. */
2472 if (cp
->low
->value
.character
.length
> 1
2473 && cp
->low
->value
.character
.string
[1] != ' ')
2476 if (cp
->low
->value
.character
.length
> 0)
2477 r
= cp
->low
->value
.character
.string
[0];
2480 low
= build_int_cst (ctype
, r
);
2482 /* If there's only a lower bound, set the high bound
2483 to the maximum value of the case expression. */
2485 high
= TYPE_MAX_VALUE (ctype
);
2491 || (cp
->low
->value
.character
.string
[0]
2492 != cp
->high
->value
.character
.string
[0]))
2494 if (cp
->high
->value
.character
.length
> 0)
2495 r
= cp
->high
->value
.character
.string
[0];
2498 high
= build_int_cst (ctype
, r
);
2501 /* Unbounded case. */
2503 low
= TYPE_MIN_VALUE (ctype
);
2506 /* Build a label. */
2507 label
= gfc_build_label_decl (NULL_TREE
);
2509 /* Add this case label.
2510 Add parameter 'label', make it match GCC backend. */
2511 tmp
= build_case_label (low
, high
, label
);
2512 gfc_add_expr_to_block (&body
, tmp
);
2515 /* Add the statements for this case. */
2516 tmp
= gfc_trans_code (c
->next
);
2517 gfc_add_expr_to_block (&body
, tmp
);
2519 /* Break to the end of the construct. */
2520 tmp
= build1_v (GOTO_EXPR
, end_label
);
2521 gfc_add_expr_to_block (&body
, tmp
);
2524 tmp
= gfc_string_to_single_character (expr1se
.string_length
,
2526 code
->expr1
->ts
.kind
);
2527 case_num
= gfc_create_var (ctype
, "case_num");
2528 gfc_add_modify (&block
, case_num
, tmp
);
2530 gfc_add_block_to_block (&block
, &expr1se
.post
);
2532 tmp
= gfc_finish_block (&body
);
2533 tmp
= fold_build3_loc (input_location
, SWITCH_EXPR
, NULL_TREE
,
2534 case_num
, tmp
, NULL_TREE
);
2535 gfc_add_expr_to_block (&block
, tmp
);
2537 tmp
= build1_v (LABEL_EXPR
, end_label
);
2538 gfc_add_expr_to_block (&block
, tmp
);
2540 return gfc_finish_block (&block
);
2544 if (code
->expr1
->ts
.kind
== 1)
2546 else if (code
->expr1
->ts
.kind
== 4)
2551 if (select_struct
[k
] == NULL
)
2554 select_struct
[k
] = make_node (RECORD_TYPE
);
2556 if (code
->expr1
->ts
.kind
== 1)
2557 TYPE_NAME (select_struct
[k
]) = get_identifier ("_jump_struct_char1");
2558 else if (code
->expr1
->ts
.kind
== 4)
2559 TYPE_NAME (select_struct
[k
]) = get_identifier ("_jump_struct_char4");
2564 #define ADD_FIELD(NAME, TYPE) \
2565 ss_##NAME[k] = gfc_add_field_to_struct (select_struct[k], \
2566 get_identifier (stringize(NAME)), \
2570 ADD_FIELD (string1
, pchartype
);
2571 ADD_FIELD (string1_len
, gfc_charlen_type_node
);
2573 ADD_FIELD (string2
, pchartype
);
2574 ADD_FIELD (string2_len
, gfc_charlen_type_node
);
2576 ADD_FIELD (target
, integer_type_node
);
2579 gfc_finish_type (select_struct
[k
]);
2583 for (d
= cp
; d
; d
= d
->right
)
2586 for (c
= code
->block
; c
; c
= c
->block
)
2588 for (d
= c
->ext
.block
.case_list
; d
; d
= d
->next
)
2590 label
= gfc_build_label_decl (NULL_TREE
);
2591 tmp
= build_case_label ((d
->low
== NULL
&& d
->high
== NULL
)
2593 : build_int_cst (integer_type_node
, d
->n
),
2595 gfc_add_expr_to_block (&body
, tmp
);
2598 tmp
= gfc_trans_code (c
->next
);
2599 gfc_add_expr_to_block (&body
, tmp
);
2601 tmp
= build1_v (GOTO_EXPR
, end_label
);
2602 gfc_add_expr_to_block (&body
, tmp
);
2605 /* Generate the structure describing the branches */
2606 for (d
= cp
; d
; d
= d
->right
)
2608 vec
<constructor_elt
, va_gc
> *node
= NULL
;
2610 gfc_init_se (&se
, NULL
);
2614 CONSTRUCTOR_APPEND_ELT (node
, ss_string1
[k
], null_pointer_node
);
2615 CONSTRUCTOR_APPEND_ELT (node
, ss_string1_len
[k
], integer_zero_node
);
2619 gfc_conv_expr_reference (&se
, d
->low
);
2621 CONSTRUCTOR_APPEND_ELT (node
, ss_string1
[k
], se
.expr
);
2622 CONSTRUCTOR_APPEND_ELT (node
, ss_string1_len
[k
], se
.string_length
);
2625 if (d
->high
== NULL
)
2627 CONSTRUCTOR_APPEND_ELT (node
, ss_string2
[k
], null_pointer_node
);
2628 CONSTRUCTOR_APPEND_ELT (node
, ss_string2_len
[k
], integer_zero_node
);
2632 gfc_init_se (&se
, NULL
);
2633 gfc_conv_expr_reference (&se
, d
->high
);
2635 CONSTRUCTOR_APPEND_ELT (node
, ss_string2
[k
], se
.expr
);
2636 CONSTRUCTOR_APPEND_ELT (node
, ss_string2_len
[k
], se
.string_length
);
2639 CONSTRUCTOR_APPEND_ELT (node
, ss_target
[k
],
2640 build_int_cst (integer_type_node
, d
->n
));
2642 tmp
= build_constructor (select_struct
[k
], node
);
2643 CONSTRUCTOR_APPEND_ELT (inits
, NULL_TREE
, tmp
);
2646 type
= build_array_type (select_struct
[k
],
2647 build_index_type (size_int (n
-1)));
2649 init
= build_constructor (type
, inits
);
2650 TREE_CONSTANT (init
) = 1;
2651 TREE_STATIC (init
) = 1;
2652 /* Create a static variable to hold the jump table. */
2653 tmp
= gfc_create_var (type
, "jumptable");
2654 TREE_CONSTANT (tmp
) = 1;
2655 TREE_STATIC (tmp
) = 1;
2656 TREE_READONLY (tmp
) = 1;
2657 DECL_INITIAL (tmp
) = init
;
2660 /* Build the library call */
2661 init
= gfc_build_addr_expr (pvoid_type_node
, init
);
2663 if (code
->expr1
->ts
.kind
== 1)
2664 fndecl
= gfor_fndecl_select_string
;
2665 else if (code
->expr1
->ts
.kind
== 4)
2666 fndecl
= gfor_fndecl_select_string_char4
;
2670 tmp
= build_call_expr_loc (input_location
,
2672 build_int_cst (gfc_charlen_type_node
, n
),
2673 expr1se
.expr
, expr1se
.string_length
);
2674 case_num
= gfc_create_var (integer_type_node
, "case_num");
2675 gfc_add_modify (&block
, case_num
, tmp
);
2677 gfc_add_block_to_block (&block
, &expr1se
.post
);
2679 tmp
= gfc_finish_block (&body
);
2680 tmp
= fold_build3_loc (input_location
, SWITCH_EXPR
, NULL_TREE
,
2681 case_num
, tmp
, NULL_TREE
);
2682 gfc_add_expr_to_block (&block
, tmp
);
2684 tmp
= build1_v (LABEL_EXPR
, end_label
);
2685 gfc_add_expr_to_block (&block
, tmp
);
2687 return gfc_finish_block (&block
);
2691 /* Translate the three variants of the SELECT CASE construct.
2693 SELECT CASEs with INTEGER case expressions can be translated to an
2694 equivalent GENERIC switch statement, and for LOGICAL case
2695 expressions we build one or two if-else compares.
2697 SELECT CASEs with CHARACTER case expressions are a whole different
2698 story, because they don't exist in GENERIC. So we sort them and
2699 do a binary search at runtime.
2701 Fortran has no BREAK statement, and it does not allow jumps from
2702 one case block to another. That makes things a lot easier for
2706 gfc_trans_select (gfc_code
* code
)
2712 gcc_assert (code
&& code
->expr1
);
2713 gfc_init_block (&block
);
2715 /* Build the exit label and hang it in. */
2716 exit_label
= gfc_build_label_decl (NULL_TREE
);
2717 code
->exit_label
= exit_label
;
2719 /* Empty SELECT constructs are legal. */
2720 if (code
->block
== NULL
)
2721 body
= build_empty_stmt (input_location
);
2723 /* Select the correct translation function. */
2725 switch (code
->expr1
->ts
.type
)
2728 body
= gfc_trans_logical_select (code
);
2732 body
= gfc_trans_integer_select (code
);
2736 body
= gfc_trans_character_select (code
);
2740 gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
2744 /* Build everything together. */
2745 gfc_add_expr_to_block (&block
, body
);
2746 gfc_add_expr_to_block (&block
, build1_v (LABEL_EXPR
, exit_label
));
2748 return gfc_finish_block (&block
);
2752 /* Traversal function to substitute a replacement symtree if the symbol
2753 in the expression is the same as that passed. f == 2 signals that
2754 that variable itself is not to be checked - only the references.
2755 This group of functions is used when the variable expression in a
2756 FORALL assignment has internal references. For example:
2757 FORALL (i = 1:4) p(p(i)) = i
2758 The only recourse here is to store a copy of 'p' for the index
2761 static gfc_symtree
*new_symtree
;
2762 static gfc_symtree
*old_symtree
;
2765 forall_replace (gfc_expr
*expr
, gfc_symbol
*sym
, int *f
)
2767 if (expr
->expr_type
!= EXPR_VARIABLE
)
2772 else if (expr
->symtree
->n
.sym
== sym
)
2773 expr
->symtree
= new_symtree
;
2779 forall_replace_symtree (gfc_expr
*e
, gfc_symbol
*sym
, int f
)
2781 gfc_traverse_expr (e
, sym
, forall_replace
, f
);
2785 forall_restore (gfc_expr
*expr
,
2786 gfc_symbol
*sym ATTRIBUTE_UNUSED
,
2787 int *f ATTRIBUTE_UNUSED
)
2789 if (expr
->expr_type
!= EXPR_VARIABLE
)
2792 if (expr
->symtree
== new_symtree
)
2793 expr
->symtree
= old_symtree
;
2799 forall_restore_symtree (gfc_expr
*e
)
2801 gfc_traverse_expr (e
, NULL
, forall_restore
, 0);
2805 forall_make_variable_temp (gfc_code
*c
, stmtblock_t
*pre
, stmtblock_t
*post
)
2810 gfc_symbol
*new_sym
;
2811 gfc_symbol
*old_sym
;
2815 /* Build a copy of the lvalue. */
2816 old_symtree
= c
->expr1
->symtree
;
2817 old_sym
= old_symtree
->n
.sym
;
2818 e
= gfc_lval_expr_from_sym (old_sym
);
2819 if (old_sym
->attr
.dimension
)
2821 gfc_init_se (&tse
, NULL
);
2822 gfc_conv_subref_array_arg (&tse
, e
, 0, INTENT_IN
, false);
2823 gfc_add_block_to_block (pre
, &tse
.pre
);
2824 gfc_add_block_to_block (post
, &tse
.post
);
2825 tse
.expr
= build_fold_indirect_ref_loc (input_location
, tse
.expr
);
2827 if (e
->ts
.type
!= BT_CHARACTER
)
2829 /* Use the variable offset for the temporary. */
2830 tmp
= gfc_conv_array_offset (old_sym
->backend_decl
);
2831 gfc_conv_descriptor_offset_set (pre
, tse
.expr
, tmp
);
2836 gfc_init_se (&tse
, NULL
);
2837 gfc_init_se (&rse
, NULL
);
2838 gfc_conv_expr (&rse
, e
);
2839 if (e
->ts
.type
== BT_CHARACTER
)
2841 tse
.string_length
= rse
.string_length
;
2842 tmp
= gfc_get_character_type_len (gfc_default_character_kind
,
2844 tse
.expr
= gfc_conv_string_tmp (&tse
, build_pointer_type (tmp
),
2846 gfc_add_block_to_block (pre
, &tse
.pre
);
2847 gfc_add_block_to_block (post
, &tse
.post
);
2851 tmp
= gfc_typenode_for_spec (&e
->ts
);
2852 tse
.expr
= gfc_create_var (tmp
, "temp");
2855 tmp
= gfc_trans_scalar_assign (&tse
, &rse
, e
->ts
,
2856 e
->expr_type
== EXPR_VARIABLE
, false);
2857 gfc_add_expr_to_block (pre
, tmp
);
2861 /* Create a new symbol to represent the lvalue. */
2862 new_sym
= gfc_new_symbol (old_sym
->name
, NULL
);
2863 new_sym
->ts
= old_sym
->ts
;
2864 new_sym
->attr
.referenced
= 1;
2865 new_sym
->attr
.temporary
= 1;
2866 new_sym
->attr
.dimension
= old_sym
->attr
.dimension
;
2867 new_sym
->attr
.flavor
= old_sym
->attr
.flavor
;
2869 /* Use the temporary as the backend_decl. */
2870 new_sym
->backend_decl
= tse
.expr
;
2872 /* Create a fake symtree for it. */
2874 new_symtree
= gfc_new_symtree (&root
, old_sym
->name
);
2875 new_symtree
->n
.sym
= new_sym
;
2876 gcc_assert (new_symtree
== root
);
2878 /* Go through the expression reference replacing the old_symtree
2880 forall_replace_symtree (c
->expr1
, old_sym
, 2);
2882 /* Now we have made this temporary, we might as well use it for
2883 the right hand side. */
2884 forall_replace_symtree (c
->expr2
, old_sym
, 1);
2888 /* Handles dependencies in forall assignments. */
2890 check_forall_dependencies (gfc_code
*c
, stmtblock_t
*pre
, stmtblock_t
*post
)
2897 lsym
= c
->expr1
->symtree
->n
.sym
;
2898 need_temp
= gfc_check_dependency (c
->expr1
, c
->expr2
, 0);
2900 /* Now check for dependencies within the 'variable'
2901 expression itself. These are treated by making a complete
2902 copy of variable and changing all the references to it
2903 point to the copy instead. Note that the shallow copy of
2904 the variable will not suffice for derived types with
2905 pointer components. We therefore leave these to their
2907 if (lsym
->ts
.type
== BT_DERIVED
2908 && lsym
->ts
.u
.derived
->attr
.pointer_comp
)
2912 if (find_forall_index (c
->expr1
, lsym
, 2))
2914 forall_make_variable_temp (c
, pre
, post
);
2918 /* Substrings with dependencies are treated in the same
2920 if (c
->expr1
->ts
.type
== BT_CHARACTER
2922 && c
->expr2
->expr_type
== EXPR_VARIABLE
2923 && lsym
== c
->expr2
->symtree
->n
.sym
)
2925 for (lref
= c
->expr1
->ref
; lref
; lref
= lref
->next
)
2926 if (lref
->type
== REF_SUBSTRING
)
2928 for (rref
= c
->expr2
->ref
; rref
; rref
= rref
->next
)
2929 if (rref
->type
== REF_SUBSTRING
)
2933 && gfc_dep_compare_expr (rref
->u
.ss
.start
, lref
->u
.ss
.start
) < 0)
2935 forall_make_variable_temp (c
, pre
, post
);
2944 cleanup_forall_symtrees (gfc_code
*c
)
2946 forall_restore_symtree (c
->expr1
);
2947 forall_restore_symtree (c
->expr2
);
2948 free (new_symtree
->n
.sym
);
2953 /* Generate the loops for a FORALL block, specified by FORALL_TMP. BODY
2954 is the contents of the FORALL block/stmt to be iterated. MASK_FLAG
2955 indicates whether we should generate code to test the FORALLs mask
2956 array. OUTER is the loop header to be used for initializing mask
2959 The generated loop format is:
2960 count = (end - start + step) / step
2973 gfc_trans_forall_loop (forall_info
*forall_tmp
, tree body
,
2974 int mask_flag
, stmtblock_t
*outer
)
2982 tree var
, start
, end
, step
;
2985 /* Initialize the mask index outside the FORALL nest. */
2986 if (mask_flag
&& forall_tmp
->mask
)
2987 gfc_add_modify (outer
, forall_tmp
->maskindex
, gfc_index_zero_node
);
2989 iter
= forall_tmp
->this_loop
;
2990 nvar
= forall_tmp
->nvar
;
2991 for (n
= 0; n
< nvar
; n
++)
2994 start
= iter
->start
;
2998 exit_label
= gfc_build_label_decl (NULL_TREE
);
2999 TREE_USED (exit_label
) = 1;
3001 /* The loop counter. */
3002 count
= gfc_create_var (TREE_TYPE (var
), "count");
3004 /* The body of the loop. */
3005 gfc_init_block (&block
);
3007 /* The exit condition. */
3008 cond
= fold_build2_loc (input_location
, LE_EXPR
, boolean_type_node
,
3009 count
, build_int_cst (TREE_TYPE (count
), 0));
3010 if (forall_tmp
->do_concurrent
)
3011 cond
= build2 (ANNOTATE_EXPR
, TREE_TYPE (cond
), cond
,
3012 build_int_cst (integer_type_node
,
3013 annot_expr_ivdep_kind
));
3015 tmp
= build1_v (GOTO_EXPR
, exit_label
);
3016 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
3017 cond
, tmp
, build_empty_stmt (input_location
));
3018 gfc_add_expr_to_block (&block
, tmp
);
3020 /* The main loop body. */
3021 gfc_add_expr_to_block (&block
, body
);
3023 /* Increment the loop variable. */
3024 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, TREE_TYPE (var
), var
,
3026 gfc_add_modify (&block
, var
, tmp
);
3028 /* Advance to the next mask element. Only do this for the
3030 if (n
== 0 && mask_flag
&& forall_tmp
->mask
)
3032 tree maskindex
= forall_tmp
->maskindex
;
3033 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
3034 maskindex
, gfc_index_one_node
);
3035 gfc_add_modify (&block
, maskindex
, tmp
);
3038 /* Decrement the loop counter. */
3039 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, TREE_TYPE (var
), count
,
3040 build_int_cst (TREE_TYPE (var
), 1));
3041 gfc_add_modify (&block
, count
, tmp
);
3043 body
= gfc_finish_block (&block
);
3045 /* Loop var initialization. */
3046 gfc_init_block (&block
);
3047 gfc_add_modify (&block
, var
, start
);
3050 /* Initialize the loop counter. */
3051 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, TREE_TYPE (var
), step
,
3053 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, TREE_TYPE (var
), end
,
3055 tmp
= fold_build2_loc (input_location
, TRUNC_DIV_EXPR
, TREE_TYPE (var
),
3057 gfc_add_modify (&block
, count
, tmp
);
3059 /* The loop expression. */
3060 tmp
= build1_v (LOOP_EXPR
, body
);
3061 gfc_add_expr_to_block (&block
, tmp
);
3063 /* The exit label. */
3064 tmp
= build1_v (LABEL_EXPR
, exit_label
);
3065 gfc_add_expr_to_block (&block
, tmp
);
3067 body
= gfc_finish_block (&block
);
3074 /* Generate the body and loops according to MASK_FLAG. If MASK_FLAG
3075 is nonzero, the body is controlled by all masks in the forall nest.
3076 Otherwise, the innermost loop is not controlled by it's mask. This
3077 is used for initializing that mask. */
3080 gfc_trans_nested_forall_loop (forall_info
* nested_forall_info
, tree body
,
3085 forall_info
*forall_tmp
;
3086 tree mask
, maskindex
;
3088 gfc_start_block (&header
);
3090 forall_tmp
= nested_forall_info
;
3091 while (forall_tmp
!= NULL
)
3093 /* Generate body with masks' control. */
3096 mask
= forall_tmp
->mask
;
3097 maskindex
= forall_tmp
->maskindex
;
3099 /* If a mask was specified make the assignment conditional. */
3102 tmp
= gfc_build_array_ref (mask
, maskindex
, NULL
);
3103 body
= build3_v (COND_EXPR
, tmp
, body
,
3104 build_empty_stmt (input_location
));
3107 body
= gfc_trans_forall_loop (forall_tmp
, body
, mask_flag
, &header
);
3108 forall_tmp
= forall_tmp
->prev_nest
;
3112 gfc_add_expr_to_block (&header
, body
);
3113 return gfc_finish_block (&header
);
3117 /* Allocate data for holding a temporary array. Returns either a local
3118 temporary array or a pointer variable. */
3121 gfc_do_allocate (tree bytesize
, tree size
, tree
* pdata
, stmtblock_t
* pblock
,
3128 if (INTEGER_CST_P (size
))
3129 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, gfc_array_index_type
,
3130 size
, gfc_index_one_node
);
3134 type
= build_range_type (gfc_array_index_type
, gfc_index_zero_node
, tmp
);
3135 type
= build_array_type (elem_type
, type
);
3136 if (gfc_can_put_var_on_stack (bytesize
))
3138 gcc_assert (INTEGER_CST_P (size
));
3139 tmpvar
= gfc_create_var (type
, "temp");
3144 tmpvar
= gfc_create_var (build_pointer_type (type
), "temp");
3145 *pdata
= convert (pvoid_type_node
, tmpvar
);
3147 tmp
= gfc_call_malloc (pblock
, TREE_TYPE (tmpvar
), bytesize
);
3148 gfc_add_modify (pblock
, tmpvar
, tmp
);
3154 /* Generate codes to copy the temporary to the actual lhs. */
3157 generate_loop_for_temp_to_lhs (gfc_expr
*expr
, tree tmp1
, tree count3
,
3158 tree count1
, tree wheremask
, bool invert
)
3162 stmtblock_t block
, body
;
3168 lss
= gfc_walk_expr (expr
);
3170 if (lss
== gfc_ss_terminator
)
3172 gfc_start_block (&block
);
3174 gfc_init_se (&lse
, NULL
);
3176 /* Translate the expression. */
3177 gfc_conv_expr (&lse
, expr
);
3179 /* Form the expression for the temporary. */
3180 tmp
= gfc_build_array_ref (tmp1
, count1
, NULL
);
3182 /* Use the scalar assignment as is. */
3183 gfc_add_block_to_block (&block
, &lse
.pre
);
3184 gfc_add_modify (&block
, lse
.expr
, tmp
);
3185 gfc_add_block_to_block (&block
, &lse
.post
);
3187 /* Increment the count1. */
3188 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, TREE_TYPE (count1
),
3189 count1
, gfc_index_one_node
);
3190 gfc_add_modify (&block
, count1
, tmp
);
3192 tmp
= gfc_finish_block (&block
);
3196 gfc_start_block (&block
);
3198 gfc_init_loopinfo (&loop1
);
3199 gfc_init_se (&rse
, NULL
);
3200 gfc_init_se (&lse
, NULL
);
3202 /* Associate the lss with the loop. */
3203 gfc_add_ss_to_loop (&loop1
, lss
);
3205 /* Calculate the bounds of the scalarization. */
3206 gfc_conv_ss_startstride (&loop1
);
3207 /* Setup the scalarizing loops. */
3208 gfc_conv_loop_setup (&loop1
, &expr
->where
);
3210 gfc_mark_ss_chain_used (lss
, 1);
3212 /* Start the scalarized loop body. */
3213 gfc_start_scalarized_body (&loop1
, &body
);
3215 /* Setup the gfc_se structures. */
3216 gfc_copy_loopinfo_to_se (&lse
, &loop1
);
3219 /* Form the expression of the temporary. */
3220 if (lss
!= gfc_ss_terminator
)
3221 rse
.expr
= gfc_build_array_ref (tmp1
, count1
, NULL
);
3222 /* Translate expr. */
3223 gfc_conv_expr (&lse
, expr
);
3225 /* Use the scalar assignment. */
3226 rse
.string_length
= lse
.string_length
;
3227 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr
->ts
, true, true);
3229 /* Form the mask expression according to the mask tree list. */
3232 wheremaskexpr
= gfc_build_array_ref (wheremask
, count3
, NULL
);
3234 wheremaskexpr
= fold_build1_loc (input_location
, TRUTH_NOT_EXPR
,
3235 TREE_TYPE (wheremaskexpr
),
3237 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
3239 build_empty_stmt (input_location
));
3242 gfc_add_expr_to_block (&body
, tmp
);
3244 /* Increment count1. */
3245 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
3246 count1
, gfc_index_one_node
);
3247 gfc_add_modify (&body
, count1
, tmp
);
3249 /* Increment count3. */
3252 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
3253 gfc_array_index_type
, count3
,
3254 gfc_index_one_node
);
3255 gfc_add_modify (&body
, count3
, tmp
);
3258 /* Generate the copying loops. */
3259 gfc_trans_scalarizing_loops (&loop1
, &body
);
3260 gfc_add_block_to_block (&block
, &loop1
.pre
);
3261 gfc_add_block_to_block (&block
, &loop1
.post
);
3262 gfc_cleanup_loop (&loop1
);
3264 tmp
= gfc_finish_block (&block
);
3270 /* Generate codes to copy rhs to the temporary. TMP1 is the address of
3271 temporary, LSS and RSS are formed in function compute_inner_temp_size(),
3272 and should not be freed. WHEREMASK is the conditional execution mask
3273 whose sense may be inverted by INVERT. */
3276 generate_loop_for_rhs_to_temp (gfc_expr
*expr2
, tree tmp1
, tree count3
,
3277 tree count1
, gfc_ss
*lss
, gfc_ss
*rss
,
3278 tree wheremask
, bool invert
)
3280 stmtblock_t block
, body1
;
3287 gfc_start_block (&block
);
3289 gfc_init_se (&rse
, NULL
);
3290 gfc_init_se (&lse
, NULL
);
3292 if (lss
== gfc_ss_terminator
)
3294 gfc_init_block (&body1
);
3295 gfc_conv_expr (&rse
, expr2
);
3296 lse
.expr
= gfc_build_array_ref (tmp1
, count1
, NULL
);
3300 /* Initialize the loop. */
3301 gfc_init_loopinfo (&loop
);
3303 /* We may need LSS to determine the shape of the expression. */
3304 gfc_add_ss_to_loop (&loop
, lss
);
3305 gfc_add_ss_to_loop (&loop
, rss
);
3307 gfc_conv_ss_startstride (&loop
);
3308 gfc_conv_loop_setup (&loop
, &expr2
->where
);
3310 gfc_mark_ss_chain_used (rss
, 1);
3311 /* Start the loop body. */
3312 gfc_start_scalarized_body (&loop
, &body1
);
3314 /* Translate the expression. */
3315 gfc_copy_loopinfo_to_se (&rse
, &loop
);
3317 gfc_conv_expr (&rse
, expr2
);
3319 /* Form the expression of the temporary. */
3320 lse
.expr
= gfc_build_array_ref (tmp1
, count1
, NULL
);
3323 /* Use the scalar assignment. */
3324 lse
.string_length
= rse
.string_length
;
3325 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr2
->ts
,
3326 expr2
->expr_type
== EXPR_VARIABLE
, false);
3328 /* Form the mask expression according to the mask tree list. */
3331 wheremaskexpr
= gfc_build_array_ref (wheremask
, count3
, NULL
);
3333 wheremaskexpr
= fold_build1_loc (input_location
, TRUTH_NOT_EXPR
,
3334 TREE_TYPE (wheremaskexpr
),
3336 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
3338 build_empty_stmt (input_location
));
3341 gfc_add_expr_to_block (&body1
, tmp
);
3343 if (lss
== gfc_ss_terminator
)
3345 gfc_add_block_to_block (&block
, &body1
);
3347 /* Increment count1. */
3348 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, TREE_TYPE (count1
),
3349 count1
, gfc_index_one_node
);
3350 gfc_add_modify (&block
, count1
, tmp
);
3354 /* Increment count1. */
3355 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
3356 count1
, gfc_index_one_node
);
3357 gfc_add_modify (&body1
, count1
, tmp
);
3359 /* Increment count3. */
3362 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
3363 gfc_array_index_type
,
3364 count3
, gfc_index_one_node
);
3365 gfc_add_modify (&body1
, count3
, tmp
);
3368 /* Generate the copying loops. */
3369 gfc_trans_scalarizing_loops (&loop
, &body1
);
3371 gfc_add_block_to_block (&block
, &loop
.pre
);
3372 gfc_add_block_to_block (&block
, &loop
.post
);
3374 gfc_cleanup_loop (&loop
);
3375 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
3376 as tree nodes in SS may not be valid in different scope. */
3379 tmp
= gfc_finish_block (&block
);
3384 /* Calculate the size of temporary needed in the assignment inside forall.
3385 LSS and RSS are filled in this function. */
3388 compute_inner_temp_size (gfc_expr
*expr1
, gfc_expr
*expr2
,
3389 stmtblock_t
* pblock
,
3390 gfc_ss
**lss
, gfc_ss
**rss
)
3398 *lss
= gfc_walk_expr (expr1
);
3401 size
= gfc_index_one_node
;
3402 if (*lss
!= gfc_ss_terminator
)
3404 gfc_init_loopinfo (&loop
);
3406 /* Walk the RHS of the expression. */
3407 *rss
= gfc_walk_expr (expr2
);
3408 if (*rss
== gfc_ss_terminator
)
3409 /* The rhs is scalar. Add a ss for the expression. */
3410 *rss
= gfc_get_scalar_ss (gfc_ss_terminator
, expr2
);
3412 /* Associate the SS with the loop. */
3413 gfc_add_ss_to_loop (&loop
, *lss
);
3414 /* We don't actually need to add the rhs at this point, but it might
3415 make guessing the loop bounds a bit easier. */
3416 gfc_add_ss_to_loop (&loop
, *rss
);
3418 /* We only want the shape of the expression, not rest of the junk
3419 generated by the scalarizer. */
3420 loop
.array_parameter
= 1;
3422 /* Calculate the bounds of the scalarization. */
3423 save_flag
= gfc_option
.rtcheck
;
3424 gfc_option
.rtcheck
&= ~GFC_RTCHECK_BOUNDS
;
3425 gfc_conv_ss_startstride (&loop
);
3426 gfc_option
.rtcheck
= save_flag
;
3427 gfc_conv_loop_setup (&loop
, &expr2
->where
);
3429 /* Figure out how many elements we need. */
3430 for (i
= 0; i
< loop
.dimen
; i
++)
3432 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
3433 gfc_array_index_type
,
3434 gfc_index_one_node
, loop
.from
[i
]);
3435 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
3436 gfc_array_index_type
, tmp
, loop
.to
[i
]);
3437 size
= fold_build2_loc (input_location
, MULT_EXPR
,
3438 gfc_array_index_type
, size
, tmp
);
3440 gfc_add_block_to_block (pblock
, &loop
.pre
);
3441 size
= gfc_evaluate_now (size
, pblock
);
3442 gfc_add_block_to_block (pblock
, &loop
.post
);
3444 /* TODO: write a function that cleans up a loopinfo without freeing
3445 the SS chains. Currently a NOP. */
3452 /* Calculate the overall iterator number of the nested forall construct.
3453 This routine actually calculates the number of times the body of the
3454 nested forall specified by NESTED_FORALL_INFO is executed and multiplies
3455 that by the expression INNER_SIZE. The BLOCK argument specifies the
3456 block in which to calculate the result, and the optional INNER_SIZE_BODY
3457 argument contains any statements that need to executed (inside the loop)
3458 to initialize or calculate INNER_SIZE. */
3461 compute_overall_iter_number (forall_info
*nested_forall_info
, tree inner_size
,
3462 stmtblock_t
*inner_size_body
, stmtblock_t
*block
)
3464 forall_info
*forall_tmp
= nested_forall_info
;
3468 /* We can eliminate the innermost unconditional loops with constant
3470 if (INTEGER_CST_P (inner_size
))
3473 && !forall_tmp
->mask
3474 && INTEGER_CST_P (forall_tmp
->size
))
3476 inner_size
= fold_build2_loc (input_location
, MULT_EXPR
,
3477 gfc_array_index_type
,
3478 inner_size
, forall_tmp
->size
);
3479 forall_tmp
= forall_tmp
->prev_nest
;
3482 /* If there are no loops left, we have our constant result. */
3487 /* Otherwise, create a temporary variable to compute the result. */
3488 number
= gfc_create_var (gfc_array_index_type
, "num");
3489 gfc_add_modify (block
, number
, gfc_index_zero_node
);
3491 gfc_start_block (&body
);
3492 if (inner_size_body
)
3493 gfc_add_block_to_block (&body
, inner_size_body
);
3495 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
3496 gfc_array_index_type
, number
, inner_size
);
3499 gfc_add_modify (&body
, number
, tmp
);
3500 tmp
= gfc_finish_block (&body
);
3502 /* Generate loops. */
3503 if (forall_tmp
!= NULL
)
3504 tmp
= gfc_trans_nested_forall_loop (forall_tmp
, tmp
, 1);
3506 gfc_add_expr_to_block (block
, tmp
);
3512 /* Allocate temporary for forall construct. SIZE is the size of temporary
3513 needed. PTEMP1 is returned for space free. */
3516 allocate_temp_for_forall_nest_1 (tree type
, tree size
, stmtblock_t
* block
,
3523 unit
= fold_convert (gfc_array_index_type
, TYPE_SIZE_UNIT (type
));
3524 if (!integer_onep (unit
))
3525 bytesize
= fold_build2_loc (input_location
, MULT_EXPR
,
3526 gfc_array_index_type
, size
, unit
);
3531 tmp
= gfc_do_allocate (bytesize
, size
, ptemp1
, block
, type
);
3534 tmp
= build_fold_indirect_ref_loc (input_location
, tmp
);
3539 /* Allocate temporary for forall construct according to the information in
3540 nested_forall_info. INNER_SIZE is the size of temporary needed in the
3541 assignment inside forall. PTEMP1 is returned for space free. */
3544 allocate_temp_for_forall_nest (forall_info
* nested_forall_info
, tree type
,
3545 tree inner_size
, stmtblock_t
* inner_size_body
,
3546 stmtblock_t
* block
, tree
* ptemp1
)
3550 /* Calculate the total size of temporary needed in forall construct. */
3551 size
= compute_overall_iter_number (nested_forall_info
, inner_size
,
3552 inner_size_body
, block
);
3554 return allocate_temp_for_forall_nest_1 (type
, size
, block
, ptemp1
);
3558 /* Handle assignments inside forall which need temporary.
3560 forall (i=start:end:stride; maskexpr)
3563 (where e,f<i> are arbitrary expressions possibly involving i
3564 and there is a dependency between e<i> and f<i>)
3566 masktmp(:) = maskexpr(:)
3571 for (i = start; i <= end; i += stride)
3575 for (i = start; i <= end; i += stride)
3577 if (masktmp[maskindex++])
3578 tmp[count1++] = f<i>
3582 for (i = start; i <= end; i += stride)
3584 if (masktmp[maskindex++])
3585 e<i> = tmp[count1++]
3590 gfc_trans_assign_need_temp (gfc_expr
* expr1
, gfc_expr
* expr2
,
3591 tree wheremask
, bool invert
,
3592 forall_info
* nested_forall_info
,
3593 stmtblock_t
* block
)
3601 stmtblock_t inner_size_body
;
3603 /* Create vars. count1 is the current iterator number of the nested
3605 count1
= gfc_create_var (gfc_array_index_type
, "count1");
3607 /* Count is the wheremask index. */
3610 count
= gfc_create_var (gfc_array_index_type
, "count");
3611 gfc_add_modify (block
, count
, gfc_index_zero_node
);
3616 /* Initialize count1. */
3617 gfc_add_modify (block
, count1
, gfc_index_zero_node
);
3619 /* Calculate the size of temporary needed in the assignment. Return loop, lss
3620 and rss which are used in function generate_loop_for_rhs_to_temp(). */
3621 gfc_init_block (&inner_size_body
);
3622 inner_size
= compute_inner_temp_size (expr1
, expr2
, &inner_size_body
,
3625 /* The type of LHS. Used in function allocate_temp_for_forall_nest */
3626 if (expr1
->ts
.type
== BT_CHARACTER
&& expr1
->ts
.u
.cl
->length
)
3628 if (!expr1
->ts
.u
.cl
->backend_decl
)
3631 gfc_init_se (&tse
, NULL
);
3632 gfc_conv_expr (&tse
, expr1
->ts
.u
.cl
->length
);
3633 expr1
->ts
.u
.cl
->backend_decl
= tse
.expr
;
3635 type
= gfc_get_character_type_len (gfc_default_character_kind
,
3636 expr1
->ts
.u
.cl
->backend_decl
);
3639 type
= gfc_typenode_for_spec (&expr1
->ts
);
3641 /* Allocate temporary for nested forall construct according to the
3642 information in nested_forall_info and inner_size. */
3643 tmp1
= allocate_temp_for_forall_nest (nested_forall_info
, type
, inner_size
,
3644 &inner_size_body
, block
, &ptemp1
);
3646 /* Generate codes to copy rhs to the temporary . */
3647 tmp
= generate_loop_for_rhs_to_temp (expr2
, tmp1
, count
, count1
, lss
, rss
,
3650 /* Generate body and loops according to the information in
3651 nested_forall_info. */
3652 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
, tmp
, 1);
3653 gfc_add_expr_to_block (block
, tmp
);
3656 gfc_add_modify (block
, count1
, gfc_index_zero_node
);
3660 gfc_add_modify (block
, count
, gfc_index_zero_node
);
3662 /* Generate codes to copy the temporary to lhs. */
3663 tmp
= generate_loop_for_temp_to_lhs (expr1
, tmp1
, count
, count1
,
3666 /* Generate body and loops according to the information in
3667 nested_forall_info. */
3668 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
, tmp
, 1);
3669 gfc_add_expr_to_block (block
, tmp
);
3673 /* Free the temporary. */
3674 tmp
= gfc_call_free (ptemp1
);
3675 gfc_add_expr_to_block (block
, tmp
);
3680 /* Translate pointer assignment inside FORALL which need temporary. */
3683 gfc_trans_pointer_assign_need_temp (gfc_expr
* expr1
, gfc_expr
* expr2
,
3684 forall_info
* nested_forall_info
,
3685 stmtblock_t
* block
)
3692 gfc_array_info
*info
;
3699 tree tmp
, tmp1
, ptemp1
;
3701 count
= gfc_create_var (gfc_array_index_type
, "count");
3702 gfc_add_modify (block
, count
, gfc_index_zero_node
);
3704 inner_size
= gfc_index_one_node
;
3705 lss
= gfc_walk_expr (expr1
);
3706 rss
= gfc_walk_expr (expr2
);
3707 if (lss
== gfc_ss_terminator
)
3709 type
= gfc_typenode_for_spec (&expr1
->ts
);
3710 type
= build_pointer_type (type
);
3712 /* Allocate temporary for nested forall construct according to the
3713 information in nested_forall_info and inner_size. */
3714 tmp1
= allocate_temp_for_forall_nest (nested_forall_info
, type
,
3715 inner_size
, NULL
, block
, &ptemp1
);
3716 gfc_start_block (&body
);
3717 gfc_init_se (&lse
, NULL
);
3718 lse
.expr
= gfc_build_array_ref (tmp1
, count
, NULL
);
3719 gfc_init_se (&rse
, NULL
);
3720 rse
.want_pointer
= 1;
3721 gfc_conv_expr (&rse
, expr2
);
3722 gfc_add_block_to_block (&body
, &rse
.pre
);
3723 gfc_add_modify (&body
, lse
.expr
,
3724 fold_convert (TREE_TYPE (lse
.expr
), rse
.expr
));
3725 gfc_add_block_to_block (&body
, &rse
.post
);
3727 /* Increment count. */
3728 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
3729 count
, gfc_index_one_node
);
3730 gfc_add_modify (&body
, count
, tmp
);
3732 tmp
= gfc_finish_block (&body
);
3734 /* Generate body and loops according to the information in
3735 nested_forall_info. */
3736 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
, tmp
, 1);
3737 gfc_add_expr_to_block (block
, tmp
);
3740 gfc_add_modify (block
, count
, gfc_index_zero_node
);
3742 gfc_start_block (&body
);
3743 gfc_init_se (&lse
, NULL
);
3744 gfc_init_se (&rse
, NULL
);
3745 rse
.expr
= gfc_build_array_ref (tmp1
, count
, NULL
);
3746 lse
.want_pointer
= 1;
3747 gfc_conv_expr (&lse
, expr1
);
3748 gfc_add_block_to_block (&body
, &lse
.pre
);
3749 gfc_add_modify (&body
, lse
.expr
, rse
.expr
);
3750 gfc_add_block_to_block (&body
, &lse
.post
);
3751 /* Increment count. */
3752 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
3753 count
, gfc_index_one_node
);
3754 gfc_add_modify (&body
, count
, tmp
);
3755 tmp
= gfc_finish_block (&body
);
3757 /* Generate body and loops according to the information in
3758 nested_forall_info. */
3759 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
, tmp
, 1);
3760 gfc_add_expr_to_block (block
, tmp
);
3764 gfc_init_loopinfo (&loop
);
3766 /* Associate the SS with the loop. */
3767 gfc_add_ss_to_loop (&loop
, rss
);
3769 /* Setup the scalarizing loops and bounds. */
3770 gfc_conv_ss_startstride (&loop
);
3772 gfc_conv_loop_setup (&loop
, &expr2
->where
);
3774 info
= &rss
->info
->data
.array
;
3775 desc
= info
->descriptor
;
3777 /* Make a new descriptor. */
3778 parmtype
= gfc_get_element_type (TREE_TYPE (desc
));
3779 parmtype
= gfc_get_array_type_bounds (parmtype
, loop
.dimen
, 0,
3780 loop
.from
, loop
.to
, 1,
3781 GFC_ARRAY_UNKNOWN
, true);
3783 /* Allocate temporary for nested forall construct. */
3784 tmp1
= allocate_temp_for_forall_nest (nested_forall_info
, parmtype
,
3785 inner_size
, NULL
, block
, &ptemp1
);
3786 gfc_start_block (&body
);
3787 gfc_init_se (&lse
, NULL
);
3788 lse
.expr
= gfc_build_array_ref (tmp1
, count
, NULL
);
3789 lse
.direct_byref
= 1;
3790 gfc_conv_expr_descriptor (&lse
, expr2
);
3792 gfc_add_block_to_block (&body
, &lse
.pre
);
3793 gfc_add_block_to_block (&body
, &lse
.post
);
3795 /* Increment count. */
3796 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
3797 count
, gfc_index_one_node
);
3798 gfc_add_modify (&body
, count
, tmp
);
3800 tmp
= gfc_finish_block (&body
);
3802 /* Generate body and loops according to the information in
3803 nested_forall_info. */
3804 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
, tmp
, 1);
3805 gfc_add_expr_to_block (block
, tmp
);
3808 gfc_add_modify (block
, count
, gfc_index_zero_node
);
3810 parm
= gfc_build_array_ref (tmp1
, count
, NULL
);
3811 gfc_init_se (&lse
, NULL
);
3812 gfc_conv_expr_descriptor (&lse
, expr1
);
3813 gfc_add_modify (&lse
.pre
, lse
.expr
, parm
);
3814 gfc_start_block (&body
);
3815 gfc_add_block_to_block (&body
, &lse
.pre
);
3816 gfc_add_block_to_block (&body
, &lse
.post
);
3818 /* Increment count. */
3819 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
3820 count
, gfc_index_one_node
);
3821 gfc_add_modify (&body
, count
, tmp
);
3823 tmp
= gfc_finish_block (&body
);
3825 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
, tmp
, 1);
3826 gfc_add_expr_to_block (block
, tmp
);
3828 /* Free the temporary. */
3831 tmp
= gfc_call_free (ptemp1
);
3832 gfc_add_expr_to_block (block
, tmp
);
3837 /* FORALL and WHERE statements are really nasty, especially when you nest
3838 them. All the rhs of a forall assignment must be evaluated before the
3839 actual assignments are performed. Presumably this also applies to all the
3840 assignments in an inner where statement. */
3842 /* Generate code for a FORALL statement. Any temporaries are allocated as a
3843 linear array, relying on the fact that we process in the same order in all
3846 forall (i=start:end:stride; maskexpr)
3850 (where e,f,g,h<i> are arbitrary expressions possibly involving i)
3852 count = ((end + 1 - start) / stride)
3853 masktmp(:) = maskexpr(:)
3856 for (i = start; i <= end; i += stride)
3858 if (masktmp[maskindex++])
3862 for (i = start; i <= end; i += stride)
3864 if (masktmp[maskindex++])
3868 Note that this code only works when there are no dependencies.
3869 Forall loop with array assignments and data dependencies are a real pain,
3870 because the size of the temporary cannot always be determined before the
3871 loop is executed. This problem is compounded by the presence of nested
3876 gfc_trans_forall_1 (gfc_code
* code
, forall_info
* nested_forall_info
)
3893 tree cycle_label
= NULL_TREE
;
3897 gfc_forall_iterator
*fa
;
3900 gfc_saved_var
*saved_vars
;
3901 iter_info
*this_forall
;
3905 /* Do nothing if the mask is false. */
3907 && code
->expr1
->expr_type
== EXPR_CONSTANT
3908 && !code
->expr1
->value
.logical
)
3909 return build_empty_stmt (input_location
);
3912 /* Count the FORALL index number. */
3913 for (fa
= code
->ext
.forall_iterator
; fa
; fa
= fa
->next
)
3917 /* Allocate the space for var, start, end, step, varexpr. */
3918 var
= XCNEWVEC (tree
, nvar
);
3919 start
= XCNEWVEC (tree
, nvar
);
3920 end
= XCNEWVEC (tree
, nvar
);
3921 step
= XCNEWVEC (tree
, nvar
);
3922 varexpr
= XCNEWVEC (gfc_expr
*, nvar
);
3923 saved_vars
= XCNEWVEC (gfc_saved_var
, nvar
);
3925 /* Allocate the space for info. */
3926 info
= XCNEW (forall_info
);
3928 gfc_start_block (&pre
);
3929 gfc_init_block (&post
);
3930 gfc_init_block (&block
);
3933 for (fa
= code
->ext
.forall_iterator
; fa
; fa
= fa
->next
)
3935 gfc_symbol
*sym
= fa
->var
->symtree
->n
.sym
;
3937 /* Allocate space for this_forall. */
3938 this_forall
= XCNEW (iter_info
);
3940 /* Create a temporary variable for the FORALL index. */
3941 tmp
= gfc_typenode_for_spec (&sym
->ts
);
3942 var
[n
] = gfc_create_var (tmp
, sym
->name
);
3943 gfc_shadow_sym (sym
, var
[n
], &saved_vars
[n
]);
3945 /* Record it in this_forall. */
3946 this_forall
->var
= var
[n
];
3948 /* Replace the index symbol's backend_decl with the temporary decl. */
3949 sym
->backend_decl
= var
[n
];
3951 /* Work out the start, end and stride for the loop. */
3952 gfc_init_se (&se
, NULL
);
3953 gfc_conv_expr_val (&se
, fa
->start
);
3954 /* Record it in this_forall. */
3955 this_forall
->start
= se
.expr
;
3956 gfc_add_block_to_block (&block
, &se
.pre
);
3959 gfc_init_se (&se
, NULL
);
3960 gfc_conv_expr_val (&se
, fa
->end
);
3961 /* Record it in this_forall. */
3962 this_forall
->end
= se
.expr
;
3963 gfc_make_safe_expr (&se
);
3964 gfc_add_block_to_block (&block
, &se
.pre
);
3967 gfc_init_se (&se
, NULL
);
3968 gfc_conv_expr_val (&se
, fa
->stride
);
3969 /* Record it in this_forall. */
3970 this_forall
->step
= se
.expr
;
3971 gfc_make_safe_expr (&se
);
3972 gfc_add_block_to_block (&block
, &se
.pre
);
3975 /* Set the NEXT field of this_forall to NULL. */
3976 this_forall
->next
= NULL
;
3977 /* Link this_forall to the info construct. */
3978 if (info
->this_loop
)
3980 iter_info
*iter_tmp
= info
->this_loop
;
3981 while (iter_tmp
->next
!= NULL
)
3982 iter_tmp
= iter_tmp
->next
;
3983 iter_tmp
->next
= this_forall
;
3986 info
->this_loop
= this_forall
;
3992 /* Calculate the size needed for the current forall level. */
3993 size
= gfc_index_one_node
;
3994 for (n
= 0; n
< nvar
; n
++)
3996 /* size = (end + step - start) / step. */
3997 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, TREE_TYPE (start
[n
]),
3999 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, TREE_TYPE (end
[n
]),
4001 tmp
= fold_build2_loc (input_location
, FLOOR_DIV_EXPR
, TREE_TYPE (tmp
),
4003 tmp
= convert (gfc_array_index_type
, tmp
);
4005 size
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
4009 /* Record the nvar and size of current forall level. */
4015 /* If the mask is .true., consider the FORALL unconditional. */
4016 if (code
->expr1
->expr_type
== EXPR_CONSTANT
4017 && code
->expr1
->value
.logical
)
4025 /* First we need to allocate the mask. */
4028 /* As the mask array can be very big, prefer compact boolean types. */
4029 tree mask_type
= gfc_get_logical_type (gfc_logical_kinds
[0].kind
);
4030 mask
= allocate_temp_for_forall_nest (nested_forall_info
, mask_type
,
4031 size
, NULL
, &block
, &pmask
);
4032 maskindex
= gfc_create_var_np (gfc_array_index_type
, "mi");
4034 /* Record them in the info structure. */
4035 info
->maskindex
= maskindex
;
4040 /* No mask was specified. */
4041 maskindex
= NULL_TREE
;
4042 mask
= pmask
= NULL_TREE
;
4045 /* Link the current forall level to nested_forall_info. */
4046 info
->prev_nest
= nested_forall_info
;
4047 nested_forall_info
= info
;
4049 /* Copy the mask into a temporary variable if required.
4050 For now we assume a mask temporary is needed. */
4053 /* As the mask array can be very big, prefer compact boolean types. */
4054 tree mask_type
= gfc_get_logical_type (gfc_logical_kinds
[0].kind
);
4056 gfc_add_modify (&block
, maskindex
, gfc_index_zero_node
);
4058 /* Start of mask assignment loop body. */
4059 gfc_start_block (&body
);
4061 /* Evaluate the mask expression. */
4062 gfc_init_se (&se
, NULL
);
4063 gfc_conv_expr_val (&se
, code
->expr1
);
4064 gfc_add_block_to_block (&body
, &se
.pre
);
4066 /* Store the mask. */
4067 se
.expr
= convert (mask_type
, se
.expr
);
4069 tmp
= gfc_build_array_ref (mask
, maskindex
, NULL
);
4070 gfc_add_modify (&body
, tmp
, se
.expr
);
4072 /* Advance to the next mask element. */
4073 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
4074 maskindex
, gfc_index_one_node
);
4075 gfc_add_modify (&body
, maskindex
, tmp
);
4077 /* Generate the loops. */
4078 tmp
= gfc_finish_block (&body
);
4079 tmp
= gfc_trans_nested_forall_loop (info
, tmp
, 0);
4080 gfc_add_expr_to_block (&block
, tmp
);
4083 if (code
->op
== EXEC_DO_CONCURRENT
)
4085 gfc_init_block (&body
);
4086 cycle_label
= gfc_build_label_decl (NULL_TREE
);
4087 code
->cycle_label
= cycle_label
;
4088 tmp
= gfc_trans_code (code
->block
->next
);
4089 gfc_add_expr_to_block (&body
, tmp
);
4091 if (TREE_USED (cycle_label
))
4093 tmp
= build1_v (LABEL_EXPR
, cycle_label
);
4094 gfc_add_expr_to_block (&body
, tmp
);
4097 tmp
= gfc_finish_block (&body
);
4098 nested_forall_info
->do_concurrent
= true;
4099 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
, tmp
, 1);
4100 gfc_add_expr_to_block (&block
, tmp
);
4104 c
= code
->block
->next
;
4106 /* TODO: loop merging in FORALL statements. */
4107 /* Now that we've got a copy of the mask, generate the assignment loops. */
4113 /* A scalar or array assignment. DO the simple check for
4114 lhs to rhs dependencies. These make a temporary for the
4115 rhs and form a second forall block to copy to variable. */
4116 need_temp
= check_forall_dependencies(c
, &pre
, &post
);
4118 /* Temporaries due to array assignment data dependencies introduce
4119 no end of problems. */
4121 gfc_trans_assign_need_temp (c
->expr1
, c
->expr2
, NULL
, false,
4122 nested_forall_info
, &block
);
4125 /* Use the normal assignment copying routines. */
4126 assign
= gfc_trans_assignment (c
->expr1
, c
->expr2
, false, true);
4128 /* Generate body and loops. */
4129 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
,
4131 gfc_add_expr_to_block (&block
, tmp
);
4134 /* Cleanup any temporary symtrees that have been made to deal
4135 with dependencies. */
4137 cleanup_forall_symtrees (c
);
4142 /* Translate WHERE or WHERE construct nested in FORALL. */
4143 gfc_trans_where_2 (c
, NULL
, false, nested_forall_info
, &block
);
4146 /* Pointer assignment inside FORALL. */
4147 case EXEC_POINTER_ASSIGN
:
4148 need_temp
= gfc_check_dependency (c
->expr1
, c
->expr2
, 0);
4150 gfc_trans_pointer_assign_need_temp (c
->expr1
, c
->expr2
,
4151 nested_forall_info
, &block
);
4154 /* Use the normal assignment copying routines. */
4155 assign
= gfc_trans_pointer_assignment (c
->expr1
, c
->expr2
);
4157 /* Generate body and loops. */
4158 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
,
4160 gfc_add_expr_to_block (&block
, tmp
);
4165 tmp
= gfc_trans_forall_1 (c
, nested_forall_info
);
4166 gfc_add_expr_to_block (&block
, tmp
);
4169 /* Explicit subroutine calls are prevented by the frontend but interface
4170 assignments can legitimately produce them. */
4171 case EXEC_ASSIGN_CALL
:
4172 assign
= gfc_trans_call (c
, true, NULL_TREE
, NULL_TREE
, false);
4173 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
, assign
, 1);
4174 gfc_add_expr_to_block (&block
, tmp
);
4185 /* Restore the original index variables. */
4186 for (fa
= code
->ext
.forall_iterator
, n
= 0; fa
; fa
= fa
->next
, n
++)
4187 gfc_restore_sym (fa
->var
->symtree
->n
.sym
, &saved_vars
[n
]);
4189 /* Free the space for var, start, end, step, varexpr. */
4197 for (this_forall
= info
->this_loop
; this_forall
;)
4199 iter_info
*next
= this_forall
->next
;
4204 /* Free the space for this forall_info. */
4209 /* Free the temporary for the mask. */
4210 tmp
= gfc_call_free (pmask
);
4211 gfc_add_expr_to_block (&block
, tmp
);
4214 pushdecl (maskindex
);
4216 gfc_add_block_to_block (&pre
, &block
);
4217 gfc_add_block_to_block (&pre
, &post
);
4219 return gfc_finish_block (&pre
);
4223 /* Translate the FORALL statement or construct. */
4225 tree
gfc_trans_forall (gfc_code
* code
)
4227 return gfc_trans_forall_1 (code
, NULL
);
4231 /* Translate the DO CONCURRENT construct. */
4233 tree
gfc_trans_do_concurrent (gfc_code
* code
)
4235 return gfc_trans_forall_1 (code
, NULL
);
4239 /* Evaluate the WHERE mask expression, copy its value to a temporary.
4240 If the WHERE construct is nested in FORALL, compute the overall temporary
4241 needed by the WHERE mask expression multiplied by the iterator number of
4243 ME is the WHERE mask expression.
4244 MASK is the current execution mask upon input, whose sense may or may
4245 not be inverted as specified by the INVERT argument.
4246 CMASK is the updated execution mask on output, or NULL if not required.
4247 PMASK is the pending execution mask on output, or NULL if not required.
4248 BLOCK is the block in which to place the condition evaluation loops. */
4251 gfc_evaluate_where_mask (gfc_expr
* me
, forall_info
* nested_forall_info
,
4252 tree mask
, bool invert
, tree cmask
, tree pmask
,
4253 tree mask_type
, stmtblock_t
* block
)
4258 stmtblock_t body
, body1
;
4259 tree count
, cond
, mtmp
;
4262 gfc_init_loopinfo (&loop
);
4264 lss
= gfc_walk_expr (me
);
4265 rss
= gfc_walk_expr (me
);
4267 /* Variable to index the temporary. */
4268 count
= gfc_create_var (gfc_array_index_type
, "count");
4269 /* Initialize count. */
4270 gfc_add_modify (block
, count
, gfc_index_zero_node
);
4272 gfc_start_block (&body
);
4274 gfc_init_se (&rse
, NULL
);
4275 gfc_init_se (&lse
, NULL
);
4277 if (lss
== gfc_ss_terminator
)
4279 gfc_init_block (&body1
);
4283 /* Initialize the loop. */
4284 gfc_init_loopinfo (&loop
);
4286 /* We may need LSS to determine the shape of the expression. */
4287 gfc_add_ss_to_loop (&loop
, lss
);
4288 gfc_add_ss_to_loop (&loop
, rss
);
4290 gfc_conv_ss_startstride (&loop
);
4291 gfc_conv_loop_setup (&loop
, &me
->where
);
4293 gfc_mark_ss_chain_used (rss
, 1);
4294 /* Start the loop body. */
4295 gfc_start_scalarized_body (&loop
, &body1
);
4297 /* Translate the expression. */
4298 gfc_copy_loopinfo_to_se (&rse
, &loop
);
4300 gfc_conv_expr (&rse
, me
);
4303 /* Variable to evaluate mask condition. */
4304 cond
= gfc_create_var (mask_type
, "cond");
4305 if (mask
&& (cmask
|| pmask
))
4306 mtmp
= gfc_create_var (mask_type
, "mask");
4307 else mtmp
= NULL_TREE
;
4309 gfc_add_block_to_block (&body1
, &lse
.pre
);
4310 gfc_add_block_to_block (&body1
, &rse
.pre
);
4312 gfc_add_modify (&body1
, cond
, fold_convert (mask_type
, rse
.expr
));
4314 if (mask
&& (cmask
|| pmask
))
4316 tmp
= gfc_build_array_ref (mask
, count
, NULL
);
4318 tmp
= fold_build1_loc (input_location
, TRUTH_NOT_EXPR
, mask_type
, tmp
);
4319 gfc_add_modify (&body1
, mtmp
, tmp
);
4324 tmp1
= gfc_build_array_ref (cmask
, count
, NULL
);
4327 tmp
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
, mask_type
,
4329 gfc_add_modify (&body1
, tmp1
, tmp
);
4334 tmp1
= gfc_build_array_ref (pmask
, count
, NULL
);
4335 tmp
= fold_build1_loc (input_location
, TRUTH_NOT_EXPR
, mask_type
, cond
);
4337 tmp
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
, mask_type
, mtmp
,
4339 gfc_add_modify (&body1
, tmp1
, tmp
);
4342 gfc_add_block_to_block (&body1
, &lse
.post
);
4343 gfc_add_block_to_block (&body1
, &rse
.post
);
4345 if (lss
== gfc_ss_terminator
)
4347 gfc_add_block_to_block (&body
, &body1
);
4351 /* Increment count. */
4352 tmp1
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
4353 count
, gfc_index_one_node
);
4354 gfc_add_modify (&body1
, count
, tmp1
);
4356 /* Generate the copying loops. */
4357 gfc_trans_scalarizing_loops (&loop
, &body1
);
4359 gfc_add_block_to_block (&body
, &loop
.pre
);
4360 gfc_add_block_to_block (&body
, &loop
.post
);
4362 gfc_cleanup_loop (&loop
);
4363 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
4364 as tree nodes in SS may not be valid in different scope. */
4367 tmp1
= gfc_finish_block (&body
);
4368 /* If the WHERE construct is inside FORALL, fill the full temporary. */
4369 if (nested_forall_info
!= NULL
)
4370 tmp1
= gfc_trans_nested_forall_loop (nested_forall_info
, tmp1
, 1);
4372 gfc_add_expr_to_block (block
, tmp1
);
4376 /* Translate an assignment statement in a WHERE statement or construct
4377 statement. The MASK expression is used to control which elements
4378 of EXPR1 shall be assigned. The sense of MASK is specified by
4382 gfc_trans_where_assign (gfc_expr
*expr1
, gfc_expr
*expr2
,
4383 tree mask
, bool invert
,
4384 tree count1
, tree count2
,
4390 gfc_ss
*lss_section
;
4397 tree index
, maskexpr
;
4399 /* A defined assignment. */
4400 if (cnext
&& cnext
->resolved_sym
)
4401 return gfc_trans_call (cnext
, true, mask
, count1
, invert
);
4404 /* TODO: handle this special case.
4405 Special case a single function returning an array. */
4406 if (expr2
->expr_type
== EXPR_FUNCTION
&& expr2
->rank
> 0)
4408 tmp
= gfc_trans_arrayfunc_assign (expr1
, expr2
);
4414 /* Assignment of the form lhs = rhs. */
4415 gfc_start_block (&block
);
4417 gfc_init_se (&lse
, NULL
);
4418 gfc_init_se (&rse
, NULL
);
4421 lss
= gfc_walk_expr (expr1
);
4424 /* In each where-assign-stmt, the mask-expr and the variable being
4425 defined shall be arrays of the same shape. */
4426 gcc_assert (lss
!= gfc_ss_terminator
);
4428 /* The assignment needs scalarization. */
4431 /* Find a non-scalar SS from the lhs. */
4432 while (lss_section
!= gfc_ss_terminator
4433 && lss_section
->info
->type
!= GFC_SS_SECTION
)
4434 lss_section
= lss_section
->next
;
4436 gcc_assert (lss_section
!= gfc_ss_terminator
);
4438 /* Initialize the scalarizer. */
4439 gfc_init_loopinfo (&loop
);
4442 rss
= gfc_walk_expr (expr2
);
4443 if (rss
== gfc_ss_terminator
)
4445 /* The rhs is scalar. Add a ss for the expression. */
4446 rss
= gfc_get_scalar_ss (gfc_ss_terminator
, expr2
);
4447 rss
->info
->where
= 1;
4450 /* Associate the SS with the loop. */
4451 gfc_add_ss_to_loop (&loop
, lss
);
4452 gfc_add_ss_to_loop (&loop
, rss
);
4454 /* Calculate the bounds of the scalarization. */
4455 gfc_conv_ss_startstride (&loop
);
4457 /* Resolve any data dependencies in the statement. */
4458 gfc_conv_resolve_dependencies (&loop
, lss_section
, rss
);
4460 /* Setup the scalarizing loops. */
4461 gfc_conv_loop_setup (&loop
, &expr2
->where
);
4463 /* Setup the gfc_se structures. */
4464 gfc_copy_loopinfo_to_se (&lse
, &loop
);
4465 gfc_copy_loopinfo_to_se (&rse
, &loop
);
4468 gfc_mark_ss_chain_used (rss
, 1);
4469 if (loop
.temp_ss
== NULL
)
4472 gfc_mark_ss_chain_used (lss
, 1);
4476 lse
.ss
= loop
.temp_ss
;
4477 gfc_mark_ss_chain_used (lss
, 3);
4478 gfc_mark_ss_chain_used (loop
.temp_ss
, 3);
4481 /* Start the scalarized loop body. */
4482 gfc_start_scalarized_body (&loop
, &body
);
4484 /* Translate the expression. */
4485 gfc_conv_expr (&rse
, expr2
);
4486 if (lss
!= gfc_ss_terminator
&& loop
.temp_ss
!= NULL
)
4487 gfc_conv_tmp_array_ref (&lse
);
4489 gfc_conv_expr (&lse
, expr1
);
4491 /* Form the mask expression according to the mask. */
4493 maskexpr
= gfc_build_array_ref (mask
, index
, NULL
);
4495 maskexpr
= fold_build1_loc (input_location
, TRUTH_NOT_EXPR
,
4496 TREE_TYPE (maskexpr
), maskexpr
);
4498 /* Use the scalar assignment as is. */
4499 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr1
->ts
,
4500 false, loop
.temp_ss
== NULL
);
4502 tmp
= build3_v (COND_EXPR
, maskexpr
, tmp
, build_empty_stmt (input_location
));
4504 gfc_add_expr_to_block (&body
, tmp
);
4506 if (lss
== gfc_ss_terminator
)
4508 /* Increment count1. */
4509 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
4510 count1
, gfc_index_one_node
);
4511 gfc_add_modify (&body
, count1
, tmp
);
4513 /* Use the scalar assignment as is. */
4514 gfc_add_block_to_block (&block
, &body
);
4518 gcc_assert (lse
.ss
== gfc_ss_terminator
4519 && rse
.ss
== gfc_ss_terminator
);
4521 if (loop
.temp_ss
!= NULL
)
4523 /* Increment count1 before finish the main body of a scalarized
4525 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
4526 gfc_array_index_type
, count1
, gfc_index_one_node
);
4527 gfc_add_modify (&body
, count1
, tmp
);
4528 gfc_trans_scalarized_loop_boundary (&loop
, &body
);
4530 /* We need to copy the temporary to the actual lhs. */
4531 gfc_init_se (&lse
, NULL
);
4532 gfc_init_se (&rse
, NULL
);
4533 gfc_copy_loopinfo_to_se (&lse
, &loop
);
4534 gfc_copy_loopinfo_to_se (&rse
, &loop
);
4536 rse
.ss
= loop
.temp_ss
;
4539 gfc_conv_tmp_array_ref (&rse
);
4540 gfc_conv_expr (&lse
, expr1
);
4542 gcc_assert (lse
.ss
== gfc_ss_terminator
4543 && rse
.ss
== gfc_ss_terminator
);
4545 /* Form the mask expression according to the mask tree list. */
4547 maskexpr
= gfc_build_array_ref (mask
, index
, NULL
);
4549 maskexpr
= fold_build1_loc (input_location
, TRUTH_NOT_EXPR
,
4550 TREE_TYPE (maskexpr
), maskexpr
);
4552 /* Use the scalar assignment as is. */
4553 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr1
->ts
, false, true);
4554 tmp
= build3_v (COND_EXPR
, maskexpr
, tmp
,
4555 build_empty_stmt (input_location
));
4556 gfc_add_expr_to_block (&body
, tmp
);
4558 /* Increment count2. */
4559 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
4560 gfc_array_index_type
, count2
,
4561 gfc_index_one_node
);
4562 gfc_add_modify (&body
, count2
, tmp
);
4566 /* Increment count1. */
4567 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
4568 gfc_array_index_type
, count1
,
4569 gfc_index_one_node
);
4570 gfc_add_modify (&body
, count1
, tmp
);
4573 /* Generate the copying loops. */
4574 gfc_trans_scalarizing_loops (&loop
, &body
);
4576 /* Wrap the whole thing up. */
4577 gfc_add_block_to_block (&block
, &loop
.pre
);
4578 gfc_add_block_to_block (&block
, &loop
.post
);
4579 gfc_cleanup_loop (&loop
);
4582 return gfc_finish_block (&block
);
4586 /* Translate the WHERE construct or statement.
4587 This function can be called iteratively to translate the nested WHERE
4588 construct or statement.
4589 MASK is the control mask. */
4592 gfc_trans_where_2 (gfc_code
* code
, tree mask
, bool invert
,
4593 forall_info
* nested_forall_info
, stmtblock_t
* block
)
4595 stmtblock_t inner_size_body
;
4596 tree inner_size
, size
;
4605 tree count1
, count2
;
4609 tree pcmask
= NULL_TREE
;
4610 tree ppmask
= NULL_TREE
;
4611 tree cmask
= NULL_TREE
;
4612 tree pmask
= NULL_TREE
;
4613 gfc_actual_arglist
*arg
;
4615 /* the WHERE statement or the WHERE construct statement. */
4616 cblock
= code
->block
;
4618 /* As the mask array can be very big, prefer compact boolean types. */
4619 mask_type
= gfc_get_logical_type (gfc_logical_kinds
[0].kind
);
4621 /* Determine which temporary masks are needed. */
4624 /* One clause: No ELSEWHEREs. */
4625 need_cmask
= (cblock
->next
!= 0);
4628 else if (cblock
->block
->block
)
4630 /* Three or more clauses: Conditional ELSEWHEREs. */
4634 else if (cblock
->next
)
4636 /* Two clauses, the first non-empty. */
4638 need_pmask
= (mask
!= NULL_TREE
4639 && cblock
->block
->next
!= 0);
4641 else if (!cblock
->block
->next
)
4643 /* Two clauses, both empty. */
4647 /* Two clauses, the first empty, the second non-empty. */
4650 need_cmask
= (cblock
->block
->expr1
!= 0);
4659 if (need_cmask
|| need_pmask
)
4661 /* Calculate the size of temporary needed by the mask-expr. */
4662 gfc_init_block (&inner_size_body
);
4663 inner_size
= compute_inner_temp_size (cblock
->expr1
, cblock
->expr1
,
4664 &inner_size_body
, &lss
, &rss
);
4666 gfc_free_ss_chain (lss
);
4667 gfc_free_ss_chain (rss
);
4669 /* Calculate the total size of temporary needed. */
4670 size
= compute_overall_iter_number (nested_forall_info
, inner_size
,
4671 &inner_size_body
, block
);
4673 /* Check whether the size is negative. */
4674 cond
= fold_build2_loc (input_location
, LE_EXPR
, boolean_type_node
, size
,
4675 gfc_index_zero_node
);
4676 size
= fold_build3_loc (input_location
, COND_EXPR
, gfc_array_index_type
,
4677 cond
, gfc_index_zero_node
, size
);
4678 size
= gfc_evaluate_now (size
, block
);
4680 /* Allocate temporary for WHERE mask if needed. */
4682 cmask
= allocate_temp_for_forall_nest_1 (mask_type
, size
, block
,
4685 /* Allocate temporary for !mask if needed. */
4687 pmask
= allocate_temp_for_forall_nest_1 (mask_type
, size
, block
,
4693 /* Each time around this loop, the where clause is conditional
4694 on the value of mask and invert, which are updated at the
4695 bottom of the loop. */
4697 /* Has mask-expr. */
4700 /* Ensure that the WHERE mask will be evaluated exactly once.
4701 If there are no statements in this WHERE/ELSEWHERE clause,
4702 then we don't need to update the control mask (cmask).
4703 If this is the last clause of the WHERE construct, then
4704 we don't need to update the pending control mask (pmask). */
4706 gfc_evaluate_where_mask (cblock
->expr1
, nested_forall_info
,
4708 cblock
->next
? cmask
: NULL_TREE
,
4709 cblock
->block
? pmask
: NULL_TREE
,
4712 gfc_evaluate_where_mask (cblock
->expr1
, nested_forall_info
,
4714 (cblock
->next
|| cblock
->block
)
4715 ? cmask
: NULL_TREE
,
4716 NULL_TREE
, mask_type
, block
);
4720 /* It's a final elsewhere-stmt. No mask-expr is present. */
4724 /* The body of this where clause are controlled by cmask with
4725 sense specified by invert. */
4727 /* Get the assignment statement of a WHERE statement, or the first
4728 statement in where-body-construct of a WHERE construct. */
4729 cnext
= cblock
->next
;
4734 /* WHERE assignment statement. */
4735 case EXEC_ASSIGN_CALL
:
4737 arg
= cnext
->ext
.actual
;
4738 expr1
= expr2
= NULL
;
4739 for (; arg
; arg
= arg
->next
)
4751 expr1
= cnext
->expr1
;
4752 expr2
= cnext
->expr2
;
4754 if (nested_forall_info
!= NULL
)
4756 need_temp
= gfc_check_dependency (expr1
, expr2
, 0);
4757 if (need_temp
&& cnext
->op
!= EXEC_ASSIGN_CALL
)
4758 gfc_trans_assign_need_temp (expr1
, expr2
,
4760 nested_forall_info
, block
);
4763 /* Variables to control maskexpr. */
4764 count1
= gfc_create_var (gfc_array_index_type
, "count1");
4765 count2
= gfc_create_var (gfc_array_index_type
, "count2");
4766 gfc_add_modify (block
, count1
, gfc_index_zero_node
);
4767 gfc_add_modify (block
, count2
, gfc_index_zero_node
);
4769 tmp
= gfc_trans_where_assign (expr1
, expr2
,
4774 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
,
4776 gfc_add_expr_to_block (block
, tmp
);
4781 /* Variables to control maskexpr. */
4782 count1
= gfc_create_var (gfc_array_index_type
, "count1");
4783 count2
= gfc_create_var (gfc_array_index_type
, "count2");
4784 gfc_add_modify (block
, count1
, gfc_index_zero_node
);
4785 gfc_add_modify (block
, count2
, gfc_index_zero_node
);
4787 tmp
= gfc_trans_where_assign (expr1
, expr2
,
4791 gfc_add_expr_to_block (block
, tmp
);
4796 /* WHERE or WHERE construct is part of a where-body-construct. */
4798 gfc_trans_where_2 (cnext
, cmask
, invert
,
4799 nested_forall_info
, block
);
4806 /* The next statement within the same where-body-construct. */
4807 cnext
= cnext
->next
;
4809 /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt. */
4810 cblock
= cblock
->block
;
4811 if (mask
== NULL_TREE
)
4813 /* If we're the initial WHERE, we can simply invert the sense
4814 of the current mask to obtain the "mask" for the remaining
4821 /* Otherwise, for nested WHERE's we need to use the pending mask. */
4827 /* If we allocated a pending mask array, deallocate it now. */
4830 tmp
= gfc_call_free (ppmask
);
4831 gfc_add_expr_to_block (block
, tmp
);
4834 /* If we allocated a current mask array, deallocate it now. */
4837 tmp
= gfc_call_free (pcmask
);
4838 gfc_add_expr_to_block (block
, tmp
);
4842 /* Translate a simple WHERE construct or statement without dependencies.
4843 CBLOCK is the "then" clause of the WHERE statement, where CBLOCK->EXPR
4844 is the mask condition, and EBLOCK if non-NULL is the "else" clause.
4845 Currently both CBLOCK and EBLOCK are restricted to single assignments. */
4848 gfc_trans_where_3 (gfc_code
* cblock
, gfc_code
* eblock
)
4850 stmtblock_t block
, body
;
4851 gfc_expr
*cond
, *tdst
, *tsrc
, *edst
, *esrc
;
4852 tree tmp
, cexpr
, tstmt
, estmt
;
4853 gfc_ss
*css
, *tdss
, *tsss
;
4854 gfc_se cse
, tdse
, tsse
, edse
, esse
;
4859 /* Allow the scalarizer to workshare simple where loops. */
4860 if (ompws_flags
& OMPWS_WORKSHARE_FLAG
)
4861 ompws_flags
|= OMPWS_SCALARIZER_WS
;
4863 cond
= cblock
->expr1
;
4864 tdst
= cblock
->next
->expr1
;
4865 tsrc
= cblock
->next
->expr2
;
4866 edst
= eblock
? eblock
->next
->expr1
: NULL
;
4867 esrc
= eblock
? eblock
->next
->expr2
: NULL
;
4869 gfc_start_block (&block
);
4870 gfc_init_loopinfo (&loop
);
4872 /* Handle the condition. */
4873 gfc_init_se (&cse
, NULL
);
4874 css
= gfc_walk_expr (cond
);
4875 gfc_add_ss_to_loop (&loop
, css
);
4877 /* Handle the then-clause. */
4878 gfc_init_se (&tdse
, NULL
);
4879 gfc_init_se (&tsse
, NULL
);
4880 tdss
= gfc_walk_expr (tdst
);
4881 tsss
= gfc_walk_expr (tsrc
);
4882 if (tsss
== gfc_ss_terminator
)
4884 tsss
= gfc_get_scalar_ss (gfc_ss_terminator
, tsrc
);
4885 tsss
->info
->where
= 1;
4887 gfc_add_ss_to_loop (&loop
, tdss
);
4888 gfc_add_ss_to_loop (&loop
, tsss
);
4892 /* Handle the else clause. */
4893 gfc_init_se (&edse
, NULL
);
4894 gfc_init_se (&esse
, NULL
);
4895 edss
= gfc_walk_expr (edst
);
4896 esss
= gfc_walk_expr (esrc
);
4897 if (esss
== gfc_ss_terminator
)
4899 esss
= gfc_get_scalar_ss (gfc_ss_terminator
, esrc
);
4900 esss
->info
->where
= 1;
4902 gfc_add_ss_to_loop (&loop
, edss
);
4903 gfc_add_ss_to_loop (&loop
, esss
);
4906 gfc_conv_ss_startstride (&loop
);
4907 gfc_conv_loop_setup (&loop
, &tdst
->where
);
4909 gfc_mark_ss_chain_used (css
, 1);
4910 gfc_mark_ss_chain_used (tdss
, 1);
4911 gfc_mark_ss_chain_used (tsss
, 1);
4914 gfc_mark_ss_chain_used (edss
, 1);
4915 gfc_mark_ss_chain_used (esss
, 1);
4918 gfc_start_scalarized_body (&loop
, &body
);
4920 gfc_copy_loopinfo_to_se (&cse
, &loop
);
4921 gfc_copy_loopinfo_to_se (&tdse
, &loop
);
4922 gfc_copy_loopinfo_to_se (&tsse
, &loop
);
4928 gfc_copy_loopinfo_to_se (&edse
, &loop
);
4929 gfc_copy_loopinfo_to_se (&esse
, &loop
);
4934 gfc_conv_expr (&cse
, cond
);
4935 gfc_add_block_to_block (&body
, &cse
.pre
);
4938 gfc_conv_expr (&tsse
, tsrc
);
4939 if (tdss
!= gfc_ss_terminator
&& loop
.temp_ss
!= NULL
)
4940 gfc_conv_tmp_array_ref (&tdse
);
4942 gfc_conv_expr (&tdse
, tdst
);
4946 gfc_conv_expr (&esse
, esrc
);
4947 if (edss
!= gfc_ss_terminator
&& loop
.temp_ss
!= NULL
)
4948 gfc_conv_tmp_array_ref (&edse
);
4950 gfc_conv_expr (&edse
, edst
);
4953 tstmt
= gfc_trans_scalar_assign (&tdse
, &tsse
, tdst
->ts
, false, true);
4954 estmt
= eblock
? gfc_trans_scalar_assign (&edse
, &esse
, edst
->ts
,
4956 : build_empty_stmt (input_location
);
4957 tmp
= build3_v (COND_EXPR
, cexpr
, tstmt
, estmt
);
4958 gfc_add_expr_to_block (&body
, tmp
);
4959 gfc_add_block_to_block (&body
, &cse
.post
);
4961 gfc_trans_scalarizing_loops (&loop
, &body
);
4962 gfc_add_block_to_block (&block
, &loop
.pre
);
4963 gfc_add_block_to_block (&block
, &loop
.post
);
4964 gfc_cleanup_loop (&loop
);
4966 return gfc_finish_block (&block
);
4969 /* As the WHERE or WHERE construct statement can be nested, we call
4970 gfc_trans_where_2 to do the translation, and pass the initial
4971 NULL values for both the control mask and the pending control mask. */
4974 gfc_trans_where (gfc_code
* code
)
4980 cblock
= code
->block
;
4982 && cblock
->next
->op
== EXEC_ASSIGN
4983 && !cblock
->next
->next
)
4985 eblock
= cblock
->block
;
4988 /* A simple "WHERE (cond) x = y" statement or block is
4989 dependence free if cond is not dependent upon writing x,
4990 and the source y is unaffected by the destination x. */
4991 if (!gfc_check_dependency (cblock
->next
->expr1
,
4993 && !gfc_check_dependency (cblock
->next
->expr1
,
4994 cblock
->next
->expr2
, 0))
4995 return gfc_trans_where_3 (cblock
, NULL
);
4997 else if (!eblock
->expr1
5000 && eblock
->next
->op
== EXEC_ASSIGN
5001 && !eblock
->next
->next
)
5003 /* A simple "WHERE (cond) x1 = y1 ELSEWHERE x2 = y2 ENDWHERE"
5004 block is dependence free if cond is not dependent on writes
5005 to x1 and x2, y1 is not dependent on writes to x2, and y2
5006 is not dependent on writes to x1, and both y's are not
5007 dependent upon their own x's. In addition to this, the
5008 final two dependency checks below exclude all but the same
5009 array reference if the where and elswhere destinations
5010 are the same. In short, this is VERY conservative and this
5011 is needed because the two loops, required by the standard
5012 are coalesced in gfc_trans_where_3. */
5013 if (!gfc_check_dependency (cblock
->next
->expr1
,
5015 && !gfc_check_dependency (eblock
->next
->expr1
,
5017 && !gfc_check_dependency (cblock
->next
->expr1
,
5018 eblock
->next
->expr2
, 1)
5019 && !gfc_check_dependency (eblock
->next
->expr1
,
5020 cblock
->next
->expr2
, 1)
5021 && !gfc_check_dependency (cblock
->next
->expr1
,
5022 cblock
->next
->expr2
, 1)
5023 && !gfc_check_dependency (eblock
->next
->expr1
,
5024 eblock
->next
->expr2
, 1)
5025 && !gfc_check_dependency (cblock
->next
->expr1
,
5026 eblock
->next
->expr1
, 0)
5027 && !gfc_check_dependency (eblock
->next
->expr1
,
5028 cblock
->next
->expr1
, 0))
5029 return gfc_trans_where_3 (cblock
, eblock
);
5033 gfc_start_block (&block
);
5035 gfc_trans_where_2 (code
, NULL
, false, NULL
, &block
);
5037 return gfc_finish_block (&block
);
5041 /* CYCLE a DO loop. The label decl has already been created by
5042 gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
5043 node at the head of the loop. We must mark the label as used. */
5046 gfc_trans_cycle (gfc_code
* code
)
5050 cycle_label
= code
->ext
.which_construct
->cycle_label
;
5051 gcc_assert (cycle_label
);
5053 TREE_USED (cycle_label
) = 1;
5054 return build1_v (GOTO_EXPR
, cycle_label
);
5058 /* EXIT a DO loop. Similar to CYCLE, but now the label is in
5059 TREE_VALUE (backend_decl) of the gfc_code node at the head of the
5063 gfc_trans_exit (gfc_code
* code
)
5067 exit_label
= code
->ext
.which_construct
->exit_label
;
5068 gcc_assert (exit_label
);
5070 TREE_USED (exit_label
) = 1;
5071 return build1_v (GOTO_EXPR
, exit_label
);
5075 /* Translate the ALLOCATE statement. */
5078 gfc_trans_allocate (gfc_code
* code
)
5081 gfc_expr
*expr
, *e3rhs
= NULL
;
5091 tree al_vptr
, al_len
;
5092 /* If an expr3 is present, then store the tree for accessing its
5093 _vptr, and _len components in the variables, respectively. The
5094 element size, i.e. _vptr%size, is stored in expr3_esize. Any of
5095 the trees may be the NULL_TREE indicating that this is not
5096 available for expr3's type. */
5097 tree expr3
, expr3_vptr
, expr3_len
, expr3_esize
;
5098 /* Classify what expr3 stores. */
5099 enum { E3_UNSET
= 0, E3_SOURCE
, E3_MOLD
, E3_DESC
} e3_is
;
5103 bool upoly_expr
, tmp_expr3_len_flag
= false, al_len_needs_set
;
5104 gfc_symtree
*newsym
= NULL
;
5106 if (!code
->ext
.alloc
.list
)
5109 stat
= tmp
= memsz
= al_vptr
= al_len
= NULL_TREE
;
5110 expr3
= expr3_vptr
= expr3_len
= expr3_esize
= NULL_TREE
;
5111 label_errmsg
= label_finish
= errmsg
= errlen
= NULL_TREE
;
5114 gfc_init_block (&block
);
5115 gfc_init_block (&post
);
5117 /* STAT= (and maybe ERRMSG=) is present. */
5121 tree gfc_int4_type_node
= gfc_get_int_type (4);
5122 stat
= gfc_create_var (gfc_int4_type_node
, "stat");
5124 /* ERRMSG= only makes sense with STAT=. */
5127 gfc_init_se (&se
, NULL
);
5128 se
.want_pointer
= 1;
5129 gfc_conv_expr_lhs (&se
, code
->expr2
);
5131 errlen
= se
.string_length
;
5135 errmsg
= null_pointer_node
;
5136 errlen
= build_int_cst (gfc_charlen_type_node
, 0);
5139 /* GOTO destinations. */
5140 label_errmsg
= gfc_build_label_decl (NULL_TREE
);
5141 label_finish
= gfc_build_label_decl (NULL_TREE
);
5142 TREE_USED (label_finish
) = 0;
5145 /* When an expr3 is present evaluate it only once. The standards prevent a
5146 dependency of expr3 on the objects in the allocate list. An expr3 can
5147 be pre-evaluated in all cases. One just has to make sure, to use the
5148 correct way, i.e., to get the descriptor or to get a reference
5152 bool vtab_needed
= false, temp_var_needed
= false;
5154 /* Figure whether we need the vtab from expr3. */
5155 for (al
= code
->ext
.alloc
.list
; !vtab_needed
&& al
!= NULL
;
5157 vtab_needed
= (al
->expr
->ts
.type
== BT_CLASS
);
5159 gfc_init_se (&se
, NULL
);
5160 /* When expr3 is a variable, i.e., a very simple expression,
5161 then convert it once here. */
5162 if (code
->expr3
->expr_type
== EXPR_VARIABLE
5163 || code
->expr3
->expr_type
== EXPR_ARRAY
5164 || code
->expr3
->expr_type
== EXPR_CONSTANT
)
5166 if (!code
->expr3
->mold
5167 || code
->expr3
->ts
.type
== BT_CHARACTER
5169 || code
->ext
.alloc
.arr_spec_from_expr3
)
5171 /* Convert expr3 to a tree. For all "simple" expression just
5172 get the descriptor or the reference, respectively, depending
5173 on the rank of the expr. */
5174 if (code
->ext
.alloc
.arr_spec_from_expr3
|| code
->expr3
->rank
!= 0)
5175 gfc_conv_expr_descriptor (&se
, code
->expr3
);
5177 gfc_conv_expr_reference (&se
, code
->expr3
);
5178 /* Create a temp variable only for component refs to prevent
5179 having to go through the full deref-chain each time and to
5180 simplfy computation of array properties. */
5181 temp_var_needed
= TREE_CODE (se
.expr
) == COMPONENT_REF
;
5186 /* In all other cases evaluate the expr3. */
5187 symbol_attribute attr
;
5188 /* Get the descriptor for all arrays, that are not allocatable or
5189 pointer, because the latter are descriptors already. */
5190 attr
= gfc_expr_attr (code
->expr3
);
5191 if (code
->expr3
->rank
!= 0 && !attr
.allocatable
&& !attr
.pointer
)
5192 gfc_conv_expr_descriptor (&se
, code
->expr3
);
5194 gfc_conv_expr_reference (&se
, code
->expr3
);
5195 if (code
->expr3
->ts
.type
== BT_CLASS
)
5196 gfc_conv_class_to_class (&se
, code
->expr3
,
5200 temp_var_needed
= !VAR_P (se
.expr
);
5202 gfc_add_block_to_block (&block
, &se
.pre
);
5203 gfc_add_block_to_block (&post
, &se
.post
);
5204 /* Prevent aliasing, i.e., se.expr may be already a
5205 variable declaration. */
5206 if (se
.expr
!= NULL_TREE
&& temp_var_needed
)
5209 tmp
= GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se
.expr
)) ?
5211 : build_fold_indirect_ref_loc (input_location
, se
.expr
);
5212 /* We need a regular (non-UID) symbol here, therefore give a
5214 var
= gfc_create_var (TREE_TYPE (tmp
), "source");
5215 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se
.expr
)))
5217 gfc_allocate_lang_decl (var
);
5218 GFC_DECL_SAVED_DESCRIPTOR (var
) = se
.expr
;
5220 gfc_add_modify_loc (input_location
, &block
, var
, tmp
);
5222 /* Deallocate any allocatable components after all the allocations
5223 and assignments of expr3 have been completed. */
5224 if (code
->expr3
->ts
.type
== BT_DERIVED
5225 && code
->expr3
->rank
== 0
5226 && code
->expr3
->ts
.u
.derived
->attr
.alloc_comp
)
5228 tmp
= gfc_deallocate_alloc_comp (code
->expr3
->ts
.u
.derived
,
5230 gfc_add_expr_to_block (&post
, tmp
);
5234 if (se
.string_length
)
5235 /* Evaluate it assuming that it also is complicated like expr3. */
5236 expr3_len
= gfc_evaluate_now (se
.string_length
, &block
);
5241 expr3_len
= se
.string_length
;
5243 /* Store what the expr3 is to be used for. */
5244 e3_is
= expr3
!= NULL_TREE
?
5245 (code
->ext
.alloc
.arr_spec_from_expr3
?
5247 : (code
->expr3
->mold
? E3_MOLD
: E3_SOURCE
))
5250 /* Figure how to get the _vtab entry. This also obtains the tree
5251 expression for accessing the _len component, because only
5252 unlimited polymorphic objects, which are a subcategory of class
5253 types, have a _len component. */
5254 if (code
->expr3
->ts
.type
== BT_CLASS
)
5257 /* Polymorphic SOURCE: VPTR must be determined at run time.
5258 expr3 may be a temporary array declaration, therefore check for
5259 GFC_CLASS_TYPE_P before trying to get the _vptr component. */
5260 if (expr3
!= NULL_TREE
&& GFC_CLASS_TYPE_P (TREE_TYPE (expr3
))
5261 && (VAR_P (expr3
) || !code
->expr3
->ref
))
5262 tmp
= gfc_class_vptr_get (expr3
);
5265 rhs
= gfc_find_and_cut_at_last_class_ref (code
->expr3
);
5266 gfc_add_vptr_component (rhs
);
5267 gfc_init_se (&se
, NULL
);
5268 se
.want_pointer
= 1;
5269 gfc_conv_expr (&se
, rhs
);
5271 gfc_free_expr (rhs
);
5273 /* Set the element size. */
5274 expr3_esize
= gfc_vptr_size_get (tmp
);
5277 /* Initialize the ref to the _len component. */
5278 if (expr3_len
== NULL_TREE
&& UNLIMITED_POLY (code
->expr3
))
5280 /* Same like for retrieving the _vptr. */
5281 if (expr3
!= NULL_TREE
&& !code
->expr3
->ref
)
5282 expr3_len
= gfc_class_len_get (expr3
);
5285 rhs
= gfc_find_and_cut_at_last_class_ref (code
->expr3
);
5286 gfc_add_len_component (rhs
);
5287 gfc_init_se (&se
, NULL
);
5288 gfc_conv_expr (&se
, rhs
);
5289 expr3_len
= se
.expr
;
5290 gfc_free_expr (rhs
);
5296 /* When the object to allocate is polymorphic type, then it
5297 needs its vtab set correctly, so deduce the required _vtab
5298 and _len from the source expression. */
5301 /* VPTR is fixed at compile time. */
5304 vtab
= gfc_find_vtab (&code
->expr3
->ts
);
5306 expr3_vptr
= gfc_get_symbol_decl (vtab
);
5307 expr3_vptr
= gfc_build_addr_expr (NULL_TREE
,
5310 /* _len component needs to be set, when ts is a character
5312 if (expr3_len
== NULL_TREE
5313 && code
->expr3
->ts
.type
== BT_CHARACTER
)
5315 if (code
->expr3
->ts
.u
.cl
5316 && code
->expr3
->ts
.u
.cl
->length
)
5318 gfc_init_se (&se
, NULL
);
5319 gfc_conv_expr (&se
, code
->expr3
->ts
.u
.cl
->length
);
5320 gfc_add_block_to_block (&block
, &se
.pre
);
5321 expr3_len
= gfc_evaluate_now (se
.expr
, &block
);
5323 gcc_assert (expr3_len
);
5325 /* For character arrays only the kind's size is needed, because
5326 the array mem_size is _len * (elem_size = kind_size).
5327 For all other get the element size in the normal way. */
5328 if (code
->expr3
->ts
.type
== BT_CHARACTER
)
5329 expr3_esize
= TYPE_SIZE_UNIT (
5330 gfc_get_char_type (code
->expr3
->ts
.kind
));
5332 expr3_esize
= TYPE_SIZE_UNIT (
5333 gfc_typenode_for_spec (&code
->expr3
->ts
));
5335 /* The routine gfc_trans_assignment () already implements all
5336 techniques needed. Unfortunately we may have a temporary
5337 variable for the source= expression here. When that is the
5338 case convert this variable into a temporary gfc_expr of type
5339 EXPR_VARIABLE and used it as rhs for the assignment. The
5340 advantage is, that we get scalarizer support for free,
5341 don't have to take care about scalar to array treatment and
5342 will benefit of every enhancements gfc_trans_assignment ()
5344 No need to check whether e3_is is E3_UNSET, because that is
5345 done by expr3 != NULL_TREE. */
5346 if (e3_is
!= E3_MOLD
&& expr3
!= NULL_TREE
5347 && DECL_P (expr3
) && DECL_ARTIFICIAL (expr3
))
5349 /* Build a temporary symtree and symbol. Do not add it to
5350 the current namespace to prevent accidently modifying
5351 a colliding symbol's as. */
5352 newsym
= XCNEW (gfc_symtree
);
5353 /* The name of the symtree should be unique, because
5354 gfc_create_var () took care about generating the
5356 newsym
->name
= gfc_get_string (IDENTIFIER_POINTER (
5357 DECL_NAME (expr3
)));
5358 newsym
->n
.sym
= gfc_new_symbol (newsym
->name
, NULL
);
5359 /* The backend_decl is known. It is expr3, which is inserted
5361 newsym
->n
.sym
->backend_decl
= expr3
;
5362 e3rhs
= gfc_get_expr ();
5363 e3rhs
->ts
= code
->expr3
->ts
;
5364 e3rhs
->rank
= code
->expr3
->rank
;
5365 e3rhs
->symtree
= newsym
;
5366 /* Mark the symbol referenced or gfc_trans_assignment will
5368 newsym
->n
.sym
->attr
.referenced
= 1;
5369 e3rhs
->expr_type
= EXPR_VARIABLE
;
5370 e3rhs
->where
= code
->expr3
->where
;
5371 /* Set the symbols type, upto it was BT_UNKNOWN. */
5372 newsym
->n
.sym
->ts
= e3rhs
->ts
;
5373 /* Check whether the expr3 is array valued. */
5376 gfc_array_spec
*arr
;
5377 arr
= gfc_get_array_spec ();
5378 arr
->rank
= e3rhs
->rank
;
5379 arr
->type
= AS_DEFERRED
;
5380 /* Set the dimension and pointer attribute for arrays
5381 to be on the safe side. */
5382 newsym
->n
.sym
->attr
.dimension
= 1;
5383 newsym
->n
.sym
->attr
.pointer
= 1;
5384 newsym
->n
.sym
->as
= arr
;
5385 gfc_add_full_array_ref (e3rhs
, arr
);
5387 else if (POINTER_TYPE_P (TREE_TYPE (expr3
)))
5388 newsym
->n
.sym
->attr
.pointer
= 1;
5389 /* The string length is known to. Set it for char arrays. */
5390 if (e3rhs
->ts
.type
== BT_CHARACTER
)
5391 newsym
->n
.sym
->ts
.u
.cl
->backend_decl
= expr3_len
;
5392 gfc_commit_symbol (newsym
->n
.sym
);
5395 e3rhs
= gfc_copy_expr (code
->expr3
);
5397 gcc_assert (expr3_esize
);
5398 expr3_esize
= fold_convert (sizetype
, expr3_esize
);
5399 if (e3_is
== E3_MOLD
)
5401 /* The expr3 is no longer valid after this point. */
5406 else if (code
->ext
.alloc
.ts
.type
!= BT_UNKNOWN
)
5408 /* Compute the explicit typespec given only once for all objects
5410 if (code
->ext
.alloc
.ts
.type
!= BT_CHARACTER
)
5411 expr3_esize
= TYPE_SIZE_UNIT (
5412 gfc_typenode_for_spec (&code
->ext
.alloc
.ts
));
5416 gcc_assert (code
->ext
.alloc
.ts
.u
.cl
->length
!= NULL
);
5417 sz
= gfc_copy_expr (code
->ext
.alloc
.ts
.u
.cl
->length
);
5418 gfc_init_se (&se_sz
, NULL
);
5419 gfc_conv_expr (&se_sz
, sz
);
5421 tmp
= gfc_get_char_type (code
->ext
.alloc
.ts
.kind
);
5422 tmp
= TYPE_SIZE_UNIT (tmp
);
5423 tmp
= fold_convert (TREE_TYPE (se_sz
.expr
), tmp
);
5424 expr3_esize
= fold_build2_loc (input_location
, MULT_EXPR
,
5425 TREE_TYPE (se_sz
.expr
),
5430 /* Loop over all objects to allocate. */
5431 for (al
= code
->ext
.alloc
.list
; al
!= NULL
; al
= al
->next
)
5433 expr
= gfc_copy_expr (al
->expr
);
5434 /* UNLIMITED_POLY () needs the _data component to be set, when
5435 expr is a unlimited polymorphic object. But the _data component
5436 has not been set yet, so check the derived type's attr for the
5437 unlimited polymorphic flag to be safe. */
5438 upoly_expr
= UNLIMITED_POLY (expr
)
5439 || (expr
->ts
.type
== BT_DERIVED
5440 && expr
->ts
.u
.derived
->attr
.unlimited_polymorphic
);
5441 gfc_init_se (&se
, NULL
);
5443 /* For class types prepare the expressions to ref the _vptr
5444 and the _len component. The latter for unlimited polymorphic
5446 if (expr
->ts
.type
== BT_CLASS
)
5448 gfc_expr
*expr_ref_vptr
, *expr_ref_len
;
5449 gfc_add_data_component (expr
);
5450 /* Prep the vptr handle. */
5451 expr_ref_vptr
= gfc_copy_expr (al
->expr
);
5452 gfc_add_vptr_component (expr_ref_vptr
);
5453 se
.want_pointer
= 1;
5454 gfc_conv_expr (&se
, expr_ref_vptr
);
5456 se
.want_pointer
= 0;
5457 gfc_free_expr (expr_ref_vptr
);
5458 /* Allocated unlimited polymorphic objects always have a _len
5462 expr_ref_len
= gfc_copy_expr (al
->expr
);
5463 gfc_add_len_component (expr_ref_len
);
5464 gfc_conv_expr (&se
, expr_ref_len
);
5466 gfc_free_expr (expr_ref_len
);
5469 /* In a loop ensure that all loop variable dependent variables
5470 are initialized at the same spot in all execution paths. */
5474 al_vptr
= al_len
= NULL_TREE
;
5476 se
.want_pointer
= 1;
5477 se
.descriptor_only
= 1;
5478 gfc_conv_expr (&se
, expr
);
5479 if (expr
->ts
.type
== BT_CHARACTER
&& expr
->ts
.deferred
)
5480 /* se.string_length now stores the .string_length variable of expr
5481 needed to allocate character(len=:) arrays. */
5482 al_len
= se
.string_length
;
5484 al_len_needs_set
= al_len
!= NULL_TREE
;
5485 /* When allocating an array one can not use much of the
5486 pre-evaluated expr3 expressions, because for most of them the
5487 scalarizer is needed which is not available in the pre-evaluation
5488 step. Therefore gfc_array_allocate () is responsible (and able)
5489 to handle the complete array allocation. Only the element size
5490 needs to be provided, which is done most of the time by the
5491 pre-evaluation step. */
5493 if (expr3_len
&& code
->expr3
->ts
.type
== BT_CHARACTER
)
5494 /* When al is an array, then the element size for each element
5495 in the array is needed, which is the product of the len and
5496 esize for char arrays. */
5497 tmp
= fold_build2_loc (input_location
, MULT_EXPR
,
5498 TREE_TYPE (expr3_esize
), expr3_esize
,
5499 fold_convert (TREE_TYPE (expr3_esize
),
5503 if (!gfc_array_allocate (&se
, expr
, stat
, errmsg
, errlen
,
5504 label_finish
, tmp
, &nelems
,
5505 e3rhs
? e3rhs
: code
->expr3
,
5506 e3_is
== E3_DESC
? expr3
: NULL_TREE
,
5507 code
->expr3
!= NULL
&& e3_is
== E3_DESC
5508 && code
->expr3
->expr_type
== EXPR_ARRAY
))
5510 /* A scalar or derived type. First compute the size to
5513 expr3_len is set when expr3 is an unlimited polymorphic
5514 object or a deferred length string. */
5515 if (expr3_len
!= NULL_TREE
)
5517 tmp
= fold_convert (TREE_TYPE (expr3_esize
), expr3_len
);
5518 tmp
= fold_build2_loc (input_location
, MULT_EXPR
,
5519 TREE_TYPE (expr3_esize
),
5521 if (code
->expr3
->ts
.type
!= BT_CLASS
)
5522 /* expr3 is a deferred length string, i.e., we are
5527 /* For unlimited polymorphic enties build
5528 (len > 0) ? element_size * len : element_size
5529 to compute the number of bytes to allocate.
5530 This allows the allocation of unlimited polymorphic
5531 objects from an expr3 that is also unlimited
5532 polymorphic and stores a _len dependent object,
5534 memsz
= fold_build2_loc (input_location
, GT_EXPR
,
5535 boolean_type_node
, expr3_len
,
5537 memsz
= fold_build3_loc (input_location
, COND_EXPR
,
5538 TREE_TYPE (expr3_esize
),
5539 memsz
, tmp
, expr3_esize
);
5542 else if (expr3_esize
!= NULL_TREE
)
5543 /* Any other object in expr3 just needs element size in
5545 memsz
= expr3_esize
;
5546 else if ((expr
->ts
.type
== BT_CHARACTER
&& expr
->ts
.deferred
)
5548 && code
->ext
.alloc
.ts
.type
== BT_CHARACTER
))
5550 /* Allocating deferred length char arrays need the length
5551 to allocate in the alloc_type_spec. But also unlimited
5552 polymorphic objects may be allocated as char arrays.
5553 Both are handled here. */
5554 gfc_init_se (&se_sz
, NULL
);
5555 gfc_conv_expr (&se_sz
, code
->ext
.alloc
.ts
.u
.cl
->length
);
5556 gfc_add_block_to_block (&se
.pre
, &se_sz
.pre
);
5557 se_sz
.expr
= gfc_evaluate_now (se_sz
.expr
, &se
.pre
);
5558 gfc_add_block_to_block (&se
.pre
, &se_sz
.post
);
5559 expr3_len
= se_sz
.expr
;
5560 tmp_expr3_len_flag
= true;
5561 tmp
= TYPE_SIZE_UNIT (
5562 gfc_get_char_type (code
->ext
.alloc
.ts
.kind
));
5563 memsz
= fold_build2_loc (input_location
, MULT_EXPR
,
5565 fold_convert (TREE_TYPE (tmp
),
5569 else if (expr
->ts
.type
== BT_CHARACTER
)
5571 /* Compute the number of bytes needed to allocate a fixed
5572 length char array. */
5573 gcc_assert (se
.string_length
!= NULL_TREE
);
5574 tmp
= TYPE_SIZE_UNIT (gfc_get_char_type (expr
->ts
.kind
));
5575 memsz
= fold_build2_loc (input_location
, MULT_EXPR
,
5576 TREE_TYPE (tmp
), tmp
,
5577 fold_convert (TREE_TYPE (tmp
),
5580 else if (code
->ext
.alloc
.ts
.type
!= BT_UNKNOWN
)
5581 /* Handle all types, where the alloc_type_spec is set. */
5582 memsz
= TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code
->ext
.alloc
.ts
));
5584 /* Handle size computation of the type declared to alloc. */
5585 memsz
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se
.expr
)));
5587 /* Allocate - for non-pointers with re-alloc checking. */
5588 if (gfc_expr_attr (expr
).allocatable
)
5589 gfc_allocate_allocatable (&se
.pre
, se
.expr
, memsz
, NULL_TREE
,
5590 stat
, errmsg
, errlen
, label_finish
,
5593 gfc_allocate_using_malloc (&se
.pre
, se
.expr
, memsz
, stat
);
5595 if (al
->expr
->ts
.type
== BT_DERIVED
5596 && expr
->ts
.u
.derived
->attr
.alloc_comp
)
5598 tmp
= build_fold_indirect_ref_loc (input_location
, se
.expr
);
5599 tmp
= gfc_nullify_alloc_comp (expr
->ts
.u
.derived
, tmp
, 0);
5600 gfc_add_expr_to_block (&se
.pre
, tmp
);
5605 if (expr
->ts
.type
== BT_CHARACTER
&& al_len
!= NULL_TREE
5606 && expr3_len
!= NULL_TREE
)
5608 /* Arrays need to have a _len set before the array
5609 descriptor is filled. */
5610 gfc_add_modify (&block
, al_len
,
5611 fold_convert (TREE_TYPE (al_len
), expr3_len
));
5612 /* Prevent setting the length twice. */
5613 al_len_needs_set
= false;
5617 gfc_add_block_to_block (&block
, &se
.pre
);
5619 /* Error checking -- Note: ERRMSG only makes sense with STAT. */
5622 tmp
= build1_v (GOTO_EXPR
, label_errmsg
);
5623 parm
= fold_build2_loc (input_location
, NE_EXPR
,
5624 boolean_type_node
, stat
,
5625 build_int_cst (TREE_TYPE (stat
), 0));
5626 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
5627 gfc_unlikely (parm
, PRED_FORTRAN_FAIL_ALLOC
),
5628 tmp
, build_empty_stmt (input_location
));
5629 gfc_add_expr_to_block (&block
, tmp
);
5633 if (al_vptr
!= NULL_TREE
)
5635 if (expr3_vptr
!= NULL_TREE
)
5636 /* The vtab is already known, so just assign it. */
5637 gfc_add_modify (&block
, al_vptr
,
5638 fold_convert (TREE_TYPE (al_vptr
), expr3_vptr
));
5641 /* VPTR is fixed at compile time. */
5646 /* Although expr3 is pre-evaluated above, it may happen,
5647 that for arrays or in mold= cases the pre-evaluation
5648 was not successful. In these rare cases take the vtab
5649 from the typespec of expr3 here. */
5650 ts
= &code
->expr3
->ts
;
5651 else if (code
->ext
.alloc
.ts
.type
== BT_DERIVED
|| upoly_expr
)
5652 /* The alloc_type_spec gives the type to allocate or the
5653 al is unlimited polymorphic, which enforces the use of
5654 an alloc_type_spec that is not necessarily a BT_DERIVED. */
5655 ts
= &code
->ext
.alloc
.ts
;
5657 /* Prepare for setting the vtab as declared. */
5660 vtab
= gfc_find_vtab (ts
);
5662 tmp
= gfc_build_addr_expr (NULL_TREE
,
5663 gfc_get_symbol_decl (vtab
));
5664 gfc_add_modify (&block
, al_vptr
,
5665 fold_convert (TREE_TYPE (al_vptr
), tmp
));
5669 /* Add assignment for string length. */
5670 if (al_len
!= NULL_TREE
&& al_len_needs_set
)
5672 if (expr3_len
!= NULL_TREE
)
5674 gfc_add_modify (&block
, al_len
,
5675 fold_convert (TREE_TYPE (al_len
),
5677 /* When tmp_expr3_len_flag is set, then expr3_len is
5678 abused to carry the length information from the
5679 alloc_type. Clear it to prevent setting incorrect len
5680 information in future loop iterations. */
5681 if (tmp_expr3_len_flag
)
5682 /* No need to reset tmp_expr3_len_flag, because the
5683 presence of an expr3 can not change within in the
5685 expr3_len
= NULL_TREE
;
5687 else if (code
->ext
.alloc
.ts
.type
== BT_CHARACTER
5688 && code
->ext
.alloc
.ts
.u
.cl
->length
)
5690 /* Cover the cases where a string length is explicitly
5691 specified by a type spec for deferred length character
5692 arrays or unlimited polymorphic objects without a
5693 source= or mold= expression. */
5694 gfc_init_se (&se_sz
, NULL
);
5695 gfc_conv_expr (&se_sz
, code
->ext
.alloc
.ts
.u
.cl
->length
);
5696 gfc_add_modify (&block
, al_len
,
5697 fold_convert (TREE_TYPE (al_len
),
5701 /* No length information needed, because type to allocate
5702 has no length. Set _len to 0. */
5703 gfc_add_modify (&block
, al_len
,
5704 fold_convert (TREE_TYPE (al_len
),
5705 integer_zero_node
));
5707 if (code
->expr3
&& !code
->expr3
->mold
)
5709 /* Initialization via SOURCE block (or static default initializer).
5710 Classes need some special handling, so catch them first. */
5711 if (expr3
!= NULL_TREE
5712 && ((POINTER_TYPE_P (TREE_TYPE (expr3
))
5713 && TREE_CODE (expr3
) != POINTER_PLUS_EXPR
)
5714 || (VAR_P (expr3
) && GFC_CLASS_TYPE_P (
5715 TREE_TYPE (expr3
))))
5716 && code
->expr3
->ts
.type
== BT_CLASS
5717 && (expr
->ts
.type
== BT_CLASS
5718 || expr
->ts
.type
== BT_DERIVED
))
5720 /* copy_class_to_class can be used for class arrays, too.
5721 It just needs to be ensured, that the decl_saved_descriptor
5722 has a way to get to the vptr. */
5724 to
= VAR_P (se
.expr
) ? se
.expr
: TREE_OPERAND (se
.expr
, 0);
5725 tmp
= gfc_copy_class_to_class (expr3
, to
,
5726 nelems
, upoly_expr
);
5728 else if (al
->expr
->ts
.type
== BT_CLASS
)
5730 gfc_actual_arglist
*actual
, *last_arg
;
5733 gfc_ref
*ref
, *dataref
;
5734 gfc_expr
*rhs
= gfc_copy_expr (code
->expr3
);
5736 /* Do a polymorphic deep copy. */
5737 actual
= gfc_get_actual_arglist ();
5738 actual
->expr
= gfc_copy_expr (rhs
);
5739 if (rhs
->ts
.type
== BT_CLASS
)
5740 gfc_add_data_component (actual
->expr
);
5741 last_arg
= actual
->next
= gfc_get_actual_arglist ();
5742 last_arg
->expr
= gfc_copy_expr (al
->expr
);
5743 last_arg
->expr
->ts
.type
= BT_CLASS
;
5744 gfc_add_data_component (last_arg
->expr
);
5747 /* Make sure we go up through the reference chain to
5748 the _data reference, where the arrayspec is found. */
5749 for (ref
= last_arg
->expr
->ref
; ref
; ref
= ref
->next
)
5750 if (ref
->type
== REF_COMPONENT
5751 && strcmp (ref
->u
.c
.component
->name
, "_data") == 0)
5754 if (dataref
&& dataref
->u
.c
.component
->as
)
5756 gfc_array_spec
*as
= dataref
->u
.c
.component
->as
;
5757 gfc_free_ref_list (dataref
->next
);
5758 dataref
->next
= NULL
;
5759 gfc_add_full_array_ref (last_arg
->expr
, as
);
5760 gfc_resolve_expr (last_arg
->expr
);
5761 gcc_assert (last_arg
->expr
->ts
.type
== BT_CLASS
5762 || last_arg
->expr
->ts
.type
== BT_DERIVED
);
5763 last_arg
->expr
->ts
.type
= BT_CLASS
;
5765 if (rhs
->ts
.type
== BT_CLASS
)
5768 ppc
= gfc_find_and_cut_at_last_class_ref (rhs
);
5770 ppc
= gfc_copy_expr (rhs
);
5771 gfc_add_vptr_component (ppc
);
5774 ppc
= gfc_lval_expr_from_sym (gfc_find_vtab (&rhs
->ts
));
5775 gfc_add_component_ref (ppc
, "_copy");
5777 ppc_code
= gfc_get_code (EXEC_CALL
);
5778 ppc_code
->resolved_sym
= ppc
->symtree
->n
.sym
;
5779 ppc_code
->loc
= al
->expr
->where
;
5780 /* Although '_copy' is set to be elemental in class.c, it is
5781 not staying that way. Find out why, sometime.... */
5782 ppc_code
->resolved_sym
->attr
.elemental
= 1;
5783 ppc_code
->ext
.actual
= actual
;
5784 ppc_code
->expr1
= ppc
;
5785 /* Since '_copy' is elemental, the scalarizer will take care
5786 of arrays in gfc_trans_call. */
5787 tmp
= gfc_trans_call (ppc_code
, true, NULL
, NULL
, false);
5788 /* We need to add the
5790 al_vptr->copy (expr3_data, al_data, expr3_len, al_len);
5792 al_vptr->copy (expr3_data, al_data);
5793 block, because al is unlimited polymorphic or a deferred
5794 length char array, whose copy routine needs the array lengths
5795 as third and fourth arguments. */
5796 if (al_len
&& UNLIMITED_POLY (code
->expr3
))
5798 tree stdcopy
, extcopy
;
5800 last_arg
->next
= gfc_get_actual_arglist ();
5801 last_arg
= last_arg
->next
;
5802 last_arg
->expr
= gfc_find_and_cut_at_last_class_ref (
5804 gfc_add_len_component (last_arg
->expr
);
5805 /* Add expr3's length. */
5806 last_arg
->next
= gfc_get_actual_arglist ();
5807 last_arg
= last_arg
->next
;
5808 if (code
->expr3
->ts
.type
== BT_CLASS
)
5811 gfc_find_and_cut_at_last_class_ref (code
->expr3
);
5812 gfc_add_len_component (last_arg
->expr
);
5814 else if (code
->expr3
->ts
.type
== BT_CHARACTER
)
5816 gfc_copy_expr (code
->expr3
->ts
.u
.cl
->length
);
5821 extcopy
= gfc_trans_call (ppc_code
, true, NULL
, NULL
, false);
5823 tmp
= fold_build2_loc (input_location
, GT_EXPR
,
5824 boolean_type_node
, expr3_len
,
5826 tmp
= fold_build3_loc (input_location
, COND_EXPR
,
5827 void_type_node
, tmp
, extcopy
, stdcopy
);
5829 gfc_free_statements (ppc_code
);
5830 gfc_free_expr (rhs
);
5834 /* Switch off automatic reallocation since we have just
5835 done the ALLOCATE. */
5836 int realloc_lhs
= flag_realloc_lhs
;
5837 flag_realloc_lhs
= 0;
5838 tmp
= gfc_trans_assignment (gfc_expr_to_initialize (expr
),
5839 e3rhs
, false, false);
5840 flag_realloc_lhs
= realloc_lhs
;
5842 gfc_add_expr_to_block (&block
, tmp
);
5844 else if (code
->expr3
&& code
->expr3
->mold
5845 && code
->expr3
->ts
.type
== BT_CLASS
)
5847 /* Since the _vptr has already been assigned to the allocate
5848 object, we can use gfc_copy_class_to_class in its
5849 initialization mode. */
5850 tmp
= TREE_OPERAND (se
.expr
, 0);
5851 tmp
= gfc_copy_class_to_class (NULL_TREE
, tmp
, nelems
,
5853 gfc_add_expr_to_block (&block
, tmp
);
5856 gfc_free_expr (expr
);
5863 gfc_free_symbol (newsym
->n
.sym
);
5866 gfc_free_expr (e3rhs
);
5871 tmp
= build1_v (LABEL_EXPR
, label_errmsg
);
5872 gfc_add_expr_to_block (&block
, tmp
);
5875 /* ERRMSG - only useful if STAT is present. */
5876 if (code
->expr1
&& code
->expr2
)
5878 const char *msg
= "Attempt to allocate an allocated object";
5879 tree slen
, dlen
, errmsg_str
;
5880 stmtblock_t errmsg_block
;
5882 gfc_init_block (&errmsg_block
);
5884 errmsg_str
= gfc_create_var (pchar_type_node
, "ERRMSG");
5885 gfc_add_modify (&errmsg_block
, errmsg_str
,
5886 gfc_build_addr_expr (pchar_type_node
,
5887 gfc_build_localized_cstring_const (msg
)));
5889 slen
= build_int_cst (gfc_charlen_type_node
, ((int) strlen (msg
)));
5890 dlen
= gfc_get_expr_charlen (code
->expr2
);
5891 slen
= fold_build2_loc (input_location
, MIN_EXPR
,
5892 TREE_TYPE (slen
), dlen
, slen
);
5894 gfc_trans_string_copy (&errmsg_block
, dlen
, errmsg
,
5895 code
->expr2
->ts
.kind
,
5897 gfc_default_character_kind
);
5898 dlen
= gfc_finish_block (&errmsg_block
);
5900 tmp
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
,
5901 stat
, build_int_cst (TREE_TYPE (stat
), 0));
5903 tmp
= build3_v (COND_EXPR
, tmp
,
5904 dlen
, build_empty_stmt (input_location
));
5906 gfc_add_expr_to_block (&block
, tmp
);
5912 if (TREE_USED (label_finish
))
5914 tmp
= build1_v (LABEL_EXPR
, label_finish
);
5915 gfc_add_expr_to_block (&block
, tmp
);
5918 gfc_init_se (&se
, NULL
);
5919 gfc_conv_expr_lhs (&se
, code
->expr1
);
5920 tmp
= convert (TREE_TYPE (se
.expr
), stat
);
5921 gfc_add_modify (&block
, se
.expr
, tmp
);
5924 gfc_add_block_to_block (&block
, &se
.post
);
5925 gfc_add_block_to_block (&block
, &post
);
5927 return gfc_finish_block (&block
);
5931 /* Translate a DEALLOCATE statement. */
5934 gfc_trans_deallocate (gfc_code
*code
)
5938 tree apstat
, pstat
, stat
, errmsg
, errlen
, tmp
;
5939 tree label_finish
, label_errmsg
;
5942 pstat
= apstat
= stat
= errmsg
= errlen
= tmp
= NULL_TREE
;
5943 label_finish
= label_errmsg
= NULL_TREE
;
5945 gfc_start_block (&block
);
5947 /* Count the number of failed deallocations. If deallocate() was
5948 called with STAT= , then set STAT to the count. If deallocate
5949 was called with ERRMSG, then set ERRMG to a string. */
5952 tree gfc_int4_type_node
= gfc_get_int_type (4);
5954 stat
= gfc_create_var (gfc_int4_type_node
, "stat");
5955 pstat
= gfc_build_addr_expr (NULL_TREE
, stat
);
5957 /* GOTO destinations. */
5958 label_errmsg
= gfc_build_label_decl (NULL_TREE
);
5959 label_finish
= gfc_build_label_decl (NULL_TREE
);
5960 TREE_USED (label_finish
) = 0;
5963 /* Set ERRMSG - only needed if STAT is available. */
5964 if (code
->expr1
&& code
->expr2
)
5966 gfc_init_se (&se
, NULL
);
5967 se
.want_pointer
= 1;
5968 gfc_conv_expr_lhs (&se
, code
->expr2
);
5970 errlen
= se
.string_length
;
5973 for (al
= code
->ext
.alloc
.list
; al
!= NULL
; al
= al
->next
)
5975 gfc_expr
*expr
= gfc_copy_expr (al
->expr
);
5976 gcc_assert (expr
->expr_type
== EXPR_VARIABLE
);
5978 if (expr
->ts
.type
== BT_CLASS
)
5979 gfc_add_data_component (expr
);
5981 gfc_init_se (&se
, NULL
);
5982 gfc_start_block (&se
.pre
);
5984 se
.want_pointer
= 1;
5985 se
.descriptor_only
= 1;
5986 gfc_conv_expr (&se
, expr
);
5988 if (expr
->rank
|| gfc_is_coarray (expr
))
5992 if (expr
->ts
.type
== BT_DERIVED
&& expr
->ts
.u
.derived
->attr
.alloc_comp
5993 && !gfc_is_finalizable (expr
->ts
.u
.derived
, NULL
))
5995 gfc_ref
*last
= NULL
;
5997 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
5998 if (ref
->type
== REF_COMPONENT
)
6001 /* Do not deallocate the components of a derived type
6002 ultimate pointer component. */
6003 if (!(last
&& last
->u
.c
.component
->attr
.pointer
)
6004 && !(!last
&& expr
->symtree
->n
.sym
->attr
.pointer
))
6006 tmp
= gfc_deallocate_alloc_comp (expr
->ts
.u
.derived
, se
.expr
,
6008 gfc_add_expr_to_block (&se
.pre
, tmp
);
6012 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se
.expr
)))
6014 tmp
= gfc_array_deallocate (se
.expr
, pstat
, errmsg
, errlen
,
6015 label_finish
, expr
);
6016 gfc_add_expr_to_block (&se
.pre
, tmp
);
6018 else if (TREE_CODE (se
.expr
) == COMPONENT_REF
6019 && TREE_CODE (TREE_TYPE (se
.expr
)) == ARRAY_TYPE
6020 && TREE_CODE (TREE_TYPE (TREE_TYPE (se
.expr
)))
6023 /* class.c(finalize_component) generates these, when a
6024 finalizable entity has a non-allocatable derived type array
6025 component, which has allocatable components. Obtain the
6026 derived type of the array and deallocate the allocatable
6028 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
6030 if (ref
->u
.c
.component
->attr
.dimension
6031 && ref
->u
.c
.component
->ts
.type
== BT_DERIVED
)
6035 if (ref
&& ref
->u
.c
.component
->ts
.u
.derived
->attr
.alloc_comp
6036 && !gfc_is_finalizable (ref
->u
.c
.component
->ts
.u
.derived
,
6039 tmp
= gfc_deallocate_alloc_comp
6040 (ref
->u
.c
.component
->ts
.u
.derived
,
6041 se
.expr
, expr
->rank
);
6042 gfc_add_expr_to_block (&se
.pre
, tmp
);
6046 if (al
->expr
->ts
.type
== BT_CLASS
)
6048 gfc_reset_vptr (&se
.pre
, al
->expr
);
6049 if (UNLIMITED_POLY (al
->expr
)
6050 || (al
->expr
->ts
.type
== BT_DERIVED
6051 && al
->expr
->ts
.u
.derived
->attr
.unlimited_polymorphic
))
6052 /* Clear _len, too. */
6053 gfc_reset_len (&se
.pre
, al
->expr
);
6058 tmp
= gfc_deallocate_scalar_with_status (se
.expr
, pstat
, false,
6059 al
->expr
, al
->expr
->ts
);
6060 gfc_add_expr_to_block (&se
.pre
, tmp
);
6062 /* Set to zero after deallocation. */
6063 tmp
= fold_build2_loc (input_location
, MODIFY_EXPR
, void_type_node
,
6065 build_int_cst (TREE_TYPE (se
.expr
), 0));
6066 gfc_add_expr_to_block (&se
.pre
, tmp
);
6068 if (al
->expr
->ts
.type
== BT_CLASS
)
6070 gfc_reset_vptr (&se
.pre
, al
->expr
);
6071 if (UNLIMITED_POLY (al
->expr
)
6072 || (al
->expr
->ts
.type
== BT_DERIVED
6073 && al
->expr
->ts
.u
.derived
->attr
.unlimited_polymorphic
))
6074 /* Clear _len, too. */
6075 gfc_reset_len (&se
.pre
, al
->expr
);
6083 cond
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
, stat
,
6084 build_int_cst (TREE_TYPE (stat
), 0));
6085 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
6086 gfc_unlikely (cond
, PRED_FORTRAN_FAIL_ALLOC
),
6087 build1_v (GOTO_EXPR
, label_errmsg
),
6088 build_empty_stmt (input_location
));
6089 gfc_add_expr_to_block (&se
.pre
, tmp
);
6092 tmp
= gfc_finish_block (&se
.pre
);
6093 gfc_add_expr_to_block (&block
, tmp
);
6094 gfc_free_expr (expr
);
6099 tmp
= build1_v (LABEL_EXPR
, label_errmsg
);
6100 gfc_add_expr_to_block (&block
, tmp
);
6103 /* Set ERRMSG - only needed if STAT is available. */
6104 if (code
->expr1
&& code
->expr2
)
6106 const char *msg
= "Attempt to deallocate an unallocated object";
6107 stmtblock_t errmsg_block
;
6108 tree errmsg_str
, slen
, dlen
, cond
;
6110 gfc_init_block (&errmsg_block
);
6112 errmsg_str
= gfc_create_var (pchar_type_node
, "ERRMSG");
6113 gfc_add_modify (&errmsg_block
, errmsg_str
,
6114 gfc_build_addr_expr (pchar_type_node
,
6115 gfc_build_localized_cstring_const (msg
)));
6116 slen
= build_int_cst (gfc_charlen_type_node
, ((int) strlen (msg
)));
6117 dlen
= gfc_get_expr_charlen (code
->expr2
);
6119 gfc_trans_string_copy (&errmsg_block
, dlen
, errmsg
, code
->expr2
->ts
.kind
,
6120 slen
, errmsg_str
, gfc_default_character_kind
);
6121 tmp
= gfc_finish_block (&errmsg_block
);
6123 cond
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
, stat
,
6124 build_int_cst (TREE_TYPE (stat
), 0));
6125 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
,
6126 gfc_unlikely (cond
, PRED_FORTRAN_FAIL_ALLOC
), tmp
,
6127 build_empty_stmt (input_location
));
6129 gfc_add_expr_to_block (&block
, tmp
);
6132 if (code
->expr1
&& TREE_USED (label_finish
))
6134 tmp
= build1_v (LABEL_EXPR
, label_finish
);
6135 gfc_add_expr_to_block (&block
, tmp
);
6141 gfc_init_se (&se
, NULL
);
6142 gfc_conv_expr_lhs (&se
, code
->expr1
);
6143 tmp
= convert (TREE_TYPE (se
.expr
), stat
);
6144 gfc_add_modify (&block
, se
.expr
, tmp
);
6147 return gfc_finish_block (&block
);
6150 #include "gt-fortran-trans-stmt.h"