2015-06-11 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / gcc / fortran / trans-stmt.c
blob69750dfa01030814a0f14e7893f5b892f8974a1a
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 "input.h"
27 #include "alias.h"
28 #include "symtab.h"
29 #include "options.h"
30 #include "tree.h"
31 #include "fold-const.h"
32 #include "stringpool.h"
33 #include "gfortran.h"
34 #include "flags.h"
35 #include "trans.h"
36 #include "trans-stmt.h"
37 #include "trans-types.h"
38 #include "trans-array.h"
39 #include "trans-const.h"
40 #include "arith.h"
41 #include "dependency.h"
43 typedef struct iter_info
45 tree var;
46 tree start;
47 tree end;
48 tree step;
49 struct iter_info *next;
51 iter_info;
53 typedef struct forall_info
55 iter_info *this_loop;
56 tree mask;
57 tree maskindex;
58 int nvar;
59 tree size;
60 struct forall_info *prev_nest;
61 bool do_concurrent;
63 forall_info;
65 static void gfc_trans_where_2 (gfc_code *, tree, bool,
66 forall_info *, stmtblock_t *);
68 /* Translate a F95 label number to a LABEL_EXPR. */
70 tree
71 gfc_trans_label_here (gfc_code * code)
73 return build1_v (LABEL_EXPR, gfc_get_label_decl (code->here));
77 /* Given a variable expression which has been ASSIGNed to, find the decl
78 containing the auxiliary variables. For variables in common blocks this
79 is a field_decl. */
81 void
82 gfc_conv_label_variable (gfc_se * se, gfc_expr * expr)
84 gcc_assert (expr->symtree->n.sym->attr.assign == 1);
85 gfc_conv_expr (se, expr);
86 /* Deals with variable in common block. Get the field declaration. */
87 if (TREE_CODE (se->expr) == COMPONENT_REF)
88 se->expr = TREE_OPERAND (se->expr, 1);
89 /* Deals with dummy argument. Get the parameter declaration. */
90 else if (TREE_CODE (se->expr) == INDIRECT_REF)
91 se->expr = TREE_OPERAND (se->expr, 0);
94 /* Translate a label assignment statement. */
96 tree
97 gfc_trans_label_assign (gfc_code * code)
99 tree label_tree;
100 gfc_se se;
101 tree len;
102 tree addr;
103 tree len_tree;
104 int label_len;
106 /* Start a new block. */
107 gfc_init_se (&se, NULL);
108 gfc_start_block (&se.pre);
109 gfc_conv_label_variable (&se, code->expr1);
111 len = GFC_DECL_STRING_LEN (se.expr);
112 addr = GFC_DECL_ASSIGN_ADDR (se.expr);
114 label_tree = gfc_get_label_decl (code->label1);
116 if (code->label1->defined == ST_LABEL_TARGET
117 || code->label1->defined == ST_LABEL_DO_TARGET)
119 label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
120 len_tree = integer_minus_one_node;
122 else
124 gfc_expr *format = code->label1->format;
126 label_len = format->value.character.length;
127 len_tree = build_int_cst (gfc_charlen_type_node, label_len);
128 label_tree = gfc_build_wide_string_const (format->ts.kind, label_len + 1,
129 format->value.character.string);
130 label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
133 gfc_add_modify (&se.pre, len, len_tree);
134 gfc_add_modify (&se.pre, addr, label_tree);
136 return gfc_finish_block (&se.pre);
139 /* Translate a GOTO statement. */
141 tree
142 gfc_trans_goto (gfc_code * code)
144 locus loc = code->loc;
145 tree assigned_goto;
146 tree target;
147 tree tmp;
148 gfc_se se;
150 if (code->label1 != NULL)
151 return build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
153 /* ASSIGNED GOTO. */
154 gfc_init_se (&se, NULL);
155 gfc_start_block (&se.pre);
156 gfc_conv_label_variable (&se, code->expr1);
157 tmp = GFC_DECL_STRING_LEN (se.expr);
158 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp,
159 build_int_cst (TREE_TYPE (tmp), -1));
160 gfc_trans_runtime_check (true, false, tmp, &se.pre, &loc,
161 "Assigned label is not a target label");
163 assigned_goto = GFC_DECL_ASSIGN_ADDR (se.expr);
165 /* We're going to ignore a label list. It does not really change the
166 statement's semantics (because it is just a further restriction on
167 what's legal code); before, we were comparing label addresses here, but
168 that's a very fragile business and may break with optimization. So
169 just ignore it. */
171 target = fold_build1_loc (input_location, GOTO_EXPR, void_type_node,
172 assigned_goto);
173 gfc_add_expr_to_block (&se.pre, target);
174 return gfc_finish_block (&se.pre);
178 /* Translate an ENTRY statement. Just adds a label for this entry point. */
179 tree
180 gfc_trans_entry (gfc_code * code)
182 return build1_v (LABEL_EXPR, code->ext.entry->label);
186 /* Replace a gfc_ss structure by another both in the gfc_se struct
187 and the gfc_loopinfo struct. This is used in gfc_conv_elemental_dependencies
188 to replace a variable ss by the corresponding temporary. */
190 static void
191 replace_ss (gfc_se *se, gfc_ss *old_ss, gfc_ss *new_ss)
193 gfc_ss **sess, **loopss;
195 /* The old_ss is a ss for a single variable. */
196 gcc_assert (old_ss->info->type == GFC_SS_SECTION);
198 for (sess = &(se->ss); *sess != gfc_ss_terminator; sess = &((*sess)->next))
199 if (*sess == old_ss)
200 break;
201 gcc_assert (*sess != gfc_ss_terminator);
203 *sess = new_ss;
204 new_ss->next = old_ss->next;
207 for (loopss = &(se->loop->ss); *loopss != gfc_ss_terminator;
208 loopss = &((*loopss)->loop_chain))
209 if (*loopss == old_ss)
210 break;
211 gcc_assert (*loopss != gfc_ss_terminator);
213 *loopss = new_ss;
214 new_ss->loop_chain = old_ss->loop_chain;
215 new_ss->loop = old_ss->loop;
217 gfc_free_ss (old_ss);
221 /* Check for dependencies between INTENT(IN) and INTENT(OUT) arguments of
222 elemental subroutines. Make temporaries for output arguments if any such
223 dependencies are found. Output arguments are chosen because internal_unpack
224 can be used, as is, to copy the result back to the variable. */
225 static void
226 gfc_conv_elemental_dependencies (gfc_se * se, gfc_se * loopse,
227 gfc_symbol * sym, gfc_actual_arglist * arg,
228 gfc_dep_check check_variable)
230 gfc_actual_arglist *arg0;
231 gfc_expr *e;
232 gfc_formal_arglist *formal;
233 gfc_se parmse;
234 gfc_ss *ss;
235 gfc_symbol *fsym;
236 tree data;
237 tree size;
238 tree tmp;
240 if (loopse->ss == NULL)
241 return;
243 ss = loopse->ss;
244 arg0 = arg;
245 formal = gfc_sym_get_dummy_args (sym);
247 /* Loop over all the arguments testing for dependencies. */
248 for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
250 e = arg->expr;
251 if (e == NULL)
252 continue;
254 /* Obtain the info structure for the current argument. */
255 for (ss = loopse->ss; ss && ss != gfc_ss_terminator; ss = ss->next)
256 if (ss->info->expr == e)
257 break;
259 /* If there is a dependency, create a temporary and use it
260 instead of the variable. */
261 fsym = formal ? formal->sym : NULL;
262 if (e->expr_type == EXPR_VARIABLE
263 && e->rank && fsym
264 && fsym->attr.intent != INTENT_IN
265 && gfc_check_fncall_dependency (e, fsym->attr.intent,
266 sym, arg0, check_variable))
268 tree initial, temptype;
269 stmtblock_t temp_post;
270 gfc_ss *tmp_ss;
272 tmp_ss = gfc_get_array_ss (gfc_ss_terminator, NULL, ss->dimen,
273 GFC_SS_SECTION);
274 gfc_mark_ss_chain_used (tmp_ss, 1);
275 tmp_ss->info->expr = ss->info->expr;
276 replace_ss (loopse, ss, tmp_ss);
278 /* Obtain the argument descriptor for unpacking. */
279 gfc_init_se (&parmse, NULL);
280 parmse.want_pointer = 1;
281 gfc_conv_expr_descriptor (&parmse, e);
282 gfc_add_block_to_block (&se->pre, &parmse.pre);
284 /* If we've got INTENT(INOUT) or a derived type with INTENT(OUT),
285 initialize the array temporary with a copy of the values. */
286 if (fsym->attr.intent == INTENT_INOUT
287 || (fsym->ts.type ==BT_DERIVED
288 && fsym->attr.intent == INTENT_OUT))
289 initial = parmse.expr;
290 /* For class expressions, we always initialize with the copy of
291 the values. */
292 else if (e->ts.type == BT_CLASS)
293 initial = parmse.expr;
294 else
295 initial = NULL_TREE;
297 if (e->ts.type != BT_CLASS)
299 /* Find the type of the temporary to create; we don't use the type
300 of e itself as this breaks for subcomponent-references in e
301 (where the type of e is that of the final reference, but
302 parmse.expr's type corresponds to the full derived-type). */
303 /* TODO: Fix this somehow so we don't need a temporary of the whole
304 array but instead only the components referenced. */
305 temptype = TREE_TYPE (parmse.expr); /* Pointer to descriptor. */
306 gcc_assert (TREE_CODE (temptype) == POINTER_TYPE);
307 temptype = TREE_TYPE (temptype);
308 temptype = gfc_get_element_type (temptype);
311 else
312 /* For class arrays signal that the size of the dynamic type has to
313 be obtained from the vtable, using the 'initial' expression. */
314 temptype = NULL_TREE;
316 /* Generate the temporary. Cleaning up the temporary should be the
317 very last thing done, so we add the code to a new block and add it
318 to se->post as last instructions. */
319 size = gfc_create_var (gfc_array_index_type, NULL);
320 data = gfc_create_var (pvoid_type_node, NULL);
321 gfc_init_block (&temp_post);
322 tmp = gfc_trans_create_temp_array (&se->pre, &temp_post, tmp_ss,
323 temptype, initial, false, true,
324 false, &arg->expr->where);
325 gfc_add_modify (&se->pre, size, tmp);
326 tmp = fold_convert (pvoid_type_node, tmp_ss->info->data.array.data);
327 gfc_add_modify (&se->pre, data, tmp);
329 /* Update other ss' delta. */
330 gfc_set_delta (loopse->loop);
332 /* Copy the result back using unpack..... */
333 if (e->ts.type != BT_CLASS)
334 tmp = build_call_expr_loc (input_location,
335 gfor_fndecl_in_unpack, 2, parmse.expr, data);
336 else
338 /* ... except for class results where the copy is
339 unconditional. */
340 tmp = build_fold_indirect_ref_loc (input_location, parmse.expr);
341 tmp = gfc_conv_descriptor_data_get (tmp);
342 tmp = build_call_expr_loc (input_location,
343 builtin_decl_explicit (BUILT_IN_MEMCPY),
344 3, tmp, data,
345 fold_convert (size_type_node, size));
347 gfc_add_expr_to_block (&se->post, tmp);
349 /* parmse.pre is already added above. */
350 gfc_add_block_to_block (&se->post, &parmse.post);
351 gfc_add_block_to_block (&se->post, &temp_post);
357 /* Get the interface symbol for the procedure corresponding to the given call.
358 We can't get the procedure symbol directly as we have to handle the case
359 of (deferred) type-bound procedures. */
361 static gfc_symbol *
362 get_proc_ifc_for_call (gfc_code *c)
364 gfc_symbol *sym;
366 gcc_assert (c->op == EXEC_ASSIGN_CALL || c->op == EXEC_CALL);
368 sym = gfc_get_proc_ifc_for_expr (c->expr1);
370 /* Fall back/last resort try. */
371 if (sym == NULL)
372 sym = c->resolved_sym;
374 return sym;
378 /* Translate the CALL statement. Builds a call to an F95 subroutine. */
380 tree
381 gfc_trans_call (gfc_code * code, bool dependency_check,
382 tree mask, tree count1, bool invert)
384 gfc_se se;
385 gfc_ss * ss;
386 int has_alternate_specifier;
387 gfc_dep_check check_variable;
388 tree index = NULL_TREE;
389 tree maskexpr = NULL_TREE;
390 tree tmp;
392 /* A CALL starts a new block because the actual arguments may have to
393 be evaluated first. */
394 gfc_init_se (&se, NULL);
395 gfc_start_block (&se.pre);
397 gcc_assert (code->resolved_sym);
399 ss = gfc_ss_terminator;
400 if (code->resolved_sym->attr.elemental)
401 ss = gfc_walk_elemental_function_args (ss, code->ext.actual,
402 get_proc_ifc_for_call (code),
403 GFC_SS_REFERENCE);
405 /* Is not an elemental subroutine call with array valued arguments. */
406 if (ss == gfc_ss_terminator)
409 /* Translate the call. */
410 has_alternate_specifier
411 = gfc_conv_procedure_call (&se, code->resolved_sym, code->ext.actual,
412 code->expr1, NULL);
414 /* A subroutine without side-effect, by definition, does nothing! */
415 TREE_SIDE_EFFECTS (se.expr) = 1;
417 /* Chain the pieces together and return the block. */
418 if (has_alternate_specifier)
420 gfc_code *select_code;
421 gfc_symbol *sym;
422 select_code = code->next;
423 gcc_assert(select_code->op == EXEC_SELECT);
424 sym = select_code->expr1->symtree->n.sym;
425 se.expr = convert (gfc_typenode_for_spec (&sym->ts), se.expr);
426 if (sym->backend_decl == NULL)
427 sym->backend_decl = gfc_get_symbol_decl (sym);
428 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
430 else
431 gfc_add_expr_to_block (&se.pre, se.expr);
433 gfc_add_block_to_block (&se.pre, &se.post);
436 else
438 /* An elemental subroutine call with array valued arguments has
439 to be scalarized. */
440 gfc_loopinfo loop;
441 stmtblock_t body;
442 stmtblock_t block;
443 gfc_se loopse;
444 gfc_se depse;
446 /* gfc_walk_elemental_function_args renders the ss chain in the
447 reverse order to the actual argument order. */
448 ss = gfc_reverse_ss (ss);
450 /* Initialize the loop. */
451 gfc_init_se (&loopse, NULL);
452 gfc_init_loopinfo (&loop);
453 gfc_add_ss_to_loop (&loop, ss);
455 gfc_conv_ss_startstride (&loop);
456 /* TODO: gfc_conv_loop_setup generates a temporary for vector
457 subscripts. This could be prevented in the elemental case
458 as temporaries are handled separatedly
459 (below in gfc_conv_elemental_dependencies). */
460 gfc_conv_loop_setup (&loop, &code->expr1->where);
461 gfc_mark_ss_chain_used (ss, 1);
463 /* Convert the arguments, checking for dependencies. */
464 gfc_copy_loopinfo_to_se (&loopse, &loop);
465 loopse.ss = ss;
467 /* For operator assignment, do dependency checking. */
468 if (dependency_check)
469 check_variable = ELEM_CHECK_VARIABLE;
470 else
471 check_variable = ELEM_DONT_CHECK_VARIABLE;
473 gfc_init_se (&depse, NULL);
474 gfc_conv_elemental_dependencies (&depse, &loopse, code->resolved_sym,
475 code->ext.actual, check_variable);
477 gfc_add_block_to_block (&loop.pre, &depse.pre);
478 gfc_add_block_to_block (&loop.post, &depse.post);
480 /* Generate the loop body. */
481 gfc_start_scalarized_body (&loop, &body);
482 gfc_init_block (&block);
484 if (mask && count1)
486 /* Form the mask expression according to the mask. */
487 index = count1;
488 maskexpr = gfc_build_array_ref (mask, index, NULL);
489 if (invert)
490 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
491 TREE_TYPE (maskexpr), maskexpr);
494 /* Add the subroutine call to the block. */
495 gfc_conv_procedure_call (&loopse, code->resolved_sym,
496 code->ext.actual, code->expr1,
497 NULL);
499 if (mask && count1)
501 tmp = build3_v (COND_EXPR, maskexpr, loopse.expr,
502 build_empty_stmt (input_location));
503 gfc_add_expr_to_block (&loopse.pre, tmp);
504 tmp = fold_build2_loc (input_location, PLUS_EXPR,
505 gfc_array_index_type,
506 count1, gfc_index_one_node);
507 gfc_add_modify (&loopse.pre, count1, tmp);
509 else
510 gfc_add_expr_to_block (&loopse.pre, loopse.expr);
512 gfc_add_block_to_block (&block, &loopse.pre);
513 gfc_add_block_to_block (&block, &loopse.post);
515 /* Finish up the loop block and the loop. */
516 gfc_add_expr_to_block (&body, gfc_finish_block (&block));
517 gfc_trans_scalarizing_loops (&loop, &body);
518 gfc_add_block_to_block (&se.pre, &loop.pre);
519 gfc_add_block_to_block (&se.pre, &loop.post);
520 gfc_add_block_to_block (&se.pre, &se.post);
521 gfc_cleanup_loop (&loop);
524 return gfc_finish_block (&se.pre);
528 /* Translate the RETURN statement. */
530 tree
531 gfc_trans_return (gfc_code * code)
533 if (code->expr1)
535 gfc_se se;
536 tree tmp;
537 tree result;
539 /* If code->expr is not NULL, this return statement must appear
540 in a subroutine and current_fake_result_decl has already
541 been generated. */
543 result = gfc_get_fake_result_decl (NULL, 0);
544 if (!result)
546 gfc_warning (0,
547 "An alternate return at %L without a * dummy argument",
548 &code->expr1->where);
549 return gfc_generate_return ();
552 /* Start a new block for this statement. */
553 gfc_init_se (&se, NULL);
554 gfc_start_block (&se.pre);
556 gfc_conv_expr (&se, code->expr1);
558 /* Note that the actually returned expression is a simple value and
559 does not depend on any pointers or such; thus we can clean-up with
560 se.post before returning. */
561 tmp = fold_build2_loc (input_location, MODIFY_EXPR, TREE_TYPE (result),
562 result, fold_convert (TREE_TYPE (result),
563 se.expr));
564 gfc_add_expr_to_block (&se.pre, tmp);
565 gfc_add_block_to_block (&se.pre, &se.post);
567 tmp = gfc_generate_return ();
568 gfc_add_expr_to_block (&se.pre, tmp);
569 return gfc_finish_block (&se.pre);
572 return gfc_generate_return ();
576 /* Translate the PAUSE statement. We have to translate this statement
577 to a runtime library call. */
579 tree
580 gfc_trans_pause (gfc_code * code)
582 tree gfc_int4_type_node = gfc_get_int_type (4);
583 gfc_se se;
584 tree tmp;
586 /* Start a new block for this statement. */
587 gfc_init_se (&se, NULL);
588 gfc_start_block (&se.pre);
591 if (code->expr1 == NULL)
593 tmp = build_int_cst (gfc_int4_type_node, 0);
594 tmp = build_call_expr_loc (input_location,
595 gfor_fndecl_pause_string, 2,
596 build_int_cst (pchar_type_node, 0), tmp);
598 else if (code->expr1->ts.type == BT_INTEGER)
600 gfc_conv_expr (&se, code->expr1);
601 tmp = build_call_expr_loc (input_location,
602 gfor_fndecl_pause_numeric, 1,
603 fold_convert (gfc_int4_type_node, se.expr));
605 else
607 gfc_conv_expr_reference (&se, code->expr1);
608 tmp = build_call_expr_loc (input_location,
609 gfor_fndecl_pause_string, 2,
610 se.expr, se.string_length);
613 gfc_add_expr_to_block (&se.pre, tmp);
615 gfc_add_block_to_block (&se.pre, &se.post);
617 return gfc_finish_block (&se.pre);
621 /* Translate the STOP statement. We have to translate this statement
622 to a runtime library call. */
624 tree
625 gfc_trans_stop (gfc_code *code, bool error_stop)
627 tree gfc_int4_type_node = gfc_get_int_type (4);
628 gfc_se se;
629 tree tmp;
631 /* Start a new block for this statement. */
632 gfc_init_se (&se, NULL);
633 gfc_start_block (&se.pre);
635 if (code->expr1 == NULL)
637 tmp = build_int_cst (gfc_int4_type_node, 0);
638 tmp = build_call_expr_loc (input_location,
639 error_stop
640 ? (flag_coarray == GFC_FCOARRAY_LIB
641 ? gfor_fndecl_caf_error_stop_str
642 : gfor_fndecl_error_stop_string)
643 : gfor_fndecl_stop_string,
644 2, build_int_cst (pchar_type_node, 0), tmp);
646 else if (code->expr1->ts.type == BT_INTEGER)
648 gfc_conv_expr (&se, code->expr1);
649 tmp = build_call_expr_loc (input_location,
650 error_stop
651 ? (flag_coarray == GFC_FCOARRAY_LIB
652 ? gfor_fndecl_caf_error_stop
653 : gfor_fndecl_error_stop_numeric)
654 : gfor_fndecl_stop_numeric_f08, 1,
655 fold_convert (gfc_int4_type_node, se.expr));
657 else
659 gfc_conv_expr_reference (&se, code->expr1);
660 tmp = build_call_expr_loc (input_location,
661 error_stop
662 ? (flag_coarray == GFC_FCOARRAY_LIB
663 ? gfor_fndecl_caf_error_stop_str
664 : gfor_fndecl_error_stop_string)
665 : gfor_fndecl_stop_string,
666 2, se.expr, se.string_length);
669 gfc_add_expr_to_block (&se.pre, tmp);
671 gfc_add_block_to_block (&se.pre, &se.post);
673 return gfc_finish_block (&se.pre);
677 tree
678 gfc_trans_lock_unlock (gfc_code *code, gfc_exec_op op)
680 gfc_se se, argse;
681 tree stat = NULL_TREE, stat2 = NULL_TREE;
682 tree lock_acquired = NULL_TREE, lock_acquired2 = NULL_TREE;
684 /* Short cut: For single images without STAT= or LOCK_ACQUIRED
685 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
686 if (!code->expr2 && !code->expr4 && flag_coarray != GFC_FCOARRAY_LIB)
687 return NULL_TREE;
689 if (code->expr2)
691 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
692 gfc_init_se (&argse, NULL);
693 gfc_conv_expr_val (&argse, code->expr2);
694 stat = argse.expr;
696 else if (flag_coarray == GFC_FCOARRAY_LIB)
697 stat = null_pointer_node;
699 if (code->expr4)
701 gcc_assert (code->expr4->expr_type == EXPR_VARIABLE);
702 gfc_init_se (&argse, NULL);
703 gfc_conv_expr_val (&argse, code->expr4);
704 lock_acquired = argse.expr;
706 else if (flag_coarray == GFC_FCOARRAY_LIB)
707 lock_acquired = null_pointer_node;
709 gfc_start_block (&se.pre);
710 if (flag_coarray == GFC_FCOARRAY_LIB)
712 tree tmp, token, image_index, errmsg, errmsg_len;
713 tree index = size_zero_node;
714 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
716 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
717 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
718 != INTMOD_ISO_FORTRAN_ENV
719 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
720 != ISOFORTRAN_LOCK_TYPE)
722 gfc_error ("Sorry, the lock component of derived type at %L is not "
723 "yet supported", &code->expr1->where);
724 return NULL_TREE;
727 gfc_get_caf_token_offset (&token, NULL, caf_decl, NULL_TREE, code->expr1);
729 if (gfc_is_coindexed (code->expr1))
730 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
731 else
732 image_index = integer_zero_node;
734 /* For arrays, obtain the array index. */
735 if (gfc_expr_attr (code->expr1).dimension)
737 tree desc, tmp, extent, lbound, ubound;
738 gfc_array_ref *ar, ar2;
739 int i;
741 /* TODO: Extend this, once DT components are supported. */
742 ar = &code->expr1->ref->u.ar;
743 ar2 = *ar;
744 memset (ar, '\0', sizeof (*ar));
745 ar->as = ar2.as;
746 ar->type = AR_FULL;
748 gfc_init_se (&argse, NULL);
749 argse.descriptor_only = 1;
750 gfc_conv_expr_descriptor (&argse, code->expr1);
751 gfc_add_block_to_block (&se.pre, &argse.pre);
752 desc = argse.expr;
753 *ar = ar2;
755 extent = integer_one_node;
756 for (i = 0; i < ar->dimen; i++)
758 gfc_init_se (&argse, NULL);
759 gfc_conv_expr_type (&argse, ar->start[i], integer_type_node);
760 gfc_add_block_to_block (&argse.pre, &argse.pre);
761 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
762 tmp = fold_build2_loc (input_location, MINUS_EXPR,
763 integer_type_node, argse.expr,
764 fold_convert(integer_type_node, lbound));
765 tmp = fold_build2_loc (input_location, MULT_EXPR,
766 integer_type_node, extent, tmp);
767 index = fold_build2_loc (input_location, PLUS_EXPR,
768 integer_type_node, index, tmp);
769 if (i < ar->dimen - 1)
771 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
772 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
773 tmp = fold_convert (integer_type_node, tmp);
774 extent = fold_build2_loc (input_location, MULT_EXPR,
775 integer_type_node, extent, tmp);
780 /* errmsg. */
781 if (code->expr3)
783 gfc_init_se (&argse, NULL);
784 gfc_conv_expr (&argse, code->expr3);
785 gfc_add_block_to_block (&se.pre, &argse.pre);
786 errmsg = argse.expr;
787 errmsg_len = fold_convert (integer_type_node, argse.string_length);
789 else
791 errmsg = null_pointer_node;
792 errmsg_len = integer_zero_node;
795 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
797 stat2 = stat;
798 stat = gfc_create_var (integer_type_node, "stat");
801 if (lock_acquired != null_pointer_node
802 && TREE_TYPE (lock_acquired) != integer_type_node)
804 lock_acquired2 = lock_acquired;
805 lock_acquired = gfc_create_var (integer_type_node, "acquired");
808 if (op == EXEC_LOCK)
809 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
810 token, index, image_index,
811 lock_acquired != null_pointer_node
812 ? gfc_build_addr_expr (NULL, lock_acquired)
813 : lock_acquired,
814 stat != null_pointer_node
815 ? gfc_build_addr_expr (NULL, stat) : stat,
816 errmsg, errmsg_len);
817 else
818 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
819 token, index, image_index,
820 stat != null_pointer_node
821 ? gfc_build_addr_expr (NULL, stat) : stat,
822 errmsg, errmsg_len);
823 gfc_add_expr_to_block (&se.pre, tmp);
825 if (stat2 != NULL_TREE)
826 gfc_add_modify (&se.pre, stat2,
827 fold_convert (TREE_TYPE (stat2), stat));
829 if (lock_acquired2 != NULL_TREE)
830 gfc_add_modify (&se.pre, lock_acquired2,
831 fold_convert (TREE_TYPE (lock_acquired2),
832 lock_acquired));
834 return gfc_finish_block (&se.pre);
837 if (stat != NULL_TREE)
838 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
840 if (lock_acquired != NULL_TREE)
841 gfc_add_modify (&se.pre, lock_acquired,
842 fold_convert (TREE_TYPE (lock_acquired),
843 boolean_true_node));
845 return gfc_finish_block (&se.pre);
849 tree
850 gfc_trans_sync (gfc_code *code, gfc_exec_op type)
852 gfc_se se, argse;
853 tree tmp;
854 tree images = NULL_TREE, stat = NULL_TREE,
855 errmsg = NULL_TREE, errmsglen = NULL_TREE;
857 /* Short cut: For single images without bound checking or without STAT=,
858 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
859 if (!code->expr2 && !(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
860 && flag_coarray != GFC_FCOARRAY_LIB)
861 return NULL_TREE;
863 gfc_init_se (&se, NULL);
864 gfc_start_block (&se.pre);
866 if (code->expr1 && code->expr1->rank == 0)
868 gfc_init_se (&argse, NULL);
869 gfc_conv_expr_val (&argse, code->expr1);
870 images = argse.expr;
873 if (code->expr2)
875 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
876 gfc_init_se (&argse, NULL);
877 gfc_conv_expr_val (&argse, code->expr2);
878 stat = argse.expr;
880 else
881 stat = null_pointer_node;
883 if (code->expr3 && flag_coarray == GFC_FCOARRAY_LIB)
885 gcc_assert (code->expr3->expr_type == EXPR_VARIABLE);
886 gfc_init_se (&argse, NULL);
887 gfc_conv_expr (&argse, code->expr3);
888 gfc_conv_string_parameter (&argse);
889 errmsg = gfc_build_addr_expr (NULL, argse.expr);
890 errmsglen = argse.string_length;
892 else if (flag_coarray == GFC_FCOARRAY_LIB)
894 errmsg = null_pointer_node;
895 errmsglen = build_int_cst (integer_type_node, 0);
898 /* Check SYNC IMAGES(imageset) for valid image index.
899 FIXME: Add a check for image-set arrays. */
900 if (code->expr1 && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
901 && code->expr1->rank == 0)
903 tree cond;
904 if (flag_coarray != GFC_FCOARRAY_LIB)
905 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
906 images, build_int_cst (TREE_TYPE (images), 1));
907 else
909 tree cond2;
910 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images,
911 2, integer_zero_node,
912 build_int_cst (integer_type_node, -1));
913 cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
914 images, tmp);
915 cond2 = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
916 images,
917 build_int_cst (TREE_TYPE (images), 1));
918 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
919 boolean_type_node, cond, cond2);
921 gfc_trans_runtime_check (true, false, cond, &se.pre,
922 &code->expr1->where, "Invalid image number "
923 "%d in SYNC IMAGES",
924 fold_convert (integer_type_node, images));
927 if (flag_coarray != GFC_FCOARRAY_LIB)
929 /* Set STAT to zero. */
930 if (code->expr2)
931 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
933 else if (type == EXEC_SYNC_ALL || type == EXEC_SYNC_MEMORY)
935 /* SYNC ALL => stat == null_pointer_node
936 SYNC ALL(stat=s) => stat has an integer type
938 If "stat" has the wrong integer type, use a temp variable of
939 the right type and later cast the result back into "stat". */
940 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
942 if (TREE_TYPE (stat) == integer_type_node)
943 stat = gfc_build_addr_expr (NULL, stat);
945 if(type == EXEC_SYNC_MEMORY)
946 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_memory,
947 3, stat, errmsg, errmsglen);
948 else
949 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
950 3, stat, errmsg, errmsglen);
952 gfc_add_expr_to_block (&se.pre, tmp);
954 else
956 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
958 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
959 3, gfc_build_addr_expr (NULL, tmp_stat),
960 errmsg, errmsglen);
961 gfc_add_expr_to_block (&se.pre, tmp);
963 gfc_add_modify (&se.pre, stat,
964 fold_convert (TREE_TYPE (stat), tmp_stat));
967 else
969 tree len;
971 gcc_assert (type == EXEC_SYNC_IMAGES);
973 if (!code->expr1)
975 len = build_int_cst (integer_type_node, -1);
976 images = null_pointer_node;
978 else if (code->expr1->rank == 0)
980 len = build_int_cst (integer_type_node, 1);
981 images = gfc_build_addr_expr (NULL_TREE, images);
983 else
985 /* FIXME. */
986 if (code->expr1->ts.kind != gfc_c_int_kind)
987 gfc_fatal_error ("Sorry, only support for integer kind %d "
988 "implemented for image-set at %L",
989 gfc_c_int_kind, &code->expr1->where);
991 gfc_conv_array_parameter (&se, code->expr1, true, NULL, NULL, &len);
992 images = se.expr;
994 tmp = gfc_typenode_for_spec (&code->expr1->ts);
995 if (GFC_ARRAY_TYPE_P (tmp) || GFC_DESCRIPTOR_TYPE_P (tmp))
996 tmp = gfc_get_element_type (tmp);
998 len = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
999 TREE_TYPE (len), len,
1000 fold_convert (TREE_TYPE (len),
1001 TYPE_SIZE_UNIT (tmp)));
1002 len = fold_convert (integer_type_node, len);
1005 /* SYNC IMAGES(imgs) => stat == null_pointer_node
1006 SYNC IMAGES(imgs,stat=s) => stat has an integer type
1008 If "stat" has the wrong integer type, use a temp variable of
1009 the right type and later cast the result back into "stat". */
1010 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1012 if (TREE_TYPE (stat) == integer_type_node)
1013 stat = gfc_build_addr_expr (NULL, stat);
1015 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1016 5, fold_convert (integer_type_node, len),
1017 images, stat, errmsg, errmsglen);
1018 gfc_add_expr_to_block (&se.pre, tmp);
1020 else
1022 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1024 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1025 5, fold_convert (integer_type_node, len),
1026 images, gfc_build_addr_expr (NULL, tmp_stat),
1027 errmsg, errmsglen);
1028 gfc_add_expr_to_block (&se.pre, tmp);
1030 gfc_add_modify (&se.pre, stat,
1031 fold_convert (TREE_TYPE (stat), tmp_stat));
1035 return gfc_finish_block (&se.pre);
1039 /* Generate GENERIC for the IF construct. This function also deals with
1040 the simple IF statement, because the front end translates the IF
1041 statement into an IF construct.
1043 We translate:
1045 IF (cond) THEN
1046 then_clause
1047 ELSEIF (cond2)
1048 elseif_clause
1049 ELSE
1050 else_clause
1051 ENDIF
1053 into:
1055 pre_cond_s;
1056 if (cond_s)
1058 then_clause;
1060 else
1062 pre_cond_s
1063 if (cond_s)
1065 elseif_clause
1067 else
1069 else_clause;
1073 where COND_S is the simplified version of the predicate. PRE_COND_S
1074 are the pre side-effects produced by the translation of the
1075 conditional.
1076 We need to build the chain recursively otherwise we run into
1077 problems with folding incomplete statements. */
1079 static tree
1080 gfc_trans_if_1 (gfc_code * code)
1082 gfc_se if_se;
1083 tree stmt, elsestmt;
1084 locus saved_loc;
1085 location_t loc;
1087 /* Check for an unconditional ELSE clause. */
1088 if (!code->expr1)
1089 return gfc_trans_code (code->next);
1091 /* Initialize a statement builder for each block. Puts in NULL_TREEs. */
1092 gfc_init_se (&if_se, NULL);
1093 gfc_start_block (&if_se.pre);
1095 /* Calculate the IF condition expression. */
1096 if (code->expr1->where.lb)
1098 gfc_save_backend_locus (&saved_loc);
1099 gfc_set_backend_locus (&code->expr1->where);
1102 gfc_conv_expr_val (&if_se, code->expr1);
1104 if (code->expr1->where.lb)
1105 gfc_restore_backend_locus (&saved_loc);
1107 /* Translate the THEN clause. */
1108 stmt = gfc_trans_code (code->next);
1110 /* Translate the ELSE clause. */
1111 if (code->block)
1112 elsestmt = gfc_trans_if_1 (code->block);
1113 else
1114 elsestmt = build_empty_stmt (input_location);
1116 /* Build the condition expression and add it to the condition block. */
1117 loc = code->expr1->where.lb ? code->expr1->where.lb->location : input_location;
1118 stmt = fold_build3_loc (loc, COND_EXPR, void_type_node, if_se.expr, stmt,
1119 elsestmt);
1121 gfc_add_expr_to_block (&if_se.pre, stmt);
1123 /* Finish off this statement. */
1124 return gfc_finish_block (&if_se.pre);
1127 tree
1128 gfc_trans_if (gfc_code * code)
1130 stmtblock_t body;
1131 tree exit_label;
1133 /* Create exit label so it is available for trans'ing the body code. */
1134 exit_label = gfc_build_label_decl (NULL_TREE);
1135 code->exit_label = exit_label;
1137 /* Translate the actual code in code->block. */
1138 gfc_init_block (&body);
1139 gfc_add_expr_to_block (&body, gfc_trans_if_1 (code->block));
1141 /* Add exit label. */
1142 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
1144 return gfc_finish_block (&body);
1148 /* Translate an arithmetic IF expression.
1150 IF (cond) label1, label2, label3 translates to
1152 if (cond <= 0)
1154 if (cond < 0)
1155 goto label1;
1156 else // cond == 0
1157 goto label2;
1159 else // cond > 0
1160 goto label3;
1162 An optimized version can be generated in case of equal labels.
1163 E.g., if label1 is equal to label2, we can translate it to
1165 if (cond <= 0)
1166 goto label1;
1167 else
1168 goto label3;
1171 tree
1172 gfc_trans_arithmetic_if (gfc_code * code)
1174 gfc_se se;
1175 tree tmp;
1176 tree branch1;
1177 tree branch2;
1178 tree zero;
1180 /* Start a new block. */
1181 gfc_init_se (&se, NULL);
1182 gfc_start_block (&se.pre);
1184 /* Pre-evaluate COND. */
1185 gfc_conv_expr_val (&se, code->expr1);
1186 se.expr = gfc_evaluate_now (se.expr, &se.pre);
1188 /* Build something to compare with. */
1189 zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
1191 if (code->label1->value != code->label2->value)
1193 /* If (cond < 0) take branch1 else take branch2.
1194 First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases. */
1195 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1196 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
1198 if (code->label1->value != code->label3->value)
1199 tmp = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1200 se.expr, zero);
1201 else
1202 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1203 se.expr, zero);
1205 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1206 tmp, branch1, branch2);
1208 else
1209 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1211 if (code->label1->value != code->label3->value
1212 && code->label2->value != code->label3->value)
1214 /* if (cond <= 0) take branch1 else take branch2. */
1215 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label3));
1216 tmp = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
1217 se.expr, zero);
1218 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1219 tmp, branch1, branch2);
1222 /* Append the COND_EXPR to the evaluation of COND, and return. */
1223 gfc_add_expr_to_block (&se.pre, branch1);
1224 return gfc_finish_block (&se.pre);
1228 /* Translate a CRITICAL block. */
1229 tree
1230 gfc_trans_critical (gfc_code *code)
1232 stmtblock_t block;
1233 tree tmp, token = NULL_TREE;
1235 gfc_start_block (&block);
1237 if (flag_coarray == GFC_FCOARRAY_LIB)
1239 token = gfc_get_symbol_decl (code->resolved_sym);
1240 token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (token));
1241 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
1242 token, integer_zero_node, integer_one_node,
1243 null_pointer_node, null_pointer_node,
1244 null_pointer_node, integer_zero_node);
1245 gfc_add_expr_to_block (&block, tmp);
1248 tmp = gfc_trans_code (code->block->next);
1249 gfc_add_expr_to_block (&block, tmp);
1251 if (flag_coarray == GFC_FCOARRAY_LIB)
1253 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
1254 token, integer_zero_node, integer_one_node,
1255 null_pointer_node, null_pointer_node,
1256 integer_zero_node);
1257 gfc_add_expr_to_block (&block, tmp);
1261 return gfc_finish_block (&block);
1265 /* Return true, when the class has a _len component. */
1267 static bool
1268 class_has_len_component (gfc_symbol *sym)
1270 gfc_component *comp = sym->ts.u.derived->components;
1271 while (comp)
1273 if (strcmp (comp->name, "_len") == 0)
1274 return true;
1275 comp = comp->next;
1277 return false;
1281 /* Do proper initialization for ASSOCIATE names. */
1283 static void
1284 trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
1286 gfc_expr *e;
1287 tree tmp;
1288 bool class_target;
1289 bool unlimited;
1290 tree desc;
1291 tree offset;
1292 tree dim;
1293 int n;
1294 tree charlen;
1295 bool need_len_assign;
1297 gcc_assert (sym->assoc);
1298 e = sym->assoc->target;
1300 class_target = (e->expr_type == EXPR_VARIABLE)
1301 && (gfc_is_class_scalar_expr (e)
1302 || gfc_is_class_array_ref (e, NULL));
1304 unlimited = UNLIMITED_POLY (e);
1306 /* Assignments to the string length need to be generated, when
1307 ( sym is a char array or
1308 sym has a _len component)
1309 and the associated expression is unlimited polymorphic, which is
1310 not (yet) correctly in 'unlimited', because for an already associated
1311 BT_DERIVED the u-poly flag is not set, i.e.,
1312 __tmp_CHARACTER_0_1 => w => arg
1313 ^ generated temp ^ from code, the w does not have the u-poly
1314 flag set, where UNLIMITED_POLY(e) expects it. */
1315 need_len_assign = ((unlimited || (e->ts.type == BT_DERIVED
1316 && e->ts.u.derived->attr.unlimited_polymorphic))
1317 && (sym->ts.type == BT_CHARACTER
1318 || ((sym->ts.type == BT_CLASS || sym->ts.type == BT_DERIVED)
1319 && class_has_len_component (sym))));
1320 /* Do a `pointer assignment' with updated descriptor (or assign descriptor
1321 to array temporary) for arrays with either unknown shape or if associating
1322 to a variable. */
1323 if (sym->attr.dimension && !class_target
1324 && (sym->as->type == AS_DEFERRED || sym->assoc->variable))
1326 gfc_se se;
1327 tree desc;
1328 bool cst_array_ctor;
1330 desc = sym->backend_decl;
1331 cst_array_ctor = e->expr_type == EXPR_ARRAY
1332 && gfc_constant_array_constructor_p (e->value.constructor);
1334 /* If association is to an expression, evaluate it and create temporary.
1335 Otherwise, get descriptor of target for pointer assignment. */
1336 gfc_init_se (&se, NULL);
1337 if (sym->assoc->variable || cst_array_ctor)
1339 se.direct_byref = 1;
1340 se.use_offset = 1;
1341 se.expr = desc;
1344 gfc_conv_expr_descriptor (&se, e);
1346 /* If we didn't already do the pointer assignment, set associate-name
1347 descriptor to the one generated for the temporary. */
1348 if (!sym->assoc->variable && !cst_array_ctor)
1350 int dim;
1352 gfc_add_modify (&se.pre, desc, se.expr);
1354 /* The generated descriptor has lower bound zero (as array
1355 temporary), shift bounds so we get lower bounds of 1. */
1356 for (dim = 0; dim < e->rank; ++dim)
1357 gfc_conv_shift_descriptor_lbound (&se.pre, desc,
1358 dim, gfc_index_one_node);
1361 /* If this is a subreference array pointer associate name use the
1362 associate variable element size for the value of 'span'. */
1363 if (sym->attr.subref_array_pointer)
1365 gcc_assert (e->expr_type == EXPR_VARIABLE);
1366 tmp = e->symtree->n.sym->backend_decl;
1367 tmp = gfc_get_element_type (TREE_TYPE (tmp));
1368 tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
1369 gfc_add_modify (&se.pre, GFC_DECL_SPAN(desc), tmp);
1372 /* Done, register stuff as init / cleanup code. */
1373 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1374 gfc_finish_block (&se.post));
1377 /* Temporaries, arising from TYPE IS, just need the descriptor of class
1378 arrays to be assigned directly. */
1379 else if (class_target && sym->attr.dimension
1380 && (sym->ts.type == BT_DERIVED || unlimited))
1382 gfc_se se;
1384 gfc_init_se (&se, NULL);
1385 se.descriptor_only = 1;
1386 /* In a select type the (temporary) associate variable shall point to
1387 a standard fortran array (lower bound == 1), but conv_expr ()
1388 just maps to the input array in the class object, whose lbound may
1389 be arbitrary. conv_expr_descriptor solves this by inserting a
1390 temporary array descriptor. */
1391 gfc_conv_expr_descriptor (&se, e);
1393 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
1394 || GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)));
1395 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)));
1397 if (GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)))
1399 if (INDIRECT_REF_P (se.expr))
1400 tmp = TREE_OPERAND (se.expr, 0);
1401 else
1402 tmp = se.expr;
1404 gfc_add_modify (&se.pre, sym->backend_decl,
1405 gfc_class_data_get (GFC_DECL_SAVED_DESCRIPTOR (tmp)));
1407 else
1408 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
1410 if (unlimited)
1412 /* Recover the dtype, which has been overwritten by the
1413 assignment from an unlimited polymorphic object. */
1414 tmp = gfc_conv_descriptor_dtype (sym->backend_decl);
1415 gfc_add_modify (&se.pre, tmp,
1416 gfc_get_dtype (TREE_TYPE (sym->backend_decl)));
1419 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1420 gfc_finish_block (&se.post));
1423 /* Do a scalar pointer assignment; this is for scalar variable targets. */
1424 else if (gfc_is_associate_pointer (sym))
1426 gfc_se se;
1428 gcc_assert (!sym->attr.dimension);
1430 gfc_init_se (&se, NULL);
1432 /* Class associate-names come this way because they are
1433 unconditionally associate pointers and the symbol is scalar. */
1434 if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.dimension)
1436 tree target_expr;
1437 /* For a class array we need a descriptor for the selector. */
1438 gfc_conv_expr_descriptor (&se, e);
1439 /* Needed to get/set the _len component below. */
1440 target_expr = se.expr;
1442 /* Obtain a temporary class container for the result. */
1443 gfc_conv_class_to_class (&se, e, sym->ts, false, true, false, false);
1444 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1446 /* Set the offset. */
1447 desc = gfc_class_data_get (se.expr);
1448 offset = gfc_index_zero_node;
1449 for (n = 0; n < e->rank; n++)
1451 dim = gfc_rank_cst[n];
1452 tmp = fold_build2_loc (input_location, MULT_EXPR,
1453 gfc_array_index_type,
1454 gfc_conv_descriptor_stride_get (desc, dim),
1455 gfc_conv_descriptor_lbound_get (desc, dim));
1456 offset = fold_build2_loc (input_location, MINUS_EXPR,
1457 gfc_array_index_type,
1458 offset, tmp);
1460 if (need_len_assign)
1462 if (e->symtree
1463 && DECL_LANG_SPECIFIC (e->symtree->n.sym->backend_decl)
1464 && GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl))
1465 /* Use the original class descriptor stored in the saved
1466 descriptor to get the target_expr. */
1467 target_expr =
1468 GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl);
1469 else
1470 /* Strip the _data component from the target_expr. */
1471 target_expr = TREE_OPERAND (target_expr, 0);
1472 /* Add a reference to the _len comp to the target expr. */
1473 tmp = gfc_class_len_get (target_expr);
1474 /* Get the component-ref for the temp structure's _len comp. */
1475 charlen = gfc_class_len_get (se.expr);
1476 /* Add the assign to the beginning of the the block... */
1477 gfc_add_modify (&se.pre, charlen,
1478 fold_convert (TREE_TYPE (charlen), tmp));
1479 /* and the oposite way at the end of the block, to hand changes
1480 on the string length back. */
1481 gfc_add_modify (&se.post, tmp,
1482 fold_convert (TREE_TYPE (tmp), charlen));
1483 /* Length assignment done, prevent adding it again below. */
1484 need_len_assign = false;
1486 gfc_conv_descriptor_offset_set (&se.pre, desc, offset);
1488 else if (sym->ts.type == BT_CLASS && e->ts.type == BT_CLASS
1489 && CLASS_DATA (e)->attr.dimension)
1491 /* This is bound to be a class array element. */
1492 gfc_conv_expr_reference (&se, e);
1493 /* Get the _vptr component of the class object. */
1494 tmp = gfc_get_vptr_from_expr (se.expr);
1495 /* Obtain a temporary class container for the result. */
1496 gfc_conv_derived_to_class (&se, e, sym->ts, tmp, false, false);
1497 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1499 else
1501 /* For BT_CLASS and BT_DERIVED, this boils down to a pointer assign,
1502 which has the string length included. For CHARACTERS it is still
1503 needed and will be done at the end of this routine. */
1504 gfc_conv_expr (&se, e);
1505 need_len_assign = need_len_assign && sym->ts.type == BT_CHARACTER;
1508 tmp = TREE_TYPE (sym->backend_decl);
1509 tmp = gfc_build_addr_expr (tmp, se.expr);
1510 gfc_add_modify (&se.pre, sym->backend_decl, tmp);
1512 gfc_add_init_cleanup (block, gfc_finish_block( &se.pre),
1513 gfc_finish_block (&se.post));
1516 /* Do a simple assignment. This is for scalar expressions, where we
1517 can simply use expression assignment. */
1518 else
1520 gfc_expr *lhs;
1522 lhs = gfc_lval_expr_from_sym (sym);
1523 tmp = gfc_trans_assignment (lhs, e, false, true);
1524 gfc_add_init_cleanup (block, tmp, NULL_TREE);
1527 /* Set the stringlength, when needed. */
1528 if (need_len_assign)
1530 gfc_se se;
1531 gfc_init_se (&se, NULL);
1532 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
1534 /* What about deferred strings? */
1535 gcc_assert (!e->symtree->n.sym->ts.deferred);
1536 tmp = e->symtree->n.sym->ts.u.cl->backend_decl;
1538 else
1539 tmp = gfc_class_len_get (gfc_get_symbol_decl (e->symtree->n.sym));
1540 gfc_get_symbol_decl (sym);
1541 charlen = sym->ts.type == BT_CHARACTER ? sym->ts.u.cl->backend_decl
1542 : gfc_class_len_get (sym->backend_decl);
1543 /* Prevent adding a noop len= len. */
1544 if (tmp != charlen)
1546 gfc_add_modify (&se.pre, charlen,
1547 fold_convert (TREE_TYPE (charlen), tmp));
1548 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1549 gfc_finish_block (&se.post));
1555 /* Translate a BLOCK construct. This is basically what we would do for a
1556 procedure body. */
1558 tree
1559 gfc_trans_block_construct (gfc_code* code)
1561 gfc_namespace* ns;
1562 gfc_symbol* sym;
1563 gfc_wrapped_block block;
1564 tree exit_label;
1565 stmtblock_t body;
1566 gfc_association_list *ass;
1568 ns = code->ext.block.ns;
1569 gcc_assert (ns);
1570 sym = ns->proc_name;
1571 gcc_assert (sym);
1573 /* Process local variables. */
1574 gcc_assert (!sym->tlink);
1575 sym->tlink = sym;
1576 gfc_process_block_locals (ns);
1578 /* Generate code including exit-label. */
1579 gfc_init_block (&body);
1580 exit_label = gfc_build_label_decl (NULL_TREE);
1581 code->exit_label = exit_label;
1583 /* Generate !$ACC DECLARE directive. */
1584 if (ns->oacc_declare_clauses)
1586 tree tmp = gfc_trans_oacc_declare (&body, ns);
1587 gfc_add_expr_to_block (&body, tmp);
1590 gfc_add_expr_to_block (&body, gfc_trans_code (ns->code));
1591 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
1593 /* Finish everything. */
1594 gfc_start_wrapped_block (&block, gfc_finish_block (&body));
1595 gfc_trans_deferred_vars (sym, &block);
1596 for (ass = code->ext.block.assoc; ass; ass = ass->next)
1597 trans_associate_var (ass->st->n.sym, &block);
1599 return gfc_finish_wrapped_block (&block);
1603 /* Translate the simple DO construct. This is where the loop variable has
1604 integer type and step +-1. We can't use this in the general case
1605 because integer overflow and floating point errors could give incorrect
1606 results.
1607 We translate a do loop from:
1609 DO dovar = from, to, step
1610 body
1611 END DO
1615 [Evaluate loop bounds and step]
1616 dovar = from;
1617 if ((step > 0) ? (dovar <= to) : (dovar => to))
1619 for (;;)
1621 body;
1622 cycle_label:
1623 cond = (dovar == to);
1624 dovar += step;
1625 if (cond) goto end_label;
1628 end_label:
1630 This helps the optimizers by avoiding the extra induction variable
1631 used in the general case. */
1633 static tree
1634 gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
1635 tree from, tree to, tree step, tree exit_cond)
1637 stmtblock_t body;
1638 tree type;
1639 tree cond;
1640 tree tmp;
1641 tree saved_dovar = NULL;
1642 tree cycle_label;
1643 tree exit_label;
1644 location_t loc;
1646 type = TREE_TYPE (dovar);
1648 loc = code->ext.iterator->start->where.lb->location;
1650 /* Initialize the DO variable: dovar = from. */
1651 gfc_add_modify_loc (loc, pblock, dovar,
1652 fold_convert (TREE_TYPE(dovar), from));
1654 /* Save value for do-tinkering checking. */
1655 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1657 saved_dovar = gfc_create_var (type, ".saved_dovar");
1658 gfc_add_modify_loc (loc, pblock, saved_dovar, dovar);
1661 /* Cycle and exit statements are implemented with gotos. */
1662 cycle_label = gfc_build_label_decl (NULL_TREE);
1663 exit_label = gfc_build_label_decl (NULL_TREE);
1665 /* Put the labels where they can be found later. See gfc_trans_do(). */
1666 code->cycle_label = cycle_label;
1667 code->exit_label = exit_label;
1669 /* Loop body. */
1670 gfc_start_block (&body);
1672 /* Main loop body. */
1673 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
1674 gfc_add_expr_to_block (&body, tmp);
1676 /* Label for cycle statements (if needed). */
1677 if (TREE_USED (cycle_label))
1679 tmp = build1_v (LABEL_EXPR, cycle_label);
1680 gfc_add_expr_to_block (&body, tmp);
1683 /* Check whether someone has modified the loop variable. */
1684 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1686 tmp = fold_build2_loc (loc, NE_EXPR, boolean_type_node,
1687 dovar, saved_dovar);
1688 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
1689 "Loop variable has been modified");
1692 /* Exit the loop if there is an I/O result condition or error. */
1693 if (exit_cond)
1695 tmp = build1_v (GOTO_EXPR, exit_label);
1696 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
1697 exit_cond, tmp,
1698 build_empty_stmt (loc));
1699 gfc_add_expr_to_block (&body, tmp);
1702 /* Evaluate the loop condition. */
1703 cond = fold_build2_loc (loc, EQ_EXPR, boolean_type_node, dovar,
1704 to);
1705 cond = gfc_evaluate_now_loc (loc, cond, &body);
1707 /* Increment the loop variable. */
1708 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
1709 gfc_add_modify_loc (loc, &body, dovar, tmp);
1711 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1712 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
1714 /* The loop exit. */
1715 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
1716 TREE_USED (exit_label) = 1;
1717 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
1718 cond, tmp, build_empty_stmt (loc));
1719 gfc_add_expr_to_block (&body, tmp);
1721 /* Finish the loop body. */
1722 tmp = gfc_finish_block (&body);
1723 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
1725 /* Only execute the loop if the number of iterations is positive. */
1726 if (tree_int_cst_sgn (step) > 0)
1727 cond = fold_build2_loc (loc, LE_EXPR, boolean_type_node, dovar,
1728 to);
1729 else
1730 cond = fold_build2_loc (loc, GE_EXPR, boolean_type_node, dovar,
1731 to);
1732 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, cond, tmp,
1733 build_empty_stmt (loc));
1734 gfc_add_expr_to_block (pblock, tmp);
1736 /* Add the exit label. */
1737 tmp = build1_v (LABEL_EXPR, exit_label);
1738 gfc_add_expr_to_block (pblock, tmp);
1740 return gfc_finish_block (pblock);
1743 /* Translate the DO construct. This obviously is one of the most
1744 important ones to get right with any compiler, but especially
1745 so for Fortran.
1747 We special case some loop forms as described in gfc_trans_simple_do.
1748 For other cases we implement them with a separate loop count,
1749 as described in the standard.
1751 We translate a do loop from:
1753 DO dovar = from, to, step
1754 body
1755 END DO
1759 [evaluate loop bounds and step]
1760 empty = (step > 0 ? to < from : to > from);
1761 countm1 = (to - from) / step;
1762 dovar = from;
1763 if (empty) goto exit_label;
1764 for (;;)
1766 body;
1767 cycle_label:
1768 dovar += step
1769 countm1t = countm1;
1770 countm1--;
1771 if (countm1t == 0) goto exit_label;
1773 exit_label:
1775 countm1 is an unsigned integer. It is equal to the loop count minus one,
1776 because the loop count itself can overflow. */
1778 tree
1779 gfc_trans_do (gfc_code * code, tree exit_cond)
1781 gfc_se se;
1782 tree dovar;
1783 tree saved_dovar = NULL;
1784 tree from;
1785 tree to;
1786 tree step;
1787 tree countm1;
1788 tree type;
1789 tree utype;
1790 tree cond;
1791 tree cycle_label;
1792 tree exit_label;
1793 tree tmp;
1794 stmtblock_t block;
1795 stmtblock_t body;
1796 location_t loc;
1798 gfc_start_block (&block);
1800 loc = code->ext.iterator->start->where.lb->location;
1802 /* Evaluate all the expressions in the iterator. */
1803 gfc_init_se (&se, NULL);
1804 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
1805 gfc_add_block_to_block (&block, &se.pre);
1806 dovar = se.expr;
1807 type = TREE_TYPE (dovar);
1809 gfc_init_se (&se, NULL);
1810 gfc_conv_expr_val (&se, code->ext.iterator->start);
1811 gfc_add_block_to_block (&block, &se.pre);
1812 from = gfc_evaluate_now (se.expr, &block);
1814 gfc_init_se (&se, NULL);
1815 gfc_conv_expr_val (&se, code->ext.iterator->end);
1816 gfc_add_block_to_block (&block, &se.pre);
1817 to = gfc_evaluate_now (se.expr, &block);
1819 gfc_init_se (&se, NULL);
1820 gfc_conv_expr_val (&se, code->ext.iterator->step);
1821 gfc_add_block_to_block (&block, &se.pre);
1822 step = gfc_evaluate_now (se.expr, &block);
1824 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1826 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, step,
1827 build_zero_cst (type));
1828 gfc_trans_runtime_check (true, false, tmp, &block, &code->loc,
1829 "DO step value is zero");
1832 /* Special case simple loops. */
1833 if (TREE_CODE (type) == INTEGER_TYPE
1834 && (integer_onep (step)
1835 || tree_int_cst_equal (step, integer_minus_one_node)))
1836 return gfc_trans_simple_do (code, &block, dovar, from, to, step, exit_cond);
1839 if (TREE_CODE (type) == INTEGER_TYPE)
1840 utype = unsigned_type_for (type);
1841 else
1842 utype = unsigned_type_for (gfc_array_index_type);
1843 countm1 = gfc_create_var (utype, "countm1");
1845 /* Cycle and exit statements are implemented with gotos. */
1846 cycle_label = gfc_build_label_decl (NULL_TREE);
1847 exit_label = gfc_build_label_decl (NULL_TREE);
1848 TREE_USED (exit_label) = 1;
1850 /* Put these labels where they can be found later. */
1851 code->cycle_label = cycle_label;
1852 code->exit_label = exit_label;
1854 /* Initialize the DO variable: dovar = from. */
1855 gfc_add_modify (&block, dovar, from);
1857 /* Save value for do-tinkering checking. */
1858 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1860 saved_dovar = gfc_create_var (type, ".saved_dovar");
1861 gfc_add_modify_loc (loc, &block, saved_dovar, dovar);
1864 /* Initialize loop count and jump to exit label if the loop is empty.
1865 This code is executed before we enter the loop body. We generate:
1866 if (step > 0)
1868 countm1 = (to - from) / step;
1869 if (to < from)
1870 goto exit_label;
1872 else
1874 countm1 = (from - to) / -step;
1875 if (to > from)
1876 goto exit_label;
1880 if (TREE_CODE (type) == INTEGER_TYPE)
1882 tree pos, neg, tou, fromu, stepu, tmp2;
1884 /* The distance from FROM to TO cannot always be represented in a signed
1885 type, thus use unsigned arithmetic, also to avoid any undefined
1886 overflow issues. */
1887 tou = fold_convert (utype, to);
1888 fromu = fold_convert (utype, from);
1889 stepu = fold_convert (utype, step);
1891 /* For a positive step, when to < from, exit, otherwise compute
1892 countm1 = ((unsigned)to - (unsigned)from) / (unsigned)step */
1893 tmp = fold_build2_loc (loc, LT_EXPR, boolean_type_node, to, from);
1894 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
1895 fold_build2_loc (loc, MINUS_EXPR, utype,
1896 tou, fromu),
1897 stepu);
1898 pos = build2 (COMPOUND_EXPR, void_type_node,
1899 fold_build2 (MODIFY_EXPR, void_type_node,
1900 countm1, tmp2),
1901 build3_loc (loc, COND_EXPR, void_type_node, tmp,
1902 build1_loc (loc, GOTO_EXPR, void_type_node,
1903 exit_label), NULL_TREE));
1905 /* For a negative step, when to > from, exit, otherwise compute
1906 countm1 = ((unsigned)from - (unsigned)to) / -(unsigned)step */
1907 tmp = fold_build2_loc (loc, GT_EXPR, boolean_type_node, to, from);
1908 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
1909 fold_build2_loc (loc, MINUS_EXPR, utype,
1910 fromu, tou),
1911 fold_build1_loc (loc, NEGATE_EXPR, utype, stepu));
1912 neg = build2 (COMPOUND_EXPR, void_type_node,
1913 fold_build2 (MODIFY_EXPR, void_type_node,
1914 countm1, tmp2),
1915 build3_loc (loc, COND_EXPR, void_type_node, tmp,
1916 build1_loc (loc, GOTO_EXPR, void_type_node,
1917 exit_label), NULL_TREE));
1919 tmp = fold_build2_loc (loc, LT_EXPR, boolean_type_node, step,
1920 build_int_cst (TREE_TYPE (step), 0));
1921 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp, neg, pos);
1923 gfc_add_expr_to_block (&block, tmp);
1925 else
1927 tree pos_step;
1929 /* TODO: We could use the same width as the real type.
1930 This would probably cause more problems that it solves
1931 when we implement "long double" types. */
1933 tmp = fold_build2_loc (loc, MINUS_EXPR, type, to, from);
1934 tmp = fold_build2_loc (loc, RDIV_EXPR, type, tmp, step);
1935 tmp = fold_build1_loc (loc, FIX_TRUNC_EXPR, utype, tmp);
1936 gfc_add_modify (&block, countm1, tmp);
1938 /* We need a special check for empty loops:
1939 empty = (step > 0 ? to < from : to > from); */
1940 pos_step = fold_build2_loc (loc, GT_EXPR, boolean_type_node, step,
1941 build_zero_cst (type));
1942 tmp = fold_build3_loc (loc, COND_EXPR, boolean_type_node, pos_step,
1943 fold_build2_loc (loc, LT_EXPR,
1944 boolean_type_node, to, from),
1945 fold_build2_loc (loc, GT_EXPR,
1946 boolean_type_node, to, from));
1947 /* If the loop is empty, go directly to the exit label. */
1948 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp,
1949 build1_v (GOTO_EXPR, exit_label),
1950 build_empty_stmt (input_location));
1951 gfc_add_expr_to_block (&block, tmp);
1954 /* Loop body. */
1955 gfc_start_block (&body);
1957 /* Main loop body. */
1958 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
1959 gfc_add_expr_to_block (&body, tmp);
1961 /* Label for cycle statements (if needed). */
1962 if (TREE_USED (cycle_label))
1964 tmp = build1_v (LABEL_EXPR, cycle_label);
1965 gfc_add_expr_to_block (&body, tmp);
1968 /* Check whether someone has modified the loop variable. */
1969 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1971 tmp = fold_build2_loc (loc, NE_EXPR, boolean_type_node, dovar,
1972 saved_dovar);
1973 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
1974 "Loop variable has been modified");
1977 /* Exit the loop if there is an I/O result condition or error. */
1978 if (exit_cond)
1980 tmp = build1_v (GOTO_EXPR, exit_label);
1981 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
1982 exit_cond, tmp,
1983 build_empty_stmt (input_location));
1984 gfc_add_expr_to_block (&body, tmp);
1987 /* Increment the loop variable. */
1988 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
1989 gfc_add_modify_loc (loc, &body, dovar, tmp);
1991 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1992 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
1994 /* Initialize countm1t. */
1995 tree countm1t = gfc_create_var (utype, "countm1t");
1996 gfc_add_modify_loc (loc, &body, countm1t, countm1);
1998 /* Decrement the loop count. */
1999 tmp = fold_build2_loc (loc, MINUS_EXPR, utype, countm1,
2000 build_int_cst (utype, 1));
2001 gfc_add_modify_loc (loc, &body, countm1, tmp);
2003 /* End with the loop condition. Loop until countm1t == 0. */
2004 cond = fold_build2_loc (loc, EQ_EXPR, boolean_type_node, countm1t,
2005 build_int_cst (utype, 0));
2006 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
2007 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2008 cond, tmp, build_empty_stmt (loc));
2009 gfc_add_expr_to_block (&body, tmp);
2011 /* End of loop body. */
2012 tmp = gfc_finish_block (&body);
2014 /* The for loop itself. */
2015 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
2016 gfc_add_expr_to_block (&block, tmp);
2018 /* Add the exit label. */
2019 tmp = build1_v (LABEL_EXPR, exit_label);
2020 gfc_add_expr_to_block (&block, tmp);
2022 return gfc_finish_block (&block);
2026 /* Translate the DO WHILE construct.
2028 We translate
2030 DO WHILE (cond)
2031 body
2032 END DO
2036 for ( ; ; )
2038 pre_cond;
2039 if (! cond) goto exit_label;
2040 body;
2041 cycle_label:
2043 exit_label:
2045 Because the evaluation of the exit condition `cond' may have side
2046 effects, we can't do much for empty loop bodies. The backend optimizers
2047 should be smart enough to eliminate any dead loops. */
2049 tree
2050 gfc_trans_do_while (gfc_code * code)
2052 gfc_se cond;
2053 tree tmp;
2054 tree cycle_label;
2055 tree exit_label;
2056 stmtblock_t block;
2058 /* Everything we build here is part of the loop body. */
2059 gfc_start_block (&block);
2061 /* Cycle and exit statements are implemented with gotos. */
2062 cycle_label = gfc_build_label_decl (NULL_TREE);
2063 exit_label = gfc_build_label_decl (NULL_TREE);
2065 /* Put the labels where they can be found later. See gfc_trans_do(). */
2066 code->cycle_label = cycle_label;
2067 code->exit_label = exit_label;
2069 /* Create a GIMPLE version of the exit condition. */
2070 gfc_init_se (&cond, NULL);
2071 gfc_conv_expr_val (&cond, code->expr1);
2072 gfc_add_block_to_block (&block, &cond.pre);
2073 cond.expr = fold_build1_loc (code->expr1->where.lb->location,
2074 TRUTH_NOT_EXPR, TREE_TYPE (cond.expr), cond.expr);
2076 /* Build "IF (! cond) GOTO exit_label". */
2077 tmp = build1_v (GOTO_EXPR, exit_label);
2078 TREE_USED (exit_label) = 1;
2079 tmp = fold_build3_loc (code->expr1->where.lb->location, COND_EXPR,
2080 void_type_node, cond.expr, tmp,
2081 build_empty_stmt (code->expr1->where.lb->location));
2082 gfc_add_expr_to_block (&block, tmp);
2084 /* The main body of the loop. */
2085 tmp = gfc_trans_code (code->block->next);
2086 gfc_add_expr_to_block (&block, tmp);
2088 /* Label for cycle statements (if needed). */
2089 if (TREE_USED (cycle_label))
2091 tmp = build1_v (LABEL_EXPR, cycle_label);
2092 gfc_add_expr_to_block (&block, tmp);
2095 /* End of loop body. */
2096 tmp = gfc_finish_block (&block);
2098 gfc_init_block (&block);
2099 /* Build the loop. */
2100 tmp = fold_build1_loc (code->expr1->where.lb->location, LOOP_EXPR,
2101 void_type_node, tmp);
2102 gfc_add_expr_to_block (&block, tmp);
2104 /* Add the exit label. */
2105 tmp = build1_v (LABEL_EXPR, exit_label);
2106 gfc_add_expr_to_block (&block, tmp);
2108 return gfc_finish_block (&block);
2112 /* Translate the SELECT CASE construct for INTEGER case expressions,
2113 without killing all potential optimizations. The problem is that
2114 Fortran allows unbounded cases, but the back-end does not, so we
2115 need to intercept those before we enter the equivalent SWITCH_EXPR
2116 we can build.
2118 For example, we translate this,
2120 SELECT CASE (expr)
2121 CASE (:100,101,105:115)
2122 block_1
2123 CASE (190:199,200:)
2124 block_2
2125 CASE (300)
2126 block_3
2127 CASE DEFAULT
2128 block_4
2129 END SELECT
2131 to the GENERIC equivalent,
2133 switch (expr)
2135 case (minimum value for typeof(expr) ... 100:
2136 case 101:
2137 case 105 ... 114:
2138 block1:
2139 goto end_label;
2141 case 200 ... (maximum value for typeof(expr):
2142 case 190 ... 199:
2143 block2;
2144 goto end_label;
2146 case 300:
2147 block_3;
2148 goto end_label;
2150 default:
2151 block_4;
2152 goto end_label;
2155 end_label: */
2157 static tree
2158 gfc_trans_integer_select (gfc_code * code)
2160 gfc_code *c;
2161 gfc_case *cp;
2162 tree end_label;
2163 tree tmp;
2164 gfc_se se;
2165 stmtblock_t block;
2166 stmtblock_t body;
2168 gfc_start_block (&block);
2170 /* Calculate the switch expression. */
2171 gfc_init_se (&se, NULL);
2172 gfc_conv_expr_val (&se, code->expr1);
2173 gfc_add_block_to_block (&block, &se.pre);
2175 end_label = gfc_build_label_decl (NULL_TREE);
2177 gfc_init_block (&body);
2179 for (c = code->block; c; c = c->block)
2181 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2183 tree low, high;
2184 tree label;
2186 /* Assume it's the default case. */
2187 low = high = NULL_TREE;
2189 if (cp->low)
2191 low = gfc_conv_mpz_to_tree (cp->low->value.integer,
2192 cp->low->ts.kind);
2194 /* If there's only a lower bound, set the high bound to the
2195 maximum value of the case expression. */
2196 if (!cp->high)
2197 high = TYPE_MAX_VALUE (TREE_TYPE (se.expr));
2200 if (cp->high)
2202 /* Three cases are possible here:
2204 1) There is no lower bound, e.g. CASE (:N).
2205 2) There is a lower bound .NE. high bound, that is
2206 a case range, e.g. CASE (N:M) where M>N (we make
2207 sure that M>N during type resolution).
2208 3) There is a lower bound, and it has the same value
2209 as the high bound, e.g. CASE (N:N). This is our
2210 internal representation of CASE(N).
2212 In the first and second case, we need to set a value for
2213 high. In the third case, we don't because the GCC middle
2214 end represents a single case value by just letting high be
2215 a NULL_TREE. We can't do that because we need to be able
2216 to represent unbounded cases. */
2218 if (!cp->low
2219 || (cp->low
2220 && mpz_cmp (cp->low->value.integer,
2221 cp->high->value.integer) != 0))
2222 high = gfc_conv_mpz_to_tree (cp->high->value.integer,
2223 cp->high->ts.kind);
2225 /* Unbounded case. */
2226 if (!cp->low)
2227 low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
2230 /* Build a label. */
2231 label = gfc_build_label_decl (NULL_TREE);
2233 /* Add this case label.
2234 Add parameter 'label', make it match GCC backend. */
2235 tmp = build_case_label (low, high, label);
2236 gfc_add_expr_to_block (&body, tmp);
2239 /* Add the statements for this case. */
2240 tmp = gfc_trans_code (c->next);
2241 gfc_add_expr_to_block (&body, tmp);
2243 /* Break to the end of the construct. */
2244 tmp = build1_v (GOTO_EXPR, end_label);
2245 gfc_add_expr_to_block (&body, tmp);
2248 tmp = gfc_finish_block (&body);
2249 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2250 se.expr, tmp, NULL_TREE);
2251 gfc_add_expr_to_block (&block, tmp);
2253 tmp = build1_v (LABEL_EXPR, end_label);
2254 gfc_add_expr_to_block (&block, tmp);
2256 return gfc_finish_block (&block);
2260 /* Translate the SELECT CASE construct for LOGICAL case expressions.
2262 There are only two cases possible here, even though the standard
2263 does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
2264 .FALSE., and DEFAULT.
2266 We never generate more than two blocks here. Instead, we always
2267 try to eliminate the DEFAULT case. This way, we can translate this
2268 kind of SELECT construct to a simple
2270 if {} else {};
2272 expression in GENERIC. */
2274 static tree
2275 gfc_trans_logical_select (gfc_code * code)
2277 gfc_code *c;
2278 gfc_code *t, *f, *d;
2279 gfc_case *cp;
2280 gfc_se se;
2281 stmtblock_t block;
2283 /* Assume we don't have any cases at all. */
2284 t = f = d = NULL;
2286 /* Now see which ones we actually do have. We can have at most two
2287 cases in a single case list: one for .TRUE. and one for .FALSE.
2288 The default case is always separate. If the cases for .TRUE. and
2289 .FALSE. are in the same case list, the block for that case list
2290 always executed, and we don't generate code a COND_EXPR. */
2291 for (c = code->block; c; c = c->block)
2293 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2295 if (cp->low)
2297 if (cp->low->value.logical == 0) /* .FALSE. */
2298 f = c;
2299 else /* if (cp->value.logical != 0), thus .TRUE. */
2300 t = c;
2302 else
2303 d = c;
2307 /* Start a new block. */
2308 gfc_start_block (&block);
2310 /* Calculate the switch expression. We always need to do this
2311 because it may have side effects. */
2312 gfc_init_se (&se, NULL);
2313 gfc_conv_expr_val (&se, code->expr1);
2314 gfc_add_block_to_block (&block, &se.pre);
2316 if (t == f && t != NULL)
2318 /* Cases for .TRUE. and .FALSE. are in the same block. Just
2319 translate the code for these cases, append it to the current
2320 block. */
2321 gfc_add_expr_to_block (&block, gfc_trans_code (t->next));
2323 else
2325 tree true_tree, false_tree, stmt;
2327 true_tree = build_empty_stmt (input_location);
2328 false_tree = build_empty_stmt (input_location);
2330 /* If we have a case for .TRUE. and for .FALSE., discard the default case.
2331 Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
2332 make the missing case the default case. */
2333 if (t != NULL && f != NULL)
2334 d = NULL;
2335 else if (d != NULL)
2337 if (t == NULL)
2338 t = d;
2339 else
2340 f = d;
2343 /* Translate the code for each of these blocks, and append it to
2344 the current block. */
2345 if (t != NULL)
2346 true_tree = gfc_trans_code (t->next);
2348 if (f != NULL)
2349 false_tree = gfc_trans_code (f->next);
2351 stmt = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2352 se.expr, true_tree, false_tree);
2353 gfc_add_expr_to_block (&block, stmt);
2356 return gfc_finish_block (&block);
2360 /* The jump table types are stored in static variables to avoid
2361 constructing them from scratch every single time. */
2362 static GTY(()) tree select_struct[2];
2364 /* Translate the SELECT CASE construct for CHARACTER case expressions.
2365 Instead of generating compares and jumps, it is far simpler to
2366 generate a data structure describing the cases in order and call a
2367 library subroutine that locates the right case.
2368 This is particularly true because this is the only case where we
2369 might have to dispose of a temporary.
2370 The library subroutine returns a pointer to jump to or NULL if no
2371 branches are to be taken. */
2373 static tree
2374 gfc_trans_character_select (gfc_code *code)
2376 tree init, end_label, tmp, type, case_num, label, fndecl;
2377 stmtblock_t block, body;
2378 gfc_case *cp, *d;
2379 gfc_code *c;
2380 gfc_se se, expr1se;
2381 int n, k;
2382 vec<constructor_elt, va_gc> *inits = NULL;
2384 tree pchartype = gfc_get_pchar_type (code->expr1->ts.kind);
2386 /* The jump table types are stored in static variables to avoid
2387 constructing them from scratch every single time. */
2388 static tree ss_string1[2], ss_string1_len[2];
2389 static tree ss_string2[2], ss_string2_len[2];
2390 static tree ss_target[2];
2392 cp = code->block->ext.block.case_list;
2393 while (cp->left != NULL)
2394 cp = cp->left;
2396 /* Generate the body */
2397 gfc_start_block (&block);
2398 gfc_init_se (&expr1se, NULL);
2399 gfc_conv_expr_reference (&expr1se, code->expr1);
2401 gfc_add_block_to_block (&block, &expr1se.pre);
2403 end_label = gfc_build_label_decl (NULL_TREE);
2405 gfc_init_block (&body);
2407 /* Attempt to optimize length 1 selects. */
2408 if (integer_onep (expr1se.string_length))
2410 for (d = cp; d; d = d->right)
2412 int i;
2413 if (d->low)
2415 gcc_assert (d->low->expr_type == EXPR_CONSTANT
2416 && d->low->ts.type == BT_CHARACTER);
2417 if (d->low->value.character.length > 1)
2419 for (i = 1; i < d->low->value.character.length; i++)
2420 if (d->low->value.character.string[i] != ' ')
2421 break;
2422 if (i != d->low->value.character.length)
2424 if (optimize && d->high && i == 1)
2426 gcc_assert (d->high->expr_type == EXPR_CONSTANT
2427 && d->high->ts.type == BT_CHARACTER);
2428 if (d->high->value.character.length > 1
2429 && (d->low->value.character.string[0]
2430 == d->high->value.character.string[0])
2431 && d->high->value.character.string[1] != ' '
2432 && ((d->low->value.character.string[1] < ' ')
2433 == (d->high->value.character.string[1]
2434 < ' ')))
2435 continue;
2437 break;
2441 if (d->high)
2443 gcc_assert (d->high->expr_type == EXPR_CONSTANT
2444 && d->high->ts.type == BT_CHARACTER);
2445 if (d->high->value.character.length > 1)
2447 for (i = 1; i < d->high->value.character.length; i++)
2448 if (d->high->value.character.string[i] != ' ')
2449 break;
2450 if (i != d->high->value.character.length)
2451 break;
2455 if (d == NULL)
2457 tree ctype = gfc_get_char_type (code->expr1->ts.kind);
2459 for (c = code->block; c; c = c->block)
2461 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2463 tree low, high;
2464 tree label;
2465 gfc_char_t r;
2467 /* Assume it's the default case. */
2468 low = high = NULL_TREE;
2470 if (cp->low)
2472 /* CASE ('ab') or CASE ('ab':'az') will never match
2473 any length 1 character. */
2474 if (cp->low->value.character.length > 1
2475 && cp->low->value.character.string[1] != ' ')
2476 continue;
2478 if (cp->low->value.character.length > 0)
2479 r = cp->low->value.character.string[0];
2480 else
2481 r = ' ';
2482 low = build_int_cst (ctype, r);
2484 /* If there's only a lower bound, set the high bound
2485 to the maximum value of the case expression. */
2486 if (!cp->high)
2487 high = TYPE_MAX_VALUE (ctype);
2490 if (cp->high)
2492 if (!cp->low
2493 || (cp->low->value.character.string[0]
2494 != cp->high->value.character.string[0]))
2496 if (cp->high->value.character.length > 0)
2497 r = cp->high->value.character.string[0];
2498 else
2499 r = ' ';
2500 high = build_int_cst (ctype, r);
2503 /* Unbounded case. */
2504 if (!cp->low)
2505 low = TYPE_MIN_VALUE (ctype);
2508 /* Build a label. */
2509 label = gfc_build_label_decl (NULL_TREE);
2511 /* Add this case label.
2512 Add parameter 'label', make it match GCC backend. */
2513 tmp = build_case_label (low, high, label);
2514 gfc_add_expr_to_block (&body, tmp);
2517 /* Add the statements for this case. */
2518 tmp = gfc_trans_code (c->next);
2519 gfc_add_expr_to_block (&body, tmp);
2521 /* Break to the end of the construct. */
2522 tmp = build1_v (GOTO_EXPR, end_label);
2523 gfc_add_expr_to_block (&body, tmp);
2526 tmp = gfc_string_to_single_character (expr1se.string_length,
2527 expr1se.expr,
2528 code->expr1->ts.kind);
2529 case_num = gfc_create_var (ctype, "case_num");
2530 gfc_add_modify (&block, case_num, tmp);
2532 gfc_add_block_to_block (&block, &expr1se.post);
2534 tmp = gfc_finish_block (&body);
2535 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2536 case_num, tmp, NULL_TREE);
2537 gfc_add_expr_to_block (&block, tmp);
2539 tmp = build1_v (LABEL_EXPR, end_label);
2540 gfc_add_expr_to_block (&block, tmp);
2542 return gfc_finish_block (&block);
2546 if (code->expr1->ts.kind == 1)
2547 k = 0;
2548 else if (code->expr1->ts.kind == 4)
2549 k = 1;
2550 else
2551 gcc_unreachable ();
2553 if (select_struct[k] == NULL)
2555 tree *chain = NULL;
2556 select_struct[k] = make_node (RECORD_TYPE);
2558 if (code->expr1->ts.kind == 1)
2559 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char1");
2560 else if (code->expr1->ts.kind == 4)
2561 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char4");
2562 else
2563 gcc_unreachable ();
2565 #undef ADD_FIELD
2566 #define ADD_FIELD(NAME, TYPE) \
2567 ss_##NAME[k] = gfc_add_field_to_struct (select_struct[k], \
2568 get_identifier (stringize(NAME)), \
2569 TYPE, \
2570 &chain)
2572 ADD_FIELD (string1, pchartype);
2573 ADD_FIELD (string1_len, gfc_charlen_type_node);
2575 ADD_FIELD (string2, pchartype);
2576 ADD_FIELD (string2_len, gfc_charlen_type_node);
2578 ADD_FIELD (target, integer_type_node);
2579 #undef ADD_FIELD
2581 gfc_finish_type (select_struct[k]);
2584 n = 0;
2585 for (d = cp; d; d = d->right)
2586 d->n = n++;
2588 for (c = code->block; c; c = c->block)
2590 for (d = c->ext.block.case_list; d; d = d->next)
2592 label = gfc_build_label_decl (NULL_TREE);
2593 tmp = build_case_label ((d->low == NULL && d->high == NULL)
2594 ? NULL
2595 : build_int_cst (integer_type_node, d->n),
2596 NULL, label);
2597 gfc_add_expr_to_block (&body, tmp);
2600 tmp = gfc_trans_code (c->next);
2601 gfc_add_expr_to_block (&body, tmp);
2603 tmp = build1_v (GOTO_EXPR, end_label);
2604 gfc_add_expr_to_block (&body, tmp);
2607 /* Generate the structure describing the branches */
2608 for (d = cp; d; d = d->right)
2610 vec<constructor_elt, va_gc> *node = NULL;
2612 gfc_init_se (&se, NULL);
2614 if (d->low == NULL)
2616 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], null_pointer_node);
2617 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], integer_zero_node);
2619 else
2621 gfc_conv_expr_reference (&se, d->low);
2623 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], se.expr);
2624 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], se.string_length);
2627 if (d->high == NULL)
2629 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], null_pointer_node);
2630 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], integer_zero_node);
2632 else
2634 gfc_init_se (&se, NULL);
2635 gfc_conv_expr_reference (&se, d->high);
2637 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], se.expr);
2638 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], se.string_length);
2641 CONSTRUCTOR_APPEND_ELT (node, ss_target[k],
2642 build_int_cst (integer_type_node, d->n));
2644 tmp = build_constructor (select_struct[k], node);
2645 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, tmp);
2648 type = build_array_type (select_struct[k],
2649 build_index_type (size_int (n-1)));
2651 init = build_constructor (type, inits);
2652 TREE_CONSTANT (init) = 1;
2653 TREE_STATIC (init) = 1;
2654 /* Create a static variable to hold the jump table. */
2655 tmp = gfc_create_var (type, "jumptable");
2656 TREE_CONSTANT (tmp) = 1;
2657 TREE_STATIC (tmp) = 1;
2658 TREE_READONLY (tmp) = 1;
2659 DECL_INITIAL (tmp) = init;
2660 init = tmp;
2662 /* Build the library call */
2663 init = gfc_build_addr_expr (pvoid_type_node, init);
2665 if (code->expr1->ts.kind == 1)
2666 fndecl = gfor_fndecl_select_string;
2667 else if (code->expr1->ts.kind == 4)
2668 fndecl = gfor_fndecl_select_string_char4;
2669 else
2670 gcc_unreachable ();
2672 tmp = build_call_expr_loc (input_location,
2673 fndecl, 4, init,
2674 build_int_cst (gfc_charlen_type_node, n),
2675 expr1se.expr, expr1se.string_length);
2676 case_num = gfc_create_var (integer_type_node, "case_num");
2677 gfc_add_modify (&block, case_num, tmp);
2679 gfc_add_block_to_block (&block, &expr1se.post);
2681 tmp = gfc_finish_block (&body);
2682 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2683 case_num, tmp, NULL_TREE);
2684 gfc_add_expr_to_block (&block, tmp);
2686 tmp = build1_v (LABEL_EXPR, end_label);
2687 gfc_add_expr_to_block (&block, tmp);
2689 return gfc_finish_block (&block);
2693 /* Translate the three variants of the SELECT CASE construct.
2695 SELECT CASEs with INTEGER case expressions can be translated to an
2696 equivalent GENERIC switch statement, and for LOGICAL case
2697 expressions we build one or two if-else compares.
2699 SELECT CASEs with CHARACTER case expressions are a whole different
2700 story, because they don't exist in GENERIC. So we sort them and
2701 do a binary search at runtime.
2703 Fortran has no BREAK statement, and it does not allow jumps from
2704 one case block to another. That makes things a lot easier for
2705 the optimizers. */
2707 tree
2708 gfc_trans_select (gfc_code * code)
2710 stmtblock_t block;
2711 tree body;
2712 tree exit_label;
2714 gcc_assert (code && code->expr1);
2715 gfc_init_block (&block);
2717 /* Build the exit label and hang it in. */
2718 exit_label = gfc_build_label_decl (NULL_TREE);
2719 code->exit_label = exit_label;
2721 /* Empty SELECT constructs are legal. */
2722 if (code->block == NULL)
2723 body = build_empty_stmt (input_location);
2725 /* Select the correct translation function. */
2726 else
2727 switch (code->expr1->ts.type)
2729 case BT_LOGICAL:
2730 body = gfc_trans_logical_select (code);
2731 break;
2733 case BT_INTEGER:
2734 body = gfc_trans_integer_select (code);
2735 break;
2737 case BT_CHARACTER:
2738 body = gfc_trans_character_select (code);
2739 break;
2741 default:
2742 gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
2743 /* Not reached */
2746 /* Build everything together. */
2747 gfc_add_expr_to_block (&block, body);
2748 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
2750 return gfc_finish_block (&block);
2754 /* Traversal function to substitute a replacement symtree if the symbol
2755 in the expression is the same as that passed. f == 2 signals that
2756 that variable itself is not to be checked - only the references.
2757 This group of functions is used when the variable expression in a
2758 FORALL assignment has internal references. For example:
2759 FORALL (i = 1:4) p(p(i)) = i
2760 The only recourse here is to store a copy of 'p' for the index
2761 expression. */
2763 static gfc_symtree *new_symtree;
2764 static gfc_symtree *old_symtree;
2766 static bool
2767 forall_replace (gfc_expr *expr, gfc_symbol *sym, int *f)
2769 if (expr->expr_type != EXPR_VARIABLE)
2770 return false;
2772 if (*f == 2)
2773 *f = 1;
2774 else if (expr->symtree->n.sym == sym)
2775 expr->symtree = new_symtree;
2777 return false;
2780 static void
2781 forall_replace_symtree (gfc_expr *e, gfc_symbol *sym, int f)
2783 gfc_traverse_expr (e, sym, forall_replace, f);
2786 static bool
2787 forall_restore (gfc_expr *expr,
2788 gfc_symbol *sym ATTRIBUTE_UNUSED,
2789 int *f ATTRIBUTE_UNUSED)
2791 if (expr->expr_type != EXPR_VARIABLE)
2792 return false;
2794 if (expr->symtree == new_symtree)
2795 expr->symtree = old_symtree;
2797 return false;
2800 static void
2801 forall_restore_symtree (gfc_expr *e)
2803 gfc_traverse_expr (e, NULL, forall_restore, 0);
2806 static void
2807 forall_make_variable_temp (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
2809 gfc_se tse;
2810 gfc_se rse;
2811 gfc_expr *e;
2812 gfc_symbol *new_sym;
2813 gfc_symbol *old_sym;
2814 gfc_symtree *root;
2815 tree tmp;
2817 /* Build a copy of the lvalue. */
2818 old_symtree = c->expr1->symtree;
2819 old_sym = old_symtree->n.sym;
2820 e = gfc_lval_expr_from_sym (old_sym);
2821 if (old_sym->attr.dimension)
2823 gfc_init_se (&tse, NULL);
2824 gfc_conv_subref_array_arg (&tse, e, 0, INTENT_IN, false);
2825 gfc_add_block_to_block (pre, &tse.pre);
2826 gfc_add_block_to_block (post, &tse.post);
2827 tse.expr = build_fold_indirect_ref_loc (input_location, tse.expr);
2829 if (e->ts.type != BT_CHARACTER)
2831 /* Use the variable offset for the temporary. */
2832 tmp = gfc_conv_array_offset (old_sym->backend_decl);
2833 gfc_conv_descriptor_offset_set (pre, tse.expr, tmp);
2836 else
2838 gfc_init_se (&tse, NULL);
2839 gfc_init_se (&rse, NULL);
2840 gfc_conv_expr (&rse, e);
2841 if (e->ts.type == BT_CHARACTER)
2843 tse.string_length = rse.string_length;
2844 tmp = gfc_get_character_type_len (gfc_default_character_kind,
2845 tse.string_length);
2846 tse.expr = gfc_conv_string_tmp (&tse, build_pointer_type (tmp),
2847 rse.string_length);
2848 gfc_add_block_to_block (pre, &tse.pre);
2849 gfc_add_block_to_block (post, &tse.post);
2851 else
2853 tmp = gfc_typenode_for_spec (&e->ts);
2854 tse.expr = gfc_create_var (tmp, "temp");
2857 tmp = gfc_trans_scalar_assign (&tse, &rse, e->ts, true,
2858 e->expr_type == EXPR_VARIABLE, true);
2859 gfc_add_expr_to_block (pre, tmp);
2861 gfc_free_expr (e);
2863 /* Create a new symbol to represent the lvalue. */
2864 new_sym = gfc_new_symbol (old_sym->name, NULL);
2865 new_sym->ts = old_sym->ts;
2866 new_sym->attr.referenced = 1;
2867 new_sym->attr.temporary = 1;
2868 new_sym->attr.dimension = old_sym->attr.dimension;
2869 new_sym->attr.flavor = old_sym->attr.flavor;
2871 /* Use the temporary as the backend_decl. */
2872 new_sym->backend_decl = tse.expr;
2874 /* Create a fake symtree for it. */
2875 root = NULL;
2876 new_symtree = gfc_new_symtree (&root, old_sym->name);
2877 new_symtree->n.sym = new_sym;
2878 gcc_assert (new_symtree == root);
2880 /* Go through the expression reference replacing the old_symtree
2881 with the new. */
2882 forall_replace_symtree (c->expr1, old_sym, 2);
2884 /* Now we have made this temporary, we might as well use it for
2885 the right hand side. */
2886 forall_replace_symtree (c->expr2, old_sym, 1);
2890 /* Handles dependencies in forall assignments. */
2891 static int
2892 check_forall_dependencies (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
2894 gfc_ref *lref;
2895 gfc_ref *rref;
2896 int need_temp;
2897 gfc_symbol *lsym;
2899 lsym = c->expr1->symtree->n.sym;
2900 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
2902 /* Now check for dependencies within the 'variable'
2903 expression itself. These are treated by making a complete
2904 copy of variable and changing all the references to it
2905 point to the copy instead. Note that the shallow copy of
2906 the variable will not suffice for derived types with
2907 pointer components. We therefore leave these to their
2908 own devices. */
2909 if (lsym->ts.type == BT_DERIVED
2910 && lsym->ts.u.derived->attr.pointer_comp)
2911 return need_temp;
2913 new_symtree = NULL;
2914 if (find_forall_index (c->expr1, lsym, 2))
2916 forall_make_variable_temp (c, pre, post);
2917 need_temp = 0;
2920 /* Substrings with dependencies are treated in the same
2921 way. */
2922 if (c->expr1->ts.type == BT_CHARACTER
2923 && c->expr1->ref
2924 && c->expr2->expr_type == EXPR_VARIABLE
2925 && lsym == c->expr2->symtree->n.sym)
2927 for (lref = c->expr1->ref; lref; lref = lref->next)
2928 if (lref->type == REF_SUBSTRING)
2929 break;
2930 for (rref = c->expr2->ref; rref; rref = rref->next)
2931 if (rref->type == REF_SUBSTRING)
2932 break;
2934 if (rref && lref
2935 && gfc_dep_compare_expr (rref->u.ss.start, lref->u.ss.start) < 0)
2937 forall_make_variable_temp (c, pre, post);
2938 need_temp = 0;
2941 return need_temp;
2945 static void
2946 cleanup_forall_symtrees (gfc_code *c)
2948 forall_restore_symtree (c->expr1);
2949 forall_restore_symtree (c->expr2);
2950 free (new_symtree->n.sym);
2951 free (new_symtree);
2955 /* Generate the loops for a FORALL block, specified by FORALL_TMP. BODY
2956 is the contents of the FORALL block/stmt to be iterated. MASK_FLAG
2957 indicates whether we should generate code to test the FORALLs mask
2958 array. OUTER is the loop header to be used for initializing mask
2959 indices.
2961 The generated loop format is:
2962 count = (end - start + step) / step
2963 loopvar = start
2964 while (1)
2966 if (count <=0 )
2967 goto end_of_loop
2968 <body>
2969 loopvar += step
2970 count --
2972 end_of_loop: */
2974 static tree
2975 gfc_trans_forall_loop (forall_info *forall_tmp, tree body,
2976 int mask_flag, stmtblock_t *outer)
2978 int n, nvar;
2979 tree tmp;
2980 tree cond;
2981 stmtblock_t block;
2982 tree exit_label;
2983 tree count;
2984 tree var, start, end, step;
2985 iter_info *iter;
2987 /* Initialize the mask index outside the FORALL nest. */
2988 if (mask_flag && forall_tmp->mask)
2989 gfc_add_modify (outer, forall_tmp->maskindex, gfc_index_zero_node);
2991 iter = forall_tmp->this_loop;
2992 nvar = forall_tmp->nvar;
2993 for (n = 0; n < nvar; n++)
2995 var = iter->var;
2996 start = iter->start;
2997 end = iter->end;
2998 step = iter->step;
3000 exit_label = gfc_build_label_decl (NULL_TREE);
3001 TREE_USED (exit_label) = 1;
3003 /* The loop counter. */
3004 count = gfc_create_var (TREE_TYPE (var), "count");
3006 /* The body of the loop. */
3007 gfc_init_block (&block);
3009 /* The exit condition. */
3010 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
3011 count, build_int_cst (TREE_TYPE (count), 0));
3012 if (forall_tmp->do_concurrent)
3013 cond = build2 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
3014 build_int_cst (integer_type_node,
3015 annot_expr_ivdep_kind));
3017 tmp = build1_v (GOTO_EXPR, exit_label);
3018 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3019 cond, tmp, build_empty_stmt (input_location));
3020 gfc_add_expr_to_block (&block, tmp);
3022 /* The main loop body. */
3023 gfc_add_expr_to_block (&block, body);
3025 /* Increment the loop variable. */
3026 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var,
3027 step);
3028 gfc_add_modify (&block, var, tmp);
3030 /* Advance to the next mask element. Only do this for the
3031 innermost loop. */
3032 if (n == 0 && mask_flag && forall_tmp->mask)
3034 tree maskindex = forall_tmp->maskindex;
3035 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3036 maskindex, gfc_index_one_node);
3037 gfc_add_modify (&block, maskindex, tmp);
3040 /* Decrement the loop counter. */
3041 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), count,
3042 build_int_cst (TREE_TYPE (var), 1));
3043 gfc_add_modify (&block, count, tmp);
3045 body = gfc_finish_block (&block);
3047 /* Loop var initialization. */
3048 gfc_init_block (&block);
3049 gfc_add_modify (&block, var, start);
3052 /* Initialize the loop counter. */
3053 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), step,
3054 start);
3055 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), end,
3056 tmp);
3057 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (var),
3058 tmp, step);
3059 gfc_add_modify (&block, count, tmp);
3061 /* The loop expression. */
3062 tmp = build1_v (LOOP_EXPR, body);
3063 gfc_add_expr_to_block (&block, tmp);
3065 /* The exit label. */
3066 tmp = build1_v (LABEL_EXPR, exit_label);
3067 gfc_add_expr_to_block (&block, tmp);
3069 body = gfc_finish_block (&block);
3070 iter = iter->next;
3072 return body;
3076 /* Generate the body and loops according to MASK_FLAG. If MASK_FLAG
3077 is nonzero, the body is controlled by all masks in the forall nest.
3078 Otherwise, the innermost loop is not controlled by it's mask. This
3079 is used for initializing that mask. */
3081 static tree
3082 gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
3083 int mask_flag)
3085 tree tmp;
3086 stmtblock_t header;
3087 forall_info *forall_tmp;
3088 tree mask, maskindex;
3090 gfc_start_block (&header);
3092 forall_tmp = nested_forall_info;
3093 while (forall_tmp != NULL)
3095 /* Generate body with masks' control. */
3096 if (mask_flag)
3098 mask = forall_tmp->mask;
3099 maskindex = forall_tmp->maskindex;
3101 /* If a mask was specified make the assignment conditional. */
3102 if (mask)
3104 tmp = gfc_build_array_ref (mask, maskindex, NULL);
3105 body = build3_v (COND_EXPR, tmp, body,
3106 build_empty_stmt (input_location));
3109 body = gfc_trans_forall_loop (forall_tmp, body, mask_flag, &header);
3110 forall_tmp = forall_tmp->prev_nest;
3111 mask_flag = 1;
3114 gfc_add_expr_to_block (&header, body);
3115 return gfc_finish_block (&header);
3119 /* Allocate data for holding a temporary array. Returns either a local
3120 temporary array or a pointer variable. */
3122 static tree
3123 gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
3124 tree elem_type)
3126 tree tmpvar;
3127 tree type;
3128 tree tmp;
3130 if (INTEGER_CST_P (size))
3131 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3132 size, gfc_index_one_node);
3133 else
3134 tmp = NULL_TREE;
3136 type = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
3137 type = build_array_type (elem_type, type);
3138 if (gfc_can_put_var_on_stack (bytesize))
3140 gcc_assert (INTEGER_CST_P (size));
3141 tmpvar = gfc_create_var (type, "temp");
3142 *pdata = NULL_TREE;
3144 else
3146 tmpvar = gfc_create_var (build_pointer_type (type), "temp");
3147 *pdata = convert (pvoid_type_node, tmpvar);
3149 tmp = gfc_call_malloc (pblock, TREE_TYPE (tmpvar), bytesize);
3150 gfc_add_modify (pblock, tmpvar, tmp);
3152 return tmpvar;
3156 /* Generate codes to copy the temporary to the actual lhs. */
3158 static tree
3159 generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
3160 tree count1, tree wheremask, bool invert)
3162 gfc_ss *lss;
3163 gfc_se lse, rse;
3164 stmtblock_t block, body;
3165 gfc_loopinfo loop1;
3166 tree tmp;
3167 tree wheremaskexpr;
3169 /* Walk the lhs. */
3170 lss = gfc_walk_expr (expr);
3172 if (lss == gfc_ss_terminator)
3174 gfc_start_block (&block);
3176 gfc_init_se (&lse, NULL);
3178 /* Translate the expression. */
3179 gfc_conv_expr (&lse, expr);
3181 /* Form the expression for the temporary. */
3182 tmp = gfc_build_array_ref (tmp1, count1, NULL);
3184 /* Use the scalar assignment as is. */
3185 gfc_add_block_to_block (&block, &lse.pre);
3186 gfc_add_modify (&block, lse.expr, tmp);
3187 gfc_add_block_to_block (&block, &lse.post);
3189 /* Increment the count1. */
3190 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3191 count1, gfc_index_one_node);
3192 gfc_add_modify (&block, count1, tmp);
3194 tmp = gfc_finish_block (&block);
3196 else
3198 gfc_start_block (&block);
3200 gfc_init_loopinfo (&loop1);
3201 gfc_init_se (&rse, NULL);
3202 gfc_init_se (&lse, NULL);
3204 /* Associate the lss with the loop. */
3205 gfc_add_ss_to_loop (&loop1, lss);
3207 /* Calculate the bounds of the scalarization. */
3208 gfc_conv_ss_startstride (&loop1);
3209 /* Setup the scalarizing loops. */
3210 gfc_conv_loop_setup (&loop1, &expr->where);
3212 gfc_mark_ss_chain_used (lss, 1);
3214 /* Start the scalarized loop body. */
3215 gfc_start_scalarized_body (&loop1, &body);
3217 /* Setup the gfc_se structures. */
3218 gfc_copy_loopinfo_to_se (&lse, &loop1);
3219 lse.ss = lss;
3221 /* Form the expression of the temporary. */
3222 if (lss != gfc_ss_terminator)
3223 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3224 /* Translate expr. */
3225 gfc_conv_expr (&lse, expr);
3227 /* Use the scalar assignment. */
3228 rse.string_length = lse.string_length;
3229 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, true, true);
3231 /* Form the mask expression according to the mask tree list. */
3232 if (wheremask)
3234 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3235 if (invert)
3236 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3237 TREE_TYPE (wheremaskexpr),
3238 wheremaskexpr);
3239 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3240 wheremaskexpr, tmp,
3241 build_empty_stmt (input_location));
3244 gfc_add_expr_to_block (&body, tmp);
3246 /* Increment count1. */
3247 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3248 count1, gfc_index_one_node);
3249 gfc_add_modify (&body, count1, tmp);
3251 /* Increment count3. */
3252 if (count3)
3254 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3255 gfc_array_index_type, count3,
3256 gfc_index_one_node);
3257 gfc_add_modify (&body, count3, tmp);
3260 /* Generate the copying loops. */
3261 gfc_trans_scalarizing_loops (&loop1, &body);
3262 gfc_add_block_to_block (&block, &loop1.pre);
3263 gfc_add_block_to_block (&block, &loop1.post);
3264 gfc_cleanup_loop (&loop1);
3266 tmp = gfc_finish_block (&block);
3268 return tmp;
3272 /* Generate codes to copy rhs to the temporary. TMP1 is the address of
3273 temporary, LSS and RSS are formed in function compute_inner_temp_size(),
3274 and should not be freed. WHEREMASK is the conditional execution mask
3275 whose sense may be inverted by INVERT. */
3277 static tree
3278 generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree count3,
3279 tree count1, gfc_ss *lss, gfc_ss *rss,
3280 tree wheremask, bool invert)
3282 stmtblock_t block, body1;
3283 gfc_loopinfo loop;
3284 gfc_se lse;
3285 gfc_se rse;
3286 tree tmp;
3287 tree wheremaskexpr;
3289 gfc_start_block (&block);
3291 gfc_init_se (&rse, NULL);
3292 gfc_init_se (&lse, NULL);
3294 if (lss == gfc_ss_terminator)
3296 gfc_init_block (&body1);
3297 gfc_conv_expr (&rse, expr2);
3298 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3300 else
3302 /* Initialize the loop. */
3303 gfc_init_loopinfo (&loop);
3305 /* We may need LSS to determine the shape of the expression. */
3306 gfc_add_ss_to_loop (&loop, lss);
3307 gfc_add_ss_to_loop (&loop, rss);
3309 gfc_conv_ss_startstride (&loop);
3310 gfc_conv_loop_setup (&loop, &expr2->where);
3312 gfc_mark_ss_chain_used (rss, 1);
3313 /* Start the loop body. */
3314 gfc_start_scalarized_body (&loop, &body1);
3316 /* Translate the expression. */
3317 gfc_copy_loopinfo_to_se (&rse, &loop);
3318 rse.ss = rss;
3319 gfc_conv_expr (&rse, expr2);
3321 /* Form the expression of the temporary. */
3322 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3325 /* Use the scalar assignment. */
3326 lse.string_length = rse.string_length;
3327 tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts, true,
3328 expr2->expr_type == EXPR_VARIABLE, true);
3330 /* Form the mask expression according to the mask tree list. */
3331 if (wheremask)
3333 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3334 if (invert)
3335 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3336 TREE_TYPE (wheremaskexpr),
3337 wheremaskexpr);
3338 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3339 wheremaskexpr, tmp,
3340 build_empty_stmt (input_location));
3343 gfc_add_expr_to_block (&body1, tmp);
3345 if (lss == gfc_ss_terminator)
3347 gfc_add_block_to_block (&block, &body1);
3349 /* Increment count1. */
3350 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3351 count1, gfc_index_one_node);
3352 gfc_add_modify (&block, count1, tmp);
3354 else
3356 /* Increment count1. */
3357 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3358 count1, gfc_index_one_node);
3359 gfc_add_modify (&body1, count1, tmp);
3361 /* Increment count3. */
3362 if (count3)
3364 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3365 gfc_array_index_type,
3366 count3, gfc_index_one_node);
3367 gfc_add_modify (&body1, count3, tmp);
3370 /* Generate the copying loops. */
3371 gfc_trans_scalarizing_loops (&loop, &body1);
3373 gfc_add_block_to_block (&block, &loop.pre);
3374 gfc_add_block_to_block (&block, &loop.post);
3376 gfc_cleanup_loop (&loop);
3377 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
3378 as tree nodes in SS may not be valid in different scope. */
3381 tmp = gfc_finish_block (&block);
3382 return tmp;
3386 /* Calculate the size of temporary needed in the assignment inside forall.
3387 LSS and RSS are filled in this function. */
3389 static tree
3390 compute_inner_temp_size (gfc_expr *expr1, gfc_expr *expr2,
3391 stmtblock_t * pblock,
3392 gfc_ss **lss, gfc_ss **rss)
3394 gfc_loopinfo loop;
3395 tree size;
3396 int i;
3397 int save_flag;
3398 tree tmp;
3400 *lss = gfc_walk_expr (expr1);
3401 *rss = NULL;
3403 size = gfc_index_one_node;
3404 if (*lss != gfc_ss_terminator)
3406 gfc_init_loopinfo (&loop);
3408 /* Walk the RHS of the expression. */
3409 *rss = gfc_walk_expr (expr2);
3410 if (*rss == gfc_ss_terminator)
3411 /* The rhs is scalar. Add a ss for the expression. */
3412 *rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
3414 /* Associate the SS with the loop. */
3415 gfc_add_ss_to_loop (&loop, *lss);
3416 /* We don't actually need to add the rhs at this point, but it might
3417 make guessing the loop bounds a bit easier. */
3418 gfc_add_ss_to_loop (&loop, *rss);
3420 /* We only want the shape of the expression, not rest of the junk
3421 generated by the scalarizer. */
3422 loop.array_parameter = 1;
3424 /* Calculate the bounds of the scalarization. */
3425 save_flag = gfc_option.rtcheck;
3426 gfc_option.rtcheck &= ~GFC_RTCHECK_BOUNDS;
3427 gfc_conv_ss_startstride (&loop);
3428 gfc_option.rtcheck = save_flag;
3429 gfc_conv_loop_setup (&loop, &expr2->where);
3431 /* Figure out how many elements we need. */
3432 for (i = 0; i < loop.dimen; i++)
3434 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3435 gfc_array_index_type,
3436 gfc_index_one_node, loop.from[i]);
3437 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3438 gfc_array_index_type, tmp, loop.to[i]);
3439 size = fold_build2_loc (input_location, MULT_EXPR,
3440 gfc_array_index_type, size, tmp);
3442 gfc_add_block_to_block (pblock, &loop.pre);
3443 size = gfc_evaluate_now (size, pblock);
3444 gfc_add_block_to_block (pblock, &loop.post);
3446 /* TODO: write a function that cleans up a loopinfo without freeing
3447 the SS chains. Currently a NOP. */
3450 return size;
3454 /* Calculate the overall iterator number of the nested forall construct.
3455 This routine actually calculates the number of times the body of the
3456 nested forall specified by NESTED_FORALL_INFO is executed and multiplies
3457 that by the expression INNER_SIZE. The BLOCK argument specifies the
3458 block in which to calculate the result, and the optional INNER_SIZE_BODY
3459 argument contains any statements that need to executed (inside the loop)
3460 to initialize or calculate INNER_SIZE. */
3462 static tree
3463 compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
3464 stmtblock_t *inner_size_body, stmtblock_t *block)
3466 forall_info *forall_tmp = nested_forall_info;
3467 tree tmp, number;
3468 stmtblock_t body;
3470 /* We can eliminate the innermost unconditional loops with constant
3471 array bounds. */
3472 if (INTEGER_CST_P (inner_size))
3474 while (forall_tmp
3475 && !forall_tmp->mask
3476 && INTEGER_CST_P (forall_tmp->size))
3478 inner_size = fold_build2_loc (input_location, MULT_EXPR,
3479 gfc_array_index_type,
3480 inner_size, forall_tmp->size);
3481 forall_tmp = forall_tmp->prev_nest;
3484 /* If there are no loops left, we have our constant result. */
3485 if (!forall_tmp)
3486 return inner_size;
3489 /* Otherwise, create a temporary variable to compute the result. */
3490 number = gfc_create_var (gfc_array_index_type, "num");
3491 gfc_add_modify (block, number, gfc_index_zero_node);
3493 gfc_start_block (&body);
3494 if (inner_size_body)
3495 gfc_add_block_to_block (&body, inner_size_body);
3496 if (forall_tmp)
3497 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3498 gfc_array_index_type, number, inner_size);
3499 else
3500 tmp = inner_size;
3501 gfc_add_modify (&body, number, tmp);
3502 tmp = gfc_finish_block (&body);
3504 /* Generate loops. */
3505 if (forall_tmp != NULL)
3506 tmp = gfc_trans_nested_forall_loop (forall_tmp, tmp, 1);
3508 gfc_add_expr_to_block (block, tmp);
3510 return number;
3514 /* Allocate temporary for forall construct. SIZE is the size of temporary
3515 needed. PTEMP1 is returned for space free. */
3517 static tree
3518 allocate_temp_for_forall_nest_1 (tree type, tree size, stmtblock_t * block,
3519 tree * ptemp1)
3521 tree bytesize;
3522 tree unit;
3523 tree tmp;
3525 unit = fold_convert (gfc_array_index_type, TYPE_SIZE_UNIT (type));
3526 if (!integer_onep (unit))
3527 bytesize = fold_build2_loc (input_location, MULT_EXPR,
3528 gfc_array_index_type, size, unit);
3529 else
3530 bytesize = size;
3532 *ptemp1 = NULL;
3533 tmp = gfc_do_allocate (bytesize, size, ptemp1, block, type);
3535 if (*ptemp1)
3536 tmp = build_fold_indirect_ref_loc (input_location, tmp);
3537 return tmp;
3541 /* Allocate temporary for forall construct according to the information in
3542 nested_forall_info. INNER_SIZE is the size of temporary needed in the
3543 assignment inside forall. PTEMP1 is returned for space free. */
3545 static tree
3546 allocate_temp_for_forall_nest (forall_info * nested_forall_info, tree type,
3547 tree inner_size, stmtblock_t * inner_size_body,
3548 stmtblock_t * block, tree * ptemp1)
3550 tree size;
3552 /* Calculate the total size of temporary needed in forall construct. */
3553 size = compute_overall_iter_number (nested_forall_info, inner_size,
3554 inner_size_body, block);
3556 return allocate_temp_for_forall_nest_1 (type, size, block, ptemp1);
3560 /* Handle assignments inside forall which need temporary.
3562 forall (i=start:end:stride; maskexpr)
3563 e<i> = f<i>
3564 end forall
3565 (where e,f<i> are arbitrary expressions possibly involving i
3566 and there is a dependency between e<i> and f<i>)
3567 Translates to:
3568 masktmp(:) = maskexpr(:)
3570 maskindex = 0;
3571 count1 = 0;
3572 num = 0;
3573 for (i = start; i <= end; i += stride)
3574 num += SIZE (f<i>)
3575 count1 = 0;
3576 ALLOCATE (tmp(num))
3577 for (i = start; i <= end; i += stride)
3579 if (masktmp[maskindex++])
3580 tmp[count1++] = f<i>
3582 maskindex = 0;
3583 count1 = 0;
3584 for (i = start; i <= end; i += stride)
3586 if (masktmp[maskindex++])
3587 e<i> = tmp[count1++]
3589 DEALLOCATE (tmp)
3591 static void
3592 gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
3593 tree wheremask, bool invert,
3594 forall_info * nested_forall_info,
3595 stmtblock_t * block)
3597 tree type;
3598 tree inner_size;
3599 gfc_ss *lss, *rss;
3600 tree count, count1;
3601 tree tmp, tmp1;
3602 tree ptemp1;
3603 stmtblock_t inner_size_body;
3605 /* Create vars. count1 is the current iterator number of the nested
3606 forall. */
3607 count1 = gfc_create_var (gfc_array_index_type, "count1");
3609 /* Count is the wheremask index. */
3610 if (wheremask)
3612 count = gfc_create_var (gfc_array_index_type, "count");
3613 gfc_add_modify (block, count, gfc_index_zero_node);
3615 else
3616 count = NULL;
3618 /* Initialize count1. */
3619 gfc_add_modify (block, count1, gfc_index_zero_node);
3621 /* Calculate the size of temporary needed in the assignment. Return loop, lss
3622 and rss which are used in function generate_loop_for_rhs_to_temp(). */
3623 gfc_init_block (&inner_size_body);
3624 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
3625 &lss, &rss);
3627 /* The type of LHS. Used in function allocate_temp_for_forall_nest */
3628 if (expr1->ts.type == BT_CHARACTER && expr1->ts.u.cl->length)
3630 if (!expr1->ts.u.cl->backend_decl)
3632 gfc_se tse;
3633 gfc_init_se (&tse, NULL);
3634 gfc_conv_expr (&tse, expr1->ts.u.cl->length);
3635 expr1->ts.u.cl->backend_decl = tse.expr;
3637 type = gfc_get_character_type_len (gfc_default_character_kind,
3638 expr1->ts.u.cl->backend_decl);
3640 else
3641 type = gfc_typenode_for_spec (&expr1->ts);
3643 /* Allocate temporary for nested forall construct according to the
3644 information in nested_forall_info and inner_size. */
3645 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type, inner_size,
3646 &inner_size_body, block, &ptemp1);
3648 /* Generate codes to copy rhs to the temporary . */
3649 tmp = generate_loop_for_rhs_to_temp (expr2, tmp1, count, count1, lss, rss,
3650 wheremask, invert);
3652 /* Generate body and loops according to the information in
3653 nested_forall_info. */
3654 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3655 gfc_add_expr_to_block (block, tmp);
3657 /* Reset count1. */
3658 gfc_add_modify (block, count1, gfc_index_zero_node);
3660 /* Reset count. */
3661 if (wheremask)
3662 gfc_add_modify (block, count, gfc_index_zero_node);
3664 /* Generate codes to copy the temporary to lhs. */
3665 tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, count, count1,
3666 wheremask, invert);
3668 /* Generate body and loops according to the information in
3669 nested_forall_info. */
3670 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3671 gfc_add_expr_to_block (block, tmp);
3673 if (ptemp1)
3675 /* Free the temporary. */
3676 tmp = gfc_call_free (ptemp1);
3677 gfc_add_expr_to_block (block, tmp);
3682 /* Translate pointer assignment inside FORALL which need temporary. */
3684 static void
3685 gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
3686 forall_info * nested_forall_info,
3687 stmtblock_t * block)
3689 tree type;
3690 tree inner_size;
3691 gfc_ss *lss, *rss;
3692 gfc_se lse;
3693 gfc_se rse;
3694 gfc_array_info *info;
3695 gfc_loopinfo loop;
3696 tree desc;
3697 tree parm;
3698 tree parmtype;
3699 stmtblock_t body;
3700 tree count;
3701 tree tmp, tmp1, ptemp1;
3703 count = gfc_create_var (gfc_array_index_type, "count");
3704 gfc_add_modify (block, count, gfc_index_zero_node);
3706 inner_size = gfc_index_one_node;
3707 lss = gfc_walk_expr (expr1);
3708 rss = gfc_walk_expr (expr2);
3709 if (lss == gfc_ss_terminator)
3711 type = gfc_typenode_for_spec (&expr1->ts);
3712 type = build_pointer_type (type);
3714 /* Allocate temporary for nested forall construct according to the
3715 information in nested_forall_info and inner_size. */
3716 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type,
3717 inner_size, NULL, block, &ptemp1);
3718 gfc_start_block (&body);
3719 gfc_init_se (&lse, NULL);
3720 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
3721 gfc_init_se (&rse, NULL);
3722 rse.want_pointer = 1;
3723 gfc_conv_expr (&rse, expr2);
3724 gfc_add_block_to_block (&body, &rse.pre);
3725 gfc_add_modify (&body, lse.expr,
3726 fold_convert (TREE_TYPE (lse.expr), rse.expr));
3727 gfc_add_block_to_block (&body, &rse.post);
3729 /* Increment count. */
3730 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3731 count, gfc_index_one_node);
3732 gfc_add_modify (&body, count, tmp);
3734 tmp = gfc_finish_block (&body);
3736 /* Generate body and loops according to the information in
3737 nested_forall_info. */
3738 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3739 gfc_add_expr_to_block (block, tmp);
3741 /* Reset count. */
3742 gfc_add_modify (block, count, gfc_index_zero_node);
3744 gfc_start_block (&body);
3745 gfc_init_se (&lse, NULL);
3746 gfc_init_se (&rse, NULL);
3747 rse.expr = gfc_build_array_ref (tmp1, count, NULL);
3748 lse.want_pointer = 1;
3749 gfc_conv_expr (&lse, expr1);
3750 gfc_add_block_to_block (&body, &lse.pre);
3751 gfc_add_modify (&body, lse.expr, rse.expr);
3752 gfc_add_block_to_block (&body, &lse.post);
3753 /* Increment count. */
3754 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3755 count, gfc_index_one_node);
3756 gfc_add_modify (&body, count, tmp);
3757 tmp = gfc_finish_block (&body);
3759 /* Generate body and loops according to the information in
3760 nested_forall_info. */
3761 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3762 gfc_add_expr_to_block (block, tmp);
3764 else
3766 gfc_init_loopinfo (&loop);
3768 /* Associate the SS with the loop. */
3769 gfc_add_ss_to_loop (&loop, rss);
3771 /* Setup the scalarizing loops and bounds. */
3772 gfc_conv_ss_startstride (&loop);
3774 gfc_conv_loop_setup (&loop, &expr2->where);
3776 info = &rss->info->data.array;
3777 desc = info->descriptor;
3779 /* Make a new descriptor. */
3780 parmtype = gfc_get_element_type (TREE_TYPE (desc));
3781 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0,
3782 loop.from, loop.to, 1,
3783 GFC_ARRAY_UNKNOWN, true);
3785 /* Allocate temporary for nested forall construct. */
3786 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
3787 inner_size, NULL, block, &ptemp1);
3788 gfc_start_block (&body);
3789 gfc_init_se (&lse, NULL);
3790 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
3791 lse.direct_byref = 1;
3792 gfc_conv_expr_descriptor (&lse, expr2);
3794 gfc_add_block_to_block (&body, &lse.pre);
3795 gfc_add_block_to_block (&body, &lse.post);
3797 /* Increment count. */
3798 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3799 count, gfc_index_one_node);
3800 gfc_add_modify (&body, count, tmp);
3802 tmp = gfc_finish_block (&body);
3804 /* Generate body and loops according to the information in
3805 nested_forall_info. */
3806 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3807 gfc_add_expr_to_block (block, tmp);
3809 /* Reset count. */
3810 gfc_add_modify (block, count, gfc_index_zero_node);
3812 parm = gfc_build_array_ref (tmp1, count, NULL);
3813 gfc_init_se (&lse, NULL);
3814 gfc_conv_expr_descriptor (&lse, expr1);
3815 gfc_add_modify (&lse.pre, lse.expr, parm);
3816 gfc_start_block (&body);
3817 gfc_add_block_to_block (&body, &lse.pre);
3818 gfc_add_block_to_block (&body, &lse.post);
3820 /* Increment count. */
3821 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3822 count, gfc_index_one_node);
3823 gfc_add_modify (&body, count, tmp);
3825 tmp = gfc_finish_block (&body);
3827 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3828 gfc_add_expr_to_block (block, tmp);
3830 /* Free the temporary. */
3831 if (ptemp1)
3833 tmp = gfc_call_free (ptemp1);
3834 gfc_add_expr_to_block (block, tmp);
3839 /* FORALL and WHERE statements are really nasty, especially when you nest
3840 them. All the rhs of a forall assignment must be evaluated before the
3841 actual assignments are performed. Presumably this also applies to all the
3842 assignments in an inner where statement. */
3844 /* Generate code for a FORALL statement. Any temporaries are allocated as a
3845 linear array, relying on the fact that we process in the same order in all
3846 loops.
3848 forall (i=start:end:stride; maskexpr)
3849 e<i> = f<i>
3850 g<i> = h<i>
3851 end forall
3852 (where e,f,g,h<i> are arbitrary expressions possibly involving i)
3853 Translates to:
3854 count = ((end + 1 - start) / stride)
3855 masktmp(:) = maskexpr(:)
3857 maskindex = 0;
3858 for (i = start; i <= end; i += stride)
3860 if (masktmp[maskindex++])
3861 e<i> = f<i>
3863 maskindex = 0;
3864 for (i = start; i <= end; i += stride)
3866 if (masktmp[maskindex++])
3867 g<i> = h<i>
3870 Note that this code only works when there are no dependencies.
3871 Forall loop with array assignments and data dependencies are a real pain,
3872 because the size of the temporary cannot always be determined before the
3873 loop is executed. This problem is compounded by the presence of nested
3874 FORALL constructs.
3877 static tree
3878 gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
3880 stmtblock_t pre;
3881 stmtblock_t post;
3882 stmtblock_t block;
3883 stmtblock_t body;
3884 tree *var;
3885 tree *start;
3886 tree *end;
3887 tree *step;
3888 gfc_expr **varexpr;
3889 tree tmp;
3890 tree assign;
3891 tree size;
3892 tree maskindex;
3893 tree mask;
3894 tree pmask;
3895 tree cycle_label = NULL_TREE;
3896 int n;
3897 int nvar;
3898 int need_temp;
3899 gfc_forall_iterator *fa;
3900 gfc_se se;
3901 gfc_code *c;
3902 gfc_saved_var *saved_vars;
3903 iter_info *this_forall;
3904 forall_info *info;
3905 bool need_mask;
3907 /* Do nothing if the mask is false. */
3908 if (code->expr1
3909 && code->expr1->expr_type == EXPR_CONSTANT
3910 && !code->expr1->value.logical)
3911 return build_empty_stmt (input_location);
3913 n = 0;
3914 /* Count the FORALL index number. */
3915 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
3916 n++;
3917 nvar = n;
3919 /* Allocate the space for var, start, end, step, varexpr. */
3920 var = XCNEWVEC (tree, nvar);
3921 start = XCNEWVEC (tree, nvar);
3922 end = XCNEWVEC (tree, nvar);
3923 step = XCNEWVEC (tree, nvar);
3924 varexpr = XCNEWVEC (gfc_expr *, nvar);
3925 saved_vars = XCNEWVEC (gfc_saved_var, nvar);
3927 /* Allocate the space for info. */
3928 info = XCNEW (forall_info);
3930 gfc_start_block (&pre);
3931 gfc_init_block (&post);
3932 gfc_init_block (&block);
3934 n = 0;
3935 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
3937 gfc_symbol *sym = fa->var->symtree->n.sym;
3939 /* Allocate space for this_forall. */
3940 this_forall = XCNEW (iter_info);
3942 /* Create a temporary variable for the FORALL index. */
3943 tmp = gfc_typenode_for_spec (&sym->ts);
3944 var[n] = gfc_create_var (tmp, sym->name);
3945 gfc_shadow_sym (sym, var[n], &saved_vars[n]);
3947 /* Record it in this_forall. */
3948 this_forall->var = var[n];
3950 /* Replace the index symbol's backend_decl with the temporary decl. */
3951 sym->backend_decl = var[n];
3953 /* Work out the start, end and stride for the loop. */
3954 gfc_init_se (&se, NULL);
3955 gfc_conv_expr_val (&se, fa->start);
3956 /* Record it in this_forall. */
3957 this_forall->start = se.expr;
3958 gfc_add_block_to_block (&block, &se.pre);
3959 start[n] = se.expr;
3961 gfc_init_se (&se, NULL);
3962 gfc_conv_expr_val (&se, fa->end);
3963 /* Record it in this_forall. */
3964 this_forall->end = se.expr;
3965 gfc_make_safe_expr (&se);
3966 gfc_add_block_to_block (&block, &se.pre);
3967 end[n] = se.expr;
3969 gfc_init_se (&se, NULL);
3970 gfc_conv_expr_val (&se, fa->stride);
3971 /* Record it in this_forall. */
3972 this_forall->step = se.expr;
3973 gfc_make_safe_expr (&se);
3974 gfc_add_block_to_block (&block, &se.pre);
3975 step[n] = se.expr;
3977 /* Set the NEXT field of this_forall to NULL. */
3978 this_forall->next = NULL;
3979 /* Link this_forall to the info construct. */
3980 if (info->this_loop)
3982 iter_info *iter_tmp = info->this_loop;
3983 while (iter_tmp->next != NULL)
3984 iter_tmp = iter_tmp->next;
3985 iter_tmp->next = this_forall;
3987 else
3988 info->this_loop = this_forall;
3990 n++;
3992 nvar = n;
3994 /* Calculate the size needed for the current forall level. */
3995 size = gfc_index_one_node;
3996 for (n = 0; n < nvar; n++)
3998 /* size = (end + step - start) / step. */
3999 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (start[n]),
4000 step[n], start[n]);
4001 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (end[n]),
4002 end[n], tmp);
4003 tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, TREE_TYPE (tmp),
4004 tmp, step[n]);
4005 tmp = convert (gfc_array_index_type, tmp);
4007 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4008 size, tmp);
4011 /* Record the nvar and size of current forall level. */
4012 info->nvar = nvar;
4013 info->size = size;
4015 if (code->expr1)
4017 /* If the mask is .true., consider the FORALL unconditional. */
4018 if (code->expr1->expr_type == EXPR_CONSTANT
4019 && code->expr1->value.logical)
4020 need_mask = false;
4021 else
4022 need_mask = true;
4024 else
4025 need_mask = false;
4027 /* First we need to allocate the mask. */
4028 if (need_mask)
4030 /* As the mask array can be very big, prefer compact boolean types. */
4031 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4032 mask = allocate_temp_for_forall_nest (nested_forall_info, mask_type,
4033 size, NULL, &block, &pmask);
4034 maskindex = gfc_create_var_np (gfc_array_index_type, "mi");
4036 /* Record them in the info structure. */
4037 info->maskindex = maskindex;
4038 info->mask = mask;
4040 else
4042 /* No mask was specified. */
4043 maskindex = NULL_TREE;
4044 mask = pmask = NULL_TREE;
4047 /* Link the current forall level to nested_forall_info. */
4048 info->prev_nest = nested_forall_info;
4049 nested_forall_info = info;
4051 /* Copy the mask into a temporary variable if required.
4052 For now we assume a mask temporary is needed. */
4053 if (need_mask)
4055 /* As the mask array can be very big, prefer compact boolean types. */
4056 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4058 gfc_add_modify (&block, maskindex, gfc_index_zero_node);
4060 /* Start of mask assignment loop body. */
4061 gfc_start_block (&body);
4063 /* Evaluate the mask expression. */
4064 gfc_init_se (&se, NULL);
4065 gfc_conv_expr_val (&se, code->expr1);
4066 gfc_add_block_to_block (&body, &se.pre);
4068 /* Store the mask. */
4069 se.expr = convert (mask_type, se.expr);
4071 tmp = gfc_build_array_ref (mask, maskindex, NULL);
4072 gfc_add_modify (&body, tmp, se.expr);
4074 /* Advance to the next mask element. */
4075 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4076 maskindex, gfc_index_one_node);
4077 gfc_add_modify (&body, maskindex, tmp);
4079 /* Generate the loops. */
4080 tmp = gfc_finish_block (&body);
4081 tmp = gfc_trans_nested_forall_loop (info, tmp, 0);
4082 gfc_add_expr_to_block (&block, tmp);
4085 if (code->op == EXEC_DO_CONCURRENT)
4087 gfc_init_block (&body);
4088 cycle_label = gfc_build_label_decl (NULL_TREE);
4089 code->cycle_label = cycle_label;
4090 tmp = gfc_trans_code (code->block->next);
4091 gfc_add_expr_to_block (&body, tmp);
4093 if (TREE_USED (cycle_label))
4095 tmp = build1_v (LABEL_EXPR, cycle_label);
4096 gfc_add_expr_to_block (&body, tmp);
4099 tmp = gfc_finish_block (&body);
4100 nested_forall_info->do_concurrent = true;
4101 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4102 gfc_add_expr_to_block (&block, tmp);
4103 goto done;
4106 c = code->block->next;
4108 /* TODO: loop merging in FORALL statements. */
4109 /* Now that we've got a copy of the mask, generate the assignment loops. */
4110 while (c)
4112 switch (c->op)
4114 case EXEC_ASSIGN:
4115 /* A scalar or array assignment. DO the simple check for
4116 lhs to rhs dependencies. These make a temporary for the
4117 rhs and form a second forall block to copy to variable. */
4118 need_temp = check_forall_dependencies(c, &pre, &post);
4120 /* Temporaries due to array assignment data dependencies introduce
4121 no end of problems. */
4122 if (need_temp)
4123 gfc_trans_assign_need_temp (c->expr1, c->expr2, NULL, false,
4124 nested_forall_info, &block);
4125 else
4127 /* Use the normal assignment copying routines. */
4128 assign = gfc_trans_assignment (c->expr1, c->expr2, false, true);
4130 /* Generate body and loops. */
4131 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4132 assign, 1);
4133 gfc_add_expr_to_block (&block, tmp);
4136 /* Cleanup any temporary symtrees that have been made to deal
4137 with dependencies. */
4138 if (new_symtree)
4139 cleanup_forall_symtrees (c);
4141 break;
4143 case EXEC_WHERE:
4144 /* Translate WHERE or WHERE construct nested in FORALL. */
4145 gfc_trans_where_2 (c, NULL, false, nested_forall_info, &block);
4146 break;
4148 /* Pointer assignment inside FORALL. */
4149 case EXEC_POINTER_ASSIGN:
4150 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
4151 if (need_temp)
4152 gfc_trans_pointer_assign_need_temp (c->expr1, c->expr2,
4153 nested_forall_info, &block);
4154 else
4156 /* Use the normal assignment copying routines. */
4157 assign = gfc_trans_pointer_assignment (c->expr1, c->expr2);
4159 /* Generate body and loops. */
4160 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4161 assign, 1);
4162 gfc_add_expr_to_block (&block, tmp);
4164 break;
4166 case EXEC_FORALL:
4167 tmp = gfc_trans_forall_1 (c, nested_forall_info);
4168 gfc_add_expr_to_block (&block, tmp);
4169 break;
4171 /* Explicit subroutine calls are prevented by the frontend but interface
4172 assignments can legitimately produce them. */
4173 case EXEC_ASSIGN_CALL:
4174 assign = gfc_trans_call (c, true, NULL_TREE, NULL_TREE, false);
4175 tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign, 1);
4176 gfc_add_expr_to_block (&block, tmp);
4177 break;
4179 default:
4180 gcc_unreachable ();
4183 c = c->next;
4186 done:
4187 /* Restore the original index variables. */
4188 for (fa = code->ext.forall_iterator, n = 0; fa; fa = fa->next, n++)
4189 gfc_restore_sym (fa->var->symtree->n.sym, &saved_vars[n]);
4191 /* Free the space for var, start, end, step, varexpr. */
4192 free (var);
4193 free (start);
4194 free (end);
4195 free (step);
4196 free (varexpr);
4197 free (saved_vars);
4199 for (this_forall = info->this_loop; this_forall;)
4201 iter_info *next = this_forall->next;
4202 free (this_forall);
4203 this_forall = next;
4206 /* Free the space for this forall_info. */
4207 free (info);
4209 if (pmask)
4211 /* Free the temporary for the mask. */
4212 tmp = gfc_call_free (pmask);
4213 gfc_add_expr_to_block (&block, tmp);
4215 if (maskindex)
4216 pushdecl (maskindex);
4218 gfc_add_block_to_block (&pre, &block);
4219 gfc_add_block_to_block (&pre, &post);
4221 return gfc_finish_block (&pre);
4225 /* Translate the FORALL statement or construct. */
4227 tree gfc_trans_forall (gfc_code * code)
4229 return gfc_trans_forall_1 (code, NULL);
4233 /* Translate the DO CONCURRENT construct. */
4235 tree gfc_trans_do_concurrent (gfc_code * code)
4237 return gfc_trans_forall_1 (code, NULL);
4241 /* Evaluate the WHERE mask expression, copy its value to a temporary.
4242 If the WHERE construct is nested in FORALL, compute the overall temporary
4243 needed by the WHERE mask expression multiplied by the iterator number of
4244 the nested forall.
4245 ME is the WHERE mask expression.
4246 MASK is the current execution mask upon input, whose sense may or may
4247 not be inverted as specified by the INVERT argument.
4248 CMASK is the updated execution mask on output, or NULL if not required.
4249 PMASK is the pending execution mask on output, or NULL if not required.
4250 BLOCK is the block in which to place the condition evaluation loops. */
4252 static void
4253 gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
4254 tree mask, bool invert, tree cmask, tree pmask,
4255 tree mask_type, stmtblock_t * block)
4257 tree tmp, tmp1;
4258 gfc_ss *lss, *rss;
4259 gfc_loopinfo loop;
4260 stmtblock_t body, body1;
4261 tree count, cond, mtmp;
4262 gfc_se lse, rse;
4264 gfc_init_loopinfo (&loop);
4266 lss = gfc_walk_expr (me);
4267 rss = gfc_walk_expr (me);
4269 /* Variable to index the temporary. */
4270 count = gfc_create_var (gfc_array_index_type, "count");
4271 /* Initialize count. */
4272 gfc_add_modify (block, count, gfc_index_zero_node);
4274 gfc_start_block (&body);
4276 gfc_init_se (&rse, NULL);
4277 gfc_init_se (&lse, NULL);
4279 if (lss == gfc_ss_terminator)
4281 gfc_init_block (&body1);
4283 else
4285 /* Initialize the loop. */
4286 gfc_init_loopinfo (&loop);
4288 /* We may need LSS to determine the shape of the expression. */
4289 gfc_add_ss_to_loop (&loop, lss);
4290 gfc_add_ss_to_loop (&loop, rss);
4292 gfc_conv_ss_startstride (&loop);
4293 gfc_conv_loop_setup (&loop, &me->where);
4295 gfc_mark_ss_chain_used (rss, 1);
4296 /* Start the loop body. */
4297 gfc_start_scalarized_body (&loop, &body1);
4299 /* Translate the expression. */
4300 gfc_copy_loopinfo_to_se (&rse, &loop);
4301 rse.ss = rss;
4302 gfc_conv_expr (&rse, me);
4305 /* Variable to evaluate mask condition. */
4306 cond = gfc_create_var (mask_type, "cond");
4307 if (mask && (cmask || pmask))
4308 mtmp = gfc_create_var (mask_type, "mask");
4309 else mtmp = NULL_TREE;
4311 gfc_add_block_to_block (&body1, &lse.pre);
4312 gfc_add_block_to_block (&body1, &rse.pre);
4314 gfc_add_modify (&body1, cond, fold_convert (mask_type, rse.expr));
4316 if (mask && (cmask || pmask))
4318 tmp = gfc_build_array_ref (mask, count, NULL);
4319 if (invert)
4320 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, tmp);
4321 gfc_add_modify (&body1, mtmp, tmp);
4324 if (cmask)
4326 tmp1 = gfc_build_array_ref (cmask, count, NULL);
4327 tmp = cond;
4328 if (mask)
4329 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type,
4330 mtmp, tmp);
4331 gfc_add_modify (&body1, tmp1, tmp);
4334 if (pmask)
4336 tmp1 = gfc_build_array_ref (pmask, count, NULL);
4337 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, cond);
4338 if (mask)
4339 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type, mtmp,
4340 tmp);
4341 gfc_add_modify (&body1, tmp1, tmp);
4344 gfc_add_block_to_block (&body1, &lse.post);
4345 gfc_add_block_to_block (&body1, &rse.post);
4347 if (lss == gfc_ss_terminator)
4349 gfc_add_block_to_block (&body, &body1);
4351 else
4353 /* Increment count. */
4354 tmp1 = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4355 count, gfc_index_one_node);
4356 gfc_add_modify (&body1, count, tmp1);
4358 /* Generate the copying loops. */
4359 gfc_trans_scalarizing_loops (&loop, &body1);
4361 gfc_add_block_to_block (&body, &loop.pre);
4362 gfc_add_block_to_block (&body, &loop.post);
4364 gfc_cleanup_loop (&loop);
4365 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
4366 as tree nodes in SS may not be valid in different scope. */
4369 tmp1 = gfc_finish_block (&body);
4370 /* If the WHERE construct is inside FORALL, fill the full temporary. */
4371 if (nested_forall_info != NULL)
4372 tmp1 = gfc_trans_nested_forall_loop (nested_forall_info, tmp1, 1);
4374 gfc_add_expr_to_block (block, tmp1);
4378 /* Translate an assignment statement in a WHERE statement or construct
4379 statement. The MASK expression is used to control which elements
4380 of EXPR1 shall be assigned. The sense of MASK is specified by
4381 INVERT. */
4383 static tree
4384 gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
4385 tree mask, bool invert,
4386 tree count1, tree count2,
4387 gfc_code *cnext)
4389 gfc_se lse;
4390 gfc_se rse;
4391 gfc_ss *lss;
4392 gfc_ss *lss_section;
4393 gfc_ss *rss;
4395 gfc_loopinfo loop;
4396 tree tmp;
4397 stmtblock_t block;
4398 stmtblock_t body;
4399 tree index, maskexpr;
4401 /* A defined assignment. */
4402 if (cnext && cnext->resolved_sym)
4403 return gfc_trans_call (cnext, true, mask, count1, invert);
4405 #if 0
4406 /* TODO: handle this special case.
4407 Special case a single function returning an array. */
4408 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
4410 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
4411 if (tmp)
4412 return tmp;
4414 #endif
4416 /* Assignment of the form lhs = rhs. */
4417 gfc_start_block (&block);
4419 gfc_init_se (&lse, NULL);
4420 gfc_init_se (&rse, NULL);
4422 /* Walk the lhs. */
4423 lss = gfc_walk_expr (expr1);
4424 rss = NULL;
4426 /* In each where-assign-stmt, the mask-expr and the variable being
4427 defined shall be arrays of the same shape. */
4428 gcc_assert (lss != gfc_ss_terminator);
4430 /* The assignment needs scalarization. */
4431 lss_section = lss;
4433 /* Find a non-scalar SS from the lhs. */
4434 while (lss_section != gfc_ss_terminator
4435 && lss_section->info->type != GFC_SS_SECTION)
4436 lss_section = lss_section->next;
4438 gcc_assert (lss_section != gfc_ss_terminator);
4440 /* Initialize the scalarizer. */
4441 gfc_init_loopinfo (&loop);
4443 /* Walk the rhs. */
4444 rss = gfc_walk_expr (expr2);
4445 if (rss == gfc_ss_terminator)
4447 /* The rhs is scalar. Add a ss for the expression. */
4448 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
4449 rss->info->where = 1;
4452 /* Associate the SS with the loop. */
4453 gfc_add_ss_to_loop (&loop, lss);
4454 gfc_add_ss_to_loop (&loop, rss);
4456 /* Calculate the bounds of the scalarization. */
4457 gfc_conv_ss_startstride (&loop);
4459 /* Resolve any data dependencies in the statement. */
4460 gfc_conv_resolve_dependencies (&loop, lss_section, rss);
4462 /* Setup the scalarizing loops. */
4463 gfc_conv_loop_setup (&loop, &expr2->where);
4465 /* Setup the gfc_se structures. */
4466 gfc_copy_loopinfo_to_se (&lse, &loop);
4467 gfc_copy_loopinfo_to_se (&rse, &loop);
4469 rse.ss = rss;
4470 gfc_mark_ss_chain_used (rss, 1);
4471 if (loop.temp_ss == NULL)
4473 lse.ss = lss;
4474 gfc_mark_ss_chain_used (lss, 1);
4476 else
4478 lse.ss = loop.temp_ss;
4479 gfc_mark_ss_chain_used (lss, 3);
4480 gfc_mark_ss_chain_used (loop.temp_ss, 3);
4483 /* Start the scalarized loop body. */
4484 gfc_start_scalarized_body (&loop, &body);
4486 /* Translate the expression. */
4487 gfc_conv_expr (&rse, expr2);
4488 if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
4489 gfc_conv_tmp_array_ref (&lse);
4490 else
4491 gfc_conv_expr (&lse, expr1);
4493 /* Form the mask expression according to the mask. */
4494 index = count1;
4495 maskexpr = gfc_build_array_ref (mask, index, NULL);
4496 if (invert)
4497 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
4498 TREE_TYPE (maskexpr), maskexpr);
4500 /* Use the scalar assignment as is. */
4501 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
4502 loop.temp_ss != NULL, false, true);
4504 tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt (input_location));
4506 gfc_add_expr_to_block (&body, tmp);
4508 if (lss == gfc_ss_terminator)
4510 /* Increment count1. */
4511 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4512 count1, gfc_index_one_node);
4513 gfc_add_modify (&body, count1, tmp);
4515 /* Use the scalar assignment as is. */
4516 gfc_add_block_to_block (&block, &body);
4518 else
4520 gcc_assert (lse.ss == gfc_ss_terminator
4521 && rse.ss == gfc_ss_terminator);
4523 if (loop.temp_ss != NULL)
4525 /* Increment count1 before finish the main body of a scalarized
4526 expression. */
4527 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4528 gfc_array_index_type, count1, gfc_index_one_node);
4529 gfc_add_modify (&body, count1, tmp);
4530 gfc_trans_scalarized_loop_boundary (&loop, &body);
4532 /* We need to copy the temporary to the actual lhs. */
4533 gfc_init_se (&lse, NULL);
4534 gfc_init_se (&rse, NULL);
4535 gfc_copy_loopinfo_to_se (&lse, &loop);
4536 gfc_copy_loopinfo_to_se (&rse, &loop);
4538 rse.ss = loop.temp_ss;
4539 lse.ss = lss;
4541 gfc_conv_tmp_array_ref (&rse);
4542 gfc_conv_expr (&lse, expr1);
4544 gcc_assert (lse.ss == gfc_ss_terminator
4545 && rse.ss == gfc_ss_terminator);
4547 /* Form the mask expression according to the mask tree list. */
4548 index = count2;
4549 maskexpr = gfc_build_array_ref (mask, index, NULL);
4550 if (invert)
4551 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
4552 TREE_TYPE (maskexpr), maskexpr);
4554 /* Use the scalar assignment as is. */
4555 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, false, false,
4556 true);
4557 tmp = build3_v (COND_EXPR, maskexpr, tmp,
4558 build_empty_stmt (input_location));
4559 gfc_add_expr_to_block (&body, tmp);
4561 /* Increment count2. */
4562 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4563 gfc_array_index_type, count2,
4564 gfc_index_one_node);
4565 gfc_add_modify (&body, count2, tmp);
4567 else
4569 /* Increment count1. */
4570 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4571 gfc_array_index_type, count1,
4572 gfc_index_one_node);
4573 gfc_add_modify (&body, count1, tmp);
4576 /* Generate the copying loops. */
4577 gfc_trans_scalarizing_loops (&loop, &body);
4579 /* Wrap the whole thing up. */
4580 gfc_add_block_to_block (&block, &loop.pre);
4581 gfc_add_block_to_block (&block, &loop.post);
4582 gfc_cleanup_loop (&loop);
4585 return gfc_finish_block (&block);
4589 /* Translate the WHERE construct or statement.
4590 This function can be called iteratively to translate the nested WHERE
4591 construct or statement.
4592 MASK is the control mask. */
4594 static void
4595 gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
4596 forall_info * nested_forall_info, stmtblock_t * block)
4598 stmtblock_t inner_size_body;
4599 tree inner_size, size;
4600 gfc_ss *lss, *rss;
4601 tree mask_type;
4602 gfc_expr *expr1;
4603 gfc_expr *expr2;
4604 gfc_code *cblock;
4605 gfc_code *cnext;
4606 tree tmp;
4607 tree cond;
4608 tree count1, count2;
4609 bool need_cmask;
4610 bool need_pmask;
4611 int need_temp;
4612 tree pcmask = NULL_TREE;
4613 tree ppmask = NULL_TREE;
4614 tree cmask = NULL_TREE;
4615 tree pmask = NULL_TREE;
4616 gfc_actual_arglist *arg;
4618 /* the WHERE statement or the WHERE construct statement. */
4619 cblock = code->block;
4621 /* As the mask array can be very big, prefer compact boolean types. */
4622 mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4624 /* Determine which temporary masks are needed. */
4625 if (!cblock->block)
4627 /* One clause: No ELSEWHEREs. */
4628 need_cmask = (cblock->next != 0);
4629 need_pmask = false;
4631 else if (cblock->block->block)
4633 /* Three or more clauses: Conditional ELSEWHEREs. */
4634 need_cmask = true;
4635 need_pmask = true;
4637 else if (cblock->next)
4639 /* Two clauses, the first non-empty. */
4640 need_cmask = true;
4641 need_pmask = (mask != NULL_TREE
4642 && cblock->block->next != 0);
4644 else if (!cblock->block->next)
4646 /* Two clauses, both empty. */
4647 need_cmask = false;
4648 need_pmask = false;
4650 /* Two clauses, the first empty, the second non-empty. */
4651 else if (mask)
4653 need_cmask = (cblock->block->expr1 != 0);
4654 need_pmask = true;
4656 else
4658 need_cmask = true;
4659 need_pmask = false;
4662 if (need_cmask || need_pmask)
4664 /* Calculate the size of temporary needed by the mask-expr. */
4665 gfc_init_block (&inner_size_body);
4666 inner_size = compute_inner_temp_size (cblock->expr1, cblock->expr1,
4667 &inner_size_body, &lss, &rss);
4669 gfc_free_ss_chain (lss);
4670 gfc_free_ss_chain (rss);
4672 /* Calculate the total size of temporary needed. */
4673 size = compute_overall_iter_number (nested_forall_info, inner_size,
4674 &inner_size_body, block);
4676 /* Check whether the size is negative. */
4677 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node, size,
4678 gfc_index_zero_node);
4679 size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
4680 cond, gfc_index_zero_node, size);
4681 size = gfc_evaluate_now (size, block);
4683 /* Allocate temporary for WHERE mask if needed. */
4684 if (need_cmask)
4685 cmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
4686 &pcmask);
4688 /* Allocate temporary for !mask if needed. */
4689 if (need_pmask)
4690 pmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
4691 &ppmask);
4694 while (cblock)
4696 /* Each time around this loop, the where clause is conditional
4697 on the value of mask and invert, which are updated at the
4698 bottom of the loop. */
4700 /* Has mask-expr. */
4701 if (cblock->expr1)
4703 /* Ensure that the WHERE mask will be evaluated exactly once.
4704 If there are no statements in this WHERE/ELSEWHERE clause,
4705 then we don't need to update the control mask (cmask).
4706 If this is the last clause of the WHERE construct, then
4707 we don't need to update the pending control mask (pmask). */
4708 if (mask)
4709 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
4710 mask, invert,
4711 cblock->next ? cmask : NULL_TREE,
4712 cblock->block ? pmask : NULL_TREE,
4713 mask_type, block);
4714 else
4715 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
4716 NULL_TREE, false,
4717 (cblock->next || cblock->block)
4718 ? cmask : NULL_TREE,
4719 NULL_TREE, mask_type, block);
4721 invert = false;
4723 /* It's a final elsewhere-stmt. No mask-expr is present. */
4724 else
4725 cmask = mask;
4727 /* The body of this where clause are controlled by cmask with
4728 sense specified by invert. */
4730 /* Get the assignment statement of a WHERE statement, or the first
4731 statement in where-body-construct of a WHERE construct. */
4732 cnext = cblock->next;
4733 while (cnext)
4735 switch (cnext->op)
4737 /* WHERE assignment statement. */
4738 case EXEC_ASSIGN_CALL:
4740 arg = cnext->ext.actual;
4741 expr1 = expr2 = NULL;
4742 for (; arg; arg = arg->next)
4744 if (!arg->expr)
4745 continue;
4746 if (expr1 == NULL)
4747 expr1 = arg->expr;
4748 else
4749 expr2 = arg->expr;
4751 goto evaluate;
4753 case EXEC_ASSIGN:
4754 expr1 = cnext->expr1;
4755 expr2 = cnext->expr2;
4756 evaluate:
4757 if (nested_forall_info != NULL)
4759 need_temp = gfc_check_dependency (expr1, expr2, 0);
4760 if (need_temp && cnext->op != EXEC_ASSIGN_CALL)
4761 gfc_trans_assign_need_temp (expr1, expr2,
4762 cmask, invert,
4763 nested_forall_info, block);
4764 else
4766 /* Variables to control maskexpr. */
4767 count1 = gfc_create_var (gfc_array_index_type, "count1");
4768 count2 = gfc_create_var (gfc_array_index_type, "count2");
4769 gfc_add_modify (block, count1, gfc_index_zero_node);
4770 gfc_add_modify (block, count2, gfc_index_zero_node);
4772 tmp = gfc_trans_where_assign (expr1, expr2,
4773 cmask, invert,
4774 count1, count2,
4775 cnext);
4777 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4778 tmp, 1);
4779 gfc_add_expr_to_block (block, tmp);
4782 else
4784 /* Variables to control maskexpr. */
4785 count1 = gfc_create_var (gfc_array_index_type, "count1");
4786 count2 = gfc_create_var (gfc_array_index_type, "count2");
4787 gfc_add_modify (block, count1, gfc_index_zero_node);
4788 gfc_add_modify (block, count2, gfc_index_zero_node);
4790 tmp = gfc_trans_where_assign (expr1, expr2,
4791 cmask, invert,
4792 count1, count2,
4793 cnext);
4794 gfc_add_expr_to_block (block, tmp);
4797 break;
4799 /* WHERE or WHERE construct is part of a where-body-construct. */
4800 case EXEC_WHERE:
4801 gfc_trans_where_2 (cnext, cmask, invert,
4802 nested_forall_info, block);
4803 break;
4805 default:
4806 gcc_unreachable ();
4809 /* The next statement within the same where-body-construct. */
4810 cnext = cnext->next;
4812 /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt. */
4813 cblock = cblock->block;
4814 if (mask == NULL_TREE)
4816 /* If we're the initial WHERE, we can simply invert the sense
4817 of the current mask to obtain the "mask" for the remaining
4818 ELSEWHEREs. */
4819 invert = true;
4820 mask = cmask;
4822 else
4824 /* Otherwise, for nested WHERE's we need to use the pending mask. */
4825 invert = false;
4826 mask = pmask;
4830 /* If we allocated a pending mask array, deallocate it now. */
4831 if (ppmask)
4833 tmp = gfc_call_free (ppmask);
4834 gfc_add_expr_to_block (block, tmp);
4837 /* If we allocated a current mask array, deallocate it now. */
4838 if (pcmask)
4840 tmp = gfc_call_free (pcmask);
4841 gfc_add_expr_to_block (block, tmp);
4845 /* Translate a simple WHERE construct or statement without dependencies.
4846 CBLOCK is the "then" clause of the WHERE statement, where CBLOCK->EXPR
4847 is the mask condition, and EBLOCK if non-NULL is the "else" clause.
4848 Currently both CBLOCK and EBLOCK are restricted to single assignments. */
4850 static tree
4851 gfc_trans_where_3 (gfc_code * cblock, gfc_code * eblock)
4853 stmtblock_t block, body;
4854 gfc_expr *cond, *tdst, *tsrc, *edst, *esrc;
4855 tree tmp, cexpr, tstmt, estmt;
4856 gfc_ss *css, *tdss, *tsss;
4857 gfc_se cse, tdse, tsse, edse, esse;
4858 gfc_loopinfo loop;
4859 gfc_ss *edss = 0;
4860 gfc_ss *esss = 0;
4862 /* Allow the scalarizer to workshare simple where loops. */
4863 if (ompws_flags & OMPWS_WORKSHARE_FLAG)
4864 ompws_flags |= OMPWS_SCALARIZER_WS;
4866 cond = cblock->expr1;
4867 tdst = cblock->next->expr1;
4868 tsrc = cblock->next->expr2;
4869 edst = eblock ? eblock->next->expr1 : NULL;
4870 esrc = eblock ? eblock->next->expr2 : NULL;
4872 gfc_start_block (&block);
4873 gfc_init_loopinfo (&loop);
4875 /* Handle the condition. */
4876 gfc_init_se (&cse, NULL);
4877 css = gfc_walk_expr (cond);
4878 gfc_add_ss_to_loop (&loop, css);
4880 /* Handle the then-clause. */
4881 gfc_init_se (&tdse, NULL);
4882 gfc_init_se (&tsse, NULL);
4883 tdss = gfc_walk_expr (tdst);
4884 tsss = gfc_walk_expr (tsrc);
4885 if (tsss == gfc_ss_terminator)
4887 tsss = gfc_get_scalar_ss (gfc_ss_terminator, tsrc);
4888 tsss->info->where = 1;
4890 gfc_add_ss_to_loop (&loop, tdss);
4891 gfc_add_ss_to_loop (&loop, tsss);
4893 if (eblock)
4895 /* Handle the else clause. */
4896 gfc_init_se (&edse, NULL);
4897 gfc_init_se (&esse, NULL);
4898 edss = gfc_walk_expr (edst);
4899 esss = gfc_walk_expr (esrc);
4900 if (esss == gfc_ss_terminator)
4902 esss = gfc_get_scalar_ss (gfc_ss_terminator, esrc);
4903 esss->info->where = 1;
4905 gfc_add_ss_to_loop (&loop, edss);
4906 gfc_add_ss_to_loop (&loop, esss);
4909 gfc_conv_ss_startstride (&loop);
4910 gfc_conv_loop_setup (&loop, &tdst->where);
4912 gfc_mark_ss_chain_used (css, 1);
4913 gfc_mark_ss_chain_used (tdss, 1);
4914 gfc_mark_ss_chain_used (tsss, 1);
4915 if (eblock)
4917 gfc_mark_ss_chain_used (edss, 1);
4918 gfc_mark_ss_chain_used (esss, 1);
4921 gfc_start_scalarized_body (&loop, &body);
4923 gfc_copy_loopinfo_to_se (&cse, &loop);
4924 gfc_copy_loopinfo_to_se (&tdse, &loop);
4925 gfc_copy_loopinfo_to_se (&tsse, &loop);
4926 cse.ss = css;
4927 tdse.ss = tdss;
4928 tsse.ss = tsss;
4929 if (eblock)
4931 gfc_copy_loopinfo_to_se (&edse, &loop);
4932 gfc_copy_loopinfo_to_se (&esse, &loop);
4933 edse.ss = edss;
4934 esse.ss = esss;
4937 gfc_conv_expr (&cse, cond);
4938 gfc_add_block_to_block (&body, &cse.pre);
4939 cexpr = cse.expr;
4941 gfc_conv_expr (&tsse, tsrc);
4942 if (tdss != gfc_ss_terminator && loop.temp_ss != NULL)
4943 gfc_conv_tmp_array_ref (&tdse);
4944 else
4945 gfc_conv_expr (&tdse, tdst);
4947 if (eblock)
4949 gfc_conv_expr (&esse, esrc);
4950 if (edss != gfc_ss_terminator && loop.temp_ss != NULL)
4951 gfc_conv_tmp_array_ref (&edse);
4952 else
4953 gfc_conv_expr (&edse, edst);
4956 tstmt = gfc_trans_scalar_assign (&tdse, &tsse, tdst->ts, false, false, true);
4957 estmt = eblock ? gfc_trans_scalar_assign (&edse, &esse, edst->ts, false,
4958 false, true)
4959 : build_empty_stmt (input_location);
4960 tmp = build3_v (COND_EXPR, cexpr, tstmt, estmt);
4961 gfc_add_expr_to_block (&body, tmp);
4962 gfc_add_block_to_block (&body, &cse.post);
4964 gfc_trans_scalarizing_loops (&loop, &body);
4965 gfc_add_block_to_block (&block, &loop.pre);
4966 gfc_add_block_to_block (&block, &loop.post);
4967 gfc_cleanup_loop (&loop);
4969 return gfc_finish_block (&block);
4972 /* As the WHERE or WHERE construct statement can be nested, we call
4973 gfc_trans_where_2 to do the translation, and pass the initial
4974 NULL values for both the control mask and the pending control mask. */
4976 tree
4977 gfc_trans_where (gfc_code * code)
4979 stmtblock_t block;
4980 gfc_code *cblock;
4981 gfc_code *eblock;
4983 cblock = code->block;
4984 if (cblock->next
4985 && cblock->next->op == EXEC_ASSIGN
4986 && !cblock->next->next)
4988 eblock = cblock->block;
4989 if (!eblock)
4991 /* A simple "WHERE (cond) x = y" statement or block is
4992 dependence free if cond is not dependent upon writing x,
4993 and the source y is unaffected by the destination x. */
4994 if (!gfc_check_dependency (cblock->next->expr1,
4995 cblock->expr1, 0)
4996 && !gfc_check_dependency (cblock->next->expr1,
4997 cblock->next->expr2, 0))
4998 return gfc_trans_where_3 (cblock, NULL);
5000 else if (!eblock->expr1
5001 && !eblock->block
5002 && eblock->next
5003 && eblock->next->op == EXEC_ASSIGN
5004 && !eblock->next->next)
5006 /* A simple "WHERE (cond) x1 = y1 ELSEWHERE x2 = y2 ENDWHERE"
5007 block is dependence free if cond is not dependent on writes
5008 to x1 and x2, y1 is not dependent on writes to x2, and y2
5009 is not dependent on writes to x1, and both y's are not
5010 dependent upon their own x's. In addition to this, the
5011 final two dependency checks below exclude all but the same
5012 array reference if the where and elswhere destinations
5013 are the same. In short, this is VERY conservative and this
5014 is needed because the two loops, required by the standard
5015 are coalesced in gfc_trans_where_3. */
5016 if (!gfc_check_dependency (cblock->next->expr1,
5017 cblock->expr1, 0)
5018 && !gfc_check_dependency (eblock->next->expr1,
5019 cblock->expr1, 0)
5020 && !gfc_check_dependency (cblock->next->expr1,
5021 eblock->next->expr2, 1)
5022 && !gfc_check_dependency (eblock->next->expr1,
5023 cblock->next->expr2, 1)
5024 && !gfc_check_dependency (cblock->next->expr1,
5025 cblock->next->expr2, 1)
5026 && !gfc_check_dependency (eblock->next->expr1,
5027 eblock->next->expr2, 1)
5028 && !gfc_check_dependency (cblock->next->expr1,
5029 eblock->next->expr1, 0)
5030 && !gfc_check_dependency (eblock->next->expr1,
5031 cblock->next->expr1, 0))
5032 return gfc_trans_where_3 (cblock, eblock);
5036 gfc_start_block (&block);
5038 gfc_trans_where_2 (code, NULL, false, NULL, &block);
5040 return gfc_finish_block (&block);
5044 /* CYCLE a DO loop. The label decl has already been created by
5045 gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
5046 node at the head of the loop. We must mark the label as used. */
5048 tree
5049 gfc_trans_cycle (gfc_code * code)
5051 tree cycle_label;
5053 cycle_label = code->ext.which_construct->cycle_label;
5054 gcc_assert (cycle_label);
5056 TREE_USED (cycle_label) = 1;
5057 return build1_v (GOTO_EXPR, cycle_label);
5061 /* EXIT a DO loop. Similar to CYCLE, but now the label is in
5062 TREE_VALUE (backend_decl) of the gfc_code node at the head of the
5063 loop. */
5065 tree
5066 gfc_trans_exit (gfc_code * code)
5068 tree exit_label;
5070 exit_label = code->ext.which_construct->exit_label;
5071 gcc_assert (exit_label);
5073 TREE_USED (exit_label) = 1;
5074 return build1_v (GOTO_EXPR, exit_label);
5078 /* Translate the ALLOCATE statement. */
5080 tree
5081 gfc_trans_allocate (gfc_code * code)
5083 gfc_alloc *al;
5084 gfc_expr *expr, *e3rhs = NULL;
5085 gfc_se se, se_sz;
5086 tree tmp;
5087 tree parm;
5088 tree stat;
5089 tree errmsg;
5090 tree errlen;
5091 tree label_errmsg;
5092 tree label_finish;
5093 tree memsz;
5094 tree al_vptr, al_len;
5095 /* If an expr3 is present, then store the tree for accessing its
5096 _vptr, and _len components in the variables, respectively. The
5097 element size, i.e. _vptr%size, is stored in expr3_esize. Any of
5098 the trees may be the NULL_TREE indicating that this is not
5099 available for expr3's type. */
5100 tree expr3, expr3_vptr, expr3_len, expr3_esize;
5101 stmtblock_t block;
5102 stmtblock_t post;
5103 tree nelems;
5104 bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set;
5105 gfc_symtree *newsym = NULL;
5107 if (!code->ext.alloc.list)
5108 return NULL_TREE;
5110 stat = tmp = memsz = al_vptr = al_len = NULL_TREE;
5111 expr3 = expr3_vptr = expr3_len = expr3_esize = NULL_TREE;
5112 label_errmsg = label_finish = errmsg = errlen = NULL_TREE;
5114 gfc_init_block (&block);
5115 gfc_init_block (&post);
5117 /* STAT= (and maybe ERRMSG=) is present. */
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;
5153 /* expr3_tmp gets the tree when code->expr3.mold is set, i.e.,
5154 the expression is only needed to get the _vptr, _len a.s.o. */
5155 tree expr3_tmp = NULL_TREE;
5157 /* Figure whether we need the vtab from expr3. */
5158 for (al = code->ext.alloc.list; !vtab_needed && al != NULL;
5159 al = al->next)
5160 vtab_needed = (al->expr->ts.type == BT_CLASS);
5162 /* When expr3 is a variable, i.e., a very simple expression,
5163 then convert it once here. */
5164 if (code->expr3->expr_type == EXPR_VARIABLE
5165 || code->expr3->expr_type == EXPR_ARRAY
5166 || code->expr3->expr_type == EXPR_CONSTANT)
5168 if (!code->expr3->mold
5169 || code->expr3->ts.type == BT_CHARACTER
5170 || vtab_needed)
5172 /* Convert expr3 to a tree. */
5173 gfc_init_se (&se, NULL);
5174 /* For all "simple" expression just get the descriptor or the
5175 reference, respectively, depending on the rank of the expr. */
5176 if (code->expr3->rank != 0)
5177 gfc_conv_expr_descriptor (&se, code->expr3);
5178 else
5179 gfc_conv_expr_reference (&se, code->expr3);
5180 if (!code->expr3->mold)
5181 expr3 = se.expr;
5182 else
5183 expr3_tmp = se.expr;
5184 expr3_len = se.string_length;
5185 gfc_add_block_to_block (&block, &se.pre);
5186 gfc_add_block_to_block (&post, &se.post);
5188 /* else expr3 = NULL_TREE set above. */
5190 else
5192 /* In all other cases evaluate the expr3 and create a
5193 temporary. */
5194 gfc_init_se (&se, NULL);
5195 symbol_attribute attr;
5196 /* Get the descriptor for all arrays, that are not allocatable or
5197 pointer, because the latter are descriptors already. */
5198 attr = gfc_expr_attr (code->expr3);
5199 if (code->expr3->rank != 0 && !attr.allocatable && !attr.pointer)
5200 gfc_conv_expr_descriptor (&se, code->expr3);
5201 else
5202 gfc_conv_expr_reference (&se, code->expr3);
5203 if (code->expr3->ts.type == BT_CLASS)
5204 gfc_conv_class_to_class (&se, code->expr3,
5205 code->expr3->ts,
5206 false, true,
5207 false, false);
5208 gfc_add_block_to_block (&block, &se.pre);
5209 gfc_add_block_to_block (&post, &se.post);
5211 /* Prevent aliasing, i.e., se.expr may be already a
5212 variable declaration. */
5213 if (!VAR_P (se.expr))
5215 tree var;
5216 tmp = build_fold_indirect_ref_loc (input_location,
5217 se.expr);
5218 /* We need a regular (non-UID) symbol here, therefore give a
5219 prefix. */
5220 var = gfc_create_var (TREE_TYPE (tmp), "source");
5221 gfc_add_modify_loc (input_location, &block, var, tmp);
5223 /* Deallocate any allocatable components after all the allocations
5224 and assignments of expr3 have been completed. */
5225 if (code->expr3->ts.type == BT_DERIVED
5226 && code->expr3->rank == 0
5227 && code->expr3->ts.u.derived->attr.alloc_comp)
5229 tmp = gfc_deallocate_alloc_comp (code->expr3->ts.u.derived,
5230 var, 0);
5231 gfc_add_expr_to_block (&post, tmp);
5234 tmp = var;
5236 else
5237 tmp = se.expr;
5238 if (!code->expr3->mold)
5239 expr3 = tmp;
5240 else
5241 expr3_tmp = tmp;
5242 /* When he length of a char array is easily available
5243 here, fix it for future use. */
5244 if (se.string_length)
5245 expr3_len = gfc_evaluate_now (se.string_length, &block);
5248 /* Figure how to get the _vtab entry. This also obtains the tree
5249 expression for accessing the _len component, because only
5250 unlimited polymorphic objects, which are a subcategory of class
5251 types, have a _len component. */
5252 if (code->expr3->ts.type == BT_CLASS)
5254 gfc_expr *rhs;
5255 /* Polymorphic SOURCE: VPTR must be determined at run time.
5256 expr3 may be a temporary array declaration, therefore check for
5257 GFC_CLASS_TYPE_P before trying to get the _vptr component. */
5258 if (expr3 != NULL_TREE && GFC_CLASS_TYPE_P (TREE_TYPE (expr3))
5259 && (VAR_P (expr3) || !code->expr3->ref))
5260 tmp = gfc_class_vptr_get (expr3);
5261 else if (expr3_tmp != NULL_TREE
5262 && GFC_CLASS_TYPE_P (TREE_TYPE (expr3_tmp))
5263 && (VAR_P (expr3_tmp) || !code->expr3->ref))
5264 tmp = gfc_class_vptr_get (expr3_tmp);
5265 else
5267 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
5268 gfc_add_vptr_component (rhs);
5269 gfc_init_se (&se, NULL);
5270 se.want_pointer = 1;
5271 gfc_conv_expr (&se, rhs);
5272 tmp = se.expr;
5273 gfc_free_expr (rhs);
5275 /* Set the element size. */
5276 expr3_esize = gfc_vptr_size_get (tmp);
5277 if (vtab_needed)
5278 expr3_vptr = tmp;
5279 /* Initialize the ref to the _len component. */
5280 if (expr3_len == NULL_TREE && UNLIMITED_POLY (code->expr3))
5282 /* Same like for retrieving the _vptr. */
5283 if (expr3 != NULL_TREE && !code->expr3->ref)
5284 expr3_len = gfc_class_len_get (expr3);
5285 else if (expr3_tmp != NULL_TREE && !code->expr3->ref)
5286 expr3_len = gfc_class_len_get (expr3_tmp);
5287 else
5289 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
5290 gfc_add_len_component (rhs);
5291 gfc_init_se (&se, NULL);
5292 gfc_conv_expr (&se, rhs);
5293 expr3_len = se.expr;
5294 gfc_free_expr (rhs);
5298 else
5300 /* When the object to allocate is polymorphic type, then it
5301 needs its vtab set correctly, so deduce the required _vtab
5302 and _len from the source expression. */
5303 if (vtab_needed)
5305 /* VPTR is fixed at compile time. */
5306 gfc_symbol *vtab;
5308 vtab = gfc_find_vtab (&code->expr3->ts);
5309 gcc_assert (vtab);
5310 expr3_vptr = gfc_get_symbol_decl (vtab);
5311 expr3_vptr = gfc_build_addr_expr (NULL_TREE,
5312 expr3_vptr);
5314 /* _len component needs to be set, when ts is a character
5315 array. */
5316 if (expr3_len == NULL_TREE
5317 && code->expr3->ts.type == BT_CHARACTER)
5319 if (code->expr3->ts.u.cl
5320 && code->expr3->ts.u.cl->length)
5322 gfc_init_se (&se, NULL);
5323 gfc_conv_expr (&se, code->expr3->ts.u.cl->length);
5324 gfc_add_block_to_block (&block, &se.pre);
5325 expr3_len = gfc_evaluate_now (se.expr, &block);
5327 gcc_assert (expr3_len);
5329 /* For character arrays only the kind's size is needed, because
5330 the array mem_size is _len * (elem_size = kind_size).
5331 For all other get the element size in the normal way. */
5332 if (code->expr3->ts.type == BT_CHARACTER)
5333 expr3_esize = TYPE_SIZE_UNIT (
5334 gfc_get_char_type (code->expr3->ts.kind));
5335 else
5336 expr3_esize = TYPE_SIZE_UNIT (
5337 gfc_typenode_for_spec (&code->expr3->ts));
5339 /* The routine gfc_trans_assignment () already implements all
5340 techniques needed. Unfortunately we may have a temporary
5341 variable for the source= expression here. When that is the
5342 case convert this variable into a temporary gfc_expr of type
5343 EXPR_VARIABLE and used it as rhs for the assignment. The
5344 advantage is, that we get scalarizer support for free,
5345 don't have to take care about scalar to array treatment and
5346 will benefit of every enhancements gfc_trans_assignment ()
5347 gets. */
5348 if (expr3 != NULL_TREE && DECL_P (expr3) && DECL_ARTIFICIAL (expr3))
5350 /* Build a temporary symtree and symbol. Do not add it to
5351 the current namespace to prevent accidently modifying
5352 a colliding symbol's as. */
5353 newsym = XCNEW (gfc_symtree);
5354 /* The name of the symtree should be unique, because
5355 gfc_create_var () took care about generating the
5356 identifier. */
5357 newsym->name = gfc_get_string (IDENTIFIER_POINTER (
5358 DECL_NAME (expr3)));
5359 newsym->n.sym = gfc_new_symbol (newsym->name, NULL);
5360 /* The backend_decl is known. It is expr3, which is inserted
5361 here. */
5362 newsym->n.sym->backend_decl = expr3;
5363 e3rhs = gfc_get_expr ();
5364 e3rhs->ts = code->expr3->ts;
5365 e3rhs->rank = code->expr3->rank;
5366 e3rhs->symtree = newsym;
5367 /* Mark the symbol referenced or gfc_trans_assignment will
5368 bug. */
5369 newsym->n.sym->attr.referenced = 1;
5370 e3rhs->expr_type = EXPR_VARIABLE;
5371 e3rhs->where = code->expr3->where;
5372 /* Set the symbols type, upto it was BT_UNKNOWN. */
5373 newsym->n.sym->ts = e3rhs->ts;
5374 /* Check whether the expr3 is array valued. */
5375 if (e3rhs->rank)
5377 gfc_array_spec *arr;
5378 arr = gfc_get_array_spec ();
5379 arr->rank = e3rhs->rank;
5380 arr->type = AS_DEFERRED;
5381 /* Set the dimension and pointer attribute for arrays
5382 to be on the safe side. */
5383 newsym->n.sym->attr.dimension = 1;
5384 newsym->n.sym->attr.pointer = 1;
5385 newsym->n.sym->as = arr;
5386 gfc_add_full_array_ref (e3rhs, arr);
5388 else if (POINTER_TYPE_P (TREE_TYPE (expr3)))
5389 newsym->n.sym->attr.pointer = 1;
5390 /* The string length is known to. Set it for char arrays. */
5391 if (e3rhs->ts.type == BT_CHARACTER)
5392 newsym->n.sym->ts.u.cl->backend_decl = expr3_len;
5393 gfc_commit_symbol (newsym->n.sym);
5395 else
5396 e3rhs = gfc_copy_expr (code->expr3);
5398 gcc_assert (expr3_esize);
5399 expr3_esize = fold_convert (sizetype, expr3_esize);
5401 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
5403 /* Compute the explicit typespec given only once for all objects
5404 to allocate. */
5405 if (code->ext.alloc.ts.type != BT_CHARACTER)
5406 expr3_esize = TYPE_SIZE_UNIT (
5407 gfc_typenode_for_spec (&code->ext.alloc.ts));
5408 else
5410 gfc_expr *sz;
5411 gcc_assert (code->ext.alloc.ts.u.cl->length != NULL);
5412 sz = gfc_copy_expr (code->ext.alloc.ts.u.cl->length);
5413 gfc_init_se (&se_sz, NULL);
5414 gfc_conv_expr (&se_sz, sz);
5415 gfc_free_expr (sz);
5416 tmp = gfc_get_char_type (code->ext.alloc.ts.kind);
5417 tmp = TYPE_SIZE_UNIT (tmp);
5418 tmp = fold_convert (TREE_TYPE (se_sz.expr), tmp);
5419 expr3_esize = fold_build2_loc (input_location, MULT_EXPR,
5420 TREE_TYPE (se_sz.expr),
5421 tmp, se_sz.expr);
5425 /* Loop over all objects to allocate. */
5426 for (al = code->ext.alloc.list; al != NULL; al = al->next)
5428 expr = gfc_copy_expr (al->expr);
5429 /* UNLIMITED_POLY () needs the _data component to be set, when
5430 expr is a unlimited polymorphic object. But the _data component
5431 has not been set yet, so check the derived type's attr for the
5432 unlimited polymorphic flag to be safe. */
5433 upoly_expr = UNLIMITED_POLY (expr)
5434 || (expr->ts.type == BT_DERIVED
5435 && expr->ts.u.derived->attr.unlimited_polymorphic);
5436 gfc_init_se (&se, NULL);
5438 /* For class types prepare the expressions to ref the _vptr
5439 and the _len component. The latter for unlimited polymorphic
5440 types only. */
5441 if (expr->ts.type == BT_CLASS)
5443 gfc_expr *expr_ref_vptr, *expr_ref_len;
5444 gfc_add_data_component (expr);
5445 /* Prep the vptr handle. */
5446 expr_ref_vptr = gfc_copy_expr (al->expr);
5447 gfc_add_vptr_component (expr_ref_vptr);
5448 se.want_pointer = 1;
5449 gfc_conv_expr (&se, expr_ref_vptr);
5450 al_vptr = se.expr;
5451 se.want_pointer = 0;
5452 gfc_free_expr (expr_ref_vptr);
5453 /* Allocated unlimited polymorphic objects always have a _len
5454 component. */
5455 if (upoly_expr)
5457 expr_ref_len = gfc_copy_expr (al->expr);
5458 gfc_add_len_component (expr_ref_len);
5459 gfc_conv_expr (&se, expr_ref_len);
5460 al_len = se.expr;
5461 gfc_free_expr (expr_ref_len);
5463 else
5464 /* In a loop ensure that all loop variable dependent variables
5465 are initialized at the same spot in all execution paths. */
5466 al_len = NULL_TREE;
5468 else
5469 al_vptr = al_len = NULL_TREE;
5471 se.want_pointer = 1;
5472 se.descriptor_only = 1;
5473 gfc_conv_expr (&se, expr);
5474 if (expr->ts.type == BT_CHARACTER && expr->ts.deferred)
5475 /* se.string_length now stores the .string_length variable of expr
5476 needed to allocate character(len=:) arrays. */
5477 al_len = se.string_length;
5479 al_len_needs_set = al_len != NULL_TREE;
5480 /* When allocating an array one can not use much of the
5481 pre-evaluated expr3 expressions, because for most of them the
5482 scalarizer is needed which is not available in the pre-evaluation
5483 step. Therefore gfc_array_allocate () is responsible (and able)
5484 to handle the complete array allocation. Only the element size
5485 needs to be provided, which is done most of the time by the
5486 pre-evaluation step. */
5487 nelems = NULL_TREE;
5488 if (expr3_len && code->expr3->ts.type == BT_CHARACTER)
5489 /* When al is an array, then the element size for each element
5490 in the array is needed, which is the product of the len and
5491 esize for char arrays. */
5492 tmp = fold_build2_loc (input_location, MULT_EXPR,
5493 TREE_TYPE (expr3_esize), expr3_esize,
5494 fold_convert (TREE_TYPE (expr3_esize),
5495 expr3_len));
5496 else
5497 tmp = expr3_esize;
5498 if (!gfc_array_allocate (&se, expr, stat, errmsg, errlen,
5499 label_finish, tmp, &nelems, code->expr3))
5501 /* A scalar or derived type. First compute the size to
5502 allocate.
5504 expr3_len is set when expr3 is an unlimited polymorphic
5505 object or a deferred length string. */
5506 if (expr3_len != NULL_TREE)
5508 tmp = fold_convert (TREE_TYPE (expr3_esize), expr3_len);
5509 tmp = fold_build2_loc (input_location, MULT_EXPR,
5510 TREE_TYPE (expr3_esize),
5511 expr3_esize, tmp);
5512 if (code->expr3->ts.type != BT_CLASS)
5513 /* expr3 is a deferred length string, i.e., we are
5514 done. */
5515 memsz = tmp;
5516 else
5518 /* For unlimited polymorphic enties build
5519 (len > 0) ? element_size * len : element_size
5520 to compute the number of bytes to allocate.
5521 This allows the allocation of unlimited polymorphic
5522 objects from an expr3 that is also unlimited
5523 polymorphic and stores a _len dependent object,
5524 e.g., a string. */
5525 memsz = fold_build2_loc (input_location, GT_EXPR,
5526 boolean_type_node, expr3_len,
5527 integer_zero_node);
5528 memsz = fold_build3_loc (input_location, COND_EXPR,
5529 TREE_TYPE (expr3_esize),
5530 memsz, tmp, expr3_esize);
5533 else if (expr3_esize != NULL_TREE)
5534 /* Any other object in expr3 just needs element size in
5535 bytes. */
5536 memsz = expr3_esize;
5537 else if ((expr->ts.type == BT_CHARACTER && expr->ts.deferred)
5538 || (upoly_expr
5539 && code->ext.alloc.ts.type == BT_CHARACTER))
5541 /* Allocating deferred length char arrays need the length
5542 to allocate in the alloc_type_spec. But also unlimited
5543 polymorphic objects may be allocated as char arrays.
5544 Both are handled here. */
5545 gfc_init_se (&se_sz, NULL);
5546 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
5547 gfc_add_block_to_block (&se.pre, &se_sz.pre);
5548 se_sz.expr = gfc_evaluate_now (se_sz.expr, &se.pre);
5549 gfc_add_block_to_block (&se.pre, &se_sz.post);
5550 expr3_len = se_sz.expr;
5551 tmp_expr3_len_flag = true;
5552 tmp = TYPE_SIZE_UNIT (
5553 gfc_get_char_type (code->ext.alloc.ts.kind));
5554 memsz = fold_build2_loc (input_location, MULT_EXPR,
5555 TREE_TYPE (tmp),
5556 fold_convert (TREE_TYPE (tmp),
5557 expr3_len),
5558 tmp);
5560 else if (expr->ts.type == BT_CHARACTER)
5562 /* Compute the number of bytes needed to allocate a fixed
5563 length char array. */
5564 gcc_assert (se.string_length != NULL_TREE);
5565 tmp = TYPE_SIZE_UNIT (gfc_get_char_type (expr->ts.kind));
5566 memsz = fold_build2_loc (input_location, MULT_EXPR,
5567 TREE_TYPE (tmp), tmp,
5568 fold_convert (TREE_TYPE (tmp),
5569 se.string_length));
5571 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
5572 /* Handle all types, where the alloc_type_spec is set. */
5573 memsz = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->ext.alloc.ts));
5574 else
5575 /* Handle size computation of the type declared to alloc. */
5576 memsz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
5578 /* Allocate - for non-pointers with re-alloc checking. */
5579 if (gfc_expr_attr (expr).allocatable)
5580 gfc_allocate_allocatable (&se.pre, se.expr, memsz, NULL_TREE,
5581 stat, errmsg, errlen, label_finish,
5582 expr);
5583 else
5584 gfc_allocate_using_malloc (&se.pre, se.expr, memsz, stat);
5586 if (al->expr->ts.type == BT_DERIVED
5587 && expr->ts.u.derived->attr.alloc_comp)
5589 tmp = build_fold_indirect_ref_loc (input_location, se.expr);
5590 tmp = gfc_nullify_alloc_comp (expr->ts.u.derived, tmp, 0);
5591 gfc_add_expr_to_block (&se.pre, tmp);
5594 else
5596 if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
5597 && expr3_len != NULL_TREE)
5599 /* Arrays need to have a _len set before the array
5600 descriptor is filled. */
5601 gfc_add_modify (&block, al_len,
5602 fold_convert (TREE_TYPE (al_len), expr3_len));
5603 /* Prevent setting the length twice. */
5604 al_len_needs_set = false;
5608 gfc_add_block_to_block (&block, &se.pre);
5610 /* Error checking -- Note: ERRMSG only makes sense with STAT. */
5611 if (code->expr1)
5613 tmp = build1_v (GOTO_EXPR, label_errmsg);
5614 parm = fold_build2_loc (input_location, NE_EXPR,
5615 boolean_type_node, stat,
5616 build_int_cst (TREE_TYPE (stat), 0));
5617 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
5618 gfc_unlikely (parm, PRED_FORTRAN_FAIL_ALLOC),
5619 tmp, build_empty_stmt (input_location));
5620 gfc_add_expr_to_block (&block, tmp);
5623 /* Set the vptr. */
5624 if (al_vptr != NULL_TREE)
5626 if (expr3_vptr != NULL_TREE)
5627 /* The vtab is already known, so just assign it. */
5628 gfc_add_modify (&block, al_vptr,
5629 fold_convert (TREE_TYPE (al_vptr), expr3_vptr));
5630 else
5632 /* VPTR is fixed at compile time. */
5633 gfc_symbol *vtab;
5634 gfc_typespec *ts;
5636 if (code->expr3)
5637 /* Although expr3 is pre-evaluated above, it may happen,
5638 that for arrays or in mold= cases the pre-evaluation
5639 was not successful. In these rare cases take the vtab
5640 from the typespec of expr3 here. */
5641 ts = &code->expr3->ts;
5642 else if (code->ext.alloc.ts.type == BT_DERIVED || upoly_expr)
5643 /* The alloc_type_spec gives the type to allocate or the
5644 al is unlimited polymorphic, which enforces the use of
5645 an alloc_type_spec that is not necessarily a BT_DERIVED. */
5646 ts = &code->ext.alloc.ts;
5647 else
5648 /* Prepare for setting the vtab as declared. */
5649 ts = &expr->ts;
5651 vtab = gfc_find_vtab (ts);
5652 gcc_assert (vtab);
5653 tmp = gfc_build_addr_expr (NULL_TREE,
5654 gfc_get_symbol_decl (vtab));
5655 gfc_add_modify (&block, al_vptr,
5656 fold_convert (TREE_TYPE (al_vptr), tmp));
5660 /* Add assignment for string length. */
5661 if (al_len != NULL_TREE && al_len_needs_set)
5663 if (expr3_len != NULL_TREE)
5665 gfc_add_modify (&block, al_len,
5666 fold_convert (TREE_TYPE (al_len),
5667 expr3_len));
5668 /* When tmp_expr3_len_flag is set, then expr3_len is
5669 abused to carry the length information from the
5670 alloc_type. Clear it to prevent setting incorrect len
5671 information in future loop iterations. */
5672 if (tmp_expr3_len_flag)
5673 /* No need to reset tmp_expr3_len_flag, because the
5674 presence of an expr3 can not change within in the
5675 loop. */
5676 expr3_len = NULL_TREE;
5678 else if (code->ext.alloc.ts.type == BT_CHARACTER
5679 && code->ext.alloc.ts.u.cl->length)
5681 /* Cover the cases where a string length is explicitly
5682 specified by a type spec for deferred length character
5683 arrays or unlimited polymorphic objects without a
5684 source= or mold= expression. */
5685 gfc_init_se (&se_sz, NULL);
5686 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
5687 gfc_add_modify (&block, al_len,
5688 fold_convert (TREE_TYPE (al_len),
5689 se_sz.expr));
5691 else
5692 /* No length information needed, because type to allocate
5693 has no length. Set _len to 0. */
5694 gfc_add_modify (&block, al_len,
5695 fold_convert (TREE_TYPE (al_len),
5696 integer_zero_node));
5698 if (code->expr3 && !code->expr3->mold)
5700 /* Initialization via SOURCE block (or static default initializer).
5701 Classes need some special handling, so catch them first. */
5702 if (expr3 != NULL_TREE
5703 && ((POINTER_TYPE_P (TREE_TYPE (expr3))
5704 && TREE_CODE (expr3) != POINTER_PLUS_EXPR)
5705 || (VAR_P (expr3) && GFC_CLASS_TYPE_P (TREE_TYPE (expr3))))
5706 && code->expr3->ts.type == BT_CLASS
5707 && (expr->ts.type == BT_CLASS
5708 || expr->ts.type == BT_DERIVED))
5710 tree to;
5711 to = VAR_P (se.expr) ? se.expr : TREE_OPERAND (se.expr, 0);
5712 tmp = gfc_copy_class_to_class (expr3, to,
5713 nelems, upoly_expr);
5715 else if (al->expr->ts.type == BT_CLASS)
5717 gfc_actual_arglist *actual, *last_arg;
5718 gfc_expr *ppc;
5719 gfc_code *ppc_code;
5720 gfc_ref *ref, *dataref;
5721 gfc_expr *rhs = gfc_copy_expr (code->expr3);
5723 /* Do a polymorphic deep copy. */
5724 actual = gfc_get_actual_arglist ();
5725 actual->expr = gfc_copy_expr (rhs);
5726 if (rhs->ts.type == BT_CLASS)
5727 gfc_add_data_component (actual->expr);
5728 last_arg = actual->next = gfc_get_actual_arglist ();
5729 last_arg->expr = gfc_copy_expr (al->expr);
5730 last_arg->expr->ts.type = BT_CLASS;
5731 gfc_add_data_component (last_arg->expr);
5733 dataref = NULL;
5734 /* Make sure we go up through the reference chain to
5735 the _data reference, where the arrayspec is found. */
5736 for (ref = last_arg->expr->ref; ref; ref = ref->next)
5737 if (ref->type == REF_COMPONENT
5738 && strcmp (ref->u.c.component->name, "_data") == 0)
5739 dataref = ref;
5741 if (dataref && dataref->u.c.component->as)
5743 int dim;
5744 gfc_expr *temp;
5745 gfc_ref *ref = dataref->next;
5746 ref->u.ar.type = AR_SECTION;
5747 /* We have to set up the array reference to give ranges
5748 in all dimensions and ensure that the end and stride
5749 are set so that the copy can be scalarized. */
5750 dim = 0;
5751 for (; dim < dataref->u.c.component->as->rank; dim++)
5753 ref->u.ar.dimen_type[dim] = DIMEN_RANGE;
5754 if (ref->u.ar.end[dim] == NULL)
5756 ref->u.ar.end[dim] = ref->u.ar.start[dim];
5757 temp = gfc_get_int_expr (gfc_default_integer_kind,
5758 &al->expr->where, 1);
5759 ref->u.ar.start[dim] = temp;
5761 temp = gfc_subtract (gfc_copy_expr (ref->u.ar.end[dim]),
5762 gfc_copy_expr (ref->u.ar.start[dim]));
5763 temp = gfc_add (gfc_get_int_expr (gfc_default_integer_kind,
5764 &al->expr->where, 1),
5765 temp);
5768 if (rhs->ts.type == BT_CLASS)
5770 if (rhs->ref)
5771 ppc = gfc_find_and_cut_at_last_class_ref (rhs);
5772 else
5773 ppc = gfc_copy_expr (rhs);
5774 gfc_add_vptr_component (ppc);
5776 else
5777 ppc = gfc_lval_expr_from_sym (gfc_find_vtab (&rhs->ts));
5778 gfc_add_component_ref (ppc, "_copy");
5780 ppc_code = gfc_get_code (EXEC_CALL);
5781 ppc_code->resolved_sym = ppc->symtree->n.sym;
5782 ppc_code->loc = al->expr->where;
5783 /* Although '_copy' is set to be elemental in class.c, it is
5784 not staying that way. Find out why, sometime.... */
5785 ppc_code->resolved_sym->attr.elemental = 1;
5786 ppc_code->ext.actual = actual;
5787 ppc_code->expr1 = ppc;
5788 /* Since '_copy' is elemental, the scalarizer will take care
5789 of arrays in gfc_trans_call. */
5790 tmp = gfc_trans_call (ppc_code, true, NULL, NULL, false);
5791 /* We need to add the
5792 if (al_len > 0)
5793 al_vptr->copy (expr3_data, al_data, expr3_len, al_len);
5794 else
5795 al_vptr->copy (expr3_data, al_data);
5796 block, because al is unlimited polymorphic or a deferred
5797 length char array, whose copy routine needs the array lengths
5798 as third and fourth arguments. */
5799 if (al_len && UNLIMITED_POLY (code->expr3))
5801 tree stdcopy, extcopy;
5802 /* Add al%_len. */
5803 last_arg->next = gfc_get_actual_arglist ();
5804 last_arg = last_arg->next;
5805 last_arg->expr = gfc_find_and_cut_at_last_class_ref (
5806 al->expr);
5807 gfc_add_len_component (last_arg->expr);
5808 /* Add expr3's length. */
5809 last_arg->next = gfc_get_actual_arglist ();
5810 last_arg = last_arg->next;
5811 if (code->expr3->ts.type == BT_CLASS)
5813 last_arg->expr =
5814 gfc_find_and_cut_at_last_class_ref (code->expr3);
5815 gfc_add_len_component (last_arg->expr);
5817 else if (code->expr3->ts.type == BT_CHARACTER)
5818 last_arg->expr =
5819 gfc_copy_expr (code->expr3->ts.u.cl->length);
5820 else
5821 gcc_unreachable ();
5823 stdcopy = tmp;
5824 extcopy = gfc_trans_call (ppc_code, true, NULL, NULL, false);
5826 tmp = fold_build2_loc (input_location, GT_EXPR,
5827 boolean_type_node, expr3_len,
5828 integer_zero_node);
5829 tmp = fold_build3_loc (input_location, COND_EXPR,
5830 void_type_node, tmp, extcopy, stdcopy);
5832 gfc_free_statements (ppc_code);
5833 gfc_free_expr (rhs);
5835 else
5837 /* Switch off automatic reallocation since we have just
5838 done the ALLOCATE. */
5839 int realloc_lhs = flag_realloc_lhs;
5840 flag_realloc_lhs = 0;
5841 tmp = gfc_trans_assignment (gfc_expr_to_initialize (expr),
5842 e3rhs, false, false);
5843 flag_realloc_lhs = realloc_lhs;
5845 gfc_add_expr_to_block (&block, tmp);
5847 else if (code->expr3 && code->expr3->mold
5848 && code->expr3->ts.type == BT_CLASS)
5850 /* Since the _vptr has already been assigned to the allocate
5851 object, we can use gfc_copy_class_to_class in its
5852 initialization mode. */
5853 tmp = TREE_OPERAND (se.expr, 0);
5854 tmp = gfc_copy_class_to_class (NULL_TREE, tmp, nelems,
5855 upoly_expr);
5856 gfc_add_expr_to_block (&block, tmp);
5859 gfc_free_expr (expr);
5860 } // for-loop
5862 if (e3rhs)
5864 if (newsym)
5866 gfc_free_symbol (newsym->n.sym);
5867 XDELETE (newsym);
5869 gfc_free_expr (e3rhs);
5871 /* STAT. */
5872 if (code->expr1)
5874 tmp = build1_v (LABEL_EXPR, label_errmsg);
5875 gfc_add_expr_to_block (&block, tmp);
5878 /* ERRMSG - only useful if STAT is present. */
5879 if (code->expr1 && code->expr2)
5881 const char *msg = "Attempt to allocate an allocated object";
5882 tree slen, dlen, errmsg_str;
5883 stmtblock_t errmsg_block;
5885 gfc_init_block (&errmsg_block);
5887 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
5888 gfc_add_modify (&errmsg_block, errmsg_str,
5889 gfc_build_addr_expr (pchar_type_node,
5890 gfc_build_localized_cstring_const (msg)));
5892 slen = build_int_cst (gfc_charlen_type_node, ((int) strlen (msg)));
5893 dlen = gfc_get_expr_charlen (code->expr2);
5894 slen = fold_build2_loc (input_location, MIN_EXPR,
5895 TREE_TYPE (slen), dlen, slen);
5897 gfc_trans_string_copy (&errmsg_block, dlen, errmsg,
5898 code->expr2->ts.kind,
5899 slen, errmsg_str,
5900 gfc_default_character_kind);
5901 dlen = gfc_finish_block (&errmsg_block);
5903 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5904 stat, build_int_cst (TREE_TYPE (stat), 0));
5906 tmp = build3_v (COND_EXPR, tmp,
5907 dlen, build_empty_stmt (input_location));
5909 gfc_add_expr_to_block (&block, tmp);
5912 /* STAT block. */
5913 if (code->expr1)
5915 if (TREE_USED (label_finish))
5917 tmp = build1_v (LABEL_EXPR, label_finish);
5918 gfc_add_expr_to_block (&block, tmp);
5921 gfc_init_se (&se, NULL);
5922 gfc_conv_expr_lhs (&se, code->expr1);
5923 tmp = convert (TREE_TYPE (se.expr), stat);
5924 gfc_add_modify (&block, se.expr, tmp);
5927 gfc_add_block_to_block (&block, &se.post);
5928 gfc_add_block_to_block (&block, &post);
5930 return gfc_finish_block (&block);
5934 /* Translate a DEALLOCATE statement. */
5936 tree
5937 gfc_trans_deallocate (gfc_code *code)
5939 gfc_se se;
5940 gfc_alloc *al;
5941 tree apstat, pstat, stat, errmsg, errlen, tmp;
5942 tree label_finish, label_errmsg;
5943 stmtblock_t block;
5945 pstat = apstat = stat = errmsg = errlen = tmp = NULL_TREE;
5946 label_finish = label_errmsg = NULL_TREE;
5948 gfc_start_block (&block);
5950 /* Count the number of failed deallocations. If deallocate() was
5951 called with STAT= , then set STAT to the count. If deallocate
5952 was called with ERRMSG, then set ERRMG to a string. */
5953 if (code->expr1)
5955 tree gfc_int4_type_node = gfc_get_int_type (4);
5957 stat = gfc_create_var (gfc_int4_type_node, "stat");
5958 pstat = gfc_build_addr_expr (NULL_TREE, stat);
5960 /* GOTO destinations. */
5961 label_errmsg = gfc_build_label_decl (NULL_TREE);
5962 label_finish = gfc_build_label_decl (NULL_TREE);
5963 TREE_USED (label_finish) = 0;
5966 /* Set ERRMSG - only needed if STAT is available. */
5967 if (code->expr1 && code->expr2)
5969 gfc_init_se (&se, NULL);
5970 se.want_pointer = 1;
5971 gfc_conv_expr_lhs (&se, code->expr2);
5972 errmsg = se.expr;
5973 errlen = se.string_length;
5976 for (al = code->ext.alloc.list; al != NULL; al = al->next)
5978 gfc_expr *expr = gfc_copy_expr (al->expr);
5979 gcc_assert (expr->expr_type == EXPR_VARIABLE);
5981 if (expr->ts.type == BT_CLASS)
5982 gfc_add_data_component (expr);
5984 gfc_init_se (&se, NULL);
5985 gfc_start_block (&se.pre);
5987 se.want_pointer = 1;
5988 se.descriptor_only = 1;
5989 gfc_conv_expr (&se, expr);
5991 if (expr->rank || gfc_is_coarray (expr))
5993 gfc_ref *ref;
5995 if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->attr.alloc_comp
5996 && !gfc_is_finalizable (expr->ts.u.derived, NULL))
5998 gfc_ref *last = NULL;
6000 for (ref = expr->ref; ref; ref = ref->next)
6001 if (ref->type == REF_COMPONENT)
6002 last = ref;
6004 /* Do not deallocate the components of a derived type
6005 ultimate pointer component. */
6006 if (!(last && last->u.c.component->attr.pointer)
6007 && !(!last && expr->symtree->n.sym->attr.pointer))
6009 tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, se.expr,
6010 expr->rank);
6011 gfc_add_expr_to_block (&se.pre, tmp);
6015 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
6017 tmp = gfc_array_deallocate (se.expr, pstat, errmsg, errlen,
6018 label_finish, expr);
6019 gfc_add_expr_to_block (&se.pre, tmp);
6021 else if (TREE_CODE (se.expr) == COMPONENT_REF
6022 && TREE_CODE (TREE_TYPE (se.expr)) == ARRAY_TYPE
6023 && TREE_CODE (TREE_TYPE (TREE_TYPE (se.expr)))
6024 == RECORD_TYPE)
6026 /* class.c(finalize_component) generates these, when a
6027 finalizable entity has a non-allocatable derived type array
6028 component, which has allocatable components. Obtain the
6029 derived type of the array and deallocate the allocatable
6030 components. */
6031 for (ref = expr->ref; ref; ref = ref->next)
6033 if (ref->u.c.component->attr.dimension
6034 && ref->u.c.component->ts.type == BT_DERIVED)
6035 break;
6038 if (ref && ref->u.c.component->ts.u.derived->attr.alloc_comp
6039 && !gfc_is_finalizable (ref->u.c.component->ts.u.derived,
6040 NULL))
6042 tmp = gfc_deallocate_alloc_comp
6043 (ref->u.c.component->ts.u.derived,
6044 se.expr, expr->rank);
6045 gfc_add_expr_to_block (&se.pre, tmp);
6049 if (al->expr->ts.type == BT_CLASS)
6051 gfc_reset_vptr (&se.pre, al->expr);
6052 if (UNLIMITED_POLY (al->expr)
6053 || (al->expr->ts.type == BT_DERIVED
6054 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6055 /* Clear _len, too. */
6056 gfc_reset_len (&se.pre, al->expr);
6059 else
6061 tmp = gfc_deallocate_scalar_with_status (se.expr, pstat, false,
6062 al->expr, al->expr->ts);
6063 gfc_add_expr_to_block (&se.pre, tmp);
6065 /* Set to zero after deallocation. */
6066 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
6067 se.expr,
6068 build_int_cst (TREE_TYPE (se.expr), 0));
6069 gfc_add_expr_to_block (&se.pre, tmp);
6071 if (al->expr->ts.type == BT_CLASS)
6073 gfc_reset_vptr (&se.pre, al->expr);
6074 if (UNLIMITED_POLY (al->expr)
6075 || (al->expr->ts.type == BT_DERIVED
6076 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6077 /* Clear _len, too. */
6078 gfc_reset_len (&se.pre, al->expr);
6082 if (code->expr1)
6084 tree cond;
6086 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, stat,
6087 build_int_cst (TREE_TYPE (stat), 0));
6088 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6089 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
6090 build1_v (GOTO_EXPR, label_errmsg),
6091 build_empty_stmt (input_location));
6092 gfc_add_expr_to_block (&se.pre, tmp);
6095 tmp = gfc_finish_block (&se.pre);
6096 gfc_add_expr_to_block (&block, tmp);
6097 gfc_free_expr (expr);
6100 if (code->expr1)
6102 tmp = build1_v (LABEL_EXPR, label_errmsg);
6103 gfc_add_expr_to_block (&block, tmp);
6106 /* Set ERRMSG - only needed if STAT is available. */
6107 if (code->expr1 && code->expr2)
6109 const char *msg = "Attempt to deallocate an unallocated object";
6110 stmtblock_t errmsg_block;
6111 tree errmsg_str, slen, dlen, cond;
6113 gfc_init_block (&errmsg_block);
6115 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6116 gfc_add_modify (&errmsg_block, errmsg_str,
6117 gfc_build_addr_expr (pchar_type_node,
6118 gfc_build_localized_cstring_const (msg)));
6119 slen = build_int_cst (gfc_charlen_type_node, ((int) strlen (msg)));
6120 dlen = gfc_get_expr_charlen (code->expr2);
6122 gfc_trans_string_copy (&errmsg_block, dlen, errmsg, code->expr2->ts.kind,
6123 slen, errmsg_str, gfc_default_character_kind);
6124 tmp = gfc_finish_block (&errmsg_block);
6126 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, stat,
6127 build_int_cst (TREE_TYPE (stat), 0));
6128 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6129 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC), tmp,
6130 build_empty_stmt (input_location));
6132 gfc_add_expr_to_block (&block, tmp);
6135 if (code->expr1 && TREE_USED (label_finish))
6137 tmp = build1_v (LABEL_EXPR, label_finish);
6138 gfc_add_expr_to_block (&block, tmp);
6141 /* Set STAT. */
6142 if (code->expr1)
6144 gfc_init_se (&se, NULL);
6145 gfc_conv_expr_lhs (&se, code->expr1);
6146 tmp = convert (TREE_TYPE (se.expr), stat);
6147 gfc_add_modify (&block, se.expr, tmp);
6150 return gfc_finish_block (&block);
6153 #include "gt-fortran-trans-stmt.h"