* configure.ac (LD_AS_NEEDED_OPTION, LD_NO_AS_NEEDED_OPTION): Use
[official-gcc.git] / gcc / fortran / trans-stmt.c
blob1952f6cdc0847fb6b945cddb9dab469291187dd3
1 /* Statement translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2002-2018 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 struct iter_info *next;
46 iter_info;
48 typedef struct forall_info
50 iter_info *this_loop;
51 tree mask;
52 tree maskindex;
53 int nvar;
54 tree size;
55 struct forall_info *prev_nest;
56 bool do_concurrent;
58 forall_info;
60 static void gfc_trans_where_2 (gfc_code *, tree, bool,
61 forall_info *, stmtblock_t *);
63 /* Translate a F95 label number to a LABEL_EXPR. */
65 tree
66 gfc_trans_label_here (gfc_code * code)
68 return build1_v (LABEL_EXPR, gfc_get_label_decl (code->here));
72 /* Given a variable expression which has been ASSIGNed to, find the decl
73 containing the auxiliary variables. For variables in common blocks this
74 is a field_decl. */
76 void
77 gfc_conv_label_variable (gfc_se * se, gfc_expr * expr)
79 gcc_assert (expr->symtree->n.sym->attr.assign == 1);
80 gfc_conv_expr (se, expr);
81 /* Deals with variable in common block. Get the field declaration. */
82 if (TREE_CODE (se->expr) == COMPONENT_REF)
83 se->expr = TREE_OPERAND (se->expr, 1);
84 /* Deals with dummy argument. Get the parameter declaration. */
85 else if (TREE_CODE (se->expr) == INDIRECT_REF)
86 se->expr = TREE_OPERAND (se->expr, 0);
89 /* Translate a label assignment statement. */
91 tree
92 gfc_trans_label_assign (gfc_code * code)
94 tree label_tree;
95 gfc_se se;
96 tree len;
97 tree addr;
98 tree len_tree;
99 int label_len;
101 /* Start a new block. */
102 gfc_init_se (&se, NULL);
103 gfc_start_block (&se.pre);
104 gfc_conv_label_variable (&se, code->expr1);
106 len = GFC_DECL_STRING_LEN (se.expr);
107 addr = GFC_DECL_ASSIGN_ADDR (se.expr);
109 label_tree = gfc_get_label_decl (code->label1);
111 if (code->label1->defined == ST_LABEL_TARGET
112 || code->label1->defined == ST_LABEL_DO_TARGET)
114 label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
115 len_tree = build_int_cst (gfc_charlen_type_node, -1);
117 else
119 gfc_expr *format = code->label1->format;
121 label_len = format->value.character.length;
122 len_tree = build_int_cst (gfc_charlen_type_node, label_len);
123 label_tree = gfc_build_wide_string_const (format->ts.kind, label_len + 1,
124 format->value.character.string);
125 label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
128 gfc_add_modify (&se.pre, len, fold_convert (TREE_TYPE (len), len_tree));
129 gfc_add_modify (&se.pre, addr, label_tree);
131 return gfc_finish_block (&se.pre);
134 /* Translate a GOTO statement. */
136 tree
137 gfc_trans_goto (gfc_code * code)
139 locus loc = code->loc;
140 tree assigned_goto;
141 tree target;
142 tree tmp;
143 gfc_se se;
145 if (code->label1 != NULL)
146 return build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
148 /* ASSIGNED GOTO. */
149 gfc_init_se (&se, NULL);
150 gfc_start_block (&se.pre);
151 gfc_conv_label_variable (&se, code->expr1);
152 tmp = GFC_DECL_STRING_LEN (se.expr);
153 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp,
154 build_int_cst (TREE_TYPE (tmp), -1));
155 gfc_trans_runtime_check (true, false, tmp, &se.pre, &loc,
156 "Assigned label is not a target label");
158 assigned_goto = GFC_DECL_ASSIGN_ADDR (se.expr);
160 /* We're going to ignore a label list. It does not really change the
161 statement's semantics (because it is just a further restriction on
162 what's legal code); before, we were comparing label addresses here, but
163 that's a very fragile business and may break with optimization. So
164 just ignore it. */
166 target = fold_build1_loc (input_location, GOTO_EXPR, void_type_node,
167 assigned_goto);
168 gfc_add_expr_to_block (&se.pre, target);
169 return gfc_finish_block (&se.pre);
173 /* Translate an ENTRY statement. Just adds a label for this entry point. */
174 tree
175 gfc_trans_entry (gfc_code * code)
177 return build1_v (LABEL_EXPR, code->ext.entry->label);
181 /* Replace a gfc_ss structure by another both in the gfc_se struct
182 and the gfc_loopinfo struct. This is used in gfc_conv_elemental_dependencies
183 to replace a variable ss by the corresponding temporary. */
185 static void
186 replace_ss (gfc_se *se, gfc_ss *old_ss, gfc_ss *new_ss)
188 gfc_ss **sess, **loopss;
190 /* The old_ss is a ss for a single variable. */
191 gcc_assert (old_ss->info->type == GFC_SS_SECTION);
193 for (sess = &(se->ss); *sess != gfc_ss_terminator; sess = &((*sess)->next))
194 if (*sess == old_ss)
195 break;
196 gcc_assert (*sess != gfc_ss_terminator);
198 *sess = new_ss;
199 new_ss->next = old_ss->next;
202 for (loopss = &(se->loop->ss); *loopss != gfc_ss_terminator;
203 loopss = &((*loopss)->loop_chain))
204 if (*loopss == old_ss)
205 break;
206 gcc_assert (*loopss != gfc_ss_terminator);
208 *loopss = new_ss;
209 new_ss->loop_chain = old_ss->loop_chain;
210 new_ss->loop = old_ss->loop;
212 gfc_free_ss (old_ss);
216 /* Check for dependencies between INTENT(IN) and INTENT(OUT) arguments of
217 elemental subroutines. Make temporaries for output arguments if any such
218 dependencies are found. Output arguments are chosen because internal_unpack
219 can be used, as is, to copy the result back to the variable. */
220 static void
221 gfc_conv_elemental_dependencies (gfc_se * se, gfc_se * loopse,
222 gfc_symbol * sym, gfc_actual_arglist * arg,
223 gfc_dep_check check_variable)
225 gfc_actual_arglist *arg0;
226 gfc_expr *e;
227 gfc_formal_arglist *formal;
228 gfc_se parmse;
229 gfc_ss *ss;
230 gfc_symbol *fsym;
231 tree data;
232 tree size;
233 tree tmp;
235 if (loopse->ss == NULL)
236 return;
238 ss = loopse->ss;
239 arg0 = arg;
240 formal = gfc_sym_get_dummy_args (sym);
242 /* Loop over all the arguments testing for dependencies. */
243 for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
245 e = arg->expr;
246 if (e == NULL)
247 continue;
249 /* Obtain the info structure for the current argument. */
250 for (ss = loopse->ss; ss && ss != gfc_ss_terminator; ss = ss->next)
251 if (ss->info->expr == e)
252 break;
254 /* If there is a dependency, create a temporary and use it
255 instead of the variable. */
256 fsym = formal ? formal->sym : NULL;
257 if (e->expr_type == EXPR_VARIABLE
258 && e->rank && fsym
259 && fsym->attr.intent != INTENT_IN
260 && gfc_check_fncall_dependency (e, fsym->attr.intent,
261 sym, arg0, check_variable))
263 tree initial, temptype;
264 stmtblock_t temp_post;
265 gfc_ss *tmp_ss;
267 tmp_ss = gfc_get_array_ss (gfc_ss_terminator, NULL, ss->dimen,
268 GFC_SS_SECTION);
269 gfc_mark_ss_chain_used (tmp_ss, 1);
270 tmp_ss->info->expr = ss->info->expr;
271 replace_ss (loopse, ss, tmp_ss);
273 /* Obtain the argument descriptor for unpacking. */
274 gfc_init_se (&parmse, NULL);
275 parmse.want_pointer = 1;
276 gfc_conv_expr_descriptor (&parmse, e);
277 gfc_add_block_to_block (&se->pre, &parmse.pre);
279 /* If we've got INTENT(INOUT) or a derived type with INTENT(OUT),
280 initialize the array temporary with a copy of the values. */
281 if (fsym->attr.intent == INTENT_INOUT
282 || (fsym->ts.type ==BT_DERIVED
283 && fsym->attr.intent == INTENT_OUT))
284 initial = parmse.expr;
285 /* For class expressions, we always initialize with the copy of
286 the values. */
287 else if (e->ts.type == BT_CLASS)
288 initial = parmse.expr;
289 else
290 initial = NULL_TREE;
292 if (e->ts.type != BT_CLASS)
294 /* Find the type of the temporary to create; we don't use the type
295 of e itself as this breaks for subcomponent-references in e
296 (where the type of e is that of the final reference, but
297 parmse.expr's type corresponds to the full derived-type). */
298 /* TODO: Fix this somehow so we don't need a temporary of the whole
299 array but instead only the components referenced. */
300 temptype = TREE_TYPE (parmse.expr); /* Pointer to descriptor. */
301 gcc_assert (TREE_CODE (temptype) == POINTER_TYPE);
302 temptype = TREE_TYPE (temptype);
303 temptype = gfc_get_element_type (temptype);
306 else
307 /* For class arrays signal that the size of the dynamic type has to
308 be obtained from the vtable, using the 'initial' expression. */
309 temptype = NULL_TREE;
311 /* Generate the temporary. Cleaning up the temporary should be the
312 very last thing done, so we add the code to a new block and add it
313 to se->post as last instructions. */
314 size = gfc_create_var (gfc_array_index_type, NULL);
315 data = gfc_create_var (pvoid_type_node, NULL);
316 gfc_init_block (&temp_post);
317 tmp = gfc_trans_create_temp_array (&se->pre, &temp_post, tmp_ss,
318 temptype, initial, false, true,
319 false, &arg->expr->where);
320 gfc_add_modify (&se->pre, size, tmp);
321 tmp = fold_convert (pvoid_type_node, tmp_ss->info->data.array.data);
322 gfc_add_modify (&se->pre, data, tmp);
324 /* Update other ss' delta. */
325 gfc_set_delta (loopse->loop);
327 /* Copy the result back using unpack..... */
328 if (e->ts.type != BT_CLASS)
329 tmp = build_call_expr_loc (input_location,
330 gfor_fndecl_in_unpack, 2, parmse.expr, data);
331 else
333 /* ... except for class results where the copy is
334 unconditional. */
335 tmp = build_fold_indirect_ref_loc (input_location, parmse.expr);
336 tmp = gfc_conv_descriptor_data_get (tmp);
337 tmp = build_call_expr_loc (input_location,
338 builtin_decl_explicit (BUILT_IN_MEMCPY),
339 3, tmp, data,
340 fold_convert (size_type_node, size));
342 gfc_add_expr_to_block (&se->post, tmp);
344 /* parmse.pre is already added above. */
345 gfc_add_block_to_block (&se->post, &parmse.post);
346 gfc_add_block_to_block (&se->post, &temp_post);
352 /* Get the interface symbol for the procedure corresponding to the given call.
353 We can't get the procedure symbol directly as we have to handle the case
354 of (deferred) type-bound procedures. */
356 static gfc_symbol *
357 get_proc_ifc_for_call (gfc_code *c)
359 gfc_symbol *sym;
361 gcc_assert (c->op == EXEC_ASSIGN_CALL || c->op == EXEC_CALL);
363 sym = gfc_get_proc_ifc_for_expr (c->expr1);
365 /* Fall back/last resort try. */
366 if (sym == NULL)
367 sym = c->resolved_sym;
369 return sym;
373 /* Translate the CALL statement. Builds a call to an F95 subroutine. */
375 tree
376 gfc_trans_call (gfc_code * code, bool dependency_check,
377 tree mask, tree count1, bool invert)
379 gfc_se se;
380 gfc_ss * ss;
381 int has_alternate_specifier;
382 gfc_dep_check check_variable;
383 tree index = NULL_TREE;
384 tree maskexpr = NULL_TREE;
385 tree tmp;
387 /* A CALL starts a new block because the actual arguments may have to
388 be evaluated first. */
389 gfc_init_se (&se, NULL);
390 gfc_start_block (&se.pre);
392 gcc_assert (code->resolved_sym);
394 ss = gfc_ss_terminator;
395 if (code->resolved_sym->attr.elemental)
396 ss = gfc_walk_elemental_function_args (ss, code->ext.actual,
397 get_proc_ifc_for_call (code),
398 GFC_SS_REFERENCE);
400 /* Is not an elemental subroutine call with array valued arguments. */
401 if (ss == gfc_ss_terminator)
404 /* Translate the call. */
405 has_alternate_specifier
406 = gfc_conv_procedure_call (&se, code->resolved_sym, code->ext.actual,
407 code->expr1, NULL);
409 /* A subroutine without side-effect, by definition, does nothing! */
410 TREE_SIDE_EFFECTS (se.expr) = 1;
412 /* Chain the pieces together and return the block. */
413 if (has_alternate_specifier)
415 gfc_code *select_code;
416 gfc_symbol *sym;
417 select_code = code->next;
418 gcc_assert(select_code->op == EXEC_SELECT);
419 sym = select_code->expr1->symtree->n.sym;
420 se.expr = convert (gfc_typenode_for_spec (&sym->ts), se.expr);
421 if (sym->backend_decl == NULL)
422 sym->backend_decl = gfc_get_symbol_decl (sym);
423 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
425 else
426 gfc_add_expr_to_block (&se.pre, se.expr);
428 gfc_add_block_to_block (&se.pre, &se.post);
431 else
433 /* An elemental subroutine call with array valued arguments has
434 to be scalarized. */
435 gfc_loopinfo loop;
436 stmtblock_t body;
437 stmtblock_t block;
438 gfc_se loopse;
439 gfc_se depse;
441 /* gfc_walk_elemental_function_args renders the ss chain in the
442 reverse order to the actual argument order. */
443 ss = gfc_reverse_ss (ss);
445 /* Initialize the loop. */
446 gfc_init_se (&loopse, NULL);
447 gfc_init_loopinfo (&loop);
448 gfc_add_ss_to_loop (&loop, ss);
450 gfc_conv_ss_startstride (&loop);
451 /* TODO: gfc_conv_loop_setup generates a temporary for vector
452 subscripts. This could be prevented in the elemental case
453 as temporaries are handled separatedly
454 (below in gfc_conv_elemental_dependencies). */
455 if (code->expr1)
456 gfc_conv_loop_setup (&loop, &code->expr1->where);
457 else
458 gfc_conv_loop_setup (&loop, &code->loc);
460 gfc_mark_ss_chain_used (ss, 1);
462 /* Convert the arguments, checking for dependencies. */
463 gfc_copy_loopinfo_to_se (&loopse, &loop);
464 loopse.ss = ss;
466 /* For operator assignment, do dependency checking. */
467 if (dependency_check)
468 check_variable = ELEM_CHECK_VARIABLE;
469 else
470 check_variable = ELEM_DONT_CHECK_VARIABLE;
472 gfc_init_se (&depse, NULL);
473 gfc_conv_elemental_dependencies (&depse, &loopse, code->resolved_sym,
474 code->ext.actual, check_variable);
476 gfc_add_block_to_block (&loop.pre, &depse.pre);
477 gfc_add_block_to_block (&loop.post, &depse.post);
479 /* Generate the loop body. */
480 gfc_start_scalarized_body (&loop, &body);
481 gfc_init_block (&block);
483 if (mask && count1)
485 /* Form the mask expression according to the mask. */
486 index = count1;
487 maskexpr = gfc_build_array_ref (mask, index, NULL);
488 if (invert)
489 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
490 TREE_TYPE (maskexpr), maskexpr);
493 /* Add the subroutine call to the block. */
494 gfc_conv_procedure_call (&loopse, code->resolved_sym,
495 code->ext.actual, code->expr1,
496 NULL);
498 if (mask && count1)
500 tmp = build3_v (COND_EXPR, maskexpr, loopse.expr,
501 build_empty_stmt (input_location));
502 gfc_add_expr_to_block (&loopse.pre, tmp);
503 tmp = fold_build2_loc (input_location, PLUS_EXPR,
504 gfc_array_index_type,
505 count1, gfc_index_one_node);
506 gfc_add_modify (&loopse.pre, count1, tmp);
508 else
509 gfc_add_expr_to_block (&loopse.pre, loopse.expr);
511 gfc_add_block_to_block (&block, &loopse.pre);
512 gfc_add_block_to_block (&block, &loopse.post);
514 /* Finish up the loop block and the loop. */
515 gfc_add_expr_to_block (&body, gfc_finish_block (&block));
516 gfc_trans_scalarizing_loops (&loop, &body);
517 gfc_add_block_to_block (&se.pre, &loop.pre);
518 gfc_add_block_to_block (&se.pre, &loop.post);
519 gfc_add_block_to_block (&se.pre, &se.post);
520 gfc_cleanup_loop (&loop);
523 return gfc_finish_block (&se.pre);
527 /* Translate the RETURN statement. */
529 tree
530 gfc_trans_return (gfc_code * code)
532 if (code->expr1)
534 gfc_se se;
535 tree tmp;
536 tree result;
538 /* If code->expr is not NULL, this return statement must appear
539 in a subroutine and current_fake_result_decl has already
540 been generated. */
542 result = gfc_get_fake_result_decl (NULL, 0);
543 if (!result)
545 gfc_warning (0,
546 "An alternate return at %L without a * dummy argument",
547 &code->expr1->where);
548 return gfc_generate_return ();
551 /* Start a new block for this statement. */
552 gfc_init_se (&se, NULL);
553 gfc_start_block (&se.pre);
555 gfc_conv_expr (&se, code->expr1);
557 /* Note that the actually returned expression is a simple value and
558 does not depend on any pointers or such; thus we can clean-up with
559 se.post before returning. */
560 tmp = fold_build2_loc (input_location, MODIFY_EXPR, TREE_TYPE (result),
561 result, fold_convert (TREE_TYPE (result),
562 se.expr));
563 gfc_add_expr_to_block (&se.pre, tmp);
564 gfc_add_block_to_block (&se.pre, &se.post);
566 tmp = gfc_generate_return ();
567 gfc_add_expr_to_block (&se.pre, tmp);
568 return gfc_finish_block (&se.pre);
571 return gfc_generate_return ();
575 /* Translate the PAUSE statement. We have to translate this statement
576 to a runtime library call. */
578 tree
579 gfc_trans_pause (gfc_code * code)
581 tree gfc_int8_type_node = gfc_get_int_type (8);
582 gfc_se se;
583 tree tmp;
585 /* Start a new block for this statement. */
586 gfc_init_se (&se, NULL);
587 gfc_start_block (&se.pre);
590 if (code->expr1 == NULL)
592 tmp = build_int_cst (size_type_node, 0);
593 tmp = build_call_expr_loc (input_location,
594 gfor_fndecl_pause_string, 2,
595 build_int_cst (pchar_type_node, 0), tmp);
597 else if (code->expr1->ts.type == BT_INTEGER)
599 gfc_conv_expr (&se, code->expr1);
600 tmp = build_call_expr_loc (input_location,
601 gfor_fndecl_pause_numeric, 1,
602 fold_convert (gfc_int8_type_node, se.expr));
604 else
606 gfc_conv_expr_reference (&se, code->expr1);
607 tmp = build_call_expr_loc (input_location,
608 gfor_fndecl_pause_string, 2,
609 se.expr, fold_convert (size_type_node,
610 se.string_length));
613 gfc_add_expr_to_block (&se.pre, tmp);
615 gfc_add_block_to_block (&se.pre, &se.post);
617 return gfc_finish_block (&se.pre);
621 /* Translate the STOP statement. We have to translate this statement
622 to a runtime library call. */
624 tree
625 gfc_trans_stop (gfc_code *code, bool error_stop)
627 gfc_se se;
628 tree tmp;
630 /* Start a new block for this statement. */
631 gfc_init_se (&se, NULL);
632 gfc_start_block (&se.pre);
634 if (code->expr1 == NULL)
636 tmp = build_int_cst (size_type_node, 0);
637 tmp = build_call_expr_loc (input_location,
638 error_stop
639 ? (flag_coarray == GFC_FCOARRAY_LIB
640 ? gfor_fndecl_caf_error_stop_str
641 : gfor_fndecl_error_stop_string)
642 : (flag_coarray == GFC_FCOARRAY_LIB
643 ? gfor_fndecl_caf_stop_str
644 : gfor_fndecl_stop_string),
645 3, build_int_cst (pchar_type_node, 0), tmp,
646 boolean_false_node);
648 else if (code->expr1->ts.type == BT_INTEGER)
650 gfc_conv_expr (&se, code->expr1);
651 tmp = build_call_expr_loc (input_location,
652 error_stop
653 ? (flag_coarray == GFC_FCOARRAY_LIB
654 ? gfor_fndecl_caf_error_stop
655 : gfor_fndecl_error_stop_numeric)
656 : (flag_coarray == GFC_FCOARRAY_LIB
657 ? gfor_fndecl_caf_stop_numeric
658 : gfor_fndecl_stop_numeric), 2,
659 fold_convert (integer_type_node, se.expr),
660 boolean_false_node);
662 else
664 gfc_conv_expr_reference (&se, code->expr1);
665 tmp = build_call_expr_loc (input_location,
666 error_stop
667 ? (flag_coarray == GFC_FCOARRAY_LIB
668 ? gfor_fndecl_caf_error_stop_str
669 : gfor_fndecl_error_stop_string)
670 : (flag_coarray == GFC_FCOARRAY_LIB
671 ? gfor_fndecl_caf_stop_str
672 : gfor_fndecl_stop_string),
673 3, se.expr, fold_convert (size_type_node,
674 se.string_length),
675 boolean_false_node);
678 gfc_add_expr_to_block (&se.pre, tmp);
680 gfc_add_block_to_block (&se.pre, &se.post);
682 return gfc_finish_block (&se.pre);
685 /* Translate the FAIL IMAGE statement. */
687 tree
688 gfc_trans_fail_image (gfc_code *code ATTRIBUTE_UNUSED)
690 if (flag_coarray == GFC_FCOARRAY_LIB)
691 return build_call_expr_loc (input_location,
692 gfor_fndecl_caf_fail_image, 1,
693 build_int_cst (pchar_type_node, 0));
694 else
696 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
697 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
698 tree tmp = gfc_get_symbol_decl (exsym);
699 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
703 /* Translate the FORM TEAM statement. */
705 tree
706 gfc_trans_form_team (gfc_code *code)
708 if (flag_coarray == GFC_FCOARRAY_LIB)
710 gfc_se argse;
711 tree team_id,team_type;
712 gfc_init_se (&argse, NULL);
713 gfc_conv_expr_val (&argse, code->expr1);
714 team_id = fold_convert (integer_type_node, argse.expr);
715 gfc_init_se (&argse, NULL);
716 gfc_conv_expr_val (&argse, code->expr2);
717 team_type = gfc_build_addr_expr (ppvoid_type_node, argse.expr);
719 return build_call_expr_loc (input_location,
720 gfor_fndecl_caf_form_team, 3,
721 team_id, team_type,
722 build_int_cst (integer_type_node, 0));
724 else
726 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
727 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
728 tree tmp = gfc_get_symbol_decl (exsym);
729 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
733 /* Translate the CHANGE TEAM statement. */
735 tree
736 gfc_trans_change_team (gfc_code *code)
738 if (flag_coarray == GFC_FCOARRAY_LIB)
740 gfc_se argse;
741 tree team_type;
743 gfc_init_se (&argse, NULL);
744 gfc_conv_expr_val (&argse, code->expr1);
745 team_type = gfc_build_addr_expr (ppvoid_type_node, argse.expr);
747 return build_call_expr_loc (input_location,
748 gfor_fndecl_caf_change_team, 2, team_type,
749 build_int_cst (integer_type_node, 0));
751 else
753 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
754 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
755 tree tmp = gfc_get_symbol_decl (exsym);
756 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
760 /* Translate the END TEAM statement. */
762 tree
763 gfc_trans_end_team (gfc_code *code ATTRIBUTE_UNUSED)
765 if (flag_coarray == GFC_FCOARRAY_LIB)
767 return build_call_expr_loc (input_location,
768 gfor_fndecl_caf_end_team, 1,
769 build_int_cst (pchar_type_node, 0));
771 else
773 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
774 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
775 tree tmp = gfc_get_symbol_decl (exsym);
776 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
780 /* Translate the SYNC TEAM statement. */
782 tree
783 gfc_trans_sync_team (gfc_code *code)
785 if (flag_coarray == GFC_FCOARRAY_LIB)
787 gfc_se argse;
788 tree team_type;
790 gfc_init_se (&argse, NULL);
791 gfc_conv_expr_val (&argse, code->expr1);
792 team_type = gfc_build_addr_expr (ppvoid_type_node, argse.expr);
794 return build_call_expr_loc (input_location,
795 gfor_fndecl_caf_sync_team, 2,
796 team_type,
797 build_int_cst (integer_type_node, 0));
799 else
801 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
802 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
803 tree tmp = gfc_get_symbol_decl (exsym);
804 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
808 tree
809 gfc_trans_lock_unlock (gfc_code *code, gfc_exec_op op)
811 gfc_se se, argse;
812 tree stat = NULL_TREE, stat2 = NULL_TREE;
813 tree lock_acquired = NULL_TREE, lock_acquired2 = NULL_TREE;
815 /* Short cut: For single images without STAT= or LOCK_ACQUIRED
816 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
817 if (!code->expr2 && !code->expr4 && flag_coarray != GFC_FCOARRAY_LIB)
818 return NULL_TREE;
820 if (code->expr2)
822 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
823 gfc_init_se (&argse, NULL);
824 gfc_conv_expr_val (&argse, code->expr2);
825 stat = argse.expr;
827 else if (flag_coarray == GFC_FCOARRAY_LIB)
828 stat = null_pointer_node;
830 if (code->expr4)
832 gcc_assert (code->expr4->expr_type == EXPR_VARIABLE);
833 gfc_init_se (&argse, NULL);
834 gfc_conv_expr_val (&argse, code->expr4);
835 lock_acquired = argse.expr;
837 else if (flag_coarray == GFC_FCOARRAY_LIB)
838 lock_acquired = null_pointer_node;
840 gfc_start_block (&se.pre);
841 if (flag_coarray == GFC_FCOARRAY_LIB)
843 tree tmp, token, image_index, errmsg, errmsg_len;
844 tree index = size_zero_node;
845 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
847 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
848 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
849 != INTMOD_ISO_FORTRAN_ENV
850 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
851 != ISOFORTRAN_LOCK_TYPE)
853 gfc_error ("Sorry, the lock component of derived type at %L is not "
854 "yet supported", &code->expr1->where);
855 return NULL_TREE;
858 gfc_get_caf_token_offset (&se, &token, NULL, caf_decl, NULL_TREE,
859 code->expr1);
861 if (gfc_is_coindexed (code->expr1))
862 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
863 else
864 image_index = integer_zero_node;
866 /* For arrays, obtain the array index. */
867 if (gfc_expr_attr (code->expr1).dimension)
869 tree desc, tmp, extent, lbound, ubound;
870 gfc_array_ref *ar, ar2;
871 int i;
873 /* TODO: Extend this, once DT components are supported. */
874 ar = &code->expr1->ref->u.ar;
875 ar2 = *ar;
876 memset (ar, '\0', sizeof (*ar));
877 ar->as = ar2.as;
878 ar->type = AR_FULL;
880 gfc_init_se (&argse, NULL);
881 argse.descriptor_only = 1;
882 gfc_conv_expr_descriptor (&argse, code->expr1);
883 gfc_add_block_to_block (&se.pre, &argse.pre);
884 desc = argse.expr;
885 *ar = ar2;
887 extent = integer_one_node;
888 for (i = 0; i < ar->dimen; i++)
890 gfc_init_se (&argse, NULL);
891 gfc_conv_expr_type (&argse, ar->start[i], integer_type_node);
892 gfc_add_block_to_block (&argse.pre, &argse.pre);
893 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
894 tmp = fold_build2_loc (input_location, MINUS_EXPR,
895 integer_type_node, argse.expr,
896 fold_convert(integer_type_node, lbound));
897 tmp = fold_build2_loc (input_location, MULT_EXPR,
898 integer_type_node, extent, tmp);
899 index = fold_build2_loc (input_location, PLUS_EXPR,
900 integer_type_node, index, tmp);
901 if (i < ar->dimen - 1)
903 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
904 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
905 tmp = fold_convert (integer_type_node, tmp);
906 extent = fold_build2_loc (input_location, MULT_EXPR,
907 integer_type_node, extent, tmp);
912 /* errmsg. */
913 if (code->expr3)
915 gfc_init_se (&argse, NULL);
916 argse.want_pointer = 1;
917 gfc_conv_expr (&argse, code->expr3);
918 gfc_add_block_to_block (&se.pre, &argse.pre);
919 errmsg = argse.expr;
920 errmsg_len = fold_convert (size_type_node, argse.string_length);
922 else
924 errmsg = null_pointer_node;
925 errmsg_len = build_zero_cst (size_type_node);
928 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
930 stat2 = stat;
931 stat = gfc_create_var (integer_type_node, "stat");
934 if (lock_acquired != null_pointer_node
935 && TREE_TYPE (lock_acquired) != integer_type_node)
937 lock_acquired2 = lock_acquired;
938 lock_acquired = gfc_create_var (integer_type_node, "acquired");
941 if (op == EXEC_LOCK)
942 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
943 token, index, image_index,
944 lock_acquired != null_pointer_node
945 ? gfc_build_addr_expr (NULL, lock_acquired)
946 : lock_acquired,
947 stat != null_pointer_node
948 ? gfc_build_addr_expr (NULL, stat) : stat,
949 errmsg, errmsg_len);
950 else
951 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
952 token, index, image_index,
953 stat != null_pointer_node
954 ? gfc_build_addr_expr (NULL, stat) : stat,
955 errmsg, errmsg_len);
956 gfc_add_expr_to_block (&se.pre, tmp);
958 /* It guarantees memory consistency within the same segment */
959 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
960 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
961 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
962 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
963 ASM_VOLATILE_P (tmp) = 1;
965 gfc_add_expr_to_block (&se.pre, tmp);
967 if (stat2 != NULL_TREE)
968 gfc_add_modify (&se.pre, stat2,
969 fold_convert (TREE_TYPE (stat2), stat));
971 if (lock_acquired2 != NULL_TREE)
972 gfc_add_modify (&se.pre, lock_acquired2,
973 fold_convert (TREE_TYPE (lock_acquired2),
974 lock_acquired));
976 return gfc_finish_block (&se.pre);
979 if (stat != NULL_TREE)
980 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
982 if (lock_acquired != NULL_TREE)
983 gfc_add_modify (&se.pre, lock_acquired,
984 fold_convert (TREE_TYPE (lock_acquired),
985 boolean_true_node));
987 return gfc_finish_block (&se.pre);
990 tree
991 gfc_trans_event_post_wait (gfc_code *code, gfc_exec_op op)
993 gfc_se se, argse;
994 tree stat = NULL_TREE, stat2 = NULL_TREE;
995 tree until_count = NULL_TREE;
997 if (code->expr2)
999 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
1000 gfc_init_se (&argse, NULL);
1001 gfc_conv_expr_val (&argse, code->expr2);
1002 stat = argse.expr;
1004 else if (flag_coarray == GFC_FCOARRAY_LIB)
1005 stat = null_pointer_node;
1007 if (code->expr4)
1009 gfc_init_se (&argse, NULL);
1010 gfc_conv_expr_val (&argse, code->expr4);
1011 until_count = fold_convert (integer_type_node, argse.expr);
1013 else
1014 until_count = integer_one_node;
1016 if (flag_coarray != GFC_FCOARRAY_LIB)
1018 gfc_start_block (&se.pre);
1019 gfc_init_se (&argse, NULL);
1020 gfc_conv_expr_val (&argse, code->expr1);
1022 if (op == EXEC_EVENT_POST)
1023 gfc_add_modify (&se.pre, argse.expr,
1024 fold_build2_loc (input_location, PLUS_EXPR,
1025 TREE_TYPE (argse.expr), argse.expr,
1026 build_int_cst (TREE_TYPE (argse.expr), 1)));
1027 else
1028 gfc_add_modify (&se.pre, argse.expr,
1029 fold_build2_loc (input_location, MINUS_EXPR,
1030 TREE_TYPE (argse.expr), argse.expr,
1031 fold_convert (TREE_TYPE (argse.expr),
1032 until_count)));
1033 if (stat != NULL_TREE)
1034 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
1036 return gfc_finish_block (&se.pre);
1039 gfc_start_block (&se.pre);
1040 tree tmp, token, image_index, errmsg, errmsg_len;
1041 tree index = size_zero_node;
1042 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
1044 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
1045 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
1046 != INTMOD_ISO_FORTRAN_ENV
1047 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
1048 != ISOFORTRAN_EVENT_TYPE)
1050 gfc_error ("Sorry, the event component of derived type at %L is not "
1051 "yet supported", &code->expr1->where);
1052 return NULL_TREE;
1055 gfc_init_se (&argse, NULL);
1056 gfc_get_caf_token_offset (&argse, &token, NULL, caf_decl, NULL_TREE,
1057 code->expr1);
1058 gfc_add_block_to_block (&se.pre, &argse.pre);
1060 if (gfc_is_coindexed (code->expr1))
1061 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
1062 else
1063 image_index = integer_zero_node;
1065 /* For arrays, obtain the array index. */
1066 if (gfc_expr_attr (code->expr1).dimension)
1068 tree desc, tmp, extent, lbound, ubound;
1069 gfc_array_ref *ar, ar2;
1070 int i;
1072 /* TODO: Extend this, once DT components are supported. */
1073 ar = &code->expr1->ref->u.ar;
1074 ar2 = *ar;
1075 memset (ar, '\0', sizeof (*ar));
1076 ar->as = ar2.as;
1077 ar->type = AR_FULL;
1079 gfc_init_se (&argse, NULL);
1080 argse.descriptor_only = 1;
1081 gfc_conv_expr_descriptor (&argse, code->expr1);
1082 gfc_add_block_to_block (&se.pre, &argse.pre);
1083 desc = argse.expr;
1084 *ar = ar2;
1086 extent = integer_one_node;
1087 for (i = 0; i < ar->dimen; i++)
1089 gfc_init_se (&argse, NULL);
1090 gfc_conv_expr_type (&argse, ar->start[i], integer_type_node);
1091 gfc_add_block_to_block (&argse.pre, &argse.pre);
1092 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
1093 tmp = fold_build2_loc (input_location, MINUS_EXPR,
1094 integer_type_node, argse.expr,
1095 fold_convert(integer_type_node, lbound));
1096 tmp = fold_build2_loc (input_location, MULT_EXPR,
1097 integer_type_node, extent, tmp);
1098 index = fold_build2_loc (input_location, PLUS_EXPR,
1099 integer_type_node, index, tmp);
1100 if (i < ar->dimen - 1)
1102 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
1103 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
1104 tmp = fold_convert (integer_type_node, tmp);
1105 extent = fold_build2_loc (input_location, MULT_EXPR,
1106 integer_type_node, extent, tmp);
1111 /* errmsg. */
1112 if (code->expr3)
1114 gfc_init_se (&argse, NULL);
1115 argse.want_pointer = 1;
1116 gfc_conv_expr (&argse, code->expr3);
1117 gfc_add_block_to_block (&se.pre, &argse.pre);
1118 errmsg = argse.expr;
1119 errmsg_len = fold_convert (size_type_node, argse.string_length);
1121 else
1123 errmsg = null_pointer_node;
1124 errmsg_len = build_zero_cst (size_type_node);
1127 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
1129 stat2 = stat;
1130 stat = gfc_create_var (integer_type_node, "stat");
1133 if (op == EXEC_EVENT_POST)
1134 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_post, 6,
1135 token, index, image_index,
1136 stat != null_pointer_node
1137 ? gfc_build_addr_expr (NULL, stat) : stat,
1138 errmsg, errmsg_len);
1139 else
1140 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_wait, 6,
1141 token, index, until_count,
1142 stat != null_pointer_node
1143 ? gfc_build_addr_expr (NULL, stat) : stat,
1144 errmsg, errmsg_len);
1145 gfc_add_expr_to_block (&se.pre, tmp);
1147 /* It guarantees memory consistency within the same segment */
1148 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1149 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1150 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1151 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1152 ASM_VOLATILE_P (tmp) = 1;
1153 gfc_add_expr_to_block (&se.pre, tmp);
1155 if (stat2 != NULL_TREE)
1156 gfc_add_modify (&se.pre, stat2, fold_convert (TREE_TYPE (stat2), stat));
1158 return gfc_finish_block (&se.pre);
1161 tree
1162 gfc_trans_sync (gfc_code *code, gfc_exec_op type)
1164 gfc_se se, argse;
1165 tree tmp;
1166 tree images = NULL_TREE, stat = NULL_TREE,
1167 errmsg = NULL_TREE, errmsglen = NULL_TREE;
1169 /* Short cut: For single images without bound checking or without STAT=,
1170 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
1171 if (!code->expr2 && !(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1172 && flag_coarray != GFC_FCOARRAY_LIB)
1173 return NULL_TREE;
1175 gfc_init_se (&se, NULL);
1176 gfc_start_block (&se.pre);
1178 if (code->expr1 && code->expr1->rank == 0)
1180 gfc_init_se (&argse, NULL);
1181 gfc_conv_expr_val (&argse, code->expr1);
1182 images = argse.expr;
1185 if (code->expr2)
1187 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
1188 gfc_init_se (&argse, NULL);
1189 gfc_conv_expr_val (&argse, code->expr2);
1190 stat = argse.expr;
1192 else
1193 stat = null_pointer_node;
1195 if (code->expr3 && flag_coarray == GFC_FCOARRAY_LIB)
1197 gcc_assert (code->expr3->expr_type == EXPR_VARIABLE);
1198 gfc_init_se (&argse, NULL);
1199 argse.want_pointer = 1;
1200 gfc_conv_expr (&argse, code->expr3);
1201 gfc_conv_string_parameter (&argse);
1202 errmsg = gfc_build_addr_expr (NULL, argse.expr);
1203 errmsglen = fold_convert (size_type_node, argse.string_length);
1205 else if (flag_coarray == GFC_FCOARRAY_LIB)
1207 errmsg = null_pointer_node;
1208 errmsglen = build_int_cst (size_type_node, 0);
1211 /* Check SYNC IMAGES(imageset) for valid image index.
1212 FIXME: Add a check for image-set arrays. */
1213 if (code->expr1 && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1214 && code->expr1->rank == 0)
1216 tree cond;
1217 if (flag_coarray != GFC_FCOARRAY_LIB)
1218 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1219 images, build_int_cst (TREE_TYPE (images), 1));
1220 else
1222 tree cond2;
1223 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images,
1224 2, integer_zero_node,
1225 build_int_cst (integer_type_node, -1));
1226 cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
1227 images, tmp);
1228 cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
1229 images,
1230 build_int_cst (TREE_TYPE (images), 1));
1231 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1232 logical_type_node, cond, cond2);
1234 gfc_trans_runtime_check (true, false, cond, &se.pre,
1235 &code->expr1->where, "Invalid image number "
1236 "%d in SYNC IMAGES",
1237 fold_convert (integer_type_node, images));
1240 /* Per F2008, 8.5.1, a SYNC MEMORY is implied by calling the
1241 image control statements SYNC IMAGES and SYNC ALL. */
1242 if (flag_coarray == GFC_FCOARRAY_LIB)
1244 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1245 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1246 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1247 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1248 ASM_VOLATILE_P (tmp) = 1;
1249 gfc_add_expr_to_block (&se.pre, tmp);
1252 if (flag_coarray != GFC_FCOARRAY_LIB)
1254 /* Set STAT to zero. */
1255 if (code->expr2)
1256 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
1258 else if (type == EXEC_SYNC_ALL || type == EXEC_SYNC_MEMORY)
1260 /* SYNC ALL => stat == null_pointer_node
1261 SYNC ALL(stat=s) => stat has an integer type
1263 If "stat" has the wrong integer type, use a temp variable of
1264 the right type and later cast the result back into "stat". */
1265 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1267 if (TREE_TYPE (stat) == integer_type_node)
1268 stat = gfc_build_addr_expr (NULL, stat);
1270 if(type == EXEC_SYNC_MEMORY)
1271 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_memory,
1272 3, stat, errmsg, errmsglen);
1273 else
1274 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
1275 3, stat, errmsg, errmsglen);
1277 gfc_add_expr_to_block (&se.pre, tmp);
1279 else
1281 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1283 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
1284 3, gfc_build_addr_expr (NULL, tmp_stat),
1285 errmsg, errmsglen);
1286 gfc_add_expr_to_block (&se.pre, tmp);
1288 gfc_add_modify (&se.pre, stat,
1289 fold_convert (TREE_TYPE (stat), tmp_stat));
1292 else
1294 tree len;
1296 gcc_assert (type == EXEC_SYNC_IMAGES);
1298 if (!code->expr1)
1300 len = build_int_cst (integer_type_node, -1);
1301 images = null_pointer_node;
1303 else if (code->expr1->rank == 0)
1305 len = build_int_cst (integer_type_node, 1);
1306 images = gfc_build_addr_expr (NULL_TREE, images);
1308 else
1310 /* FIXME. */
1311 if (code->expr1->ts.kind != gfc_c_int_kind)
1312 gfc_fatal_error ("Sorry, only support for integer kind %d "
1313 "implemented for image-set at %L",
1314 gfc_c_int_kind, &code->expr1->where);
1316 gfc_conv_array_parameter (&se, code->expr1, true, NULL, NULL, &len);
1317 images = se.expr;
1319 tmp = gfc_typenode_for_spec (&code->expr1->ts);
1320 if (GFC_ARRAY_TYPE_P (tmp) || GFC_DESCRIPTOR_TYPE_P (tmp))
1321 tmp = gfc_get_element_type (tmp);
1323 len = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
1324 TREE_TYPE (len), len,
1325 fold_convert (TREE_TYPE (len),
1326 TYPE_SIZE_UNIT (tmp)));
1327 len = fold_convert (integer_type_node, len);
1330 /* SYNC IMAGES(imgs) => stat == null_pointer_node
1331 SYNC IMAGES(imgs,stat=s) => stat has an integer type
1333 If "stat" has the wrong integer type, use a temp variable of
1334 the right type and later cast the result back into "stat". */
1335 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1337 if (TREE_TYPE (stat) == integer_type_node)
1338 stat = gfc_build_addr_expr (NULL, stat);
1340 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1341 5, fold_convert (integer_type_node, len),
1342 images, stat, errmsg, errmsglen);
1343 gfc_add_expr_to_block (&se.pre, tmp);
1345 else
1347 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1349 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1350 5, fold_convert (integer_type_node, len),
1351 images, gfc_build_addr_expr (NULL, tmp_stat),
1352 errmsg, errmsglen);
1353 gfc_add_expr_to_block (&se.pre, tmp);
1355 gfc_add_modify (&se.pre, stat,
1356 fold_convert (TREE_TYPE (stat), tmp_stat));
1360 return gfc_finish_block (&se.pre);
1364 /* Generate GENERIC for the IF construct. This function also deals with
1365 the simple IF statement, because the front end translates the IF
1366 statement into an IF construct.
1368 We translate:
1370 IF (cond) THEN
1371 then_clause
1372 ELSEIF (cond2)
1373 elseif_clause
1374 ELSE
1375 else_clause
1376 ENDIF
1378 into:
1380 pre_cond_s;
1381 if (cond_s)
1383 then_clause;
1385 else
1387 pre_cond_s
1388 if (cond_s)
1390 elseif_clause
1392 else
1394 else_clause;
1398 where COND_S is the simplified version of the predicate. PRE_COND_S
1399 are the pre side-effects produced by the translation of the
1400 conditional.
1401 We need to build the chain recursively otherwise we run into
1402 problems with folding incomplete statements. */
1404 static tree
1405 gfc_trans_if_1 (gfc_code * code)
1407 gfc_se if_se;
1408 tree stmt, elsestmt;
1409 locus saved_loc;
1410 location_t loc;
1412 /* Check for an unconditional ELSE clause. */
1413 if (!code->expr1)
1414 return gfc_trans_code (code->next);
1416 /* Initialize a statement builder for each block. Puts in NULL_TREEs. */
1417 gfc_init_se (&if_se, NULL);
1418 gfc_start_block (&if_se.pre);
1420 /* Calculate the IF condition expression. */
1421 if (code->expr1->where.lb)
1423 gfc_save_backend_locus (&saved_loc);
1424 gfc_set_backend_locus (&code->expr1->where);
1427 gfc_conv_expr_val (&if_se, code->expr1);
1429 if (code->expr1->where.lb)
1430 gfc_restore_backend_locus (&saved_loc);
1432 /* Translate the THEN clause. */
1433 stmt = gfc_trans_code (code->next);
1435 /* Translate the ELSE clause. */
1436 if (code->block)
1437 elsestmt = gfc_trans_if_1 (code->block);
1438 else
1439 elsestmt = build_empty_stmt (input_location);
1441 /* Build the condition expression and add it to the condition block. */
1442 loc = code->expr1->where.lb ? code->expr1->where.lb->location : input_location;
1443 stmt = fold_build3_loc (loc, COND_EXPR, void_type_node, if_se.expr, stmt,
1444 elsestmt);
1446 gfc_add_expr_to_block (&if_se.pre, stmt);
1448 /* Finish off this statement. */
1449 return gfc_finish_block (&if_se.pre);
1452 tree
1453 gfc_trans_if (gfc_code * code)
1455 stmtblock_t body;
1456 tree exit_label;
1458 /* Create exit label so it is available for trans'ing the body code. */
1459 exit_label = gfc_build_label_decl (NULL_TREE);
1460 code->exit_label = exit_label;
1462 /* Translate the actual code in code->block. */
1463 gfc_init_block (&body);
1464 gfc_add_expr_to_block (&body, gfc_trans_if_1 (code->block));
1466 /* Add exit label. */
1467 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
1469 return gfc_finish_block (&body);
1473 /* Translate an arithmetic IF expression.
1475 IF (cond) label1, label2, label3 translates to
1477 if (cond <= 0)
1479 if (cond < 0)
1480 goto label1;
1481 else // cond == 0
1482 goto label2;
1484 else // cond > 0
1485 goto label3;
1487 An optimized version can be generated in case of equal labels.
1488 E.g., if label1 is equal to label2, we can translate it to
1490 if (cond <= 0)
1491 goto label1;
1492 else
1493 goto label3;
1496 tree
1497 gfc_trans_arithmetic_if (gfc_code * code)
1499 gfc_se se;
1500 tree tmp;
1501 tree branch1;
1502 tree branch2;
1503 tree zero;
1505 /* Start a new block. */
1506 gfc_init_se (&se, NULL);
1507 gfc_start_block (&se.pre);
1509 /* Pre-evaluate COND. */
1510 gfc_conv_expr_val (&se, code->expr1);
1511 se.expr = gfc_evaluate_now (se.expr, &se.pre);
1513 /* Build something to compare with. */
1514 zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
1516 if (code->label1->value != code->label2->value)
1518 /* If (cond < 0) take branch1 else take branch2.
1519 First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases. */
1520 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1521 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
1523 if (code->label1->value != code->label3->value)
1524 tmp = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
1525 se.expr, zero);
1526 else
1527 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1528 se.expr, zero);
1530 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1531 tmp, branch1, branch2);
1533 else
1534 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1536 if (code->label1->value != code->label3->value
1537 && code->label2->value != code->label3->value)
1539 /* if (cond <= 0) take branch1 else take branch2. */
1540 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label3));
1541 tmp = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
1542 se.expr, zero);
1543 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1544 tmp, branch1, branch2);
1547 /* Append the COND_EXPR to the evaluation of COND, and return. */
1548 gfc_add_expr_to_block (&se.pre, branch1);
1549 return gfc_finish_block (&se.pre);
1553 /* Translate a CRITICAL block. */
1554 tree
1555 gfc_trans_critical (gfc_code *code)
1557 stmtblock_t block;
1558 tree tmp, token = NULL_TREE;
1560 gfc_start_block (&block);
1562 if (flag_coarray == GFC_FCOARRAY_LIB)
1564 token = gfc_get_symbol_decl (code->resolved_sym);
1565 token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (token));
1566 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
1567 token, integer_zero_node, integer_one_node,
1568 null_pointer_node, null_pointer_node,
1569 null_pointer_node, integer_zero_node);
1570 gfc_add_expr_to_block (&block, tmp);
1572 /* It guarantees memory consistency within the same segment */
1573 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1574 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1575 gfc_build_string_const (1, ""),
1576 NULL_TREE, NULL_TREE,
1577 tree_cons (NULL_TREE, tmp, NULL_TREE),
1578 NULL_TREE);
1579 ASM_VOLATILE_P (tmp) = 1;
1581 gfc_add_expr_to_block (&block, tmp);
1584 tmp = gfc_trans_code (code->block->next);
1585 gfc_add_expr_to_block (&block, tmp);
1587 if (flag_coarray == GFC_FCOARRAY_LIB)
1589 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
1590 token, integer_zero_node, integer_one_node,
1591 null_pointer_node, null_pointer_node,
1592 integer_zero_node);
1593 gfc_add_expr_to_block (&block, tmp);
1595 /* It guarantees memory consistency within the same segment */
1596 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1597 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1598 gfc_build_string_const (1, ""),
1599 NULL_TREE, NULL_TREE,
1600 tree_cons (NULL_TREE, tmp, NULL_TREE),
1601 NULL_TREE);
1602 ASM_VOLATILE_P (tmp) = 1;
1604 gfc_add_expr_to_block (&block, tmp);
1607 return gfc_finish_block (&block);
1611 /* Return true, when the class has a _len component. */
1613 static bool
1614 class_has_len_component (gfc_symbol *sym)
1616 gfc_component *comp = sym->ts.u.derived->components;
1617 while (comp)
1619 if (strcmp (comp->name, "_len") == 0)
1620 return true;
1621 comp = comp->next;
1623 return false;
1627 /* Do proper initialization for ASSOCIATE names. */
1629 static void
1630 trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
1632 gfc_expr *e;
1633 tree tmp;
1634 bool class_target;
1635 bool unlimited;
1636 tree desc;
1637 tree offset;
1638 tree dim;
1639 int n;
1640 tree charlen;
1641 bool need_len_assign;
1642 bool whole_array = true;
1643 gfc_ref *ref;
1644 symbol_attribute attr;
1646 gcc_assert (sym->assoc);
1647 e = sym->assoc->target;
1649 class_target = (e->expr_type == EXPR_VARIABLE)
1650 && (gfc_is_class_scalar_expr (e)
1651 || gfc_is_class_array_ref (e, NULL));
1653 unlimited = UNLIMITED_POLY (e);
1655 for (ref = e->ref; ref; ref = ref->next)
1656 if (ref->type == REF_ARRAY
1657 && ref->u.ar.type == AR_FULL
1658 && ref->next)
1660 whole_array = false;
1661 break;
1664 /* Assignments to the string length need to be generated, when
1665 ( sym is a char array or
1666 sym has a _len component)
1667 and the associated expression is unlimited polymorphic, which is
1668 not (yet) correctly in 'unlimited', because for an already associated
1669 BT_DERIVED the u-poly flag is not set, i.e.,
1670 __tmp_CHARACTER_0_1 => w => arg
1671 ^ generated temp ^ from code, the w does not have the u-poly
1672 flag set, where UNLIMITED_POLY(e) expects it. */
1673 need_len_assign = ((unlimited || (e->ts.type == BT_DERIVED
1674 && e->ts.u.derived->attr.unlimited_polymorphic))
1675 && (sym->ts.type == BT_CHARACTER
1676 || ((sym->ts.type == BT_CLASS || sym->ts.type == BT_DERIVED)
1677 && class_has_len_component (sym))));
1678 /* Do a `pointer assignment' with updated descriptor (or assign descriptor
1679 to array temporary) for arrays with either unknown shape or if associating
1680 to a variable. */
1681 if (sym->attr.dimension && !class_target
1682 && (sym->as->type == AS_DEFERRED || sym->assoc->variable))
1684 gfc_se se;
1685 tree desc;
1686 bool cst_array_ctor;
1688 desc = sym->backend_decl;
1689 cst_array_ctor = e->expr_type == EXPR_ARRAY
1690 && gfc_constant_array_constructor_p (e->value.constructor)
1691 && e->ts.type != BT_CHARACTER;
1693 /* If association is to an expression, evaluate it and create temporary.
1694 Otherwise, get descriptor of target for pointer assignment. */
1695 gfc_init_se (&se, NULL);
1696 if (sym->assoc->variable || cst_array_ctor)
1698 se.direct_byref = 1;
1699 se.use_offset = 1;
1700 se.expr = desc;
1703 gfc_conv_expr_descriptor (&se, e);
1705 if (sym->ts.type == BT_CHARACTER
1706 && sym->ts.deferred
1707 && !sym->attr.select_type_temporary
1708 && VAR_P (sym->ts.u.cl->backend_decl)
1709 && se.string_length != sym->ts.u.cl->backend_decl)
1711 gfc_add_modify (&se.pre, sym->ts.u.cl->backend_decl,
1712 fold_convert (TREE_TYPE (sym->ts.u.cl->backend_decl),
1713 se.string_length));
1716 /* If we didn't already do the pointer assignment, set associate-name
1717 descriptor to the one generated for the temporary. */
1718 if ((!sym->assoc->variable && !cst_array_ctor)
1719 || !whole_array)
1721 int dim;
1723 if (whole_array)
1724 gfc_add_modify (&se.pre, desc, se.expr);
1726 /* The generated descriptor has lower bound zero (as array
1727 temporary), shift bounds so we get lower bounds of 1. */
1728 for (dim = 0; dim < e->rank; ++dim)
1729 gfc_conv_shift_descriptor_lbound (&se.pre, desc,
1730 dim, gfc_index_one_node);
1733 /* If this is a subreference array pointer associate name use the
1734 associate variable element size for the value of 'span'. */
1735 if (sym->attr.subref_array_pointer)
1737 gcc_assert (e->expr_type == EXPR_VARIABLE);
1738 tmp = e->symtree->n.sym->ts.type == BT_CLASS
1739 ? gfc_class_data_get (e->symtree->n.sym->backend_decl)
1740 : e->symtree->n.sym->backend_decl;
1741 tmp = gfc_get_element_type (TREE_TYPE (tmp));
1742 tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
1743 gfc_conv_descriptor_span_set (&se.pre, desc, tmp);
1746 if (e->expr_type == EXPR_FUNCTION
1747 && sym->ts.type == BT_DERIVED
1748 && sym->ts.u.derived
1749 && sym->ts.u.derived->attr.pdt_type)
1751 tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived, se.expr,
1752 sym->as->rank);
1753 gfc_add_expr_to_block (&se.post, tmp);
1756 /* Done, register stuff as init / cleanup code. */
1757 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1758 gfc_finish_block (&se.post));
1761 /* Temporaries, arising from TYPE IS, just need the descriptor of class
1762 arrays to be assigned directly. */
1763 else if (class_target && sym->attr.dimension
1764 && (sym->ts.type == BT_DERIVED || unlimited))
1766 gfc_se se;
1768 gfc_init_se (&se, NULL);
1769 se.descriptor_only = 1;
1770 /* In a select type the (temporary) associate variable shall point to
1771 a standard fortran array (lower bound == 1), but conv_expr ()
1772 just maps to the input array in the class object, whose lbound may
1773 be arbitrary. conv_expr_descriptor solves this by inserting a
1774 temporary array descriptor. */
1775 gfc_conv_expr_descriptor (&se, e);
1777 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
1778 || GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)));
1779 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)));
1781 if (GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)))
1783 if (INDIRECT_REF_P (se.expr))
1784 tmp = TREE_OPERAND (se.expr, 0);
1785 else
1786 tmp = se.expr;
1788 gfc_add_modify (&se.pre, sym->backend_decl,
1789 gfc_class_data_get (GFC_DECL_SAVED_DESCRIPTOR (tmp)));
1791 else
1792 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
1794 if (unlimited)
1796 /* Recover the dtype, which has been overwritten by the
1797 assignment from an unlimited polymorphic object. */
1798 tmp = gfc_conv_descriptor_dtype (sym->backend_decl);
1799 gfc_add_modify (&se.pre, tmp,
1800 gfc_get_dtype (TREE_TYPE (sym->backend_decl)));
1803 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1804 gfc_finish_block (&se.post));
1807 /* Do a scalar pointer assignment; this is for scalar variable targets. */
1808 else if (gfc_is_associate_pointer (sym))
1810 gfc_se se;
1812 gcc_assert (!sym->attr.dimension);
1814 gfc_init_se (&se, NULL);
1816 /* Class associate-names come this way because they are
1817 unconditionally associate pointers and the symbol is scalar. */
1818 if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.dimension)
1820 tree target_expr;
1821 /* For a class array we need a descriptor for the selector. */
1822 gfc_conv_expr_descriptor (&se, e);
1823 /* Needed to get/set the _len component below. */
1824 target_expr = se.expr;
1826 /* Obtain a temporary class container for the result. */
1827 gfc_conv_class_to_class (&se, e, sym->ts, false, true, false, false);
1828 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1830 /* Set the offset. */
1831 desc = gfc_class_data_get (se.expr);
1832 offset = gfc_index_zero_node;
1833 for (n = 0; n < e->rank; n++)
1835 dim = gfc_rank_cst[n];
1836 tmp = fold_build2_loc (input_location, MULT_EXPR,
1837 gfc_array_index_type,
1838 gfc_conv_descriptor_stride_get (desc, dim),
1839 gfc_conv_descriptor_lbound_get (desc, dim));
1840 offset = fold_build2_loc (input_location, MINUS_EXPR,
1841 gfc_array_index_type,
1842 offset, tmp);
1844 if (need_len_assign)
1846 if (e->symtree
1847 && DECL_LANG_SPECIFIC (e->symtree->n.sym->backend_decl)
1848 && GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl))
1849 /* Use the original class descriptor stored in the saved
1850 descriptor to get the target_expr. */
1851 target_expr =
1852 GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl);
1853 else
1854 /* Strip the _data component from the target_expr. */
1855 target_expr = TREE_OPERAND (target_expr, 0);
1856 /* Add a reference to the _len comp to the target expr. */
1857 tmp = gfc_class_len_get (target_expr);
1858 /* Get the component-ref for the temp structure's _len comp. */
1859 charlen = gfc_class_len_get (se.expr);
1860 /* Add the assign to the beginning of the block... */
1861 gfc_add_modify (&se.pre, charlen,
1862 fold_convert (TREE_TYPE (charlen), tmp));
1863 /* and the oposite way at the end of the block, to hand changes
1864 on the string length back. */
1865 gfc_add_modify (&se.post, tmp,
1866 fold_convert (TREE_TYPE (tmp), charlen));
1867 /* Length assignment done, prevent adding it again below. */
1868 need_len_assign = false;
1870 gfc_conv_descriptor_offset_set (&se.pre, desc, offset);
1872 else if (sym->ts.type == BT_CLASS && e->ts.type == BT_CLASS
1873 && CLASS_DATA (e)->attr.dimension)
1875 /* This is bound to be a class array element. */
1876 gfc_conv_expr_reference (&se, e);
1877 /* Get the _vptr component of the class object. */
1878 tmp = gfc_get_vptr_from_expr (se.expr);
1879 /* Obtain a temporary class container for the result. */
1880 gfc_conv_derived_to_class (&se, e, sym->ts, tmp, false, false);
1881 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1883 else
1885 /* For BT_CLASS and BT_DERIVED, this boils down to a pointer assign,
1886 which has the string length included. For CHARACTERS it is still
1887 needed and will be done at the end of this routine. */
1888 gfc_conv_expr (&se, e);
1889 need_len_assign = need_len_assign && sym->ts.type == BT_CHARACTER;
1892 if (sym->ts.type == BT_CHARACTER
1893 && sym->ts.deferred
1894 && !sym->attr.select_type_temporary
1895 && VAR_P (sym->ts.u.cl->backend_decl)
1896 && se.string_length != sym->ts.u.cl->backend_decl)
1898 gfc_add_modify (&se.pre, sym->ts.u.cl->backend_decl,
1899 fold_convert (TREE_TYPE (sym->ts.u.cl->backend_decl),
1900 se.string_length));
1901 if (e->expr_type == EXPR_FUNCTION)
1903 tmp = gfc_call_free (sym->backend_decl);
1904 gfc_add_expr_to_block (&se.post, tmp);
1908 attr = gfc_expr_attr (e);
1909 if (sym->ts.type == BT_CHARACTER && e->ts.type == BT_CHARACTER
1910 && (attr.allocatable || attr.pointer || attr.dummy)
1911 && POINTER_TYPE_P (TREE_TYPE (se.expr)))
1913 /* These are pointer types already. */
1914 tmp = fold_convert (TREE_TYPE (sym->backend_decl), se.expr);
1916 else
1918 tmp = TREE_TYPE (sym->backend_decl);
1919 tmp = gfc_build_addr_expr (tmp, se.expr);
1922 gfc_add_modify (&se.pre, sym->backend_decl, tmp);
1924 gfc_add_init_cleanup (block, gfc_finish_block( &se.pre),
1925 gfc_finish_block (&se.post));
1928 /* Do a simple assignment. This is for scalar expressions, where we
1929 can simply use expression assignment. */
1930 else
1932 gfc_expr *lhs;
1933 tree res;
1934 gfc_se se;
1936 gfc_init_se (&se, NULL);
1938 /* resolve.c converts some associate names to allocatable so that
1939 allocation can take place automatically in gfc_trans_assignment.
1940 The frontend prevents them from being either allocated,
1941 deallocated or reallocated. */
1942 if (sym->attr.allocatable)
1944 tmp = sym->backend_decl;
1945 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
1946 tmp = gfc_conv_descriptor_data_get (tmp);
1947 gfc_add_modify (&se.pre, tmp, fold_convert (TREE_TYPE (tmp),
1948 null_pointer_node));
1951 lhs = gfc_lval_expr_from_sym (sym);
1952 res = gfc_trans_assignment (lhs, e, false, true);
1953 gfc_add_expr_to_block (&se.pre, res);
1955 tmp = sym->backend_decl;
1956 if (e->expr_type == EXPR_FUNCTION
1957 && sym->ts.type == BT_DERIVED
1958 && sym->ts.u.derived
1959 && sym->ts.u.derived->attr.pdt_type)
1961 tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived, tmp,
1964 else if (e->expr_type == EXPR_FUNCTION
1965 && sym->ts.type == BT_CLASS
1966 && CLASS_DATA (sym)->ts.u.derived
1967 && CLASS_DATA (sym)->ts.u.derived->attr.pdt_type)
1969 tmp = gfc_class_data_get (tmp);
1970 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (sym)->ts.u.derived,
1971 tmp, 0);
1973 else if (sym->attr.allocatable)
1975 tmp = sym->backend_decl;
1977 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
1978 tmp = gfc_conv_descriptor_data_get (tmp);
1980 /* A simple call to free suffices here. */
1981 tmp = gfc_call_free (tmp);
1983 /* Make sure that reallocation on assignment cannot occur. */
1984 sym->attr.allocatable = 0;
1986 else
1987 tmp = NULL_TREE;
1989 res = gfc_finish_block (&se.pre);
1990 gfc_add_init_cleanup (block, res, tmp);
1991 gfc_free_expr (lhs);
1994 /* Set the stringlength, when needed. */
1995 if (need_len_assign)
1997 gfc_se se;
1998 gfc_init_se (&se, NULL);
1999 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
2001 /* Deferred strings are dealt with in the preceeding. */
2002 gcc_assert (!e->symtree->n.sym->ts.deferred);
2003 tmp = e->symtree->n.sym->ts.u.cl->backend_decl;
2005 else if (e->symtree->n.sym->attr.function
2006 && e->symtree->n.sym == e->symtree->n.sym->result)
2008 tmp = gfc_get_fake_result_decl (e->symtree->n.sym, 0);
2009 tmp = gfc_class_len_get (tmp);
2011 else
2012 tmp = gfc_class_len_get (gfc_get_symbol_decl (e->symtree->n.sym));
2013 gfc_get_symbol_decl (sym);
2014 charlen = sym->ts.type == BT_CHARACTER ? sym->ts.u.cl->backend_decl
2015 : gfc_class_len_get (sym->backend_decl);
2016 /* Prevent adding a noop len= len. */
2017 if (tmp != charlen)
2019 gfc_add_modify (&se.pre, charlen,
2020 fold_convert (TREE_TYPE (charlen), tmp));
2021 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
2022 gfc_finish_block (&se.post));
2028 /* Translate a BLOCK construct. This is basically what we would do for a
2029 procedure body. */
2031 tree
2032 gfc_trans_block_construct (gfc_code* code)
2034 gfc_namespace* ns;
2035 gfc_symbol* sym;
2036 gfc_wrapped_block block;
2037 tree exit_label;
2038 stmtblock_t body;
2039 gfc_association_list *ass;
2041 ns = code->ext.block.ns;
2042 gcc_assert (ns);
2043 sym = ns->proc_name;
2044 gcc_assert (sym);
2046 /* Process local variables. */
2047 gcc_assert (!sym->tlink);
2048 sym->tlink = sym;
2049 gfc_process_block_locals (ns);
2051 /* Generate code including exit-label. */
2052 gfc_init_block (&body);
2053 exit_label = gfc_build_label_decl (NULL_TREE);
2054 code->exit_label = exit_label;
2056 finish_oacc_declare (ns, sym, true);
2058 gfc_add_expr_to_block (&body, gfc_trans_code (ns->code));
2059 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
2061 /* Finish everything. */
2062 gfc_start_wrapped_block (&block, gfc_finish_block (&body));
2063 gfc_trans_deferred_vars (sym, &block);
2064 for (ass = code->ext.block.assoc; ass; ass = ass->next)
2065 trans_associate_var (ass->st->n.sym, &block);
2067 return gfc_finish_wrapped_block (&block);
2070 /* Translate the simple DO construct in a C-style manner.
2071 This is where the loop variable has integer type and step +-1.
2072 Following code will generate infinite loop in case where TO is INT_MAX
2073 (for +1 step) or INT_MIN (for -1 step)
2075 We translate a do loop from:
2077 DO dovar = from, to, step
2078 body
2079 END DO
2083 [Evaluate loop bounds and step]
2084 dovar = from;
2085 for (;;)
2087 if (dovar > to)
2088 goto end_label;
2089 body;
2090 cycle_label:
2091 dovar += step;
2093 end_label:
2095 This helps the optimizers by avoiding the extra pre-header condition and
2096 we save a register as we just compare the updated IV (not a value in
2097 previous step). */
2099 static tree
2100 gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
2101 tree from, tree to, tree step, tree exit_cond)
2103 stmtblock_t body;
2104 tree type;
2105 tree cond;
2106 tree tmp;
2107 tree saved_dovar = NULL;
2108 tree cycle_label;
2109 tree exit_label;
2110 location_t loc;
2111 type = TREE_TYPE (dovar);
2112 bool is_step_positive = tree_int_cst_sgn (step) > 0;
2114 loc = code->ext.iterator->start->where.lb->location;
2116 /* Initialize the DO variable: dovar = from. */
2117 gfc_add_modify_loc (loc, pblock, dovar,
2118 fold_convert (TREE_TYPE (dovar), from));
2120 /* Save value for do-tinkering checking. */
2121 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2123 saved_dovar = gfc_create_var (type, ".saved_dovar");
2124 gfc_add_modify_loc (loc, pblock, saved_dovar, dovar);
2127 /* Cycle and exit statements are implemented with gotos. */
2128 cycle_label = gfc_build_label_decl (NULL_TREE);
2129 exit_label = gfc_build_label_decl (NULL_TREE);
2131 /* Put the labels where they can be found later. See gfc_trans_do(). */
2132 code->cycle_label = cycle_label;
2133 code->exit_label = exit_label;
2135 /* Loop body. */
2136 gfc_start_block (&body);
2138 /* Exit the loop if there is an I/O result condition or error. */
2139 if (exit_cond)
2141 tmp = build1_v (GOTO_EXPR, exit_label);
2142 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2143 exit_cond, tmp,
2144 build_empty_stmt (loc));
2145 gfc_add_expr_to_block (&body, tmp);
2148 /* Evaluate the loop condition. */
2149 if (is_step_positive)
2150 cond = fold_build2_loc (loc, GT_EXPR, logical_type_node, dovar,
2151 fold_convert (type, to));
2152 else
2153 cond = fold_build2_loc (loc, LT_EXPR, logical_type_node, dovar,
2154 fold_convert (type, to));
2156 cond = gfc_evaluate_now_loc (loc, cond, &body);
2157 if (code->ext.iterator->unroll && cond != error_mark_node)
2158 cond
2159 = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2160 build_int_cst (integer_type_node, annot_expr_unroll_kind),
2161 build_int_cst (integer_type_node, code->ext.iterator->unroll));
2163 /* The loop exit. */
2164 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
2165 TREE_USED (exit_label) = 1;
2166 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2167 cond, tmp, build_empty_stmt (loc));
2168 gfc_add_expr_to_block (&body, tmp);
2170 /* Check whether the induction variable is equal to INT_MAX
2171 (respectively to INT_MIN). */
2172 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2174 tree boundary = is_step_positive ? TYPE_MAX_VALUE (type)
2175 : TYPE_MIN_VALUE (type);
2177 tmp = fold_build2_loc (loc, EQ_EXPR, logical_type_node,
2178 dovar, boundary);
2179 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2180 "Loop iterates infinitely");
2183 /* Main loop body. */
2184 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
2185 gfc_add_expr_to_block (&body, tmp);
2187 /* Label for cycle statements (if needed). */
2188 if (TREE_USED (cycle_label))
2190 tmp = build1_v (LABEL_EXPR, cycle_label);
2191 gfc_add_expr_to_block (&body, tmp);
2194 /* Check whether someone has modified the loop variable. */
2195 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2197 tmp = fold_build2_loc (loc, NE_EXPR, logical_type_node,
2198 dovar, saved_dovar);
2199 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2200 "Loop variable has been modified");
2203 /* Increment the loop variable. */
2204 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
2205 gfc_add_modify_loc (loc, &body, dovar, tmp);
2207 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2208 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
2210 /* Finish the loop body. */
2211 tmp = gfc_finish_block (&body);
2212 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
2214 gfc_add_expr_to_block (pblock, tmp);
2216 /* Add the exit label. */
2217 tmp = build1_v (LABEL_EXPR, exit_label);
2218 gfc_add_expr_to_block (pblock, tmp);
2220 return gfc_finish_block (pblock);
2223 /* Translate the DO construct. This obviously is one of the most
2224 important ones to get right with any compiler, but especially
2225 so for Fortran.
2227 We special case some loop forms as described in gfc_trans_simple_do.
2228 For other cases we implement them with a separate loop count,
2229 as described in the standard.
2231 We translate a do loop from:
2233 DO dovar = from, to, step
2234 body
2235 END DO
2239 [evaluate loop bounds and step]
2240 empty = (step > 0 ? to < from : to > from);
2241 countm1 = (to - from) / step;
2242 dovar = from;
2243 if (empty) goto exit_label;
2244 for (;;)
2246 body;
2247 cycle_label:
2248 dovar += step
2249 countm1t = countm1;
2250 countm1--;
2251 if (countm1t == 0) goto exit_label;
2253 exit_label:
2255 countm1 is an unsigned integer. It is equal to the loop count minus one,
2256 because the loop count itself can overflow. */
2258 tree
2259 gfc_trans_do (gfc_code * code, tree exit_cond)
2261 gfc_se se;
2262 tree dovar;
2263 tree saved_dovar = NULL;
2264 tree from;
2265 tree to;
2266 tree step;
2267 tree countm1;
2268 tree type;
2269 tree utype;
2270 tree cond;
2271 tree cycle_label;
2272 tree exit_label;
2273 tree tmp;
2274 stmtblock_t block;
2275 stmtblock_t body;
2276 location_t loc;
2278 gfc_start_block (&block);
2280 loc = code->ext.iterator->start->where.lb->location;
2282 /* Evaluate all the expressions in the iterator. */
2283 gfc_init_se (&se, NULL);
2284 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
2285 gfc_add_block_to_block (&block, &se.pre);
2286 dovar = se.expr;
2287 type = TREE_TYPE (dovar);
2289 gfc_init_se (&se, NULL);
2290 gfc_conv_expr_val (&se, code->ext.iterator->start);
2291 gfc_add_block_to_block (&block, &se.pre);
2292 from = gfc_evaluate_now (se.expr, &block);
2294 gfc_init_se (&se, NULL);
2295 gfc_conv_expr_val (&se, code->ext.iterator->end);
2296 gfc_add_block_to_block (&block, &se.pre);
2297 to = gfc_evaluate_now (se.expr, &block);
2299 gfc_init_se (&se, NULL);
2300 gfc_conv_expr_val (&se, code->ext.iterator->step);
2301 gfc_add_block_to_block (&block, &se.pre);
2302 step = gfc_evaluate_now (se.expr, &block);
2304 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2306 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, step,
2307 build_zero_cst (type));
2308 gfc_trans_runtime_check (true, false, tmp, &block, &code->loc,
2309 "DO step value is zero");
2312 /* Special case simple loops. */
2313 if (TREE_CODE (type) == INTEGER_TYPE
2314 && (integer_onep (step)
2315 || tree_int_cst_equal (step, integer_minus_one_node)))
2316 return gfc_trans_simple_do (code, &block, dovar, from, to, step,
2317 exit_cond);
2319 if (TREE_CODE (type) == INTEGER_TYPE)
2320 utype = unsigned_type_for (type);
2321 else
2322 utype = unsigned_type_for (gfc_array_index_type);
2323 countm1 = gfc_create_var (utype, "countm1");
2325 /* Cycle and exit statements are implemented with gotos. */
2326 cycle_label = gfc_build_label_decl (NULL_TREE);
2327 exit_label = gfc_build_label_decl (NULL_TREE);
2328 TREE_USED (exit_label) = 1;
2330 /* Put these labels where they can be found later. */
2331 code->cycle_label = cycle_label;
2332 code->exit_label = exit_label;
2334 /* Initialize the DO variable: dovar = from. */
2335 gfc_add_modify (&block, dovar, from);
2337 /* Save value for do-tinkering checking. */
2338 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2340 saved_dovar = gfc_create_var (type, ".saved_dovar");
2341 gfc_add_modify_loc (loc, &block, saved_dovar, dovar);
2344 /* Initialize loop count and jump to exit label if the loop is empty.
2345 This code is executed before we enter the loop body. We generate:
2346 if (step > 0)
2348 countm1 = (to - from) / step;
2349 if (to < from)
2350 goto exit_label;
2352 else
2354 countm1 = (from - to) / -step;
2355 if (to > from)
2356 goto exit_label;
2360 if (TREE_CODE (type) == INTEGER_TYPE)
2362 tree pos, neg, tou, fromu, stepu, tmp2;
2364 /* The distance from FROM to TO cannot always be represented in a signed
2365 type, thus use unsigned arithmetic, also to avoid any undefined
2366 overflow issues. */
2367 tou = fold_convert (utype, to);
2368 fromu = fold_convert (utype, from);
2369 stepu = fold_convert (utype, step);
2371 /* For a positive step, when to < from, exit, otherwise compute
2372 countm1 = ((unsigned)to - (unsigned)from) / (unsigned)step */
2373 tmp = fold_build2_loc (loc, LT_EXPR, logical_type_node, to, from);
2374 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2375 fold_build2_loc (loc, MINUS_EXPR, utype,
2376 tou, fromu),
2377 stepu);
2378 pos = build2 (COMPOUND_EXPR, void_type_node,
2379 fold_build2 (MODIFY_EXPR, void_type_node,
2380 countm1, tmp2),
2381 build3_loc (loc, COND_EXPR, void_type_node,
2382 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
2383 build1_loc (loc, GOTO_EXPR, void_type_node,
2384 exit_label), NULL_TREE));
2386 /* For a negative step, when to > from, exit, otherwise compute
2387 countm1 = ((unsigned)from - (unsigned)to) / -(unsigned)step */
2388 tmp = fold_build2_loc (loc, GT_EXPR, logical_type_node, to, from);
2389 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2390 fold_build2_loc (loc, MINUS_EXPR, utype,
2391 fromu, tou),
2392 fold_build1_loc (loc, NEGATE_EXPR, utype, stepu));
2393 neg = build2 (COMPOUND_EXPR, void_type_node,
2394 fold_build2 (MODIFY_EXPR, void_type_node,
2395 countm1, tmp2),
2396 build3_loc (loc, COND_EXPR, void_type_node,
2397 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
2398 build1_loc (loc, GOTO_EXPR, void_type_node,
2399 exit_label), NULL_TREE));
2401 tmp = fold_build2_loc (loc, LT_EXPR, logical_type_node, step,
2402 build_int_cst (TREE_TYPE (step), 0));
2403 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp, neg, pos);
2405 gfc_add_expr_to_block (&block, tmp);
2407 else
2409 tree pos_step;
2411 /* TODO: We could use the same width as the real type.
2412 This would probably cause more problems that it solves
2413 when we implement "long double" types. */
2415 tmp = fold_build2_loc (loc, MINUS_EXPR, type, to, from);
2416 tmp = fold_build2_loc (loc, RDIV_EXPR, type, tmp, step);
2417 tmp = fold_build1_loc (loc, FIX_TRUNC_EXPR, utype, tmp);
2418 gfc_add_modify (&block, countm1, tmp);
2420 /* We need a special check for empty loops:
2421 empty = (step > 0 ? to < from : to > from); */
2422 pos_step = fold_build2_loc (loc, GT_EXPR, logical_type_node, step,
2423 build_zero_cst (type));
2424 tmp = fold_build3_loc (loc, COND_EXPR, logical_type_node, pos_step,
2425 fold_build2_loc (loc, LT_EXPR,
2426 logical_type_node, to, from),
2427 fold_build2_loc (loc, GT_EXPR,
2428 logical_type_node, to, from));
2429 /* If the loop is empty, go directly to the exit label. */
2430 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp,
2431 build1_v (GOTO_EXPR, exit_label),
2432 build_empty_stmt (input_location));
2433 gfc_add_expr_to_block (&block, tmp);
2436 /* Loop body. */
2437 gfc_start_block (&body);
2439 /* Main loop body. */
2440 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
2441 gfc_add_expr_to_block (&body, tmp);
2443 /* Label for cycle statements (if needed). */
2444 if (TREE_USED (cycle_label))
2446 tmp = build1_v (LABEL_EXPR, cycle_label);
2447 gfc_add_expr_to_block (&body, tmp);
2450 /* Check whether someone has modified the loop variable. */
2451 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2453 tmp = fold_build2_loc (loc, NE_EXPR, logical_type_node, dovar,
2454 saved_dovar);
2455 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2456 "Loop variable has been modified");
2459 /* Exit the loop if there is an I/O result condition or error. */
2460 if (exit_cond)
2462 tmp = build1_v (GOTO_EXPR, exit_label);
2463 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2464 exit_cond, tmp,
2465 build_empty_stmt (input_location));
2466 gfc_add_expr_to_block (&body, tmp);
2469 /* Increment the loop variable. */
2470 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
2471 gfc_add_modify_loc (loc, &body, dovar, tmp);
2473 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2474 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
2476 /* Initialize countm1t. */
2477 tree countm1t = gfc_create_var (utype, "countm1t");
2478 gfc_add_modify_loc (loc, &body, countm1t, countm1);
2480 /* Decrement the loop count. */
2481 tmp = fold_build2_loc (loc, MINUS_EXPR, utype, countm1,
2482 build_int_cst (utype, 1));
2483 gfc_add_modify_loc (loc, &body, countm1, tmp);
2485 /* End with the loop condition. Loop until countm1t == 0. */
2486 cond = fold_build2_loc (loc, EQ_EXPR, logical_type_node, countm1t,
2487 build_int_cst (utype, 0));
2488 if (code->ext.iterator->unroll && cond != error_mark_node)
2489 cond
2490 = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2491 build_int_cst (integer_type_node, annot_expr_unroll_kind),
2492 build_int_cst (integer_type_node, code->ext.iterator->unroll));
2493 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
2494 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2495 cond, tmp, build_empty_stmt (loc));
2496 gfc_add_expr_to_block (&body, tmp);
2498 /* End of loop body. */
2499 tmp = gfc_finish_block (&body);
2501 /* The for loop itself. */
2502 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
2503 gfc_add_expr_to_block (&block, tmp);
2505 /* Add the exit label. */
2506 tmp = build1_v (LABEL_EXPR, exit_label);
2507 gfc_add_expr_to_block (&block, tmp);
2509 return gfc_finish_block (&block);
2513 /* Translate the DO WHILE construct.
2515 We translate
2517 DO WHILE (cond)
2518 body
2519 END DO
2523 for ( ; ; )
2525 pre_cond;
2526 if (! cond) goto exit_label;
2527 body;
2528 cycle_label:
2530 exit_label:
2532 Because the evaluation of the exit condition `cond' may have side
2533 effects, we can't do much for empty loop bodies. The backend optimizers
2534 should be smart enough to eliminate any dead loops. */
2536 tree
2537 gfc_trans_do_while (gfc_code * code)
2539 gfc_se cond;
2540 tree tmp;
2541 tree cycle_label;
2542 tree exit_label;
2543 stmtblock_t block;
2545 /* Everything we build here is part of the loop body. */
2546 gfc_start_block (&block);
2548 /* Cycle and exit statements are implemented with gotos. */
2549 cycle_label = gfc_build_label_decl (NULL_TREE);
2550 exit_label = gfc_build_label_decl (NULL_TREE);
2552 /* Put the labels where they can be found later. See gfc_trans_do(). */
2553 code->cycle_label = cycle_label;
2554 code->exit_label = exit_label;
2556 /* Create a GIMPLE version of the exit condition. */
2557 gfc_init_se (&cond, NULL);
2558 gfc_conv_expr_val (&cond, code->expr1);
2559 gfc_add_block_to_block (&block, &cond.pre);
2560 cond.expr = fold_build1_loc (code->expr1->where.lb->location,
2561 TRUTH_NOT_EXPR, TREE_TYPE (cond.expr), cond.expr);
2563 /* Build "IF (! cond) GOTO exit_label". */
2564 tmp = build1_v (GOTO_EXPR, exit_label);
2565 TREE_USED (exit_label) = 1;
2566 tmp = fold_build3_loc (code->expr1->where.lb->location, COND_EXPR,
2567 void_type_node, cond.expr, tmp,
2568 build_empty_stmt (code->expr1->where.lb->location));
2569 gfc_add_expr_to_block (&block, tmp);
2571 /* The main body of the loop. */
2572 tmp = gfc_trans_code (code->block->next);
2573 gfc_add_expr_to_block (&block, tmp);
2575 /* Label for cycle statements (if needed). */
2576 if (TREE_USED (cycle_label))
2578 tmp = build1_v (LABEL_EXPR, cycle_label);
2579 gfc_add_expr_to_block (&block, tmp);
2582 /* End of loop body. */
2583 tmp = gfc_finish_block (&block);
2585 gfc_init_block (&block);
2586 /* Build the loop. */
2587 tmp = fold_build1_loc (code->expr1->where.lb->location, LOOP_EXPR,
2588 void_type_node, tmp);
2589 gfc_add_expr_to_block (&block, tmp);
2591 /* Add the exit label. */
2592 tmp = build1_v (LABEL_EXPR, exit_label);
2593 gfc_add_expr_to_block (&block, tmp);
2595 return gfc_finish_block (&block);
2599 /* Deal with the particular case of SELECT_TYPE, where the vtable
2600 addresses are used for the selection. Since these are not sorted,
2601 the selection has to be made by a series of if statements. */
2603 static tree
2604 gfc_trans_select_type_cases (gfc_code * code)
2606 gfc_code *c;
2607 gfc_case *cp;
2608 tree tmp;
2609 tree cond;
2610 tree low;
2611 tree high;
2612 gfc_se se;
2613 gfc_se cse;
2614 stmtblock_t block;
2615 stmtblock_t body;
2616 bool def = false;
2617 gfc_expr *e;
2618 gfc_start_block (&block);
2620 /* Calculate the switch expression. */
2621 gfc_init_se (&se, NULL);
2622 gfc_conv_expr_val (&se, code->expr1);
2623 gfc_add_block_to_block (&block, &se.pre);
2625 /* Generate an expression for the selector hash value, for
2626 use to resolve character cases. */
2627 e = gfc_copy_expr (code->expr1->value.function.actual->expr);
2628 gfc_add_hash_component (e);
2630 TREE_USED (code->exit_label) = 0;
2632 repeat:
2633 for (c = code->block; c; c = c->block)
2635 cp = c->ext.block.case_list;
2637 /* Assume it's the default case. */
2638 low = NULL_TREE;
2639 high = NULL_TREE;
2640 tmp = NULL_TREE;
2642 /* Put the default case at the end. */
2643 if ((!def && !cp->low) || (def && cp->low))
2644 continue;
2646 if (cp->low && (cp->ts.type == BT_CLASS
2647 || cp->ts.type == BT_DERIVED))
2649 gfc_init_se (&cse, NULL);
2650 gfc_conv_expr_val (&cse, cp->low);
2651 gfc_add_block_to_block (&block, &cse.pre);
2652 low = cse.expr;
2654 else if (cp->ts.type != BT_UNKNOWN)
2656 gcc_assert (cp->high);
2657 gfc_init_se (&cse, NULL);
2658 gfc_conv_expr_val (&cse, cp->high);
2659 gfc_add_block_to_block (&block, &cse.pre);
2660 high = cse.expr;
2663 gfc_init_block (&body);
2665 /* Add the statements for this case. */
2666 tmp = gfc_trans_code (c->next);
2667 gfc_add_expr_to_block (&body, tmp);
2669 /* Break to the end of the SELECT TYPE construct. The default
2670 case just falls through. */
2671 if (!def)
2673 TREE_USED (code->exit_label) = 1;
2674 tmp = build1_v (GOTO_EXPR, code->exit_label);
2675 gfc_add_expr_to_block (&body, tmp);
2678 tmp = gfc_finish_block (&body);
2680 if (low != NULL_TREE)
2682 /* Compare vtable pointers. */
2683 cond = fold_build2_loc (input_location, EQ_EXPR,
2684 TREE_TYPE (se.expr), se.expr, low);
2685 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2686 cond, tmp,
2687 build_empty_stmt (input_location));
2689 else if (high != NULL_TREE)
2691 /* Compare hash values for character cases. */
2692 gfc_init_se (&cse, NULL);
2693 gfc_conv_expr_val (&cse, e);
2694 gfc_add_block_to_block (&block, &cse.pre);
2696 cond = fold_build2_loc (input_location, EQ_EXPR,
2697 TREE_TYPE (se.expr), high, cse.expr);
2698 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2699 cond, tmp,
2700 build_empty_stmt (input_location));
2703 gfc_add_expr_to_block (&block, tmp);
2706 if (!def)
2708 def = true;
2709 goto repeat;
2712 gfc_free_expr (e);
2714 return gfc_finish_block (&block);
2718 /* Translate the SELECT CASE construct for INTEGER case expressions,
2719 without killing all potential optimizations. The problem is that
2720 Fortran allows unbounded cases, but the back-end does not, so we
2721 need to intercept those before we enter the equivalent SWITCH_EXPR
2722 we can build.
2724 For example, we translate this,
2726 SELECT CASE (expr)
2727 CASE (:100,101,105:115)
2728 block_1
2729 CASE (190:199,200:)
2730 block_2
2731 CASE (300)
2732 block_3
2733 CASE DEFAULT
2734 block_4
2735 END SELECT
2737 to the GENERIC equivalent,
2739 switch (expr)
2741 case (minimum value for typeof(expr) ... 100:
2742 case 101:
2743 case 105 ... 114:
2744 block1:
2745 goto end_label;
2747 case 200 ... (maximum value for typeof(expr):
2748 case 190 ... 199:
2749 block2;
2750 goto end_label;
2752 case 300:
2753 block_3;
2754 goto end_label;
2756 default:
2757 block_4;
2758 goto end_label;
2761 end_label: */
2763 static tree
2764 gfc_trans_integer_select (gfc_code * code)
2766 gfc_code *c;
2767 gfc_case *cp;
2768 tree end_label;
2769 tree tmp;
2770 gfc_se se;
2771 stmtblock_t block;
2772 stmtblock_t body;
2774 gfc_start_block (&block);
2776 /* Calculate the switch expression. */
2777 gfc_init_se (&se, NULL);
2778 gfc_conv_expr_val (&se, code->expr1);
2779 gfc_add_block_to_block (&block, &se.pre);
2781 end_label = gfc_build_label_decl (NULL_TREE);
2783 gfc_init_block (&body);
2785 for (c = code->block; c; c = c->block)
2787 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2789 tree low, high;
2790 tree label;
2792 /* Assume it's the default case. */
2793 low = high = NULL_TREE;
2795 if (cp->low)
2797 low = gfc_conv_mpz_to_tree (cp->low->value.integer,
2798 cp->low->ts.kind);
2800 /* If there's only a lower bound, set the high bound to the
2801 maximum value of the case expression. */
2802 if (!cp->high)
2803 high = TYPE_MAX_VALUE (TREE_TYPE (se.expr));
2806 if (cp->high)
2808 /* Three cases are possible here:
2810 1) There is no lower bound, e.g. CASE (:N).
2811 2) There is a lower bound .NE. high bound, that is
2812 a case range, e.g. CASE (N:M) where M>N (we make
2813 sure that M>N during type resolution).
2814 3) There is a lower bound, and it has the same value
2815 as the high bound, e.g. CASE (N:N). This is our
2816 internal representation of CASE(N).
2818 In the first and second case, we need to set a value for
2819 high. In the third case, we don't because the GCC middle
2820 end represents a single case value by just letting high be
2821 a NULL_TREE. We can't do that because we need to be able
2822 to represent unbounded cases. */
2824 if (!cp->low
2825 || (mpz_cmp (cp->low->value.integer,
2826 cp->high->value.integer) != 0))
2827 high = gfc_conv_mpz_to_tree (cp->high->value.integer,
2828 cp->high->ts.kind);
2830 /* Unbounded case. */
2831 if (!cp->low)
2832 low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
2835 /* Build a label. */
2836 label = gfc_build_label_decl (NULL_TREE);
2838 /* Add this case label.
2839 Add parameter 'label', make it match GCC backend. */
2840 tmp = build_case_label (low, high, label);
2841 gfc_add_expr_to_block (&body, tmp);
2844 /* Add the statements for this case. */
2845 tmp = gfc_trans_code (c->next);
2846 gfc_add_expr_to_block (&body, tmp);
2848 /* Break to the end of the construct. */
2849 tmp = build1_v (GOTO_EXPR, end_label);
2850 gfc_add_expr_to_block (&body, tmp);
2853 tmp = gfc_finish_block (&body);
2854 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE, se.expr, tmp);
2855 gfc_add_expr_to_block (&block, tmp);
2857 tmp = build1_v (LABEL_EXPR, end_label);
2858 gfc_add_expr_to_block (&block, tmp);
2860 return gfc_finish_block (&block);
2864 /* Translate the SELECT CASE construct for LOGICAL case expressions.
2866 There are only two cases possible here, even though the standard
2867 does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
2868 .FALSE., and DEFAULT.
2870 We never generate more than two blocks here. Instead, we always
2871 try to eliminate the DEFAULT case. This way, we can translate this
2872 kind of SELECT construct to a simple
2874 if {} else {};
2876 expression in GENERIC. */
2878 static tree
2879 gfc_trans_logical_select (gfc_code * code)
2881 gfc_code *c;
2882 gfc_code *t, *f, *d;
2883 gfc_case *cp;
2884 gfc_se se;
2885 stmtblock_t block;
2887 /* Assume we don't have any cases at all. */
2888 t = f = d = NULL;
2890 /* Now see which ones we actually do have. We can have at most two
2891 cases in a single case list: one for .TRUE. and one for .FALSE.
2892 The default case is always separate. If the cases for .TRUE. and
2893 .FALSE. are in the same case list, the block for that case list
2894 always executed, and we don't generate code a COND_EXPR. */
2895 for (c = code->block; c; c = c->block)
2897 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2899 if (cp->low)
2901 if (cp->low->value.logical == 0) /* .FALSE. */
2902 f = c;
2903 else /* if (cp->value.logical != 0), thus .TRUE. */
2904 t = c;
2906 else
2907 d = c;
2911 /* Start a new block. */
2912 gfc_start_block (&block);
2914 /* Calculate the switch expression. We always need to do this
2915 because it may have side effects. */
2916 gfc_init_se (&se, NULL);
2917 gfc_conv_expr_val (&se, code->expr1);
2918 gfc_add_block_to_block (&block, &se.pre);
2920 if (t == f && t != NULL)
2922 /* Cases for .TRUE. and .FALSE. are in the same block. Just
2923 translate the code for these cases, append it to the current
2924 block. */
2925 gfc_add_expr_to_block (&block, gfc_trans_code (t->next));
2927 else
2929 tree true_tree, false_tree, stmt;
2931 true_tree = build_empty_stmt (input_location);
2932 false_tree = build_empty_stmt (input_location);
2934 /* If we have a case for .TRUE. and for .FALSE., discard the default case.
2935 Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
2936 make the missing case the default case. */
2937 if (t != NULL && f != NULL)
2938 d = NULL;
2939 else if (d != NULL)
2941 if (t == NULL)
2942 t = d;
2943 else
2944 f = d;
2947 /* Translate the code for each of these blocks, and append it to
2948 the current block. */
2949 if (t != NULL)
2950 true_tree = gfc_trans_code (t->next);
2952 if (f != NULL)
2953 false_tree = gfc_trans_code (f->next);
2955 stmt = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2956 se.expr, true_tree, false_tree);
2957 gfc_add_expr_to_block (&block, stmt);
2960 return gfc_finish_block (&block);
2964 /* The jump table types are stored in static variables to avoid
2965 constructing them from scratch every single time. */
2966 static GTY(()) tree select_struct[2];
2968 /* Translate the SELECT CASE construct for CHARACTER case expressions.
2969 Instead of generating compares and jumps, it is far simpler to
2970 generate a data structure describing the cases in order and call a
2971 library subroutine that locates the right case.
2972 This is particularly true because this is the only case where we
2973 might have to dispose of a temporary.
2974 The library subroutine returns a pointer to jump to or NULL if no
2975 branches are to be taken. */
2977 static tree
2978 gfc_trans_character_select (gfc_code *code)
2980 tree init, end_label, tmp, type, case_num, label, fndecl;
2981 stmtblock_t block, body;
2982 gfc_case *cp, *d;
2983 gfc_code *c;
2984 gfc_se se, expr1se;
2985 int n, k;
2986 vec<constructor_elt, va_gc> *inits = NULL;
2988 tree pchartype = gfc_get_pchar_type (code->expr1->ts.kind);
2990 /* The jump table types are stored in static variables to avoid
2991 constructing them from scratch every single time. */
2992 static tree ss_string1[2], ss_string1_len[2];
2993 static tree ss_string2[2], ss_string2_len[2];
2994 static tree ss_target[2];
2996 cp = code->block->ext.block.case_list;
2997 while (cp->left != NULL)
2998 cp = cp->left;
3000 /* Generate the body */
3001 gfc_start_block (&block);
3002 gfc_init_se (&expr1se, NULL);
3003 gfc_conv_expr_reference (&expr1se, code->expr1);
3005 gfc_add_block_to_block (&block, &expr1se.pre);
3007 end_label = gfc_build_label_decl (NULL_TREE);
3009 gfc_init_block (&body);
3011 /* Attempt to optimize length 1 selects. */
3012 if (integer_onep (expr1se.string_length))
3014 for (d = cp; d; d = d->right)
3016 gfc_charlen_t i;
3017 if (d->low)
3019 gcc_assert (d->low->expr_type == EXPR_CONSTANT
3020 && d->low->ts.type == BT_CHARACTER);
3021 if (d->low->value.character.length > 1)
3023 for (i = 1; i < d->low->value.character.length; i++)
3024 if (d->low->value.character.string[i] != ' ')
3025 break;
3026 if (i != d->low->value.character.length)
3028 if (optimize && d->high && i == 1)
3030 gcc_assert (d->high->expr_type == EXPR_CONSTANT
3031 && d->high->ts.type == BT_CHARACTER);
3032 if (d->high->value.character.length > 1
3033 && (d->low->value.character.string[0]
3034 == d->high->value.character.string[0])
3035 && d->high->value.character.string[1] != ' '
3036 && ((d->low->value.character.string[1] < ' ')
3037 == (d->high->value.character.string[1]
3038 < ' ')))
3039 continue;
3041 break;
3045 if (d->high)
3047 gcc_assert (d->high->expr_type == EXPR_CONSTANT
3048 && d->high->ts.type == BT_CHARACTER);
3049 if (d->high->value.character.length > 1)
3051 for (i = 1; i < d->high->value.character.length; i++)
3052 if (d->high->value.character.string[i] != ' ')
3053 break;
3054 if (i != d->high->value.character.length)
3055 break;
3059 if (d == NULL)
3061 tree ctype = gfc_get_char_type (code->expr1->ts.kind);
3063 for (c = code->block; c; c = c->block)
3065 for (cp = c->ext.block.case_list; cp; cp = cp->next)
3067 tree low, high;
3068 tree label;
3069 gfc_char_t r;
3071 /* Assume it's the default case. */
3072 low = high = NULL_TREE;
3074 if (cp->low)
3076 /* CASE ('ab') or CASE ('ab':'az') will never match
3077 any length 1 character. */
3078 if (cp->low->value.character.length > 1
3079 && cp->low->value.character.string[1] != ' ')
3080 continue;
3082 if (cp->low->value.character.length > 0)
3083 r = cp->low->value.character.string[0];
3084 else
3085 r = ' ';
3086 low = build_int_cst (ctype, r);
3088 /* If there's only a lower bound, set the high bound
3089 to the maximum value of the case expression. */
3090 if (!cp->high)
3091 high = TYPE_MAX_VALUE (ctype);
3094 if (cp->high)
3096 if (!cp->low
3097 || (cp->low->value.character.string[0]
3098 != cp->high->value.character.string[0]))
3100 if (cp->high->value.character.length > 0)
3101 r = cp->high->value.character.string[0];
3102 else
3103 r = ' ';
3104 high = build_int_cst (ctype, r);
3107 /* Unbounded case. */
3108 if (!cp->low)
3109 low = TYPE_MIN_VALUE (ctype);
3112 /* Build a label. */
3113 label = gfc_build_label_decl (NULL_TREE);
3115 /* Add this case label.
3116 Add parameter 'label', make it match GCC backend. */
3117 tmp = build_case_label (low, high, label);
3118 gfc_add_expr_to_block (&body, tmp);
3121 /* Add the statements for this case. */
3122 tmp = gfc_trans_code (c->next);
3123 gfc_add_expr_to_block (&body, tmp);
3125 /* Break to the end of the construct. */
3126 tmp = build1_v (GOTO_EXPR, end_label);
3127 gfc_add_expr_to_block (&body, tmp);
3130 tmp = gfc_string_to_single_character (expr1se.string_length,
3131 expr1se.expr,
3132 code->expr1->ts.kind);
3133 case_num = gfc_create_var (ctype, "case_num");
3134 gfc_add_modify (&block, case_num, tmp);
3136 gfc_add_block_to_block (&block, &expr1se.post);
3138 tmp = gfc_finish_block (&body);
3139 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE,
3140 case_num, tmp);
3141 gfc_add_expr_to_block (&block, tmp);
3143 tmp = build1_v (LABEL_EXPR, end_label);
3144 gfc_add_expr_to_block (&block, tmp);
3146 return gfc_finish_block (&block);
3150 if (code->expr1->ts.kind == 1)
3151 k = 0;
3152 else if (code->expr1->ts.kind == 4)
3153 k = 1;
3154 else
3155 gcc_unreachable ();
3157 if (select_struct[k] == NULL)
3159 tree *chain = NULL;
3160 select_struct[k] = make_node (RECORD_TYPE);
3162 if (code->expr1->ts.kind == 1)
3163 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char1");
3164 else if (code->expr1->ts.kind == 4)
3165 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char4");
3166 else
3167 gcc_unreachable ();
3169 #undef ADD_FIELD
3170 #define ADD_FIELD(NAME, TYPE) \
3171 ss_##NAME[k] = gfc_add_field_to_struct (select_struct[k], \
3172 get_identifier (stringize(NAME)), \
3173 TYPE, \
3174 &chain)
3176 ADD_FIELD (string1, pchartype);
3177 ADD_FIELD (string1_len, gfc_charlen_type_node);
3179 ADD_FIELD (string2, pchartype);
3180 ADD_FIELD (string2_len, gfc_charlen_type_node);
3182 ADD_FIELD (target, integer_type_node);
3183 #undef ADD_FIELD
3185 gfc_finish_type (select_struct[k]);
3188 n = 0;
3189 for (d = cp; d; d = d->right)
3190 d->n = n++;
3192 for (c = code->block; c; c = c->block)
3194 for (d = c->ext.block.case_list; d; d = d->next)
3196 label = gfc_build_label_decl (NULL_TREE);
3197 tmp = build_case_label ((d->low == NULL && d->high == NULL)
3198 ? NULL
3199 : build_int_cst (integer_type_node, d->n),
3200 NULL, label);
3201 gfc_add_expr_to_block (&body, tmp);
3204 tmp = gfc_trans_code (c->next);
3205 gfc_add_expr_to_block (&body, tmp);
3207 tmp = build1_v (GOTO_EXPR, end_label);
3208 gfc_add_expr_to_block (&body, tmp);
3211 /* Generate the structure describing the branches */
3212 for (d = cp; d; d = d->right)
3214 vec<constructor_elt, va_gc> *node = NULL;
3216 gfc_init_se (&se, NULL);
3218 if (d->low == NULL)
3220 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], null_pointer_node);
3221 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], build_zero_cst (gfc_charlen_type_node));
3223 else
3225 gfc_conv_expr_reference (&se, d->low);
3227 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], se.expr);
3228 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], se.string_length);
3231 if (d->high == NULL)
3233 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], null_pointer_node);
3234 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], build_zero_cst (gfc_charlen_type_node));
3236 else
3238 gfc_init_se (&se, NULL);
3239 gfc_conv_expr_reference (&se, d->high);
3241 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], se.expr);
3242 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], se.string_length);
3245 CONSTRUCTOR_APPEND_ELT (node, ss_target[k],
3246 build_int_cst (integer_type_node, d->n));
3248 tmp = build_constructor (select_struct[k], node);
3249 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, tmp);
3252 type = build_array_type (select_struct[k],
3253 build_index_type (size_int (n-1)));
3255 init = build_constructor (type, inits);
3256 TREE_CONSTANT (init) = 1;
3257 TREE_STATIC (init) = 1;
3258 /* Create a static variable to hold the jump table. */
3259 tmp = gfc_create_var (type, "jumptable");
3260 TREE_CONSTANT (tmp) = 1;
3261 TREE_STATIC (tmp) = 1;
3262 TREE_READONLY (tmp) = 1;
3263 DECL_INITIAL (tmp) = init;
3264 init = tmp;
3266 /* Build the library call */
3267 init = gfc_build_addr_expr (pvoid_type_node, init);
3269 if (code->expr1->ts.kind == 1)
3270 fndecl = gfor_fndecl_select_string;
3271 else if (code->expr1->ts.kind == 4)
3272 fndecl = gfor_fndecl_select_string_char4;
3273 else
3274 gcc_unreachable ();
3276 tmp = build_call_expr_loc (input_location,
3277 fndecl, 4, init,
3278 build_int_cst (gfc_charlen_type_node, n),
3279 expr1se.expr, expr1se.string_length);
3280 case_num = gfc_create_var (integer_type_node, "case_num");
3281 gfc_add_modify (&block, case_num, tmp);
3283 gfc_add_block_to_block (&block, &expr1se.post);
3285 tmp = gfc_finish_block (&body);
3286 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE,
3287 case_num, tmp);
3288 gfc_add_expr_to_block (&block, tmp);
3290 tmp = build1_v (LABEL_EXPR, end_label);
3291 gfc_add_expr_to_block (&block, tmp);
3293 return gfc_finish_block (&block);
3297 /* Translate the three variants of the SELECT CASE construct.
3299 SELECT CASEs with INTEGER case expressions can be translated to an
3300 equivalent GENERIC switch statement, and for LOGICAL case
3301 expressions we build one or two if-else compares.
3303 SELECT CASEs with CHARACTER case expressions are a whole different
3304 story, because they don't exist in GENERIC. So we sort them and
3305 do a binary search at runtime.
3307 Fortran has no BREAK statement, and it does not allow jumps from
3308 one case block to another. That makes things a lot easier for
3309 the optimizers. */
3311 tree
3312 gfc_trans_select (gfc_code * code)
3314 stmtblock_t block;
3315 tree body;
3316 tree exit_label;
3318 gcc_assert (code && code->expr1);
3319 gfc_init_block (&block);
3321 /* Build the exit label and hang it in. */
3322 exit_label = gfc_build_label_decl (NULL_TREE);
3323 code->exit_label = exit_label;
3325 /* Empty SELECT constructs are legal. */
3326 if (code->block == NULL)
3327 body = build_empty_stmt (input_location);
3329 /* Select the correct translation function. */
3330 else
3331 switch (code->expr1->ts.type)
3333 case BT_LOGICAL:
3334 body = gfc_trans_logical_select (code);
3335 break;
3337 case BT_INTEGER:
3338 body = gfc_trans_integer_select (code);
3339 break;
3341 case BT_CHARACTER:
3342 body = gfc_trans_character_select (code);
3343 break;
3345 default:
3346 gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
3347 /* Not reached */
3350 /* Build everything together. */
3351 gfc_add_expr_to_block (&block, body);
3352 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3354 return gfc_finish_block (&block);
3357 tree
3358 gfc_trans_select_type (gfc_code * code)
3360 stmtblock_t block;
3361 tree body;
3362 tree exit_label;
3364 gcc_assert (code && code->expr1);
3365 gfc_init_block (&block);
3367 /* Build the exit label and hang it in. */
3368 exit_label = gfc_build_label_decl (NULL_TREE);
3369 code->exit_label = exit_label;
3371 /* Empty SELECT constructs are legal. */
3372 if (code->block == NULL)
3373 body = build_empty_stmt (input_location);
3374 else
3375 body = gfc_trans_select_type_cases (code);
3377 /* Build everything together. */
3378 gfc_add_expr_to_block (&block, body);
3380 if (TREE_USED (exit_label))
3381 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3383 return gfc_finish_block (&block);
3387 /* Traversal function to substitute a replacement symtree if the symbol
3388 in the expression is the same as that passed. f == 2 signals that
3389 that variable itself is not to be checked - only the references.
3390 This group of functions is used when the variable expression in a
3391 FORALL assignment has internal references. For example:
3392 FORALL (i = 1:4) p(p(i)) = i
3393 The only recourse here is to store a copy of 'p' for the index
3394 expression. */
3396 static gfc_symtree *new_symtree;
3397 static gfc_symtree *old_symtree;
3399 static bool
3400 forall_replace (gfc_expr *expr, gfc_symbol *sym, int *f)
3402 if (expr->expr_type != EXPR_VARIABLE)
3403 return false;
3405 if (*f == 2)
3406 *f = 1;
3407 else if (expr->symtree->n.sym == sym)
3408 expr->symtree = new_symtree;
3410 return false;
3413 static void
3414 forall_replace_symtree (gfc_expr *e, gfc_symbol *sym, int f)
3416 gfc_traverse_expr (e, sym, forall_replace, f);
3419 static bool
3420 forall_restore (gfc_expr *expr,
3421 gfc_symbol *sym ATTRIBUTE_UNUSED,
3422 int *f ATTRIBUTE_UNUSED)
3424 if (expr->expr_type != EXPR_VARIABLE)
3425 return false;
3427 if (expr->symtree == new_symtree)
3428 expr->symtree = old_symtree;
3430 return false;
3433 static void
3434 forall_restore_symtree (gfc_expr *e)
3436 gfc_traverse_expr (e, NULL, forall_restore, 0);
3439 static void
3440 forall_make_variable_temp (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
3442 gfc_se tse;
3443 gfc_se rse;
3444 gfc_expr *e;
3445 gfc_symbol *new_sym;
3446 gfc_symbol *old_sym;
3447 gfc_symtree *root;
3448 tree tmp;
3450 /* Build a copy of the lvalue. */
3451 old_symtree = c->expr1->symtree;
3452 old_sym = old_symtree->n.sym;
3453 e = gfc_lval_expr_from_sym (old_sym);
3454 if (old_sym->attr.dimension)
3456 gfc_init_se (&tse, NULL);
3457 gfc_conv_subref_array_arg (&tse, e, 0, INTENT_IN, false);
3458 gfc_add_block_to_block (pre, &tse.pre);
3459 gfc_add_block_to_block (post, &tse.post);
3460 tse.expr = build_fold_indirect_ref_loc (input_location, tse.expr);
3462 if (c->expr1->ref->u.ar.type != AR_SECTION)
3464 /* Use the variable offset for the temporary. */
3465 tmp = gfc_conv_array_offset (old_sym->backend_decl);
3466 gfc_conv_descriptor_offset_set (pre, tse.expr, tmp);
3469 else
3471 gfc_init_se (&tse, NULL);
3472 gfc_init_se (&rse, NULL);
3473 gfc_conv_expr (&rse, e);
3474 if (e->ts.type == BT_CHARACTER)
3476 tse.string_length = rse.string_length;
3477 tmp = gfc_get_character_type_len (gfc_default_character_kind,
3478 tse.string_length);
3479 tse.expr = gfc_conv_string_tmp (&tse, build_pointer_type (tmp),
3480 rse.string_length);
3481 gfc_add_block_to_block (pre, &tse.pre);
3482 gfc_add_block_to_block (post, &tse.post);
3484 else
3486 tmp = gfc_typenode_for_spec (&e->ts);
3487 tse.expr = gfc_create_var (tmp, "temp");
3490 tmp = gfc_trans_scalar_assign (&tse, &rse, e->ts,
3491 e->expr_type == EXPR_VARIABLE, false);
3492 gfc_add_expr_to_block (pre, tmp);
3494 gfc_free_expr (e);
3496 /* Create a new symbol to represent the lvalue. */
3497 new_sym = gfc_new_symbol (old_sym->name, NULL);
3498 new_sym->ts = old_sym->ts;
3499 new_sym->attr.referenced = 1;
3500 new_sym->attr.temporary = 1;
3501 new_sym->attr.dimension = old_sym->attr.dimension;
3502 new_sym->attr.flavor = old_sym->attr.flavor;
3504 /* Use the temporary as the backend_decl. */
3505 new_sym->backend_decl = tse.expr;
3507 /* Create a fake symtree for it. */
3508 root = NULL;
3509 new_symtree = gfc_new_symtree (&root, old_sym->name);
3510 new_symtree->n.sym = new_sym;
3511 gcc_assert (new_symtree == root);
3513 /* Go through the expression reference replacing the old_symtree
3514 with the new. */
3515 forall_replace_symtree (c->expr1, old_sym, 2);
3517 /* Now we have made this temporary, we might as well use it for
3518 the right hand side. */
3519 forall_replace_symtree (c->expr2, old_sym, 1);
3523 /* Handles dependencies in forall assignments. */
3524 static int
3525 check_forall_dependencies (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
3527 gfc_ref *lref;
3528 gfc_ref *rref;
3529 int need_temp;
3530 gfc_symbol *lsym;
3532 lsym = c->expr1->symtree->n.sym;
3533 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
3535 /* Now check for dependencies within the 'variable'
3536 expression itself. These are treated by making a complete
3537 copy of variable and changing all the references to it
3538 point to the copy instead. Note that the shallow copy of
3539 the variable will not suffice for derived types with
3540 pointer components. We therefore leave these to their
3541 own devices. */
3542 if (lsym->ts.type == BT_DERIVED
3543 && lsym->ts.u.derived->attr.pointer_comp)
3544 return need_temp;
3546 new_symtree = NULL;
3547 if (find_forall_index (c->expr1, lsym, 2))
3549 forall_make_variable_temp (c, pre, post);
3550 need_temp = 0;
3553 /* Substrings with dependencies are treated in the same
3554 way. */
3555 if (c->expr1->ts.type == BT_CHARACTER
3556 && c->expr1->ref
3557 && c->expr2->expr_type == EXPR_VARIABLE
3558 && lsym == c->expr2->symtree->n.sym)
3560 for (lref = c->expr1->ref; lref; lref = lref->next)
3561 if (lref->type == REF_SUBSTRING)
3562 break;
3563 for (rref = c->expr2->ref; rref; rref = rref->next)
3564 if (rref->type == REF_SUBSTRING)
3565 break;
3567 if (rref && lref
3568 && gfc_dep_compare_expr (rref->u.ss.start, lref->u.ss.start) < 0)
3570 forall_make_variable_temp (c, pre, post);
3571 need_temp = 0;
3574 return need_temp;
3578 static void
3579 cleanup_forall_symtrees (gfc_code *c)
3581 forall_restore_symtree (c->expr1);
3582 forall_restore_symtree (c->expr2);
3583 free (new_symtree->n.sym);
3584 free (new_symtree);
3588 /* Generate the loops for a FORALL block, specified by FORALL_TMP. BODY
3589 is the contents of the FORALL block/stmt to be iterated. MASK_FLAG
3590 indicates whether we should generate code to test the FORALLs mask
3591 array. OUTER is the loop header to be used for initializing mask
3592 indices.
3594 The generated loop format is:
3595 count = (end - start + step) / step
3596 loopvar = start
3597 while (1)
3599 if (count <=0 )
3600 goto end_of_loop
3601 <body>
3602 loopvar += step
3603 count --
3605 end_of_loop: */
3607 static tree
3608 gfc_trans_forall_loop (forall_info *forall_tmp, tree body,
3609 int mask_flag, stmtblock_t *outer)
3611 int n, nvar;
3612 tree tmp;
3613 tree cond;
3614 stmtblock_t block;
3615 tree exit_label;
3616 tree count;
3617 tree var, start, end, step;
3618 iter_info *iter;
3620 /* Initialize the mask index outside the FORALL nest. */
3621 if (mask_flag && forall_tmp->mask)
3622 gfc_add_modify (outer, forall_tmp->maskindex, gfc_index_zero_node);
3624 iter = forall_tmp->this_loop;
3625 nvar = forall_tmp->nvar;
3626 for (n = 0; n < nvar; n++)
3628 var = iter->var;
3629 start = iter->start;
3630 end = iter->end;
3631 step = iter->step;
3633 exit_label = gfc_build_label_decl (NULL_TREE);
3634 TREE_USED (exit_label) = 1;
3636 /* The loop counter. */
3637 count = gfc_create_var (TREE_TYPE (var), "count");
3639 /* The body of the loop. */
3640 gfc_init_block (&block);
3642 /* The exit condition. */
3643 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
3644 count, build_int_cst (TREE_TYPE (count), 0));
3646 /* PR 83064 means that we cannot use annot_expr_parallel_kind until
3647 the autoparallelizer can hande this. */
3648 if (forall_tmp->do_concurrent)
3649 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
3650 build_int_cst (integer_type_node,
3651 annot_expr_ivdep_kind),
3652 integer_zero_node);
3654 tmp = build1_v (GOTO_EXPR, exit_label);
3655 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3656 cond, tmp, build_empty_stmt (input_location));
3657 gfc_add_expr_to_block (&block, tmp);
3659 /* The main loop body. */
3660 gfc_add_expr_to_block (&block, body);
3662 /* Increment the loop variable. */
3663 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var,
3664 step);
3665 gfc_add_modify (&block, var, tmp);
3667 /* Advance to the next mask element. Only do this for the
3668 innermost loop. */
3669 if (n == 0 && mask_flag && forall_tmp->mask)
3671 tree maskindex = forall_tmp->maskindex;
3672 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3673 maskindex, gfc_index_one_node);
3674 gfc_add_modify (&block, maskindex, tmp);
3677 /* Decrement the loop counter. */
3678 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), count,
3679 build_int_cst (TREE_TYPE (var), 1));
3680 gfc_add_modify (&block, count, tmp);
3682 body = gfc_finish_block (&block);
3684 /* Loop var initialization. */
3685 gfc_init_block (&block);
3686 gfc_add_modify (&block, var, start);
3689 /* Initialize the loop counter. */
3690 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), step,
3691 start);
3692 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), end,
3693 tmp);
3694 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (var),
3695 tmp, step);
3696 gfc_add_modify (&block, count, tmp);
3698 /* The loop expression. */
3699 tmp = build1_v (LOOP_EXPR, body);
3700 gfc_add_expr_to_block (&block, tmp);
3702 /* The exit label. */
3703 tmp = build1_v (LABEL_EXPR, exit_label);
3704 gfc_add_expr_to_block (&block, tmp);
3706 body = gfc_finish_block (&block);
3707 iter = iter->next;
3709 return body;
3713 /* Generate the body and loops according to MASK_FLAG. If MASK_FLAG
3714 is nonzero, the body is controlled by all masks in the forall nest.
3715 Otherwise, the innermost loop is not controlled by it's mask. This
3716 is used for initializing that mask. */
3718 static tree
3719 gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
3720 int mask_flag)
3722 tree tmp;
3723 stmtblock_t header;
3724 forall_info *forall_tmp;
3725 tree mask, maskindex;
3727 gfc_start_block (&header);
3729 forall_tmp = nested_forall_info;
3730 while (forall_tmp != NULL)
3732 /* Generate body with masks' control. */
3733 if (mask_flag)
3735 mask = forall_tmp->mask;
3736 maskindex = forall_tmp->maskindex;
3738 /* If a mask was specified make the assignment conditional. */
3739 if (mask)
3741 tmp = gfc_build_array_ref (mask, maskindex, NULL);
3742 body = build3_v (COND_EXPR, tmp, body,
3743 build_empty_stmt (input_location));
3746 body = gfc_trans_forall_loop (forall_tmp, body, mask_flag, &header);
3747 forall_tmp = forall_tmp->prev_nest;
3748 mask_flag = 1;
3751 gfc_add_expr_to_block (&header, body);
3752 return gfc_finish_block (&header);
3756 /* Allocate data for holding a temporary array. Returns either a local
3757 temporary array or a pointer variable. */
3759 static tree
3760 gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
3761 tree elem_type)
3763 tree tmpvar;
3764 tree type;
3765 tree tmp;
3767 if (INTEGER_CST_P (size))
3768 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3769 size, gfc_index_one_node);
3770 else
3771 tmp = NULL_TREE;
3773 type = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
3774 type = build_array_type (elem_type, type);
3775 if (gfc_can_put_var_on_stack (bytesize) && INTEGER_CST_P (size))
3777 tmpvar = gfc_create_var (type, "temp");
3778 *pdata = NULL_TREE;
3780 else
3782 tmpvar = gfc_create_var (build_pointer_type (type), "temp");
3783 *pdata = convert (pvoid_type_node, tmpvar);
3785 tmp = gfc_call_malloc (pblock, TREE_TYPE (tmpvar), bytesize);
3786 gfc_add_modify (pblock, tmpvar, tmp);
3788 return tmpvar;
3792 /* Generate codes to copy the temporary to the actual lhs. */
3794 static tree
3795 generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
3796 tree count1,
3797 gfc_ss *lss, gfc_ss *rss,
3798 tree wheremask, bool invert)
3800 stmtblock_t block, body1;
3801 gfc_loopinfo loop;
3802 gfc_se lse;
3803 gfc_se rse;
3804 tree tmp;
3805 tree wheremaskexpr;
3807 (void) rss; /* TODO: unused. */
3809 gfc_start_block (&block);
3811 gfc_init_se (&rse, NULL);
3812 gfc_init_se (&lse, NULL);
3814 if (lss == gfc_ss_terminator)
3816 gfc_init_block (&body1);
3817 gfc_conv_expr (&lse, expr);
3818 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3820 else
3822 /* Initialize the loop. */
3823 gfc_init_loopinfo (&loop);
3825 /* We may need LSS to determine the shape of the expression. */
3826 gfc_add_ss_to_loop (&loop, lss);
3828 gfc_conv_ss_startstride (&loop);
3829 gfc_conv_loop_setup (&loop, &expr->where);
3831 gfc_mark_ss_chain_used (lss, 1);
3832 /* Start the loop body. */
3833 gfc_start_scalarized_body (&loop, &body1);
3835 /* Translate the expression. */
3836 gfc_copy_loopinfo_to_se (&lse, &loop);
3837 lse.ss = lss;
3838 gfc_conv_expr (&lse, expr);
3840 /* Form the expression of the temporary. */
3841 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3844 /* Use the scalar assignment. */
3845 rse.string_length = lse.string_length;
3846 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts,
3847 expr->expr_type == EXPR_VARIABLE, false);
3849 /* Form the mask expression according to the mask tree list. */
3850 if (wheremask)
3852 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3853 if (invert)
3854 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3855 TREE_TYPE (wheremaskexpr),
3856 wheremaskexpr);
3857 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3858 wheremaskexpr, tmp,
3859 build_empty_stmt (input_location));
3862 gfc_add_expr_to_block (&body1, tmp);
3864 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3865 count1, gfc_index_one_node);
3866 gfc_add_modify (&body1, count1, tmp);
3868 if (lss == gfc_ss_terminator)
3869 gfc_add_block_to_block (&block, &body1);
3870 else
3872 /* Increment count3. */
3873 if (count3)
3875 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3876 gfc_array_index_type,
3877 count3, gfc_index_one_node);
3878 gfc_add_modify (&body1, count3, tmp);
3881 /* Generate the copying loops. */
3882 gfc_trans_scalarizing_loops (&loop, &body1);
3884 gfc_add_block_to_block (&block, &loop.pre);
3885 gfc_add_block_to_block (&block, &loop.post);
3887 gfc_cleanup_loop (&loop);
3888 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
3889 as tree nodes in SS may not be valid in different scope. */
3892 tmp = gfc_finish_block (&block);
3893 return tmp;
3897 /* Generate codes to copy rhs to the temporary. TMP1 is the address of
3898 temporary, LSS and RSS are formed in function compute_inner_temp_size(),
3899 and should not be freed. WHEREMASK is the conditional execution mask
3900 whose sense may be inverted by INVERT. */
3902 static tree
3903 generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree count3,
3904 tree count1, gfc_ss *lss, gfc_ss *rss,
3905 tree wheremask, bool invert)
3907 stmtblock_t block, body1;
3908 gfc_loopinfo loop;
3909 gfc_se lse;
3910 gfc_se rse;
3911 tree tmp;
3912 tree wheremaskexpr;
3914 gfc_start_block (&block);
3916 gfc_init_se (&rse, NULL);
3917 gfc_init_se (&lse, NULL);
3919 if (lss == gfc_ss_terminator)
3921 gfc_init_block (&body1);
3922 gfc_conv_expr (&rse, expr2);
3923 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3925 else
3927 /* Initialize the loop. */
3928 gfc_init_loopinfo (&loop);
3930 /* We may need LSS to determine the shape of the expression. */
3931 gfc_add_ss_to_loop (&loop, lss);
3932 gfc_add_ss_to_loop (&loop, rss);
3934 gfc_conv_ss_startstride (&loop);
3935 gfc_conv_loop_setup (&loop, &expr2->where);
3937 gfc_mark_ss_chain_used (rss, 1);
3938 /* Start the loop body. */
3939 gfc_start_scalarized_body (&loop, &body1);
3941 /* Translate the expression. */
3942 gfc_copy_loopinfo_to_se (&rse, &loop);
3943 rse.ss = rss;
3944 gfc_conv_expr (&rse, expr2);
3946 /* Form the expression of the temporary. */
3947 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3950 /* Use the scalar assignment. */
3951 lse.string_length = rse.string_length;
3952 tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts,
3953 expr2->expr_type == EXPR_VARIABLE, false);
3955 /* Form the mask expression according to the mask tree list. */
3956 if (wheremask)
3958 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3959 if (invert)
3960 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3961 TREE_TYPE (wheremaskexpr),
3962 wheremaskexpr);
3963 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3964 wheremaskexpr, tmp,
3965 build_empty_stmt (input_location));
3968 gfc_add_expr_to_block (&body1, tmp);
3970 if (lss == gfc_ss_terminator)
3972 gfc_add_block_to_block (&block, &body1);
3974 /* Increment count1. */
3975 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3976 count1, gfc_index_one_node);
3977 gfc_add_modify (&block, count1, tmp);
3979 else
3981 /* Increment count1. */
3982 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3983 count1, gfc_index_one_node);
3984 gfc_add_modify (&body1, count1, tmp);
3986 /* Increment count3. */
3987 if (count3)
3989 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3990 gfc_array_index_type,
3991 count3, gfc_index_one_node);
3992 gfc_add_modify (&body1, count3, tmp);
3995 /* Generate the copying loops. */
3996 gfc_trans_scalarizing_loops (&loop, &body1);
3998 gfc_add_block_to_block (&block, &loop.pre);
3999 gfc_add_block_to_block (&block, &loop.post);
4001 gfc_cleanup_loop (&loop);
4002 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
4003 as tree nodes in SS may not be valid in different scope. */
4006 tmp = gfc_finish_block (&block);
4007 return tmp;
4011 /* Calculate the size of temporary needed in the assignment inside forall.
4012 LSS and RSS are filled in this function. */
4014 static tree
4015 compute_inner_temp_size (gfc_expr *expr1, gfc_expr *expr2,
4016 stmtblock_t * pblock,
4017 gfc_ss **lss, gfc_ss **rss)
4019 gfc_loopinfo loop;
4020 tree size;
4021 int i;
4022 int save_flag;
4023 tree tmp;
4025 *lss = gfc_walk_expr (expr1);
4026 *rss = NULL;
4028 size = gfc_index_one_node;
4029 if (*lss != gfc_ss_terminator)
4031 gfc_init_loopinfo (&loop);
4033 /* Walk the RHS of the expression. */
4034 *rss = gfc_walk_expr (expr2);
4035 if (*rss == gfc_ss_terminator)
4036 /* The rhs is scalar. Add a ss for the expression. */
4037 *rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
4039 /* Associate the SS with the loop. */
4040 gfc_add_ss_to_loop (&loop, *lss);
4041 /* We don't actually need to add the rhs at this point, but it might
4042 make guessing the loop bounds a bit easier. */
4043 gfc_add_ss_to_loop (&loop, *rss);
4045 /* We only want the shape of the expression, not rest of the junk
4046 generated by the scalarizer. */
4047 loop.array_parameter = 1;
4049 /* Calculate the bounds of the scalarization. */
4050 save_flag = gfc_option.rtcheck;
4051 gfc_option.rtcheck &= ~GFC_RTCHECK_BOUNDS;
4052 gfc_conv_ss_startstride (&loop);
4053 gfc_option.rtcheck = save_flag;
4054 gfc_conv_loop_setup (&loop, &expr2->where);
4056 /* Figure out how many elements we need. */
4057 for (i = 0; i < loop.dimen; i++)
4059 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4060 gfc_array_index_type,
4061 gfc_index_one_node, loop.from[i]);
4062 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4063 gfc_array_index_type, tmp, loop.to[i]);
4064 size = fold_build2_loc (input_location, MULT_EXPR,
4065 gfc_array_index_type, size, tmp);
4067 gfc_add_block_to_block (pblock, &loop.pre);
4068 size = gfc_evaluate_now (size, pblock);
4069 gfc_add_block_to_block (pblock, &loop.post);
4071 /* TODO: write a function that cleans up a loopinfo without freeing
4072 the SS chains. Currently a NOP. */
4075 return size;
4079 /* Calculate the overall iterator number of the nested forall construct.
4080 This routine actually calculates the number of times the body of the
4081 nested forall specified by NESTED_FORALL_INFO is executed and multiplies
4082 that by the expression INNER_SIZE. The BLOCK argument specifies the
4083 block in which to calculate the result, and the optional INNER_SIZE_BODY
4084 argument contains any statements that need to executed (inside the loop)
4085 to initialize or calculate INNER_SIZE. */
4087 static tree
4088 compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
4089 stmtblock_t *inner_size_body, stmtblock_t *block)
4091 forall_info *forall_tmp = nested_forall_info;
4092 tree tmp, number;
4093 stmtblock_t body;
4095 /* We can eliminate the innermost unconditional loops with constant
4096 array bounds. */
4097 if (INTEGER_CST_P (inner_size))
4099 while (forall_tmp
4100 && !forall_tmp->mask
4101 && INTEGER_CST_P (forall_tmp->size))
4103 inner_size = fold_build2_loc (input_location, MULT_EXPR,
4104 gfc_array_index_type,
4105 inner_size, forall_tmp->size);
4106 forall_tmp = forall_tmp->prev_nest;
4109 /* If there are no loops left, we have our constant result. */
4110 if (!forall_tmp)
4111 return inner_size;
4114 /* Otherwise, create a temporary variable to compute the result. */
4115 number = gfc_create_var (gfc_array_index_type, "num");
4116 gfc_add_modify (block, number, gfc_index_zero_node);
4118 gfc_start_block (&body);
4119 if (inner_size_body)
4120 gfc_add_block_to_block (&body, inner_size_body);
4121 if (forall_tmp)
4122 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4123 gfc_array_index_type, number, inner_size);
4124 else
4125 tmp = inner_size;
4126 gfc_add_modify (&body, number, tmp);
4127 tmp = gfc_finish_block (&body);
4129 /* Generate loops. */
4130 if (forall_tmp != NULL)
4131 tmp = gfc_trans_nested_forall_loop (forall_tmp, tmp, 1);
4133 gfc_add_expr_to_block (block, tmp);
4135 return number;
4139 /* Allocate temporary for forall construct. SIZE is the size of temporary
4140 needed. PTEMP1 is returned for space free. */
4142 static tree
4143 allocate_temp_for_forall_nest_1 (tree type, tree size, stmtblock_t * block,
4144 tree * ptemp1)
4146 tree bytesize;
4147 tree unit;
4148 tree tmp;
4150 unit = fold_convert (gfc_array_index_type, TYPE_SIZE_UNIT (type));
4151 if (!integer_onep (unit))
4152 bytesize = fold_build2_loc (input_location, MULT_EXPR,
4153 gfc_array_index_type, size, unit);
4154 else
4155 bytesize = size;
4157 *ptemp1 = NULL;
4158 tmp = gfc_do_allocate (bytesize, size, ptemp1, block, type);
4160 if (*ptemp1)
4161 tmp = build_fold_indirect_ref_loc (input_location, tmp);
4162 return tmp;
4166 /* Allocate temporary for forall construct according to the information in
4167 nested_forall_info. INNER_SIZE is the size of temporary needed in the
4168 assignment inside forall. PTEMP1 is returned for space free. */
4170 static tree
4171 allocate_temp_for_forall_nest (forall_info * nested_forall_info, tree type,
4172 tree inner_size, stmtblock_t * inner_size_body,
4173 stmtblock_t * block, tree * ptemp1)
4175 tree size;
4177 /* Calculate the total size of temporary needed in forall construct. */
4178 size = compute_overall_iter_number (nested_forall_info, inner_size,
4179 inner_size_body, block);
4181 return allocate_temp_for_forall_nest_1 (type, size, block, ptemp1);
4185 /* Handle assignments inside forall which need temporary.
4187 forall (i=start:end:stride; maskexpr)
4188 e<i> = f<i>
4189 end forall
4190 (where e,f<i> are arbitrary expressions possibly involving i
4191 and there is a dependency between e<i> and f<i>)
4192 Translates to:
4193 masktmp(:) = maskexpr(:)
4195 maskindex = 0;
4196 count1 = 0;
4197 num = 0;
4198 for (i = start; i <= end; i += stride)
4199 num += SIZE (f<i>)
4200 count1 = 0;
4201 ALLOCATE (tmp(num))
4202 for (i = start; i <= end; i += stride)
4204 if (masktmp[maskindex++])
4205 tmp[count1++] = f<i>
4207 maskindex = 0;
4208 count1 = 0;
4209 for (i = start; i <= end; i += stride)
4211 if (masktmp[maskindex++])
4212 e<i> = tmp[count1++]
4214 DEALLOCATE (tmp)
4216 static void
4217 gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
4218 tree wheremask, bool invert,
4219 forall_info * nested_forall_info,
4220 stmtblock_t * block)
4222 tree type;
4223 tree inner_size;
4224 gfc_ss *lss, *rss;
4225 tree count, count1;
4226 tree tmp, tmp1;
4227 tree ptemp1;
4228 stmtblock_t inner_size_body;
4230 /* Create vars. count1 is the current iterator number of the nested
4231 forall. */
4232 count1 = gfc_create_var (gfc_array_index_type, "count1");
4234 /* Count is the wheremask index. */
4235 if (wheremask)
4237 count = gfc_create_var (gfc_array_index_type, "count");
4238 gfc_add_modify (block, count, gfc_index_zero_node);
4240 else
4241 count = NULL;
4243 /* Initialize count1. */
4244 gfc_add_modify (block, count1, gfc_index_zero_node);
4246 /* Calculate the size of temporary needed in the assignment. Return loop, lss
4247 and rss which are used in function generate_loop_for_rhs_to_temp(). */
4248 /* The type of LHS. Used in function allocate_temp_for_forall_nest */
4249 if (expr1->ts.type == BT_CHARACTER)
4251 type = NULL;
4252 if (expr1->ref && expr1->ref->type == REF_SUBSTRING)
4254 gfc_se ssse;
4255 gfc_init_se (&ssse, NULL);
4256 gfc_conv_expr (&ssse, expr1);
4257 type = gfc_get_character_type_len (gfc_default_character_kind,
4258 ssse.string_length);
4260 else
4262 if (!expr1->ts.u.cl->backend_decl)
4264 gfc_se tse;
4265 gcc_assert (expr1->ts.u.cl->length);
4266 gfc_init_se (&tse, NULL);
4267 gfc_conv_expr (&tse, expr1->ts.u.cl->length);
4268 expr1->ts.u.cl->backend_decl = tse.expr;
4270 type = gfc_get_character_type_len (gfc_default_character_kind,
4271 expr1->ts.u.cl->backend_decl);
4274 else
4275 type = gfc_typenode_for_spec (&expr1->ts);
4277 gfc_init_block (&inner_size_body);
4278 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
4279 &lss, &rss);
4281 /* Allocate temporary for nested forall construct according to the
4282 information in nested_forall_info and inner_size. */
4283 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type, inner_size,
4284 &inner_size_body, block, &ptemp1);
4286 /* Generate codes to copy rhs to the temporary . */
4287 tmp = generate_loop_for_rhs_to_temp (expr2, tmp1, count, count1, lss, rss,
4288 wheremask, invert);
4290 /* Generate body and loops according to the information in
4291 nested_forall_info. */
4292 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4293 gfc_add_expr_to_block (block, tmp);
4295 /* Reset count1. */
4296 gfc_add_modify (block, count1, gfc_index_zero_node);
4298 /* Reset count. */
4299 if (wheremask)
4300 gfc_add_modify (block, count, gfc_index_zero_node);
4302 /* TODO: Second call to compute_inner_temp_size to initialize lss and
4303 rss; there must be a better way. */
4304 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
4305 &lss, &rss);
4307 /* Generate codes to copy the temporary to lhs. */
4308 tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, count, count1,
4309 lss, rss,
4310 wheremask, invert);
4312 /* Generate body and loops according to the information in
4313 nested_forall_info. */
4314 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4315 gfc_add_expr_to_block (block, tmp);
4317 if (ptemp1)
4319 /* Free the temporary. */
4320 tmp = gfc_call_free (ptemp1);
4321 gfc_add_expr_to_block (block, tmp);
4326 /* Translate pointer assignment inside FORALL which need temporary. */
4328 static void
4329 gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
4330 forall_info * nested_forall_info,
4331 stmtblock_t * block)
4333 tree type;
4334 tree inner_size;
4335 gfc_ss *lss, *rss;
4336 gfc_se lse;
4337 gfc_se rse;
4338 gfc_array_info *info;
4339 gfc_loopinfo loop;
4340 tree desc;
4341 tree parm;
4342 tree parmtype;
4343 stmtblock_t body;
4344 tree count;
4345 tree tmp, tmp1, ptemp1;
4347 count = gfc_create_var (gfc_array_index_type, "count");
4348 gfc_add_modify (block, count, gfc_index_zero_node);
4350 inner_size = gfc_index_one_node;
4351 lss = gfc_walk_expr (expr1);
4352 rss = gfc_walk_expr (expr2);
4353 if (lss == gfc_ss_terminator)
4355 type = gfc_typenode_for_spec (&expr1->ts);
4356 type = build_pointer_type (type);
4358 /* Allocate temporary for nested forall construct according to the
4359 information in nested_forall_info and inner_size. */
4360 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type,
4361 inner_size, NULL, block, &ptemp1);
4362 gfc_start_block (&body);
4363 gfc_init_se (&lse, NULL);
4364 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
4365 gfc_init_se (&rse, NULL);
4366 rse.want_pointer = 1;
4367 gfc_conv_expr (&rse, expr2);
4368 gfc_add_block_to_block (&body, &rse.pre);
4369 gfc_add_modify (&body, lse.expr,
4370 fold_convert (TREE_TYPE (lse.expr), rse.expr));
4371 gfc_add_block_to_block (&body, &rse.post);
4373 /* Increment count. */
4374 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4375 count, gfc_index_one_node);
4376 gfc_add_modify (&body, count, tmp);
4378 tmp = gfc_finish_block (&body);
4380 /* Generate body and loops according to the information in
4381 nested_forall_info. */
4382 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4383 gfc_add_expr_to_block (block, tmp);
4385 /* Reset count. */
4386 gfc_add_modify (block, count, gfc_index_zero_node);
4388 gfc_start_block (&body);
4389 gfc_init_se (&lse, NULL);
4390 gfc_init_se (&rse, NULL);
4391 rse.expr = gfc_build_array_ref (tmp1, count, NULL);
4392 lse.want_pointer = 1;
4393 gfc_conv_expr (&lse, expr1);
4394 gfc_add_block_to_block (&body, &lse.pre);
4395 gfc_add_modify (&body, lse.expr, rse.expr);
4396 gfc_add_block_to_block (&body, &lse.post);
4397 /* Increment count. */
4398 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4399 count, gfc_index_one_node);
4400 gfc_add_modify (&body, count, tmp);
4401 tmp = gfc_finish_block (&body);
4403 /* Generate body and loops according to the information in
4404 nested_forall_info. */
4405 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4406 gfc_add_expr_to_block (block, tmp);
4408 else
4410 gfc_init_loopinfo (&loop);
4412 /* Associate the SS with the loop. */
4413 gfc_add_ss_to_loop (&loop, rss);
4415 /* Setup the scalarizing loops and bounds. */
4416 gfc_conv_ss_startstride (&loop);
4418 gfc_conv_loop_setup (&loop, &expr2->where);
4420 info = &rss->info->data.array;
4421 desc = info->descriptor;
4423 /* Make a new descriptor. */
4424 parmtype = gfc_get_element_type (TREE_TYPE (desc));
4425 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0,
4426 loop.from, loop.to, 1,
4427 GFC_ARRAY_UNKNOWN, true);
4429 /* Allocate temporary for nested forall construct. */
4430 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
4431 inner_size, NULL, block, &ptemp1);
4432 gfc_start_block (&body);
4433 gfc_init_se (&lse, NULL);
4434 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
4435 lse.direct_byref = 1;
4436 gfc_conv_expr_descriptor (&lse, expr2);
4438 gfc_add_block_to_block (&body, &lse.pre);
4439 gfc_add_block_to_block (&body, &lse.post);
4441 /* Increment count. */
4442 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4443 count, gfc_index_one_node);
4444 gfc_add_modify (&body, count, tmp);
4446 tmp = gfc_finish_block (&body);
4448 /* Generate body and loops according to the information in
4449 nested_forall_info. */
4450 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4451 gfc_add_expr_to_block (block, tmp);
4453 /* Reset count. */
4454 gfc_add_modify (block, count, gfc_index_zero_node);
4456 parm = gfc_build_array_ref (tmp1, count, NULL);
4457 gfc_init_se (&lse, NULL);
4458 gfc_conv_expr_descriptor (&lse, expr1);
4459 gfc_add_modify (&lse.pre, lse.expr, parm);
4460 gfc_start_block (&body);
4461 gfc_add_block_to_block (&body, &lse.pre);
4462 gfc_add_block_to_block (&body, &lse.post);
4464 /* Increment count. */
4465 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4466 count, gfc_index_one_node);
4467 gfc_add_modify (&body, count, tmp);
4469 tmp = gfc_finish_block (&body);
4471 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4472 gfc_add_expr_to_block (block, tmp);
4474 /* Free the temporary. */
4475 if (ptemp1)
4477 tmp = gfc_call_free (ptemp1);
4478 gfc_add_expr_to_block (block, tmp);
4483 /* FORALL and WHERE statements are really nasty, especially when you nest
4484 them. All the rhs of a forall assignment must be evaluated before the
4485 actual assignments are performed. Presumably this also applies to all the
4486 assignments in an inner where statement. */
4488 /* Generate code for a FORALL statement. Any temporaries are allocated as a
4489 linear array, relying on the fact that we process in the same order in all
4490 loops.
4492 forall (i=start:end:stride; maskexpr)
4493 e<i> = f<i>
4494 g<i> = h<i>
4495 end forall
4496 (where e,f,g,h<i> are arbitrary expressions possibly involving i)
4497 Translates to:
4498 count = ((end + 1 - start) / stride)
4499 masktmp(:) = maskexpr(:)
4501 maskindex = 0;
4502 for (i = start; i <= end; i += stride)
4504 if (masktmp[maskindex++])
4505 e<i> = f<i>
4507 maskindex = 0;
4508 for (i = start; i <= end; i += stride)
4510 if (masktmp[maskindex++])
4511 g<i> = h<i>
4514 Note that this code only works when there are no dependencies.
4515 Forall loop with array assignments and data dependencies are a real pain,
4516 because the size of the temporary cannot always be determined before the
4517 loop is executed. This problem is compounded by the presence of nested
4518 FORALL constructs.
4521 static tree
4522 gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
4524 stmtblock_t pre;
4525 stmtblock_t post;
4526 stmtblock_t block;
4527 stmtblock_t body;
4528 tree *var;
4529 tree *start;
4530 tree *end;
4531 tree *step;
4532 gfc_expr **varexpr;
4533 tree tmp;
4534 tree assign;
4535 tree size;
4536 tree maskindex;
4537 tree mask;
4538 tree pmask;
4539 tree cycle_label = NULL_TREE;
4540 int n;
4541 int nvar;
4542 int need_temp;
4543 gfc_forall_iterator *fa;
4544 gfc_se se;
4545 gfc_code *c;
4546 gfc_saved_var *saved_vars;
4547 iter_info *this_forall;
4548 forall_info *info;
4549 bool need_mask;
4551 /* Do nothing if the mask is false. */
4552 if (code->expr1
4553 && code->expr1->expr_type == EXPR_CONSTANT
4554 && !code->expr1->value.logical)
4555 return build_empty_stmt (input_location);
4557 n = 0;
4558 /* Count the FORALL index number. */
4559 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
4560 n++;
4561 nvar = n;
4563 /* Allocate the space for var, start, end, step, varexpr. */
4564 var = XCNEWVEC (tree, nvar);
4565 start = XCNEWVEC (tree, nvar);
4566 end = XCNEWVEC (tree, nvar);
4567 step = XCNEWVEC (tree, nvar);
4568 varexpr = XCNEWVEC (gfc_expr *, nvar);
4569 saved_vars = XCNEWVEC (gfc_saved_var, nvar);
4571 /* Allocate the space for info. */
4572 info = XCNEW (forall_info);
4574 gfc_start_block (&pre);
4575 gfc_init_block (&post);
4576 gfc_init_block (&block);
4578 n = 0;
4579 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
4581 gfc_symbol *sym = fa->var->symtree->n.sym;
4583 /* Allocate space for this_forall. */
4584 this_forall = XCNEW (iter_info);
4586 /* Create a temporary variable for the FORALL index. */
4587 tmp = gfc_typenode_for_spec (&sym->ts);
4588 var[n] = gfc_create_var (tmp, sym->name);
4589 gfc_shadow_sym (sym, var[n], &saved_vars[n]);
4591 /* Record it in this_forall. */
4592 this_forall->var = var[n];
4594 /* Replace the index symbol's backend_decl with the temporary decl. */
4595 sym->backend_decl = var[n];
4597 /* Work out the start, end and stride for the loop. */
4598 gfc_init_se (&se, NULL);
4599 gfc_conv_expr_val (&se, fa->start);
4600 /* Record it in this_forall. */
4601 this_forall->start = se.expr;
4602 gfc_add_block_to_block (&block, &se.pre);
4603 start[n] = se.expr;
4605 gfc_init_se (&se, NULL);
4606 gfc_conv_expr_val (&se, fa->end);
4607 /* Record it in this_forall. */
4608 this_forall->end = se.expr;
4609 gfc_make_safe_expr (&se);
4610 gfc_add_block_to_block (&block, &se.pre);
4611 end[n] = se.expr;
4613 gfc_init_se (&se, NULL);
4614 gfc_conv_expr_val (&se, fa->stride);
4615 /* Record it in this_forall. */
4616 this_forall->step = se.expr;
4617 gfc_make_safe_expr (&se);
4618 gfc_add_block_to_block (&block, &se.pre);
4619 step[n] = se.expr;
4621 /* Set the NEXT field of this_forall to NULL. */
4622 this_forall->next = NULL;
4623 /* Link this_forall to the info construct. */
4624 if (info->this_loop)
4626 iter_info *iter_tmp = info->this_loop;
4627 while (iter_tmp->next != NULL)
4628 iter_tmp = iter_tmp->next;
4629 iter_tmp->next = this_forall;
4631 else
4632 info->this_loop = this_forall;
4634 n++;
4636 nvar = n;
4638 /* Calculate the size needed for the current forall level. */
4639 size = gfc_index_one_node;
4640 for (n = 0; n < nvar; n++)
4642 /* size = (end + step - start) / step. */
4643 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (start[n]),
4644 step[n], start[n]);
4645 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (end[n]),
4646 end[n], tmp);
4647 tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, TREE_TYPE (tmp),
4648 tmp, step[n]);
4649 tmp = convert (gfc_array_index_type, tmp);
4651 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4652 size, tmp);
4655 /* Record the nvar and size of current forall level. */
4656 info->nvar = nvar;
4657 info->size = size;
4659 if (code->expr1)
4661 /* If the mask is .true., consider the FORALL unconditional. */
4662 if (code->expr1->expr_type == EXPR_CONSTANT
4663 && code->expr1->value.logical)
4664 need_mask = false;
4665 else
4666 need_mask = true;
4668 else
4669 need_mask = false;
4671 /* First we need to allocate the mask. */
4672 if (need_mask)
4674 /* As the mask array can be very big, prefer compact boolean types. */
4675 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4676 mask = allocate_temp_for_forall_nest (nested_forall_info, mask_type,
4677 size, NULL, &block, &pmask);
4678 maskindex = gfc_create_var_np (gfc_array_index_type, "mi");
4680 /* Record them in the info structure. */
4681 info->maskindex = maskindex;
4682 info->mask = mask;
4684 else
4686 /* No mask was specified. */
4687 maskindex = NULL_TREE;
4688 mask = pmask = NULL_TREE;
4691 /* Link the current forall level to nested_forall_info. */
4692 info->prev_nest = nested_forall_info;
4693 nested_forall_info = info;
4695 /* Copy the mask into a temporary variable if required.
4696 For now we assume a mask temporary is needed. */
4697 if (need_mask)
4699 /* As the mask array can be very big, prefer compact boolean types. */
4700 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4702 gfc_add_modify (&block, maskindex, gfc_index_zero_node);
4704 /* Start of mask assignment loop body. */
4705 gfc_start_block (&body);
4707 /* Evaluate the mask expression. */
4708 gfc_init_se (&se, NULL);
4709 gfc_conv_expr_val (&se, code->expr1);
4710 gfc_add_block_to_block (&body, &se.pre);
4712 /* Store the mask. */
4713 se.expr = convert (mask_type, se.expr);
4715 tmp = gfc_build_array_ref (mask, maskindex, NULL);
4716 gfc_add_modify (&body, tmp, se.expr);
4718 /* Advance to the next mask element. */
4719 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4720 maskindex, gfc_index_one_node);
4721 gfc_add_modify (&body, maskindex, tmp);
4723 /* Generate the loops. */
4724 tmp = gfc_finish_block (&body);
4725 tmp = gfc_trans_nested_forall_loop (info, tmp, 0);
4726 gfc_add_expr_to_block (&block, tmp);
4729 if (code->op == EXEC_DO_CONCURRENT)
4731 gfc_init_block (&body);
4732 cycle_label = gfc_build_label_decl (NULL_TREE);
4733 code->cycle_label = cycle_label;
4734 tmp = gfc_trans_code (code->block->next);
4735 gfc_add_expr_to_block (&body, tmp);
4737 if (TREE_USED (cycle_label))
4739 tmp = build1_v (LABEL_EXPR, cycle_label);
4740 gfc_add_expr_to_block (&body, tmp);
4743 tmp = gfc_finish_block (&body);
4744 nested_forall_info->do_concurrent = true;
4745 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4746 gfc_add_expr_to_block (&block, tmp);
4747 goto done;
4750 c = code->block->next;
4752 /* TODO: loop merging in FORALL statements. */
4753 /* Now that we've got a copy of the mask, generate the assignment loops. */
4754 while (c)
4756 switch (c->op)
4758 case EXEC_ASSIGN:
4759 /* A scalar or array assignment. DO the simple check for
4760 lhs to rhs dependencies. These make a temporary for the
4761 rhs and form a second forall block to copy to variable. */
4762 need_temp = check_forall_dependencies(c, &pre, &post);
4764 /* Temporaries due to array assignment data dependencies introduce
4765 no end of problems. */
4766 if (need_temp || flag_test_forall_temp)
4767 gfc_trans_assign_need_temp (c->expr1, c->expr2, NULL, false,
4768 nested_forall_info, &block);
4769 else
4771 /* Use the normal assignment copying routines. */
4772 assign = gfc_trans_assignment (c->expr1, c->expr2, false, true);
4774 /* Generate body and loops. */
4775 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4776 assign, 1);
4777 gfc_add_expr_to_block (&block, tmp);
4780 /* Cleanup any temporary symtrees that have been made to deal
4781 with dependencies. */
4782 if (new_symtree)
4783 cleanup_forall_symtrees (c);
4785 break;
4787 case EXEC_WHERE:
4788 /* Translate WHERE or WHERE construct nested in FORALL. */
4789 gfc_trans_where_2 (c, NULL, false, nested_forall_info, &block);
4790 break;
4792 /* Pointer assignment inside FORALL. */
4793 case EXEC_POINTER_ASSIGN:
4794 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
4795 /* Avoid cases where a temporary would never be needed and where
4796 the temp code is guaranteed to fail. */
4797 if (need_temp
4798 || (flag_test_forall_temp
4799 && c->expr2->expr_type != EXPR_CONSTANT
4800 && c->expr2->expr_type != EXPR_NULL))
4801 gfc_trans_pointer_assign_need_temp (c->expr1, c->expr2,
4802 nested_forall_info, &block);
4803 else
4805 /* Use the normal assignment copying routines. */
4806 assign = gfc_trans_pointer_assignment (c->expr1, c->expr2);
4808 /* Generate body and loops. */
4809 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4810 assign, 1);
4811 gfc_add_expr_to_block (&block, tmp);
4813 break;
4815 case EXEC_FORALL:
4816 tmp = gfc_trans_forall_1 (c, nested_forall_info);
4817 gfc_add_expr_to_block (&block, tmp);
4818 break;
4820 /* Explicit subroutine calls are prevented by the frontend but interface
4821 assignments can legitimately produce them. */
4822 case EXEC_ASSIGN_CALL:
4823 assign = gfc_trans_call (c, true, NULL_TREE, NULL_TREE, false);
4824 tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign, 1);
4825 gfc_add_expr_to_block (&block, tmp);
4826 break;
4828 default:
4829 gcc_unreachable ();
4832 c = c->next;
4835 done:
4836 /* Restore the original index variables. */
4837 for (fa = code->ext.forall_iterator, n = 0; fa; fa = fa->next, n++)
4838 gfc_restore_sym (fa->var->symtree->n.sym, &saved_vars[n]);
4840 /* Free the space for var, start, end, step, varexpr. */
4841 free (var);
4842 free (start);
4843 free (end);
4844 free (step);
4845 free (varexpr);
4846 free (saved_vars);
4848 for (this_forall = info->this_loop; this_forall;)
4850 iter_info *next = this_forall->next;
4851 free (this_forall);
4852 this_forall = next;
4855 /* Free the space for this forall_info. */
4856 free (info);
4858 if (pmask)
4860 /* Free the temporary for the mask. */
4861 tmp = gfc_call_free (pmask);
4862 gfc_add_expr_to_block (&block, tmp);
4864 if (maskindex)
4865 pushdecl (maskindex);
4867 gfc_add_block_to_block (&pre, &block);
4868 gfc_add_block_to_block (&pre, &post);
4870 return gfc_finish_block (&pre);
4874 /* Translate the FORALL statement or construct. */
4876 tree gfc_trans_forall (gfc_code * code)
4878 return gfc_trans_forall_1 (code, NULL);
4882 /* Translate the DO CONCURRENT construct. */
4884 tree gfc_trans_do_concurrent (gfc_code * code)
4886 return gfc_trans_forall_1 (code, NULL);
4890 /* Evaluate the WHERE mask expression, copy its value to a temporary.
4891 If the WHERE construct is nested in FORALL, compute the overall temporary
4892 needed by the WHERE mask expression multiplied by the iterator number of
4893 the nested forall.
4894 ME is the WHERE mask expression.
4895 MASK is the current execution mask upon input, whose sense may or may
4896 not be inverted as specified by the INVERT argument.
4897 CMASK is the updated execution mask on output, or NULL if not required.
4898 PMASK is the pending execution mask on output, or NULL if not required.
4899 BLOCK is the block in which to place the condition evaluation loops. */
4901 static void
4902 gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
4903 tree mask, bool invert, tree cmask, tree pmask,
4904 tree mask_type, stmtblock_t * block)
4906 tree tmp, tmp1;
4907 gfc_ss *lss, *rss;
4908 gfc_loopinfo loop;
4909 stmtblock_t body, body1;
4910 tree count, cond, mtmp;
4911 gfc_se lse, rse;
4913 gfc_init_loopinfo (&loop);
4915 lss = gfc_walk_expr (me);
4916 rss = gfc_walk_expr (me);
4918 /* Variable to index the temporary. */
4919 count = gfc_create_var (gfc_array_index_type, "count");
4920 /* Initialize count. */
4921 gfc_add_modify (block, count, gfc_index_zero_node);
4923 gfc_start_block (&body);
4925 gfc_init_se (&rse, NULL);
4926 gfc_init_se (&lse, NULL);
4928 if (lss == gfc_ss_terminator)
4930 gfc_init_block (&body1);
4932 else
4934 /* Initialize the loop. */
4935 gfc_init_loopinfo (&loop);
4937 /* We may need LSS to determine the shape of the expression. */
4938 gfc_add_ss_to_loop (&loop, lss);
4939 gfc_add_ss_to_loop (&loop, rss);
4941 gfc_conv_ss_startstride (&loop);
4942 gfc_conv_loop_setup (&loop, &me->where);
4944 gfc_mark_ss_chain_used (rss, 1);
4945 /* Start the loop body. */
4946 gfc_start_scalarized_body (&loop, &body1);
4948 /* Translate the expression. */
4949 gfc_copy_loopinfo_to_se (&rse, &loop);
4950 rse.ss = rss;
4951 gfc_conv_expr (&rse, me);
4954 /* Variable to evaluate mask condition. */
4955 cond = gfc_create_var (mask_type, "cond");
4956 if (mask && (cmask || pmask))
4957 mtmp = gfc_create_var (mask_type, "mask");
4958 else mtmp = NULL_TREE;
4960 gfc_add_block_to_block (&body1, &lse.pre);
4961 gfc_add_block_to_block (&body1, &rse.pre);
4963 gfc_add_modify (&body1, cond, fold_convert (mask_type, rse.expr));
4965 if (mask && (cmask || pmask))
4967 tmp = gfc_build_array_ref (mask, count, NULL);
4968 if (invert)
4969 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, tmp);
4970 gfc_add_modify (&body1, mtmp, tmp);
4973 if (cmask)
4975 tmp1 = gfc_build_array_ref (cmask, count, NULL);
4976 tmp = cond;
4977 if (mask)
4978 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type,
4979 mtmp, tmp);
4980 gfc_add_modify (&body1, tmp1, tmp);
4983 if (pmask)
4985 tmp1 = gfc_build_array_ref (pmask, count, NULL);
4986 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, cond);
4987 if (mask)
4988 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type, mtmp,
4989 tmp);
4990 gfc_add_modify (&body1, tmp1, tmp);
4993 gfc_add_block_to_block (&body1, &lse.post);
4994 gfc_add_block_to_block (&body1, &rse.post);
4996 if (lss == gfc_ss_terminator)
4998 gfc_add_block_to_block (&body, &body1);
5000 else
5002 /* Increment count. */
5003 tmp1 = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5004 count, gfc_index_one_node);
5005 gfc_add_modify (&body1, count, tmp1);
5007 /* Generate the copying loops. */
5008 gfc_trans_scalarizing_loops (&loop, &body1);
5010 gfc_add_block_to_block (&body, &loop.pre);
5011 gfc_add_block_to_block (&body, &loop.post);
5013 gfc_cleanup_loop (&loop);
5014 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
5015 as tree nodes in SS may not be valid in different scope. */
5018 tmp1 = gfc_finish_block (&body);
5019 /* If the WHERE construct is inside FORALL, fill the full temporary. */
5020 if (nested_forall_info != NULL)
5021 tmp1 = gfc_trans_nested_forall_loop (nested_forall_info, tmp1, 1);
5023 gfc_add_expr_to_block (block, tmp1);
5027 /* Translate an assignment statement in a WHERE statement or construct
5028 statement. The MASK expression is used to control which elements
5029 of EXPR1 shall be assigned. The sense of MASK is specified by
5030 INVERT. */
5032 static tree
5033 gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
5034 tree mask, bool invert,
5035 tree count1, tree count2,
5036 gfc_code *cnext)
5038 gfc_se lse;
5039 gfc_se rse;
5040 gfc_ss *lss;
5041 gfc_ss *lss_section;
5042 gfc_ss *rss;
5044 gfc_loopinfo loop;
5045 tree tmp;
5046 stmtblock_t block;
5047 stmtblock_t body;
5048 tree index, maskexpr;
5050 /* A defined assignment. */
5051 if (cnext && cnext->resolved_sym)
5052 return gfc_trans_call (cnext, true, mask, count1, invert);
5054 #if 0
5055 /* TODO: handle this special case.
5056 Special case a single function returning an array. */
5057 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
5059 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
5060 if (tmp)
5061 return tmp;
5063 #endif
5065 /* Assignment of the form lhs = rhs. */
5066 gfc_start_block (&block);
5068 gfc_init_se (&lse, NULL);
5069 gfc_init_se (&rse, NULL);
5071 /* Walk the lhs. */
5072 lss = gfc_walk_expr (expr1);
5073 rss = NULL;
5075 /* In each where-assign-stmt, the mask-expr and the variable being
5076 defined shall be arrays of the same shape. */
5077 gcc_assert (lss != gfc_ss_terminator);
5079 /* The assignment needs scalarization. */
5080 lss_section = lss;
5082 /* Find a non-scalar SS from the lhs. */
5083 while (lss_section != gfc_ss_terminator
5084 && lss_section->info->type != GFC_SS_SECTION)
5085 lss_section = lss_section->next;
5087 gcc_assert (lss_section != gfc_ss_terminator);
5089 /* Initialize the scalarizer. */
5090 gfc_init_loopinfo (&loop);
5092 /* Walk the rhs. */
5093 rss = gfc_walk_expr (expr2);
5094 if (rss == gfc_ss_terminator)
5096 /* The rhs is scalar. Add a ss for the expression. */
5097 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
5098 rss->info->where = 1;
5101 /* Associate the SS with the loop. */
5102 gfc_add_ss_to_loop (&loop, lss);
5103 gfc_add_ss_to_loop (&loop, rss);
5105 /* Calculate the bounds of the scalarization. */
5106 gfc_conv_ss_startstride (&loop);
5108 /* Resolve any data dependencies in the statement. */
5109 gfc_conv_resolve_dependencies (&loop, lss_section, rss);
5111 /* Setup the scalarizing loops. */
5112 gfc_conv_loop_setup (&loop, &expr2->where);
5114 /* Setup the gfc_se structures. */
5115 gfc_copy_loopinfo_to_se (&lse, &loop);
5116 gfc_copy_loopinfo_to_se (&rse, &loop);
5118 rse.ss = rss;
5119 gfc_mark_ss_chain_used (rss, 1);
5120 if (loop.temp_ss == NULL)
5122 lse.ss = lss;
5123 gfc_mark_ss_chain_used (lss, 1);
5125 else
5127 lse.ss = loop.temp_ss;
5128 gfc_mark_ss_chain_used (lss, 3);
5129 gfc_mark_ss_chain_used (loop.temp_ss, 3);
5132 /* Start the scalarized loop body. */
5133 gfc_start_scalarized_body (&loop, &body);
5135 /* Translate the expression. */
5136 gfc_conv_expr (&rse, expr2);
5137 if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
5138 gfc_conv_tmp_array_ref (&lse);
5139 else
5140 gfc_conv_expr (&lse, expr1);
5142 /* Form the mask expression according to the mask. */
5143 index = count1;
5144 maskexpr = gfc_build_array_ref (mask, index, NULL);
5145 if (invert)
5146 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
5147 TREE_TYPE (maskexpr), maskexpr);
5149 /* Use the scalar assignment as is. */
5150 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
5151 false, loop.temp_ss == NULL);
5153 tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt (input_location));
5155 gfc_add_expr_to_block (&body, tmp);
5157 if (lss == gfc_ss_terminator)
5159 /* Increment count1. */
5160 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5161 count1, gfc_index_one_node);
5162 gfc_add_modify (&body, count1, tmp);
5164 /* Use the scalar assignment as is. */
5165 gfc_add_block_to_block (&block, &body);
5167 else
5169 gcc_assert (lse.ss == gfc_ss_terminator
5170 && rse.ss == gfc_ss_terminator);
5172 if (loop.temp_ss != NULL)
5174 /* Increment count1 before finish the main body of a scalarized
5175 expression. */
5176 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5177 gfc_array_index_type, count1, gfc_index_one_node);
5178 gfc_add_modify (&body, count1, tmp);
5179 gfc_trans_scalarized_loop_boundary (&loop, &body);
5181 /* We need to copy the temporary to the actual lhs. */
5182 gfc_init_se (&lse, NULL);
5183 gfc_init_se (&rse, NULL);
5184 gfc_copy_loopinfo_to_se (&lse, &loop);
5185 gfc_copy_loopinfo_to_se (&rse, &loop);
5187 rse.ss = loop.temp_ss;
5188 lse.ss = lss;
5190 gfc_conv_tmp_array_ref (&rse);
5191 gfc_conv_expr (&lse, expr1);
5193 gcc_assert (lse.ss == gfc_ss_terminator
5194 && rse.ss == gfc_ss_terminator);
5196 /* Form the mask expression according to the mask tree list. */
5197 index = count2;
5198 maskexpr = gfc_build_array_ref (mask, index, NULL);
5199 if (invert)
5200 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
5201 TREE_TYPE (maskexpr), maskexpr);
5203 /* Use the scalar assignment as is. */
5204 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, false, true);
5205 tmp = build3_v (COND_EXPR, maskexpr, tmp,
5206 build_empty_stmt (input_location));
5207 gfc_add_expr_to_block (&body, tmp);
5209 /* Increment count2. */
5210 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5211 gfc_array_index_type, count2,
5212 gfc_index_one_node);
5213 gfc_add_modify (&body, count2, tmp);
5215 else
5217 /* Increment count1. */
5218 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5219 gfc_array_index_type, count1,
5220 gfc_index_one_node);
5221 gfc_add_modify (&body, count1, tmp);
5224 /* Generate the copying loops. */
5225 gfc_trans_scalarizing_loops (&loop, &body);
5227 /* Wrap the whole thing up. */
5228 gfc_add_block_to_block (&block, &loop.pre);
5229 gfc_add_block_to_block (&block, &loop.post);
5230 gfc_cleanup_loop (&loop);
5233 return gfc_finish_block (&block);
5237 /* Translate the WHERE construct or statement.
5238 This function can be called iteratively to translate the nested WHERE
5239 construct or statement.
5240 MASK is the control mask. */
5242 static void
5243 gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
5244 forall_info * nested_forall_info, stmtblock_t * block)
5246 stmtblock_t inner_size_body;
5247 tree inner_size, size;
5248 gfc_ss *lss, *rss;
5249 tree mask_type;
5250 gfc_expr *expr1;
5251 gfc_expr *expr2;
5252 gfc_code *cblock;
5253 gfc_code *cnext;
5254 tree tmp;
5255 tree cond;
5256 tree count1, count2;
5257 bool need_cmask;
5258 bool need_pmask;
5259 int need_temp;
5260 tree pcmask = NULL_TREE;
5261 tree ppmask = NULL_TREE;
5262 tree cmask = NULL_TREE;
5263 tree pmask = NULL_TREE;
5264 gfc_actual_arglist *arg;
5266 /* the WHERE statement or the WHERE construct statement. */
5267 cblock = code->block;
5269 /* As the mask array can be very big, prefer compact boolean types. */
5270 mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
5272 /* Determine which temporary masks are needed. */
5273 if (!cblock->block)
5275 /* One clause: No ELSEWHEREs. */
5276 need_cmask = (cblock->next != 0);
5277 need_pmask = false;
5279 else if (cblock->block->block)
5281 /* Three or more clauses: Conditional ELSEWHEREs. */
5282 need_cmask = true;
5283 need_pmask = true;
5285 else if (cblock->next)
5287 /* Two clauses, the first non-empty. */
5288 need_cmask = true;
5289 need_pmask = (mask != NULL_TREE
5290 && cblock->block->next != 0);
5292 else if (!cblock->block->next)
5294 /* Two clauses, both empty. */
5295 need_cmask = false;
5296 need_pmask = false;
5298 /* Two clauses, the first empty, the second non-empty. */
5299 else if (mask)
5301 need_cmask = (cblock->block->expr1 != 0);
5302 need_pmask = true;
5304 else
5306 need_cmask = true;
5307 need_pmask = false;
5310 if (need_cmask || need_pmask)
5312 /* Calculate the size of temporary needed by the mask-expr. */
5313 gfc_init_block (&inner_size_body);
5314 inner_size = compute_inner_temp_size (cblock->expr1, cblock->expr1,
5315 &inner_size_body, &lss, &rss);
5317 gfc_free_ss_chain (lss);
5318 gfc_free_ss_chain (rss);
5320 /* Calculate the total size of temporary needed. */
5321 size = compute_overall_iter_number (nested_forall_info, inner_size,
5322 &inner_size_body, block);
5324 /* Check whether the size is negative. */
5325 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, size,
5326 gfc_index_zero_node);
5327 size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
5328 cond, gfc_index_zero_node, size);
5329 size = gfc_evaluate_now (size, block);
5331 /* Allocate temporary for WHERE mask if needed. */
5332 if (need_cmask)
5333 cmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
5334 &pcmask);
5336 /* Allocate temporary for !mask if needed. */
5337 if (need_pmask)
5338 pmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
5339 &ppmask);
5342 while (cblock)
5344 /* Each time around this loop, the where clause is conditional
5345 on the value of mask and invert, which are updated at the
5346 bottom of the loop. */
5348 /* Has mask-expr. */
5349 if (cblock->expr1)
5351 /* Ensure that the WHERE mask will be evaluated exactly once.
5352 If there are no statements in this WHERE/ELSEWHERE clause,
5353 then we don't need to update the control mask (cmask).
5354 If this is the last clause of the WHERE construct, then
5355 we don't need to update the pending control mask (pmask). */
5356 if (mask)
5357 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
5358 mask, invert,
5359 cblock->next ? cmask : NULL_TREE,
5360 cblock->block ? pmask : NULL_TREE,
5361 mask_type, block);
5362 else
5363 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
5364 NULL_TREE, false,
5365 (cblock->next || cblock->block)
5366 ? cmask : NULL_TREE,
5367 NULL_TREE, mask_type, block);
5369 invert = false;
5371 /* It's a final elsewhere-stmt. No mask-expr is present. */
5372 else
5373 cmask = mask;
5375 /* The body of this where clause are controlled by cmask with
5376 sense specified by invert. */
5378 /* Get the assignment statement of a WHERE statement, or the first
5379 statement in where-body-construct of a WHERE construct. */
5380 cnext = cblock->next;
5381 while (cnext)
5383 switch (cnext->op)
5385 /* WHERE assignment statement. */
5386 case EXEC_ASSIGN_CALL:
5388 arg = cnext->ext.actual;
5389 expr1 = expr2 = NULL;
5390 for (; arg; arg = arg->next)
5392 if (!arg->expr)
5393 continue;
5394 if (expr1 == NULL)
5395 expr1 = arg->expr;
5396 else
5397 expr2 = arg->expr;
5399 goto evaluate;
5401 case EXEC_ASSIGN:
5402 expr1 = cnext->expr1;
5403 expr2 = cnext->expr2;
5404 evaluate:
5405 if (nested_forall_info != NULL)
5407 need_temp = gfc_check_dependency (expr1, expr2, 0);
5408 if ((need_temp || flag_test_forall_temp)
5409 && cnext->op != EXEC_ASSIGN_CALL)
5410 gfc_trans_assign_need_temp (expr1, expr2,
5411 cmask, invert,
5412 nested_forall_info, block);
5413 else
5415 /* Variables to control maskexpr. */
5416 count1 = gfc_create_var (gfc_array_index_type, "count1");
5417 count2 = gfc_create_var (gfc_array_index_type, "count2");
5418 gfc_add_modify (block, count1, gfc_index_zero_node);
5419 gfc_add_modify (block, count2, gfc_index_zero_node);
5421 tmp = gfc_trans_where_assign (expr1, expr2,
5422 cmask, invert,
5423 count1, count2,
5424 cnext);
5426 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
5427 tmp, 1);
5428 gfc_add_expr_to_block (block, tmp);
5431 else
5433 /* Variables to control maskexpr. */
5434 count1 = gfc_create_var (gfc_array_index_type, "count1");
5435 count2 = gfc_create_var (gfc_array_index_type, "count2");
5436 gfc_add_modify (block, count1, gfc_index_zero_node);
5437 gfc_add_modify (block, count2, gfc_index_zero_node);
5439 tmp = gfc_trans_where_assign (expr1, expr2,
5440 cmask, invert,
5441 count1, count2,
5442 cnext);
5443 gfc_add_expr_to_block (block, tmp);
5446 break;
5448 /* WHERE or WHERE construct is part of a where-body-construct. */
5449 case EXEC_WHERE:
5450 gfc_trans_where_2 (cnext, cmask, invert,
5451 nested_forall_info, block);
5452 break;
5454 default:
5455 gcc_unreachable ();
5458 /* The next statement within the same where-body-construct. */
5459 cnext = cnext->next;
5461 /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt. */
5462 cblock = cblock->block;
5463 if (mask == NULL_TREE)
5465 /* If we're the initial WHERE, we can simply invert the sense
5466 of the current mask to obtain the "mask" for the remaining
5467 ELSEWHEREs. */
5468 invert = true;
5469 mask = cmask;
5471 else
5473 /* Otherwise, for nested WHERE's we need to use the pending mask. */
5474 invert = false;
5475 mask = pmask;
5479 /* If we allocated a pending mask array, deallocate it now. */
5480 if (ppmask)
5482 tmp = gfc_call_free (ppmask);
5483 gfc_add_expr_to_block (block, tmp);
5486 /* If we allocated a current mask array, deallocate it now. */
5487 if (pcmask)
5489 tmp = gfc_call_free (pcmask);
5490 gfc_add_expr_to_block (block, tmp);
5494 /* Translate a simple WHERE construct or statement without dependencies.
5495 CBLOCK is the "then" clause of the WHERE statement, where CBLOCK->EXPR
5496 is the mask condition, and EBLOCK if non-NULL is the "else" clause.
5497 Currently both CBLOCK and EBLOCK are restricted to single assignments. */
5499 static tree
5500 gfc_trans_where_3 (gfc_code * cblock, gfc_code * eblock)
5502 stmtblock_t block, body;
5503 gfc_expr *cond, *tdst, *tsrc, *edst, *esrc;
5504 tree tmp, cexpr, tstmt, estmt;
5505 gfc_ss *css, *tdss, *tsss;
5506 gfc_se cse, tdse, tsse, edse, esse;
5507 gfc_loopinfo loop;
5508 gfc_ss *edss = 0;
5509 gfc_ss *esss = 0;
5510 bool maybe_workshare = false;
5512 /* Allow the scalarizer to workshare simple where loops. */
5513 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
5514 == OMPWS_WORKSHARE_FLAG)
5516 maybe_workshare = true;
5517 ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
5520 cond = cblock->expr1;
5521 tdst = cblock->next->expr1;
5522 tsrc = cblock->next->expr2;
5523 edst = eblock ? eblock->next->expr1 : NULL;
5524 esrc = eblock ? eblock->next->expr2 : NULL;
5526 gfc_start_block (&block);
5527 gfc_init_loopinfo (&loop);
5529 /* Handle the condition. */
5530 gfc_init_se (&cse, NULL);
5531 css = gfc_walk_expr (cond);
5532 gfc_add_ss_to_loop (&loop, css);
5534 /* Handle the then-clause. */
5535 gfc_init_se (&tdse, NULL);
5536 gfc_init_se (&tsse, NULL);
5537 tdss = gfc_walk_expr (tdst);
5538 tsss = gfc_walk_expr (tsrc);
5539 if (tsss == gfc_ss_terminator)
5541 tsss = gfc_get_scalar_ss (gfc_ss_terminator, tsrc);
5542 tsss->info->where = 1;
5544 gfc_add_ss_to_loop (&loop, tdss);
5545 gfc_add_ss_to_loop (&loop, tsss);
5547 if (eblock)
5549 /* Handle the else clause. */
5550 gfc_init_se (&edse, NULL);
5551 gfc_init_se (&esse, NULL);
5552 edss = gfc_walk_expr (edst);
5553 esss = gfc_walk_expr (esrc);
5554 if (esss == gfc_ss_terminator)
5556 esss = gfc_get_scalar_ss (gfc_ss_terminator, esrc);
5557 esss->info->where = 1;
5559 gfc_add_ss_to_loop (&loop, edss);
5560 gfc_add_ss_to_loop (&loop, esss);
5563 gfc_conv_ss_startstride (&loop);
5564 gfc_conv_loop_setup (&loop, &tdst->where);
5566 gfc_mark_ss_chain_used (css, 1);
5567 gfc_mark_ss_chain_used (tdss, 1);
5568 gfc_mark_ss_chain_used (tsss, 1);
5569 if (eblock)
5571 gfc_mark_ss_chain_used (edss, 1);
5572 gfc_mark_ss_chain_used (esss, 1);
5575 gfc_start_scalarized_body (&loop, &body);
5577 gfc_copy_loopinfo_to_se (&cse, &loop);
5578 gfc_copy_loopinfo_to_se (&tdse, &loop);
5579 gfc_copy_loopinfo_to_se (&tsse, &loop);
5580 cse.ss = css;
5581 tdse.ss = tdss;
5582 tsse.ss = tsss;
5583 if (eblock)
5585 gfc_copy_loopinfo_to_se (&edse, &loop);
5586 gfc_copy_loopinfo_to_se (&esse, &loop);
5587 edse.ss = edss;
5588 esse.ss = esss;
5591 gfc_conv_expr (&cse, cond);
5592 gfc_add_block_to_block (&body, &cse.pre);
5593 cexpr = cse.expr;
5595 gfc_conv_expr (&tsse, tsrc);
5596 if (tdss != gfc_ss_terminator && loop.temp_ss != NULL)
5597 gfc_conv_tmp_array_ref (&tdse);
5598 else
5599 gfc_conv_expr (&tdse, tdst);
5601 if (eblock)
5603 gfc_conv_expr (&esse, esrc);
5604 if (edss != gfc_ss_terminator && loop.temp_ss != NULL)
5605 gfc_conv_tmp_array_ref (&edse);
5606 else
5607 gfc_conv_expr (&edse, edst);
5610 tstmt = gfc_trans_scalar_assign (&tdse, &tsse, tdst->ts, false, true);
5611 estmt = eblock ? gfc_trans_scalar_assign (&edse, &esse, edst->ts,
5612 false, true)
5613 : build_empty_stmt (input_location);
5614 tmp = build3_v (COND_EXPR, cexpr, tstmt, estmt);
5615 gfc_add_expr_to_block (&body, tmp);
5616 gfc_add_block_to_block (&body, &cse.post);
5618 if (maybe_workshare)
5619 ompws_flags &= ~OMPWS_SCALARIZER_BODY;
5620 gfc_trans_scalarizing_loops (&loop, &body);
5621 gfc_add_block_to_block (&block, &loop.pre);
5622 gfc_add_block_to_block (&block, &loop.post);
5623 gfc_cleanup_loop (&loop);
5625 return gfc_finish_block (&block);
5628 /* As the WHERE or WHERE construct statement can be nested, we call
5629 gfc_trans_where_2 to do the translation, and pass the initial
5630 NULL values for both the control mask and the pending control mask. */
5632 tree
5633 gfc_trans_where (gfc_code * code)
5635 stmtblock_t block;
5636 gfc_code *cblock;
5637 gfc_code *eblock;
5639 cblock = code->block;
5640 if (cblock->next
5641 && cblock->next->op == EXEC_ASSIGN
5642 && !cblock->next->next)
5644 eblock = cblock->block;
5645 if (!eblock)
5647 /* A simple "WHERE (cond) x = y" statement or block is
5648 dependence free if cond is not dependent upon writing x,
5649 and the source y is unaffected by the destination x. */
5650 if (!gfc_check_dependency (cblock->next->expr1,
5651 cblock->expr1, 0)
5652 && !gfc_check_dependency (cblock->next->expr1,
5653 cblock->next->expr2, 0))
5654 return gfc_trans_where_3 (cblock, NULL);
5656 else if (!eblock->expr1
5657 && !eblock->block
5658 && eblock->next
5659 && eblock->next->op == EXEC_ASSIGN
5660 && !eblock->next->next)
5662 /* A simple "WHERE (cond) x1 = y1 ELSEWHERE x2 = y2 ENDWHERE"
5663 block is dependence free if cond is not dependent on writes
5664 to x1 and x2, y1 is not dependent on writes to x2, and y2
5665 is not dependent on writes to x1, and both y's are not
5666 dependent upon their own x's. In addition to this, the
5667 final two dependency checks below exclude all but the same
5668 array reference if the where and elswhere destinations
5669 are the same. In short, this is VERY conservative and this
5670 is needed because the two loops, required by the standard
5671 are coalesced in gfc_trans_where_3. */
5672 if (!gfc_check_dependency (cblock->next->expr1,
5673 cblock->expr1, 0)
5674 && !gfc_check_dependency (eblock->next->expr1,
5675 cblock->expr1, 0)
5676 && !gfc_check_dependency (cblock->next->expr1,
5677 eblock->next->expr2, 1)
5678 && !gfc_check_dependency (eblock->next->expr1,
5679 cblock->next->expr2, 1)
5680 && !gfc_check_dependency (cblock->next->expr1,
5681 cblock->next->expr2, 1)
5682 && !gfc_check_dependency (eblock->next->expr1,
5683 eblock->next->expr2, 1)
5684 && !gfc_check_dependency (cblock->next->expr1,
5685 eblock->next->expr1, 0)
5686 && !gfc_check_dependency (eblock->next->expr1,
5687 cblock->next->expr1, 0))
5688 return gfc_trans_where_3 (cblock, eblock);
5692 gfc_start_block (&block);
5694 gfc_trans_where_2 (code, NULL, false, NULL, &block);
5696 return gfc_finish_block (&block);
5700 /* CYCLE a DO loop. The label decl has already been created by
5701 gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
5702 node at the head of the loop. We must mark the label as used. */
5704 tree
5705 gfc_trans_cycle (gfc_code * code)
5707 tree cycle_label;
5709 cycle_label = code->ext.which_construct->cycle_label;
5710 gcc_assert (cycle_label);
5712 TREE_USED (cycle_label) = 1;
5713 return build1_v (GOTO_EXPR, cycle_label);
5717 /* EXIT a DO loop. Similar to CYCLE, but now the label is in
5718 TREE_VALUE (backend_decl) of the gfc_code node at the head of the
5719 loop. */
5721 tree
5722 gfc_trans_exit (gfc_code * code)
5724 tree exit_label;
5726 exit_label = code->ext.which_construct->exit_label;
5727 gcc_assert (exit_label);
5729 TREE_USED (exit_label) = 1;
5730 return build1_v (GOTO_EXPR, exit_label);
5734 /* Get the initializer expression for the code and expr of an allocate.
5735 When no initializer is needed return NULL. */
5737 static gfc_expr *
5738 allocate_get_initializer (gfc_code * code, gfc_expr * expr)
5740 if (!gfc_bt_struct (expr->ts.type) && expr->ts.type != BT_CLASS)
5741 return NULL;
5743 /* An explicit type was given in allocate ( T:: object). */
5744 if (code->ext.alloc.ts.type == BT_DERIVED
5745 && (code->ext.alloc.ts.u.derived->attr.alloc_comp
5746 || gfc_has_default_initializer (code->ext.alloc.ts.u.derived)))
5747 return gfc_default_initializer (&code->ext.alloc.ts);
5749 if (gfc_bt_struct (expr->ts.type)
5750 && (expr->ts.u.derived->attr.alloc_comp
5751 || gfc_has_default_initializer (expr->ts.u.derived)))
5752 return gfc_default_initializer (&expr->ts);
5754 if (expr->ts.type == BT_CLASS
5755 && (CLASS_DATA (expr)->ts.u.derived->attr.alloc_comp
5756 || gfc_has_default_initializer (CLASS_DATA (expr)->ts.u.derived)))
5757 return gfc_default_initializer (&CLASS_DATA (expr)->ts);
5759 return NULL;
5762 /* Translate the ALLOCATE statement. */
5764 tree
5765 gfc_trans_allocate (gfc_code * code)
5767 gfc_alloc *al;
5768 gfc_expr *expr, *e3rhs = NULL, *init_expr;
5769 gfc_se se, se_sz;
5770 tree tmp;
5771 tree parm;
5772 tree stat;
5773 tree errmsg;
5774 tree errlen;
5775 tree label_errmsg;
5776 tree label_finish;
5777 tree memsz;
5778 tree al_vptr, al_len;
5779 /* If an expr3 is present, then store the tree for accessing its
5780 _vptr, and _len components in the variables, respectively. The
5781 element size, i.e. _vptr%size, is stored in expr3_esize. Any of
5782 the trees may be the NULL_TREE indicating that this is not
5783 available for expr3's type. */
5784 tree expr3, expr3_vptr, expr3_len, expr3_esize;
5785 /* Classify what expr3 stores. */
5786 enum { E3_UNSET = 0, E3_SOURCE, E3_MOLD, E3_DESC } e3_is;
5787 stmtblock_t block;
5788 stmtblock_t post;
5789 tree nelems;
5790 bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set, is_coarray;
5791 bool needs_caf_sync, caf_refs_comp;
5792 gfc_symtree *newsym = NULL;
5793 symbol_attribute caf_attr;
5794 gfc_actual_arglist *param_list;
5796 if (!code->ext.alloc.list)
5797 return NULL_TREE;
5799 stat = tmp = memsz = al_vptr = al_len = NULL_TREE;
5800 expr3 = expr3_vptr = expr3_len = expr3_esize = NULL_TREE;
5801 label_errmsg = label_finish = errmsg = errlen = NULL_TREE;
5802 e3_is = E3_UNSET;
5803 is_coarray = needs_caf_sync = false;
5805 gfc_init_block (&block);
5806 gfc_init_block (&post);
5808 /* STAT= (and maybe ERRMSG=) is present. */
5809 if (code->expr1)
5811 /* STAT=. */
5812 tree gfc_int4_type_node = gfc_get_int_type (4);
5813 stat = gfc_create_var (gfc_int4_type_node, "stat");
5815 /* ERRMSG= only makes sense with STAT=. */
5816 if (code->expr2)
5818 gfc_init_se (&se, NULL);
5819 se.want_pointer = 1;
5820 gfc_conv_expr_lhs (&se, code->expr2);
5821 errmsg = se.expr;
5822 errlen = se.string_length;
5824 else
5826 errmsg = null_pointer_node;
5827 errlen = build_int_cst (gfc_charlen_type_node, 0);
5830 /* GOTO destinations. */
5831 label_errmsg = gfc_build_label_decl (NULL_TREE);
5832 label_finish = gfc_build_label_decl (NULL_TREE);
5833 TREE_USED (label_finish) = 0;
5836 /* When an expr3 is present evaluate it only once. The standards prevent a
5837 dependency of expr3 on the objects in the allocate list. An expr3 can
5838 be pre-evaluated in all cases. One just has to make sure, to use the
5839 correct way, i.e., to get the descriptor or to get a reference
5840 expression. */
5841 if (code->expr3)
5843 bool vtab_needed = false, temp_var_needed = false,
5844 temp_obj_created = false;
5846 is_coarray = gfc_is_coarray (code->expr3);
5848 /* Figure whether we need the vtab from expr3. */
5849 for (al = code->ext.alloc.list; !vtab_needed && al != NULL;
5850 al = al->next)
5851 vtab_needed = (al->expr->ts.type == BT_CLASS);
5853 gfc_init_se (&se, NULL);
5854 /* When expr3 is a variable, i.e., a very simple expression,
5855 then convert it once here. */
5856 if (code->expr3->expr_type == EXPR_VARIABLE
5857 || code->expr3->expr_type == EXPR_ARRAY
5858 || code->expr3->expr_type == EXPR_CONSTANT)
5860 if (!code->expr3->mold
5861 || code->expr3->ts.type == BT_CHARACTER
5862 || vtab_needed
5863 || code->ext.alloc.arr_spec_from_expr3)
5865 /* Convert expr3 to a tree. For all "simple" expression just
5866 get the descriptor or the reference, respectively, depending
5867 on the rank of the expr. */
5868 if (code->ext.alloc.arr_spec_from_expr3 || code->expr3->rank != 0)
5869 gfc_conv_expr_descriptor (&se, code->expr3);
5870 else
5872 gfc_conv_expr_reference (&se, code->expr3);
5874 /* gfc_conv_expr_reference wraps POINTER_PLUS_EXPR in a
5875 NOP_EXPR, which prevents gfortran from getting the vptr
5876 from the source=-expression. Remove the NOP_EXPR and go
5877 with the POINTER_PLUS_EXPR in this case. */
5878 if (code->expr3->ts.type == BT_CLASS
5879 && TREE_CODE (se.expr) == NOP_EXPR
5880 && (TREE_CODE (TREE_OPERAND (se.expr, 0))
5881 == POINTER_PLUS_EXPR
5882 || is_coarray))
5883 se.expr = TREE_OPERAND (se.expr, 0);
5885 /* Create a temp variable only for component refs to prevent
5886 having to go through the full deref-chain each time and to
5887 simplfy computation of array properties. */
5888 temp_var_needed = TREE_CODE (se.expr) == COMPONENT_REF;
5891 else
5893 /* In all other cases evaluate the expr3. */
5894 symbol_attribute attr;
5895 /* Get the descriptor for all arrays, that are not allocatable or
5896 pointer, because the latter are descriptors already.
5897 The exception are function calls returning a class object:
5898 The descriptor is stored in their results _data component, which
5899 is easier to access, when first a temporary variable for the
5900 result is created and the descriptor retrieved from there. */
5901 attr = gfc_expr_attr (code->expr3);
5902 if (code->expr3->rank != 0
5903 && ((!attr.allocatable && !attr.pointer)
5904 || (code->expr3->expr_type == EXPR_FUNCTION
5905 && (code->expr3->ts.type != BT_CLASS
5906 || (code->expr3->value.function.isym
5907 && code->expr3->value.function.isym
5908 ->transformational)))))
5909 gfc_conv_expr_descriptor (&se, code->expr3);
5910 else
5911 gfc_conv_expr_reference (&se, code->expr3);
5912 if (code->expr3->ts.type == BT_CLASS)
5913 gfc_conv_class_to_class (&se, code->expr3,
5914 code->expr3->ts,
5915 false, true,
5916 false, false);
5917 temp_obj_created = temp_var_needed = !VAR_P (se.expr);
5919 gfc_add_block_to_block (&block, &se.pre);
5920 gfc_add_block_to_block (&post, &se.post);
5922 /* Special case when string in expr3 is zero. */
5923 if (code->expr3->ts.type == BT_CHARACTER
5924 && integer_zerop (se.string_length))
5926 gfc_init_se (&se, NULL);
5927 temp_var_needed = false;
5928 expr3_len = build_zero_cst (gfc_charlen_type_node);
5929 e3_is = E3_MOLD;
5931 /* Prevent aliasing, i.e., se.expr may be already a
5932 variable declaration. */
5933 else if (se.expr != NULL_TREE && temp_var_needed)
5935 tree var, desc;
5936 tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)) || is_coarray ?
5937 se.expr
5938 : build_fold_indirect_ref_loc (input_location, se.expr);
5940 /* Get the array descriptor and prepare it to be assigned to the
5941 temporary variable var. For classes the array descriptor is
5942 in the _data component and the object goes into the
5943 GFC_DECL_SAVED_DESCRIPTOR. */
5944 if (code->expr3->ts.type == BT_CLASS
5945 && code->expr3->rank != 0)
5947 /* When an array_ref was in expr3, then the descriptor is the
5948 first operand. */
5949 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
5951 desc = TREE_OPERAND (tmp, 0);
5953 else
5955 desc = tmp;
5956 tmp = gfc_class_data_get (tmp);
5958 if (code->ext.alloc.arr_spec_from_expr3)
5959 e3_is = E3_DESC;
5961 else
5962 desc = !is_coarray ? se.expr
5963 : TREE_OPERAND (TREE_OPERAND (se.expr, 0), 0);
5964 /* We need a regular (non-UID) symbol here, therefore give a
5965 prefix. */
5966 var = gfc_create_var (TREE_TYPE (tmp), "source");
5967 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
5969 gfc_allocate_lang_decl (var);
5970 GFC_DECL_SAVED_DESCRIPTOR (var) = desc;
5972 gfc_add_modify_loc (input_location, &block, var, tmp);
5974 expr3 = var;
5975 if (se.string_length)
5976 /* Evaluate it assuming that it also is complicated like expr3. */
5977 expr3_len = gfc_evaluate_now (se.string_length, &block);
5979 else
5981 expr3 = se.expr;
5982 expr3_len = se.string_length;
5985 /* Deallocate any allocatable components in expressions that use a
5986 temporary object, i.e. are not a simple alias of to an EXPR_VARIABLE.
5987 E.g. temporaries of a function call need freeing of their components
5988 here. */
5989 if ((code->expr3->ts.type == BT_DERIVED
5990 || code->expr3->ts.type == BT_CLASS)
5991 && (code->expr3->expr_type != EXPR_VARIABLE || temp_obj_created)
5992 && code->expr3->ts.u.derived->attr.alloc_comp)
5994 tmp = gfc_deallocate_alloc_comp (code->expr3->ts.u.derived,
5995 expr3, code->expr3->rank);
5996 gfc_prepend_expr_to_block (&post, tmp);
5999 /* Store what the expr3 is to be used for. */
6000 if (e3_is == E3_UNSET)
6001 e3_is = expr3 != NULL_TREE ?
6002 (code->ext.alloc.arr_spec_from_expr3 ?
6003 E3_DESC
6004 : (code->expr3->mold ? E3_MOLD : E3_SOURCE))
6005 : E3_UNSET;
6007 /* Figure how to get the _vtab entry. This also obtains the tree
6008 expression for accessing the _len component, because only
6009 unlimited polymorphic objects, which are a subcategory of class
6010 types, have a _len component. */
6011 if (code->expr3->ts.type == BT_CLASS)
6013 gfc_expr *rhs;
6014 tmp = expr3 != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (expr3)) ?
6015 build_fold_indirect_ref (expr3): expr3;
6016 /* Polymorphic SOURCE: VPTR must be determined at run time.
6017 expr3 may be a temporary array declaration, therefore check for
6018 GFC_CLASS_TYPE_P before trying to get the _vptr component. */
6019 if (tmp != NULL_TREE
6020 && (e3_is == E3_DESC
6021 || (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
6022 && (VAR_P (tmp) || !code->expr3->ref))
6023 || (VAR_P (tmp) && DECL_LANG_SPECIFIC (tmp))))
6024 tmp = gfc_class_vptr_get (expr3);
6025 else
6027 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
6028 gfc_add_vptr_component (rhs);
6029 gfc_init_se (&se, NULL);
6030 se.want_pointer = 1;
6031 gfc_conv_expr (&se, rhs);
6032 tmp = se.expr;
6033 gfc_free_expr (rhs);
6035 /* Set the element size. */
6036 expr3_esize = gfc_vptr_size_get (tmp);
6037 if (vtab_needed)
6038 expr3_vptr = tmp;
6039 /* Initialize the ref to the _len component. */
6040 if (expr3_len == NULL_TREE && UNLIMITED_POLY (code->expr3))
6042 /* Same like for retrieving the _vptr. */
6043 if (expr3 != NULL_TREE && !code->expr3->ref)
6044 expr3_len = gfc_class_len_get (expr3);
6045 else
6047 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
6048 gfc_add_len_component (rhs);
6049 gfc_init_se (&se, NULL);
6050 gfc_conv_expr (&se, rhs);
6051 expr3_len = se.expr;
6052 gfc_free_expr (rhs);
6056 else
6058 /* When the object to allocate is polymorphic type, then it
6059 needs its vtab set correctly, so deduce the required _vtab
6060 and _len from the source expression. */
6061 if (vtab_needed)
6063 /* VPTR is fixed at compile time. */
6064 gfc_symbol *vtab;
6066 vtab = gfc_find_vtab (&code->expr3->ts);
6067 gcc_assert (vtab);
6068 expr3_vptr = gfc_get_symbol_decl (vtab);
6069 expr3_vptr = gfc_build_addr_expr (NULL_TREE,
6070 expr3_vptr);
6072 /* _len component needs to be set, when ts is a character
6073 array. */
6074 if (expr3_len == NULL_TREE
6075 && code->expr3->ts.type == BT_CHARACTER)
6077 if (code->expr3->ts.u.cl
6078 && code->expr3->ts.u.cl->length)
6080 gfc_init_se (&se, NULL);
6081 gfc_conv_expr (&se, code->expr3->ts.u.cl->length);
6082 gfc_add_block_to_block (&block, &se.pre);
6083 expr3_len = gfc_evaluate_now (se.expr, &block);
6085 gcc_assert (expr3_len);
6087 /* For character arrays only the kind's size is needed, because
6088 the array mem_size is _len * (elem_size = kind_size).
6089 For all other get the element size in the normal way. */
6090 if (code->expr3->ts.type == BT_CHARACTER)
6091 expr3_esize = TYPE_SIZE_UNIT (
6092 gfc_get_char_type (code->expr3->ts.kind));
6093 else
6094 expr3_esize = TYPE_SIZE_UNIT (
6095 gfc_typenode_for_spec (&code->expr3->ts));
6097 gcc_assert (expr3_esize);
6098 expr3_esize = fold_convert (sizetype, expr3_esize);
6099 if (e3_is == E3_MOLD)
6100 /* The expr3 is no longer valid after this point. */
6101 expr3 = NULL_TREE;
6103 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
6105 /* Compute the explicit typespec given only once for all objects
6106 to allocate. */
6107 if (code->ext.alloc.ts.type != BT_CHARACTER)
6108 expr3_esize = TYPE_SIZE_UNIT (
6109 gfc_typenode_for_spec (&code->ext.alloc.ts));
6110 else if (code->ext.alloc.ts.u.cl->length != NULL)
6112 gfc_expr *sz;
6113 sz = gfc_copy_expr (code->ext.alloc.ts.u.cl->length);
6114 gfc_init_se (&se_sz, NULL);
6115 gfc_conv_expr (&se_sz, sz);
6116 gfc_free_expr (sz);
6117 tmp = gfc_get_char_type (code->ext.alloc.ts.kind);
6118 tmp = TYPE_SIZE_UNIT (tmp);
6119 tmp = fold_convert (TREE_TYPE (se_sz.expr), tmp);
6120 gfc_add_block_to_block (&block, &se_sz.pre);
6121 expr3_esize = fold_build2_loc (input_location, MULT_EXPR,
6122 TREE_TYPE (se_sz.expr),
6123 tmp, se_sz.expr);
6124 expr3_esize = gfc_evaluate_now (expr3_esize, &block);
6126 else
6127 expr3_esize = NULL_TREE;
6130 /* The routine gfc_trans_assignment () already implements all
6131 techniques needed. Unfortunately we may have a temporary
6132 variable for the source= expression here. When that is the
6133 case convert this variable into a temporary gfc_expr of type
6134 EXPR_VARIABLE and used it as rhs for the assignment. The
6135 advantage is, that we get scalarizer support for free,
6136 don't have to take care about scalar to array treatment and
6137 will benefit of every enhancements gfc_trans_assignment ()
6138 gets.
6139 No need to check whether e3_is is E3_UNSET, because that is
6140 done by expr3 != NULL_TREE.
6141 Exclude variables since the following block does not handle
6142 array sections. In any case, there is no harm in sending
6143 variables to gfc_trans_assignment because there is no
6144 evaluation of variables. */
6145 if (code->expr3)
6147 if (code->expr3->expr_type != EXPR_VARIABLE
6148 && e3_is != E3_MOLD && expr3 != NULL_TREE
6149 && DECL_P (expr3) && DECL_ARTIFICIAL (expr3))
6151 /* Build a temporary symtree and symbol. Do not add it to the current
6152 namespace to prevent accidently modifying a colliding
6153 symbol's as. */
6154 newsym = XCNEW (gfc_symtree);
6155 /* The name of the symtree should be unique, because gfc_create_var ()
6156 took care about generating the identifier. */
6157 newsym->name
6158 = gfc_get_string ("%s", IDENTIFIER_POINTER (DECL_NAME (expr3)));
6159 newsym->n.sym = gfc_new_symbol (newsym->name, NULL);
6160 /* The backend_decl is known. It is expr3, which is inserted
6161 here. */
6162 newsym->n.sym->backend_decl = expr3;
6163 e3rhs = gfc_get_expr ();
6164 e3rhs->rank = code->expr3->rank;
6165 e3rhs->symtree = newsym;
6166 /* Mark the symbol referenced or gfc_trans_assignment will bug. */
6167 newsym->n.sym->attr.referenced = 1;
6168 e3rhs->expr_type = EXPR_VARIABLE;
6169 e3rhs->where = code->expr3->where;
6170 /* Set the symbols type, upto it was BT_UNKNOWN. */
6171 if (IS_CLASS_ARRAY (code->expr3)
6172 && code->expr3->expr_type == EXPR_FUNCTION
6173 && code->expr3->value.function.isym
6174 && code->expr3->value.function.isym->transformational)
6176 e3rhs->ts = CLASS_DATA (code->expr3)->ts;
6178 else if (code->expr3->ts.type == BT_CLASS
6179 && !GFC_CLASS_TYPE_P (TREE_TYPE (expr3)))
6180 e3rhs->ts = CLASS_DATA (code->expr3)->ts;
6181 else
6182 e3rhs->ts = code->expr3->ts;
6183 newsym->n.sym->ts = e3rhs->ts;
6184 /* Check whether the expr3 is array valued. */
6185 if (e3rhs->rank)
6187 gfc_array_spec *arr;
6188 arr = gfc_get_array_spec ();
6189 arr->rank = e3rhs->rank;
6190 arr->type = AS_DEFERRED;
6191 /* Set the dimension and pointer attribute for arrays
6192 to be on the safe side. */
6193 newsym->n.sym->attr.dimension = 1;
6194 newsym->n.sym->attr.pointer = 1;
6195 newsym->n.sym->as = arr;
6196 if (IS_CLASS_ARRAY (code->expr3)
6197 && code->expr3->expr_type == EXPR_FUNCTION
6198 && code->expr3->value.function.isym
6199 && code->expr3->value.function.isym->transformational)
6201 gfc_array_spec *tarr;
6202 tarr = gfc_get_array_spec ();
6203 *tarr = *arr;
6204 e3rhs->ts.u.derived->as = tarr;
6206 gfc_add_full_array_ref (e3rhs, arr);
6208 else if (POINTER_TYPE_P (TREE_TYPE (expr3)))
6209 newsym->n.sym->attr.pointer = 1;
6210 /* The string length is known, too. Set it for char arrays. */
6211 if (e3rhs->ts.type == BT_CHARACTER)
6212 newsym->n.sym->ts.u.cl->backend_decl = expr3_len;
6213 gfc_commit_symbol (newsym->n.sym);
6215 else
6216 e3rhs = gfc_copy_expr (code->expr3);
6219 /* Loop over all objects to allocate. */
6220 for (al = code->ext.alloc.list; al != NULL; al = al->next)
6222 expr = gfc_copy_expr (al->expr);
6223 /* UNLIMITED_POLY () needs the _data component to be set, when
6224 expr is a unlimited polymorphic object. But the _data component
6225 has not been set yet, so check the derived type's attr for the
6226 unlimited polymorphic flag to be safe. */
6227 upoly_expr = UNLIMITED_POLY (expr)
6228 || (expr->ts.type == BT_DERIVED
6229 && expr->ts.u.derived->attr.unlimited_polymorphic);
6230 gfc_init_se (&se, NULL);
6232 /* For class types prepare the expressions to ref the _vptr
6233 and the _len component. The latter for unlimited polymorphic
6234 types only. */
6235 if (expr->ts.type == BT_CLASS)
6237 gfc_expr *expr_ref_vptr, *expr_ref_len;
6238 gfc_add_data_component (expr);
6239 /* Prep the vptr handle. */
6240 expr_ref_vptr = gfc_copy_expr (al->expr);
6241 gfc_add_vptr_component (expr_ref_vptr);
6242 se.want_pointer = 1;
6243 gfc_conv_expr (&se, expr_ref_vptr);
6244 al_vptr = se.expr;
6245 se.want_pointer = 0;
6246 gfc_free_expr (expr_ref_vptr);
6247 /* Allocated unlimited polymorphic objects always have a _len
6248 component. */
6249 if (upoly_expr)
6251 expr_ref_len = gfc_copy_expr (al->expr);
6252 gfc_add_len_component (expr_ref_len);
6253 gfc_conv_expr (&se, expr_ref_len);
6254 al_len = se.expr;
6255 gfc_free_expr (expr_ref_len);
6257 else
6258 /* In a loop ensure that all loop variable dependent variables
6259 are initialized at the same spot in all execution paths. */
6260 al_len = NULL_TREE;
6262 else
6263 al_vptr = al_len = NULL_TREE;
6265 se.want_pointer = 1;
6266 se.descriptor_only = 1;
6268 gfc_conv_expr (&se, expr);
6269 if (expr->ts.type == BT_CHARACTER && expr->ts.deferred)
6270 /* se.string_length now stores the .string_length variable of expr
6271 needed to allocate character(len=:) arrays. */
6272 al_len = se.string_length;
6274 al_len_needs_set = al_len != NULL_TREE;
6275 /* When allocating an array one can not use much of the
6276 pre-evaluated expr3 expressions, because for most of them the
6277 scalarizer is needed which is not available in the pre-evaluation
6278 step. Therefore gfc_array_allocate () is responsible (and able)
6279 to handle the complete array allocation. Only the element size
6280 needs to be provided, which is done most of the time by the
6281 pre-evaluation step. */
6282 nelems = NULL_TREE;
6283 if (expr3_len && (code->expr3->ts.type == BT_CHARACTER
6284 || code->expr3->ts.type == BT_CLASS))
6286 /* When al is an array, then the element size for each element
6287 in the array is needed, which is the product of the len and
6288 esize for char arrays. For unlimited polymorphics len can be
6289 zero, therefore take the maximum of len and one. */
6290 tmp = fold_build2_loc (input_location, MAX_EXPR,
6291 TREE_TYPE (expr3_len),
6292 expr3_len, fold_convert (TREE_TYPE (expr3_len),
6293 integer_one_node));
6294 tmp = fold_build2_loc (input_location, MULT_EXPR,
6295 TREE_TYPE (expr3_esize), expr3_esize,
6296 fold_convert (TREE_TYPE (expr3_esize), tmp));
6298 else
6299 tmp = expr3_esize;
6300 if (!gfc_array_allocate (&se, expr, stat, errmsg, errlen,
6301 label_finish, tmp, &nelems,
6302 e3rhs ? e3rhs : code->expr3,
6303 e3_is == E3_DESC ? expr3 : NULL_TREE,
6304 code->expr3 != NULL && e3_is == E3_DESC
6305 && code->expr3->expr_type == EXPR_ARRAY))
6307 /* A scalar or derived type. First compute the size to
6308 allocate.
6310 expr3_len is set when expr3 is an unlimited polymorphic
6311 object or a deferred length string. */
6312 if (expr3_len != NULL_TREE)
6314 tmp = fold_convert (TREE_TYPE (expr3_esize), expr3_len);
6315 tmp = fold_build2_loc (input_location, MULT_EXPR,
6316 TREE_TYPE (expr3_esize),
6317 expr3_esize, tmp);
6318 if (code->expr3->ts.type != BT_CLASS)
6319 /* expr3 is a deferred length string, i.e., we are
6320 done. */
6321 memsz = tmp;
6322 else
6324 /* For unlimited polymorphic enties build
6325 (len > 0) ? element_size * len : element_size
6326 to compute the number of bytes to allocate.
6327 This allows the allocation of unlimited polymorphic
6328 objects from an expr3 that is also unlimited
6329 polymorphic and stores a _len dependent object,
6330 e.g., a string. */
6331 memsz = fold_build2_loc (input_location, GT_EXPR,
6332 logical_type_node, expr3_len,
6333 build_zero_cst
6334 (TREE_TYPE (expr3_len)));
6335 memsz = fold_build3_loc (input_location, COND_EXPR,
6336 TREE_TYPE (expr3_esize),
6337 memsz, tmp, expr3_esize);
6340 else if (expr3_esize != NULL_TREE)
6341 /* Any other object in expr3 just needs element size in
6342 bytes. */
6343 memsz = expr3_esize;
6344 else if ((expr->ts.type == BT_CHARACTER && expr->ts.deferred)
6345 || (upoly_expr
6346 && code->ext.alloc.ts.type == BT_CHARACTER))
6348 /* Allocating deferred length char arrays need the length
6349 to allocate in the alloc_type_spec. But also unlimited
6350 polymorphic objects may be allocated as char arrays.
6351 Both are handled here. */
6352 gfc_init_se (&se_sz, NULL);
6353 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6354 gfc_add_block_to_block (&se.pre, &se_sz.pre);
6355 se_sz.expr = gfc_evaluate_now (se_sz.expr, &se.pre);
6356 gfc_add_block_to_block (&se.pre, &se_sz.post);
6357 expr3_len = se_sz.expr;
6358 tmp_expr3_len_flag = true;
6359 tmp = TYPE_SIZE_UNIT (
6360 gfc_get_char_type (code->ext.alloc.ts.kind));
6361 memsz = fold_build2_loc (input_location, MULT_EXPR,
6362 TREE_TYPE (tmp),
6363 fold_convert (TREE_TYPE (tmp),
6364 expr3_len),
6365 tmp);
6367 else if (expr->ts.type == BT_CHARACTER)
6369 /* Compute the number of bytes needed to allocate a fixed
6370 length char array. */
6371 gcc_assert (se.string_length != NULL_TREE);
6372 tmp = TYPE_SIZE_UNIT (gfc_get_char_type (expr->ts.kind));
6373 memsz = fold_build2_loc (input_location, MULT_EXPR,
6374 TREE_TYPE (tmp), tmp,
6375 fold_convert (TREE_TYPE (tmp),
6376 se.string_length));
6378 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
6379 /* Handle all types, where the alloc_type_spec is set. */
6380 memsz = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->ext.alloc.ts));
6381 else
6382 /* Handle size computation of the type declared to alloc. */
6383 memsz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
6385 /* Store the caf-attributes for latter use. */
6386 if (flag_coarray == GFC_FCOARRAY_LIB
6387 && (caf_attr = gfc_caf_attr (expr, true, &caf_refs_comp))
6388 .codimension)
6390 /* Scalar allocatable components in coarray'ed derived types make
6391 it here and are treated now. */
6392 tree caf_decl, token;
6393 gfc_se caf_se;
6395 is_coarray = true;
6396 /* Set flag, to add synchronize after the allocate. */
6397 needs_caf_sync = needs_caf_sync
6398 || caf_attr.coarray_comp || !caf_refs_comp;
6400 gfc_init_se (&caf_se, NULL);
6402 caf_decl = gfc_get_tree_for_caf_expr (expr);
6403 gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl,
6404 NULL_TREE, NULL);
6405 gfc_add_block_to_block (&se.pre, &caf_se.pre);
6406 gfc_allocate_allocatable (&se.pre, se.expr, memsz,
6407 gfc_build_addr_expr (NULL_TREE, token),
6408 NULL_TREE, NULL_TREE, NULL_TREE,
6409 label_finish, expr, 1);
6411 /* Allocate - for non-pointers with re-alloc checking. */
6412 else if (gfc_expr_attr (expr).allocatable)
6413 gfc_allocate_allocatable (&se.pre, se.expr, memsz,
6414 NULL_TREE, stat, errmsg, errlen,
6415 label_finish, expr, 0);
6416 else
6417 gfc_allocate_using_malloc (&se.pre, se.expr, memsz, stat);
6419 else
6421 /* Allocating coarrays needs a sync after the allocate executed.
6422 Set the flag to add the sync after all objects are allocated. */
6423 if (flag_coarray == GFC_FCOARRAY_LIB
6424 && (caf_attr = gfc_caf_attr (expr, true, &caf_refs_comp))
6425 .codimension)
6427 is_coarray = true;
6428 needs_caf_sync = needs_caf_sync
6429 || caf_attr.coarray_comp || !caf_refs_comp;
6432 if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
6433 && expr3_len != NULL_TREE)
6435 /* Arrays need to have a _len set before the array
6436 descriptor is filled. */
6437 gfc_add_modify (&block, al_len,
6438 fold_convert (TREE_TYPE (al_len), expr3_len));
6439 /* Prevent setting the length twice. */
6440 al_len_needs_set = false;
6442 else if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
6443 && code->ext.alloc.ts.u.cl->length)
6445 /* Cover the cases where a string length is explicitly
6446 specified by a type spec for deferred length character
6447 arrays or unlimited polymorphic objects without a
6448 source= or mold= expression. */
6449 gfc_init_se (&se_sz, NULL);
6450 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6451 gfc_add_block_to_block (&block, &se_sz.pre);
6452 gfc_add_modify (&block, al_len,
6453 fold_convert (TREE_TYPE (al_len),
6454 se_sz.expr));
6455 al_len_needs_set = false;
6459 gfc_add_block_to_block (&block, &se.pre);
6461 /* Error checking -- Note: ERRMSG only makes sense with STAT. */
6462 if (code->expr1)
6464 tmp = build1_v (GOTO_EXPR, label_errmsg);
6465 parm = fold_build2_loc (input_location, NE_EXPR,
6466 logical_type_node, stat,
6467 build_int_cst (TREE_TYPE (stat), 0));
6468 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6469 gfc_unlikely (parm, PRED_FORTRAN_FAIL_ALLOC),
6470 tmp, build_empty_stmt (input_location));
6471 gfc_add_expr_to_block (&block, tmp);
6474 /* Set the vptr only when no source= is set. When source= is set, then
6475 the trans_assignment below will set the vptr. */
6476 if (al_vptr != NULL_TREE && (!code->expr3 || code->expr3->mold))
6478 if (expr3_vptr != NULL_TREE)
6479 /* The vtab is already known, so just assign it. */
6480 gfc_add_modify (&block, al_vptr,
6481 fold_convert (TREE_TYPE (al_vptr), expr3_vptr));
6482 else
6484 /* VPTR is fixed at compile time. */
6485 gfc_symbol *vtab;
6486 gfc_typespec *ts;
6488 if (code->expr3)
6489 /* Although expr3 is pre-evaluated above, it may happen,
6490 that for arrays or in mold= cases the pre-evaluation
6491 was not successful. In these rare cases take the vtab
6492 from the typespec of expr3 here. */
6493 ts = &code->expr3->ts;
6494 else if (code->ext.alloc.ts.type == BT_DERIVED || upoly_expr)
6495 /* The alloc_type_spec gives the type to allocate or the
6496 al is unlimited polymorphic, which enforces the use of
6497 an alloc_type_spec that is not necessarily a BT_DERIVED. */
6498 ts = &code->ext.alloc.ts;
6499 else
6500 /* Prepare for setting the vtab as declared. */
6501 ts = &expr->ts;
6503 vtab = gfc_find_vtab (ts);
6504 gcc_assert (vtab);
6505 tmp = gfc_build_addr_expr (NULL_TREE,
6506 gfc_get_symbol_decl (vtab));
6507 gfc_add_modify (&block, al_vptr,
6508 fold_convert (TREE_TYPE (al_vptr), tmp));
6512 /* Add assignment for string length. */
6513 if (al_len != NULL_TREE && al_len_needs_set)
6515 if (expr3_len != NULL_TREE)
6517 gfc_add_modify (&block, al_len,
6518 fold_convert (TREE_TYPE (al_len),
6519 expr3_len));
6520 /* When tmp_expr3_len_flag is set, then expr3_len is
6521 abused to carry the length information from the
6522 alloc_type. Clear it to prevent setting incorrect len
6523 information in future loop iterations. */
6524 if (tmp_expr3_len_flag)
6525 /* No need to reset tmp_expr3_len_flag, because the
6526 presence of an expr3 can not change within in the
6527 loop. */
6528 expr3_len = NULL_TREE;
6530 else if (code->ext.alloc.ts.type == BT_CHARACTER
6531 && code->ext.alloc.ts.u.cl->length)
6533 /* Cover the cases where a string length is explicitly
6534 specified by a type spec for deferred length character
6535 arrays or unlimited polymorphic objects without a
6536 source= or mold= expression. */
6537 if (expr3_esize == NULL_TREE || code->ext.alloc.ts.kind != 1)
6539 gfc_init_se (&se_sz, NULL);
6540 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6541 gfc_add_block_to_block (&block, &se_sz.pre);
6542 gfc_add_modify (&block, al_len,
6543 fold_convert (TREE_TYPE (al_len),
6544 se_sz.expr));
6546 else
6547 gfc_add_modify (&block, al_len,
6548 fold_convert (TREE_TYPE (al_len),
6549 expr3_esize));
6551 else
6552 /* No length information needed, because type to allocate
6553 has no length. Set _len to 0. */
6554 gfc_add_modify (&block, al_len,
6555 fold_convert (TREE_TYPE (al_len),
6556 integer_zero_node));
6559 init_expr = NULL;
6560 if (code->expr3 && !code->expr3->mold && e3_is != E3_MOLD)
6562 /* Initialization via SOURCE block (or static default initializer).
6563 Switch off automatic reallocation since we have just done the
6564 ALLOCATE. */
6565 int realloc_lhs = flag_realloc_lhs;
6566 gfc_expr *init_expr = gfc_expr_to_initialize (expr);
6567 gfc_expr *rhs = e3rhs ? e3rhs : gfc_copy_expr (code->expr3);
6568 flag_realloc_lhs = 0;
6569 tmp = gfc_trans_assignment (init_expr, rhs, false, false, true,
6570 false);
6571 flag_realloc_lhs = realloc_lhs;
6572 /* Free the expression allocated for init_expr. */
6573 gfc_free_expr (init_expr);
6574 if (rhs != e3rhs)
6575 gfc_free_expr (rhs);
6576 gfc_add_expr_to_block (&block, tmp);
6578 /* Set KIND and LEN PDT components and allocate those that are
6579 parameterized. */
6580 else if (expr->ts.type == BT_DERIVED
6581 && expr->ts.u.derived->attr.pdt_type)
6583 if (code->expr3 && code->expr3->param_list)
6584 param_list = code->expr3->param_list;
6585 else if (expr->param_list)
6586 param_list = expr->param_list;
6587 else
6588 param_list = expr->symtree->n.sym->param_list;
6589 tmp = gfc_allocate_pdt_comp (expr->ts.u.derived, se.expr,
6590 expr->rank, param_list);
6591 gfc_add_expr_to_block (&block, tmp);
6593 /* Ditto for CLASS expressions. */
6594 else if (expr->ts.type == BT_CLASS
6595 && CLASS_DATA (expr)->ts.u.derived->attr.pdt_type)
6597 if (code->expr3 && code->expr3->param_list)
6598 param_list = code->expr3->param_list;
6599 else if (expr->param_list)
6600 param_list = expr->param_list;
6601 else
6602 param_list = expr->symtree->n.sym->param_list;
6603 tmp = gfc_allocate_pdt_comp (CLASS_DATA (expr)->ts.u.derived,
6604 se.expr, expr->rank, param_list);
6605 gfc_add_expr_to_block (&block, tmp);
6607 else if (code->expr3 && code->expr3->mold
6608 && code->expr3->ts.type == BT_CLASS)
6610 /* Use class_init_assign to initialize expr. */
6611 gfc_code *ini;
6612 ini = gfc_get_code (EXEC_INIT_ASSIGN);
6613 ini->expr1 = gfc_find_and_cut_at_last_class_ref (expr);
6614 tmp = gfc_trans_class_init_assign (ini);
6615 gfc_free_statements (ini);
6616 gfc_add_expr_to_block (&block, tmp);
6618 else if ((init_expr = allocate_get_initializer (code, expr)))
6620 /* Use class_init_assign to initialize expr. */
6621 gfc_code *ini;
6622 int realloc_lhs = flag_realloc_lhs;
6623 ini = gfc_get_code (EXEC_INIT_ASSIGN);
6624 ini->expr1 = gfc_expr_to_initialize (expr);
6625 ini->expr2 = init_expr;
6626 flag_realloc_lhs = 0;
6627 tmp= gfc_trans_init_assign (ini);
6628 flag_realloc_lhs = realloc_lhs;
6629 gfc_free_statements (ini);
6630 /* Init_expr is freeed by above free_statements, just need to null
6631 it here. */
6632 init_expr = NULL;
6633 gfc_add_expr_to_block (&block, tmp);
6636 /* Nullify all pointers in derived type coarrays. This registers a
6637 token for them which allows their allocation. */
6638 if (is_coarray)
6640 gfc_symbol *type = NULL;
6641 symbol_attribute caf_attr;
6642 int rank = 0;
6643 if (code->ext.alloc.ts.type == BT_DERIVED
6644 && code->ext.alloc.ts.u.derived->attr.pointer_comp)
6646 type = code->ext.alloc.ts.u.derived;
6647 rank = type->attr.dimension ? type->as->rank : 0;
6648 gfc_clear_attr (&caf_attr);
6650 else if (expr->ts.type == BT_DERIVED
6651 && expr->ts.u.derived->attr.pointer_comp)
6653 type = expr->ts.u.derived;
6654 rank = expr->rank;
6655 caf_attr = gfc_caf_attr (expr, true);
6658 /* Initialize the tokens of pointer components in derived type
6659 coarrays. */
6660 if (type)
6662 tmp = (caf_attr.codimension && !caf_attr.dimension)
6663 ? gfc_conv_descriptor_data_get (se.expr) : se.expr;
6664 tmp = gfc_nullify_alloc_comp (type, tmp, rank,
6665 GFC_STRUCTURE_CAF_MODE_IN_COARRAY);
6666 gfc_add_expr_to_block (&block, tmp);
6670 gfc_free_expr (expr);
6671 } // for-loop
6673 if (e3rhs)
6675 if (newsym)
6677 gfc_free_symbol (newsym->n.sym);
6678 XDELETE (newsym);
6680 gfc_free_expr (e3rhs);
6682 /* STAT. */
6683 if (code->expr1)
6685 tmp = build1_v (LABEL_EXPR, label_errmsg);
6686 gfc_add_expr_to_block (&block, tmp);
6689 /* ERRMSG - only useful if STAT is present. */
6690 if (code->expr1 && code->expr2)
6692 const char *msg = "Attempt to allocate an allocated object";
6693 tree slen, dlen, errmsg_str;
6694 stmtblock_t errmsg_block;
6696 gfc_init_block (&errmsg_block);
6698 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6699 gfc_add_modify (&errmsg_block, errmsg_str,
6700 gfc_build_addr_expr (pchar_type_node,
6701 gfc_build_localized_cstring_const (msg)));
6703 slen = build_int_cst (gfc_charlen_type_node, strlen (msg));
6704 dlen = gfc_get_expr_charlen (code->expr2);
6705 slen = fold_build2_loc (input_location, MIN_EXPR,
6706 TREE_TYPE (slen), dlen, slen);
6708 gfc_trans_string_copy (&errmsg_block, dlen, errmsg,
6709 code->expr2->ts.kind,
6710 slen, errmsg_str,
6711 gfc_default_character_kind);
6712 dlen = gfc_finish_block (&errmsg_block);
6714 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
6715 stat, build_int_cst (TREE_TYPE (stat), 0));
6717 tmp = build3_v (COND_EXPR, tmp,
6718 dlen, build_empty_stmt (input_location));
6720 gfc_add_expr_to_block (&block, tmp);
6723 /* STAT block. */
6724 if (code->expr1)
6726 if (TREE_USED (label_finish))
6728 tmp = build1_v (LABEL_EXPR, label_finish);
6729 gfc_add_expr_to_block (&block, tmp);
6732 gfc_init_se (&se, NULL);
6733 gfc_conv_expr_lhs (&se, code->expr1);
6734 tmp = convert (TREE_TYPE (se.expr), stat);
6735 gfc_add_modify (&block, se.expr, tmp);
6738 if (needs_caf_sync)
6740 /* Add a sync all after the allocation has been executed. */
6741 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
6742 3, null_pointer_node, null_pointer_node,
6743 integer_zero_node);
6744 gfc_add_expr_to_block (&post, tmp);
6747 gfc_add_block_to_block (&block, &se.post);
6748 gfc_add_block_to_block (&block, &post);
6750 return gfc_finish_block (&block);
6754 /* Translate a DEALLOCATE statement. */
6756 tree
6757 gfc_trans_deallocate (gfc_code *code)
6759 gfc_se se;
6760 gfc_alloc *al;
6761 tree apstat, pstat, stat, errmsg, errlen, tmp;
6762 tree label_finish, label_errmsg;
6763 stmtblock_t block;
6765 pstat = apstat = stat = errmsg = errlen = tmp = NULL_TREE;
6766 label_finish = label_errmsg = NULL_TREE;
6768 gfc_start_block (&block);
6770 /* Count the number of failed deallocations. If deallocate() was
6771 called with STAT= , then set STAT to the count. If deallocate
6772 was called with ERRMSG, then set ERRMG to a string. */
6773 if (code->expr1)
6775 tree gfc_int4_type_node = gfc_get_int_type (4);
6777 stat = gfc_create_var (gfc_int4_type_node, "stat");
6778 pstat = gfc_build_addr_expr (NULL_TREE, stat);
6780 /* GOTO destinations. */
6781 label_errmsg = gfc_build_label_decl (NULL_TREE);
6782 label_finish = gfc_build_label_decl (NULL_TREE);
6783 TREE_USED (label_finish) = 0;
6786 /* Set ERRMSG - only needed if STAT is available. */
6787 if (code->expr1 && code->expr2)
6789 gfc_init_se (&se, NULL);
6790 se.want_pointer = 1;
6791 gfc_conv_expr_lhs (&se, code->expr2);
6792 errmsg = se.expr;
6793 errlen = se.string_length;
6796 for (al = code->ext.alloc.list; al != NULL; al = al->next)
6798 gfc_expr *expr = gfc_copy_expr (al->expr);
6799 bool is_coarray = false, is_coarray_array = false;
6800 int caf_mode = 0;
6802 gcc_assert (expr->expr_type == EXPR_VARIABLE);
6804 if (expr->ts.type == BT_CLASS)
6805 gfc_add_data_component (expr);
6807 gfc_init_se (&se, NULL);
6808 gfc_start_block (&se.pre);
6810 se.want_pointer = 1;
6811 se.descriptor_only = 1;
6812 gfc_conv_expr (&se, expr);
6814 /* Deallocate PDT components that are parameterized. */
6815 tmp = NULL;
6816 if (expr->ts.type == BT_DERIVED
6817 && expr->ts.u.derived->attr.pdt_type
6818 && expr->symtree->n.sym->param_list)
6819 tmp = gfc_deallocate_pdt_comp (expr->ts.u.derived, se.expr, expr->rank);
6820 else if (expr->ts.type == BT_CLASS
6821 && CLASS_DATA (expr)->ts.u.derived->attr.pdt_type
6822 && expr->symtree->n.sym->param_list)
6823 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr)->ts.u.derived,
6824 se.expr, expr->rank);
6826 if (tmp)
6827 gfc_add_expr_to_block (&block, tmp);
6829 if (flag_coarray == GFC_FCOARRAY_LIB
6830 || flag_coarray == GFC_FCOARRAY_SINGLE)
6832 bool comp_ref;
6833 symbol_attribute caf_attr = gfc_caf_attr (expr, false, &comp_ref);
6834 if (caf_attr.codimension)
6836 is_coarray = true;
6837 is_coarray_array = caf_attr.dimension || !comp_ref
6838 || caf_attr.coarray_comp;
6840 if (flag_coarray == GFC_FCOARRAY_LIB)
6841 /* When the expression to deallocate is referencing a
6842 component, then only deallocate it, but do not
6843 deregister. */
6844 caf_mode = GFC_STRUCTURE_CAF_MODE_IN_COARRAY
6845 | (comp_ref && !caf_attr.coarray_comp
6846 ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY : 0);
6850 if (expr->rank || is_coarray_array)
6852 gfc_ref *ref;
6854 if (gfc_bt_struct (expr->ts.type)
6855 && expr->ts.u.derived->attr.alloc_comp
6856 && !gfc_is_finalizable (expr->ts.u.derived, NULL))
6858 gfc_ref *last = NULL;
6860 for (ref = expr->ref; ref; ref = ref->next)
6861 if (ref->type == REF_COMPONENT)
6862 last = ref;
6864 /* Do not deallocate the components of a derived type
6865 ultimate pointer component. */
6866 if (!(last && last->u.c.component->attr.pointer)
6867 && !(!last && expr->symtree->n.sym->attr.pointer))
6869 if (is_coarray && expr->rank == 0
6870 && (!last || !last->u.c.component->attr.dimension)
6871 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
6873 /* Add the ref to the data member only, when this is not
6874 a regular array or deallocate_alloc_comp will try to
6875 add another one. */
6876 tmp = gfc_conv_descriptor_data_get (se.expr);
6878 else
6879 tmp = se.expr;
6880 tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp,
6881 expr->rank, caf_mode);
6882 gfc_add_expr_to_block (&se.pre, tmp);
6886 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
6888 gfc_coarray_deregtype caf_dtype;
6890 if (is_coarray)
6891 caf_dtype = gfc_caf_is_dealloc_only (caf_mode)
6892 ? GFC_CAF_COARRAY_DEALLOCATE_ONLY
6893 : GFC_CAF_COARRAY_DEREGISTER;
6894 else
6895 caf_dtype = GFC_CAF_COARRAY_NOCOARRAY;
6896 tmp = gfc_deallocate_with_status (se.expr, pstat, errmsg, errlen,
6897 label_finish, false, expr,
6898 caf_dtype);
6899 gfc_add_expr_to_block (&se.pre, tmp);
6901 else if (TREE_CODE (se.expr) == COMPONENT_REF
6902 && TREE_CODE (TREE_TYPE (se.expr)) == ARRAY_TYPE
6903 && TREE_CODE (TREE_TYPE (TREE_TYPE (se.expr)))
6904 == RECORD_TYPE)
6906 /* class.c(finalize_component) generates these, when a
6907 finalizable entity has a non-allocatable derived type array
6908 component, which has allocatable components. Obtain the
6909 derived type of the array and deallocate the allocatable
6910 components. */
6911 for (ref = expr->ref; ref; ref = ref->next)
6913 if (ref->u.c.component->attr.dimension
6914 && ref->u.c.component->ts.type == BT_DERIVED)
6915 break;
6918 if (ref && ref->u.c.component->ts.u.derived->attr.alloc_comp
6919 && !gfc_is_finalizable (ref->u.c.component->ts.u.derived,
6920 NULL))
6922 tmp = gfc_deallocate_alloc_comp
6923 (ref->u.c.component->ts.u.derived,
6924 se.expr, expr->rank);
6925 gfc_add_expr_to_block (&se.pre, tmp);
6929 if (al->expr->ts.type == BT_CLASS)
6931 gfc_reset_vptr (&se.pre, al->expr);
6932 if (UNLIMITED_POLY (al->expr)
6933 || (al->expr->ts.type == BT_DERIVED
6934 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6935 /* Clear _len, too. */
6936 gfc_reset_len (&se.pre, al->expr);
6939 else
6941 tmp = gfc_deallocate_scalar_with_status (se.expr, pstat, label_finish,
6942 false, al->expr,
6943 al->expr->ts, is_coarray);
6944 gfc_add_expr_to_block (&se.pre, tmp);
6946 /* Set to zero after deallocation. */
6947 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
6948 se.expr,
6949 build_int_cst (TREE_TYPE (se.expr), 0));
6950 gfc_add_expr_to_block (&se.pre, tmp);
6952 if (al->expr->ts.type == BT_CLASS)
6954 gfc_reset_vptr (&se.pre, al->expr);
6955 if (UNLIMITED_POLY (al->expr)
6956 || (al->expr->ts.type == BT_DERIVED
6957 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6958 /* Clear _len, too. */
6959 gfc_reset_len (&se.pre, al->expr);
6963 if (code->expr1)
6965 tree cond;
6967 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, stat,
6968 build_int_cst (TREE_TYPE (stat), 0));
6969 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6970 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
6971 build1_v (GOTO_EXPR, label_errmsg),
6972 build_empty_stmt (input_location));
6973 gfc_add_expr_to_block (&se.pre, tmp);
6976 tmp = gfc_finish_block (&se.pre);
6977 gfc_add_expr_to_block (&block, tmp);
6978 gfc_free_expr (expr);
6981 if (code->expr1)
6983 tmp = build1_v (LABEL_EXPR, label_errmsg);
6984 gfc_add_expr_to_block (&block, tmp);
6987 /* Set ERRMSG - only needed if STAT is available. */
6988 if (code->expr1 && code->expr2)
6990 const char *msg = "Attempt to deallocate an unallocated object";
6991 stmtblock_t errmsg_block;
6992 tree errmsg_str, slen, dlen, cond;
6994 gfc_init_block (&errmsg_block);
6996 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6997 gfc_add_modify (&errmsg_block, errmsg_str,
6998 gfc_build_addr_expr (pchar_type_node,
6999 gfc_build_localized_cstring_const (msg)));
7000 slen = build_int_cst (gfc_charlen_type_node, strlen (msg));
7001 dlen = gfc_get_expr_charlen (code->expr2);
7003 gfc_trans_string_copy (&errmsg_block, dlen, errmsg, code->expr2->ts.kind,
7004 slen, errmsg_str, gfc_default_character_kind);
7005 tmp = gfc_finish_block (&errmsg_block);
7007 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, stat,
7008 build_int_cst (TREE_TYPE (stat), 0));
7009 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
7010 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC), tmp,
7011 build_empty_stmt (input_location));
7013 gfc_add_expr_to_block (&block, tmp);
7016 if (code->expr1 && TREE_USED (label_finish))
7018 tmp = build1_v (LABEL_EXPR, label_finish);
7019 gfc_add_expr_to_block (&block, tmp);
7022 /* Set STAT. */
7023 if (code->expr1)
7025 gfc_init_se (&se, NULL);
7026 gfc_conv_expr_lhs (&se, code->expr1);
7027 tmp = convert (TREE_TYPE (se.expr), stat);
7028 gfc_add_modify (&block, se.expr, tmp);
7031 return gfc_finish_block (&block);
7034 #include "gt-fortran-trans-stmt.h"