* doc/generic.texi (ANNOTATE_EXPR): Document 3rd operand.
[official-gcc.git] / gcc / fortran / trans-stmt.c
blob96ca21756742514d635bbe45678a917a05d10d47
1 /* Statement translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2002-2017 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 = integer_minus_one_node;
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, 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_int4_type_node = gfc_get_int_type (4);
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 (gfc_int4_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_int4_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, se.string_length);
612 gfc_add_expr_to_block (&se.pre, tmp);
614 gfc_add_block_to_block (&se.pre, &se.post);
616 return gfc_finish_block (&se.pre);
620 /* Translate the STOP statement. We have to translate this statement
621 to a runtime library call. */
623 tree
624 gfc_trans_stop (gfc_code *code, bool error_stop)
626 tree gfc_int4_type_node = gfc_get_int_type (4);
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 (gfc_int4_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 2, build_int_cst (pchar_type_node, 0), tmp);
647 else if (code->expr1->ts.type == BT_INTEGER)
649 gfc_conv_expr (&se, code->expr1);
650 tmp = build_call_expr_loc (input_location,
651 error_stop
652 ? (flag_coarray == GFC_FCOARRAY_LIB
653 ? gfor_fndecl_caf_error_stop
654 : gfor_fndecl_error_stop_numeric)
655 : (flag_coarray == GFC_FCOARRAY_LIB
656 ? gfor_fndecl_caf_stop_numeric
657 : gfor_fndecl_stop_numeric), 1,
658 fold_convert (gfc_int4_type_node, se.expr));
660 else
662 gfc_conv_expr_reference (&se, code->expr1);
663 tmp = build_call_expr_loc (input_location,
664 error_stop
665 ? (flag_coarray == GFC_FCOARRAY_LIB
666 ? gfor_fndecl_caf_error_stop_str
667 : gfor_fndecl_error_stop_string)
668 : (flag_coarray == GFC_FCOARRAY_LIB
669 ? gfor_fndecl_caf_stop_str
670 : gfor_fndecl_stop_string),
671 2, se.expr, se.string_length);
674 gfc_add_expr_to_block (&se.pre, tmp);
676 gfc_add_block_to_block (&se.pre, &se.post);
678 return gfc_finish_block (&se.pre);
681 /* Translate the FAIL IMAGE statement. */
683 tree
684 gfc_trans_fail_image (gfc_code *code ATTRIBUTE_UNUSED)
686 if (flag_coarray == GFC_FCOARRAY_LIB)
687 return build_call_expr_loc (input_location,
688 gfor_fndecl_caf_fail_image, 1,
689 build_int_cst (pchar_type_node, 0));
690 else
692 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
693 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
694 tree tmp = gfc_get_symbol_decl (exsym);
695 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
700 tree
701 gfc_trans_lock_unlock (gfc_code *code, gfc_exec_op op)
703 gfc_se se, argse;
704 tree stat = NULL_TREE, stat2 = NULL_TREE;
705 tree lock_acquired = NULL_TREE, lock_acquired2 = NULL_TREE;
707 /* Short cut: For single images without STAT= or LOCK_ACQUIRED
708 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
709 if (!code->expr2 && !code->expr4 && flag_coarray != GFC_FCOARRAY_LIB)
710 return NULL_TREE;
712 if (code->expr2)
714 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
715 gfc_init_se (&argse, NULL);
716 gfc_conv_expr_val (&argse, code->expr2);
717 stat = argse.expr;
719 else if (flag_coarray == GFC_FCOARRAY_LIB)
720 stat = null_pointer_node;
722 if (code->expr4)
724 gcc_assert (code->expr4->expr_type == EXPR_VARIABLE);
725 gfc_init_se (&argse, NULL);
726 gfc_conv_expr_val (&argse, code->expr4);
727 lock_acquired = argse.expr;
729 else if (flag_coarray == GFC_FCOARRAY_LIB)
730 lock_acquired = null_pointer_node;
732 gfc_start_block (&se.pre);
733 if (flag_coarray == GFC_FCOARRAY_LIB)
735 tree tmp, token, image_index, errmsg, errmsg_len;
736 tree index = size_zero_node;
737 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
739 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
740 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
741 != INTMOD_ISO_FORTRAN_ENV
742 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
743 != ISOFORTRAN_LOCK_TYPE)
745 gfc_error ("Sorry, the lock component of derived type at %L is not "
746 "yet supported", &code->expr1->where);
747 return NULL_TREE;
750 gfc_get_caf_token_offset (&se, &token, NULL, caf_decl, NULL_TREE,
751 code->expr1);
753 if (gfc_is_coindexed (code->expr1))
754 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
755 else
756 image_index = integer_zero_node;
758 /* For arrays, obtain the array index. */
759 if (gfc_expr_attr (code->expr1).dimension)
761 tree desc, tmp, extent, lbound, ubound;
762 gfc_array_ref *ar, ar2;
763 int i;
765 /* TODO: Extend this, once DT components are supported. */
766 ar = &code->expr1->ref->u.ar;
767 ar2 = *ar;
768 memset (ar, '\0', sizeof (*ar));
769 ar->as = ar2.as;
770 ar->type = AR_FULL;
772 gfc_init_se (&argse, NULL);
773 argse.descriptor_only = 1;
774 gfc_conv_expr_descriptor (&argse, code->expr1);
775 gfc_add_block_to_block (&se.pre, &argse.pre);
776 desc = argse.expr;
777 *ar = ar2;
779 extent = integer_one_node;
780 for (i = 0; i < ar->dimen; i++)
782 gfc_init_se (&argse, NULL);
783 gfc_conv_expr_type (&argse, ar->start[i], integer_type_node);
784 gfc_add_block_to_block (&argse.pre, &argse.pre);
785 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
786 tmp = fold_build2_loc (input_location, MINUS_EXPR,
787 integer_type_node, argse.expr,
788 fold_convert(integer_type_node, lbound));
789 tmp = fold_build2_loc (input_location, MULT_EXPR,
790 integer_type_node, extent, tmp);
791 index = fold_build2_loc (input_location, PLUS_EXPR,
792 integer_type_node, index, tmp);
793 if (i < ar->dimen - 1)
795 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
796 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
797 tmp = fold_convert (integer_type_node, tmp);
798 extent = fold_build2_loc (input_location, MULT_EXPR,
799 integer_type_node, extent, tmp);
804 /* errmsg. */
805 if (code->expr3)
807 gfc_init_se (&argse, NULL);
808 argse.want_pointer = 1;
809 gfc_conv_expr (&argse, code->expr3);
810 gfc_add_block_to_block (&se.pre, &argse.pre);
811 errmsg = argse.expr;
812 errmsg_len = fold_convert (integer_type_node, argse.string_length);
814 else
816 errmsg = null_pointer_node;
817 errmsg_len = integer_zero_node;
820 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
822 stat2 = stat;
823 stat = gfc_create_var (integer_type_node, "stat");
826 if (lock_acquired != null_pointer_node
827 && TREE_TYPE (lock_acquired) != integer_type_node)
829 lock_acquired2 = lock_acquired;
830 lock_acquired = gfc_create_var (integer_type_node, "acquired");
833 if (op == EXEC_LOCK)
834 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
835 token, index, image_index,
836 lock_acquired != null_pointer_node
837 ? gfc_build_addr_expr (NULL, lock_acquired)
838 : lock_acquired,
839 stat != null_pointer_node
840 ? gfc_build_addr_expr (NULL, stat) : stat,
841 errmsg, errmsg_len);
842 else
843 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
844 token, index, image_index,
845 stat != null_pointer_node
846 ? gfc_build_addr_expr (NULL, stat) : stat,
847 errmsg, errmsg_len);
848 gfc_add_expr_to_block (&se.pre, tmp);
850 /* It guarantees memory consistency within the same segment */
851 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
852 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
853 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
854 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
855 ASM_VOLATILE_P (tmp) = 1;
857 gfc_add_expr_to_block (&se.pre, tmp);
859 if (stat2 != NULL_TREE)
860 gfc_add_modify (&se.pre, stat2,
861 fold_convert (TREE_TYPE (stat2), stat));
863 if (lock_acquired2 != NULL_TREE)
864 gfc_add_modify (&se.pre, lock_acquired2,
865 fold_convert (TREE_TYPE (lock_acquired2),
866 lock_acquired));
868 return gfc_finish_block (&se.pre);
871 if (stat != NULL_TREE)
872 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
874 if (lock_acquired != NULL_TREE)
875 gfc_add_modify (&se.pre, lock_acquired,
876 fold_convert (TREE_TYPE (lock_acquired),
877 boolean_true_node));
879 return gfc_finish_block (&se.pre);
882 tree
883 gfc_trans_event_post_wait (gfc_code *code, gfc_exec_op op)
885 gfc_se se, argse;
886 tree stat = NULL_TREE, stat2 = NULL_TREE;
887 tree until_count = NULL_TREE;
889 if (code->expr2)
891 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
892 gfc_init_se (&argse, NULL);
893 gfc_conv_expr_val (&argse, code->expr2);
894 stat = argse.expr;
896 else if (flag_coarray == GFC_FCOARRAY_LIB)
897 stat = null_pointer_node;
899 if (code->expr4)
901 gfc_init_se (&argse, NULL);
902 gfc_conv_expr_val (&argse, code->expr4);
903 until_count = fold_convert (integer_type_node, argse.expr);
905 else
906 until_count = integer_one_node;
908 if (flag_coarray != GFC_FCOARRAY_LIB)
910 gfc_start_block (&se.pre);
911 gfc_init_se (&argse, NULL);
912 gfc_conv_expr_val (&argse, code->expr1);
914 if (op == EXEC_EVENT_POST)
915 gfc_add_modify (&se.pre, argse.expr,
916 fold_build2_loc (input_location, PLUS_EXPR,
917 TREE_TYPE (argse.expr), argse.expr,
918 build_int_cst (TREE_TYPE (argse.expr), 1)));
919 else
920 gfc_add_modify (&se.pre, argse.expr,
921 fold_build2_loc (input_location, MINUS_EXPR,
922 TREE_TYPE (argse.expr), argse.expr,
923 fold_convert (TREE_TYPE (argse.expr),
924 until_count)));
925 if (stat != NULL_TREE)
926 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
928 return gfc_finish_block (&se.pre);
931 gfc_start_block (&se.pre);
932 tree tmp, token, image_index, errmsg, errmsg_len;
933 tree index = size_zero_node;
934 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
936 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
937 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
938 != INTMOD_ISO_FORTRAN_ENV
939 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
940 != ISOFORTRAN_EVENT_TYPE)
942 gfc_error ("Sorry, the event component of derived type at %L is not "
943 "yet supported", &code->expr1->where);
944 return NULL_TREE;
947 gfc_init_se (&argse, NULL);
948 gfc_get_caf_token_offset (&argse, &token, NULL, caf_decl, NULL_TREE,
949 code->expr1);
950 gfc_add_block_to_block (&se.pre, &argse.pre);
952 if (gfc_is_coindexed (code->expr1))
953 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
954 else
955 image_index = integer_zero_node;
957 /* For arrays, obtain the array index. */
958 if (gfc_expr_attr (code->expr1).dimension)
960 tree desc, tmp, extent, lbound, ubound;
961 gfc_array_ref *ar, ar2;
962 int i;
964 /* TODO: Extend this, once DT components are supported. */
965 ar = &code->expr1->ref->u.ar;
966 ar2 = *ar;
967 memset (ar, '\0', sizeof (*ar));
968 ar->as = ar2.as;
969 ar->type = AR_FULL;
971 gfc_init_se (&argse, NULL);
972 argse.descriptor_only = 1;
973 gfc_conv_expr_descriptor (&argse, code->expr1);
974 gfc_add_block_to_block (&se.pre, &argse.pre);
975 desc = argse.expr;
976 *ar = ar2;
978 extent = integer_one_node;
979 for (i = 0; i < ar->dimen; i++)
981 gfc_init_se (&argse, NULL);
982 gfc_conv_expr_type (&argse, ar->start[i], integer_type_node);
983 gfc_add_block_to_block (&argse.pre, &argse.pre);
984 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
985 tmp = fold_build2_loc (input_location, MINUS_EXPR,
986 integer_type_node, argse.expr,
987 fold_convert(integer_type_node, lbound));
988 tmp = fold_build2_loc (input_location, MULT_EXPR,
989 integer_type_node, extent, tmp);
990 index = fold_build2_loc (input_location, PLUS_EXPR,
991 integer_type_node, index, tmp);
992 if (i < ar->dimen - 1)
994 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
995 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
996 tmp = fold_convert (integer_type_node, tmp);
997 extent = fold_build2_loc (input_location, MULT_EXPR,
998 integer_type_node, extent, tmp);
1003 /* errmsg. */
1004 if (code->expr3)
1006 gfc_init_se (&argse, NULL);
1007 argse.want_pointer = 1;
1008 gfc_conv_expr (&argse, code->expr3);
1009 gfc_add_block_to_block (&se.pre, &argse.pre);
1010 errmsg = argse.expr;
1011 errmsg_len = fold_convert (integer_type_node, argse.string_length);
1013 else
1015 errmsg = null_pointer_node;
1016 errmsg_len = integer_zero_node;
1019 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
1021 stat2 = stat;
1022 stat = gfc_create_var (integer_type_node, "stat");
1025 if (op == EXEC_EVENT_POST)
1026 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_post, 6,
1027 token, index, image_index,
1028 stat != null_pointer_node
1029 ? gfc_build_addr_expr (NULL, stat) : stat,
1030 errmsg, errmsg_len);
1031 else
1032 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_wait, 6,
1033 token, index, until_count,
1034 stat != null_pointer_node
1035 ? gfc_build_addr_expr (NULL, stat) : stat,
1036 errmsg, errmsg_len);
1037 gfc_add_expr_to_block (&se.pre, tmp);
1039 /* It guarantees memory consistency within the same segment */
1040 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1041 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1042 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1043 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1044 ASM_VOLATILE_P (tmp) = 1;
1045 gfc_add_expr_to_block (&se.pre, tmp);
1047 if (stat2 != NULL_TREE)
1048 gfc_add_modify (&se.pre, stat2, fold_convert (TREE_TYPE (stat2), stat));
1050 return gfc_finish_block (&se.pre);
1053 tree
1054 gfc_trans_sync (gfc_code *code, gfc_exec_op type)
1056 gfc_se se, argse;
1057 tree tmp;
1058 tree images = NULL_TREE, stat = NULL_TREE,
1059 errmsg = NULL_TREE, errmsglen = NULL_TREE;
1061 /* Short cut: For single images without bound checking or without STAT=,
1062 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
1063 if (!code->expr2 && !(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1064 && flag_coarray != GFC_FCOARRAY_LIB)
1065 return NULL_TREE;
1067 gfc_init_se (&se, NULL);
1068 gfc_start_block (&se.pre);
1070 if (code->expr1 && code->expr1->rank == 0)
1072 gfc_init_se (&argse, NULL);
1073 gfc_conv_expr_val (&argse, code->expr1);
1074 images = argse.expr;
1077 if (code->expr2)
1079 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
1080 gfc_init_se (&argse, NULL);
1081 gfc_conv_expr_val (&argse, code->expr2);
1082 stat = argse.expr;
1084 else
1085 stat = null_pointer_node;
1087 if (code->expr3 && flag_coarray == GFC_FCOARRAY_LIB)
1089 gcc_assert (code->expr3->expr_type == EXPR_VARIABLE);
1090 gfc_init_se (&argse, NULL);
1091 argse.want_pointer = 1;
1092 gfc_conv_expr (&argse, code->expr3);
1093 gfc_conv_string_parameter (&argse);
1094 errmsg = gfc_build_addr_expr (NULL, argse.expr);
1095 errmsglen = argse.string_length;
1097 else if (flag_coarray == GFC_FCOARRAY_LIB)
1099 errmsg = null_pointer_node;
1100 errmsglen = build_int_cst (integer_type_node, 0);
1103 /* Check SYNC IMAGES(imageset) for valid image index.
1104 FIXME: Add a check for image-set arrays. */
1105 if (code->expr1 && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1106 && code->expr1->rank == 0)
1108 tree cond;
1109 if (flag_coarray != GFC_FCOARRAY_LIB)
1110 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1111 images, build_int_cst (TREE_TYPE (images), 1));
1112 else
1114 tree cond2;
1115 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images,
1116 2, integer_zero_node,
1117 build_int_cst (integer_type_node, -1));
1118 cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
1119 images, tmp);
1120 cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
1121 images,
1122 build_int_cst (TREE_TYPE (images), 1));
1123 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1124 logical_type_node, cond, cond2);
1126 gfc_trans_runtime_check (true, false, cond, &se.pre,
1127 &code->expr1->where, "Invalid image number "
1128 "%d in SYNC IMAGES",
1129 fold_convert (integer_type_node, images));
1132 /* Per F2008, 8.5.1, a SYNC MEMORY is implied by calling the
1133 image control statements SYNC IMAGES and SYNC ALL. */
1134 if (flag_coarray == GFC_FCOARRAY_LIB)
1136 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1137 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1138 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1139 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1140 ASM_VOLATILE_P (tmp) = 1;
1141 gfc_add_expr_to_block (&se.pre, tmp);
1144 if (flag_coarray != GFC_FCOARRAY_LIB)
1146 /* Set STAT to zero. */
1147 if (code->expr2)
1148 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
1150 else if (type == EXEC_SYNC_ALL || type == EXEC_SYNC_MEMORY)
1152 /* SYNC ALL => stat == null_pointer_node
1153 SYNC ALL(stat=s) => stat has an integer type
1155 If "stat" has the wrong integer type, use a temp variable of
1156 the right type and later cast the result back into "stat". */
1157 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1159 if (TREE_TYPE (stat) == integer_type_node)
1160 stat = gfc_build_addr_expr (NULL, stat);
1162 if(type == EXEC_SYNC_MEMORY)
1163 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_memory,
1164 3, stat, errmsg, errmsglen);
1165 else
1166 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
1167 3, stat, errmsg, errmsglen);
1169 gfc_add_expr_to_block (&se.pre, tmp);
1171 else
1173 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1175 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
1176 3, gfc_build_addr_expr (NULL, tmp_stat),
1177 errmsg, errmsglen);
1178 gfc_add_expr_to_block (&se.pre, tmp);
1180 gfc_add_modify (&se.pre, stat,
1181 fold_convert (TREE_TYPE (stat), tmp_stat));
1184 else
1186 tree len;
1188 gcc_assert (type == EXEC_SYNC_IMAGES);
1190 if (!code->expr1)
1192 len = build_int_cst (integer_type_node, -1);
1193 images = null_pointer_node;
1195 else if (code->expr1->rank == 0)
1197 len = build_int_cst (integer_type_node, 1);
1198 images = gfc_build_addr_expr (NULL_TREE, images);
1200 else
1202 /* FIXME. */
1203 if (code->expr1->ts.kind != gfc_c_int_kind)
1204 gfc_fatal_error ("Sorry, only support for integer kind %d "
1205 "implemented for image-set at %L",
1206 gfc_c_int_kind, &code->expr1->where);
1208 gfc_conv_array_parameter (&se, code->expr1, true, NULL, NULL, &len);
1209 images = se.expr;
1211 tmp = gfc_typenode_for_spec (&code->expr1->ts);
1212 if (GFC_ARRAY_TYPE_P (tmp) || GFC_DESCRIPTOR_TYPE_P (tmp))
1213 tmp = gfc_get_element_type (tmp);
1215 len = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
1216 TREE_TYPE (len), len,
1217 fold_convert (TREE_TYPE (len),
1218 TYPE_SIZE_UNIT (tmp)));
1219 len = fold_convert (integer_type_node, len);
1222 /* SYNC IMAGES(imgs) => stat == null_pointer_node
1223 SYNC IMAGES(imgs,stat=s) => stat has an integer type
1225 If "stat" has the wrong integer type, use a temp variable of
1226 the right type and later cast the result back into "stat". */
1227 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1229 if (TREE_TYPE (stat) == integer_type_node)
1230 stat = gfc_build_addr_expr (NULL, stat);
1232 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1233 5, fold_convert (integer_type_node, len),
1234 images, stat, errmsg, errmsglen);
1235 gfc_add_expr_to_block (&se.pre, tmp);
1237 else
1239 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1241 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1242 5, fold_convert (integer_type_node, len),
1243 images, gfc_build_addr_expr (NULL, tmp_stat),
1244 errmsg, errmsglen);
1245 gfc_add_expr_to_block (&se.pre, tmp);
1247 gfc_add_modify (&se.pre, stat,
1248 fold_convert (TREE_TYPE (stat), tmp_stat));
1252 return gfc_finish_block (&se.pre);
1256 /* Generate GENERIC for the IF construct. This function also deals with
1257 the simple IF statement, because the front end translates the IF
1258 statement into an IF construct.
1260 We translate:
1262 IF (cond) THEN
1263 then_clause
1264 ELSEIF (cond2)
1265 elseif_clause
1266 ELSE
1267 else_clause
1268 ENDIF
1270 into:
1272 pre_cond_s;
1273 if (cond_s)
1275 then_clause;
1277 else
1279 pre_cond_s
1280 if (cond_s)
1282 elseif_clause
1284 else
1286 else_clause;
1290 where COND_S is the simplified version of the predicate. PRE_COND_S
1291 are the pre side-effects produced by the translation of the
1292 conditional.
1293 We need to build the chain recursively otherwise we run into
1294 problems with folding incomplete statements. */
1296 static tree
1297 gfc_trans_if_1 (gfc_code * code)
1299 gfc_se if_se;
1300 tree stmt, elsestmt;
1301 locus saved_loc;
1302 location_t loc;
1304 /* Check for an unconditional ELSE clause. */
1305 if (!code->expr1)
1306 return gfc_trans_code (code->next);
1308 /* Initialize a statement builder for each block. Puts in NULL_TREEs. */
1309 gfc_init_se (&if_se, NULL);
1310 gfc_start_block (&if_se.pre);
1312 /* Calculate the IF condition expression. */
1313 if (code->expr1->where.lb)
1315 gfc_save_backend_locus (&saved_loc);
1316 gfc_set_backend_locus (&code->expr1->where);
1319 gfc_conv_expr_val (&if_se, code->expr1);
1321 if (code->expr1->where.lb)
1322 gfc_restore_backend_locus (&saved_loc);
1324 /* Translate the THEN clause. */
1325 stmt = gfc_trans_code (code->next);
1327 /* Translate the ELSE clause. */
1328 if (code->block)
1329 elsestmt = gfc_trans_if_1 (code->block);
1330 else
1331 elsestmt = build_empty_stmt (input_location);
1333 /* Build the condition expression and add it to the condition block. */
1334 loc = code->expr1->where.lb ? code->expr1->where.lb->location : input_location;
1335 stmt = fold_build3_loc (loc, COND_EXPR, void_type_node, if_se.expr, stmt,
1336 elsestmt);
1338 gfc_add_expr_to_block (&if_se.pre, stmt);
1340 /* Finish off this statement. */
1341 return gfc_finish_block (&if_se.pre);
1344 tree
1345 gfc_trans_if (gfc_code * code)
1347 stmtblock_t body;
1348 tree exit_label;
1350 /* Create exit label so it is available for trans'ing the body code. */
1351 exit_label = gfc_build_label_decl (NULL_TREE);
1352 code->exit_label = exit_label;
1354 /* Translate the actual code in code->block. */
1355 gfc_init_block (&body);
1356 gfc_add_expr_to_block (&body, gfc_trans_if_1 (code->block));
1358 /* Add exit label. */
1359 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
1361 return gfc_finish_block (&body);
1365 /* Translate an arithmetic IF expression.
1367 IF (cond) label1, label2, label3 translates to
1369 if (cond <= 0)
1371 if (cond < 0)
1372 goto label1;
1373 else // cond == 0
1374 goto label2;
1376 else // cond > 0
1377 goto label3;
1379 An optimized version can be generated in case of equal labels.
1380 E.g., if label1 is equal to label2, we can translate it to
1382 if (cond <= 0)
1383 goto label1;
1384 else
1385 goto label3;
1388 tree
1389 gfc_trans_arithmetic_if (gfc_code * code)
1391 gfc_se se;
1392 tree tmp;
1393 tree branch1;
1394 tree branch2;
1395 tree zero;
1397 /* Start a new block. */
1398 gfc_init_se (&se, NULL);
1399 gfc_start_block (&se.pre);
1401 /* Pre-evaluate COND. */
1402 gfc_conv_expr_val (&se, code->expr1);
1403 se.expr = gfc_evaluate_now (se.expr, &se.pre);
1405 /* Build something to compare with. */
1406 zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
1408 if (code->label1->value != code->label2->value)
1410 /* If (cond < 0) take branch1 else take branch2.
1411 First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases. */
1412 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1413 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
1415 if (code->label1->value != code->label3->value)
1416 tmp = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
1417 se.expr, zero);
1418 else
1419 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1420 se.expr, zero);
1422 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1423 tmp, branch1, branch2);
1425 else
1426 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1428 if (code->label1->value != code->label3->value
1429 && code->label2->value != code->label3->value)
1431 /* if (cond <= 0) take branch1 else take branch2. */
1432 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label3));
1433 tmp = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
1434 se.expr, zero);
1435 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1436 tmp, branch1, branch2);
1439 /* Append the COND_EXPR to the evaluation of COND, and return. */
1440 gfc_add_expr_to_block (&se.pre, branch1);
1441 return gfc_finish_block (&se.pre);
1445 /* Translate a CRITICAL block. */
1446 tree
1447 gfc_trans_critical (gfc_code *code)
1449 stmtblock_t block;
1450 tree tmp, token = NULL_TREE;
1452 gfc_start_block (&block);
1454 if (flag_coarray == GFC_FCOARRAY_LIB)
1456 token = gfc_get_symbol_decl (code->resolved_sym);
1457 token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (token));
1458 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
1459 token, integer_zero_node, integer_one_node,
1460 null_pointer_node, null_pointer_node,
1461 null_pointer_node, integer_zero_node);
1462 gfc_add_expr_to_block (&block, tmp);
1464 /* It guarantees memory consistency within the same segment */
1465 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1466 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1467 gfc_build_string_const (1, ""),
1468 NULL_TREE, NULL_TREE,
1469 tree_cons (NULL_TREE, tmp, NULL_TREE),
1470 NULL_TREE);
1471 ASM_VOLATILE_P (tmp) = 1;
1473 gfc_add_expr_to_block (&block, tmp);
1476 tmp = gfc_trans_code (code->block->next);
1477 gfc_add_expr_to_block (&block, tmp);
1479 if (flag_coarray == GFC_FCOARRAY_LIB)
1481 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
1482 token, integer_zero_node, integer_one_node,
1483 null_pointer_node, null_pointer_node,
1484 integer_zero_node);
1485 gfc_add_expr_to_block (&block, tmp);
1487 /* It guarantees memory consistency within the same segment */
1488 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1489 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1490 gfc_build_string_const (1, ""),
1491 NULL_TREE, NULL_TREE,
1492 tree_cons (NULL_TREE, tmp, NULL_TREE),
1493 NULL_TREE);
1494 ASM_VOLATILE_P (tmp) = 1;
1496 gfc_add_expr_to_block (&block, tmp);
1499 return gfc_finish_block (&block);
1503 /* Return true, when the class has a _len component. */
1505 static bool
1506 class_has_len_component (gfc_symbol *sym)
1508 gfc_component *comp = sym->ts.u.derived->components;
1509 while (comp)
1511 if (strcmp (comp->name, "_len") == 0)
1512 return true;
1513 comp = comp->next;
1515 return false;
1519 /* Do proper initialization for ASSOCIATE names. */
1521 static void
1522 trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
1524 gfc_expr *e;
1525 tree tmp;
1526 bool class_target;
1527 bool unlimited;
1528 tree desc;
1529 tree offset;
1530 tree dim;
1531 int n;
1532 tree charlen;
1533 bool need_len_assign;
1534 bool whole_array = true;
1535 gfc_ref *ref;
1536 symbol_attribute attr;
1538 gcc_assert (sym->assoc);
1539 e = sym->assoc->target;
1541 class_target = (e->expr_type == EXPR_VARIABLE)
1542 && (gfc_is_class_scalar_expr (e)
1543 || gfc_is_class_array_ref (e, NULL));
1545 unlimited = UNLIMITED_POLY (e);
1547 for (ref = e->ref; ref; ref = ref->next)
1548 if (ref->type == REF_ARRAY
1549 && ref->u.ar.type == AR_FULL
1550 && ref->next)
1552 whole_array = false;
1553 break;
1556 /* Assignments to the string length need to be generated, when
1557 ( sym is a char array or
1558 sym has a _len component)
1559 and the associated expression is unlimited polymorphic, which is
1560 not (yet) correctly in 'unlimited', because for an already associated
1561 BT_DERIVED the u-poly flag is not set, i.e.,
1562 __tmp_CHARACTER_0_1 => w => arg
1563 ^ generated temp ^ from code, the w does not have the u-poly
1564 flag set, where UNLIMITED_POLY(e) expects it. */
1565 need_len_assign = ((unlimited || (e->ts.type == BT_DERIVED
1566 && e->ts.u.derived->attr.unlimited_polymorphic))
1567 && (sym->ts.type == BT_CHARACTER
1568 || ((sym->ts.type == BT_CLASS || sym->ts.type == BT_DERIVED)
1569 && class_has_len_component (sym))));
1570 /* Do a `pointer assignment' with updated descriptor (or assign descriptor
1571 to array temporary) for arrays with either unknown shape or if associating
1572 to a variable. */
1573 if (sym->attr.dimension && !class_target
1574 && (sym->as->type == AS_DEFERRED || sym->assoc->variable))
1576 gfc_se se;
1577 tree desc;
1578 bool cst_array_ctor;
1580 desc = sym->backend_decl;
1581 cst_array_ctor = e->expr_type == EXPR_ARRAY
1582 && gfc_constant_array_constructor_p (e->value.constructor);
1584 /* If association is to an expression, evaluate it and create temporary.
1585 Otherwise, get descriptor of target for pointer assignment. */
1586 gfc_init_se (&se, NULL);
1587 if (sym->assoc->variable || cst_array_ctor)
1589 se.direct_byref = 1;
1590 se.use_offset = 1;
1591 se.expr = desc;
1594 gfc_conv_expr_descriptor (&se, e);
1596 if (sym->ts.type == BT_CHARACTER
1597 && sym->ts.deferred
1598 && !sym->attr.select_type_temporary
1599 && VAR_P (sym->ts.u.cl->backend_decl)
1600 && se.string_length != sym->ts.u.cl->backend_decl)
1602 gfc_add_modify (&se.pre, sym->ts.u.cl->backend_decl,
1603 fold_convert (gfc_charlen_type_node,
1604 se.string_length));
1607 /* If we didn't already do the pointer assignment, set associate-name
1608 descriptor to the one generated for the temporary. */
1609 if ((!sym->assoc->variable && !cst_array_ctor)
1610 || !whole_array)
1612 int dim;
1614 if (whole_array)
1615 gfc_add_modify (&se.pre, desc, se.expr);
1617 /* The generated descriptor has lower bound zero (as array
1618 temporary), shift bounds so we get lower bounds of 1. */
1619 for (dim = 0; dim < e->rank; ++dim)
1620 gfc_conv_shift_descriptor_lbound (&se.pre, desc,
1621 dim, gfc_index_one_node);
1624 /* If this is a subreference array pointer associate name use the
1625 associate variable element size for the value of 'span'. */
1626 if (sym->attr.subref_array_pointer)
1628 gcc_assert (e->expr_type == EXPR_VARIABLE);
1629 tmp = e->symtree->n.sym->ts.type == BT_CLASS
1630 ? gfc_class_data_get (e->symtree->n.sym->backend_decl)
1631 : e->symtree->n.sym->backend_decl;
1632 tmp = gfc_get_element_type (TREE_TYPE (tmp));
1633 tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
1634 gfc_conv_descriptor_span_set (&se.pre, desc, tmp);
1637 /* Done, register stuff as init / cleanup code. */
1638 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1639 gfc_finish_block (&se.post));
1642 /* Temporaries, arising from TYPE IS, just need the descriptor of class
1643 arrays to be assigned directly. */
1644 else if (class_target && sym->attr.dimension
1645 && (sym->ts.type == BT_DERIVED || unlimited))
1647 gfc_se se;
1649 gfc_init_se (&se, NULL);
1650 se.descriptor_only = 1;
1651 /* In a select type the (temporary) associate variable shall point to
1652 a standard fortran array (lower bound == 1), but conv_expr ()
1653 just maps to the input array in the class object, whose lbound may
1654 be arbitrary. conv_expr_descriptor solves this by inserting a
1655 temporary array descriptor. */
1656 gfc_conv_expr_descriptor (&se, e);
1658 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
1659 || GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)));
1660 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)));
1662 if (GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)))
1664 if (INDIRECT_REF_P (se.expr))
1665 tmp = TREE_OPERAND (se.expr, 0);
1666 else
1667 tmp = se.expr;
1669 gfc_add_modify (&se.pre, sym->backend_decl,
1670 gfc_class_data_get (GFC_DECL_SAVED_DESCRIPTOR (tmp)));
1672 else
1673 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
1675 if (unlimited)
1677 /* Recover the dtype, which has been overwritten by the
1678 assignment from an unlimited polymorphic object. */
1679 tmp = gfc_conv_descriptor_dtype (sym->backend_decl);
1680 gfc_add_modify (&se.pre, tmp,
1681 gfc_get_dtype (TREE_TYPE (sym->backend_decl)));
1684 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1685 gfc_finish_block (&se.post));
1688 /* Do a scalar pointer assignment; this is for scalar variable targets. */
1689 else if (gfc_is_associate_pointer (sym))
1691 gfc_se se;
1693 gcc_assert (!sym->attr.dimension);
1695 gfc_init_se (&se, NULL);
1697 /* Class associate-names come this way because they are
1698 unconditionally associate pointers and the symbol is scalar. */
1699 if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.dimension)
1701 tree target_expr;
1702 /* For a class array we need a descriptor for the selector. */
1703 gfc_conv_expr_descriptor (&se, e);
1704 /* Needed to get/set the _len component below. */
1705 target_expr = se.expr;
1707 /* Obtain a temporary class container for the result. */
1708 gfc_conv_class_to_class (&se, e, sym->ts, false, true, false, false);
1709 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1711 /* Set the offset. */
1712 desc = gfc_class_data_get (se.expr);
1713 offset = gfc_index_zero_node;
1714 for (n = 0; n < e->rank; n++)
1716 dim = gfc_rank_cst[n];
1717 tmp = fold_build2_loc (input_location, MULT_EXPR,
1718 gfc_array_index_type,
1719 gfc_conv_descriptor_stride_get (desc, dim),
1720 gfc_conv_descriptor_lbound_get (desc, dim));
1721 offset = fold_build2_loc (input_location, MINUS_EXPR,
1722 gfc_array_index_type,
1723 offset, tmp);
1725 if (need_len_assign)
1727 if (e->symtree
1728 && DECL_LANG_SPECIFIC (e->symtree->n.sym->backend_decl)
1729 && GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl))
1730 /* Use the original class descriptor stored in the saved
1731 descriptor to get the target_expr. */
1732 target_expr =
1733 GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl);
1734 else
1735 /* Strip the _data component from the target_expr. */
1736 target_expr = TREE_OPERAND (target_expr, 0);
1737 /* Add a reference to the _len comp to the target expr. */
1738 tmp = gfc_class_len_get (target_expr);
1739 /* Get the component-ref for the temp structure's _len comp. */
1740 charlen = gfc_class_len_get (se.expr);
1741 /* Add the assign to the beginning of the block... */
1742 gfc_add_modify (&se.pre, charlen,
1743 fold_convert (TREE_TYPE (charlen), tmp));
1744 /* and the oposite way at the end of the block, to hand changes
1745 on the string length back. */
1746 gfc_add_modify (&se.post, tmp,
1747 fold_convert (TREE_TYPE (tmp), charlen));
1748 /* Length assignment done, prevent adding it again below. */
1749 need_len_assign = false;
1751 gfc_conv_descriptor_offset_set (&se.pre, desc, offset);
1753 else if (sym->ts.type == BT_CLASS && e->ts.type == BT_CLASS
1754 && CLASS_DATA (e)->attr.dimension)
1756 /* This is bound to be a class array element. */
1757 gfc_conv_expr_reference (&se, e);
1758 /* Get the _vptr component of the class object. */
1759 tmp = gfc_get_vptr_from_expr (se.expr);
1760 /* Obtain a temporary class container for the result. */
1761 gfc_conv_derived_to_class (&se, e, sym->ts, tmp, false, false);
1762 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1764 else
1766 /* For BT_CLASS and BT_DERIVED, this boils down to a pointer assign,
1767 which has the string length included. For CHARACTERS it is still
1768 needed and will be done at the end of this routine. */
1769 gfc_conv_expr (&se, e);
1770 need_len_assign = need_len_assign && sym->ts.type == BT_CHARACTER;
1773 if (sym->ts.type == BT_CHARACTER
1774 && sym->ts.deferred
1775 && !sym->attr.select_type_temporary
1776 && VAR_P (sym->ts.u.cl->backend_decl)
1777 && se.string_length != sym->ts.u.cl->backend_decl)
1779 gfc_add_modify (&se.pre, sym->ts.u.cl->backend_decl,
1780 fold_convert (gfc_charlen_type_node,
1781 se.string_length));
1782 if (e->expr_type == EXPR_FUNCTION)
1784 tmp = gfc_call_free (sym->backend_decl);
1785 gfc_add_expr_to_block (&se.post, tmp);
1789 attr = gfc_expr_attr (e);
1790 if (sym->ts.type == BT_CHARACTER && e->ts.type == BT_CHARACTER
1791 && (attr.allocatable || attr.pointer || attr.dummy))
1793 /* These are pointer types already. */
1794 tmp = fold_convert (TREE_TYPE (sym->backend_decl), se.expr);
1796 else
1798 tmp = TREE_TYPE (sym->backend_decl);
1799 tmp = gfc_build_addr_expr (tmp, se.expr);
1802 gfc_add_modify (&se.pre, sym->backend_decl, tmp);
1804 gfc_add_init_cleanup (block, gfc_finish_block( &se.pre),
1805 gfc_finish_block (&se.post));
1808 /* Do a simple assignment. This is for scalar expressions, where we
1809 can simply use expression assignment. */
1810 else
1812 gfc_expr *lhs;
1814 lhs = gfc_lval_expr_from_sym (sym);
1815 tmp = gfc_trans_assignment (lhs, e, false, true);
1816 gfc_add_init_cleanup (block, tmp, NULL_TREE);
1819 /* Set the stringlength, when needed. */
1820 if (need_len_assign)
1822 gfc_se se;
1823 gfc_init_se (&se, NULL);
1824 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
1826 /* Deferred strings are dealt with in the preceeding. */
1827 gcc_assert (!e->symtree->n.sym->ts.deferred);
1828 tmp = e->symtree->n.sym->ts.u.cl->backend_decl;
1830 else if (e->symtree->n.sym->attr.function
1831 && e->symtree->n.sym == e->symtree->n.sym->result)
1833 tmp = gfc_get_fake_result_decl (e->symtree->n.sym, 0);
1834 tmp = gfc_class_len_get (tmp);
1836 else
1837 tmp = gfc_class_len_get (gfc_get_symbol_decl (e->symtree->n.sym));
1838 gfc_get_symbol_decl (sym);
1839 charlen = sym->ts.type == BT_CHARACTER ? sym->ts.u.cl->backend_decl
1840 : gfc_class_len_get (sym->backend_decl);
1841 /* Prevent adding a noop len= len. */
1842 if (tmp != charlen)
1844 gfc_add_modify (&se.pre, charlen,
1845 fold_convert (TREE_TYPE (charlen), tmp));
1846 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1847 gfc_finish_block (&se.post));
1853 /* Translate a BLOCK construct. This is basically what we would do for a
1854 procedure body. */
1856 tree
1857 gfc_trans_block_construct (gfc_code* code)
1859 gfc_namespace* ns;
1860 gfc_symbol* sym;
1861 gfc_wrapped_block block;
1862 tree exit_label;
1863 stmtblock_t body;
1864 gfc_association_list *ass;
1866 ns = code->ext.block.ns;
1867 gcc_assert (ns);
1868 sym = ns->proc_name;
1869 gcc_assert (sym);
1871 /* Process local variables. */
1872 gcc_assert (!sym->tlink);
1873 sym->tlink = sym;
1874 gfc_process_block_locals (ns);
1876 /* Generate code including exit-label. */
1877 gfc_init_block (&body);
1878 exit_label = gfc_build_label_decl (NULL_TREE);
1879 code->exit_label = exit_label;
1881 finish_oacc_declare (ns, sym, true);
1883 gfc_add_expr_to_block (&body, gfc_trans_code (ns->code));
1884 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
1886 /* Finish everything. */
1887 gfc_start_wrapped_block (&block, gfc_finish_block (&body));
1888 gfc_trans_deferred_vars (sym, &block);
1889 for (ass = code->ext.block.assoc; ass; ass = ass->next)
1890 trans_associate_var (ass->st->n.sym, &block);
1892 return gfc_finish_wrapped_block (&block);
1895 /* Translate the simple DO construct in a C-style manner.
1896 This is where the loop variable has integer type and step +-1.
1897 Following code will generate infinite loop in case where TO is INT_MAX
1898 (for +1 step) or INT_MIN (for -1 step)
1900 We translate a do loop from:
1902 DO dovar = from, to, step
1903 body
1904 END DO
1908 [Evaluate loop bounds and step]
1909 dovar = from;
1910 for (;;)
1912 if (dovar > to)
1913 goto end_label;
1914 body;
1915 cycle_label:
1916 dovar += step;
1918 end_label:
1920 This helps the optimizers by avoiding the extra pre-header condition and
1921 we save a register as we just compare the updated IV (not a value in
1922 previous step). */
1924 static tree
1925 gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
1926 tree from, tree to, tree step, tree exit_cond)
1928 stmtblock_t body;
1929 tree type;
1930 tree cond;
1931 tree tmp;
1932 tree saved_dovar = NULL;
1933 tree cycle_label;
1934 tree exit_label;
1935 location_t loc;
1936 type = TREE_TYPE (dovar);
1937 bool is_step_positive = tree_int_cst_sgn (step) > 0;
1939 loc = code->ext.iterator->start->where.lb->location;
1941 /* Initialize the DO variable: dovar = from. */
1942 gfc_add_modify_loc (loc, pblock, dovar,
1943 fold_convert (TREE_TYPE (dovar), from));
1945 /* Save value for do-tinkering checking. */
1946 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1948 saved_dovar = gfc_create_var (type, ".saved_dovar");
1949 gfc_add_modify_loc (loc, pblock, saved_dovar, dovar);
1952 /* Cycle and exit statements are implemented with gotos. */
1953 cycle_label = gfc_build_label_decl (NULL_TREE);
1954 exit_label = gfc_build_label_decl (NULL_TREE);
1956 /* Put the labels where they can be found later. See gfc_trans_do(). */
1957 code->cycle_label = cycle_label;
1958 code->exit_label = exit_label;
1960 /* Loop body. */
1961 gfc_start_block (&body);
1963 /* Exit the loop if there is an I/O result condition or error. */
1964 if (exit_cond)
1966 tmp = build1_v (GOTO_EXPR, exit_label);
1967 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
1968 exit_cond, tmp,
1969 build_empty_stmt (loc));
1970 gfc_add_expr_to_block (&body, tmp);
1973 /* Evaluate the loop condition. */
1974 if (is_step_positive)
1975 cond = fold_build2_loc (loc, GT_EXPR, logical_type_node, dovar,
1976 fold_convert (type, to));
1977 else
1978 cond = fold_build2_loc (loc, LT_EXPR, logical_type_node, dovar,
1979 fold_convert (type, to));
1981 cond = gfc_evaluate_now_loc (loc, cond, &body);
1983 /* The loop exit. */
1984 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
1985 TREE_USED (exit_label) = 1;
1986 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
1987 cond, tmp, build_empty_stmt (loc));
1988 gfc_add_expr_to_block (&body, tmp);
1990 /* Check whether the induction variable is equal to INT_MAX
1991 (respectively to INT_MIN). */
1992 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1994 tree boundary = is_step_positive ? TYPE_MAX_VALUE (type)
1995 : TYPE_MIN_VALUE (type);
1997 tmp = fold_build2_loc (loc, EQ_EXPR, logical_type_node,
1998 dovar, boundary);
1999 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2000 "Loop iterates infinitely");
2003 /* Main loop body. */
2004 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
2005 gfc_add_expr_to_block (&body, tmp);
2007 /* Label for cycle statements (if needed). */
2008 if (TREE_USED (cycle_label))
2010 tmp = build1_v (LABEL_EXPR, cycle_label);
2011 gfc_add_expr_to_block (&body, tmp);
2014 /* Check whether someone has modified the loop variable. */
2015 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2017 tmp = fold_build2_loc (loc, NE_EXPR, logical_type_node,
2018 dovar, saved_dovar);
2019 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2020 "Loop variable has been modified");
2023 /* Increment the loop variable. */
2024 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
2025 gfc_add_modify_loc (loc, &body, dovar, tmp);
2027 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2028 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
2030 /* Finish the loop body. */
2031 tmp = gfc_finish_block (&body);
2032 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
2034 gfc_add_expr_to_block (pblock, tmp);
2036 /* Add the exit label. */
2037 tmp = build1_v (LABEL_EXPR, exit_label);
2038 gfc_add_expr_to_block (pblock, tmp);
2040 return gfc_finish_block (pblock);
2043 /* Translate the DO construct. This obviously is one of the most
2044 important ones to get right with any compiler, but especially
2045 so for Fortran.
2047 We special case some loop forms as described in gfc_trans_simple_do.
2048 For other cases we implement them with a separate loop count,
2049 as described in the standard.
2051 We translate a do loop from:
2053 DO dovar = from, to, step
2054 body
2055 END DO
2059 [evaluate loop bounds and step]
2060 empty = (step > 0 ? to < from : to > from);
2061 countm1 = (to - from) / step;
2062 dovar = from;
2063 if (empty) goto exit_label;
2064 for (;;)
2066 body;
2067 cycle_label:
2068 dovar += step
2069 countm1t = countm1;
2070 countm1--;
2071 if (countm1t == 0) goto exit_label;
2073 exit_label:
2075 countm1 is an unsigned integer. It is equal to the loop count minus one,
2076 because the loop count itself can overflow. */
2078 tree
2079 gfc_trans_do (gfc_code * code, tree exit_cond)
2081 gfc_se se;
2082 tree dovar;
2083 tree saved_dovar = NULL;
2084 tree from;
2085 tree to;
2086 tree step;
2087 tree countm1;
2088 tree type;
2089 tree utype;
2090 tree cond;
2091 tree cycle_label;
2092 tree exit_label;
2093 tree tmp;
2094 stmtblock_t block;
2095 stmtblock_t body;
2096 location_t loc;
2098 gfc_start_block (&block);
2100 loc = code->ext.iterator->start->where.lb->location;
2102 /* Evaluate all the expressions in the iterator. */
2103 gfc_init_se (&se, NULL);
2104 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
2105 gfc_add_block_to_block (&block, &se.pre);
2106 dovar = se.expr;
2107 type = TREE_TYPE (dovar);
2109 gfc_init_se (&se, NULL);
2110 gfc_conv_expr_val (&se, code->ext.iterator->start);
2111 gfc_add_block_to_block (&block, &se.pre);
2112 from = gfc_evaluate_now (se.expr, &block);
2114 gfc_init_se (&se, NULL);
2115 gfc_conv_expr_val (&se, code->ext.iterator->end);
2116 gfc_add_block_to_block (&block, &se.pre);
2117 to = gfc_evaluate_now (se.expr, &block);
2119 gfc_init_se (&se, NULL);
2120 gfc_conv_expr_val (&se, code->ext.iterator->step);
2121 gfc_add_block_to_block (&block, &se.pre);
2122 step = gfc_evaluate_now (se.expr, &block);
2124 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2126 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, step,
2127 build_zero_cst (type));
2128 gfc_trans_runtime_check (true, false, tmp, &block, &code->loc,
2129 "DO step value is zero");
2132 /* Special case simple loops. */
2133 if (TREE_CODE (type) == INTEGER_TYPE
2134 && (integer_onep (step)
2135 || tree_int_cst_equal (step, integer_minus_one_node)))
2136 return gfc_trans_simple_do (code, &block, dovar, from, to, step,
2137 exit_cond);
2139 if (TREE_CODE (type) == INTEGER_TYPE)
2140 utype = unsigned_type_for (type);
2141 else
2142 utype = unsigned_type_for (gfc_array_index_type);
2143 countm1 = gfc_create_var (utype, "countm1");
2145 /* Cycle and exit statements are implemented with gotos. */
2146 cycle_label = gfc_build_label_decl (NULL_TREE);
2147 exit_label = gfc_build_label_decl (NULL_TREE);
2148 TREE_USED (exit_label) = 1;
2150 /* Put these labels where they can be found later. */
2151 code->cycle_label = cycle_label;
2152 code->exit_label = exit_label;
2154 /* Initialize the DO variable: dovar = from. */
2155 gfc_add_modify (&block, dovar, from);
2157 /* Save value for do-tinkering checking. */
2158 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2160 saved_dovar = gfc_create_var (type, ".saved_dovar");
2161 gfc_add_modify_loc (loc, &block, saved_dovar, dovar);
2164 /* Initialize loop count and jump to exit label if the loop is empty.
2165 This code is executed before we enter the loop body. We generate:
2166 if (step > 0)
2168 countm1 = (to - from) / step;
2169 if (to < from)
2170 goto exit_label;
2172 else
2174 countm1 = (from - to) / -step;
2175 if (to > from)
2176 goto exit_label;
2180 if (TREE_CODE (type) == INTEGER_TYPE)
2182 tree pos, neg, tou, fromu, stepu, tmp2;
2184 /* The distance from FROM to TO cannot always be represented in a signed
2185 type, thus use unsigned arithmetic, also to avoid any undefined
2186 overflow issues. */
2187 tou = fold_convert (utype, to);
2188 fromu = fold_convert (utype, from);
2189 stepu = fold_convert (utype, step);
2191 /* For a positive step, when to < from, exit, otherwise compute
2192 countm1 = ((unsigned)to - (unsigned)from) / (unsigned)step */
2193 tmp = fold_build2_loc (loc, LT_EXPR, logical_type_node, to, from);
2194 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2195 fold_build2_loc (loc, MINUS_EXPR, utype,
2196 tou, fromu),
2197 stepu);
2198 pos = build2 (COMPOUND_EXPR, void_type_node,
2199 fold_build2 (MODIFY_EXPR, void_type_node,
2200 countm1, tmp2),
2201 build3_loc (loc, COND_EXPR, void_type_node,
2202 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
2203 build1_loc (loc, GOTO_EXPR, void_type_node,
2204 exit_label), NULL_TREE));
2206 /* For a negative step, when to > from, exit, otherwise compute
2207 countm1 = ((unsigned)from - (unsigned)to) / -(unsigned)step */
2208 tmp = fold_build2_loc (loc, GT_EXPR, logical_type_node, to, from);
2209 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2210 fold_build2_loc (loc, MINUS_EXPR, utype,
2211 fromu, tou),
2212 fold_build1_loc (loc, NEGATE_EXPR, utype, stepu));
2213 neg = build2 (COMPOUND_EXPR, void_type_node,
2214 fold_build2 (MODIFY_EXPR, void_type_node,
2215 countm1, tmp2),
2216 build3_loc (loc, COND_EXPR, void_type_node,
2217 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
2218 build1_loc (loc, GOTO_EXPR, void_type_node,
2219 exit_label), NULL_TREE));
2221 tmp = fold_build2_loc (loc, LT_EXPR, logical_type_node, step,
2222 build_int_cst (TREE_TYPE (step), 0));
2223 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp, neg, pos);
2225 gfc_add_expr_to_block (&block, tmp);
2227 else
2229 tree pos_step;
2231 /* TODO: We could use the same width as the real type.
2232 This would probably cause more problems that it solves
2233 when we implement "long double" types. */
2235 tmp = fold_build2_loc (loc, MINUS_EXPR, type, to, from);
2236 tmp = fold_build2_loc (loc, RDIV_EXPR, type, tmp, step);
2237 tmp = fold_build1_loc (loc, FIX_TRUNC_EXPR, utype, tmp);
2238 gfc_add_modify (&block, countm1, tmp);
2240 /* We need a special check for empty loops:
2241 empty = (step > 0 ? to < from : to > from); */
2242 pos_step = fold_build2_loc (loc, GT_EXPR, logical_type_node, step,
2243 build_zero_cst (type));
2244 tmp = fold_build3_loc (loc, COND_EXPR, logical_type_node, pos_step,
2245 fold_build2_loc (loc, LT_EXPR,
2246 logical_type_node, to, from),
2247 fold_build2_loc (loc, GT_EXPR,
2248 logical_type_node, to, from));
2249 /* If the loop is empty, go directly to the exit label. */
2250 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp,
2251 build1_v (GOTO_EXPR, exit_label),
2252 build_empty_stmt (input_location));
2253 gfc_add_expr_to_block (&block, tmp);
2256 /* Loop body. */
2257 gfc_start_block (&body);
2259 /* Main loop body. */
2260 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
2261 gfc_add_expr_to_block (&body, tmp);
2263 /* Label for cycle statements (if needed). */
2264 if (TREE_USED (cycle_label))
2266 tmp = build1_v (LABEL_EXPR, cycle_label);
2267 gfc_add_expr_to_block (&body, tmp);
2270 /* Check whether someone has modified the loop variable. */
2271 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2273 tmp = fold_build2_loc (loc, NE_EXPR, logical_type_node, dovar,
2274 saved_dovar);
2275 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2276 "Loop variable has been modified");
2279 /* Exit the loop if there is an I/O result condition or error. */
2280 if (exit_cond)
2282 tmp = build1_v (GOTO_EXPR, exit_label);
2283 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2284 exit_cond, tmp,
2285 build_empty_stmt (input_location));
2286 gfc_add_expr_to_block (&body, tmp);
2289 /* Increment the loop variable. */
2290 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
2291 gfc_add_modify_loc (loc, &body, dovar, tmp);
2293 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2294 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
2296 /* Initialize countm1t. */
2297 tree countm1t = gfc_create_var (utype, "countm1t");
2298 gfc_add_modify_loc (loc, &body, countm1t, countm1);
2300 /* Decrement the loop count. */
2301 tmp = fold_build2_loc (loc, MINUS_EXPR, utype, countm1,
2302 build_int_cst (utype, 1));
2303 gfc_add_modify_loc (loc, &body, countm1, tmp);
2305 /* End with the loop condition. Loop until countm1t == 0. */
2306 cond = fold_build2_loc (loc, EQ_EXPR, logical_type_node, countm1t,
2307 build_int_cst (utype, 0));
2308 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
2309 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2310 cond, tmp, build_empty_stmt (loc));
2311 gfc_add_expr_to_block (&body, tmp);
2313 /* End of loop body. */
2314 tmp = gfc_finish_block (&body);
2316 /* The for loop itself. */
2317 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
2318 gfc_add_expr_to_block (&block, tmp);
2320 /* Add the exit label. */
2321 tmp = build1_v (LABEL_EXPR, exit_label);
2322 gfc_add_expr_to_block (&block, tmp);
2324 return gfc_finish_block (&block);
2328 /* Translate the DO WHILE construct.
2330 We translate
2332 DO WHILE (cond)
2333 body
2334 END DO
2338 for ( ; ; )
2340 pre_cond;
2341 if (! cond) goto exit_label;
2342 body;
2343 cycle_label:
2345 exit_label:
2347 Because the evaluation of the exit condition `cond' may have side
2348 effects, we can't do much for empty loop bodies. The backend optimizers
2349 should be smart enough to eliminate any dead loops. */
2351 tree
2352 gfc_trans_do_while (gfc_code * code)
2354 gfc_se cond;
2355 tree tmp;
2356 tree cycle_label;
2357 tree exit_label;
2358 stmtblock_t block;
2360 /* Everything we build here is part of the loop body. */
2361 gfc_start_block (&block);
2363 /* Cycle and exit statements are implemented with gotos. */
2364 cycle_label = gfc_build_label_decl (NULL_TREE);
2365 exit_label = gfc_build_label_decl (NULL_TREE);
2367 /* Put the labels where they can be found later. See gfc_trans_do(). */
2368 code->cycle_label = cycle_label;
2369 code->exit_label = exit_label;
2371 /* Create a GIMPLE version of the exit condition. */
2372 gfc_init_se (&cond, NULL);
2373 gfc_conv_expr_val (&cond, code->expr1);
2374 gfc_add_block_to_block (&block, &cond.pre);
2375 cond.expr = fold_build1_loc (code->expr1->where.lb->location,
2376 TRUTH_NOT_EXPR, TREE_TYPE (cond.expr), cond.expr);
2378 /* Build "IF (! cond) GOTO exit_label". */
2379 tmp = build1_v (GOTO_EXPR, exit_label);
2380 TREE_USED (exit_label) = 1;
2381 tmp = fold_build3_loc (code->expr1->where.lb->location, COND_EXPR,
2382 void_type_node, cond.expr, tmp,
2383 build_empty_stmt (code->expr1->where.lb->location));
2384 gfc_add_expr_to_block (&block, tmp);
2386 /* The main body of the loop. */
2387 tmp = gfc_trans_code (code->block->next);
2388 gfc_add_expr_to_block (&block, tmp);
2390 /* Label for cycle statements (if needed). */
2391 if (TREE_USED (cycle_label))
2393 tmp = build1_v (LABEL_EXPR, cycle_label);
2394 gfc_add_expr_to_block (&block, tmp);
2397 /* End of loop body. */
2398 tmp = gfc_finish_block (&block);
2400 gfc_init_block (&block);
2401 /* Build the loop. */
2402 tmp = fold_build1_loc (code->expr1->where.lb->location, LOOP_EXPR,
2403 void_type_node, tmp);
2404 gfc_add_expr_to_block (&block, tmp);
2406 /* Add the exit label. */
2407 tmp = build1_v (LABEL_EXPR, exit_label);
2408 gfc_add_expr_to_block (&block, tmp);
2410 return gfc_finish_block (&block);
2414 /* Deal with the particular case of SELECT_TYPE, where the vtable
2415 addresses are used for the selection. Since these are not sorted,
2416 the selection has to be made by a series of if statements. */
2418 static tree
2419 gfc_trans_select_type_cases (gfc_code * code)
2421 gfc_code *c;
2422 gfc_case *cp;
2423 tree tmp;
2424 tree cond;
2425 tree low;
2426 tree high;
2427 gfc_se se;
2428 gfc_se cse;
2429 stmtblock_t block;
2430 stmtblock_t body;
2431 bool def = false;
2432 gfc_expr *e;
2433 gfc_start_block (&block);
2435 /* Calculate the switch expression. */
2436 gfc_init_se (&se, NULL);
2437 gfc_conv_expr_val (&se, code->expr1);
2438 gfc_add_block_to_block (&block, &se.pre);
2440 /* Generate an expression for the selector hash value, for
2441 use to resolve character cases. */
2442 e = gfc_copy_expr (code->expr1->value.function.actual->expr);
2443 gfc_add_hash_component (e);
2445 TREE_USED (code->exit_label) = 0;
2447 repeat:
2448 for (c = code->block; c; c = c->block)
2450 cp = c->ext.block.case_list;
2452 /* Assume it's the default case. */
2453 low = NULL_TREE;
2454 high = NULL_TREE;
2455 tmp = NULL_TREE;
2457 /* Put the default case at the end. */
2458 if ((!def && !cp->low) || (def && cp->low))
2459 continue;
2461 if (cp->low && (cp->ts.type == BT_CLASS
2462 || cp->ts.type == BT_DERIVED))
2464 gfc_init_se (&cse, NULL);
2465 gfc_conv_expr_val (&cse, cp->low);
2466 gfc_add_block_to_block (&block, &cse.pre);
2467 low = cse.expr;
2469 else if (cp->ts.type != BT_UNKNOWN)
2471 gcc_assert (cp->high);
2472 gfc_init_se (&cse, NULL);
2473 gfc_conv_expr_val (&cse, cp->high);
2474 gfc_add_block_to_block (&block, &cse.pre);
2475 high = cse.expr;
2478 gfc_init_block (&body);
2480 /* Add the statements for this case. */
2481 tmp = gfc_trans_code (c->next);
2482 gfc_add_expr_to_block (&body, tmp);
2484 /* Break to the end of the SELECT TYPE construct. The default
2485 case just falls through. */
2486 if (!def)
2488 TREE_USED (code->exit_label) = 1;
2489 tmp = build1_v (GOTO_EXPR, code->exit_label);
2490 gfc_add_expr_to_block (&body, tmp);
2493 tmp = gfc_finish_block (&body);
2495 if (low != NULL_TREE)
2497 /* Compare vtable pointers. */
2498 cond = fold_build2_loc (input_location, EQ_EXPR,
2499 TREE_TYPE (se.expr), se.expr, low);
2500 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2501 cond, tmp,
2502 build_empty_stmt (input_location));
2504 else if (high != NULL_TREE)
2506 /* Compare hash values for character cases. */
2507 gfc_init_se (&cse, NULL);
2508 gfc_conv_expr_val (&cse, e);
2509 gfc_add_block_to_block (&block, &cse.pre);
2511 cond = fold_build2_loc (input_location, EQ_EXPR,
2512 TREE_TYPE (se.expr), high, cse.expr);
2513 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2514 cond, tmp,
2515 build_empty_stmt (input_location));
2518 gfc_add_expr_to_block (&block, tmp);
2521 if (!def)
2523 def = true;
2524 goto repeat;
2527 gfc_free_expr (e);
2529 return gfc_finish_block (&block);
2533 /* Translate the SELECT CASE construct for INTEGER case expressions,
2534 without killing all potential optimizations. The problem is that
2535 Fortran allows unbounded cases, but the back-end does not, so we
2536 need to intercept those before we enter the equivalent SWITCH_EXPR
2537 we can build.
2539 For example, we translate this,
2541 SELECT CASE (expr)
2542 CASE (:100,101,105:115)
2543 block_1
2544 CASE (190:199,200:)
2545 block_2
2546 CASE (300)
2547 block_3
2548 CASE DEFAULT
2549 block_4
2550 END SELECT
2552 to the GENERIC equivalent,
2554 switch (expr)
2556 case (minimum value for typeof(expr) ... 100:
2557 case 101:
2558 case 105 ... 114:
2559 block1:
2560 goto end_label;
2562 case 200 ... (maximum value for typeof(expr):
2563 case 190 ... 199:
2564 block2;
2565 goto end_label;
2567 case 300:
2568 block_3;
2569 goto end_label;
2571 default:
2572 block_4;
2573 goto end_label;
2576 end_label: */
2578 static tree
2579 gfc_trans_integer_select (gfc_code * code)
2581 gfc_code *c;
2582 gfc_case *cp;
2583 tree end_label;
2584 tree tmp;
2585 gfc_se se;
2586 stmtblock_t block;
2587 stmtblock_t body;
2589 gfc_start_block (&block);
2591 /* Calculate the switch expression. */
2592 gfc_init_se (&se, NULL);
2593 gfc_conv_expr_val (&se, code->expr1);
2594 gfc_add_block_to_block (&block, &se.pre);
2596 end_label = gfc_build_label_decl (NULL_TREE);
2598 gfc_init_block (&body);
2600 for (c = code->block; c; c = c->block)
2602 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2604 tree low, high;
2605 tree label;
2607 /* Assume it's the default case. */
2608 low = high = NULL_TREE;
2610 if (cp->low)
2612 low = gfc_conv_mpz_to_tree (cp->low->value.integer,
2613 cp->low->ts.kind);
2615 /* If there's only a lower bound, set the high bound to the
2616 maximum value of the case expression. */
2617 if (!cp->high)
2618 high = TYPE_MAX_VALUE (TREE_TYPE (se.expr));
2621 if (cp->high)
2623 /* Three cases are possible here:
2625 1) There is no lower bound, e.g. CASE (:N).
2626 2) There is a lower bound .NE. high bound, that is
2627 a case range, e.g. CASE (N:M) where M>N (we make
2628 sure that M>N during type resolution).
2629 3) There is a lower bound, and it has the same value
2630 as the high bound, e.g. CASE (N:N). This is our
2631 internal representation of CASE(N).
2633 In the first and second case, we need to set a value for
2634 high. In the third case, we don't because the GCC middle
2635 end represents a single case value by just letting high be
2636 a NULL_TREE. We can't do that because we need to be able
2637 to represent unbounded cases. */
2639 if (!cp->low
2640 || (mpz_cmp (cp->low->value.integer,
2641 cp->high->value.integer) != 0))
2642 high = gfc_conv_mpz_to_tree (cp->high->value.integer,
2643 cp->high->ts.kind);
2645 /* Unbounded case. */
2646 if (!cp->low)
2647 low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
2650 /* Build a label. */
2651 label = gfc_build_label_decl (NULL_TREE);
2653 /* Add this case label.
2654 Add parameter 'label', make it match GCC backend. */
2655 tmp = build_case_label (low, high, label);
2656 gfc_add_expr_to_block (&body, tmp);
2659 /* Add the statements for this case. */
2660 tmp = gfc_trans_code (c->next);
2661 gfc_add_expr_to_block (&body, tmp);
2663 /* Break to the end of the construct. */
2664 tmp = build1_v (GOTO_EXPR, end_label);
2665 gfc_add_expr_to_block (&body, tmp);
2668 tmp = gfc_finish_block (&body);
2669 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2670 se.expr, tmp, NULL_TREE);
2671 gfc_add_expr_to_block (&block, tmp);
2673 tmp = build1_v (LABEL_EXPR, end_label);
2674 gfc_add_expr_to_block (&block, tmp);
2676 return gfc_finish_block (&block);
2680 /* Translate the SELECT CASE construct for LOGICAL case expressions.
2682 There are only two cases possible here, even though the standard
2683 does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
2684 .FALSE., and DEFAULT.
2686 We never generate more than two blocks here. Instead, we always
2687 try to eliminate the DEFAULT case. This way, we can translate this
2688 kind of SELECT construct to a simple
2690 if {} else {};
2692 expression in GENERIC. */
2694 static tree
2695 gfc_trans_logical_select (gfc_code * code)
2697 gfc_code *c;
2698 gfc_code *t, *f, *d;
2699 gfc_case *cp;
2700 gfc_se se;
2701 stmtblock_t block;
2703 /* Assume we don't have any cases at all. */
2704 t = f = d = NULL;
2706 /* Now see which ones we actually do have. We can have at most two
2707 cases in a single case list: one for .TRUE. and one for .FALSE.
2708 The default case is always separate. If the cases for .TRUE. and
2709 .FALSE. are in the same case list, the block for that case list
2710 always executed, and we don't generate code a COND_EXPR. */
2711 for (c = code->block; c; c = c->block)
2713 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2715 if (cp->low)
2717 if (cp->low->value.logical == 0) /* .FALSE. */
2718 f = c;
2719 else /* if (cp->value.logical != 0), thus .TRUE. */
2720 t = c;
2722 else
2723 d = c;
2727 /* Start a new block. */
2728 gfc_start_block (&block);
2730 /* Calculate the switch expression. We always need to do this
2731 because it may have side effects. */
2732 gfc_init_se (&se, NULL);
2733 gfc_conv_expr_val (&se, code->expr1);
2734 gfc_add_block_to_block (&block, &se.pre);
2736 if (t == f && t != NULL)
2738 /* Cases for .TRUE. and .FALSE. are in the same block. Just
2739 translate the code for these cases, append it to the current
2740 block. */
2741 gfc_add_expr_to_block (&block, gfc_trans_code (t->next));
2743 else
2745 tree true_tree, false_tree, stmt;
2747 true_tree = build_empty_stmt (input_location);
2748 false_tree = build_empty_stmt (input_location);
2750 /* If we have a case for .TRUE. and for .FALSE., discard the default case.
2751 Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
2752 make the missing case the default case. */
2753 if (t != NULL && f != NULL)
2754 d = NULL;
2755 else if (d != NULL)
2757 if (t == NULL)
2758 t = d;
2759 else
2760 f = d;
2763 /* Translate the code for each of these blocks, and append it to
2764 the current block. */
2765 if (t != NULL)
2766 true_tree = gfc_trans_code (t->next);
2768 if (f != NULL)
2769 false_tree = gfc_trans_code (f->next);
2771 stmt = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2772 se.expr, true_tree, false_tree);
2773 gfc_add_expr_to_block (&block, stmt);
2776 return gfc_finish_block (&block);
2780 /* The jump table types are stored in static variables to avoid
2781 constructing them from scratch every single time. */
2782 static GTY(()) tree select_struct[2];
2784 /* Translate the SELECT CASE construct for CHARACTER case expressions.
2785 Instead of generating compares and jumps, it is far simpler to
2786 generate a data structure describing the cases in order and call a
2787 library subroutine that locates the right case.
2788 This is particularly true because this is the only case where we
2789 might have to dispose of a temporary.
2790 The library subroutine returns a pointer to jump to or NULL if no
2791 branches are to be taken. */
2793 static tree
2794 gfc_trans_character_select (gfc_code *code)
2796 tree init, end_label, tmp, type, case_num, label, fndecl;
2797 stmtblock_t block, body;
2798 gfc_case *cp, *d;
2799 gfc_code *c;
2800 gfc_se se, expr1se;
2801 int n, k;
2802 vec<constructor_elt, va_gc> *inits = NULL;
2804 tree pchartype = gfc_get_pchar_type (code->expr1->ts.kind);
2806 /* The jump table types are stored in static variables to avoid
2807 constructing them from scratch every single time. */
2808 static tree ss_string1[2], ss_string1_len[2];
2809 static tree ss_string2[2], ss_string2_len[2];
2810 static tree ss_target[2];
2812 cp = code->block->ext.block.case_list;
2813 while (cp->left != NULL)
2814 cp = cp->left;
2816 /* Generate the body */
2817 gfc_start_block (&block);
2818 gfc_init_se (&expr1se, NULL);
2819 gfc_conv_expr_reference (&expr1se, code->expr1);
2821 gfc_add_block_to_block (&block, &expr1se.pre);
2823 end_label = gfc_build_label_decl (NULL_TREE);
2825 gfc_init_block (&body);
2827 /* Attempt to optimize length 1 selects. */
2828 if (integer_onep (expr1se.string_length))
2830 for (d = cp; d; d = d->right)
2832 int i;
2833 if (d->low)
2835 gcc_assert (d->low->expr_type == EXPR_CONSTANT
2836 && d->low->ts.type == BT_CHARACTER);
2837 if (d->low->value.character.length > 1)
2839 for (i = 1; i < d->low->value.character.length; i++)
2840 if (d->low->value.character.string[i] != ' ')
2841 break;
2842 if (i != d->low->value.character.length)
2844 if (optimize && d->high && i == 1)
2846 gcc_assert (d->high->expr_type == EXPR_CONSTANT
2847 && d->high->ts.type == BT_CHARACTER);
2848 if (d->high->value.character.length > 1
2849 && (d->low->value.character.string[0]
2850 == d->high->value.character.string[0])
2851 && d->high->value.character.string[1] != ' '
2852 && ((d->low->value.character.string[1] < ' ')
2853 == (d->high->value.character.string[1]
2854 < ' ')))
2855 continue;
2857 break;
2861 if (d->high)
2863 gcc_assert (d->high->expr_type == EXPR_CONSTANT
2864 && d->high->ts.type == BT_CHARACTER);
2865 if (d->high->value.character.length > 1)
2867 for (i = 1; i < d->high->value.character.length; i++)
2868 if (d->high->value.character.string[i] != ' ')
2869 break;
2870 if (i != d->high->value.character.length)
2871 break;
2875 if (d == NULL)
2877 tree ctype = gfc_get_char_type (code->expr1->ts.kind);
2879 for (c = code->block; c; c = c->block)
2881 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2883 tree low, high;
2884 tree label;
2885 gfc_char_t r;
2887 /* Assume it's the default case. */
2888 low = high = NULL_TREE;
2890 if (cp->low)
2892 /* CASE ('ab') or CASE ('ab':'az') will never match
2893 any length 1 character. */
2894 if (cp->low->value.character.length > 1
2895 && cp->low->value.character.string[1] != ' ')
2896 continue;
2898 if (cp->low->value.character.length > 0)
2899 r = cp->low->value.character.string[0];
2900 else
2901 r = ' ';
2902 low = build_int_cst (ctype, r);
2904 /* If there's only a lower bound, set the high bound
2905 to the maximum value of the case expression. */
2906 if (!cp->high)
2907 high = TYPE_MAX_VALUE (ctype);
2910 if (cp->high)
2912 if (!cp->low
2913 || (cp->low->value.character.string[0]
2914 != cp->high->value.character.string[0]))
2916 if (cp->high->value.character.length > 0)
2917 r = cp->high->value.character.string[0];
2918 else
2919 r = ' ';
2920 high = build_int_cst (ctype, r);
2923 /* Unbounded case. */
2924 if (!cp->low)
2925 low = TYPE_MIN_VALUE (ctype);
2928 /* Build a label. */
2929 label = gfc_build_label_decl (NULL_TREE);
2931 /* Add this case label.
2932 Add parameter 'label', make it match GCC backend. */
2933 tmp = build_case_label (low, high, label);
2934 gfc_add_expr_to_block (&body, tmp);
2937 /* Add the statements for this case. */
2938 tmp = gfc_trans_code (c->next);
2939 gfc_add_expr_to_block (&body, tmp);
2941 /* Break to the end of the construct. */
2942 tmp = build1_v (GOTO_EXPR, end_label);
2943 gfc_add_expr_to_block (&body, tmp);
2946 tmp = gfc_string_to_single_character (expr1se.string_length,
2947 expr1se.expr,
2948 code->expr1->ts.kind);
2949 case_num = gfc_create_var (ctype, "case_num");
2950 gfc_add_modify (&block, case_num, tmp);
2952 gfc_add_block_to_block (&block, &expr1se.post);
2954 tmp = gfc_finish_block (&body);
2955 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2956 case_num, tmp, NULL_TREE);
2957 gfc_add_expr_to_block (&block, tmp);
2959 tmp = build1_v (LABEL_EXPR, end_label);
2960 gfc_add_expr_to_block (&block, tmp);
2962 return gfc_finish_block (&block);
2966 if (code->expr1->ts.kind == 1)
2967 k = 0;
2968 else if (code->expr1->ts.kind == 4)
2969 k = 1;
2970 else
2971 gcc_unreachable ();
2973 if (select_struct[k] == NULL)
2975 tree *chain = NULL;
2976 select_struct[k] = make_node (RECORD_TYPE);
2978 if (code->expr1->ts.kind == 1)
2979 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char1");
2980 else if (code->expr1->ts.kind == 4)
2981 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char4");
2982 else
2983 gcc_unreachable ();
2985 #undef ADD_FIELD
2986 #define ADD_FIELD(NAME, TYPE) \
2987 ss_##NAME[k] = gfc_add_field_to_struct (select_struct[k], \
2988 get_identifier (stringize(NAME)), \
2989 TYPE, \
2990 &chain)
2992 ADD_FIELD (string1, pchartype);
2993 ADD_FIELD (string1_len, gfc_charlen_type_node);
2995 ADD_FIELD (string2, pchartype);
2996 ADD_FIELD (string2_len, gfc_charlen_type_node);
2998 ADD_FIELD (target, integer_type_node);
2999 #undef ADD_FIELD
3001 gfc_finish_type (select_struct[k]);
3004 n = 0;
3005 for (d = cp; d; d = d->right)
3006 d->n = n++;
3008 for (c = code->block; c; c = c->block)
3010 for (d = c->ext.block.case_list; d; d = d->next)
3012 label = gfc_build_label_decl (NULL_TREE);
3013 tmp = build_case_label ((d->low == NULL && d->high == NULL)
3014 ? NULL
3015 : build_int_cst (integer_type_node, d->n),
3016 NULL, label);
3017 gfc_add_expr_to_block (&body, tmp);
3020 tmp = gfc_trans_code (c->next);
3021 gfc_add_expr_to_block (&body, tmp);
3023 tmp = build1_v (GOTO_EXPR, end_label);
3024 gfc_add_expr_to_block (&body, tmp);
3027 /* Generate the structure describing the branches */
3028 for (d = cp; d; d = d->right)
3030 vec<constructor_elt, va_gc> *node = NULL;
3032 gfc_init_se (&se, NULL);
3034 if (d->low == NULL)
3036 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], null_pointer_node);
3037 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], integer_zero_node);
3039 else
3041 gfc_conv_expr_reference (&se, d->low);
3043 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], se.expr);
3044 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], se.string_length);
3047 if (d->high == NULL)
3049 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], null_pointer_node);
3050 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], integer_zero_node);
3052 else
3054 gfc_init_se (&se, NULL);
3055 gfc_conv_expr_reference (&se, d->high);
3057 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], se.expr);
3058 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], se.string_length);
3061 CONSTRUCTOR_APPEND_ELT (node, ss_target[k],
3062 build_int_cst (integer_type_node, d->n));
3064 tmp = build_constructor (select_struct[k], node);
3065 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, tmp);
3068 type = build_array_type (select_struct[k],
3069 build_index_type (size_int (n-1)));
3071 init = build_constructor (type, inits);
3072 TREE_CONSTANT (init) = 1;
3073 TREE_STATIC (init) = 1;
3074 /* Create a static variable to hold the jump table. */
3075 tmp = gfc_create_var (type, "jumptable");
3076 TREE_CONSTANT (tmp) = 1;
3077 TREE_STATIC (tmp) = 1;
3078 TREE_READONLY (tmp) = 1;
3079 DECL_INITIAL (tmp) = init;
3080 init = tmp;
3082 /* Build the library call */
3083 init = gfc_build_addr_expr (pvoid_type_node, init);
3085 if (code->expr1->ts.kind == 1)
3086 fndecl = gfor_fndecl_select_string;
3087 else if (code->expr1->ts.kind == 4)
3088 fndecl = gfor_fndecl_select_string_char4;
3089 else
3090 gcc_unreachable ();
3092 tmp = build_call_expr_loc (input_location,
3093 fndecl, 4, init,
3094 build_int_cst (gfc_charlen_type_node, n),
3095 expr1se.expr, expr1se.string_length);
3096 case_num = gfc_create_var (integer_type_node, "case_num");
3097 gfc_add_modify (&block, case_num, tmp);
3099 gfc_add_block_to_block (&block, &expr1se.post);
3101 tmp = gfc_finish_block (&body);
3102 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
3103 case_num, tmp, NULL_TREE);
3104 gfc_add_expr_to_block (&block, tmp);
3106 tmp = build1_v (LABEL_EXPR, end_label);
3107 gfc_add_expr_to_block (&block, tmp);
3109 return gfc_finish_block (&block);
3113 /* Translate the three variants of the SELECT CASE construct.
3115 SELECT CASEs with INTEGER case expressions can be translated to an
3116 equivalent GENERIC switch statement, and for LOGICAL case
3117 expressions we build one or two if-else compares.
3119 SELECT CASEs with CHARACTER case expressions are a whole different
3120 story, because they don't exist in GENERIC. So we sort them and
3121 do a binary search at runtime.
3123 Fortran has no BREAK statement, and it does not allow jumps from
3124 one case block to another. That makes things a lot easier for
3125 the optimizers. */
3127 tree
3128 gfc_trans_select (gfc_code * code)
3130 stmtblock_t block;
3131 tree body;
3132 tree exit_label;
3134 gcc_assert (code && code->expr1);
3135 gfc_init_block (&block);
3137 /* Build the exit label and hang it in. */
3138 exit_label = gfc_build_label_decl (NULL_TREE);
3139 code->exit_label = exit_label;
3141 /* Empty SELECT constructs are legal. */
3142 if (code->block == NULL)
3143 body = build_empty_stmt (input_location);
3145 /* Select the correct translation function. */
3146 else
3147 switch (code->expr1->ts.type)
3149 case BT_LOGICAL:
3150 body = gfc_trans_logical_select (code);
3151 break;
3153 case BT_INTEGER:
3154 body = gfc_trans_integer_select (code);
3155 break;
3157 case BT_CHARACTER:
3158 body = gfc_trans_character_select (code);
3159 break;
3161 default:
3162 gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
3163 /* Not reached */
3166 /* Build everything together. */
3167 gfc_add_expr_to_block (&block, body);
3168 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3170 return gfc_finish_block (&block);
3173 tree
3174 gfc_trans_select_type (gfc_code * code)
3176 stmtblock_t block;
3177 tree body;
3178 tree exit_label;
3180 gcc_assert (code && code->expr1);
3181 gfc_init_block (&block);
3183 /* Build the exit label and hang it in. */
3184 exit_label = gfc_build_label_decl (NULL_TREE);
3185 code->exit_label = exit_label;
3187 /* Empty SELECT constructs are legal. */
3188 if (code->block == NULL)
3189 body = build_empty_stmt (input_location);
3190 else
3191 body = gfc_trans_select_type_cases (code);
3193 /* Build everything together. */
3194 gfc_add_expr_to_block (&block, body);
3196 if (TREE_USED (exit_label))
3197 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3199 return gfc_finish_block (&block);
3203 /* Traversal function to substitute a replacement symtree if the symbol
3204 in the expression is the same as that passed. f == 2 signals that
3205 that variable itself is not to be checked - only the references.
3206 This group of functions is used when the variable expression in a
3207 FORALL assignment has internal references. For example:
3208 FORALL (i = 1:4) p(p(i)) = i
3209 The only recourse here is to store a copy of 'p' for the index
3210 expression. */
3212 static gfc_symtree *new_symtree;
3213 static gfc_symtree *old_symtree;
3215 static bool
3216 forall_replace (gfc_expr *expr, gfc_symbol *sym, int *f)
3218 if (expr->expr_type != EXPR_VARIABLE)
3219 return false;
3221 if (*f == 2)
3222 *f = 1;
3223 else if (expr->symtree->n.sym == sym)
3224 expr->symtree = new_symtree;
3226 return false;
3229 static void
3230 forall_replace_symtree (gfc_expr *e, gfc_symbol *sym, int f)
3232 gfc_traverse_expr (e, sym, forall_replace, f);
3235 static bool
3236 forall_restore (gfc_expr *expr,
3237 gfc_symbol *sym ATTRIBUTE_UNUSED,
3238 int *f ATTRIBUTE_UNUSED)
3240 if (expr->expr_type != EXPR_VARIABLE)
3241 return false;
3243 if (expr->symtree == new_symtree)
3244 expr->symtree = old_symtree;
3246 return false;
3249 static void
3250 forall_restore_symtree (gfc_expr *e)
3252 gfc_traverse_expr (e, NULL, forall_restore, 0);
3255 static void
3256 forall_make_variable_temp (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
3258 gfc_se tse;
3259 gfc_se rse;
3260 gfc_expr *e;
3261 gfc_symbol *new_sym;
3262 gfc_symbol *old_sym;
3263 gfc_symtree *root;
3264 tree tmp;
3266 /* Build a copy of the lvalue. */
3267 old_symtree = c->expr1->symtree;
3268 old_sym = old_symtree->n.sym;
3269 e = gfc_lval_expr_from_sym (old_sym);
3270 if (old_sym->attr.dimension)
3272 gfc_init_se (&tse, NULL);
3273 gfc_conv_subref_array_arg (&tse, e, 0, INTENT_IN, false);
3274 gfc_add_block_to_block (pre, &tse.pre);
3275 gfc_add_block_to_block (post, &tse.post);
3276 tse.expr = build_fold_indirect_ref_loc (input_location, tse.expr);
3278 if (c->expr1->ref->u.ar.type != AR_SECTION)
3280 /* Use the variable offset for the temporary. */
3281 tmp = gfc_conv_array_offset (old_sym->backend_decl);
3282 gfc_conv_descriptor_offset_set (pre, tse.expr, tmp);
3285 else
3287 gfc_init_se (&tse, NULL);
3288 gfc_init_se (&rse, NULL);
3289 gfc_conv_expr (&rse, e);
3290 if (e->ts.type == BT_CHARACTER)
3292 tse.string_length = rse.string_length;
3293 tmp = gfc_get_character_type_len (gfc_default_character_kind,
3294 tse.string_length);
3295 tse.expr = gfc_conv_string_tmp (&tse, build_pointer_type (tmp),
3296 rse.string_length);
3297 gfc_add_block_to_block (pre, &tse.pre);
3298 gfc_add_block_to_block (post, &tse.post);
3300 else
3302 tmp = gfc_typenode_for_spec (&e->ts);
3303 tse.expr = gfc_create_var (tmp, "temp");
3306 tmp = gfc_trans_scalar_assign (&tse, &rse, e->ts,
3307 e->expr_type == EXPR_VARIABLE, false);
3308 gfc_add_expr_to_block (pre, tmp);
3310 gfc_free_expr (e);
3312 /* Create a new symbol to represent the lvalue. */
3313 new_sym = gfc_new_symbol (old_sym->name, NULL);
3314 new_sym->ts = old_sym->ts;
3315 new_sym->attr.referenced = 1;
3316 new_sym->attr.temporary = 1;
3317 new_sym->attr.dimension = old_sym->attr.dimension;
3318 new_sym->attr.flavor = old_sym->attr.flavor;
3320 /* Use the temporary as the backend_decl. */
3321 new_sym->backend_decl = tse.expr;
3323 /* Create a fake symtree for it. */
3324 root = NULL;
3325 new_symtree = gfc_new_symtree (&root, old_sym->name);
3326 new_symtree->n.sym = new_sym;
3327 gcc_assert (new_symtree == root);
3329 /* Go through the expression reference replacing the old_symtree
3330 with the new. */
3331 forall_replace_symtree (c->expr1, old_sym, 2);
3333 /* Now we have made this temporary, we might as well use it for
3334 the right hand side. */
3335 forall_replace_symtree (c->expr2, old_sym, 1);
3339 /* Handles dependencies in forall assignments. */
3340 static int
3341 check_forall_dependencies (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
3343 gfc_ref *lref;
3344 gfc_ref *rref;
3345 int need_temp;
3346 gfc_symbol *lsym;
3348 lsym = c->expr1->symtree->n.sym;
3349 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
3351 /* Now check for dependencies within the 'variable'
3352 expression itself. These are treated by making a complete
3353 copy of variable and changing all the references to it
3354 point to the copy instead. Note that the shallow copy of
3355 the variable will not suffice for derived types with
3356 pointer components. We therefore leave these to their
3357 own devices. */
3358 if (lsym->ts.type == BT_DERIVED
3359 && lsym->ts.u.derived->attr.pointer_comp)
3360 return need_temp;
3362 new_symtree = NULL;
3363 if (find_forall_index (c->expr1, lsym, 2))
3365 forall_make_variable_temp (c, pre, post);
3366 need_temp = 0;
3369 /* Substrings with dependencies are treated in the same
3370 way. */
3371 if (c->expr1->ts.type == BT_CHARACTER
3372 && c->expr1->ref
3373 && c->expr2->expr_type == EXPR_VARIABLE
3374 && lsym == c->expr2->symtree->n.sym)
3376 for (lref = c->expr1->ref; lref; lref = lref->next)
3377 if (lref->type == REF_SUBSTRING)
3378 break;
3379 for (rref = c->expr2->ref; rref; rref = rref->next)
3380 if (rref->type == REF_SUBSTRING)
3381 break;
3383 if (rref && lref
3384 && gfc_dep_compare_expr (rref->u.ss.start, lref->u.ss.start) < 0)
3386 forall_make_variable_temp (c, pre, post);
3387 need_temp = 0;
3390 return need_temp;
3394 static void
3395 cleanup_forall_symtrees (gfc_code *c)
3397 forall_restore_symtree (c->expr1);
3398 forall_restore_symtree (c->expr2);
3399 free (new_symtree->n.sym);
3400 free (new_symtree);
3404 /* Generate the loops for a FORALL block, specified by FORALL_TMP. BODY
3405 is the contents of the FORALL block/stmt to be iterated. MASK_FLAG
3406 indicates whether we should generate code to test the FORALLs mask
3407 array. OUTER is the loop header to be used for initializing mask
3408 indices.
3410 The generated loop format is:
3411 count = (end - start + step) / step
3412 loopvar = start
3413 while (1)
3415 if (count <=0 )
3416 goto end_of_loop
3417 <body>
3418 loopvar += step
3419 count --
3421 end_of_loop: */
3423 static tree
3424 gfc_trans_forall_loop (forall_info *forall_tmp, tree body,
3425 int mask_flag, stmtblock_t *outer)
3427 int n, nvar;
3428 tree tmp;
3429 tree cond;
3430 stmtblock_t block;
3431 tree exit_label;
3432 tree count;
3433 tree var, start, end, step;
3434 iter_info *iter;
3436 /* Initialize the mask index outside the FORALL nest. */
3437 if (mask_flag && forall_tmp->mask)
3438 gfc_add_modify (outer, forall_tmp->maskindex, gfc_index_zero_node);
3440 iter = forall_tmp->this_loop;
3441 nvar = forall_tmp->nvar;
3442 for (n = 0; n < nvar; n++)
3444 var = iter->var;
3445 start = iter->start;
3446 end = iter->end;
3447 step = iter->step;
3449 exit_label = gfc_build_label_decl (NULL_TREE);
3450 TREE_USED (exit_label) = 1;
3452 /* The loop counter. */
3453 count = gfc_create_var (TREE_TYPE (var), "count");
3455 /* The body of the loop. */
3456 gfc_init_block (&block);
3458 /* The exit condition. */
3459 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
3460 count, build_int_cst (TREE_TYPE (count), 0));
3461 if (forall_tmp->do_concurrent)
3462 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
3463 build_int_cst (integer_type_node,
3464 annot_expr_parallel_kind),
3465 integer_zero_node);
3467 tmp = build1_v (GOTO_EXPR, exit_label);
3468 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3469 cond, tmp, build_empty_stmt (input_location));
3470 gfc_add_expr_to_block (&block, tmp);
3472 /* The main loop body. */
3473 gfc_add_expr_to_block (&block, body);
3475 /* Increment the loop variable. */
3476 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var,
3477 step);
3478 gfc_add_modify (&block, var, tmp);
3480 /* Advance to the next mask element. Only do this for the
3481 innermost loop. */
3482 if (n == 0 && mask_flag && forall_tmp->mask)
3484 tree maskindex = forall_tmp->maskindex;
3485 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3486 maskindex, gfc_index_one_node);
3487 gfc_add_modify (&block, maskindex, tmp);
3490 /* Decrement the loop counter. */
3491 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), count,
3492 build_int_cst (TREE_TYPE (var), 1));
3493 gfc_add_modify (&block, count, tmp);
3495 body = gfc_finish_block (&block);
3497 /* Loop var initialization. */
3498 gfc_init_block (&block);
3499 gfc_add_modify (&block, var, start);
3502 /* Initialize the loop counter. */
3503 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), step,
3504 start);
3505 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), end,
3506 tmp);
3507 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (var),
3508 tmp, step);
3509 gfc_add_modify (&block, count, tmp);
3511 /* The loop expression. */
3512 tmp = build1_v (LOOP_EXPR, body);
3513 gfc_add_expr_to_block (&block, tmp);
3515 /* The exit label. */
3516 tmp = build1_v (LABEL_EXPR, exit_label);
3517 gfc_add_expr_to_block (&block, tmp);
3519 body = gfc_finish_block (&block);
3520 iter = iter->next;
3522 return body;
3526 /* Generate the body and loops according to MASK_FLAG. If MASK_FLAG
3527 is nonzero, the body is controlled by all masks in the forall nest.
3528 Otherwise, the innermost loop is not controlled by it's mask. This
3529 is used for initializing that mask. */
3531 static tree
3532 gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
3533 int mask_flag)
3535 tree tmp;
3536 stmtblock_t header;
3537 forall_info *forall_tmp;
3538 tree mask, maskindex;
3540 gfc_start_block (&header);
3542 forall_tmp = nested_forall_info;
3543 while (forall_tmp != NULL)
3545 /* Generate body with masks' control. */
3546 if (mask_flag)
3548 mask = forall_tmp->mask;
3549 maskindex = forall_tmp->maskindex;
3551 /* If a mask was specified make the assignment conditional. */
3552 if (mask)
3554 tmp = gfc_build_array_ref (mask, maskindex, NULL);
3555 body = build3_v (COND_EXPR, tmp, body,
3556 build_empty_stmt (input_location));
3559 body = gfc_trans_forall_loop (forall_tmp, body, mask_flag, &header);
3560 forall_tmp = forall_tmp->prev_nest;
3561 mask_flag = 1;
3564 gfc_add_expr_to_block (&header, body);
3565 return gfc_finish_block (&header);
3569 /* Allocate data for holding a temporary array. Returns either a local
3570 temporary array or a pointer variable. */
3572 static tree
3573 gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
3574 tree elem_type)
3576 tree tmpvar;
3577 tree type;
3578 tree tmp;
3580 if (INTEGER_CST_P (size))
3581 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3582 size, gfc_index_one_node);
3583 else
3584 tmp = NULL_TREE;
3586 type = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
3587 type = build_array_type (elem_type, type);
3588 if (gfc_can_put_var_on_stack (bytesize) && INTEGER_CST_P (size))
3590 tmpvar = gfc_create_var (type, "temp");
3591 *pdata = NULL_TREE;
3593 else
3595 tmpvar = gfc_create_var (build_pointer_type (type), "temp");
3596 *pdata = convert (pvoid_type_node, tmpvar);
3598 tmp = gfc_call_malloc (pblock, TREE_TYPE (tmpvar), bytesize);
3599 gfc_add_modify (pblock, tmpvar, tmp);
3601 return tmpvar;
3605 /* Generate codes to copy the temporary to the actual lhs. */
3607 static tree
3608 generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
3609 tree count1,
3610 gfc_ss *lss, gfc_ss *rss,
3611 tree wheremask, bool invert)
3613 stmtblock_t block, body1;
3614 gfc_loopinfo loop;
3615 gfc_se lse;
3616 gfc_se rse;
3617 tree tmp;
3618 tree wheremaskexpr;
3620 (void) rss; /* TODO: unused. */
3622 gfc_start_block (&block);
3624 gfc_init_se (&rse, NULL);
3625 gfc_init_se (&lse, NULL);
3627 if (lss == gfc_ss_terminator)
3629 gfc_init_block (&body1);
3630 gfc_conv_expr (&lse, expr);
3631 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3633 else
3635 /* Initialize the loop. */
3636 gfc_init_loopinfo (&loop);
3638 /* We may need LSS to determine the shape of the expression. */
3639 gfc_add_ss_to_loop (&loop, lss);
3641 gfc_conv_ss_startstride (&loop);
3642 gfc_conv_loop_setup (&loop, &expr->where);
3644 gfc_mark_ss_chain_used (lss, 1);
3645 /* Start the loop body. */
3646 gfc_start_scalarized_body (&loop, &body1);
3648 /* Translate the expression. */
3649 gfc_copy_loopinfo_to_se (&lse, &loop);
3650 lse.ss = lss;
3651 gfc_conv_expr (&lse, expr);
3653 /* Form the expression of the temporary. */
3654 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3657 /* Use the scalar assignment. */
3658 rse.string_length = lse.string_length;
3659 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts,
3660 expr->expr_type == EXPR_VARIABLE, false);
3662 /* Form the mask expression according to the mask tree list. */
3663 if (wheremask)
3665 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3666 if (invert)
3667 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3668 TREE_TYPE (wheremaskexpr),
3669 wheremaskexpr);
3670 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3671 wheremaskexpr, tmp,
3672 build_empty_stmt (input_location));
3675 gfc_add_expr_to_block (&body1, tmp);
3677 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3678 count1, gfc_index_one_node);
3679 gfc_add_modify (&body1, count1, tmp);
3681 if (lss == gfc_ss_terminator)
3682 gfc_add_block_to_block (&block, &body1);
3683 else
3685 /* Increment count3. */
3686 if (count3)
3688 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3689 gfc_array_index_type,
3690 count3, gfc_index_one_node);
3691 gfc_add_modify (&body1, count3, tmp);
3694 /* Generate the copying loops. */
3695 gfc_trans_scalarizing_loops (&loop, &body1);
3697 gfc_add_block_to_block (&block, &loop.pre);
3698 gfc_add_block_to_block (&block, &loop.post);
3700 gfc_cleanup_loop (&loop);
3701 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
3702 as tree nodes in SS may not be valid in different scope. */
3705 tmp = gfc_finish_block (&block);
3706 return tmp;
3710 /* Generate codes to copy rhs to the temporary. TMP1 is the address of
3711 temporary, LSS and RSS are formed in function compute_inner_temp_size(),
3712 and should not be freed. WHEREMASK is the conditional execution mask
3713 whose sense may be inverted by INVERT. */
3715 static tree
3716 generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree count3,
3717 tree count1, gfc_ss *lss, gfc_ss *rss,
3718 tree wheremask, bool invert)
3720 stmtblock_t block, body1;
3721 gfc_loopinfo loop;
3722 gfc_se lse;
3723 gfc_se rse;
3724 tree tmp;
3725 tree wheremaskexpr;
3727 gfc_start_block (&block);
3729 gfc_init_se (&rse, NULL);
3730 gfc_init_se (&lse, NULL);
3732 if (lss == gfc_ss_terminator)
3734 gfc_init_block (&body1);
3735 gfc_conv_expr (&rse, expr2);
3736 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3738 else
3740 /* Initialize the loop. */
3741 gfc_init_loopinfo (&loop);
3743 /* We may need LSS to determine the shape of the expression. */
3744 gfc_add_ss_to_loop (&loop, lss);
3745 gfc_add_ss_to_loop (&loop, rss);
3747 gfc_conv_ss_startstride (&loop);
3748 gfc_conv_loop_setup (&loop, &expr2->where);
3750 gfc_mark_ss_chain_used (rss, 1);
3751 /* Start the loop body. */
3752 gfc_start_scalarized_body (&loop, &body1);
3754 /* Translate the expression. */
3755 gfc_copy_loopinfo_to_se (&rse, &loop);
3756 rse.ss = rss;
3757 gfc_conv_expr (&rse, expr2);
3759 /* Form the expression of the temporary. */
3760 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3763 /* Use the scalar assignment. */
3764 lse.string_length = rse.string_length;
3765 tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts,
3766 expr2->expr_type == EXPR_VARIABLE, false);
3768 /* Form the mask expression according to the mask tree list. */
3769 if (wheremask)
3771 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3772 if (invert)
3773 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3774 TREE_TYPE (wheremaskexpr),
3775 wheremaskexpr);
3776 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3777 wheremaskexpr, tmp,
3778 build_empty_stmt (input_location));
3781 gfc_add_expr_to_block (&body1, tmp);
3783 if (lss == gfc_ss_terminator)
3785 gfc_add_block_to_block (&block, &body1);
3787 /* Increment count1. */
3788 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3789 count1, gfc_index_one_node);
3790 gfc_add_modify (&block, count1, tmp);
3792 else
3794 /* Increment count1. */
3795 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3796 count1, gfc_index_one_node);
3797 gfc_add_modify (&body1, count1, tmp);
3799 /* Increment count3. */
3800 if (count3)
3802 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3803 gfc_array_index_type,
3804 count3, gfc_index_one_node);
3805 gfc_add_modify (&body1, count3, tmp);
3808 /* Generate the copying loops. */
3809 gfc_trans_scalarizing_loops (&loop, &body1);
3811 gfc_add_block_to_block (&block, &loop.pre);
3812 gfc_add_block_to_block (&block, &loop.post);
3814 gfc_cleanup_loop (&loop);
3815 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
3816 as tree nodes in SS may not be valid in different scope. */
3819 tmp = gfc_finish_block (&block);
3820 return tmp;
3824 /* Calculate the size of temporary needed in the assignment inside forall.
3825 LSS and RSS are filled in this function. */
3827 static tree
3828 compute_inner_temp_size (gfc_expr *expr1, gfc_expr *expr2,
3829 stmtblock_t * pblock,
3830 gfc_ss **lss, gfc_ss **rss)
3832 gfc_loopinfo loop;
3833 tree size;
3834 int i;
3835 int save_flag;
3836 tree tmp;
3838 *lss = gfc_walk_expr (expr1);
3839 *rss = NULL;
3841 size = gfc_index_one_node;
3842 if (*lss != gfc_ss_terminator)
3844 gfc_init_loopinfo (&loop);
3846 /* Walk the RHS of the expression. */
3847 *rss = gfc_walk_expr (expr2);
3848 if (*rss == gfc_ss_terminator)
3849 /* The rhs is scalar. Add a ss for the expression. */
3850 *rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
3852 /* Associate the SS with the loop. */
3853 gfc_add_ss_to_loop (&loop, *lss);
3854 /* We don't actually need to add the rhs at this point, but it might
3855 make guessing the loop bounds a bit easier. */
3856 gfc_add_ss_to_loop (&loop, *rss);
3858 /* We only want the shape of the expression, not rest of the junk
3859 generated by the scalarizer. */
3860 loop.array_parameter = 1;
3862 /* Calculate the bounds of the scalarization. */
3863 save_flag = gfc_option.rtcheck;
3864 gfc_option.rtcheck &= ~GFC_RTCHECK_BOUNDS;
3865 gfc_conv_ss_startstride (&loop);
3866 gfc_option.rtcheck = save_flag;
3867 gfc_conv_loop_setup (&loop, &expr2->where);
3869 /* Figure out how many elements we need. */
3870 for (i = 0; i < loop.dimen; i++)
3872 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3873 gfc_array_index_type,
3874 gfc_index_one_node, loop.from[i]);
3875 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3876 gfc_array_index_type, tmp, loop.to[i]);
3877 size = fold_build2_loc (input_location, MULT_EXPR,
3878 gfc_array_index_type, size, tmp);
3880 gfc_add_block_to_block (pblock, &loop.pre);
3881 size = gfc_evaluate_now (size, pblock);
3882 gfc_add_block_to_block (pblock, &loop.post);
3884 /* TODO: write a function that cleans up a loopinfo without freeing
3885 the SS chains. Currently a NOP. */
3888 return size;
3892 /* Calculate the overall iterator number of the nested forall construct.
3893 This routine actually calculates the number of times the body of the
3894 nested forall specified by NESTED_FORALL_INFO is executed and multiplies
3895 that by the expression INNER_SIZE. The BLOCK argument specifies the
3896 block in which to calculate the result, and the optional INNER_SIZE_BODY
3897 argument contains any statements that need to executed (inside the loop)
3898 to initialize or calculate INNER_SIZE. */
3900 static tree
3901 compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
3902 stmtblock_t *inner_size_body, stmtblock_t *block)
3904 forall_info *forall_tmp = nested_forall_info;
3905 tree tmp, number;
3906 stmtblock_t body;
3908 /* We can eliminate the innermost unconditional loops with constant
3909 array bounds. */
3910 if (INTEGER_CST_P (inner_size))
3912 while (forall_tmp
3913 && !forall_tmp->mask
3914 && INTEGER_CST_P (forall_tmp->size))
3916 inner_size = fold_build2_loc (input_location, MULT_EXPR,
3917 gfc_array_index_type,
3918 inner_size, forall_tmp->size);
3919 forall_tmp = forall_tmp->prev_nest;
3922 /* If there are no loops left, we have our constant result. */
3923 if (!forall_tmp)
3924 return inner_size;
3927 /* Otherwise, create a temporary variable to compute the result. */
3928 number = gfc_create_var (gfc_array_index_type, "num");
3929 gfc_add_modify (block, number, gfc_index_zero_node);
3931 gfc_start_block (&body);
3932 if (inner_size_body)
3933 gfc_add_block_to_block (&body, inner_size_body);
3934 if (forall_tmp)
3935 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3936 gfc_array_index_type, number, inner_size);
3937 else
3938 tmp = inner_size;
3939 gfc_add_modify (&body, number, tmp);
3940 tmp = gfc_finish_block (&body);
3942 /* Generate loops. */
3943 if (forall_tmp != NULL)
3944 tmp = gfc_trans_nested_forall_loop (forall_tmp, tmp, 1);
3946 gfc_add_expr_to_block (block, tmp);
3948 return number;
3952 /* Allocate temporary for forall construct. SIZE is the size of temporary
3953 needed. PTEMP1 is returned for space free. */
3955 static tree
3956 allocate_temp_for_forall_nest_1 (tree type, tree size, stmtblock_t * block,
3957 tree * ptemp1)
3959 tree bytesize;
3960 tree unit;
3961 tree tmp;
3963 unit = fold_convert (gfc_array_index_type, TYPE_SIZE_UNIT (type));
3964 if (!integer_onep (unit))
3965 bytesize = fold_build2_loc (input_location, MULT_EXPR,
3966 gfc_array_index_type, size, unit);
3967 else
3968 bytesize = size;
3970 *ptemp1 = NULL;
3971 tmp = gfc_do_allocate (bytesize, size, ptemp1, block, type);
3973 if (*ptemp1)
3974 tmp = build_fold_indirect_ref_loc (input_location, tmp);
3975 return tmp;
3979 /* Allocate temporary for forall construct according to the information in
3980 nested_forall_info. INNER_SIZE is the size of temporary needed in the
3981 assignment inside forall. PTEMP1 is returned for space free. */
3983 static tree
3984 allocate_temp_for_forall_nest (forall_info * nested_forall_info, tree type,
3985 tree inner_size, stmtblock_t * inner_size_body,
3986 stmtblock_t * block, tree * ptemp1)
3988 tree size;
3990 /* Calculate the total size of temporary needed in forall construct. */
3991 size = compute_overall_iter_number (nested_forall_info, inner_size,
3992 inner_size_body, block);
3994 return allocate_temp_for_forall_nest_1 (type, size, block, ptemp1);
3998 /* Handle assignments inside forall which need temporary.
4000 forall (i=start:end:stride; maskexpr)
4001 e<i> = f<i>
4002 end forall
4003 (where e,f<i> are arbitrary expressions possibly involving i
4004 and there is a dependency between e<i> and f<i>)
4005 Translates to:
4006 masktmp(:) = maskexpr(:)
4008 maskindex = 0;
4009 count1 = 0;
4010 num = 0;
4011 for (i = start; i <= end; i += stride)
4012 num += SIZE (f<i>)
4013 count1 = 0;
4014 ALLOCATE (tmp(num))
4015 for (i = start; i <= end; i += stride)
4017 if (masktmp[maskindex++])
4018 tmp[count1++] = f<i>
4020 maskindex = 0;
4021 count1 = 0;
4022 for (i = start; i <= end; i += stride)
4024 if (masktmp[maskindex++])
4025 e<i> = tmp[count1++]
4027 DEALLOCATE (tmp)
4029 static void
4030 gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
4031 tree wheremask, bool invert,
4032 forall_info * nested_forall_info,
4033 stmtblock_t * block)
4035 tree type;
4036 tree inner_size;
4037 gfc_ss *lss, *rss;
4038 tree count, count1;
4039 tree tmp, tmp1;
4040 tree ptemp1;
4041 stmtblock_t inner_size_body;
4043 /* Create vars. count1 is the current iterator number of the nested
4044 forall. */
4045 count1 = gfc_create_var (gfc_array_index_type, "count1");
4047 /* Count is the wheremask index. */
4048 if (wheremask)
4050 count = gfc_create_var (gfc_array_index_type, "count");
4051 gfc_add_modify (block, count, gfc_index_zero_node);
4053 else
4054 count = NULL;
4056 /* Initialize count1. */
4057 gfc_add_modify (block, count1, gfc_index_zero_node);
4059 /* Calculate the size of temporary needed in the assignment. Return loop, lss
4060 and rss which are used in function generate_loop_for_rhs_to_temp(). */
4061 /* The type of LHS. Used in function allocate_temp_for_forall_nest */
4062 if (expr1->ts.type == BT_CHARACTER)
4064 type = NULL;
4065 if (expr1->ref && expr1->ref->type == REF_SUBSTRING)
4067 gfc_se ssse;
4068 gfc_init_se (&ssse, NULL);
4069 gfc_conv_expr (&ssse, expr1);
4070 type = gfc_get_character_type_len (gfc_default_character_kind,
4071 ssse.string_length);
4073 else
4075 if (!expr1->ts.u.cl->backend_decl)
4077 gfc_se tse;
4078 gcc_assert (expr1->ts.u.cl->length);
4079 gfc_init_se (&tse, NULL);
4080 gfc_conv_expr (&tse, expr1->ts.u.cl->length);
4081 expr1->ts.u.cl->backend_decl = tse.expr;
4083 type = gfc_get_character_type_len (gfc_default_character_kind,
4084 expr1->ts.u.cl->backend_decl);
4087 else
4088 type = gfc_typenode_for_spec (&expr1->ts);
4090 gfc_init_block (&inner_size_body);
4091 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
4092 &lss, &rss);
4094 /* Allocate temporary for nested forall construct according to the
4095 information in nested_forall_info and inner_size. */
4096 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type, inner_size,
4097 &inner_size_body, block, &ptemp1);
4099 /* Generate codes to copy rhs to the temporary . */
4100 tmp = generate_loop_for_rhs_to_temp (expr2, tmp1, count, count1, lss, rss,
4101 wheremask, invert);
4103 /* Generate body and loops according to the information in
4104 nested_forall_info. */
4105 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4106 gfc_add_expr_to_block (block, tmp);
4108 /* Reset count1. */
4109 gfc_add_modify (block, count1, gfc_index_zero_node);
4111 /* Reset count. */
4112 if (wheremask)
4113 gfc_add_modify (block, count, gfc_index_zero_node);
4115 /* TODO: Second call to compute_inner_temp_size to initialize lss and
4116 rss; there must be a better way. */
4117 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
4118 &lss, &rss);
4120 /* Generate codes to copy the temporary to lhs. */
4121 tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, count, count1,
4122 lss, rss,
4123 wheremask, invert);
4125 /* Generate body and loops according to the information in
4126 nested_forall_info. */
4127 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4128 gfc_add_expr_to_block (block, tmp);
4130 if (ptemp1)
4132 /* Free the temporary. */
4133 tmp = gfc_call_free (ptemp1);
4134 gfc_add_expr_to_block (block, tmp);
4139 /* Translate pointer assignment inside FORALL which need temporary. */
4141 static void
4142 gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
4143 forall_info * nested_forall_info,
4144 stmtblock_t * block)
4146 tree type;
4147 tree inner_size;
4148 gfc_ss *lss, *rss;
4149 gfc_se lse;
4150 gfc_se rse;
4151 gfc_array_info *info;
4152 gfc_loopinfo loop;
4153 tree desc;
4154 tree parm;
4155 tree parmtype;
4156 stmtblock_t body;
4157 tree count;
4158 tree tmp, tmp1, ptemp1;
4160 count = gfc_create_var (gfc_array_index_type, "count");
4161 gfc_add_modify (block, count, gfc_index_zero_node);
4163 inner_size = gfc_index_one_node;
4164 lss = gfc_walk_expr (expr1);
4165 rss = gfc_walk_expr (expr2);
4166 if (lss == gfc_ss_terminator)
4168 type = gfc_typenode_for_spec (&expr1->ts);
4169 type = build_pointer_type (type);
4171 /* Allocate temporary for nested forall construct according to the
4172 information in nested_forall_info and inner_size. */
4173 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type,
4174 inner_size, NULL, block, &ptemp1);
4175 gfc_start_block (&body);
4176 gfc_init_se (&lse, NULL);
4177 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
4178 gfc_init_se (&rse, NULL);
4179 rse.want_pointer = 1;
4180 gfc_conv_expr (&rse, expr2);
4181 gfc_add_block_to_block (&body, &rse.pre);
4182 gfc_add_modify (&body, lse.expr,
4183 fold_convert (TREE_TYPE (lse.expr), rse.expr));
4184 gfc_add_block_to_block (&body, &rse.post);
4186 /* Increment count. */
4187 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4188 count, gfc_index_one_node);
4189 gfc_add_modify (&body, count, tmp);
4191 tmp = gfc_finish_block (&body);
4193 /* Generate body and loops according to the information in
4194 nested_forall_info. */
4195 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4196 gfc_add_expr_to_block (block, tmp);
4198 /* Reset count. */
4199 gfc_add_modify (block, count, gfc_index_zero_node);
4201 gfc_start_block (&body);
4202 gfc_init_se (&lse, NULL);
4203 gfc_init_se (&rse, NULL);
4204 rse.expr = gfc_build_array_ref (tmp1, count, NULL);
4205 lse.want_pointer = 1;
4206 gfc_conv_expr (&lse, expr1);
4207 gfc_add_block_to_block (&body, &lse.pre);
4208 gfc_add_modify (&body, lse.expr, rse.expr);
4209 gfc_add_block_to_block (&body, &lse.post);
4210 /* Increment count. */
4211 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4212 count, gfc_index_one_node);
4213 gfc_add_modify (&body, count, tmp);
4214 tmp = gfc_finish_block (&body);
4216 /* Generate body and loops according to the information in
4217 nested_forall_info. */
4218 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4219 gfc_add_expr_to_block (block, tmp);
4221 else
4223 gfc_init_loopinfo (&loop);
4225 /* Associate the SS with the loop. */
4226 gfc_add_ss_to_loop (&loop, rss);
4228 /* Setup the scalarizing loops and bounds. */
4229 gfc_conv_ss_startstride (&loop);
4231 gfc_conv_loop_setup (&loop, &expr2->where);
4233 info = &rss->info->data.array;
4234 desc = info->descriptor;
4236 /* Make a new descriptor. */
4237 parmtype = gfc_get_element_type (TREE_TYPE (desc));
4238 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0,
4239 loop.from, loop.to, 1,
4240 GFC_ARRAY_UNKNOWN, true);
4242 /* Allocate temporary for nested forall construct. */
4243 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
4244 inner_size, NULL, block, &ptemp1);
4245 gfc_start_block (&body);
4246 gfc_init_se (&lse, NULL);
4247 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
4248 lse.direct_byref = 1;
4249 gfc_conv_expr_descriptor (&lse, expr2);
4251 gfc_add_block_to_block (&body, &lse.pre);
4252 gfc_add_block_to_block (&body, &lse.post);
4254 /* Increment count. */
4255 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4256 count, gfc_index_one_node);
4257 gfc_add_modify (&body, count, tmp);
4259 tmp = gfc_finish_block (&body);
4261 /* Generate body and loops according to the information in
4262 nested_forall_info. */
4263 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4264 gfc_add_expr_to_block (block, tmp);
4266 /* Reset count. */
4267 gfc_add_modify (block, count, gfc_index_zero_node);
4269 parm = gfc_build_array_ref (tmp1, count, NULL);
4270 gfc_init_se (&lse, NULL);
4271 gfc_conv_expr_descriptor (&lse, expr1);
4272 gfc_add_modify (&lse.pre, lse.expr, parm);
4273 gfc_start_block (&body);
4274 gfc_add_block_to_block (&body, &lse.pre);
4275 gfc_add_block_to_block (&body, &lse.post);
4277 /* Increment count. */
4278 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4279 count, gfc_index_one_node);
4280 gfc_add_modify (&body, count, tmp);
4282 tmp = gfc_finish_block (&body);
4284 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4285 gfc_add_expr_to_block (block, tmp);
4287 /* Free the temporary. */
4288 if (ptemp1)
4290 tmp = gfc_call_free (ptemp1);
4291 gfc_add_expr_to_block (block, tmp);
4296 /* FORALL and WHERE statements are really nasty, especially when you nest
4297 them. All the rhs of a forall assignment must be evaluated before the
4298 actual assignments are performed. Presumably this also applies to all the
4299 assignments in an inner where statement. */
4301 /* Generate code for a FORALL statement. Any temporaries are allocated as a
4302 linear array, relying on the fact that we process in the same order in all
4303 loops.
4305 forall (i=start:end:stride; maskexpr)
4306 e<i> = f<i>
4307 g<i> = h<i>
4308 end forall
4309 (where e,f,g,h<i> are arbitrary expressions possibly involving i)
4310 Translates to:
4311 count = ((end + 1 - start) / stride)
4312 masktmp(:) = maskexpr(:)
4314 maskindex = 0;
4315 for (i = start; i <= end; i += stride)
4317 if (masktmp[maskindex++])
4318 e<i> = f<i>
4320 maskindex = 0;
4321 for (i = start; i <= end; i += stride)
4323 if (masktmp[maskindex++])
4324 g<i> = h<i>
4327 Note that this code only works when there are no dependencies.
4328 Forall loop with array assignments and data dependencies are a real pain,
4329 because the size of the temporary cannot always be determined before the
4330 loop is executed. This problem is compounded by the presence of nested
4331 FORALL constructs.
4334 static tree
4335 gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
4337 stmtblock_t pre;
4338 stmtblock_t post;
4339 stmtblock_t block;
4340 stmtblock_t body;
4341 tree *var;
4342 tree *start;
4343 tree *end;
4344 tree *step;
4345 gfc_expr **varexpr;
4346 tree tmp;
4347 tree assign;
4348 tree size;
4349 tree maskindex;
4350 tree mask;
4351 tree pmask;
4352 tree cycle_label = NULL_TREE;
4353 int n;
4354 int nvar;
4355 int need_temp;
4356 gfc_forall_iterator *fa;
4357 gfc_se se;
4358 gfc_code *c;
4359 gfc_saved_var *saved_vars;
4360 iter_info *this_forall;
4361 forall_info *info;
4362 bool need_mask;
4364 /* Do nothing if the mask is false. */
4365 if (code->expr1
4366 && code->expr1->expr_type == EXPR_CONSTANT
4367 && !code->expr1->value.logical)
4368 return build_empty_stmt (input_location);
4370 n = 0;
4371 /* Count the FORALL index number. */
4372 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
4373 n++;
4374 nvar = n;
4376 /* Allocate the space for var, start, end, step, varexpr. */
4377 var = XCNEWVEC (tree, nvar);
4378 start = XCNEWVEC (tree, nvar);
4379 end = XCNEWVEC (tree, nvar);
4380 step = XCNEWVEC (tree, nvar);
4381 varexpr = XCNEWVEC (gfc_expr *, nvar);
4382 saved_vars = XCNEWVEC (gfc_saved_var, nvar);
4384 /* Allocate the space for info. */
4385 info = XCNEW (forall_info);
4387 gfc_start_block (&pre);
4388 gfc_init_block (&post);
4389 gfc_init_block (&block);
4391 n = 0;
4392 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
4394 gfc_symbol *sym = fa->var->symtree->n.sym;
4396 /* Allocate space for this_forall. */
4397 this_forall = XCNEW (iter_info);
4399 /* Create a temporary variable for the FORALL index. */
4400 tmp = gfc_typenode_for_spec (&sym->ts);
4401 var[n] = gfc_create_var (tmp, sym->name);
4402 gfc_shadow_sym (sym, var[n], &saved_vars[n]);
4404 /* Record it in this_forall. */
4405 this_forall->var = var[n];
4407 /* Replace the index symbol's backend_decl with the temporary decl. */
4408 sym->backend_decl = var[n];
4410 /* Work out the start, end and stride for the loop. */
4411 gfc_init_se (&se, NULL);
4412 gfc_conv_expr_val (&se, fa->start);
4413 /* Record it in this_forall. */
4414 this_forall->start = se.expr;
4415 gfc_add_block_to_block (&block, &se.pre);
4416 start[n] = se.expr;
4418 gfc_init_se (&se, NULL);
4419 gfc_conv_expr_val (&se, fa->end);
4420 /* Record it in this_forall. */
4421 this_forall->end = se.expr;
4422 gfc_make_safe_expr (&se);
4423 gfc_add_block_to_block (&block, &se.pre);
4424 end[n] = se.expr;
4426 gfc_init_se (&se, NULL);
4427 gfc_conv_expr_val (&se, fa->stride);
4428 /* Record it in this_forall. */
4429 this_forall->step = se.expr;
4430 gfc_make_safe_expr (&se);
4431 gfc_add_block_to_block (&block, &se.pre);
4432 step[n] = se.expr;
4434 /* Set the NEXT field of this_forall to NULL. */
4435 this_forall->next = NULL;
4436 /* Link this_forall to the info construct. */
4437 if (info->this_loop)
4439 iter_info *iter_tmp = info->this_loop;
4440 while (iter_tmp->next != NULL)
4441 iter_tmp = iter_tmp->next;
4442 iter_tmp->next = this_forall;
4444 else
4445 info->this_loop = this_forall;
4447 n++;
4449 nvar = n;
4451 /* Calculate the size needed for the current forall level. */
4452 size = gfc_index_one_node;
4453 for (n = 0; n < nvar; n++)
4455 /* size = (end + step - start) / step. */
4456 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (start[n]),
4457 step[n], start[n]);
4458 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (end[n]),
4459 end[n], tmp);
4460 tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, TREE_TYPE (tmp),
4461 tmp, step[n]);
4462 tmp = convert (gfc_array_index_type, tmp);
4464 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4465 size, tmp);
4468 /* Record the nvar and size of current forall level. */
4469 info->nvar = nvar;
4470 info->size = size;
4472 if (code->expr1)
4474 /* If the mask is .true., consider the FORALL unconditional. */
4475 if (code->expr1->expr_type == EXPR_CONSTANT
4476 && code->expr1->value.logical)
4477 need_mask = false;
4478 else
4479 need_mask = true;
4481 else
4482 need_mask = false;
4484 /* First we need to allocate the mask. */
4485 if (need_mask)
4487 /* As the mask array can be very big, prefer compact boolean types. */
4488 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4489 mask = allocate_temp_for_forall_nest (nested_forall_info, mask_type,
4490 size, NULL, &block, &pmask);
4491 maskindex = gfc_create_var_np (gfc_array_index_type, "mi");
4493 /* Record them in the info structure. */
4494 info->maskindex = maskindex;
4495 info->mask = mask;
4497 else
4499 /* No mask was specified. */
4500 maskindex = NULL_TREE;
4501 mask = pmask = NULL_TREE;
4504 /* Link the current forall level to nested_forall_info. */
4505 info->prev_nest = nested_forall_info;
4506 nested_forall_info = info;
4508 /* Copy the mask into a temporary variable if required.
4509 For now we assume a mask temporary is needed. */
4510 if (need_mask)
4512 /* As the mask array can be very big, prefer compact boolean types. */
4513 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4515 gfc_add_modify (&block, maskindex, gfc_index_zero_node);
4517 /* Start of mask assignment loop body. */
4518 gfc_start_block (&body);
4520 /* Evaluate the mask expression. */
4521 gfc_init_se (&se, NULL);
4522 gfc_conv_expr_val (&se, code->expr1);
4523 gfc_add_block_to_block (&body, &se.pre);
4525 /* Store the mask. */
4526 se.expr = convert (mask_type, se.expr);
4528 tmp = gfc_build_array_ref (mask, maskindex, NULL);
4529 gfc_add_modify (&body, tmp, se.expr);
4531 /* Advance to the next mask element. */
4532 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4533 maskindex, gfc_index_one_node);
4534 gfc_add_modify (&body, maskindex, tmp);
4536 /* Generate the loops. */
4537 tmp = gfc_finish_block (&body);
4538 tmp = gfc_trans_nested_forall_loop (info, tmp, 0);
4539 gfc_add_expr_to_block (&block, tmp);
4542 if (code->op == EXEC_DO_CONCURRENT)
4544 gfc_init_block (&body);
4545 cycle_label = gfc_build_label_decl (NULL_TREE);
4546 code->cycle_label = cycle_label;
4547 tmp = gfc_trans_code (code->block->next);
4548 gfc_add_expr_to_block (&body, tmp);
4550 if (TREE_USED (cycle_label))
4552 tmp = build1_v (LABEL_EXPR, cycle_label);
4553 gfc_add_expr_to_block (&body, tmp);
4556 tmp = gfc_finish_block (&body);
4557 nested_forall_info->do_concurrent = true;
4558 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4559 gfc_add_expr_to_block (&block, tmp);
4560 goto done;
4563 c = code->block->next;
4565 /* TODO: loop merging in FORALL statements. */
4566 /* Now that we've got a copy of the mask, generate the assignment loops. */
4567 while (c)
4569 switch (c->op)
4571 case EXEC_ASSIGN:
4572 /* A scalar or array assignment. DO the simple check for
4573 lhs to rhs dependencies. These make a temporary for the
4574 rhs and form a second forall block to copy to variable. */
4575 need_temp = check_forall_dependencies(c, &pre, &post);
4577 /* Temporaries due to array assignment data dependencies introduce
4578 no end of problems. */
4579 if (need_temp || flag_test_forall_temp)
4580 gfc_trans_assign_need_temp (c->expr1, c->expr2, NULL, false,
4581 nested_forall_info, &block);
4582 else
4584 /* Use the normal assignment copying routines. */
4585 assign = gfc_trans_assignment (c->expr1, c->expr2, false, true);
4587 /* Generate body and loops. */
4588 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4589 assign, 1);
4590 gfc_add_expr_to_block (&block, tmp);
4593 /* Cleanup any temporary symtrees that have been made to deal
4594 with dependencies. */
4595 if (new_symtree)
4596 cleanup_forall_symtrees (c);
4598 break;
4600 case EXEC_WHERE:
4601 /* Translate WHERE or WHERE construct nested in FORALL. */
4602 gfc_trans_where_2 (c, NULL, false, nested_forall_info, &block);
4603 break;
4605 /* Pointer assignment inside FORALL. */
4606 case EXEC_POINTER_ASSIGN:
4607 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
4608 /* Avoid cases where a temporary would never be needed and where
4609 the temp code is guaranteed to fail. */
4610 if (need_temp
4611 || (flag_test_forall_temp
4612 && c->expr2->expr_type != EXPR_CONSTANT
4613 && c->expr2->expr_type != EXPR_NULL))
4614 gfc_trans_pointer_assign_need_temp (c->expr1, c->expr2,
4615 nested_forall_info, &block);
4616 else
4618 /* Use the normal assignment copying routines. */
4619 assign = gfc_trans_pointer_assignment (c->expr1, c->expr2);
4621 /* Generate body and loops. */
4622 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4623 assign, 1);
4624 gfc_add_expr_to_block (&block, tmp);
4626 break;
4628 case EXEC_FORALL:
4629 tmp = gfc_trans_forall_1 (c, nested_forall_info);
4630 gfc_add_expr_to_block (&block, tmp);
4631 break;
4633 /* Explicit subroutine calls are prevented by the frontend but interface
4634 assignments can legitimately produce them. */
4635 case EXEC_ASSIGN_CALL:
4636 assign = gfc_trans_call (c, true, NULL_TREE, NULL_TREE, false);
4637 tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign, 1);
4638 gfc_add_expr_to_block (&block, tmp);
4639 break;
4641 default:
4642 gcc_unreachable ();
4645 c = c->next;
4648 done:
4649 /* Restore the original index variables. */
4650 for (fa = code->ext.forall_iterator, n = 0; fa; fa = fa->next, n++)
4651 gfc_restore_sym (fa->var->symtree->n.sym, &saved_vars[n]);
4653 /* Free the space for var, start, end, step, varexpr. */
4654 free (var);
4655 free (start);
4656 free (end);
4657 free (step);
4658 free (varexpr);
4659 free (saved_vars);
4661 for (this_forall = info->this_loop; this_forall;)
4663 iter_info *next = this_forall->next;
4664 free (this_forall);
4665 this_forall = next;
4668 /* Free the space for this forall_info. */
4669 free (info);
4671 if (pmask)
4673 /* Free the temporary for the mask. */
4674 tmp = gfc_call_free (pmask);
4675 gfc_add_expr_to_block (&block, tmp);
4677 if (maskindex)
4678 pushdecl (maskindex);
4680 gfc_add_block_to_block (&pre, &block);
4681 gfc_add_block_to_block (&pre, &post);
4683 return gfc_finish_block (&pre);
4687 /* Translate the FORALL statement or construct. */
4689 tree gfc_trans_forall (gfc_code * code)
4691 return gfc_trans_forall_1 (code, NULL);
4695 /* Translate the DO CONCURRENT construct. */
4697 tree gfc_trans_do_concurrent (gfc_code * code)
4699 return gfc_trans_forall_1 (code, NULL);
4703 /* Evaluate the WHERE mask expression, copy its value to a temporary.
4704 If the WHERE construct is nested in FORALL, compute the overall temporary
4705 needed by the WHERE mask expression multiplied by the iterator number of
4706 the nested forall.
4707 ME is the WHERE mask expression.
4708 MASK is the current execution mask upon input, whose sense may or may
4709 not be inverted as specified by the INVERT argument.
4710 CMASK is the updated execution mask on output, or NULL if not required.
4711 PMASK is the pending execution mask on output, or NULL if not required.
4712 BLOCK is the block in which to place the condition evaluation loops. */
4714 static void
4715 gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
4716 tree mask, bool invert, tree cmask, tree pmask,
4717 tree mask_type, stmtblock_t * block)
4719 tree tmp, tmp1;
4720 gfc_ss *lss, *rss;
4721 gfc_loopinfo loop;
4722 stmtblock_t body, body1;
4723 tree count, cond, mtmp;
4724 gfc_se lse, rse;
4726 gfc_init_loopinfo (&loop);
4728 lss = gfc_walk_expr (me);
4729 rss = gfc_walk_expr (me);
4731 /* Variable to index the temporary. */
4732 count = gfc_create_var (gfc_array_index_type, "count");
4733 /* Initialize count. */
4734 gfc_add_modify (block, count, gfc_index_zero_node);
4736 gfc_start_block (&body);
4738 gfc_init_se (&rse, NULL);
4739 gfc_init_se (&lse, NULL);
4741 if (lss == gfc_ss_terminator)
4743 gfc_init_block (&body1);
4745 else
4747 /* Initialize the loop. */
4748 gfc_init_loopinfo (&loop);
4750 /* We may need LSS to determine the shape of the expression. */
4751 gfc_add_ss_to_loop (&loop, lss);
4752 gfc_add_ss_to_loop (&loop, rss);
4754 gfc_conv_ss_startstride (&loop);
4755 gfc_conv_loop_setup (&loop, &me->where);
4757 gfc_mark_ss_chain_used (rss, 1);
4758 /* Start the loop body. */
4759 gfc_start_scalarized_body (&loop, &body1);
4761 /* Translate the expression. */
4762 gfc_copy_loopinfo_to_se (&rse, &loop);
4763 rse.ss = rss;
4764 gfc_conv_expr (&rse, me);
4767 /* Variable to evaluate mask condition. */
4768 cond = gfc_create_var (mask_type, "cond");
4769 if (mask && (cmask || pmask))
4770 mtmp = gfc_create_var (mask_type, "mask");
4771 else mtmp = NULL_TREE;
4773 gfc_add_block_to_block (&body1, &lse.pre);
4774 gfc_add_block_to_block (&body1, &rse.pre);
4776 gfc_add_modify (&body1, cond, fold_convert (mask_type, rse.expr));
4778 if (mask && (cmask || pmask))
4780 tmp = gfc_build_array_ref (mask, count, NULL);
4781 if (invert)
4782 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, tmp);
4783 gfc_add_modify (&body1, mtmp, tmp);
4786 if (cmask)
4788 tmp1 = gfc_build_array_ref (cmask, count, NULL);
4789 tmp = cond;
4790 if (mask)
4791 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type,
4792 mtmp, tmp);
4793 gfc_add_modify (&body1, tmp1, tmp);
4796 if (pmask)
4798 tmp1 = gfc_build_array_ref (pmask, count, NULL);
4799 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, cond);
4800 if (mask)
4801 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type, mtmp,
4802 tmp);
4803 gfc_add_modify (&body1, tmp1, tmp);
4806 gfc_add_block_to_block (&body1, &lse.post);
4807 gfc_add_block_to_block (&body1, &rse.post);
4809 if (lss == gfc_ss_terminator)
4811 gfc_add_block_to_block (&body, &body1);
4813 else
4815 /* Increment count. */
4816 tmp1 = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4817 count, gfc_index_one_node);
4818 gfc_add_modify (&body1, count, tmp1);
4820 /* Generate the copying loops. */
4821 gfc_trans_scalarizing_loops (&loop, &body1);
4823 gfc_add_block_to_block (&body, &loop.pre);
4824 gfc_add_block_to_block (&body, &loop.post);
4826 gfc_cleanup_loop (&loop);
4827 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
4828 as tree nodes in SS may not be valid in different scope. */
4831 tmp1 = gfc_finish_block (&body);
4832 /* If the WHERE construct is inside FORALL, fill the full temporary. */
4833 if (nested_forall_info != NULL)
4834 tmp1 = gfc_trans_nested_forall_loop (nested_forall_info, tmp1, 1);
4836 gfc_add_expr_to_block (block, tmp1);
4840 /* Translate an assignment statement in a WHERE statement or construct
4841 statement. The MASK expression is used to control which elements
4842 of EXPR1 shall be assigned. The sense of MASK is specified by
4843 INVERT. */
4845 static tree
4846 gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
4847 tree mask, bool invert,
4848 tree count1, tree count2,
4849 gfc_code *cnext)
4851 gfc_se lse;
4852 gfc_se rse;
4853 gfc_ss *lss;
4854 gfc_ss *lss_section;
4855 gfc_ss *rss;
4857 gfc_loopinfo loop;
4858 tree tmp;
4859 stmtblock_t block;
4860 stmtblock_t body;
4861 tree index, maskexpr;
4863 /* A defined assignment. */
4864 if (cnext && cnext->resolved_sym)
4865 return gfc_trans_call (cnext, true, mask, count1, invert);
4867 #if 0
4868 /* TODO: handle this special case.
4869 Special case a single function returning an array. */
4870 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
4872 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
4873 if (tmp)
4874 return tmp;
4876 #endif
4878 /* Assignment of the form lhs = rhs. */
4879 gfc_start_block (&block);
4881 gfc_init_se (&lse, NULL);
4882 gfc_init_se (&rse, NULL);
4884 /* Walk the lhs. */
4885 lss = gfc_walk_expr (expr1);
4886 rss = NULL;
4888 /* In each where-assign-stmt, the mask-expr and the variable being
4889 defined shall be arrays of the same shape. */
4890 gcc_assert (lss != gfc_ss_terminator);
4892 /* The assignment needs scalarization. */
4893 lss_section = lss;
4895 /* Find a non-scalar SS from the lhs. */
4896 while (lss_section != gfc_ss_terminator
4897 && lss_section->info->type != GFC_SS_SECTION)
4898 lss_section = lss_section->next;
4900 gcc_assert (lss_section != gfc_ss_terminator);
4902 /* Initialize the scalarizer. */
4903 gfc_init_loopinfo (&loop);
4905 /* Walk the rhs. */
4906 rss = gfc_walk_expr (expr2);
4907 if (rss == gfc_ss_terminator)
4909 /* The rhs is scalar. Add a ss for the expression. */
4910 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
4911 rss->info->where = 1;
4914 /* Associate the SS with the loop. */
4915 gfc_add_ss_to_loop (&loop, lss);
4916 gfc_add_ss_to_loop (&loop, rss);
4918 /* Calculate the bounds of the scalarization. */
4919 gfc_conv_ss_startstride (&loop);
4921 /* Resolve any data dependencies in the statement. */
4922 gfc_conv_resolve_dependencies (&loop, lss_section, rss);
4924 /* Setup the scalarizing loops. */
4925 gfc_conv_loop_setup (&loop, &expr2->where);
4927 /* Setup the gfc_se structures. */
4928 gfc_copy_loopinfo_to_se (&lse, &loop);
4929 gfc_copy_loopinfo_to_se (&rse, &loop);
4931 rse.ss = rss;
4932 gfc_mark_ss_chain_used (rss, 1);
4933 if (loop.temp_ss == NULL)
4935 lse.ss = lss;
4936 gfc_mark_ss_chain_used (lss, 1);
4938 else
4940 lse.ss = loop.temp_ss;
4941 gfc_mark_ss_chain_used (lss, 3);
4942 gfc_mark_ss_chain_used (loop.temp_ss, 3);
4945 /* Start the scalarized loop body. */
4946 gfc_start_scalarized_body (&loop, &body);
4948 /* Translate the expression. */
4949 gfc_conv_expr (&rse, expr2);
4950 if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
4951 gfc_conv_tmp_array_ref (&lse);
4952 else
4953 gfc_conv_expr (&lse, expr1);
4955 /* Form the mask expression according to the mask. */
4956 index = count1;
4957 maskexpr = gfc_build_array_ref (mask, index, NULL);
4958 if (invert)
4959 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
4960 TREE_TYPE (maskexpr), maskexpr);
4962 /* Use the scalar assignment as is. */
4963 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
4964 false, loop.temp_ss == NULL);
4966 tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt (input_location));
4968 gfc_add_expr_to_block (&body, tmp);
4970 if (lss == gfc_ss_terminator)
4972 /* Increment count1. */
4973 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4974 count1, gfc_index_one_node);
4975 gfc_add_modify (&body, count1, tmp);
4977 /* Use the scalar assignment as is. */
4978 gfc_add_block_to_block (&block, &body);
4980 else
4982 gcc_assert (lse.ss == gfc_ss_terminator
4983 && rse.ss == gfc_ss_terminator);
4985 if (loop.temp_ss != NULL)
4987 /* Increment count1 before finish the main body of a scalarized
4988 expression. */
4989 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4990 gfc_array_index_type, count1, gfc_index_one_node);
4991 gfc_add_modify (&body, count1, tmp);
4992 gfc_trans_scalarized_loop_boundary (&loop, &body);
4994 /* We need to copy the temporary to the actual lhs. */
4995 gfc_init_se (&lse, NULL);
4996 gfc_init_se (&rse, NULL);
4997 gfc_copy_loopinfo_to_se (&lse, &loop);
4998 gfc_copy_loopinfo_to_se (&rse, &loop);
5000 rse.ss = loop.temp_ss;
5001 lse.ss = lss;
5003 gfc_conv_tmp_array_ref (&rse);
5004 gfc_conv_expr (&lse, expr1);
5006 gcc_assert (lse.ss == gfc_ss_terminator
5007 && rse.ss == gfc_ss_terminator);
5009 /* Form the mask expression according to the mask tree list. */
5010 index = count2;
5011 maskexpr = gfc_build_array_ref (mask, index, NULL);
5012 if (invert)
5013 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
5014 TREE_TYPE (maskexpr), maskexpr);
5016 /* Use the scalar assignment as is. */
5017 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, false, true);
5018 tmp = build3_v (COND_EXPR, maskexpr, tmp,
5019 build_empty_stmt (input_location));
5020 gfc_add_expr_to_block (&body, tmp);
5022 /* Increment count2. */
5023 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5024 gfc_array_index_type, count2,
5025 gfc_index_one_node);
5026 gfc_add_modify (&body, count2, tmp);
5028 else
5030 /* Increment count1. */
5031 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5032 gfc_array_index_type, count1,
5033 gfc_index_one_node);
5034 gfc_add_modify (&body, count1, tmp);
5037 /* Generate the copying loops. */
5038 gfc_trans_scalarizing_loops (&loop, &body);
5040 /* Wrap the whole thing up. */
5041 gfc_add_block_to_block (&block, &loop.pre);
5042 gfc_add_block_to_block (&block, &loop.post);
5043 gfc_cleanup_loop (&loop);
5046 return gfc_finish_block (&block);
5050 /* Translate the WHERE construct or statement.
5051 This function can be called iteratively to translate the nested WHERE
5052 construct or statement.
5053 MASK is the control mask. */
5055 static void
5056 gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
5057 forall_info * nested_forall_info, stmtblock_t * block)
5059 stmtblock_t inner_size_body;
5060 tree inner_size, size;
5061 gfc_ss *lss, *rss;
5062 tree mask_type;
5063 gfc_expr *expr1;
5064 gfc_expr *expr2;
5065 gfc_code *cblock;
5066 gfc_code *cnext;
5067 tree tmp;
5068 tree cond;
5069 tree count1, count2;
5070 bool need_cmask;
5071 bool need_pmask;
5072 int need_temp;
5073 tree pcmask = NULL_TREE;
5074 tree ppmask = NULL_TREE;
5075 tree cmask = NULL_TREE;
5076 tree pmask = NULL_TREE;
5077 gfc_actual_arglist *arg;
5079 /* the WHERE statement or the WHERE construct statement. */
5080 cblock = code->block;
5082 /* As the mask array can be very big, prefer compact boolean types. */
5083 mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
5085 /* Determine which temporary masks are needed. */
5086 if (!cblock->block)
5088 /* One clause: No ELSEWHEREs. */
5089 need_cmask = (cblock->next != 0);
5090 need_pmask = false;
5092 else if (cblock->block->block)
5094 /* Three or more clauses: Conditional ELSEWHEREs. */
5095 need_cmask = true;
5096 need_pmask = true;
5098 else if (cblock->next)
5100 /* Two clauses, the first non-empty. */
5101 need_cmask = true;
5102 need_pmask = (mask != NULL_TREE
5103 && cblock->block->next != 0);
5105 else if (!cblock->block->next)
5107 /* Two clauses, both empty. */
5108 need_cmask = false;
5109 need_pmask = false;
5111 /* Two clauses, the first empty, the second non-empty. */
5112 else if (mask)
5114 need_cmask = (cblock->block->expr1 != 0);
5115 need_pmask = true;
5117 else
5119 need_cmask = true;
5120 need_pmask = false;
5123 if (need_cmask || need_pmask)
5125 /* Calculate the size of temporary needed by the mask-expr. */
5126 gfc_init_block (&inner_size_body);
5127 inner_size = compute_inner_temp_size (cblock->expr1, cblock->expr1,
5128 &inner_size_body, &lss, &rss);
5130 gfc_free_ss_chain (lss);
5131 gfc_free_ss_chain (rss);
5133 /* Calculate the total size of temporary needed. */
5134 size = compute_overall_iter_number (nested_forall_info, inner_size,
5135 &inner_size_body, block);
5137 /* Check whether the size is negative. */
5138 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, size,
5139 gfc_index_zero_node);
5140 size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
5141 cond, gfc_index_zero_node, size);
5142 size = gfc_evaluate_now (size, block);
5144 /* Allocate temporary for WHERE mask if needed. */
5145 if (need_cmask)
5146 cmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
5147 &pcmask);
5149 /* Allocate temporary for !mask if needed. */
5150 if (need_pmask)
5151 pmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
5152 &ppmask);
5155 while (cblock)
5157 /* Each time around this loop, the where clause is conditional
5158 on the value of mask and invert, which are updated at the
5159 bottom of the loop. */
5161 /* Has mask-expr. */
5162 if (cblock->expr1)
5164 /* Ensure that the WHERE mask will be evaluated exactly once.
5165 If there are no statements in this WHERE/ELSEWHERE clause,
5166 then we don't need to update the control mask (cmask).
5167 If this is the last clause of the WHERE construct, then
5168 we don't need to update the pending control mask (pmask). */
5169 if (mask)
5170 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
5171 mask, invert,
5172 cblock->next ? cmask : NULL_TREE,
5173 cblock->block ? pmask : NULL_TREE,
5174 mask_type, block);
5175 else
5176 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
5177 NULL_TREE, false,
5178 (cblock->next || cblock->block)
5179 ? cmask : NULL_TREE,
5180 NULL_TREE, mask_type, block);
5182 invert = false;
5184 /* It's a final elsewhere-stmt. No mask-expr is present. */
5185 else
5186 cmask = mask;
5188 /* The body of this where clause are controlled by cmask with
5189 sense specified by invert. */
5191 /* Get the assignment statement of a WHERE statement, or the first
5192 statement in where-body-construct of a WHERE construct. */
5193 cnext = cblock->next;
5194 while (cnext)
5196 switch (cnext->op)
5198 /* WHERE assignment statement. */
5199 case EXEC_ASSIGN_CALL:
5201 arg = cnext->ext.actual;
5202 expr1 = expr2 = NULL;
5203 for (; arg; arg = arg->next)
5205 if (!arg->expr)
5206 continue;
5207 if (expr1 == NULL)
5208 expr1 = arg->expr;
5209 else
5210 expr2 = arg->expr;
5212 goto evaluate;
5214 case EXEC_ASSIGN:
5215 expr1 = cnext->expr1;
5216 expr2 = cnext->expr2;
5217 evaluate:
5218 if (nested_forall_info != NULL)
5220 need_temp = gfc_check_dependency (expr1, expr2, 0);
5221 if ((need_temp || flag_test_forall_temp)
5222 && cnext->op != EXEC_ASSIGN_CALL)
5223 gfc_trans_assign_need_temp (expr1, expr2,
5224 cmask, invert,
5225 nested_forall_info, block);
5226 else
5228 /* Variables to control maskexpr. */
5229 count1 = gfc_create_var (gfc_array_index_type, "count1");
5230 count2 = gfc_create_var (gfc_array_index_type, "count2");
5231 gfc_add_modify (block, count1, gfc_index_zero_node);
5232 gfc_add_modify (block, count2, gfc_index_zero_node);
5234 tmp = gfc_trans_where_assign (expr1, expr2,
5235 cmask, invert,
5236 count1, count2,
5237 cnext);
5239 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
5240 tmp, 1);
5241 gfc_add_expr_to_block (block, tmp);
5244 else
5246 /* Variables to control maskexpr. */
5247 count1 = gfc_create_var (gfc_array_index_type, "count1");
5248 count2 = gfc_create_var (gfc_array_index_type, "count2");
5249 gfc_add_modify (block, count1, gfc_index_zero_node);
5250 gfc_add_modify (block, count2, gfc_index_zero_node);
5252 tmp = gfc_trans_where_assign (expr1, expr2,
5253 cmask, invert,
5254 count1, count2,
5255 cnext);
5256 gfc_add_expr_to_block (block, tmp);
5259 break;
5261 /* WHERE or WHERE construct is part of a where-body-construct. */
5262 case EXEC_WHERE:
5263 gfc_trans_where_2 (cnext, cmask, invert,
5264 nested_forall_info, block);
5265 break;
5267 default:
5268 gcc_unreachable ();
5271 /* The next statement within the same where-body-construct. */
5272 cnext = cnext->next;
5274 /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt. */
5275 cblock = cblock->block;
5276 if (mask == NULL_TREE)
5278 /* If we're the initial WHERE, we can simply invert the sense
5279 of the current mask to obtain the "mask" for the remaining
5280 ELSEWHEREs. */
5281 invert = true;
5282 mask = cmask;
5284 else
5286 /* Otherwise, for nested WHERE's we need to use the pending mask. */
5287 invert = false;
5288 mask = pmask;
5292 /* If we allocated a pending mask array, deallocate it now. */
5293 if (ppmask)
5295 tmp = gfc_call_free (ppmask);
5296 gfc_add_expr_to_block (block, tmp);
5299 /* If we allocated a current mask array, deallocate it now. */
5300 if (pcmask)
5302 tmp = gfc_call_free (pcmask);
5303 gfc_add_expr_to_block (block, tmp);
5307 /* Translate a simple WHERE construct or statement without dependencies.
5308 CBLOCK is the "then" clause of the WHERE statement, where CBLOCK->EXPR
5309 is the mask condition, and EBLOCK if non-NULL is the "else" clause.
5310 Currently both CBLOCK and EBLOCK are restricted to single assignments. */
5312 static tree
5313 gfc_trans_where_3 (gfc_code * cblock, gfc_code * eblock)
5315 stmtblock_t block, body;
5316 gfc_expr *cond, *tdst, *tsrc, *edst, *esrc;
5317 tree tmp, cexpr, tstmt, estmt;
5318 gfc_ss *css, *tdss, *tsss;
5319 gfc_se cse, tdse, tsse, edse, esse;
5320 gfc_loopinfo loop;
5321 gfc_ss *edss = 0;
5322 gfc_ss *esss = 0;
5323 bool maybe_workshare = false;
5325 /* Allow the scalarizer to workshare simple where loops. */
5326 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
5327 == OMPWS_WORKSHARE_FLAG)
5329 maybe_workshare = true;
5330 ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
5333 cond = cblock->expr1;
5334 tdst = cblock->next->expr1;
5335 tsrc = cblock->next->expr2;
5336 edst = eblock ? eblock->next->expr1 : NULL;
5337 esrc = eblock ? eblock->next->expr2 : NULL;
5339 gfc_start_block (&block);
5340 gfc_init_loopinfo (&loop);
5342 /* Handle the condition. */
5343 gfc_init_se (&cse, NULL);
5344 css = gfc_walk_expr (cond);
5345 gfc_add_ss_to_loop (&loop, css);
5347 /* Handle the then-clause. */
5348 gfc_init_se (&tdse, NULL);
5349 gfc_init_se (&tsse, NULL);
5350 tdss = gfc_walk_expr (tdst);
5351 tsss = gfc_walk_expr (tsrc);
5352 if (tsss == gfc_ss_terminator)
5354 tsss = gfc_get_scalar_ss (gfc_ss_terminator, tsrc);
5355 tsss->info->where = 1;
5357 gfc_add_ss_to_loop (&loop, tdss);
5358 gfc_add_ss_to_loop (&loop, tsss);
5360 if (eblock)
5362 /* Handle the else clause. */
5363 gfc_init_se (&edse, NULL);
5364 gfc_init_se (&esse, NULL);
5365 edss = gfc_walk_expr (edst);
5366 esss = gfc_walk_expr (esrc);
5367 if (esss == gfc_ss_terminator)
5369 esss = gfc_get_scalar_ss (gfc_ss_terminator, esrc);
5370 esss->info->where = 1;
5372 gfc_add_ss_to_loop (&loop, edss);
5373 gfc_add_ss_to_loop (&loop, esss);
5376 gfc_conv_ss_startstride (&loop);
5377 gfc_conv_loop_setup (&loop, &tdst->where);
5379 gfc_mark_ss_chain_used (css, 1);
5380 gfc_mark_ss_chain_used (tdss, 1);
5381 gfc_mark_ss_chain_used (tsss, 1);
5382 if (eblock)
5384 gfc_mark_ss_chain_used (edss, 1);
5385 gfc_mark_ss_chain_used (esss, 1);
5388 gfc_start_scalarized_body (&loop, &body);
5390 gfc_copy_loopinfo_to_se (&cse, &loop);
5391 gfc_copy_loopinfo_to_se (&tdse, &loop);
5392 gfc_copy_loopinfo_to_se (&tsse, &loop);
5393 cse.ss = css;
5394 tdse.ss = tdss;
5395 tsse.ss = tsss;
5396 if (eblock)
5398 gfc_copy_loopinfo_to_se (&edse, &loop);
5399 gfc_copy_loopinfo_to_se (&esse, &loop);
5400 edse.ss = edss;
5401 esse.ss = esss;
5404 gfc_conv_expr (&cse, cond);
5405 gfc_add_block_to_block (&body, &cse.pre);
5406 cexpr = cse.expr;
5408 gfc_conv_expr (&tsse, tsrc);
5409 if (tdss != gfc_ss_terminator && loop.temp_ss != NULL)
5410 gfc_conv_tmp_array_ref (&tdse);
5411 else
5412 gfc_conv_expr (&tdse, tdst);
5414 if (eblock)
5416 gfc_conv_expr (&esse, esrc);
5417 if (edss != gfc_ss_terminator && loop.temp_ss != NULL)
5418 gfc_conv_tmp_array_ref (&edse);
5419 else
5420 gfc_conv_expr (&edse, edst);
5423 tstmt = gfc_trans_scalar_assign (&tdse, &tsse, tdst->ts, false, true);
5424 estmt = eblock ? gfc_trans_scalar_assign (&edse, &esse, edst->ts,
5425 false, true)
5426 : build_empty_stmt (input_location);
5427 tmp = build3_v (COND_EXPR, cexpr, tstmt, estmt);
5428 gfc_add_expr_to_block (&body, tmp);
5429 gfc_add_block_to_block (&body, &cse.post);
5431 if (maybe_workshare)
5432 ompws_flags &= ~OMPWS_SCALARIZER_BODY;
5433 gfc_trans_scalarizing_loops (&loop, &body);
5434 gfc_add_block_to_block (&block, &loop.pre);
5435 gfc_add_block_to_block (&block, &loop.post);
5436 gfc_cleanup_loop (&loop);
5438 return gfc_finish_block (&block);
5441 /* As the WHERE or WHERE construct statement can be nested, we call
5442 gfc_trans_where_2 to do the translation, and pass the initial
5443 NULL values for both the control mask and the pending control mask. */
5445 tree
5446 gfc_trans_where (gfc_code * code)
5448 stmtblock_t block;
5449 gfc_code *cblock;
5450 gfc_code *eblock;
5452 cblock = code->block;
5453 if (cblock->next
5454 && cblock->next->op == EXEC_ASSIGN
5455 && !cblock->next->next)
5457 eblock = cblock->block;
5458 if (!eblock)
5460 /* A simple "WHERE (cond) x = y" statement or block is
5461 dependence free if cond is not dependent upon writing x,
5462 and the source y is unaffected by the destination x. */
5463 if (!gfc_check_dependency (cblock->next->expr1,
5464 cblock->expr1, 0)
5465 && !gfc_check_dependency (cblock->next->expr1,
5466 cblock->next->expr2, 0))
5467 return gfc_trans_where_3 (cblock, NULL);
5469 else if (!eblock->expr1
5470 && !eblock->block
5471 && eblock->next
5472 && eblock->next->op == EXEC_ASSIGN
5473 && !eblock->next->next)
5475 /* A simple "WHERE (cond) x1 = y1 ELSEWHERE x2 = y2 ENDWHERE"
5476 block is dependence free if cond is not dependent on writes
5477 to x1 and x2, y1 is not dependent on writes to x2, and y2
5478 is not dependent on writes to x1, and both y's are not
5479 dependent upon their own x's. In addition to this, the
5480 final two dependency checks below exclude all but the same
5481 array reference if the where and elswhere destinations
5482 are the same. In short, this is VERY conservative and this
5483 is needed because the two loops, required by the standard
5484 are coalesced in gfc_trans_where_3. */
5485 if (!gfc_check_dependency (cblock->next->expr1,
5486 cblock->expr1, 0)
5487 && !gfc_check_dependency (eblock->next->expr1,
5488 cblock->expr1, 0)
5489 && !gfc_check_dependency (cblock->next->expr1,
5490 eblock->next->expr2, 1)
5491 && !gfc_check_dependency (eblock->next->expr1,
5492 cblock->next->expr2, 1)
5493 && !gfc_check_dependency (cblock->next->expr1,
5494 cblock->next->expr2, 1)
5495 && !gfc_check_dependency (eblock->next->expr1,
5496 eblock->next->expr2, 1)
5497 && !gfc_check_dependency (cblock->next->expr1,
5498 eblock->next->expr1, 0)
5499 && !gfc_check_dependency (eblock->next->expr1,
5500 cblock->next->expr1, 0))
5501 return gfc_trans_where_3 (cblock, eblock);
5505 gfc_start_block (&block);
5507 gfc_trans_where_2 (code, NULL, false, NULL, &block);
5509 return gfc_finish_block (&block);
5513 /* CYCLE a DO loop. The label decl has already been created by
5514 gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
5515 node at the head of the loop. We must mark the label as used. */
5517 tree
5518 gfc_trans_cycle (gfc_code * code)
5520 tree cycle_label;
5522 cycle_label = code->ext.which_construct->cycle_label;
5523 gcc_assert (cycle_label);
5525 TREE_USED (cycle_label) = 1;
5526 return build1_v (GOTO_EXPR, cycle_label);
5530 /* EXIT a DO loop. Similar to CYCLE, but now the label is in
5531 TREE_VALUE (backend_decl) of the gfc_code node at the head of the
5532 loop. */
5534 tree
5535 gfc_trans_exit (gfc_code * code)
5537 tree exit_label;
5539 exit_label = code->ext.which_construct->exit_label;
5540 gcc_assert (exit_label);
5542 TREE_USED (exit_label) = 1;
5543 return build1_v (GOTO_EXPR, exit_label);
5547 /* Get the initializer expression for the code and expr of an allocate.
5548 When no initializer is needed return NULL. */
5550 static gfc_expr *
5551 allocate_get_initializer (gfc_code * code, gfc_expr * expr)
5553 if (!gfc_bt_struct (expr->ts.type) && expr->ts.type != BT_CLASS)
5554 return NULL;
5556 /* An explicit type was given in allocate ( T:: object). */
5557 if (code->ext.alloc.ts.type == BT_DERIVED
5558 && (code->ext.alloc.ts.u.derived->attr.alloc_comp
5559 || gfc_has_default_initializer (code->ext.alloc.ts.u.derived)))
5560 return gfc_default_initializer (&code->ext.alloc.ts);
5562 if (gfc_bt_struct (expr->ts.type)
5563 && (expr->ts.u.derived->attr.alloc_comp
5564 || gfc_has_default_initializer (expr->ts.u.derived)))
5565 return gfc_default_initializer (&expr->ts);
5567 if (expr->ts.type == BT_CLASS
5568 && (CLASS_DATA (expr)->ts.u.derived->attr.alloc_comp
5569 || gfc_has_default_initializer (CLASS_DATA (expr)->ts.u.derived)))
5570 return gfc_default_initializer (&CLASS_DATA (expr)->ts);
5572 return NULL;
5575 /* Translate the ALLOCATE statement. */
5577 tree
5578 gfc_trans_allocate (gfc_code * code)
5580 gfc_alloc *al;
5581 gfc_expr *expr, *e3rhs = NULL, *init_expr;
5582 gfc_se se, se_sz;
5583 tree tmp;
5584 tree parm;
5585 tree stat;
5586 tree errmsg;
5587 tree errlen;
5588 tree label_errmsg;
5589 tree label_finish;
5590 tree memsz;
5591 tree al_vptr, al_len;
5592 /* If an expr3 is present, then store the tree for accessing its
5593 _vptr, and _len components in the variables, respectively. The
5594 element size, i.e. _vptr%size, is stored in expr3_esize. Any of
5595 the trees may be the NULL_TREE indicating that this is not
5596 available for expr3's type. */
5597 tree expr3, expr3_vptr, expr3_len, expr3_esize;
5598 /* Classify what expr3 stores. */
5599 enum { E3_UNSET = 0, E3_SOURCE, E3_MOLD, E3_DESC } e3_is;
5600 stmtblock_t block;
5601 stmtblock_t post;
5602 tree nelems;
5603 bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set, is_coarray;
5604 bool needs_caf_sync, caf_refs_comp;
5605 gfc_symtree *newsym = NULL;
5606 symbol_attribute caf_attr;
5607 gfc_actual_arglist *param_list;
5609 if (!code->ext.alloc.list)
5610 return NULL_TREE;
5612 stat = tmp = memsz = al_vptr = al_len = NULL_TREE;
5613 expr3 = expr3_vptr = expr3_len = expr3_esize = NULL_TREE;
5614 label_errmsg = label_finish = errmsg = errlen = NULL_TREE;
5615 e3_is = E3_UNSET;
5616 is_coarray = needs_caf_sync = false;
5618 gfc_init_block (&block);
5619 gfc_init_block (&post);
5621 /* STAT= (and maybe ERRMSG=) is present. */
5622 if (code->expr1)
5624 /* STAT=. */
5625 tree gfc_int4_type_node = gfc_get_int_type (4);
5626 stat = gfc_create_var (gfc_int4_type_node, "stat");
5628 /* ERRMSG= only makes sense with STAT=. */
5629 if (code->expr2)
5631 gfc_init_se (&se, NULL);
5632 se.want_pointer = 1;
5633 gfc_conv_expr_lhs (&se, code->expr2);
5634 errmsg = se.expr;
5635 errlen = se.string_length;
5637 else
5639 errmsg = null_pointer_node;
5640 errlen = build_int_cst (gfc_charlen_type_node, 0);
5643 /* GOTO destinations. */
5644 label_errmsg = gfc_build_label_decl (NULL_TREE);
5645 label_finish = gfc_build_label_decl (NULL_TREE);
5646 TREE_USED (label_finish) = 0;
5649 /* When an expr3 is present evaluate it only once. The standards prevent a
5650 dependency of expr3 on the objects in the allocate list. An expr3 can
5651 be pre-evaluated in all cases. One just has to make sure, to use the
5652 correct way, i.e., to get the descriptor or to get a reference
5653 expression. */
5654 if (code->expr3)
5656 bool vtab_needed = false, temp_var_needed = false,
5657 temp_obj_created = false;
5659 is_coarray = gfc_is_coarray (code->expr3);
5661 /* Figure whether we need the vtab from expr3. */
5662 for (al = code->ext.alloc.list; !vtab_needed && al != NULL;
5663 al = al->next)
5664 vtab_needed = (al->expr->ts.type == BT_CLASS);
5666 gfc_init_se (&se, NULL);
5667 /* When expr3 is a variable, i.e., a very simple expression,
5668 then convert it once here. */
5669 if (code->expr3->expr_type == EXPR_VARIABLE
5670 || code->expr3->expr_type == EXPR_ARRAY
5671 || code->expr3->expr_type == EXPR_CONSTANT)
5673 if (!code->expr3->mold
5674 || code->expr3->ts.type == BT_CHARACTER
5675 || vtab_needed
5676 || code->ext.alloc.arr_spec_from_expr3)
5678 /* Convert expr3 to a tree. For all "simple" expression just
5679 get the descriptor or the reference, respectively, depending
5680 on the rank of the expr. */
5681 if (code->ext.alloc.arr_spec_from_expr3 || code->expr3->rank != 0)
5682 gfc_conv_expr_descriptor (&se, code->expr3);
5683 else
5685 gfc_conv_expr_reference (&se, code->expr3);
5687 /* gfc_conv_expr_reference wraps POINTER_PLUS_EXPR in a
5688 NOP_EXPR, which prevents gfortran from getting the vptr
5689 from the source=-expression. Remove the NOP_EXPR and go
5690 with the POINTER_PLUS_EXPR in this case. */
5691 if (code->expr3->ts.type == BT_CLASS
5692 && TREE_CODE (se.expr) == NOP_EXPR
5693 && (TREE_CODE (TREE_OPERAND (se.expr, 0))
5694 == POINTER_PLUS_EXPR
5695 || is_coarray))
5696 se.expr = TREE_OPERAND (se.expr, 0);
5698 /* Create a temp variable only for component refs to prevent
5699 having to go through the full deref-chain each time and to
5700 simplfy computation of array properties. */
5701 temp_var_needed = TREE_CODE (se.expr) == COMPONENT_REF;
5704 else
5706 /* In all other cases evaluate the expr3. */
5707 symbol_attribute attr;
5708 /* Get the descriptor for all arrays, that are not allocatable or
5709 pointer, because the latter are descriptors already.
5710 The exception are function calls returning a class object:
5711 The descriptor is stored in their results _data component, which
5712 is easier to access, when first a temporary variable for the
5713 result is created and the descriptor retrieved from there. */
5714 attr = gfc_expr_attr (code->expr3);
5715 if (code->expr3->rank != 0
5716 && ((!attr.allocatable && !attr.pointer)
5717 || (code->expr3->expr_type == EXPR_FUNCTION
5718 && (code->expr3->ts.type != BT_CLASS
5719 || (code->expr3->value.function.isym
5720 && code->expr3->value.function.isym
5721 ->transformational)))))
5722 gfc_conv_expr_descriptor (&se, code->expr3);
5723 else
5724 gfc_conv_expr_reference (&se, code->expr3);
5725 if (code->expr3->ts.type == BT_CLASS)
5726 gfc_conv_class_to_class (&se, code->expr3,
5727 code->expr3->ts,
5728 false, true,
5729 false, false);
5730 temp_obj_created = temp_var_needed = !VAR_P (se.expr);
5732 gfc_add_block_to_block (&block, &se.pre);
5733 gfc_add_block_to_block (&post, &se.post);
5735 /* Special case when string in expr3 is zero. */
5736 if (code->expr3->ts.type == BT_CHARACTER
5737 && integer_zerop (se.string_length))
5739 gfc_init_se (&se, NULL);
5740 temp_var_needed = false;
5741 expr3_len = integer_zero_node;
5742 e3_is = E3_MOLD;
5744 /* Prevent aliasing, i.e., se.expr may be already a
5745 variable declaration. */
5746 else if (se.expr != NULL_TREE && temp_var_needed)
5748 tree var, desc;
5749 tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)) || is_coarray ?
5750 se.expr
5751 : build_fold_indirect_ref_loc (input_location, se.expr);
5753 /* Get the array descriptor and prepare it to be assigned to the
5754 temporary variable var. For classes the array descriptor is
5755 in the _data component and the object goes into the
5756 GFC_DECL_SAVED_DESCRIPTOR. */
5757 if (code->expr3->ts.type == BT_CLASS
5758 && code->expr3->rank != 0)
5760 /* When an array_ref was in expr3, then the descriptor is the
5761 first operand. */
5762 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
5764 desc = TREE_OPERAND (tmp, 0);
5766 else
5768 desc = tmp;
5769 tmp = gfc_class_data_get (tmp);
5771 if (code->ext.alloc.arr_spec_from_expr3)
5772 e3_is = E3_DESC;
5774 else
5775 desc = !is_coarray ? se.expr
5776 : TREE_OPERAND (TREE_OPERAND (se.expr, 0), 0);
5777 /* We need a regular (non-UID) symbol here, therefore give a
5778 prefix. */
5779 var = gfc_create_var (TREE_TYPE (tmp), "source");
5780 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
5782 gfc_allocate_lang_decl (var);
5783 GFC_DECL_SAVED_DESCRIPTOR (var) = desc;
5785 gfc_add_modify_loc (input_location, &block, var, tmp);
5787 expr3 = var;
5788 if (se.string_length)
5789 /* Evaluate it assuming that it also is complicated like expr3. */
5790 expr3_len = gfc_evaluate_now (se.string_length, &block);
5792 else
5794 expr3 = se.expr;
5795 expr3_len = se.string_length;
5798 /* Deallocate any allocatable components in expressions that use a
5799 temporary object, i.e. are not a simple alias of to an EXPR_VARIABLE.
5800 E.g. temporaries of a function call need freeing of their components
5801 here. */
5802 if ((code->expr3->ts.type == BT_DERIVED
5803 || code->expr3->ts.type == BT_CLASS)
5804 && (code->expr3->expr_type != EXPR_VARIABLE || temp_obj_created)
5805 && code->expr3->ts.u.derived->attr.alloc_comp)
5807 tmp = gfc_deallocate_alloc_comp (code->expr3->ts.u.derived,
5808 expr3, code->expr3->rank);
5809 gfc_prepend_expr_to_block (&post, tmp);
5812 /* Store what the expr3 is to be used for. */
5813 if (e3_is == E3_UNSET)
5814 e3_is = expr3 != NULL_TREE ?
5815 (code->ext.alloc.arr_spec_from_expr3 ?
5816 E3_DESC
5817 : (code->expr3->mold ? E3_MOLD : E3_SOURCE))
5818 : E3_UNSET;
5820 /* Figure how to get the _vtab entry. This also obtains the tree
5821 expression for accessing the _len component, because only
5822 unlimited polymorphic objects, which are a subcategory of class
5823 types, have a _len component. */
5824 if (code->expr3->ts.type == BT_CLASS)
5826 gfc_expr *rhs;
5827 tmp = expr3 != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (expr3)) ?
5828 build_fold_indirect_ref (expr3): expr3;
5829 /* Polymorphic SOURCE: VPTR must be determined at run time.
5830 expr3 may be a temporary array declaration, therefore check for
5831 GFC_CLASS_TYPE_P before trying to get the _vptr component. */
5832 if (tmp != NULL_TREE
5833 && (e3_is == E3_DESC
5834 || (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
5835 && (VAR_P (tmp) || !code->expr3->ref))
5836 || (VAR_P (tmp) && DECL_LANG_SPECIFIC (tmp))))
5837 tmp = gfc_class_vptr_get (expr3);
5838 else
5840 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
5841 gfc_add_vptr_component (rhs);
5842 gfc_init_se (&se, NULL);
5843 se.want_pointer = 1;
5844 gfc_conv_expr (&se, rhs);
5845 tmp = se.expr;
5846 gfc_free_expr (rhs);
5848 /* Set the element size. */
5849 expr3_esize = gfc_vptr_size_get (tmp);
5850 if (vtab_needed)
5851 expr3_vptr = tmp;
5852 /* Initialize the ref to the _len component. */
5853 if (expr3_len == NULL_TREE && UNLIMITED_POLY (code->expr3))
5855 /* Same like for retrieving the _vptr. */
5856 if (expr3 != NULL_TREE && !code->expr3->ref)
5857 expr3_len = gfc_class_len_get (expr3);
5858 else
5860 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
5861 gfc_add_len_component (rhs);
5862 gfc_init_se (&se, NULL);
5863 gfc_conv_expr (&se, rhs);
5864 expr3_len = se.expr;
5865 gfc_free_expr (rhs);
5869 else
5871 /* When the object to allocate is polymorphic type, then it
5872 needs its vtab set correctly, so deduce the required _vtab
5873 and _len from the source expression. */
5874 if (vtab_needed)
5876 /* VPTR is fixed at compile time. */
5877 gfc_symbol *vtab;
5879 vtab = gfc_find_vtab (&code->expr3->ts);
5880 gcc_assert (vtab);
5881 expr3_vptr = gfc_get_symbol_decl (vtab);
5882 expr3_vptr = gfc_build_addr_expr (NULL_TREE,
5883 expr3_vptr);
5885 /* _len component needs to be set, when ts is a character
5886 array. */
5887 if (expr3_len == NULL_TREE
5888 && code->expr3->ts.type == BT_CHARACTER)
5890 if (code->expr3->ts.u.cl
5891 && code->expr3->ts.u.cl->length)
5893 gfc_init_se (&se, NULL);
5894 gfc_conv_expr (&se, code->expr3->ts.u.cl->length);
5895 gfc_add_block_to_block (&block, &se.pre);
5896 expr3_len = gfc_evaluate_now (se.expr, &block);
5898 gcc_assert (expr3_len);
5900 /* For character arrays only the kind's size is needed, because
5901 the array mem_size is _len * (elem_size = kind_size).
5902 For all other get the element size in the normal way. */
5903 if (code->expr3->ts.type == BT_CHARACTER)
5904 expr3_esize = TYPE_SIZE_UNIT (
5905 gfc_get_char_type (code->expr3->ts.kind));
5906 else
5907 expr3_esize = TYPE_SIZE_UNIT (
5908 gfc_typenode_for_spec (&code->expr3->ts));
5910 gcc_assert (expr3_esize);
5911 expr3_esize = fold_convert (sizetype, expr3_esize);
5912 if (e3_is == E3_MOLD)
5913 /* The expr3 is no longer valid after this point. */
5914 expr3 = NULL_TREE;
5916 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
5918 /* Compute the explicit typespec given only once for all objects
5919 to allocate. */
5920 if (code->ext.alloc.ts.type != BT_CHARACTER)
5921 expr3_esize = TYPE_SIZE_UNIT (
5922 gfc_typenode_for_spec (&code->ext.alloc.ts));
5923 else if (code->ext.alloc.ts.u.cl->length != NULL)
5925 gfc_expr *sz;
5926 sz = gfc_copy_expr (code->ext.alloc.ts.u.cl->length);
5927 gfc_init_se (&se_sz, NULL);
5928 gfc_conv_expr (&se_sz, sz);
5929 gfc_free_expr (sz);
5930 tmp = gfc_get_char_type (code->ext.alloc.ts.kind);
5931 tmp = TYPE_SIZE_UNIT (tmp);
5932 tmp = fold_convert (TREE_TYPE (se_sz.expr), tmp);
5933 gfc_add_block_to_block (&block, &se_sz.pre);
5934 expr3_esize = fold_build2_loc (input_location, MULT_EXPR,
5935 TREE_TYPE (se_sz.expr),
5936 tmp, se_sz.expr);
5937 expr3_esize = gfc_evaluate_now (expr3_esize, &block);
5939 else
5940 expr3_esize = NULL_TREE;
5943 /* The routine gfc_trans_assignment () already implements all
5944 techniques needed. Unfortunately we may have a temporary
5945 variable for the source= expression here. When that is the
5946 case convert this variable into a temporary gfc_expr of type
5947 EXPR_VARIABLE and used it as rhs for the assignment. The
5948 advantage is, that we get scalarizer support for free,
5949 don't have to take care about scalar to array treatment and
5950 will benefit of every enhancements gfc_trans_assignment ()
5951 gets.
5952 No need to check whether e3_is is E3_UNSET, because that is
5953 done by expr3 != NULL_TREE.
5954 Exclude variables since the following block does not handle
5955 array sections. In any case, there is no harm in sending
5956 variables to gfc_trans_assignment because there is no
5957 evaluation of variables. */
5958 if (code->expr3)
5960 if (code->expr3->expr_type != EXPR_VARIABLE
5961 && e3_is != E3_MOLD && expr3 != NULL_TREE
5962 && DECL_P (expr3) && DECL_ARTIFICIAL (expr3))
5964 /* Build a temporary symtree and symbol. Do not add it to the current
5965 namespace to prevent accidently modifying a colliding
5966 symbol's as. */
5967 newsym = XCNEW (gfc_symtree);
5968 /* The name of the symtree should be unique, because gfc_create_var ()
5969 took care about generating the identifier. */
5970 newsym->name
5971 = gfc_get_string ("%s", IDENTIFIER_POINTER (DECL_NAME (expr3)));
5972 newsym->n.sym = gfc_new_symbol (newsym->name, NULL);
5973 /* The backend_decl is known. It is expr3, which is inserted
5974 here. */
5975 newsym->n.sym->backend_decl = expr3;
5976 e3rhs = gfc_get_expr ();
5977 e3rhs->rank = code->expr3->rank;
5978 e3rhs->symtree = newsym;
5979 /* Mark the symbol referenced or gfc_trans_assignment will bug. */
5980 newsym->n.sym->attr.referenced = 1;
5981 e3rhs->expr_type = EXPR_VARIABLE;
5982 e3rhs->where = code->expr3->where;
5983 /* Set the symbols type, upto it was BT_UNKNOWN. */
5984 if (IS_CLASS_ARRAY (code->expr3)
5985 && code->expr3->expr_type == EXPR_FUNCTION
5986 && code->expr3->value.function.isym
5987 && code->expr3->value.function.isym->transformational)
5989 e3rhs->ts = CLASS_DATA (code->expr3)->ts;
5991 else if (code->expr3->ts.type == BT_CLASS
5992 && !GFC_CLASS_TYPE_P (TREE_TYPE (expr3)))
5993 e3rhs->ts = CLASS_DATA (code->expr3)->ts;
5994 else
5995 e3rhs->ts = code->expr3->ts;
5996 newsym->n.sym->ts = e3rhs->ts;
5997 /* Check whether the expr3 is array valued. */
5998 if (e3rhs->rank)
6000 gfc_array_spec *arr;
6001 arr = gfc_get_array_spec ();
6002 arr->rank = e3rhs->rank;
6003 arr->type = AS_DEFERRED;
6004 /* Set the dimension and pointer attribute for arrays
6005 to be on the safe side. */
6006 newsym->n.sym->attr.dimension = 1;
6007 newsym->n.sym->attr.pointer = 1;
6008 newsym->n.sym->as = arr;
6009 if (IS_CLASS_ARRAY (code->expr3)
6010 && code->expr3->expr_type == EXPR_FUNCTION
6011 && code->expr3->value.function.isym
6012 && code->expr3->value.function.isym->transformational)
6014 gfc_array_spec *tarr;
6015 tarr = gfc_get_array_spec ();
6016 *tarr = *arr;
6017 e3rhs->ts.u.derived->as = tarr;
6019 gfc_add_full_array_ref (e3rhs, arr);
6021 else if (POINTER_TYPE_P (TREE_TYPE (expr3)))
6022 newsym->n.sym->attr.pointer = 1;
6023 /* The string length is known, too. Set it for char arrays. */
6024 if (e3rhs->ts.type == BT_CHARACTER)
6025 newsym->n.sym->ts.u.cl->backend_decl = expr3_len;
6026 gfc_commit_symbol (newsym->n.sym);
6028 else
6029 e3rhs = gfc_copy_expr (code->expr3);
6032 /* Loop over all objects to allocate. */
6033 for (al = code->ext.alloc.list; al != NULL; al = al->next)
6035 expr = gfc_copy_expr (al->expr);
6036 /* UNLIMITED_POLY () needs the _data component to be set, when
6037 expr is a unlimited polymorphic object. But the _data component
6038 has not been set yet, so check the derived type's attr for the
6039 unlimited polymorphic flag to be safe. */
6040 upoly_expr = UNLIMITED_POLY (expr)
6041 || (expr->ts.type == BT_DERIVED
6042 && expr->ts.u.derived->attr.unlimited_polymorphic);
6043 gfc_init_se (&se, NULL);
6045 /* For class types prepare the expressions to ref the _vptr
6046 and the _len component. The latter for unlimited polymorphic
6047 types only. */
6048 if (expr->ts.type == BT_CLASS)
6050 gfc_expr *expr_ref_vptr, *expr_ref_len;
6051 gfc_add_data_component (expr);
6052 /* Prep the vptr handle. */
6053 expr_ref_vptr = gfc_copy_expr (al->expr);
6054 gfc_add_vptr_component (expr_ref_vptr);
6055 se.want_pointer = 1;
6056 gfc_conv_expr (&se, expr_ref_vptr);
6057 al_vptr = se.expr;
6058 se.want_pointer = 0;
6059 gfc_free_expr (expr_ref_vptr);
6060 /* Allocated unlimited polymorphic objects always have a _len
6061 component. */
6062 if (upoly_expr)
6064 expr_ref_len = gfc_copy_expr (al->expr);
6065 gfc_add_len_component (expr_ref_len);
6066 gfc_conv_expr (&se, expr_ref_len);
6067 al_len = se.expr;
6068 gfc_free_expr (expr_ref_len);
6070 else
6071 /* In a loop ensure that all loop variable dependent variables
6072 are initialized at the same spot in all execution paths. */
6073 al_len = NULL_TREE;
6075 else
6076 al_vptr = al_len = NULL_TREE;
6078 se.want_pointer = 1;
6079 se.descriptor_only = 1;
6081 gfc_conv_expr (&se, expr);
6082 if (expr->ts.type == BT_CHARACTER && expr->ts.deferred)
6083 /* se.string_length now stores the .string_length variable of expr
6084 needed to allocate character(len=:) arrays. */
6085 al_len = se.string_length;
6087 al_len_needs_set = al_len != NULL_TREE;
6088 /* When allocating an array one can not use much of the
6089 pre-evaluated expr3 expressions, because for most of them the
6090 scalarizer is needed which is not available in the pre-evaluation
6091 step. Therefore gfc_array_allocate () is responsible (and able)
6092 to handle the complete array allocation. Only the element size
6093 needs to be provided, which is done most of the time by the
6094 pre-evaluation step. */
6095 nelems = NULL_TREE;
6096 if (expr3_len && (code->expr3->ts.type == BT_CHARACTER
6097 || code->expr3->ts.type == BT_CLASS))
6099 /* When al is an array, then the element size for each element
6100 in the array is needed, which is the product of the len and
6101 esize for char arrays. For unlimited polymorphics len can be
6102 zero, therefore take the maximum of len and one. */
6103 tmp = fold_build2_loc (input_location, MAX_EXPR,
6104 TREE_TYPE (expr3_len),
6105 expr3_len, fold_convert (TREE_TYPE (expr3_len),
6106 integer_one_node));
6107 tmp = fold_build2_loc (input_location, MULT_EXPR,
6108 TREE_TYPE (expr3_esize), expr3_esize,
6109 fold_convert (TREE_TYPE (expr3_esize), tmp));
6111 else
6112 tmp = expr3_esize;
6113 if (!gfc_array_allocate (&se, expr, stat, errmsg, errlen,
6114 label_finish, tmp, &nelems,
6115 e3rhs ? e3rhs : code->expr3,
6116 e3_is == E3_DESC ? expr3 : NULL_TREE,
6117 code->expr3 != NULL && e3_is == E3_DESC
6118 && code->expr3->expr_type == EXPR_ARRAY))
6120 /* A scalar or derived type. First compute the size to
6121 allocate.
6123 expr3_len is set when expr3 is an unlimited polymorphic
6124 object or a deferred length string. */
6125 if (expr3_len != NULL_TREE)
6127 tmp = fold_convert (TREE_TYPE (expr3_esize), expr3_len);
6128 tmp = fold_build2_loc (input_location, MULT_EXPR,
6129 TREE_TYPE (expr3_esize),
6130 expr3_esize, tmp);
6131 if (code->expr3->ts.type != BT_CLASS)
6132 /* expr3 is a deferred length string, i.e., we are
6133 done. */
6134 memsz = tmp;
6135 else
6137 /* For unlimited polymorphic enties build
6138 (len > 0) ? element_size * len : element_size
6139 to compute the number of bytes to allocate.
6140 This allows the allocation of unlimited polymorphic
6141 objects from an expr3 that is also unlimited
6142 polymorphic and stores a _len dependent object,
6143 e.g., a string. */
6144 memsz = fold_build2_loc (input_location, GT_EXPR,
6145 logical_type_node, expr3_len,
6146 integer_zero_node);
6147 memsz = fold_build3_loc (input_location, COND_EXPR,
6148 TREE_TYPE (expr3_esize),
6149 memsz, tmp, expr3_esize);
6152 else if (expr3_esize != NULL_TREE)
6153 /* Any other object in expr3 just needs element size in
6154 bytes. */
6155 memsz = expr3_esize;
6156 else if ((expr->ts.type == BT_CHARACTER && expr->ts.deferred)
6157 || (upoly_expr
6158 && code->ext.alloc.ts.type == BT_CHARACTER))
6160 /* Allocating deferred length char arrays need the length
6161 to allocate in the alloc_type_spec. But also unlimited
6162 polymorphic objects may be allocated as char arrays.
6163 Both are handled here. */
6164 gfc_init_se (&se_sz, NULL);
6165 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6166 gfc_add_block_to_block (&se.pre, &se_sz.pre);
6167 se_sz.expr = gfc_evaluate_now (se_sz.expr, &se.pre);
6168 gfc_add_block_to_block (&se.pre, &se_sz.post);
6169 expr3_len = se_sz.expr;
6170 tmp_expr3_len_flag = true;
6171 tmp = TYPE_SIZE_UNIT (
6172 gfc_get_char_type (code->ext.alloc.ts.kind));
6173 memsz = fold_build2_loc (input_location, MULT_EXPR,
6174 TREE_TYPE (tmp),
6175 fold_convert (TREE_TYPE (tmp),
6176 expr3_len),
6177 tmp);
6179 else if (expr->ts.type == BT_CHARACTER)
6181 /* Compute the number of bytes needed to allocate a fixed
6182 length char array. */
6183 gcc_assert (se.string_length != NULL_TREE);
6184 tmp = TYPE_SIZE_UNIT (gfc_get_char_type (expr->ts.kind));
6185 memsz = fold_build2_loc (input_location, MULT_EXPR,
6186 TREE_TYPE (tmp), tmp,
6187 fold_convert (TREE_TYPE (tmp),
6188 se.string_length));
6190 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
6191 /* Handle all types, where the alloc_type_spec is set. */
6192 memsz = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->ext.alloc.ts));
6193 else
6194 /* Handle size computation of the type declared to alloc. */
6195 memsz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
6197 /* Store the caf-attributes for latter use. */
6198 if (flag_coarray == GFC_FCOARRAY_LIB
6199 && (caf_attr = gfc_caf_attr (expr, true, &caf_refs_comp))
6200 .codimension)
6202 /* Scalar allocatable components in coarray'ed derived types make
6203 it here and are treated now. */
6204 tree caf_decl, token;
6205 gfc_se caf_se;
6207 is_coarray = true;
6208 /* Set flag, to add synchronize after the allocate. */
6209 needs_caf_sync = needs_caf_sync
6210 || caf_attr.coarray_comp || !caf_refs_comp;
6212 gfc_init_se (&caf_se, NULL);
6214 caf_decl = gfc_get_tree_for_caf_expr (expr);
6215 gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl,
6216 NULL_TREE, NULL);
6217 gfc_add_block_to_block (&se.pre, &caf_se.pre);
6218 gfc_allocate_allocatable (&se.pre, se.expr, memsz,
6219 gfc_build_addr_expr (NULL_TREE, token),
6220 NULL_TREE, NULL_TREE, NULL_TREE,
6221 label_finish, expr, 1);
6223 /* Allocate - for non-pointers with re-alloc checking. */
6224 else if (gfc_expr_attr (expr).allocatable)
6225 gfc_allocate_allocatable (&se.pre, se.expr, memsz,
6226 NULL_TREE, stat, errmsg, errlen,
6227 label_finish, expr, 0);
6228 else
6229 gfc_allocate_using_malloc (&se.pre, se.expr, memsz, stat);
6231 else
6233 /* Allocating coarrays needs a sync after the allocate executed.
6234 Set the flag to add the sync after all objects are allocated. */
6235 if (flag_coarray == GFC_FCOARRAY_LIB
6236 && (caf_attr = gfc_caf_attr (expr, true, &caf_refs_comp))
6237 .codimension)
6239 is_coarray = true;
6240 needs_caf_sync = needs_caf_sync
6241 || caf_attr.coarray_comp || !caf_refs_comp;
6244 if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
6245 && expr3_len != NULL_TREE)
6247 /* Arrays need to have a _len set before the array
6248 descriptor is filled. */
6249 gfc_add_modify (&block, al_len,
6250 fold_convert (TREE_TYPE (al_len), expr3_len));
6251 /* Prevent setting the length twice. */
6252 al_len_needs_set = false;
6254 else if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
6255 && code->ext.alloc.ts.u.cl->length)
6257 /* Cover the cases where a string length is explicitly
6258 specified by a type spec for deferred length character
6259 arrays or unlimited polymorphic objects without a
6260 source= or mold= expression. */
6261 gfc_init_se (&se_sz, NULL);
6262 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6263 gfc_add_block_to_block (&block, &se_sz.pre);
6264 gfc_add_modify (&block, al_len,
6265 fold_convert (TREE_TYPE (al_len),
6266 se_sz.expr));
6267 al_len_needs_set = false;
6271 gfc_add_block_to_block (&block, &se.pre);
6273 /* Error checking -- Note: ERRMSG only makes sense with STAT. */
6274 if (code->expr1)
6276 tmp = build1_v (GOTO_EXPR, label_errmsg);
6277 parm = fold_build2_loc (input_location, NE_EXPR,
6278 logical_type_node, stat,
6279 build_int_cst (TREE_TYPE (stat), 0));
6280 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6281 gfc_unlikely (parm, PRED_FORTRAN_FAIL_ALLOC),
6282 tmp, build_empty_stmt (input_location));
6283 gfc_add_expr_to_block (&block, tmp);
6286 /* Set the vptr only when no source= is set. When source= is set, then
6287 the trans_assignment below will set the vptr. */
6288 if (al_vptr != NULL_TREE && (!code->expr3 || code->expr3->mold))
6290 if (expr3_vptr != NULL_TREE)
6291 /* The vtab is already known, so just assign it. */
6292 gfc_add_modify (&block, al_vptr,
6293 fold_convert (TREE_TYPE (al_vptr), expr3_vptr));
6294 else
6296 /* VPTR is fixed at compile time. */
6297 gfc_symbol *vtab;
6298 gfc_typespec *ts;
6300 if (code->expr3)
6301 /* Although expr3 is pre-evaluated above, it may happen,
6302 that for arrays or in mold= cases the pre-evaluation
6303 was not successful. In these rare cases take the vtab
6304 from the typespec of expr3 here. */
6305 ts = &code->expr3->ts;
6306 else if (code->ext.alloc.ts.type == BT_DERIVED || upoly_expr)
6307 /* The alloc_type_spec gives the type to allocate or the
6308 al is unlimited polymorphic, which enforces the use of
6309 an alloc_type_spec that is not necessarily a BT_DERIVED. */
6310 ts = &code->ext.alloc.ts;
6311 else
6312 /* Prepare for setting the vtab as declared. */
6313 ts = &expr->ts;
6315 vtab = gfc_find_vtab (ts);
6316 gcc_assert (vtab);
6317 tmp = gfc_build_addr_expr (NULL_TREE,
6318 gfc_get_symbol_decl (vtab));
6319 gfc_add_modify (&block, al_vptr,
6320 fold_convert (TREE_TYPE (al_vptr), tmp));
6324 /* Add assignment for string length. */
6325 if (al_len != NULL_TREE && al_len_needs_set)
6327 if (expr3_len != NULL_TREE)
6329 gfc_add_modify (&block, al_len,
6330 fold_convert (TREE_TYPE (al_len),
6331 expr3_len));
6332 /* When tmp_expr3_len_flag is set, then expr3_len is
6333 abused to carry the length information from the
6334 alloc_type. Clear it to prevent setting incorrect len
6335 information in future loop iterations. */
6336 if (tmp_expr3_len_flag)
6337 /* No need to reset tmp_expr3_len_flag, because the
6338 presence of an expr3 can not change within in the
6339 loop. */
6340 expr3_len = NULL_TREE;
6342 else if (code->ext.alloc.ts.type == BT_CHARACTER
6343 && code->ext.alloc.ts.u.cl->length)
6345 /* Cover the cases where a string length is explicitly
6346 specified by a type spec for deferred length character
6347 arrays or unlimited polymorphic objects without a
6348 source= or mold= expression. */
6349 if (expr3_esize == NULL_TREE || code->ext.alloc.ts.kind != 1)
6351 gfc_init_se (&se_sz, NULL);
6352 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6353 gfc_add_block_to_block (&block, &se_sz.pre);
6354 gfc_add_modify (&block, al_len,
6355 fold_convert (TREE_TYPE (al_len),
6356 se_sz.expr));
6358 else
6359 gfc_add_modify (&block, al_len,
6360 fold_convert (TREE_TYPE (al_len),
6361 expr3_esize));
6363 else
6364 /* No length information needed, because type to allocate
6365 has no length. Set _len to 0. */
6366 gfc_add_modify (&block, al_len,
6367 fold_convert (TREE_TYPE (al_len),
6368 integer_zero_node));
6371 init_expr = NULL;
6372 if (code->expr3 && !code->expr3->mold && e3_is != E3_MOLD)
6374 /* Initialization via SOURCE block (or static default initializer).
6375 Switch off automatic reallocation since we have just done the
6376 ALLOCATE. */
6377 int realloc_lhs = flag_realloc_lhs;
6378 gfc_expr *init_expr = gfc_expr_to_initialize (expr);
6379 gfc_expr *rhs = e3rhs ? e3rhs : gfc_copy_expr (code->expr3);
6380 flag_realloc_lhs = 0;
6381 tmp = gfc_trans_assignment (init_expr, rhs, false, false, true,
6382 false);
6383 flag_realloc_lhs = realloc_lhs;
6384 /* Free the expression allocated for init_expr. */
6385 gfc_free_expr (init_expr);
6386 if (rhs != e3rhs)
6387 gfc_free_expr (rhs);
6388 gfc_add_expr_to_block (&block, tmp);
6390 /* Set KIND and LEN PDT components and allocate those that are
6391 parameterized. */
6392 else if (expr->ts.type == BT_DERIVED
6393 && expr->ts.u.derived->attr.pdt_type)
6395 if (code->expr3 && code->expr3->param_list)
6396 param_list = code->expr3->param_list;
6397 else if (expr->param_list)
6398 param_list = expr->param_list;
6399 else
6400 param_list = expr->symtree->n.sym->param_list;
6401 tmp = gfc_allocate_pdt_comp (expr->ts.u.derived, se.expr,
6402 expr->rank, param_list);
6403 gfc_add_expr_to_block (&block, tmp);
6405 /* Ditto for CLASS expressions. */
6406 else if (expr->ts.type == BT_CLASS
6407 && CLASS_DATA (expr)->ts.u.derived->attr.pdt_type)
6409 if (code->expr3 && code->expr3->param_list)
6410 param_list = code->expr3->param_list;
6411 else if (expr->param_list)
6412 param_list = expr->param_list;
6413 else
6414 param_list = expr->symtree->n.sym->param_list;
6415 tmp = gfc_allocate_pdt_comp (CLASS_DATA (expr)->ts.u.derived,
6416 se.expr, expr->rank, param_list);
6417 gfc_add_expr_to_block (&block, tmp);
6419 else if (code->expr3 && code->expr3->mold
6420 && code->expr3->ts.type == BT_CLASS)
6422 /* Use class_init_assign to initialize expr. */
6423 gfc_code *ini;
6424 ini = gfc_get_code (EXEC_INIT_ASSIGN);
6425 ini->expr1 = gfc_find_and_cut_at_last_class_ref (expr);
6426 tmp = gfc_trans_class_init_assign (ini);
6427 gfc_free_statements (ini);
6428 gfc_add_expr_to_block (&block, tmp);
6430 else if ((init_expr = allocate_get_initializer (code, expr)))
6432 /* Use class_init_assign to initialize expr. */
6433 gfc_code *ini;
6434 int realloc_lhs = flag_realloc_lhs;
6435 ini = gfc_get_code (EXEC_INIT_ASSIGN);
6436 ini->expr1 = gfc_expr_to_initialize (expr);
6437 ini->expr2 = init_expr;
6438 flag_realloc_lhs = 0;
6439 tmp= gfc_trans_init_assign (ini);
6440 flag_realloc_lhs = realloc_lhs;
6441 gfc_free_statements (ini);
6442 /* Init_expr is freeed by above free_statements, just need to null
6443 it here. */
6444 init_expr = NULL;
6445 gfc_add_expr_to_block (&block, tmp);
6448 /* Nullify all pointers in derived type coarrays. This registers a
6449 token for them which allows their allocation. */
6450 if (is_coarray)
6452 gfc_symbol *type = NULL;
6453 symbol_attribute caf_attr;
6454 int rank = 0;
6455 if (code->ext.alloc.ts.type == BT_DERIVED
6456 && code->ext.alloc.ts.u.derived->attr.pointer_comp)
6458 type = code->ext.alloc.ts.u.derived;
6459 rank = type->attr.dimension ? type->as->rank : 0;
6460 gfc_clear_attr (&caf_attr);
6462 else if (expr->ts.type == BT_DERIVED
6463 && expr->ts.u.derived->attr.pointer_comp)
6465 type = expr->ts.u.derived;
6466 rank = expr->rank;
6467 caf_attr = gfc_caf_attr (expr, true);
6470 /* Initialize the tokens of pointer components in derived type
6471 coarrays. */
6472 if (type)
6474 tmp = (caf_attr.codimension && !caf_attr.dimension)
6475 ? gfc_conv_descriptor_data_get (se.expr) : se.expr;
6476 tmp = gfc_nullify_alloc_comp (type, tmp, rank,
6477 GFC_STRUCTURE_CAF_MODE_IN_COARRAY);
6478 gfc_add_expr_to_block (&block, tmp);
6482 gfc_free_expr (expr);
6483 } // for-loop
6485 if (e3rhs)
6487 if (newsym)
6489 gfc_free_symbol (newsym->n.sym);
6490 XDELETE (newsym);
6492 gfc_free_expr (e3rhs);
6494 /* STAT. */
6495 if (code->expr1)
6497 tmp = build1_v (LABEL_EXPR, label_errmsg);
6498 gfc_add_expr_to_block (&block, tmp);
6501 /* ERRMSG - only useful if STAT is present. */
6502 if (code->expr1 && code->expr2)
6504 const char *msg = "Attempt to allocate an allocated object";
6505 tree slen, dlen, errmsg_str;
6506 stmtblock_t errmsg_block;
6508 gfc_init_block (&errmsg_block);
6510 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6511 gfc_add_modify (&errmsg_block, errmsg_str,
6512 gfc_build_addr_expr (pchar_type_node,
6513 gfc_build_localized_cstring_const (msg)));
6515 slen = build_int_cst (gfc_charlen_type_node, ((int) strlen (msg)));
6516 dlen = gfc_get_expr_charlen (code->expr2);
6517 slen = fold_build2_loc (input_location, MIN_EXPR,
6518 TREE_TYPE (slen), dlen, slen);
6520 gfc_trans_string_copy (&errmsg_block, dlen, errmsg,
6521 code->expr2->ts.kind,
6522 slen, errmsg_str,
6523 gfc_default_character_kind);
6524 dlen = gfc_finish_block (&errmsg_block);
6526 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
6527 stat, build_int_cst (TREE_TYPE (stat), 0));
6529 tmp = build3_v (COND_EXPR, tmp,
6530 dlen, build_empty_stmt (input_location));
6532 gfc_add_expr_to_block (&block, tmp);
6535 /* STAT block. */
6536 if (code->expr1)
6538 if (TREE_USED (label_finish))
6540 tmp = build1_v (LABEL_EXPR, label_finish);
6541 gfc_add_expr_to_block (&block, tmp);
6544 gfc_init_se (&se, NULL);
6545 gfc_conv_expr_lhs (&se, code->expr1);
6546 tmp = convert (TREE_TYPE (se.expr), stat);
6547 gfc_add_modify (&block, se.expr, tmp);
6550 if (needs_caf_sync)
6552 /* Add a sync all after the allocation has been executed. */
6553 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
6554 3, null_pointer_node, null_pointer_node,
6555 integer_zero_node);
6556 gfc_add_expr_to_block (&post, tmp);
6559 gfc_add_block_to_block (&block, &se.post);
6560 gfc_add_block_to_block (&block, &post);
6562 return gfc_finish_block (&block);
6566 /* Translate a DEALLOCATE statement. */
6568 tree
6569 gfc_trans_deallocate (gfc_code *code)
6571 gfc_se se;
6572 gfc_alloc *al;
6573 tree apstat, pstat, stat, errmsg, errlen, tmp;
6574 tree label_finish, label_errmsg;
6575 stmtblock_t block;
6577 pstat = apstat = stat = errmsg = errlen = tmp = NULL_TREE;
6578 label_finish = label_errmsg = NULL_TREE;
6580 gfc_start_block (&block);
6582 /* Count the number of failed deallocations. If deallocate() was
6583 called with STAT= , then set STAT to the count. If deallocate
6584 was called with ERRMSG, then set ERRMG to a string. */
6585 if (code->expr1)
6587 tree gfc_int4_type_node = gfc_get_int_type (4);
6589 stat = gfc_create_var (gfc_int4_type_node, "stat");
6590 pstat = gfc_build_addr_expr (NULL_TREE, stat);
6592 /* GOTO destinations. */
6593 label_errmsg = gfc_build_label_decl (NULL_TREE);
6594 label_finish = gfc_build_label_decl (NULL_TREE);
6595 TREE_USED (label_finish) = 0;
6598 /* Set ERRMSG - only needed if STAT is available. */
6599 if (code->expr1 && code->expr2)
6601 gfc_init_se (&se, NULL);
6602 se.want_pointer = 1;
6603 gfc_conv_expr_lhs (&se, code->expr2);
6604 errmsg = se.expr;
6605 errlen = se.string_length;
6608 for (al = code->ext.alloc.list; al != NULL; al = al->next)
6610 gfc_expr *expr = gfc_copy_expr (al->expr);
6611 bool is_coarray = false, is_coarray_array = false;
6612 int caf_mode = 0;
6614 gcc_assert (expr->expr_type == EXPR_VARIABLE);
6616 if (expr->ts.type == BT_CLASS)
6617 gfc_add_data_component (expr);
6619 gfc_init_se (&se, NULL);
6620 gfc_start_block (&se.pre);
6622 se.want_pointer = 1;
6623 se.descriptor_only = 1;
6624 gfc_conv_expr (&se, expr);
6626 /* Deallocate PDT components that are parameterized. */
6627 tmp = NULL;
6628 if (expr->ts.type == BT_DERIVED
6629 && expr->ts.u.derived->attr.pdt_type
6630 && expr->symtree->n.sym->param_list)
6631 tmp = gfc_deallocate_pdt_comp (expr->ts.u.derived, se.expr, expr->rank);
6632 else if (expr->ts.type == BT_CLASS
6633 && CLASS_DATA (expr)->ts.u.derived->attr.pdt_type
6634 && expr->symtree->n.sym->param_list)
6635 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr)->ts.u.derived,
6636 se.expr, expr->rank);
6638 if (tmp)
6639 gfc_add_expr_to_block (&block, tmp);
6641 if (flag_coarray == GFC_FCOARRAY_LIB
6642 || flag_coarray == GFC_FCOARRAY_SINGLE)
6644 bool comp_ref;
6645 symbol_attribute caf_attr = gfc_caf_attr (expr, false, &comp_ref);
6646 if (caf_attr.codimension)
6648 is_coarray = true;
6649 is_coarray_array = caf_attr.dimension || !comp_ref
6650 || caf_attr.coarray_comp;
6652 if (flag_coarray == GFC_FCOARRAY_LIB)
6653 /* When the expression to deallocate is referencing a
6654 component, then only deallocate it, but do not
6655 deregister. */
6656 caf_mode = GFC_STRUCTURE_CAF_MODE_IN_COARRAY
6657 | (comp_ref && !caf_attr.coarray_comp
6658 ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY : 0);
6662 if (expr->rank || is_coarray_array)
6664 gfc_ref *ref;
6666 if (gfc_bt_struct (expr->ts.type)
6667 && expr->ts.u.derived->attr.alloc_comp
6668 && !gfc_is_finalizable (expr->ts.u.derived, NULL))
6670 gfc_ref *last = NULL;
6672 for (ref = expr->ref; ref; ref = ref->next)
6673 if (ref->type == REF_COMPONENT)
6674 last = ref;
6676 /* Do not deallocate the components of a derived type
6677 ultimate pointer component. */
6678 if (!(last && last->u.c.component->attr.pointer)
6679 && !(!last && expr->symtree->n.sym->attr.pointer))
6681 if (is_coarray && expr->rank == 0
6682 && (!last || !last->u.c.component->attr.dimension)
6683 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
6685 /* Add the ref to the data member only, when this is not
6686 a regular array or deallocate_alloc_comp will try to
6687 add another one. */
6688 tmp = gfc_conv_descriptor_data_get (se.expr);
6690 else
6691 tmp = se.expr;
6692 tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp,
6693 expr->rank, caf_mode);
6694 gfc_add_expr_to_block (&se.pre, tmp);
6698 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
6700 gfc_coarray_deregtype caf_dtype;
6702 if (is_coarray)
6703 caf_dtype = gfc_caf_is_dealloc_only (caf_mode)
6704 ? GFC_CAF_COARRAY_DEALLOCATE_ONLY
6705 : GFC_CAF_COARRAY_DEREGISTER;
6706 else
6707 caf_dtype = GFC_CAF_COARRAY_NOCOARRAY;
6708 tmp = gfc_deallocate_with_status (se.expr, pstat, errmsg, errlen,
6709 label_finish, false, expr,
6710 caf_dtype);
6711 gfc_add_expr_to_block (&se.pre, tmp);
6713 else if (TREE_CODE (se.expr) == COMPONENT_REF
6714 && TREE_CODE (TREE_TYPE (se.expr)) == ARRAY_TYPE
6715 && TREE_CODE (TREE_TYPE (TREE_TYPE (se.expr)))
6716 == RECORD_TYPE)
6718 /* class.c(finalize_component) generates these, when a
6719 finalizable entity has a non-allocatable derived type array
6720 component, which has allocatable components. Obtain the
6721 derived type of the array and deallocate the allocatable
6722 components. */
6723 for (ref = expr->ref; ref; ref = ref->next)
6725 if (ref->u.c.component->attr.dimension
6726 && ref->u.c.component->ts.type == BT_DERIVED)
6727 break;
6730 if (ref && ref->u.c.component->ts.u.derived->attr.alloc_comp
6731 && !gfc_is_finalizable (ref->u.c.component->ts.u.derived,
6732 NULL))
6734 tmp = gfc_deallocate_alloc_comp
6735 (ref->u.c.component->ts.u.derived,
6736 se.expr, expr->rank);
6737 gfc_add_expr_to_block (&se.pre, tmp);
6741 if (al->expr->ts.type == BT_CLASS)
6743 gfc_reset_vptr (&se.pre, al->expr);
6744 if (UNLIMITED_POLY (al->expr)
6745 || (al->expr->ts.type == BT_DERIVED
6746 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6747 /* Clear _len, too. */
6748 gfc_reset_len (&se.pre, al->expr);
6751 else
6753 tmp = gfc_deallocate_scalar_with_status (se.expr, pstat, label_finish,
6754 false, al->expr,
6755 al->expr->ts, is_coarray);
6756 gfc_add_expr_to_block (&se.pre, tmp);
6758 /* Set to zero after deallocation. */
6759 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
6760 se.expr,
6761 build_int_cst (TREE_TYPE (se.expr), 0));
6762 gfc_add_expr_to_block (&se.pre, tmp);
6764 if (al->expr->ts.type == BT_CLASS)
6766 gfc_reset_vptr (&se.pre, al->expr);
6767 if (UNLIMITED_POLY (al->expr)
6768 || (al->expr->ts.type == BT_DERIVED
6769 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6770 /* Clear _len, too. */
6771 gfc_reset_len (&se.pre, al->expr);
6775 if (code->expr1)
6777 tree cond;
6779 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, stat,
6780 build_int_cst (TREE_TYPE (stat), 0));
6781 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6782 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
6783 build1_v (GOTO_EXPR, label_errmsg),
6784 build_empty_stmt (input_location));
6785 gfc_add_expr_to_block (&se.pre, tmp);
6788 tmp = gfc_finish_block (&se.pre);
6789 gfc_add_expr_to_block (&block, tmp);
6790 gfc_free_expr (expr);
6793 if (code->expr1)
6795 tmp = build1_v (LABEL_EXPR, label_errmsg);
6796 gfc_add_expr_to_block (&block, tmp);
6799 /* Set ERRMSG - only needed if STAT is available. */
6800 if (code->expr1 && code->expr2)
6802 const char *msg = "Attempt to deallocate an unallocated object";
6803 stmtblock_t errmsg_block;
6804 tree errmsg_str, slen, dlen, cond;
6806 gfc_init_block (&errmsg_block);
6808 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6809 gfc_add_modify (&errmsg_block, errmsg_str,
6810 gfc_build_addr_expr (pchar_type_node,
6811 gfc_build_localized_cstring_const (msg)));
6812 slen = build_int_cst (gfc_charlen_type_node, ((int) strlen (msg)));
6813 dlen = gfc_get_expr_charlen (code->expr2);
6815 gfc_trans_string_copy (&errmsg_block, dlen, errmsg, code->expr2->ts.kind,
6816 slen, errmsg_str, gfc_default_character_kind);
6817 tmp = gfc_finish_block (&errmsg_block);
6819 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, stat,
6820 build_int_cst (TREE_TYPE (stat), 0));
6821 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6822 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC), tmp,
6823 build_empty_stmt (input_location));
6825 gfc_add_expr_to_block (&block, tmp);
6828 if (code->expr1 && TREE_USED (label_finish))
6830 tmp = build1_v (LABEL_EXPR, label_finish);
6831 gfc_add_expr_to_block (&block, tmp);
6834 /* Set STAT. */
6835 if (code->expr1)
6837 gfc_init_se (&se, NULL);
6838 gfc_conv_expr_lhs (&se, code->expr1);
6839 tmp = convert (TREE_TYPE (se.expr), stat);
6840 gfc_add_modify (&block, se.expr, tmp);
6843 return gfc_finish_block (&block);
6846 #include "gt-fortran-trans-stmt.h"