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