Daily bump.
[official-gcc.git] / gcc / fortran / trans-stmt.cc
blob703a705e7caf89e6f2fe071491588a8e28bddc22
1 /* Statement translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2002-2024 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
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "options.h"
27 #include "tree.h"
28 #include "gfortran.h"
29 #include "trans.h"
30 #include "stringpool.h"
31 #include "fold-const.h"
32 #include "trans-stmt.h"
33 #include "trans-types.h"
34 #include "trans-array.h"
35 #include "trans-const.h"
36 #include "dependency.h"
38 typedef struct iter_info
40 tree var;
41 tree start;
42 tree end;
43 tree step;
44 gfc_loop_annot annot;
45 struct iter_info *next;
47 iter_info;
49 typedef struct forall_info
51 iter_info *this_loop;
52 tree mask;
53 tree maskindex;
54 int nvar;
55 tree size;
56 struct forall_info *prev_nest;
57 bool do_concurrent;
59 forall_info;
61 static void gfc_trans_where_2 (gfc_code *, tree, bool,
62 forall_info *, stmtblock_t *);
64 /* Translate a F95 label number to a LABEL_EXPR. */
66 tree
67 gfc_trans_label_here (gfc_code * code)
69 return build1_v (LABEL_EXPR, gfc_get_label_decl (code->here));
73 /* Given a variable expression which has been ASSIGNed to, find the decl
74 containing the auxiliary variables. For variables in common blocks this
75 is a field_decl. */
77 void
78 gfc_conv_label_variable (gfc_se * se, gfc_expr * expr)
80 gcc_assert (expr->symtree->n.sym->attr.assign == 1);
81 gfc_conv_expr (se, expr);
82 /* Deals with variable in common block. Get the field declaration. */
83 if (TREE_CODE (se->expr) == COMPONENT_REF)
84 se->expr = TREE_OPERAND (se->expr, 1);
85 /* Deals with dummy argument. Get the parameter declaration. */
86 else if (INDIRECT_REF_P (se->expr))
87 se->expr = TREE_OPERAND (se->expr, 0);
90 /* Translate a label assignment statement. */
92 tree
93 gfc_trans_label_assign (gfc_code * code)
95 tree label_tree;
96 gfc_se se;
97 tree len;
98 tree addr;
99 tree len_tree;
100 int label_len;
102 /* Start a new block. */
103 gfc_init_se (&se, NULL);
104 gfc_start_block (&se.pre);
105 gfc_conv_label_variable (&se, code->expr1);
107 len = GFC_DECL_STRING_LEN (se.expr);
108 addr = GFC_DECL_ASSIGN_ADDR (se.expr);
110 label_tree = gfc_get_label_decl (code->label1);
112 if (code->label1->defined == ST_LABEL_TARGET
113 || code->label1->defined == ST_LABEL_DO_TARGET)
115 label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
116 len_tree = build_int_cst (gfc_charlen_type_node, -1);
118 else
120 gfc_expr *format = code->label1->format;
122 label_len = format->value.character.length;
123 len_tree = build_int_cst (gfc_charlen_type_node, label_len);
124 label_tree = gfc_build_wide_string_const (format->ts.kind, label_len + 1,
125 format->value.character.string);
126 label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
129 gfc_add_modify (&se.pre, len, fold_convert (TREE_TYPE (len), len_tree));
130 gfc_add_modify (&se.pre, addr, label_tree);
132 return gfc_finish_block (&se.pre);
135 /* Translate a GOTO statement. */
137 tree
138 gfc_trans_goto (gfc_code * code)
140 locus loc = code->loc;
141 tree assigned_goto;
142 tree target;
143 tree tmp;
144 gfc_se se;
146 if (code->label1 != NULL)
147 return build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
149 /* ASSIGNED GOTO. */
150 gfc_init_se (&se, NULL);
151 gfc_start_block (&se.pre);
152 gfc_conv_label_variable (&se, code->expr1);
153 tmp = GFC_DECL_STRING_LEN (se.expr);
154 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp,
155 build_int_cst (TREE_TYPE (tmp), -1));
156 gfc_trans_runtime_check (true, false, tmp, &se.pre, &loc,
157 "Assigned label is not a target label");
159 assigned_goto = GFC_DECL_ASSIGN_ADDR (se.expr);
161 /* We're going to ignore a label list. It does not really change the
162 statement's semantics (because it is just a further restriction on
163 what's legal code); before, we were comparing label addresses here, but
164 that's a very fragile business and may break with optimization. So
165 just ignore it. */
167 target = fold_build1_loc (input_location, GOTO_EXPR, void_type_node,
168 assigned_goto);
169 gfc_add_expr_to_block (&se.pre, target);
170 return gfc_finish_block (&se.pre);
174 /* Translate an ENTRY statement. Just adds a label for this entry point. */
175 tree
176 gfc_trans_entry (gfc_code * code)
178 return build1_v (LABEL_EXPR, code->ext.entry->label);
182 /* Replace a gfc_ss structure by another both in the gfc_se struct
183 and the gfc_loopinfo struct. This is used in gfc_conv_elemental_dependencies
184 to replace a variable ss by the corresponding temporary. */
186 static void
187 replace_ss (gfc_se *se, gfc_ss *old_ss, gfc_ss *new_ss)
189 gfc_ss **sess, **loopss;
191 /* The old_ss is a ss for a single variable. */
192 gcc_assert (old_ss->info->type == GFC_SS_SECTION);
194 for (sess = &(se->ss); *sess != gfc_ss_terminator; sess = &((*sess)->next))
195 if (*sess == old_ss)
196 break;
197 gcc_assert (*sess != gfc_ss_terminator);
199 *sess = new_ss;
200 new_ss->next = old_ss->next;
202 /* Make sure that trailing references are not lost. */
203 if (old_ss->info
204 && old_ss->info->data.array.ref
205 && old_ss->info->data.array.ref->next
206 && !(new_ss->info->data.array.ref
207 && new_ss->info->data.array.ref->next))
208 new_ss->info->data.array.ref = old_ss->info->data.array.ref;
210 for (loopss = &(se->loop->ss); *loopss != gfc_ss_terminator;
211 loopss = &((*loopss)->loop_chain))
212 if (*loopss == old_ss)
213 break;
214 gcc_assert (*loopss != gfc_ss_terminator);
216 *loopss = new_ss;
217 new_ss->loop_chain = old_ss->loop_chain;
218 new_ss->loop = old_ss->loop;
220 gfc_free_ss (old_ss);
224 /* Check for dependencies between INTENT(IN) and INTENT(OUT) arguments of
225 elemental subroutines. Make temporaries for output arguments if any such
226 dependencies are found. Output arguments are chosen because internal_unpack
227 can be used, as is, to copy the result back to the variable. */
228 static void
229 gfc_conv_elemental_dependencies (gfc_se * se, gfc_se * loopse,
230 gfc_symbol * sym, gfc_actual_arglist * arg,
231 gfc_dep_check check_variable)
233 gfc_actual_arglist *arg0;
234 gfc_expr *e;
235 gfc_formal_arglist *formal;
236 gfc_se parmse;
237 gfc_ss *ss;
238 gfc_symbol *fsym;
239 tree data;
240 tree size;
241 tree tmp;
243 if (loopse->ss == NULL)
244 return;
246 ss = loopse->ss;
247 arg0 = arg;
248 formal = gfc_sym_get_dummy_args (sym);
250 /* Loop over all the arguments testing for dependencies. */
251 for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
253 e = arg->expr;
254 if (e == NULL)
255 continue;
257 /* Obtain the info structure for the current argument. */
258 for (ss = loopse->ss; ss && ss != gfc_ss_terminator; ss = ss->next)
259 if (ss->info->expr == e)
260 break;
262 /* If there is a dependency, create a temporary and use it
263 instead of the variable. */
264 fsym = formal ? formal->sym : NULL;
265 if (e->expr_type == EXPR_VARIABLE
266 && e->rank && fsym
267 && fsym->attr.intent != INTENT_IN
268 && !fsym->attr.value
269 && gfc_check_fncall_dependency (e, fsym->attr.intent,
270 sym, arg0, check_variable))
272 tree initial, temptype;
273 stmtblock_t temp_post;
274 gfc_ss *tmp_ss;
276 tmp_ss = gfc_get_array_ss (gfc_ss_terminator, NULL, ss->dimen,
277 GFC_SS_SECTION);
278 gfc_mark_ss_chain_used (tmp_ss, 1);
279 tmp_ss->info->expr = ss->info->expr;
280 replace_ss (loopse, ss, tmp_ss);
282 /* Obtain the argument descriptor for unpacking. */
283 gfc_init_se (&parmse, NULL);
284 parmse.want_pointer = 1;
285 gfc_conv_expr_descriptor (&parmse, e);
286 gfc_add_block_to_block (&se->pre, &parmse.pre);
288 /* If we've got INTENT(INOUT) or a derived type with INTENT(OUT),
289 initialize the array temporary with a copy of the values. */
290 if (fsym->attr.intent == INTENT_INOUT
291 || (fsym->ts.type ==BT_DERIVED
292 && fsym->attr.intent == INTENT_OUT))
293 initial = parmse.expr;
294 /* For class expressions, we always initialize with the copy of
295 the values. */
296 else if (e->ts.type == BT_CLASS)
297 initial = parmse.expr;
298 else
299 initial = NULL_TREE;
301 if (e->ts.type != BT_CLASS)
303 /* Find the type of the temporary to create; we don't use the type
304 of e itself as this breaks for subcomponent-references in e
305 (where the type of e is that of the final reference, but
306 parmse.expr's type corresponds to the full derived-type). */
307 /* TODO: Fix this somehow so we don't need a temporary of the whole
308 array but instead only the components referenced. */
309 temptype = TREE_TYPE (parmse.expr); /* Pointer to descriptor. */
310 gcc_assert (TREE_CODE (temptype) == POINTER_TYPE);
311 temptype = TREE_TYPE (temptype);
312 temptype = gfc_get_element_type (temptype);
315 else
316 /* For class arrays signal that the size of the dynamic type has to
317 be obtained from the vtable, using the 'initial' expression. */
318 temptype = NULL_TREE;
320 /* Generate the temporary. Cleaning up the temporary should be the
321 very last thing done, so we add the code to a new block and add it
322 to se->post as last instructions. */
323 size = gfc_create_var (gfc_array_index_type, NULL);
324 data = gfc_create_var (pvoid_type_node, NULL);
325 gfc_init_block (&temp_post);
326 tmp = gfc_trans_create_temp_array (&se->pre, &temp_post, tmp_ss,
327 temptype, initial, false, true,
328 false, &arg->expr->where);
329 gfc_add_modify (&se->pre, size, tmp);
330 tmp = fold_convert (pvoid_type_node, tmp_ss->info->data.array.data);
331 gfc_add_modify (&se->pre, data, tmp);
333 /* Update other ss' delta. */
334 gfc_set_delta (loopse->loop);
336 /* Copy the result back using unpack..... */
337 if (e->ts.type != BT_CLASS)
338 tmp = build_call_expr_loc (input_location,
339 gfor_fndecl_in_unpack, 2, parmse.expr, data);
340 else
342 /* ... except for class results where the copy is
343 unconditional. */
344 tmp = build_fold_indirect_ref_loc (input_location, parmse.expr);
345 tmp = gfc_conv_descriptor_data_get (tmp);
346 tmp = build_call_expr_loc (input_location,
347 builtin_decl_explicit (BUILT_IN_MEMCPY),
348 3, tmp, data,
349 fold_convert (size_type_node, size));
351 gfc_add_expr_to_block (&se->post, tmp);
353 /* parmse.pre is already added above. */
354 gfc_add_block_to_block (&se->post, &parmse.post);
355 gfc_add_block_to_block (&se->post, &temp_post);
361 /* Given an executable statement referring to an intrinsic function call,
362 returns the intrinsic symbol. */
364 static gfc_intrinsic_sym *
365 get_intrinsic_for_code (gfc_code *code)
367 if (code->op == EXEC_CALL)
369 gfc_intrinsic_sym * const isym = code->resolved_isym;
370 if (isym)
371 return isym;
372 else
373 return gfc_get_intrinsic_for_expr (code->expr1);
376 return NULL;
380 /* Translate the CALL statement. Builds a call to an F95 subroutine. */
382 tree
383 gfc_trans_call (gfc_code * code, bool dependency_check,
384 tree mask, tree count1, bool invert)
386 gfc_se se;
387 gfc_ss * ss;
388 int has_alternate_specifier;
389 gfc_dep_check check_variable;
390 tree index = NULL_TREE;
391 tree maskexpr = NULL_TREE;
392 tree tmp;
393 bool is_intrinsic_mvbits;
395 /* A CALL starts a new block because the actual arguments may have to
396 be evaluated first. */
397 gfc_init_se (&se, NULL);
398 gfc_start_block (&se.pre);
400 gcc_assert (code->resolved_sym);
402 ss = gfc_ss_terminator;
403 if (code->resolved_sym->attr.elemental)
404 ss = gfc_walk_elemental_function_args (ss, code->ext.actual,
405 get_intrinsic_for_code (code),
406 GFC_SS_REFERENCE);
408 /* MVBITS is inlined but needs the dependency checking found here. */
409 is_intrinsic_mvbits = code->resolved_isym
410 && code->resolved_isym->id == GFC_ISYM_MVBITS;
412 /* Is not an elemental subroutine call with array valued arguments. */
413 if (ss == gfc_ss_terminator)
416 if (is_intrinsic_mvbits)
418 has_alternate_specifier = 0;
419 gfc_conv_intrinsic_mvbits (&se, code->ext.actual, NULL);
421 else
423 /* Translate the call. */
424 has_alternate_specifier =
425 gfc_conv_procedure_call (&se, code->resolved_sym,
426 code->ext.actual, code->expr1, NULL);
428 /* A subroutine without side-effect, by definition, does nothing! */
429 TREE_SIDE_EFFECTS (se.expr) = 1;
432 /* Chain the pieces together and return the block. */
433 if (has_alternate_specifier)
435 gfc_code *select_code;
436 gfc_symbol *sym;
437 select_code = code->next;
438 gcc_assert(select_code->op == EXEC_SELECT);
439 sym = select_code->expr1->symtree->n.sym;
440 se.expr = convert (gfc_typenode_for_spec (&sym->ts), se.expr);
441 if (sym->backend_decl == NULL)
442 sym->backend_decl = gfc_get_symbol_decl (sym);
443 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
445 else
446 gfc_add_expr_to_block (&se.pre, se.expr);
448 gfc_add_block_to_block (&se.finalblock, &se.post);
449 gfc_add_block_to_block (&se.pre, &se.finalblock);
452 else
454 /* An elemental subroutine call with array valued arguments has
455 to be scalarized. */
456 gfc_loopinfo loop;
457 stmtblock_t body;
458 stmtblock_t block;
459 gfc_se loopse;
460 gfc_se depse;
462 /* gfc_walk_elemental_function_args renders the ss chain in the
463 reverse order to the actual argument order. */
464 ss = gfc_reverse_ss (ss);
466 /* Initialize the loop. */
467 gfc_init_se (&loopse, NULL);
468 gfc_init_loopinfo (&loop);
469 gfc_add_ss_to_loop (&loop, ss);
471 gfc_conv_ss_startstride (&loop);
472 /* TODO: gfc_conv_loop_setup generates a temporary for vector
473 subscripts. This could be prevented in the elemental case
474 as temporaries are handled separately
475 (below in gfc_conv_elemental_dependencies). */
476 if (code->expr1)
477 gfc_conv_loop_setup (&loop, &code->expr1->where);
478 else
479 gfc_conv_loop_setup (&loop, &code->loc);
481 gfc_mark_ss_chain_used (ss, 1);
483 /* Convert the arguments, checking for dependencies. */
484 gfc_copy_loopinfo_to_se (&loopse, &loop);
485 loopse.ss = ss;
487 /* For operator assignment, do dependency checking. */
488 if (dependency_check)
489 check_variable = ELEM_CHECK_VARIABLE;
490 else
491 check_variable = ELEM_DONT_CHECK_VARIABLE;
493 gfc_init_se (&depse, NULL);
494 gfc_conv_elemental_dependencies (&depse, &loopse, code->resolved_sym,
495 code->ext.actual, check_variable);
497 gfc_add_block_to_block (&loop.pre, &depse.pre);
498 gfc_add_block_to_block (&loop.post, &depse.post);
500 /* Generate the loop body. */
501 gfc_start_scalarized_body (&loop, &body);
502 gfc_init_block (&block);
504 if (mask && count1)
506 /* Form the mask expression according to the mask. */
507 index = count1;
508 maskexpr = gfc_build_array_ref (mask, index, NULL);
509 if (invert)
510 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
511 TREE_TYPE (maskexpr), maskexpr);
514 if (is_intrinsic_mvbits)
516 has_alternate_specifier = 0;
517 gfc_conv_intrinsic_mvbits (&loopse, code->ext.actual, &loop);
519 else
521 /* Add the subroutine call to the block. */
522 gfc_conv_procedure_call (&loopse, code->resolved_sym,
523 code->ext.actual, code->expr1,
524 NULL);
527 if (mask && count1)
529 tmp = build3_v (COND_EXPR, maskexpr, loopse.expr,
530 build_empty_stmt (input_location));
531 gfc_add_expr_to_block (&loopse.pre, tmp);
532 tmp = fold_build2_loc (input_location, PLUS_EXPR,
533 gfc_array_index_type,
534 count1, gfc_index_one_node);
535 gfc_add_modify (&loopse.pre, count1, tmp);
537 else
538 gfc_add_expr_to_block (&loopse.pre, loopse.expr);
540 gfc_add_block_to_block (&block, &loopse.pre);
541 gfc_add_block_to_block (&block, &loopse.post);
543 /* Finish up the loop block and the loop. */
544 gfc_add_expr_to_block (&body, gfc_finish_block (&block));
545 gfc_trans_scalarizing_loops (&loop, &body);
546 gfc_add_block_to_block (&se.pre, &loop.pre);
547 gfc_add_block_to_block (&se.pre, &loop.post);
548 gfc_add_block_to_block (&se.pre, &loopse.finalblock);
549 gfc_add_block_to_block (&se.pre, &se.post);
550 gfc_cleanup_loop (&loop);
553 return gfc_finish_block (&se.pre);
557 /* Translate the RETURN statement. */
559 tree
560 gfc_trans_return (gfc_code * code)
562 if (code->expr1)
564 gfc_se se;
565 tree tmp;
566 tree result;
568 /* If code->expr is not NULL, this return statement must appear
569 in a subroutine and current_fake_result_decl has already
570 been generated. */
572 result = gfc_get_fake_result_decl (NULL, 0);
573 if (!result)
575 gfc_warning (0,
576 "An alternate return at %L without a * dummy argument",
577 &code->expr1->where);
578 return gfc_generate_return ();
581 /* Start a new block for this statement. */
582 gfc_init_se (&se, NULL);
583 gfc_start_block (&se.pre);
585 gfc_conv_expr (&se, code->expr1);
587 /* Note that the actually returned expression is a simple value and
588 does not depend on any pointers or such; thus we can clean-up with
589 se.post before returning. */
590 tmp = fold_build2_loc (input_location, MODIFY_EXPR, TREE_TYPE (result),
591 result, fold_convert (TREE_TYPE (result),
592 se.expr));
593 gfc_add_expr_to_block (&se.pre, tmp);
594 gfc_add_block_to_block (&se.pre, &se.post);
596 tmp = gfc_generate_return ();
597 gfc_add_expr_to_block (&se.pre, tmp);
598 return gfc_finish_block (&se.pre);
601 return gfc_generate_return ();
605 /* Translate the PAUSE statement. We have to translate this statement
606 to a runtime library call. */
608 tree
609 gfc_trans_pause (gfc_code * code)
611 tree gfc_int8_type_node = gfc_get_int_type (8);
612 gfc_se se;
613 tree tmp;
615 /* Start a new block for this statement. */
616 gfc_init_se (&se, NULL);
617 gfc_start_block (&se.pre);
620 if (code->expr1 == NULL)
622 tmp = build_int_cst (size_type_node, 0);
623 tmp = build_call_expr_loc (input_location,
624 gfor_fndecl_pause_string, 2,
625 build_int_cst (pchar_type_node, 0), tmp);
627 else if (code->expr1->ts.type == BT_INTEGER)
629 gfc_conv_expr (&se, code->expr1);
630 tmp = build_call_expr_loc (input_location,
631 gfor_fndecl_pause_numeric, 1,
632 fold_convert (gfc_int8_type_node, se.expr));
634 else
636 gfc_conv_expr_reference (&se, code->expr1);
637 tmp = build_call_expr_loc (input_location,
638 gfor_fndecl_pause_string, 2,
639 se.expr, fold_convert (size_type_node,
640 se.string_length));
643 gfc_add_expr_to_block (&se.pre, tmp);
645 gfc_add_block_to_block (&se.pre, &se.post);
647 return gfc_finish_block (&se.pre);
651 /* Translate the STOP statement. We have to translate this statement
652 to a runtime library call. */
654 tree
655 gfc_trans_stop (gfc_code *code, bool error_stop)
657 gfc_se se;
658 tree tmp;
659 tree quiet;
661 /* Start a new block for this statement. */
662 gfc_init_se (&se, NULL);
663 gfc_start_block (&se.pre);
665 if (code->expr2)
667 gfc_conv_expr_val (&se, code->expr2);
668 quiet = fold_convert (boolean_type_node, se.expr);
670 else
671 quiet = boolean_false_node;
673 if (code->expr1 == NULL)
675 tmp = build_int_cst (size_type_node, 0);
676 tmp = build_call_expr_loc (input_location,
677 error_stop
678 ? (flag_coarray == GFC_FCOARRAY_LIB
679 ? gfor_fndecl_caf_error_stop_str
680 : gfor_fndecl_error_stop_string)
681 : (flag_coarray == GFC_FCOARRAY_LIB
682 ? gfor_fndecl_caf_stop_str
683 : gfor_fndecl_stop_string),
684 3, build_int_cst (pchar_type_node, 0), tmp,
685 quiet);
687 else if (code->expr1->ts.type == BT_INTEGER)
689 gfc_conv_expr (&se, code->expr1);
690 tmp = build_call_expr_loc (input_location,
691 error_stop
692 ? (flag_coarray == GFC_FCOARRAY_LIB
693 ? gfor_fndecl_caf_error_stop
694 : gfor_fndecl_error_stop_numeric)
695 : (flag_coarray == GFC_FCOARRAY_LIB
696 ? gfor_fndecl_caf_stop_numeric
697 : gfor_fndecl_stop_numeric), 2,
698 fold_convert (integer_type_node, se.expr),
699 quiet);
701 else
703 gfc_conv_expr_reference (&se, code->expr1);
704 tmp = build_call_expr_loc (input_location,
705 error_stop
706 ? (flag_coarray == GFC_FCOARRAY_LIB
707 ? gfor_fndecl_caf_error_stop_str
708 : gfor_fndecl_error_stop_string)
709 : (flag_coarray == GFC_FCOARRAY_LIB
710 ? gfor_fndecl_caf_stop_str
711 : gfor_fndecl_stop_string),
712 3, se.expr, fold_convert (size_type_node,
713 se.string_length),
714 quiet);
717 gfc_add_expr_to_block (&se.pre, tmp);
719 gfc_add_block_to_block (&se.pre, &se.post);
721 return gfc_finish_block (&se.pre);
724 /* Translate the FAIL IMAGE statement. */
726 tree
727 gfc_trans_fail_image (gfc_code *code ATTRIBUTE_UNUSED)
729 if (flag_coarray == GFC_FCOARRAY_LIB)
730 return build_call_expr_loc (input_location,
731 gfor_fndecl_caf_fail_image, 0);
732 else
734 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
735 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
736 tree tmp = gfc_get_symbol_decl (exsym);
737 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
741 /* Translate the FORM TEAM statement. */
743 tree
744 gfc_trans_form_team (gfc_code *code)
746 if (flag_coarray == GFC_FCOARRAY_LIB)
748 gfc_se se;
749 gfc_se argse1, argse2;
750 tree team_id, team_type, tmp;
752 gfc_init_se (&se, NULL);
753 gfc_init_se (&argse1, NULL);
754 gfc_init_se (&argse2, NULL);
755 gfc_start_block (&se.pre);
757 gfc_conv_expr_val (&argse1, code->expr1);
758 gfc_conv_expr_val (&argse2, code->expr2);
759 team_id = fold_convert (integer_type_node, argse1.expr);
760 team_type = gfc_build_addr_expr (ppvoid_type_node, argse2.expr);
762 gfc_add_block_to_block (&se.pre, &argse1.pre);
763 gfc_add_block_to_block (&se.pre, &argse2.pre);
764 tmp = build_call_expr_loc (input_location,
765 gfor_fndecl_caf_form_team, 3,
766 team_id, team_type,
767 integer_zero_node);
768 gfc_add_expr_to_block (&se.pre, tmp);
769 gfc_add_block_to_block (&se.pre, &argse1.post);
770 gfc_add_block_to_block (&se.pre, &argse2.post);
771 return gfc_finish_block (&se.pre);
773 else
775 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
776 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
777 tree tmp = gfc_get_symbol_decl (exsym);
778 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
782 /* Translate the CHANGE TEAM statement. */
784 tree
785 gfc_trans_change_team (gfc_code *code)
787 if (flag_coarray == GFC_FCOARRAY_LIB)
789 gfc_se argse;
790 tree team_type, tmp;
792 gfc_init_se (&argse, NULL);
793 gfc_conv_expr_val (&argse, code->expr1);
794 team_type = gfc_build_addr_expr (ppvoid_type_node, argse.expr);
796 tmp = build_call_expr_loc (input_location,
797 gfor_fndecl_caf_change_team, 2, team_type,
798 integer_zero_node);
799 gfc_add_expr_to_block (&argse.pre, tmp);
800 gfc_add_block_to_block (&argse.pre, &argse.post);
801 return gfc_finish_block (&argse.pre);
803 else
805 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
806 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
807 tree tmp = gfc_get_symbol_decl (exsym);
808 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
812 /* Translate the END TEAM statement. */
814 tree
815 gfc_trans_end_team (gfc_code *code ATTRIBUTE_UNUSED)
817 if (flag_coarray == GFC_FCOARRAY_LIB)
819 return build_call_expr_loc (input_location,
820 gfor_fndecl_caf_end_team, 1,
821 build_int_cst (pchar_type_node, 0));
823 else
825 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
826 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
827 tree tmp = gfc_get_symbol_decl (exsym);
828 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
832 /* Translate the SYNC TEAM statement. */
834 tree
835 gfc_trans_sync_team (gfc_code *code)
837 if (flag_coarray == GFC_FCOARRAY_LIB)
839 gfc_se argse;
840 tree team_type, tmp;
842 gfc_init_se (&argse, NULL);
843 gfc_conv_expr_val (&argse, code->expr1);
844 team_type = gfc_build_addr_expr (ppvoid_type_node, argse.expr);
846 tmp = build_call_expr_loc (input_location,
847 gfor_fndecl_caf_sync_team, 2,
848 team_type,
849 integer_zero_node);
850 gfc_add_expr_to_block (&argse.pre, tmp);
851 gfc_add_block_to_block (&argse.pre, &argse.post);
852 return gfc_finish_block (&argse.pre);
854 else
856 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
857 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
858 tree tmp = gfc_get_symbol_decl (exsym);
859 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
863 tree
864 gfc_trans_lock_unlock (gfc_code *code, gfc_exec_op op)
866 gfc_se se, argse;
867 tree stat = NULL_TREE, stat2 = NULL_TREE;
868 tree lock_acquired = NULL_TREE, lock_acquired2 = NULL_TREE;
870 /* Short cut: For single images without STAT= or LOCK_ACQUIRED
871 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
872 if (!code->expr2 && !code->expr4 && flag_coarray != GFC_FCOARRAY_LIB)
873 return NULL_TREE;
875 if (code->expr2)
877 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
878 gfc_init_se (&argse, NULL);
879 gfc_conv_expr_val (&argse, code->expr2);
880 stat = argse.expr;
882 else if (flag_coarray == GFC_FCOARRAY_LIB)
883 stat = null_pointer_node;
885 if (code->expr4)
887 gcc_assert (code->expr4->expr_type == EXPR_VARIABLE);
888 gfc_init_se (&argse, NULL);
889 gfc_conv_expr_val (&argse, code->expr4);
890 lock_acquired = argse.expr;
892 else if (flag_coarray == GFC_FCOARRAY_LIB)
893 lock_acquired = null_pointer_node;
895 gfc_start_block (&se.pre);
896 if (flag_coarray == GFC_FCOARRAY_LIB)
898 tree tmp, token, image_index, errmsg, errmsg_len;
899 tree index = build_zero_cst (gfc_array_index_type);
900 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
902 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
903 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
904 != INTMOD_ISO_FORTRAN_ENV
905 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
906 != ISOFORTRAN_LOCK_TYPE)
908 gfc_error ("Sorry, the lock component of derived type at %L is not "
909 "yet supported", &code->expr1->where);
910 return NULL_TREE;
913 gfc_get_caf_token_offset (&se, &token, NULL, caf_decl, NULL_TREE,
914 code->expr1);
916 if (gfc_is_coindexed (code->expr1))
917 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
918 else
919 image_index = integer_zero_node;
921 /* For arrays, obtain the array index. */
922 if (gfc_expr_attr (code->expr1).dimension)
924 tree desc, tmp, extent, lbound, ubound;
925 gfc_array_ref *ar, ar2;
926 int i;
928 /* TODO: Extend this, once DT components are supported. */
929 ar = &code->expr1->ref->u.ar;
930 ar2 = *ar;
931 memset (ar, '\0', sizeof (*ar));
932 ar->as = ar2.as;
933 ar->type = AR_FULL;
935 gfc_init_se (&argse, NULL);
936 argse.descriptor_only = 1;
937 gfc_conv_expr_descriptor (&argse, code->expr1);
938 gfc_add_block_to_block (&se.pre, &argse.pre);
939 desc = argse.expr;
940 *ar = ar2;
942 extent = build_one_cst (gfc_array_index_type);
943 for (i = 0; i < ar->dimen; i++)
945 gfc_init_se (&argse, NULL);
946 gfc_conv_expr_type (&argse, ar->start[i], gfc_array_index_type);
947 gfc_add_block_to_block (&argse.pre, &argse.pre);
948 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
949 tmp = fold_build2_loc (input_location, MINUS_EXPR,
950 TREE_TYPE (lbound), argse.expr, lbound);
951 tmp = fold_build2_loc (input_location, MULT_EXPR,
952 TREE_TYPE (tmp), extent, tmp);
953 index = fold_build2_loc (input_location, PLUS_EXPR,
954 TREE_TYPE (tmp), index, tmp);
955 if (i < ar->dimen - 1)
957 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
958 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
959 extent = fold_build2_loc (input_location, MULT_EXPR,
960 TREE_TYPE (tmp), extent, tmp);
965 /* errmsg. */
966 if (code->expr3)
968 gfc_init_se (&argse, NULL);
969 argse.want_pointer = 1;
970 gfc_conv_expr (&argse, code->expr3);
971 gfc_add_block_to_block (&se.pre, &argse.pre);
972 errmsg = argse.expr;
973 errmsg_len = fold_convert (size_type_node, argse.string_length);
975 else
977 errmsg = null_pointer_node;
978 errmsg_len = build_zero_cst (size_type_node);
981 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
983 stat2 = stat;
984 stat = gfc_create_var (integer_type_node, "stat");
987 if (lock_acquired != null_pointer_node
988 && TREE_TYPE (lock_acquired) != integer_type_node)
990 lock_acquired2 = lock_acquired;
991 lock_acquired = gfc_create_var (integer_type_node, "acquired");
994 index = fold_convert (size_type_node, index);
995 if (op == EXEC_LOCK)
996 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
997 token, index, image_index,
998 lock_acquired != null_pointer_node
999 ? gfc_build_addr_expr (NULL, lock_acquired)
1000 : lock_acquired,
1001 stat != null_pointer_node
1002 ? gfc_build_addr_expr (NULL, stat) : stat,
1003 errmsg, errmsg_len);
1004 else
1005 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
1006 token, index, image_index,
1007 stat != null_pointer_node
1008 ? gfc_build_addr_expr (NULL, stat) : stat,
1009 errmsg, errmsg_len);
1010 gfc_add_expr_to_block (&se.pre, tmp);
1012 /* It guarantees memory consistency within the same segment */
1013 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1014 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1015 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1016 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1017 ASM_VOLATILE_P (tmp) = 1;
1019 gfc_add_expr_to_block (&se.pre, tmp);
1021 if (stat2 != NULL_TREE)
1022 gfc_add_modify (&se.pre, stat2,
1023 fold_convert (TREE_TYPE (stat2), stat));
1025 if (lock_acquired2 != NULL_TREE)
1026 gfc_add_modify (&se.pre, lock_acquired2,
1027 fold_convert (TREE_TYPE (lock_acquired2),
1028 lock_acquired));
1030 return gfc_finish_block (&se.pre);
1033 if (stat != NULL_TREE)
1034 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
1036 if (lock_acquired != NULL_TREE)
1037 gfc_add_modify (&se.pre, lock_acquired,
1038 fold_convert (TREE_TYPE (lock_acquired),
1039 boolean_true_node));
1041 return gfc_finish_block (&se.pre);
1044 tree
1045 gfc_trans_event_post_wait (gfc_code *code, gfc_exec_op op)
1047 gfc_se se, argse;
1048 tree stat = NULL_TREE, stat2 = NULL_TREE;
1049 tree until_count = NULL_TREE;
1051 if (code->expr2)
1053 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
1054 gfc_init_se (&argse, NULL);
1055 gfc_conv_expr_val (&argse, code->expr2);
1056 stat = argse.expr;
1058 else if (flag_coarray == GFC_FCOARRAY_LIB)
1059 stat = null_pointer_node;
1061 if (code->expr4)
1063 gfc_init_se (&argse, NULL);
1064 gfc_conv_expr_val (&argse, code->expr4);
1065 until_count = fold_convert (integer_type_node, argse.expr);
1067 else
1068 until_count = integer_one_node;
1070 if (flag_coarray != GFC_FCOARRAY_LIB)
1072 gfc_start_block (&se.pre);
1073 gfc_init_se (&argse, NULL);
1074 gfc_conv_expr_val (&argse, code->expr1);
1076 if (op == EXEC_EVENT_POST)
1077 gfc_add_modify (&se.pre, argse.expr,
1078 fold_build2_loc (input_location, PLUS_EXPR,
1079 TREE_TYPE (argse.expr), argse.expr,
1080 build_int_cst (TREE_TYPE (argse.expr), 1)));
1081 else
1082 gfc_add_modify (&se.pre, argse.expr,
1083 fold_build2_loc (input_location, MINUS_EXPR,
1084 TREE_TYPE (argse.expr), argse.expr,
1085 fold_convert (TREE_TYPE (argse.expr),
1086 until_count)));
1087 if (stat != NULL_TREE)
1088 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
1090 return gfc_finish_block (&se.pre);
1093 gfc_start_block (&se.pre);
1094 tree tmp, token, image_index, errmsg, errmsg_len;
1095 tree index = build_zero_cst (gfc_array_index_type);
1096 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
1098 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
1099 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
1100 != INTMOD_ISO_FORTRAN_ENV
1101 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
1102 != ISOFORTRAN_EVENT_TYPE)
1104 gfc_error ("Sorry, the event component of derived type at %L is not "
1105 "yet supported", &code->expr1->where);
1106 return NULL_TREE;
1109 gfc_init_se (&argse, NULL);
1110 gfc_get_caf_token_offset (&argse, &token, NULL, caf_decl, NULL_TREE,
1111 code->expr1);
1112 gfc_add_block_to_block (&se.pre, &argse.pre);
1114 if (gfc_is_coindexed (code->expr1))
1115 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
1116 else
1117 image_index = integer_zero_node;
1119 /* For arrays, obtain the array index. */
1120 if (gfc_expr_attr (code->expr1).dimension)
1122 tree desc, tmp, extent, lbound, ubound;
1123 gfc_array_ref *ar, ar2;
1124 int i;
1126 /* TODO: Extend this, once DT components are supported. */
1127 ar = &code->expr1->ref->u.ar;
1128 ar2 = *ar;
1129 memset (ar, '\0', sizeof (*ar));
1130 ar->as = ar2.as;
1131 ar->type = AR_FULL;
1133 gfc_init_se (&argse, NULL);
1134 argse.descriptor_only = 1;
1135 gfc_conv_expr_descriptor (&argse, code->expr1);
1136 gfc_add_block_to_block (&se.pre, &argse.pre);
1137 desc = argse.expr;
1138 *ar = ar2;
1140 extent = build_one_cst (gfc_array_index_type);
1141 for (i = 0; i < ar->dimen; i++)
1143 gfc_init_se (&argse, NULL);
1144 gfc_conv_expr_type (&argse, ar->start[i], gfc_array_index_type);
1145 gfc_add_block_to_block (&argse.pre, &argse.pre);
1146 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
1147 tmp = fold_build2_loc (input_location, MINUS_EXPR,
1148 TREE_TYPE (lbound), argse.expr, lbound);
1149 tmp = fold_build2_loc (input_location, MULT_EXPR,
1150 TREE_TYPE (tmp), extent, tmp);
1151 index = fold_build2_loc (input_location, PLUS_EXPR,
1152 TREE_TYPE (tmp), index, tmp);
1153 if (i < ar->dimen - 1)
1155 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
1156 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
1157 extent = fold_build2_loc (input_location, MULT_EXPR,
1158 TREE_TYPE (tmp), extent, tmp);
1163 /* errmsg. */
1164 if (code->expr3)
1166 gfc_init_se (&argse, NULL);
1167 argse.want_pointer = 1;
1168 gfc_conv_expr (&argse, code->expr3);
1169 gfc_add_block_to_block (&se.pre, &argse.pre);
1170 errmsg = argse.expr;
1171 errmsg_len = fold_convert (size_type_node, argse.string_length);
1173 else
1175 errmsg = null_pointer_node;
1176 errmsg_len = build_zero_cst (size_type_node);
1179 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
1181 stat2 = stat;
1182 stat = gfc_create_var (integer_type_node, "stat");
1185 index = fold_convert (size_type_node, index);
1186 if (op == EXEC_EVENT_POST)
1187 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_post, 6,
1188 token, index, image_index,
1189 stat != null_pointer_node
1190 ? gfc_build_addr_expr (NULL, stat) : stat,
1191 errmsg, errmsg_len);
1192 else
1193 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_wait, 6,
1194 token, index, until_count,
1195 stat != null_pointer_node
1196 ? gfc_build_addr_expr (NULL, stat) : stat,
1197 errmsg, errmsg_len);
1198 gfc_add_expr_to_block (&se.pre, tmp);
1200 /* It guarantees memory consistency within the same segment */
1201 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1202 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1203 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1204 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1205 ASM_VOLATILE_P (tmp) = 1;
1206 gfc_add_expr_to_block (&se.pre, tmp);
1208 if (stat2 != NULL_TREE)
1209 gfc_add_modify (&se.pre, stat2, fold_convert (TREE_TYPE (stat2), stat));
1211 return gfc_finish_block (&se.pre);
1214 tree
1215 gfc_trans_sync (gfc_code *code, gfc_exec_op type)
1217 gfc_se se, argse;
1218 tree tmp;
1219 tree images = NULL_TREE, stat = NULL_TREE,
1220 errmsg = NULL_TREE, errmsglen = NULL_TREE;
1222 /* Short cut: For single images without bound checking or without STAT=,
1223 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
1224 if (!code->expr2 && !(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1225 && flag_coarray != GFC_FCOARRAY_LIB)
1226 return NULL_TREE;
1228 gfc_init_se (&se, NULL);
1229 gfc_start_block (&se.pre);
1231 if (code->expr1 && code->expr1->rank == 0)
1233 gfc_init_se (&argse, NULL);
1234 gfc_conv_expr_val (&argse, code->expr1);
1235 images = argse.expr;
1238 if (code->expr2)
1240 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE
1241 || code->expr2->expr_type == EXPR_FUNCTION);
1242 gfc_init_se (&argse, NULL);
1243 gfc_conv_expr_val (&argse, code->expr2);
1244 stat = argse.expr;
1246 else
1247 stat = null_pointer_node;
1249 if (code->expr3 && flag_coarray == GFC_FCOARRAY_LIB)
1251 gcc_assert (code->expr3->expr_type == EXPR_VARIABLE
1252 || code->expr3->expr_type == EXPR_FUNCTION);
1253 gfc_init_se (&argse, NULL);
1254 argse.want_pointer = 1;
1255 gfc_conv_expr (&argse, code->expr3);
1256 gfc_conv_string_parameter (&argse);
1257 errmsg = gfc_build_addr_expr (NULL, argse.expr);
1258 errmsglen = fold_convert (size_type_node, argse.string_length);
1260 else if (flag_coarray == GFC_FCOARRAY_LIB)
1262 errmsg = null_pointer_node;
1263 errmsglen = build_int_cst (size_type_node, 0);
1266 /* Check SYNC IMAGES(imageset) for valid image index.
1267 FIXME: Add a check for image-set arrays. */
1268 if (code->expr1 && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1269 && code->expr1->rank == 0)
1271 tree images2 = fold_convert (integer_type_node, images);
1272 tree cond;
1273 if (flag_coarray != GFC_FCOARRAY_LIB)
1274 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1275 images, build_int_cst (TREE_TYPE (images), 1));
1276 else
1278 tree cond2;
1279 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images,
1280 2, integer_zero_node,
1281 build_int_cst (integer_type_node, -1));
1282 cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
1283 images2, tmp);
1284 cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
1285 images,
1286 build_int_cst (TREE_TYPE (images), 1));
1287 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1288 logical_type_node, cond, cond2);
1290 gfc_trans_runtime_check (true, false, cond, &se.pre,
1291 &code->expr1->where, "Invalid image number "
1292 "%d in SYNC IMAGES", images2);
1295 /* Per F2008, 8.5.1, a SYNC MEMORY is implied by calling the
1296 image control statements SYNC IMAGES and SYNC ALL. */
1297 if (flag_coarray == GFC_FCOARRAY_LIB)
1299 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1300 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1301 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1302 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1303 ASM_VOLATILE_P (tmp) = 1;
1304 gfc_add_expr_to_block (&se.pre, tmp);
1307 if (flag_coarray != GFC_FCOARRAY_LIB)
1309 /* Set STAT to zero. */
1310 if (code->expr2)
1311 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
1313 else if (type == EXEC_SYNC_ALL || type == EXEC_SYNC_MEMORY)
1315 /* SYNC ALL => stat == null_pointer_node
1316 SYNC ALL(stat=s) => stat has an integer type
1318 If "stat" has the wrong integer type, use a temp variable of
1319 the right type and later cast the result back into "stat". */
1320 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1322 if (TREE_TYPE (stat) == integer_type_node)
1323 stat = gfc_build_addr_expr (NULL, stat);
1325 if(type == EXEC_SYNC_MEMORY)
1326 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_memory,
1327 3, stat, errmsg, errmsglen);
1328 else
1329 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
1330 3, stat, errmsg, errmsglen);
1332 gfc_add_expr_to_block (&se.pre, tmp);
1334 else
1336 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1338 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
1339 3, gfc_build_addr_expr (NULL, tmp_stat),
1340 errmsg, errmsglen);
1341 gfc_add_expr_to_block (&se.pre, tmp);
1343 gfc_add_modify (&se.pre, stat,
1344 fold_convert (TREE_TYPE (stat), tmp_stat));
1347 else
1349 tree len;
1351 gcc_assert (type == EXEC_SYNC_IMAGES);
1353 if (!code->expr1)
1355 len = build_int_cst (integer_type_node, -1);
1356 images = null_pointer_node;
1358 else if (code->expr1->rank == 0)
1360 len = integer_one_node;
1361 images = gfc_build_addr_expr (NULL_TREE, images);
1363 else
1365 /* FIXME. */
1366 if (code->expr1->ts.kind != gfc_c_int_kind)
1367 gfc_fatal_error ("Sorry, only support for integer kind %d "
1368 "implemented for image-set at %L",
1369 gfc_c_int_kind, &code->expr1->where);
1371 gfc_conv_array_parameter (&se, code->expr1, true, NULL, NULL, &len);
1372 images = se.expr;
1374 tmp = gfc_typenode_for_spec (&code->expr1->ts);
1375 if (GFC_ARRAY_TYPE_P (tmp) || GFC_DESCRIPTOR_TYPE_P (tmp))
1376 tmp = gfc_get_element_type (tmp);
1378 len = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
1379 TREE_TYPE (len), len,
1380 fold_convert (TREE_TYPE (len),
1381 TYPE_SIZE_UNIT (tmp)));
1382 len = fold_convert (integer_type_node, len);
1385 /* SYNC IMAGES(imgs) => stat == null_pointer_node
1386 SYNC IMAGES(imgs,stat=s) => stat has an integer type
1388 If "stat" has the wrong integer type, use a temp variable of
1389 the right type and later cast the result back into "stat". */
1390 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1392 if (TREE_TYPE (stat) == integer_type_node)
1393 stat = gfc_build_addr_expr (NULL, stat);
1395 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1396 5, fold_convert (integer_type_node, len),
1397 images, stat, errmsg, errmsglen);
1398 gfc_add_expr_to_block (&se.pre, tmp);
1400 else
1402 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1404 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1405 5, fold_convert (integer_type_node, len),
1406 images, gfc_build_addr_expr (NULL, tmp_stat),
1407 errmsg, errmsglen);
1408 gfc_add_expr_to_block (&se.pre, tmp);
1410 gfc_add_modify (&se.pre, stat,
1411 fold_convert (TREE_TYPE (stat), tmp_stat));
1415 return gfc_finish_block (&se.pre);
1419 /* Generate GENERIC for the IF construct. This function also deals with
1420 the simple IF statement, because the front end translates the IF
1421 statement into an IF construct.
1423 We translate:
1425 IF (cond) THEN
1426 then_clause
1427 ELSEIF (cond2)
1428 elseif_clause
1429 ELSE
1430 else_clause
1431 ENDIF
1433 into:
1435 pre_cond_s;
1436 if (cond_s)
1438 then_clause;
1440 else
1442 pre_cond_s
1443 if (cond_s)
1445 elseif_clause
1447 else
1449 else_clause;
1453 where COND_S is the simplified version of the predicate. PRE_COND_S
1454 are the pre side-effects produced by the translation of the
1455 conditional.
1456 We need to build the chain recursively otherwise we run into
1457 problems with folding incomplete statements. */
1459 static tree
1460 gfc_trans_if_1 (gfc_code * code)
1462 gfc_se if_se;
1463 tree stmt, elsestmt;
1464 locus saved_loc;
1465 location_t loc;
1467 /* Check for an unconditional ELSE clause. */
1468 if (!code->expr1)
1469 return gfc_trans_code (code->next);
1471 /* Initialize a statement builder for each block. Puts in NULL_TREEs. */
1472 gfc_init_se (&if_se, NULL);
1473 gfc_start_block (&if_se.pre);
1475 /* Calculate the IF condition expression. */
1476 if (code->expr1->where.lb)
1478 gfc_save_backend_locus (&saved_loc);
1479 gfc_set_backend_locus (&code->expr1->where);
1482 gfc_conv_expr_val (&if_se, code->expr1);
1484 if (code->expr1->where.lb)
1485 gfc_restore_backend_locus (&saved_loc);
1487 /* Translate the THEN clause. */
1488 stmt = gfc_trans_code (code->next);
1490 /* Translate the ELSE clause. */
1491 if (code->block)
1492 elsestmt = gfc_trans_if_1 (code->block);
1493 else
1494 elsestmt = build_empty_stmt (input_location);
1496 /* Build the condition expression and add it to the condition block. */
1497 loc = code->expr1->where.lb ? gfc_get_location (&code->expr1->where)
1498 : input_location;
1499 stmt = fold_build3_loc (loc, COND_EXPR, void_type_node, if_se.expr, stmt,
1500 elsestmt);
1502 gfc_add_expr_to_block (&if_se.pre, stmt);
1504 /* Finish off this statement. */
1505 return gfc_finish_block (&if_se.pre);
1508 tree
1509 gfc_trans_if (gfc_code * code)
1511 stmtblock_t body;
1512 tree exit_label;
1514 /* Create exit label so it is available for trans'ing the body code. */
1515 exit_label = gfc_build_label_decl (NULL_TREE);
1516 code->exit_label = exit_label;
1518 /* Translate the actual code in code->block. */
1519 gfc_init_block (&body);
1520 gfc_add_expr_to_block (&body, gfc_trans_if_1 (code->block));
1522 /* Add exit label. */
1523 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
1525 return gfc_finish_block (&body);
1529 /* Translate an arithmetic IF expression.
1531 IF (cond) label1, label2, label3 translates to
1533 if (cond <= 0)
1535 if (cond < 0)
1536 goto label1;
1537 else // cond == 0
1538 goto label2;
1540 else // cond > 0
1541 goto label3;
1543 An optimized version can be generated in case of equal labels.
1544 E.g., if label1 is equal to label2, we can translate it to
1546 if (cond <= 0)
1547 goto label1;
1548 else
1549 goto label3;
1552 tree
1553 gfc_trans_arithmetic_if (gfc_code * code)
1555 gfc_se se;
1556 tree tmp;
1557 tree branch1;
1558 tree branch2;
1559 tree zero;
1561 /* Start a new block. */
1562 gfc_init_se (&se, NULL);
1563 gfc_start_block (&se.pre);
1565 /* Pre-evaluate COND. */
1566 gfc_conv_expr_val (&se, code->expr1);
1567 se.expr = gfc_evaluate_now (se.expr, &se.pre);
1569 /* Build something to compare with. */
1570 zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
1572 if (code->label1->value != code->label2->value)
1574 /* If (cond < 0) take branch1 else take branch2.
1575 First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases. */
1576 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1577 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
1579 if (code->label1->value != code->label3->value)
1580 tmp = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
1581 se.expr, zero);
1582 else
1583 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1584 se.expr, zero);
1586 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1587 tmp, branch1, branch2);
1589 else
1590 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1592 if (code->label1->value != code->label3->value
1593 && code->label2->value != code->label3->value)
1595 /* if (cond <= 0) take branch1 else take branch2. */
1596 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label3));
1597 tmp = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
1598 se.expr, zero);
1599 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1600 tmp, branch1, branch2);
1603 /* Append the COND_EXPR to the evaluation of COND, and return. */
1604 gfc_add_expr_to_block (&se.pre, branch1);
1605 return gfc_finish_block (&se.pre);
1609 /* Translate a CRITICAL block. */
1610 tree
1611 gfc_trans_critical (gfc_code *code)
1613 stmtblock_t block;
1614 tree tmp, token = NULL_TREE;
1616 gfc_start_block (&block);
1618 if (flag_coarray == GFC_FCOARRAY_LIB)
1620 tree zero_size = build_zero_cst (size_type_node);
1621 token = gfc_get_symbol_decl (code->resolved_sym);
1622 token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (token));
1623 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
1624 token, zero_size, integer_one_node,
1625 null_pointer_node, null_pointer_node,
1626 null_pointer_node, zero_size);
1627 gfc_add_expr_to_block (&block, tmp);
1629 /* It guarantees memory consistency within the same segment */
1630 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1631 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1632 gfc_build_string_const (1, ""),
1633 NULL_TREE, NULL_TREE,
1634 tree_cons (NULL_TREE, tmp, NULL_TREE),
1635 NULL_TREE);
1636 ASM_VOLATILE_P (tmp) = 1;
1638 gfc_add_expr_to_block (&block, tmp);
1641 tmp = gfc_trans_code (code->block->next);
1642 gfc_add_expr_to_block (&block, tmp);
1644 if (flag_coarray == GFC_FCOARRAY_LIB)
1646 tree zero_size = build_zero_cst (size_type_node);
1647 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
1648 token, zero_size, integer_one_node,
1649 null_pointer_node, null_pointer_node,
1650 zero_size);
1651 gfc_add_expr_to_block (&block, tmp);
1653 /* It guarantees memory consistency within the same segment */
1654 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1655 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1656 gfc_build_string_const (1, ""),
1657 NULL_TREE, NULL_TREE,
1658 tree_cons (NULL_TREE, tmp, NULL_TREE),
1659 NULL_TREE);
1660 ASM_VOLATILE_P (tmp) = 1;
1662 gfc_add_expr_to_block (&block, tmp);
1665 return gfc_finish_block (&block);
1669 /* Return true, when the class has a _len component. */
1671 static bool
1672 class_has_len_component (gfc_symbol *sym)
1674 gfc_component *comp = sym->ts.u.derived->components;
1675 while (comp)
1677 if (strcmp (comp->name, "_len") == 0)
1678 return true;
1679 comp = comp->next;
1681 return false;
1685 static void
1686 copy_descriptor (stmtblock_t *block, tree dst, tree src, int rank)
1688 int n;
1689 tree dim;
1690 tree tmp;
1691 tree tmp2;
1692 tree size;
1693 tree offset;
1695 offset = gfc_index_zero_node;
1697 /* Use memcpy to copy the descriptor. The size is the minimum of
1698 the sizes of 'src' and 'dst'. This avoids a non-trivial conversion. */
1699 tmp = TYPE_SIZE_UNIT (TREE_TYPE (src));
1700 tmp2 = TYPE_SIZE_UNIT (TREE_TYPE (dst));
1701 size = fold_build2_loc (input_location, MIN_EXPR,
1702 TREE_TYPE (tmp), tmp, tmp2);
1703 tmp = builtin_decl_explicit (BUILT_IN_MEMCPY);
1704 tmp = build_call_expr_loc (input_location, tmp, 3,
1705 gfc_build_addr_expr (NULL_TREE, dst),
1706 gfc_build_addr_expr (NULL_TREE, src),
1707 fold_convert (size_type_node, size));
1708 gfc_add_expr_to_block (block, tmp);
1710 /* Set the offset correctly. */
1711 for (n = 0; n < rank; n++)
1713 dim = gfc_rank_cst[n];
1714 tmp = gfc_conv_descriptor_lbound_get (src, dim);
1715 tmp2 = gfc_conv_descriptor_stride_get (src, dim);
1716 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
1717 tmp, tmp2);
1718 offset = fold_build2_loc (input_location, MINUS_EXPR,
1719 TREE_TYPE (offset), offset, tmp);
1720 offset = gfc_evaluate_now (offset, block);
1723 gfc_conv_descriptor_offset_set (block, dst, offset);
1727 /* Do proper initialization for ASSOCIATE names. */
1729 static void
1730 trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
1732 gfc_expr *e;
1733 tree tmp;
1734 bool class_target;
1735 bool unlimited;
1736 tree desc;
1737 tree offset;
1738 tree dim;
1739 int n;
1740 tree charlen;
1741 bool need_len_assign;
1742 bool whole_array = true;
1743 gfc_ref *ref;
1744 gfc_symbol *sym2;
1746 gcc_assert (sym->assoc);
1747 e = sym->assoc->target;
1749 class_target = (e->expr_type == EXPR_VARIABLE)
1750 && e->ts.type == BT_CLASS
1751 && (gfc_is_class_scalar_expr (e)
1752 || gfc_is_class_array_ref (e, NULL));
1754 unlimited = UNLIMITED_POLY (e);
1756 for (ref = e->ref; ref; ref = ref->next)
1757 if (ref->type == REF_ARRAY
1758 && ref->u.ar.type == AR_FULL
1759 && ref->next)
1761 whole_array = false;
1762 break;
1765 /* Assignments to the string length need to be generated, when
1766 ( sym is a char array or
1767 sym has a _len component)
1768 and the associated expression is unlimited polymorphic, which is
1769 not (yet) correctly in 'unlimited', because for an already associated
1770 BT_DERIVED the u-poly flag is not set, i.e.,
1771 __tmp_CHARACTER_0_1 => w => arg
1772 ^ generated temp ^ from code, the w does not have the u-poly
1773 flag set, where UNLIMITED_POLY(e) expects it. */
1774 need_len_assign = ((unlimited || (e->ts.type == BT_DERIVED
1775 && e->ts.u.derived->attr.unlimited_polymorphic))
1776 && (sym->ts.type == BT_CHARACTER
1777 || ((sym->ts.type == BT_CLASS || sym->ts.type == BT_DERIVED)
1778 && class_has_len_component (sym)))
1779 && !sym->attr.select_rank_temporary);
1781 /* Do a `pointer assignment' with updated descriptor (or assign descriptor
1782 to array temporary) for arrays with either unknown shape or if associating
1783 to a variable. Select rank temporaries need somewhat different treatment
1784 to other associate names and case temporaries. This because the selector
1785 is assumed rank and so the offset in particular has to be changed. Also,
1786 the case temporaries carry both allocatable and target attributes if
1787 present in the selector. This means that an allocatation or change of
1788 association can occur and so has to be dealt with. */
1789 if (sym->attr.select_rank_temporary)
1791 gfc_se se;
1792 tree class_decl = NULL_TREE;
1793 int rank = 0;
1794 bool class_ptr;
1796 sym2 = e->symtree->n.sym;
1797 gfc_init_se (&se, NULL);
1798 if (e->ts.type == BT_CLASS)
1800 /* Go straight to the class data. */
1801 if (sym2->attr.dummy && !sym2->attr.optional)
1803 class_decl = sym2->backend_decl;
1804 if (DECL_LANG_SPECIFIC (class_decl)
1805 && GFC_DECL_SAVED_DESCRIPTOR (class_decl))
1806 class_decl = GFC_DECL_SAVED_DESCRIPTOR (class_decl);
1807 if (POINTER_TYPE_P (TREE_TYPE (class_decl)))
1808 class_decl = build_fold_indirect_ref_loc (input_location,
1809 class_decl);
1810 gcc_assert (GFC_CLASS_TYPE_P (TREE_TYPE (class_decl)));
1811 se.expr = gfc_class_data_get (class_decl);
1813 else
1815 class_decl = sym2->backend_decl;
1816 gfc_conv_expr_descriptor (&se, e);
1817 if (POINTER_TYPE_P (TREE_TYPE (se.expr)))
1818 se.expr = build_fold_indirect_ref_loc (input_location,
1819 se.expr);
1822 if (CLASS_DATA (sym)->as && CLASS_DATA (sym)->as->rank > 0)
1823 rank = CLASS_DATA (sym)->as->rank;
1825 else
1827 gfc_conv_expr_descriptor (&se, e);
1828 if (sym->as && sym->as->rank > 0)
1829 rank = sym->as->rank;
1832 desc = sym->backend_decl;
1834 /* The SELECT TYPE mechanisms turn class temporaries into pointers, which
1835 point to the selector. */
1836 class_ptr = class_decl != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (desc));
1837 if (class_ptr)
1839 tmp = gfc_create_var (TREE_TYPE (TREE_TYPE (desc)), "class");
1840 tmp = gfc_build_addr_expr (NULL, tmp);
1841 gfc_add_modify (&se.pre, desc, tmp);
1843 tmp = gfc_class_vptr_get (class_decl);
1844 gfc_add_modify (&se.pre, gfc_class_vptr_get (desc), tmp);
1845 if (UNLIMITED_POLY (sym))
1846 gfc_add_modify (&se.pre, gfc_class_len_get (desc),
1847 gfc_class_len_get (class_decl));
1849 desc = gfc_class_data_get (desc);
1852 /* SELECT RANK temporaries can carry the allocatable and pointer
1853 attributes so the selector descriptor must be copied in and
1854 copied out. */
1855 if (rank > 0)
1856 copy_descriptor (&se.pre, desc, se.expr, rank);
1857 else
1859 tmp = gfc_conv_descriptor_data_get (se.expr);
1860 gfc_add_modify (&se.pre, desc,
1861 fold_convert (TREE_TYPE (desc), tmp));
1864 /* Deal with associate_name => selector. Class associate names are
1865 treated in the same way as in SELECT TYPE. */
1866 sym2 = sym->assoc->target->symtree->n.sym;
1867 if (sym2->assoc && sym->assoc->target && sym2->ts.type != BT_CLASS)
1869 sym2 = sym2->assoc->target->symtree->n.sym;
1870 se.expr = sym2->backend_decl;
1872 if (POINTER_TYPE_P (TREE_TYPE (se.expr)))
1873 se.expr = build_fold_indirect_ref_loc (input_location,
1874 se.expr);
1877 /* There could have been reallocation. Copy descriptor back to the
1878 selector and update the offset. */
1879 if (sym->attr.allocatable || sym->attr.pointer
1880 || (sym->ts.type == BT_CLASS
1881 && (CLASS_DATA (sym)->attr.allocatable
1882 || CLASS_DATA (sym)->attr.pointer)))
1884 if (rank > 0)
1885 copy_descriptor (&se.post, se.expr, desc, rank);
1886 else
1887 gfc_conv_descriptor_data_set (&se.post, se.expr, desc);
1889 /* The dynamic type could have changed too. */
1890 if (sym->ts.type == BT_CLASS)
1892 tmp = sym->backend_decl;
1893 if (class_ptr)
1894 tmp = build_fold_indirect_ref_loc (input_location, tmp);
1895 gfc_add_modify (&se.post, gfc_class_vptr_get (class_decl),
1896 gfc_class_vptr_get (tmp));
1897 if (UNLIMITED_POLY (sym))
1898 gfc_add_modify (&se.post, gfc_class_len_get (class_decl),
1899 gfc_class_len_get (tmp));
1903 tmp = gfc_finish_block (&se.post);
1905 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre), tmp);
1907 /* Now all the other kinds of associate variable. */
1908 else if (sym->attr.dimension && !class_target
1909 && (sym->as->type == AS_DEFERRED || sym->assoc->variable))
1911 gfc_se se;
1912 tree desc;
1913 bool cst_array_ctor;
1914 stmtblock_t init;
1915 gfc_init_block (&init);
1917 desc = sym->backend_decl;
1918 cst_array_ctor = e->expr_type == EXPR_ARRAY
1919 && gfc_constant_array_constructor_p (e->value.constructor)
1920 && e->ts.type != BT_CHARACTER;
1922 /* If association is to an expression, evaluate it and create temporary.
1923 Otherwise, get descriptor of target for pointer assignment. */
1924 gfc_init_se (&se, NULL);
1926 if (sym->assoc->variable || cst_array_ctor)
1928 se.direct_byref = 1;
1929 se.use_offset = 1;
1930 se.expr = desc;
1931 GFC_DECL_PTR_ARRAY_P (sym->backend_decl) = 1;
1934 gfc_conv_expr_descriptor (&se, e);
1936 if (sym->ts.type == BT_CHARACTER
1937 && !sym->attr.select_type_temporary
1938 && sym->ts.u.cl->backend_decl
1939 && VAR_P (sym->ts.u.cl->backend_decl)
1940 && se.string_length
1941 && se.string_length != sym->ts.u.cl->backend_decl)
1943 /* When the target is a variable, its length is already known. */
1944 tree len = fold_convert (TREE_TYPE (sym->ts.u.cl->backend_decl),
1945 se.string_length);
1946 if (e->expr_type == EXPR_VARIABLE)
1947 gfc_add_modify (&init, sym->ts.u.cl->backend_decl, len);
1948 else
1949 gfc_add_modify (&se.pre, sym->ts.u.cl->backend_decl, len);
1952 /* If we didn't already do the pointer assignment, set associate-name
1953 descriptor to the one generated for the temporary. */
1954 if ((!sym->assoc->variable && !cst_array_ctor)
1955 || !whole_array)
1957 int dim;
1959 if (whole_array)
1960 gfc_add_modify (&se.pre, desc, se.expr);
1962 /* The generated descriptor has lower bound zero (as array
1963 temporary), shift bounds so we get lower bounds of 1. */
1964 for (dim = 0; dim < e->rank; ++dim)
1965 gfc_conv_shift_descriptor_lbound (&se.pre, desc,
1966 dim, gfc_index_one_node);
1969 /* If this is a subreference array pointer associate name use the
1970 associate variable element size for the value of 'span'. */
1971 if (sym->attr.subref_array_pointer && !se.direct_byref)
1973 gcc_assert (e->expr_type == EXPR_VARIABLE);
1974 tmp = gfc_get_array_span (se.expr, e);
1976 gfc_conv_descriptor_span_set (&se.pre, desc, tmp);
1979 if (e->expr_type == EXPR_FUNCTION
1980 && sym->ts.type == BT_DERIVED
1981 && sym->ts.u.derived
1982 && sym->ts.u.derived->attr.pdt_type)
1984 tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived, se.expr,
1985 sym->as->rank);
1986 gfc_add_expr_to_block (&se.post, tmp);
1989 /* Done, register stuff as init / cleanup code. */
1990 gfc_add_block_to_block (&init, &se.pre);
1991 gfc_add_init_cleanup (block, gfc_finish_block (&init),
1992 gfc_finish_block (&se.post));
1995 /* Temporaries, arising from TYPE IS, just need the descriptor of class
1996 arrays to be assigned directly. */
1997 else if (class_target && sym->attr.dimension
1998 && (sym->ts.type == BT_DERIVED || unlimited))
2000 gfc_se se;
2002 gfc_init_se (&se, NULL);
2003 se.descriptor_only = 1;
2004 /* In a select type the (temporary) associate variable shall point to
2005 a standard fortran array (lower bound == 1), but conv_expr ()
2006 just maps to the input array in the class object, whose lbound may
2007 be arbitrary. conv_expr_descriptor solves this by inserting a
2008 temporary array descriptor. */
2009 gfc_conv_expr_descriptor (&se, e);
2011 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
2012 || GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)));
2013 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)));
2015 if (GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)))
2017 if (INDIRECT_REF_P (se.expr))
2018 tmp = TREE_OPERAND (se.expr, 0);
2019 else
2020 tmp = se.expr;
2022 gfc_add_modify (&se.pre, sym->backend_decl,
2023 gfc_class_data_get (GFC_DECL_SAVED_DESCRIPTOR (tmp)));
2025 else
2026 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
2028 if (unlimited)
2030 /* Recover the dtype, which has been overwritten by the
2031 assignment from an unlimited polymorphic object. */
2032 tmp = gfc_conv_descriptor_dtype (sym->backend_decl);
2033 gfc_add_modify (&se.pre, tmp,
2034 gfc_get_dtype (TREE_TYPE (sym->backend_decl)));
2037 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
2038 gfc_finish_block (&se.post));
2041 /* Do a scalar pointer assignment; this is for scalar variable targets. */
2042 else if (gfc_is_associate_pointer (sym))
2044 gfc_se se;
2046 gcc_assert (!sym->attr.dimension);
2048 gfc_init_se (&se, NULL);
2050 /* Class associate-names come this way because they are
2051 unconditionally associate pointers and the symbol is scalar. */
2052 if (sym->ts.type == BT_CLASS && e->expr_type == EXPR_FUNCTION)
2054 gfc_conv_expr (&se, e);
2055 se.expr = gfc_evaluate_now (se.expr, &se.pre);
2056 /* Finalize the expression and free if it is allocatable. */
2057 gfc_finalize_tree_expr (&se, NULL, gfc_expr_attr (e), e->rank);
2058 gfc_add_block_to_block (&se.post, &se.finalblock);
2059 need_len_assign = false;
2061 else if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.dimension)
2063 tree target_expr;
2064 /* For a class array we need a descriptor for the selector. */
2065 gfc_conv_expr_descriptor (&se, e);
2066 /* Needed to get/set the _len component below. */
2067 target_expr = se.expr;
2069 /* Obtain a temporary class container for the result. */
2070 gfc_conv_class_to_class (&se, e, sym->ts, false, true, false, false);
2071 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
2073 /* Set the offset. */
2074 desc = gfc_class_data_get (se.expr);
2075 offset = gfc_index_zero_node;
2076 for (n = 0; n < e->rank; n++)
2078 dim = gfc_rank_cst[n];
2079 tmp = fold_build2_loc (input_location, MULT_EXPR,
2080 gfc_array_index_type,
2081 gfc_conv_descriptor_stride_get (desc, dim),
2082 gfc_conv_descriptor_lbound_get (desc, dim));
2083 offset = fold_build2_loc (input_location, MINUS_EXPR,
2084 gfc_array_index_type,
2085 offset, tmp);
2087 if (need_len_assign)
2089 if (e->symtree
2090 && DECL_LANG_SPECIFIC (e->symtree->n.sym->backend_decl)
2091 && GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl)
2092 && TREE_CODE (target_expr) != COMPONENT_REF)
2093 /* Use the original class descriptor stored in the saved
2094 descriptor to get the target_expr. */
2095 target_expr =
2096 GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl);
2097 else
2098 /* Strip the _data component from the target_expr. */
2099 target_expr = TREE_OPERAND (target_expr, 0);
2100 /* Add a reference to the _len comp to the target expr. */
2101 tmp = gfc_class_len_get (target_expr);
2102 /* Get the component-ref for the temp structure's _len comp. */
2103 charlen = gfc_class_len_get (se.expr);
2104 /* Add the assign to the beginning of the block... */
2105 gfc_add_modify (&se.pre, charlen,
2106 fold_convert (TREE_TYPE (charlen), tmp));
2107 /* and the oposite way at the end of the block, to hand changes
2108 on the string length back. */
2109 gfc_add_modify (&se.post, tmp,
2110 fold_convert (TREE_TYPE (tmp), charlen));
2111 /* Length assignment done, prevent adding it again below. */
2112 need_len_assign = false;
2114 gfc_conv_descriptor_offset_set (&se.pre, desc, offset);
2116 else if (sym->ts.type == BT_CLASS && e->ts.type == BT_CLASS
2117 && CLASS_DATA (e)->attr.dimension)
2119 /* This is bound to be a class array element. */
2120 gfc_conv_expr_reference (&se, e);
2121 /* Get the _vptr component of the class object. */
2122 tmp = gfc_get_vptr_from_expr (se.expr);
2123 /* Obtain a temporary class container for the result. */
2124 gfc_conv_derived_to_class (&se, e, sym->ts, tmp, false, false);
2125 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
2126 need_len_assign = false;
2128 else
2130 /* For BT_CLASS and BT_DERIVED, this boils down to a pointer assign,
2131 which has the string length included. For CHARACTERS it is still
2132 needed and will be done at the end of this routine. */
2133 gfc_conv_expr (&se, e);
2134 need_len_assign = need_len_assign && sym->ts.type == BT_CHARACTER;
2137 if (sym->ts.type == BT_CHARACTER
2138 && !sym->attr.select_type_temporary
2139 && VAR_P (sym->ts.u.cl->backend_decl)
2140 && se.string_length != sym->ts.u.cl->backend_decl)
2142 gfc_add_modify (&se.pre, sym->ts.u.cl->backend_decl,
2143 fold_convert (TREE_TYPE (sym->ts.u.cl->backend_decl),
2144 se.string_length));
2145 if (e->expr_type == EXPR_FUNCTION)
2147 tmp = gfc_call_free (sym->backend_decl);
2148 gfc_add_expr_to_block (&se.post, tmp);
2152 if (sym->ts.type == BT_CHARACTER && e->ts.type == BT_CHARACTER
2153 && POINTER_TYPE_P (TREE_TYPE (se.expr)))
2155 /* These are pointer types already. */
2156 tmp = fold_convert (TREE_TYPE (sym->backend_decl), se.expr);
2158 else
2160 tree ctree = gfc_get_class_from_expr (se.expr);
2161 tmp = TREE_TYPE (sym->backend_decl);
2163 /* F2018:19.5.1.6 "If a selector has the POINTER attribute,
2164 it shall be associated; the associate name is associated
2165 with the target of the pointer and does not have the
2166 POINTER attribute." */
2167 if (sym->ts.type == BT_CLASS
2168 && e->ts.type == BT_CLASS && e->rank == 0 && ctree
2169 && (!GFC_CLASS_TYPE_P (TREE_TYPE (se.expr))
2170 || CLASS_DATA (e)->attr.class_pointer))
2172 tree stmp;
2173 tree dtmp;
2174 tree ctmp;
2176 ctmp = ctree;
2177 dtmp = TREE_TYPE (TREE_TYPE (sym->backend_decl));
2178 ctree = gfc_create_var (dtmp, "class");
2180 if (IS_INFERRED_TYPE (e)
2181 && !GFC_CLASS_TYPE_P (TREE_TYPE (se.expr)))
2182 stmp = se.expr;
2183 else
2184 stmp = gfc_class_data_get (ctmp);
2186 /* Coarray scalar component expressions can emerge from
2187 the front end as array elements of the _data field. */
2188 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (stmp)))
2189 stmp = gfc_conv_descriptor_data_get (stmp);
2191 if (!POINTER_TYPE_P (TREE_TYPE (stmp)))
2192 stmp = gfc_build_addr_expr (NULL, stmp);
2194 dtmp = gfc_class_data_get (ctree);
2195 stmp = fold_convert (TREE_TYPE (dtmp), stmp);
2196 gfc_add_modify (&se.pre, dtmp, stmp);
2197 stmp = gfc_class_vptr_get (ctmp);
2198 dtmp = gfc_class_vptr_get (ctree);
2199 stmp = fold_convert (TREE_TYPE (dtmp), stmp);
2200 gfc_add_modify (&se.pre, dtmp, stmp);
2201 if (UNLIMITED_POLY (sym))
2203 stmp = gfc_class_len_get (ctmp);
2204 dtmp = gfc_class_len_get (ctree);
2205 stmp = fold_convert (TREE_TYPE (dtmp), stmp);
2206 gfc_add_modify (&se.pre, dtmp, stmp);
2207 need_len_assign = false;
2209 se.expr = ctree;
2211 tmp = gfc_build_addr_expr (tmp, se.expr);
2214 gfc_add_modify (&se.pre, sym->backend_decl, tmp);
2216 gfc_add_init_cleanup (block, gfc_finish_block( &se.pre),
2217 gfc_finish_block (&se.post));
2220 /* Do a simple assignment. This is for scalar expressions, where we
2221 can simply use expression assignment. */
2222 else
2224 gfc_expr *lhs;
2225 tree res;
2226 gfc_se se;
2227 stmtblock_t final_block;
2229 gfc_init_se (&se, NULL);
2231 /* resolve.cc converts some associate names to allocatable so that
2232 allocation can take place automatically in gfc_trans_assignment.
2233 The frontend prevents them from being either allocated,
2234 deallocated or reallocated. */
2235 if (sym->ts.type == BT_DERIVED
2236 && sym->ts.u.derived->attr.alloc_comp)
2238 tmp = sym->backend_decl;
2239 tmp = gfc_nullify_alloc_comp (sym->ts.u.derived, tmp,
2240 sym->attr.dimension ? sym->as->rank : 0);
2241 gfc_add_expr_to_block (&se.pre, tmp);
2244 if (sym->attr.allocatable)
2246 tmp = sym->backend_decl;
2247 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
2248 tmp = gfc_conv_descriptor_data_get (tmp);
2249 gfc_add_modify (&se.pre, tmp, fold_convert (TREE_TYPE (tmp),
2250 null_pointer_node));
2253 lhs = gfc_lval_expr_from_sym (sym);
2254 lhs->must_finalize = 0;
2255 res = gfc_trans_assignment (lhs, e, false, true);
2256 gfc_add_expr_to_block (&se.pre, res);
2258 gfc_init_block (&final_block);
2260 if (sym->attr.associate_var
2261 && sym->ts.type == BT_DERIVED
2262 && sym->ts.u.derived->attr.defined_assign_comp
2263 && gfc_may_be_finalized (sym->ts)
2264 && e->expr_type == EXPR_FUNCTION)
2266 gfc_expr *ef;
2267 ef = gfc_lval_expr_from_sym (sym);
2268 gfc_add_finalizer_call (&final_block, ef);
2269 gfc_free_expr (ef);
2272 if (sym->ts.type == BT_DERIVED
2273 && sym->ts.u.derived->attr.alloc_comp)
2275 tmp = sym->backend_decl;
2276 tmp = gfc_deallocate_alloc_comp (sym->ts.u.derived,
2277 tmp, 0);
2278 gfc_add_expr_to_block (&final_block, tmp);
2281 tmp = sym->backend_decl;
2282 if (e->expr_type == EXPR_FUNCTION
2283 && sym->ts.type == BT_DERIVED
2284 && sym->ts.u.derived
2285 && sym->ts.u.derived->attr.pdt_type)
2287 tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived, tmp,
2290 else if (e->expr_type == EXPR_FUNCTION
2291 && sym->ts.type == BT_CLASS
2292 && CLASS_DATA (sym)->ts.u.derived
2293 && CLASS_DATA (sym)->ts.u.derived->attr.pdt_type)
2295 tmp = gfc_class_data_get (tmp);
2296 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (sym)->ts.u.derived,
2297 tmp, 0);
2299 else if (sym->attr.allocatable)
2301 tmp = sym->backend_decl;
2303 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
2304 tmp = gfc_conv_descriptor_data_get (tmp);
2306 /* A simple call to free suffices here. */
2307 tmp = gfc_call_free (tmp);
2309 /* Make sure that reallocation on assignment cannot occur. */
2310 sym->attr.allocatable = 0;
2312 else
2313 tmp = NULL_TREE;
2315 gfc_add_expr_to_block (&final_block, tmp);
2316 tmp = gfc_finish_block (&final_block);
2317 res = gfc_finish_block (&se.pre);
2318 gfc_add_init_cleanup (block, res, tmp);
2319 gfc_free_expr (lhs);
2322 /* Set the stringlength, when needed. */
2323 if (need_len_assign)
2325 gfc_se se;
2326 gfc_init_se (&se, NULL);
2327 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
2329 /* Deferred strings are dealt with in the preceding. */
2330 gcc_assert (!e->symtree->n.sym->ts.deferred);
2331 tmp = e->symtree->n.sym->ts.u.cl->backend_decl;
2333 else if (e->symtree->n.sym->attr.function
2334 && e->symtree->n.sym == e->symtree->n.sym->result)
2336 tmp = gfc_get_fake_result_decl (e->symtree->n.sym, 0);
2337 tmp = gfc_class_len_get (tmp);
2339 else
2340 tmp = gfc_class_len_get (gfc_get_symbol_decl (e->symtree->n.sym));
2341 gfc_get_symbol_decl (sym);
2342 charlen = sym->ts.type == BT_CHARACTER ? sym->ts.u.cl->backend_decl
2343 : gfc_class_len_get (sym->backend_decl);
2344 /* Prevent adding a noop len= len. */
2345 if (tmp != charlen)
2347 gfc_add_modify (&se.pre, charlen,
2348 fold_convert (TREE_TYPE (charlen), tmp));
2349 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
2350 gfc_finish_block (&se.post));
2356 /* Translate a BLOCK construct. This is basically what we would do for a
2357 procedure body. */
2359 tree
2360 gfc_trans_block_construct (gfc_code* code)
2362 gfc_namespace* ns;
2363 gfc_symbol* sym;
2364 gfc_wrapped_block block;
2365 tree exit_label;
2366 stmtblock_t body;
2367 gfc_association_list *ass;
2368 tree translated_body;
2370 ns = code->ext.block.ns;
2371 gcc_assert (ns);
2372 sym = ns->proc_name;
2373 gcc_assert (sym);
2375 /* Process local variables. */
2376 gcc_assert (!sym->tlink);
2377 sym->tlink = sym;
2378 gfc_process_block_locals (ns);
2380 /* Generate code including exit-label. */
2381 gfc_init_block (&body);
2382 exit_label = gfc_build_label_decl (NULL_TREE);
2383 code->exit_label = exit_label;
2385 finish_oacc_declare (ns, sym, true);
2387 translated_body = gfc_trans_code (ns->code);
2388 if (ns->omp_structured_block)
2389 translated_body = build1 (OMP_STRUCTURED_BLOCK, void_type_node,
2390 translated_body);
2391 gfc_add_expr_to_block (&body, translated_body);
2392 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
2394 /* Finish everything. */
2395 gfc_start_wrapped_block (&block, gfc_finish_block (&body));
2396 gfc_trans_deferred_vars (sym, &block);
2397 for (ass = code->ext.block.assoc; ass; ass = ass->next)
2398 trans_associate_var (ass->st->n.sym, &block);
2400 return gfc_finish_wrapped_block (&block);
2403 /* Translate the simple DO construct in a C-style manner.
2404 This is where the loop variable has integer type and step +-1.
2405 Following code will generate infinite loop in case where TO is INT_MAX
2406 (for +1 step) or INT_MIN (for -1 step)
2408 We translate a do loop from:
2410 DO dovar = from, to, step
2411 body
2412 END DO
2416 [Evaluate loop bounds and step]
2417 dovar = from;
2418 for (;;)
2420 if (dovar > to)
2421 goto end_label;
2422 body;
2423 cycle_label:
2424 dovar += step;
2426 end_label:
2428 This helps the optimizers by avoiding the extra pre-header condition and
2429 we save a register as we just compare the updated IV (not a value in
2430 previous step). */
2432 static tree
2433 gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
2434 tree from, tree to, tree step, tree exit_cond)
2436 stmtblock_t body;
2437 tree type;
2438 tree cond;
2439 tree tmp;
2440 tree saved_dovar = NULL;
2441 tree cycle_label;
2442 tree exit_label;
2443 location_t loc;
2444 type = TREE_TYPE (dovar);
2445 bool is_step_positive = tree_int_cst_sgn (step) > 0;
2447 loc = gfc_get_location (&code->ext.iterator->start->where);
2449 /* Initialize the DO variable: dovar = from. */
2450 gfc_add_modify_loc (loc, pblock, dovar,
2451 fold_convert (TREE_TYPE (dovar), from));
2453 /* Save value for do-tinkering checking. */
2454 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2456 saved_dovar = gfc_create_var (type, ".saved_dovar");
2457 gfc_add_modify_loc (loc, pblock, saved_dovar, dovar);
2460 /* Cycle and exit statements are implemented with gotos. */
2461 cycle_label = gfc_build_label_decl (NULL_TREE);
2462 exit_label = gfc_build_label_decl (NULL_TREE);
2464 /* Put the labels where they can be found later. See gfc_trans_do(). */
2465 code->cycle_label = cycle_label;
2466 code->exit_label = exit_label;
2468 /* Loop body. */
2469 gfc_start_block (&body);
2471 /* Exit the loop if there is an I/O result condition or error. */
2472 if (exit_cond)
2474 tmp = build1_v (GOTO_EXPR, exit_label);
2475 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2476 exit_cond, tmp,
2477 build_empty_stmt (loc));
2478 gfc_add_expr_to_block (&body, tmp);
2481 /* Evaluate the loop condition. */
2482 if (is_step_positive)
2483 cond = fold_build2_loc (loc, GT_EXPR, logical_type_node, dovar,
2484 fold_convert (type, to));
2485 else
2486 cond = fold_build2_loc (loc, LT_EXPR, logical_type_node, dovar,
2487 fold_convert (type, to));
2489 cond = gfc_evaluate_now_loc (loc, cond, &body);
2490 if (code->ext.iterator->annot.unroll && cond != error_mark_node)
2491 cond
2492 = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2493 build_int_cst (integer_type_node, annot_expr_unroll_kind),
2494 build_int_cst (integer_type_node,
2495 code->ext.iterator->annot.unroll));
2497 if (code->ext.iterator->annot.ivdep && cond != error_mark_node)
2498 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2499 build_int_cst (integer_type_node, annot_expr_ivdep_kind),
2500 integer_zero_node);
2501 if (code->ext.iterator->annot.vector && cond != error_mark_node)
2502 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2503 build_int_cst (integer_type_node, annot_expr_vector_kind),
2504 integer_zero_node);
2505 if (code->ext.iterator->annot.novector && cond != error_mark_node)
2506 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2507 build_int_cst (integer_type_node, annot_expr_no_vector_kind),
2508 integer_zero_node);
2510 /* The loop exit. */
2511 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
2512 TREE_USED (exit_label) = 1;
2513 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2514 cond, tmp, build_empty_stmt (loc));
2515 gfc_add_expr_to_block (&body, tmp);
2517 /* Check whether the induction variable is equal to INT_MAX
2518 (respectively to INT_MIN). */
2519 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2521 tree boundary = is_step_positive ? TYPE_MAX_VALUE (type)
2522 : TYPE_MIN_VALUE (type);
2524 tmp = fold_build2_loc (loc, EQ_EXPR, logical_type_node,
2525 dovar, boundary);
2526 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2527 "Loop iterates infinitely");
2530 /* Main loop body. */
2531 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
2532 gfc_add_expr_to_block (&body, tmp);
2534 /* Label for cycle statements (if needed). */
2535 if (TREE_USED (cycle_label))
2537 tmp = build1_v (LABEL_EXPR, cycle_label);
2538 gfc_add_expr_to_block (&body, tmp);
2541 /* Check whether someone has modified the loop variable. */
2542 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2544 tmp = fold_build2_loc (loc, NE_EXPR, logical_type_node,
2545 dovar, saved_dovar);
2546 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2547 "Loop variable has been modified");
2550 /* Increment the loop variable. */
2551 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
2552 gfc_add_modify_loc (loc, &body, dovar, tmp);
2554 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2555 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
2557 /* Finish the loop body. */
2558 tmp = gfc_finish_block (&body);
2559 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
2561 gfc_add_expr_to_block (pblock, tmp);
2563 /* Add the exit label. */
2564 tmp = build1_v (LABEL_EXPR, exit_label);
2565 gfc_add_expr_to_block (pblock, tmp);
2567 return gfc_finish_block (pblock);
2570 /* Translate the DO construct. This obviously is one of the most
2571 important ones to get right with any compiler, but especially
2572 so for Fortran.
2574 We special case some loop forms as described in gfc_trans_simple_do.
2575 For other cases we implement them with a separate loop count,
2576 as described in the standard.
2578 We translate a do loop from:
2580 DO dovar = from, to, step
2581 body
2582 END DO
2586 [evaluate loop bounds and step]
2587 empty = (step > 0 ? to < from : to > from);
2588 countm1 = (to - from) / step;
2589 dovar = from;
2590 if (empty) goto exit_label;
2591 for (;;)
2593 body;
2594 cycle_label:
2595 dovar += step
2596 countm1t = countm1;
2597 countm1--;
2598 if (countm1t == 0) goto exit_label;
2600 exit_label:
2602 countm1 is an unsigned integer. It is equal to the loop count minus one,
2603 because the loop count itself can overflow. */
2605 tree
2606 gfc_trans_do (gfc_code * code, tree exit_cond)
2608 gfc_se se;
2609 tree dovar;
2610 tree saved_dovar = NULL;
2611 tree from;
2612 tree to;
2613 tree step;
2614 tree countm1;
2615 tree type;
2616 tree utype;
2617 tree cond;
2618 tree cycle_label;
2619 tree exit_label;
2620 tree tmp;
2621 stmtblock_t block;
2622 stmtblock_t body;
2623 location_t loc;
2625 gfc_start_block (&block);
2627 loc = gfc_get_location (&code->ext.iterator->start->where);
2629 /* Evaluate all the expressions in the iterator. */
2630 gfc_init_se (&se, NULL);
2631 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
2632 gfc_add_block_to_block (&block, &se.pre);
2633 dovar = se.expr;
2634 type = TREE_TYPE (dovar);
2636 gfc_init_se (&se, NULL);
2637 gfc_conv_expr_val (&se, code->ext.iterator->start);
2638 gfc_add_block_to_block (&block, &se.pre);
2639 from = gfc_evaluate_now (se.expr, &block);
2641 gfc_init_se (&se, NULL);
2642 gfc_conv_expr_val (&se, code->ext.iterator->end);
2643 gfc_add_block_to_block (&block, &se.pre);
2644 to = gfc_evaluate_now (se.expr, &block);
2646 gfc_init_se (&se, NULL);
2647 gfc_conv_expr_val (&se, code->ext.iterator->step);
2648 gfc_add_block_to_block (&block, &se.pre);
2649 step = gfc_evaluate_now (se.expr, &block);
2651 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2653 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, step,
2654 build_zero_cst (type));
2655 gfc_trans_runtime_check (true, false, tmp, &block, &code->loc,
2656 "DO step value is zero");
2659 /* Special case simple loops. */
2660 if (TREE_CODE (type) == INTEGER_TYPE
2661 && (integer_onep (step)
2662 || tree_int_cst_equal (step, integer_minus_one_node)))
2663 return gfc_trans_simple_do (code, &block, dovar, from, to, step,
2664 exit_cond);
2666 if (TREE_CODE (type) == INTEGER_TYPE)
2667 utype = unsigned_type_for (type);
2668 else
2669 utype = unsigned_type_for (gfc_array_index_type);
2670 countm1 = gfc_create_var (utype, "countm1");
2672 /* Cycle and exit statements are implemented with gotos. */
2673 cycle_label = gfc_build_label_decl (NULL_TREE);
2674 exit_label = gfc_build_label_decl (NULL_TREE);
2675 TREE_USED (exit_label) = 1;
2677 /* Put these labels where they can be found later. */
2678 code->cycle_label = cycle_label;
2679 code->exit_label = exit_label;
2681 /* Initialize the DO variable: dovar = from. */
2682 gfc_add_modify (&block, dovar, from);
2684 /* Save value for do-tinkering checking. */
2685 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2687 saved_dovar = gfc_create_var (type, ".saved_dovar");
2688 gfc_add_modify_loc (loc, &block, saved_dovar, dovar);
2691 /* Initialize loop count and jump to exit label if the loop is empty.
2692 This code is executed before we enter the loop body. We generate:
2693 if (step > 0)
2695 countm1 = (to - from) / step;
2696 if (to < from)
2697 goto exit_label;
2699 else
2701 countm1 = (from - to) / -step;
2702 if (to > from)
2703 goto exit_label;
2707 if (TREE_CODE (type) == INTEGER_TYPE)
2709 tree pos, neg, tou, fromu, stepu, tmp2;
2711 /* The distance from FROM to TO cannot always be represented in a signed
2712 type, thus use unsigned arithmetic, also to avoid any undefined
2713 overflow issues. */
2714 tou = fold_convert (utype, to);
2715 fromu = fold_convert (utype, from);
2716 stepu = fold_convert (utype, step);
2718 /* For a positive step, when to < from, exit, otherwise compute
2719 countm1 = ((unsigned)to - (unsigned)from) / (unsigned)step */
2720 tmp = fold_build2_loc (loc, LT_EXPR, logical_type_node, to, from);
2721 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2722 fold_build2_loc (loc, MINUS_EXPR, utype,
2723 tou, fromu),
2724 stepu);
2725 pos = build2 (COMPOUND_EXPR, void_type_node,
2726 fold_build2 (MODIFY_EXPR, void_type_node,
2727 countm1, tmp2),
2728 build3_loc (loc, COND_EXPR, void_type_node,
2729 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
2730 build1_loc (loc, GOTO_EXPR, void_type_node,
2731 exit_label), NULL_TREE));
2733 /* For a negative step, when to > from, exit, otherwise compute
2734 countm1 = ((unsigned)from - (unsigned)to) / -(unsigned)step */
2735 tmp = fold_build2_loc (loc, GT_EXPR, logical_type_node, to, from);
2736 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2737 fold_build2_loc (loc, MINUS_EXPR, utype,
2738 fromu, tou),
2739 fold_build1_loc (loc, NEGATE_EXPR, utype, stepu));
2740 neg = build2 (COMPOUND_EXPR, void_type_node,
2741 fold_build2 (MODIFY_EXPR, void_type_node,
2742 countm1, tmp2),
2743 build3_loc (loc, COND_EXPR, void_type_node,
2744 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
2745 build1_loc (loc, GOTO_EXPR, void_type_node,
2746 exit_label), NULL_TREE));
2748 tmp = fold_build2_loc (loc, LT_EXPR, logical_type_node, step,
2749 build_int_cst (TREE_TYPE (step), 0));
2750 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp, neg, pos);
2752 gfc_add_expr_to_block (&block, tmp);
2754 else
2756 tree pos_step;
2758 /* TODO: We could use the same width as the real type.
2759 This would probably cause more problems that it solves
2760 when we implement "long double" types. */
2762 tmp = fold_build2_loc (loc, MINUS_EXPR, type, to, from);
2763 tmp = fold_build2_loc (loc, RDIV_EXPR, type, tmp, step);
2764 tmp = fold_build1_loc (loc, FIX_TRUNC_EXPR, utype, tmp);
2765 gfc_add_modify (&block, countm1, tmp);
2767 /* We need a special check for empty loops:
2768 empty = (step > 0 ? to < from : to > from); */
2769 pos_step = fold_build2_loc (loc, GT_EXPR, logical_type_node, step,
2770 build_zero_cst (type));
2771 tmp = fold_build3_loc (loc, COND_EXPR, logical_type_node, pos_step,
2772 fold_build2_loc (loc, LT_EXPR,
2773 logical_type_node, to, from),
2774 fold_build2_loc (loc, GT_EXPR,
2775 logical_type_node, to, from));
2776 /* If the loop is empty, go directly to the exit label. */
2777 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp,
2778 build1_v (GOTO_EXPR, exit_label),
2779 build_empty_stmt (input_location));
2780 gfc_add_expr_to_block (&block, tmp);
2783 /* Loop body. */
2784 gfc_start_block (&body);
2786 /* Main loop body. */
2787 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
2788 gfc_add_expr_to_block (&body, tmp);
2790 /* Label for cycle statements (if needed). */
2791 if (TREE_USED (cycle_label))
2793 tmp = build1_v (LABEL_EXPR, cycle_label);
2794 gfc_add_expr_to_block (&body, tmp);
2797 /* Check whether someone has modified the loop variable. */
2798 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2800 tmp = fold_build2_loc (loc, NE_EXPR, logical_type_node, dovar,
2801 saved_dovar);
2802 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2803 "Loop variable has been modified");
2806 /* Exit the loop if there is an I/O result condition or error. */
2807 if (exit_cond)
2809 tmp = build1_v (GOTO_EXPR, exit_label);
2810 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2811 exit_cond, tmp,
2812 build_empty_stmt (input_location));
2813 gfc_add_expr_to_block (&body, tmp);
2816 /* Increment the loop variable. */
2817 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
2818 gfc_add_modify_loc (loc, &body, dovar, tmp);
2820 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2821 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
2823 /* Initialize countm1t. */
2824 tree countm1t = gfc_create_var (utype, "countm1t");
2825 gfc_add_modify_loc (loc, &body, countm1t, countm1);
2827 /* Decrement the loop count. */
2828 tmp = fold_build2_loc (loc, MINUS_EXPR, utype, countm1,
2829 build_int_cst (utype, 1));
2830 gfc_add_modify_loc (loc, &body, countm1, tmp);
2832 /* End with the loop condition. Loop until countm1t == 0. */
2833 cond = fold_build2_loc (loc, EQ_EXPR, logical_type_node, countm1t,
2834 build_int_cst (utype, 0));
2835 if (code->ext.iterator->annot.unroll && cond != error_mark_node)
2836 cond
2837 = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2838 build_int_cst (integer_type_node, annot_expr_unroll_kind),
2839 build_int_cst (integer_type_node,
2840 code->ext.iterator->annot.unroll));
2842 if (code->ext.iterator->annot.ivdep && cond != error_mark_node)
2843 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2844 build_int_cst (integer_type_node, annot_expr_ivdep_kind),
2845 integer_zero_node);
2846 if (code->ext.iterator->annot.vector && cond != error_mark_node)
2847 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2848 build_int_cst (integer_type_node, annot_expr_vector_kind),
2849 integer_zero_node);
2850 if (code->ext.iterator->annot.novector && cond != error_mark_node)
2851 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2852 build_int_cst (integer_type_node, annot_expr_no_vector_kind),
2853 integer_zero_node);
2855 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
2856 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2857 cond, tmp, build_empty_stmt (loc));
2858 gfc_add_expr_to_block (&body, tmp);
2860 /* End of loop body. */
2861 tmp = gfc_finish_block (&body);
2863 /* The for loop itself. */
2864 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
2865 gfc_add_expr_to_block (&block, tmp);
2867 /* Add the exit label. */
2868 tmp = build1_v (LABEL_EXPR, exit_label);
2869 gfc_add_expr_to_block (&block, tmp);
2871 return gfc_finish_block (&block);
2875 /* Translate the DO WHILE construct.
2877 We translate
2879 DO WHILE (cond)
2880 body
2881 END DO
2885 for ( ; ; )
2887 pre_cond;
2888 if (! cond) goto exit_label;
2889 body;
2890 cycle_label:
2892 exit_label:
2894 Because the evaluation of the exit condition `cond' may have side
2895 effects, we can't do much for empty loop bodies. The backend optimizers
2896 should be smart enough to eliminate any dead loops. */
2898 tree
2899 gfc_trans_do_while (gfc_code * code)
2901 gfc_se cond;
2902 tree tmp;
2903 tree cycle_label;
2904 tree exit_label;
2905 stmtblock_t block;
2907 /* Everything we build here is part of the loop body. */
2908 gfc_start_block (&block);
2910 /* Cycle and exit statements are implemented with gotos. */
2911 cycle_label = gfc_build_label_decl (NULL_TREE);
2912 exit_label = gfc_build_label_decl (NULL_TREE);
2914 /* Put the labels where they can be found later. See gfc_trans_do(). */
2915 code->cycle_label = cycle_label;
2916 code->exit_label = exit_label;
2918 /* Create a GIMPLE version of the exit condition. */
2919 gfc_init_se (&cond, NULL);
2920 gfc_conv_expr_val (&cond, code->expr1);
2921 gfc_add_block_to_block (&block, &cond.pre);
2922 cond.expr = fold_build1_loc (gfc_get_location (&code->expr1->where),
2923 TRUTH_NOT_EXPR, TREE_TYPE (cond.expr),
2924 cond.expr);
2926 /* Build "IF (! cond) GOTO exit_label". */
2927 tmp = build1_v (GOTO_EXPR, exit_label);
2928 TREE_USED (exit_label) = 1;
2929 tmp = fold_build3_loc (gfc_get_location (&code->expr1->where), COND_EXPR,
2930 void_type_node, cond.expr, tmp,
2931 build_empty_stmt (gfc_get_location (
2932 &code->expr1->where)));
2933 gfc_add_expr_to_block (&block, tmp);
2935 /* The main body of the loop. */
2936 tmp = gfc_trans_code (code->block->next);
2937 gfc_add_expr_to_block (&block, tmp);
2939 /* Label for cycle statements (if needed). */
2940 if (TREE_USED (cycle_label))
2942 tmp = build1_v (LABEL_EXPR, cycle_label);
2943 gfc_add_expr_to_block (&block, tmp);
2946 /* End of loop body. */
2947 tmp = gfc_finish_block (&block);
2949 gfc_init_block (&block);
2950 /* Build the loop. */
2951 tmp = fold_build1_loc (gfc_get_location (&code->expr1->where), LOOP_EXPR,
2952 void_type_node, tmp);
2953 gfc_add_expr_to_block (&block, tmp);
2955 /* Add the exit label. */
2956 tmp = build1_v (LABEL_EXPR, exit_label);
2957 gfc_add_expr_to_block (&block, tmp);
2959 return gfc_finish_block (&block);
2963 /* Deal with the particular case of SELECT_TYPE, where the vtable
2964 addresses are used for the selection. Since these are not sorted,
2965 the selection has to be made by a series of if statements. */
2967 static tree
2968 gfc_trans_select_type_cases (gfc_code * code)
2970 gfc_code *c;
2971 gfc_case *cp;
2972 tree tmp;
2973 tree cond;
2974 tree low;
2975 tree high;
2976 gfc_se se;
2977 gfc_se cse;
2978 stmtblock_t block;
2979 stmtblock_t body;
2980 bool def = false;
2981 gfc_expr *e;
2982 gfc_start_block (&block);
2984 /* Calculate the switch expression. */
2985 gfc_init_se (&se, NULL);
2986 gfc_conv_expr_val (&se, code->expr1);
2987 gfc_add_block_to_block (&block, &se.pre);
2989 /* Generate an expression for the selector hash value, for
2990 use to resolve character cases. */
2991 e = gfc_copy_expr (code->expr1->value.function.actual->expr);
2992 gfc_add_hash_component (e);
2994 TREE_USED (code->exit_label) = 0;
2996 repeat:
2997 for (c = code->block; c; c = c->block)
2999 cp = c->ext.block.case_list;
3001 /* Assume it's the default case. */
3002 low = NULL_TREE;
3003 high = NULL_TREE;
3004 tmp = NULL_TREE;
3006 /* Put the default case at the end. */
3007 if ((!def && !cp->low) || (def && cp->low))
3008 continue;
3010 if (cp->low && (cp->ts.type == BT_CLASS
3011 || cp->ts.type == BT_DERIVED))
3013 gfc_init_se (&cse, NULL);
3014 gfc_conv_expr_val (&cse, cp->low);
3015 gfc_add_block_to_block (&block, &cse.pre);
3016 low = cse.expr;
3018 else if (cp->ts.type != BT_UNKNOWN)
3020 gcc_assert (cp->high);
3021 gfc_init_se (&cse, NULL);
3022 gfc_conv_expr_val (&cse, cp->high);
3023 gfc_add_block_to_block (&block, &cse.pre);
3024 high = cse.expr;
3027 gfc_init_block (&body);
3029 /* Add the statements for this case. */
3030 tmp = gfc_trans_code (c->next);
3031 gfc_add_expr_to_block (&body, tmp);
3033 /* Break to the end of the SELECT TYPE construct. The default
3034 case just falls through. */
3035 if (!def)
3037 TREE_USED (code->exit_label) = 1;
3038 tmp = build1_v (GOTO_EXPR, code->exit_label);
3039 gfc_add_expr_to_block (&body, tmp);
3042 tmp = gfc_finish_block (&body);
3044 if (low != NULL_TREE)
3046 /* Compare vtable pointers. */
3047 cond = fold_build2_loc (input_location, EQ_EXPR,
3048 TREE_TYPE (se.expr), se.expr, low);
3049 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3050 cond, tmp,
3051 build_empty_stmt (input_location));
3053 else if (high != NULL_TREE)
3055 /* Compare hash values for character cases. */
3056 gfc_init_se (&cse, NULL);
3057 gfc_conv_expr_val (&cse, e);
3058 gfc_add_block_to_block (&block, &cse.pre);
3060 cond = fold_build2_loc (input_location, EQ_EXPR,
3061 TREE_TYPE (se.expr), high, cse.expr);
3062 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3063 cond, tmp,
3064 build_empty_stmt (input_location));
3067 gfc_add_expr_to_block (&block, tmp);
3070 if (!def)
3072 def = true;
3073 goto repeat;
3076 gfc_free_expr (e);
3078 return gfc_finish_block (&block);
3082 /* Translate the SELECT CASE construct for INTEGER case expressions,
3083 without killing all potential optimizations. The problem is that
3084 Fortran allows unbounded cases, but the back-end does not, so we
3085 need to intercept those before we enter the equivalent SWITCH_EXPR
3086 we can build.
3088 For example, we translate this,
3090 SELECT CASE (expr)
3091 CASE (:100,101,105:115)
3092 block_1
3093 CASE (190:199,200:)
3094 block_2
3095 CASE (300)
3096 block_3
3097 CASE DEFAULT
3098 block_4
3099 END SELECT
3101 to the GENERIC equivalent,
3103 switch (expr)
3105 case (minimum value for typeof(expr) ... 100:
3106 case 101:
3107 case 105 ... 114:
3108 block1:
3109 goto end_label;
3111 case 200 ... (maximum value for typeof(expr):
3112 case 190 ... 199:
3113 block2;
3114 goto end_label;
3116 case 300:
3117 block_3;
3118 goto end_label;
3120 default:
3121 block_4;
3122 goto end_label;
3125 end_label: */
3127 static tree
3128 gfc_trans_integer_select (gfc_code * code)
3130 gfc_code *c;
3131 gfc_case *cp;
3132 tree end_label;
3133 tree tmp;
3134 gfc_se se;
3135 stmtblock_t block;
3136 stmtblock_t body;
3138 gfc_start_block (&block);
3140 /* Calculate the switch expression. */
3141 gfc_init_se (&se, NULL);
3142 gfc_conv_expr_val (&se, code->expr1);
3143 gfc_add_block_to_block (&block, &se.pre);
3145 end_label = gfc_build_label_decl (NULL_TREE);
3147 gfc_init_block (&body);
3149 for (c = code->block; c; c = c->block)
3151 for (cp = c->ext.block.case_list; cp; cp = cp->next)
3153 tree low, high;
3154 tree label;
3156 /* Assume it's the default case. */
3157 low = high = NULL_TREE;
3159 if (cp->low)
3161 low = gfc_conv_mpz_to_tree (cp->low->value.integer,
3162 cp->low->ts.kind);
3164 /* If there's only a lower bound, set the high bound to the
3165 maximum value of the case expression. */
3166 if (!cp->high)
3167 high = TYPE_MAX_VALUE (TREE_TYPE (se.expr));
3170 if (cp->high)
3172 /* Three cases are possible here:
3174 1) There is no lower bound, e.g. CASE (:N).
3175 2) There is a lower bound .NE. high bound, that is
3176 a case range, e.g. CASE (N:M) where M>N (we make
3177 sure that M>N during type resolution).
3178 3) There is a lower bound, and it has the same value
3179 as the high bound, e.g. CASE (N:N). This is our
3180 internal representation of CASE(N).
3182 In the first and second case, we need to set a value for
3183 high. In the third case, we don't because the GCC middle
3184 end represents a single case value by just letting high be
3185 a NULL_TREE. We can't do that because we need to be able
3186 to represent unbounded cases. */
3188 if (!cp->low
3189 || (mpz_cmp (cp->low->value.integer,
3190 cp->high->value.integer) != 0))
3191 high = gfc_conv_mpz_to_tree (cp->high->value.integer,
3192 cp->high->ts.kind);
3194 /* Unbounded case. */
3195 if (!cp->low)
3196 low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
3199 /* Build a label. */
3200 label = gfc_build_label_decl (NULL_TREE);
3202 /* Add this case label.
3203 Add parameter 'label', make it match GCC backend. */
3204 tmp = build_case_label (low, high, label);
3205 gfc_add_expr_to_block (&body, tmp);
3208 /* Add the statements for this case. */
3209 tmp = gfc_trans_code (c->next);
3210 gfc_add_expr_to_block (&body, tmp);
3212 /* Break to the end of the construct. */
3213 tmp = build1_v (GOTO_EXPR, end_label);
3214 gfc_add_expr_to_block (&body, tmp);
3217 tmp = gfc_finish_block (&body);
3218 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE, se.expr, tmp);
3219 gfc_add_expr_to_block (&block, tmp);
3221 tmp = build1_v (LABEL_EXPR, end_label);
3222 gfc_add_expr_to_block (&block, tmp);
3224 return gfc_finish_block (&block);
3228 /* Translate the SELECT CASE construct for LOGICAL case expressions.
3230 There are only two cases possible here, even though the standard
3231 does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
3232 .FALSE., and DEFAULT.
3234 We never generate more than two blocks here. Instead, we always
3235 try to eliminate the DEFAULT case. This way, we can translate this
3236 kind of SELECT construct to a simple
3238 if {} else {};
3240 expression in GENERIC. */
3242 static tree
3243 gfc_trans_logical_select (gfc_code * code)
3245 gfc_code *c;
3246 gfc_code *t, *f, *d;
3247 gfc_case *cp;
3248 gfc_se se;
3249 stmtblock_t block;
3251 /* Assume we don't have any cases at all. */
3252 t = f = d = NULL;
3254 /* Now see which ones we actually do have. We can have at most two
3255 cases in a single case list: one for .TRUE. and one for .FALSE.
3256 The default case is always separate. If the cases for .TRUE. and
3257 .FALSE. are in the same case list, the block for that case list
3258 always executed, and we don't generate code a COND_EXPR. */
3259 for (c = code->block; c; c = c->block)
3261 for (cp = c->ext.block.case_list; cp; cp = cp->next)
3263 if (cp->low)
3265 if (cp->low->value.logical == 0) /* .FALSE. */
3266 f = c;
3267 else /* if (cp->value.logical != 0), thus .TRUE. */
3268 t = c;
3270 else
3271 d = c;
3275 /* Start a new block. */
3276 gfc_start_block (&block);
3278 /* Calculate the switch expression. We always need to do this
3279 because it may have side effects. */
3280 gfc_init_se (&se, NULL);
3281 gfc_conv_expr_val (&se, code->expr1);
3282 gfc_add_block_to_block (&block, &se.pre);
3284 if (t == f && t != NULL)
3286 /* Cases for .TRUE. and .FALSE. are in the same block. Just
3287 translate the code for these cases, append it to the current
3288 block. */
3289 gfc_add_expr_to_block (&block, gfc_trans_code (t->next));
3291 else
3293 tree true_tree, false_tree, stmt;
3295 true_tree = build_empty_stmt (input_location);
3296 false_tree = build_empty_stmt (input_location);
3298 /* If we have a case for .TRUE. and for .FALSE., discard the default case.
3299 Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
3300 make the missing case the default case. */
3301 if (t != NULL && f != NULL)
3302 d = NULL;
3303 else if (d != NULL)
3305 if (t == NULL)
3306 t = d;
3307 else
3308 f = d;
3311 /* Translate the code for each of these blocks, and append it to
3312 the current block. */
3313 if (t != NULL)
3314 true_tree = gfc_trans_code (t->next);
3316 if (f != NULL)
3317 false_tree = gfc_trans_code (f->next);
3319 stmt = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3320 se.expr, true_tree, false_tree);
3321 gfc_add_expr_to_block (&block, stmt);
3324 return gfc_finish_block (&block);
3328 /* The jump table types are stored in static variables to avoid
3329 constructing them from scratch every single time. */
3330 static GTY(()) tree select_struct[2];
3332 /* Translate the SELECT CASE construct for CHARACTER case expressions.
3333 Instead of generating compares and jumps, it is far simpler to
3334 generate a data structure describing the cases in order and call a
3335 library subroutine that locates the right case.
3336 This is particularly true because this is the only case where we
3337 might have to dispose of a temporary.
3338 The library subroutine returns a pointer to jump to or NULL if no
3339 branches are to be taken. */
3341 static tree
3342 gfc_trans_character_select (gfc_code *code)
3344 tree init, end_label, tmp, type, case_num, label, fndecl;
3345 stmtblock_t block, body;
3346 gfc_case *cp, *d;
3347 gfc_code *c;
3348 gfc_se se, expr1se;
3349 int n, k;
3350 vec<constructor_elt, va_gc> *inits = NULL;
3352 tree pchartype = gfc_get_pchar_type (code->expr1->ts.kind);
3354 /* The jump table types are stored in static variables to avoid
3355 constructing them from scratch every single time. */
3356 static tree ss_string1[2], ss_string1_len[2];
3357 static tree ss_string2[2], ss_string2_len[2];
3358 static tree ss_target[2];
3360 cp = code->block->ext.block.case_list;
3361 while (cp->left != NULL)
3362 cp = cp->left;
3364 /* Generate the body */
3365 gfc_start_block (&block);
3366 gfc_init_se (&expr1se, NULL);
3367 gfc_conv_expr_reference (&expr1se, code->expr1);
3369 gfc_add_block_to_block (&block, &expr1se.pre);
3371 end_label = gfc_build_label_decl (NULL_TREE);
3373 gfc_init_block (&body);
3375 /* Attempt to optimize length 1 selects. */
3376 if (integer_onep (expr1se.string_length))
3378 for (d = cp; d; d = d->right)
3380 gfc_charlen_t i;
3381 if (d->low)
3383 gcc_assert (d->low->expr_type == EXPR_CONSTANT
3384 && d->low->ts.type == BT_CHARACTER);
3385 if (d->low->value.character.length > 1)
3387 for (i = 1; i < d->low->value.character.length; i++)
3388 if (d->low->value.character.string[i] != ' ')
3389 break;
3390 if (i != d->low->value.character.length)
3392 if (optimize && d->high && i == 1)
3394 gcc_assert (d->high->expr_type == EXPR_CONSTANT
3395 && d->high->ts.type == BT_CHARACTER);
3396 if (d->high->value.character.length > 1
3397 && (d->low->value.character.string[0]
3398 == d->high->value.character.string[0])
3399 && d->high->value.character.string[1] != ' '
3400 && ((d->low->value.character.string[1] < ' ')
3401 == (d->high->value.character.string[1]
3402 < ' ')))
3403 continue;
3405 break;
3409 if (d->high)
3411 gcc_assert (d->high->expr_type == EXPR_CONSTANT
3412 && d->high->ts.type == BT_CHARACTER);
3413 if (d->high->value.character.length > 1)
3415 for (i = 1; i < d->high->value.character.length; i++)
3416 if (d->high->value.character.string[i] != ' ')
3417 break;
3418 if (i != d->high->value.character.length)
3419 break;
3423 if (d == NULL)
3425 tree ctype = gfc_get_char_type (code->expr1->ts.kind);
3427 for (c = code->block; c; c = c->block)
3429 for (cp = c->ext.block.case_list; cp; cp = cp->next)
3431 tree low, high;
3432 tree label;
3433 gfc_char_t r;
3435 /* Assume it's the default case. */
3436 low = high = NULL_TREE;
3438 if (cp->low)
3440 /* CASE ('ab') or CASE ('ab':'az') will never match
3441 any length 1 character. */
3442 if (cp->low->value.character.length > 1
3443 && cp->low->value.character.string[1] != ' ')
3444 continue;
3446 if (cp->low->value.character.length > 0)
3447 r = cp->low->value.character.string[0];
3448 else
3449 r = ' ';
3450 low = build_int_cst (ctype, r);
3452 /* If there's only a lower bound, set the high bound
3453 to the maximum value of the case expression. */
3454 if (!cp->high)
3455 high = TYPE_MAX_VALUE (ctype);
3458 if (cp->high)
3460 if (!cp->low
3461 || (cp->low->value.character.string[0]
3462 != cp->high->value.character.string[0]))
3464 if (cp->high->value.character.length > 0)
3465 r = cp->high->value.character.string[0];
3466 else
3467 r = ' ';
3468 high = build_int_cst (ctype, r);
3471 /* Unbounded case. */
3472 if (!cp->low)
3473 low = TYPE_MIN_VALUE (ctype);
3476 /* Build a label. */
3477 label = gfc_build_label_decl (NULL_TREE);
3479 /* Add this case label.
3480 Add parameter 'label', make it match GCC backend. */
3481 tmp = build_case_label (low, high, label);
3482 gfc_add_expr_to_block (&body, tmp);
3485 /* Add the statements for this case. */
3486 tmp = gfc_trans_code (c->next);
3487 gfc_add_expr_to_block (&body, tmp);
3489 /* Break to the end of the construct. */
3490 tmp = build1_v (GOTO_EXPR, end_label);
3491 gfc_add_expr_to_block (&body, tmp);
3494 tmp = gfc_string_to_single_character (expr1se.string_length,
3495 expr1se.expr,
3496 code->expr1->ts.kind);
3497 case_num = gfc_create_var (ctype, "case_num");
3498 gfc_add_modify (&block, case_num, tmp);
3500 gfc_add_block_to_block (&block, &expr1se.post);
3502 tmp = gfc_finish_block (&body);
3503 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE,
3504 case_num, tmp);
3505 gfc_add_expr_to_block (&block, tmp);
3507 tmp = build1_v (LABEL_EXPR, end_label);
3508 gfc_add_expr_to_block (&block, tmp);
3510 return gfc_finish_block (&block);
3514 if (code->expr1->ts.kind == 1)
3515 k = 0;
3516 else if (code->expr1->ts.kind == 4)
3517 k = 1;
3518 else
3519 gcc_unreachable ();
3521 if (select_struct[k] == NULL)
3523 tree *chain = NULL;
3524 select_struct[k] = make_node (RECORD_TYPE);
3526 if (code->expr1->ts.kind == 1)
3527 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char1");
3528 else if (code->expr1->ts.kind == 4)
3529 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char4");
3530 else
3531 gcc_unreachable ();
3533 #undef ADD_FIELD
3534 #define ADD_FIELD(NAME, TYPE) \
3535 ss_##NAME[k] = gfc_add_field_to_struct (select_struct[k], \
3536 get_identifier (stringize(NAME)), \
3537 TYPE, \
3538 &chain)
3540 ADD_FIELD (string1, pchartype);
3541 ADD_FIELD (string1_len, gfc_charlen_type_node);
3543 ADD_FIELD (string2, pchartype);
3544 ADD_FIELD (string2_len, gfc_charlen_type_node);
3546 ADD_FIELD (target, integer_type_node);
3547 #undef ADD_FIELD
3549 gfc_finish_type (select_struct[k]);
3552 n = 0;
3553 for (d = cp; d; d = d->right)
3554 d->n = n++;
3556 for (c = code->block; c; c = c->block)
3558 for (d = c->ext.block.case_list; d; d = d->next)
3560 label = gfc_build_label_decl (NULL_TREE);
3561 tmp = build_case_label ((d->low == NULL && d->high == NULL)
3562 ? NULL
3563 : build_int_cst (integer_type_node, d->n),
3564 NULL, label);
3565 gfc_add_expr_to_block (&body, tmp);
3568 tmp = gfc_trans_code (c->next);
3569 gfc_add_expr_to_block (&body, tmp);
3571 tmp = build1_v (GOTO_EXPR, end_label);
3572 gfc_add_expr_to_block (&body, tmp);
3575 /* Generate the structure describing the branches */
3576 for (d = cp; d; d = d->right)
3578 vec<constructor_elt, va_gc> *node = NULL;
3580 gfc_init_se (&se, NULL);
3582 if (d->low == NULL)
3584 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], null_pointer_node);
3585 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], build_zero_cst (gfc_charlen_type_node));
3587 else
3589 gfc_conv_expr_reference (&se, d->low);
3591 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], se.expr);
3592 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], se.string_length);
3595 if (d->high == NULL)
3597 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], null_pointer_node);
3598 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], build_zero_cst (gfc_charlen_type_node));
3600 else
3602 gfc_init_se (&se, NULL);
3603 gfc_conv_expr_reference (&se, d->high);
3605 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], se.expr);
3606 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], se.string_length);
3609 CONSTRUCTOR_APPEND_ELT (node, ss_target[k],
3610 build_int_cst (integer_type_node, d->n));
3612 tmp = build_constructor (select_struct[k], node);
3613 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, tmp);
3616 type = build_array_type (select_struct[k],
3617 build_index_type (size_int (n-1)));
3619 init = build_constructor (type, inits);
3620 TREE_CONSTANT (init) = 1;
3621 TREE_STATIC (init) = 1;
3622 /* Create a static variable to hold the jump table. */
3623 tmp = gfc_create_var (type, "jumptable");
3624 TREE_CONSTANT (tmp) = 1;
3625 TREE_STATIC (tmp) = 1;
3626 TREE_READONLY (tmp) = 1;
3627 DECL_INITIAL (tmp) = init;
3628 init = tmp;
3630 /* Build the library call */
3631 init = gfc_build_addr_expr (pvoid_type_node, init);
3633 if (code->expr1->ts.kind == 1)
3634 fndecl = gfor_fndecl_select_string;
3635 else if (code->expr1->ts.kind == 4)
3636 fndecl = gfor_fndecl_select_string_char4;
3637 else
3638 gcc_unreachable ();
3640 tmp = build_call_expr_loc (input_location,
3641 fndecl, 4, init,
3642 build_int_cst (gfc_charlen_type_node, n),
3643 expr1se.expr, expr1se.string_length);
3644 case_num = gfc_create_var (integer_type_node, "case_num");
3645 gfc_add_modify (&block, case_num, tmp);
3647 gfc_add_block_to_block (&block, &expr1se.post);
3649 tmp = gfc_finish_block (&body);
3650 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE,
3651 case_num, tmp);
3652 gfc_add_expr_to_block (&block, tmp);
3654 tmp = build1_v (LABEL_EXPR, end_label);
3655 gfc_add_expr_to_block (&block, tmp);
3657 return gfc_finish_block (&block);
3661 /* Translate the three variants of the SELECT CASE construct.
3663 SELECT CASEs with INTEGER case expressions can be translated to an
3664 equivalent GENERIC switch statement, and for LOGICAL case
3665 expressions we build one or two if-else compares.
3667 SELECT CASEs with CHARACTER case expressions are a whole different
3668 story, because they don't exist in GENERIC. So we sort them and
3669 do a binary search at runtime.
3671 Fortran has no BREAK statement, and it does not allow jumps from
3672 one case block to another. That makes things a lot easier for
3673 the optimizers. */
3675 tree
3676 gfc_trans_select (gfc_code * code)
3678 stmtblock_t block;
3679 tree body;
3680 tree exit_label;
3682 gcc_assert (code && code->expr1);
3683 gfc_init_block (&block);
3685 /* Build the exit label and hang it in. */
3686 exit_label = gfc_build_label_decl (NULL_TREE);
3687 code->exit_label = exit_label;
3689 /* Empty SELECT constructs are legal. */
3690 if (code->block == NULL)
3691 body = build_empty_stmt (input_location);
3693 /* Select the correct translation function. */
3694 else
3695 switch (code->expr1->ts.type)
3697 case BT_LOGICAL:
3698 body = gfc_trans_logical_select (code);
3699 break;
3701 case BT_INTEGER:
3702 body = gfc_trans_integer_select (code);
3703 break;
3705 case BT_CHARACTER:
3706 body = gfc_trans_character_select (code);
3707 break;
3709 default:
3710 gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
3711 /* Not reached */
3714 /* Build everything together. */
3715 gfc_add_expr_to_block (&block, body);
3716 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3718 return gfc_finish_block (&block);
3721 tree
3722 gfc_trans_select_type (gfc_code * code)
3724 stmtblock_t block;
3725 tree body;
3726 tree exit_label;
3728 gcc_assert (code && code->expr1);
3729 gfc_init_block (&block);
3731 /* Build the exit label and hang it in. */
3732 exit_label = gfc_build_label_decl (NULL_TREE);
3733 code->exit_label = exit_label;
3735 /* Empty SELECT constructs are legal. */
3736 if (code->block == NULL)
3737 body = build_empty_stmt (input_location);
3738 else
3739 body = gfc_trans_select_type_cases (code);
3741 /* Build everything together. */
3742 gfc_add_expr_to_block (&block, body);
3744 if (TREE_USED (exit_label))
3745 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3747 return gfc_finish_block (&block);
3751 static tree
3752 gfc_trans_select_rank_cases (gfc_code * code)
3754 gfc_code *c;
3755 gfc_case *cp;
3756 tree tmp;
3757 tree cond;
3758 tree low;
3759 tree rank;
3760 gfc_se se;
3761 gfc_se cse;
3762 stmtblock_t block;
3763 stmtblock_t body;
3764 bool def = false;
3766 gfc_start_block (&block);
3768 /* Calculate the switch expression. */
3769 gfc_init_se (&se, NULL);
3770 gfc_conv_expr_descriptor (&se, code->expr1);
3771 rank = gfc_conv_descriptor_rank (se.expr);
3772 rank = gfc_evaluate_now (rank, &block);
3773 symbol_attribute attr = gfc_expr_attr (code->expr1);
3774 if (!attr.pointer && !attr.allocatable)
3776 /* Special case for assumed-rank ('rank(*)', internally -1):
3777 rank = (rank == 0 || ubound[rank-1] != -1) ? rank : -1. */
3778 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
3779 rank, build_int_cst (TREE_TYPE (rank), 0));
3780 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3781 fold_convert (gfc_array_index_type, rank),
3782 gfc_index_one_node);
3783 tmp = gfc_conv_descriptor_ubound_get (se.expr, tmp);
3784 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
3785 tmp, build_int_cst (TREE_TYPE (tmp), -1));
3786 cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
3787 logical_type_node, cond, tmp);
3788 tmp = fold_build3_loc (input_location, COND_EXPR, TREE_TYPE (rank),
3789 cond, rank, build_int_cst (TREE_TYPE (rank), -1));
3790 rank = gfc_evaluate_now (tmp, &block);
3792 TREE_USED (code->exit_label) = 0;
3794 repeat:
3795 for (c = code->block; c; c = c->block)
3797 cp = c->ext.block.case_list;
3799 /* Assume it's the default case. */
3800 low = NULL_TREE;
3801 tmp = NULL_TREE;
3803 /* Put the default case at the end. */
3804 if ((!def && !cp->low) || (def && cp->low))
3805 continue;
3807 if (cp->low)
3809 gfc_init_se (&cse, NULL);
3810 gfc_conv_expr_val (&cse, cp->low);
3811 gfc_add_block_to_block (&block, &cse.pre);
3812 low = cse.expr;
3815 gfc_init_block (&body);
3817 /* Add the statements for this case. */
3818 tmp = gfc_trans_code (c->next);
3819 gfc_add_expr_to_block (&body, tmp);
3821 /* Break to the end of the SELECT RANK construct. The default
3822 case just falls through. */
3823 if (!def)
3825 TREE_USED (code->exit_label) = 1;
3826 tmp = build1_v (GOTO_EXPR, code->exit_label);
3827 gfc_add_expr_to_block (&body, tmp);
3830 tmp = gfc_finish_block (&body);
3832 if (low != NULL_TREE)
3834 cond = fold_build2_loc (input_location, EQ_EXPR,
3835 TREE_TYPE (rank), rank,
3836 fold_convert (TREE_TYPE (rank), low));
3837 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3838 cond, tmp,
3839 build_empty_stmt (input_location));
3842 gfc_add_expr_to_block (&block, tmp);
3845 if (!def)
3847 def = true;
3848 goto repeat;
3851 return gfc_finish_block (&block);
3855 tree
3856 gfc_trans_select_rank (gfc_code * code)
3858 stmtblock_t block;
3859 tree body;
3860 tree exit_label;
3862 gcc_assert (code && code->expr1);
3863 gfc_init_block (&block);
3865 /* Build the exit label and hang it in. */
3866 exit_label = gfc_build_label_decl (NULL_TREE);
3867 code->exit_label = exit_label;
3869 /* Empty SELECT constructs are legal. */
3870 if (code->block == NULL)
3871 body = build_empty_stmt (input_location);
3872 else
3873 body = gfc_trans_select_rank_cases (code);
3875 /* Build everything together. */
3876 gfc_add_expr_to_block (&block, body);
3878 if (TREE_USED (exit_label))
3879 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3881 return gfc_finish_block (&block);
3885 /* Traversal function to substitute a replacement symtree if the symbol
3886 in the expression is the same as that passed. f == 2 signals that
3887 that variable itself is not to be checked - only the references.
3888 This group of functions is used when the variable expression in a
3889 FORALL assignment has internal references. For example:
3890 FORALL (i = 1:4) p(p(i)) = i
3891 The only recourse here is to store a copy of 'p' for the index
3892 expression. */
3894 static gfc_symtree *new_symtree;
3895 static gfc_symtree *old_symtree;
3897 static bool
3898 forall_replace (gfc_expr *expr, gfc_symbol *sym, int *f)
3900 if (expr->expr_type != EXPR_VARIABLE)
3901 return false;
3903 if (*f == 2)
3904 *f = 1;
3905 else if (expr->symtree->n.sym == sym)
3906 expr->symtree = new_symtree;
3908 return false;
3911 static void
3912 forall_replace_symtree (gfc_expr *e, gfc_symbol *sym, int f)
3914 gfc_traverse_expr (e, sym, forall_replace, f);
3917 static bool
3918 forall_restore (gfc_expr *expr,
3919 gfc_symbol *sym ATTRIBUTE_UNUSED,
3920 int *f ATTRIBUTE_UNUSED)
3922 if (expr->expr_type != EXPR_VARIABLE)
3923 return false;
3925 if (expr->symtree == new_symtree)
3926 expr->symtree = old_symtree;
3928 return false;
3931 static void
3932 forall_restore_symtree (gfc_expr *e)
3934 gfc_traverse_expr (e, NULL, forall_restore, 0);
3937 static void
3938 forall_make_variable_temp (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
3940 gfc_se tse;
3941 gfc_se rse;
3942 gfc_expr *e;
3943 gfc_symbol *new_sym;
3944 gfc_symbol *old_sym;
3945 gfc_symtree *root;
3946 tree tmp;
3948 /* Build a copy of the lvalue. */
3949 old_symtree = c->expr1->symtree;
3950 old_sym = old_symtree->n.sym;
3951 e = gfc_lval_expr_from_sym (old_sym);
3952 if (old_sym->attr.dimension)
3954 gfc_init_se (&tse, NULL);
3955 gfc_conv_subref_array_arg (&tse, e, 0, INTENT_IN, false);
3956 gfc_add_block_to_block (pre, &tse.pre);
3957 gfc_add_block_to_block (post, &tse.post);
3958 tse.expr = build_fold_indirect_ref_loc (input_location, tse.expr);
3960 if (c->expr1->ref->u.ar.type != AR_SECTION)
3962 /* Use the variable offset for the temporary. */
3963 tmp = gfc_conv_array_offset (old_sym->backend_decl);
3964 gfc_conv_descriptor_offset_set (pre, tse.expr, tmp);
3967 else
3969 gfc_init_se (&tse, NULL);
3970 gfc_init_se (&rse, NULL);
3971 gfc_conv_expr (&rse, e);
3972 if (e->ts.type == BT_CHARACTER)
3974 tse.string_length = rse.string_length;
3975 tmp = gfc_get_character_type_len (gfc_default_character_kind,
3976 tse.string_length);
3977 tse.expr = gfc_conv_string_tmp (&tse, build_pointer_type (tmp),
3978 rse.string_length);
3979 gfc_add_block_to_block (pre, &tse.pre);
3980 gfc_add_block_to_block (post, &tse.post);
3982 else
3984 tmp = gfc_typenode_for_spec (&e->ts);
3985 tse.expr = gfc_create_var (tmp, "temp");
3988 tmp = gfc_trans_scalar_assign (&tse, &rse, e->ts,
3989 e->expr_type == EXPR_VARIABLE, false);
3990 gfc_add_expr_to_block (pre, tmp);
3992 gfc_free_expr (e);
3994 /* Create a new symbol to represent the lvalue. */
3995 new_sym = gfc_new_symbol (old_sym->name, NULL);
3996 new_sym->ts = old_sym->ts;
3997 new_sym->attr.referenced = 1;
3998 new_sym->attr.temporary = 1;
3999 new_sym->attr.dimension = old_sym->attr.dimension;
4000 new_sym->attr.flavor = old_sym->attr.flavor;
4002 /* Use the temporary as the backend_decl. */
4003 new_sym->backend_decl = tse.expr;
4005 /* Create a fake symtree for it. */
4006 root = NULL;
4007 new_symtree = gfc_new_symtree (&root, old_sym->name);
4008 new_symtree->n.sym = new_sym;
4009 gcc_assert (new_symtree == root);
4011 /* Go through the expression reference replacing the old_symtree
4012 with the new. */
4013 forall_replace_symtree (c->expr1, old_sym, 2);
4015 /* Now we have made this temporary, we might as well use it for
4016 the right hand side. */
4017 forall_replace_symtree (c->expr2, old_sym, 1);
4021 /* Handles dependencies in forall assignments. */
4022 static int
4023 check_forall_dependencies (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
4025 gfc_ref *lref;
4026 gfc_ref *rref;
4027 int need_temp;
4028 gfc_symbol *lsym;
4030 lsym = c->expr1->symtree->n.sym;
4031 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
4033 /* Now check for dependencies within the 'variable'
4034 expression itself. These are treated by making a complete
4035 copy of variable and changing all the references to it
4036 point to the copy instead. Note that the shallow copy of
4037 the variable will not suffice for derived types with
4038 pointer components. We therefore leave these to their
4039 own devices. Likewise for allocatable components. */
4040 if (lsym->ts.type == BT_DERIVED
4041 && (lsym->ts.u.derived->attr.pointer_comp
4042 || lsym->ts.u.derived->attr.alloc_comp))
4043 return need_temp;
4045 new_symtree = NULL;
4046 if (find_forall_index (c->expr1, lsym, 2))
4048 forall_make_variable_temp (c, pre, post);
4049 need_temp = 0;
4052 /* Substrings with dependencies are treated in the same
4053 way. */
4054 if (c->expr1->ts.type == BT_CHARACTER
4055 && c->expr1->ref
4056 && c->expr2->expr_type == EXPR_VARIABLE
4057 && lsym == c->expr2->symtree->n.sym)
4059 for (lref = c->expr1->ref; lref; lref = lref->next)
4060 if (lref->type == REF_SUBSTRING)
4061 break;
4062 for (rref = c->expr2->ref; rref; rref = rref->next)
4063 if (rref->type == REF_SUBSTRING)
4064 break;
4066 if (rref && lref
4067 && gfc_dep_compare_expr (rref->u.ss.start, lref->u.ss.start) < 0)
4069 forall_make_variable_temp (c, pre, post);
4070 need_temp = 0;
4073 return need_temp;
4077 static void
4078 cleanup_forall_symtrees (gfc_code *c)
4080 forall_restore_symtree (c->expr1);
4081 forall_restore_symtree (c->expr2);
4082 free (new_symtree->n.sym);
4083 free (new_symtree);
4087 /* Generate the loops for a FORALL block, specified by FORALL_TMP. BODY
4088 is the contents of the FORALL block/stmt to be iterated. MASK_FLAG
4089 indicates whether we should generate code to test the FORALLs mask
4090 array. OUTER is the loop header to be used for initializing mask
4091 indices.
4093 The generated loop format is:
4094 count = (end - start + step) / step
4095 loopvar = start
4096 while (1)
4098 if (count <=0 )
4099 goto end_of_loop
4100 <body>
4101 loopvar += step
4102 count --
4104 end_of_loop: */
4106 static tree
4107 gfc_trans_forall_loop (forall_info *forall_tmp, tree body,
4108 int mask_flag, stmtblock_t *outer)
4110 int n, nvar;
4111 tree tmp;
4112 tree cond;
4113 stmtblock_t block;
4114 tree exit_label;
4115 tree count;
4116 tree var, start, end, step;
4117 iter_info *iter;
4119 /* Initialize the mask index outside the FORALL nest. */
4120 if (mask_flag && forall_tmp->mask)
4121 gfc_add_modify (outer, forall_tmp->maskindex, gfc_index_zero_node);
4123 iter = forall_tmp->this_loop;
4124 nvar = forall_tmp->nvar;
4125 for (n = 0; n < nvar; n++)
4127 var = iter->var;
4128 start = iter->start;
4129 end = iter->end;
4130 step = iter->step;
4132 exit_label = gfc_build_label_decl (NULL_TREE);
4133 TREE_USED (exit_label) = 1;
4135 /* The loop counter. */
4136 count = gfc_create_var (TREE_TYPE (var), "count");
4138 /* The body of the loop. */
4139 gfc_init_block (&block);
4141 /* The exit condition. */
4142 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
4143 count, build_int_cst (TREE_TYPE (count), 0));
4145 /* PR 83064 means that we cannot use annot_expr_parallel_kind until
4146 the autoparallelizer can handle this. */
4147 if (forall_tmp->do_concurrent || iter->annot.ivdep)
4148 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
4149 build_int_cst (integer_type_node,
4150 annot_expr_ivdep_kind),
4151 integer_zero_node);
4153 if (iter->annot.unroll && cond != error_mark_node)
4154 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
4155 build_int_cst (integer_type_node,
4156 annot_expr_unroll_kind),
4157 build_int_cst (integer_type_node, iter->annot.unroll));
4159 if (iter->annot.vector && cond != error_mark_node)
4160 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
4161 build_int_cst (integer_type_node,
4162 annot_expr_vector_kind),
4163 integer_zero_node);
4165 if (iter->annot.novector && cond != error_mark_node)
4166 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
4167 build_int_cst (integer_type_node,
4168 annot_expr_no_vector_kind),
4169 integer_zero_node);
4171 tmp = build1_v (GOTO_EXPR, exit_label);
4172 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
4173 cond, tmp, build_empty_stmt (input_location));
4174 gfc_add_expr_to_block (&block, tmp);
4176 /* The main loop body. */
4177 gfc_add_expr_to_block (&block, body);
4179 /* Increment the loop variable. */
4180 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var,
4181 step);
4182 gfc_add_modify (&block, var, tmp);
4184 /* Advance to the next mask element. Only do this for the
4185 innermost loop. */
4186 if (n == 0 && mask_flag && forall_tmp->mask)
4188 tree maskindex = forall_tmp->maskindex;
4189 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4190 maskindex, gfc_index_one_node);
4191 gfc_add_modify (&block, maskindex, tmp);
4194 /* Decrement the loop counter. */
4195 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), count,
4196 build_int_cst (TREE_TYPE (var), 1));
4197 gfc_add_modify (&block, count, tmp);
4199 body = gfc_finish_block (&block);
4201 /* Loop var initialization. */
4202 gfc_init_block (&block);
4203 gfc_add_modify (&block, var, start);
4206 /* Initialize the loop counter. */
4207 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), step,
4208 start);
4209 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), end,
4210 tmp);
4211 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (var),
4212 tmp, step);
4213 gfc_add_modify (&block, count, tmp);
4215 /* The loop expression. */
4216 tmp = build1_v (LOOP_EXPR, body);
4217 gfc_add_expr_to_block (&block, tmp);
4219 /* The exit label. */
4220 tmp = build1_v (LABEL_EXPR, exit_label);
4221 gfc_add_expr_to_block (&block, tmp);
4223 body = gfc_finish_block (&block);
4224 iter = iter->next;
4226 return body;
4230 /* Generate the body and loops according to MASK_FLAG. If MASK_FLAG
4231 is nonzero, the body is controlled by all masks in the forall nest.
4232 Otherwise, the innermost loop is not controlled by it's mask. This
4233 is used for initializing that mask. */
4235 static tree
4236 gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
4237 int mask_flag)
4239 tree tmp;
4240 stmtblock_t header;
4241 forall_info *forall_tmp;
4242 tree mask, maskindex;
4244 gfc_start_block (&header);
4246 forall_tmp = nested_forall_info;
4247 while (forall_tmp != NULL)
4249 /* Generate body with masks' control. */
4250 if (mask_flag)
4252 mask = forall_tmp->mask;
4253 maskindex = forall_tmp->maskindex;
4255 /* If a mask was specified make the assignment conditional. */
4256 if (mask)
4258 tmp = gfc_build_array_ref (mask, maskindex, NULL);
4259 body = build3_v (COND_EXPR, tmp, body,
4260 build_empty_stmt (input_location));
4263 body = gfc_trans_forall_loop (forall_tmp, body, mask_flag, &header);
4264 forall_tmp = forall_tmp->prev_nest;
4265 mask_flag = 1;
4268 gfc_add_expr_to_block (&header, body);
4269 return gfc_finish_block (&header);
4273 /* Allocate data for holding a temporary array. Returns either a local
4274 temporary array or a pointer variable. */
4276 static tree
4277 gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
4278 tree elem_type)
4280 tree tmpvar;
4281 tree type;
4282 tree tmp;
4284 if (INTEGER_CST_P (size))
4285 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
4286 size, gfc_index_one_node);
4287 else
4288 tmp = NULL_TREE;
4290 type = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
4291 type = build_array_type (elem_type, type);
4292 if (gfc_can_put_var_on_stack (bytesize) && INTEGER_CST_P (size))
4294 tmpvar = gfc_create_var (type, "temp");
4295 *pdata = NULL_TREE;
4297 else
4299 tmpvar = gfc_create_var (build_pointer_type (type), "temp");
4300 *pdata = convert (pvoid_type_node, tmpvar);
4302 tmp = gfc_call_malloc (pblock, TREE_TYPE (tmpvar), bytesize);
4303 gfc_add_modify (pblock, tmpvar, tmp);
4305 return tmpvar;
4309 /* Generate codes to copy the temporary to the actual lhs. */
4311 static tree
4312 generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
4313 tree count1,
4314 gfc_ss *lss, gfc_ss *rss,
4315 tree wheremask, bool invert)
4317 stmtblock_t block, body1;
4318 gfc_loopinfo loop;
4319 gfc_se lse;
4320 gfc_se rse;
4321 tree tmp;
4322 tree wheremaskexpr;
4324 (void) rss; /* TODO: unused. */
4326 gfc_start_block (&block);
4328 gfc_init_se (&rse, NULL);
4329 gfc_init_se (&lse, NULL);
4331 if (lss == gfc_ss_terminator)
4333 gfc_init_block (&body1);
4334 gfc_conv_expr (&lse, expr);
4335 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
4337 else
4339 /* Initialize the loop. */
4340 gfc_init_loopinfo (&loop);
4342 /* We may need LSS to determine the shape of the expression. */
4343 gfc_add_ss_to_loop (&loop, lss);
4345 gfc_conv_ss_startstride (&loop);
4346 gfc_conv_loop_setup (&loop, &expr->where);
4348 gfc_mark_ss_chain_used (lss, 1);
4349 /* Start the loop body. */
4350 gfc_start_scalarized_body (&loop, &body1);
4352 /* Translate the expression. */
4353 gfc_copy_loopinfo_to_se (&lse, &loop);
4354 lse.ss = lss;
4355 gfc_conv_expr (&lse, expr);
4357 /* Form the expression of the temporary. */
4358 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
4361 /* Use the scalar assignment. */
4362 rse.string_length = lse.string_length;
4363 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts,
4364 expr->expr_type == EXPR_VARIABLE, false);
4366 /* Form the mask expression according to the mask tree list. */
4367 if (wheremask)
4369 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
4370 if (invert)
4371 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
4372 TREE_TYPE (wheremaskexpr),
4373 wheremaskexpr);
4374 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
4375 wheremaskexpr, tmp,
4376 build_empty_stmt (input_location));
4379 gfc_add_expr_to_block (&body1, tmp);
4381 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
4382 count1, gfc_index_one_node);
4383 gfc_add_modify (&body1, count1, tmp);
4385 if (lss == gfc_ss_terminator)
4386 gfc_add_block_to_block (&block, &body1);
4387 else
4389 /* Increment count3. */
4390 if (count3)
4392 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4393 gfc_array_index_type,
4394 count3, gfc_index_one_node);
4395 gfc_add_modify (&body1, count3, tmp);
4398 /* Generate the copying loops. */
4399 gfc_trans_scalarizing_loops (&loop, &body1);
4401 gfc_add_block_to_block (&block, &loop.pre);
4402 gfc_add_block_to_block (&block, &loop.post);
4404 gfc_cleanup_loop (&loop);
4405 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
4406 as tree nodes in SS may not be valid in different scope. */
4409 tmp = gfc_finish_block (&block);
4410 return tmp;
4414 /* Generate codes to copy rhs to the temporary. TMP1 is the address of
4415 temporary, LSS and RSS are formed in function compute_inner_temp_size(),
4416 and should not be freed. WHEREMASK is the conditional execution mask
4417 whose sense may be inverted by INVERT. */
4419 static tree
4420 generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree count3,
4421 tree count1, gfc_ss *lss, gfc_ss *rss,
4422 tree wheremask, bool invert)
4424 stmtblock_t block, body1;
4425 gfc_loopinfo loop;
4426 gfc_se lse;
4427 gfc_se rse;
4428 tree tmp;
4429 tree wheremaskexpr;
4431 gfc_start_block (&block);
4433 gfc_init_se (&rse, NULL);
4434 gfc_init_se (&lse, NULL);
4436 if (lss == gfc_ss_terminator)
4438 gfc_init_block (&body1);
4439 gfc_conv_expr (&rse, expr2);
4440 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
4442 else
4444 /* Initialize the loop. */
4445 gfc_init_loopinfo (&loop);
4447 /* We may need LSS to determine the shape of the expression. */
4448 gfc_add_ss_to_loop (&loop, lss);
4449 gfc_add_ss_to_loop (&loop, rss);
4451 gfc_conv_ss_startstride (&loop);
4452 gfc_conv_loop_setup (&loop, &expr2->where);
4454 gfc_mark_ss_chain_used (rss, 1);
4455 /* Start the loop body. */
4456 gfc_start_scalarized_body (&loop, &body1);
4458 /* Translate the expression. */
4459 gfc_copy_loopinfo_to_se (&rse, &loop);
4460 rse.ss = rss;
4461 gfc_conv_expr (&rse, expr2);
4463 /* Form the expression of the temporary. */
4464 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
4467 /* Use the scalar assignment. */
4468 lse.string_length = rse.string_length;
4469 tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts,
4470 expr2->expr_type == EXPR_VARIABLE, false);
4472 /* Form the mask expression according to the mask tree list. */
4473 if (wheremask)
4475 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
4476 if (invert)
4477 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
4478 TREE_TYPE (wheremaskexpr),
4479 wheremaskexpr);
4480 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
4481 wheremaskexpr, tmp,
4482 build_empty_stmt (input_location));
4485 gfc_add_expr_to_block (&body1, tmp);
4487 if (lss == gfc_ss_terminator)
4489 gfc_add_block_to_block (&block, &body1);
4491 /* Increment count1. */
4492 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
4493 count1, gfc_index_one_node);
4494 gfc_add_modify (&block, count1, tmp);
4496 else
4498 /* Increment count1. */
4499 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4500 count1, gfc_index_one_node);
4501 gfc_add_modify (&body1, count1, tmp);
4503 /* Increment count3. */
4504 if (count3)
4506 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4507 gfc_array_index_type,
4508 count3, gfc_index_one_node);
4509 gfc_add_modify (&body1, count3, tmp);
4512 /* Generate the copying loops. */
4513 gfc_trans_scalarizing_loops (&loop, &body1);
4515 gfc_add_block_to_block (&block, &loop.pre);
4516 gfc_add_block_to_block (&block, &loop.post);
4518 gfc_cleanup_loop (&loop);
4519 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
4520 as tree nodes in SS may not be valid in different scope. */
4523 tmp = gfc_finish_block (&block);
4524 return tmp;
4528 /* Calculate the size of temporary needed in the assignment inside forall.
4529 LSS and RSS are filled in this function. */
4531 static tree
4532 compute_inner_temp_size (gfc_expr *expr1, gfc_expr *expr2,
4533 stmtblock_t * pblock,
4534 gfc_ss **lss, gfc_ss **rss)
4536 gfc_loopinfo loop;
4537 tree size;
4538 int i;
4539 int save_flag;
4540 tree tmp;
4542 *lss = gfc_walk_expr (expr1);
4543 *rss = NULL;
4545 size = gfc_index_one_node;
4546 if (*lss != gfc_ss_terminator)
4548 gfc_init_loopinfo (&loop);
4550 /* Walk the RHS of the expression. */
4551 *rss = gfc_walk_expr (expr2);
4552 if (*rss == gfc_ss_terminator)
4553 /* The rhs is scalar. Add a ss for the expression. */
4554 *rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
4556 /* Associate the SS with the loop. */
4557 gfc_add_ss_to_loop (&loop, *lss);
4558 /* We don't actually need to add the rhs at this point, but it might
4559 make guessing the loop bounds a bit easier. */
4560 gfc_add_ss_to_loop (&loop, *rss);
4562 /* We only want the shape of the expression, not rest of the junk
4563 generated by the scalarizer. */
4564 loop.array_parameter = 1;
4566 /* Calculate the bounds of the scalarization. */
4567 save_flag = gfc_option.rtcheck;
4568 gfc_option.rtcheck &= ~GFC_RTCHECK_BOUNDS;
4569 gfc_conv_ss_startstride (&loop);
4570 gfc_option.rtcheck = save_flag;
4571 gfc_conv_loop_setup (&loop, &expr2->where);
4573 /* Figure out how many elements we need. */
4574 for (i = 0; i < loop.dimen; i++)
4576 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4577 gfc_array_index_type,
4578 gfc_index_one_node, loop.from[i]);
4579 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4580 gfc_array_index_type, tmp, loop.to[i]);
4581 size = fold_build2_loc (input_location, MULT_EXPR,
4582 gfc_array_index_type, size, tmp);
4584 gfc_add_block_to_block (pblock, &loop.pre);
4585 size = gfc_evaluate_now (size, pblock);
4586 gfc_add_block_to_block (pblock, &loop.post);
4588 /* TODO: write a function that cleans up a loopinfo without freeing
4589 the SS chains. Currently a NOP. */
4592 return size;
4596 /* Calculate the overall iterator number of the nested forall construct.
4597 This routine actually calculates the number of times the body of the
4598 nested forall specified by NESTED_FORALL_INFO is executed and multiplies
4599 that by the expression INNER_SIZE. The BLOCK argument specifies the
4600 block in which to calculate the result, and the optional INNER_SIZE_BODY
4601 argument contains any statements that need to executed (inside the loop)
4602 to initialize or calculate INNER_SIZE. */
4604 static tree
4605 compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
4606 stmtblock_t *inner_size_body, stmtblock_t *block)
4608 forall_info *forall_tmp = nested_forall_info;
4609 tree tmp, number;
4610 stmtblock_t body;
4612 /* We can eliminate the innermost unconditional loops with constant
4613 array bounds. */
4614 if (INTEGER_CST_P (inner_size))
4616 while (forall_tmp
4617 && !forall_tmp->mask
4618 && INTEGER_CST_P (forall_tmp->size))
4620 inner_size = fold_build2_loc (input_location, MULT_EXPR,
4621 gfc_array_index_type,
4622 inner_size, forall_tmp->size);
4623 forall_tmp = forall_tmp->prev_nest;
4626 /* If there are no loops left, we have our constant result. */
4627 if (!forall_tmp)
4628 return inner_size;
4631 /* Otherwise, create a temporary variable to compute the result. */
4632 number = gfc_create_var (gfc_array_index_type, "num");
4633 gfc_add_modify (block, number, gfc_index_zero_node);
4635 gfc_start_block (&body);
4636 if (inner_size_body)
4637 gfc_add_block_to_block (&body, inner_size_body);
4638 if (forall_tmp)
4639 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4640 gfc_array_index_type, number, inner_size);
4641 else
4642 tmp = inner_size;
4643 gfc_add_modify (&body, number, tmp);
4644 tmp = gfc_finish_block (&body);
4646 /* Generate loops. */
4647 if (forall_tmp != NULL)
4648 tmp = gfc_trans_nested_forall_loop (forall_tmp, tmp, 1);
4650 gfc_add_expr_to_block (block, tmp);
4652 return number;
4656 /* Allocate temporary for forall construct. SIZE is the size of temporary
4657 needed. PTEMP1 is returned for space free. */
4659 static tree
4660 allocate_temp_for_forall_nest_1 (tree type, tree size, stmtblock_t * block,
4661 tree * ptemp1)
4663 tree bytesize;
4664 tree unit;
4665 tree tmp;
4667 unit = fold_convert (gfc_array_index_type, TYPE_SIZE_UNIT (type));
4668 if (!integer_onep (unit))
4669 bytesize = fold_build2_loc (input_location, MULT_EXPR,
4670 gfc_array_index_type, size, unit);
4671 else
4672 bytesize = size;
4674 *ptemp1 = NULL;
4675 tmp = gfc_do_allocate (bytesize, size, ptemp1, block, type);
4677 if (*ptemp1)
4678 tmp = build_fold_indirect_ref_loc (input_location, tmp);
4679 return tmp;
4683 /* Allocate temporary for forall construct according to the information in
4684 nested_forall_info. INNER_SIZE is the size of temporary needed in the
4685 assignment inside forall. PTEMP1 is returned for space free. */
4687 static tree
4688 allocate_temp_for_forall_nest (forall_info * nested_forall_info, tree type,
4689 tree inner_size, stmtblock_t * inner_size_body,
4690 stmtblock_t * block, tree * ptemp1)
4692 tree size;
4694 /* Calculate the total size of temporary needed in forall construct. */
4695 size = compute_overall_iter_number (nested_forall_info, inner_size,
4696 inner_size_body, block);
4698 return allocate_temp_for_forall_nest_1 (type, size, block, ptemp1);
4702 /* Handle assignments inside forall which need temporary.
4704 forall (i=start:end:stride; maskexpr)
4705 e<i> = f<i>
4706 end forall
4707 (where e,f<i> are arbitrary expressions possibly involving i
4708 and there is a dependency between e<i> and f<i>)
4709 Translates to:
4710 masktmp(:) = maskexpr(:)
4712 maskindex = 0;
4713 count1 = 0;
4714 num = 0;
4715 for (i = start; i <= end; i += stride)
4716 num += SIZE (f<i>)
4717 count1 = 0;
4718 ALLOCATE (tmp(num))
4719 for (i = start; i <= end; i += stride)
4721 if (masktmp[maskindex++])
4722 tmp[count1++] = f<i>
4724 maskindex = 0;
4725 count1 = 0;
4726 for (i = start; i <= end; i += stride)
4728 if (masktmp[maskindex++])
4729 e<i> = tmp[count1++]
4731 DEALLOCATE (tmp)
4733 static void
4734 gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
4735 tree wheremask, bool invert,
4736 forall_info * nested_forall_info,
4737 stmtblock_t * block)
4739 tree type;
4740 tree inner_size;
4741 gfc_ss *lss, *rss;
4742 tree count, count1;
4743 tree tmp, tmp1;
4744 tree ptemp1;
4745 stmtblock_t inner_size_body;
4747 /* Create vars. count1 is the current iterator number of the nested
4748 forall. */
4749 count1 = gfc_create_var (gfc_array_index_type, "count1");
4751 /* Count is the wheremask index. */
4752 if (wheremask)
4754 count = gfc_create_var (gfc_array_index_type, "count");
4755 gfc_add_modify (block, count, gfc_index_zero_node);
4757 else
4758 count = NULL;
4760 /* Initialize count1. */
4761 gfc_add_modify (block, count1, gfc_index_zero_node);
4763 /* Calculate the size of temporary needed in the assignment. Return loop, lss
4764 and rss which are used in function generate_loop_for_rhs_to_temp(). */
4765 /* The type of LHS. Used in function allocate_temp_for_forall_nest */
4766 if (expr1->ts.type == BT_CHARACTER)
4768 type = NULL;
4769 if (expr1->ref && expr1->ref->type == REF_SUBSTRING)
4771 gfc_se ssse;
4772 gfc_init_se (&ssse, NULL);
4773 gfc_conv_expr (&ssse, expr1);
4774 type = gfc_get_character_type_len (gfc_default_character_kind,
4775 ssse.string_length);
4777 else
4779 if (!expr1->ts.u.cl->backend_decl)
4781 gfc_se tse;
4782 gcc_assert (expr1->ts.u.cl->length);
4783 gfc_init_se (&tse, NULL);
4784 gfc_conv_expr (&tse, expr1->ts.u.cl->length);
4785 expr1->ts.u.cl->backend_decl = tse.expr;
4787 type = gfc_get_character_type_len (gfc_default_character_kind,
4788 expr1->ts.u.cl->backend_decl);
4791 else
4792 type = gfc_typenode_for_spec (&expr1->ts);
4794 gfc_init_block (&inner_size_body);
4795 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
4796 &lss, &rss);
4798 /* Allocate temporary for nested forall construct according to the
4799 information in nested_forall_info and inner_size. */
4800 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type, inner_size,
4801 &inner_size_body, block, &ptemp1);
4803 /* Generate codes to copy rhs to the temporary . */
4804 tmp = generate_loop_for_rhs_to_temp (expr2, tmp1, count, count1, lss, rss,
4805 wheremask, invert);
4807 /* Generate body and loops according to the information in
4808 nested_forall_info. */
4809 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4810 gfc_add_expr_to_block (block, tmp);
4812 /* Reset count1. */
4813 gfc_add_modify (block, count1, gfc_index_zero_node);
4815 /* Reset count. */
4816 if (wheremask)
4817 gfc_add_modify (block, count, gfc_index_zero_node);
4819 /* TODO: Second call to compute_inner_temp_size to initialize lss and
4820 rss; there must be a better way. */
4821 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
4822 &lss, &rss);
4824 /* Generate codes to copy the temporary to lhs. */
4825 tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, count, count1,
4826 lss, rss,
4827 wheremask, invert);
4829 /* Generate body and loops according to the information in
4830 nested_forall_info. */
4831 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4832 gfc_add_expr_to_block (block, tmp);
4834 if (ptemp1)
4836 /* Free the temporary. */
4837 tmp = gfc_call_free (ptemp1);
4838 gfc_add_expr_to_block (block, tmp);
4843 /* Translate pointer assignment inside FORALL which need temporary. */
4845 static void
4846 gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
4847 forall_info * nested_forall_info,
4848 stmtblock_t * block)
4850 tree type;
4851 tree inner_size;
4852 gfc_ss *lss, *rss;
4853 gfc_se lse;
4854 gfc_se rse;
4855 gfc_array_info *info;
4856 gfc_loopinfo loop;
4857 tree desc;
4858 tree parm;
4859 tree parmtype;
4860 stmtblock_t body;
4861 tree count;
4862 tree tmp, tmp1, ptemp1;
4864 count = gfc_create_var (gfc_array_index_type, "count");
4865 gfc_add_modify (block, count, gfc_index_zero_node);
4867 inner_size = gfc_index_one_node;
4868 lss = gfc_walk_expr (expr1);
4869 rss = gfc_walk_expr (expr2);
4870 if (lss == gfc_ss_terminator)
4872 type = gfc_typenode_for_spec (&expr1->ts);
4873 type = build_pointer_type (type);
4875 /* Allocate temporary for nested forall construct according to the
4876 information in nested_forall_info and inner_size. */
4877 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type,
4878 inner_size, NULL, block, &ptemp1);
4879 gfc_start_block (&body);
4880 gfc_init_se (&lse, NULL);
4881 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
4882 gfc_init_se (&rse, NULL);
4883 rse.want_pointer = 1;
4884 gfc_conv_expr (&rse, expr2);
4885 gfc_add_block_to_block (&body, &rse.pre);
4886 gfc_add_modify (&body, lse.expr,
4887 fold_convert (TREE_TYPE (lse.expr), rse.expr));
4888 gfc_add_block_to_block (&body, &rse.post);
4890 /* Increment count. */
4891 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4892 count, gfc_index_one_node);
4893 gfc_add_modify (&body, count, tmp);
4895 tmp = gfc_finish_block (&body);
4897 /* Generate body and loops according to the information in
4898 nested_forall_info. */
4899 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4900 gfc_add_expr_to_block (block, tmp);
4902 /* Reset count. */
4903 gfc_add_modify (block, count, gfc_index_zero_node);
4905 gfc_start_block (&body);
4906 gfc_init_se (&lse, NULL);
4907 gfc_init_se (&rse, NULL);
4908 rse.expr = gfc_build_array_ref (tmp1, count, NULL);
4909 lse.want_pointer = 1;
4910 gfc_conv_expr (&lse, expr1);
4911 gfc_add_block_to_block (&body, &lse.pre);
4912 gfc_add_modify (&body, lse.expr, rse.expr);
4913 gfc_add_block_to_block (&body, &lse.post);
4914 /* Increment count. */
4915 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4916 count, gfc_index_one_node);
4917 gfc_add_modify (&body, count, tmp);
4918 tmp = gfc_finish_block (&body);
4920 /* Generate body and loops according to the information in
4921 nested_forall_info. */
4922 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4923 gfc_add_expr_to_block (block, tmp);
4925 else
4927 gfc_init_loopinfo (&loop);
4929 /* Associate the SS with the loop. */
4930 gfc_add_ss_to_loop (&loop, rss);
4932 /* Setup the scalarizing loops and bounds. */
4933 gfc_conv_ss_startstride (&loop);
4935 gfc_conv_loop_setup (&loop, &expr2->where);
4937 info = &rss->info->data.array;
4938 desc = info->descriptor;
4940 /* Make a new descriptor. */
4941 parmtype = gfc_get_element_type (TREE_TYPE (desc));
4942 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0,
4943 loop.from, loop.to, 1,
4944 GFC_ARRAY_UNKNOWN, true);
4946 /* Allocate temporary for nested forall construct. */
4947 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
4948 inner_size, NULL, block, &ptemp1);
4949 gfc_start_block (&body);
4950 gfc_init_se (&lse, NULL);
4951 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
4952 lse.direct_byref = 1;
4953 gfc_conv_expr_descriptor (&lse, expr2);
4955 gfc_add_block_to_block (&body, &lse.pre);
4956 gfc_add_block_to_block (&body, &lse.post);
4958 /* Increment count. */
4959 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4960 count, gfc_index_one_node);
4961 gfc_add_modify (&body, count, tmp);
4963 tmp = gfc_finish_block (&body);
4965 /* Generate body and loops according to the information in
4966 nested_forall_info. */
4967 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4968 gfc_add_expr_to_block (block, tmp);
4970 /* Reset count. */
4971 gfc_add_modify (block, count, gfc_index_zero_node);
4973 parm = gfc_build_array_ref (tmp1, count, NULL);
4974 gfc_init_se (&lse, NULL);
4975 gfc_conv_expr_descriptor (&lse, expr1);
4976 gfc_add_modify (&lse.pre, lse.expr, parm);
4977 gfc_start_block (&body);
4978 gfc_add_block_to_block (&body, &lse.pre);
4979 gfc_add_block_to_block (&body, &lse.post);
4981 /* Increment count. */
4982 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4983 count, gfc_index_one_node);
4984 gfc_add_modify (&body, count, tmp);
4986 tmp = gfc_finish_block (&body);
4988 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4989 gfc_add_expr_to_block (block, tmp);
4991 /* Free the temporary. */
4992 if (ptemp1)
4994 tmp = gfc_call_free (ptemp1);
4995 gfc_add_expr_to_block (block, tmp);
5000 /* FORALL and WHERE statements are really nasty, especially when you nest
5001 them. All the rhs of a forall assignment must be evaluated before the
5002 actual assignments are performed. Presumably this also applies to all the
5003 assignments in an inner where statement. */
5005 /* Generate code for a FORALL statement. Any temporaries are allocated as a
5006 linear array, relying on the fact that we process in the same order in all
5007 loops.
5009 forall (i=start:end:stride; maskexpr)
5010 e<i> = f<i>
5011 g<i> = h<i>
5012 end forall
5013 (where e,f,g,h<i> are arbitrary expressions possibly involving i)
5014 Translates to:
5015 count = ((end + 1 - start) / stride)
5016 masktmp(:) = maskexpr(:)
5018 maskindex = 0;
5019 for (i = start; i <= end; i += stride)
5021 if (masktmp[maskindex++])
5022 e<i> = f<i>
5024 maskindex = 0;
5025 for (i = start; i <= end; i += stride)
5027 if (masktmp[maskindex++])
5028 g<i> = h<i>
5031 Note that this code only works when there are no dependencies.
5032 Forall loop with array assignments and data dependencies are a real pain,
5033 because the size of the temporary cannot always be determined before the
5034 loop is executed. This problem is compounded by the presence of nested
5035 FORALL constructs.
5038 static tree
5039 gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
5041 stmtblock_t pre;
5042 stmtblock_t post;
5043 stmtblock_t block;
5044 stmtblock_t body;
5045 tree *var;
5046 tree *start;
5047 tree *end;
5048 tree *step;
5049 gfc_expr **varexpr;
5050 tree tmp;
5051 tree assign;
5052 tree size;
5053 tree maskindex;
5054 tree mask;
5055 tree pmask;
5056 tree cycle_label = NULL_TREE;
5057 int n;
5058 int nvar;
5059 int need_temp;
5060 gfc_forall_iterator *fa;
5061 gfc_se se;
5062 gfc_code *c;
5063 gfc_saved_var *saved_vars;
5064 iter_info *this_forall;
5065 forall_info *info;
5066 bool need_mask;
5068 /* Do nothing if the mask is false. */
5069 if (code->expr1
5070 && code->expr1->expr_type == EXPR_CONSTANT
5071 && !code->expr1->value.logical)
5072 return build_empty_stmt (input_location);
5074 n = 0;
5075 /* Count the FORALL index number. */
5076 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
5077 n++;
5078 nvar = n;
5080 /* Allocate the space for var, start, end, step, varexpr. */
5081 var = XCNEWVEC (tree, nvar);
5082 start = XCNEWVEC (tree, nvar);
5083 end = XCNEWVEC (tree, nvar);
5084 step = XCNEWVEC (tree, nvar);
5085 varexpr = XCNEWVEC (gfc_expr *, nvar);
5086 saved_vars = XCNEWVEC (gfc_saved_var, nvar);
5088 /* Allocate the space for info. */
5089 info = XCNEW (forall_info);
5091 gfc_start_block (&pre);
5092 gfc_init_block (&post);
5093 gfc_init_block (&block);
5095 n = 0;
5096 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
5098 gfc_symbol *sym = fa->var->symtree->n.sym;
5100 /* Allocate space for this_forall. */
5101 this_forall = XCNEW (iter_info);
5103 /* Create a temporary variable for the FORALL index. */
5104 tmp = gfc_typenode_for_spec (&sym->ts);
5105 var[n] = gfc_create_var (tmp, sym->name);
5106 gfc_shadow_sym (sym, var[n], &saved_vars[n]);
5108 /* Record it in this_forall. */
5109 this_forall->var = var[n];
5111 /* Replace the index symbol's backend_decl with the temporary decl. */
5112 sym->backend_decl = var[n];
5114 /* Work out the start, end and stride for the loop. */
5115 gfc_init_se (&se, NULL);
5116 gfc_conv_expr_val (&se, fa->start);
5117 /* Record it in this_forall. */
5118 this_forall->start = se.expr;
5119 gfc_add_block_to_block (&block, &se.pre);
5120 start[n] = se.expr;
5122 gfc_init_se (&se, NULL);
5123 gfc_conv_expr_val (&se, fa->end);
5124 /* Record it in this_forall. */
5125 this_forall->end = se.expr;
5126 gfc_make_safe_expr (&se);
5127 gfc_add_block_to_block (&block, &se.pre);
5128 end[n] = se.expr;
5130 gfc_init_se (&se, NULL);
5131 gfc_conv_expr_val (&se, fa->stride);
5132 /* Record it in this_forall. */
5133 this_forall->step = se.expr;
5134 gfc_make_safe_expr (&se);
5135 gfc_add_block_to_block (&block, &se.pre);
5136 step[n] = se.expr;
5138 /* Copy loop annotations. */
5139 this_forall->annot = fa->annot;
5141 /* Set the NEXT field of this_forall to NULL. */
5142 this_forall->next = NULL;
5143 /* Link this_forall to the info construct. */
5144 if (info->this_loop)
5146 iter_info *iter_tmp = info->this_loop;
5147 while (iter_tmp->next != NULL)
5148 iter_tmp = iter_tmp->next;
5149 iter_tmp->next = this_forall;
5151 else
5152 info->this_loop = this_forall;
5154 n++;
5156 nvar = n;
5158 /* Calculate the size needed for the current forall level. */
5159 size = gfc_index_one_node;
5160 for (n = 0; n < nvar; n++)
5162 /* size = (end + step - start) / step. */
5163 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (start[n]),
5164 step[n], start[n]);
5165 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (end[n]),
5166 end[n], tmp);
5167 tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, TREE_TYPE (tmp),
5168 tmp, step[n]);
5169 tmp = convert (gfc_array_index_type, tmp);
5171 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5172 size, tmp);
5175 /* Record the nvar and size of current forall level. */
5176 info->nvar = nvar;
5177 info->size = size;
5179 if (code->expr1)
5181 /* If the mask is .true., consider the FORALL unconditional. */
5182 if (code->expr1->expr_type == EXPR_CONSTANT
5183 && code->expr1->value.logical)
5184 need_mask = false;
5185 else
5186 need_mask = true;
5188 else
5189 need_mask = false;
5191 /* First we need to allocate the mask. */
5192 if (need_mask)
5194 /* As the mask array can be very big, prefer compact boolean types. */
5195 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
5196 mask = allocate_temp_for_forall_nest (nested_forall_info, mask_type,
5197 size, NULL, &block, &pmask);
5198 maskindex = gfc_create_var_np (gfc_array_index_type, "mi");
5200 /* Record them in the info structure. */
5201 info->maskindex = maskindex;
5202 info->mask = mask;
5204 else
5206 /* No mask was specified. */
5207 maskindex = NULL_TREE;
5208 mask = pmask = NULL_TREE;
5211 /* Link the current forall level to nested_forall_info. */
5212 info->prev_nest = nested_forall_info;
5213 nested_forall_info = info;
5215 /* Copy the mask into a temporary variable if required.
5216 For now we assume a mask temporary is needed. */
5217 if (need_mask)
5219 /* As the mask array can be very big, prefer compact boolean types. */
5220 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
5222 gfc_add_modify (&block, maskindex, gfc_index_zero_node);
5224 /* Start of mask assignment loop body. */
5225 gfc_start_block (&body);
5227 /* Evaluate the mask expression. */
5228 gfc_init_se (&se, NULL);
5229 gfc_conv_expr_val (&se, code->expr1);
5230 gfc_add_block_to_block (&body, &se.pre);
5232 /* Store the mask. */
5233 se.expr = convert (mask_type, se.expr);
5235 tmp = gfc_build_array_ref (mask, maskindex, NULL);
5236 gfc_add_modify (&body, tmp, se.expr);
5238 /* Advance to the next mask element. */
5239 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5240 maskindex, gfc_index_one_node);
5241 gfc_add_modify (&body, maskindex, tmp);
5243 /* Generate the loops. */
5244 tmp = gfc_finish_block (&body);
5245 tmp = gfc_trans_nested_forall_loop (info, tmp, 0);
5246 gfc_add_expr_to_block (&block, tmp);
5249 if (code->op == EXEC_DO_CONCURRENT)
5251 gfc_init_block (&body);
5252 cycle_label = gfc_build_label_decl (NULL_TREE);
5253 code->cycle_label = cycle_label;
5254 tmp = gfc_trans_code (code->block->next);
5255 gfc_add_expr_to_block (&body, tmp);
5257 if (TREE_USED (cycle_label))
5259 tmp = build1_v (LABEL_EXPR, cycle_label);
5260 gfc_add_expr_to_block (&body, tmp);
5263 tmp = gfc_finish_block (&body);
5264 nested_forall_info->do_concurrent = true;
5265 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
5266 gfc_add_expr_to_block (&block, tmp);
5267 goto done;
5270 c = code->block->next;
5272 /* TODO: loop merging in FORALL statements. */
5273 /* Now that we've got a copy of the mask, generate the assignment loops. */
5274 while (c)
5276 switch (c->op)
5278 case EXEC_ASSIGN:
5279 /* A scalar or array assignment. DO the simple check for
5280 lhs to rhs dependencies. These make a temporary for the
5281 rhs and form a second forall block to copy to variable. */
5282 need_temp = check_forall_dependencies(c, &pre, &post);
5284 /* Temporaries due to array assignment data dependencies introduce
5285 no end of problems. */
5286 if (need_temp || flag_test_forall_temp)
5287 gfc_trans_assign_need_temp (c->expr1, c->expr2, NULL, false,
5288 nested_forall_info, &block);
5289 else
5291 /* Use the normal assignment copying routines. */
5292 assign = gfc_trans_assignment (c->expr1, c->expr2, false, true);
5294 /* Generate body and loops. */
5295 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
5296 assign, 1);
5297 gfc_add_expr_to_block (&block, tmp);
5300 /* Cleanup any temporary symtrees that have been made to deal
5301 with dependencies. */
5302 if (new_symtree)
5303 cleanup_forall_symtrees (c);
5305 break;
5307 case EXEC_WHERE:
5308 /* Translate WHERE or WHERE construct nested in FORALL. */
5309 gfc_trans_where_2 (c, NULL, false, nested_forall_info, &block);
5310 break;
5312 /* Pointer assignment inside FORALL. */
5313 case EXEC_POINTER_ASSIGN:
5314 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
5315 /* Avoid cases where a temporary would never be needed and where
5316 the temp code is guaranteed to fail. */
5317 if (need_temp
5318 || (flag_test_forall_temp
5319 && c->expr2->expr_type != EXPR_CONSTANT
5320 && c->expr2->expr_type != EXPR_NULL))
5321 gfc_trans_pointer_assign_need_temp (c->expr1, c->expr2,
5322 nested_forall_info, &block);
5323 else
5325 /* Use the normal assignment copying routines. */
5326 assign = gfc_trans_pointer_assignment (c->expr1, c->expr2);
5328 /* Generate body and loops. */
5329 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
5330 assign, 1);
5331 gfc_add_expr_to_block (&block, tmp);
5333 break;
5335 case EXEC_FORALL:
5336 tmp = gfc_trans_forall_1 (c, nested_forall_info);
5337 gfc_add_expr_to_block (&block, tmp);
5338 break;
5340 /* Explicit subroutine calls are prevented by the frontend but interface
5341 assignments can legitimately produce them. */
5342 case EXEC_ASSIGN_CALL:
5343 assign = gfc_trans_call (c, true, NULL_TREE, NULL_TREE, false);
5344 tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign, 1);
5345 gfc_add_expr_to_block (&block, tmp);
5346 break;
5348 default:
5349 gcc_unreachable ();
5352 c = c->next;
5355 done:
5356 /* Restore the original index variables. */
5357 for (fa = code->ext.forall_iterator, n = 0; fa; fa = fa->next, n++)
5358 gfc_restore_sym (fa->var->symtree->n.sym, &saved_vars[n]);
5360 /* Free the space for var, start, end, step, varexpr. */
5361 free (var);
5362 free (start);
5363 free (end);
5364 free (step);
5365 free (varexpr);
5366 free (saved_vars);
5368 for (this_forall = info->this_loop; this_forall;)
5370 iter_info *next = this_forall->next;
5371 free (this_forall);
5372 this_forall = next;
5375 /* Free the space for this forall_info. */
5376 free (info);
5378 if (pmask)
5380 /* Free the temporary for the mask. */
5381 tmp = gfc_call_free (pmask);
5382 gfc_add_expr_to_block (&block, tmp);
5384 if (maskindex)
5385 pushdecl (maskindex);
5387 gfc_add_block_to_block (&pre, &block);
5388 gfc_add_block_to_block (&pre, &post);
5390 return gfc_finish_block (&pre);
5394 /* Translate the FORALL statement or construct. */
5396 tree gfc_trans_forall (gfc_code * code)
5398 return gfc_trans_forall_1 (code, NULL);
5402 /* Translate the DO CONCURRENT construct. */
5404 tree gfc_trans_do_concurrent (gfc_code * code)
5406 return gfc_trans_forall_1 (code, NULL);
5410 /* Evaluate the WHERE mask expression, copy its value to a temporary.
5411 If the WHERE construct is nested in FORALL, compute the overall temporary
5412 needed by the WHERE mask expression multiplied by the iterator number of
5413 the nested forall.
5414 ME is the WHERE mask expression.
5415 MASK is the current execution mask upon input, whose sense may or may
5416 not be inverted as specified by the INVERT argument.
5417 CMASK is the updated execution mask on output, or NULL if not required.
5418 PMASK is the pending execution mask on output, or NULL if not required.
5419 BLOCK is the block in which to place the condition evaluation loops. */
5421 static void
5422 gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
5423 tree mask, bool invert, tree cmask, tree pmask,
5424 tree mask_type, stmtblock_t * block)
5426 tree tmp, tmp1;
5427 gfc_ss *lss, *rss;
5428 gfc_loopinfo loop;
5429 stmtblock_t body, body1;
5430 tree count, cond, mtmp;
5431 gfc_se lse, rse;
5433 gfc_init_loopinfo (&loop);
5435 lss = gfc_walk_expr (me);
5436 rss = gfc_walk_expr (me);
5438 /* Variable to index the temporary. */
5439 count = gfc_create_var (gfc_array_index_type, "count");
5440 /* Initialize count. */
5441 gfc_add_modify (block, count, gfc_index_zero_node);
5443 gfc_start_block (&body);
5445 gfc_init_se (&rse, NULL);
5446 gfc_init_se (&lse, NULL);
5448 if (lss == gfc_ss_terminator)
5450 gfc_init_block (&body1);
5452 else
5454 /* Initialize the loop. */
5455 gfc_init_loopinfo (&loop);
5457 /* We may need LSS to determine the shape of the expression. */
5458 gfc_add_ss_to_loop (&loop, lss);
5459 gfc_add_ss_to_loop (&loop, rss);
5461 gfc_conv_ss_startstride (&loop);
5462 gfc_conv_loop_setup (&loop, &me->where);
5464 gfc_mark_ss_chain_used (rss, 1);
5465 /* Start the loop body. */
5466 gfc_start_scalarized_body (&loop, &body1);
5468 /* Translate the expression. */
5469 gfc_copy_loopinfo_to_se (&rse, &loop);
5470 rse.ss = rss;
5471 gfc_conv_expr (&rse, me);
5474 /* Variable to evaluate mask condition. */
5475 cond = gfc_create_var (mask_type, "cond");
5476 if (mask && (cmask || pmask))
5477 mtmp = gfc_create_var (mask_type, "mask");
5478 else mtmp = NULL_TREE;
5480 gfc_add_block_to_block (&body1, &lse.pre);
5481 gfc_add_block_to_block (&body1, &rse.pre);
5483 gfc_add_modify (&body1, cond, fold_convert (mask_type, rse.expr));
5485 if (mask && (cmask || pmask))
5487 tmp = gfc_build_array_ref (mask, count, NULL);
5488 if (invert)
5489 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, tmp);
5490 gfc_add_modify (&body1, mtmp, tmp);
5493 if (cmask)
5495 tmp1 = gfc_build_array_ref (cmask, count, NULL);
5496 tmp = cond;
5497 if (mask)
5498 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type,
5499 mtmp, tmp);
5500 gfc_add_modify (&body1, tmp1, tmp);
5503 if (pmask)
5505 tmp1 = gfc_build_array_ref (pmask, count, NULL);
5506 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, cond);
5507 if (mask)
5508 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type, mtmp,
5509 tmp);
5510 gfc_add_modify (&body1, tmp1, tmp);
5513 gfc_add_block_to_block (&body1, &lse.post);
5514 gfc_add_block_to_block (&body1, &rse.post);
5516 if (lss == gfc_ss_terminator)
5518 gfc_add_block_to_block (&body, &body1);
5520 else
5522 /* Increment count. */
5523 tmp1 = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5524 count, gfc_index_one_node);
5525 gfc_add_modify (&body1, count, tmp1);
5527 /* Generate the copying loops. */
5528 gfc_trans_scalarizing_loops (&loop, &body1);
5530 gfc_add_block_to_block (&body, &loop.pre);
5531 gfc_add_block_to_block (&body, &loop.post);
5533 gfc_cleanup_loop (&loop);
5534 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
5535 as tree nodes in SS may not be valid in different scope. */
5538 tmp1 = gfc_finish_block (&body);
5539 /* If the WHERE construct is inside FORALL, fill the full temporary. */
5540 if (nested_forall_info != NULL)
5541 tmp1 = gfc_trans_nested_forall_loop (nested_forall_info, tmp1, 1);
5543 gfc_add_expr_to_block (block, tmp1);
5547 /* Translate an assignment statement in a WHERE statement or construct
5548 statement. The MASK expression is used to control which elements
5549 of EXPR1 shall be assigned. The sense of MASK is specified by
5550 INVERT. */
5552 static tree
5553 gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
5554 tree mask, bool invert,
5555 tree count1, tree count2,
5556 gfc_code *cnext)
5558 gfc_se lse;
5559 gfc_se rse;
5560 gfc_ss *lss;
5561 gfc_ss *lss_section;
5562 gfc_ss *rss;
5564 gfc_loopinfo loop;
5565 tree tmp;
5566 stmtblock_t block;
5567 stmtblock_t body;
5568 tree index, maskexpr;
5570 /* A defined assignment. */
5571 if (cnext && cnext->resolved_sym)
5572 return gfc_trans_call (cnext, true, mask, count1, invert);
5574 #if 0
5575 /* TODO: handle this special case.
5576 Special case a single function returning an array. */
5577 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
5579 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
5580 if (tmp)
5581 return tmp;
5583 #endif
5585 /* Assignment of the form lhs = rhs. */
5586 gfc_start_block (&block);
5588 gfc_init_se (&lse, NULL);
5589 gfc_init_se (&rse, NULL);
5591 /* Walk the lhs. */
5592 lss = gfc_walk_expr (expr1);
5593 rss = NULL;
5595 /* In each where-assign-stmt, the mask-expr and the variable being
5596 defined shall be arrays of the same shape. */
5597 gcc_assert (lss != gfc_ss_terminator);
5599 /* The assignment needs scalarization. */
5600 lss_section = lss;
5602 /* Find a non-scalar SS from the lhs. */
5603 while (lss_section != gfc_ss_terminator
5604 && lss_section->info->type != GFC_SS_SECTION)
5605 lss_section = lss_section->next;
5607 gcc_assert (lss_section != gfc_ss_terminator);
5609 /* Initialize the scalarizer. */
5610 gfc_init_loopinfo (&loop);
5612 /* Walk the rhs. */
5613 rss = gfc_walk_expr (expr2);
5614 if (rss == gfc_ss_terminator)
5616 /* The rhs is scalar. Add a ss for the expression. */
5617 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
5618 rss->info->where = 1;
5621 /* Associate the SS with the loop. */
5622 gfc_add_ss_to_loop (&loop, lss);
5623 gfc_add_ss_to_loop (&loop, rss);
5625 /* Calculate the bounds of the scalarization. */
5626 gfc_conv_ss_startstride (&loop);
5628 /* Resolve any data dependencies in the statement. */
5629 gfc_conv_resolve_dependencies (&loop, lss_section, rss);
5631 /* Setup the scalarizing loops. */
5632 gfc_conv_loop_setup (&loop, &expr2->where);
5634 /* Setup the gfc_se structures. */
5635 gfc_copy_loopinfo_to_se (&lse, &loop);
5636 gfc_copy_loopinfo_to_se (&rse, &loop);
5638 rse.ss = rss;
5639 gfc_mark_ss_chain_used (rss, 1);
5640 if (loop.temp_ss == NULL)
5642 lse.ss = lss;
5643 gfc_mark_ss_chain_used (lss, 1);
5645 else
5647 lse.ss = loop.temp_ss;
5648 gfc_mark_ss_chain_used (lss, 3);
5649 gfc_mark_ss_chain_used (loop.temp_ss, 3);
5652 /* Start the scalarized loop body. */
5653 gfc_start_scalarized_body (&loop, &body);
5655 /* Translate the expression. */
5656 gfc_conv_expr (&rse, expr2);
5657 if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
5658 gfc_conv_tmp_array_ref (&lse);
5659 else
5660 gfc_conv_expr (&lse, expr1);
5662 /* Form the mask expression according to the mask. */
5663 index = count1;
5664 maskexpr = gfc_build_array_ref (mask, index, NULL);
5665 if (invert)
5666 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
5667 TREE_TYPE (maskexpr), maskexpr);
5669 /* Use the scalar assignment as is. */
5670 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
5671 false, loop.temp_ss == NULL);
5673 tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt (input_location));
5675 gfc_add_expr_to_block (&body, tmp);
5677 if (lss == gfc_ss_terminator)
5679 /* Increment count1. */
5680 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5681 count1, gfc_index_one_node);
5682 gfc_add_modify (&body, count1, tmp);
5684 /* Use the scalar assignment as is. */
5685 gfc_add_block_to_block (&block, &body);
5687 else
5689 gcc_assert (lse.ss == gfc_ss_terminator
5690 && rse.ss == gfc_ss_terminator);
5692 if (loop.temp_ss != NULL)
5694 /* Increment count1 before finish the main body of a scalarized
5695 expression. */
5696 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5697 gfc_array_index_type, count1, gfc_index_one_node);
5698 gfc_add_modify (&body, count1, tmp);
5699 gfc_trans_scalarized_loop_boundary (&loop, &body);
5701 /* We need to copy the temporary to the actual lhs. */
5702 gfc_init_se (&lse, NULL);
5703 gfc_init_se (&rse, NULL);
5704 gfc_copy_loopinfo_to_se (&lse, &loop);
5705 gfc_copy_loopinfo_to_se (&rse, &loop);
5707 rse.ss = loop.temp_ss;
5708 lse.ss = lss;
5710 gfc_conv_tmp_array_ref (&rse);
5711 gfc_conv_expr (&lse, expr1);
5713 gcc_assert (lse.ss == gfc_ss_terminator
5714 && rse.ss == gfc_ss_terminator);
5716 /* Form the mask expression according to the mask tree list. */
5717 index = count2;
5718 maskexpr = gfc_build_array_ref (mask, index, NULL);
5719 if (invert)
5720 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
5721 TREE_TYPE (maskexpr), maskexpr);
5723 /* Use the scalar assignment as is. */
5724 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, false, true);
5725 tmp = build3_v (COND_EXPR, maskexpr, tmp,
5726 build_empty_stmt (input_location));
5727 gfc_add_expr_to_block (&body, tmp);
5729 /* Increment count2. */
5730 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5731 gfc_array_index_type, count2,
5732 gfc_index_one_node);
5733 gfc_add_modify (&body, count2, tmp);
5735 else
5737 /* Increment count1. */
5738 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5739 gfc_array_index_type, count1,
5740 gfc_index_one_node);
5741 gfc_add_modify (&body, count1, tmp);
5744 /* Generate the copying loops. */
5745 gfc_trans_scalarizing_loops (&loop, &body);
5747 /* Wrap the whole thing up. */
5748 gfc_add_block_to_block (&block, &loop.pre);
5749 gfc_add_block_to_block (&block, &loop.post);
5750 gfc_cleanup_loop (&loop);
5753 return gfc_finish_block (&block);
5757 /* Translate the WHERE construct or statement.
5758 This function can be called iteratively to translate the nested WHERE
5759 construct or statement.
5760 MASK is the control mask. */
5762 static void
5763 gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
5764 forall_info * nested_forall_info, stmtblock_t * block)
5766 stmtblock_t inner_size_body;
5767 tree inner_size, size;
5768 gfc_ss *lss, *rss;
5769 tree mask_type;
5770 gfc_expr *expr1;
5771 gfc_expr *expr2;
5772 gfc_code *cblock;
5773 gfc_code *cnext;
5774 tree tmp;
5775 tree cond;
5776 tree count1, count2;
5777 bool need_cmask;
5778 bool need_pmask;
5779 int need_temp;
5780 tree pcmask = NULL_TREE;
5781 tree ppmask = NULL_TREE;
5782 tree cmask = NULL_TREE;
5783 tree pmask = NULL_TREE;
5784 gfc_actual_arglist *arg;
5786 /* the WHERE statement or the WHERE construct statement. */
5787 cblock = code->block;
5789 /* As the mask array can be very big, prefer compact boolean types. */
5790 mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
5792 /* Determine which temporary masks are needed. */
5793 if (!cblock->block)
5795 /* One clause: No ELSEWHEREs. */
5796 need_cmask = (cblock->next != 0);
5797 need_pmask = false;
5799 else if (cblock->block->block)
5801 /* Three or more clauses: Conditional ELSEWHEREs. */
5802 need_cmask = true;
5803 need_pmask = true;
5805 else if (cblock->next)
5807 /* Two clauses, the first non-empty. */
5808 need_cmask = true;
5809 need_pmask = (mask != NULL_TREE
5810 && cblock->block->next != 0);
5812 else if (!cblock->block->next)
5814 /* Two clauses, both empty. */
5815 need_cmask = false;
5816 need_pmask = false;
5818 /* Two clauses, the first empty, the second non-empty. */
5819 else if (mask)
5821 need_cmask = (cblock->block->expr1 != 0);
5822 need_pmask = true;
5824 else
5826 need_cmask = true;
5827 need_pmask = false;
5830 if (need_cmask || need_pmask)
5832 /* Calculate the size of temporary needed by the mask-expr. */
5833 gfc_init_block (&inner_size_body);
5834 inner_size = compute_inner_temp_size (cblock->expr1, cblock->expr1,
5835 &inner_size_body, &lss, &rss);
5837 gfc_free_ss_chain (lss);
5838 gfc_free_ss_chain (rss);
5840 /* Calculate the total size of temporary needed. */
5841 size = compute_overall_iter_number (nested_forall_info, inner_size,
5842 &inner_size_body, block);
5844 /* Check whether the size is negative. */
5845 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, size,
5846 gfc_index_zero_node);
5847 size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
5848 cond, gfc_index_zero_node, size);
5849 size = gfc_evaluate_now (size, block);
5851 /* Allocate temporary for WHERE mask if needed. */
5852 if (need_cmask)
5853 cmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
5854 &pcmask);
5856 /* Allocate temporary for !mask if needed. */
5857 if (need_pmask)
5858 pmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
5859 &ppmask);
5862 while (cblock)
5864 /* Each time around this loop, the where clause is conditional
5865 on the value of mask and invert, which are updated at the
5866 bottom of the loop. */
5868 /* Has mask-expr. */
5869 if (cblock->expr1)
5871 /* Ensure that the WHERE mask will be evaluated exactly once.
5872 If there are no statements in this WHERE/ELSEWHERE clause,
5873 then we don't need to update the control mask (cmask).
5874 If this is the last clause of the WHERE construct, then
5875 we don't need to update the pending control mask (pmask). */
5876 if (mask)
5877 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
5878 mask, invert,
5879 cblock->next ? cmask : NULL_TREE,
5880 cblock->block ? pmask : NULL_TREE,
5881 mask_type, block);
5882 else
5883 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
5884 NULL_TREE, false,
5885 (cblock->next || cblock->block)
5886 ? cmask : NULL_TREE,
5887 NULL_TREE, mask_type, block);
5889 invert = false;
5891 /* It's a final elsewhere-stmt. No mask-expr is present. */
5892 else
5893 cmask = mask;
5895 /* The body of this where clause are controlled by cmask with
5896 sense specified by invert. */
5898 /* Get the assignment statement of a WHERE statement, or the first
5899 statement in where-body-construct of a WHERE construct. */
5900 cnext = cblock->next;
5901 while (cnext)
5903 switch (cnext->op)
5905 /* WHERE assignment statement. */
5906 case EXEC_ASSIGN_CALL:
5908 arg = cnext->ext.actual;
5909 expr1 = expr2 = NULL;
5910 for (; arg; arg = arg->next)
5912 if (!arg->expr)
5913 continue;
5914 if (expr1 == NULL)
5915 expr1 = arg->expr;
5916 else
5917 expr2 = arg->expr;
5919 goto evaluate;
5921 case EXEC_ASSIGN:
5922 expr1 = cnext->expr1;
5923 expr2 = cnext->expr2;
5924 evaluate:
5925 if (nested_forall_info != NULL)
5927 need_temp = gfc_check_dependency (expr1, expr2, 0);
5928 if ((need_temp || flag_test_forall_temp)
5929 && cnext->op != EXEC_ASSIGN_CALL)
5930 gfc_trans_assign_need_temp (expr1, expr2,
5931 cmask, invert,
5932 nested_forall_info, block);
5933 else
5935 /* Variables to control maskexpr. */
5936 count1 = gfc_create_var (gfc_array_index_type, "count1");
5937 count2 = gfc_create_var (gfc_array_index_type, "count2");
5938 gfc_add_modify (block, count1, gfc_index_zero_node);
5939 gfc_add_modify (block, count2, gfc_index_zero_node);
5941 tmp = gfc_trans_where_assign (expr1, expr2,
5942 cmask, invert,
5943 count1, count2,
5944 cnext);
5946 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
5947 tmp, 1);
5948 gfc_add_expr_to_block (block, tmp);
5951 else
5953 /* Variables to control maskexpr. */
5954 count1 = gfc_create_var (gfc_array_index_type, "count1");
5955 count2 = gfc_create_var (gfc_array_index_type, "count2");
5956 gfc_add_modify (block, count1, gfc_index_zero_node);
5957 gfc_add_modify (block, count2, gfc_index_zero_node);
5959 tmp = gfc_trans_where_assign (expr1, expr2,
5960 cmask, invert,
5961 count1, count2,
5962 cnext);
5963 gfc_add_expr_to_block (block, tmp);
5966 break;
5968 /* WHERE or WHERE construct is part of a where-body-construct. */
5969 case EXEC_WHERE:
5970 gfc_trans_where_2 (cnext, cmask, invert,
5971 nested_forall_info, block);
5972 break;
5974 default:
5975 gcc_unreachable ();
5978 /* The next statement within the same where-body-construct. */
5979 cnext = cnext->next;
5981 /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt. */
5982 cblock = cblock->block;
5983 if (mask == NULL_TREE)
5985 /* If we're the initial WHERE, we can simply invert the sense
5986 of the current mask to obtain the "mask" for the remaining
5987 ELSEWHEREs. */
5988 invert = true;
5989 mask = cmask;
5991 else
5993 /* Otherwise, for nested WHERE's we need to use the pending mask. */
5994 invert = false;
5995 mask = pmask;
5999 /* If we allocated a pending mask array, deallocate it now. */
6000 if (ppmask)
6002 tmp = gfc_call_free (ppmask);
6003 gfc_add_expr_to_block (block, tmp);
6006 /* If we allocated a current mask array, deallocate it now. */
6007 if (pcmask)
6009 tmp = gfc_call_free (pcmask);
6010 gfc_add_expr_to_block (block, tmp);
6014 /* Translate a simple WHERE construct or statement without dependencies.
6015 CBLOCK is the "then" clause of the WHERE statement, where CBLOCK->EXPR
6016 is the mask condition, and EBLOCK if non-NULL is the "else" clause.
6017 Currently both CBLOCK and EBLOCK are restricted to single assignments. */
6019 static tree
6020 gfc_trans_where_3 (gfc_code * cblock, gfc_code * eblock)
6022 stmtblock_t block, body;
6023 gfc_expr *cond, *tdst, *tsrc, *edst, *esrc;
6024 tree tmp, cexpr, tstmt, estmt;
6025 gfc_ss *css, *tdss, *tsss;
6026 gfc_se cse, tdse, tsse, edse, esse;
6027 gfc_loopinfo loop;
6028 gfc_ss *edss = 0;
6029 gfc_ss *esss = 0;
6030 bool maybe_workshare = false;
6032 /* Allow the scalarizer to workshare simple where loops. */
6033 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
6034 == OMPWS_WORKSHARE_FLAG)
6036 maybe_workshare = true;
6037 ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
6040 cond = cblock->expr1;
6041 tdst = cblock->next->expr1;
6042 tsrc = cblock->next->expr2;
6043 edst = eblock ? eblock->next->expr1 : NULL;
6044 esrc = eblock ? eblock->next->expr2 : NULL;
6046 gfc_start_block (&block);
6047 gfc_init_loopinfo (&loop);
6049 /* Handle the condition. */
6050 gfc_init_se (&cse, NULL);
6051 css = gfc_walk_expr (cond);
6052 gfc_add_ss_to_loop (&loop, css);
6054 /* Handle the then-clause. */
6055 gfc_init_se (&tdse, NULL);
6056 gfc_init_se (&tsse, NULL);
6057 tdss = gfc_walk_expr (tdst);
6058 tsss = gfc_walk_expr (tsrc);
6059 if (tsss == gfc_ss_terminator)
6061 tsss = gfc_get_scalar_ss (gfc_ss_terminator, tsrc);
6062 tsss->info->where = 1;
6064 gfc_add_ss_to_loop (&loop, tdss);
6065 gfc_add_ss_to_loop (&loop, tsss);
6067 if (eblock)
6069 /* Handle the else clause. */
6070 gfc_init_se (&edse, NULL);
6071 gfc_init_se (&esse, NULL);
6072 edss = gfc_walk_expr (edst);
6073 esss = gfc_walk_expr (esrc);
6074 if (esss == gfc_ss_terminator)
6076 esss = gfc_get_scalar_ss (gfc_ss_terminator, esrc);
6077 esss->info->where = 1;
6079 gfc_add_ss_to_loop (&loop, edss);
6080 gfc_add_ss_to_loop (&loop, esss);
6083 gfc_conv_ss_startstride (&loop);
6084 gfc_conv_loop_setup (&loop, &tdst->where);
6086 gfc_mark_ss_chain_used (css, 1);
6087 gfc_mark_ss_chain_used (tdss, 1);
6088 gfc_mark_ss_chain_used (tsss, 1);
6089 if (eblock)
6091 gfc_mark_ss_chain_used (edss, 1);
6092 gfc_mark_ss_chain_used (esss, 1);
6095 gfc_start_scalarized_body (&loop, &body);
6097 gfc_copy_loopinfo_to_se (&cse, &loop);
6098 gfc_copy_loopinfo_to_se (&tdse, &loop);
6099 gfc_copy_loopinfo_to_se (&tsse, &loop);
6100 cse.ss = css;
6101 tdse.ss = tdss;
6102 tsse.ss = tsss;
6103 if (eblock)
6105 gfc_copy_loopinfo_to_se (&edse, &loop);
6106 gfc_copy_loopinfo_to_se (&esse, &loop);
6107 edse.ss = edss;
6108 esse.ss = esss;
6111 gfc_conv_expr (&cse, cond);
6112 gfc_add_block_to_block (&body, &cse.pre);
6113 cexpr = cse.expr;
6115 gfc_conv_expr (&tsse, tsrc);
6116 if (tdss != gfc_ss_terminator && loop.temp_ss != NULL)
6117 gfc_conv_tmp_array_ref (&tdse);
6118 else
6119 gfc_conv_expr (&tdse, tdst);
6121 if (eblock)
6123 gfc_conv_expr (&esse, esrc);
6124 if (edss != gfc_ss_terminator && loop.temp_ss != NULL)
6125 gfc_conv_tmp_array_ref (&edse);
6126 else
6127 gfc_conv_expr (&edse, edst);
6130 tstmt = gfc_trans_scalar_assign (&tdse, &tsse, tdst->ts, false, true);
6131 estmt = eblock ? gfc_trans_scalar_assign (&edse, &esse, edst->ts,
6132 false, true)
6133 : build_empty_stmt (input_location);
6134 tmp = build3_v (COND_EXPR, cexpr, tstmt, estmt);
6135 gfc_add_expr_to_block (&body, tmp);
6136 gfc_add_block_to_block (&body, &cse.post);
6138 if (maybe_workshare)
6139 ompws_flags &= ~OMPWS_SCALARIZER_BODY;
6140 gfc_trans_scalarizing_loops (&loop, &body);
6141 gfc_add_block_to_block (&block, &loop.pre);
6142 gfc_add_block_to_block (&block, &loop.post);
6143 gfc_cleanup_loop (&loop);
6145 return gfc_finish_block (&block);
6148 /* As the WHERE or WHERE construct statement can be nested, we call
6149 gfc_trans_where_2 to do the translation, and pass the initial
6150 NULL values for both the control mask and the pending control mask. */
6152 tree
6153 gfc_trans_where (gfc_code * code)
6155 stmtblock_t block;
6156 gfc_code *cblock;
6157 gfc_code *eblock;
6159 cblock = code->block;
6160 if (cblock->next
6161 && cblock->next->op == EXEC_ASSIGN
6162 && !cblock->next->next)
6164 eblock = cblock->block;
6165 if (!eblock)
6167 /* A simple "WHERE (cond) x = y" statement or block is
6168 dependence free if cond is not dependent upon writing x,
6169 and the source y is unaffected by the destination x. */
6170 if (!gfc_check_dependency (cblock->next->expr1,
6171 cblock->expr1, 0)
6172 && !gfc_check_dependency (cblock->next->expr1,
6173 cblock->next->expr2, 0))
6174 return gfc_trans_where_3 (cblock, NULL);
6176 else if (!eblock->expr1
6177 && !eblock->block
6178 && eblock->next
6179 && eblock->next->op == EXEC_ASSIGN
6180 && !eblock->next->next)
6182 /* A simple "WHERE (cond) x1 = y1 ELSEWHERE x2 = y2 ENDWHERE"
6183 block is dependence free if cond is not dependent on writes
6184 to x1 and x2, y1 is not dependent on writes to x2, and y2
6185 is not dependent on writes to x1, and both y's are not
6186 dependent upon their own x's. In addition to this, the
6187 final two dependency checks below exclude all but the same
6188 array reference if the where and elswhere destinations
6189 are the same. In short, this is VERY conservative and this
6190 is needed because the two loops, required by the standard
6191 are coalesced in gfc_trans_where_3. */
6192 if (!gfc_check_dependency (cblock->next->expr1,
6193 cblock->expr1, 0)
6194 && !gfc_check_dependency (eblock->next->expr1,
6195 cblock->expr1, 0)
6196 && !gfc_check_dependency (cblock->next->expr1,
6197 eblock->next->expr2, 1)
6198 && !gfc_check_dependency (eblock->next->expr1,
6199 cblock->next->expr2, 1)
6200 && !gfc_check_dependency (cblock->next->expr1,
6201 cblock->next->expr2, 1)
6202 && !gfc_check_dependency (eblock->next->expr1,
6203 eblock->next->expr2, 1)
6204 && !gfc_check_dependency (cblock->next->expr1,
6205 eblock->next->expr1, 0)
6206 && !gfc_check_dependency (eblock->next->expr1,
6207 cblock->next->expr1, 0))
6208 return gfc_trans_where_3 (cblock, eblock);
6212 gfc_start_block (&block);
6214 gfc_trans_where_2 (code, NULL, false, NULL, &block);
6216 return gfc_finish_block (&block);
6220 /* CYCLE a DO loop. The label decl has already been created by
6221 gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
6222 node at the head of the loop. We must mark the label as used. */
6224 tree
6225 gfc_trans_cycle (gfc_code * code)
6227 tree cycle_label;
6229 cycle_label = code->ext.which_construct->cycle_label;
6230 gcc_assert (cycle_label);
6232 TREE_USED (cycle_label) = 1;
6233 return build1_v (GOTO_EXPR, cycle_label);
6237 /* EXIT a DO loop. Similar to CYCLE, but now the label is in
6238 TREE_VALUE (backend_decl) of the gfc_code node at the head of the
6239 loop. */
6241 tree
6242 gfc_trans_exit (gfc_code * code)
6244 tree exit_label;
6246 exit_label = code->ext.which_construct->exit_label;
6247 gcc_assert (exit_label);
6249 TREE_USED (exit_label) = 1;
6250 return build1_v (GOTO_EXPR, exit_label);
6254 /* Get the initializer expression for the code and expr of an allocate.
6255 When no initializer is needed return NULL. */
6257 static gfc_expr *
6258 allocate_get_initializer (gfc_code * code, gfc_expr * expr)
6260 if (!gfc_bt_struct (expr->ts.type) && expr->ts.type != BT_CLASS)
6261 return NULL;
6263 /* An explicit type was given in allocate ( T:: object). */
6264 if (code->ext.alloc.ts.type == BT_DERIVED
6265 && (code->ext.alloc.ts.u.derived->attr.alloc_comp
6266 || gfc_has_default_initializer (code->ext.alloc.ts.u.derived)))
6267 return gfc_default_initializer (&code->ext.alloc.ts);
6269 if (gfc_bt_struct (expr->ts.type)
6270 && (expr->ts.u.derived->attr.alloc_comp
6271 || gfc_has_default_initializer (expr->ts.u.derived)))
6272 return gfc_default_initializer (&expr->ts);
6274 if (expr->ts.type == BT_CLASS
6275 && (CLASS_DATA (expr)->ts.u.derived->attr.alloc_comp
6276 || gfc_has_default_initializer (CLASS_DATA (expr)->ts.u.derived)))
6277 return gfc_default_initializer (&CLASS_DATA (expr)->ts);
6279 return NULL;
6282 /* Translate the ALLOCATE statement. */
6284 tree
6285 gfc_trans_allocate (gfc_code * code, gfc_omp_namelist *omp_allocate)
6287 gfc_alloc *al;
6288 gfc_expr *expr, *e3rhs = NULL, *init_expr;
6289 gfc_se se, se_sz;
6290 tree tmp;
6291 tree parm;
6292 tree stat;
6293 tree errmsg;
6294 tree errlen;
6295 tree label_errmsg;
6296 tree label_finish;
6297 tree memsz;
6298 tree al_vptr, al_len;
6299 /* If an expr3 is present, then store the tree for accessing its
6300 _vptr, and _len components in the variables, respectively. The
6301 element size, i.e. _vptr%size, is stored in expr3_esize. Any of
6302 the trees may be the NULL_TREE indicating that this is not
6303 available for expr3's type. */
6304 tree expr3, expr3_vptr, expr3_len, expr3_esize;
6305 /* Classify what expr3 stores. */
6306 enum { E3_UNSET = 0, E3_SOURCE, E3_MOLD, E3_DESC } e3_is;
6307 stmtblock_t block;
6308 stmtblock_t post;
6309 stmtblock_t final_block;
6310 tree nelems;
6311 bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set, is_coarray;
6312 bool needs_caf_sync, caf_refs_comp;
6313 bool e3_has_nodescriptor = false;
6314 gfc_symtree *newsym = NULL;
6315 symbol_attribute caf_attr;
6316 gfc_actual_arglist *param_list;
6318 if (!code->ext.alloc.list)
6319 return NULL_TREE;
6321 stat = tmp = memsz = al_vptr = al_len = NULL_TREE;
6322 expr3 = expr3_vptr = expr3_len = expr3_esize = NULL_TREE;
6323 label_errmsg = label_finish = errmsg = errlen = NULL_TREE;
6324 e3_is = E3_UNSET;
6325 is_coarray = needs_caf_sync = false;
6327 gfc_init_block (&block);
6328 gfc_init_block (&post);
6329 gfc_init_block (&final_block);
6331 /* STAT= (and maybe ERRMSG=) is present. */
6332 if (code->expr1)
6334 /* STAT=. */
6335 tree gfc_int4_type_node = gfc_get_int_type (4);
6336 stat = gfc_create_var (gfc_int4_type_node, "stat");
6338 /* ERRMSG= only makes sense with STAT=. */
6339 if (code->expr2)
6341 gfc_init_se (&se, NULL);
6342 se.want_pointer = 1;
6343 gfc_conv_expr_lhs (&se, code->expr2);
6344 errmsg = se.expr;
6345 errlen = se.string_length;
6347 else
6349 errmsg = null_pointer_node;
6350 errlen = build_int_cst (gfc_charlen_type_node, 0);
6353 /* GOTO destinations. */
6354 label_errmsg = gfc_build_label_decl (NULL_TREE);
6355 label_finish = gfc_build_label_decl (NULL_TREE);
6356 TREE_USED (label_finish) = 0;
6359 /* When an expr3 is present evaluate it only once. The standards prevent a
6360 dependency of expr3 on the objects in the allocate list. An expr3 can
6361 be pre-evaluated in all cases. One just has to make sure, to use the
6362 correct way, i.e., to get the descriptor or to get a reference
6363 expression. */
6364 if (code->expr3)
6366 bool vtab_needed = false, temp_var_needed = false,
6367 temp_obj_created = false;
6369 is_coarray = gfc_is_coarray (code->expr3);
6371 if (code->expr3->expr_type == EXPR_FUNCTION && !code->expr3->mold
6372 && (gfc_is_class_array_function (code->expr3)
6373 || gfc_is_alloc_class_scalar_function (code->expr3)))
6374 code->expr3->must_finalize = 1;
6376 /* Figure whether we need the vtab from expr3. */
6377 for (al = code->ext.alloc.list; !vtab_needed && al != NULL;
6378 al = al->next)
6379 vtab_needed = (al->expr->ts.type == BT_CLASS);
6381 gfc_init_se (&se, NULL);
6382 /* When expr3 is a variable, i.e., a very simple expression, then
6383 convert it once here. If one has a source expression that has
6384 substring references, part-refs, or %re/%im inquiries, wrap the
6385 entity in parentheses to force evaluation of the expression. */
6386 if (code->expr3->expr_type == EXPR_VARIABLE
6387 && is_subref_array (code->expr3))
6388 code->expr3 = gfc_get_parentheses (code->expr3);
6390 if (code->expr3->expr_type == EXPR_VARIABLE
6391 || code->expr3->expr_type == EXPR_ARRAY
6392 || code->expr3->expr_type == EXPR_CONSTANT)
6394 if (!code->expr3->mold
6395 || code->expr3->ts.type == BT_CHARACTER
6396 || vtab_needed
6397 || code->ext.alloc.arr_spec_from_expr3)
6399 /* Convert expr3 to a tree. For all "simple" expression just
6400 get the descriptor or the reference, respectively, depending
6401 on the rank of the expr. */
6402 if (code->ext.alloc.arr_spec_from_expr3 || code->expr3->rank != 0)
6403 gfc_conv_expr_descriptor (&se, code->expr3);
6404 else
6406 gfc_conv_expr_reference (&se, code->expr3);
6408 /* gfc_conv_expr_reference wraps POINTER_PLUS_EXPR in a
6409 NOP_EXPR, which prevents gfortran from getting the vptr
6410 from the source=-expression. Remove the NOP_EXPR and go
6411 with the POINTER_PLUS_EXPR in this case. */
6412 if (code->expr3->ts.type == BT_CLASS
6413 && TREE_CODE (se.expr) == NOP_EXPR
6414 && (TREE_CODE (TREE_OPERAND (se.expr, 0))
6415 == POINTER_PLUS_EXPR
6416 || is_coarray))
6417 se.expr = TREE_OPERAND (se.expr, 0);
6419 /* Create a temp variable only for component refs to prevent
6420 having to go through the full deref-chain each time and to
6421 simplify computation of array properties. */
6422 temp_var_needed = TREE_CODE (se.expr) == COMPONENT_REF;
6425 else
6427 /* In all other cases evaluate the expr3. */
6428 symbol_attribute attr;
6429 /* Get the descriptor for all arrays, that are not allocatable or
6430 pointer, because the latter are descriptors already.
6431 The exception are function calls returning a class object:
6432 The descriptor is stored in their results _data component, which
6433 is easier to access, when first a temporary variable for the
6434 result is created and the descriptor retrieved from there. */
6435 attr = gfc_expr_attr (code->expr3);
6436 if (code->expr3->rank != 0
6437 && ((!attr.allocatable && !attr.pointer)
6438 || (code->expr3->expr_type == EXPR_FUNCTION
6439 && (code->expr3->ts.type != BT_CLASS
6440 || (code->expr3->value.function.isym
6441 && code->expr3->value.function.isym
6442 ->transformational)))))
6443 gfc_conv_expr_descriptor (&se, code->expr3);
6444 else
6445 gfc_conv_expr_reference (&se, code->expr3);
6446 if (code->expr3->ts.type == BT_CLASS)
6447 gfc_conv_class_to_class (&se, code->expr3,
6448 code->expr3->ts,
6449 false, true,
6450 false, false);
6451 temp_obj_created = temp_var_needed = !VAR_P (se.expr);
6453 gfc_add_block_to_block (&block, &se.pre);
6454 if (code->expr3->must_finalize)
6456 gfc_add_block_to_block (&final_block, &se.finalblock);
6457 gfc_add_block_to_block (&final_block, &se.post);
6459 else
6460 gfc_add_block_to_block (&post, &se.post);
6462 /* Special case when string in expr3 is scalar and has length zero. */
6463 if (code->expr3->ts.type == BT_CHARACTER
6464 && code->expr3->rank == 0
6465 && integer_zerop (se.string_length))
6467 gfc_init_se (&se, NULL);
6468 temp_var_needed = false;
6469 expr3_len = build_zero_cst (gfc_charlen_type_node);
6470 e3_is = E3_MOLD;
6472 /* Prevent aliasing, i.e., se.expr may be already a
6473 variable declaration. */
6474 else if (se.expr != NULL_TREE && temp_var_needed)
6476 tree var, desc;
6477 tmp = (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
6478 || is_coarray
6479 || (code->expr3->ts.type == BT_CHARACTER
6480 && code->expr3->rank == 0)) ?
6481 se.expr
6482 : build_fold_indirect_ref_loc (input_location, se.expr);
6484 /* Get the array descriptor and prepare it to be assigned to the
6485 temporary variable var. For classes the array descriptor is
6486 in the _data component and the object goes into the
6487 GFC_DECL_SAVED_DESCRIPTOR. */
6488 if (code->expr3->ts.type == BT_CLASS
6489 && code->expr3->rank != 0)
6491 /* When an array_ref was in expr3, then the descriptor is the
6492 first operand. */
6493 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
6495 desc = TREE_OPERAND (tmp, 0);
6497 else
6499 desc = tmp;
6500 tmp = gfc_class_data_get (tmp);
6502 if (code->ext.alloc.arr_spec_from_expr3)
6503 e3_is = E3_DESC;
6505 else
6506 desc = !is_coarray ? se.expr
6507 : TREE_OPERAND (TREE_OPERAND (se.expr, 0), 0);
6508 /* We need a regular (non-UID) symbol here, therefore give a
6509 prefix. */
6510 var = gfc_create_var (TREE_TYPE (tmp), "source");
6511 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
6513 gfc_allocate_lang_decl (var);
6514 GFC_DECL_SAVED_DESCRIPTOR (var) = desc;
6516 gfc_add_modify_loc (input_location, &block, var, tmp);
6518 expr3 = var;
6519 if (se.string_length)
6520 /* Evaluate it assuming that it also is complicated like expr3. */
6521 expr3_len = gfc_evaluate_now (se.string_length, &block);
6523 else
6525 expr3 = se.expr;
6526 expr3_len = se.string_length;
6529 /* Deallocate any allocatable components in expressions that use a
6530 temporary object, i.e. are not a simple alias of to an EXPR_VARIABLE.
6531 E.g. temporaries of a function call need freeing of their components
6532 here. Explicit derived type allocation of class entities uses expr3
6533 to carry the default initializer. This must not be deallocated or
6534 finalized. */
6535 if ((code->expr3->ts.type == BT_DERIVED
6536 || code->expr3->ts.type == BT_CLASS)
6537 && (code->expr3->expr_type != EXPR_VARIABLE || temp_obj_created)
6538 && code->expr3->ts.u.derived->attr.alloc_comp
6539 && !code->expr3->must_finalize
6540 && !code->ext.alloc.expr3_not_explicit)
6542 tmp = gfc_deallocate_alloc_comp (code->expr3->ts.u.derived,
6543 expr3, code->expr3->rank);
6544 gfc_prepend_expr_to_block (&post, tmp);
6547 /* Store what the expr3 is to be used for. */
6548 if (e3_is == E3_UNSET)
6549 e3_is = expr3 != NULL_TREE ?
6550 (code->ext.alloc.arr_spec_from_expr3 ?
6551 E3_DESC
6552 : (code->expr3->mold ? E3_MOLD : E3_SOURCE))
6553 : E3_UNSET;
6555 /* Figure how to get the _vtab entry. This also obtains the tree
6556 expression for accessing the _len component, because only
6557 unlimited polymorphic objects, which are a subcategory of class
6558 types, have a _len component. */
6559 if (code->expr3->ts.type == BT_CLASS)
6561 gfc_expr *rhs;
6562 tmp = expr3 != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (expr3)) ?
6563 build_fold_indirect_ref (expr3): expr3;
6564 /* Polymorphic SOURCE: VPTR must be determined at run time.
6565 expr3 may be a temporary array declaration, therefore check for
6566 GFC_CLASS_TYPE_P before trying to get the _vptr component. */
6567 if (tmp != NULL_TREE
6568 && (e3_is == E3_DESC
6569 || (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
6570 && (VAR_P (tmp) || !code->expr3->ref))
6571 || (VAR_P (tmp) && DECL_LANG_SPECIFIC (tmp))))
6572 tmp = gfc_class_vptr_get (expr3);
6573 else
6575 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
6576 gfc_add_vptr_component (rhs);
6577 gfc_init_se (&se, NULL);
6578 se.want_pointer = 1;
6579 gfc_conv_expr (&se, rhs);
6580 tmp = se.expr;
6581 gfc_free_expr (rhs);
6583 /* Set the element size. */
6584 expr3_esize = gfc_vptr_size_get (tmp);
6585 if (vtab_needed)
6586 expr3_vptr = tmp;
6587 /* Initialize the ref to the _len component. */
6588 if (expr3_len == NULL_TREE && UNLIMITED_POLY (code->expr3))
6590 /* Same like for retrieving the _vptr. */
6591 if (expr3 != NULL_TREE && !code->expr3->ref)
6592 expr3_len = gfc_class_len_get (expr3);
6593 else
6595 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
6596 gfc_add_len_component (rhs);
6597 gfc_init_se (&se, NULL);
6598 gfc_conv_expr (&se, rhs);
6599 expr3_len = se.expr;
6600 gfc_free_expr (rhs);
6604 else
6606 /* When the object to allocate is polymorphic type, then it
6607 needs its vtab set correctly, so deduce the required _vtab
6608 and _len from the source expression. */
6609 if (vtab_needed)
6611 /* VPTR is fixed at compile time. */
6612 gfc_symbol *vtab;
6614 vtab = gfc_find_vtab (&code->expr3->ts);
6615 gcc_assert (vtab);
6616 expr3_vptr = gfc_get_symbol_decl (vtab);
6617 expr3_vptr = gfc_build_addr_expr (NULL_TREE,
6618 expr3_vptr);
6620 /* _len component needs to be set, when ts is a character
6621 array. */
6622 if (expr3_len == NULL_TREE
6623 && code->expr3->ts.type == BT_CHARACTER)
6625 if (code->expr3->ts.u.cl
6626 && code->expr3->ts.u.cl->length)
6628 gfc_init_se (&se, NULL);
6629 gfc_conv_expr (&se, code->expr3->ts.u.cl->length);
6630 gfc_add_block_to_block (&block, &se.pre);
6631 expr3_len = gfc_evaluate_now (se.expr, &block);
6633 gcc_assert (expr3_len);
6635 /* For character arrays only the kind's size is needed, because
6636 the array mem_size is _len * (elem_size = kind_size).
6637 For all other get the element size in the normal way. */
6638 if (code->expr3->ts.type == BT_CHARACTER)
6639 expr3_esize = TYPE_SIZE_UNIT (
6640 gfc_get_char_type (code->expr3->ts.kind));
6641 else
6642 expr3_esize = TYPE_SIZE_UNIT (
6643 gfc_typenode_for_spec (&code->expr3->ts));
6645 gcc_assert (expr3_esize);
6646 expr3_esize = fold_convert (sizetype, expr3_esize);
6647 if (e3_is == E3_MOLD)
6648 /* The expr3 is no longer valid after this point. */
6649 expr3 = NULL_TREE;
6651 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
6653 /* Compute the explicit typespec given only once for all objects
6654 to allocate. */
6655 if (code->ext.alloc.ts.type != BT_CHARACTER)
6656 expr3_esize = TYPE_SIZE_UNIT (
6657 gfc_typenode_for_spec (&code->ext.alloc.ts));
6658 else if (code->ext.alloc.ts.u.cl->length != NULL)
6660 gfc_expr *sz;
6661 sz = gfc_copy_expr (code->ext.alloc.ts.u.cl->length);
6662 gfc_init_se (&se_sz, NULL);
6663 gfc_conv_expr (&se_sz, sz);
6664 gfc_free_expr (sz);
6665 tmp = gfc_get_char_type (code->ext.alloc.ts.kind);
6666 tmp = TYPE_SIZE_UNIT (tmp);
6667 tmp = fold_convert (TREE_TYPE (se_sz.expr), tmp);
6668 gfc_add_block_to_block (&block, &se_sz.pre);
6669 expr3_esize = fold_build2_loc (input_location, MULT_EXPR,
6670 TREE_TYPE (se_sz.expr),
6671 tmp, se_sz.expr);
6672 expr3_esize = gfc_evaluate_now (expr3_esize, &block);
6674 else
6675 expr3_esize = NULL_TREE;
6678 /* The routine gfc_trans_assignment () already implements all
6679 techniques needed. Unfortunately we may have a temporary
6680 variable for the source= expression here. When that is the
6681 case convert this variable into a temporary gfc_expr of type
6682 EXPR_VARIABLE and used it as rhs for the assignment. The
6683 advantage is, that we get scalarizer support for free,
6684 don't have to take care about scalar to array treatment and
6685 will benefit of every enhancements gfc_trans_assignment ()
6686 gets.
6687 No need to check whether e3_is is E3_UNSET, because that is
6688 done by expr3 != NULL_TREE.
6689 Exclude variables since the following block does not handle
6690 array sections. In any case, there is no harm in sending
6691 variables to gfc_trans_assignment because there is no
6692 evaluation of variables. */
6693 if (code->expr3)
6695 if (code->expr3->expr_type != EXPR_VARIABLE
6696 && e3_is != E3_MOLD && expr3 != NULL_TREE
6697 && DECL_P (expr3) && DECL_ARTIFICIAL (expr3))
6699 /* Build a temporary symtree and symbol. Do not add it to the current
6700 namespace to prevent accidentaly modifying a colliding
6701 symbol's as. */
6702 newsym = XCNEW (gfc_symtree);
6703 /* The name of the symtree should be unique, because gfc_create_var ()
6704 took care about generating the identifier. */
6705 newsym->name
6706 = gfc_get_string ("%s", IDENTIFIER_POINTER (DECL_NAME (expr3)));
6707 newsym->n.sym = gfc_new_symbol (newsym->name, NULL);
6708 /* The backend_decl is known. It is expr3, which is inserted
6709 here. */
6710 newsym->n.sym->backend_decl = expr3;
6711 e3rhs = gfc_get_expr ();
6712 e3rhs->rank = code->expr3->rank;
6713 e3rhs->symtree = newsym;
6714 /* Mark the symbol referenced or gfc_trans_assignment will bug. */
6715 newsym->n.sym->attr.referenced = 1;
6716 e3rhs->expr_type = EXPR_VARIABLE;
6717 e3rhs->where = code->expr3->where;
6718 /* Set the symbols type, upto it was BT_UNKNOWN. */
6719 if (IS_CLASS_ARRAY (code->expr3)
6720 && code->expr3->expr_type == EXPR_FUNCTION
6721 && code->expr3->value.function.isym
6722 && code->expr3->value.function.isym->transformational)
6724 e3rhs->ts = CLASS_DATA (code->expr3)->ts;
6726 else if (code->expr3->ts.type == BT_CLASS
6727 && !GFC_CLASS_TYPE_P (TREE_TYPE (expr3)))
6728 e3rhs->ts = CLASS_DATA (code->expr3)->ts;
6729 else
6730 e3rhs->ts = code->expr3->ts;
6731 newsym->n.sym->ts = e3rhs->ts;
6732 /* Check whether the expr3 is array valued. */
6733 if (e3rhs->rank)
6735 gfc_array_spec *arr;
6736 arr = gfc_get_array_spec ();
6737 arr->rank = e3rhs->rank;
6738 arr->type = AS_DEFERRED;
6739 /* Set the dimension and pointer attribute for arrays
6740 to be on the safe side. */
6741 newsym->n.sym->attr.dimension = 1;
6742 newsym->n.sym->attr.pointer = 1;
6743 newsym->n.sym->as = arr;
6744 if (IS_CLASS_ARRAY (code->expr3)
6745 && code->expr3->expr_type == EXPR_FUNCTION
6746 && code->expr3->value.function.isym
6747 && code->expr3->value.function.isym->transformational)
6749 gfc_array_spec *tarr;
6750 tarr = gfc_get_array_spec ();
6751 *tarr = *arr;
6752 e3rhs->ts.u.derived->as = tarr;
6754 gfc_add_full_array_ref (e3rhs, arr);
6756 else if (POINTER_TYPE_P (TREE_TYPE (expr3)))
6757 newsym->n.sym->attr.pointer = 1;
6758 /* The string length is known, too. Set it for char arrays. */
6759 if (e3rhs->ts.type == BT_CHARACTER)
6760 newsym->n.sym->ts.u.cl->backend_decl = expr3_len;
6761 gfc_commit_symbol (newsym->n.sym);
6763 else
6764 e3rhs = gfc_copy_expr (code->expr3);
6766 // We need to propagate the bounds of the expr3 for source=/mold=.
6767 // However, for non-named arrays, the lbound has to be 1 and neither the
6768 // bound used inside the called function even when returning an
6769 // allocatable/pointer nor the zero used internally.
6770 if (e3_is == E3_DESC
6771 && code->expr3->expr_type != EXPR_VARIABLE)
6772 e3_has_nodescriptor = true;
6775 /* Loop over all objects to allocate. */
6776 for (al = code->ext.alloc.list; al != NULL; al = al->next)
6778 expr = gfc_copy_expr (al->expr);
6779 /* UNLIMITED_POLY () needs the _data component to be set, when
6780 expr is a unlimited polymorphic object. But the _data component
6781 has not been set yet, so check the derived type's attr for the
6782 unlimited polymorphic flag to be safe. */
6783 upoly_expr = UNLIMITED_POLY (expr)
6784 || (expr->ts.type == BT_DERIVED
6785 && expr->ts.u.derived->attr.unlimited_polymorphic);
6786 gfc_init_se (&se, NULL);
6788 /* For class types prepare the expressions to ref the _vptr
6789 and the _len component. The latter for unlimited polymorphic
6790 types only. */
6791 if (expr->ts.type == BT_CLASS)
6793 gfc_expr *expr_ref_vptr, *expr_ref_len;
6794 gfc_add_data_component (expr);
6795 /* Prep the vptr handle. */
6796 expr_ref_vptr = gfc_copy_expr (al->expr);
6797 gfc_add_vptr_component (expr_ref_vptr);
6798 se.want_pointer = 1;
6799 gfc_conv_expr (&se, expr_ref_vptr);
6800 al_vptr = se.expr;
6801 se.want_pointer = 0;
6802 gfc_free_expr (expr_ref_vptr);
6803 /* Allocated unlimited polymorphic objects always have a _len
6804 component. */
6805 if (upoly_expr)
6807 expr_ref_len = gfc_copy_expr (al->expr);
6808 gfc_add_len_component (expr_ref_len);
6809 gfc_conv_expr (&se, expr_ref_len);
6810 al_len = se.expr;
6811 gfc_free_expr (expr_ref_len);
6813 else
6814 /* In a loop ensure that all loop variable dependent variables
6815 are initialized at the same spot in all execution paths. */
6816 al_len = NULL_TREE;
6818 else
6819 al_vptr = al_len = NULL_TREE;
6821 se.want_pointer = 1;
6822 se.descriptor_only = 1;
6824 gfc_conv_expr (&se, expr);
6825 if (expr->ts.type == BT_CHARACTER && expr->ts.deferred)
6826 /* se.string_length now stores the .string_length variable of expr
6827 needed to allocate character(len=:) arrays. */
6828 al_len = se.string_length;
6830 al_len_needs_set = al_len != NULL_TREE;
6831 /* When allocating an array one cannot use much of the
6832 pre-evaluated expr3 expressions, because for most of them the
6833 scalarizer is needed which is not available in the pre-evaluation
6834 step. Therefore gfc_array_allocate () is responsible (and able)
6835 to handle the complete array allocation. Only the element size
6836 needs to be provided, which is done most of the time by the
6837 pre-evaluation step. */
6838 nelems = NULL_TREE;
6839 if (expr3_len && (code->expr3->ts.type == BT_CHARACTER
6840 || code->expr3->ts.type == BT_CLASS))
6842 /* When al is an array, then the element size for each element
6843 in the array is needed, which is the product of the len and
6844 esize for char arrays. For unlimited polymorphics len can be
6845 zero, therefore take the maximum of len and one. */
6846 tree lhs_len;
6848 /* If an allocatable character variable has fixed length, use it.
6849 Otherwise use source length. As different lengths are not
6850 allowed by the standard, generate a runtime check. */
6851 if (expr->ts.type == BT_CHARACTER && !expr->ts.deferred)
6853 gfc_trans_same_strlen_check ("ALLOCATE with SOURCE= or MOLD=",
6854 &code->expr3->where,
6855 se.string_length, expr3_len,
6856 &block);
6857 lhs_len = fold_convert (TREE_TYPE (expr3_len), se.string_length);
6859 else
6860 lhs_len = expr3_len;
6862 tmp = fold_build2_loc (input_location, MAX_EXPR,
6863 TREE_TYPE (expr3_len),
6864 lhs_len, fold_convert (TREE_TYPE (expr3_len),
6865 integer_one_node));
6866 tmp = fold_build2_loc (input_location, MULT_EXPR,
6867 TREE_TYPE (expr3_esize), expr3_esize,
6868 fold_convert (TREE_TYPE (expr3_esize), tmp));
6870 else
6871 tmp = expr3_esize;
6873 gfc_omp_namelist *omp_alloc_item = NULL;
6874 if (omp_allocate)
6876 gfc_omp_namelist *n = NULL;
6877 gfc_omp_namelist *n_null = NULL;
6878 for (n = omp_allocate; n; n = n->next)
6880 if (n->sym == NULL)
6882 n_null = n;
6883 continue;
6885 if (expr->expr_type == EXPR_VARIABLE
6886 && expr->symtree->n.sym == n->sym)
6888 gfc_ref *ref;
6889 for (ref = expr->ref; ref; ref = ref->next)
6890 if (ref->type == REF_COMPONENT)
6891 break;
6892 if (ref == NULL)
6893 break;
6896 omp_alloc_item = n ? n : n_null;
6900 if (!gfc_array_allocate (&se, expr, stat, errmsg, errlen,
6901 label_finish, tmp, &nelems,
6902 e3rhs ? e3rhs : code->expr3,
6903 e3_is == E3_DESC ? expr3 : NULL_TREE,
6904 e3_has_nodescriptor, omp_alloc_item))
6906 /* A scalar or derived type. First compute the size to
6907 allocate.
6909 expr3_len is set when expr3 is an unlimited polymorphic
6910 object or a deferred length string.
6912 If an allocatable character variable has fixed length, use it.
6913 Otherwise use source length. As different lengths are not
6914 allowed by the standard, a runtime check was inserted
6915 above. */
6916 if (expr3_len != NULL_TREE)
6918 tree lhs_len;
6919 if (expr->ts.type == BT_CHARACTER && !expr->ts.deferred)
6920 lhs_len = fold_convert (TREE_TYPE (expr3_len),
6921 se.string_length);
6922 else
6923 lhs_len = expr3_len;
6925 tmp = fold_convert (TREE_TYPE (expr3_esize), lhs_len);
6926 tmp = fold_build2_loc (input_location, MULT_EXPR,
6927 TREE_TYPE (expr3_esize),
6928 expr3_esize, tmp);
6929 if (code->expr3->ts.type != BT_CLASS)
6930 /* expr3 is a deferred length string, i.e., we are
6931 done. */
6932 memsz = tmp;
6933 else
6935 /* For unlimited polymorphic enties build
6936 (len > 0) ? element_size * len : element_size
6937 to compute the number of bytes to allocate.
6938 This allows the allocation of unlimited polymorphic
6939 objects from an expr3 that is also unlimited
6940 polymorphic and stores a _len dependent object,
6941 e.g., a string. */
6942 memsz = fold_build2_loc (input_location, GT_EXPR,
6943 logical_type_node, expr3_len,
6944 build_zero_cst
6945 (TREE_TYPE (expr3_len)));
6946 memsz = fold_build3_loc (input_location, COND_EXPR,
6947 TREE_TYPE (expr3_esize),
6948 memsz, tmp, expr3_esize);
6951 else if (expr3_esize != NULL_TREE)
6952 /* Any other object in expr3 just needs element size in
6953 bytes. */
6954 memsz = expr3_esize;
6955 else if ((expr->ts.type == BT_CHARACTER && expr->ts.deferred)
6956 || (upoly_expr
6957 && code->ext.alloc.ts.type == BT_CHARACTER))
6959 /* Allocating deferred length char arrays need the length
6960 to allocate in the alloc_type_spec. But also unlimited
6961 polymorphic objects may be allocated as char arrays.
6962 Both are handled here. */
6963 gfc_init_se (&se_sz, NULL);
6964 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6965 gfc_add_block_to_block (&se.pre, &se_sz.pre);
6966 se_sz.expr = gfc_evaluate_now (se_sz.expr, &se.pre);
6967 gfc_add_block_to_block (&se.pre, &se_sz.post);
6968 expr3_len = se_sz.expr;
6969 tmp_expr3_len_flag = true;
6970 tmp = TYPE_SIZE_UNIT (
6971 gfc_get_char_type (code->ext.alloc.ts.kind));
6972 memsz = fold_build2_loc (input_location, MULT_EXPR,
6973 TREE_TYPE (tmp),
6974 fold_convert (TREE_TYPE (tmp),
6975 expr3_len),
6976 tmp);
6978 else if (expr->ts.type == BT_CHARACTER)
6980 /* Compute the number of bytes needed to allocate a fixed
6981 length char array. */
6982 gcc_assert (se.string_length != NULL_TREE);
6983 tmp = TYPE_SIZE_UNIT (gfc_get_char_type (expr->ts.kind));
6984 memsz = fold_build2_loc (input_location, MULT_EXPR,
6985 TREE_TYPE (tmp), tmp,
6986 fold_convert (TREE_TYPE (tmp),
6987 se.string_length));
6989 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
6990 /* Handle all types, where the alloc_type_spec is set. */
6991 memsz = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->ext.alloc.ts));
6992 else
6993 /* Handle size computation of the type declared to alloc. */
6994 memsz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
6996 bool use_coarray_alloc
6997 = (flag_coarray == GFC_FCOARRAY_LIB
6998 && (caf_attr = gfc_caf_attr (expr, true, &caf_refs_comp))
6999 .codimension);
7000 tree omp_cond = NULL_TREE;
7001 tree omp_alt_alloc = NULL_TREE;
7002 tree succ_add_expr = NULL_TREE;
7003 if (!use_coarray_alloc && omp_alloc_item)
7005 tree align, alloc, sz;
7006 gfc_se se2;
7008 omp_cond = boolean_true_node;
7009 if (omp_alloc_item->u2.allocator)
7011 gfc_init_se (&se2, NULL);
7012 gfc_conv_expr (&se2, omp_alloc_item->u2.allocator);
7013 gfc_add_block_to_block (&se.pre, &se2.pre);
7014 alloc = gfc_evaluate_now (se2.expr, &se.pre);
7015 gfc_add_block_to_block (&se.pre, &se2.post);
7017 else
7018 alloc = build_zero_cst (ptr_type_node);
7019 tmp = TREE_TYPE (TREE_TYPE (se.expr));
7020 if (tmp == void_type_node)
7021 tmp = gfc_typenode_for_spec (&expr->ts, 0);
7022 if (omp_alloc_item->u.align)
7024 gfc_init_se (&se2, NULL);
7025 gfc_conv_expr (&se2, omp_alloc_item->u.align);
7026 gcc_assert (CONSTANT_CLASS_P (se2.expr)
7027 && se2.pre.head == NULL
7028 && se2.post.head == NULL);
7029 align = build_int_cst (size_type_node,
7030 MAX (tree_to_uhwi (se2.expr),
7031 TYPE_ALIGN_UNIT (tmp)));
7033 else
7034 align = build_int_cst (size_type_node, TYPE_ALIGN_UNIT (tmp));
7035 sz = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
7036 fold_convert (size_type_node, memsz),
7037 build_int_cst (size_type_node, 1));
7038 omp_alt_alloc = builtin_decl_explicit (BUILT_IN_GOMP_ALLOC);
7039 DECL_ATTRIBUTES (omp_alt_alloc)
7040 = tree_cons (get_identifier ("omp allocator"),
7041 build_tree_list (NULL_TREE, alloc),
7042 DECL_ATTRIBUTES (omp_alt_alloc));
7043 omp_alt_alloc = build_call_expr (omp_alt_alloc, 3, align, sz, alloc);
7044 succ_add_expr = gfc_omp_call_add_alloc (se.expr);
7047 /* Store the caf-attributes for latter use. */
7048 if (use_coarray_alloc)
7050 /* Scalar allocatable components in coarray'ed derived types make
7051 it here and are treated now. */
7052 tree caf_decl, token;
7053 gfc_se caf_se;
7055 is_coarray = true;
7056 /* Set flag, to add synchronize after the allocate. */
7057 needs_caf_sync = needs_caf_sync
7058 || caf_attr.coarray_comp || !caf_refs_comp;
7060 gfc_init_se (&caf_se, NULL);
7062 caf_decl = gfc_get_tree_for_caf_expr (expr);
7063 gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl,
7064 NULL_TREE, NULL);
7065 gfc_add_block_to_block (&se.pre, &caf_se.pre);
7066 gfc_allocate_allocatable (&se.pre, se.expr, memsz,
7067 gfc_build_addr_expr (NULL_TREE, token),
7068 NULL_TREE, NULL_TREE, NULL_TREE,
7069 label_finish, expr, 1);
7071 /* Allocate - for non-pointers with re-alloc checking. */
7072 else if (gfc_expr_attr (expr).allocatable)
7073 gfc_allocate_allocatable (&se.pre, se.expr, memsz,
7074 NULL_TREE, stat, errmsg, errlen,
7075 label_finish, expr, 0,
7076 omp_cond, omp_alt_alloc, succ_add_expr);
7077 else
7078 gfc_allocate_using_malloc (&se.pre, se.expr, memsz, stat,
7079 omp_cond, omp_alt_alloc, succ_add_expr);
7081 else
7083 /* Allocating coarrays needs a sync after the allocate executed.
7084 Set the flag to add the sync after all objects are allocated. */
7085 if (flag_coarray == GFC_FCOARRAY_LIB
7086 && (caf_attr = gfc_caf_attr (expr, true, &caf_refs_comp))
7087 .codimension)
7089 is_coarray = true;
7090 needs_caf_sync = needs_caf_sync
7091 || caf_attr.coarray_comp || !caf_refs_comp;
7094 if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
7095 && expr3_len != NULL_TREE)
7097 /* Arrays need to have a _len set before the array
7098 descriptor is filled. */
7099 gfc_add_modify (&block, al_len,
7100 fold_convert (TREE_TYPE (al_len), expr3_len));
7101 /* Prevent setting the length twice. */
7102 al_len_needs_set = false;
7104 else if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
7105 && code->ext.alloc.ts.u.cl->length)
7107 /* Cover the cases where a string length is explicitly
7108 specified by a type spec for deferred length character
7109 arrays or unlimited polymorphic objects without a
7110 source= or mold= expression. */
7111 gfc_init_se (&se_sz, NULL);
7112 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
7113 gfc_add_block_to_block (&block, &se_sz.pre);
7114 gfc_add_modify (&block, al_len,
7115 fold_convert (TREE_TYPE (al_len),
7116 se_sz.expr));
7117 al_len_needs_set = false;
7121 gfc_add_block_to_block (&block, &se.pre);
7123 /* Error checking -- Note: ERRMSG only makes sense with STAT. */
7124 if (code->expr1)
7126 tmp = build1_v (GOTO_EXPR, label_errmsg);
7127 parm = fold_build2_loc (input_location, NE_EXPR,
7128 logical_type_node, stat,
7129 build_int_cst (TREE_TYPE (stat), 0));
7130 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
7131 gfc_unlikely (parm, PRED_FORTRAN_FAIL_ALLOC),
7132 tmp, build_empty_stmt (input_location));
7133 gfc_add_expr_to_block (&block, tmp);
7136 /* Set the vptr only when no source= is set. When source= is set, then
7137 the trans_assignment below will set the vptr. */
7138 if (al_vptr != NULL_TREE && (!code->expr3 || code->expr3->mold))
7140 if (expr3_vptr != NULL_TREE)
7141 /* The vtab is already known, so just assign it. */
7142 gfc_add_modify (&block, al_vptr,
7143 fold_convert (TREE_TYPE (al_vptr), expr3_vptr));
7144 else
7146 /* VPTR is fixed at compile time. */
7147 gfc_symbol *vtab;
7148 gfc_typespec *ts;
7150 if (code->expr3)
7151 /* Although expr3 is pre-evaluated above, it may happen,
7152 that for arrays or in mold= cases the pre-evaluation
7153 was not successful. In these rare cases take the vtab
7154 from the typespec of expr3 here. */
7155 ts = &code->expr3->ts;
7156 else if (code->ext.alloc.ts.type == BT_DERIVED || upoly_expr)
7157 /* The alloc_type_spec gives the type to allocate or the
7158 al is unlimited polymorphic, which enforces the use of
7159 an alloc_type_spec that is not necessarily a BT_DERIVED. */
7160 ts = &code->ext.alloc.ts;
7161 else
7162 /* Prepare for setting the vtab as declared. */
7163 ts = &expr->ts;
7165 vtab = gfc_find_vtab (ts);
7166 gcc_assert (vtab);
7167 tmp = gfc_build_addr_expr (NULL_TREE,
7168 gfc_get_symbol_decl (vtab));
7169 gfc_add_modify (&block, al_vptr,
7170 fold_convert (TREE_TYPE (al_vptr), tmp));
7174 /* Add assignment for string length. */
7175 if (al_len != NULL_TREE && al_len_needs_set)
7177 if (expr3_len != NULL_TREE)
7179 gfc_add_modify (&block, al_len,
7180 fold_convert (TREE_TYPE (al_len),
7181 expr3_len));
7182 /* When tmp_expr3_len_flag is set, then expr3_len is
7183 abused to carry the length information from the
7184 alloc_type. Clear it to prevent setting incorrect len
7185 information in future loop iterations. */
7186 if (tmp_expr3_len_flag)
7187 /* No need to reset tmp_expr3_len_flag, because the
7188 presence of an expr3 cannot change within in the
7189 loop. */
7190 expr3_len = NULL_TREE;
7192 else if (code->ext.alloc.ts.type == BT_CHARACTER
7193 && code->ext.alloc.ts.u.cl->length)
7195 /* Cover the cases where a string length is explicitly
7196 specified by a type spec for deferred length character
7197 arrays or unlimited polymorphic objects without a
7198 source= or mold= expression. */
7199 if (expr3_esize == NULL_TREE || code->ext.alloc.ts.kind != 1)
7201 gfc_init_se (&se_sz, NULL);
7202 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
7203 gfc_add_block_to_block (&block, &se_sz.pre);
7204 gfc_add_modify (&block, al_len,
7205 fold_convert (TREE_TYPE (al_len),
7206 se_sz.expr));
7208 else
7209 gfc_add_modify (&block, al_len,
7210 fold_convert (TREE_TYPE (al_len),
7211 expr3_esize));
7213 else
7214 /* No length information needed, because type to allocate
7215 has no length. Set _len to 0. */
7216 gfc_add_modify (&block, al_len,
7217 fold_convert (TREE_TYPE (al_len),
7218 integer_zero_node));
7221 init_expr = NULL;
7222 if (code->expr3 && !code->expr3->mold && e3_is != E3_MOLD)
7224 /* Initialization via SOURCE block (or static default initializer).
7225 Switch off automatic reallocation since we have just done the
7226 ALLOCATE. */
7227 int realloc_lhs = flag_realloc_lhs;
7228 gfc_expr *init_expr = gfc_expr_to_initialize (expr);
7229 gfc_expr *rhs = e3rhs ? e3rhs : gfc_copy_expr (code->expr3);
7230 flag_realloc_lhs = 0;
7232 /* The handling of code->expr3 above produces a derived type of
7233 type "STAR", whose size defaults to size(void*). In order to
7234 have the right type information for the assignment, we must
7235 reconstruct an unlimited polymorphic rhs. */
7236 if (UNLIMITED_POLY (code->expr3)
7237 && e3rhs && e3rhs->ts.type == BT_DERIVED
7238 && !strcmp (e3rhs->ts.u.derived->name, "STAR"))
7240 gfc_ref *ref;
7241 gcc_assert (TREE_CODE (expr3_vptr) == COMPONENT_REF);
7242 tmp = gfc_create_var (gfc_typenode_for_spec (&code->expr3->ts),
7243 "e3");
7244 gfc_add_modify (&block, tmp,
7245 gfc_get_class_from_expr (expr3_vptr));
7246 rhs->symtree->n.sym->backend_decl = tmp;
7247 rhs->ts = code->expr3->ts;
7248 rhs->symtree->n.sym->ts = rhs->ts;
7249 for (ref = init_expr->ref; ref; ref = ref->next)
7251 /* Copy over the lhs _data component ref followed by the
7252 full array reference for source expressions with rank.
7253 Otherwise, just copy the _data component ref. */
7254 if (code->expr3->rank
7255 && ref && ref->next && !ref->next->next)
7257 rhs->ref = gfc_copy_ref (ref);
7258 break;
7260 else if ((init_expr->rank && !code->expr3->rank
7261 && ref && ref->next && !ref->next->next)
7262 || (ref && !ref->next))
7264 rhs->ref = gfc_copy_ref (ref);
7265 gfc_free_ref_list (rhs->ref->next);
7266 rhs->ref->next = NULL;
7267 break;
7272 /* Set the symbol to be artificial so that the result is not finalized. */
7273 init_expr->symtree->n.sym->attr.artificial = 1;
7274 tmp = gfc_trans_assignment (init_expr, rhs, true, false, true,
7275 false);
7276 init_expr->symtree->n.sym->attr.artificial = 0;
7278 flag_realloc_lhs = realloc_lhs;
7279 /* Free the expression allocated for init_expr. */
7280 gfc_free_expr (init_expr);
7281 if (rhs != e3rhs)
7282 gfc_free_expr (rhs);
7283 gfc_add_expr_to_block (&block, tmp);
7285 /* Set KIND and LEN PDT components and allocate those that are
7286 parameterized. */
7287 else if (expr->ts.type == BT_DERIVED
7288 && expr->ts.u.derived->attr.pdt_type)
7290 if (code->expr3 && code->expr3->param_list)
7291 param_list = code->expr3->param_list;
7292 else if (expr->param_list)
7293 param_list = expr->param_list;
7294 else
7295 param_list = expr->symtree->n.sym->param_list;
7296 tmp = gfc_allocate_pdt_comp (expr->ts.u.derived, se.expr,
7297 expr->rank, param_list);
7298 gfc_add_expr_to_block (&block, tmp);
7300 /* Ditto for CLASS expressions. */
7301 else if (expr->ts.type == BT_CLASS
7302 && CLASS_DATA (expr)->ts.u.derived->attr.pdt_type)
7304 if (code->expr3 && code->expr3->param_list)
7305 param_list = code->expr3->param_list;
7306 else if (expr->param_list)
7307 param_list = expr->param_list;
7308 else
7309 param_list = expr->symtree->n.sym->param_list;
7310 tmp = gfc_allocate_pdt_comp (CLASS_DATA (expr)->ts.u.derived,
7311 se.expr, expr->rank, param_list);
7312 gfc_add_expr_to_block (&block, tmp);
7314 else if (code->expr3 && code->expr3->mold
7315 && code->expr3->ts.type == BT_CLASS)
7317 /* Use class_init_assign to initialize expr. */
7318 gfc_code *ini;
7319 ini = gfc_get_code (EXEC_ALLOCATE);
7320 ini->expr1 = gfc_find_and_cut_at_last_class_ref (expr, true);
7321 tmp = gfc_trans_class_init_assign (ini);
7322 gfc_free_statements (ini);
7323 if (tmp != NULL_TREE)
7324 gfc_add_expr_to_block (&block, tmp);
7326 else if ((init_expr = allocate_get_initializer (code, expr)))
7328 /* Use class_init_assign to initialize expr. */
7329 gfc_code *ini;
7330 int realloc_lhs = flag_realloc_lhs;
7331 ini = gfc_get_code (EXEC_INIT_ASSIGN);
7332 ini->expr1 = gfc_expr_to_initialize (expr);
7333 ini->expr2 = init_expr;
7334 flag_realloc_lhs = 0;
7335 tmp= gfc_trans_init_assign (ini);
7336 flag_realloc_lhs = realloc_lhs;
7337 gfc_free_statements (ini);
7338 /* Init_expr is freeed by above free_statements, just need to null
7339 it here. */
7340 init_expr = NULL;
7341 gfc_add_expr_to_block (&block, tmp);
7344 /* Nullify all pointers in derived type coarrays. This registers a
7345 token for them which allows their allocation. */
7346 if (is_coarray)
7348 gfc_symbol *type = NULL;
7349 symbol_attribute caf_attr;
7350 int rank = 0;
7351 if (code->ext.alloc.ts.type == BT_DERIVED
7352 && code->ext.alloc.ts.u.derived->attr.pointer_comp)
7354 type = code->ext.alloc.ts.u.derived;
7355 rank = type->attr.dimension ? type->as->rank : 0;
7356 gfc_clear_attr (&caf_attr);
7358 else if (expr->ts.type == BT_DERIVED
7359 && expr->ts.u.derived->attr.pointer_comp)
7361 type = expr->ts.u.derived;
7362 rank = expr->rank;
7363 caf_attr = gfc_caf_attr (expr, true);
7366 /* Initialize the tokens of pointer components in derived type
7367 coarrays. */
7368 if (type)
7370 tmp = (caf_attr.codimension && !caf_attr.dimension)
7371 ? gfc_conv_descriptor_data_get (se.expr) : se.expr;
7372 tmp = gfc_nullify_alloc_comp (type, tmp, rank,
7373 GFC_STRUCTURE_CAF_MODE_IN_COARRAY);
7374 gfc_add_expr_to_block (&block, tmp);
7378 gfc_free_expr (expr);
7379 } // for-loop
7381 if (e3rhs)
7383 if (newsym)
7385 gfc_free_symbol (newsym->n.sym);
7386 XDELETE (newsym);
7388 gfc_free_expr (e3rhs);
7390 /* STAT. */
7391 if (code->expr1)
7393 tmp = build1_v (LABEL_EXPR, label_errmsg);
7394 gfc_add_expr_to_block (&block, tmp);
7397 /* ERRMSG - only useful if STAT is present. */
7398 if (code->expr1 && code->expr2)
7400 const char *msg = "Attempt to allocate an allocated object";
7401 const char *oommsg = "Insufficient virtual memory";
7402 tree slen, dlen, errmsg_str, oom_str, oom_loc;
7403 stmtblock_t errmsg_block;
7405 gfc_init_block (&errmsg_block);
7407 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
7408 gfc_add_modify (&errmsg_block, errmsg_str,
7409 gfc_build_addr_expr (pchar_type_node,
7410 gfc_build_localized_cstring_const (msg)));
7412 slen = build_int_cst (gfc_charlen_type_node, strlen (msg));
7413 dlen = gfc_get_expr_charlen (code->expr2);
7414 slen = fold_build2_loc (input_location, MIN_EXPR,
7415 TREE_TYPE (slen), dlen, slen);
7417 gfc_trans_string_copy (&errmsg_block, dlen, errmsg,
7418 code->expr2->ts.kind,
7419 slen, errmsg_str,
7420 gfc_default_character_kind);
7421 dlen = gfc_finish_block (&errmsg_block);
7423 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
7424 stat, build_int_cst (TREE_TYPE (stat),
7425 LIBERROR_ALLOCATION));
7427 tmp = build3_v (COND_EXPR, tmp,
7428 dlen, build_empty_stmt (input_location));
7430 gfc_add_expr_to_block (&block, tmp);
7432 oom_str = gfc_create_var (pchar_type_node, "OOMMSG");
7433 oom_loc = gfc_build_localized_cstring_const (oommsg);
7434 gfc_add_modify (&errmsg_block, oom_str,
7435 gfc_build_addr_expr (pchar_type_node, oom_loc));
7437 slen = build_int_cst (gfc_charlen_type_node, strlen (oommsg));
7438 dlen = gfc_get_expr_charlen (code->expr2);
7439 slen = fold_build2_loc (input_location, MIN_EXPR,
7440 TREE_TYPE (slen), dlen, slen);
7442 gfc_trans_string_copy (&errmsg_block, dlen, errmsg,
7443 code->expr2->ts.kind,
7444 slen, oom_str,
7445 gfc_default_character_kind);
7446 dlen = gfc_finish_block (&errmsg_block);
7448 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
7449 stat, build_int_cst (TREE_TYPE (stat),
7450 LIBERROR_NO_MEMORY));
7452 tmp = build3_v (COND_EXPR, tmp,
7453 dlen, build_empty_stmt (input_location));
7455 gfc_add_expr_to_block (&block, tmp);
7458 /* STAT block. */
7459 if (code->expr1)
7461 if (TREE_USED (label_finish))
7463 tmp = build1_v (LABEL_EXPR, label_finish);
7464 gfc_add_expr_to_block (&block, tmp);
7467 gfc_init_se (&se, NULL);
7468 gfc_conv_expr_lhs (&se, code->expr1);
7469 tmp = convert (TREE_TYPE (se.expr), stat);
7470 gfc_add_modify (&block, se.expr, tmp);
7473 if (needs_caf_sync)
7475 /* Add a sync all after the allocation has been executed. */
7476 tree zero_size = build_zero_cst (size_type_node);
7477 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
7478 3, null_pointer_node, null_pointer_node,
7479 zero_size);
7480 gfc_add_expr_to_block (&post, tmp);
7483 gfc_add_block_to_block (&block, &se.post);
7484 gfc_add_block_to_block (&block, &post);
7485 if (code->expr3 && code->expr3->must_finalize)
7486 gfc_add_block_to_block (&block, &final_block);
7488 return gfc_finish_block (&block);
7492 /* Translate a DEALLOCATE statement. */
7494 tree
7495 gfc_trans_deallocate (gfc_code *code)
7497 gfc_se se;
7498 gfc_alloc *al;
7499 tree apstat, pstat, stat, errmsg, errlen, tmp;
7500 tree label_finish, label_errmsg;
7501 stmtblock_t block;
7503 pstat = apstat = stat = errmsg = errlen = tmp = NULL_TREE;
7504 label_finish = label_errmsg = NULL_TREE;
7506 gfc_start_block (&block);
7508 /* Count the number of failed deallocations. If deallocate() was
7509 called with STAT= , then set STAT to the count. If deallocate
7510 was called with ERRMSG, then set ERRMG to a string. */
7511 if (code->expr1)
7513 tree gfc_int4_type_node = gfc_get_int_type (4);
7515 stat = gfc_create_var (gfc_int4_type_node, "stat");
7516 pstat = gfc_build_addr_expr (NULL_TREE, stat);
7518 /* GOTO destinations. */
7519 label_errmsg = gfc_build_label_decl (NULL_TREE);
7520 label_finish = gfc_build_label_decl (NULL_TREE);
7521 TREE_USED (label_finish) = 0;
7524 /* Set ERRMSG - only needed if STAT is available. */
7525 if (code->expr1 && code->expr2)
7527 gfc_init_se (&se, NULL);
7528 se.want_pointer = 1;
7529 gfc_conv_expr_lhs (&se, code->expr2);
7530 errmsg = se.expr;
7531 errlen = se.string_length;
7534 for (al = code->ext.alloc.list; al != NULL; al = al->next)
7536 gfc_expr *expr = gfc_copy_expr (al->expr);
7537 bool is_coarray = false, is_coarray_array = false;
7538 int caf_mode = 0;
7540 gcc_assert (expr->expr_type == EXPR_VARIABLE);
7542 if (expr->ts.type == BT_CLASS)
7543 gfc_add_data_component (expr);
7545 gfc_init_se (&se, NULL);
7546 gfc_start_block (&se.pre);
7548 se.want_pointer = 1;
7549 se.descriptor_only = 1;
7550 gfc_conv_expr (&se, expr);
7552 /* Deallocate PDT components that are parameterized. */
7553 tmp = NULL;
7554 if (expr->ts.type == BT_DERIVED
7555 && expr->ts.u.derived->attr.pdt_type
7556 && expr->symtree->n.sym->param_list)
7557 tmp = gfc_deallocate_pdt_comp (expr->ts.u.derived, se.expr, expr->rank);
7558 else if (expr->ts.type == BT_CLASS
7559 && CLASS_DATA (expr)->ts.u.derived->attr.pdt_type
7560 && expr->symtree->n.sym->param_list)
7561 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr)->ts.u.derived,
7562 se.expr, expr->rank);
7564 if (tmp)
7565 gfc_add_expr_to_block (&block, tmp);
7567 if (flag_coarray == GFC_FCOARRAY_LIB
7568 || flag_coarray == GFC_FCOARRAY_SINGLE)
7570 bool comp_ref;
7571 symbol_attribute caf_attr = gfc_caf_attr (expr, false, &comp_ref);
7572 if (caf_attr.codimension)
7574 is_coarray = true;
7575 is_coarray_array = caf_attr.dimension || !comp_ref
7576 || caf_attr.coarray_comp;
7578 if (flag_coarray == GFC_FCOARRAY_LIB)
7579 /* When the expression to deallocate is referencing a
7580 component, then only deallocate it, but do not
7581 deregister. */
7582 caf_mode = GFC_STRUCTURE_CAF_MODE_IN_COARRAY
7583 | (comp_ref && !caf_attr.coarray_comp
7584 ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY : 0);
7588 if (expr->rank || is_coarray_array)
7590 gfc_ref *ref;
7592 if (gfc_bt_struct (expr->ts.type)
7593 && expr->ts.u.derived->attr.alloc_comp
7594 && !gfc_is_finalizable (expr->ts.u.derived, NULL))
7596 gfc_ref *last = NULL;
7598 for (ref = expr->ref; ref; ref = ref->next)
7599 if (ref->type == REF_COMPONENT)
7600 last = ref;
7602 /* Do not deallocate the components of a derived type
7603 ultimate pointer component. */
7604 if (!(last && last->u.c.component->attr.pointer)
7605 && !(!last && expr->symtree->n.sym->attr.pointer))
7607 if (is_coarray && expr->rank == 0
7608 && (!last || !last->u.c.component->attr.dimension)
7609 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
7611 /* Add the ref to the data member only, when this is not
7612 a regular array or deallocate_alloc_comp will try to
7613 add another one. */
7614 tmp = gfc_conv_descriptor_data_get (se.expr);
7616 else
7617 tmp = se.expr;
7618 tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp,
7619 expr->rank, caf_mode);
7620 gfc_add_expr_to_block (&se.pre, tmp);
7624 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
7626 gfc_coarray_deregtype caf_dtype;
7628 if (is_coarray)
7629 caf_dtype = gfc_caf_is_dealloc_only (caf_mode)
7630 ? GFC_CAF_COARRAY_DEALLOCATE_ONLY
7631 : GFC_CAF_COARRAY_DEREGISTER;
7632 else
7633 caf_dtype = GFC_CAF_COARRAY_NOCOARRAY;
7634 tmp = gfc_deallocate_with_status (se.expr, pstat, errmsg, errlen,
7635 label_finish, false, expr,
7636 caf_dtype);
7637 gfc_add_expr_to_block (&se.pre, tmp);
7639 else if (TREE_CODE (se.expr) == COMPONENT_REF
7640 && TREE_CODE (TREE_TYPE (se.expr)) == ARRAY_TYPE
7641 && TREE_CODE (TREE_TYPE (TREE_TYPE (se.expr)))
7642 == RECORD_TYPE)
7644 /* class.cc(finalize_component) generates these, when a
7645 finalizable entity has a non-allocatable derived type array
7646 component, which has allocatable components. Obtain the
7647 derived type of the array and deallocate the allocatable
7648 components. */
7649 for (ref = expr->ref; ref; ref = ref->next)
7651 if (ref->u.c.component->attr.dimension
7652 && ref->u.c.component->ts.type == BT_DERIVED)
7653 break;
7656 if (ref && ref->u.c.component->ts.u.derived->attr.alloc_comp
7657 && !gfc_is_finalizable (ref->u.c.component->ts.u.derived,
7658 NULL))
7660 tmp = gfc_deallocate_alloc_comp
7661 (ref->u.c.component->ts.u.derived,
7662 se.expr, expr->rank);
7663 gfc_add_expr_to_block (&se.pre, tmp);
7667 if (al->expr->ts.type == BT_CLASS)
7669 gfc_reset_vptr (&se.pre, al->expr);
7670 if (UNLIMITED_POLY (al->expr)
7671 || (al->expr->ts.type == BT_DERIVED
7672 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
7673 /* Clear _len, too. */
7674 gfc_reset_len (&se.pre, al->expr);
7677 else
7679 tmp = gfc_deallocate_scalar_with_status (se.expr, pstat, label_finish,
7680 false, al->expr,
7681 al->expr->ts, NULL_TREE,
7682 is_coarray);
7683 gfc_add_expr_to_block (&se.pre, tmp);
7685 /* Set to zero after deallocation. */
7686 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
7687 se.expr,
7688 build_int_cst (TREE_TYPE (se.expr), 0));
7689 gfc_add_expr_to_block (&se.pre, tmp);
7691 if (al->expr->ts.type == BT_CLASS)
7693 gfc_reset_vptr (&se.pre, al->expr);
7694 if (UNLIMITED_POLY (al->expr)
7695 || (al->expr->ts.type == BT_DERIVED
7696 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
7697 /* Clear _len, too. */
7698 gfc_reset_len (&se.pre, al->expr);
7702 if (code->expr1)
7704 tree cond;
7706 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, stat,
7707 build_int_cst (TREE_TYPE (stat), 0));
7708 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
7709 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
7710 build1_v (GOTO_EXPR, label_errmsg),
7711 build_empty_stmt (input_location));
7712 gfc_add_expr_to_block (&se.pre, tmp);
7715 tmp = gfc_finish_block (&se.pre);
7716 gfc_add_expr_to_block (&block, tmp);
7717 gfc_free_expr (expr);
7720 if (code->expr1)
7722 tmp = build1_v (LABEL_EXPR, label_errmsg);
7723 gfc_add_expr_to_block (&block, tmp);
7726 /* Set ERRMSG - only needed if STAT is available. */
7727 if (code->expr1 && code->expr2)
7729 const char *msg = "Attempt to deallocate an unallocated object";
7730 stmtblock_t errmsg_block;
7731 tree errmsg_str, slen, dlen, cond;
7733 gfc_init_block (&errmsg_block);
7735 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
7736 gfc_add_modify (&errmsg_block, errmsg_str,
7737 gfc_build_addr_expr (pchar_type_node,
7738 gfc_build_localized_cstring_const (msg)));
7739 slen = build_int_cst (gfc_charlen_type_node, strlen (msg));
7740 dlen = gfc_get_expr_charlen (code->expr2);
7742 gfc_trans_string_copy (&errmsg_block, dlen, errmsg, code->expr2->ts.kind,
7743 slen, errmsg_str, gfc_default_character_kind);
7744 tmp = gfc_finish_block (&errmsg_block);
7746 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, stat,
7747 build_int_cst (TREE_TYPE (stat), 0));
7748 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
7749 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC), tmp,
7750 build_empty_stmt (input_location));
7752 gfc_add_expr_to_block (&block, tmp);
7755 if (code->expr1 && TREE_USED (label_finish))
7757 tmp = build1_v (LABEL_EXPR, label_finish);
7758 gfc_add_expr_to_block (&block, tmp);
7761 /* Set STAT. */
7762 if (code->expr1)
7764 gfc_init_se (&se, NULL);
7765 gfc_conv_expr_lhs (&se, code->expr1);
7766 tmp = convert (TREE_TYPE (se.expr), stat);
7767 gfc_add_modify (&block, se.expr, tmp);
7770 return gfc_finish_block (&block);
7773 #include "gt-fortran-trans-stmt.h"