Daily bump.
[official-gcc.git] / gcc / fortran / trans-stmt.c
blob54b56c4f01d036b9f71bb2a0f3790c0594eabaae
1 /* Statement translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2002-2020 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "options.h"
27 #include "tree.h"
28 #include "gfortran.h"
29 #include "trans.h"
30 #include "stringpool.h"
31 #include "fold-const.h"
32 #include "trans-stmt.h"
33 #include "trans-types.h"
34 #include "trans-array.h"
35 #include "trans-const.h"
36 #include "dependency.h"
38 typedef struct iter_info
40 tree var;
41 tree start;
42 tree end;
43 tree step;
44 struct iter_info *next;
46 iter_info;
48 typedef struct forall_info
50 iter_info *this_loop;
51 tree mask;
52 tree maskindex;
53 int nvar;
54 tree size;
55 struct forall_info *prev_nest;
56 bool do_concurrent;
58 forall_info;
60 static void gfc_trans_where_2 (gfc_code *, tree, bool,
61 forall_info *, stmtblock_t *);
63 /* Translate a F95 label number to a LABEL_EXPR. */
65 tree
66 gfc_trans_label_here (gfc_code * code)
68 return build1_v (LABEL_EXPR, gfc_get_label_decl (code->here));
72 /* Given a variable expression which has been ASSIGNed to, find the decl
73 containing the auxiliary variables. For variables in common blocks this
74 is a field_decl. */
76 void
77 gfc_conv_label_variable (gfc_se * se, gfc_expr * expr)
79 gcc_assert (expr->symtree->n.sym->attr.assign == 1);
80 gfc_conv_expr (se, expr);
81 /* Deals with variable in common block. Get the field declaration. */
82 if (TREE_CODE (se->expr) == COMPONENT_REF)
83 se->expr = TREE_OPERAND (se->expr, 1);
84 /* Deals with dummy argument. Get the parameter declaration. */
85 else if (TREE_CODE (se->expr) == INDIRECT_REF)
86 se->expr = TREE_OPERAND (se->expr, 0);
89 /* Translate a label assignment statement. */
91 tree
92 gfc_trans_label_assign (gfc_code * code)
94 tree label_tree;
95 gfc_se se;
96 tree len;
97 tree addr;
98 tree len_tree;
99 int label_len;
101 /* Start a new block. */
102 gfc_init_se (&se, NULL);
103 gfc_start_block (&se.pre);
104 gfc_conv_label_variable (&se, code->expr1);
106 len = GFC_DECL_STRING_LEN (se.expr);
107 addr = GFC_DECL_ASSIGN_ADDR (se.expr);
109 label_tree = gfc_get_label_decl (code->label1);
111 if (code->label1->defined == ST_LABEL_TARGET
112 || code->label1->defined == ST_LABEL_DO_TARGET)
114 label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
115 len_tree = build_int_cst (gfc_charlen_type_node, -1);
117 else
119 gfc_expr *format = code->label1->format;
121 label_len = format->value.character.length;
122 len_tree = build_int_cst (gfc_charlen_type_node, label_len);
123 label_tree = gfc_build_wide_string_const (format->ts.kind, label_len + 1,
124 format->value.character.string);
125 label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
128 gfc_add_modify (&se.pre, len, fold_convert (TREE_TYPE (len), len_tree));
129 gfc_add_modify (&se.pre, addr, label_tree);
131 return gfc_finish_block (&se.pre);
134 /* Translate a GOTO statement. */
136 tree
137 gfc_trans_goto (gfc_code * code)
139 locus loc = code->loc;
140 tree assigned_goto;
141 tree target;
142 tree tmp;
143 gfc_se se;
145 if (code->label1 != NULL)
146 return build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
148 /* ASSIGNED GOTO. */
149 gfc_init_se (&se, NULL);
150 gfc_start_block (&se.pre);
151 gfc_conv_label_variable (&se, code->expr1);
152 tmp = GFC_DECL_STRING_LEN (se.expr);
153 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp,
154 build_int_cst (TREE_TYPE (tmp), -1));
155 gfc_trans_runtime_check (true, false, tmp, &se.pre, &loc,
156 "Assigned label is not a target label");
158 assigned_goto = GFC_DECL_ASSIGN_ADDR (se.expr);
160 /* We're going to ignore a label list. It does not really change the
161 statement's semantics (because it is just a further restriction on
162 what's legal code); before, we were comparing label addresses here, but
163 that's a very fragile business and may break with optimization. So
164 just ignore it. */
166 target = fold_build1_loc (input_location, GOTO_EXPR, void_type_node,
167 assigned_goto);
168 gfc_add_expr_to_block (&se.pre, target);
169 return gfc_finish_block (&se.pre);
173 /* Translate an ENTRY statement. Just adds a label for this entry point. */
174 tree
175 gfc_trans_entry (gfc_code * code)
177 return build1_v (LABEL_EXPR, code->ext.entry->label);
181 /* Replace a gfc_ss structure by another both in the gfc_se struct
182 and the gfc_loopinfo struct. This is used in gfc_conv_elemental_dependencies
183 to replace a variable ss by the corresponding temporary. */
185 static void
186 replace_ss (gfc_se *se, gfc_ss *old_ss, gfc_ss *new_ss)
188 gfc_ss **sess, **loopss;
190 /* The old_ss is a ss for a single variable. */
191 gcc_assert (old_ss->info->type == GFC_SS_SECTION);
193 for (sess = &(se->ss); *sess != gfc_ss_terminator; sess = &((*sess)->next))
194 if (*sess == old_ss)
195 break;
196 gcc_assert (*sess != gfc_ss_terminator);
198 *sess = new_ss;
199 new_ss->next = old_ss->next;
202 for (loopss = &(se->loop->ss); *loopss != gfc_ss_terminator;
203 loopss = &((*loopss)->loop_chain))
204 if (*loopss == old_ss)
205 break;
206 gcc_assert (*loopss != gfc_ss_terminator);
208 *loopss = new_ss;
209 new_ss->loop_chain = old_ss->loop_chain;
210 new_ss->loop = old_ss->loop;
212 gfc_free_ss (old_ss);
216 /* Check for dependencies between INTENT(IN) and INTENT(OUT) arguments of
217 elemental subroutines. Make temporaries for output arguments if any such
218 dependencies are found. Output arguments are chosen because internal_unpack
219 can be used, as is, to copy the result back to the variable. */
220 static void
221 gfc_conv_elemental_dependencies (gfc_se * se, gfc_se * loopse,
222 gfc_symbol * sym, gfc_actual_arglist * arg,
223 gfc_dep_check check_variable)
225 gfc_actual_arglist *arg0;
226 gfc_expr *e;
227 gfc_formal_arglist *formal;
228 gfc_se parmse;
229 gfc_ss *ss;
230 gfc_symbol *fsym;
231 tree data;
232 tree size;
233 tree tmp;
235 if (loopse->ss == NULL)
236 return;
238 ss = loopse->ss;
239 arg0 = arg;
240 formal = gfc_sym_get_dummy_args (sym);
242 /* Loop over all the arguments testing for dependencies. */
243 for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
245 e = arg->expr;
246 if (e == NULL)
247 continue;
249 /* Obtain the info structure for the current argument. */
250 for (ss = loopse->ss; ss && ss != gfc_ss_terminator; ss = ss->next)
251 if (ss->info->expr == e)
252 break;
254 /* If there is a dependency, create a temporary and use it
255 instead of the variable. */
256 fsym = formal ? formal->sym : NULL;
257 if (e->expr_type == EXPR_VARIABLE
258 && e->rank && fsym
259 && fsym->attr.intent != INTENT_IN
260 && gfc_check_fncall_dependency (e, fsym->attr.intent,
261 sym, arg0, check_variable))
263 tree initial, temptype;
264 stmtblock_t temp_post;
265 gfc_ss *tmp_ss;
267 tmp_ss = gfc_get_array_ss (gfc_ss_terminator, NULL, ss->dimen,
268 GFC_SS_SECTION);
269 gfc_mark_ss_chain_used (tmp_ss, 1);
270 tmp_ss->info->expr = ss->info->expr;
271 replace_ss (loopse, ss, tmp_ss);
273 /* Obtain the argument descriptor for unpacking. */
274 gfc_init_se (&parmse, NULL);
275 parmse.want_pointer = 1;
276 gfc_conv_expr_descriptor (&parmse, e);
277 gfc_add_block_to_block (&se->pre, &parmse.pre);
279 /* If we've got INTENT(INOUT) or a derived type with INTENT(OUT),
280 initialize the array temporary with a copy of the values. */
281 if (fsym->attr.intent == INTENT_INOUT
282 || (fsym->ts.type ==BT_DERIVED
283 && fsym->attr.intent == INTENT_OUT))
284 initial = parmse.expr;
285 /* For class expressions, we always initialize with the copy of
286 the values. */
287 else if (e->ts.type == BT_CLASS)
288 initial = parmse.expr;
289 else
290 initial = NULL_TREE;
292 if (e->ts.type != BT_CLASS)
294 /* Find the type of the temporary to create; we don't use the type
295 of e itself as this breaks for subcomponent-references in e
296 (where the type of e is that of the final reference, but
297 parmse.expr's type corresponds to the full derived-type). */
298 /* TODO: Fix this somehow so we don't need a temporary of the whole
299 array but instead only the components referenced. */
300 temptype = TREE_TYPE (parmse.expr); /* Pointer to descriptor. */
301 gcc_assert (TREE_CODE (temptype) == POINTER_TYPE);
302 temptype = TREE_TYPE (temptype);
303 temptype = gfc_get_element_type (temptype);
306 else
307 /* For class arrays signal that the size of the dynamic type has to
308 be obtained from the vtable, using the 'initial' expression. */
309 temptype = NULL_TREE;
311 /* Generate the temporary. Cleaning up the temporary should be the
312 very last thing done, so we add the code to a new block and add it
313 to se->post as last instructions. */
314 size = gfc_create_var (gfc_array_index_type, NULL);
315 data = gfc_create_var (pvoid_type_node, NULL);
316 gfc_init_block (&temp_post);
317 tmp = gfc_trans_create_temp_array (&se->pre, &temp_post, tmp_ss,
318 temptype, initial, false, true,
319 false, &arg->expr->where);
320 gfc_add_modify (&se->pre, size, tmp);
321 tmp = fold_convert (pvoid_type_node, tmp_ss->info->data.array.data);
322 gfc_add_modify (&se->pre, data, tmp);
324 /* Update other ss' delta. */
325 gfc_set_delta (loopse->loop);
327 /* Copy the result back using unpack..... */
328 if (e->ts.type != BT_CLASS)
329 tmp = build_call_expr_loc (input_location,
330 gfor_fndecl_in_unpack, 2, parmse.expr, data);
331 else
333 /* ... except for class results where the copy is
334 unconditional. */
335 tmp = build_fold_indirect_ref_loc (input_location, parmse.expr);
336 tmp = gfc_conv_descriptor_data_get (tmp);
337 tmp = build_call_expr_loc (input_location,
338 builtin_decl_explicit (BUILT_IN_MEMCPY),
339 3, tmp, data,
340 fold_convert (size_type_node, size));
342 gfc_add_expr_to_block (&se->post, tmp);
344 /* parmse.pre is already added above. */
345 gfc_add_block_to_block (&se->post, &parmse.post);
346 gfc_add_block_to_block (&se->post, &temp_post);
352 /* Get the interface symbol for the procedure corresponding to the given call.
353 We can't get the procedure symbol directly as we have to handle the case
354 of (deferred) type-bound procedures. */
356 static gfc_symbol *
357 get_proc_ifc_for_call (gfc_code *c)
359 gfc_symbol *sym;
361 gcc_assert (c->op == EXEC_ASSIGN_CALL || c->op == EXEC_CALL);
363 sym = gfc_get_proc_ifc_for_expr (c->expr1);
365 /* Fall back/last resort try. */
366 if (sym == NULL)
367 sym = c->resolved_sym;
369 return sym;
373 /* Translate the CALL statement. Builds a call to an F95 subroutine. */
375 tree
376 gfc_trans_call (gfc_code * code, bool dependency_check,
377 tree mask, tree count1, bool invert)
379 gfc_se se;
380 gfc_ss * ss;
381 int has_alternate_specifier;
382 gfc_dep_check check_variable;
383 tree index = NULL_TREE;
384 tree maskexpr = NULL_TREE;
385 tree tmp;
387 /* A CALL starts a new block because the actual arguments may have to
388 be evaluated first. */
389 gfc_init_se (&se, NULL);
390 gfc_start_block (&se.pre);
392 gcc_assert (code->resolved_sym);
394 ss = gfc_ss_terminator;
395 if (code->resolved_sym->attr.elemental)
396 ss = gfc_walk_elemental_function_args (ss, code->ext.actual,
397 get_proc_ifc_for_call (code),
398 GFC_SS_REFERENCE);
400 /* Is not an elemental subroutine call with array valued arguments. */
401 if (ss == gfc_ss_terminator)
404 /* Translate the call. */
405 has_alternate_specifier
406 = gfc_conv_procedure_call (&se, code->resolved_sym, code->ext.actual,
407 code->expr1, NULL);
409 /* A subroutine without side-effect, by definition, does nothing! */
410 TREE_SIDE_EFFECTS (se.expr) = 1;
412 /* Chain the pieces together and return the block. */
413 if (has_alternate_specifier)
415 gfc_code *select_code;
416 gfc_symbol *sym;
417 select_code = code->next;
418 gcc_assert(select_code->op == EXEC_SELECT);
419 sym = select_code->expr1->symtree->n.sym;
420 se.expr = convert (gfc_typenode_for_spec (&sym->ts), se.expr);
421 if (sym->backend_decl == NULL)
422 sym->backend_decl = gfc_get_symbol_decl (sym);
423 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
425 else
426 gfc_add_expr_to_block (&se.pre, se.expr);
428 gfc_add_block_to_block (&se.pre, &se.post);
431 else
433 /* An elemental subroutine call with array valued arguments has
434 to be scalarized. */
435 gfc_loopinfo loop;
436 stmtblock_t body;
437 stmtblock_t block;
438 gfc_se loopse;
439 gfc_se depse;
441 /* gfc_walk_elemental_function_args renders the ss chain in the
442 reverse order to the actual argument order. */
443 ss = gfc_reverse_ss (ss);
445 /* Initialize the loop. */
446 gfc_init_se (&loopse, NULL);
447 gfc_init_loopinfo (&loop);
448 gfc_add_ss_to_loop (&loop, ss);
450 gfc_conv_ss_startstride (&loop);
451 /* TODO: gfc_conv_loop_setup generates a temporary for vector
452 subscripts. This could be prevented in the elemental case
453 as temporaries are handled separatedly
454 (below in gfc_conv_elemental_dependencies). */
455 if (code->expr1)
456 gfc_conv_loop_setup (&loop, &code->expr1->where);
457 else
458 gfc_conv_loop_setup (&loop, &code->loc);
460 gfc_mark_ss_chain_used (ss, 1);
462 /* Convert the arguments, checking for dependencies. */
463 gfc_copy_loopinfo_to_se (&loopse, &loop);
464 loopse.ss = ss;
466 /* For operator assignment, do dependency checking. */
467 if (dependency_check)
468 check_variable = ELEM_CHECK_VARIABLE;
469 else
470 check_variable = ELEM_DONT_CHECK_VARIABLE;
472 gfc_init_se (&depse, NULL);
473 gfc_conv_elemental_dependencies (&depse, &loopse, code->resolved_sym,
474 code->ext.actual, check_variable);
476 gfc_add_block_to_block (&loop.pre, &depse.pre);
477 gfc_add_block_to_block (&loop.post, &depse.post);
479 /* Generate the loop body. */
480 gfc_start_scalarized_body (&loop, &body);
481 gfc_init_block (&block);
483 if (mask && count1)
485 /* Form the mask expression according to the mask. */
486 index = count1;
487 maskexpr = gfc_build_array_ref (mask, index, NULL);
488 if (invert)
489 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
490 TREE_TYPE (maskexpr), maskexpr);
493 /* Add the subroutine call to the block. */
494 gfc_conv_procedure_call (&loopse, code->resolved_sym,
495 code->ext.actual, code->expr1,
496 NULL);
498 if (mask && count1)
500 tmp = build3_v (COND_EXPR, maskexpr, loopse.expr,
501 build_empty_stmt (input_location));
502 gfc_add_expr_to_block (&loopse.pre, tmp);
503 tmp = fold_build2_loc (input_location, PLUS_EXPR,
504 gfc_array_index_type,
505 count1, gfc_index_one_node);
506 gfc_add_modify (&loopse.pre, count1, tmp);
508 else
509 gfc_add_expr_to_block (&loopse.pre, loopse.expr);
511 gfc_add_block_to_block (&block, &loopse.pre);
512 gfc_add_block_to_block (&block, &loopse.post);
514 /* Finish up the loop block and the loop. */
515 gfc_add_expr_to_block (&body, gfc_finish_block (&block));
516 gfc_trans_scalarizing_loops (&loop, &body);
517 gfc_add_block_to_block (&se.pre, &loop.pre);
518 gfc_add_block_to_block (&se.pre, &loop.post);
519 gfc_add_block_to_block (&se.pre, &se.post);
520 gfc_cleanup_loop (&loop);
523 return gfc_finish_block (&se.pre);
527 /* Translate the RETURN statement. */
529 tree
530 gfc_trans_return (gfc_code * code)
532 if (code->expr1)
534 gfc_se se;
535 tree tmp;
536 tree result;
538 /* If code->expr is not NULL, this return statement must appear
539 in a subroutine and current_fake_result_decl has already
540 been generated. */
542 result = gfc_get_fake_result_decl (NULL, 0);
543 if (!result)
545 gfc_warning (0,
546 "An alternate return at %L without a * dummy argument",
547 &code->expr1->where);
548 return gfc_generate_return ();
551 /* Start a new block for this statement. */
552 gfc_init_se (&se, NULL);
553 gfc_start_block (&se.pre);
555 gfc_conv_expr (&se, code->expr1);
557 /* Note that the actually returned expression is a simple value and
558 does not depend on any pointers or such; thus we can clean-up with
559 se.post before returning. */
560 tmp = fold_build2_loc (input_location, MODIFY_EXPR, TREE_TYPE (result),
561 result, fold_convert (TREE_TYPE (result),
562 se.expr));
563 gfc_add_expr_to_block (&se.pre, tmp);
564 gfc_add_block_to_block (&se.pre, &se.post);
566 tmp = gfc_generate_return ();
567 gfc_add_expr_to_block (&se.pre, tmp);
568 return gfc_finish_block (&se.pre);
571 return gfc_generate_return ();
575 /* Translate the PAUSE statement. We have to translate this statement
576 to a runtime library call. */
578 tree
579 gfc_trans_pause (gfc_code * code)
581 tree gfc_int8_type_node = gfc_get_int_type (8);
582 gfc_se se;
583 tree tmp;
585 /* Start a new block for this statement. */
586 gfc_init_se (&se, NULL);
587 gfc_start_block (&se.pre);
590 if (code->expr1 == NULL)
592 tmp = build_int_cst (size_type_node, 0);
593 tmp = build_call_expr_loc (input_location,
594 gfor_fndecl_pause_string, 2,
595 build_int_cst (pchar_type_node, 0), tmp);
597 else if (code->expr1->ts.type == BT_INTEGER)
599 gfc_conv_expr (&se, code->expr1);
600 tmp = build_call_expr_loc (input_location,
601 gfor_fndecl_pause_numeric, 1,
602 fold_convert (gfc_int8_type_node, se.expr));
604 else
606 gfc_conv_expr_reference (&se, code->expr1);
607 tmp = build_call_expr_loc (input_location,
608 gfor_fndecl_pause_string, 2,
609 se.expr, fold_convert (size_type_node,
610 se.string_length));
613 gfc_add_expr_to_block (&se.pre, tmp);
615 gfc_add_block_to_block (&se.pre, &se.post);
617 return gfc_finish_block (&se.pre);
621 /* Translate the STOP statement. We have to translate this statement
622 to a runtime library call. */
624 tree
625 gfc_trans_stop (gfc_code *code, bool error_stop)
627 gfc_se se;
628 tree tmp;
630 /* Start a new block for this statement. */
631 gfc_init_se (&se, NULL);
632 gfc_start_block (&se.pre);
634 if (code->expr1 == NULL)
636 tmp = build_int_cst (size_type_node, 0);
637 tmp = build_call_expr_loc (input_location,
638 error_stop
639 ? (flag_coarray == GFC_FCOARRAY_LIB
640 ? gfor_fndecl_caf_error_stop_str
641 : gfor_fndecl_error_stop_string)
642 : (flag_coarray == GFC_FCOARRAY_LIB
643 ? gfor_fndecl_caf_stop_str
644 : gfor_fndecl_stop_string),
645 3, build_int_cst (pchar_type_node, 0), tmp,
646 boolean_false_node);
648 else if (code->expr1->ts.type == BT_INTEGER)
650 gfc_conv_expr (&se, code->expr1);
651 tmp = build_call_expr_loc (input_location,
652 error_stop
653 ? (flag_coarray == GFC_FCOARRAY_LIB
654 ? gfor_fndecl_caf_error_stop
655 : gfor_fndecl_error_stop_numeric)
656 : (flag_coarray == GFC_FCOARRAY_LIB
657 ? gfor_fndecl_caf_stop_numeric
658 : gfor_fndecl_stop_numeric), 2,
659 fold_convert (integer_type_node, se.expr),
660 boolean_false_node);
662 else
664 gfc_conv_expr_reference (&se, code->expr1);
665 tmp = build_call_expr_loc (input_location,
666 error_stop
667 ? (flag_coarray == GFC_FCOARRAY_LIB
668 ? gfor_fndecl_caf_error_stop_str
669 : gfor_fndecl_error_stop_string)
670 : (flag_coarray == GFC_FCOARRAY_LIB
671 ? gfor_fndecl_caf_stop_str
672 : gfor_fndecl_stop_string),
673 3, se.expr, fold_convert (size_type_node,
674 se.string_length),
675 boolean_false_node);
678 gfc_add_expr_to_block (&se.pre, tmp);
680 gfc_add_block_to_block (&se.pre, &se.post);
682 return gfc_finish_block (&se.pre);
685 /* Translate the FAIL IMAGE statement. */
687 tree
688 gfc_trans_fail_image (gfc_code *code ATTRIBUTE_UNUSED)
690 if (flag_coarray == GFC_FCOARRAY_LIB)
691 return build_call_expr_loc (input_location,
692 gfor_fndecl_caf_fail_image, 1,
693 build_int_cst (pchar_type_node, 0));
694 else
696 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
697 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
698 tree tmp = gfc_get_symbol_decl (exsym);
699 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
703 /* Translate the FORM TEAM statement. */
705 tree
706 gfc_trans_form_team (gfc_code *code)
708 if (flag_coarray == GFC_FCOARRAY_LIB)
710 gfc_se se;
711 gfc_se argse1, argse2;
712 tree team_id, team_type, tmp;
714 gfc_init_se (&se, NULL);
715 gfc_init_se (&argse1, NULL);
716 gfc_init_se (&argse2, NULL);
717 gfc_start_block (&se.pre);
719 gfc_conv_expr_val (&argse1, code->expr1);
720 gfc_conv_expr_val (&argse2, code->expr2);
721 team_id = fold_convert (integer_type_node, argse1.expr);
722 team_type = gfc_build_addr_expr (ppvoid_type_node, argse2.expr);
724 gfc_add_block_to_block (&se.pre, &argse1.pre);
725 gfc_add_block_to_block (&se.pre, &argse2.pre);
726 tmp = build_call_expr_loc (input_location,
727 gfor_fndecl_caf_form_team, 3,
728 team_id, team_type,
729 build_int_cst (integer_type_node, 0));
730 gfc_add_expr_to_block (&se.pre, tmp);
731 gfc_add_block_to_block (&se.pre, &argse1.post);
732 gfc_add_block_to_block (&se.pre, &argse2.post);
733 return gfc_finish_block (&se.pre);
735 else
737 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
738 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
739 tree tmp = gfc_get_symbol_decl (exsym);
740 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
744 /* Translate the CHANGE TEAM statement. */
746 tree
747 gfc_trans_change_team (gfc_code *code)
749 if (flag_coarray == GFC_FCOARRAY_LIB)
751 gfc_se argse;
752 tree team_type, tmp;
754 gfc_init_se (&argse, NULL);
755 gfc_conv_expr_val (&argse, code->expr1);
756 team_type = gfc_build_addr_expr (ppvoid_type_node, argse.expr);
758 tmp = build_call_expr_loc (input_location,
759 gfor_fndecl_caf_change_team, 2, team_type,
760 build_int_cst (integer_type_node, 0));
761 gfc_add_expr_to_block (&argse.pre, tmp);
762 gfc_add_block_to_block (&argse.pre, &argse.post);
763 return gfc_finish_block (&argse.pre);
765 else
767 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
768 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
769 tree tmp = gfc_get_symbol_decl (exsym);
770 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
774 /* Translate the END TEAM statement. */
776 tree
777 gfc_trans_end_team (gfc_code *code ATTRIBUTE_UNUSED)
779 if (flag_coarray == GFC_FCOARRAY_LIB)
781 return build_call_expr_loc (input_location,
782 gfor_fndecl_caf_end_team, 1,
783 build_int_cst (pchar_type_node, 0));
785 else
787 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
788 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
789 tree tmp = gfc_get_symbol_decl (exsym);
790 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
794 /* Translate the SYNC TEAM statement. */
796 tree
797 gfc_trans_sync_team (gfc_code *code)
799 if (flag_coarray == GFC_FCOARRAY_LIB)
801 gfc_se argse;
802 tree team_type, tmp;
804 gfc_init_se (&argse, NULL);
805 gfc_conv_expr_val (&argse, code->expr1);
806 team_type = gfc_build_addr_expr (ppvoid_type_node, argse.expr);
808 tmp = build_call_expr_loc (input_location,
809 gfor_fndecl_caf_sync_team, 2,
810 team_type,
811 build_int_cst (integer_type_node, 0));
812 gfc_add_expr_to_block (&argse.pre, tmp);
813 gfc_add_block_to_block (&argse.pre, &argse.post);
814 return gfc_finish_block (&argse.pre);
816 else
818 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
819 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
820 tree tmp = gfc_get_symbol_decl (exsym);
821 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
825 tree
826 gfc_trans_lock_unlock (gfc_code *code, gfc_exec_op op)
828 gfc_se se, argse;
829 tree stat = NULL_TREE, stat2 = NULL_TREE;
830 tree lock_acquired = NULL_TREE, lock_acquired2 = NULL_TREE;
832 /* Short cut: For single images without STAT= or LOCK_ACQUIRED
833 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
834 if (!code->expr2 && !code->expr4 && flag_coarray != GFC_FCOARRAY_LIB)
835 return NULL_TREE;
837 if (code->expr2)
839 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
840 gfc_init_se (&argse, NULL);
841 gfc_conv_expr_val (&argse, code->expr2);
842 stat = argse.expr;
844 else if (flag_coarray == GFC_FCOARRAY_LIB)
845 stat = null_pointer_node;
847 if (code->expr4)
849 gcc_assert (code->expr4->expr_type == EXPR_VARIABLE);
850 gfc_init_se (&argse, NULL);
851 gfc_conv_expr_val (&argse, code->expr4);
852 lock_acquired = argse.expr;
854 else if (flag_coarray == GFC_FCOARRAY_LIB)
855 lock_acquired = null_pointer_node;
857 gfc_start_block (&se.pre);
858 if (flag_coarray == GFC_FCOARRAY_LIB)
860 tree tmp, token, image_index, errmsg, errmsg_len;
861 tree index = build_zero_cst (gfc_array_index_type);
862 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
864 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
865 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
866 != INTMOD_ISO_FORTRAN_ENV
867 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
868 != ISOFORTRAN_LOCK_TYPE)
870 gfc_error ("Sorry, the lock component of derived type at %L is not "
871 "yet supported", &code->expr1->where);
872 return NULL_TREE;
875 gfc_get_caf_token_offset (&se, &token, NULL, caf_decl, NULL_TREE,
876 code->expr1);
878 if (gfc_is_coindexed (code->expr1))
879 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
880 else
881 image_index = integer_zero_node;
883 /* For arrays, obtain the array index. */
884 if (gfc_expr_attr (code->expr1).dimension)
886 tree desc, tmp, extent, lbound, ubound;
887 gfc_array_ref *ar, ar2;
888 int i;
890 /* TODO: Extend this, once DT components are supported. */
891 ar = &code->expr1->ref->u.ar;
892 ar2 = *ar;
893 memset (ar, '\0', sizeof (*ar));
894 ar->as = ar2.as;
895 ar->type = AR_FULL;
897 gfc_init_se (&argse, NULL);
898 argse.descriptor_only = 1;
899 gfc_conv_expr_descriptor (&argse, code->expr1);
900 gfc_add_block_to_block (&se.pre, &argse.pre);
901 desc = argse.expr;
902 *ar = ar2;
904 extent = build_one_cst (gfc_array_index_type);
905 for (i = 0; i < ar->dimen; i++)
907 gfc_init_se (&argse, NULL);
908 gfc_conv_expr_type (&argse, ar->start[i], gfc_array_index_type);
909 gfc_add_block_to_block (&argse.pre, &argse.pre);
910 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
911 tmp = fold_build2_loc (input_location, MINUS_EXPR,
912 TREE_TYPE (lbound), argse.expr, lbound);
913 tmp = fold_build2_loc (input_location, MULT_EXPR,
914 TREE_TYPE (tmp), extent, tmp);
915 index = fold_build2_loc (input_location, PLUS_EXPR,
916 TREE_TYPE (tmp), index, tmp);
917 if (i < ar->dimen - 1)
919 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
920 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
921 extent = fold_build2_loc (input_location, MULT_EXPR,
922 TREE_TYPE (tmp), extent, tmp);
927 /* errmsg. */
928 if (code->expr3)
930 gfc_init_se (&argse, NULL);
931 argse.want_pointer = 1;
932 gfc_conv_expr (&argse, code->expr3);
933 gfc_add_block_to_block (&se.pre, &argse.pre);
934 errmsg = argse.expr;
935 errmsg_len = fold_convert (size_type_node, argse.string_length);
937 else
939 errmsg = null_pointer_node;
940 errmsg_len = build_zero_cst (size_type_node);
943 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
945 stat2 = stat;
946 stat = gfc_create_var (integer_type_node, "stat");
949 if (lock_acquired != null_pointer_node
950 && TREE_TYPE (lock_acquired) != integer_type_node)
952 lock_acquired2 = lock_acquired;
953 lock_acquired = gfc_create_var (integer_type_node, "acquired");
956 index = fold_convert (size_type_node, index);
957 if (op == EXEC_LOCK)
958 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
959 token, index, image_index,
960 lock_acquired != null_pointer_node
961 ? gfc_build_addr_expr (NULL, lock_acquired)
962 : lock_acquired,
963 stat != null_pointer_node
964 ? gfc_build_addr_expr (NULL, stat) : stat,
965 errmsg, errmsg_len);
966 else
967 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
968 token, index, image_index,
969 stat != null_pointer_node
970 ? gfc_build_addr_expr (NULL, stat) : stat,
971 errmsg, errmsg_len);
972 gfc_add_expr_to_block (&se.pre, tmp);
974 /* It guarantees memory consistency within the same segment */
975 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
976 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
977 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
978 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
979 ASM_VOLATILE_P (tmp) = 1;
981 gfc_add_expr_to_block (&se.pre, tmp);
983 if (stat2 != NULL_TREE)
984 gfc_add_modify (&se.pre, stat2,
985 fold_convert (TREE_TYPE (stat2), stat));
987 if (lock_acquired2 != NULL_TREE)
988 gfc_add_modify (&se.pre, lock_acquired2,
989 fold_convert (TREE_TYPE (lock_acquired2),
990 lock_acquired));
992 return gfc_finish_block (&se.pre);
995 if (stat != NULL_TREE)
996 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
998 if (lock_acquired != NULL_TREE)
999 gfc_add_modify (&se.pre, lock_acquired,
1000 fold_convert (TREE_TYPE (lock_acquired),
1001 boolean_true_node));
1003 return gfc_finish_block (&se.pre);
1006 tree
1007 gfc_trans_event_post_wait (gfc_code *code, gfc_exec_op op)
1009 gfc_se se, argse;
1010 tree stat = NULL_TREE, stat2 = NULL_TREE;
1011 tree until_count = NULL_TREE;
1013 if (code->expr2)
1015 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
1016 gfc_init_se (&argse, NULL);
1017 gfc_conv_expr_val (&argse, code->expr2);
1018 stat = argse.expr;
1020 else if (flag_coarray == GFC_FCOARRAY_LIB)
1021 stat = null_pointer_node;
1023 if (code->expr4)
1025 gfc_init_se (&argse, NULL);
1026 gfc_conv_expr_val (&argse, code->expr4);
1027 until_count = fold_convert (integer_type_node, argse.expr);
1029 else
1030 until_count = integer_one_node;
1032 if (flag_coarray != GFC_FCOARRAY_LIB)
1034 gfc_start_block (&se.pre);
1035 gfc_init_se (&argse, NULL);
1036 gfc_conv_expr_val (&argse, code->expr1);
1038 if (op == EXEC_EVENT_POST)
1039 gfc_add_modify (&se.pre, argse.expr,
1040 fold_build2_loc (input_location, PLUS_EXPR,
1041 TREE_TYPE (argse.expr), argse.expr,
1042 build_int_cst (TREE_TYPE (argse.expr), 1)));
1043 else
1044 gfc_add_modify (&se.pre, argse.expr,
1045 fold_build2_loc (input_location, MINUS_EXPR,
1046 TREE_TYPE (argse.expr), argse.expr,
1047 fold_convert (TREE_TYPE (argse.expr),
1048 until_count)));
1049 if (stat != NULL_TREE)
1050 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
1052 return gfc_finish_block (&se.pre);
1055 gfc_start_block (&se.pre);
1056 tree tmp, token, image_index, errmsg, errmsg_len;
1057 tree index = build_zero_cst (gfc_array_index_type);
1058 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
1060 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
1061 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
1062 != INTMOD_ISO_FORTRAN_ENV
1063 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
1064 != ISOFORTRAN_EVENT_TYPE)
1066 gfc_error ("Sorry, the event component of derived type at %L is not "
1067 "yet supported", &code->expr1->where);
1068 return NULL_TREE;
1071 gfc_init_se (&argse, NULL);
1072 gfc_get_caf_token_offset (&argse, &token, NULL, caf_decl, NULL_TREE,
1073 code->expr1);
1074 gfc_add_block_to_block (&se.pre, &argse.pre);
1076 if (gfc_is_coindexed (code->expr1))
1077 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
1078 else
1079 image_index = integer_zero_node;
1081 /* For arrays, obtain the array index. */
1082 if (gfc_expr_attr (code->expr1).dimension)
1084 tree desc, tmp, extent, lbound, ubound;
1085 gfc_array_ref *ar, ar2;
1086 int i;
1088 /* TODO: Extend this, once DT components are supported. */
1089 ar = &code->expr1->ref->u.ar;
1090 ar2 = *ar;
1091 memset (ar, '\0', sizeof (*ar));
1092 ar->as = ar2.as;
1093 ar->type = AR_FULL;
1095 gfc_init_se (&argse, NULL);
1096 argse.descriptor_only = 1;
1097 gfc_conv_expr_descriptor (&argse, code->expr1);
1098 gfc_add_block_to_block (&se.pre, &argse.pre);
1099 desc = argse.expr;
1100 *ar = ar2;
1102 extent = build_one_cst (gfc_array_index_type);
1103 for (i = 0; i < ar->dimen; i++)
1105 gfc_init_se (&argse, NULL);
1106 gfc_conv_expr_type (&argse, ar->start[i], gfc_array_index_type);
1107 gfc_add_block_to_block (&argse.pre, &argse.pre);
1108 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
1109 tmp = fold_build2_loc (input_location, MINUS_EXPR,
1110 TREE_TYPE (lbound), argse.expr, lbound);
1111 tmp = fold_build2_loc (input_location, MULT_EXPR,
1112 TREE_TYPE (tmp), extent, tmp);
1113 index = fold_build2_loc (input_location, PLUS_EXPR,
1114 TREE_TYPE (tmp), index, tmp);
1115 if (i < ar->dimen - 1)
1117 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
1118 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
1119 extent = fold_build2_loc (input_location, MULT_EXPR,
1120 TREE_TYPE (tmp), extent, tmp);
1125 /* errmsg. */
1126 if (code->expr3)
1128 gfc_init_se (&argse, NULL);
1129 argse.want_pointer = 1;
1130 gfc_conv_expr (&argse, code->expr3);
1131 gfc_add_block_to_block (&se.pre, &argse.pre);
1132 errmsg = argse.expr;
1133 errmsg_len = fold_convert (size_type_node, argse.string_length);
1135 else
1137 errmsg = null_pointer_node;
1138 errmsg_len = build_zero_cst (size_type_node);
1141 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
1143 stat2 = stat;
1144 stat = gfc_create_var (integer_type_node, "stat");
1147 index = fold_convert (size_type_node, index);
1148 if (op == EXEC_EVENT_POST)
1149 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_post, 6,
1150 token, index, image_index,
1151 stat != null_pointer_node
1152 ? gfc_build_addr_expr (NULL, stat) : stat,
1153 errmsg, errmsg_len);
1154 else
1155 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_wait, 6,
1156 token, index, until_count,
1157 stat != null_pointer_node
1158 ? gfc_build_addr_expr (NULL, stat) : stat,
1159 errmsg, errmsg_len);
1160 gfc_add_expr_to_block (&se.pre, tmp);
1162 /* It guarantees memory consistency within the same segment */
1163 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1164 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1165 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1166 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1167 ASM_VOLATILE_P (tmp) = 1;
1168 gfc_add_expr_to_block (&se.pre, tmp);
1170 if (stat2 != NULL_TREE)
1171 gfc_add_modify (&se.pre, stat2, fold_convert (TREE_TYPE (stat2), stat));
1173 return gfc_finish_block (&se.pre);
1176 tree
1177 gfc_trans_sync (gfc_code *code, gfc_exec_op type)
1179 gfc_se se, argse;
1180 tree tmp;
1181 tree images = NULL_TREE, stat = NULL_TREE,
1182 errmsg = NULL_TREE, errmsglen = NULL_TREE;
1184 /* Short cut: For single images without bound checking or without STAT=,
1185 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
1186 if (!code->expr2 && !(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1187 && flag_coarray != GFC_FCOARRAY_LIB)
1188 return NULL_TREE;
1190 gfc_init_se (&se, NULL);
1191 gfc_start_block (&se.pre);
1193 if (code->expr1 && code->expr1->rank == 0)
1195 gfc_init_se (&argse, NULL);
1196 gfc_conv_expr_val (&argse, code->expr1);
1197 images = argse.expr;
1200 if (code->expr2)
1202 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
1203 gfc_init_se (&argse, NULL);
1204 gfc_conv_expr_val (&argse, code->expr2);
1205 stat = argse.expr;
1207 else
1208 stat = null_pointer_node;
1210 if (code->expr3 && flag_coarray == GFC_FCOARRAY_LIB)
1212 gcc_assert (code->expr3->expr_type == EXPR_VARIABLE);
1213 gfc_init_se (&argse, NULL);
1214 argse.want_pointer = 1;
1215 gfc_conv_expr (&argse, code->expr3);
1216 gfc_conv_string_parameter (&argse);
1217 errmsg = gfc_build_addr_expr (NULL, argse.expr);
1218 errmsglen = fold_convert (size_type_node, argse.string_length);
1220 else if (flag_coarray == GFC_FCOARRAY_LIB)
1222 errmsg = null_pointer_node;
1223 errmsglen = build_int_cst (size_type_node, 0);
1226 /* Check SYNC IMAGES(imageset) for valid image index.
1227 FIXME: Add a check for image-set arrays. */
1228 if (code->expr1 && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1229 && code->expr1->rank == 0)
1231 tree images2 = fold_convert (integer_type_node, images);
1232 tree cond;
1233 if (flag_coarray != GFC_FCOARRAY_LIB)
1234 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1235 images, build_int_cst (TREE_TYPE (images), 1));
1236 else
1238 tree cond2;
1239 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images,
1240 2, integer_zero_node,
1241 build_int_cst (integer_type_node, -1));
1242 cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
1243 images2, tmp);
1244 cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
1245 images,
1246 build_int_cst (TREE_TYPE (images), 1));
1247 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1248 logical_type_node, cond, cond2);
1250 gfc_trans_runtime_check (true, false, cond, &se.pre,
1251 &code->expr1->where, "Invalid image number "
1252 "%d in SYNC IMAGES", images2);
1255 /* Per F2008, 8.5.1, a SYNC MEMORY is implied by calling the
1256 image control statements SYNC IMAGES and SYNC ALL. */
1257 if (flag_coarray == GFC_FCOARRAY_LIB)
1259 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1260 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1261 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1262 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1263 ASM_VOLATILE_P (tmp) = 1;
1264 gfc_add_expr_to_block (&se.pre, tmp);
1267 if (flag_coarray != GFC_FCOARRAY_LIB)
1269 /* Set STAT to zero. */
1270 if (code->expr2)
1271 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
1273 else if (type == EXEC_SYNC_ALL || type == EXEC_SYNC_MEMORY)
1275 /* SYNC ALL => stat == null_pointer_node
1276 SYNC ALL(stat=s) => stat has an integer type
1278 If "stat" has the wrong integer type, use a temp variable of
1279 the right type and later cast the result back into "stat". */
1280 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1282 if (TREE_TYPE (stat) == integer_type_node)
1283 stat = gfc_build_addr_expr (NULL, stat);
1285 if(type == EXEC_SYNC_MEMORY)
1286 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_memory,
1287 3, stat, errmsg, errmsglen);
1288 else
1289 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
1290 3, stat, errmsg, errmsglen);
1292 gfc_add_expr_to_block (&se.pre, tmp);
1294 else
1296 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1298 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
1299 3, gfc_build_addr_expr (NULL, tmp_stat),
1300 errmsg, errmsglen);
1301 gfc_add_expr_to_block (&se.pre, tmp);
1303 gfc_add_modify (&se.pre, stat,
1304 fold_convert (TREE_TYPE (stat), tmp_stat));
1307 else
1309 tree len;
1311 gcc_assert (type == EXEC_SYNC_IMAGES);
1313 if (!code->expr1)
1315 len = build_int_cst (integer_type_node, -1);
1316 images = null_pointer_node;
1318 else if (code->expr1->rank == 0)
1320 len = build_int_cst (integer_type_node, 1);
1321 images = gfc_build_addr_expr (NULL_TREE, images);
1323 else
1325 /* FIXME. */
1326 if (code->expr1->ts.kind != gfc_c_int_kind)
1327 gfc_fatal_error ("Sorry, only support for integer kind %d "
1328 "implemented for image-set at %L",
1329 gfc_c_int_kind, &code->expr1->where);
1331 gfc_conv_array_parameter (&se, code->expr1, true, NULL, NULL, &len);
1332 images = se.expr;
1334 tmp = gfc_typenode_for_spec (&code->expr1->ts);
1335 if (GFC_ARRAY_TYPE_P (tmp) || GFC_DESCRIPTOR_TYPE_P (tmp))
1336 tmp = gfc_get_element_type (tmp);
1338 len = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
1339 TREE_TYPE (len), len,
1340 fold_convert (TREE_TYPE (len),
1341 TYPE_SIZE_UNIT (tmp)));
1342 len = fold_convert (integer_type_node, len);
1345 /* SYNC IMAGES(imgs) => stat == null_pointer_node
1346 SYNC IMAGES(imgs,stat=s) => stat has an integer type
1348 If "stat" has the wrong integer type, use a temp variable of
1349 the right type and later cast the result back into "stat". */
1350 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1352 if (TREE_TYPE (stat) == integer_type_node)
1353 stat = gfc_build_addr_expr (NULL, stat);
1355 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1356 5, fold_convert (integer_type_node, len),
1357 images, stat, errmsg, errmsglen);
1358 gfc_add_expr_to_block (&se.pre, tmp);
1360 else
1362 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1364 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1365 5, fold_convert (integer_type_node, len),
1366 images, gfc_build_addr_expr (NULL, tmp_stat),
1367 errmsg, errmsglen);
1368 gfc_add_expr_to_block (&se.pre, tmp);
1370 gfc_add_modify (&se.pre, stat,
1371 fold_convert (TREE_TYPE (stat), tmp_stat));
1375 return gfc_finish_block (&se.pre);
1379 /* Generate GENERIC for the IF construct. This function also deals with
1380 the simple IF statement, because the front end translates the IF
1381 statement into an IF construct.
1383 We translate:
1385 IF (cond) THEN
1386 then_clause
1387 ELSEIF (cond2)
1388 elseif_clause
1389 ELSE
1390 else_clause
1391 ENDIF
1393 into:
1395 pre_cond_s;
1396 if (cond_s)
1398 then_clause;
1400 else
1402 pre_cond_s
1403 if (cond_s)
1405 elseif_clause
1407 else
1409 else_clause;
1413 where COND_S is the simplified version of the predicate. PRE_COND_S
1414 are the pre side-effects produced by the translation of the
1415 conditional.
1416 We need to build the chain recursively otherwise we run into
1417 problems with folding incomplete statements. */
1419 static tree
1420 gfc_trans_if_1 (gfc_code * code)
1422 gfc_se if_se;
1423 tree stmt, elsestmt;
1424 locus saved_loc;
1425 location_t loc;
1427 /* Check for an unconditional ELSE clause. */
1428 if (!code->expr1)
1429 return gfc_trans_code (code->next);
1431 /* Initialize a statement builder for each block. Puts in NULL_TREEs. */
1432 gfc_init_se (&if_se, NULL);
1433 gfc_start_block (&if_se.pre);
1435 /* Calculate the IF condition expression. */
1436 if (code->expr1->where.lb)
1438 gfc_save_backend_locus (&saved_loc);
1439 gfc_set_backend_locus (&code->expr1->where);
1442 gfc_conv_expr_val (&if_se, code->expr1);
1444 if (code->expr1->where.lb)
1445 gfc_restore_backend_locus (&saved_loc);
1447 /* Translate the THEN clause. */
1448 stmt = gfc_trans_code (code->next);
1450 /* Translate the ELSE clause. */
1451 if (code->block)
1452 elsestmt = gfc_trans_if_1 (code->block);
1453 else
1454 elsestmt = build_empty_stmt (input_location);
1456 /* Build the condition expression and add it to the condition block. */
1457 loc = code->expr1->where.lb ? gfc_get_location (&code->expr1->where)
1458 : input_location;
1459 stmt = fold_build3_loc (loc, COND_EXPR, void_type_node, if_se.expr, stmt,
1460 elsestmt);
1462 gfc_add_expr_to_block (&if_se.pre, stmt);
1464 /* Finish off this statement. */
1465 return gfc_finish_block (&if_se.pre);
1468 tree
1469 gfc_trans_if (gfc_code * code)
1471 stmtblock_t body;
1472 tree exit_label;
1474 /* Create exit label so it is available for trans'ing the body code. */
1475 exit_label = gfc_build_label_decl (NULL_TREE);
1476 code->exit_label = exit_label;
1478 /* Translate the actual code in code->block. */
1479 gfc_init_block (&body);
1480 gfc_add_expr_to_block (&body, gfc_trans_if_1 (code->block));
1482 /* Add exit label. */
1483 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
1485 return gfc_finish_block (&body);
1489 /* Translate an arithmetic IF expression.
1491 IF (cond) label1, label2, label3 translates to
1493 if (cond <= 0)
1495 if (cond < 0)
1496 goto label1;
1497 else // cond == 0
1498 goto label2;
1500 else // cond > 0
1501 goto label3;
1503 An optimized version can be generated in case of equal labels.
1504 E.g., if label1 is equal to label2, we can translate it to
1506 if (cond <= 0)
1507 goto label1;
1508 else
1509 goto label3;
1512 tree
1513 gfc_trans_arithmetic_if (gfc_code * code)
1515 gfc_se se;
1516 tree tmp;
1517 tree branch1;
1518 tree branch2;
1519 tree zero;
1521 /* Start a new block. */
1522 gfc_init_se (&se, NULL);
1523 gfc_start_block (&se.pre);
1525 /* Pre-evaluate COND. */
1526 gfc_conv_expr_val (&se, code->expr1);
1527 se.expr = gfc_evaluate_now (se.expr, &se.pre);
1529 /* Build something to compare with. */
1530 zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
1532 if (code->label1->value != code->label2->value)
1534 /* If (cond < 0) take branch1 else take branch2.
1535 First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases. */
1536 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1537 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
1539 if (code->label1->value != code->label3->value)
1540 tmp = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
1541 se.expr, zero);
1542 else
1543 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1544 se.expr, zero);
1546 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1547 tmp, branch1, branch2);
1549 else
1550 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1552 if (code->label1->value != code->label3->value
1553 && code->label2->value != code->label3->value)
1555 /* if (cond <= 0) take branch1 else take branch2. */
1556 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label3));
1557 tmp = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
1558 se.expr, zero);
1559 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1560 tmp, branch1, branch2);
1563 /* Append the COND_EXPR to the evaluation of COND, and return. */
1564 gfc_add_expr_to_block (&se.pre, branch1);
1565 return gfc_finish_block (&se.pre);
1569 /* Translate a CRITICAL block. */
1570 tree
1571 gfc_trans_critical (gfc_code *code)
1573 stmtblock_t block;
1574 tree tmp, token = NULL_TREE;
1576 gfc_start_block (&block);
1578 if (flag_coarray == GFC_FCOARRAY_LIB)
1580 tree zero_size = build_zero_cst (size_type_node);
1581 token = gfc_get_symbol_decl (code->resolved_sym);
1582 token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (token));
1583 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
1584 token, zero_size, integer_one_node,
1585 null_pointer_node, null_pointer_node,
1586 null_pointer_node, zero_size);
1587 gfc_add_expr_to_block (&block, tmp);
1589 /* It guarantees memory consistency within the same segment */
1590 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1591 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1592 gfc_build_string_const (1, ""),
1593 NULL_TREE, NULL_TREE,
1594 tree_cons (NULL_TREE, tmp, NULL_TREE),
1595 NULL_TREE);
1596 ASM_VOLATILE_P (tmp) = 1;
1598 gfc_add_expr_to_block (&block, tmp);
1601 tmp = gfc_trans_code (code->block->next);
1602 gfc_add_expr_to_block (&block, tmp);
1604 if (flag_coarray == GFC_FCOARRAY_LIB)
1606 tree zero_size = build_zero_cst (size_type_node);
1607 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
1608 token, zero_size, integer_one_node,
1609 null_pointer_node, null_pointer_node,
1610 zero_size);
1611 gfc_add_expr_to_block (&block, tmp);
1613 /* It guarantees memory consistency within the same segment */
1614 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1615 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1616 gfc_build_string_const (1, ""),
1617 NULL_TREE, NULL_TREE,
1618 tree_cons (NULL_TREE, tmp, NULL_TREE),
1619 NULL_TREE);
1620 ASM_VOLATILE_P (tmp) = 1;
1622 gfc_add_expr_to_block (&block, tmp);
1625 return gfc_finish_block (&block);
1629 /* Return true, when the class has a _len component. */
1631 static bool
1632 class_has_len_component (gfc_symbol *sym)
1634 gfc_component *comp = sym->ts.u.derived->components;
1635 while (comp)
1637 if (strcmp (comp->name, "_len") == 0)
1638 return true;
1639 comp = comp->next;
1641 return false;
1645 static void
1646 copy_descriptor (stmtblock_t *block, tree dst, tree src, int rank)
1648 int n;
1649 tree dim;
1650 tree tmp;
1651 tree tmp2;
1652 tree size;
1653 tree offset;
1655 offset = gfc_index_zero_node;
1657 /* Use memcpy to copy the descriptor. The size is the minimum of
1658 the sizes of 'src' and 'dst'. This avoids a non-trivial conversion. */
1659 tmp = TYPE_SIZE_UNIT (TREE_TYPE (src));
1660 tmp2 = TYPE_SIZE_UNIT (TREE_TYPE (dst));
1661 size = fold_build2_loc (input_location, MIN_EXPR,
1662 TREE_TYPE (tmp), tmp, tmp2);
1663 tmp = builtin_decl_explicit (BUILT_IN_MEMCPY);
1664 tmp = build_call_expr_loc (input_location, tmp, 3,
1665 gfc_build_addr_expr (NULL_TREE, dst),
1666 gfc_build_addr_expr (NULL_TREE, src),
1667 fold_convert (size_type_node, size));
1668 gfc_add_expr_to_block (block, tmp);
1670 /* Set the offset correctly. */
1671 for (n = 0; n < rank; n++)
1673 dim = gfc_rank_cst[n];
1674 tmp = gfc_conv_descriptor_lbound_get (src, dim);
1675 tmp2 = gfc_conv_descriptor_stride_get (src, dim);
1676 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
1677 tmp, tmp2);
1678 offset = fold_build2_loc (input_location, MINUS_EXPR,
1679 TREE_TYPE (offset), offset, tmp);
1680 offset = gfc_evaluate_now (offset, block);
1683 gfc_conv_descriptor_offset_set (block, dst, offset);
1687 /* Do proper initialization for ASSOCIATE names. */
1689 static void
1690 trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
1692 gfc_expr *e;
1693 tree tmp;
1694 bool class_target;
1695 bool unlimited;
1696 tree desc;
1697 tree offset;
1698 tree dim;
1699 int n;
1700 tree charlen;
1701 bool need_len_assign;
1702 bool whole_array = true;
1703 gfc_ref *ref;
1704 gfc_symbol *sym2;
1706 gcc_assert (sym->assoc);
1707 e = sym->assoc->target;
1709 class_target = (e->expr_type == EXPR_VARIABLE)
1710 && (gfc_is_class_scalar_expr (e)
1711 || gfc_is_class_array_ref (e, NULL));
1713 unlimited = UNLIMITED_POLY (e);
1715 for (ref = e->ref; ref; ref = ref->next)
1716 if (ref->type == REF_ARRAY
1717 && ref->u.ar.type == AR_FULL
1718 && ref->next)
1720 whole_array = false;
1721 break;
1724 /* Assignments to the string length need to be generated, when
1725 ( sym is a char array or
1726 sym has a _len component)
1727 and the associated expression is unlimited polymorphic, which is
1728 not (yet) correctly in 'unlimited', because for an already associated
1729 BT_DERIVED the u-poly flag is not set, i.e.,
1730 __tmp_CHARACTER_0_1 => w => arg
1731 ^ generated temp ^ from code, the w does not have the u-poly
1732 flag set, where UNLIMITED_POLY(e) expects it. */
1733 need_len_assign = ((unlimited || (e->ts.type == BT_DERIVED
1734 && e->ts.u.derived->attr.unlimited_polymorphic))
1735 && (sym->ts.type == BT_CHARACTER
1736 || ((sym->ts.type == BT_CLASS || sym->ts.type == BT_DERIVED)
1737 && class_has_len_component (sym)))
1738 && !sym->attr.select_rank_temporary);
1740 /* Do a `pointer assignment' with updated descriptor (or assign descriptor
1741 to array temporary) for arrays with either unknown shape or if associating
1742 to a variable. Select rank temporaries need somewhat different treatment
1743 to other associate names and case temporaries. This because the selector
1744 is assumed rank and so the offset in particular has to be changed. Also,
1745 the case temporaries carry both allocatable and target attributes if
1746 present in the selector. This means that an allocatation or change of
1747 association can occur and so has to be dealt with. */
1748 if (sym->attr.select_rank_temporary)
1750 gfc_se se;
1751 tree class_decl = NULL_TREE;
1752 int rank = 0;
1753 bool class_ptr;
1755 sym2 = e->symtree->n.sym;
1756 gfc_init_se (&se, NULL);
1757 if (e->ts.type == BT_CLASS)
1759 /* Go straight to the class data. */
1760 if (sym2->attr.dummy)
1762 class_decl = DECL_LANG_SPECIFIC (sym2->backend_decl) ?
1763 GFC_DECL_SAVED_DESCRIPTOR (sym2->backend_decl) :
1764 sym2->backend_decl;
1765 if (POINTER_TYPE_P (TREE_TYPE (class_decl)))
1766 class_decl = build_fold_indirect_ref_loc (input_location,
1767 class_decl);
1768 gcc_assert (GFC_CLASS_TYPE_P (TREE_TYPE (class_decl)));
1769 se.expr = gfc_class_data_get (class_decl);
1771 else
1773 class_decl = sym2->backend_decl;
1774 gfc_conv_expr_descriptor (&se, e);
1775 if (POINTER_TYPE_P (TREE_TYPE (se.expr)))
1776 se.expr = build_fold_indirect_ref_loc (input_location,
1777 se.expr);
1780 if (CLASS_DATA (sym)->as && CLASS_DATA (sym)->as->rank > 0)
1781 rank = CLASS_DATA (sym)->as->rank;
1783 else
1785 gfc_conv_expr_descriptor (&se, e);
1786 if (sym->as && sym->as->rank > 0)
1787 rank = sym->as->rank;
1790 desc = sym->backend_decl;
1792 /* The SELECT TYPE mechanisms turn class temporaries into pointers, which
1793 point to the selector. */
1794 class_ptr = class_decl != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (desc));
1795 if (class_ptr)
1797 tmp = gfc_create_var (TREE_TYPE (TREE_TYPE (desc)), "class");
1798 tmp = gfc_build_addr_expr (NULL, tmp);
1799 gfc_add_modify (&se.pre, desc, tmp);
1801 tmp = gfc_class_vptr_get (class_decl);
1802 gfc_add_modify (&se.pre, gfc_class_vptr_get (desc), tmp);
1803 if (UNLIMITED_POLY (sym))
1804 gfc_add_modify (&se.pre, gfc_class_len_get (desc),
1805 gfc_class_len_get (class_decl));
1807 desc = gfc_class_data_get (desc);
1810 /* SELECT RANK temporaries can carry the allocatable and pointer
1811 attributes so the selector descriptor must be copied in and
1812 copied out. */
1813 if (rank > 0)
1814 copy_descriptor (&se.pre, desc, se.expr, rank);
1815 else
1817 tmp = gfc_conv_descriptor_data_get (se.expr);
1818 gfc_add_modify (&se.pre, desc,
1819 fold_convert (TREE_TYPE (desc), tmp));
1822 /* Deal with associate_name => selector. Class associate names are
1823 treated in the same way as in SELECT TYPE. */
1824 sym2 = sym->assoc->target->symtree->n.sym;
1825 if (sym2->assoc && sym->assoc->target && sym2->ts.type != BT_CLASS)
1827 sym2 = sym2->assoc->target->symtree->n.sym;
1828 se.expr = sym2->backend_decl;
1830 if (POINTER_TYPE_P (TREE_TYPE (se.expr)))
1831 se.expr = build_fold_indirect_ref_loc (input_location,
1832 se.expr);
1835 /* There could have been reallocation. Copy descriptor back to the
1836 selector and update the offset. */
1837 if (sym->attr.allocatable || sym->attr.pointer
1838 || (sym->ts.type == BT_CLASS
1839 && (CLASS_DATA (sym)->attr.allocatable
1840 || CLASS_DATA (sym)->attr.pointer)))
1842 if (rank > 0)
1843 copy_descriptor (&se.post, se.expr, desc, rank);
1844 else
1845 gfc_conv_descriptor_data_set (&se.post, se.expr, desc);
1847 /* The dynamic type could have changed too. */
1848 if (sym->ts.type == BT_CLASS)
1850 tmp = sym->backend_decl;
1851 if (class_ptr)
1852 tmp = build_fold_indirect_ref_loc (input_location, tmp);
1853 gfc_add_modify (&se.post, gfc_class_vptr_get (class_decl),
1854 gfc_class_vptr_get (tmp));
1855 if (UNLIMITED_POLY (sym))
1856 gfc_add_modify (&se.post, gfc_class_len_get (class_decl),
1857 gfc_class_len_get (tmp));
1861 tmp = gfc_finish_block (&se.post);
1863 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre), tmp);
1865 /* Now all the other kinds of associate variable. */
1866 else if (sym->attr.dimension && !class_target
1867 && (sym->as->type == AS_DEFERRED || sym->assoc->variable))
1869 gfc_se se;
1870 tree desc;
1871 bool cst_array_ctor;
1873 desc = sym->backend_decl;
1874 cst_array_ctor = e->expr_type == EXPR_ARRAY
1875 && gfc_constant_array_constructor_p (e->value.constructor)
1876 && e->ts.type != BT_CHARACTER;
1878 /* If association is to an expression, evaluate it and create temporary.
1879 Otherwise, get descriptor of target for pointer assignment. */
1880 gfc_init_se (&se, NULL);
1882 if (sym->assoc->variable || cst_array_ctor)
1884 se.direct_byref = 1;
1885 se.use_offset = 1;
1886 se.expr = desc;
1887 GFC_DECL_PTR_ARRAY_P (sym->backend_decl) = 1;
1890 gfc_conv_expr_descriptor (&se, e);
1892 if (sym->ts.type == BT_CHARACTER
1893 && !se.direct_byref && sym->ts.deferred
1894 && !sym->attr.select_type_temporary
1895 && VAR_P (sym->ts.u.cl->backend_decl)
1896 && se.string_length != sym->ts.u.cl->backend_decl)
1898 gfc_add_modify (&se.pre, sym->ts.u.cl->backend_decl,
1899 fold_convert (TREE_TYPE (sym->ts.u.cl->backend_decl),
1900 se.string_length));
1903 /* If we didn't already do the pointer assignment, set associate-name
1904 descriptor to the one generated for the temporary. */
1905 if ((!sym->assoc->variable && !cst_array_ctor)
1906 || !whole_array)
1908 int dim;
1910 if (whole_array)
1911 gfc_add_modify (&se.pre, desc, se.expr);
1913 /* The generated descriptor has lower bound zero (as array
1914 temporary), shift bounds so we get lower bounds of 1. */
1915 for (dim = 0; dim < e->rank; ++dim)
1916 gfc_conv_shift_descriptor_lbound (&se.pre, desc,
1917 dim, gfc_index_one_node);
1920 /* If this is a subreference array pointer associate name use the
1921 associate variable element size for the value of 'span'. */
1922 if (sym->attr.subref_array_pointer && !se.direct_byref)
1924 gcc_assert (e->expr_type == EXPR_VARIABLE);
1925 tmp = gfc_get_array_span (se.expr, e);
1927 gfc_conv_descriptor_span_set (&se.pre, desc, tmp);
1930 if (e->expr_type == EXPR_FUNCTION
1931 && sym->ts.type == BT_DERIVED
1932 && sym->ts.u.derived
1933 && sym->ts.u.derived->attr.pdt_type)
1935 tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived, se.expr,
1936 sym->as->rank);
1937 gfc_add_expr_to_block (&se.post, tmp);
1940 /* Done, register stuff as init / cleanup code. */
1941 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1942 gfc_finish_block (&se.post));
1945 /* Temporaries, arising from TYPE IS, just need the descriptor of class
1946 arrays to be assigned directly. */
1947 else if (class_target && sym->attr.dimension
1948 && (sym->ts.type == BT_DERIVED || unlimited))
1950 gfc_se se;
1952 gfc_init_se (&se, NULL);
1953 se.descriptor_only = 1;
1954 /* In a select type the (temporary) associate variable shall point to
1955 a standard fortran array (lower bound == 1), but conv_expr ()
1956 just maps to the input array in the class object, whose lbound may
1957 be arbitrary. conv_expr_descriptor solves this by inserting a
1958 temporary array descriptor. */
1959 gfc_conv_expr_descriptor (&se, e);
1961 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
1962 || GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)));
1963 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)));
1965 if (GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)))
1967 if (INDIRECT_REF_P (se.expr))
1968 tmp = TREE_OPERAND (se.expr, 0);
1969 else
1970 tmp = se.expr;
1972 gfc_add_modify (&se.pre, sym->backend_decl,
1973 gfc_class_data_get (GFC_DECL_SAVED_DESCRIPTOR (tmp)));
1975 else
1976 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
1978 if (unlimited)
1980 /* Recover the dtype, which has been overwritten by the
1981 assignment from an unlimited polymorphic object. */
1982 tmp = gfc_conv_descriptor_dtype (sym->backend_decl);
1983 gfc_add_modify (&se.pre, tmp,
1984 gfc_get_dtype (TREE_TYPE (sym->backend_decl)));
1987 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1988 gfc_finish_block (&se.post));
1991 /* Do a scalar pointer assignment; this is for scalar variable targets. */
1992 else if (gfc_is_associate_pointer (sym))
1994 gfc_se se;
1996 gcc_assert (!sym->attr.dimension);
1998 gfc_init_se (&se, NULL);
2000 /* Class associate-names come this way because they are
2001 unconditionally associate pointers and the symbol is scalar. */
2002 if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.dimension)
2004 tree target_expr;
2005 /* For a class array we need a descriptor for the selector. */
2006 gfc_conv_expr_descriptor (&se, e);
2007 /* Needed to get/set the _len component below. */
2008 target_expr = se.expr;
2010 /* Obtain a temporary class container for the result. */
2011 gfc_conv_class_to_class (&se, e, sym->ts, false, true, false, false);
2012 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
2014 /* Set the offset. */
2015 desc = gfc_class_data_get (se.expr);
2016 offset = gfc_index_zero_node;
2017 for (n = 0; n < e->rank; n++)
2019 dim = gfc_rank_cst[n];
2020 tmp = fold_build2_loc (input_location, MULT_EXPR,
2021 gfc_array_index_type,
2022 gfc_conv_descriptor_stride_get (desc, dim),
2023 gfc_conv_descriptor_lbound_get (desc, dim));
2024 offset = fold_build2_loc (input_location, MINUS_EXPR,
2025 gfc_array_index_type,
2026 offset, tmp);
2028 if (need_len_assign)
2030 if (e->symtree
2031 && DECL_LANG_SPECIFIC (e->symtree->n.sym->backend_decl)
2032 && GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl)
2033 && TREE_CODE (target_expr) != COMPONENT_REF)
2034 /* Use the original class descriptor stored in the saved
2035 descriptor to get the target_expr. */
2036 target_expr =
2037 GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl);
2038 else
2039 /* Strip the _data component from the target_expr. */
2040 target_expr = TREE_OPERAND (target_expr, 0);
2041 /* Add a reference to the _len comp to the target expr. */
2042 tmp = gfc_class_len_get (target_expr);
2043 /* Get the component-ref for the temp structure's _len comp. */
2044 charlen = gfc_class_len_get (se.expr);
2045 /* Add the assign to the beginning of the block... */
2046 gfc_add_modify (&se.pre, charlen,
2047 fold_convert (TREE_TYPE (charlen), tmp));
2048 /* and the oposite way at the end of the block, to hand changes
2049 on the string length back. */
2050 gfc_add_modify (&se.post, tmp,
2051 fold_convert (TREE_TYPE (tmp), charlen));
2052 /* Length assignment done, prevent adding it again below. */
2053 need_len_assign = false;
2055 gfc_conv_descriptor_offset_set (&se.pre, desc, offset);
2057 else if (sym->ts.type == BT_CLASS && e->ts.type == BT_CLASS
2058 && CLASS_DATA (e)->attr.dimension)
2060 /* This is bound to be a class array element. */
2061 gfc_conv_expr_reference (&se, e);
2062 /* Get the _vptr component of the class object. */
2063 tmp = gfc_get_vptr_from_expr (se.expr);
2064 /* Obtain a temporary class container for the result. */
2065 gfc_conv_derived_to_class (&se, e, sym->ts, tmp, false, false);
2066 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
2068 else
2070 /* For BT_CLASS and BT_DERIVED, this boils down to a pointer assign,
2071 which has the string length included. For CHARACTERS it is still
2072 needed and will be done at the end of this routine. */
2073 gfc_conv_expr (&se, e);
2074 need_len_assign = need_len_assign && sym->ts.type == BT_CHARACTER;
2077 if (sym->ts.type == BT_CHARACTER
2078 && !sym->attr.select_type_temporary
2079 && VAR_P (sym->ts.u.cl->backend_decl)
2080 && se.string_length != sym->ts.u.cl->backend_decl)
2082 gfc_add_modify (&se.pre, sym->ts.u.cl->backend_decl,
2083 fold_convert (TREE_TYPE (sym->ts.u.cl->backend_decl),
2084 se.string_length));
2085 if (e->expr_type == EXPR_FUNCTION)
2087 tmp = gfc_call_free (sym->backend_decl);
2088 gfc_add_expr_to_block (&se.post, tmp);
2092 if (sym->ts.type == BT_CHARACTER && e->ts.type == BT_CHARACTER
2093 && POINTER_TYPE_P (TREE_TYPE (se.expr)))
2095 /* These are pointer types already. */
2096 tmp = fold_convert (TREE_TYPE (sym->backend_decl), se.expr);
2098 else
2100 tree ctree = gfc_get_class_from_expr (se.expr);
2101 tmp = TREE_TYPE (sym->backend_decl);
2103 /* Coarray scalar component expressions can emerge from
2104 the front end as array elements of the _data field. */
2105 if (sym->ts.type == BT_CLASS
2106 && e->ts.type == BT_CLASS && e->rank == 0
2107 && !GFC_CLASS_TYPE_P (TREE_TYPE (se.expr)) && ctree)
2109 tree stmp;
2110 tree dtmp;
2112 se.expr = ctree;
2113 dtmp = TREE_TYPE (TREE_TYPE (sym->backend_decl));
2114 ctree = gfc_create_var (dtmp, "class");
2116 stmp = gfc_class_data_get (se.expr);
2117 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (stmp)));
2119 /* Set the fields of the target class variable. */
2120 stmp = gfc_conv_descriptor_data_get (stmp);
2121 dtmp = gfc_class_data_get (ctree);
2122 stmp = fold_convert (TREE_TYPE (dtmp), stmp);
2123 gfc_add_modify (&se.pre, dtmp, stmp);
2124 stmp = gfc_class_vptr_get (se.expr);
2125 dtmp = gfc_class_vptr_get (ctree);
2126 stmp = fold_convert (TREE_TYPE (dtmp), stmp);
2127 gfc_add_modify (&se.pre, dtmp, stmp);
2128 if (UNLIMITED_POLY (sym))
2130 stmp = gfc_class_len_get (se.expr);
2131 dtmp = gfc_class_len_get (ctree);
2132 stmp = fold_convert (TREE_TYPE (dtmp), stmp);
2133 gfc_add_modify (&se.pre, dtmp, stmp);
2135 se.expr = ctree;
2137 tmp = gfc_build_addr_expr (tmp, se.expr);
2140 gfc_add_modify (&se.pre, sym->backend_decl, tmp);
2142 gfc_add_init_cleanup (block, gfc_finish_block( &se.pre),
2143 gfc_finish_block (&se.post));
2146 /* Do a simple assignment. This is for scalar expressions, where we
2147 can simply use expression assignment. */
2148 else
2150 gfc_expr *lhs;
2151 tree res;
2152 gfc_se se;
2154 gfc_init_se (&se, NULL);
2156 /* resolve.c converts some associate names to allocatable so that
2157 allocation can take place automatically in gfc_trans_assignment.
2158 The frontend prevents them from being either allocated,
2159 deallocated or reallocated. */
2160 if (sym->attr.allocatable)
2162 tmp = sym->backend_decl;
2163 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
2164 tmp = gfc_conv_descriptor_data_get (tmp);
2165 gfc_add_modify (&se.pre, tmp, fold_convert (TREE_TYPE (tmp),
2166 null_pointer_node));
2169 lhs = gfc_lval_expr_from_sym (sym);
2170 res = gfc_trans_assignment (lhs, e, false, true);
2171 gfc_add_expr_to_block (&se.pre, res);
2173 tmp = sym->backend_decl;
2174 if (e->expr_type == EXPR_FUNCTION
2175 && sym->ts.type == BT_DERIVED
2176 && sym->ts.u.derived
2177 && sym->ts.u.derived->attr.pdt_type)
2179 tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived, tmp,
2182 else if (e->expr_type == EXPR_FUNCTION
2183 && sym->ts.type == BT_CLASS
2184 && CLASS_DATA (sym)->ts.u.derived
2185 && CLASS_DATA (sym)->ts.u.derived->attr.pdt_type)
2187 tmp = gfc_class_data_get (tmp);
2188 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (sym)->ts.u.derived,
2189 tmp, 0);
2191 else if (sym->attr.allocatable)
2193 tmp = sym->backend_decl;
2195 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
2196 tmp = gfc_conv_descriptor_data_get (tmp);
2198 /* A simple call to free suffices here. */
2199 tmp = gfc_call_free (tmp);
2201 /* Make sure that reallocation on assignment cannot occur. */
2202 sym->attr.allocatable = 0;
2204 else
2205 tmp = NULL_TREE;
2207 res = gfc_finish_block (&se.pre);
2208 gfc_add_init_cleanup (block, res, tmp);
2209 gfc_free_expr (lhs);
2212 /* Set the stringlength, when needed. */
2213 if (need_len_assign)
2215 gfc_se se;
2216 gfc_init_se (&se, NULL);
2217 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
2219 /* Deferred strings are dealt with in the preceeding. */
2220 gcc_assert (!e->symtree->n.sym->ts.deferred);
2221 tmp = e->symtree->n.sym->ts.u.cl->backend_decl;
2223 else if (e->symtree->n.sym->attr.function
2224 && e->symtree->n.sym == e->symtree->n.sym->result)
2226 tmp = gfc_get_fake_result_decl (e->symtree->n.sym, 0);
2227 tmp = gfc_class_len_get (tmp);
2229 else
2230 tmp = gfc_class_len_get (gfc_get_symbol_decl (e->symtree->n.sym));
2231 gfc_get_symbol_decl (sym);
2232 charlen = sym->ts.type == BT_CHARACTER ? sym->ts.u.cl->backend_decl
2233 : gfc_class_len_get (sym->backend_decl);
2234 /* Prevent adding a noop len= len. */
2235 if (tmp != charlen)
2237 gfc_add_modify (&se.pre, charlen,
2238 fold_convert (TREE_TYPE (charlen), tmp));
2239 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
2240 gfc_finish_block (&se.post));
2246 /* Translate a BLOCK construct. This is basically what we would do for a
2247 procedure body. */
2249 tree
2250 gfc_trans_block_construct (gfc_code* code)
2252 gfc_namespace* ns;
2253 gfc_symbol* sym;
2254 gfc_wrapped_block block;
2255 tree exit_label;
2256 stmtblock_t body;
2257 gfc_association_list *ass;
2259 ns = code->ext.block.ns;
2260 gcc_assert (ns);
2261 sym = ns->proc_name;
2262 gcc_assert (sym);
2264 /* Process local variables. */
2265 gcc_assert (!sym->tlink);
2266 sym->tlink = sym;
2267 gfc_process_block_locals (ns);
2269 /* Generate code including exit-label. */
2270 gfc_init_block (&body);
2271 exit_label = gfc_build_label_decl (NULL_TREE);
2272 code->exit_label = exit_label;
2274 finish_oacc_declare (ns, sym, true);
2276 gfc_add_expr_to_block (&body, gfc_trans_code (ns->code));
2277 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
2279 /* Finish everything. */
2280 gfc_start_wrapped_block (&block, gfc_finish_block (&body));
2281 gfc_trans_deferred_vars (sym, &block);
2282 for (ass = code->ext.block.assoc; ass; ass = ass->next)
2283 trans_associate_var (ass->st->n.sym, &block);
2285 return gfc_finish_wrapped_block (&block);
2288 /* Translate the simple DO construct in a C-style manner.
2289 This is where the loop variable has integer type and step +-1.
2290 Following code will generate infinite loop in case where TO is INT_MAX
2291 (for +1 step) or INT_MIN (for -1 step)
2293 We translate a do loop from:
2295 DO dovar = from, to, step
2296 body
2297 END DO
2301 [Evaluate loop bounds and step]
2302 dovar = from;
2303 for (;;)
2305 if (dovar > to)
2306 goto end_label;
2307 body;
2308 cycle_label:
2309 dovar += step;
2311 end_label:
2313 This helps the optimizers by avoiding the extra pre-header condition and
2314 we save a register as we just compare the updated IV (not a value in
2315 previous step). */
2317 static tree
2318 gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
2319 tree from, tree to, tree step, tree exit_cond)
2321 stmtblock_t body;
2322 tree type;
2323 tree cond;
2324 tree tmp;
2325 tree saved_dovar = NULL;
2326 tree cycle_label;
2327 tree exit_label;
2328 location_t loc;
2329 type = TREE_TYPE (dovar);
2330 bool is_step_positive = tree_int_cst_sgn (step) > 0;
2332 loc = gfc_get_location (&code->ext.iterator->start->where);
2334 /* Initialize the DO variable: dovar = from. */
2335 gfc_add_modify_loc (loc, pblock, dovar,
2336 fold_convert (TREE_TYPE (dovar), from));
2338 /* Save value for do-tinkering checking. */
2339 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2341 saved_dovar = gfc_create_var (type, ".saved_dovar");
2342 gfc_add_modify_loc (loc, pblock, saved_dovar, dovar);
2345 /* Cycle and exit statements are implemented with gotos. */
2346 cycle_label = gfc_build_label_decl (NULL_TREE);
2347 exit_label = gfc_build_label_decl (NULL_TREE);
2349 /* Put the labels where they can be found later. See gfc_trans_do(). */
2350 code->cycle_label = cycle_label;
2351 code->exit_label = exit_label;
2353 /* Loop body. */
2354 gfc_start_block (&body);
2356 /* Exit the loop if there is an I/O result condition or error. */
2357 if (exit_cond)
2359 tmp = build1_v (GOTO_EXPR, exit_label);
2360 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2361 exit_cond, tmp,
2362 build_empty_stmt (loc));
2363 gfc_add_expr_to_block (&body, tmp);
2366 /* Evaluate the loop condition. */
2367 if (is_step_positive)
2368 cond = fold_build2_loc (loc, GT_EXPR, logical_type_node, dovar,
2369 fold_convert (type, to));
2370 else
2371 cond = fold_build2_loc (loc, LT_EXPR, logical_type_node, dovar,
2372 fold_convert (type, to));
2374 cond = gfc_evaluate_now_loc (loc, cond, &body);
2375 if (code->ext.iterator->unroll && cond != error_mark_node)
2376 cond
2377 = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2378 build_int_cst (integer_type_node, annot_expr_unroll_kind),
2379 build_int_cst (integer_type_node, code->ext.iterator->unroll));
2381 if (code->ext.iterator->ivdep && cond != error_mark_node)
2382 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2383 build_int_cst (integer_type_node, annot_expr_ivdep_kind),
2384 integer_zero_node);
2385 if (code->ext.iterator->vector && cond != error_mark_node)
2386 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2387 build_int_cst (integer_type_node, annot_expr_vector_kind),
2388 integer_zero_node);
2389 if (code->ext.iterator->novector && cond != error_mark_node)
2390 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2391 build_int_cst (integer_type_node, annot_expr_no_vector_kind),
2392 integer_zero_node);
2394 /* The loop exit. */
2395 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
2396 TREE_USED (exit_label) = 1;
2397 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2398 cond, tmp, build_empty_stmt (loc));
2399 gfc_add_expr_to_block (&body, tmp);
2401 /* Check whether the induction variable is equal to INT_MAX
2402 (respectively to INT_MIN). */
2403 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2405 tree boundary = is_step_positive ? TYPE_MAX_VALUE (type)
2406 : TYPE_MIN_VALUE (type);
2408 tmp = fold_build2_loc (loc, EQ_EXPR, logical_type_node,
2409 dovar, boundary);
2410 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2411 "Loop iterates infinitely");
2414 /* Main loop body. */
2415 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
2416 gfc_add_expr_to_block (&body, tmp);
2418 /* Label for cycle statements (if needed). */
2419 if (TREE_USED (cycle_label))
2421 tmp = build1_v (LABEL_EXPR, cycle_label);
2422 gfc_add_expr_to_block (&body, tmp);
2425 /* Check whether someone has modified the loop variable. */
2426 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2428 tmp = fold_build2_loc (loc, NE_EXPR, logical_type_node,
2429 dovar, saved_dovar);
2430 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2431 "Loop variable has been modified");
2434 /* Increment the loop variable. */
2435 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
2436 gfc_add_modify_loc (loc, &body, dovar, tmp);
2438 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2439 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
2441 /* Finish the loop body. */
2442 tmp = gfc_finish_block (&body);
2443 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
2445 gfc_add_expr_to_block (pblock, tmp);
2447 /* Add the exit label. */
2448 tmp = build1_v (LABEL_EXPR, exit_label);
2449 gfc_add_expr_to_block (pblock, tmp);
2451 return gfc_finish_block (pblock);
2454 /* Translate the DO construct. This obviously is one of the most
2455 important ones to get right with any compiler, but especially
2456 so for Fortran.
2458 We special case some loop forms as described in gfc_trans_simple_do.
2459 For other cases we implement them with a separate loop count,
2460 as described in the standard.
2462 We translate a do loop from:
2464 DO dovar = from, to, step
2465 body
2466 END DO
2470 [evaluate loop bounds and step]
2471 empty = (step > 0 ? to < from : to > from);
2472 countm1 = (to - from) / step;
2473 dovar = from;
2474 if (empty) goto exit_label;
2475 for (;;)
2477 body;
2478 cycle_label:
2479 dovar += step
2480 countm1t = countm1;
2481 countm1--;
2482 if (countm1t == 0) goto exit_label;
2484 exit_label:
2486 countm1 is an unsigned integer. It is equal to the loop count minus one,
2487 because the loop count itself can overflow. */
2489 tree
2490 gfc_trans_do (gfc_code * code, tree exit_cond)
2492 gfc_se se;
2493 tree dovar;
2494 tree saved_dovar = NULL;
2495 tree from;
2496 tree to;
2497 tree step;
2498 tree countm1;
2499 tree type;
2500 tree utype;
2501 tree cond;
2502 tree cycle_label;
2503 tree exit_label;
2504 tree tmp;
2505 stmtblock_t block;
2506 stmtblock_t body;
2507 location_t loc;
2509 gfc_start_block (&block);
2511 loc = gfc_get_location (&code->ext.iterator->start->where);
2513 /* Evaluate all the expressions in the iterator. */
2514 gfc_init_se (&se, NULL);
2515 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
2516 gfc_add_block_to_block (&block, &se.pre);
2517 dovar = se.expr;
2518 type = TREE_TYPE (dovar);
2520 gfc_init_se (&se, NULL);
2521 gfc_conv_expr_val (&se, code->ext.iterator->start);
2522 gfc_add_block_to_block (&block, &se.pre);
2523 from = gfc_evaluate_now (se.expr, &block);
2525 gfc_init_se (&se, NULL);
2526 gfc_conv_expr_val (&se, code->ext.iterator->end);
2527 gfc_add_block_to_block (&block, &se.pre);
2528 to = gfc_evaluate_now (se.expr, &block);
2530 gfc_init_se (&se, NULL);
2531 gfc_conv_expr_val (&se, code->ext.iterator->step);
2532 gfc_add_block_to_block (&block, &se.pre);
2533 step = gfc_evaluate_now (se.expr, &block);
2535 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2537 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, step,
2538 build_zero_cst (type));
2539 gfc_trans_runtime_check (true, false, tmp, &block, &code->loc,
2540 "DO step value is zero");
2543 /* Special case simple loops. */
2544 if (TREE_CODE (type) == INTEGER_TYPE
2545 && (integer_onep (step)
2546 || tree_int_cst_equal (step, integer_minus_one_node)))
2547 return gfc_trans_simple_do (code, &block, dovar, from, to, step,
2548 exit_cond);
2550 if (TREE_CODE (type) == INTEGER_TYPE)
2551 utype = unsigned_type_for (type);
2552 else
2553 utype = unsigned_type_for (gfc_array_index_type);
2554 countm1 = gfc_create_var (utype, "countm1");
2556 /* Cycle and exit statements are implemented with gotos. */
2557 cycle_label = gfc_build_label_decl (NULL_TREE);
2558 exit_label = gfc_build_label_decl (NULL_TREE);
2559 TREE_USED (exit_label) = 1;
2561 /* Put these labels where they can be found later. */
2562 code->cycle_label = cycle_label;
2563 code->exit_label = exit_label;
2565 /* Initialize the DO variable: dovar = from. */
2566 gfc_add_modify (&block, dovar, from);
2568 /* Save value for do-tinkering checking. */
2569 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2571 saved_dovar = gfc_create_var (type, ".saved_dovar");
2572 gfc_add_modify_loc (loc, &block, saved_dovar, dovar);
2575 /* Initialize loop count and jump to exit label if the loop is empty.
2576 This code is executed before we enter the loop body. We generate:
2577 if (step > 0)
2579 countm1 = (to - from) / step;
2580 if (to < from)
2581 goto exit_label;
2583 else
2585 countm1 = (from - to) / -step;
2586 if (to > from)
2587 goto exit_label;
2591 if (TREE_CODE (type) == INTEGER_TYPE)
2593 tree pos, neg, tou, fromu, stepu, tmp2;
2595 /* The distance from FROM to TO cannot always be represented in a signed
2596 type, thus use unsigned arithmetic, also to avoid any undefined
2597 overflow issues. */
2598 tou = fold_convert (utype, to);
2599 fromu = fold_convert (utype, from);
2600 stepu = fold_convert (utype, step);
2602 /* For a positive step, when to < from, exit, otherwise compute
2603 countm1 = ((unsigned)to - (unsigned)from) / (unsigned)step */
2604 tmp = fold_build2_loc (loc, LT_EXPR, logical_type_node, to, from);
2605 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2606 fold_build2_loc (loc, MINUS_EXPR, utype,
2607 tou, fromu),
2608 stepu);
2609 pos = build2 (COMPOUND_EXPR, void_type_node,
2610 fold_build2 (MODIFY_EXPR, void_type_node,
2611 countm1, tmp2),
2612 build3_loc (loc, COND_EXPR, void_type_node,
2613 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
2614 build1_loc (loc, GOTO_EXPR, void_type_node,
2615 exit_label), NULL_TREE));
2617 /* For a negative step, when to > from, exit, otherwise compute
2618 countm1 = ((unsigned)from - (unsigned)to) / -(unsigned)step */
2619 tmp = fold_build2_loc (loc, GT_EXPR, logical_type_node, to, from);
2620 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2621 fold_build2_loc (loc, MINUS_EXPR, utype,
2622 fromu, tou),
2623 fold_build1_loc (loc, NEGATE_EXPR, utype, stepu));
2624 neg = build2 (COMPOUND_EXPR, void_type_node,
2625 fold_build2 (MODIFY_EXPR, void_type_node,
2626 countm1, tmp2),
2627 build3_loc (loc, COND_EXPR, void_type_node,
2628 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
2629 build1_loc (loc, GOTO_EXPR, void_type_node,
2630 exit_label), NULL_TREE));
2632 tmp = fold_build2_loc (loc, LT_EXPR, logical_type_node, step,
2633 build_int_cst (TREE_TYPE (step), 0));
2634 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp, neg, pos);
2636 gfc_add_expr_to_block (&block, tmp);
2638 else
2640 tree pos_step;
2642 /* TODO: We could use the same width as the real type.
2643 This would probably cause more problems that it solves
2644 when we implement "long double" types. */
2646 tmp = fold_build2_loc (loc, MINUS_EXPR, type, to, from);
2647 tmp = fold_build2_loc (loc, RDIV_EXPR, type, tmp, step);
2648 tmp = fold_build1_loc (loc, FIX_TRUNC_EXPR, utype, tmp);
2649 gfc_add_modify (&block, countm1, tmp);
2651 /* We need a special check for empty loops:
2652 empty = (step > 0 ? to < from : to > from); */
2653 pos_step = fold_build2_loc (loc, GT_EXPR, logical_type_node, step,
2654 build_zero_cst (type));
2655 tmp = fold_build3_loc (loc, COND_EXPR, logical_type_node, pos_step,
2656 fold_build2_loc (loc, LT_EXPR,
2657 logical_type_node, to, from),
2658 fold_build2_loc (loc, GT_EXPR,
2659 logical_type_node, to, from));
2660 /* If the loop is empty, go directly to the exit label. */
2661 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp,
2662 build1_v (GOTO_EXPR, exit_label),
2663 build_empty_stmt (input_location));
2664 gfc_add_expr_to_block (&block, tmp);
2667 /* Loop body. */
2668 gfc_start_block (&body);
2670 /* Main loop body. */
2671 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
2672 gfc_add_expr_to_block (&body, tmp);
2674 /* Label for cycle statements (if needed). */
2675 if (TREE_USED (cycle_label))
2677 tmp = build1_v (LABEL_EXPR, cycle_label);
2678 gfc_add_expr_to_block (&body, tmp);
2681 /* Check whether someone has modified the loop variable. */
2682 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2684 tmp = fold_build2_loc (loc, NE_EXPR, logical_type_node, dovar,
2685 saved_dovar);
2686 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2687 "Loop variable has been modified");
2690 /* Exit the loop if there is an I/O result condition or error. */
2691 if (exit_cond)
2693 tmp = build1_v (GOTO_EXPR, exit_label);
2694 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2695 exit_cond, tmp,
2696 build_empty_stmt (input_location));
2697 gfc_add_expr_to_block (&body, tmp);
2700 /* Increment the loop variable. */
2701 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
2702 gfc_add_modify_loc (loc, &body, dovar, tmp);
2704 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2705 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
2707 /* Initialize countm1t. */
2708 tree countm1t = gfc_create_var (utype, "countm1t");
2709 gfc_add_modify_loc (loc, &body, countm1t, countm1);
2711 /* Decrement the loop count. */
2712 tmp = fold_build2_loc (loc, MINUS_EXPR, utype, countm1,
2713 build_int_cst (utype, 1));
2714 gfc_add_modify_loc (loc, &body, countm1, tmp);
2716 /* End with the loop condition. Loop until countm1t == 0. */
2717 cond = fold_build2_loc (loc, EQ_EXPR, logical_type_node, countm1t,
2718 build_int_cst (utype, 0));
2719 if (code->ext.iterator->unroll && cond != error_mark_node)
2720 cond
2721 = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2722 build_int_cst (integer_type_node, annot_expr_unroll_kind),
2723 build_int_cst (integer_type_node, code->ext.iterator->unroll));
2725 if (code->ext.iterator->ivdep && cond != error_mark_node)
2726 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2727 build_int_cst (integer_type_node, annot_expr_ivdep_kind),
2728 integer_zero_node);
2729 if (code->ext.iterator->vector && cond != error_mark_node)
2730 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2731 build_int_cst (integer_type_node, annot_expr_vector_kind),
2732 integer_zero_node);
2733 if (code->ext.iterator->novector && cond != error_mark_node)
2734 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2735 build_int_cst (integer_type_node, annot_expr_no_vector_kind),
2736 integer_zero_node);
2738 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
2739 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2740 cond, tmp, build_empty_stmt (loc));
2741 gfc_add_expr_to_block (&body, tmp);
2743 /* End of loop body. */
2744 tmp = gfc_finish_block (&body);
2746 /* The for loop itself. */
2747 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
2748 gfc_add_expr_to_block (&block, tmp);
2750 /* Add the exit label. */
2751 tmp = build1_v (LABEL_EXPR, exit_label);
2752 gfc_add_expr_to_block (&block, tmp);
2754 return gfc_finish_block (&block);
2758 /* Translate the DO WHILE construct.
2760 We translate
2762 DO WHILE (cond)
2763 body
2764 END DO
2768 for ( ; ; )
2770 pre_cond;
2771 if (! cond) goto exit_label;
2772 body;
2773 cycle_label:
2775 exit_label:
2777 Because the evaluation of the exit condition `cond' may have side
2778 effects, we can't do much for empty loop bodies. The backend optimizers
2779 should be smart enough to eliminate any dead loops. */
2781 tree
2782 gfc_trans_do_while (gfc_code * code)
2784 gfc_se cond;
2785 tree tmp;
2786 tree cycle_label;
2787 tree exit_label;
2788 stmtblock_t block;
2790 /* Everything we build here is part of the loop body. */
2791 gfc_start_block (&block);
2793 /* Cycle and exit statements are implemented with gotos. */
2794 cycle_label = gfc_build_label_decl (NULL_TREE);
2795 exit_label = gfc_build_label_decl (NULL_TREE);
2797 /* Put the labels where they can be found later. See gfc_trans_do(). */
2798 code->cycle_label = cycle_label;
2799 code->exit_label = exit_label;
2801 /* Create a GIMPLE version of the exit condition. */
2802 gfc_init_se (&cond, NULL);
2803 gfc_conv_expr_val (&cond, code->expr1);
2804 gfc_add_block_to_block (&block, &cond.pre);
2805 cond.expr = fold_build1_loc (gfc_get_location (&code->expr1->where),
2806 TRUTH_NOT_EXPR, TREE_TYPE (cond.expr),
2807 cond.expr);
2809 /* Build "IF (! cond) GOTO exit_label". */
2810 tmp = build1_v (GOTO_EXPR, exit_label);
2811 TREE_USED (exit_label) = 1;
2812 tmp = fold_build3_loc (gfc_get_location (&code->expr1->where), COND_EXPR,
2813 void_type_node, cond.expr, tmp,
2814 build_empty_stmt (gfc_get_location (
2815 &code->expr1->where)));
2816 gfc_add_expr_to_block (&block, tmp);
2818 /* The main body of the loop. */
2819 tmp = gfc_trans_code (code->block->next);
2820 gfc_add_expr_to_block (&block, tmp);
2822 /* Label for cycle statements (if needed). */
2823 if (TREE_USED (cycle_label))
2825 tmp = build1_v (LABEL_EXPR, cycle_label);
2826 gfc_add_expr_to_block (&block, tmp);
2829 /* End of loop body. */
2830 tmp = gfc_finish_block (&block);
2832 gfc_init_block (&block);
2833 /* Build the loop. */
2834 tmp = fold_build1_loc (gfc_get_location (&code->expr1->where), LOOP_EXPR,
2835 void_type_node, tmp);
2836 gfc_add_expr_to_block (&block, tmp);
2838 /* Add the exit label. */
2839 tmp = build1_v (LABEL_EXPR, exit_label);
2840 gfc_add_expr_to_block (&block, tmp);
2842 return gfc_finish_block (&block);
2846 /* Deal with the particular case of SELECT_TYPE, where the vtable
2847 addresses are used for the selection. Since these are not sorted,
2848 the selection has to be made by a series of if statements. */
2850 static tree
2851 gfc_trans_select_type_cases (gfc_code * code)
2853 gfc_code *c;
2854 gfc_case *cp;
2855 tree tmp;
2856 tree cond;
2857 tree low;
2858 tree high;
2859 gfc_se se;
2860 gfc_se cse;
2861 stmtblock_t block;
2862 stmtblock_t body;
2863 bool def = false;
2864 gfc_expr *e;
2865 gfc_start_block (&block);
2867 /* Calculate the switch expression. */
2868 gfc_init_se (&se, NULL);
2869 gfc_conv_expr_val (&se, code->expr1);
2870 gfc_add_block_to_block (&block, &se.pre);
2872 /* Generate an expression for the selector hash value, for
2873 use to resolve character cases. */
2874 e = gfc_copy_expr (code->expr1->value.function.actual->expr);
2875 gfc_add_hash_component (e);
2877 TREE_USED (code->exit_label) = 0;
2879 repeat:
2880 for (c = code->block; c; c = c->block)
2882 cp = c->ext.block.case_list;
2884 /* Assume it's the default case. */
2885 low = NULL_TREE;
2886 high = NULL_TREE;
2887 tmp = NULL_TREE;
2889 /* Put the default case at the end. */
2890 if ((!def && !cp->low) || (def && cp->low))
2891 continue;
2893 if (cp->low && (cp->ts.type == BT_CLASS
2894 || cp->ts.type == BT_DERIVED))
2896 gfc_init_se (&cse, NULL);
2897 gfc_conv_expr_val (&cse, cp->low);
2898 gfc_add_block_to_block (&block, &cse.pre);
2899 low = cse.expr;
2901 else if (cp->ts.type != BT_UNKNOWN)
2903 gcc_assert (cp->high);
2904 gfc_init_se (&cse, NULL);
2905 gfc_conv_expr_val (&cse, cp->high);
2906 gfc_add_block_to_block (&block, &cse.pre);
2907 high = cse.expr;
2910 gfc_init_block (&body);
2912 /* Add the statements for this case. */
2913 tmp = gfc_trans_code (c->next);
2914 gfc_add_expr_to_block (&body, tmp);
2916 /* Break to the end of the SELECT TYPE construct. The default
2917 case just falls through. */
2918 if (!def)
2920 TREE_USED (code->exit_label) = 1;
2921 tmp = build1_v (GOTO_EXPR, code->exit_label);
2922 gfc_add_expr_to_block (&body, tmp);
2925 tmp = gfc_finish_block (&body);
2927 if (low != NULL_TREE)
2929 /* Compare vtable pointers. */
2930 cond = fold_build2_loc (input_location, EQ_EXPR,
2931 TREE_TYPE (se.expr), se.expr, low);
2932 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2933 cond, tmp,
2934 build_empty_stmt (input_location));
2936 else if (high != NULL_TREE)
2938 /* Compare hash values for character cases. */
2939 gfc_init_se (&cse, NULL);
2940 gfc_conv_expr_val (&cse, e);
2941 gfc_add_block_to_block (&block, &cse.pre);
2943 cond = fold_build2_loc (input_location, EQ_EXPR,
2944 TREE_TYPE (se.expr), high, cse.expr);
2945 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2946 cond, tmp,
2947 build_empty_stmt (input_location));
2950 gfc_add_expr_to_block (&block, tmp);
2953 if (!def)
2955 def = true;
2956 goto repeat;
2959 gfc_free_expr (e);
2961 return gfc_finish_block (&block);
2965 /* Translate the SELECT CASE construct for INTEGER case expressions,
2966 without killing all potential optimizations. The problem is that
2967 Fortran allows unbounded cases, but the back-end does not, so we
2968 need to intercept those before we enter the equivalent SWITCH_EXPR
2969 we can build.
2971 For example, we translate this,
2973 SELECT CASE (expr)
2974 CASE (:100,101,105:115)
2975 block_1
2976 CASE (190:199,200:)
2977 block_2
2978 CASE (300)
2979 block_3
2980 CASE DEFAULT
2981 block_4
2982 END SELECT
2984 to the GENERIC equivalent,
2986 switch (expr)
2988 case (minimum value for typeof(expr) ... 100:
2989 case 101:
2990 case 105 ... 114:
2991 block1:
2992 goto end_label;
2994 case 200 ... (maximum value for typeof(expr):
2995 case 190 ... 199:
2996 block2;
2997 goto end_label;
2999 case 300:
3000 block_3;
3001 goto end_label;
3003 default:
3004 block_4;
3005 goto end_label;
3008 end_label: */
3010 static tree
3011 gfc_trans_integer_select (gfc_code * code)
3013 gfc_code *c;
3014 gfc_case *cp;
3015 tree end_label;
3016 tree tmp;
3017 gfc_se se;
3018 stmtblock_t block;
3019 stmtblock_t body;
3021 gfc_start_block (&block);
3023 /* Calculate the switch expression. */
3024 gfc_init_se (&se, NULL);
3025 gfc_conv_expr_val (&se, code->expr1);
3026 gfc_add_block_to_block (&block, &se.pre);
3028 end_label = gfc_build_label_decl (NULL_TREE);
3030 gfc_init_block (&body);
3032 for (c = code->block; c; c = c->block)
3034 for (cp = c->ext.block.case_list; cp; cp = cp->next)
3036 tree low, high;
3037 tree label;
3039 /* Assume it's the default case. */
3040 low = high = NULL_TREE;
3042 if (cp->low)
3044 low = gfc_conv_mpz_to_tree (cp->low->value.integer,
3045 cp->low->ts.kind);
3047 /* If there's only a lower bound, set the high bound to the
3048 maximum value of the case expression. */
3049 if (!cp->high)
3050 high = TYPE_MAX_VALUE (TREE_TYPE (se.expr));
3053 if (cp->high)
3055 /* Three cases are possible here:
3057 1) There is no lower bound, e.g. CASE (:N).
3058 2) There is a lower bound .NE. high bound, that is
3059 a case range, e.g. CASE (N:M) where M>N (we make
3060 sure that M>N during type resolution).
3061 3) There is a lower bound, and it has the same value
3062 as the high bound, e.g. CASE (N:N). This is our
3063 internal representation of CASE(N).
3065 In the first and second case, we need to set a value for
3066 high. In the third case, we don't because the GCC middle
3067 end represents a single case value by just letting high be
3068 a NULL_TREE. We can't do that because we need to be able
3069 to represent unbounded cases. */
3071 if (!cp->low
3072 || (mpz_cmp (cp->low->value.integer,
3073 cp->high->value.integer) != 0))
3074 high = gfc_conv_mpz_to_tree (cp->high->value.integer,
3075 cp->high->ts.kind);
3077 /* Unbounded case. */
3078 if (!cp->low)
3079 low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
3082 /* Build a label. */
3083 label = gfc_build_label_decl (NULL_TREE);
3085 /* Add this case label.
3086 Add parameter 'label', make it match GCC backend. */
3087 tmp = build_case_label (low, high, label);
3088 gfc_add_expr_to_block (&body, tmp);
3091 /* Add the statements for this case. */
3092 tmp = gfc_trans_code (c->next);
3093 gfc_add_expr_to_block (&body, tmp);
3095 /* Break to the end of the construct. */
3096 tmp = build1_v (GOTO_EXPR, end_label);
3097 gfc_add_expr_to_block (&body, tmp);
3100 tmp = gfc_finish_block (&body);
3101 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE, se.expr, tmp);
3102 gfc_add_expr_to_block (&block, tmp);
3104 tmp = build1_v (LABEL_EXPR, end_label);
3105 gfc_add_expr_to_block (&block, tmp);
3107 return gfc_finish_block (&block);
3111 /* Translate the SELECT CASE construct for LOGICAL case expressions.
3113 There are only two cases possible here, even though the standard
3114 does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
3115 .FALSE., and DEFAULT.
3117 We never generate more than two blocks here. Instead, we always
3118 try to eliminate the DEFAULT case. This way, we can translate this
3119 kind of SELECT construct to a simple
3121 if {} else {};
3123 expression in GENERIC. */
3125 static tree
3126 gfc_trans_logical_select (gfc_code * code)
3128 gfc_code *c;
3129 gfc_code *t, *f, *d;
3130 gfc_case *cp;
3131 gfc_se se;
3132 stmtblock_t block;
3134 /* Assume we don't have any cases at all. */
3135 t = f = d = NULL;
3137 /* Now see which ones we actually do have. We can have at most two
3138 cases in a single case list: one for .TRUE. and one for .FALSE.
3139 The default case is always separate. If the cases for .TRUE. and
3140 .FALSE. are in the same case list, the block for that case list
3141 always executed, and we don't generate code a COND_EXPR. */
3142 for (c = code->block; c; c = c->block)
3144 for (cp = c->ext.block.case_list; cp; cp = cp->next)
3146 if (cp->low)
3148 if (cp->low->value.logical == 0) /* .FALSE. */
3149 f = c;
3150 else /* if (cp->value.logical != 0), thus .TRUE. */
3151 t = c;
3153 else
3154 d = c;
3158 /* Start a new block. */
3159 gfc_start_block (&block);
3161 /* Calculate the switch expression. We always need to do this
3162 because it may have side effects. */
3163 gfc_init_se (&se, NULL);
3164 gfc_conv_expr_val (&se, code->expr1);
3165 gfc_add_block_to_block (&block, &se.pre);
3167 if (t == f && t != NULL)
3169 /* Cases for .TRUE. and .FALSE. are in the same block. Just
3170 translate the code for these cases, append it to the current
3171 block. */
3172 gfc_add_expr_to_block (&block, gfc_trans_code (t->next));
3174 else
3176 tree true_tree, false_tree, stmt;
3178 true_tree = build_empty_stmt (input_location);
3179 false_tree = build_empty_stmt (input_location);
3181 /* If we have a case for .TRUE. and for .FALSE., discard the default case.
3182 Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
3183 make the missing case the default case. */
3184 if (t != NULL && f != NULL)
3185 d = NULL;
3186 else if (d != NULL)
3188 if (t == NULL)
3189 t = d;
3190 else
3191 f = d;
3194 /* Translate the code for each of these blocks, and append it to
3195 the current block. */
3196 if (t != NULL)
3197 true_tree = gfc_trans_code (t->next);
3199 if (f != NULL)
3200 false_tree = gfc_trans_code (f->next);
3202 stmt = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3203 se.expr, true_tree, false_tree);
3204 gfc_add_expr_to_block (&block, stmt);
3207 return gfc_finish_block (&block);
3211 /* The jump table types are stored in static variables to avoid
3212 constructing them from scratch every single time. */
3213 static GTY(()) tree select_struct[2];
3215 /* Translate the SELECT CASE construct for CHARACTER case expressions.
3216 Instead of generating compares and jumps, it is far simpler to
3217 generate a data structure describing the cases in order and call a
3218 library subroutine that locates the right case.
3219 This is particularly true because this is the only case where we
3220 might have to dispose of a temporary.
3221 The library subroutine returns a pointer to jump to or NULL if no
3222 branches are to be taken. */
3224 static tree
3225 gfc_trans_character_select (gfc_code *code)
3227 tree init, end_label, tmp, type, case_num, label, fndecl;
3228 stmtblock_t block, body;
3229 gfc_case *cp, *d;
3230 gfc_code *c;
3231 gfc_se se, expr1se;
3232 int n, k;
3233 vec<constructor_elt, va_gc> *inits = NULL;
3235 tree pchartype = gfc_get_pchar_type (code->expr1->ts.kind);
3237 /* The jump table types are stored in static variables to avoid
3238 constructing them from scratch every single time. */
3239 static tree ss_string1[2], ss_string1_len[2];
3240 static tree ss_string2[2], ss_string2_len[2];
3241 static tree ss_target[2];
3243 cp = code->block->ext.block.case_list;
3244 while (cp->left != NULL)
3245 cp = cp->left;
3247 /* Generate the body */
3248 gfc_start_block (&block);
3249 gfc_init_se (&expr1se, NULL);
3250 gfc_conv_expr_reference (&expr1se, code->expr1);
3252 gfc_add_block_to_block (&block, &expr1se.pre);
3254 end_label = gfc_build_label_decl (NULL_TREE);
3256 gfc_init_block (&body);
3258 /* Attempt to optimize length 1 selects. */
3259 if (integer_onep (expr1se.string_length))
3261 for (d = cp; d; d = d->right)
3263 gfc_charlen_t i;
3264 if (d->low)
3266 gcc_assert (d->low->expr_type == EXPR_CONSTANT
3267 && d->low->ts.type == BT_CHARACTER);
3268 if (d->low->value.character.length > 1)
3270 for (i = 1; i < d->low->value.character.length; i++)
3271 if (d->low->value.character.string[i] != ' ')
3272 break;
3273 if (i != d->low->value.character.length)
3275 if (optimize && d->high && i == 1)
3277 gcc_assert (d->high->expr_type == EXPR_CONSTANT
3278 && d->high->ts.type == BT_CHARACTER);
3279 if (d->high->value.character.length > 1
3280 && (d->low->value.character.string[0]
3281 == d->high->value.character.string[0])
3282 && d->high->value.character.string[1] != ' '
3283 && ((d->low->value.character.string[1] < ' ')
3284 == (d->high->value.character.string[1]
3285 < ' ')))
3286 continue;
3288 break;
3292 if (d->high)
3294 gcc_assert (d->high->expr_type == EXPR_CONSTANT
3295 && d->high->ts.type == BT_CHARACTER);
3296 if (d->high->value.character.length > 1)
3298 for (i = 1; i < d->high->value.character.length; i++)
3299 if (d->high->value.character.string[i] != ' ')
3300 break;
3301 if (i != d->high->value.character.length)
3302 break;
3306 if (d == NULL)
3308 tree ctype = gfc_get_char_type (code->expr1->ts.kind);
3310 for (c = code->block; c; c = c->block)
3312 for (cp = c->ext.block.case_list; cp; cp = cp->next)
3314 tree low, high;
3315 tree label;
3316 gfc_char_t r;
3318 /* Assume it's the default case. */
3319 low = high = NULL_TREE;
3321 if (cp->low)
3323 /* CASE ('ab') or CASE ('ab':'az') will never match
3324 any length 1 character. */
3325 if (cp->low->value.character.length > 1
3326 && cp->low->value.character.string[1] != ' ')
3327 continue;
3329 if (cp->low->value.character.length > 0)
3330 r = cp->low->value.character.string[0];
3331 else
3332 r = ' ';
3333 low = build_int_cst (ctype, r);
3335 /* If there's only a lower bound, set the high bound
3336 to the maximum value of the case expression. */
3337 if (!cp->high)
3338 high = TYPE_MAX_VALUE (ctype);
3341 if (cp->high)
3343 if (!cp->low
3344 || (cp->low->value.character.string[0]
3345 != cp->high->value.character.string[0]))
3347 if (cp->high->value.character.length > 0)
3348 r = cp->high->value.character.string[0];
3349 else
3350 r = ' ';
3351 high = build_int_cst (ctype, r);
3354 /* Unbounded case. */
3355 if (!cp->low)
3356 low = TYPE_MIN_VALUE (ctype);
3359 /* Build a label. */
3360 label = gfc_build_label_decl (NULL_TREE);
3362 /* Add this case label.
3363 Add parameter 'label', make it match GCC backend. */
3364 tmp = build_case_label (low, high, label);
3365 gfc_add_expr_to_block (&body, tmp);
3368 /* Add the statements for this case. */
3369 tmp = gfc_trans_code (c->next);
3370 gfc_add_expr_to_block (&body, tmp);
3372 /* Break to the end of the construct. */
3373 tmp = build1_v (GOTO_EXPR, end_label);
3374 gfc_add_expr_to_block (&body, tmp);
3377 tmp = gfc_string_to_single_character (expr1se.string_length,
3378 expr1se.expr,
3379 code->expr1->ts.kind);
3380 case_num = gfc_create_var (ctype, "case_num");
3381 gfc_add_modify (&block, case_num, tmp);
3383 gfc_add_block_to_block (&block, &expr1se.post);
3385 tmp = gfc_finish_block (&body);
3386 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE,
3387 case_num, tmp);
3388 gfc_add_expr_to_block (&block, tmp);
3390 tmp = build1_v (LABEL_EXPR, end_label);
3391 gfc_add_expr_to_block (&block, tmp);
3393 return gfc_finish_block (&block);
3397 if (code->expr1->ts.kind == 1)
3398 k = 0;
3399 else if (code->expr1->ts.kind == 4)
3400 k = 1;
3401 else
3402 gcc_unreachable ();
3404 if (select_struct[k] == NULL)
3406 tree *chain = NULL;
3407 select_struct[k] = make_node (RECORD_TYPE);
3409 if (code->expr1->ts.kind == 1)
3410 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char1");
3411 else if (code->expr1->ts.kind == 4)
3412 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char4");
3413 else
3414 gcc_unreachable ();
3416 #undef ADD_FIELD
3417 #define ADD_FIELD(NAME, TYPE) \
3418 ss_##NAME[k] = gfc_add_field_to_struct (select_struct[k], \
3419 get_identifier (stringize(NAME)), \
3420 TYPE, \
3421 &chain)
3423 ADD_FIELD (string1, pchartype);
3424 ADD_FIELD (string1_len, gfc_charlen_type_node);
3426 ADD_FIELD (string2, pchartype);
3427 ADD_FIELD (string2_len, gfc_charlen_type_node);
3429 ADD_FIELD (target, integer_type_node);
3430 #undef ADD_FIELD
3432 gfc_finish_type (select_struct[k]);
3435 n = 0;
3436 for (d = cp; d; d = d->right)
3437 d->n = n++;
3439 for (c = code->block; c; c = c->block)
3441 for (d = c->ext.block.case_list; d; d = d->next)
3443 label = gfc_build_label_decl (NULL_TREE);
3444 tmp = build_case_label ((d->low == NULL && d->high == NULL)
3445 ? NULL
3446 : build_int_cst (integer_type_node, d->n),
3447 NULL, label);
3448 gfc_add_expr_to_block (&body, tmp);
3451 tmp = gfc_trans_code (c->next);
3452 gfc_add_expr_to_block (&body, tmp);
3454 tmp = build1_v (GOTO_EXPR, end_label);
3455 gfc_add_expr_to_block (&body, tmp);
3458 /* Generate the structure describing the branches */
3459 for (d = cp; d; d = d->right)
3461 vec<constructor_elt, va_gc> *node = NULL;
3463 gfc_init_se (&se, NULL);
3465 if (d->low == NULL)
3467 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], null_pointer_node);
3468 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], build_zero_cst (gfc_charlen_type_node));
3470 else
3472 gfc_conv_expr_reference (&se, d->low);
3474 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], se.expr);
3475 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], se.string_length);
3478 if (d->high == NULL)
3480 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], null_pointer_node);
3481 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], build_zero_cst (gfc_charlen_type_node));
3483 else
3485 gfc_init_se (&se, NULL);
3486 gfc_conv_expr_reference (&se, d->high);
3488 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], se.expr);
3489 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], se.string_length);
3492 CONSTRUCTOR_APPEND_ELT (node, ss_target[k],
3493 build_int_cst (integer_type_node, d->n));
3495 tmp = build_constructor (select_struct[k], node);
3496 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, tmp);
3499 type = build_array_type (select_struct[k],
3500 build_index_type (size_int (n-1)));
3502 init = build_constructor (type, inits);
3503 TREE_CONSTANT (init) = 1;
3504 TREE_STATIC (init) = 1;
3505 /* Create a static variable to hold the jump table. */
3506 tmp = gfc_create_var (type, "jumptable");
3507 TREE_CONSTANT (tmp) = 1;
3508 TREE_STATIC (tmp) = 1;
3509 TREE_READONLY (tmp) = 1;
3510 DECL_INITIAL (tmp) = init;
3511 init = tmp;
3513 /* Build the library call */
3514 init = gfc_build_addr_expr (pvoid_type_node, init);
3516 if (code->expr1->ts.kind == 1)
3517 fndecl = gfor_fndecl_select_string;
3518 else if (code->expr1->ts.kind == 4)
3519 fndecl = gfor_fndecl_select_string_char4;
3520 else
3521 gcc_unreachable ();
3523 tmp = build_call_expr_loc (input_location,
3524 fndecl, 4, init,
3525 build_int_cst (gfc_charlen_type_node, n),
3526 expr1se.expr, expr1se.string_length);
3527 case_num = gfc_create_var (integer_type_node, "case_num");
3528 gfc_add_modify (&block, case_num, tmp);
3530 gfc_add_block_to_block (&block, &expr1se.post);
3532 tmp = gfc_finish_block (&body);
3533 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE,
3534 case_num, tmp);
3535 gfc_add_expr_to_block (&block, tmp);
3537 tmp = build1_v (LABEL_EXPR, end_label);
3538 gfc_add_expr_to_block (&block, tmp);
3540 return gfc_finish_block (&block);
3544 /* Translate the three variants of the SELECT CASE construct.
3546 SELECT CASEs with INTEGER case expressions can be translated to an
3547 equivalent GENERIC switch statement, and for LOGICAL case
3548 expressions we build one or two if-else compares.
3550 SELECT CASEs with CHARACTER case expressions are a whole different
3551 story, because they don't exist in GENERIC. So we sort them and
3552 do a binary search at runtime.
3554 Fortran has no BREAK statement, and it does not allow jumps from
3555 one case block to another. That makes things a lot easier for
3556 the optimizers. */
3558 tree
3559 gfc_trans_select (gfc_code * code)
3561 stmtblock_t block;
3562 tree body;
3563 tree exit_label;
3565 gcc_assert (code && code->expr1);
3566 gfc_init_block (&block);
3568 /* Build the exit label and hang it in. */
3569 exit_label = gfc_build_label_decl (NULL_TREE);
3570 code->exit_label = exit_label;
3572 /* Empty SELECT constructs are legal. */
3573 if (code->block == NULL)
3574 body = build_empty_stmt (input_location);
3576 /* Select the correct translation function. */
3577 else
3578 switch (code->expr1->ts.type)
3580 case BT_LOGICAL:
3581 body = gfc_trans_logical_select (code);
3582 break;
3584 case BT_INTEGER:
3585 body = gfc_trans_integer_select (code);
3586 break;
3588 case BT_CHARACTER:
3589 body = gfc_trans_character_select (code);
3590 break;
3592 default:
3593 gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
3594 /* Not reached */
3597 /* Build everything together. */
3598 gfc_add_expr_to_block (&block, body);
3599 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3601 return gfc_finish_block (&block);
3604 tree
3605 gfc_trans_select_type (gfc_code * code)
3607 stmtblock_t block;
3608 tree body;
3609 tree exit_label;
3611 gcc_assert (code && code->expr1);
3612 gfc_init_block (&block);
3614 /* Build the exit label and hang it in. */
3615 exit_label = gfc_build_label_decl (NULL_TREE);
3616 code->exit_label = exit_label;
3618 /* Empty SELECT constructs are legal. */
3619 if (code->block == NULL)
3620 body = build_empty_stmt (input_location);
3621 else
3622 body = gfc_trans_select_type_cases (code);
3624 /* Build everything together. */
3625 gfc_add_expr_to_block (&block, body);
3627 if (TREE_USED (exit_label))
3628 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3630 return gfc_finish_block (&block);
3634 static tree
3635 gfc_trans_select_rank_cases (gfc_code * code)
3637 gfc_code *c;
3638 gfc_case *cp;
3639 tree tmp;
3640 tree cond;
3641 tree low;
3642 tree sexpr;
3643 tree rank;
3644 tree rank_minus_one;
3645 tree minus_one;
3646 gfc_se se;
3647 gfc_se cse;
3648 stmtblock_t block;
3649 stmtblock_t body;
3650 bool def = false;
3652 gfc_start_block (&block);
3654 /* Calculate the switch expression. */
3655 gfc_init_se (&se, NULL);
3656 gfc_conv_expr_descriptor (&se, code->expr1);
3657 rank = gfc_conv_descriptor_rank (se.expr);
3658 rank = gfc_evaluate_now (rank, &block);
3659 minus_one = build_int_cst (TREE_TYPE (rank), -1);
3660 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3661 gfc_array_index_type,
3662 fold_convert (gfc_array_index_type, rank),
3663 build_int_cst (gfc_array_index_type, 1));
3664 rank_minus_one = gfc_evaluate_now (tmp, &block);
3665 tmp = gfc_conv_descriptor_ubound_get (se.expr, rank_minus_one);
3666 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
3667 tmp, build_int_cst (TREE_TYPE (tmp), -1));
3668 tmp = fold_build3_loc (input_location, COND_EXPR,
3669 TREE_TYPE (rank), cond,
3670 rank, minus_one);
3671 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
3672 rank, build_int_cst (TREE_TYPE (rank), 0));
3673 sexpr = fold_build3_loc (input_location, COND_EXPR,
3674 TREE_TYPE (rank), cond,
3675 rank, tmp);
3676 sexpr = gfc_evaluate_now (sexpr, &block);
3677 TREE_USED (code->exit_label) = 0;
3679 repeat:
3680 for (c = code->block; c; c = c->block)
3682 cp = c->ext.block.case_list;
3684 /* Assume it's the default case. */
3685 low = NULL_TREE;
3686 tmp = NULL_TREE;
3688 /* Put the default case at the end. */
3689 if ((!def && !cp->low) || (def && cp->low))
3690 continue;
3692 if (cp->low)
3694 gfc_init_se (&cse, NULL);
3695 gfc_conv_expr_val (&cse, cp->low);
3696 gfc_add_block_to_block (&block, &cse.pre);
3697 low = cse.expr;
3700 gfc_init_block (&body);
3702 /* Add the statements for this case. */
3703 tmp = gfc_trans_code (c->next);
3704 gfc_add_expr_to_block (&body, tmp);
3706 /* Break to the end of the SELECT RANK construct. The default
3707 case just falls through. */
3708 if (!def)
3710 TREE_USED (code->exit_label) = 1;
3711 tmp = build1_v (GOTO_EXPR, code->exit_label);
3712 gfc_add_expr_to_block (&body, tmp);
3715 tmp = gfc_finish_block (&body);
3717 if (low != NULL_TREE)
3719 cond = fold_build2_loc (input_location, EQ_EXPR,
3720 TREE_TYPE (sexpr), sexpr,
3721 fold_convert (TREE_TYPE (sexpr), low));
3722 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3723 cond, tmp,
3724 build_empty_stmt (input_location));
3727 gfc_add_expr_to_block (&block, tmp);
3730 if (!def)
3732 def = true;
3733 goto repeat;
3736 return gfc_finish_block (&block);
3740 tree
3741 gfc_trans_select_rank (gfc_code * code)
3743 stmtblock_t block;
3744 tree body;
3745 tree exit_label;
3747 gcc_assert (code && code->expr1);
3748 gfc_init_block (&block);
3750 /* Build the exit label and hang it in. */
3751 exit_label = gfc_build_label_decl (NULL_TREE);
3752 code->exit_label = exit_label;
3754 /* Empty SELECT constructs are legal. */
3755 if (code->block == NULL)
3756 body = build_empty_stmt (input_location);
3757 else
3758 body = gfc_trans_select_rank_cases (code);
3760 /* Build everything together. */
3761 gfc_add_expr_to_block (&block, body);
3763 if (TREE_USED (exit_label))
3764 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3766 return gfc_finish_block (&block);
3770 /* Traversal function to substitute a replacement symtree if the symbol
3771 in the expression is the same as that passed. f == 2 signals that
3772 that variable itself is not to be checked - only the references.
3773 This group of functions is used when the variable expression in a
3774 FORALL assignment has internal references. For example:
3775 FORALL (i = 1:4) p(p(i)) = i
3776 The only recourse here is to store a copy of 'p' for the index
3777 expression. */
3779 static gfc_symtree *new_symtree;
3780 static gfc_symtree *old_symtree;
3782 static bool
3783 forall_replace (gfc_expr *expr, gfc_symbol *sym, int *f)
3785 if (expr->expr_type != EXPR_VARIABLE)
3786 return false;
3788 if (*f == 2)
3789 *f = 1;
3790 else if (expr->symtree->n.sym == sym)
3791 expr->symtree = new_symtree;
3793 return false;
3796 static void
3797 forall_replace_symtree (gfc_expr *e, gfc_symbol *sym, int f)
3799 gfc_traverse_expr (e, sym, forall_replace, f);
3802 static bool
3803 forall_restore (gfc_expr *expr,
3804 gfc_symbol *sym ATTRIBUTE_UNUSED,
3805 int *f ATTRIBUTE_UNUSED)
3807 if (expr->expr_type != EXPR_VARIABLE)
3808 return false;
3810 if (expr->symtree == new_symtree)
3811 expr->symtree = old_symtree;
3813 return false;
3816 static void
3817 forall_restore_symtree (gfc_expr *e)
3819 gfc_traverse_expr (e, NULL, forall_restore, 0);
3822 static void
3823 forall_make_variable_temp (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
3825 gfc_se tse;
3826 gfc_se rse;
3827 gfc_expr *e;
3828 gfc_symbol *new_sym;
3829 gfc_symbol *old_sym;
3830 gfc_symtree *root;
3831 tree tmp;
3833 /* Build a copy of the lvalue. */
3834 old_symtree = c->expr1->symtree;
3835 old_sym = old_symtree->n.sym;
3836 e = gfc_lval_expr_from_sym (old_sym);
3837 if (old_sym->attr.dimension)
3839 gfc_init_se (&tse, NULL);
3840 gfc_conv_subref_array_arg (&tse, e, 0, INTENT_IN, false);
3841 gfc_add_block_to_block (pre, &tse.pre);
3842 gfc_add_block_to_block (post, &tse.post);
3843 tse.expr = build_fold_indirect_ref_loc (input_location, tse.expr);
3845 if (c->expr1->ref->u.ar.type != AR_SECTION)
3847 /* Use the variable offset for the temporary. */
3848 tmp = gfc_conv_array_offset (old_sym->backend_decl);
3849 gfc_conv_descriptor_offset_set (pre, tse.expr, tmp);
3852 else
3854 gfc_init_se (&tse, NULL);
3855 gfc_init_se (&rse, NULL);
3856 gfc_conv_expr (&rse, e);
3857 if (e->ts.type == BT_CHARACTER)
3859 tse.string_length = rse.string_length;
3860 tmp = gfc_get_character_type_len (gfc_default_character_kind,
3861 tse.string_length);
3862 tse.expr = gfc_conv_string_tmp (&tse, build_pointer_type (tmp),
3863 rse.string_length);
3864 gfc_add_block_to_block (pre, &tse.pre);
3865 gfc_add_block_to_block (post, &tse.post);
3867 else
3869 tmp = gfc_typenode_for_spec (&e->ts);
3870 tse.expr = gfc_create_var (tmp, "temp");
3873 tmp = gfc_trans_scalar_assign (&tse, &rse, e->ts,
3874 e->expr_type == EXPR_VARIABLE, false);
3875 gfc_add_expr_to_block (pre, tmp);
3877 gfc_free_expr (e);
3879 /* Create a new symbol to represent the lvalue. */
3880 new_sym = gfc_new_symbol (old_sym->name, NULL);
3881 new_sym->ts = old_sym->ts;
3882 new_sym->attr.referenced = 1;
3883 new_sym->attr.temporary = 1;
3884 new_sym->attr.dimension = old_sym->attr.dimension;
3885 new_sym->attr.flavor = old_sym->attr.flavor;
3887 /* Use the temporary as the backend_decl. */
3888 new_sym->backend_decl = tse.expr;
3890 /* Create a fake symtree for it. */
3891 root = NULL;
3892 new_symtree = gfc_new_symtree (&root, old_sym->name);
3893 new_symtree->n.sym = new_sym;
3894 gcc_assert (new_symtree == root);
3896 /* Go through the expression reference replacing the old_symtree
3897 with the new. */
3898 forall_replace_symtree (c->expr1, old_sym, 2);
3900 /* Now we have made this temporary, we might as well use it for
3901 the right hand side. */
3902 forall_replace_symtree (c->expr2, old_sym, 1);
3906 /* Handles dependencies in forall assignments. */
3907 static int
3908 check_forall_dependencies (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
3910 gfc_ref *lref;
3911 gfc_ref *rref;
3912 int need_temp;
3913 gfc_symbol *lsym;
3915 lsym = c->expr1->symtree->n.sym;
3916 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
3918 /* Now check for dependencies within the 'variable'
3919 expression itself. These are treated by making a complete
3920 copy of variable and changing all the references to it
3921 point to the copy instead. Note that the shallow copy of
3922 the variable will not suffice for derived types with
3923 pointer components. We therefore leave these to their
3924 own devices. */
3925 if (lsym->ts.type == BT_DERIVED
3926 && lsym->ts.u.derived->attr.pointer_comp)
3927 return need_temp;
3929 new_symtree = NULL;
3930 if (find_forall_index (c->expr1, lsym, 2))
3932 forall_make_variable_temp (c, pre, post);
3933 need_temp = 0;
3936 /* Substrings with dependencies are treated in the same
3937 way. */
3938 if (c->expr1->ts.type == BT_CHARACTER
3939 && c->expr1->ref
3940 && c->expr2->expr_type == EXPR_VARIABLE
3941 && lsym == c->expr2->symtree->n.sym)
3943 for (lref = c->expr1->ref; lref; lref = lref->next)
3944 if (lref->type == REF_SUBSTRING)
3945 break;
3946 for (rref = c->expr2->ref; rref; rref = rref->next)
3947 if (rref->type == REF_SUBSTRING)
3948 break;
3950 if (rref && lref
3951 && gfc_dep_compare_expr (rref->u.ss.start, lref->u.ss.start) < 0)
3953 forall_make_variable_temp (c, pre, post);
3954 need_temp = 0;
3957 return need_temp;
3961 static void
3962 cleanup_forall_symtrees (gfc_code *c)
3964 forall_restore_symtree (c->expr1);
3965 forall_restore_symtree (c->expr2);
3966 free (new_symtree->n.sym);
3967 free (new_symtree);
3971 /* Generate the loops for a FORALL block, specified by FORALL_TMP. BODY
3972 is the contents of the FORALL block/stmt to be iterated. MASK_FLAG
3973 indicates whether we should generate code to test the FORALLs mask
3974 array. OUTER is the loop header to be used for initializing mask
3975 indices.
3977 The generated loop format is:
3978 count = (end - start + step) / step
3979 loopvar = start
3980 while (1)
3982 if (count <=0 )
3983 goto end_of_loop
3984 <body>
3985 loopvar += step
3986 count --
3988 end_of_loop: */
3990 static tree
3991 gfc_trans_forall_loop (forall_info *forall_tmp, tree body,
3992 int mask_flag, stmtblock_t *outer)
3994 int n, nvar;
3995 tree tmp;
3996 tree cond;
3997 stmtblock_t block;
3998 tree exit_label;
3999 tree count;
4000 tree var, start, end, step;
4001 iter_info *iter;
4003 /* Initialize the mask index outside the FORALL nest. */
4004 if (mask_flag && forall_tmp->mask)
4005 gfc_add_modify (outer, forall_tmp->maskindex, gfc_index_zero_node);
4007 iter = forall_tmp->this_loop;
4008 nvar = forall_tmp->nvar;
4009 for (n = 0; n < nvar; n++)
4011 var = iter->var;
4012 start = iter->start;
4013 end = iter->end;
4014 step = iter->step;
4016 exit_label = gfc_build_label_decl (NULL_TREE);
4017 TREE_USED (exit_label) = 1;
4019 /* The loop counter. */
4020 count = gfc_create_var (TREE_TYPE (var), "count");
4022 /* The body of the loop. */
4023 gfc_init_block (&block);
4025 /* The exit condition. */
4026 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
4027 count, build_int_cst (TREE_TYPE (count), 0));
4029 /* PR 83064 means that we cannot use annot_expr_parallel_kind until
4030 the autoparallelizer can hande this. */
4031 if (forall_tmp->do_concurrent)
4032 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
4033 build_int_cst (integer_type_node,
4034 annot_expr_ivdep_kind),
4035 integer_zero_node);
4037 tmp = build1_v (GOTO_EXPR, exit_label);
4038 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
4039 cond, tmp, build_empty_stmt (input_location));
4040 gfc_add_expr_to_block (&block, tmp);
4042 /* The main loop body. */
4043 gfc_add_expr_to_block (&block, body);
4045 /* Increment the loop variable. */
4046 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var,
4047 step);
4048 gfc_add_modify (&block, var, tmp);
4050 /* Advance to the next mask element. Only do this for the
4051 innermost loop. */
4052 if (n == 0 && mask_flag && forall_tmp->mask)
4054 tree maskindex = forall_tmp->maskindex;
4055 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4056 maskindex, gfc_index_one_node);
4057 gfc_add_modify (&block, maskindex, tmp);
4060 /* Decrement the loop counter. */
4061 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), count,
4062 build_int_cst (TREE_TYPE (var), 1));
4063 gfc_add_modify (&block, count, tmp);
4065 body = gfc_finish_block (&block);
4067 /* Loop var initialization. */
4068 gfc_init_block (&block);
4069 gfc_add_modify (&block, var, start);
4072 /* Initialize the loop counter. */
4073 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), step,
4074 start);
4075 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), end,
4076 tmp);
4077 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (var),
4078 tmp, step);
4079 gfc_add_modify (&block, count, tmp);
4081 /* The loop expression. */
4082 tmp = build1_v (LOOP_EXPR, body);
4083 gfc_add_expr_to_block (&block, tmp);
4085 /* The exit label. */
4086 tmp = build1_v (LABEL_EXPR, exit_label);
4087 gfc_add_expr_to_block (&block, tmp);
4089 body = gfc_finish_block (&block);
4090 iter = iter->next;
4092 return body;
4096 /* Generate the body and loops according to MASK_FLAG. If MASK_FLAG
4097 is nonzero, the body is controlled by all masks in the forall nest.
4098 Otherwise, the innermost loop is not controlled by it's mask. This
4099 is used for initializing that mask. */
4101 static tree
4102 gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
4103 int mask_flag)
4105 tree tmp;
4106 stmtblock_t header;
4107 forall_info *forall_tmp;
4108 tree mask, maskindex;
4110 gfc_start_block (&header);
4112 forall_tmp = nested_forall_info;
4113 while (forall_tmp != NULL)
4115 /* Generate body with masks' control. */
4116 if (mask_flag)
4118 mask = forall_tmp->mask;
4119 maskindex = forall_tmp->maskindex;
4121 /* If a mask was specified make the assignment conditional. */
4122 if (mask)
4124 tmp = gfc_build_array_ref (mask, maskindex, NULL);
4125 body = build3_v (COND_EXPR, tmp, body,
4126 build_empty_stmt (input_location));
4129 body = gfc_trans_forall_loop (forall_tmp, body, mask_flag, &header);
4130 forall_tmp = forall_tmp->prev_nest;
4131 mask_flag = 1;
4134 gfc_add_expr_to_block (&header, body);
4135 return gfc_finish_block (&header);
4139 /* Allocate data for holding a temporary array. Returns either a local
4140 temporary array or a pointer variable. */
4142 static tree
4143 gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
4144 tree elem_type)
4146 tree tmpvar;
4147 tree type;
4148 tree tmp;
4150 if (INTEGER_CST_P (size))
4151 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
4152 size, gfc_index_one_node);
4153 else
4154 tmp = NULL_TREE;
4156 type = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
4157 type = build_array_type (elem_type, type);
4158 if (gfc_can_put_var_on_stack (bytesize) && INTEGER_CST_P (size))
4160 tmpvar = gfc_create_var (type, "temp");
4161 *pdata = NULL_TREE;
4163 else
4165 tmpvar = gfc_create_var (build_pointer_type (type), "temp");
4166 *pdata = convert (pvoid_type_node, tmpvar);
4168 tmp = gfc_call_malloc (pblock, TREE_TYPE (tmpvar), bytesize);
4169 gfc_add_modify (pblock, tmpvar, tmp);
4171 return tmpvar;
4175 /* Generate codes to copy the temporary to the actual lhs. */
4177 static tree
4178 generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
4179 tree count1,
4180 gfc_ss *lss, gfc_ss *rss,
4181 tree wheremask, bool invert)
4183 stmtblock_t block, body1;
4184 gfc_loopinfo loop;
4185 gfc_se lse;
4186 gfc_se rse;
4187 tree tmp;
4188 tree wheremaskexpr;
4190 (void) rss; /* TODO: unused. */
4192 gfc_start_block (&block);
4194 gfc_init_se (&rse, NULL);
4195 gfc_init_se (&lse, NULL);
4197 if (lss == gfc_ss_terminator)
4199 gfc_init_block (&body1);
4200 gfc_conv_expr (&lse, expr);
4201 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
4203 else
4205 /* Initialize the loop. */
4206 gfc_init_loopinfo (&loop);
4208 /* We may need LSS to determine the shape of the expression. */
4209 gfc_add_ss_to_loop (&loop, lss);
4211 gfc_conv_ss_startstride (&loop);
4212 gfc_conv_loop_setup (&loop, &expr->where);
4214 gfc_mark_ss_chain_used (lss, 1);
4215 /* Start the loop body. */
4216 gfc_start_scalarized_body (&loop, &body1);
4218 /* Translate the expression. */
4219 gfc_copy_loopinfo_to_se (&lse, &loop);
4220 lse.ss = lss;
4221 gfc_conv_expr (&lse, expr);
4223 /* Form the expression of the temporary. */
4224 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
4227 /* Use the scalar assignment. */
4228 rse.string_length = lse.string_length;
4229 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts,
4230 expr->expr_type == EXPR_VARIABLE, false);
4232 /* Form the mask expression according to the mask tree list. */
4233 if (wheremask)
4235 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
4236 if (invert)
4237 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
4238 TREE_TYPE (wheremaskexpr),
4239 wheremaskexpr);
4240 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
4241 wheremaskexpr, tmp,
4242 build_empty_stmt (input_location));
4245 gfc_add_expr_to_block (&body1, tmp);
4247 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
4248 count1, gfc_index_one_node);
4249 gfc_add_modify (&body1, count1, tmp);
4251 if (lss == gfc_ss_terminator)
4252 gfc_add_block_to_block (&block, &body1);
4253 else
4255 /* Increment count3. */
4256 if (count3)
4258 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4259 gfc_array_index_type,
4260 count3, gfc_index_one_node);
4261 gfc_add_modify (&body1, count3, tmp);
4264 /* Generate the copying loops. */
4265 gfc_trans_scalarizing_loops (&loop, &body1);
4267 gfc_add_block_to_block (&block, &loop.pre);
4268 gfc_add_block_to_block (&block, &loop.post);
4270 gfc_cleanup_loop (&loop);
4271 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
4272 as tree nodes in SS may not be valid in different scope. */
4275 tmp = gfc_finish_block (&block);
4276 return tmp;
4280 /* Generate codes to copy rhs to the temporary. TMP1 is the address of
4281 temporary, LSS and RSS are formed in function compute_inner_temp_size(),
4282 and should not be freed. WHEREMASK is the conditional execution mask
4283 whose sense may be inverted by INVERT. */
4285 static tree
4286 generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree count3,
4287 tree count1, gfc_ss *lss, gfc_ss *rss,
4288 tree wheremask, bool invert)
4290 stmtblock_t block, body1;
4291 gfc_loopinfo loop;
4292 gfc_se lse;
4293 gfc_se rse;
4294 tree tmp;
4295 tree wheremaskexpr;
4297 gfc_start_block (&block);
4299 gfc_init_se (&rse, NULL);
4300 gfc_init_se (&lse, NULL);
4302 if (lss == gfc_ss_terminator)
4304 gfc_init_block (&body1);
4305 gfc_conv_expr (&rse, expr2);
4306 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
4308 else
4310 /* Initialize the loop. */
4311 gfc_init_loopinfo (&loop);
4313 /* We may need LSS to determine the shape of the expression. */
4314 gfc_add_ss_to_loop (&loop, lss);
4315 gfc_add_ss_to_loop (&loop, rss);
4317 gfc_conv_ss_startstride (&loop);
4318 gfc_conv_loop_setup (&loop, &expr2->where);
4320 gfc_mark_ss_chain_used (rss, 1);
4321 /* Start the loop body. */
4322 gfc_start_scalarized_body (&loop, &body1);
4324 /* Translate the expression. */
4325 gfc_copy_loopinfo_to_se (&rse, &loop);
4326 rse.ss = rss;
4327 gfc_conv_expr (&rse, expr2);
4329 /* Form the expression of the temporary. */
4330 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
4333 /* Use the scalar assignment. */
4334 lse.string_length = rse.string_length;
4335 tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts,
4336 expr2->expr_type == EXPR_VARIABLE, false);
4338 /* Form the mask expression according to the mask tree list. */
4339 if (wheremask)
4341 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
4342 if (invert)
4343 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
4344 TREE_TYPE (wheremaskexpr),
4345 wheremaskexpr);
4346 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
4347 wheremaskexpr, tmp,
4348 build_empty_stmt (input_location));
4351 gfc_add_expr_to_block (&body1, tmp);
4353 if (lss == gfc_ss_terminator)
4355 gfc_add_block_to_block (&block, &body1);
4357 /* Increment count1. */
4358 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
4359 count1, gfc_index_one_node);
4360 gfc_add_modify (&block, count1, tmp);
4362 else
4364 /* Increment count1. */
4365 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4366 count1, gfc_index_one_node);
4367 gfc_add_modify (&body1, count1, tmp);
4369 /* Increment count3. */
4370 if (count3)
4372 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4373 gfc_array_index_type,
4374 count3, gfc_index_one_node);
4375 gfc_add_modify (&body1, count3, tmp);
4378 /* Generate the copying loops. */
4379 gfc_trans_scalarizing_loops (&loop, &body1);
4381 gfc_add_block_to_block (&block, &loop.pre);
4382 gfc_add_block_to_block (&block, &loop.post);
4384 gfc_cleanup_loop (&loop);
4385 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
4386 as tree nodes in SS may not be valid in different scope. */
4389 tmp = gfc_finish_block (&block);
4390 return tmp;
4394 /* Calculate the size of temporary needed in the assignment inside forall.
4395 LSS and RSS are filled in this function. */
4397 static tree
4398 compute_inner_temp_size (gfc_expr *expr1, gfc_expr *expr2,
4399 stmtblock_t * pblock,
4400 gfc_ss **lss, gfc_ss **rss)
4402 gfc_loopinfo loop;
4403 tree size;
4404 int i;
4405 int save_flag;
4406 tree tmp;
4408 *lss = gfc_walk_expr (expr1);
4409 *rss = NULL;
4411 size = gfc_index_one_node;
4412 if (*lss != gfc_ss_terminator)
4414 gfc_init_loopinfo (&loop);
4416 /* Walk the RHS of the expression. */
4417 *rss = gfc_walk_expr (expr2);
4418 if (*rss == gfc_ss_terminator)
4419 /* The rhs is scalar. Add a ss for the expression. */
4420 *rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
4422 /* Associate the SS with the loop. */
4423 gfc_add_ss_to_loop (&loop, *lss);
4424 /* We don't actually need to add the rhs at this point, but it might
4425 make guessing the loop bounds a bit easier. */
4426 gfc_add_ss_to_loop (&loop, *rss);
4428 /* We only want the shape of the expression, not rest of the junk
4429 generated by the scalarizer. */
4430 loop.array_parameter = 1;
4432 /* Calculate the bounds of the scalarization. */
4433 save_flag = gfc_option.rtcheck;
4434 gfc_option.rtcheck &= ~GFC_RTCHECK_BOUNDS;
4435 gfc_conv_ss_startstride (&loop);
4436 gfc_option.rtcheck = save_flag;
4437 gfc_conv_loop_setup (&loop, &expr2->where);
4439 /* Figure out how many elements we need. */
4440 for (i = 0; i < loop.dimen; i++)
4442 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4443 gfc_array_index_type,
4444 gfc_index_one_node, loop.from[i]);
4445 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4446 gfc_array_index_type, tmp, loop.to[i]);
4447 size = fold_build2_loc (input_location, MULT_EXPR,
4448 gfc_array_index_type, size, tmp);
4450 gfc_add_block_to_block (pblock, &loop.pre);
4451 size = gfc_evaluate_now (size, pblock);
4452 gfc_add_block_to_block (pblock, &loop.post);
4454 /* TODO: write a function that cleans up a loopinfo without freeing
4455 the SS chains. Currently a NOP. */
4458 return size;
4462 /* Calculate the overall iterator number of the nested forall construct.
4463 This routine actually calculates the number of times the body of the
4464 nested forall specified by NESTED_FORALL_INFO is executed and multiplies
4465 that by the expression INNER_SIZE. The BLOCK argument specifies the
4466 block in which to calculate the result, and the optional INNER_SIZE_BODY
4467 argument contains any statements that need to executed (inside the loop)
4468 to initialize or calculate INNER_SIZE. */
4470 static tree
4471 compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
4472 stmtblock_t *inner_size_body, stmtblock_t *block)
4474 forall_info *forall_tmp = nested_forall_info;
4475 tree tmp, number;
4476 stmtblock_t body;
4478 /* We can eliminate the innermost unconditional loops with constant
4479 array bounds. */
4480 if (INTEGER_CST_P (inner_size))
4482 while (forall_tmp
4483 && !forall_tmp->mask
4484 && INTEGER_CST_P (forall_tmp->size))
4486 inner_size = fold_build2_loc (input_location, MULT_EXPR,
4487 gfc_array_index_type,
4488 inner_size, forall_tmp->size);
4489 forall_tmp = forall_tmp->prev_nest;
4492 /* If there are no loops left, we have our constant result. */
4493 if (!forall_tmp)
4494 return inner_size;
4497 /* Otherwise, create a temporary variable to compute the result. */
4498 number = gfc_create_var (gfc_array_index_type, "num");
4499 gfc_add_modify (block, number, gfc_index_zero_node);
4501 gfc_start_block (&body);
4502 if (inner_size_body)
4503 gfc_add_block_to_block (&body, inner_size_body);
4504 if (forall_tmp)
4505 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4506 gfc_array_index_type, number, inner_size);
4507 else
4508 tmp = inner_size;
4509 gfc_add_modify (&body, number, tmp);
4510 tmp = gfc_finish_block (&body);
4512 /* Generate loops. */
4513 if (forall_tmp != NULL)
4514 tmp = gfc_trans_nested_forall_loop (forall_tmp, tmp, 1);
4516 gfc_add_expr_to_block (block, tmp);
4518 return number;
4522 /* Allocate temporary for forall construct. SIZE is the size of temporary
4523 needed. PTEMP1 is returned for space free. */
4525 static tree
4526 allocate_temp_for_forall_nest_1 (tree type, tree size, stmtblock_t * block,
4527 tree * ptemp1)
4529 tree bytesize;
4530 tree unit;
4531 tree tmp;
4533 unit = fold_convert (gfc_array_index_type, TYPE_SIZE_UNIT (type));
4534 if (!integer_onep (unit))
4535 bytesize = fold_build2_loc (input_location, MULT_EXPR,
4536 gfc_array_index_type, size, unit);
4537 else
4538 bytesize = size;
4540 *ptemp1 = NULL;
4541 tmp = gfc_do_allocate (bytesize, size, ptemp1, block, type);
4543 if (*ptemp1)
4544 tmp = build_fold_indirect_ref_loc (input_location, tmp);
4545 return tmp;
4549 /* Allocate temporary for forall construct according to the information in
4550 nested_forall_info. INNER_SIZE is the size of temporary needed in the
4551 assignment inside forall. PTEMP1 is returned for space free. */
4553 static tree
4554 allocate_temp_for_forall_nest (forall_info * nested_forall_info, tree type,
4555 tree inner_size, stmtblock_t * inner_size_body,
4556 stmtblock_t * block, tree * ptemp1)
4558 tree size;
4560 /* Calculate the total size of temporary needed in forall construct. */
4561 size = compute_overall_iter_number (nested_forall_info, inner_size,
4562 inner_size_body, block);
4564 return allocate_temp_for_forall_nest_1 (type, size, block, ptemp1);
4568 /* Handle assignments inside forall which need temporary.
4570 forall (i=start:end:stride; maskexpr)
4571 e<i> = f<i>
4572 end forall
4573 (where e,f<i> are arbitrary expressions possibly involving i
4574 and there is a dependency between e<i> and f<i>)
4575 Translates to:
4576 masktmp(:) = maskexpr(:)
4578 maskindex = 0;
4579 count1 = 0;
4580 num = 0;
4581 for (i = start; i <= end; i += stride)
4582 num += SIZE (f<i>)
4583 count1 = 0;
4584 ALLOCATE (tmp(num))
4585 for (i = start; i <= end; i += stride)
4587 if (masktmp[maskindex++])
4588 tmp[count1++] = f<i>
4590 maskindex = 0;
4591 count1 = 0;
4592 for (i = start; i <= end; i += stride)
4594 if (masktmp[maskindex++])
4595 e<i> = tmp[count1++]
4597 DEALLOCATE (tmp)
4599 static void
4600 gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
4601 tree wheremask, bool invert,
4602 forall_info * nested_forall_info,
4603 stmtblock_t * block)
4605 tree type;
4606 tree inner_size;
4607 gfc_ss *lss, *rss;
4608 tree count, count1;
4609 tree tmp, tmp1;
4610 tree ptemp1;
4611 stmtblock_t inner_size_body;
4613 /* Create vars. count1 is the current iterator number of the nested
4614 forall. */
4615 count1 = gfc_create_var (gfc_array_index_type, "count1");
4617 /* Count is the wheremask index. */
4618 if (wheremask)
4620 count = gfc_create_var (gfc_array_index_type, "count");
4621 gfc_add_modify (block, count, gfc_index_zero_node);
4623 else
4624 count = NULL;
4626 /* Initialize count1. */
4627 gfc_add_modify (block, count1, gfc_index_zero_node);
4629 /* Calculate the size of temporary needed in the assignment. Return loop, lss
4630 and rss which are used in function generate_loop_for_rhs_to_temp(). */
4631 /* The type of LHS. Used in function allocate_temp_for_forall_nest */
4632 if (expr1->ts.type == BT_CHARACTER)
4634 type = NULL;
4635 if (expr1->ref && expr1->ref->type == REF_SUBSTRING)
4637 gfc_se ssse;
4638 gfc_init_se (&ssse, NULL);
4639 gfc_conv_expr (&ssse, expr1);
4640 type = gfc_get_character_type_len (gfc_default_character_kind,
4641 ssse.string_length);
4643 else
4645 if (!expr1->ts.u.cl->backend_decl)
4647 gfc_se tse;
4648 gcc_assert (expr1->ts.u.cl->length);
4649 gfc_init_se (&tse, NULL);
4650 gfc_conv_expr (&tse, expr1->ts.u.cl->length);
4651 expr1->ts.u.cl->backend_decl = tse.expr;
4653 type = gfc_get_character_type_len (gfc_default_character_kind,
4654 expr1->ts.u.cl->backend_decl);
4657 else
4658 type = gfc_typenode_for_spec (&expr1->ts);
4660 gfc_init_block (&inner_size_body);
4661 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
4662 &lss, &rss);
4664 /* Allocate temporary for nested forall construct according to the
4665 information in nested_forall_info and inner_size. */
4666 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type, inner_size,
4667 &inner_size_body, block, &ptemp1);
4669 /* Generate codes to copy rhs to the temporary . */
4670 tmp = generate_loop_for_rhs_to_temp (expr2, tmp1, count, count1, lss, rss,
4671 wheremask, invert);
4673 /* Generate body and loops according to the information in
4674 nested_forall_info. */
4675 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4676 gfc_add_expr_to_block (block, tmp);
4678 /* Reset count1. */
4679 gfc_add_modify (block, count1, gfc_index_zero_node);
4681 /* Reset count. */
4682 if (wheremask)
4683 gfc_add_modify (block, count, gfc_index_zero_node);
4685 /* TODO: Second call to compute_inner_temp_size to initialize lss and
4686 rss; there must be a better way. */
4687 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
4688 &lss, &rss);
4690 /* Generate codes to copy the temporary to lhs. */
4691 tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, count, count1,
4692 lss, rss,
4693 wheremask, invert);
4695 /* Generate body and loops according to the information in
4696 nested_forall_info. */
4697 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4698 gfc_add_expr_to_block (block, tmp);
4700 if (ptemp1)
4702 /* Free the temporary. */
4703 tmp = gfc_call_free (ptemp1);
4704 gfc_add_expr_to_block (block, tmp);
4709 /* Translate pointer assignment inside FORALL which need temporary. */
4711 static void
4712 gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
4713 forall_info * nested_forall_info,
4714 stmtblock_t * block)
4716 tree type;
4717 tree inner_size;
4718 gfc_ss *lss, *rss;
4719 gfc_se lse;
4720 gfc_se rse;
4721 gfc_array_info *info;
4722 gfc_loopinfo loop;
4723 tree desc;
4724 tree parm;
4725 tree parmtype;
4726 stmtblock_t body;
4727 tree count;
4728 tree tmp, tmp1, ptemp1;
4730 count = gfc_create_var (gfc_array_index_type, "count");
4731 gfc_add_modify (block, count, gfc_index_zero_node);
4733 inner_size = gfc_index_one_node;
4734 lss = gfc_walk_expr (expr1);
4735 rss = gfc_walk_expr (expr2);
4736 if (lss == gfc_ss_terminator)
4738 type = gfc_typenode_for_spec (&expr1->ts);
4739 type = build_pointer_type (type);
4741 /* Allocate temporary for nested forall construct according to the
4742 information in nested_forall_info and inner_size. */
4743 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type,
4744 inner_size, NULL, block, &ptemp1);
4745 gfc_start_block (&body);
4746 gfc_init_se (&lse, NULL);
4747 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
4748 gfc_init_se (&rse, NULL);
4749 rse.want_pointer = 1;
4750 gfc_conv_expr (&rse, expr2);
4751 gfc_add_block_to_block (&body, &rse.pre);
4752 gfc_add_modify (&body, lse.expr,
4753 fold_convert (TREE_TYPE (lse.expr), rse.expr));
4754 gfc_add_block_to_block (&body, &rse.post);
4756 /* Increment count. */
4757 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4758 count, gfc_index_one_node);
4759 gfc_add_modify (&body, count, tmp);
4761 tmp = gfc_finish_block (&body);
4763 /* Generate body and loops according to the information in
4764 nested_forall_info. */
4765 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4766 gfc_add_expr_to_block (block, tmp);
4768 /* Reset count. */
4769 gfc_add_modify (block, count, gfc_index_zero_node);
4771 gfc_start_block (&body);
4772 gfc_init_se (&lse, NULL);
4773 gfc_init_se (&rse, NULL);
4774 rse.expr = gfc_build_array_ref (tmp1, count, NULL);
4775 lse.want_pointer = 1;
4776 gfc_conv_expr (&lse, expr1);
4777 gfc_add_block_to_block (&body, &lse.pre);
4778 gfc_add_modify (&body, lse.expr, rse.expr);
4779 gfc_add_block_to_block (&body, &lse.post);
4780 /* Increment count. */
4781 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4782 count, gfc_index_one_node);
4783 gfc_add_modify (&body, count, tmp);
4784 tmp = gfc_finish_block (&body);
4786 /* Generate body and loops according to the information in
4787 nested_forall_info. */
4788 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4789 gfc_add_expr_to_block (block, tmp);
4791 else
4793 gfc_init_loopinfo (&loop);
4795 /* Associate the SS with the loop. */
4796 gfc_add_ss_to_loop (&loop, rss);
4798 /* Setup the scalarizing loops and bounds. */
4799 gfc_conv_ss_startstride (&loop);
4801 gfc_conv_loop_setup (&loop, &expr2->where);
4803 info = &rss->info->data.array;
4804 desc = info->descriptor;
4806 /* Make a new descriptor. */
4807 parmtype = gfc_get_element_type (TREE_TYPE (desc));
4808 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0,
4809 loop.from, loop.to, 1,
4810 GFC_ARRAY_UNKNOWN, true);
4812 /* Allocate temporary for nested forall construct. */
4813 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
4814 inner_size, NULL, block, &ptemp1);
4815 gfc_start_block (&body);
4816 gfc_init_se (&lse, NULL);
4817 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
4818 lse.direct_byref = 1;
4819 gfc_conv_expr_descriptor (&lse, expr2);
4821 gfc_add_block_to_block (&body, &lse.pre);
4822 gfc_add_block_to_block (&body, &lse.post);
4824 /* Increment count. */
4825 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4826 count, gfc_index_one_node);
4827 gfc_add_modify (&body, count, tmp);
4829 tmp = gfc_finish_block (&body);
4831 /* Generate body and loops according to the information in
4832 nested_forall_info. */
4833 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4834 gfc_add_expr_to_block (block, tmp);
4836 /* Reset count. */
4837 gfc_add_modify (block, count, gfc_index_zero_node);
4839 parm = gfc_build_array_ref (tmp1, count, NULL);
4840 gfc_init_se (&lse, NULL);
4841 gfc_conv_expr_descriptor (&lse, expr1);
4842 gfc_add_modify (&lse.pre, lse.expr, parm);
4843 gfc_start_block (&body);
4844 gfc_add_block_to_block (&body, &lse.pre);
4845 gfc_add_block_to_block (&body, &lse.post);
4847 /* Increment count. */
4848 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4849 count, gfc_index_one_node);
4850 gfc_add_modify (&body, count, tmp);
4852 tmp = gfc_finish_block (&body);
4854 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4855 gfc_add_expr_to_block (block, tmp);
4857 /* Free the temporary. */
4858 if (ptemp1)
4860 tmp = gfc_call_free (ptemp1);
4861 gfc_add_expr_to_block (block, tmp);
4866 /* FORALL and WHERE statements are really nasty, especially when you nest
4867 them. All the rhs of a forall assignment must be evaluated before the
4868 actual assignments are performed. Presumably this also applies to all the
4869 assignments in an inner where statement. */
4871 /* Generate code for a FORALL statement. Any temporaries are allocated as a
4872 linear array, relying on the fact that we process in the same order in all
4873 loops.
4875 forall (i=start:end:stride; maskexpr)
4876 e<i> = f<i>
4877 g<i> = h<i>
4878 end forall
4879 (where e,f,g,h<i> are arbitrary expressions possibly involving i)
4880 Translates to:
4881 count = ((end + 1 - start) / stride)
4882 masktmp(:) = maskexpr(:)
4884 maskindex = 0;
4885 for (i = start; i <= end; i += stride)
4887 if (masktmp[maskindex++])
4888 e<i> = f<i>
4890 maskindex = 0;
4891 for (i = start; i <= end; i += stride)
4893 if (masktmp[maskindex++])
4894 g<i> = h<i>
4897 Note that this code only works when there are no dependencies.
4898 Forall loop with array assignments and data dependencies are a real pain,
4899 because the size of the temporary cannot always be determined before the
4900 loop is executed. This problem is compounded by the presence of nested
4901 FORALL constructs.
4904 static tree
4905 gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
4907 stmtblock_t pre;
4908 stmtblock_t post;
4909 stmtblock_t block;
4910 stmtblock_t body;
4911 tree *var;
4912 tree *start;
4913 tree *end;
4914 tree *step;
4915 gfc_expr **varexpr;
4916 tree tmp;
4917 tree assign;
4918 tree size;
4919 tree maskindex;
4920 tree mask;
4921 tree pmask;
4922 tree cycle_label = NULL_TREE;
4923 int n;
4924 int nvar;
4925 int need_temp;
4926 gfc_forall_iterator *fa;
4927 gfc_se se;
4928 gfc_code *c;
4929 gfc_saved_var *saved_vars;
4930 iter_info *this_forall;
4931 forall_info *info;
4932 bool need_mask;
4934 /* Do nothing if the mask is false. */
4935 if (code->expr1
4936 && code->expr1->expr_type == EXPR_CONSTANT
4937 && !code->expr1->value.logical)
4938 return build_empty_stmt (input_location);
4940 n = 0;
4941 /* Count the FORALL index number. */
4942 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
4943 n++;
4944 nvar = n;
4946 /* Allocate the space for var, start, end, step, varexpr. */
4947 var = XCNEWVEC (tree, nvar);
4948 start = XCNEWVEC (tree, nvar);
4949 end = XCNEWVEC (tree, nvar);
4950 step = XCNEWVEC (tree, nvar);
4951 varexpr = XCNEWVEC (gfc_expr *, nvar);
4952 saved_vars = XCNEWVEC (gfc_saved_var, nvar);
4954 /* Allocate the space for info. */
4955 info = XCNEW (forall_info);
4957 gfc_start_block (&pre);
4958 gfc_init_block (&post);
4959 gfc_init_block (&block);
4961 n = 0;
4962 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
4964 gfc_symbol *sym = fa->var->symtree->n.sym;
4966 /* Allocate space for this_forall. */
4967 this_forall = XCNEW (iter_info);
4969 /* Create a temporary variable for the FORALL index. */
4970 tmp = gfc_typenode_for_spec (&sym->ts);
4971 var[n] = gfc_create_var (tmp, sym->name);
4972 gfc_shadow_sym (sym, var[n], &saved_vars[n]);
4974 /* Record it in this_forall. */
4975 this_forall->var = var[n];
4977 /* Replace the index symbol's backend_decl with the temporary decl. */
4978 sym->backend_decl = var[n];
4980 /* Work out the start, end and stride for the loop. */
4981 gfc_init_se (&se, NULL);
4982 gfc_conv_expr_val (&se, fa->start);
4983 /* Record it in this_forall. */
4984 this_forall->start = se.expr;
4985 gfc_add_block_to_block (&block, &se.pre);
4986 start[n] = se.expr;
4988 gfc_init_se (&se, NULL);
4989 gfc_conv_expr_val (&se, fa->end);
4990 /* Record it in this_forall. */
4991 this_forall->end = se.expr;
4992 gfc_make_safe_expr (&se);
4993 gfc_add_block_to_block (&block, &se.pre);
4994 end[n] = se.expr;
4996 gfc_init_se (&se, NULL);
4997 gfc_conv_expr_val (&se, fa->stride);
4998 /* Record it in this_forall. */
4999 this_forall->step = se.expr;
5000 gfc_make_safe_expr (&se);
5001 gfc_add_block_to_block (&block, &se.pre);
5002 step[n] = se.expr;
5004 /* Set the NEXT field of this_forall to NULL. */
5005 this_forall->next = NULL;
5006 /* Link this_forall to the info construct. */
5007 if (info->this_loop)
5009 iter_info *iter_tmp = info->this_loop;
5010 while (iter_tmp->next != NULL)
5011 iter_tmp = iter_tmp->next;
5012 iter_tmp->next = this_forall;
5014 else
5015 info->this_loop = this_forall;
5017 n++;
5019 nvar = n;
5021 /* Calculate the size needed for the current forall level. */
5022 size = gfc_index_one_node;
5023 for (n = 0; n < nvar; n++)
5025 /* size = (end + step - start) / step. */
5026 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (start[n]),
5027 step[n], start[n]);
5028 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (end[n]),
5029 end[n], tmp);
5030 tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, TREE_TYPE (tmp),
5031 tmp, step[n]);
5032 tmp = convert (gfc_array_index_type, tmp);
5034 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5035 size, tmp);
5038 /* Record the nvar and size of current forall level. */
5039 info->nvar = nvar;
5040 info->size = size;
5042 if (code->expr1)
5044 /* If the mask is .true., consider the FORALL unconditional. */
5045 if (code->expr1->expr_type == EXPR_CONSTANT
5046 && code->expr1->value.logical)
5047 need_mask = false;
5048 else
5049 need_mask = true;
5051 else
5052 need_mask = false;
5054 /* First we need to allocate the mask. */
5055 if (need_mask)
5057 /* As the mask array can be very big, prefer compact boolean types. */
5058 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
5059 mask = allocate_temp_for_forall_nest (nested_forall_info, mask_type,
5060 size, NULL, &block, &pmask);
5061 maskindex = gfc_create_var_np (gfc_array_index_type, "mi");
5063 /* Record them in the info structure. */
5064 info->maskindex = maskindex;
5065 info->mask = mask;
5067 else
5069 /* No mask was specified. */
5070 maskindex = NULL_TREE;
5071 mask = pmask = NULL_TREE;
5074 /* Link the current forall level to nested_forall_info. */
5075 info->prev_nest = nested_forall_info;
5076 nested_forall_info = info;
5078 /* Copy the mask into a temporary variable if required.
5079 For now we assume a mask temporary is needed. */
5080 if (need_mask)
5082 /* As the mask array can be very big, prefer compact boolean types. */
5083 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
5085 gfc_add_modify (&block, maskindex, gfc_index_zero_node);
5087 /* Start of mask assignment loop body. */
5088 gfc_start_block (&body);
5090 /* Evaluate the mask expression. */
5091 gfc_init_se (&se, NULL);
5092 gfc_conv_expr_val (&se, code->expr1);
5093 gfc_add_block_to_block (&body, &se.pre);
5095 /* Store the mask. */
5096 se.expr = convert (mask_type, se.expr);
5098 tmp = gfc_build_array_ref (mask, maskindex, NULL);
5099 gfc_add_modify (&body, tmp, se.expr);
5101 /* Advance to the next mask element. */
5102 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5103 maskindex, gfc_index_one_node);
5104 gfc_add_modify (&body, maskindex, tmp);
5106 /* Generate the loops. */
5107 tmp = gfc_finish_block (&body);
5108 tmp = gfc_trans_nested_forall_loop (info, tmp, 0);
5109 gfc_add_expr_to_block (&block, tmp);
5112 if (code->op == EXEC_DO_CONCURRENT)
5114 gfc_init_block (&body);
5115 cycle_label = gfc_build_label_decl (NULL_TREE);
5116 code->cycle_label = cycle_label;
5117 tmp = gfc_trans_code (code->block->next);
5118 gfc_add_expr_to_block (&body, tmp);
5120 if (TREE_USED (cycle_label))
5122 tmp = build1_v (LABEL_EXPR, cycle_label);
5123 gfc_add_expr_to_block (&body, tmp);
5126 tmp = gfc_finish_block (&body);
5127 nested_forall_info->do_concurrent = true;
5128 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
5129 gfc_add_expr_to_block (&block, tmp);
5130 goto done;
5133 c = code->block->next;
5135 /* TODO: loop merging in FORALL statements. */
5136 /* Now that we've got a copy of the mask, generate the assignment loops. */
5137 while (c)
5139 switch (c->op)
5141 case EXEC_ASSIGN:
5142 /* A scalar or array assignment. DO the simple check for
5143 lhs to rhs dependencies. These make a temporary for the
5144 rhs and form a second forall block to copy to variable. */
5145 need_temp = check_forall_dependencies(c, &pre, &post);
5147 /* Temporaries due to array assignment data dependencies introduce
5148 no end of problems. */
5149 if (need_temp || flag_test_forall_temp)
5150 gfc_trans_assign_need_temp (c->expr1, c->expr2, NULL, false,
5151 nested_forall_info, &block);
5152 else
5154 /* Use the normal assignment copying routines. */
5155 assign = gfc_trans_assignment (c->expr1, c->expr2, false, true);
5157 /* Generate body and loops. */
5158 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
5159 assign, 1);
5160 gfc_add_expr_to_block (&block, tmp);
5163 /* Cleanup any temporary symtrees that have been made to deal
5164 with dependencies. */
5165 if (new_symtree)
5166 cleanup_forall_symtrees (c);
5168 break;
5170 case EXEC_WHERE:
5171 /* Translate WHERE or WHERE construct nested in FORALL. */
5172 gfc_trans_where_2 (c, NULL, false, nested_forall_info, &block);
5173 break;
5175 /* Pointer assignment inside FORALL. */
5176 case EXEC_POINTER_ASSIGN:
5177 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
5178 /* Avoid cases where a temporary would never be needed and where
5179 the temp code is guaranteed to fail. */
5180 if (need_temp
5181 || (flag_test_forall_temp
5182 && c->expr2->expr_type != EXPR_CONSTANT
5183 && c->expr2->expr_type != EXPR_NULL))
5184 gfc_trans_pointer_assign_need_temp (c->expr1, c->expr2,
5185 nested_forall_info, &block);
5186 else
5188 /* Use the normal assignment copying routines. */
5189 assign = gfc_trans_pointer_assignment (c->expr1, c->expr2);
5191 /* Generate body and loops. */
5192 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
5193 assign, 1);
5194 gfc_add_expr_to_block (&block, tmp);
5196 break;
5198 case EXEC_FORALL:
5199 tmp = gfc_trans_forall_1 (c, nested_forall_info);
5200 gfc_add_expr_to_block (&block, tmp);
5201 break;
5203 /* Explicit subroutine calls are prevented by the frontend but interface
5204 assignments can legitimately produce them. */
5205 case EXEC_ASSIGN_CALL:
5206 assign = gfc_trans_call (c, true, NULL_TREE, NULL_TREE, false);
5207 tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign, 1);
5208 gfc_add_expr_to_block (&block, tmp);
5209 break;
5211 default:
5212 gcc_unreachable ();
5215 c = c->next;
5218 done:
5219 /* Restore the original index variables. */
5220 for (fa = code->ext.forall_iterator, n = 0; fa; fa = fa->next, n++)
5221 gfc_restore_sym (fa->var->symtree->n.sym, &saved_vars[n]);
5223 /* Free the space for var, start, end, step, varexpr. */
5224 free (var);
5225 free (start);
5226 free (end);
5227 free (step);
5228 free (varexpr);
5229 free (saved_vars);
5231 for (this_forall = info->this_loop; this_forall;)
5233 iter_info *next = this_forall->next;
5234 free (this_forall);
5235 this_forall = next;
5238 /* Free the space for this forall_info. */
5239 free (info);
5241 if (pmask)
5243 /* Free the temporary for the mask. */
5244 tmp = gfc_call_free (pmask);
5245 gfc_add_expr_to_block (&block, tmp);
5247 if (maskindex)
5248 pushdecl (maskindex);
5250 gfc_add_block_to_block (&pre, &block);
5251 gfc_add_block_to_block (&pre, &post);
5253 return gfc_finish_block (&pre);
5257 /* Translate the FORALL statement or construct. */
5259 tree gfc_trans_forall (gfc_code * code)
5261 return gfc_trans_forall_1 (code, NULL);
5265 /* Translate the DO CONCURRENT construct. */
5267 tree gfc_trans_do_concurrent (gfc_code * code)
5269 return gfc_trans_forall_1 (code, NULL);
5273 /* Evaluate the WHERE mask expression, copy its value to a temporary.
5274 If the WHERE construct is nested in FORALL, compute the overall temporary
5275 needed by the WHERE mask expression multiplied by the iterator number of
5276 the nested forall.
5277 ME is the WHERE mask expression.
5278 MASK is the current execution mask upon input, whose sense may or may
5279 not be inverted as specified by the INVERT argument.
5280 CMASK is the updated execution mask on output, or NULL if not required.
5281 PMASK is the pending execution mask on output, or NULL if not required.
5282 BLOCK is the block in which to place the condition evaluation loops. */
5284 static void
5285 gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
5286 tree mask, bool invert, tree cmask, tree pmask,
5287 tree mask_type, stmtblock_t * block)
5289 tree tmp, tmp1;
5290 gfc_ss *lss, *rss;
5291 gfc_loopinfo loop;
5292 stmtblock_t body, body1;
5293 tree count, cond, mtmp;
5294 gfc_se lse, rse;
5296 gfc_init_loopinfo (&loop);
5298 lss = gfc_walk_expr (me);
5299 rss = gfc_walk_expr (me);
5301 /* Variable to index the temporary. */
5302 count = gfc_create_var (gfc_array_index_type, "count");
5303 /* Initialize count. */
5304 gfc_add_modify (block, count, gfc_index_zero_node);
5306 gfc_start_block (&body);
5308 gfc_init_se (&rse, NULL);
5309 gfc_init_se (&lse, NULL);
5311 if (lss == gfc_ss_terminator)
5313 gfc_init_block (&body1);
5315 else
5317 /* Initialize the loop. */
5318 gfc_init_loopinfo (&loop);
5320 /* We may need LSS to determine the shape of the expression. */
5321 gfc_add_ss_to_loop (&loop, lss);
5322 gfc_add_ss_to_loop (&loop, rss);
5324 gfc_conv_ss_startstride (&loop);
5325 gfc_conv_loop_setup (&loop, &me->where);
5327 gfc_mark_ss_chain_used (rss, 1);
5328 /* Start the loop body. */
5329 gfc_start_scalarized_body (&loop, &body1);
5331 /* Translate the expression. */
5332 gfc_copy_loopinfo_to_se (&rse, &loop);
5333 rse.ss = rss;
5334 gfc_conv_expr (&rse, me);
5337 /* Variable to evaluate mask condition. */
5338 cond = gfc_create_var (mask_type, "cond");
5339 if (mask && (cmask || pmask))
5340 mtmp = gfc_create_var (mask_type, "mask");
5341 else mtmp = NULL_TREE;
5343 gfc_add_block_to_block (&body1, &lse.pre);
5344 gfc_add_block_to_block (&body1, &rse.pre);
5346 gfc_add_modify (&body1, cond, fold_convert (mask_type, rse.expr));
5348 if (mask && (cmask || pmask))
5350 tmp = gfc_build_array_ref (mask, count, NULL);
5351 if (invert)
5352 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, tmp);
5353 gfc_add_modify (&body1, mtmp, tmp);
5356 if (cmask)
5358 tmp1 = gfc_build_array_ref (cmask, count, NULL);
5359 tmp = cond;
5360 if (mask)
5361 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type,
5362 mtmp, tmp);
5363 gfc_add_modify (&body1, tmp1, tmp);
5366 if (pmask)
5368 tmp1 = gfc_build_array_ref (pmask, count, NULL);
5369 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, cond);
5370 if (mask)
5371 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type, mtmp,
5372 tmp);
5373 gfc_add_modify (&body1, tmp1, tmp);
5376 gfc_add_block_to_block (&body1, &lse.post);
5377 gfc_add_block_to_block (&body1, &rse.post);
5379 if (lss == gfc_ss_terminator)
5381 gfc_add_block_to_block (&body, &body1);
5383 else
5385 /* Increment count. */
5386 tmp1 = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5387 count, gfc_index_one_node);
5388 gfc_add_modify (&body1, count, tmp1);
5390 /* Generate the copying loops. */
5391 gfc_trans_scalarizing_loops (&loop, &body1);
5393 gfc_add_block_to_block (&body, &loop.pre);
5394 gfc_add_block_to_block (&body, &loop.post);
5396 gfc_cleanup_loop (&loop);
5397 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
5398 as tree nodes in SS may not be valid in different scope. */
5401 tmp1 = gfc_finish_block (&body);
5402 /* If the WHERE construct is inside FORALL, fill the full temporary. */
5403 if (nested_forall_info != NULL)
5404 tmp1 = gfc_trans_nested_forall_loop (nested_forall_info, tmp1, 1);
5406 gfc_add_expr_to_block (block, tmp1);
5410 /* Translate an assignment statement in a WHERE statement or construct
5411 statement. The MASK expression is used to control which elements
5412 of EXPR1 shall be assigned. The sense of MASK is specified by
5413 INVERT. */
5415 static tree
5416 gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
5417 tree mask, bool invert,
5418 tree count1, tree count2,
5419 gfc_code *cnext)
5421 gfc_se lse;
5422 gfc_se rse;
5423 gfc_ss *lss;
5424 gfc_ss *lss_section;
5425 gfc_ss *rss;
5427 gfc_loopinfo loop;
5428 tree tmp;
5429 stmtblock_t block;
5430 stmtblock_t body;
5431 tree index, maskexpr;
5433 /* A defined assignment. */
5434 if (cnext && cnext->resolved_sym)
5435 return gfc_trans_call (cnext, true, mask, count1, invert);
5437 #if 0
5438 /* TODO: handle this special case.
5439 Special case a single function returning an array. */
5440 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
5442 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
5443 if (tmp)
5444 return tmp;
5446 #endif
5448 /* Assignment of the form lhs = rhs. */
5449 gfc_start_block (&block);
5451 gfc_init_se (&lse, NULL);
5452 gfc_init_se (&rse, NULL);
5454 /* Walk the lhs. */
5455 lss = gfc_walk_expr (expr1);
5456 rss = NULL;
5458 /* In each where-assign-stmt, the mask-expr and the variable being
5459 defined shall be arrays of the same shape. */
5460 gcc_assert (lss != gfc_ss_terminator);
5462 /* The assignment needs scalarization. */
5463 lss_section = lss;
5465 /* Find a non-scalar SS from the lhs. */
5466 while (lss_section != gfc_ss_terminator
5467 && lss_section->info->type != GFC_SS_SECTION)
5468 lss_section = lss_section->next;
5470 gcc_assert (lss_section != gfc_ss_terminator);
5472 /* Initialize the scalarizer. */
5473 gfc_init_loopinfo (&loop);
5475 /* Walk the rhs. */
5476 rss = gfc_walk_expr (expr2);
5477 if (rss == gfc_ss_terminator)
5479 /* The rhs is scalar. Add a ss for the expression. */
5480 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
5481 rss->info->where = 1;
5484 /* Associate the SS with the loop. */
5485 gfc_add_ss_to_loop (&loop, lss);
5486 gfc_add_ss_to_loop (&loop, rss);
5488 /* Calculate the bounds of the scalarization. */
5489 gfc_conv_ss_startstride (&loop);
5491 /* Resolve any data dependencies in the statement. */
5492 gfc_conv_resolve_dependencies (&loop, lss_section, rss);
5494 /* Setup the scalarizing loops. */
5495 gfc_conv_loop_setup (&loop, &expr2->where);
5497 /* Setup the gfc_se structures. */
5498 gfc_copy_loopinfo_to_se (&lse, &loop);
5499 gfc_copy_loopinfo_to_se (&rse, &loop);
5501 rse.ss = rss;
5502 gfc_mark_ss_chain_used (rss, 1);
5503 if (loop.temp_ss == NULL)
5505 lse.ss = lss;
5506 gfc_mark_ss_chain_used (lss, 1);
5508 else
5510 lse.ss = loop.temp_ss;
5511 gfc_mark_ss_chain_used (lss, 3);
5512 gfc_mark_ss_chain_used (loop.temp_ss, 3);
5515 /* Start the scalarized loop body. */
5516 gfc_start_scalarized_body (&loop, &body);
5518 /* Translate the expression. */
5519 gfc_conv_expr (&rse, expr2);
5520 if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
5521 gfc_conv_tmp_array_ref (&lse);
5522 else
5523 gfc_conv_expr (&lse, expr1);
5525 /* Form the mask expression according to the mask. */
5526 index = count1;
5527 maskexpr = gfc_build_array_ref (mask, index, NULL);
5528 if (invert)
5529 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
5530 TREE_TYPE (maskexpr), maskexpr);
5532 /* Use the scalar assignment as is. */
5533 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
5534 false, loop.temp_ss == NULL);
5536 tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt (input_location));
5538 gfc_add_expr_to_block (&body, tmp);
5540 if (lss == gfc_ss_terminator)
5542 /* Increment count1. */
5543 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5544 count1, gfc_index_one_node);
5545 gfc_add_modify (&body, count1, tmp);
5547 /* Use the scalar assignment as is. */
5548 gfc_add_block_to_block (&block, &body);
5550 else
5552 gcc_assert (lse.ss == gfc_ss_terminator
5553 && rse.ss == gfc_ss_terminator);
5555 if (loop.temp_ss != NULL)
5557 /* Increment count1 before finish the main body of a scalarized
5558 expression. */
5559 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5560 gfc_array_index_type, count1, gfc_index_one_node);
5561 gfc_add_modify (&body, count1, tmp);
5562 gfc_trans_scalarized_loop_boundary (&loop, &body);
5564 /* We need to copy the temporary to the actual lhs. */
5565 gfc_init_se (&lse, NULL);
5566 gfc_init_se (&rse, NULL);
5567 gfc_copy_loopinfo_to_se (&lse, &loop);
5568 gfc_copy_loopinfo_to_se (&rse, &loop);
5570 rse.ss = loop.temp_ss;
5571 lse.ss = lss;
5573 gfc_conv_tmp_array_ref (&rse);
5574 gfc_conv_expr (&lse, expr1);
5576 gcc_assert (lse.ss == gfc_ss_terminator
5577 && rse.ss == gfc_ss_terminator);
5579 /* Form the mask expression according to the mask tree list. */
5580 index = count2;
5581 maskexpr = gfc_build_array_ref (mask, index, NULL);
5582 if (invert)
5583 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
5584 TREE_TYPE (maskexpr), maskexpr);
5586 /* Use the scalar assignment as is. */
5587 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, false, true);
5588 tmp = build3_v (COND_EXPR, maskexpr, tmp,
5589 build_empty_stmt (input_location));
5590 gfc_add_expr_to_block (&body, tmp);
5592 /* Increment count2. */
5593 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5594 gfc_array_index_type, count2,
5595 gfc_index_one_node);
5596 gfc_add_modify (&body, count2, tmp);
5598 else
5600 /* Increment count1. */
5601 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5602 gfc_array_index_type, count1,
5603 gfc_index_one_node);
5604 gfc_add_modify (&body, count1, tmp);
5607 /* Generate the copying loops. */
5608 gfc_trans_scalarizing_loops (&loop, &body);
5610 /* Wrap the whole thing up. */
5611 gfc_add_block_to_block (&block, &loop.pre);
5612 gfc_add_block_to_block (&block, &loop.post);
5613 gfc_cleanup_loop (&loop);
5616 return gfc_finish_block (&block);
5620 /* Translate the WHERE construct or statement.
5621 This function can be called iteratively to translate the nested WHERE
5622 construct or statement.
5623 MASK is the control mask. */
5625 static void
5626 gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
5627 forall_info * nested_forall_info, stmtblock_t * block)
5629 stmtblock_t inner_size_body;
5630 tree inner_size, size;
5631 gfc_ss *lss, *rss;
5632 tree mask_type;
5633 gfc_expr *expr1;
5634 gfc_expr *expr2;
5635 gfc_code *cblock;
5636 gfc_code *cnext;
5637 tree tmp;
5638 tree cond;
5639 tree count1, count2;
5640 bool need_cmask;
5641 bool need_pmask;
5642 int need_temp;
5643 tree pcmask = NULL_TREE;
5644 tree ppmask = NULL_TREE;
5645 tree cmask = NULL_TREE;
5646 tree pmask = NULL_TREE;
5647 gfc_actual_arglist *arg;
5649 /* the WHERE statement or the WHERE construct statement. */
5650 cblock = code->block;
5652 /* As the mask array can be very big, prefer compact boolean types. */
5653 mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
5655 /* Determine which temporary masks are needed. */
5656 if (!cblock->block)
5658 /* One clause: No ELSEWHEREs. */
5659 need_cmask = (cblock->next != 0);
5660 need_pmask = false;
5662 else if (cblock->block->block)
5664 /* Three or more clauses: Conditional ELSEWHEREs. */
5665 need_cmask = true;
5666 need_pmask = true;
5668 else if (cblock->next)
5670 /* Two clauses, the first non-empty. */
5671 need_cmask = true;
5672 need_pmask = (mask != NULL_TREE
5673 && cblock->block->next != 0);
5675 else if (!cblock->block->next)
5677 /* Two clauses, both empty. */
5678 need_cmask = false;
5679 need_pmask = false;
5681 /* Two clauses, the first empty, the second non-empty. */
5682 else if (mask)
5684 need_cmask = (cblock->block->expr1 != 0);
5685 need_pmask = true;
5687 else
5689 need_cmask = true;
5690 need_pmask = false;
5693 if (need_cmask || need_pmask)
5695 /* Calculate the size of temporary needed by the mask-expr. */
5696 gfc_init_block (&inner_size_body);
5697 inner_size = compute_inner_temp_size (cblock->expr1, cblock->expr1,
5698 &inner_size_body, &lss, &rss);
5700 gfc_free_ss_chain (lss);
5701 gfc_free_ss_chain (rss);
5703 /* Calculate the total size of temporary needed. */
5704 size = compute_overall_iter_number (nested_forall_info, inner_size,
5705 &inner_size_body, block);
5707 /* Check whether the size is negative. */
5708 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, size,
5709 gfc_index_zero_node);
5710 size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
5711 cond, gfc_index_zero_node, size);
5712 size = gfc_evaluate_now (size, block);
5714 /* Allocate temporary for WHERE mask if needed. */
5715 if (need_cmask)
5716 cmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
5717 &pcmask);
5719 /* Allocate temporary for !mask if needed. */
5720 if (need_pmask)
5721 pmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
5722 &ppmask);
5725 while (cblock)
5727 /* Each time around this loop, the where clause is conditional
5728 on the value of mask and invert, which are updated at the
5729 bottom of the loop. */
5731 /* Has mask-expr. */
5732 if (cblock->expr1)
5734 /* Ensure that the WHERE mask will be evaluated exactly once.
5735 If there are no statements in this WHERE/ELSEWHERE clause,
5736 then we don't need to update the control mask (cmask).
5737 If this is the last clause of the WHERE construct, then
5738 we don't need to update the pending control mask (pmask). */
5739 if (mask)
5740 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
5741 mask, invert,
5742 cblock->next ? cmask : NULL_TREE,
5743 cblock->block ? pmask : NULL_TREE,
5744 mask_type, block);
5745 else
5746 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
5747 NULL_TREE, false,
5748 (cblock->next || cblock->block)
5749 ? cmask : NULL_TREE,
5750 NULL_TREE, mask_type, block);
5752 invert = false;
5754 /* It's a final elsewhere-stmt. No mask-expr is present. */
5755 else
5756 cmask = mask;
5758 /* The body of this where clause are controlled by cmask with
5759 sense specified by invert. */
5761 /* Get the assignment statement of a WHERE statement, or the first
5762 statement in where-body-construct of a WHERE construct. */
5763 cnext = cblock->next;
5764 while (cnext)
5766 switch (cnext->op)
5768 /* WHERE assignment statement. */
5769 case EXEC_ASSIGN_CALL:
5771 arg = cnext->ext.actual;
5772 expr1 = expr2 = NULL;
5773 for (; arg; arg = arg->next)
5775 if (!arg->expr)
5776 continue;
5777 if (expr1 == NULL)
5778 expr1 = arg->expr;
5779 else
5780 expr2 = arg->expr;
5782 goto evaluate;
5784 case EXEC_ASSIGN:
5785 expr1 = cnext->expr1;
5786 expr2 = cnext->expr2;
5787 evaluate:
5788 if (nested_forall_info != NULL)
5790 need_temp = gfc_check_dependency (expr1, expr2, 0);
5791 if ((need_temp || flag_test_forall_temp)
5792 && cnext->op != EXEC_ASSIGN_CALL)
5793 gfc_trans_assign_need_temp (expr1, expr2,
5794 cmask, invert,
5795 nested_forall_info, block);
5796 else
5798 /* Variables to control maskexpr. */
5799 count1 = gfc_create_var (gfc_array_index_type, "count1");
5800 count2 = gfc_create_var (gfc_array_index_type, "count2");
5801 gfc_add_modify (block, count1, gfc_index_zero_node);
5802 gfc_add_modify (block, count2, gfc_index_zero_node);
5804 tmp = gfc_trans_where_assign (expr1, expr2,
5805 cmask, invert,
5806 count1, count2,
5807 cnext);
5809 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
5810 tmp, 1);
5811 gfc_add_expr_to_block (block, tmp);
5814 else
5816 /* Variables to control maskexpr. */
5817 count1 = gfc_create_var (gfc_array_index_type, "count1");
5818 count2 = gfc_create_var (gfc_array_index_type, "count2");
5819 gfc_add_modify (block, count1, gfc_index_zero_node);
5820 gfc_add_modify (block, count2, gfc_index_zero_node);
5822 tmp = gfc_trans_where_assign (expr1, expr2,
5823 cmask, invert,
5824 count1, count2,
5825 cnext);
5826 gfc_add_expr_to_block (block, tmp);
5829 break;
5831 /* WHERE or WHERE construct is part of a where-body-construct. */
5832 case EXEC_WHERE:
5833 gfc_trans_where_2 (cnext, cmask, invert,
5834 nested_forall_info, block);
5835 break;
5837 default:
5838 gcc_unreachable ();
5841 /* The next statement within the same where-body-construct. */
5842 cnext = cnext->next;
5844 /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt. */
5845 cblock = cblock->block;
5846 if (mask == NULL_TREE)
5848 /* If we're the initial WHERE, we can simply invert the sense
5849 of the current mask to obtain the "mask" for the remaining
5850 ELSEWHEREs. */
5851 invert = true;
5852 mask = cmask;
5854 else
5856 /* Otherwise, for nested WHERE's we need to use the pending mask. */
5857 invert = false;
5858 mask = pmask;
5862 /* If we allocated a pending mask array, deallocate it now. */
5863 if (ppmask)
5865 tmp = gfc_call_free (ppmask);
5866 gfc_add_expr_to_block (block, tmp);
5869 /* If we allocated a current mask array, deallocate it now. */
5870 if (pcmask)
5872 tmp = gfc_call_free (pcmask);
5873 gfc_add_expr_to_block (block, tmp);
5877 /* Translate a simple WHERE construct or statement without dependencies.
5878 CBLOCK is the "then" clause of the WHERE statement, where CBLOCK->EXPR
5879 is the mask condition, and EBLOCK if non-NULL is the "else" clause.
5880 Currently both CBLOCK and EBLOCK are restricted to single assignments. */
5882 static tree
5883 gfc_trans_where_3 (gfc_code * cblock, gfc_code * eblock)
5885 stmtblock_t block, body;
5886 gfc_expr *cond, *tdst, *tsrc, *edst, *esrc;
5887 tree tmp, cexpr, tstmt, estmt;
5888 gfc_ss *css, *tdss, *tsss;
5889 gfc_se cse, tdse, tsse, edse, esse;
5890 gfc_loopinfo loop;
5891 gfc_ss *edss = 0;
5892 gfc_ss *esss = 0;
5893 bool maybe_workshare = false;
5895 /* Allow the scalarizer to workshare simple where loops. */
5896 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
5897 == OMPWS_WORKSHARE_FLAG)
5899 maybe_workshare = true;
5900 ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
5903 cond = cblock->expr1;
5904 tdst = cblock->next->expr1;
5905 tsrc = cblock->next->expr2;
5906 edst = eblock ? eblock->next->expr1 : NULL;
5907 esrc = eblock ? eblock->next->expr2 : NULL;
5909 gfc_start_block (&block);
5910 gfc_init_loopinfo (&loop);
5912 /* Handle the condition. */
5913 gfc_init_se (&cse, NULL);
5914 css = gfc_walk_expr (cond);
5915 gfc_add_ss_to_loop (&loop, css);
5917 /* Handle the then-clause. */
5918 gfc_init_se (&tdse, NULL);
5919 gfc_init_se (&tsse, NULL);
5920 tdss = gfc_walk_expr (tdst);
5921 tsss = gfc_walk_expr (tsrc);
5922 if (tsss == gfc_ss_terminator)
5924 tsss = gfc_get_scalar_ss (gfc_ss_terminator, tsrc);
5925 tsss->info->where = 1;
5927 gfc_add_ss_to_loop (&loop, tdss);
5928 gfc_add_ss_to_loop (&loop, tsss);
5930 if (eblock)
5932 /* Handle the else clause. */
5933 gfc_init_se (&edse, NULL);
5934 gfc_init_se (&esse, NULL);
5935 edss = gfc_walk_expr (edst);
5936 esss = gfc_walk_expr (esrc);
5937 if (esss == gfc_ss_terminator)
5939 esss = gfc_get_scalar_ss (gfc_ss_terminator, esrc);
5940 esss->info->where = 1;
5942 gfc_add_ss_to_loop (&loop, edss);
5943 gfc_add_ss_to_loop (&loop, esss);
5946 gfc_conv_ss_startstride (&loop);
5947 gfc_conv_loop_setup (&loop, &tdst->where);
5949 gfc_mark_ss_chain_used (css, 1);
5950 gfc_mark_ss_chain_used (tdss, 1);
5951 gfc_mark_ss_chain_used (tsss, 1);
5952 if (eblock)
5954 gfc_mark_ss_chain_used (edss, 1);
5955 gfc_mark_ss_chain_used (esss, 1);
5958 gfc_start_scalarized_body (&loop, &body);
5960 gfc_copy_loopinfo_to_se (&cse, &loop);
5961 gfc_copy_loopinfo_to_se (&tdse, &loop);
5962 gfc_copy_loopinfo_to_se (&tsse, &loop);
5963 cse.ss = css;
5964 tdse.ss = tdss;
5965 tsse.ss = tsss;
5966 if (eblock)
5968 gfc_copy_loopinfo_to_se (&edse, &loop);
5969 gfc_copy_loopinfo_to_se (&esse, &loop);
5970 edse.ss = edss;
5971 esse.ss = esss;
5974 gfc_conv_expr (&cse, cond);
5975 gfc_add_block_to_block (&body, &cse.pre);
5976 cexpr = cse.expr;
5978 gfc_conv_expr (&tsse, tsrc);
5979 if (tdss != gfc_ss_terminator && loop.temp_ss != NULL)
5980 gfc_conv_tmp_array_ref (&tdse);
5981 else
5982 gfc_conv_expr (&tdse, tdst);
5984 if (eblock)
5986 gfc_conv_expr (&esse, esrc);
5987 if (edss != gfc_ss_terminator && loop.temp_ss != NULL)
5988 gfc_conv_tmp_array_ref (&edse);
5989 else
5990 gfc_conv_expr (&edse, edst);
5993 tstmt = gfc_trans_scalar_assign (&tdse, &tsse, tdst->ts, false, true);
5994 estmt = eblock ? gfc_trans_scalar_assign (&edse, &esse, edst->ts,
5995 false, true)
5996 : build_empty_stmt (input_location);
5997 tmp = build3_v (COND_EXPR, cexpr, tstmt, estmt);
5998 gfc_add_expr_to_block (&body, tmp);
5999 gfc_add_block_to_block (&body, &cse.post);
6001 if (maybe_workshare)
6002 ompws_flags &= ~OMPWS_SCALARIZER_BODY;
6003 gfc_trans_scalarizing_loops (&loop, &body);
6004 gfc_add_block_to_block (&block, &loop.pre);
6005 gfc_add_block_to_block (&block, &loop.post);
6006 gfc_cleanup_loop (&loop);
6008 return gfc_finish_block (&block);
6011 /* As the WHERE or WHERE construct statement can be nested, we call
6012 gfc_trans_where_2 to do the translation, and pass the initial
6013 NULL values for both the control mask and the pending control mask. */
6015 tree
6016 gfc_trans_where (gfc_code * code)
6018 stmtblock_t block;
6019 gfc_code *cblock;
6020 gfc_code *eblock;
6022 cblock = code->block;
6023 if (cblock->next
6024 && cblock->next->op == EXEC_ASSIGN
6025 && !cblock->next->next)
6027 eblock = cblock->block;
6028 if (!eblock)
6030 /* A simple "WHERE (cond) x = y" statement or block is
6031 dependence free if cond is not dependent upon writing x,
6032 and the source y is unaffected by the destination x. */
6033 if (!gfc_check_dependency (cblock->next->expr1,
6034 cblock->expr1, 0)
6035 && !gfc_check_dependency (cblock->next->expr1,
6036 cblock->next->expr2, 0))
6037 return gfc_trans_where_3 (cblock, NULL);
6039 else if (!eblock->expr1
6040 && !eblock->block
6041 && eblock->next
6042 && eblock->next->op == EXEC_ASSIGN
6043 && !eblock->next->next)
6045 /* A simple "WHERE (cond) x1 = y1 ELSEWHERE x2 = y2 ENDWHERE"
6046 block is dependence free if cond is not dependent on writes
6047 to x1 and x2, y1 is not dependent on writes to x2, and y2
6048 is not dependent on writes to x1, and both y's are not
6049 dependent upon their own x's. In addition to this, the
6050 final two dependency checks below exclude all but the same
6051 array reference if the where and elswhere destinations
6052 are the same. In short, this is VERY conservative and this
6053 is needed because the two loops, required by the standard
6054 are coalesced in gfc_trans_where_3. */
6055 if (!gfc_check_dependency (cblock->next->expr1,
6056 cblock->expr1, 0)
6057 && !gfc_check_dependency (eblock->next->expr1,
6058 cblock->expr1, 0)
6059 && !gfc_check_dependency (cblock->next->expr1,
6060 eblock->next->expr2, 1)
6061 && !gfc_check_dependency (eblock->next->expr1,
6062 cblock->next->expr2, 1)
6063 && !gfc_check_dependency (cblock->next->expr1,
6064 cblock->next->expr2, 1)
6065 && !gfc_check_dependency (eblock->next->expr1,
6066 eblock->next->expr2, 1)
6067 && !gfc_check_dependency (cblock->next->expr1,
6068 eblock->next->expr1, 0)
6069 && !gfc_check_dependency (eblock->next->expr1,
6070 cblock->next->expr1, 0))
6071 return gfc_trans_where_3 (cblock, eblock);
6075 gfc_start_block (&block);
6077 gfc_trans_where_2 (code, NULL, false, NULL, &block);
6079 return gfc_finish_block (&block);
6083 /* CYCLE a DO loop. The label decl has already been created by
6084 gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
6085 node at the head of the loop. We must mark the label as used. */
6087 tree
6088 gfc_trans_cycle (gfc_code * code)
6090 tree cycle_label;
6092 cycle_label = code->ext.which_construct->cycle_label;
6093 gcc_assert (cycle_label);
6095 TREE_USED (cycle_label) = 1;
6096 return build1_v (GOTO_EXPR, cycle_label);
6100 /* EXIT a DO loop. Similar to CYCLE, but now the label is in
6101 TREE_VALUE (backend_decl) of the gfc_code node at the head of the
6102 loop. */
6104 tree
6105 gfc_trans_exit (gfc_code * code)
6107 tree exit_label;
6109 exit_label = code->ext.which_construct->exit_label;
6110 gcc_assert (exit_label);
6112 TREE_USED (exit_label) = 1;
6113 return build1_v (GOTO_EXPR, exit_label);
6117 /* Get the initializer expression for the code and expr of an allocate.
6118 When no initializer is needed return NULL. */
6120 static gfc_expr *
6121 allocate_get_initializer (gfc_code * code, gfc_expr * expr)
6123 if (!gfc_bt_struct (expr->ts.type) && expr->ts.type != BT_CLASS)
6124 return NULL;
6126 /* An explicit type was given in allocate ( T:: object). */
6127 if (code->ext.alloc.ts.type == BT_DERIVED
6128 && (code->ext.alloc.ts.u.derived->attr.alloc_comp
6129 || gfc_has_default_initializer (code->ext.alloc.ts.u.derived)))
6130 return gfc_default_initializer (&code->ext.alloc.ts);
6132 if (gfc_bt_struct (expr->ts.type)
6133 && (expr->ts.u.derived->attr.alloc_comp
6134 || gfc_has_default_initializer (expr->ts.u.derived)))
6135 return gfc_default_initializer (&expr->ts);
6137 if (expr->ts.type == BT_CLASS
6138 && (CLASS_DATA (expr)->ts.u.derived->attr.alloc_comp
6139 || gfc_has_default_initializer (CLASS_DATA (expr)->ts.u.derived)))
6140 return gfc_default_initializer (&CLASS_DATA (expr)->ts);
6142 return NULL;
6145 /* Translate the ALLOCATE statement. */
6147 tree
6148 gfc_trans_allocate (gfc_code * code)
6150 gfc_alloc *al;
6151 gfc_expr *expr, *e3rhs = NULL, *init_expr;
6152 gfc_se se, se_sz;
6153 tree tmp;
6154 tree parm;
6155 tree stat;
6156 tree errmsg;
6157 tree errlen;
6158 tree label_errmsg;
6159 tree label_finish;
6160 tree memsz;
6161 tree al_vptr, al_len;
6162 /* If an expr3 is present, then store the tree for accessing its
6163 _vptr, and _len components in the variables, respectively. The
6164 element size, i.e. _vptr%size, is stored in expr3_esize. Any of
6165 the trees may be the NULL_TREE indicating that this is not
6166 available for expr3's type. */
6167 tree expr3, expr3_vptr, expr3_len, expr3_esize;
6168 /* Classify what expr3 stores. */
6169 enum { E3_UNSET = 0, E3_SOURCE, E3_MOLD, E3_DESC } e3_is;
6170 stmtblock_t block;
6171 stmtblock_t post;
6172 stmtblock_t final_block;
6173 tree nelems;
6174 bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set, is_coarray;
6175 bool needs_caf_sync, caf_refs_comp;
6176 bool e3_has_nodescriptor = false;
6177 gfc_symtree *newsym = NULL;
6178 symbol_attribute caf_attr;
6179 gfc_actual_arglist *param_list;
6181 if (!code->ext.alloc.list)
6182 return NULL_TREE;
6184 stat = tmp = memsz = al_vptr = al_len = NULL_TREE;
6185 expr3 = expr3_vptr = expr3_len = expr3_esize = NULL_TREE;
6186 label_errmsg = label_finish = errmsg = errlen = NULL_TREE;
6187 e3_is = E3_UNSET;
6188 is_coarray = needs_caf_sync = false;
6190 gfc_init_block (&block);
6191 gfc_init_block (&post);
6192 gfc_init_block (&final_block);
6194 /* STAT= (and maybe ERRMSG=) is present. */
6195 if (code->expr1)
6197 /* STAT=. */
6198 tree gfc_int4_type_node = gfc_get_int_type (4);
6199 stat = gfc_create_var (gfc_int4_type_node, "stat");
6201 /* ERRMSG= only makes sense with STAT=. */
6202 if (code->expr2)
6204 gfc_init_se (&se, NULL);
6205 se.want_pointer = 1;
6206 gfc_conv_expr_lhs (&se, code->expr2);
6207 errmsg = se.expr;
6208 errlen = se.string_length;
6210 else
6212 errmsg = null_pointer_node;
6213 errlen = build_int_cst (gfc_charlen_type_node, 0);
6216 /* GOTO destinations. */
6217 label_errmsg = gfc_build_label_decl (NULL_TREE);
6218 label_finish = gfc_build_label_decl (NULL_TREE);
6219 TREE_USED (label_finish) = 0;
6222 /* When an expr3 is present evaluate it only once. The standards prevent a
6223 dependency of expr3 on the objects in the allocate list. An expr3 can
6224 be pre-evaluated in all cases. One just has to make sure, to use the
6225 correct way, i.e., to get the descriptor or to get a reference
6226 expression. */
6227 if (code->expr3)
6229 bool vtab_needed = false, temp_var_needed = false,
6230 temp_obj_created = false;
6232 is_coarray = gfc_is_coarray (code->expr3);
6234 if (code->expr3->expr_type == EXPR_FUNCTION && !code->expr3->mold
6235 && (gfc_is_class_array_function (code->expr3)
6236 || gfc_is_alloc_class_scalar_function (code->expr3)))
6237 code->expr3->must_finalize = 1;
6239 /* Figure whether we need the vtab from expr3. */
6240 for (al = code->ext.alloc.list; !vtab_needed && al != NULL;
6241 al = al->next)
6242 vtab_needed = (al->expr->ts.type == BT_CLASS);
6244 gfc_init_se (&se, NULL);
6245 /* When expr3 is a variable, i.e., a very simple expression,
6246 then convert it once here. */
6247 if (code->expr3->expr_type == EXPR_VARIABLE
6248 || code->expr3->expr_type == EXPR_ARRAY
6249 || code->expr3->expr_type == EXPR_CONSTANT)
6251 if (!code->expr3->mold
6252 || code->expr3->ts.type == BT_CHARACTER
6253 || vtab_needed
6254 || code->ext.alloc.arr_spec_from_expr3)
6256 /* Convert expr3 to a tree. For all "simple" expression just
6257 get the descriptor or the reference, respectively, depending
6258 on the rank of the expr. */
6259 if (code->ext.alloc.arr_spec_from_expr3 || code->expr3->rank != 0)
6260 gfc_conv_expr_descriptor (&se, code->expr3);
6261 else
6263 gfc_conv_expr_reference (&se, code->expr3);
6265 /* gfc_conv_expr_reference wraps POINTER_PLUS_EXPR in a
6266 NOP_EXPR, which prevents gfortran from getting the vptr
6267 from the source=-expression. Remove the NOP_EXPR and go
6268 with the POINTER_PLUS_EXPR in this case. */
6269 if (code->expr3->ts.type == BT_CLASS
6270 && TREE_CODE (se.expr) == NOP_EXPR
6271 && (TREE_CODE (TREE_OPERAND (se.expr, 0))
6272 == POINTER_PLUS_EXPR
6273 || is_coarray))
6274 se.expr = TREE_OPERAND (se.expr, 0);
6276 /* Create a temp variable only for component refs to prevent
6277 having to go through the full deref-chain each time and to
6278 simplfy computation of array properties. */
6279 temp_var_needed = TREE_CODE (se.expr) == COMPONENT_REF;
6282 else
6284 /* In all other cases evaluate the expr3. */
6285 symbol_attribute attr;
6286 /* Get the descriptor for all arrays, that are not allocatable or
6287 pointer, because the latter are descriptors already.
6288 The exception are function calls returning a class object:
6289 The descriptor is stored in their results _data component, which
6290 is easier to access, when first a temporary variable for the
6291 result is created and the descriptor retrieved from there. */
6292 attr = gfc_expr_attr (code->expr3);
6293 if (code->expr3->rank != 0
6294 && ((!attr.allocatable && !attr.pointer)
6295 || (code->expr3->expr_type == EXPR_FUNCTION
6296 && (code->expr3->ts.type != BT_CLASS
6297 || (code->expr3->value.function.isym
6298 && code->expr3->value.function.isym
6299 ->transformational)))))
6300 gfc_conv_expr_descriptor (&se, code->expr3);
6301 else
6302 gfc_conv_expr_reference (&se, code->expr3);
6303 if (code->expr3->ts.type == BT_CLASS)
6304 gfc_conv_class_to_class (&se, code->expr3,
6305 code->expr3->ts,
6306 false, true,
6307 false, false);
6308 temp_obj_created = temp_var_needed = !VAR_P (se.expr);
6310 gfc_add_block_to_block (&block, &se.pre);
6311 if (code->expr3->must_finalize)
6312 gfc_add_block_to_block (&final_block, &se.post);
6313 else
6314 gfc_add_block_to_block (&post, &se.post);
6316 /* Special case when string in expr3 is zero. */
6317 if (code->expr3->ts.type == BT_CHARACTER
6318 && integer_zerop (se.string_length))
6320 gfc_init_se (&se, NULL);
6321 temp_var_needed = false;
6322 expr3_len = build_zero_cst (gfc_charlen_type_node);
6323 e3_is = E3_MOLD;
6325 /* Prevent aliasing, i.e., se.expr may be already a
6326 variable declaration. */
6327 else if (se.expr != NULL_TREE && temp_var_needed)
6329 tree var, desc;
6330 tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)) || is_coarray ?
6331 se.expr
6332 : build_fold_indirect_ref_loc (input_location, se.expr);
6334 /* Get the array descriptor and prepare it to be assigned to the
6335 temporary variable var. For classes the array descriptor is
6336 in the _data component and the object goes into the
6337 GFC_DECL_SAVED_DESCRIPTOR. */
6338 if (code->expr3->ts.type == BT_CLASS
6339 && code->expr3->rank != 0)
6341 /* When an array_ref was in expr3, then the descriptor is the
6342 first operand. */
6343 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
6345 desc = TREE_OPERAND (tmp, 0);
6347 else
6349 desc = tmp;
6350 tmp = gfc_class_data_get (tmp);
6352 if (code->ext.alloc.arr_spec_from_expr3)
6353 e3_is = E3_DESC;
6355 else
6356 desc = !is_coarray ? se.expr
6357 : TREE_OPERAND (TREE_OPERAND (se.expr, 0), 0);
6358 /* We need a regular (non-UID) symbol here, therefore give a
6359 prefix. */
6360 var = gfc_create_var (TREE_TYPE (tmp), "source");
6361 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
6363 gfc_allocate_lang_decl (var);
6364 GFC_DECL_SAVED_DESCRIPTOR (var) = desc;
6366 gfc_add_modify_loc (input_location, &block, var, tmp);
6368 expr3 = var;
6369 if (se.string_length)
6370 /* Evaluate it assuming that it also is complicated like expr3. */
6371 expr3_len = gfc_evaluate_now (se.string_length, &block);
6373 else
6375 expr3 = se.expr;
6376 expr3_len = se.string_length;
6379 /* Deallocate any allocatable components in expressions that use a
6380 temporary object, i.e. are not a simple alias of to an EXPR_VARIABLE.
6381 E.g. temporaries of a function call need freeing of their components
6382 here. */
6383 if ((code->expr3->ts.type == BT_DERIVED
6384 || code->expr3->ts.type == BT_CLASS)
6385 && (code->expr3->expr_type != EXPR_VARIABLE || temp_obj_created)
6386 && code->expr3->ts.u.derived->attr.alloc_comp
6387 && !code->expr3->must_finalize)
6389 tmp = gfc_deallocate_alloc_comp (code->expr3->ts.u.derived,
6390 expr3, code->expr3->rank);
6391 gfc_prepend_expr_to_block (&post, tmp);
6394 /* Store what the expr3 is to be used for. */
6395 if (e3_is == E3_UNSET)
6396 e3_is = expr3 != NULL_TREE ?
6397 (code->ext.alloc.arr_spec_from_expr3 ?
6398 E3_DESC
6399 : (code->expr3->mold ? E3_MOLD : E3_SOURCE))
6400 : E3_UNSET;
6402 /* Figure how to get the _vtab entry. This also obtains the tree
6403 expression for accessing the _len component, because only
6404 unlimited polymorphic objects, which are a subcategory of class
6405 types, have a _len component. */
6406 if (code->expr3->ts.type == BT_CLASS)
6408 gfc_expr *rhs;
6409 tmp = expr3 != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (expr3)) ?
6410 build_fold_indirect_ref (expr3): expr3;
6411 /* Polymorphic SOURCE: VPTR must be determined at run time.
6412 expr3 may be a temporary array declaration, therefore check for
6413 GFC_CLASS_TYPE_P before trying to get the _vptr component. */
6414 if (tmp != NULL_TREE
6415 && (e3_is == E3_DESC
6416 || (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
6417 && (VAR_P (tmp) || !code->expr3->ref))
6418 || (VAR_P (tmp) && DECL_LANG_SPECIFIC (tmp))))
6419 tmp = gfc_class_vptr_get (expr3);
6420 else
6422 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
6423 gfc_add_vptr_component (rhs);
6424 gfc_init_se (&se, NULL);
6425 se.want_pointer = 1;
6426 gfc_conv_expr (&se, rhs);
6427 tmp = se.expr;
6428 gfc_free_expr (rhs);
6430 /* Set the element size. */
6431 expr3_esize = gfc_vptr_size_get (tmp);
6432 if (vtab_needed)
6433 expr3_vptr = tmp;
6434 /* Initialize the ref to the _len component. */
6435 if (expr3_len == NULL_TREE && UNLIMITED_POLY (code->expr3))
6437 /* Same like for retrieving the _vptr. */
6438 if (expr3 != NULL_TREE && !code->expr3->ref)
6439 expr3_len = gfc_class_len_get (expr3);
6440 else
6442 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
6443 gfc_add_len_component (rhs);
6444 gfc_init_se (&se, NULL);
6445 gfc_conv_expr (&se, rhs);
6446 expr3_len = se.expr;
6447 gfc_free_expr (rhs);
6451 else
6453 /* When the object to allocate is polymorphic type, then it
6454 needs its vtab set correctly, so deduce the required _vtab
6455 and _len from the source expression. */
6456 if (vtab_needed)
6458 /* VPTR is fixed at compile time. */
6459 gfc_symbol *vtab;
6461 vtab = gfc_find_vtab (&code->expr3->ts);
6462 gcc_assert (vtab);
6463 expr3_vptr = gfc_get_symbol_decl (vtab);
6464 expr3_vptr = gfc_build_addr_expr (NULL_TREE,
6465 expr3_vptr);
6467 /* _len component needs to be set, when ts is a character
6468 array. */
6469 if (expr3_len == NULL_TREE
6470 && code->expr3->ts.type == BT_CHARACTER)
6472 if (code->expr3->ts.u.cl
6473 && code->expr3->ts.u.cl->length)
6475 gfc_init_se (&se, NULL);
6476 gfc_conv_expr (&se, code->expr3->ts.u.cl->length);
6477 gfc_add_block_to_block (&block, &se.pre);
6478 expr3_len = gfc_evaluate_now (se.expr, &block);
6480 gcc_assert (expr3_len);
6482 /* For character arrays only the kind's size is needed, because
6483 the array mem_size is _len * (elem_size = kind_size).
6484 For all other get the element size in the normal way. */
6485 if (code->expr3->ts.type == BT_CHARACTER)
6486 expr3_esize = TYPE_SIZE_UNIT (
6487 gfc_get_char_type (code->expr3->ts.kind));
6488 else
6489 expr3_esize = TYPE_SIZE_UNIT (
6490 gfc_typenode_for_spec (&code->expr3->ts));
6492 gcc_assert (expr3_esize);
6493 expr3_esize = fold_convert (sizetype, expr3_esize);
6494 if (e3_is == E3_MOLD)
6495 /* The expr3 is no longer valid after this point. */
6496 expr3 = NULL_TREE;
6498 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
6500 /* Compute the explicit typespec given only once for all objects
6501 to allocate. */
6502 if (code->ext.alloc.ts.type != BT_CHARACTER)
6503 expr3_esize = TYPE_SIZE_UNIT (
6504 gfc_typenode_for_spec (&code->ext.alloc.ts));
6505 else if (code->ext.alloc.ts.u.cl->length != NULL)
6507 gfc_expr *sz;
6508 sz = gfc_copy_expr (code->ext.alloc.ts.u.cl->length);
6509 gfc_init_se (&se_sz, NULL);
6510 gfc_conv_expr (&se_sz, sz);
6511 gfc_free_expr (sz);
6512 tmp = gfc_get_char_type (code->ext.alloc.ts.kind);
6513 tmp = TYPE_SIZE_UNIT (tmp);
6514 tmp = fold_convert (TREE_TYPE (se_sz.expr), tmp);
6515 gfc_add_block_to_block (&block, &se_sz.pre);
6516 expr3_esize = fold_build2_loc (input_location, MULT_EXPR,
6517 TREE_TYPE (se_sz.expr),
6518 tmp, se_sz.expr);
6519 expr3_esize = gfc_evaluate_now (expr3_esize, &block);
6521 else
6522 expr3_esize = NULL_TREE;
6525 /* The routine gfc_trans_assignment () already implements all
6526 techniques needed. Unfortunately we may have a temporary
6527 variable for the source= expression here. When that is the
6528 case convert this variable into a temporary gfc_expr of type
6529 EXPR_VARIABLE and used it as rhs for the assignment. The
6530 advantage is, that we get scalarizer support for free,
6531 don't have to take care about scalar to array treatment and
6532 will benefit of every enhancements gfc_trans_assignment ()
6533 gets.
6534 No need to check whether e3_is is E3_UNSET, because that is
6535 done by expr3 != NULL_TREE.
6536 Exclude variables since the following block does not handle
6537 array sections. In any case, there is no harm in sending
6538 variables to gfc_trans_assignment because there is no
6539 evaluation of variables. */
6540 if (code->expr3)
6542 if (code->expr3->expr_type != EXPR_VARIABLE
6543 && e3_is != E3_MOLD && expr3 != NULL_TREE
6544 && DECL_P (expr3) && DECL_ARTIFICIAL (expr3))
6546 /* Build a temporary symtree and symbol. Do not add it to the current
6547 namespace to prevent accidently modifying a colliding
6548 symbol's as. */
6549 newsym = XCNEW (gfc_symtree);
6550 /* The name of the symtree should be unique, because gfc_create_var ()
6551 took care about generating the identifier. */
6552 newsym->name
6553 = gfc_get_string ("%s", IDENTIFIER_POINTER (DECL_NAME (expr3)));
6554 newsym->n.sym = gfc_new_symbol (newsym->name, NULL);
6555 /* The backend_decl is known. It is expr3, which is inserted
6556 here. */
6557 newsym->n.sym->backend_decl = expr3;
6558 e3rhs = gfc_get_expr ();
6559 e3rhs->rank = code->expr3->rank;
6560 e3rhs->symtree = newsym;
6561 /* Mark the symbol referenced or gfc_trans_assignment will bug. */
6562 newsym->n.sym->attr.referenced = 1;
6563 e3rhs->expr_type = EXPR_VARIABLE;
6564 e3rhs->where = code->expr3->where;
6565 /* Set the symbols type, upto it was BT_UNKNOWN. */
6566 if (IS_CLASS_ARRAY (code->expr3)
6567 && code->expr3->expr_type == EXPR_FUNCTION
6568 && code->expr3->value.function.isym
6569 && code->expr3->value.function.isym->transformational)
6571 e3rhs->ts = CLASS_DATA (code->expr3)->ts;
6573 else if (code->expr3->ts.type == BT_CLASS
6574 && !GFC_CLASS_TYPE_P (TREE_TYPE (expr3)))
6575 e3rhs->ts = CLASS_DATA (code->expr3)->ts;
6576 else
6577 e3rhs->ts = code->expr3->ts;
6578 newsym->n.sym->ts = e3rhs->ts;
6579 /* Check whether the expr3 is array valued. */
6580 if (e3rhs->rank)
6582 gfc_array_spec *arr;
6583 arr = gfc_get_array_spec ();
6584 arr->rank = e3rhs->rank;
6585 arr->type = AS_DEFERRED;
6586 /* Set the dimension and pointer attribute for arrays
6587 to be on the safe side. */
6588 newsym->n.sym->attr.dimension = 1;
6589 newsym->n.sym->attr.pointer = 1;
6590 newsym->n.sym->as = arr;
6591 if (IS_CLASS_ARRAY (code->expr3)
6592 && code->expr3->expr_type == EXPR_FUNCTION
6593 && code->expr3->value.function.isym
6594 && code->expr3->value.function.isym->transformational)
6596 gfc_array_spec *tarr;
6597 tarr = gfc_get_array_spec ();
6598 *tarr = *arr;
6599 e3rhs->ts.u.derived->as = tarr;
6601 gfc_add_full_array_ref (e3rhs, arr);
6603 else if (POINTER_TYPE_P (TREE_TYPE (expr3)))
6604 newsym->n.sym->attr.pointer = 1;
6605 /* The string length is known, too. Set it for char arrays. */
6606 if (e3rhs->ts.type == BT_CHARACTER)
6607 newsym->n.sym->ts.u.cl->backend_decl = expr3_len;
6608 gfc_commit_symbol (newsym->n.sym);
6610 else
6611 e3rhs = gfc_copy_expr (code->expr3);
6613 // We need to propagate the bounds of the expr3 for source=/mold=;
6614 // however, for nondescriptor arrays, we use internally a lower bound
6615 // of zero instead of one, which needs to be corrected for the allocate obj
6616 if (e3_is == E3_DESC)
6618 symbol_attribute attr = gfc_expr_attr (code->expr3);
6619 if (code->expr3->expr_type == EXPR_ARRAY ||
6620 (!attr.allocatable && !attr.pointer))
6621 e3_has_nodescriptor = true;
6625 /* Loop over all objects to allocate. */
6626 for (al = code->ext.alloc.list; al != NULL; al = al->next)
6628 expr = gfc_copy_expr (al->expr);
6629 /* UNLIMITED_POLY () needs the _data component to be set, when
6630 expr is a unlimited polymorphic object. But the _data component
6631 has not been set yet, so check the derived type's attr for the
6632 unlimited polymorphic flag to be safe. */
6633 upoly_expr = UNLIMITED_POLY (expr)
6634 || (expr->ts.type == BT_DERIVED
6635 && expr->ts.u.derived->attr.unlimited_polymorphic);
6636 gfc_init_se (&se, NULL);
6638 /* For class types prepare the expressions to ref the _vptr
6639 and the _len component. The latter for unlimited polymorphic
6640 types only. */
6641 if (expr->ts.type == BT_CLASS)
6643 gfc_expr *expr_ref_vptr, *expr_ref_len;
6644 gfc_add_data_component (expr);
6645 /* Prep the vptr handle. */
6646 expr_ref_vptr = gfc_copy_expr (al->expr);
6647 gfc_add_vptr_component (expr_ref_vptr);
6648 se.want_pointer = 1;
6649 gfc_conv_expr (&se, expr_ref_vptr);
6650 al_vptr = se.expr;
6651 se.want_pointer = 0;
6652 gfc_free_expr (expr_ref_vptr);
6653 /* Allocated unlimited polymorphic objects always have a _len
6654 component. */
6655 if (upoly_expr)
6657 expr_ref_len = gfc_copy_expr (al->expr);
6658 gfc_add_len_component (expr_ref_len);
6659 gfc_conv_expr (&se, expr_ref_len);
6660 al_len = se.expr;
6661 gfc_free_expr (expr_ref_len);
6663 else
6664 /* In a loop ensure that all loop variable dependent variables
6665 are initialized at the same spot in all execution paths. */
6666 al_len = NULL_TREE;
6668 else
6669 al_vptr = al_len = NULL_TREE;
6671 se.want_pointer = 1;
6672 se.descriptor_only = 1;
6674 gfc_conv_expr (&se, expr);
6675 if (expr->ts.type == BT_CHARACTER && expr->ts.deferred)
6676 /* se.string_length now stores the .string_length variable of expr
6677 needed to allocate character(len=:) arrays. */
6678 al_len = se.string_length;
6680 al_len_needs_set = al_len != NULL_TREE;
6681 /* When allocating an array one cannot use much of the
6682 pre-evaluated expr3 expressions, because for most of them the
6683 scalarizer is needed which is not available in the pre-evaluation
6684 step. Therefore gfc_array_allocate () is responsible (and able)
6685 to handle the complete array allocation. Only the element size
6686 needs to be provided, which is done most of the time by the
6687 pre-evaluation step. */
6688 nelems = NULL_TREE;
6689 if (expr3_len && (code->expr3->ts.type == BT_CHARACTER
6690 || code->expr3->ts.type == BT_CLASS))
6692 /* When al is an array, then the element size for each element
6693 in the array is needed, which is the product of the len and
6694 esize for char arrays. For unlimited polymorphics len can be
6695 zero, therefore take the maximum of len and one. */
6696 tmp = fold_build2_loc (input_location, MAX_EXPR,
6697 TREE_TYPE (expr3_len),
6698 expr3_len, fold_convert (TREE_TYPE (expr3_len),
6699 integer_one_node));
6700 tmp = fold_build2_loc (input_location, MULT_EXPR,
6701 TREE_TYPE (expr3_esize), expr3_esize,
6702 fold_convert (TREE_TYPE (expr3_esize), tmp));
6704 else
6705 tmp = expr3_esize;
6707 if (!gfc_array_allocate (&se, expr, stat, errmsg, errlen,
6708 label_finish, tmp, &nelems,
6709 e3rhs ? e3rhs : code->expr3,
6710 e3_is == E3_DESC ? expr3 : NULL_TREE,
6711 e3_has_nodescriptor))
6713 /* A scalar or derived type. First compute the size to
6714 allocate.
6716 expr3_len is set when expr3 is an unlimited polymorphic
6717 object or a deferred length string. */
6718 if (expr3_len != NULL_TREE)
6720 tmp = fold_convert (TREE_TYPE (expr3_esize), expr3_len);
6721 tmp = fold_build2_loc (input_location, MULT_EXPR,
6722 TREE_TYPE (expr3_esize),
6723 expr3_esize, tmp);
6724 if (code->expr3->ts.type != BT_CLASS)
6725 /* expr3 is a deferred length string, i.e., we are
6726 done. */
6727 memsz = tmp;
6728 else
6730 /* For unlimited polymorphic enties build
6731 (len > 0) ? element_size * len : element_size
6732 to compute the number of bytes to allocate.
6733 This allows the allocation of unlimited polymorphic
6734 objects from an expr3 that is also unlimited
6735 polymorphic and stores a _len dependent object,
6736 e.g., a string. */
6737 memsz = fold_build2_loc (input_location, GT_EXPR,
6738 logical_type_node, expr3_len,
6739 build_zero_cst
6740 (TREE_TYPE (expr3_len)));
6741 memsz = fold_build3_loc (input_location, COND_EXPR,
6742 TREE_TYPE (expr3_esize),
6743 memsz, tmp, expr3_esize);
6746 else if (expr3_esize != NULL_TREE)
6747 /* Any other object in expr3 just needs element size in
6748 bytes. */
6749 memsz = expr3_esize;
6750 else if ((expr->ts.type == BT_CHARACTER && expr->ts.deferred)
6751 || (upoly_expr
6752 && code->ext.alloc.ts.type == BT_CHARACTER))
6754 /* Allocating deferred length char arrays need the length
6755 to allocate in the alloc_type_spec. But also unlimited
6756 polymorphic objects may be allocated as char arrays.
6757 Both are handled here. */
6758 gfc_init_se (&se_sz, NULL);
6759 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6760 gfc_add_block_to_block (&se.pre, &se_sz.pre);
6761 se_sz.expr = gfc_evaluate_now (se_sz.expr, &se.pre);
6762 gfc_add_block_to_block (&se.pre, &se_sz.post);
6763 expr3_len = se_sz.expr;
6764 tmp_expr3_len_flag = true;
6765 tmp = TYPE_SIZE_UNIT (
6766 gfc_get_char_type (code->ext.alloc.ts.kind));
6767 memsz = fold_build2_loc (input_location, MULT_EXPR,
6768 TREE_TYPE (tmp),
6769 fold_convert (TREE_TYPE (tmp),
6770 expr3_len),
6771 tmp);
6773 else if (expr->ts.type == BT_CHARACTER)
6775 /* Compute the number of bytes needed to allocate a fixed
6776 length char array. */
6777 gcc_assert (se.string_length != NULL_TREE);
6778 tmp = TYPE_SIZE_UNIT (gfc_get_char_type (expr->ts.kind));
6779 memsz = fold_build2_loc (input_location, MULT_EXPR,
6780 TREE_TYPE (tmp), tmp,
6781 fold_convert (TREE_TYPE (tmp),
6782 se.string_length));
6784 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
6785 /* Handle all types, where the alloc_type_spec is set. */
6786 memsz = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->ext.alloc.ts));
6787 else
6788 /* Handle size computation of the type declared to alloc. */
6789 memsz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
6791 /* Store the caf-attributes for latter use. */
6792 if (flag_coarray == GFC_FCOARRAY_LIB
6793 && (caf_attr = gfc_caf_attr (expr, true, &caf_refs_comp))
6794 .codimension)
6796 /* Scalar allocatable components in coarray'ed derived types make
6797 it here and are treated now. */
6798 tree caf_decl, token;
6799 gfc_se caf_se;
6801 is_coarray = true;
6802 /* Set flag, to add synchronize after the allocate. */
6803 needs_caf_sync = needs_caf_sync
6804 || caf_attr.coarray_comp || !caf_refs_comp;
6806 gfc_init_se (&caf_se, NULL);
6808 caf_decl = gfc_get_tree_for_caf_expr (expr);
6809 gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl,
6810 NULL_TREE, NULL);
6811 gfc_add_block_to_block (&se.pre, &caf_se.pre);
6812 gfc_allocate_allocatable (&se.pre, se.expr, memsz,
6813 gfc_build_addr_expr (NULL_TREE, token),
6814 NULL_TREE, NULL_TREE, NULL_TREE,
6815 label_finish, expr, 1);
6817 /* Allocate - for non-pointers with re-alloc checking. */
6818 else if (gfc_expr_attr (expr).allocatable)
6819 gfc_allocate_allocatable (&se.pre, se.expr, memsz,
6820 NULL_TREE, stat, errmsg, errlen,
6821 label_finish, expr, 0);
6822 else
6823 gfc_allocate_using_malloc (&se.pre, se.expr, memsz, stat);
6825 else
6827 /* Allocating coarrays needs a sync after the allocate executed.
6828 Set the flag to add the sync after all objects are allocated. */
6829 if (flag_coarray == GFC_FCOARRAY_LIB
6830 && (caf_attr = gfc_caf_attr (expr, true, &caf_refs_comp))
6831 .codimension)
6833 is_coarray = true;
6834 needs_caf_sync = needs_caf_sync
6835 || caf_attr.coarray_comp || !caf_refs_comp;
6838 if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
6839 && expr3_len != NULL_TREE)
6841 /* Arrays need to have a _len set before the array
6842 descriptor is filled. */
6843 gfc_add_modify (&block, al_len,
6844 fold_convert (TREE_TYPE (al_len), expr3_len));
6845 /* Prevent setting the length twice. */
6846 al_len_needs_set = false;
6848 else if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
6849 && code->ext.alloc.ts.u.cl->length)
6851 /* Cover the cases where a string length is explicitly
6852 specified by a type spec for deferred length character
6853 arrays or unlimited polymorphic objects without a
6854 source= or mold= expression. */
6855 gfc_init_se (&se_sz, NULL);
6856 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6857 gfc_add_block_to_block (&block, &se_sz.pre);
6858 gfc_add_modify (&block, al_len,
6859 fold_convert (TREE_TYPE (al_len),
6860 se_sz.expr));
6861 al_len_needs_set = false;
6865 gfc_add_block_to_block (&block, &se.pre);
6867 /* Error checking -- Note: ERRMSG only makes sense with STAT. */
6868 if (code->expr1)
6870 tmp = build1_v (GOTO_EXPR, label_errmsg);
6871 parm = fold_build2_loc (input_location, NE_EXPR,
6872 logical_type_node, stat,
6873 build_int_cst (TREE_TYPE (stat), 0));
6874 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6875 gfc_unlikely (parm, PRED_FORTRAN_FAIL_ALLOC),
6876 tmp, build_empty_stmt (input_location));
6877 gfc_add_expr_to_block (&block, tmp);
6880 /* Set the vptr only when no source= is set. When source= is set, then
6881 the trans_assignment below will set the vptr. */
6882 if (al_vptr != NULL_TREE && (!code->expr3 || code->expr3->mold))
6884 if (expr3_vptr != NULL_TREE)
6885 /* The vtab is already known, so just assign it. */
6886 gfc_add_modify (&block, al_vptr,
6887 fold_convert (TREE_TYPE (al_vptr), expr3_vptr));
6888 else
6890 /* VPTR is fixed at compile time. */
6891 gfc_symbol *vtab;
6892 gfc_typespec *ts;
6894 if (code->expr3)
6895 /* Although expr3 is pre-evaluated above, it may happen,
6896 that for arrays or in mold= cases the pre-evaluation
6897 was not successful. In these rare cases take the vtab
6898 from the typespec of expr3 here. */
6899 ts = &code->expr3->ts;
6900 else if (code->ext.alloc.ts.type == BT_DERIVED || upoly_expr)
6901 /* The alloc_type_spec gives the type to allocate or the
6902 al is unlimited polymorphic, which enforces the use of
6903 an alloc_type_spec that is not necessarily a BT_DERIVED. */
6904 ts = &code->ext.alloc.ts;
6905 else
6906 /* Prepare for setting the vtab as declared. */
6907 ts = &expr->ts;
6909 vtab = gfc_find_vtab (ts);
6910 gcc_assert (vtab);
6911 tmp = gfc_build_addr_expr (NULL_TREE,
6912 gfc_get_symbol_decl (vtab));
6913 gfc_add_modify (&block, al_vptr,
6914 fold_convert (TREE_TYPE (al_vptr), tmp));
6918 /* Add assignment for string length. */
6919 if (al_len != NULL_TREE && al_len_needs_set)
6921 if (expr3_len != NULL_TREE)
6923 gfc_add_modify (&block, al_len,
6924 fold_convert (TREE_TYPE (al_len),
6925 expr3_len));
6926 /* When tmp_expr3_len_flag is set, then expr3_len is
6927 abused to carry the length information from the
6928 alloc_type. Clear it to prevent setting incorrect len
6929 information in future loop iterations. */
6930 if (tmp_expr3_len_flag)
6931 /* No need to reset tmp_expr3_len_flag, because the
6932 presence of an expr3 cannot change within in the
6933 loop. */
6934 expr3_len = NULL_TREE;
6936 else if (code->ext.alloc.ts.type == BT_CHARACTER
6937 && code->ext.alloc.ts.u.cl->length)
6939 /* Cover the cases where a string length is explicitly
6940 specified by a type spec for deferred length character
6941 arrays or unlimited polymorphic objects without a
6942 source= or mold= expression. */
6943 if (expr3_esize == NULL_TREE || code->ext.alloc.ts.kind != 1)
6945 gfc_init_se (&se_sz, NULL);
6946 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6947 gfc_add_block_to_block (&block, &se_sz.pre);
6948 gfc_add_modify (&block, al_len,
6949 fold_convert (TREE_TYPE (al_len),
6950 se_sz.expr));
6952 else
6953 gfc_add_modify (&block, al_len,
6954 fold_convert (TREE_TYPE (al_len),
6955 expr3_esize));
6957 else
6958 /* No length information needed, because type to allocate
6959 has no length. Set _len to 0. */
6960 gfc_add_modify (&block, al_len,
6961 fold_convert (TREE_TYPE (al_len),
6962 integer_zero_node));
6965 init_expr = NULL;
6966 if (code->expr3 && !code->expr3->mold && e3_is != E3_MOLD)
6968 /* Initialization via SOURCE block (or static default initializer).
6969 Switch off automatic reallocation since we have just done the
6970 ALLOCATE. */
6971 int realloc_lhs = flag_realloc_lhs;
6972 gfc_expr *init_expr = gfc_expr_to_initialize (expr);
6973 gfc_expr *rhs = e3rhs ? e3rhs : gfc_copy_expr (code->expr3);
6974 flag_realloc_lhs = 0;
6975 tmp = gfc_trans_assignment (init_expr, rhs, false, false, true,
6976 false);
6977 flag_realloc_lhs = realloc_lhs;
6978 /* Free the expression allocated for init_expr. */
6979 gfc_free_expr (init_expr);
6980 if (rhs != e3rhs)
6981 gfc_free_expr (rhs);
6982 gfc_add_expr_to_block (&block, tmp);
6984 /* Set KIND and LEN PDT components and allocate those that are
6985 parameterized. */
6986 else if (expr->ts.type == BT_DERIVED
6987 && expr->ts.u.derived->attr.pdt_type)
6989 if (code->expr3 && code->expr3->param_list)
6990 param_list = code->expr3->param_list;
6991 else if (expr->param_list)
6992 param_list = expr->param_list;
6993 else
6994 param_list = expr->symtree->n.sym->param_list;
6995 tmp = gfc_allocate_pdt_comp (expr->ts.u.derived, se.expr,
6996 expr->rank, param_list);
6997 gfc_add_expr_to_block (&block, tmp);
6999 /* Ditto for CLASS expressions. */
7000 else if (expr->ts.type == BT_CLASS
7001 && CLASS_DATA (expr)->ts.u.derived->attr.pdt_type)
7003 if (code->expr3 && code->expr3->param_list)
7004 param_list = code->expr3->param_list;
7005 else if (expr->param_list)
7006 param_list = expr->param_list;
7007 else
7008 param_list = expr->symtree->n.sym->param_list;
7009 tmp = gfc_allocate_pdt_comp (CLASS_DATA (expr)->ts.u.derived,
7010 se.expr, expr->rank, param_list);
7011 gfc_add_expr_to_block (&block, tmp);
7013 else if (code->expr3 && code->expr3->mold
7014 && code->expr3->ts.type == BT_CLASS)
7016 /* Use class_init_assign to initialize expr. */
7017 gfc_code *ini;
7018 ini = gfc_get_code (EXEC_INIT_ASSIGN);
7019 ini->expr1 = gfc_find_and_cut_at_last_class_ref (expr, true);
7020 tmp = gfc_trans_class_init_assign (ini);
7021 gfc_free_statements (ini);
7022 gfc_add_expr_to_block (&block, tmp);
7024 else if ((init_expr = allocate_get_initializer (code, expr)))
7026 /* Use class_init_assign to initialize expr. */
7027 gfc_code *ini;
7028 int realloc_lhs = flag_realloc_lhs;
7029 ini = gfc_get_code (EXEC_INIT_ASSIGN);
7030 ini->expr1 = gfc_expr_to_initialize (expr);
7031 ini->expr2 = init_expr;
7032 flag_realloc_lhs = 0;
7033 tmp= gfc_trans_init_assign (ini);
7034 flag_realloc_lhs = realloc_lhs;
7035 gfc_free_statements (ini);
7036 /* Init_expr is freeed by above free_statements, just need to null
7037 it here. */
7038 init_expr = NULL;
7039 gfc_add_expr_to_block (&block, tmp);
7042 /* Nullify all pointers in derived type coarrays. This registers a
7043 token for them which allows their allocation. */
7044 if (is_coarray)
7046 gfc_symbol *type = NULL;
7047 symbol_attribute caf_attr;
7048 int rank = 0;
7049 if (code->ext.alloc.ts.type == BT_DERIVED
7050 && code->ext.alloc.ts.u.derived->attr.pointer_comp)
7052 type = code->ext.alloc.ts.u.derived;
7053 rank = type->attr.dimension ? type->as->rank : 0;
7054 gfc_clear_attr (&caf_attr);
7056 else if (expr->ts.type == BT_DERIVED
7057 && expr->ts.u.derived->attr.pointer_comp)
7059 type = expr->ts.u.derived;
7060 rank = expr->rank;
7061 caf_attr = gfc_caf_attr (expr, true);
7064 /* Initialize the tokens of pointer components in derived type
7065 coarrays. */
7066 if (type)
7068 tmp = (caf_attr.codimension && !caf_attr.dimension)
7069 ? gfc_conv_descriptor_data_get (se.expr) : se.expr;
7070 tmp = gfc_nullify_alloc_comp (type, tmp, rank,
7071 GFC_STRUCTURE_CAF_MODE_IN_COARRAY);
7072 gfc_add_expr_to_block (&block, tmp);
7076 gfc_free_expr (expr);
7077 } // for-loop
7079 if (e3rhs)
7081 if (newsym)
7083 gfc_free_symbol (newsym->n.sym);
7084 XDELETE (newsym);
7086 gfc_free_expr (e3rhs);
7088 /* STAT. */
7089 if (code->expr1)
7091 tmp = build1_v (LABEL_EXPR, label_errmsg);
7092 gfc_add_expr_to_block (&block, tmp);
7095 /* ERRMSG - only useful if STAT is present. */
7096 if (code->expr1 && code->expr2)
7098 const char *msg = "Attempt to allocate an allocated object";
7099 tree slen, dlen, errmsg_str;
7100 stmtblock_t errmsg_block;
7102 gfc_init_block (&errmsg_block);
7104 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
7105 gfc_add_modify (&errmsg_block, errmsg_str,
7106 gfc_build_addr_expr (pchar_type_node,
7107 gfc_build_localized_cstring_const (msg)));
7109 slen = build_int_cst (gfc_charlen_type_node, strlen (msg));
7110 dlen = gfc_get_expr_charlen (code->expr2);
7111 slen = fold_build2_loc (input_location, MIN_EXPR,
7112 TREE_TYPE (slen), dlen, slen);
7114 gfc_trans_string_copy (&errmsg_block, dlen, errmsg,
7115 code->expr2->ts.kind,
7116 slen, errmsg_str,
7117 gfc_default_character_kind);
7118 dlen = gfc_finish_block (&errmsg_block);
7120 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
7121 stat, build_int_cst (TREE_TYPE (stat), 0));
7123 tmp = build3_v (COND_EXPR, tmp,
7124 dlen, build_empty_stmt (input_location));
7126 gfc_add_expr_to_block (&block, tmp);
7129 /* STAT block. */
7130 if (code->expr1)
7132 if (TREE_USED (label_finish))
7134 tmp = build1_v (LABEL_EXPR, label_finish);
7135 gfc_add_expr_to_block (&block, tmp);
7138 gfc_init_se (&se, NULL);
7139 gfc_conv_expr_lhs (&se, code->expr1);
7140 tmp = convert (TREE_TYPE (se.expr), stat);
7141 gfc_add_modify (&block, se.expr, tmp);
7144 if (needs_caf_sync)
7146 /* Add a sync all after the allocation has been executed. */
7147 tree zero_size = build_zero_cst (size_type_node);
7148 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
7149 3, null_pointer_node, null_pointer_node,
7150 zero_size);
7151 gfc_add_expr_to_block (&post, tmp);
7154 gfc_add_block_to_block (&block, &se.post);
7155 gfc_add_block_to_block (&block, &post);
7156 if (code->expr3 && code->expr3->must_finalize)
7157 gfc_add_block_to_block (&block, &final_block);
7159 return gfc_finish_block (&block);
7163 /* Translate a DEALLOCATE statement. */
7165 tree
7166 gfc_trans_deallocate (gfc_code *code)
7168 gfc_se se;
7169 gfc_alloc *al;
7170 tree apstat, pstat, stat, errmsg, errlen, tmp;
7171 tree label_finish, label_errmsg;
7172 stmtblock_t block;
7174 pstat = apstat = stat = errmsg = errlen = tmp = NULL_TREE;
7175 label_finish = label_errmsg = NULL_TREE;
7177 gfc_start_block (&block);
7179 /* Count the number of failed deallocations. If deallocate() was
7180 called with STAT= , then set STAT to the count. If deallocate
7181 was called with ERRMSG, then set ERRMG to a string. */
7182 if (code->expr1)
7184 tree gfc_int4_type_node = gfc_get_int_type (4);
7186 stat = gfc_create_var (gfc_int4_type_node, "stat");
7187 pstat = gfc_build_addr_expr (NULL_TREE, stat);
7189 /* GOTO destinations. */
7190 label_errmsg = gfc_build_label_decl (NULL_TREE);
7191 label_finish = gfc_build_label_decl (NULL_TREE);
7192 TREE_USED (label_finish) = 0;
7195 /* Set ERRMSG - only needed if STAT is available. */
7196 if (code->expr1 && code->expr2)
7198 gfc_init_se (&se, NULL);
7199 se.want_pointer = 1;
7200 gfc_conv_expr_lhs (&se, code->expr2);
7201 errmsg = se.expr;
7202 errlen = se.string_length;
7205 for (al = code->ext.alloc.list; al != NULL; al = al->next)
7207 gfc_expr *expr = gfc_copy_expr (al->expr);
7208 bool is_coarray = false, is_coarray_array = false;
7209 int caf_mode = 0;
7211 gcc_assert (expr->expr_type == EXPR_VARIABLE);
7213 if (expr->ts.type == BT_CLASS)
7214 gfc_add_data_component (expr);
7216 gfc_init_se (&se, NULL);
7217 gfc_start_block (&se.pre);
7219 se.want_pointer = 1;
7220 se.descriptor_only = 1;
7221 gfc_conv_expr (&se, expr);
7223 /* Deallocate PDT components that are parameterized. */
7224 tmp = NULL;
7225 if (expr->ts.type == BT_DERIVED
7226 && expr->ts.u.derived->attr.pdt_type
7227 && expr->symtree->n.sym->param_list)
7228 tmp = gfc_deallocate_pdt_comp (expr->ts.u.derived, se.expr, expr->rank);
7229 else if (expr->ts.type == BT_CLASS
7230 && CLASS_DATA (expr)->ts.u.derived->attr.pdt_type
7231 && expr->symtree->n.sym->param_list)
7232 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr)->ts.u.derived,
7233 se.expr, expr->rank);
7235 if (tmp)
7236 gfc_add_expr_to_block (&block, tmp);
7238 if (flag_coarray == GFC_FCOARRAY_LIB
7239 || flag_coarray == GFC_FCOARRAY_SINGLE)
7241 bool comp_ref;
7242 symbol_attribute caf_attr = gfc_caf_attr (expr, false, &comp_ref);
7243 if (caf_attr.codimension)
7245 is_coarray = true;
7246 is_coarray_array = caf_attr.dimension || !comp_ref
7247 || caf_attr.coarray_comp;
7249 if (flag_coarray == GFC_FCOARRAY_LIB)
7250 /* When the expression to deallocate is referencing a
7251 component, then only deallocate it, but do not
7252 deregister. */
7253 caf_mode = GFC_STRUCTURE_CAF_MODE_IN_COARRAY
7254 | (comp_ref && !caf_attr.coarray_comp
7255 ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY : 0);
7259 if (expr->rank || is_coarray_array)
7261 gfc_ref *ref;
7263 if (gfc_bt_struct (expr->ts.type)
7264 && expr->ts.u.derived->attr.alloc_comp
7265 && !gfc_is_finalizable (expr->ts.u.derived, NULL))
7267 gfc_ref *last = NULL;
7269 for (ref = expr->ref; ref; ref = ref->next)
7270 if (ref->type == REF_COMPONENT)
7271 last = ref;
7273 /* Do not deallocate the components of a derived type
7274 ultimate pointer component. */
7275 if (!(last && last->u.c.component->attr.pointer)
7276 && !(!last && expr->symtree->n.sym->attr.pointer))
7278 if (is_coarray && expr->rank == 0
7279 && (!last || !last->u.c.component->attr.dimension)
7280 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
7282 /* Add the ref to the data member only, when this is not
7283 a regular array or deallocate_alloc_comp will try to
7284 add another one. */
7285 tmp = gfc_conv_descriptor_data_get (se.expr);
7287 else
7288 tmp = se.expr;
7289 tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp,
7290 expr->rank, caf_mode);
7291 gfc_add_expr_to_block (&se.pre, tmp);
7295 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
7297 gfc_coarray_deregtype caf_dtype;
7299 if (is_coarray)
7300 caf_dtype = gfc_caf_is_dealloc_only (caf_mode)
7301 ? GFC_CAF_COARRAY_DEALLOCATE_ONLY
7302 : GFC_CAF_COARRAY_DEREGISTER;
7303 else
7304 caf_dtype = GFC_CAF_COARRAY_NOCOARRAY;
7305 tmp = gfc_deallocate_with_status (se.expr, pstat, errmsg, errlen,
7306 label_finish, false, expr,
7307 caf_dtype);
7308 gfc_add_expr_to_block (&se.pre, tmp);
7310 else if (TREE_CODE (se.expr) == COMPONENT_REF
7311 && TREE_CODE (TREE_TYPE (se.expr)) == ARRAY_TYPE
7312 && TREE_CODE (TREE_TYPE (TREE_TYPE (se.expr)))
7313 == RECORD_TYPE)
7315 /* class.c(finalize_component) generates these, when a
7316 finalizable entity has a non-allocatable derived type array
7317 component, which has allocatable components. Obtain the
7318 derived type of the array and deallocate the allocatable
7319 components. */
7320 for (ref = expr->ref; ref; ref = ref->next)
7322 if (ref->u.c.component->attr.dimension
7323 && ref->u.c.component->ts.type == BT_DERIVED)
7324 break;
7327 if (ref && ref->u.c.component->ts.u.derived->attr.alloc_comp
7328 && !gfc_is_finalizable (ref->u.c.component->ts.u.derived,
7329 NULL))
7331 tmp = gfc_deallocate_alloc_comp
7332 (ref->u.c.component->ts.u.derived,
7333 se.expr, expr->rank);
7334 gfc_add_expr_to_block (&se.pre, tmp);
7338 if (al->expr->ts.type == BT_CLASS)
7340 gfc_reset_vptr (&se.pre, al->expr);
7341 if (UNLIMITED_POLY (al->expr)
7342 || (al->expr->ts.type == BT_DERIVED
7343 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
7344 /* Clear _len, too. */
7345 gfc_reset_len (&se.pre, al->expr);
7348 else
7350 tmp = gfc_deallocate_scalar_with_status (se.expr, pstat, label_finish,
7351 false, al->expr,
7352 al->expr->ts, is_coarray);
7353 gfc_add_expr_to_block (&se.pre, tmp);
7355 /* Set to zero after deallocation. */
7356 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
7357 se.expr,
7358 build_int_cst (TREE_TYPE (se.expr), 0));
7359 gfc_add_expr_to_block (&se.pre, tmp);
7361 if (al->expr->ts.type == BT_CLASS)
7363 gfc_reset_vptr (&se.pre, al->expr);
7364 if (UNLIMITED_POLY (al->expr)
7365 || (al->expr->ts.type == BT_DERIVED
7366 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
7367 /* Clear _len, too. */
7368 gfc_reset_len (&se.pre, al->expr);
7372 if (code->expr1)
7374 tree cond;
7376 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, stat,
7377 build_int_cst (TREE_TYPE (stat), 0));
7378 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
7379 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
7380 build1_v (GOTO_EXPR, label_errmsg),
7381 build_empty_stmt (input_location));
7382 gfc_add_expr_to_block (&se.pre, tmp);
7385 tmp = gfc_finish_block (&se.pre);
7386 gfc_add_expr_to_block (&block, tmp);
7387 gfc_free_expr (expr);
7390 if (code->expr1)
7392 tmp = build1_v (LABEL_EXPR, label_errmsg);
7393 gfc_add_expr_to_block (&block, tmp);
7396 /* Set ERRMSG - only needed if STAT is available. */
7397 if (code->expr1 && code->expr2)
7399 const char *msg = "Attempt to deallocate an unallocated object";
7400 stmtblock_t errmsg_block;
7401 tree errmsg_str, slen, dlen, cond;
7403 gfc_init_block (&errmsg_block);
7405 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
7406 gfc_add_modify (&errmsg_block, errmsg_str,
7407 gfc_build_addr_expr (pchar_type_node,
7408 gfc_build_localized_cstring_const (msg)));
7409 slen = build_int_cst (gfc_charlen_type_node, strlen (msg));
7410 dlen = gfc_get_expr_charlen (code->expr2);
7412 gfc_trans_string_copy (&errmsg_block, dlen, errmsg, code->expr2->ts.kind,
7413 slen, errmsg_str, gfc_default_character_kind);
7414 tmp = gfc_finish_block (&errmsg_block);
7416 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, stat,
7417 build_int_cst (TREE_TYPE (stat), 0));
7418 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
7419 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC), tmp,
7420 build_empty_stmt (input_location));
7422 gfc_add_expr_to_block (&block, tmp);
7425 if (code->expr1 && TREE_USED (label_finish))
7427 tmp = build1_v (LABEL_EXPR, label_finish);
7428 gfc_add_expr_to_block (&block, tmp);
7431 /* Set STAT. */
7432 if (code->expr1)
7434 gfc_init_se (&se, NULL);
7435 gfc_conv_expr_lhs (&se, code->expr1);
7436 tmp = convert (TREE_TYPE (se.expr), stat);
7437 gfc_add_modify (&block, se.expr, tmp);
7440 return gfc_finish_block (&block);
7443 #include "gt-fortran-trans-stmt.h"