2018-05-27 Steven G. Kargl <kargl@gcc.gnu.org>
[official-gcc.git] / gcc / fortran / trans-stmt.c
blobcc1a42943277328efbcfc109d6582c186bb25c14
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 = gfc_get_array_span (se.expr, e);
1740 gfc_conv_descriptor_span_set (&se.pre, desc, tmp);
1743 if (e->expr_type == EXPR_FUNCTION
1744 && sym->ts.type == BT_DERIVED
1745 && sym->ts.u.derived
1746 && sym->ts.u.derived->attr.pdt_type)
1748 tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived, se.expr,
1749 sym->as->rank);
1750 gfc_add_expr_to_block (&se.post, tmp);
1753 /* Done, register stuff as init / cleanup code. */
1754 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1755 gfc_finish_block (&se.post));
1758 /* Temporaries, arising from TYPE IS, just need the descriptor of class
1759 arrays to be assigned directly. */
1760 else if (class_target && sym->attr.dimension
1761 && (sym->ts.type == BT_DERIVED || unlimited))
1763 gfc_se se;
1765 gfc_init_se (&se, NULL);
1766 se.descriptor_only = 1;
1767 /* In a select type the (temporary) associate variable shall point to
1768 a standard fortran array (lower bound == 1), but conv_expr ()
1769 just maps to the input array in the class object, whose lbound may
1770 be arbitrary. conv_expr_descriptor solves this by inserting a
1771 temporary array descriptor. */
1772 gfc_conv_expr_descriptor (&se, e);
1774 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
1775 || GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)));
1776 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)));
1778 if (GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)))
1780 if (INDIRECT_REF_P (se.expr))
1781 tmp = TREE_OPERAND (se.expr, 0);
1782 else
1783 tmp = se.expr;
1785 gfc_add_modify (&se.pre, sym->backend_decl,
1786 gfc_class_data_get (GFC_DECL_SAVED_DESCRIPTOR (tmp)));
1788 else
1789 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
1791 if (unlimited)
1793 /* Recover the dtype, which has been overwritten by the
1794 assignment from an unlimited polymorphic object. */
1795 tmp = gfc_conv_descriptor_dtype (sym->backend_decl);
1796 gfc_add_modify (&se.pre, tmp,
1797 gfc_get_dtype (TREE_TYPE (sym->backend_decl)));
1800 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1801 gfc_finish_block (&se.post));
1804 /* Do a scalar pointer assignment; this is for scalar variable targets. */
1805 else if (gfc_is_associate_pointer (sym))
1807 gfc_se se;
1809 gcc_assert (!sym->attr.dimension);
1811 gfc_init_se (&se, NULL);
1813 /* Class associate-names come this way because they are
1814 unconditionally associate pointers and the symbol is scalar. */
1815 if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.dimension)
1817 tree target_expr;
1818 /* For a class array we need a descriptor for the selector. */
1819 gfc_conv_expr_descriptor (&se, e);
1820 /* Needed to get/set the _len component below. */
1821 target_expr = se.expr;
1823 /* Obtain a temporary class container for the result. */
1824 gfc_conv_class_to_class (&se, e, sym->ts, false, true, false, false);
1825 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1827 /* Set the offset. */
1828 desc = gfc_class_data_get (se.expr);
1829 offset = gfc_index_zero_node;
1830 for (n = 0; n < e->rank; n++)
1832 dim = gfc_rank_cst[n];
1833 tmp = fold_build2_loc (input_location, MULT_EXPR,
1834 gfc_array_index_type,
1835 gfc_conv_descriptor_stride_get (desc, dim),
1836 gfc_conv_descriptor_lbound_get (desc, dim));
1837 offset = fold_build2_loc (input_location, MINUS_EXPR,
1838 gfc_array_index_type,
1839 offset, tmp);
1841 if (need_len_assign)
1843 if (e->symtree
1844 && DECL_LANG_SPECIFIC (e->symtree->n.sym->backend_decl)
1845 && GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl))
1846 /* Use the original class descriptor stored in the saved
1847 descriptor to get the target_expr. */
1848 target_expr =
1849 GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl);
1850 else
1851 /* Strip the _data component from the target_expr. */
1852 target_expr = TREE_OPERAND (target_expr, 0);
1853 /* Add a reference to the _len comp to the target expr. */
1854 tmp = gfc_class_len_get (target_expr);
1855 /* Get the component-ref for the temp structure's _len comp. */
1856 charlen = gfc_class_len_get (se.expr);
1857 /* Add the assign to the beginning of the block... */
1858 gfc_add_modify (&se.pre, charlen,
1859 fold_convert (TREE_TYPE (charlen), tmp));
1860 /* and the oposite way at the end of the block, to hand changes
1861 on the string length back. */
1862 gfc_add_modify (&se.post, tmp,
1863 fold_convert (TREE_TYPE (tmp), charlen));
1864 /* Length assignment done, prevent adding it again below. */
1865 need_len_assign = false;
1867 gfc_conv_descriptor_offset_set (&se.pre, desc, offset);
1869 else if (sym->ts.type == BT_CLASS && e->ts.type == BT_CLASS
1870 && CLASS_DATA (e)->attr.dimension)
1872 /* This is bound to be a class array element. */
1873 gfc_conv_expr_reference (&se, e);
1874 /* Get the _vptr component of the class object. */
1875 tmp = gfc_get_vptr_from_expr (se.expr);
1876 /* Obtain a temporary class container for the result. */
1877 gfc_conv_derived_to_class (&se, e, sym->ts, tmp, false, false);
1878 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1880 else
1882 /* For BT_CLASS and BT_DERIVED, this boils down to a pointer assign,
1883 which has the string length included. For CHARACTERS it is still
1884 needed and will be done at the end of this routine. */
1885 gfc_conv_expr (&se, e);
1886 need_len_assign = need_len_assign && sym->ts.type == BT_CHARACTER;
1889 if (sym->ts.type == BT_CHARACTER
1890 && sym->ts.deferred
1891 && !sym->attr.select_type_temporary
1892 && VAR_P (sym->ts.u.cl->backend_decl)
1893 && se.string_length != sym->ts.u.cl->backend_decl)
1895 gfc_add_modify (&se.pre, sym->ts.u.cl->backend_decl,
1896 fold_convert (TREE_TYPE (sym->ts.u.cl->backend_decl),
1897 se.string_length));
1898 if (e->expr_type == EXPR_FUNCTION)
1900 tmp = gfc_call_free (sym->backend_decl);
1901 gfc_add_expr_to_block (&se.post, tmp);
1905 attr = gfc_expr_attr (e);
1906 if (sym->ts.type == BT_CHARACTER && e->ts.type == BT_CHARACTER
1907 && (attr.allocatable || attr.pointer || attr.dummy)
1908 && POINTER_TYPE_P (TREE_TYPE (se.expr)))
1910 /* These are pointer types already. */
1911 tmp = fold_convert (TREE_TYPE (sym->backend_decl), se.expr);
1913 else
1915 tmp = TREE_TYPE (sym->backend_decl);
1916 tmp = gfc_build_addr_expr (tmp, se.expr);
1919 gfc_add_modify (&se.pre, sym->backend_decl, tmp);
1921 gfc_add_init_cleanup (block, gfc_finish_block( &se.pre),
1922 gfc_finish_block (&se.post));
1925 /* Do a simple assignment. This is for scalar expressions, where we
1926 can simply use expression assignment. */
1927 else
1929 gfc_expr *lhs;
1930 tree res;
1931 gfc_se se;
1933 gfc_init_se (&se, NULL);
1935 /* resolve.c converts some associate names to allocatable so that
1936 allocation can take place automatically in gfc_trans_assignment.
1937 The frontend prevents them from being either allocated,
1938 deallocated or reallocated. */
1939 if (sym->attr.allocatable)
1941 tmp = sym->backend_decl;
1942 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
1943 tmp = gfc_conv_descriptor_data_get (tmp);
1944 gfc_add_modify (&se.pre, tmp, fold_convert (TREE_TYPE (tmp),
1945 null_pointer_node));
1948 lhs = gfc_lval_expr_from_sym (sym);
1949 res = gfc_trans_assignment (lhs, e, false, true);
1950 gfc_add_expr_to_block (&se.pre, res);
1952 tmp = sym->backend_decl;
1953 if (e->expr_type == EXPR_FUNCTION
1954 && sym->ts.type == BT_DERIVED
1955 && sym->ts.u.derived
1956 && sym->ts.u.derived->attr.pdt_type)
1958 tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived, tmp,
1961 else if (e->expr_type == EXPR_FUNCTION
1962 && sym->ts.type == BT_CLASS
1963 && CLASS_DATA (sym)->ts.u.derived
1964 && CLASS_DATA (sym)->ts.u.derived->attr.pdt_type)
1966 tmp = gfc_class_data_get (tmp);
1967 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (sym)->ts.u.derived,
1968 tmp, 0);
1970 else if (sym->attr.allocatable)
1972 tmp = sym->backend_decl;
1974 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
1975 tmp = gfc_conv_descriptor_data_get (tmp);
1977 /* A simple call to free suffices here. */
1978 tmp = gfc_call_free (tmp);
1980 /* Make sure that reallocation on assignment cannot occur. */
1981 sym->attr.allocatable = 0;
1983 else
1984 tmp = NULL_TREE;
1986 res = gfc_finish_block (&se.pre);
1987 gfc_add_init_cleanup (block, res, tmp);
1988 gfc_free_expr (lhs);
1991 /* Set the stringlength, when needed. */
1992 if (need_len_assign)
1994 gfc_se se;
1995 gfc_init_se (&se, NULL);
1996 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
1998 /* Deferred strings are dealt with in the preceeding. */
1999 gcc_assert (!e->symtree->n.sym->ts.deferred);
2000 tmp = e->symtree->n.sym->ts.u.cl->backend_decl;
2002 else if (e->symtree->n.sym->attr.function
2003 && e->symtree->n.sym == e->symtree->n.sym->result)
2005 tmp = gfc_get_fake_result_decl (e->symtree->n.sym, 0);
2006 tmp = gfc_class_len_get (tmp);
2008 else
2009 tmp = gfc_class_len_get (gfc_get_symbol_decl (e->symtree->n.sym));
2010 gfc_get_symbol_decl (sym);
2011 charlen = sym->ts.type == BT_CHARACTER ? sym->ts.u.cl->backend_decl
2012 : gfc_class_len_get (sym->backend_decl);
2013 /* Prevent adding a noop len= len. */
2014 if (tmp != charlen)
2016 gfc_add_modify (&se.pre, charlen,
2017 fold_convert (TREE_TYPE (charlen), tmp));
2018 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
2019 gfc_finish_block (&se.post));
2025 /* Translate a BLOCK construct. This is basically what we would do for a
2026 procedure body. */
2028 tree
2029 gfc_trans_block_construct (gfc_code* code)
2031 gfc_namespace* ns;
2032 gfc_symbol* sym;
2033 gfc_wrapped_block block;
2034 tree exit_label;
2035 stmtblock_t body;
2036 gfc_association_list *ass;
2038 ns = code->ext.block.ns;
2039 gcc_assert (ns);
2040 sym = ns->proc_name;
2041 gcc_assert (sym);
2043 /* Process local variables. */
2044 gcc_assert (!sym->tlink);
2045 sym->tlink = sym;
2046 gfc_process_block_locals (ns);
2048 /* Generate code including exit-label. */
2049 gfc_init_block (&body);
2050 exit_label = gfc_build_label_decl (NULL_TREE);
2051 code->exit_label = exit_label;
2053 finish_oacc_declare (ns, sym, true);
2055 gfc_add_expr_to_block (&body, gfc_trans_code (ns->code));
2056 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
2058 /* Finish everything. */
2059 gfc_start_wrapped_block (&block, gfc_finish_block (&body));
2060 gfc_trans_deferred_vars (sym, &block);
2061 for (ass = code->ext.block.assoc; ass; ass = ass->next)
2062 trans_associate_var (ass->st->n.sym, &block);
2064 return gfc_finish_wrapped_block (&block);
2067 /* Translate the simple DO construct in a C-style manner.
2068 This is where the loop variable has integer type and step +-1.
2069 Following code will generate infinite loop in case where TO is INT_MAX
2070 (for +1 step) or INT_MIN (for -1 step)
2072 We translate a do loop from:
2074 DO dovar = from, to, step
2075 body
2076 END DO
2080 [Evaluate loop bounds and step]
2081 dovar = from;
2082 for (;;)
2084 if (dovar > to)
2085 goto end_label;
2086 body;
2087 cycle_label:
2088 dovar += step;
2090 end_label:
2092 This helps the optimizers by avoiding the extra pre-header condition and
2093 we save a register as we just compare the updated IV (not a value in
2094 previous step). */
2096 static tree
2097 gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
2098 tree from, tree to, tree step, tree exit_cond)
2100 stmtblock_t body;
2101 tree type;
2102 tree cond;
2103 tree tmp;
2104 tree saved_dovar = NULL;
2105 tree cycle_label;
2106 tree exit_label;
2107 location_t loc;
2108 type = TREE_TYPE (dovar);
2109 bool is_step_positive = tree_int_cst_sgn (step) > 0;
2111 loc = code->ext.iterator->start->where.lb->location;
2113 /* Initialize the DO variable: dovar = from. */
2114 gfc_add_modify_loc (loc, pblock, dovar,
2115 fold_convert (TREE_TYPE (dovar), from));
2117 /* Save value for do-tinkering checking. */
2118 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2120 saved_dovar = gfc_create_var (type, ".saved_dovar");
2121 gfc_add_modify_loc (loc, pblock, saved_dovar, dovar);
2124 /* Cycle and exit statements are implemented with gotos. */
2125 cycle_label = gfc_build_label_decl (NULL_TREE);
2126 exit_label = gfc_build_label_decl (NULL_TREE);
2128 /* Put the labels where they can be found later. See gfc_trans_do(). */
2129 code->cycle_label = cycle_label;
2130 code->exit_label = exit_label;
2132 /* Loop body. */
2133 gfc_start_block (&body);
2135 /* Exit the loop if there is an I/O result condition or error. */
2136 if (exit_cond)
2138 tmp = build1_v (GOTO_EXPR, exit_label);
2139 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2140 exit_cond, tmp,
2141 build_empty_stmt (loc));
2142 gfc_add_expr_to_block (&body, tmp);
2145 /* Evaluate the loop condition. */
2146 if (is_step_positive)
2147 cond = fold_build2_loc (loc, GT_EXPR, logical_type_node, dovar,
2148 fold_convert (type, to));
2149 else
2150 cond = fold_build2_loc (loc, LT_EXPR, logical_type_node, dovar,
2151 fold_convert (type, to));
2153 cond = gfc_evaluate_now_loc (loc, cond, &body);
2154 if (code->ext.iterator->unroll && cond != error_mark_node)
2155 cond
2156 = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2157 build_int_cst (integer_type_node, annot_expr_unroll_kind),
2158 build_int_cst (integer_type_node, code->ext.iterator->unroll));
2160 /* The loop exit. */
2161 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
2162 TREE_USED (exit_label) = 1;
2163 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2164 cond, tmp, build_empty_stmt (loc));
2165 gfc_add_expr_to_block (&body, tmp);
2167 /* Check whether the induction variable is equal to INT_MAX
2168 (respectively to INT_MIN). */
2169 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2171 tree boundary = is_step_positive ? TYPE_MAX_VALUE (type)
2172 : TYPE_MIN_VALUE (type);
2174 tmp = fold_build2_loc (loc, EQ_EXPR, logical_type_node,
2175 dovar, boundary);
2176 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2177 "Loop iterates infinitely");
2180 /* Main loop body. */
2181 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
2182 gfc_add_expr_to_block (&body, tmp);
2184 /* Label for cycle statements (if needed). */
2185 if (TREE_USED (cycle_label))
2187 tmp = build1_v (LABEL_EXPR, cycle_label);
2188 gfc_add_expr_to_block (&body, tmp);
2191 /* Check whether someone has modified the loop variable. */
2192 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2194 tmp = fold_build2_loc (loc, NE_EXPR, logical_type_node,
2195 dovar, saved_dovar);
2196 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2197 "Loop variable has been modified");
2200 /* Increment the loop variable. */
2201 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
2202 gfc_add_modify_loc (loc, &body, dovar, tmp);
2204 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2205 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
2207 /* Finish the loop body. */
2208 tmp = gfc_finish_block (&body);
2209 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
2211 gfc_add_expr_to_block (pblock, tmp);
2213 /* Add the exit label. */
2214 tmp = build1_v (LABEL_EXPR, exit_label);
2215 gfc_add_expr_to_block (pblock, tmp);
2217 return gfc_finish_block (pblock);
2220 /* Translate the DO construct. This obviously is one of the most
2221 important ones to get right with any compiler, but especially
2222 so for Fortran.
2224 We special case some loop forms as described in gfc_trans_simple_do.
2225 For other cases we implement them with a separate loop count,
2226 as described in the standard.
2228 We translate a do loop from:
2230 DO dovar = from, to, step
2231 body
2232 END DO
2236 [evaluate loop bounds and step]
2237 empty = (step > 0 ? to < from : to > from);
2238 countm1 = (to - from) / step;
2239 dovar = from;
2240 if (empty) goto exit_label;
2241 for (;;)
2243 body;
2244 cycle_label:
2245 dovar += step
2246 countm1t = countm1;
2247 countm1--;
2248 if (countm1t == 0) goto exit_label;
2250 exit_label:
2252 countm1 is an unsigned integer. It is equal to the loop count minus one,
2253 because the loop count itself can overflow. */
2255 tree
2256 gfc_trans_do (gfc_code * code, tree exit_cond)
2258 gfc_se se;
2259 tree dovar;
2260 tree saved_dovar = NULL;
2261 tree from;
2262 tree to;
2263 tree step;
2264 tree countm1;
2265 tree type;
2266 tree utype;
2267 tree cond;
2268 tree cycle_label;
2269 tree exit_label;
2270 tree tmp;
2271 stmtblock_t block;
2272 stmtblock_t body;
2273 location_t loc;
2275 gfc_start_block (&block);
2277 loc = code->ext.iterator->start->where.lb->location;
2279 /* Evaluate all the expressions in the iterator. */
2280 gfc_init_se (&se, NULL);
2281 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
2282 gfc_add_block_to_block (&block, &se.pre);
2283 dovar = se.expr;
2284 type = TREE_TYPE (dovar);
2286 gfc_init_se (&se, NULL);
2287 gfc_conv_expr_val (&se, code->ext.iterator->start);
2288 gfc_add_block_to_block (&block, &se.pre);
2289 from = gfc_evaluate_now (se.expr, &block);
2291 gfc_init_se (&se, NULL);
2292 gfc_conv_expr_val (&se, code->ext.iterator->end);
2293 gfc_add_block_to_block (&block, &se.pre);
2294 to = gfc_evaluate_now (se.expr, &block);
2296 gfc_init_se (&se, NULL);
2297 gfc_conv_expr_val (&se, code->ext.iterator->step);
2298 gfc_add_block_to_block (&block, &se.pre);
2299 step = gfc_evaluate_now (se.expr, &block);
2301 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2303 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, step,
2304 build_zero_cst (type));
2305 gfc_trans_runtime_check (true, false, tmp, &block, &code->loc,
2306 "DO step value is zero");
2309 /* Special case simple loops. */
2310 if (TREE_CODE (type) == INTEGER_TYPE
2311 && (integer_onep (step)
2312 || tree_int_cst_equal (step, integer_minus_one_node)))
2313 return gfc_trans_simple_do (code, &block, dovar, from, to, step,
2314 exit_cond);
2316 if (TREE_CODE (type) == INTEGER_TYPE)
2317 utype = unsigned_type_for (type);
2318 else
2319 utype = unsigned_type_for (gfc_array_index_type);
2320 countm1 = gfc_create_var (utype, "countm1");
2322 /* Cycle and exit statements are implemented with gotos. */
2323 cycle_label = gfc_build_label_decl (NULL_TREE);
2324 exit_label = gfc_build_label_decl (NULL_TREE);
2325 TREE_USED (exit_label) = 1;
2327 /* Put these labels where they can be found later. */
2328 code->cycle_label = cycle_label;
2329 code->exit_label = exit_label;
2331 /* Initialize the DO variable: dovar = from. */
2332 gfc_add_modify (&block, dovar, from);
2334 /* Save value for do-tinkering checking. */
2335 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2337 saved_dovar = gfc_create_var (type, ".saved_dovar");
2338 gfc_add_modify_loc (loc, &block, saved_dovar, dovar);
2341 /* Initialize loop count and jump to exit label if the loop is empty.
2342 This code is executed before we enter the loop body. We generate:
2343 if (step > 0)
2345 countm1 = (to - from) / step;
2346 if (to < from)
2347 goto exit_label;
2349 else
2351 countm1 = (from - to) / -step;
2352 if (to > from)
2353 goto exit_label;
2357 if (TREE_CODE (type) == INTEGER_TYPE)
2359 tree pos, neg, tou, fromu, stepu, tmp2;
2361 /* The distance from FROM to TO cannot always be represented in a signed
2362 type, thus use unsigned arithmetic, also to avoid any undefined
2363 overflow issues. */
2364 tou = fold_convert (utype, to);
2365 fromu = fold_convert (utype, from);
2366 stepu = fold_convert (utype, step);
2368 /* For a positive step, when to < from, exit, otherwise compute
2369 countm1 = ((unsigned)to - (unsigned)from) / (unsigned)step */
2370 tmp = fold_build2_loc (loc, LT_EXPR, logical_type_node, to, from);
2371 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2372 fold_build2_loc (loc, MINUS_EXPR, utype,
2373 tou, fromu),
2374 stepu);
2375 pos = build2 (COMPOUND_EXPR, void_type_node,
2376 fold_build2 (MODIFY_EXPR, void_type_node,
2377 countm1, tmp2),
2378 build3_loc (loc, COND_EXPR, void_type_node,
2379 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
2380 build1_loc (loc, GOTO_EXPR, void_type_node,
2381 exit_label), NULL_TREE));
2383 /* For a negative step, when to > from, exit, otherwise compute
2384 countm1 = ((unsigned)from - (unsigned)to) / -(unsigned)step */
2385 tmp = fold_build2_loc (loc, GT_EXPR, logical_type_node, to, from);
2386 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2387 fold_build2_loc (loc, MINUS_EXPR, utype,
2388 fromu, tou),
2389 fold_build1_loc (loc, NEGATE_EXPR, utype, stepu));
2390 neg = build2 (COMPOUND_EXPR, void_type_node,
2391 fold_build2 (MODIFY_EXPR, void_type_node,
2392 countm1, tmp2),
2393 build3_loc (loc, COND_EXPR, void_type_node,
2394 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
2395 build1_loc (loc, GOTO_EXPR, void_type_node,
2396 exit_label), NULL_TREE));
2398 tmp = fold_build2_loc (loc, LT_EXPR, logical_type_node, step,
2399 build_int_cst (TREE_TYPE (step), 0));
2400 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp, neg, pos);
2402 gfc_add_expr_to_block (&block, tmp);
2404 else
2406 tree pos_step;
2408 /* TODO: We could use the same width as the real type.
2409 This would probably cause more problems that it solves
2410 when we implement "long double" types. */
2412 tmp = fold_build2_loc (loc, MINUS_EXPR, type, to, from);
2413 tmp = fold_build2_loc (loc, RDIV_EXPR, type, tmp, step);
2414 tmp = fold_build1_loc (loc, FIX_TRUNC_EXPR, utype, tmp);
2415 gfc_add_modify (&block, countm1, tmp);
2417 /* We need a special check for empty loops:
2418 empty = (step > 0 ? to < from : to > from); */
2419 pos_step = fold_build2_loc (loc, GT_EXPR, logical_type_node, step,
2420 build_zero_cst (type));
2421 tmp = fold_build3_loc (loc, COND_EXPR, logical_type_node, pos_step,
2422 fold_build2_loc (loc, LT_EXPR,
2423 logical_type_node, to, from),
2424 fold_build2_loc (loc, GT_EXPR,
2425 logical_type_node, to, from));
2426 /* If the loop is empty, go directly to the exit label. */
2427 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp,
2428 build1_v (GOTO_EXPR, exit_label),
2429 build_empty_stmt (input_location));
2430 gfc_add_expr_to_block (&block, tmp);
2433 /* Loop body. */
2434 gfc_start_block (&body);
2436 /* Main loop body. */
2437 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
2438 gfc_add_expr_to_block (&body, tmp);
2440 /* Label for cycle statements (if needed). */
2441 if (TREE_USED (cycle_label))
2443 tmp = build1_v (LABEL_EXPR, cycle_label);
2444 gfc_add_expr_to_block (&body, tmp);
2447 /* Check whether someone has modified the loop variable. */
2448 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2450 tmp = fold_build2_loc (loc, NE_EXPR, logical_type_node, dovar,
2451 saved_dovar);
2452 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2453 "Loop variable has been modified");
2456 /* Exit the loop if there is an I/O result condition or error. */
2457 if (exit_cond)
2459 tmp = build1_v (GOTO_EXPR, exit_label);
2460 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2461 exit_cond, tmp,
2462 build_empty_stmt (input_location));
2463 gfc_add_expr_to_block (&body, tmp);
2466 /* Increment the loop variable. */
2467 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
2468 gfc_add_modify_loc (loc, &body, dovar, tmp);
2470 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2471 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
2473 /* Initialize countm1t. */
2474 tree countm1t = gfc_create_var (utype, "countm1t");
2475 gfc_add_modify_loc (loc, &body, countm1t, countm1);
2477 /* Decrement the loop count. */
2478 tmp = fold_build2_loc (loc, MINUS_EXPR, utype, countm1,
2479 build_int_cst (utype, 1));
2480 gfc_add_modify_loc (loc, &body, countm1, tmp);
2482 /* End with the loop condition. Loop until countm1t == 0. */
2483 cond = fold_build2_loc (loc, EQ_EXPR, logical_type_node, countm1t,
2484 build_int_cst (utype, 0));
2485 if (code->ext.iterator->unroll && cond != error_mark_node)
2486 cond
2487 = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2488 build_int_cst (integer_type_node, annot_expr_unroll_kind),
2489 build_int_cst (integer_type_node, code->ext.iterator->unroll));
2490 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
2491 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2492 cond, tmp, build_empty_stmt (loc));
2493 gfc_add_expr_to_block (&body, tmp);
2495 /* End of loop body. */
2496 tmp = gfc_finish_block (&body);
2498 /* The for loop itself. */
2499 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
2500 gfc_add_expr_to_block (&block, tmp);
2502 /* Add the exit label. */
2503 tmp = build1_v (LABEL_EXPR, exit_label);
2504 gfc_add_expr_to_block (&block, tmp);
2506 return gfc_finish_block (&block);
2510 /* Translate the DO WHILE construct.
2512 We translate
2514 DO WHILE (cond)
2515 body
2516 END DO
2520 for ( ; ; )
2522 pre_cond;
2523 if (! cond) goto exit_label;
2524 body;
2525 cycle_label:
2527 exit_label:
2529 Because the evaluation of the exit condition `cond' may have side
2530 effects, we can't do much for empty loop bodies. The backend optimizers
2531 should be smart enough to eliminate any dead loops. */
2533 tree
2534 gfc_trans_do_while (gfc_code * code)
2536 gfc_se cond;
2537 tree tmp;
2538 tree cycle_label;
2539 tree exit_label;
2540 stmtblock_t block;
2542 /* Everything we build here is part of the loop body. */
2543 gfc_start_block (&block);
2545 /* Cycle and exit statements are implemented with gotos. */
2546 cycle_label = gfc_build_label_decl (NULL_TREE);
2547 exit_label = gfc_build_label_decl (NULL_TREE);
2549 /* Put the labels where they can be found later. See gfc_trans_do(). */
2550 code->cycle_label = cycle_label;
2551 code->exit_label = exit_label;
2553 /* Create a GIMPLE version of the exit condition. */
2554 gfc_init_se (&cond, NULL);
2555 gfc_conv_expr_val (&cond, code->expr1);
2556 gfc_add_block_to_block (&block, &cond.pre);
2557 cond.expr = fold_build1_loc (code->expr1->where.lb->location,
2558 TRUTH_NOT_EXPR, TREE_TYPE (cond.expr), cond.expr);
2560 /* Build "IF (! cond) GOTO exit_label". */
2561 tmp = build1_v (GOTO_EXPR, exit_label);
2562 TREE_USED (exit_label) = 1;
2563 tmp = fold_build3_loc (code->expr1->where.lb->location, COND_EXPR,
2564 void_type_node, cond.expr, tmp,
2565 build_empty_stmt (code->expr1->where.lb->location));
2566 gfc_add_expr_to_block (&block, tmp);
2568 /* The main body of the loop. */
2569 tmp = gfc_trans_code (code->block->next);
2570 gfc_add_expr_to_block (&block, tmp);
2572 /* Label for cycle statements (if needed). */
2573 if (TREE_USED (cycle_label))
2575 tmp = build1_v (LABEL_EXPR, cycle_label);
2576 gfc_add_expr_to_block (&block, tmp);
2579 /* End of loop body. */
2580 tmp = gfc_finish_block (&block);
2582 gfc_init_block (&block);
2583 /* Build the loop. */
2584 tmp = fold_build1_loc (code->expr1->where.lb->location, LOOP_EXPR,
2585 void_type_node, tmp);
2586 gfc_add_expr_to_block (&block, tmp);
2588 /* Add the exit label. */
2589 tmp = build1_v (LABEL_EXPR, exit_label);
2590 gfc_add_expr_to_block (&block, tmp);
2592 return gfc_finish_block (&block);
2596 /* Deal with the particular case of SELECT_TYPE, where the vtable
2597 addresses are used for the selection. Since these are not sorted,
2598 the selection has to be made by a series of if statements. */
2600 static tree
2601 gfc_trans_select_type_cases (gfc_code * code)
2603 gfc_code *c;
2604 gfc_case *cp;
2605 tree tmp;
2606 tree cond;
2607 tree low;
2608 tree high;
2609 gfc_se se;
2610 gfc_se cse;
2611 stmtblock_t block;
2612 stmtblock_t body;
2613 bool def = false;
2614 gfc_expr *e;
2615 gfc_start_block (&block);
2617 /* Calculate the switch expression. */
2618 gfc_init_se (&se, NULL);
2619 gfc_conv_expr_val (&se, code->expr1);
2620 gfc_add_block_to_block (&block, &se.pre);
2622 /* Generate an expression for the selector hash value, for
2623 use to resolve character cases. */
2624 e = gfc_copy_expr (code->expr1->value.function.actual->expr);
2625 gfc_add_hash_component (e);
2627 TREE_USED (code->exit_label) = 0;
2629 repeat:
2630 for (c = code->block; c; c = c->block)
2632 cp = c->ext.block.case_list;
2634 /* Assume it's the default case. */
2635 low = NULL_TREE;
2636 high = NULL_TREE;
2637 tmp = NULL_TREE;
2639 /* Put the default case at the end. */
2640 if ((!def && !cp->low) || (def && cp->low))
2641 continue;
2643 if (cp->low && (cp->ts.type == BT_CLASS
2644 || cp->ts.type == BT_DERIVED))
2646 gfc_init_se (&cse, NULL);
2647 gfc_conv_expr_val (&cse, cp->low);
2648 gfc_add_block_to_block (&block, &cse.pre);
2649 low = cse.expr;
2651 else if (cp->ts.type != BT_UNKNOWN)
2653 gcc_assert (cp->high);
2654 gfc_init_se (&cse, NULL);
2655 gfc_conv_expr_val (&cse, cp->high);
2656 gfc_add_block_to_block (&block, &cse.pre);
2657 high = cse.expr;
2660 gfc_init_block (&body);
2662 /* Add the statements for this case. */
2663 tmp = gfc_trans_code (c->next);
2664 gfc_add_expr_to_block (&body, tmp);
2666 /* Break to the end of the SELECT TYPE construct. The default
2667 case just falls through. */
2668 if (!def)
2670 TREE_USED (code->exit_label) = 1;
2671 tmp = build1_v (GOTO_EXPR, code->exit_label);
2672 gfc_add_expr_to_block (&body, tmp);
2675 tmp = gfc_finish_block (&body);
2677 if (low != NULL_TREE)
2679 /* Compare vtable pointers. */
2680 cond = fold_build2_loc (input_location, EQ_EXPR,
2681 TREE_TYPE (se.expr), se.expr, low);
2682 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2683 cond, tmp,
2684 build_empty_stmt (input_location));
2686 else if (high != NULL_TREE)
2688 /* Compare hash values for character cases. */
2689 gfc_init_se (&cse, NULL);
2690 gfc_conv_expr_val (&cse, e);
2691 gfc_add_block_to_block (&block, &cse.pre);
2693 cond = fold_build2_loc (input_location, EQ_EXPR,
2694 TREE_TYPE (se.expr), high, cse.expr);
2695 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2696 cond, tmp,
2697 build_empty_stmt (input_location));
2700 gfc_add_expr_to_block (&block, tmp);
2703 if (!def)
2705 def = true;
2706 goto repeat;
2709 gfc_free_expr (e);
2711 return gfc_finish_block (&block);
2715 /* Translate the SELECT CASE construct for INTEGER case expressions,
2716 without killing all potential optimizations. The problem is that
2717 Fortran allows unbounded cases, but the back-end does not, so we
2718 need to intercept those before we enter the equivalent SWITCH_EXPR
2719 we can build.
2721 For example, we translate this,
2723 SELECT CASE (expr)
2724 CASE (:100,101,105:115)
2725 block_1
2726 CASE (190:199,200:)
2727 block_2
2728 CASE (300)
2729 block_3
2730 CASE DEFAULT
2731 block_4
2732 END SELECT
2734 to the GENERIC equivalent,
2736 switch (expr)
2738 case (minimum value for typeof(expr) ... 100:
2739 case 101:
2740 case 105 ... 114:
2741 block1:
2742 goto end_label;
2744 case 200 ... (maximum value for typeof(expr):
2745 case 190 ... 199:
2746 block2;
2747 goto end_label;
2749 case 300:
2750 block_3;
2751 goto end_label;
2753 default:
2754 block_4;
2755 goto end_label;
2758 end_label: */
2760 static tree
2761 gfc_trans_integer_select (gfc_code * code)
2763 gfc_code *c;
2764 gfc_case *cp;
2765 tree end_label;
2766 tree tmp;
2767 gfc_se se;
2768 stmtblock_t block;
2769 stmtblock_t body;
2771 gfc_start_block (&block);
2773 /* Calculate the switch expression. */
2774 gfc_init_se (&se, NULL);
2775 gfc_conv_expr_val (&se, code->expr1);
2776 gfc_add_block_to_block (&block, &se.pre);
2778 end_label = gfc_build_label_decl (NULL_TREE);
2780 gfc_init_block (&body);
2782 for (c = code->block; c; c = c->block)
2784 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2786 tree low, high;
2787 tree label;
2789 /* Assume it's the default case. */
2790 low = high = NULL_TREE;
2792 if (cp->low)
2794 low = gfc_conv_mpz_to_tree (cp->low->value.integer,
2795 cp->low->ts.kind);
2797 /* If there's only a lower bound, set the high bound to the
2798 maximum value of the case expression. */
2799 if (!cp->high)
2800 high = TYPE_MAX_VALUE (TREE_TYPE (se.expr));
2803 if (cp->high)
2805 /* Three cases are possible here:
2807 1) There is no lower bound, e.g. CASE (:N).
2808 2) There is a lower bound .NE. high bound, that is
2809 a case range, e.g. CASE (N:M) where M>N (we make
2810 sure that M>N during type resolution).
2811 3) There is a lower bound, and it has the same value
2812 as the high bound, e.g. CASE (N:N). This is our
2813 internal representation of CASE(N).
2815 In the first and second case, we need to set a value for
2816 high. In the third case, we don't because the GCC middle
2817 end represents a single case value by just letting high be
2818 a NULL_TREE. We can't do that because we need to be able
2819 to represent unbounded cases. */
2821 if (!cp->low
2822 || (mpz_cmp (cp->low->value.integer,
2823 cp->high->value.integer) != 0))
2824 high = gfc_conv_mpz_to_tree (cp->high->value.integer,
2825 cp->high->ts.kind);
2827 /* Unbounded case. */
2828 if (!cp->low)
2829 low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
2832 /* Build a label. */
2833 label = gfc_build_label_decl (NULL_TREE);
2835 /* Add this case label.
2836 Add parameter 'label', make it match GCC backend. */
2837 tmp = build_case_label (low, high, label);
2838 gfc_add_expr_to_block (&body, tmp);
2841 /* Add the statements for this case. */
2842 tmp = gfc_trans_code (c->next);
2843 gfc_add_expr_to_block (&body, tmp);
2845 /* Break to the end of the construct. */
2846 tmp = build1_v (GOTO_EXPR, end_label);
2847 gfc_add_expr_to_block (&body, tmp);
2850 tmp = gfc_finish_block (&body);
2851 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE, se.expr, tmp);
2852 gfc_add_expr_to_block (&block, tmp);
2854 tmp = build1_v (LABEL_EXPR, end_label);
2855 gfc_add_expr_to_block (&block, tmp);
2857 return gfc_finish_block (&block);
2861 /* Translate the SELECT CASE construct for LOGICAL case expressions.
2863 There are only two cases possible here, even though the standard
2864 does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
2865 .FALSE., and DEFAULT.
2867 We never generate more than two blocks here. Instead, we always
2868 try to eliminate the DEFAULT case. This way, we can translate this
2869 kind of SELECT construct to a simple
2871 if {} else {};
2873 expression in GENERIC. */
2875 static tree
2876 gfc_trans_logical_select (gfc_code * code)
2878 gfc_code *c;
2879 gfc_code *t, *f, *d;
2880 gfc_case *cp;
2881 gfc_se se;
2882 stmtblock_t block;
2884 /* Assume we don't have any cases at all. */
2885 t = f = d = NULL;
2887 /* Now see which ones we actually do have. We can have at most two
2888 cases in a single case list: one for .TRUE. and one for .FALSE.
2889 The default case is always separate. If the cases for .TRUE. and
2890 .FALSE. are in the same case list, the block for that case list
2891 always executed, and we don't generate code a COND_EXPR. */
2892 for (c = code->block; c; c = c->block)
2894 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2896 if (cp->low)
2898 if (cp->low->value.logical == 0) /* .FALSE. */
2899 f = c;
2900 else /* if (cp->value.logical != 0), thus .TRUE. */
2901 t = c;
2903 else
2904 d = c;
2908 /* Start a new block. */
2909 gfc_start_block (&block);
2911 /* Calculate the switch expression. We always need to do this
2912 because it may have side effects. */
2913 gfc_init_se (&se, NULL);
2914 gfc_conv_expr_val (&se, code->expr1);
2915 gfc_add_block_to_block (&block, &se.pre);
2917 if (t == f && t != NULL)
2919 /* Cases for .TRUE. and .FALSE. are in the same block. Just
2920 translate the code for these cases, append it to the current
2921 block. */
2922 gfc_add_expr_to_block (&block, gfc_trans_code (t->next));
2924 else
2926 tree true_tree, false_tree, stmt;
2928 true_tree = build_empty_stmt (input_location);
2929 false_tree = build_empty_stmt (input_location);
2931 /* If we have a case for .TRUE. and for .FALSE., discard the default case.
2932 Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
2933 make the missing case the default case. */
2934 if (t != NULL && f != NULL)
2935 d = NULL;
2936 else if (d != NULL)
2938 if (t == NULL)
2939 t = d;
2940 else
2941 f = d;
2944 /* Translate the code for each of these blocks, and append it to
2945 the current block. */
2946 if (t != NULL)
2947 true_tree = gfc_trans_code (t->next);
2949 if (f != NULL)
2950 false_tree = gfc_trans_code (f->next);
2952 stmt = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2953 se.expr, true_tree, false_tree);
2954 gfc_add_expr_to_block (&block, stmt);
2957 return gfc_finish_block (&block);
2961 /* The jump table types are stored in static variables to avoid
2962 constructing them from scratch every single time. */
2963 static GTY(()) tree select_struct[2];
2965 /* Translate the SELECT CASE construct for CHARACTER case expressions.
2966 Instead of generating compares and jumps, it is far simpler to
2967 generate a data structure describing the cases in order and call a
2968 library subroutine that locates the right case.
2969 This is particularly true because this is the only case where we
2970 might have to dispose of a temporary.
2971 The library subroutine returns a pointer to jump to or NULL if no
2972 branches are to be taken. */
2974 static tree
2975 gfc_trans_character_select (gfc_code *code)
2977 tree init, end_label, tmp, type, case_num, label, fndecl;
2978 stmtblock_t block, body;
2979 gfc_case *cp, *d;
2980 gfc_code *c;
2981 gfc_se se, expr1se;
2982 int n, k;
2983 vec<constructor_elt, va_gc> *inits = NULL;
2985 tree pchartype = gfc_get_pchar_type (code->expr1->ts.kind);
2987 /* The jump table types are stored in static variables to avoid
2988 constructing them from scratch every single time. */
2989 static tree ss_string1[2], ss_string1_len[2];
2990 static tree ss_string2[2], ss_string2_len[2];
2991 static tree ss_target[2];
2993 cp = code->block->ext.block.case_list;
2994 while (cp->left != NULL)
2995 cp = cp->left;
2997 /* Generate the body */
2998 gfc_start_block (&block);
2999 gfc_init_se (&expr1se, NULL);
3000 gfc_conv_expr_reference (&expr1se, code->expr1);
3002 gfc_add_block_to_block (&block, &expr1se.pre);
3004 end_label = gfc_build_label_decl (NULL_TREE);
3006 gfc_init_block (&body);
3008 /* Attempt to optimize length 1 selects. */
3009 if (integer_onep (expr1se.string_length))
3011 for (d = cp; d; d = d->right)
3013 gfc_charlen_t i;
3014 if (d->low)
3016 gcc_assert (d->low->expr_type == EXPR_CONSTANT
3017 && d->low->ts.type == BT_CHARACTER);
3018 if (d->low->value.character.length > 1)
3020 for (i = 1; i < d->low->value.character.length; i++)
3021 if (d->low->value.character.string[i] != ' ')
3022 break;
3023 if (i != d->low->value.character.length)
3025 if (optimize && d->high && i == 1)
3027 gcc_assert (d->high->expr_type == EXPR_CONSTANT
3028 && d->high->ts.type == BT_CHARACTER);
3029 if (d->high->value.character.length > 1
3030 && (d->low->value.character.string[0]
3031 == d->high->value.character.string[0])
3032 && d->high->value.character.string[1] != ' '
3033 && ((d->low->value.character.string[1] < ' ')
3034 == (d->high->value.character.string[1]
3035 < ' ')))
3036 continue;
3038 break;
3042 if (d->high)
3044 gcc_assert (d->high->expr_type == EXPR_CONSTANT
3045 && d->high->ts.type == BT_CHARACTER);
3046 if (d->high->value.character.length > 1)
3048 for (i = 1; i < d->high->value.character.length; i++)
3049 if (d->high->value.character.string[i] != ' ')
3050 break;
3051 if (i != d->high->value.character.length)
3052 break;
3056 if (d == NULL)
3058 tree ctype = gfc_get_char_type (code->expr1->ts.kind);
3060 for (c = code->block; c; c = c->block)
3062 for (cp = c->ext.block.case_list; cp; cp = cp->next)
3064 tree low, high;
3065 tree label;
3066 gfc_char_t r;
3068 /* Assume it's the default case. */
3069 low = high = NULL_TREE;
3071 if (cp->low)
3073 /* CASE ('ab') or CASE ('ab':'az') will never match
3074 any length 1 character. */
3075 if (cp->low->value.character.length > 1
3076 && cp->low->value.character.string[1] != ' ')
3077 continue;
3079 if (cp->low->value.character.length > 0)
3080 r = cp->low->value.character.string[0];
3081 else
3082 r = ' ';
3083 low = build_int_cst (ctype, r);
3085 /* If there's only a lower bound, set the high bound
3086 to the maximum value of the case expression. */
3087 if (!cp->high)
3088 high = TYPE_MAX_VALUE (ctype);
3091 if (cp->high)
3093 if (!cp->low
3094 || (cp->low->value.character.string[0]
3095 != cp->high->value.character.string[0]))
3097 if (cp->high->value.character.length > 0)
3098 r = cp->high->value.character.string[0];
3099 else
3100 r = ' ';
3101 high = build_int_cst (ctype, r);
3104 /* Unbounded case. */
3105 if (!cp->low)
3106 low = TYPE_MIN_VALUE (ctype);
3109 /* Build a label. */
3110 label = gfc_build_label_decl (NULL_TREE);
3112 /* Add this case label.
3113 Add parameter 'label', make it match GCC backend. */
3114 tmp = build_case_label (low, high, label);
3115 gfc_add_expr_to_block (&body, tmp);
3118 /* Add the statements for this case. */
3119 tmp = gfc_trans_code (c->next);
3120 gfc_add_expr_to_block (&body, tmp);
3122 /* Break to the end of the construct. */
3123 tmp = build1_v (GOTO_EXPR, end_label);
3124 gfc_add_expr_to_block (&body, tmp);
3127 tmp = gfc_string_to_single_character (expr1se.string_length,
3128 expr1se.expr,
3129 code->expr1->ts.kind);
3130 case_num = gfc_create_var (ctype, "case_num");
3131 gfc_add_modify (&block, case_num, tmp);
3133 gfc_add_block_to_block (&block, &expr1se.post);
3135 tmp = gfc_finish_block (&body);
3136 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE,
3137 case_num, tmp);
3138 gfc_add_expr_to_block (&block, tmp);
3140 tmp = build1_v (LABEL_EXPR, end_label);
3141 gfc_add_expr_to_block (&block, tmp);
3143 return gfc_finish_block (&block);
3147 if (code->expr1->ts.kind == 1)
3148 k = 0;
3149 else if (code->expr1->ts.kind == 4)
3150 k = 1;
3151 else
3152 gcc_unreachable ();
3154 if (select_struct[k] == NULL)
3156 tree *chain = NULL;
3157 select_struct[k] = make_node (RECORD_TYPE);
3159 if (code->expr1->ts.kind == 1)
3160 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char1");
3161 else if (code->expr1->ts.kind == 4)
3162 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char4");
3163 else
3164 gcc_unreachable ();
3166 #undef ADD_FIELD
3167 #define ADD_FIELD(NAME, TYPE) \
3168 ss_##NAME[k] = gfc_add_field_to_struct (select_struct[k], \
3169 get_identifier (stringize(NAME)), \
3170 TYPE, \
3171 &chain)
3173 ADD_FIELD (string1, pchartype);
3174 ADD_FIELD (string1_len, gfc_charlen_type_node);
3176 ADD_FIELD (string2, pchartype);
3177 ADD_FIELD (string2_len, gfc_charlen_type_node);
3179 ADD_FIELD (target, integer_type_node);
3180 #undef ADD_FIELD
3182 gfc_finish_type (select_struct[k]);
3185 n = 0;
3186 for (d = cp; d; d = d->right)
3187 d->n = n++;
3189 for (c = code->block; c; c = c->block)
3191 for (d = c->ext.block.case_list; d; d = d->next)
3193 label = gfc_build_label_decl (NULL_TREE);
3194 tmp = build_case_label ((d->low == NULL && d->high == NULL)
3195 ? NULL
3196 : build_int_cst (integer_type_node, d->n),
3197 NULL, label);
3198 gfc_add_expr_to_block (&body, tmp);
3201 tmp = gfc_trans_code (c->next);
3202 gfc_add_expr_to_block (&body, tmp);
3204 tmp = build1_v (GOTO_EXPR, end_label);
3205 gfc_add_expr_to_block (&body, tmp);
3208 /* Generate the structure describing the branches */
3209 for (d = cp; d; d = d->right)
3211 vec<constructor_elt, va_gc> *node = NULL;
3213 gfc_init_se (&se, NULL);
3215 if (d->low == NULL)
3217 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], null_pointer_node);
3218 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], build_zero_cst (gfc_charlen_type_node));
3220 else
3222 gfc_conv_expr_reference (&se, d->low);
3224 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], se.expr);
3225 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], se.string_length);
3228 if (d->high == NULL)
3230 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], null_pointer_node);
3231 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], build_zero_cst (gfc_charlen_type_node));
3233 else
3235 gfc_init_se (&se, NULL);
3236 gfc_conv_expr_reference (&se, d->high);
3238 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], se.expr);
3239 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], se.string_length);
3242 CONSTRUCTOR_APPEND_ELT (node, ss_target[k],
3243 build_int_cst (integer_type_node, d->n));
3245 tmp = build_constructor (select_struct[k], node);
3246 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, tmp);
3249 type = build_array_type (select_struct[k],
3250 build_index_type (size_int (n-1)));
3252 init = build_constructor (type, inits);
3253 TREE_CONSTANT (init) = 1;
3254 TREE_STATIC (init) = 1;
3255 /* Create a static variable to hold the jump table. */
3256 tmp = gfc_create_var (type, "jumptable");
3257 TREE_CONSTANT (tmp) = 1;
3258 TREE_STATIC (tmp) = 1;
3259 TREE_READONLY (tmp) = 1;
3260 DECL_INITIAL (tmp) = init;
3261 init = tmp;
3263 /* Build the library call */
3264 init = gfc_build_addr_expr (pvoid_type_node, init);
3266 if (code->expr1->ts.kind == 1)
3267 fndecl = gfor_fndecl_select_string;
3268 else if (code->expr1->ts.kind == 4)
3269 fndecl = gfor_fndecl_select_string_char4;
3270 else
3271 gcc_unreachable ();
3273 tmp = build_call_expr_loc (input_location,
3274 fndecl, 4, init,
3275 build_int_cst (gfc_charlen_type_node, n),
3276 expr1se.expr, expr1se.string_length);
3277 case_num = gfc_create_var (integer_type_node, "case_num");
3278 gfc_add_modify (&block, case_num, tmp);
3280 gfc_add_block_to_block (&block, &expr1se.post);
3282 tmp = gfc_finish_block (&body);
3283 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE,
3284 case_num, tmp);
3285 gfc_add_expr_to_block (&block, tmp);
3287 tmp = build1_v (LABEL_EXPR, end_label);
3288 gfc_add_expr_to_block (&block, tmp);
3290 return gfc_finish_block (&block);
3294 /* Translate the three variants of the SELECT CASE construct.
3296 SELECT CASEs with INTEGER case expressions can be translated to an
3297 equivalent GENERIC switch statement, and for LOGICAL case
3298 expressions we build one or two if-else compares.
3300 SELECT CASEs with CHARACTER case expressions are a whole different
3301 story, because they don't exist in GENERIC. So we sort them and
3302 do a binary search at runtime.
3304 Fortran has no BREAK statement, and it does not allow jumps from
3305 one case block to another. That makes things a lot easier for
3306 the optimizers. */
3308 tree
3309 gfc_trans_select (gfc_code * code)
3311 stmtblock_t block;
3312 tree body;
3313 tree exit_label;
3315 gcc_assert (code && code->expr1);
3316 gfc_init_block (&block);
3318 /* Build the exit label and hang it in. */
3319 exit_label = gfc_build_label_decl (NULL_TREE);
3320 code->exit_label = exit_label;
3322 /* Empty SELECT constructs are legal. */
3323 if (code->block == NULL)
3324 body = build_empty_stmt (input_location);
3326 /* Select the correct translation function. */
3327 else
3328 switch (code->expr1->ts.type)
3330 case BT_LOGICAL:
3331 body = gfc_trans_logical_select (code);
3332 break;
3334 case BT_INTEGER:
3335 body = gfc_trans_integer_select (code);
3336 break;
3338 case BT_CHARACTER:
3339 body = gfc_trans_character_select (code);
3340 break;
3342 default:
3343 gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
3344 /* Not reached */
3347 /* Build everything together. */
3348 gfc_add_expr_to_block (&block, body);
3349 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3351 return gfc_finish_block (&block);
3354 tree
3355 gfc_trans_select_type (gfc_code * code)
3357 stmtblock_t block;
3358 tree body;
3359 tree exit_label;
3361 gcc_assert (code && code->expr1);
3362 gfc_init_block (&block);
3364 /* Build the exit label and hang it in. */
3365 exit_label = gfc_build_label_decl (NULL_TREE);
3366 code->exit_label = exit_label;
3368 /* Empty SELECT constructs are legal. */
3369 if (code->block == NULL)
3370 body = build_empty_stmt (input_location);
3371 else
3372 body = gfc_trans_select_type_cases (code);
3374 /* Build everything together. */
3375 gfc_add_expr_to_block (&block, body);
3377 if (TREE_USED (exit_label))
3378 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3380 return gfc_finish_block (&block);
3384 /* Traversal function to substitute a replacement symtree if the symbol
3385 in the expression is the same as that passed. f == 2 signals that
3386 that variable itself is not to be checked - only the references.
3387 This group of functions is used when the variable expression in a
3388 FORALL assignment has internal references. For example:
3389 FORALL (i = 1:4) p(p(i)) = i
3390 The only recourse here is to store a copy of 'p' for the index
3391 expression. */
3393 static gfc_symtree *new_symtree;
3394 static gfc_symtree *old_symtree;
3396 static bool
3397 forall_replace (gfc_expr *expr, gfc_symbol *sym, int *f)
3399 if (expr->expr_type != EXPR_VARIABLE)
3400 return false;
3402 if (*f == 2)
3403 *f = 1;
3404 else if (expr->symtree->n.sym == sym)
3405 expr->symtree = new_symtree;
3407 return false;
3410 static void
3411 forall_replace_symtree (gfc_expr *e, gfc_symbol *sym, int f)
3413 gfc_traverse_expr (e, sym, forall_replace, f);
3416 static bool
3417 forall_restore (gfc_expr *expr,
3418 gfc_symbol *sym ATTRIBUTE_UNUSED,
3419 int *f ATTRIBUTE_UNUSED)
3421 if (expr->expr_type != EXPR_VARIABLE)
3422 return false;
3424 if (expr->symtree == new_symtree)
3425 expr->symtree = old_symtree;
3427 return false;
3430 static void
3431 forall_restore_symtree (gfc_expr *e)
3433 gfc_traverse_expr (e, NULL, forall_restore, 0);
3436 static void
3437 forall_make_variable_temp (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
3439 gfc_se tse;
3440 gfc_se rse;
3441 gfc_expr *e;
3442 gfc_symbol *new_sym;
3443 gfc_symbol *old_sym;
3444 gfc_symtree *root;
3445 tree tmp;
3447 /* Build a copy of the lvalue. */
3448 old_symtree = c->expr1->symtree;
3449 old_sym = old_symtree->n.sym;
3450 e = gfc_lval_expr_from_sym (old_sym);
3451 if (old_sym->attr.dimension)
3453 gfc_init_se (&tse, NULL);
3454 gfc_conv_subref_array_arg (&tse, e, 0, INTENT_IN, false);
3455 gfc_add_block_to_block (pre, &tse.pre);
3456 gfc_add_block_to_block (post, &tse.post);
3457 tse.expr = build_fold_indirect_ref_loc (input_location, tse.expr);
3459 if (c->expr1->ref->u.ar.type != AR_SECTION)
3461 /* Use the variable offset for the temporary. */
3462 tmp = gfc_conv_array_offset (old_sym->backend_decl);
3463 gfc_conv_descriptor_offset_set (pre, tse.expr, tmp);
3466 else
3468 gfc_init_se (&tse, NULL);
3469 gfc_init_se (&rse, NULL);
3470 gfc_conv_expr (&rse, e);
3471 if (e->ts.type == BT_CHARACTER)
3473 tse.string_length = rse.string_length;
3474 tmp = gfc_get_character_type_len (gfc_default_character_kind,
3475 tse.string_length);
3476 tse.expr = gfc_conv_string_tmp (&tse, build_pointer_type (tmp),
3477 rse.string_length);
3478 gfc_add_block_to_block (pre, &tse.pre);
3479 gfc_add_block_to_block (post, &tse.post);
3481 else
3483 tmp = gfc_typenode_for_spec (&e->ts);
3484 tse.expr = gfc_create_var (tmp, "temp");
3487 tmp = gfc_trans_scalar_assign (&tse, &rse, e->ts,
3488 e->expr_type == EXPR_VARIABLE, false);
3489 gfc_add_expr_to_block (pre, tmp);
3491 gfc_free_expr (e);
3493 /* Create a new symbol to represent the lvalue. */
3494 new_sym = gfc_new_symbol (old_sym->name, NULL);
3495 new_sym->ts = old_sym->ts;
3496 new_sym->attr.referenced = 1;
3497 new_sym->attr.temporary = 1;
3498 new_sym->attr.dimension = old_sym->attr.dimension;
3499 new_sym->attr.flavor = old_sym->attr.flavor;
3501 /* Use the temporary as the backend_decl. */
3502 new_sym->backend_decl = tse.expr;
3504 /* Create a fake symtree for it. */
3505 root = NULL;
3506 new_symtree = gfc_new_symtree (&root, old_sym->name);
3507 new_symtree->n.sym = new_sym;
3508 gcc_assert (new_symtree == root);
3510 /* Go through the expression reference replacing the old_symtree
3511 with the new. */
3512 forall_replace_symtree (c->expr1, old_sym, 2);
3514 /* Now we have made this temporary, we might as well use it for
3515 the right hand side. */
3516 forall_replace_symtree (c->expr2, old_sym, 1);
3520 /* Handles dependencies in forall assignments. */
3521 static int
3522 check_forall_dependencies (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
3524 gfc_ref *lref;
3525 gfc_ref *rref;
3526 int need_temp;
3527 gfc_symbol *lsym;
3529 lsym = c->expr1->symtree->n.sym;
3530 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
3532 /* Now check for dependencies within the 'variable'
3533 expression itself. These are treated by making a complete
3534 copy of variable and changing all the references to it
3535 point to the copy instead. Note that the shallow copy of
3536 the variable will not suffice for derived types with
3537 pointer components. We therefore leave these to their
3538 own devices. */
3539 if (lsym->ts.type == BT_DERIVED
3540 && lsym->ts.u.derived->attr.pointer_comp)
3541 return need_temp;
3543 new_symtree = NULL;
3544 if (find_forall_index (c->expr1, lsym, 2))
3546 forall_make_variable_temp (c, pre, post);
3547 need_temp = 0;
3550 /* Substrings with dependencies are treated in the same
3551 way. */
3552 if (c->expr1->ts.type == BT_CHARACTER
3553 && c->expr1->ref
3554 && c->expr2->expr_type == EXPR_VARIABLE
3555 && lsym == c->expr2->symtree->n.sym)
3557 for (lref = c->expr1->ref; lref; lref = lref->next)
3558 if (lref->type == REF_SUBSTRING)
3559 break;
3560 for (rref = c->expr2->ref; rref; rref = rref->next)
3561 if (rref->type == REF_SUBSTRING)
3562 break;
3564 if (rref && lref
3565 && gfc_dep_compare_expr (rref->u.ss.start, lref->u.ss.start) < 0)
3567 forall_make_variable_temp (c, pre, post);
3568 need_temp = 0;
3571 return need_temp;
3575 static void
3576 cleanup_forall_symtrees (gfc_code *c)
3578 forall_restore_symtree (c->expr1);
3579 forall_restore_symtree (c->expr2);
3580 free (new_symtree->n.sym);
3581 free (new_symtree);
3585 /* Generate the loops for a FORALL block, specified by FORALL_TMP. BODY
3586 is the contents of the FORALL block/stmt to be iterated. MASK_FLAG
3587 indicates whether we should generate code to test the FORALLs mask
3588 array. OUTER is the loop header to be used for initializing mask
3589 indices.
3591 The generated loop format is:
3592 count = (end - start + step) / step
3593 loopvar = start
3594 while (1)
3596 if (count <=0 )
3597 goto end_of_loop
3598 <body>
3599 loopvar += step
3600 count --
3602 end_of_loop: */
3604 static tree
3605 gfc_trans_forall_loop (forall_info *forall_tmp, tree body,
3606 int mask_flag, stmtblock_t *outer)
3608 int n, nvar;
3609 tree tmp;
3610 tree cond;
3611 stmtblock_t block;
3612 tree exit_label;
3613 tree count;
3614 tree var, start, end, step;
3615 iter_info *iter;
3617 /* Initialize the mask index outside the FORALL nest. */
3618 if (mask_flag && forall_tmp->mask)
3619 gfc_add_modify (outer, forall_tmp->maskindex, gfc_index_zero_node);
3621 iter = forall_tmp->this_loop;
3622 nvar = forall_tmp->nvar;
3623 for (n = 0; n < nvar; n++)
3625 var = iter->var;
3626 start = iter->start;
3627 end = iter->end;
3628 step = iter->step;
3630 exit_label = gfc_build_label_decl (NULL_TREE);
3631 TREE_USED (exit_label) = 1;
3633 /* The loop counter. */
3634 count = gfc_create_var (TREE_TYPE (var), "count");
3636 /* The body of the loop. */
3637 gfc_init_block (&block);
3639 /* The exit condition. */
3640 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
3641 count, build_int_cst (TREE_TYPE (count), 0));
3643 /* PR 83064 means that we cannot use annot_expr_parallel_kind until
3644 the autoparallelizer can hande this. */
3645 if (forall_tmp->do_concurrent)
3646 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
3647 build_int_cst (integer_type_node,
3648 annot_expr_ivdep_kind),
3649 integer_zero_node);
3651 tmp = build1_v (GOTO_EXPR, exit_label);
3652 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3653 cond, tmp, build_empty_stmt (input_location));
3654 gfc_add_expr_to_block (&block, tmp);
3656 /* The main loop body. */
3657 gfc_add_expr_to_block (&block, body);
3659 /* Increment the loop variable. */
3660 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var,
3661 step);
3662 gfc_add_modify (&block, var, tmp);
3664 /* Advance to the next mask element. Only do this for the
3665 innermost loop. */
3666 if (n == 0 && mask_flag && forall_tmp->mask)
3668 tree maskindex = forall_tmp->maskindex;
3669 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3670 maskindex, gfc_index_one_node);
3671 gfc_add_modify (&block, maskindex, tmp);
3674 /* Decrement the loop counter. */
3675 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), count,
3676 build_int_cst (TREE_TYPE (var), 1));
3677 gfc_add_modify (&block, count, tmp);
3679 body = gfc_finish_block (&block);
3681 /* Loop var initialization. */
3682 gfc_init_block (&block);
3683 gfc_add_modify (&block, var, start);
3686 /* Initialize the loop counter. */
3687 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), step,
3688 start);
3689 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), end,
3690 tmp);
3691 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (var),
3692 tmp, step);
3693 gfc_add_modify (&block, count, tmp);
3695 /* The loop expression. */
3696 tmp = build1_v (LOOP_EXPR, body);
3697 gfc_add_expr_to_block (&block, tmp);
3699 /* The exit label. */
3700 tmp = build1_v (LABEL_EXPR, exit_label);
3701 gfc_add_expr_to_block (&block, tmp);
3703 body = gfc_finish_block (&block);
3704 iter = iter->next;
3706 return body;
3710 /* Generate the body and loops according to MASK_FLAG. If MASK_FLAG
3711 is nonzero, the body is controlled by all masks in the forall nest.
3712 Otherwise, the innermost loop is not controlled by it's mask. This
3713 is used for initializing that mask. */
3715 static tree
3716 gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
3717 int mask_flag)
3719 tree tmp;
3720 stmtblock_t header;
3721 forall_info *forall_tmp;
3722 tree mask, maskindex;
3724 gfc_start_block (&header);
3726 forall_tmp = nested_forall_info;
3727 while (forall_tmp != NULL)
3729 /* Generate body with masks' control. */
3730 if (mask_flag)
3732 mask = forall_tmp->mask;
3733 maskindex = forall_tmp->maskindex;
3735 /* If a mask was specified make the assignment conditional. */
3736 if (mask)
3738 tmp = gfc_build_array_ref (mask, maskindex, NULL);
3739 body = build3_v (COND_EXPR, tmp, body,
3740 build_empty_stmt (input_location));
3743 body = gfc_trans_forall_loop (forall_tmp, body, mask_flag, &header);
3744 forall_tmp = forall_tmp->prev_nest;
3745 mask_flag = 1;
3748 gfc_add_expr_to_block (&header, body);
3749 return gfc_finish_block (&header);
3753 /* Allocate data for holding a temporary array. Returns either a local
3754 temporary array or a pointer variable. */
3756 static tree
3757 gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
3758 tree elem_type)
3760 tree tmpvar;
3761 tree type;
3762 tree tmp;
3764 if (INTEGER_CST_P (size))
3765 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3766 size, gfc_index_one_node);
3767 else
3768 tmp = NULL_TREE;
3770 type = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
3771 type = build_array_type (elem_type, type);
3772 if (gfc_can_put_var_on_stack (bytesize) && INTEGER_CST_P (size))
3774 tmpvar = gfc_create_var (type, "temp");
3775 *pdata = NULL_TREE;
3777 else
3779 tmpvar = gfc_create_var (build_pointer_type (type), "temp");
3780 *pdata = convert (pvoid_type_node, tmpvar);
3782 tmp = gfc_call_malloc (pblock, TREE_TYPE (tmpvar), bytesize);
3783 gfc_add_modify (pblock, tmpvar, tmp);
3785 return tmpvar;
3789 /* Generate codes to copy the temporary to the actual lhs. */
3791 static tree
3792 generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
3793 tree count1,
3794 gfc_ss *lss, gfc_ss *rss,
3795 tree wheremask, bool invert)
3797 stmtblock_t block, body1;
3798 gfc_loopinfo loop;
3799 gfc_se lse;
3800 gfc_se rse;
3801 tree tmp;
3802 tree wheremaskexpr;
3804 (void) rss; /* TODO: unused. */
3806 gfc_start_block (&block);
3808 gfc_init_se (&rse, NULL);
3809 gfc_init_se (&lse, NULL);
3811 if (lss == gfc_ss_terminator)
3813 gfc_init_block (&body1);
3814 gfc_conv_expr (&lse, expr);
3815 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3817 else
3819 /* Initialize the loop. */
3820 gfc_init_loopinfo (&loop);
3822 /* We may need LSS to determine the shape of the expression. */
3823 gfc_add_ss_to_loop (&loop, lss);
3825 gfc_conv_ss_startstride (&loop);
3826 gfc_conv_loop_setup (&loop, &expr->where);
3828 gfc_mark_ss_chain_used (lss, 1);
3829 /* Start the loop body. */
3830 gfc_start_scalarized_body (&loop, &body1);
3832 /* Translate the expression. */
3833 gfc_copy_loopinfo_to_se (&lse, &loop);
3834 lse.ss = lss;
3835 gfc_conv_expr (&lse, expr);
3837 /* Form the expression of the temporary. */
3838 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3841 /* Use the scalar assignment. */
3842 rse.string_length = lse.string_length;
3843 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts,
3844 expr->expr_type == EXPR_VARIABLE, false);
3846 /* Form the mask expression according to the mask tree list. */
3847 if (wheremask)
3849 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3850 if (invert)
3851 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3852 TREE_TYPE (wheremaskexpr),
3853 wheremaskexpr);
3854 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3855 wheremaskexpr, tmp,
3856 build_empty_stmt (input_location));
3859 gfc_add_expr_to_block (&body1, tmp);
3861 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3862 count1, gfc_index_one_node);
3863 gfc_add_modify (&body1, count1, tmp);
3865 if (lss == gfc_ss_terminator)
3866 gfc_add_block_to_block (&block, &body1);
3867 else
3869 /* Increment count3. */
3870 if (count3)
3872 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3873 gfc_array_index_type,
3874 count3, gfc_index_one_node);
3875 gfc_add_modify (&body1, count3, tmp);
3878 /* Generate the copying loops. */
3879 gfc_trans_scalarizing_loops (&loop, &body1);
3881 gfc_add_block_to_block (&block, &loop.pre);
3882 gfc_add_block_to_block (&block, &loop.post);
3884 gfc_cleanup_loop (&loop);
3885 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
3886 as tree nodes in SS may not be valid in different scope. */
3889 tmp = gfc_finish_block (&block);
3890 return tmp;
3894 /* Generate codes to copy rhs to the temporary. TMP1 is the address of
3895 temporary, LSS and RSS are formed in function compute_inner_temp_size(),
3896 and should not be freed. WHEREMASK is the conditional execution mask
3897 whose sense may be inverted by INVERT. */
3899 static tree
3900 generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree count3,
3901 tree count1, gfc_ss *lss, gfc_ss *rss,
3902 tree wheremask, bool invert)
3904 stmtblock_t block, body1;
3905 gfc_loopinfo loop;
3906 gfc_se lse;
3907 gfc_se rse;
3908 tree tmp;
3909 tree wheremaskexpr;
3911 gfc_start_block (&block);
3913 gfc_init_se (&rse, NULL);
3914 gfc_init_se (&lse, NULL);
3916 if (lss == gfc_ss_terminator)
3918 gfc_init_block (&body1);
3919 gfc_conv_expr (&rse, expr2);
3920 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3922 else
3924 /* Initialize the loop. */
3925 gfc_init_loopinfo (&loop);
3927 /* We may need LSS to determine the shape of the expression. */
3928 gfc_add_ss_to_loop (&loop, lss);
3929 gfc_add_ss_to_loop (&loop, rss);
3931 gfc_conv_ss_startstride (&loop);
3932 gfc_conv_loop_setup (&loop, &expr2->where);
3934 gfc_mark_ss_chain_used (rss, 1);
3935 /* Start the loop body. */
3936 gfc_start_scalarized_body (&loop, &body1);
3938 /* Translate the expression. */
3939 gfc_copy_loopinfo_to_se (&rse, &loop);
3940 rse.ss = rss;
3941 gfc_conv_expr (&rse, expr2);
3943 /* Form the expression of the temporary. */
3944 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3947 /* Use the scalar assignment. */
3948 lse.string_length = rse.string_length;
3949 tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts,
3950 expr2->expr_type == EXPR_VARIABLE, false);
3952 /* Form the mask expression according to the mask tree list. */
3953 if (wheremask)
3955 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3956 if (invert)
3957 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3958 TREE_TYPE (wheremaskexpr),
3959 wheremaskexpr);
3960 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3961 wheremaskexpr, tmp,
3962 build_empty_stmt (input_location));
3965 gfc_add_expr_to_block (&body1, tmp);
3967 if (lss == gfc_ss_terminator)
3969 gfc_add_block_to_block (&block, &body1);
3971 /* Increment count1. */
3972 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3973 count1, gfc_index_one_node);
3974 gfc_add_modify (&block, count1, tmp);
3976 else
3978 /* Increment count1. */
3979 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3980 count1, gfc_index_one_node);
3981 gfc_add_modify (&body1, count1, tmp);
3983 /* Increment count3. */
3984 if (count3)
3986 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3987 gfc_array_index_type,
3988 count3, gfc_index_one_node);
3989 gfc_add_modify (&body1, count3, tmp);
3992 /* Generate the copying loops. */
3993 gfc_trans_scalarizing_loops (&loop, &body1);
3995 gfc_add_block_to_block (&block, &loop.pre);
3996 gfc_add_block_to_block (&block, &loop.post);
3998 gfc_cleanup_loop (&loop);
3999 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
4000 as tree nodes in SS may not be valid in different scope. */
4003 tmp = gfc_finish_block (&block);
4004 return tmp;
4008 /* Calculate the size of temporary needed in the assignment inside forall.
4009 LSS and RSS are filled in this function. */
4011 static tree
4012 compute_inner_temp_size (gfc_expr *expr1, gfc_expr *expr2,
4013 stmtblock_t * pblock,
4014 gfc_ss **lss, gfc_ss **rss)
4016 gfc_loopinfo loop;
4017 tree size;
4018 int i;
4019 int save_flag;
4020 tree tmp;
4022 *lss = gfc_walk_expr (expr1);
4023 *rss = NULL;
4025 size = gfc_index_one_node;
4026 if (*lss != gfc_ss_terminator)
4028 gfc_init_loopinfo (&loop);
4030 /* Walk the RHS of the expression. */
4031 *rss = gfc_walk_expr (expr2);
4032 if (*rss == gfc_ss_terminator)
4033 /* The rhs is scalar. Add a ss for the expression. */
4034 *rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
4036 /* Associate the SS with the loop. */
4037 gfc_add_ss_to_loop (&loop, *lss);
4038 /* We don't actually need to add the rhs at this point, but it might
4039 make guessing the loop bounds a bit easier. */
4040 gfc_add_ss_to_loop (&loop, *rss);
4042 /* We only want the shape of the expression, not rest of the junk
4043 generated by the scalarizer. */
4044 loop.array_parameter = 1;
4046 /* Calculate the bounds of the scalarization. */
4047 save_flag = gfc_option.rtcheck;
4048 gfc_option.rtcheck &= ~GFC_RTCHECK_BOUNDS;
4049 gfc_conv_ss_startstride (&loop);
4050 gfc_option.rtcheck = save_flag;
4051 gfc_conv_loop_setup (&loop, &expr2->where);
4053 /* Figure out how many elements we need. */
4054 for (i = 0; i < loop.dimen; i++)
4056 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4057 gfc_array_index_type,
4058 gfc_index_one_node, loop.from[i]);
4059 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4060 gfc_array_index_type, tmp, loop.to[i]);
4061 size = fold_build2_loc (input_location, MULT_EXPR,
4062 gfc_array_index_type, size, tmp);
4064 gfc_add_block_to_block (pblock, &loop.pre);
4065 size = gfc_evaluate_now (size, pblock);
4066 gfc_add_block_to_block (pblock, &loop.post);
4068 /* TODO: write a function that cleans up a loopinfo without freeing
4069 the SS chains. Currently a NOP. */
4072 return size;
4076 /* Calculate the overall iterator number of the nested forall construct.
4077 This routine actually calculates the number of times the body of the
4078 nested forall specified by NESTED_FORALL_INFO is executed and multiplies
4079 that by the expression INNER_SIZE. The BLOCK argument specifies the
4080 block in which to calculate the result, and the optional INNER_SIZE_BODY
4081 argument contains any statements that need to executed (inside the loop)
4082 to initialize or calculate INNER_SIZE. */
4084 static tree
4085 compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
4086 stmtblock_t *inner_size_body, stmtblock_t *block)
4088 forall_info *forall_tmp = nested_forall_info;
4089 tree tmp, number;
4090 stmtblock_t body;
4092 /* We can eliminate the innermost unconditional loops with constant
4093 array bounds. */
4094 if (INTEGER_CST_P (inner_size))
4096 while (forall_tmp
4097 && !forall_tmp->mask
4098 && INTEGER_CST_P (forall_tmp->size))
4100 inner_size = fold_build2_loc (input_location, MULT_EXPR,
4101 gfc_array_index_type,
4102 inner_size, forall_tmp->size);
4103 forall_tmp = forall_tmp->prev_nest;
4106 /* If there are no loops left, we have our constant result. */
4107 if (!forall_tmp)
4108 return inner_size;
4111 /* Otherwise, create a temporary variable to compute the result. */
4112 number = gfc_create_var (gfc_array_index_type, "num");
4113 gfc_add_modify (block, number, gfc_index_zero_node);
4115 gfc_start_block (&body);
4116 if (inner_size_body)
4117 gfc_add_block_to_block (&body, inner_size_body);
4118 if (forall_tmp)
4119 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4120 gfc_array_index_type, number, inner_size);
4121 else
4122 tmp = inner_size;
4123 gfc_add_modify (&body, number, tmp);
4124 tmp = gfc_finish_block (&body);
4126 /* Generate loops. */
4127 if (forall_tmp != NULL)
4128 tmp = gfc_trans_nested_forall_loop (forall_tmp, tmp, 1);
4130 gfc_add_expr_to_block (block, tmp);
4132 return number;
4136 /* Allocate temporary for forall construct. SIZE is the size of temporary
4137 needed. PTEMP1 is returned for space free. */
4139 static tree
4140 allocate_temp_for_forall_nest_1 (tree type, tree size, stmtblock_t * block,
4141 tree * ptemp1)
4143 tree bytesize;
4144 tree unit;
4145 tree tmp;
4147 unit = fold_convert (gfc_array_index_type, TYPE_SIZE_UNIT (type));
4148 if (!integer_onep (unit))
4149 bytesize = fold_build2_loc (input_location, MULT_EXPR,
4150 gfc_array_index_type, size, unit);
4151 else
4152 bytesize = size;
4154 *ptemp1 = NULL;
4155 tmp = gfc_do_allocate (bytesize, size, ptemp1, block, type);
4157 if (*ptemp1)
4158 tmp = build_fold_indirect_ref_loc (input_location, tmp);
4159 return tmp;
4163 /* Allocate temporary for forall construct according to the information in
4164 nested_forall_info. INNER_SIZE is the size of temporary needed in the
4165 assignment inside forall. PTEMP1 is returned for space free. */
4167 static tree
4168 allocate_temp_for_forall_nest (forall_info * nested_forall_info, tree type,
4169 tree inner_size, stmtblock_t * inner_size_body,
4170 stmtblock_t * block, tree * ptemp1)
4172 tree size;
4174 /* Calculate the total size of temporary needed in forall construct. */
4175 size = compute_overall_iter_number (nested_forall_info, inner_size,
4176 inner_size_body, block);
4178 return allocate_temp_for_forall_nest_1 (type, size, block, ptemp1);
4182 /* Handle assignments inside forall which need temporary.
4184 forall (i=start:end:stride; maskexpr)
4185 e<i> = f<i>
4186 end forall
4187 (where e,f<i> are arbitrary expressions possibly involving i
4188 and there is a dependency between e<i> and f<i>)
4189 Translates to:
4190 masktmp(:) = maskexpr(:)
4192 maskindex = 0;
4193 count1 = 0;
4194 num = 0;
4195 for (i = start; i <= end; i += stride)
4196 num += SIZE (f<i>)
4197 count1 = 0;
4198 ALLOCATE (tmp(num))
4199 for (i = start; i <= end; i += stride)
4201 if (masktmp[maskindex++])
4202 tmp[count1++] = f<i>
4204 maskindex = 0;
4205 count1 = 0;
4206 for (i = start; i <= end; i += stride)
4208 if (masktmp[maskindex++])
4209 e<i> = tmp[count1++]
4211 DEALLOCATE (tmp)
4213 static void
4214 gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
4215 tree wheremask, bool invert,
4216 forall_info * nested_forall_info,
4217 stmtblock_t * block)
4219 tree type;
4220 tree inner_size;
4221 gfc_ss *lss, *rss;
4222 tree count, count1;
4223 tree tmp, tmp1;
4224 tree ptemp1;
4225 stmtblock_t inner_size_body;
4227 /* Create vars. count1 is the current iterator number of the nested
4228 forall. */
4229 count1 = gfc_create_var (gfc_array_index_type, "count1");
4231 /* Count is the wheremask index. */
4232 if (wheremask)
4234 count = gfc_create_var (gfc_array_index_type, "count");
4235 gfc_add_modify (block, count, gfc_index_zero_node);
4237 else
4238 count = NULL;
4240 /* Initialize count1. */
4241 gfc_add_modify (block, count1, gfc_index_zero_node);
4243 /* Calculate the size of temporary needed in the assignment. Return loop, lss
4244 and rss which are used in function generate_loop_for_rhs_to_temp(). */
4245 /* The type of LHS. Used in function allocate_temp_for_forall_nest */
4246 if (expr1->ts.type == BT_CHARACTER)
4248 type = NULL;
4249 if (expr1->ref && expr1->ref->type == REF_SUBSTRING)
4251 gfc_se ssse;
4252 gfc_init_se (&ssse, NULL);
4253 gfc_conv_expr (&ssse, expr1);
4254 type = gfc_get_character_type_len (gfc_default_character_kind,
4255 ssse.string_length);
4257 else
4259 if (!expr1->ts.u.cl->backend_decl)
4261 gfc_se tse;
4262 gcc_assert (expr1->ts.u.cl->length);
4263 gfc_init_se (&tse, NULL);
4264 gfc_conv_expr (&tse, expr1->ts.u.cl->length);
4265 expr1->ts.u.cl->backend_decl = tse.expr;
4267 type = gfc_get_character_type_len (gfc_default_character_kind,
4268 expr1->ts.u.cl->backend_decl);
4271 else
4272 type = gfc_typenode_for_spec (&expr1->ts);
4274 gfc_init_block (&inner_size_body);
4275 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
4276 &lss, &rss);
4278 /* Allocate temporary for nested forall construct according to the
4279 information in nested_forall_info and inner_size. */
4280 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type, inner_size,
4281 &inner_size_body, block, &ptemp1);
4283 /* Generate codes to copy rhs to the temporary . */
4284 tmp = generate_loop_for_rhs_to_temp (expr2, tmp1, count, count1, lss, rss,
4285 wheremask, invert);
4287 /* Generate body and loops according to the information in
4288 nested_forall_info. */
4289 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4290 gfc_add_expr_to_block (block, tmp);
4292 /* Reset count1. */
4293 gfc_add_modify (block, count1, gfc_index_zero_node);
4295 /* Reset count. */
4296 if (wheremask)
4297 gfc_add_modify (block, count, gfc_index_zero_node);
4299 /* TODO: Second call to compute_inner_temp_size to initialize lss and
4300 rss; there must be a better way. */
4301 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
4302 &lss, &rss);
4304 /* Generate codes to copy the temporary to lhs. */
4305 tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, count, count1,
4306 lss, rss,
4307 wheremask, invert);
4309 /* Generate body and loops according to the information in
4310 nested_forall_info. */
4311 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4312 gfc_add_expr_to_block (block, tmp);
4314 if (ptemp1)
4316 /* Free the temporary. */
4317 tmp = gfc_call_free (ptemp1);
4318 gfc_add_expr_to_block (block, tmp);
4323 /* Translate pointer assignment inside FORALL which need temporary. */
4325 static void
4326 gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
4327 forall_info * nested_forall_info,
4328 stmtblock_t * block)
4330 tree type;
4331 tree inner_size;
4332 gfc_ss *lss, *rss;
4333 gfc_se lse;
4334 gfc_se rse;
4335 gfc_array_info *info;
4336 gfc_loopinfo loop;
4337 tree desc;
4338 tree parm;
4339 tree parmtype;
4340 stmtblock_t body;
4341 tree count;
4342 tree tmp, tmp1, ptemp1;
4344 count = gfc_create_var (gfc_array_index_type, "count");
4345 gfc_add_modify (block, count, gfc_index_zero_node);
4347 inner_size = gfc_index_one_node;
4348 lss = gfc_walk_expr (expr1);
4349 rss = gfc_walk_expr (expr2);
4350 if (lss == gfc_ss_terminator)
4352 type = gfc_typenode_for_spec (&expr1->ts);
4353 type = build_pointer_type (type);
4355 /* Allocate temporary for nested forall construct according to the
4356 information in nested_forall_info and inner_size. */
4357 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type,
4358 inner_size, NULL, block, &ptemp1);
4359 gfc_start_block (&body);
4360 gfc_init_se (&lse, NULL);
4361 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
4362 gfc_init_se (&rse, NULL);
4363 rse.want_pointer = 1;
4364 gfc_conv_expr (&rse, expr2);
4365 gfc_add_block_to_block (&body, &rse.pre);
4366 gfc_add_modify (&body, lse.expr,
4367 fold_convert (TREE_TYPE (lse.expr), rse.expr));
4368 gfc_add_block_to_block (&body, &rse.post);
4370 /* Increment count. */
4371 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4372 count, gfc_index_one_node);
4373 gfc_add_modify (&body, count, tmp);
4375 tmp = gfc_finish_block (&body);
4377 /* Generate body and loops according to the information in
4378 nested_forall_info. */
4379 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4380 gfc_add_expr_to_block (block, tmp);
4382 /* Reset count. */
4383 gfc_add_modify (block, count, gfc_index_zero_node);
4385 gfc_start_block (&body);
4386 gfc_init_se (&lse, NULL);
4387 gfc_init_se (&rse, NULL);
4388 rse.expr = gfc_build_array_ref (tmp1, count, NULL);
4389 lse.want_pointer = 1;
4390 gfc_conv_expr (&lse, expr1);
4391 gfc_add_block_to_block (&body, &lse.pre);
4392 gfc_add_modify (&body, lse.expr, rse.expr);
4393 gfc_add_block_to_block (&body, &lse.post);
4394 /* Increment count. */
4395 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4396 count, gfc_index_one_node);
4397 gfc_add_modify (&body, count, tmp);
4398 tmp = gfc_finish_block (&body);
4400 /* Generate body and loops according to the information in
4401 nested_forall_info. */
4402 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4403 gfc_add_expr_to_block (block, tmp);
4405 else
4407 gfc_init_loopinfo (&loop);
4409 /* Associate the SS with the loop. */
4410 gfc_add_ss_to_loop (&loop, rss);
4412 /* Setup the scalarizing loops and bounds. */
4413 gfc_conv_ss_startstride (&loop);
4415 gfc_conv_loop_setup (&loop, &expr2->where);
4417 info = &rss->info->data.array;
4418 desc = info->descriptor;
4420 /* Make a new descriptor. */
4421 parmtype = gfc_get_element_type (TREE_TYPE (desc));
4422 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0,
4423 loop.from, loop.to, 1,
4424 GFC_ARRAY_UNKNOWN, true);
4426 /* Allocate temporary for nested forall construct. */
4427 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
4428 inner_size, NULL, block, &ptemp1);
4429 gfc_start_block (&body);
4430 gfc_init_se (&lse, NULL);
4431 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
4432 lse.direct_byref = 1;
4433 gfc_conv_expr_descriptor (&lse, expr2);
4435 gfc_add_block_to_block (&body, &lse.pre);
4436 gfc_add_block_to_block (&body, &lse.post);
4438 /* Increment count. */
4439 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4440 count, gfc_index_one_node);
4441 gfc_add_modify (&body, count, tmp);
4443 tmp = gfc_finish_block (&body);
4445 /* Generate body and loops according to the information in
4446 nested_forall_info. */
4447 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4448 gfc_add_expr_to_block (block, tmp);
4450 /* Reset count. */
4451 gfc_add_modify (block, count, gfc_index_zero_node);
4453 parm = gfc_build_array_ref (tmp1, count, NULL);
4454 gfc_init_se (&lse, NULL);
4455 gfc_conv_expr_descriptor (&lse, expr1);
4456 gfc_add_modify (&lse.pre, lse.expr, parm);
4457 gfc_start_block (&body);
4458 gfc_add_block_to_block (&body, &lse.pre);
4459 gfc_add_block_to_block (&body, &lse.post);
4461 /* Increment count. */
4462 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4463 count, gfc_index_one_node);
4464 gfc_add_modify (&body, count, tmp);
4466 tmp = gfc_finish_block (&body);
4468 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4469 gfc_add_expr_to_block (block, tmp);
4471 /* Free the temporary. */
4472 if (ptemp1)
4474 tmp = gfc_call_free (ptemp1);
4475 gfc_add_expr_to_block (block, tmp);
4480 /* FORALL and WHERE statements are really nasty, especially when you nest
4481 them. All the rhs of a forall assignment must be evaluated before the
4482 actual assignments are performed. Presumably this also applies to all the
4483 assignments in an inner where statement. */
4485 /* Generate code for a FORALL statement. Any temporaries are allocated as a
4486 linear array, relying on the fact that we process in the same order in all
4487 loops.
4489 forall (i=start:end:stride; maskexpr)
4490 e<i> = f<i>
4491 g<i> = h<i>
4492 end forall
4493 (where e,f,g,h<i> are arbitrary expressions possibly involving i)
4494 Translates to:
4495 count = ((end + 1 - start) / stride)
4496 masktmp(:) = maskexpr(:)
4498 maskindex = 0;
4499 for (i = start; i <= end; i += stride)
4501 if (masktmp[maskindex++])
4502 e<i> = f<i>
4504 maskindex = 0;
4505 for (i = start; i <= end; i += stride)
4507 if (masktmp[maskindex++])
4508 g<i> = h<i>
4511 Note that this code only works when there are no dependencies.
4512 Forall loop with array assignments and data dependencies are a real pain,
4513 because the size of the temporary cannot always be determined before the
4514 loop is executed. This problem is compounded by the presence of nested
4515 FORALL constructs.
4518 static tree
4519 gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
4521 stmtblock_t pre;
4522 stmtblock_t post;
4523 stmtblock_t block;
4524 stmtblock_t body;
4525 tree *var;
4526 tree *start;
4527 tree *end;
4528 tree *step;
4529 gfc_expr **varexpr;
4530 tree tmp;
4531 tree assign;
4532 tree size;
4533 tree maskindex;
4534 tree mask;
4535 tree pmask;
4536 tree cycle_label = NULL_TREE;
4537 int n;
4538 int nvar;
4539 int need_temp;
4540 gfc_forall_iterator *fa;
4541 gfc_se se;
4542 gfc_code *c;
4543 gfc_saved_var *saved_vars;
4544 iter_info *this_forall;
4545 forall_info *info;
4546 bool need_mask;
4548 /* Do nothing if the mask is false. */
4549 if (code->expr1
4550 && code->expr1->expr_type == EXPR_CONSTANT
4551 && !code->expr1->value.logical)
4552 return build_empty_stmt (input_location);
4554 n = 0;
4555 /* Count the FORALL index number. */
4556 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
4557 n++;
4558 nvar = n;
4560 /* Allocate the space for var, start, end, step, varexpr. */
4561 var = XCNEWVEC (tree, nvar);
4562 start = XCNEWVEC (tree, nvar);
4563 end = XCNEWVEC (tree, nvar);
4564 step = XCNEWVEC (tree, nvar);
4565 varexpr = XCNEWVEC (gfc_expr *, nvar);
4566 saved_vars = XCNEWVEC (gfc_saved_var, nvar);
4568 /* Allocate the space for info. */
4569 info = XCNEW (forall_info);
4571 gfc_start_block (&pre);
4572 gfc_init_block (&post);
4573 gfc_init_block (&block);
4575 n = 0;
4576 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
4578 gfc_symbol *sym = fa->var->symtree->n.sym;
4580 /* Allocate space for this_forall. */
4581 this_forall = XCNEW (iter_info);
4583 /* Create a temporary variable for the FORALL index. */
4584 tmp = gfc_typenode_for_spec (&sym->ts);
4585 var[n] = gfc_create_var (tmp, sym->name);
4586 gfc_shadow_sym (sym, var[n], &saved_vars[n]);
4588 /* Record it in this_forall. */
4589 this_forall->var = var[n];
4591 /* Replace the index symbol's backend_decl with the temporary decl. */
4592 sym->backend_decl = var[n];
4594 /* Work out the start, end and stride for the loop. */
4595 gfc_init_se (&se, NULL);
4596 gfc_conv_expr_val (&se, fa->start);
4597 /* Record it in this_forall. */
4598 this_forall->start = se.expr;
4599 gfc_add_block_to_block (&block, &se.pre);
4600 start[n] = se.expr;
4602 gfc_init_se (&se, NULL);
4603 gfc_conv_expr_val (&se, fa->end);
4604 /* Record it in this_forall. */
4605 this_forall->end = se.expr;
4606 gfc_make_safe_expr (&se);
4607 gfc_add_block_to_block (&block, &se.pre);
4608 end[n] = se.expr;
4610 gfc_init_se (&se, NULL);
4611 gfc_conv_expr_val (&se, fa->stride);
4612 /* Record it in this_forall. */
4613 this_forall->step = se.expr;
4614 gfc_make_safe_expr (&se);
4615 gfc_add_block_to_block (&block, &se.pre);
4616 step[n] = se.expr;
4618 /* Set the NEXT field of this_forall to NULL. */
4619 this_forall->next = NULL;
4620 /* Link this_forall to the info construct. */
4621 if (info->this_loop)
4623 iter_info *iter_tmp = info->this_loop;
4624 while (iter_tmp->next != NULL)
4625 iter_tmp = iter_tmp->next;
4626 iter_tmp->next = this_forall;
4628 else
4629 info->this_loop = this_forall;
4631 n++;
4633 nvar = n;
4635 /* Calculate the size needed for the current forall level. */
4636 size = gfc_index_one_node;
4637 for (n = 0; n < nvar; n++)
4639 /* size = (end + step - start) / step. */
4640 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (start[n]),
4641 step[n], start[n]);
4642 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (end[n]),
4643 end[n], tmp);
4644 tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, TREE_TYPE (tmp),
4645 tmp, step[n]);
4646 tmp = convert (gfc_array_index_type, tmp);
4648 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4649 size, tmp);
4652 /* Record the nvar and size of current forall level. */
4653 info->nvar = nvar;
4654 info->size = size;
4656 if (code->expr1)
4658 /* If the mask is .true., consider the FORALL unconditional. */
4659 if (code->expr1->expr_type == EXPR_CONSTANT
4660 && code->expr1->value.logical)
4661 need_mask = false;
4662 else
4663 need_mask = true;
4665 else
4666 need_mask = false;
4668 /* First we need to allocate the mask. */
4669 if (need_mask)
4671 /* As the mask array can be very big, prefer compact boolean types. */
4672 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4673 mask = allocate_temp_for_forall_nest (nested_forall_info, mask_type,
4674 size, NULL, &block, &pmask);
4675 maskindex = gfc_create_var_np (gfc_array_index_type, "mi");
4677 /* Record them in the info structure. */
4678 info->maskindex = maskindex;
4679 info->mask = mask;
4681 else
4683 /* No mask was specified. */
4684 maskindex = NULL_TREE;
4685 mask = pmask = NULL_TREE;
4688 /* Link the current forall level to nested_forall_info. */
4689 info->prev_nest = nested_forall_info;
4690 nested_forall_info = info;
4692 /* Copy the mask into a temporary variable if required.
4693 For now we assume a mask temporary is needed. */
4694 if (need_mask)
4696 /* As the mask array can be very big, prefer compact boolean types. */
4697 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4699 gfc_add_modify (&block, maskindex, gfc_index_zero_node);
4701 /* Start of mask assignment loop body. */
4702 gfc_start_block (&body);
4704 /* Evaluate the mask expression. */
4705 gfc_init_se (&se, NULL);
4706 gfc_conv_expr_val (&se, code->expr1);
4707 gfc_add_block_to_block (&body, &se.pre);
4709 /* Store the mask. */
4710 se.expr = convert (mask_type, se.expr);
4712 tmp = gfc_build_array_ref (mask, maskindex, NULL);
4713 gfc_add_modify (&body, tmp, se.expr);
4715 /* Advance to the next mask element. */
4716 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4717 maskindex, gfc_index_one_node);
4718 gfc_add_modify (&body, maskindex, tmp);
4720 /* Generate the loops. */
4721 tmp = gfc_finish_block (&body);
4722 tmp = gfc_trans_nested_forall_loop (info, tmp, 0);
4723 gfc_add_expr_to_block (&block, tmp);
4726 if (code->op == EXEC_DO_CONCURRENT)
4728 gfc_init_block (&body);
4729 cycle_label = gfc_build_label_decl (NULL_TREE);
4730 code->cycle_label = cycle_label;
4731 tmp = gfc_trans_code (code->block->next);
4732 gfc_add_expr_to_block (&body, tmp);
4734 if (TREE_USED (cycle_label))
4736 tmp = build1_v (LABEL_EXPR, cycle_label);
4737 gfc_add_expr_to_block (&body, tmp);
4740 tmp = gfc_finish_block (&body);
4741 nested_forall_info->do_concurrent = true;
4742 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4743 gfc_add_expr_to_block (&block, tmp);
4744 goto done;
4747 c = code->block->next;
4749 /* TODO: loop merging in FORALL statements. */
4750 /* Now that we've got a copy of the mask, generate the assignment loops. */
4751 while (c)
4753 switch (c->op)
4755 case EXEC_ASSIGN:
4756 /* A scalar or array assignment. DO the simple check for
4757 lhs to rhs dependencies. These make a temporary for the
4758 rhs and form a second forall block to copy to variable. */
4759 need_temp = check_forall_dependencies(c, &pre, &post);
4761 /* Temporaries due to array assignment data dependencies introduce
4762 no end of problems. */
4763 if (need_temp || flag_test_forall_temp)
4764 gfc_trans_assign_need_temp (c->expr1, c->expr2, NULL, false,
4765 nested_forall_info, &block);
4766 else
4768 /* Use the normal assignment copying routines. */
4769 assign = gfc_trans_assignment (c->expr1, c->expr2, false, true);
4771 /* Generate body and loops. */
4772 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4773 assign, 1);
4774 gfc_add_expr_to_block (&block, tmp);
4777 /* Cleanup any temporary symtrees that have been made to deal
4778 with dependencies. */
4779 if (new_symtree)
4780 cleanup_forall_symtrees (c);
4782 break;
4784 case EXEC_WHERE:
4785 /* Translate WHERE or WHERE construct nested in FORALL. */
4786 gfc_trans_where_2 (c, NULL, false, nested_forall_info, &block);
4787 break;
4789 /* Pointer assignment inside FORALL. */
4790 case EXEC_POINTER_ASSIGN:
4791 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
4792 /* Avoid cases where a temporary would never be needed and where
4793 the temp code is guaranteed to fail. */
4794 if (need_temp
4795 || (flag_test_forall_temp
4796 && c->expr2->expr_type != EXPR_CONSTANT
4797 && c->expr2->expr_type != EXPR_NULL))
4798 gfc_trans_pointer_assign_need_temp (c->expr1, c->expr2,
4799 nested_forall_info, &block);
4800 else
4802 /* Use the normal assignment copying routines. */
4803 assign = gfc_trans_pointer_assignment (c->expr1, c->expr2);
4805 /* Generate body and loops. */
4806 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4807 assign, 1);
4808 gfc_add_expr_to_block (&block, tmp);
4810 break;
4812 case EXEC_FORALL:
4813 tmp = gfc_trans_forall_1 (c, nested_forall_info);
4814 gfc_add_expr_to_block (&block, tmp);
4815 break;
4817 /* Explicit subroutine calls are prevented by the frontend but interface
4818 assignments can legitimately produce them. */
4819 case EXEC_ASSIGN_CALL:
4820 assign = gfc_trans_call (c, true, NULL_TREE, NULL_TREE, false);
4821 tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign, 1);
4822 gfc_add_expr_to_block (&block, tmp);
4823 break;
4825 default:
4826 gcc_unreachable ();
4829 c = c->next;
4832 done:
4833 /* Restore the original index variables. */
4834 for (fa = code->ext.forall_iterator, n = 0; fa; fa = fa->next, n++)
4835 gfc_restore_sym (fa->var->symtree->n.sym, &saved_vars[n]);
4837 /* Free the space for var, start, end, step, varexpr. */
4838 free (var);
4839 free (start);
4840 free (end);
4841 free (step);
4842 free (varexpr);
4843 free (saved_vars);
4845 for (this_forall = info->this_loop; this_forall;)
4847 iter_info *next = this_forall->next;
4848 free (this_forall);
4849 this_forall = next;
4852 /* Free the space for this forall_info. */
4853 free (info);
4855 if (pmask)
4857 /* Free the temporary for the mask. */
4858 tmp = gfc_call_free (pmask);
4859 gfc_add_expr_to_block (&block, tmp);
4861 if (maskindex)
4862 pushdecl (maskindex);
4864 gfc_add_block_to_block (&pre, &block);
4865 gfc_add_block_to_block (&pre, &post);
4867 return gfc_finish_block (&pre);
4871 /* Translate the FORALL statement or construct. */
4873 tree gfc_trans_forall (gfc_code * code)
4875 return gfc_trans_forall_1 (code, NULL);
4879 /* Translate the DO CONCURRENT construct. */
4881 tree gfc_trans_do_concurrent (gfc_code * code)
4883 return gfc_trans_forall_1 (code, NULL);
4887 /* Evaluate the WHERE mask expression, copy its value to a temporary.
4888 If the WHERE construct is nested in FORALL, compute the overall temporary
4889 needed by the WHERE mask expression multiplied by the iterator number of
4890 the nested forall.
4891 ME is the WHERE mask expression.
4892 MASK is the current execution mask upon input, whose sense may or may
4893 not be inverted as specified by the INVERT argument.
4894 CMASK is the updated execution mask on output, or NULL if not required.
4895 PMASK is the pending execution mask on output, or NULL if not required.
4896 BLOCK is the block in which to place the condition evaluation loops. */
4898 static void
4899 gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
4900 tree mask, bool invert, tree cmask, tree pmask,
4901 tree mask_type, stmtblock_t * block)
4903 tree tmp, tmp1;
4904 gfc_ss *lss, *rss;
4905 gfc_loopinfo loop;
4906 stmtblock_t body, body1;
4907 tree count, cond, mtmp;
4908 gfc_se lse, rse;
4910 gfc_init_loopinfo (&loop);
4912 lss = gfc_walk_expr (me);
4913 rss = gfc_walk_expr (me);
4915 /* Variable to index the temporary. */
4916 count = gfc_create_var (gfc_array_index_type, "count");
4917 /* Initialize count. */
4918 gfc_add_modify (block, count, gfc_index_zero_node);
4920 gfc_start_block (&body);
4922 gfc_init_se (&rse, NULL);
4923 gfc_init_se (&lse, NULL);
4925 if (lss == gfc_ss_terminator)
4927 gfc_init_block (&body1);
4929 else
4931 /* Initialize the loop. */
4932 gfc_init_loopinfo (&loop);
4934 /* We may need LSS to determine the shape of the expression. */
4935 gfc_add_ss_to_loop (&loop, lss);
4936 gfc_add_ss_to_loop (&loop, rss);
4938 gfc_conv_ss_startstride (&loop);
4939 gfc_conv_loop_setup (&loop, &me->where);
4941 gfc_mark_ss_chain_used (rss, 1);
4942 /* Start the loop body. */
4943 gfc_start_scalarized_body (&loop, &body1);
4945 /* Translate the expression. */
4946 gfc_copy_loopinfo_to_se (&rse, &loop);
4947 rse.ss = rss;
4948 gfc_conv_expr (&rse, me);
4951 /* Variable to evaluate mask condition. */
4952 cond = gfc_create_var (mask_type, "cond");
4953 if (mask && (cmask || pmask))
4954 mtmp = gfc_create_var (mask_type, "mask");
4955 else mtmp = NULL_TREE;
4957 gfc_add_block_to_block (&body1, &lse.pre);
4958 gfc_add_block_to_block (&body1, &rse.pre);
4960 gfc_add_modify (&body1, cond, fold_convert (mask_type, rse.expr));
4962 if (mask && (cmask || pmask))
4964 tmp = gfc_build_array_ref (mask, count, NULL);
4965 if (invert)
4966 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, tmp);
4967 gfc_add_modify (&body1, mtmp, tmp);
4970 if (cmask)
4972 tmp1 = gfc_build_array_ref (cmask, count, NULL);
4973 tmp = cond;
4974 if (mask)
4975 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type,
4976 mtmp, tmp);
4977 gfc_add_modify (&body1, tmp1, tmp);
4980 if (pmask)
4982 tmp1 = gfc_build_array_ref (pmask, count, NULL);
4983 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, cond);
4984 if (mask)
4985 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type, mtmp,
4986 tmp);
4987 gfc_add_modify (&body1, tmp1, tmp);
4990 gfc_add_block_to_block (&body1, &lse.post);
4991 gfc_add_block_to_block (&body1, &rse.post);
4993 if (lss == gfc_ss_terminator)
4995 gfc_add_block_to_block (&body, &body1);
4997 else
4999 /* Increment count. */
5000 tmp1 = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5001 count, gfc_index_one_node);
5002 gfc_add_modify (&body1, count, tmp1);
5004 /* Generate the copying loops. */
5005 gfc_trans_scalarizing_loops (&loop, &body1);
5007 gfc_add_block_to_block (&body, &loop.pre);
5008 gfc_add_block_to_block (&body, &loop.post);
5010 gfc_cleanup_loop (&loop);
5011 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
5012 as tree nodes in SS may not be valid in different scope. */
5015 tmp1 = gfc_finish_block (&body);
5016 /* If the WHERE construct is inside FORALL, fill the full temporary. */
5017 if (nested_forall_info != NULL)
5018 tmp1 = gfc_trans_nested_forall_loop (nested_forall_info, tmp1, 1);
5020 gfc_add_expr_to_block (block, tmp1);
5024 /* Translate an assignment statement in a WHERE statement or construct
5025 statement. The MASK expression is used to control which elements
5026 of EXPR1 shall be assigned. The sense of MASK is specified by
5027 INVERT. */
5029 static tree
5030 gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
5031 tree mask, bool invert,
5032 tree count1, tree count2,
5033 gfc_code *cnext)
5035 gfc_se lse;
5036 gfc_se rse;
5037 gfc_ss *lss;
5038 gfc_ss *lss_section;
5039 gfc_ss *rss;
5041 gfc_loopinfo loop;
5042 tree tmp;
5043 stmtblock_t block;
5044 stmtblock_t body;
5045 tree index, maskexpr;
5047 /* A defined assignment. */
5048 if (cnext && cnext->resolved_sym)
5049 return gfc_trans_call (cnext, true, mask, count1, invert);
5051 #if 0
5052 /* TODO: handle this special case.
5053 Special case a single function returning an array. */
5054 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
5056 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
5057 if (tmp)
5058 return tmp;
5060 #endif
5062 /* Assignment of the form lhs = rhs. */
5063 gfc_start_block (&block);
5065 gfc_init_se (&lse, NULL);
5066 gfc_init_se (&rse, NULL);
5068 /* Walk the lhs. */
5069 lss = gfc_walk_expr (expr1);
5070 rss = NULL;
5072 /* In each where-assign-stmt, the mask-expr and the variable being
5073 defined shall be arrays of the same shape. */
5074 gcc_assert (lss != gfc_ss_terminator);
5076 /* The assignment needs scalarization. */
5077 lss_section = lss;
5079 /* Find a non-scalar SS from the lhs. */
5080 while (lss_section != gfc_ss_terminator
5081 && lss_section->info->type != GFC_SS_SECTION)
5082 lss_section = lss_section->next;
5084 gcc_assert (lss_section != gfc_ss_terminator);
5086 /* Initialize the scalarizer. */
5087 gfc_init_loopinfo (&loop);
5089 /* Walk the rhs. */
5090 rss = gfc_walk_expr (expr2);
5091 if (rss == gfc_ss_terminator)
5093 /* The rhs is scalar. Add a ss for the expression. */
5094 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
5095 rss->info->where = 1;
5098 /* Associate the SS with the loop. */
5099 gfc_add_ss_to_loop (&loop, lss);
5100 gfc_add_ss_to_loop (&loop, rss);
5102 /* Calculate the bounds of the scalarization. */
5103 gfc_conv_ss_startstride (&loop);
5105 /* Resolve any data dependencies in the statement. */
5106 gfc_conv_resolve_dependencies (&loop, lss_section, rss);
5108 /* Setup the scalarizing loops. */
5109 gfc_conv_loop_setup (&loop, &expr2->where);
5111 /* Setup the gfc_se structures. */
5112 gfc_copy_loopinfo_to_se (&lse, &loop);
5113 gfc_copy_loopinfo_to_se (&rse, &loop);
5115 rse.ss = rss;
5116 gfc_mark_ss_chain_used (rss, 1);
5117 if (loop.temp_ss == NULL)
5119 lse.ss = lss;
5120 gfc_mark_ss_chain_used (lss, 1);
5122 else
5124 lse.ss = loop.temp_ss;
5125 gfc_mark_ss_chain_used (lss, 3);
5126 gfc_mark_ss_chain_used (loop.temp_ss, 3);
5129 /* Start the scalarized loop body. */
5130 gfc_start_scalarized_body (&loop, &body);
5132 /* Translate the expression. */
5133 gfc_conv_expr (&rse, expr2);
5134 if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
5135 gfc_conv_tmp_array_ref (&lse);
5136 else
5137 gfc_conv_expr (&lse, expr1);
5139 /* Form the mask expression according to the mask. */
5140 index = count1;
5141 maskexpr = gfc_build_array_ref (mask, index, NULL);
5142 if (invert)
5143 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
5144 TREE_TYPE (maskexpr), maskexpr);
5146 /* Use the scalar assignment as is. */
5147 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
5148 false, loop.temp_ss == NULL);
5150 tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt (input_location));
5152 gfc_add_expr_to_block (&body, tmp);
5154 if (lss == gfc_ss_terminator)
5156 /* Increment count1. */
5157 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5158 count1, gfc_index_one_node);
5159 gfc_add_modify (&body, count1, tmp);
5161 /* Use the scalar assignment as is. */
5162 gfc_add_block_to_block (&block, &body);
5164 else
5166 gcc_assert (lse.ss == gfc_ss_terminator
5167 && rse.ss == gfc_ss_terminator);
5169 if (loop.temp_ss != NULL)
5171 /* Increment count1 before finish the main body of a scalarized
5172 expression. */
5173 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5174 gfc_array_index_type, count1, gfc_index_one_node);
5175 gfc_add_modify (&body, count1, tmp);
5176 gfc_trans_scalarized_loop_boundary (&loop, &body);
5178 /* We need to copy the temporary to the actual lhs. */
5179 gfc_init_se (&lse, NULL);
5180 gfc_init_se (&rse, NULL);
5181 gfc_copy_loopinfo_to_se (&lse, &loop);
5182 gfc_copy_loopinfo_to_se (&rse, &loop);
5184 rse.ss = loop.temp_ss;
5185 lse.ss = lss;
5187 gfc_conv_tmp_array_ref (&rse);
5188 gfc_conv_expr (&lse, expr1);
5190 gcc_assert (lse.ss == gfc_ss_terminator
5191 && rse.ss == gfc_ss_terminator);
5193 /* Form the mask expression according to the mask tree list. */
5194 index = count2;
5195 maskexpr = gfc_build_array_ref (mask, index, NULL);
5196 if (invert)
5197 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
5198 TREE_TYPE (maskexpr), maskexpr);
5200 /* Use the scalar assignment as is. */
5201 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, false, true);
5202 tmp = build3_v (COND_EXPR, maskexpr, tmp,
5203 build_empty_stmt (input_location));
5204 gfc_add_expr_to_block (&body, tmp);
5206 /* Increment count2. */
5207 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5208 gfc_array_index_type, count2,
5209 gfc_index_one_node);
5210 gfc_add_modify (&body, count2, tmp);
5212 else
5214 /* Increment count1. */
5215 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5216 gfc_array_index_type, count1,
5217 gfc_index_one_node);
5218 gfc_add_modify (&body, count1, tmp);
5221 /* Generate the copying loops. */
5222 gfc_trans_scalarizing_loops (&loop, &body);
5224 /* Wrap the whole thing up. */
5225 gfc_add_block_to_block (&block, &loop.pre);
5226 gfc_add_block_to_block (&block, &loop.post);
5227 gfc_cleanup_loop (&loop);
5230 return gfc_finish_block (&block);
5234 /* Translate the WHERE construct or statement.
5235 This function can be called iteratively to translate the nested WHERE
5236 construct or statement.
5237 MASK is the control mask. */
5239 static void
5240 gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
5241 forall_info * nested_forall_info, stmtblock_t * block)
5243 stmtblock_t inner_size_body;
5244 tree inner_size, size;
5245 gfc_ss *lss, *rss;
5246 tree mask_type;
5247 gfc_expr *expr1;
5248 gfc_expr *expr2;
5249 gfc_code *cblock;
5250 gfc_code *cnext;
5251 tree tmp;
5252 tree cond;
5253 tree count1, count2;
5254 bool need_cmask;
5255 bool need_pmask;
5256 int need_temp;
5257 tree pcmask = NULL_TREE;
5258 tree ppmask = NULL_TREE;
5259 tree cmask = NULL_TREE;
5260 tree pmask = NULL_TREE;
5261 gfc_actual_arglist *arg;
5263 /* the WHERE statement or the WHERE construct statement. */
5264 cblock = code->block;
5266 /* As the mask array can be very big, prefer compact boolean types. */
5267 mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
5269 /* Determine which temporary masks are needed. */
5270 if (!cblock->block)
5272 /* One clause: No ELSEWHEREs. */
5273 need_cmask = (cblock->next != 0);
5274 need_pmask = false;
5276 else if (cblock->block->block)
5278 /* Three or more clauses: Conditional ELSEWHEREs. */
5279 need_cmask = true;
5280 need_pmask = true;
5282 else if (cblock->next)
5284 /* Two clauses, the first non-empty. */
5285 need_cmask = true;
5286 need_pmask = (mask != NULL_TREE
5287 && cblock->block->next != 0);
5289 else if (!cblock->block->next)
5291 /* Two clauses, both empty. */
5292 need_cmask = false;
5293 need_pmask = false;
5295 /* Two clauses, the first empty, the second non-empty. */
5296 else if (mask)
5298 need_cmask = (cblock->block->expr1 != 0);
5299 need_pmask = true;
5301 else
5303 need_cmask = true;
5304 need_pmask = false;
5307 if (need_cmask || need_pmask)
5309 /* Calculate the size of temporary needed by the mask-expr. */
5310 gfc_init_block (&inner_size_body);
5311 inner_size = compute_inner_temp_size (cblock->expr1, cblock->expr1,
5312 &inner_size_body, &lss, &rss);
5314 gfc_free_ss_chain (lss);
5315 gfc_free_ss_chain (rss);
5317 /* Calculate the total size of temporary needed. */
5318 size = compute_overall_iter_number (nested_forall_info, inner_size,
5319 &inner_size_body, block);
5321 /* Check whether the size is negative. */
5322 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, size,
5323 gfc_index_zero_node);
5324 size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
5325 cond, gfc_index_zero_node, size);
5326 size = gfc_evaluate_now (size, block);
5328 /* Allocate temporary for WHERE mask if needed. */
5329 if (need_cmask)
5330 cmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
5331 &pcmask);
5333 /* Allocate temporary for !mask if needed. */
5334 if (need_pmask)
5335 pmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
5336 &ppmask);
5339 while (cblock)
5341 /* Each time around this loop, the where clause is conditional
5342 on the value of mask and invert, which are updated at the
5343 bottom of the loop. */
5345 /* Has mask-expr. */
5346 if (cblock->expr1)
5348 /* Ensure that the WHERE mask will be evaluated exactly once.
5349 If there are no statements in this WHERE/ELSEWHERE clause,
5350 then we don't need to update the control mask (cmask).
5351 If this is the last clause of the WHERE construct, then
5352 we don't need to update the pending control mask (pmask). */
5353 if (mask)
5354 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
5355 mask, invert,
5356 cblock->next ? cmask : NULL_TREE,
5357 cblock->block ? pmask : NULL_TREE,
5358 mask_type, block);
5359 else
5360 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
5361 NULL_TREE, false,
5362 (cblock->next || cblock->block)
5363 ? cmask : NULL_TREE,
5364 NULL_TREE, mask_type, block);
5366 invert = false;
5368 /* It's a final elsewhere-stmt. No mask-expr is present. */
5369 else
5370 cmask = mask;
5372 /* The body of this where clause are controlled by cmask with
5373 sense specified by invert. */
5375 /* Get the assignment statement of a WHERE statement, or the first
5376 statement in where-body-construct of a WHERE construct. */
5377 cnext = cblock->next;
5378 while (cnext)
5380 switch (cnext->op)
5382 /* WHERE assignment statement. */
5383 case EXEC_ASSIGN_CALL:
5385 arg = cnext->ext.actual;
5386 expr1 = expr2 = NULL;
5387 for (; arg; arg = arg->next)
5389 if (!arg->expr)
5390 continue;
5391 if (expr1 == NULL)
5392 expr1 = arg->expr;
5393 else
5394 expr2 = arg->expr;
5396 goto evaluate;
5398 case EXEC_ASSIGN:
5399 expr1 = cnext->expr1;
5400 expr2 = cnext->expr2;
5401 evaluate:
5402 if (nested_forall_info != NULL)
5404 need_temp = gfc_check_dependency (expr1, expr2, 0);
5405 if ((need_temp || flag_test_forall_temp)
5406 && cnext->op != EXEC_ASSIGN_CALL)
5407 gfc_trans_assign_need_temp (expr1, expr2,
5408 cmask, invert,
5409 nested_forall_info, block);
5410 else
5412 /* Variables to control maskexpr. */
5413 count1 = gfc_create_var (gfc_array_index_type, "count1");
5414 count2 = gfc_create_var (gfc_array_index_type, "count2");
5415 gfc_add_modify (block, count1, gfc_index_zero_node);
5416 gfc_add_modify (block, count2, gfc_index_zero_node);
5418 tmp = gfc_trans_where_assign (expr1, expr2,
5419 cmask, invert,
5420 count1, count2,
5421 cnext);
5423 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
5424 tmp, 1);
5425 gfc_add_expr_to_block (block, tmp);
5428 else
5430 /* Variables to control maskexpr. */
5431 count1 = gfc_create_var (gfc_array_index_type, "count1");
5432 count2 = gfc_create_var (gfc_array_index_type, "count2");
5433 gfc_add_modify (block, count1, gfc_index_zero_node);
5434 gfc_add_modify (block, count2, gfc_index_zero_node);
5436 tmp = gfc_trans_where_assign (expr1, expr2,
5437 cmask, invert,
5438 count1, count2,
5439 cnext);
5440 gfc_add_expr_to_block (block, tmp);
5443 break;
5445 /* WHERE or WHERE construct is part of a where-body-construct. */
5446 case EXEC_WHERE:
5447 gfc_trans_where_2 (cnext, cmask, invert,
5448 nested_forall_info, block);
5449 break;
5451 default:
5452 gcc_unreachable ();
5455 /* The next statement within the same where-body-construct. */
5456 cnext = cnext->next;
5458 /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt. */
5459 cblock = cblock->block;
5460 if (mask == NULL_TREE)
5462 /* If we're the initial WHERE, we can simply invert the sense
5463 of the current mask to obtain the "mask" for the remaining
5464 ELSEWHEREs. */
5465 invert = true;
5466 mask = cmask;
5468 else
5470 /* Otherwise, for nested WHERE's we need to use the pending mask. */
5471 invert = false;
5472 mask = pmask;
5476 /* If we allocated a pending mask array, deallocate it now. */
5477 if (ppmask)
5479 tmp = gfc_call_free (ppmask);
5480 gfc_add_expr_to_block (block, tmp);
5483 /* If we allocated a current mask array, deallocate it now. */
5484 if (pcmask)
5486 tmp = gfc_call_free (pcmask);
5487 gfc_add_expr_to_block (block, tmp);
5491 /* Translate a simple WHERE construct or statement without dependencies.
5492 CBLOCK is the "then" clause of the WHERE statement, where CBLOCK->EXPR
5493 is the mask condition, and EBLOCK if non-NULL is the "else" clause.
5494 Currently both CBLOCK and EBLOCK are restricted to single assignments. */
5496 static tree
5497 gfc_trans_where_3 (gfc_code * cblock, gfc_code * eblock)
5499 stmtblock_t block, body;
5500 gfc_expr *cond, *tdst, *tsrc, *edst, *esrc;
5501 tree tmp, cexpr, tstmt, estmt;
5502 gfc_ss *css, *tdss, *tsss;
5503 gfc_se cse, tdse, tsse, edse, esse;
5504 gfc_loopinfo loop;
5505 gfc_ss *edss = 0;
5506 gfc_ss *esss = 0;
5507 bool maybe_workshare = false;
5509 /* Allow the scalarizer to workshare simple where loops. */
5510 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
5511 == OMPWS_WORKSHARE_FLAG)
5513 maybe_workshare = true;
5514 ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
5517 cond = cblock->expr1;
5518 tdst = cblock->next->expr1;
5519 tsrc = cblock->next->expr2;
5520 edst = eblock ? eblock->next->expr1 : NULL;
5521 esrc = eblock ? eblock->next->expr2 : NULL;
5523 gfc_start_block (&block);
5524 gfc_init_loopinfo (&loop);
5526 /* Handle the condition. */
5527 gfc_init_se (&cse, NULL);
5528 css = gfc_walk_expr (cond);
5529 gfc_add_ss_to_loop (&loop, css);
5531 /* Handle the then-clause. */
5532 gfc_init_se (&tdse, NULL);
5533 gfc_init_se (&tsse, NULL);
5534 tdss = gfc_walk_expr (tdst);
5535 tsss = gfc_walk_expr (tsrc);
5536 if (tsss == gfc_ss_terminator)
5538 tsss = gfc_get_scalar_ss (gfc_ss_terminator, tsrc);
5539 tsss->info->where = 1;
5541 gfc_add_ss_to_loop (&loop, tdss);
5542 gfc_add_ss_to_loop (&loop, tsss);
5544 if (eblock)
5546 /* Handle the else clause. */
5547 gfc_init_se (&edse, NULL);
5548 gfc_init_se (&esse, NULL);
5549 edss = gfc_walk_expr (edst);
5550 esss = gfc_walk_expr (esrc);
5551 if (esss == gfc_ss_terminator)
5553 esss = gfc_get_scalar_ss (gfc_ss_terminator, esrc);
5554 esss->info->where = 1;
5556 gfc_add_ss_to_loop (&loop, edss);
5557 gfc_add_ss_to_loop (&loop, esss);
5560 gfc_conv_ss_startstride (&loop);
5561 gfc_conv_loop_setup (&loop, &tdst->where);
5563 gfc_mark_ss_chain_used (css, 1);
5564 gfc_mark_ss_chain_used (tdss, 1);
5565 gfc_mark_ss_chain_used (tsss, 1);
5566 if (eblock)
5568 gfc_mark_ss_chain_used (edss, 1);
5569 gfc_mark_ss_chain_used (esss, 1);
5572 gfc_start_scalarized_body (&loop, &body);
5574 gfc_copy_loopinfo_to_se (&cse, &loop);
5575 gfc_copy_loopinfo_to_se (&tdse, &loop);
5576 gfc_copy_loopinfo_to_se (&tsse, &loop);
5577 cse.ss = css;
5578 tdse.ss = tdss;
5579 tsse.ss = tsss;
5580 if (eblock)
5582 gfc_copy_loopinfo_to_se (&edse, &loop);
5583 gfc_copy_loopinfo_to_se (&esse, &loop);
5584 edse.ss = edss;
5585 esse.ss = esss;
5588 gfc_conv_expr (&cse, cond);
5589 gfc_add_block_to_block (&body, &cse.pre);
5590 cexpr = cse.expr;
5592 gfc_conv_expr (&tsse, tsrc);
5593 if (tdss != gfc_ss_terminator && loop.temp_ss != NULL)
5594 gfc_conv_tmp_array_ref (&tdse);
5595 else
5596 gfc_conv_expr (&tdse, tdst);
5598 if (eblock)
5600 gfc_conv_expr (&esse, esrc);
5601 if (edss != gfc_ss_terminator && loop.temp_ss != NULL)
5602 gfc_conv_tmp_array_ref (&edse);
5603 else
5604 gfc_conv_expr (&edse, edst);
5607 tstmt = gfc_trans_scalar_assign (&tdse, &tsse, tdst->ts, false, true);
5608 estmt = eblock ? gfc_trans_scalar_assign (&edse, &esse, edst->ts,
5609 false, true)
5610 : build_empty_stmt (input_location);
5611 tmp = build3_v (COND_EXPR, cexpr, tstmt, estmt);
5612 gfc_add_expr_to_block (&body, tmp);
5613 gfc_add_block_to_block (&body, &cse.post);
5615 if (maybe_workshare)
5616 ompws_flags &= ~OMPWS_SCALARIZER_BODY;
5617 gfc_trans_scalarizing_loops (&loop, &body);
5618 gfc_add_block_to_block (&block, &loop.pre);
5619 gfc_add_block_to_block (&block, &loop.post);
5620 gfc_cleanup_loop (&loop);
5622 return gfc_finish_block (&block);
5625 /* As the WHERE or WHERE construct statement can be nested, we call
5626 gfc_trans_where_2 to do the translation, and pass the initial
5627 NULL values for both the control mask and the pending control mask. */
5629 tree
5630 gfc_trans_where (gfc_code * code)
5632 stmtblock_t block;
5633 gfc_code *cblock;
5634 gfc_code *eblock;
5636 cblock = code->block;
5637 if (cblock->next
5638 && cblock->next->op == EXEC_ASSIGN
5639 && !cblock->next->next)
5641 eblock = cblock->block;
5642 if (!eblock)
5644 /* A simple "WHERE (cond) x = y" statement or block is
5645 dependence free if cond is not dependent upon writing x,
5646 and the source y is unaffected by the destination x. */
5647 if (!gfc_check_dependency (cblock->next->expr1,
5648 cblock->expr1, 0)
5649 && !gfc_check_dependency (cblock->next->expr1,
5650 cblock->next->expr2, 0))
5651 return gfc_trans_where_3 (cblock, NULL);
5653 else if (!eblock->expr1
5654 && !eblock->block
5655 && eblock->next
5656 && eblock->next->op == EXEC_ASSIGN
5657 && !eblock->next->next)
5659 /* A simple "WHERE (cond) x1 = y1 ELSEWHERE x2 = y2 ENDWHERE"
5660 block is dependence free if cond is not dependent on writes
5661 to x1 and x2, y1 is not dependent on writes to x2, and y2
5662 is not dependent on writes to x1, and both y's are not
5663 dependent upon their own x's. In addition to this, the
5664 final two dependency checks below exclude all but the same
5665 array reference if the where and elswhere destinations
5666 are the same. In short, this is VERY conservative and this
5667 is needed because the two loops, required by the standard
5668 are coalesced in gfc_trans_where_3. */
5669 if (!gfc_check_dependency (cblock->next->expr1,
5670 cblock->expr1, 0)
5671 && !gfc_check_dependency (eblock->next->expr1,
5672 cblock->expr1, 0)
5673 && !gfc_check_dependency (cblock->next->expr1,
5674 eblock->next->expr2, 1)
5675 && !gfc_check_dependency (eblock->next->expr1,
5676 cblock->next->expr2, 1)
5677 && !gfc_check_dependency (cblock->next->expr1,
5678 cblock->next->expr2, 1)
5679 && !gfc_check_dependency (eblock->next->expr1,
5680 eblock->next->expr2, 1)
5681 && !gfc_check_dependency (cblock->next->expr1,
5682 eblock->next->expr1, 0)
5683 && !gfc_check_dependency (eblock->next->expr1,
5684 cblock->next->expr1, 0))
5685 return gfc_trans_where_3 (cblock, eblock);
5689 gfc_start_block (&block);
5691 gfc_trans_where_2 (code, NULL, false, NULL, &block);
5693 return gfc_finish_block (&block);
5697 /* CYCLE a DO loop. The label decl has already been created by
5698 gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
5699 node at the head of the loop. We must mark the label as used. */
5701 tree
5702 gfc_trans_cycle (gfc_code * code)
5704 tree cycle_label;
5706 cycle_label = code->ext.which_construct->cycle_label;
5707 gcc_assert (cycle_label);
5709 TREE_USED (cycle_label) = 1;
5710 return build1_v (GOTO_EXPR, cycle_label);
5714 /* EXIT a DO loop. Similar to CYCLE, but now the label is in
5715 TREE_VALUE (backend_decl) of the gfc_code node at the head of the
5716 loop. */
5718 tree
5719 gfc_trans_exit (gfc_code * code)
5721 tree exit_label;
5723 exit_label = code->ext.which_construct->exit_label;
5724 gcc_assert (exit_label);
5726 TREE_USED (exit_label) = 1;
5727 return build1_v (GOTO_EXPR, exit_label);
5731 /* Get the initializer expression for the code and expr of an allocate.
5732 When no initializer is needed return NULL. */
5734 static gfc_expr *
5735 allocate_get_initializer (gfc_code * code, gfc_expr * expr)
5737 if (!gfc_bt_struct (expr->ts.type) && expr->ts.type != BT_CLASS)
5738 return NULL;
5740 /* An explicit type was given in allocate ( T:: object). */
5741 if (code->ext.alloc.ts.type == BT_DERIVED
5742 && (code->ext.alloc.ts.u.derived->attr.alloc_comp
5743 || gfc_has_default_initializer (code->ext.alloc.ts.u.derived)))
5744 return gfc_default_initializer (&code->ext.alloc.ts);
5746 if (gfc_bt_struct (expr->ts.type)
5747 && (expr->ts.u.derived->attr.alloc_comp
5748 || gfc_has_default_initializer (expr->ts.u.derived)))
5749 return gfc_default_initializer (&expr->ts);
5751 if (expr->ts.type == BT_CLASS
5752 && (CLASS_DATA (expr)->ts.u.derived->attr.alloc_comp
5753 || gfc_has_default_initializer (CLASS_DATA (expr)->ts.u.derived)))
5754 return gfc_default_initializer (&CLASS_DATA (expr)->ts);
5756 return NULL;
5759 /* Translate the ALLOCATE statement. */
5761 tree
5762 gfc_trans_allocate (gfc_code * code)
5764 gfc_alloc *al;
5765 gfc_expr *expr, *e3rhs = NULL, *init_expr;
5766 gfc_se se, se_sz;
5767 tree tmp;
5768 tree parm;
5769 tree stat;
5770 tree errmsg;
5771 tree errlen;
5772 tree label_errmsg;
5773 tree label_finish;
5774 tree memsz;
5775 tree al_vptr, al_len;
5776 /* If an expr3 is present, then store the tree for accessing its
5777 _vptr, and _len components in the variables, respectively. The
5778 element size, i.e. _vptr%size, is stored in expr3_esize. Any of
5779 the trees may be the NULL_TREE indicating that this is not
5780 available for expr3's type. */
5781 tree expr3, expr3_vptr, expr3_len, expr3_esize;
5782 /* Classify what expr3 stores. */
5783 enum { E3_UNSET = 0, E3_SOURCE, E3_MOLD, E3_DESC } e3_is;
5784 stmtblock_t block;
5785 stmtblock_t post;
5786 tree nelems;
5787 bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set, is_coarray;
5788 bool needs_caf_sync, caf_refs_comp;
5789 gfc_symtree *newsym = NULL;
5790 symbol_attribute caf_attr;
5791 gfc_actual_arglist *param_list;
5793 if (!code->ext.alloc.list)
5794 return NULL_TREE;
5796 stat = tmp = memsz = al_vptr = al_len = NULL_TREE;
5797 expr3 = expr3_vptr = expr3_len = expr3_esize = NULL_TREE;
5798 label_errmsg = label_finish = errmsg = errlen = NULL_TREE;
5799 e3_is = E3_UNSET;
5800 is_coarray = needs_caf_sync = false;
5802 gfc_init_block (&block);
5803 gfc_init_block (&post);
5805 /* STAT= (and maybe ERRMSG=) is present. */
5806 if (code->expr1)
5808 /* STAT=. */
5809 tree gfc_int4_type_node = gfc_get_int_type (4);
5810 stat = gfc_create_var (gfc_int4_type_node, "stat");
5812 /* ERRMSG= only makes sense with STAT=. */
5813 if (code->expr2)
5815 gfc_init_se (&se, NULL);
5816 se.want_pointer = 1;
5817 gfc_conv_expr_lhs (&se, code->expr2);
5818 errmsg = se.expr;
5819 errlen = se.string_length;
5821 else
5823 errmsg = null_pointer_node;
5824 errlen = build_int_cst (gfc_charlen_type_node, 0);
5827 /* GOTO destinations. */
5828 label_errmsg = gfc_build_label_decl (NULL_TREE);
5829 label_finish = gfc_build_label_decl (NULL_TREE);
5830 TREE_USED (label_finish) = 0;
5833 /* When an expr3 is present evaluate it only once. The standards prevent a
5834 dependency of expr3 on the objects in the allocate list. An expr3 can
5835 be pre-evaluated in all cases. One just has to make sure, to use the
5836 correct way, i.e., to get the descriptor or to get a reference
5837 expression. */
5838 if (code->expr3)
5840 bool vtab_needed = false, temp_var_needed = false,
5841 temp_obj_created = false;
5843 is_coarray = gfc_is_coarray (code->expr3);
5845 /* Figure whether we need the vtab from expr3. */
5846 for (al = code->ext.alloc.list; !vtab_needed && al != NULL;
5847 al = al->next)
5848 vtab_needed = (al->expr->ts.type == BT_CLASS);
5850 gfc_init_se (&se, NULL);
5851 /* When expr3 is a variable, i.e., a very simple expression,
5852 then convert it once here. */
5853 if (code->expr3->expr_type == EXPR_VARIABLE
5854 || code->expr3->expr_type == EXPR_ARRAY
5855 || code->expr3->expr_type == EXPR_CONSTANT)
5857 if (!code->expr3->mold
5858 || code->expr3->ts.type == BT_CHARACTER
5859 || vtab_needed
5860 || code->ext.alloc.arr_spec_from_expr3)
5862 /* Convert expr3 to a tree. For all "simple" expression just
5863 get the descriptor or the reference, respectively, depending
5864 on the rank of the expr. */
5865 if (code->ext.alloc.arr_spec_from_expr3 || code->expr3->rank != 0)
5866 gfc_conv_expr_descriptor (&se, code->expr3);
5867 else
5869 gfc_conv_expr_reference (&se, code->expr3);
5871 /* gfc_conv_expr_reference wraps POINTER_PLUS_EXPR in a
5872 NOP_EXPR, which prevents gfortran from getting the vptr
5873 from the source=-expression. Remove the NOP_EXPR and go
5874 with the POINTER_PLUS_EXPR in this case. */
5875 if (code->expr3->ts.type == BT_CLASS
5876 && TREE_CODE (se.expr) == NOP_EXPR
5877 && (TREE_CODE (TREE_OPERAND (se.expr, 0))
5878 == POINTER_PLUS_EXPR
5879 || is_coarray))
5880 se.expr = TREE_OPERAND (se.expr, 0);
5882 /* Create a temp variable only for component refs to prevent
5883 having to go through the full deref-chain each time and to
5884 simplfy computation of array properties. */
5885 temp_var_needed = TREE_CODE (se.expr) == COMPONENT_REF;
5888 else
5890 /* In all other cases evaluate the expr3. */
5891 symbol_attribute attr;
5892 /* Get the descriptor for all arrays, that are not allocatable or
5893 pointer, because the latter are descriptors already.
5894 The exception are function calls returning a class object:
5895 The descriptor is stored in their results _data component, which
5896 is easier to access, when first a temporary variable for the
5897 result is created and the descriptor retrieved from there. */
5898 attr = gfc_expr_attr (code->expr3);
5899 if (code->expr3->rank != 0
5900 && ((!attr.allocatable && !attr.pointer)
5901 || (code->expr3->expr_type == EXPR_FUNCTION
5902 && (code->expr3->ts.type != BT_CLASS
5903 || (code->expr3->value.function.isym
5904 && code->expr3->value.function.isym
5905 ->transformational)))))
5906 gfc_conv_expr_descriptor (&se, code->expr3);
5907 else
5908 gfc_conv_expr_reference (&se, code->expr3);
5909 if (code->expr3->ts.type == BT_CLASS)
5910 gfc_conv_class_to_class (&se, code->expr3,
5911 code->expr3->ts,
5912 false, true,
5913 false, false);
5914 temp_obj_created = temp_var_needed = !VAR_P (se.expr);
5916 gfc_add_block_to_block (&block, &se.pre);
5917 gfc_add_block_to_block (&post, &se.post);
5919 /* Special case when string in expr3 is zero. */
5920 if (code->expr3->ts.type == BT_CHARACTER
5921 && integer_zerop (se.string_length))
5923 gfc_init_se (&se, NULL);
5924 temp_var_needed = false;
5925 expr3_len = build_zero_cst (gfc_charlen_type_node);
5926 e3_is = E3_MOLD;
5928 /* Prevent aliasing, i.e., se.expr may be already a
5929 variable declaration. */
5930 else if (se.expr != NULL_TREE && temp_var_needed)
5932 tree var, desc;
5933 tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)) || is_coarray ?
5934 se.expr
5935 : build_fold_indirect_ref_loc (input_location, se.expr);
5937 /* Get the array descriptor and prepare it to be assigned to the
5938 temporary variable var. For classes the array descriptor is
5939 in the _data component and the object goes into the
5940 GFC_DECL_SAVED_DESCRIPTOR. */
5941 if (code->expr3->ts.type == BT_CLASS
5942 && code->expr3->rank != 0)
5944 /* When an array_ref was in expr3, then the descriptor is the
5945 first operand. */
5946 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
5948 desc = TREE_OPERAND (tmp, 0);
5950 else
5952 desc = tmp;
5953 tmp = gfc_class_data_get (tmp);
5955 if (code->ext.alloc.arr_spec_from_expr3)
5956 e3_is = E3_DESC;
5958 else
5959 desc = !is_coarray ? se.expr
5960 : TREE_OPERAND (TREE_OPERAND (se.expr, 0), 0);
5961 /* We need a regular (non-UID) symbol here, therefore give a
5962 prefix. */
5963 var = gfc_create_var (TREE_TYPE (tmp), "source");
5964 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
5966 gfc_allocate_lang_decl (var);
5967 GFC_DECL_SAVED_DESCRIPTOR (var) = desc;
5969 gfc_add_modify_loc (input_location, &block, var, tmp);
5971 expr3 = var;
5972 if (se.string_length)
5973 /* Evaluate it assuming that it also is complicated like expr3. */
5974 expr3_len = gfc_evaluate_now (se.string_length, &block);
5976 else
5978 expr3 = se.expr;
5979 expr3_len = se.string_length;
5982 /* Deallocate any allocatable components in expressions that use a
5983 temporary object, i.e. are not a simple alias of to an EXPR_VARIABLE.
5984 E.g. temporaries of a function call need freeing of their components
5985 here. */
5986 if ((code->expr3->ts.type == BT_DERIVED
5987 || code->expr3->ts.type == BT_CLASS)
5988 && (code->expr3->expr_type != EXPR_VARIABLE || temp_obj_created)
5989 && code->expr3->ts.u.derived->attr.alloc_comp)
5991 tmp = gfc_deallocate_alloc_comp (code->expr3->ts.u.derived,
5992 expr3, code->expr3->rank);
5993 gfc_prepend_expr_to_block (&post, tmp);
5996 /* Store what the expr3 is to be used for. */
5997 if (e3_is == E3_UNSET)
5998 e3_is = expr3 != NULL_TREE ?
5999 (code->ext.alloc.arr_spec_from_expr3 ?
6000 E3_DESC
6001 : (code->expr3->mold ? E3_MOLD : E3_SOURCE))
6002 : E3_UNSET;
6004 /* Figure how to get the _vtab entry. This also obtains the tree
6005 expression for accessing the _len component, because only
6006 unlimited polymorphic objects, which are a subcategory of class
6007 types, have a _len component. */
6008 if (code->expr3->ts.type == BT_CLASS)
6010 gfc_expr *rhs;
6011 tmp = expr3 != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (expr3)) ?
6012 build_fold_indirect_ref (expr3): expr3;
6013 /* Polymorphic SOURCE: VPTR must be determined at run time.
6014 expr3 may be a temporary array declaration, therefore check for
6015 GFC_CLASS_TYPE_P before trying to get the _vptr component. */
6016 if (tmp != NULL_TREE
6017 && (e3_is == E3_DESC
6018 || (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
6019 && (VAR_P (tmp) || !code->expr3->ref))
6020 || (VAR_P (tmp) && DECL_LANG_SPECIFIC (tmp))))
6021 tmp = gfc_class_vptr_get (expr3);
6022 else
6024 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
6025 gfc_add_vptr_component (rhs);
6026 gfc_init_se (&se, NULL);
6027 se.want_pointer = 1;
6028 gfc_conv_expr (&se, rhs);
6029 tmp = se.expr;
6030 gfc_free_expr (rhs);
6032 /* Set the element size. */
6033 expr3_esize = gfc_vptr_size_get (tmp);
6034 if (vtab_needed)
6035 expr3_vptr = tmp;
6036 /* Initialize the ref to the _len component. */
6037 if (expr3_len == NULL_TREE && UNLIMITED_POLY (code->expr3))
6039 /* Same like for retrieving the _vptr. */
6040 if (expr3 != NULL_TREE && !code->expr3->ref)
6041 expr3_len = gfc_class_len_get (expr3);
6042 else
6044 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
6045 gfc_add_len_component (rhs);
6046 gfc_init_se (&se, NULL);
6047 gfc_conv_expr (&se, rhs);
6048 expr3_len = se.expr;
6049 gfc_free_expr (rhs);
6053 else
6055 /* When the object to allocate is polymorphic type, then it
6056 needs its vtab set correctly, so deduce the required _vtab
6057 and _len from the source expression. */
6058 if (vtab_needed)
6060 /* VPTR is fixed at compile time. */
6061 gfc_symbol *vtab;
6063 vtab = gfc_find_vtab (&code->expr3->ts);
6064 gcc_assert (vtab);
6065 expr3_vptr = gfc_get_symbol_decl (vtab);
6066 expr3_vptr = gfc_build_addr_expr (NULL_TREE,
6067 expr3_vptr);
6069 /* _len component needs to be set, when ts is a character
6070 array. */
6071 if (expr3_len == NULL_TREE
6072 && code->expr3->ts.type == BT_CHARACTER)
6074 if (code->expr3->ts.u.cl
6075 && code->expr3->ts.u.cl->length)
6077 gfc_init_se (&se, NULL);
6078 gfc_conv_expr (&se, code->expr3->ts.u.cl->length);
6079 gfc_add_block_to_block (&block, &se.pre);
6080 expr3_len = gfc_evaluate_now (se.expr, &block);
6082 gcc_assert (expr3_len);
6084 /* For character arrays only the kind's size is needed, because
6085 the array mem_size is _len * (elem_size = kind_size).
6086 For all other get the element size in the normal way. */
6087 if (code->expr3->ts.type == BT_CHARACTER)
6088 expr3_esize = TYPE_SIZE_UNIT (
6089 gfc_get_char_type (code->expr3->ts.kind));
6090 else
6091 expr3_esize = TYPE_SIZE_UNIT (
6092 gfc_typenode_for_spec (&code->expr3->ts));
6094 gcc_assert (expr3_esize);
6095 expr3_esize = fold_convert (sizetype, expr3_esize);
6096 if (e3_is == E3_MOLD)
6097 /* The expr3 is no longer valid after this point. */
6098 expr3 = NULL_TREE;
6100 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
6102 /* Compute the explicit typespec given only once for all objects
6103 to allocate. */
6104 if (code->ext.alloc.ts.type != BT_CHARACTER)
6105 expr3_esize = TYPE_SIZE_UNIT (
6106 gfc_typenode_for_spec (&code->ext.alloc.ts));
6107 else if (code->ext.alloc.ts.u.cl->length != NULL)
6109 gfc_expr *sz;
6110 sz = gfc_copy_expr (code->ext.alloc.ts.u.cl->length);
6111 gfc_init_se (&se_sz, NULL);
6112 gfc_conv_expr (&se_sz, sz);
6113 gfc_free_expr (sz);
6114 tmp = gfc_get_char_type (code->ext.alloc.ts.kind);
6115 tmp = TYPE_SIZE_UNIT (tmp);
6116 tmp = fold_convert (TREE_TYPE (se_sz.expr), tmp);
6117 gfc_add_block_to_block (&block, &se_sz.pre);
6118 expr3_esize = fold_build2_loc (input_location, MULT_EXPR,
6119 TREE_TYPE (se_sz.expr),
6120 tmp, se_sz.expr);
6121 expr3_esize = gfc_evaluate_now (expr3_esize, &block);
6123 else
6124 expr3_esize = NULL_TREE;
6127 /* The routine gfc_trans_assignment () already implements all
6128 techniques needed. Unfortunately we may have a temporary
6129 variable for the source= expression here. When that is the
6130 case convert this variable into a temporary gfc_expr of type
6131 EXPR_VARIABLE and used it as rhs for the assignment. The
6132 advantage is, that we get scalarizer support for free,
6133 don't have to take care about scalar to array treatment and
6134 will benefit of every enhancements gfc_trans_assignment ()
6135 gets.
6136 No need to check whether e3_is is E3_UNSET, because that is
6137 done by expr3 != NULL_TREE.
6138 Exclude variables since the following block does not handle
6139 array sections. In any case, there is no harm in sending
6140 variables to gfc_trans_assignment because there is no
6141 evaluation of variables. */
6142 if (code->expr3)
6144 if (code->expr3->expr_type != EXPR_VARIABLE
6145 && e3_is != E3_MOLD && expr3 != NULL_TREE
6146 && DECL_P (expr3) && DECL_ARTIFICIAL (expr3))
6148 /* Build a temporary symtree and symbol. Do not add it to the current
6149 namespace to prevent accidently modifying a colliding
6150 symbol's as. */
6151 newsym = XCNEW (gfc_symtree);
6152 /* The name of the symtree should be unique, because gfc_create_var ()
6153 took care about generating the identifier. */
6154 newsym->name
6155 = gfc_get_string ("%s", IDENTIFIER_POINTER (DECL_NAME (expr3)));
6156 newsym->n.sym = gfc_new_symbol (newsym->name, NULL);
6157 /* The backend_decl is known. It is expr3, which is inserted
6158 here. */
6159 newsym->n.sym->backend_decl = expr3;
6160 e3rhs = gfc_get_expr ();
6161 e3rhs->rank = code->expr3->rank;
6162 e3rhs->symtree = newsym;
6163 /* Mark the symbol referenced or gfc_trans_assignment will bug. */
6164 newsym->n.sym->attr.referenced = 1;
6165 e3rhs->expr_type = EXPR_VARIABLE;
6166 e3rhs->where = code->expr3->where;
6167 /* Set the symbols type, upto it was BT_UNKNOWN. */
6168 if (IS_CLASS_ARRAY (code->expr3)
6169 && code->expr3->expr_type == EXPR_FUNCTION
6170 && code->expr3->value.function.isym
6171 && code->expr3->value.function.isym->transformational)
6173 e3rhs->ts = CLASS_DATA (code->expr3)->ts;
6175 else if (code->expr3->ts.type == BT_CLASS
6176 && !GFC_CLASS_TYPE_P (TREE_TYPE (expr3)))
6177 e3rhs->ts = CLASS_DATA (code->expr3)->ts;
6178 else
6179 e3rhs->ts = code->expr3->ts;
6180 newsym->n.sym->ts = e3rhs->ts;
6181 /* Check whether the expr3 is array valued. */
6182 if (e3rhs->rank)
6184 gfc_array_spec *arr;
6185 arr = gfc_get_array_spec ();
6186 arr->rank = e3rhs->rank;
6187 arr->type = AS_DEFERRED;
6188 /* Set the dimension and pointer attribute for arrays
6189 to be on the safe side. */
6190 newsym->n.sym->attr.dimension = 1;
6191 newsym->n.sym->attr.pointer = 1;
6192 newsym->n.sym->as = arr;
6193 if (IS_CLASS_ARRAY (code->expr3)
6194 && code->expr3->expr_type == EXPR_FUNCTION
6195 && code->expr3->value.function.isym
6196 && code->expr3->value.function.isym->transformational)
6198 gfc_array_spec *tarr;
6199 tarr = gfc_get_array_spec ();
6200 *tarr = *arr;
6201 e3rhs->ts.u.derived->as = tarr;
6203 gfc_add_full_array_ref (e3rhs, arr);
6205 else if (POINTER_TYPE_P (TREE_TYPE (expr3)))
6206 newsym->n.sym->attr.pointer = 1;
6207 /* The string length is known, too. Set it for char arrays. */
6208 if (e3rhs->ts.type == BT_CHARACTER)
6209 newsym->n.sym->ts.u.cl->backend_decl = expr3_len;
6210 gfc_commit_symbol (newsym->n.sym);
6212 else
6213 e3rhs = gfc_copy_expr (code->expr3);
6216 /* Loop over all objects to allocate. */
6217 for (al = code->ext.alloc.list; al != NULL; al = al->next)
6219 expr = gfc_copy_expr (al->expr);
6220 /* UNLIMITED_POLY () needs the _data component to be set, when
6221 expr is a unlimited polymorphic object. But the _data component
6222 has not been set yet, so check the derived type's attr for the
6223 unlimited polymorphic flag to be safe. */
6224 upoly_expr = UNLIMITED_POLY (expr)
6225 || (expr->ts.type == BT_DERIVED
6226 && expr->ts.u.derived->attr.unlimited_polymorphic);
6227 gfc_init_se (&se, NULL);
6229 /* For class types prepare the expressions to ref the _vptr
6230 and the _len component. The latter for unlimited polymorphic
6231 types only. */
6232 if (expr->ts.type == BT_CLASS)
6234 gfc_expr *expr_ref_vptr, *expr_ref_len;
6235 gfc_add_data_component (expr);
6236 /* Prep the vptr handle. */
6237 expr_ref_vptr = gfc_copy_expr (al->expr);
6238 gfc_add_vptr_component (expr_ref_vptr);
6239 se.want_pointer = 1;
6240 gfc_conv_expr (&se, expr_ref_vptr);
6241 al_vptr = se.expr;
6242 se.want_pointer = 0;
6243 gfc_free_expr (expr_ref_vptr);
6244 /* Allocated unlimited polymorphic objects always have a _len
6245 component. */
6246 if (upoly_expr)
6248 expr_ref_len = gfc_copy_expr (al->expr);
6249 gfc_add_len_component (expr_ref_len);
6250 gfc_conv_expr (&se, expr_ref_len);
6251 al_len = se.expr;
6252 gfc_free_expr (expr_ref_len);
6254 else
6255 /* In a loop ensure that all loop variable dependent variables
6256 are initialized at the same spot in all execution paths. */
6257 al_len = NULL_TREE;
6259 else
6260 al_vptr = al_len = NULL_TREE;
6262 se.want_pointer = 1;
6263 se.descriptor_only = 1;
6265 gfc_conv_expr (&se, expr);
6266 if (expr->ts.type == BT_CHARACTER && expr->ts.deferred)
6267 /* se.string_length now stores the .string_length variable of expr
6268 needed to allocate character(len=:) arrays. */
6269 al_len = se.string_length;
6271 al_len_needs_set = al_len != NULL_TREE;
6272 /* When allocating an array one can not use much of the
6273 pre-evaluated expr3 expressions, because for most of them the
6274 scalarizer is needed which is not available in the pre-evaluation
6275 step. Therefore gfc_array_allocate () is responsible (and able)
6276 to handle the complete array allocation. Only the element size
6277 needs to be provided, which is done most of the time by the
6278 pre-evaluation step. */
6279 nelems = NULL_TREE;
6280 if (expr3_len && (code->expr3->ts.type == BT_CHARACTER
6281 || code->expr3->ts.type == BT_CLASS))
6283 /* When al is an array, then the element size for each element
6284 in the array is needed, which is the product of the len and
6285 esize for char arrays. For unlimited polymorphics len can be
6286 zero, therefore take the maximum of len and one. */
6287 tmp = fold_build2_loc (input_location, MAX_EXPR,
6288 TREE_TYPE (expr3_len),
6289 expr3_len, fold_convert (TREE_TYPE (expr3_len),
6290 integer_one_node));
6291 tmp = fold_build2_loc (input_location, MULT_EXPR,
6292 TREE_TYPE (expr3_esize), expr3_esize,
6293 fold_convert (TREE_TYPE (expr3_esize), tmp));
6295 else
6296 tmp = expr3_esize;
6297 if (!gfc_array_allocate (&se, expr, stat, errmsg, errlen,
6298 label_finish, tmp, &nelems,
6299 e3rhs ? e3rhs : code->expr3,
6300 e3_is == E3_DESC ? expr3 : NULL_TREE,
6301 code->expr3 != NULL && e3_is == E3_DESC
6302 && code->expr3->expr_type == EXPR_ARRAY))
6304 /* A scalar or derived type. First compute the size to
6305 allocate.
6307 expr3_len is set when expr3 is an unlimited polymorphic
6308 object or a deferred length string. */
6309 if (expr3_len != NULL_TREE)
6311 tmp = fold_convert (TREE_TYPE (expr3_esize), expr3_len);
6312 tmp = fold_build2_loc (input_location, MULT_EXPR,
6313 TREE_TYPE (expr3_esize),
6314 expr3_esize, tmp);
6315 if (code->expr3->ts.type != BT_CLASS)
6316 /* expr3 is a deferred length string, i.e., we are
6317 done. */
6318 memsz = tmp;
6319 else
6321 /* For unlimited polymorphic enties build
6322 (len > 0) ? element_size * len : element_size
6323 to compute the number of bytes to allocate.
6324 This allows the allocation of unlimited polymorphic
6325 objects from an expr3 that is also unlimited
6326 polymorphic and stores a _len dependent object,
6327 e.g., a string. */
6328 memsz = fold_build2_loc (input_location, GT_EXPR,
6329 logical_type_node, expr3_len,
6330 build_zero_cst
6331 (TREE_TYPE (expr3_len)));
6332 memsz = fold_build3_loc (input_location, COND_EXPR,
6333 TREE_TYPE (expr3_esize),
6334 memsz, tmp, expr3_esize);
6337 else if (expr3_esize != NULL_TREE)
6338 /* Any other object in expr3 just needs element size in
6339 bytes. */
6340 memsz = expr3_esize;
6341 else if ((expr->ts.type == BT_CHARACTER && expr->ts.deferred)
6342 || (upoly_expr
6343 && code->ext.alloc.ts.type == BT_CHARACTER))
6345 /* Allocating deferred length char arrays need the length
6346 to allocate in the alloc_type_spec. But also unlimited
6347 polymorphic objects may be allocated as char arrays.
6348 Both are handled here. */
6349 gfc_init_se (&se_sz, NULL);
6350 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6351 gfc_add_block_to_block (&se.pre, &se_sz.pre);
6352 se_sz.expr = gfc_evaluate_now (se_sz.expr, &se.pre);
6353 gfc_add_block_to_block (&se.pre, &se_sz.post);
6354 expr3_len = se_sz.expr;
6355 tmp_expr3_len_flag = true;
6356 tmp = TYPE_SIZE_UNIT (
6357 gfc_get_char_type (code->ext.alloc.ts.kind));
6358 memsz = fold_build2_loc (input_location, MULT_EXPR,
6359 TREE_TYPE (tmp),
6360 fold_convert (TREE_TYPE (tmp),
6361 expr3_len),
6362 tmp);
6364 else if (expr->ts.type == BT_CHARACTER)
6366 /* Compute the number of bytes needed to allocate a fixed
6367 length char array. */
6368 gcc_assert (se.string_length != NULL_TREE);
6369 tmp = TYPE_SIZE_UNIT (gfc_get_char_type (expr->ts.kind));
6370 memsz = fold_build2_loc (input_location, MULT_EXPR,
6371 TREE_TYPE (tmp), tmp,
6372 fold_convert (TREE_TYPE (tmp),
6373 se.string_length));
6375 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
6376 /* Handle all types, where the alloc_type_spec is set. */
6377 memsz = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->ext.alloc.ts));
6378 else
6379 /* Handle size computation of the type declared to alloc. */
6380 memsz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
6382 /* Store the caf-attributes for latter use. */
6383 if (flag_coarray == GFC_FCOARRAY_LIB
6384 && (caf_attr = gfc_caf_attr (expr, true, &caf_refs_comp))
6385 .codimension)
6387 /* Scalar allocatable components in coarray'ed derived types make
6388 it here and are treated now. */
6389 tree caf_decl, token;
6390 gfc_se caf_se;
6392 is_coarray = true;
6393 /* Set flag, to add synchronize after the allocate. */
6394 needs_caf_sync = needs_caf_sync
6395 || caf_attr.coarray_comp || !caf_refs_comp;
6397 gfc_init_se (&caf_se, NULL);
6399 caf_decl = gfc_get_tree_for_caf_expr (expr);
6400 gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl,
6401 NULL_TREE, NULL);
6402 gfc_add_block_to_block (&se.pre, &caf_se.pre);
6403 gfc_allocate_allocatable (&se.pre, se.expr, memsz,
6404 gfc_build_addr_expr (NULL_TREE, token),
6405 NULL_TREE, NULL_TREE, NULL_TREE,
6406 label_finish, expr, 1);
6408 /* Allocate - for non-pointers with re-alloc checking. */
6409 else if (gfc_expr_attr (expr).allocatable)
6410 gfc_allocate_allocatable (&se.pre, se.expr, memsz,
6411 NULL_TREE, stat, errmsg, errlen,
6412 label_finish, expr, 0);
6413 else
6414 gfc_allocate_using_malloc (&se.pre, se.expr, memsz, stat);
6416 else
6418 /* Allocating coarrays needs a sync after the allocate executed.
6419 Set the flag to add the sync after all objects are allocated. */
6420 if (flag_coarray == GFC_FCOARRAY_LIB
6421 && (caf_attr = gfc_caf_attr (expr, true, &caf_refs_comp))
6422 .codimension)
6424 is_coarray = true;
6425 needs_caf_sync = needs_caf_sync
6426 || caf_attr.coarray_comp || !caf_refs_comp;
6429 if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
6430 && expr3_len != NULL_TREE)
6432 /* Arrays need to have a _len set before the array
6433 descriptor is filled. */
6434 gfc_add_modify (&block, al_len,
6435 fold_convert (TREE_TYPE (al_len), expr3_len));
6436 /* Prevent setting the length twice. */
6437 al_len_needs_set = false;
6439 else if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
6440 && code->ext.alloc.ts.u.cl->length)
6442 /* Cover the cases where a string length is explicitly
6443 specified by a type spec for deferred length character
6444 arrays or unlimited polymorphic objects without a
6445 source= or mold= expression. */
6446 gfc_init_se (&se_sz, NULL);
6447 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6448 gfc_add_block_to_block (&block, &se_sz.pre);
6449 gfc_add_modify (&block, al_len,
6450 fold_convert (TREE_TYPE (al_len),
6451 se_sz.expr));
6452 al_len_needs_set = false;
6456 gfc_add_block_to_block (&block, &se.pre);
6458 /* Error checking -- Note: ERRMSG only makes sense with STAT. */
6459 if (code->expr1)
6461 tmp = build1_v (GOTO_EXPR, label_errmsg);
6462 parm = fold_build2_loc (input_location, NE_EXPR,
6463 logical_type_node, stat,
6464 build_int_cst (TREE_TYPE (stat), 0));
6465 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6466 gfc_unlikely (parm, PRED_FORTRAN_FAIL_ALLOC),
6467 tmp, build_empty_stmt (input_location));
6468 gfc_add_expr_to_block (&block, tmp);
6471 /* Set the vptr only when no source= is set. When source= is set, then
6472 the trans_assignment below will set the vptr. */
6473 if (al_vptr != NULL_TREE && (!code->expr3 || code->expr3->mold))
6475 if (expr3_vptr != NULL_TREE)
6476 /* The vtab is already known, so just assign it. */
6477 gfc_add_modify (&block, al_vptr,
6478 fold_convert (TREE_TYPE (al_vptr), expr3_vptr));
6479 else
6481 /* VPTR is fixed at compile time. */
6482 gfc_symbol *vtab;
6483 gfc_typespec *ts;
6485 if (code->expr3)
6486 /* Although expr3 is pre-evaluated above, it may happen,
6487 that for arrays or in mold= cases the pre-evaluation
6488 was not successful. In these rare cases take the vtab
6489 from the typespec of expr3 here. */
6490 ts = &code->expr3->ts;
6491 else if (code->ext.alloc.ts.type == BT_DERIVED || upoly_expr)
6492 /* The alloc_type_spec gives the type to allocate or the
6493 al is unlimited polymorphic, which enforces the use of
6494 an alloc_type_spec that is not necessarily a BT_DERIVED. */
6495 ts = &code->ext.alloc.ts;
6496 else
6497 /* Prepare for setting the vtab as declared. */
6498 ts = &expr->ts;
6500 vtab = gfc_find_vtab (ts);
6501 gcc_assert (vtab);
6502 tmp = gfc_build_addr_expr (NULL_TREE,
6503 gfc_get_symbol_decl (vtab));
6504 gfc_add_modify (&block, al_vptr,
6505 fold_convert (TREE_TYPE (al_vptr), tmp));
6509 /* Add assignment for string length. */
6510 if (al_len != NULL_TREE && al_len_needs_set)
6512 if (expr3_len != NULL_TREE)
6514 gfc_add_modify (&block, al_len,
6515 fold_convert (TREE_TYPE (al_len),
6516 expr3_len));
6517 /* When tmp_expr3_len_flag is set, then expr3_len is
6518 abused to carry the length information from the
6519 alloc_type. Clear it to prevent setting incorrect len
6520 information in future loop iterations. */
6521 if (tmp_expr3_len_flag)
6522 /* No need to reset tmp_expr3_len_flag, because the
6523 presence of an expr3 can not change within in the
6524 loop. */
6525 expr3_len = NULL_TREE;
6527 else if (code->ext.alloc.ts.type == BT_CHARACTER
6528 && code->ext.alloc.ts.u.cl->length)
6530 /* Cover the cases where a string length is explicitly
6531 specified by a type spec for deferred length character
6532 arrays or unlimited polymorphic objects without a
6533 source= or mold= expression. */
6534 if (expr3_esize == NULL_TREE || code->ext.alloc.ts.kind != 1)
6536 gfc_init_se (&se_sz, NULL);
6537 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6538 gfc_add_block_to_block (&block, &se_sz.pre);
6539 gfc_add_modify (&block, al_len,
6540 fold_convert (TREE_TYPE (al_len),
6541 se_sz.expr));
6543 else
6544 gfc_add_modify (&block, al_len,
6545 fold_convert (TREE_TYPE (al_len),
6546 expr3_esize));
6548 else
6549 /* No length information needed, because type to allocate
6550 has no length. Set _len to 0. */
6551 gfc_add_modify (&block, al_len,
6552 fold_convert (TREE_TYPE (al_len),
6553 integer_zero_node));
6556 init_expr = NULL;
6557 if (code->expr3 && !code->expr3->mold && e3_is != E3_MOLD)
6559 /* Initialization via SOURCE block (or static default initializer).
6560 Switch off automatic reallocation since we have just done the
6561 ALLOCATE. */
6562 int realloc_lhs = flag_realloc_lhs;
6563 gfc_expr *init_expr = gfc_expr_to_initialize (expr);
6564 gfc_expr *rhs = e3rhs ? e3rhs : gfc_copy_expr (code->expr3);
6565 flag_realloc_lhs = 0;
6566 tmp = gfc_trans_assignment (init_expr, rhs, false, false, true,
6567 false);
6568 flag_realloc_lhs = realloc_lhs;
6569 /* Free the expression allocated for init_expr. */
6570 gfc_free_expr (init_expr);
6571 if (rhs != e3rhs)
6572 gfc_free_expr (rhs);
6573 gfc_add_expr_to_block (&block, tmp);
6575 /* Set KIND and LEN PDT components and allocate those that are
6576 parameterized. */
6577 else if (expr->ts.type == BT_DERIVED
6578 && expr->ts.u.derived->attr.pdt_type)
6580 if (code->expr3 && code->expr3->param_list)
6581 param_list = code->expr3->param_list;
6582 else if (expr->param_list)
6583 param_list = expr->param_list;
6584 else
6585 param_list = expr->symtree->n.sym->param_list;
6586 tmp = gfc_allocate_pdt_comp (expr->ts.u.derived, se.expr,
6587 expr->rank, param_list);
6588 gfc_add_expr_to_block (&block, tmp);
6590 /* Ditto for CLASS expressions. */
6591 else if (expr->ts.type == BT_CLASS
6592 && CLASS_DATA (expr)->ts.u.derived->attr.pdt_type)
6594 if (code->expr3 && code->expr3->param_list)
6595 param_list = code->expr3->param_list;
6596 else if (expr->param_list)
6597 param_list = expr->param_list;
6598 else
6599 param_list = expr->symtree->n.sym->param_list;
6600 tmp = gfc_allocate_pdt_comp (CLASS_DATA (expr)->ts.u.derived,
6601 se.expr, expr->rank, param_list);
6602 gfc_add_expr_to_block (&block, tmp);
6604 else if (code->expr3 && code->expr3->mold
6605 && code->expr3->ts.type == BT_CLASS)
6607 /* Use class_init_assign to initialize expr. */
6608 gfc_code *ini;
6609 ini = gfc_get_code (EXEC_INIT_ASSIGN);
6610 ini->expr1 = gfc_find_and_cut_at_last_class_ref (expr);
6611 tmp = gfc_trans_class_init_assign (ini);
6612 gfc_free_statements (ini);
6613 gfc_add_expr_to_block (&block, tmp);
6615 else if ((init_expr = allocate_get_initializer (code, expr)))
6617 /* Use class_init_assign to initialize expr. */
6618 gfc_code *ini;
6619 int realloc_lhs = flag_realloc_lhs;
6620 ini = gfc_get_code (EXEC_INIT_ASSIGN);
6621 ini->expr1 = gfc_expr_to_initialize (expr);
6622 ini->expr2 = init_expr;
6623 flag_realloc_lhs = 0;
6624 tmp= gfc_trans_init_assign (ini);
6625 flag_realloc_lhs = realloc_lhs;
6626 gfc_free_statements (ini);
6627 /* Init_expr is freeed by above free_statements, just need to null
6628 it here. */
6629 init_expr = NULL;
6630 gfc_add_expr_to_block (&block, tmp);
6633 /* Nullify all pointers in derived type coarrays. This registers a
6634 token for them which allows their allocation. */
6635 if (is_coarray)
6637 gfc_symbol *type = NULL;
6638 symbol_attribute caf_attr;
6639 int rank = 0;
6640 if (code->ext.alloc.ts.type == BT_DERIVED
6641 && code->ext.alloc.ts.u.derived->attr.pointer_comp)
6643 type = code->ext.alloc.ts.u.derived;
6644 rank = type->attr.dimension ? type->as->rank : 0;
6645 gfc_clear_attr (&caf_attr);
6647 else if (expr->ts.type == BT_DERIVED
6648 && expr->ts.u.derived->attr.pointer_comp)
6650 type = expr->ts.u.derived;
6651 rank = expr->rank;
6652 caf_attr = gfc_caf_attr (expr, true);
6655 /* Initialize the tokens of pointer components in derived type
6656 coarrays. */
6657 if (type)
6659 tmp = (caf_attr.codimension && !caf_attr.dimension)
6660 ? gfc_conv_descriptor_data_get (se.expr) : se.expr;
6661 tmp = gfc_nullify_alloc_comp (type, tmp, rank,
6662 GFC_STRUCTURE_CAF_MODE_IN_COARRAY);
6663 gfc_add_expr_to_block (&block, tmp);
6667 gfc_free_expr (expr);
6668 } // for-loop
6670 if (e3rhs)
6672 if (newsym)
6674 gfc_free_symbol (newsym->n.sym);
6675 XDELETE (newsym);
6677 gfc_free_expr (e3rhs);
6679 /* STAT. */
6680 if (code->expr1)
6682 tmp = build1_v (LABEL_EXPR, label_errmsg);
6683 gfc_add_expr_to_block (&block, tmp);
6686 /* ERRMSG - only useful if STAT is present. */
6687 if (code->expr1 && code->expr2)
6689 const char *msg = "Attempt to allocate an allocated object";
6690 tree slen, dlen, errmsg_str;
6691 stmtblock_t errmsg_block;
6693 gfc_init_block (&errmsg_block);
6695 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6696 gfc_add_modify (&errmsg_block, errmsg_str,
6697 gfc_build_addr_expr (pchar_type_node,
6698 gfc_build_localized_cstring_const (msg)));
6700 slen = build_int_cst (gfc_charlen_type_node, strlen (msg));
6701 dlen = gfc_get_expr_charlen (code->expr2);
6702 slen = fold_build2_loc (input_location, MIN_EXPR,
6703 TREE_TYPE (slen), dlen, slen);
6705 gfc_trans_string_copy (&errmsg_block, dlen, errmsg,
6706 code->expr2->ts.kind,
6707 slen, errmsg_str,
6708 gfc_default_character_kind);
6709 dlen = gfc_finish_block (&errmsg_block);
6711 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
6712 stat, build_int_cst (TREE_TYPE (stat), 0));
6714 tmp = build3_v (COND_EXPR, tmp,
6715 dlen, build_empty_stmt (input_location));
6717 gfc_add_expr_to_block (&block, tmp);
6720 /* STAT block. */
6721 if (code->expr1)
6723 if (TREE_USED (label_finish))
6725 tmp = build1_v (LABEL_EXPR, label_finish);
6726 gfc_add_expr_to_block (&block, tmp);
6729 gfc_init_se (&se, NULL);
6730 gfc_conv_expr_lhs (&se, code->expr1);
6731 tmp = convert (TREE_TYPE (se.expr), stat);
6732 gfc_add_modify (&block, se.expr, tmp);
6735 if (needs_caf_sync)
6737 /* Add a sync all after the allocation has been executed. */
6738 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
6739 3, null_pointer_node, null_pointer_node,
6740 integer_zero_node);
6741 gfc_add_expr_to_block (&post, tmp);
6744 gfc_add_block_to_block (&block, &se.post);
6745 gfc_add_block_to_block (&block, &post);
6747 return gfc_finish_block (&block);
6751 /* Translate a DEALLOCATE statement. */
6753 tree
6754 gfc_trans_deallocate (gfc_code *code)
6756 gfc_se se;
6757 gfc_alloc *al;
6758 tree apstat, pstat, stat, errmsg, errlen, tmp;
6759 tree label_finish, label_errmsg;
6760 stmtblock_t block;
6762 pstat = apstat = stat = errmsg = errlen = tmp = NULL_TREE;
6763 label_finish = label_errmsg = NULL_TREE;
6765 gfc_start_block (&block);
6767 /* Count the number of failed deallocations. If deallocate() was
6768 called with STAT= , then set STAT to the count. If deallocate
6769 was called with ERRMSG, then set ERRMG to a string. */
6770 if (code->expr1)
6772 tree gfc_int4_type_node = gfc_get_int_type (4);
6774 stat = gfc_create_var (gfc_int4_type_node, "stat");
6775 pstat = gfc_build_addr_expr (NULL_TREE, stat);
6777 /* GOTO destinations. */
6778 label_errmsg = gfc_build_label_decl (NULL_TREE);
6779 label_finish = gfc_build_label_decl (NULL_TREE);
6780 TREE_USED (label_finish) = 0;
6783 /* Set ERRMSG - only needed if STAT is available. */
6784 if (code->expr1 && code->expr2)
6786 gfc_init_se (&se, NULL);
6787 se.want_pointer = 1;
6788 gfc_conv_expr_lhs (&se, code->expr2);
6789 errmsg = se.expr;
6790 errlen = se.string_length;
6793 for (al = code->ext.alloc.list; al != NULL; al = al->next)
6795 gfc_expr *expr = gfc_copy_expr (al->expr);
6796 bool is_coarray = false, is_coarray_array = false;
6797 int caf_mode = 0;
6799 gcc_assert (expr->expr_type == EXPR_VARIABLE);
6801 if (expr->ts.type == BT_CLASS)
6802 gfc_add_data_component (expr);
6804 gfc_init_se (&se, NULL);
6805 gfc_start_block (&se.pre);
6807 se.want_pointer = 1;
6808 se.descriptor_only = 1;
6809 gfc_conv_expr (&se, expr);
6811 /* Deallocate PDT components that are parameterized. */
6812 tmp = NULL;
6813 if (expr->ts.type == BT_DERIVED
6814 && expr->ts.u.derived->attr.pdt_type
6815 && expr->symtree->n.sym->param_list)
6816 tmp = gfc_deallocate_pdt_comp (expr->ts.u.derived, se.expr, expr->rank);
6817 else if (expr->ts.type == BT_CLASS
6818 && CLASS_DATA (expr)->ts.u.derived->attr.pdt_type
6819 && expr->symtree->n.sym->param_list)
6820 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr)->ts.u.derived,
6821 se.expr, expr->rank);
6823 if (tmp)
6824 gfc_add_expr_to_block (&block, tmp);
6826 if (flag_coarray == GFC_FCOARRAY_LIB
6827 || flag_coarray == GFC_FCOARRAY_SINGLE)
6829 bool comp_ref;
6830 symbol_attribute caf_attr = gfc_caf_attr (expr, false, &comp_ref);
6831 if (caf_attr.codimension)
6833 is_coarray = true;
6834 is_coarray_array = caf_attr.dimension || !comp_ref
6835 || caf_attr.coarray_comp;
6837 if (flag_coarray == GFC_FCOARRAY_LIB)
6838 /* When the expression to deallocate is referencing a
6839 component, then only deallocate it, but do not
6840 deregister. */
6841 caf_mode = GFC_STRUCTURE_CAF_MODE_IN_COARRAY
6842 | (comp_ref && !caf_attr.coarray_comp
6843 ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY : 0);
6847 if (expr->rank || is_coarray_array)
6849 gfc_ref *ref;
6851 if (gfc_bt_struct (expr->ts.type)
6852 && expr->ts.u.derived->attr.alloc_comp
6853 && !gfc_is_finalizable (expr->ts.u.derived, NULL))
6855 gfc_ref *last = NULL;
6857 for (ref = expr->ref; ref; ref = ref->next)
6858 if (ref->type == REF_COMPONENT)
6859 last = ref;
6861 /* Do not deallocate the components of a derived type
6862 ultimate pointer component. */
6863 if (!(last && last->u.c.component->attr.pointer)
6864 && !(!last && expr->symtree->n.sym->attr.pointer))
6866 if (is_coarray && expr->rank == 0
6867 && (!last || !last->u.c.component->attr.dimension)
6868 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
6870 /* Add the ref to the data member only, when this is not
6871 a regular array or deallocate_alloc_comp will try to
6872 add another one. */
6873 tmp = gfc_conv_descriptor_data_get (se.expr);
6875 else
6876 tmp = se.expr;
6877 tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp,
6878 expr->rank, caf_mode);
6879 gfc_add_expr_to_block (&se.pre, tmp);
6883 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
6885 gfc_coarray_deregtype caf_dtype;
6887 if (is_coarray)
6888 caf_dtype = gfc_caf_is_dealloc_only (caf_mode)
6889 ? GFC_CAF_COARRAY_DEALLOCATE_ONLY
6890 : GFC_CAF_COARRAY_DEREGISTER;
6891 else
6892 caf_dtype = GFC_CAF_COARRAY_NOCOARRAY;
6893 tmp = gfc_deallocate_with_status (se.expr, pstat, errmsg, errlen,
6894 label_finish, false, expr,
6895 caf_dtype);
6896 gfc_add_expr_to_block (&se.pre, tmp);
6898 else if (TREE_CODE (se.expr) == COMPONENT_REF
6899 && TREE_CODE (TREE_TYPE (se.expr)) == ARRAY_TYPE
6900 && TREE_CODE (TREE_TYPE (TREE_TYPE (se.expr)))
6901 == RECORD_TYPE)
6903 /* class.c(finalize_component) generates these, when a
6904 finalizable entity has a non-allocatable derived type array
6905 component, which has allocatable components. Obtain the
6906 derived type of the array and deallocate the allocatable
6907 components. */
6908 for (ref = expr->ref; ref; ref = ref->next)
6910 if (ref->u.c.component->attr.dimension
6911 && ref->u.c.component->ts.type == BT_DERIVED)
6912 break;
6915 if (ref && ref->u.c.component->ts.u.derived->attr.alloc_comp
6916 && !gfc_is_finalizable (ref->u.c.component->ts.u.derived,
6917 NULL))
6919 tmp = gfc_deallocate_alloc_comp
6920 (ref->u.c.component->ts.u.derived,
6921 se.expr, expr->rank);
6922 gfc_add_expr_to_block (&se.pre, tmp);
6926 if (al->expr->ts.type == BT_CLASS)
6928 gfc_reset_vptr (&se.pre, al->expr);
6929 if (UNLIMITED_POLY (al->expr)
6930 || (al->expr->ts.type == BT_DERIVED
6931 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6932 /* Clear _len, too. */
6933 gfc_reset_len (&se.pre, al->expr);
6936 else
6938 tmp = gfc_deallocate_scalar_with_status (se.expr, pstat, label_finish,
6939 false, al->expr,
6940 al->expr->ts, is_coarray);
6941 gfc_add_expr_to_block (&se.pre, tmp);
6943 /* Set to zero after deallocation. */
6944 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
6945 se.expr,
6946 build_int_cst (TREE_TYPE (se.expr), 0));
6947 gfc_add_expr_to_block (&se.pre, tmp);
6949 if (al->expr->ts.type == BT_CLASS)
6951 gfc_reset_vptr (&se.pre, al->expr);
6952 if (UNLIMITED_POLY (al->expr)
6953 || (al->expr->ts.type == BT_DERIVED
6954 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6955 /* Clear _len, too. */
6956 gfc_reset_len (&se.pre, al->expr);
6960 if (code->expr1)
6962 tree cond;
6964 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, stat,
6965 build_int_cst (TREE_TYPE (stat), 0));
6966 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6967 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
6968 build1_v (GOTO_EXPR, label_errmsg),
6969 build_empty_stmt (input_location));
6970 gfc_add_expr_to_block (&se.pre, tmp);
6973 tmp = gfc_finish_block (&se.pre);
6974 gfc_add_expr_to_block (&block, tmp);
6975 gfc_free_expr (expr);
6978 if (code->expr1)
6980 tmp = build1_v (LABEL_EXPR, label_errmsg);
6981 gfc_add_expr_to_block (&block, tmp);
6984 /* Set ERRMSG - only needed if STAT is available. */
6985 if (code->expr1 && code->expr2)
6987 const char *msg = "Attempt to deallocate an unallocated object";
6988 stmtblock_t errmsg_block;
6989 tree errmsg_str, slen, dlen, cond;
6991 gfc_init_block (&errmsg_block);
6993 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6994 gfc_add_modify (&errmsg_block, errmsg_str,
6995 gfc_build_addr_expr (pchar_type_node,
6996 gfc_build_localized_cstring_const (msg)));
6997 slen = build_int_cst (gfc_charlen_type_node, strlen (msg));
6998 dlen = gfc_get_expr_charlen (code->expr2);
7000 gfc_trans_string_copy (&errmsg_block, dlen, errmsg, code->expr2->ts.kind,
7001 slen, errmsg_str, gfc_default_character_kind);
7002 tmp = gfc_finish_block (&errmsg_block);
7004 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, stat,
7005 build_int_cst (TREE_TYPE (stat), 0));
7006 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
7007 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC), tmp,
7008 build_empty_stmt (input_location));
7010 gfc_add_expr_to_block (&block, tmp);
7013 if (code->expr1 && TREE_USED (label_finish))
7015 tmp = build1_v (LABEL_EXPR, label_finish);
7016 gfc_add_expr_to_block (&block, tmp);
7019 /* Set STAT. */
7020 if (code->expr1)
7022 gfc_init_se (&se, NULL);
7023 gfc_conv_expr_lhs (&se, code->expr1);
7024 tmp = convert (TREE_TYPE (se.expr), stat);
7025 gfc_add_modify (&block, se.expr, tmp);
7028 return gfc_finish_block (&block);
7031 #include "gt-fortran-trans-stmt.h"